import { playgroundHelper } from "../../helpers/helpers"; import { stablecoinVaultConstants } from "../constants"; import { MPCSignature } from "chainsig.js"; import { actionCreators, createTransaction, Signature, SignedTransaction, } from "@near-js/transactions"; import { baseDecode } from "@near-js/utils"; import { Account } from "@near-js/accounts"; import { KeyType, PublicKey } from "@near-js/crypto"; // Bridge configuration const BRIDGE_AMOUNT = "799988400"; // 1 USDC with 6 decimals const TOKEN_ID = "eth-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.omft.near"; // NEAR intents token ID const RECIPIENT = "0x64aff91dc6f7be29c46cbc35be24a18b5b2e92e6"; // Must match policy memo restriction const POLICY_ID = "proxy_ft_withdraw_eth"; console.log("Initiating proxy token bridge from NEAR to Ethereum"); async function main() { // Get current block hash and derived account info const block = await playgroundHelper.provider.block({ finality: "near-final", }); const derivedAccount = new Account( stablecoinVaultConstants.NEAR_CHAINSIG_DERIVED_ACCOUNT, playgroundHelper.provider ); const allKeys = await derivedAccount.getAccessKeyList(); const publicKeyHex = stablecoinVaultConstants.NEAR_CHAINSIG_DERIVED_ACCOUNT; const publicKeyBytes = Buffer.from(publicKeyHex, "hex"); const derivedPublicKey = new PublicKey({ keyType: 0, data: new Uint8Array(publicKeyBytes), }); const matchingKey = allKeys.keys.find( (e) => e.public_key === derivedPublicKey.toString() ); if (!matchingKey) { throw new Error("Key not found for derived account"); } // Create NEAR transaction for ft_withdraw const transaction = createTransaction( stablecoinVaultConstants.NEAR_CHAINSIG_DERIVED_ACCOUNT, derivedPublicKey, "intents.near", // receiver_id for ft_withdraw BigInt(matchingKey.access_key.nonce) + 1n, [ actionCreators.functionCall( "ft_withdraw", { receiver_id: TOKEN_ID, token: TOKEN_ID, amount: BRIDGE_AMOUNT, memo: `WITHDRAW_TO:${RECIPIENT}`, }, 30000000000000n, // 30 TGas 1n // 1 yoctoNEAR ), ], baseDecode(block.header.hash) ); // Encode transaction as base64 const encodedTx = Buffer.from(transaction.encode()).toString("base64"); console.log("Proposing ft_withdraw transaction via proxy policy..."); // Execute bridge transaction using the proxy ft_withdraw policy const signatures = await playgroundHelper.account.callFunction< MPCSignature[] >({ contractId: playgroundHelper.vaultContractId, methodName: "propose_execution", args: { policy_id: POLICY_ID, function_args: encodedTx, deadline_hours: 1, }, gas: 50000000000000n, // 50 TGas }); console.log("Proposal executed, signatures received:", signatures); const firstSignResult = signatures[0]; if (!("signature" in firstSignResult)) { throw new Error("Invalid signature result from chain signature"); } const signatureBuffer = Buffer.from(firstSignResult.signature); // Create signed transaction const signedTx = new SignedTransaction({ transaction: transaction, signature: new Signature({ keyType: KeyType.ED25519, data: signatureBuffer, }), }); console.log("Publishing signed transaction to NEAR network..."); // Publish the signed transaction to NEAR const receipt = await playgroundHelper.provider.sendTransaction(signedTx); console.log("Transaction published successfully!"); console.log("Transaction hash:", receipt.transaction.hash); console.log( `Bridged ${BRIDGE_AMOUNT} tokens from proxy account to Ethereum address ${RECIPIENT}` ); } // Execute the main function main() .then(() => { console.log("Proxy bridge transaction completed successfully"); }) .catch((error) => { console.error("Failed to execute proxy bridge transaction:", error.message); process.exit(1); });