UNPKG

@wormhole-foundation/sdk-solana-cctp

Version:

SDK for Solana, used in conjunction with @wormhole-foundation/sdk

120 lines 5.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReceiveMessageInstruction = exports.nonceAccount = exports.calculateFirstNonce = void 0; const spl_token_1 = require("@solana/spl-token"); const web3_js_1 = require("@solana/web3.js"); const sdk_connect_1 = require("@wormhole-foundation/sdk-connect"); const sdk_solana_1 = require("@wormhole-foundation/sdk-solana"); const program_js_1 = require("../program.js"); const index_js_1 = require("./../accounts/index.js"); const MAX_NONCES_PER_ACCOUNT = 6400n; function calculateFirstNonce(nonce) { return (((nonce - BigInt(1)) / MAX_NONCES_PER_ACCOUNT) * MAX_NONCES_PER_ACCOUNT + BigInt(1)); } exports.calculateFirstNonce = calculateFirstNonce; function nonceAccount(nonce, sourceChain, messageTransmitterProgramId) { const srcDomain = sourceChain.toString(); const usedNonces = (0, index_js_1.findProgramAddress)('used_nonces', messageTransmitterProgramId, [srcDomain, calculateFirstNonce(nonce).toString()]).publicKey; return usedNonces; } exports.nonceAccount = nonceAccount; async function createReceiveMessageInstruction(messageTransmitterProgramId, tokenMessengerProgramId, usdcAddress, circleMessage, attestation, payer) { const messageBytes = Buffer.from(sdk_connect_1.CircleBridge.serialize(circleMessage)); const attestationBytes = Buffer.from(sdk_connect_1.encoding.hex.decode(attestation)); const solanaUsdcAddress = new web3_js_1.PublicKey(usdcAddress); const sourceUsdcAddress = new web3_js_1.PublicKey(circleMessage.payload.burnToken.toUint8Array()); const receiver = new sdk_solana_1.SolanaAddress(circleMessage.payload.mintRecipient).unwrap(); const payerPubkey = payer ? new web3_js_1.PublicKey(payer) : receiver; const srcDomain = circleMessage.sourceDomain.toString(); // Find pdas const messageTransmitterAccount = (0, index_js_1.findProgramAddress)('message_transmitter', messageTransmitterProgramId); const tokenMessenger = (0, index_js_1.findProgramAddress)('token_messenger', tokenMessengerProgramId); const tokenMinter = (0, index_js_1.findProgramAddress)('token_minter', tokenMessengerProgramId); const localToken = (0, index_js_1.findProgramAddress)('local_token', tokenMessengerProgramId, [solanaUsdcAddress]); const remoteTokenMessengerKey = (0, index_js_1.findProgramAddress)('remote_token_messenger', tokenMessengerProgramId, [srcDomain]); const tokenPair = (0, index_js_1.findProgramAddress)('token_pair', tokenMessengerProgramId, [ srcDomain, sourceUsdcAddress, ]); const custodyTokenAccount = (0, index_js_1.findProgramAddress)('custody', tokenMessengerProgramId, [solanaUsdcAddress]); const authorityPda = (0, index_js_1.findProgramAddress)('message_transmitter_authority', messageTransmitterProgramId, [tokenMessengerProgramId]).publicKey; // Calculate the nonce PDA. const usedNonces = nonceAccount(circleMessage.nonce, circleMessage.sourceDomain, messageTransmitterProgramId); const eventAuthority = (0, index_js_1.findProgramAddress)('__event_authority', messageTransmitterProgramId); const tokenMessengerEventAuthority = (0, index_js_1.findProgramAddress)('__event_authority', tokenMessengerProgramId); // Build the accountMetas list. These are passed as remainingAccounts for the TokenMessengerMinter CPI const accountMetas = []; accountMetas.push({ isSigner: false, isWritable: false, pubkey: tokenMessenger.publicKey, }); accountMetas.push({ isSigner: false, isWritable: false, pubkey: remoteTokenMessengerKey.publicKey, }); accountMetas.push({ isSigner: false, isWritable: true, pubkey: tokenMinter.publicKey, }); accountMetas.push({ isSigner: false, isWritable: true, pubkey: localToken.publicKey, }); accountMetas.push({ isSigner: false, isWritable: false, pubkey: tokenPair.publicKey, }); accountMetas.push({ isSigner: false, isWritable: true, pubkey: receiver, }); accountMetas.push({ isSigner: false, isWritable: true, pubkey: custodyTokenAccount.publicKey, }); accountMetas.push({ isSigner: false, isWritable: false, pubkey: spl_token_1.TOKEN_PROGRAM_ID, }); accountMetas.push({ isSigner: false, isWritable: false, pubkey: tokenMessengerEventAuthority.publicKey, }); accountMetas.push({ isSigner: false, isWritable: false, pubkey: tokenMessengerProgramId, }); const messageTransmitterProgram = (0, program_js_1.createMessageTransmitterProgramInterface)(messageTransmitterProgramId); return (messageTransmitterProgram.methods .receiveMessage({ message: messageBytes, attestation: attestationBytes, }) .accounts({ payer: payerPubkey, caller: payerPubkey, authorityPda, messageTransmitter: messageTransmitterAccount.publicKey, usedNonces, receiver: tokenMessengerProgramId, systemProgram: web3_js_1.SystemProgram.programId, eventAuthority: eventAuthority.publicKey, program: messageTransmitterProgram.programId, }) // Add remainingAccounts needed for TokenMessengerMinter CPI .remainingAccounts(accountMetas) .transaction()); } exports.createReceiveMessageInstruction = createReceiveMessageInstruction; //# sourceMappingURL=receiveMessage.js.map