@across-protocol/contracts 3.0.17 → 3.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/artifacts/build-info/9cb910e5bb5dd730cd01af84a0fb0466.json +1 -0
- package/artifacts/contracts/Ink_SpokePool.sol/Ink_SpokePool.dbg.json +4 -0
- package/artifacts/contracts/Ink_SpokePool.sol/Ink_SpokePool.json +2316 -0
- package/contracts/Ink_SpokePool.sol +72 -0
- package/dist/deploy/consts.js +8 -2
- package/dist/deployments/deployments.json +7 -1
- package/dist/hardhat.config.js +17 -0
- package/dist/scripts/svm/addressToPublicKey.d.ts +1 -0
- package/dist/scripts/svm/addressToPublicKey.js +20 -0
- package/dist/scripts/svm/bridgeLiabilityToHubPool.d.ts +25 -0
- package/dist/scripts/svm/bridgeLiabilityToHubPool.js +221 -0
- package/dist/scripts/svm/closeRelayerPdas.js +8 -9
- package/dist/scripts/svm/enableRoute.js +7 -1
- package/dist/scripts/svm/executeRebalanceToHubPool.d.ts +29 -0
- package/dist/scripts/svm/executeRebalanceToHubPool.js +345 -0
- package/dist/scripts/svm/executeRebalanceToSpokePool.d.ts +1 -0
- package/dist/scripts/svm/executeRebalanceToSpokePool.js +240 -0
- package/dist/scripts/svm/fakeFillWithRandomDistribution.js +6 -7
- package/dist/scripts/svm/initialize.js +2 -2
- package/dist/scripts/svm/proposeRebalanceToHubPool.d.ts +27 -0
- package/dist/scripts/svm/proposeRebalanceToHubPool.js +117 -0
- package/dist/scripts/svm/proposeRebalanceToSpokePool.d.ts +1 -0
- package/dist/scripts/svm/proposeRebalanceToSpokePool.js +97 -0
- package/dist/scripts/svm/publicKeyToAddress.d.ts +1 -0
- package/dist/scripts/svm/publicKeyToAddress.js +20 -0
- package/dist/scripts/svm/queryDeposits.js +3 -2
- package/dist/scripts/svm/queryFills.js +12 -14
- package/dist/scripts/svm/queryRoute.js +7 -1
- package/dist/scripts/svm/queryState.js +1 -0
- package/dist/scripts/svm/remoteHubPoolPauseDeposits.d.ts +1 -0
- package/dist/scripts/svm/remoteHubPoolPauseDeposits.js +191 -0
- package/dist/scripts/svm/remoteHubPoolSetDepositRoute.js +16 -29
- package/dist/scripts/svm/remotePauseDeposits.js +21 -27
- package/dist/scripts/svm/simpleDeposit.js +7 -1
- package/dist/scripts/svm/simpleFakeRelayerRepayment.js +3 -3
- package/dist/scripts/svm/simpleFill.js +6 -6
- package/dist/scripts/svm/utils/constants.d.ts +4 -0
- package/dist/scripts/svm/utils/constants.js +8 -1
- package/dist/scripts/svm/utils/helpers.d.ts +33 -0
- package/dist/scripts/svm/utils/helpers.js +60 -1
- package/dist/scripts/svm/utils/poolRebalanceTree.d.ts +22 -0
- package/dist/scripts/svm/utils/poolRebalanceTree.js +20 -0
- package/dist/src/svm/coders.d.ts +37 -0
- package/dist/src/svm/coders.js +250 -0
- package/dist/src/svm/conversionUtils.d.ts +22 -0
- package/dist/src/svm/conversionUtils.js +73 -0
- package/dist/src/svm/index.d.ts +6 -0
- package/dist/src/svm/index.js +22 -0
- package/dist/src/svm/instructionParamsUtils.d.ts +31 -0
- package/dist/src/svm/instructionParamsUtils.js +128 -0
- package/dist/src/svm/relayHashUtils.d.ts +30 -0
- package/dist/src/svm/relayHashUtils.js +209 -0
- package/dist/src/svm/solanaProgramUtils.d.ts +38 -0
- package/dist/src/svm/solanaProgramUtils.js +147 -0
- package/dist/src/svm/transactionUtils.d.ts +8 -0
- package/dist/src/svm/transactionUtils.js +55 -0
- package/dist/src/types/svm.d.ts +118 -0
- package/dist/src/types/svm.js +2 -0
- package/dist/target/types/svm_spoke.d.ts +47 -42
- package/dist/tasks/enableL1TokenAcrossEcosystem.js +3 -33
- package/dist/tasks/types.d.ts +2 -0
- package/dist/tasks/types.js +2 -0
- package/dist/tasks/utils.d.ts +12 -0
- package/dist/tasks/utils.js +34 -0
- package/dist/test/svm/MulticallHandler.js +2 -2
- package/dist/test/svm/SvmSpoke.Bundle.js +59 -60
- package/dist/test/svm/SvmSpoke.Deposit.js +23 -31
- package/dist/test/svm/SvmSpoke.Fill.AcrossPlus.js +16 -18
- package/dist/test/svm/SvmSpoke.Fill.js +38 -40
- package/dist/test/svm/SvmSpoke.HandleReceiveMessage.js +2 -2
- package/dist/test/svm/SvmSpoke.Ownership.js +11 -17
- package/dist/test/svm/SvmSpoke.RefundClaims.js +12 -11
- package/dist/test/svm/SvmSpoke.Routes.js +11 -7
- package/dist/test/svm/SvmSpoke.SlowFill.AcrossPlus.js +72 -16
- package/dist/test/svm/SvmSpoke.SlowFill.js +33 -28
- package/dist/test/svm/SvmSpoke.TokenBridge.js +15 -17
- package/dist/test/svm/SvmSpoke.common.d.ts +1 -49
- package/dist/test/svm/SvmSpoke.common.js +6 -5
- package/dist/test/svm/cctpHelpers.js +2 -2
- package/dist/test/svm/utils.d.ts +5 -67
- package/dist/test/svm/utils.js +10 -220
- package/dist/typechain/contracts/Ink_SpokePool.d.ts +1251 -0
- package/dist/typechain/contracts/Ink_SpokePool.js +2 -0
- package/dist/typechain/contracts/index.d.ts +1 -0
- package/dist/typechain/factories/contracts/Ink_SpokePool__factory.d.ts +1833 -0
- package/dist/typechain/factories/contracts/Ink_SpokePool__factory.js +2347 -0
- package/dist/typechain/factories/contracts/index.d.ts +1 -0
- package/dist/typechain/factories/contracts/index.js +3 -1
- package/dist/typechain/hardhat.d.ts +9 -0
- package/dist/typechain/index.d.ts +2 -0
- package/dist/typechain/index.js +5 -3
- package/package.json +2 -2
- package/dist/src/SvmUtils.d.ts +0 -50
- package/dist/src/SvmUtils.js +0 -415
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This script bridges remote call to pause deposits on Solana Spoke Pool. Required environment:
|
|
3
|
-
// -
|
|
4
|
-
// -
|
|
3
|
+
// - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
|
|
4
|
+
// - MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
|
|
5
5
|
// - HUB_POOL_ADDRESS: Hub Pool address
|
|
6
6
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
7
|
if (k2 === undefined) k2 = k;
|
|
@@ -37,11 +37,13 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
37
37
|
const yargs_1 = __importDefault(require("yargs"));
|
|
38
38
|
const helpers_1 = require("yargs/helpers");
|
|
39
39
|
const ethers_1 = require("ethers");
|
|
40
|
+
const common_1 = require("@uma/common");
|
|
40
41
|
const cctpHelpers_1 = require("../../test/svm/cctpHelpers");
|
|
41
42
|
const typechain_1 = require("../../typechain");
|
|
42
43
|
const spl_token_1 = require("@solana/spl-token");
|
|
43
44
|
const constants_1 = require("./utils/constants");
|
|
44
45
|
const helpers_2 = require("./utils/helpers");
|
|
46
|
+
const constants_2 = require("../../utils/constants");
|
|
45
47
|
// Set up Solana provider.
|
|
46
48
|
const provider = anchor_1.AnchorProvider.env();
|
|
47
49
|
anchor.setProvider(provider);
|
|
@@ -58,28 +60,12 @@ async function remoteHubPoolSetDepositRoute() {
|
|
|
58
60
|
const depositsEnabled = resolvedArgv.depositsEnabled;
|
|
59
61
|
const seed = new anchor_1.BN(0);
|
|
60
62
|
const resumeRemoteTx = resolvedArgv.resumeRemoteTx;
|
|
61
|
-
// Set up Ethereum provider.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
throw new Error("Environment variable ETHERS_MNEMONIC is not set");
|
|
68
|
-
}
|
|
69
|
-
const ethersSigner = ethers_1.ethers.Wallet.fromMnemonic(process.env.ETHERS_MNEMONIC).connect(ethersProvider);
|
|
70
|
-
if (!process.env.HUB_POOL_ADDRESS) {
|
|
71
|
-
throw new Error("Environment variable HUB_POOL_ADDRESS is not set");
|
|
72
|
-
}
|
|
73
|
-
const hubPoolAddress = process.env.HUB_POOL_ADDRESS;
|
|
74
|
-
let cluster;
|
|
75
|
-
const rpcEndpoint = provider.connection.rpcEndpoint;
|
|
76
|
-
if (rpcEndpoint.includes("devnet"))
|
|
77
|
-
cluster = "devnet";
|
|
78
|
-
else if (rpcEndpoint.includes("mainnet"))
|
|
79
|
-
cluster = "mainnet";
|
|
80
|
-
else
|
|
81
|
-
throw new Error(`Unsupported cluster endpoint: ${rpcEndpoint}`);
|
|
82
|
-
const isDevnet = cluster == "devnet";
|
|
63
|
+
// Set up Ethereum provider and signer.
|
|
64
|
+
const isDevnet = (0, helpers_2.isSolanaDevnet)(provider);
|
|
65
|
+
const nodeURL = isDevnet ? (0, common_1.getNodeUrl)("sepolia", true) : (0, common_1.getNodeUrl)("mainnet", true);
|
|
66
|
+
const ethersProvider = new ethers_1.ethers.providers.JsonRpcProvider(nodeURL);
|
|
67
|
+
const ethersSigner = ethers_1.ethers.Wallet.fromMnemonic((0, helpers_2.requireEnv)("MNEMONIC")).connect(ethersProvider);
|
|
68
|
+
const hubPoolAddress = (0, helpers_2.requireEnv)("HUB_POOL_ADDRESS");
|
|
83
69
|
const usdcProgramId = isDevnet ? constants_1.SOLANA_USDC_DEVNET : constants_1.SOLANA_USDC_MAINNET;
|
|
84
70
|
const originToken = new web3_js_1.PublicKey(usdcProgramId);
|
|
85
71
|
const originTokenAddress = (0, helpers_2.fromBytes32ToAddress)((0, helpers_2.fromBase58ToBytes32)(originToken.toBase58()));
|
|
@@ -103,16 +89,17 @@ async function remoteHubPoolSetDepositRoute() {
|
|
|
103
89
|
const [selfAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("self_authority")], svmSpokeProgram.programId);
|
|
104
90
|
const [eventAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], svmSpokeProgram.programId);
|
|
105
91
|
const irisApiUrl = isDevnet ? constants_1.CIRCLE_IRIS_API_URL_DEVNET : constants_1.CIRCLE_IRIS_API_URL_MAINNET;
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
92
|
+
const solanaCluster = isDevnet ? "devnet" : "mainnet";
|
|
93
|
+
const supportedEvmChainId = isDevnet ? constants_2.CHAIN_IDs.SEPOLIA : constants_2.CHAIN_IDs.MAINNET; // Sepolia is bridged to devnet, Ethereum to mainnet in CCTP.
|
|
94
|
+
const evmChainId = (await ethersProvider.getNetwork()).chainId;
|
|
95
|
+
if (evmChainId !== supportedEvmChainId) {
|
|
96
|
+
throw new Error(`Chain ID ${evmChainId} does not match expected Solana cluster ${solanaCluster}`);
|
|
110
97
|
}
|
|
111
98
|
const hubPool = typechain_1.HubPool__factory.connect(hubPoolAddress, ethersProvider);
|
|
112
99
|
console.log("Remotely configuring deposit route...");
|
|
113
100
|
console.table([
|
|
114
101
|
{ Property: "seed", Value: seed.toString() },
|
|
115
|
-
{ Property: "
|
|
102
|
+
{ Property: "evmChainId", Value: evmChainId.toString() },
|
|
116
103
|
{ Property: "originChainId", Value: originChainId },
|
|
117
104
|
{ Property: "destinationChainId", Value: destinationChainId },
|
|
118
105
|
{ Property: "depositsEnabled", Value: depositsEnabled },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This script bridges remote call to pause deposits on Solana Spoke Pool. Required environment:
|
|
3
|
-
// -
|
|
4
|
-
// -
|
|
3
|
+
// - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
|
|
4
|
+
// - MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
|
|
5
5
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
6
|
if (k2 === undefined) k2 = k;
|
|
7
7
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -36,7 +36,11 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
36
36
|
const yargs_1 = __importDefault(require("yargs"));
|
|
37
37
|
const helpers_1 = require("yargs/helpers");
|
|
38
38
|
const ethers_1 = require("ethers");
|
|
39
|
+
const common_1 = require("@uma/common");
|
|
39
40
|
const cctpHelpers_1 = require("../../test/svm/cctpHelpers");
|
|
41
|
+
const helpers_2 = require("./utils/helpers");
|
|
42
|
+
const constants_1 = require("./utils/constants");
|
|
43
|
+
const constants_2 = require("../../utils/constants");
|
|
40
44
|
// Set up Solana provider.
|
|
41
45
|
const provider = anchor_1.AnchorProvider.env();
|
|
42
46
|
anchor.setProvider(provider);
|
|
@@ -59,15 +63,11 @@ async function remotePauseDeposits() {
|
|
|
59
63
|
const seed = new anchor_1.BN(resolvedArgv.seed);
|
|
60
64
|
const pause = resolvedArgv.pause;
|
|
61
65
|
const resumeRemoteTx = resolvedArgv.resumeRemoteTx;
|
|
62
|
-
// Set up Ethereum provider.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
if (!process.env.ETHERS_MNEMONIC) {
|
|
68
|
-
throw new Error("Environment variable ETHERS_MNEMONIC is not set");
|
|
69
|
-
}
|
|
70
|
-
const ethersSigner = ethers_1.ethers.Wallet.fromMnemonic(process.env.ETHERS_MNEMONIC).connect(ethersProvider);
|
|
66
|
+
// Set up Ethereum provider and signer.
|
|
67
|
+
const isDevnet = (0, helpers_2.isSolanaDevnet)(provider);
|
|
68
|
+
const nodeURL = isDevnet ? (0, common_1.getNodeUrl)("sepolia", true) : (0, common_1.getNodeUrl)("mainnet", true);
|
|
69
|
+
const ethersProvider = new ethers_1.ethers.providers.JsonRpcProvider(nodeURL);
|
|
70
|
+
const ethersSigner = ethers_1.ethers.Wallet.fromMnemonic((0, helpers_2.requireEnv)("MNEMONIC")).connect(ethersProvider);
|
|
71
71
|
// CCTP domains.
|
|
72
72
|
const remoteDomain = 0; // Ethereum
|
|
73
73
|
const localDomain = 5; // Solana
|
|
@@ -81,33 +81,27 @@ async function remotePauseDeposits() {
|
|
|
81
81
|
const [authorityPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("message_transmitter_authority"), svmSpokeProgram.programId.toBuffer()], messageTransmitterProgram.programId);
|
|
82
82
|
const [selfAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("self_authority")], svmSpokeProgram.programId);
|
|
83
83
|
const [eventAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], svmSpokeProgram.programId);
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
cluster
|
|
90
|
-
else
|
|
91
|
-
throw new Error(`Unsupported cluster endpoint: ${rpcEndpoint}`);
|
|
92
|
-
const irisApiUrl = cluster == "devnet" ? "https://iris-api-sandbox.circle.com" : "https://iris-api.circle.com";
|
|
93
|
-
const supportedChainId = cluster == "devnet" ? 11155111 : 1; // Sepolia is bridged to devnet, Ethereum to mainnet in CCTP.
|
|
94
|
-
const chainId = (await ethersProvider.getNetwork()).chainId;
|
|
95
|
-
// TODO: improve type casting.
|
|
96
|
-
if (chainId !== BigInt(supportedChainId)) {
|
|
97
|
-
throw new Error(`Chain ID ${chainId} does not match expected Solana cluster ${cluster}`);
|
|
84
|
+
const solanaCluster = isDevnet ? "devnet" : "mainnet";
|
|
85
|
+
const irisApiUrl = isDevnet ? constants_1.CIRCLE_IRIS_API_URL_DEVNET : constants_1.CIRCLE_IRIS_API_URL_MAINNET;
|
|
86
|
+
const supportedEvmChainId = isDevnet ? constants_2.CHAIN_IDs.SEPOLIA : constants_2.CHAIN_IDs.MAINNET; // Sepolia is bridged to devnet, Ethereum to mainnet in CCTP.
|
|
87
|
+
const evmChainId = (await ethersProvider.getNetwork()).chainId;
|
|
88
|
+
if (evmChainId !== supportedEvmChainId) {
|
|
89
|
+
throw new Error(`Chain ID ${evmChainId} does not match expected Solana cluster ${solanaCluster}`);
|
|
98
90
|
}
|
|
99
91
|
const messageTransmitterRemoteIface = new ethers_1.ethers.utils.Interface([
|
|
100
92
|
"function sendMessage(uint32 destinationDomain, bytes32 recipient, bytes messageBody)",
|
|
101
93
|
"event MessageSent(bytes message)",
|
|
102
94
|
]);
|
|
103
95
|
// CCTP MessageTransmitter from https://developers.circle.com/stablecoins/docs/evm-smart-contracts
|
|
104
|
-
const messageTransmitterRemoteAddress =
|
|
96
|
+
const messageTransmitterRemoteAddress = isDevnet
|
|
97
|
+
? constants_1.SEPOLIA_CCTP_MESSAGE_TRANSMITTER_ADDRESS
|
|
98
|
+
: constants_1.MAINNET_CCTP_MESSAGE_TRANSMITTER_ADDRESS;
|
|
105
99
|
const messageTransmitterRemote = new ethers_1.ethers.Contract(messageTransmitterRemoteAddress, messageTransmitterRemoteIface, ethersSigner);
|
|
106
100
|
const spokePoolIface = new ethers_1.ethers.utils.Interface(["function pauseDeposits(bool pause)"]);
|
|
107
101
|
console.log("Remotely controlling pausedDeposits...");
|
|
108
102
|
console.table([
|
|
109
103
|
{ Property: "seed", Value: seed.toString() },
|
|
110
|
-
{ Property: "
|
|
104
|
+
{ Property: "evmChainId", Value: evmChainId.toString() },
|
|
111
105
|
{ Property: "pause", Value: pause },
|
|
112
106
|
{ Property: "svmSpokeProgramProgramId", Value: svmSpokeProgram.programId.toString() },
|
|
113
107
|
{ Property: "providerPublicKey", Value: provider.wallet.publicKey.toString() },
|
|
@@ -39,6 +39,7 @@ anchor.setProvider(provider);
|
|
|
39
39
|
const idl = require("../../target/idl/svm_spoke.json");
|
|
40
40
|
const program = new anchor_1.Program(idl, provider);
|
|
41
41
|
const programId = program.programId;
|
|
42
|
+
console.log("SVM-Spoke Program ID:", programId.toString());
|
|
42
43
|
// Parse arguments
|
|
43
44
|
const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
44
45
|
.option("seed", { type: "string", demandOption: true, describe: "Seed for the state account PDA" })
|
|
@@ -65,7 +66,12 @@ async function depositV3() {
|
|
|
65
66
|
// Define the state account PDA
|
|
66
67
|
const [statePda, _] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("state"), seed.toArrayLike(Buffer, "le", 8)], programId);
|
|
67
68
|
// Define the route account PDA
|
|
68
|
-
const [routePda] = web3_js_1.PublicKey.findProgramAddressSync([
|
|
69
|
+
const [routePda] = web3_js_1.PublicKey.findProgramAddressSync([
|
|
70
|
+
Buffer.from("route"),
|
|
71
|
+
inputToken.toBytes(),
|
|
72
|
+
seed.toArrayLike(Buffer, "le", 8),
|
|
73
|
+
destinationChainId.toArrayLike(Buffer, "le", 8),
|
|
74
|
+
], programId);
|
|
69
75
|
// Define the signer (replace with your actual signer)
|
|
70
76
|
const signer = provider.wallet.payer;
|
|
71
77
|
// Find ATA for the input token to be stored by state (vault). This was created when the route was enabled.
|
|
@@ -34,7 +34,7 @@ const spl_token_1 = require("@solana/spl-token");
|
|
|
34
34
|
const yargs_1 = __importDefault(require("yargs"));
|
|
35
35
|
const helpers_1 = require("yargs/helpers");
|
|
36
36
|
const MerkleTree_1 = require("@uma/common/dist/MerkleTree");
|
|
37
|
-
const
|
|
37
|
+
const svm_1 = require("../../src/svm");
|
|
38
38
|
// Set up the provider
|
|
39
39
|
const provider = anchor_1.AnchorProvider.env();
|
|
40
40
|
anchor.setProvider(provider);
|
|
@@ -121,7 +121,7 @@ async function testBundleLogic() {
|
|
|
121
121
|
refundAddresses, // Array of refund authority addresses
|
|
122
122
|
refundAmounts: amounts, // Array of amounts
|
|
123
123
|
};
|
|
124
|
-
const merkleTree = new MerkleTree_1.MerkleTree([relayerRefundLeaf],
|
|
124
|
+
const merkleTree = new MerkleTree_1.MerkleTree([relayerRefundLeaf], svm_1.relayerRefundHashFn);
|
|
125
125
|
const root = merkleTree.getRoot();
|
|
126
126
|
console.log("Merkle Tree Generated. Root: ", Buffer.from(root).toString("hex"));
|
|
127
127
|
// Set the tree using the methods from the .Bundle test
|
|
@@ -197,7 +197,7 @@ async function testBundleLogic() {
|
|
|
197
197
|
if (!lookupTableAccount) {
|
|
198
198
|
throw new Error("AddressLookupTableAccount not fetched");
|
|
199
199
|
}
|
|
200
|
-
await (0,
|
|
200
|
+
await (0, svm_1.loadExecuteRelayerRefundLeafParams)(program, signer.publicKey, rootBundleId, leaf, proofAsNumbers);
|
|
201
201
|
console.log(`loaded execute relayer refund leaf params ${instructionParams}. \nExecuting relayer refund leaf...`);
|
|
202
202
|
const executeInstruction = await program.methods
|
|
203
203
|
.executeRelayerRefundLeaf()
|
|
@@ -34,7 +34,7 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
34
34
|
const spl_token_1 = require("@solana/spl-token");
|
|
35
35
|
const yargs_1 = __importDefault(require("yargs"));
|
|
36
36
|
const helpers_1 = require("yargs/helpers");
|
|
37
|
-
const
|
|
37
|
+
const svm_1 = require("../../src/svm");
|
|
38
38
|
// Set up the provider
|
|
39
39
|
const provider = anchor_1.AnchorProvider.env();
|
|
40
40
|
anchor.setProvider(provider);
|
|
@@ -52,7 +52,7 @@ const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
|
52
52
|
.option("inputAmount", { type: "number", demandOption: true, describe: "Input amount" })
|
|
53
53
|
.option("outputAmount", { type: "number", demandOption: true, describe: "Output amount" })
|
|
54
54
|
.option("originChainId", { type: "string", demandOption: true, describe: "Origin chain ID" })
|
|
55
|
-
.option("depositId", { type: "
|
|
55
|
+
.option("depositId", { type: "string", demandOption: true, describe: "Deposit ID" })
|
|
56
56
|
.option("fillDeadline", { type: "number", demandOption: false, describe: "Fill deadline" })
|
|
57
57
|
.option("exclusivityDeadline", { type: "number", demandOption: false, describe: "Exclusivity deadline" }).argv;
|
|
58
58
|
async function fillV3Relay() {
|
|
@@ -65,7 +65,7 @@ async function fillV3Relay() {
|
|
|
65
65
|
const inputAmount = new anchor_1.BN(resolvedArgv.inputAmount);
|
|
66
66
|
const outputAmount = new anchor_1.BN(resolvedArgv.outputAmount);
|
|
67
67
|
const originChainId = new anchor_1.BN(resolvedArgv.originChainId);
|
|
68
|
-
const depositId = resolvedArgv.depositId;
|
|
68
|
+
const depositId = (0, svm_1.intToU8Array32)(new anchor_1.BN(resolvedArgv.depositId));
|
|
69
69
|
const fillDeadline = resolvedArgv.fillDeadline || Math.floor(Date.now() / 1000) + 60; // Current time + 1 minute
|
|
70
70
|
const exclusivityDeadline = resolvedArgv.exclusivityDeadline || Math.floor(Date.now() / 1000) + 30; // Current time + 30 seconds
|
|
71
71
|
const message = Buffer.from("");
|
|
@@ -79,7 +79,7 @@ async function fillV3Relay() {
|
|
|
79
79
|
inputAmount,
|
|
80
80
|
outputAmount,
|
|
81
81
|
originChainId,
|
|
82
|
-
depositId
|
|
82
|
+
depositId,
|
|
83
83
|
fillDeadline,
|
|
84
84
|
exclusivityDeadline,
|
|
85
85
|
message,
|
|
@@ -92,7 +92,7 @@ async function fillV3Relay() {
|
|
|
92
92
|
// Fetch the state from the on-chain program to get chainId
|
|
93
93
|
const state = await program.account.state.fetch(statePda);
|
|
94
94
|
const chainId = new anchor_1.BN(state.chainId);
|
|
95
|
-
const relayHashUint8Array = (0,
|
|
95
|
+
const relayHashUint8Array = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
|
|
96
96
|
// Define the fill status account PDA
|
|
97
97
|
const [fillStatusPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fills"), relayHashUint8Array], programId);
|
|
98
98
|
// Create ATA for the relayer and recipient token accounts
|
|
@@ -122,7 +122,7 @@ async function fillV3Relay() {
|
|
|
122
122
|
state: statePda,
|
|
123
123
|
signer: signer.publicKey,
|
|
124
124
|
instructionParams: program.programId,
|
|
125
|
-
|
|
125
|
+
mint: outputToken,
|
|
126
126
|
relayerTokenAccount: relayerTokenAccount,
|
|
127
127
|
recipientTokenAccount: recipientTokenAccount,
|
|
128
128
|
fillStatus: fillStatusPda,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import BN from "bn.js";
|
|
1
2
|
export declare const CIRCLE_IRIS_API_URL_DEVNET = "https://iris-api-sandbox.circle.com";
|
|
2
3
|
export declare const CIRCLE_IRIS_API_URL_MAINNET = "https://iris-api.circle.com";
|
|
3
4
|
export declare const SOLANA_USDC_MAINNET = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
4
5
|
export declare const SOLANA_USDC_DEVNET = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU";
|
|
6
|
+
export declare const SEPOLIA_CCTP_MESSAGE_TRANSMITTER_ADDRESS = "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD";
|
|
7
|
+
export declare const MAINNET_CCTP_MESSAGE_TRANSMITTER_ADDRESS = "0x0a992d191deec32afe36203ad87d7d289a738f81";
|
|
8
|
+
export declare const SOLANA_SPOKE_STATE_SEED: BN;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SOLANA_USDC_DEVNET = exports.SOLANA_USDC_MAINNET = exports.CIRCLE_IRIS_API_URL_MAINNET = exports.CIRCLE_IRIS_API_URL_DEVNET = void 0;
|
|
6
|
+
exports.SOLANA_SPOKE_STATE_SEED = exports.MAINNET_CCTP_MESSAGE_TRANSMITTER_ADDRESS = exports.SEPOLIA_CCTP_MESSAGE_TRANSMITTER_ADDRESS = exports.SOLANA_USDC_DEVNET = exports.SOLANA_USDC_MAINNET = exports.CIRCLE_IRIS_API_URL_MAINNET = exports.CIRCLE_IRIS_API_URL_DEVNET = void 0;
|
|
7
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
4
8
|
exports.CIRCLE_IRIS_API_URL_DEVNET = "https://iris-api-sandbox.circle.com";
|
|
5
9
|
exports.CIRCLE_IRIS_API_URL_MAINNET = "https://iris-api.circle.com";
|
|
6
10
|
exports.SOLANA_USDC_MAINNET = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
7
11
|
exports.SOLANA_USDC_DEVNET = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU";
|
|
12
|
+
exports.SEPOLIA_CCTP_MESSAGE_TRANSMITTER_ADDRESS = "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD";
|
|
13
|
+
exports.MAINNET_CCTP_MESSAGE_TRANSMITTER_ADDRESS = "0x0a992d191deec32afe36203ad87d7d289a738f81";
|
|
14
|
+
exports.SOLANA_SPOKE_STATE_SEED = new bn_js_1.default(0);
|
|
@@ -1,2 +1,35 @@
|
|
|
1
|
+
import { AnchorProvider } from "@coral-xyz/anchor";
|
|
2
|
+
import { BigNumber } from "ethers";
|
|
3
|
+
import { PublicKey } from "@solana/web3.js";
|
|
4
|
+
import { MerkleTree } from "@uma/common";
|
|
5
|
+
import { RelayerRefundLeafSolana, RelayerRefundLeafType } from "../../../src/types/svm";
|
|
6
|
+
export declare const requireEnv: (name: string) => string;
|
|
7
|
+
export declare const getSolanaChainId: (cluster: "devnet" | "mainnet") => BigNumber;
|
|
8
|
+
export declare const isSolanaDevnet: (provider: AnchorProvider) => boolean;
|
|
9
|
+
export declare const formatUsdc: (amount: BigNumber) => string;
|
|
1
10
|
export declare const fromBase58ToBytes32: (input: string) => string;
|
|
2
11
|
export declare const fromBytes32ToAddress: (input: string) => string;
|
|
12
|
+
export declare function constructEmptyPoolRebalanceTree(chainId: BigNumber, groupIndex: number): {
|
|
13
|
+
poolRebalanceLeaf: {
|
|
14
|
+
chainId: BigNumber;
|
|
15
|
+
groupIndex: BigNumber;
|
|
16
|
+
bundleLpFees: never[];
|
|
17
|
+
netSendAmounts: never[];
|
|
18
|
+
runningBalances: never[];
|
|
19
|
+
leafId: BigNumber;
|
|
20
|
+
l1Tokens: never[];
|
|
21
|
+
};
|
|
22
|
+
poolRebalanceTree: MerkleTree<{
|
|
23
|
+
chainId: BigNumber;
|
|
24
|
+
groupIndex: BigNumber;
|
|
25
|
+
bundleLpFees: never[];
|
|
26
|
+
netSendAmounts: never[];
|
|
27
|
+
runningBalances: never[];
|
|
28
|
+
leafId: BigNumber;
|
|
29
|
+
l1Tokens: never[];
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
export declare const constructSimpleRebalanceTreeToHubPool: (netSendAmount: BigNumber, solanaChainId: BigNumber, svmUsdc: PublicKey) => {
|
|
33
|
+
merkleTree: MerkleTree<RelayerRefundLeafType>;
|
|
34
|
+
leaves: RelayerRefundLeafSolana[];
|
|
35
|
+
};
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fromBytes32ToAddress = exports.fromBase58ToBytes32 = void 0;
|
|
3
|
+
exports.constructSimpleRebalanceTreeToHubPool = exports.fromBytes32ToAddress = exports.fromBase58ToBytes32 = exports.formatUsdc = exports.isSolanaDevnet = exports.getSolanaChainId = exports.requireEnv = void 0;
|
|
4
|
+
exports.constructEmptyPoolRebalanceTree = constructEmptyPoolRebalanceTree;
|
|
4
5
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
8
|
+
const common_1 = require("@uma/common");
|
|
9
|
+
const svm_1 = require("../../../src/svm");
|
|
10
|
+
const requireEnv = (name) => {
|
|
11
|
+
if (!process.env[name])
|
|
12
|
+
throw new Error(`Environment variable ${name} is not set`);
|
|
13
|
+
return process.env[name];
|
|
14
|
+
};
|
|
15
|
+
exports.requireEnv = requireEnv;
|
|
16
|
+
const getSolanaChainId = (cluster) => {
|
|
17
|
+
return ethers_1.BigNumber.from(BigInt(ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.toUtf8Bytes(`solana-${cluster}`))) & BigInt("0xFFFFFFFFFFFFFFFF"));
|
|
18
|
+
};
|
|
19
|
+
exports.getSolanaChainId = getSolanaChainId;
|
|
20
|
+
const isSolanaDevnet = (provider) => {
|
|
21
|
+
const solanaRpcEndpoint = provider.connection.rpcEndpoint;
|
|
22
|
+
if (solanaRpcEndpoint.includes("devnet"))
|
|
23
|
+
return true;
|
|
24
|
+
else if (solanaRpcEndpoint.includes("mainnet"))
|
|
25
|
+
return false;
|
|
26
|
+
else
|
|
27
|
+
throw new Error(`Unsupported solanaCluster endpoint: ${solanaRpcEndpoint}`);
|
|
28
|
+
};
|
|
29
|
+
exports.isSolanaDevnet = isSolanaDevnet;
|
|
30
|
+
const formatUsdc = (amount) => {
|
|
31
|
+
return ethers_1.ethers.utils.formatUnits(amount, 6);
|
|
32
|
+
};
|
|
33
|
+
exports.formatUsdc = formatUsdc;
|
|
5
34
|
const fromBase58ToBytes32 = (input) => {
|
|
6
35
|
const decodedBytes = anchor_1.utils.bytes.bs58.decode(input);
|
|
7
36
|
return "0x" + Buffer.from(decodedBytes).toString("hex");
|
|
@@ -19,3 +48,33 @@ const fromBytes32ToAddress = (input) => {
|
|
|
19
48
|
return "0x" + address;
|
|
20
49
|
};
|
|
21
50
|
exports.fromBytes32ToAddress = fromBytes32ToAddress;
|
|
51
|
+
function constructEmptyPoolRebalanceTree(chainId, groupIndex) {
|
|
52
|
+
const poolRebalanceLeaf = {
|
|
53
|
+
chainId,
|
|
54
|
+
groupIndex: ethers_1.BigNumber.from(groupIndex),
|
|
55
|
+
bundleLpFees: [],
|
|
56
|
+
netSendAmounts: [],
|
|
57
|
+
runningBalances: [],
|
|
58
|
+
leafId: ethers_1.BigNumber.from(0),
|
|
59
|
+
l1Tokens: [],
|
|
60
|
+
};
|
|
61
|
+
const rebalanceParamType = "tuple( uint256 chainId, uint256[] bundleLpFees, int256[] netSendAmounts, int256[] runningBalances, uint256 groupIndex, uint8 leafId, address[] l1Tokens )";
|
|
62
|
+
const rebalanceHashFn = (input) => ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode([rebalanceParamType], [input]));
|
|
63
|
+
const poolRebalanceTree = new common_1.MerkleTree([poolRebalanceLeaf], rebalanceHashFn);
|
|
64
|
+
return { poolRebalanceLeaf, poolRebalanceTree };
|
|
65
|
+
}
|
|
66
|
+
const constructSimpleRebalanceTreeToHubPool = (netSendAmount, solanaChainId, svmUsdc) => {
|
|
67
|
+
const relayerRefundLeaves = [];
|
|
68
|
+
relayerRefundLeaves.push({
|
|
69
|
+
isSolana: true,
|
|
70
|
+
leafId: new anchor_1.BN(0),
|
|
71
|
+
chainId: new anchor_1.BN(solanaChainId.toString()),
|
|
72
|
+
amountToReturn: new anchor_1.BN(netSendAmount.toString()),
|
|
73
|
+
mintPublicKey: new web3_js_1.PublicKey(svmUsdc),
|
|
74
|
+
refundAddresses: [],
|
|
75
|
+
refundAmounts: [],
|
|
76
|
+
});
|
|
77
|
+
const merkleTree = new common_1.MerkleTree(relayerRefundLeaves, svm_1.relayerRefundHashFn);
|
|
78
|
+
return { merkleTree, leaves: relayerRefundLeaves };
|
|
79
|
+
};
|
|
80
|
+
exports.constructSimpleRebalanceTreeToHubPool = constructSimpleRebalanceTreeToHubPool;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MerkleTree } from "@uma/common";
|
|
2
|
+
import { BigNumber } from "ethers";
|
|
3
|
+
export declare function constructSimpleRebalanceTree(l1TokenAddress: string, netSendAmount: BigNumber, chainId: BigNumber): {
|
|
4
|
+
poolRebalanceLeaf: {
|
|
5
|
+
chainId: BigNumber;
|
|
6
|
+
groupIndex: BigNumber;
|
|
7
|
+
bundleLpFees: BigNumber[];
|
|
8
|
+
netSendAmounts: BigNumber[];
|
|
9
|
+
runningBalances: BigNumber[];
|
|
10
|
+
leafId: BigNumber;
|
|
11
|
+
l1Tokens: string[];
|
|
12
|
+
};
|
|
13
|
+
poolRebalanceTree: MerkleTree<{
|
|
14
|
+
chainId: BigNumber;
|
|
15
|
+
groupIndex: BigNumber;
|
|
16
|
+
bundleLpFees: BigNumber[];
|
|
17
|
+
netSendAmounts: BigNumber[];
|
|
18
|
+
runningBalances: BigNumber[];
|
|
19
|
+
leafId: BigNumber;
|
|
20
|
+
l1Tokens: string[];
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.constructSimpleRebalanceTree = constructSimpleRebalanceTree;
|
|
4
|
+
const common_1 = require("@uma/common");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
function constructSimpleRebalanceTree(l1TokenAddress, netSendAmount, chainId) {
|
|
7
|
+
const poolRebalanceLeaf = {
|
|
8
|
+
chainId,
|
|
9
|
+
groupIndex: ethers_1.BigNumber.from(1), // Not 0 as this script is not relaying root bundles, only sending tokens to spoke.
|
|
10
|
+
bundleLpFees: [ethers_1.BigNumber.from(0)],
|
|
11
|
+
netSendAmounts: [netSendAmount],
|
|
12
|
+
runningBalances: [netSendAmount],
|
|
13
|
+
leafId: ethers_1.BigNumber.from(0),
|
|
14
|
+
l1Tokens: [l1TokenAddress],
|
|
15
|
+
};
|
|
16
|
+
const rebalanceParamType = "tuple( uint256 chainId, uint256[] bundleLpFees, int256[] netSendAmounts, int256[] runningBalances, uint256 groupIndex, uint8 leafId, address[] l1Tokens )";
|
|
17
|
+
const rebalanceHashFn = (input) => ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode([rebalanceParamType], [input]));
|
|
18
|
+
const poolRebalanceTree = new common_1.MerkleTree([poolRebalanceLeaf], rebalanceHashFn);
|
|
19
|
+
return { poolRebalanceLeaf, poolRebalanceTree };
|
|
20
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BorshAccountsCoder } from "@coral-xyz/anchor";
|
|
2
|
+
import { Message, PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
3
|
+
import { AcrossPlusMessage } from "../types/svm";
|
|
4
|
+
/**
|
|
5
|
+
* Extended Anchor accounts coder to handle large account data.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LargeAccountsCoder<A extends string = string> extends BorshAccountsCoder<A> {
|
|
8
|
+
private getAccountLayouts;
|
|
9
|
+
encode<T = any>(accountName: A, account: T): Promise<Buffer>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper to encode MulticallHandler transactions.
|
|
13
|
+
*/
|
|
14
|
+
export declare class MulticallHandlerCoder {
|
|
15
|
+
readonly compiledMessage: Message;
|
|
16
|
+
private readonly layout;
|
|
17
|
+
constructor(instructions: TransactionInstruction[], payerKey?: PublicKey);
|
|
18
|
+
private static coderArg;
|
|
19
|
+
private static coderTypes;
|
|
20
|
+
get readOnlyLen(): number;
|
|
21
|
+
get compiledKeyMetas(): {
|
|
22
|
+
pubkey: PublicKey;
|
|
23
|
+
isSigner: boolean;
|
|
24
|
+
isWritable: boolean;
|
|
25
|
+
}[];
|
|
26
|
+
encode(): Buffer;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Helper to encode Across+ messages.
|
|
30
|
+
*/
|
|
31
|
+
export declare class AcrossPlusMessageCoder {
|
|
32
|
+
private acrossPlusMessage;
|
|
33
|
+
constructor(acrossPlusMessage: AcrossPlusMessage);
|
|
34
|
+
private static coderArg;
|
|
35
|
+
private static coderTypes;
|
|
36
|
+
encode(): Buffer;
|
|
37
|
+
}
|