UNPKG

@relayprotocol/relay-svm-wallet-adapter

Version:

An SVM (Solana Virtual Machine) adapter for use in @relayprotocol/relay-sdk

75 lines 3.74 kB
import { AddressLookupTableAccount, Connection, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js'; import { LogLevel, getClient } from '@relayprotocol/relay-sdk'; /** * Adapts a Solana wallet to work with the Relay SDK * @param walletAddress - The public key address of the Solana wallet * @param chainId - The chain ID for the Solana network (e.g., 101 for mainnet, 102 for testnet) * @param connection - The Solana web3.js Connection instance for interacting with the network * @param signAndSendTransaction - Function to sign and send a transaction, returning a promise with the transaction signature * @param payerKey - Optional public key of the account that will pay for transaction fees (defaults to walletAddress) * @returns An AdaptedWallet object that conforms to the Relay SDK interface */ export const adaptSolanaWallet = (walletAddress, chainId, connection, signAndSendTransaction, payerKey) => { let _chainId = chainId; const getChainId = async () => { return _chainId; }; return { vmType: 'svm', getChainId, address: async () => { return walletAddress; }, handleSignMessageStep: async () => { throw new Error('Message signing not implemented for Solana'); }, handleSendTransactionStep: async (_chainId, stepItem) => { const client = getClient(); const instructions = stepItem?.data?.instructions?.map((i) => new TransactionInstruction({ keys: i.keys.map((k) => ({ isSigner: k.isSigner, isWritable: k.isWritable, pubkey: new PublicKey(k.pubkey) })), programId: new PublicKey(i.programId), data: Buffer.from(i.data, 'hex') })) ?? []; const messageV0 = new TransactionMessage({ payerKey: new PublicKey(payerKey ?? walletAddress), instructions, recentBlockhash: await connection .getLatestBlockhash() .then((b) => b.blockhash) }).compileToV0Message(await Promise.all(stepItem?.data?.addressLookupTableAddresses?.map(async (address) => await connection .getAddressLookupTable(new PublicKey(address)) .then((res) => res.value)) ?? [])); const transaction = new VersionedTransaction(messageV0); const signature = await signAndSendTransaction(transaction, undefined, instructions, stepItem.data.instructions); client.log(['Transaction Signature obtained', signature], LogLevel.Verbose); return signature.signature; }, handleConfirmTransactionStep: async (txHash) => { // Solana doesn't have a concept of replaced transactions // So we don't need to handle onReplaced and onCancelled const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed'); const result = await connection.confirmTransaction({ blockhash: blockhash, lastValidBlockHeight: lastValidBlockHeight, signature: txHash }); if (result.value.err) { throw new Error(`Transaction failed: ${result.value.err}`); } return { blockHash: result.context.slot.toString(), blockNumber: result.context.slot, txHash }; }, switchChain: (chainId) => { _chainId = chainId; return new Promise((res) => res()); } }; }; //# sourceMappingURL=adapter.js.map