@locker-labs/sdk
Version:
A utility library for enhancing your ERC-4337 experience
94 lines • 4.99 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cctpBridgeTokenFromSolana = cctpBridgeTokenFromSolana;
exports.cctpReceiveTokenFromSolana = cctpReceiveTokenFromSolana;
const web3_js_1 = require("@solana/web3.js");
const viem_1 = require("viem");
const spl = require("@solana/spl-token");
const anchor = require("@coral-xyz/anchor");
const cctpConstants_js_1 = require("./cctpConstants.js");
const cctpUtils_js_1 = require("./cctpUtils.js");
const tokens_js_1 = require("../../../accounts/tokens.js");
async function cctpBridgeTokenFromSolana(params) {
const { solanaSigner, solanaTokenAddress, amount, recipientAddress, recipientChain, solanaChain, solanaRpcUrl } = params;
const { irisApiUrl, } = cctpConstants_js_1.CIRCLE_CONFIG[solanaChain];
const destinationDomainId = cctpConstants_js_1.CCTP_DOMAIN_IDS[recipientChain];
const userTokenAccount = await (0, cctpUtils_js_1.findOrCreateUserTokenAccount)(params);
const expectedTokenAddress = tokens_js_1.USDC[solanaChain];
if (solanaTokenAddress !== expectedTokenAddress) {
throw new Error(`Cannot bridge token ${solanaTokenAddress} with CCTP in on ${solanaChain}. Expected USDC at ${expectedTokenAddress}.`);
}
const connection = new web3_js_1.Connection(solanaRpcUrl);
const provider = new anchor.AnchorProvider(connection, new anchor.Wallet(solanaSigner), {});
anchor.setProvider(provider);
const { messageTransmitterProgram, tokenMessengerMinterProgram } = (0, cctpUtils_js_1.getPrograms)(provider);
const evmRecipientBytes32 = (0, cctpUtils_js_1.evmAddressToBytes32)(recipientAddress);
const mintRecipient = new web3_js_1.PublicKey((0, viem_1.hexToBytes)(evmRecipientBytes32));
const usdcPublicKey = new web3_js_1.PublicKey(solanaTokenAddress);
const pdas = (0, cctpUtils_js_1.getDepositForBurnPdas)({ messageTransmitterProgram, tokenMessengerMinterProgram }, usdcPublicKey, destinationDomainId);
const messageSentEventAccountKeypair = web3_js_1.Keypair.generate();
console.log('Depositing for burn...');
const depositForBurnTx = await tokenMessengerMinterProgram.methods
.depositForBurn({
amount: new anchor.BN(amount),
destinationDomain: destinationDomainId,
mintRecipient,
})
.accounts({
owner: provider.wallet.publicKey,
eventRentPayer: provider.wallet.publicKey,
senderAuthorityPda: pdas.authorityPda.publicKey,
burnTokenAccount: userTokenAccount,
messageTransmitter: pdas.messageTransmitterAccount.publicKey,
tokenMessenger: pdas.tokenMessengerAccount.publicKey,
remoteTokenMessenger: pdas.remoteTokenMessengerKey.publicKey,
tokenMinter: pdas.tokenMinterAccount.publicKey,
localToken: pdas.localToken.publicKey,
burnTokenMint: usdcPublicKey,
messageTransmitterProgram: messageTransmitterProgram.programId,
tokenMessengerMinterProgram: tokenMessengerMinterProgram.programId,
messageSentEventData: messageSentEventAccountKeypair.publicKey,
tokenProgram: spl.TOKEN_PROGRAM_ID,
})
.signers([messageSentEventAccountKeypair])
.rpc();
console.log(`Fetching attestation for tx ${depositForBurnTx}`);
const response = await (0, cctpUtils_js_1.getMessages)(depositForBurnTx, irisApiUrl, solanaChain);
const { attestation, message, eventNonce } = response.messages[0];
console.log('Reclaiming event account...');
const reclaimEventAccountTx = await messageTransmitterProgram.methods
.reclaimEventAccount({
attestation: Buffer.from(attestation.replace("0x", ""), "hex"),
})
.accounts({
payee: provider.wallet.publicKey,
messageTransmitter: pdas.messageTransmitterAccount.publicKey,
messageSentEventData: messageSentEventAccountKeypair.publicKey,
})
.rpc();
return {
depositTx: depositForBurnTx,
reclaimTx: reclaimEventAccountTx,
attestation,
message,
eventNonce,
recipientChain,
};
}
async function cctpReceiveTokenFromSolana(cctpResponse, lockerClient) {
const { attestation, message, recipientChain, } = cctpResponse;
console.log('CCTP receive token from Solana...');
console.log('Attestation:', attestation);
console.log('Message:', message);
console.log('Recipient chain:', recipientChain);
const messageTransmitter = (0, cctpUtils_js_1.getMessageTransmitterFromChain)(recipientChain);
const selector = (0, viem_1.keccak256)((0, viem_1.toHex)('receiveMessage(bytes,bytes)')).slice(0, 10);
const suffixData = (0, viem_1.encodeAbiParameters)([
{ name: "message", type: "bytes" },
{ name: "attestation", type: "bytes" },
], [message, attestation]);
const data = selector + suffixData.slice(2);
const response = await lockerClient.sendUserOps(messageTransmitter.address, data, BigInt(0));
return response;
}
//# sourceMappingURL=cctpBridge.js.map