import { SolanaUtil } from './solanaUtil' ; import { Connection , Keypair , PublicKey , SystemProgram , TransactionInstruction , } from '@solana/web3.js' ; import { SignCallback } from '../wallet' ; import { debug , ExtendedCluster } from '../util' ; import { addCEK , addToChannel , createUserDetails , updateUserDetails , getCekAccountKey , getDirectChannelAccountKey , getUserDetailsKey , initializeChannel , initializeDirectChannel , post , } from './instruction' ; import { CEKData } from './models/CEKData' ; import { ChannelData } from './models/ChannelData' ; import { PROGRAM_ID } from '../constants' ; import { CEKAccountData } from './models/CEKAccountData' ; import { MessageData } from './models/MessageData' ; import { UserDetailsData } from './models/UserDetailsData' ; export class SolariumTransaction { static async createGroupChannel ( connection , payer , creatorDID , creatorAuthority , name , initialCEKs , signCallback , cluster ? ) { const channel = Keypair . generate ( ) ; debug ( `Channel address: ${ channel . publicKey . toBase58 ( ) }` ) ; const size = ChannelData . sizeBytes ( ) ; const balanceNeeded = await connection . getMinimumBalanceForRentExemption ( size ) ; const createChannelAccountInstruction = SystemProgram . createAccount ( { programId : PROGRAM_ID , fromPubkey : payer , lamports : balanceNeeded , newAccountPubkey : channel . publicKey , space : size , } ) ; const initializeChannelInstruction = await initializeChannel ( payer , channel . publicKey , name , creatorDID , creatorAuthority , initialCEKs ) ; await SolariumTransaction . signAndSendTransaction ( [ createChannelAccountInstruction , initializeChannelInstruction ] , signCallback , [ channel ] , cluster ) ; return channel . publicKey ; } static async createDirectChannel ( payer , creatorDID , creatorAuthority , inviteeDID , creatorCEKs , inviteeCEKs , signCallback , cluster ? ) { const channel = await getDirectChannelAccountKey ( creatorDID , inviteeDID ) ; debug ( `Channel address: ${ channel . toBase58 ( ) }` ) ; const initializeDirectChannelInstruction = await initializeDirectChannel ( payer , channel , creatorDID , creatorAuthority , inviteeDID , creatorCEKs , inviteeCEKs ) ; await SolariumTransaction . signAndSendTransaction ( [ initializeDirectChannelInstruction ] , signCallback , [ ] , cluster ) ; return channel ; } static async addDIDToChannel ( payer , channel , inviterDID , inviterAuthority , inviteeDID , ceks , signCallback , cluster ? ) { const addToChannelInstruction = await addToChannel ( payer , channel , inviteeDID , inviterDID , inviterAuthority , ceks ) ; await SolariumTransaction . signAndSendTransaction ( [ addToChannelInstruction ] , signCallback , [ ] , cluster ) ; } static async getChannelData ( connection , channel ) { const accountInfo = await connection . getAccountInfo ( channel ) ; if ( ! accountInfo ) return null ; return ChannelData . fromAccount ( accountInfo . data ) ; } static async getCEKAccountData ( connection , ownerDID , channel ) { const cekAccount = await getCekAccountKey ( ownerDID , channel ) ; const accountInfo = await connection . getAccountInfo ( cekAccount ) ; if ( ! accountInfo ) return null ; return CEKAccountData . fromAccount ( accountInfo . data ) ; } static async postMessage ( channel , senderDID , senderAuthority , message , signCallback , cluster ? ) { const messageData = MessageData . for ( senderDID , message ) ; const instruction = await post ( channel , senderAuthority , messageData ) ; return SolariumTransaction . signAndSendTransaction ( [ instruction ] , signCallback , [ ] , cluster ) ; } static async addCEKToAccount ( channel , memberDID , memberAuthority , cek , signCallback , cluster ? ) { const addToChannelInstruction = await addCEK ( channel , memberDID , memberAuthority , cek ) ; await SolariumTransaction . signAndSendTransaction ( [ addToChannelInstruction ] , signCallback , [ ] , cluster ) ; } static async createUserDetails ( payer , did , authority , signCallback , alias , size ? , cluster ? ) { const userDetails = await getUserDetailsKey ( did ) ; debug ( `userDetails address: ${ userDetails . toBase58 ( ) }` ) ; const createUserDetailsInstruction = await createUserDetails ( payer , did , authority , alias , size ) ; await SolariumTransaction . signAndSendTransaction ( [ createUserDetailsInstruction ] , signCallback , [ ] , cluster ) ; return userDetails ; } static async updateUserDetails ( did , authority , signCallback , alias , addressBook , cluster ? ) { const userDetails = await getUserDetailsKey ( did ) ; debug ( `userDetails address: ${ userDetails . toBase58 ( ) }` ) ; const updateUserDetailsInstruction = await updateUserDetails ( did , authority , alias , addressBook ) ; await SolariumTransaction . signAndSendTransaction ( [ updateUserDetailsInstruction ] , signCallback , [ ] , cluster ) ; return userDetails ; } static async getUserDetails ( connection , did ) { const userDetails = await getUserDetailsKey ( did ) ; const accountInfo = await connection . getAccountInfo ( userDetails ) ; if ( ! accountInfo ) return null ; return UserDetailsData . fromAccount ( accountInfo . data ) ; } static async signAndSendTransaction ( instructions , createSignedTx , additionalSigners , cluster ? ) { const connection = SolanaUtil . getConnection ( cluster ) ; const { blockhash : recentBlockhash , } = await connection . getRecentBlockhash ( ) ; const transaction = await createSignedTx ( instructions , { recentBlockhash } , additionalSigners ) ; return SolanaUtil . sendAndConfirmRawTransaction ( connection , transaction ) ; } }