@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.
Files changed (95) hide show
  1. package/README.md +2 -0
  2. package/artifacts/build-info/9cb910e5bb5dd730cd01af84a0fb0466.json +1 -0
  3. package/artifacts/contracts/Ink_SpokePool.sol/Ink_SpokePool.dbg.json +4 -0
  4. package/artifacts/contracts/Ink_SpokePool.sol/Ink_SpokePool.json +2316 -0
  5. package/contracts/Ink_SpokePool.sol +72 -0
  6. package/dist/deploy/consts.js +8 -2
  7. package/dist/deployments/deployments.json +7 -1
  8. package/dist/hardhat.config.js +17 -0
  9. package/dist/scripts/svm/addressToPublicKey.d.ts +1 -0
  10. package/dist/scripts/svm/addressToPublicKey.js +20 -0
  11. package/dist/scripts/svm/bridgeLiabilityToHubPool.d.ts +25 -0
  12. package/dist/scripts/svm/bridgeLiabilityToHubPool.js +221 -0
  13. package/dist/scripts/svm/closeRelayerPdas.js +8 -9
  14. package/dist/scripts/svm/enableRoute.js +7 -1
  15. package/dist/scripts/svm/executeRebalanceToHubPool.d.ts +29 -0
  16. package/dist/scripts/svm/executeRebalanceToHubPool.js +345 -0
  17. package/dist/scripts/svm/executeRebalanceToSpokePool.d.ts +1 -0
  18. package/dist/scripts/svm/executeRebalanceToSpokePool.js +240 -0
  19. package/dist/scripts/svm/fakeFillWithRandomDistribution.js +6 -7
  20. package/dist/scripts/svm/initialize.js +2 -2
  21. package/dist/scripts/svm/proposeRebalanceToHubPool.d.ts +27 -0
  22. package/dist/scripts/svm/proposeRebalanceToHubPool.js +117 -0
  23. package/dist/scripts/svm/proposeRebalanceToSpokePool.d.ts +1 -0
  24. package/dist/scripts/svm/proposeRebalanceToSpokePool.js +97 -0
  25. package/dist/scripts/svm/publicKeyToAddress.d.ts +1 -0
  26. package/dist/scripts/svm/publicKeyToAddress.js +20 -0
  27. package/dist/scripts/svm/queryDeposits.js +3 -2
  28. package/dist/scripts/svm/queryFills.js +12 -14
  29. package/dist/scripts/svm/queryRoute.js +7 -1
  30. package/dist/scripts/svm/queryState.js +1 -0
  31. package/dist/scripts/svm/remoteHubPoolPauseDeposits.d.ts +1 -0
  32. package/dist/scripts/svm/remoteHubPoolPauseDeposits.js +191 -0
  33. package/dist/scripts/svm/remoteHubPoolSetDepositRoute.js +16 -29
  34. package/dist/scripts/svm/remotePauseDeposits.js +21 -27
  35. package/dist/scripts/svm/simpleDeposit.js +7 -1
  36. package/dist/scripts/svm/simpleFakeRelayerRepayment.js +3 -3
  37. package/dist/scripts/svm/simpleFill.js +6 -6
  38. package/dist/scripts/svm/utils/constants.d.ts +4 -0
  39. package/dist/scripts/svm/utils/constants.js +8 -1
  40. package/dist/scripts/svm/utils/helpers.d.ts +33 -0
  41. package/dist/scripts/svm/utils/helpers.js +60 -1
  42. package/dist/scripts/svm/utils/poolRebalanceTree.d.ts +22 -0
  43. package/dist/scripts/svm/utils/poolRebalanceTree.js +20 -0
  44. package/dist/src/svm/coders.d.ts +37 -0
  45. package/dist/src/svm/coders.js +250 -0
  46. package/dist/src/svm/conversionUtils.d.ts +22 -0
  47. package/dist/src/svm/conversionUtils.js +73 -0
  48. package/dist/src/svm/index.d.ts +6 -0
  49. package/dist/src/svm/index.js +22 -0
  50. package/dist/src/svm/instructionParamsUtils.d.ts +31 -0
  51. package/dist/src/svm/instructionParamsUtils.js +128 -0
  52. package/dist/src/svm/relayHashUtils.d.ts +30 -0
  53. package/dist/src/svm/relayHashUtils.js +209 -0
  54. package/dist/src/svm/solanaProgramUtils.d.ts +38 -0
  55. package/dist/src/svm/solanaProgramUtils.js +147 -0
  56. package/dist/src/svm/transactionUtils.d.ts +8 -0
  57. package/dist/src/svm/transactionUtils.js +55 -0
  58. package/dist/src/types/svm.d.ts +118 -0
  59. package/dist/src/types/svm.js +2 -0
  60. package/dist/target/types/svm_spoke.d.ts +47 -42
  61. package/dist/tasks/enableL1TokenAcrossEcosystem.js +3 -33
  62. package/dist/tasks/types.d.ts +2 -0
  63. package/dist/tasks/types.js +2 -0
  64. package/dist/tasks/utils.d.ts +12 -0
  65. package/dist/tasks/utils.js +34 -0
  66. package/dist/test/svm/MulticallHandler.js +2 -2
  67. package/dist/test/svm/SvmSpoke.Bundle.js +59 -60
  68. package/dist/test/svm/SvmSpoke.Deposit.js +23 -31
  69. package/dist/test/svm/SvmSpoke.Fill.AcrossPlus.js +16 -18
  70. package/dist/test/svm/SvmSpoke.Fill.js +38 -40
  71. package/dist/test/svm/SvmSpoke.HandleReceiveMessage.js +2 -2
  72. package/dist/test/svm/SvmSpoke.Ownership.js +11 -17
  73. package/dist/test/svm/SvmSpoke.RefundClaims.js +12 -11
  74. package/dist/test/svm/SvmSpoke.Routes.js +11 -7
  75. package/dist/test/svm/SvmSpoke.SlowFill.AcrossPlus.js +72 -16
  76. package/dist/test/svm/SvmSpoke.SlowFill.js +33 -28
  77. package/dist/test/svm/SvmSpoke.TokenBridge.js +15 -17
  78. package/dist/test/svm/SvmSpoke.common.d.ts +1 -49
  79. package/dist/test/svm/SvmSpoke.common.js +6 -5
  80. package/dist/test/svm/cctpHelpers.js +2 -2
  81. package/dist/test/svm/utils.d.ts +5 -67
  82. package/dist/test/svm/utils.js +10 -220
  83. package/dist/typechain/contracts/Ink_SpokePool.d.ts +1251 -0
  84. package/dist/typechain/contracts/Ink_SpokePool.js +2 -0
  85. package/dist/typechain/contracts/index.d.ts +1 -0
  86. package/dist/typechain/factories/contracts/Ink_SpokePool__factory.d.ts +1833 -0
  87. package/dist/typechain/factories/contracts/Ink_SpokePool__factory.js +2347 -0
  88. package/dist/typechain/factories/contracts/index.d.ts +1 -0
  89. package/dist/typechain/factories/contracts/index.js +3 -1
  90. package/dist/typechain/hardhat.d.ts +9 -0
  91. package/dist/typechain/index.d.ts +2 -0
  92. package/dist/typechain/index.js +5 -3
  93. package/package.json +2 -2
  94. package/dist/src/SvmUtils.d.ts +0 -50
  95. package/dist/src/SvmUtils.js +0 -415
@@ -27,10 +27,8 @@ const anchor = __importStar(require("@coral-xyz/anchor"));
27
27
  const anchor_1 = require("@coral-xyz/anchor");
28
28
  const spl_token_1 = require("@solana/spl-token");
29
29
  const web3_js_1 = require("@solana/web3.js");
30
- const utils_1 = require("./utils");
31
- const SvmUtils_1 = require("../../src/SvmUtils");
30
+ const svm_1 = require("../../src/svm");
32
31
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
33
- const utils_2 = require("./utils");
34
32
  const { provider, connection, program, owner, chainId, seedBalance } = SvmSpoke_common_1.common;
35
33
  const { initializeState, assertSE } = SvmSpoke_common_1.common;
36
34
  describe("svm_spoke.fill.across_plus", () => {
@@ -45,7 +43,7 @@ describe("svm_spoke.fill.across_plus", () => {
45
43
  let accounts; // Store accounts to simplify contract interactions.
46
44
  function updateRelayData(newRelayData) {
47
45
  relayData = newRelayData;
48
- const relayHashUint8Array = (0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId);
46
+ const relayHashUint8Array = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
49
47
  const [fillStatusPDA] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fills"), relayHashUint8Array], program.programId);
50
48
  accounts = {
51
49
  state,
@@ -67,11 +65,11 @@ describe("svm_spoke.fill.across_plus", () => {
67
65
  { pubkey: handlerProgram.programId, isSigner: false, isWritable: false },
68
66
  ...multicallHandlerCoder.compiledKeyMetas,
69
67
  ];
70
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
68
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
71
69
  // Prepare fill instruction.
72
70
  const fillV3RelayValues = [relayHash, relayData, new anchor_1.BN(1), relayer.publicKey];
73
71
  if (bufferParams) {
74
- await (0, utils_2.loadFillV3RelayParams)(program, relayer, fillV3RelayValues[1], fillV3RelayValues[2], fillV3RelayValues[3]);
72
+ await (0, svm_1.loadFillV3RelayParams)(program, relayer, fillV3RelayValues[1], fillV3RelayValues[2], fillV3RelayValues[3]);
75
73
  [accounts.instructionParams] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("instruction_params"), relayer.publicKey.toBuffer()], program.programId);
76
74
  }
77
75
  const fillV3RelayParams = bufferParams
@@ -105,7 +103,7 @@ describe("svm_spoke.fill.across_plus", () => {
105
103
  inputAmount: new anchor_1.BN(relayAmount),
106
104
  outputAmount: new anchor_1.BN(relayAmount),
107
105
  originChainId: new anchor_1.BN(1),
108
- depositId: (0, utils_1.intToU8Array32)(Math.floor(Math.random() * 1000000)), // force that we always have a new deposit id.
106
+ depositId: (0, svm_1.intToU8Array32)(Math.floor(Math.random() * 1000000)), // force that we always have a new deposit id.
109
107
  fillDeadline: new anchor_1.BN(Math.floor(Date.now() / 1000) + 60), // 1 minute from now
110
108
  exclusivityDeadline: new anchor_1.BN(Math.floor(Date.now() / 1000) + 30), // 30 seconds from now
111
109
  message: Buffer.from(""), // Will be populated in the tests below.
@@ -116,9 +114,9 @@ describe("svm_spoke.fill.across_plus", () => {
116
114
  const iRelayerBal = (await (0, spl_token_1.getAccount)(connection, relayerATA)).amount;
117
115
  // Construct ix to transfer all tokens from handler to the final recipient.
118
116
  const transferIx = (0, spl_token_1.createTransferCheckedInstruction)(handlerATA, mint, finalRecipientATA, handlerSigner, relayData.outputAmount, mintDecimals);
119
- const multicallHandlerCoder = new SvmUtils_1.MulticallHandlerCoder([transferIx]);
117
+ const multicallHandlerCoder = new svm_1.MulticallHandlerCoder([transferIx]);
120
118
  const handlerMessage = multicallHandlerCoder.encode();
121
- const message = new SvmUtils_1.AcrossPlusMessageCoder({
119
+ const message = new svm_1.AcrossPlusMessageCoder({
122
120
  handler: handlerProgram.programId,
123
121
  readOnlyLen: multicallHandlerCoder.readOnlyLen,
124
122
  valueAmount: new anchor_1.BN(0),
@@ -153,9 +151,9 @@ describe("svm_spoke.fill.across_plus", () => {
153
151
  const transferInstruction = (0, spl_token_1.createTransferCheckedInstruction)(handlerATA, mint, recipientATA, handlerSigner, distributionAmount, mintDecimals);
154
152
  transferInstructions.push(transferInstruction);
155
153
  }
156
- const multicallHandlerCoder = new SvmUtils_1.MulticallHandlerCoder(transferInstructions);
154
+ const multicallHandlerCoder = new svm_1.MulticallHandlerCoder(transferInstructions);
157
155
  const handlerMessage = multicallHandlerCoder.encode();
158
- const message = new SvmUtils_1.AcrossPlusMessageCoder({
156
+ const message = new svm_1.AcrossPlusMessageCoder({
159
157
  handler: handlerProgram.programId,
160
158
  readOnlyLen: multicallHandlerCoder.readOnlyLen,
161
159
  valueAmount: new anchor_1.BN(0),
@@ -174,9 +172,9 @@ describe("svm_spoke.fill.across_plus", () => {
174
172
  const { approveIx, fillIx } = await createApproveAndFillIx(multicallHandlerCoder, bufferParams);
175
173
  // Fill using the ALT.
176
174
  const computeBudgetIx = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 });
177
- await (0, SvmUtils_1.sendTransactionWithLookupTable)(connection, [computeBudgetIx, approveIx, fillIx], relayer);
175
+ await (0, svm_1.sendTransactionWithLookupTable)(connection, [computeBudgetIx, approveIx, fillIx], relayer);
178
176
  // Verify relayer's balance after the fill
179
- await new Promise((resolve) => setTimeout(resolve, 1000)); // Make sure token transfers get processed.
177
+ await new Promise((resolve) => setTimeout(resolve, 500)); // Make sure token transfers get processed.
180
178
  const fRelayerBal = (await (0, spl_token_1.getAccount)(connection, relayerATA)).amount;
181
179
  assertSE(fRelayerBal, iRelayerBal - BigInt(distributionAmount * numberOfDistributions), "Relayer's balance should be reduced by the relay amount");
182
180
  // Verify all recipient account balances after the fill.
@@ -200,9 +198,9 @@ describe("svm_spoke.fill.across_plus", () => {
200
198
  it("Sends lamports from the relayer to value recipient", async () => {
201
199
  const valueAmount = new anchor_1.BN(1_000_000_000);
202
200
  const valueRecipient = web3_js_1.Keypair.generate().publicKey;
203
- const multicallHandlerCoder = new SvmUtils_1.MulticallHandlerCoder([], valueRecipient);
201
+ const multicallHandlerCoder = new svm_1.MulticallHandlerCoder([], valueRecipient);
204
202
  const handlerMessage = multicallHandlerCoder.encode();
205
- const message = new SvmUtils_1.AcrossPlusMessageCoder({
203
+ const message = new svm_1.AcrossPlusMessageCoder({
206
204
  handler: handlerProgram.programId,
207
205
  readOnlyLen: multicallHandlerCoder.readOnlyLen,
208
206
  valueAmount,
@@ -232,9 +230,9 @@ describe("svm_spoke.fill.across_plus", () => {
232
230
  // Construct ix to transfer all tokens from handler to the recipient ATA.
233
231
  const transferInstruction = (0, spl_token_1.createTransferCheckedInstruction)(handlerATA, mint, anotherRecipientATA, handlerSigner, relayData.outputAmount, mintDecimals);
234
232
  // Encode both instructions with handler PDA as the payer for ATA initialization.
235
- const multicallHandlerCoder = new SvmUtils_1.MulticallHandlerCoder([createTokenAccountInstruction, transferInstruction], handlerSigner);
233
+ const multicallHandlerCoder = new svm_1.MulticallHandlerCoder([createTokenAccountInstruction, transferInstruction], handlerSigner);
236
234
  const handlerMessage = multicallHandlerCoder.encode();
237
- const message = new SvmUtils_1.AcrossPlusMessageCoder({
235
+ const message = new svm_1.AcrossPlusMessageCoder({
238
236
  handler: handlerProgram.programId,
239
237
  readOnlyLen: multicallHandlerCoder.readOnlyLen,
240
238
  valueAmount: new anchor_1.BN(valueAmount), // Must exactly cover ATA creation.
@@ -248,7 +246,7 @@ describe("svm_spoke.fill.across_plus", () => {
248
246
  // Prepare approval and fill instructions as we will need to use Address Lookup Table (ALT).
249
247
  const { approveIx, fillIx } = await createApproveAndFillIx(multicallHandlerCoder);
250
248
  // Fill using the ALT.
251
- await (0, SvmUtils_1.sendTransactionWithLookupTable)(connection, [approveIx, fillIx], relayer);
249
+ await (0, svm_1.sendTransactionWithLookupTable)(connection, [approveIx, fillIx], relayer);
252
250
  // Verify recipient's balance after the fill
253
251
  await new Promise((resolve) => setTimeout(resolve, 500)); // Make sure token transfer gets processed.
254
252
  const anotherRecipientAccount = await (0, spl_token_1.getAccount)(connection, anotherRecipientATA);
@@ -27,10 +27,9 @@ const anchor = __importStar(require("@coral-xyz/anchor"));
27
27
  const anchor_1 = require("@coral-xyz/anchor");
28
28
  const spl_token_1 = require("@solana/spl-token");
29
29
  const web3_js_1 = require("@solana/web3.js");
30
- const SvmUtils_1 = require("../../src/SvmUtils");
31
- const utils_1 = require("./utils");
30
+ const svm_1 = require("../../src/svm");
32
31
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
33
- const utils_2 = require("./utils");
32
+ const utils_1 = require("./utils");
34
33
  const { provider, connection, program, owner, chainId, seedBalance } = SvmSpoke_common_1.common;
35
34
  const { recipient, initializeState, setCurrentTime, assertSE, assert } = SvmSpoke_common_1.common;
36
35
  describe("svm_spoke.fill", () => {
@@ -38,7 +37,7 @@ describe("svm_spoke.fill", () => {
38
37
  const payer = anchor.AnchorProvider.env().wallet.payer;
39
38
  const relayer = web3_js_1.Keypair.generate();
40
39
  const otherRelayer = web3_js_1.Keypair.generate();
41
- const { encodedMessage, fillRemainingAccounts } = (0, utils_2.testAcrossPlusMessage)();
40
+ const { encodedMessage, fillRemainingAccounts } = (0, utils_1.testAcrossPlusMessage)();
42
41
  const tokenDecimals = 6;
43
42
  let state, mint, relayerTA, recipientTA, otherRelayerTA, tokenProgram;
44
43
  const relayAmount = 500000;
@@ -46,7 +45,7 @@ describe("svm_spoke.fill", () => {
46
45
  let accounts; // Store accounts to simplify contract interactions.
47
46
  function updateRelayData(newRelayData) {
48
47
  relayData = newRelayData;
49
- const relayHashUint8Array = (0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId);
48
+ const relayHashUint8Array = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
50
49
  const [fillStatusPDA] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fills"), relayHashUint8Array], program.programId);
51
50
  accounts = {
52
51
  state,
@@ -71,7 +70,8 @@ describe("svm_spoke.fill", () => {
71
70
  .remainingAccounts(fillRemainingAccounts)
72
71
  .instruction();
73
72
  const fillTx = new web3_js_1.Transaction().add(approveIx, fillIx);
74
- await (0, web3_js_1.sendAndConfirmTransaction)(connection, fillTx, [payer, callingRelayer]);
73
+ const tx = await (0, web3_js_1.sendAndConfirmTransaction)(connection, fillTx, [payer, callingRelayer]);
74
+ return tx;
75
75
  };
76
76
  before("Funds relayer wallets", async () => {
77
77
  await connection.requestAirdrop(relayer.publicKey, 10_000_000_000); // 10 SOL
@@ -99,7 +99,7 @@ describe("svm_spoke.fill", () => {
99
99
  inputAmount: new anchor_1.BN(relayAmount),
100
100
  outputAmount: new anchor_1.BN(relayAmount),
101
101
  originChainId: new anchor_1.BN(1),
102
- depositId: (0, utils_1.intToU8Array32)(Math.floor(Math.random() * 1000000)), // force that we always have a new deposit id.
102
+ depositId: (0, svm_1.intToU8Array32)(Math.floor(Math.random() * 1000000)), // force that we always have a new deposit id.
103
103
  fillDeadline: Math.floor(Date.now() / 1000) + 60, // 1 minute from now
104
104
  exclusivityDeadline: Math.floor(Date.now() / 1000) + 30, // 30 seconds from now
105
105
  message: encodedMessage,
@@ -113,7 +113,7 @@ describe("svm_spoke.fill", () => {
113
113
  // Verify relayer's balance before the fill
114
114
  let relayerAccount = await (0, spl_token_1.getAccount)(connection, relayerTA);
115
115
  assertSE(relayerAccount.amount, seedBalance, "Relayer's balance should be equal to seed balance before the fill");
116
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
116
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
117
117
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
118
118
  // Verify relayer's balance after the fill
119
119
  relayerAccount = await (0, spl_token_1.getAccount)(connection, relayerTA);
@@ -123,24 +123,23 @@ describe("svm_spoke.fill", () => {
123
123
  assertSE(recipientAccount.amount, relayAmount, "Recipient's balance should be increased by the relay amount");
124
124
  });
125
125
  it("Verifies FilledV3Relay event after filling a relay", async () => {
126
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
127
- await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(420), otherRelayer.publicKey]);
126
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
127
+ const tx = await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(420), otherRelayer.publicKey]);
128
128
  // Fetch and verify the FilledV3Relay event
129
- await new Promise((resolve) => setTimeout(resolve, 500));
130
- const events = await (0, SvmUtils_1.readProgramEvents)(connection, program);
131
- const event = events.find((event) => event.name === "filledV3Relay").data;
129
+ const events = await (0, svm_1.readEventsUntilFound)(connection, tx, [program]);
130
+ const event = events.find((event) => event.name === "filledV3Relay")?.data;
132
131
  assert.isNotNull(event, "FilledV3Relay event should be emitted");
133
132
  // Verify that the event data matches the relay data.
134
133
  Object.entries(relayData).forEach(([key, value]) => {
135
134
  if (key === "message") {
136
- assertSE(event.messageHash, (0, utils_2.hashNonEmptyMessage)(value), `MessageHash should match`);
135
+ assertSE(event.messageHash, (0, svm_1.hashNonEmptyMessage)(value), `MessageHash should match`);
137
136
  }
138
137
  else
139
138
  assertSE(event[key], value, `${key.charAt(0).toUpperCase() + key.slice(1)} should match`);
140
139
  });
141
140
  // RelayExecutionInfo should match.
142
141
  assertSE(event.relayExecutionInfo.updatedRecipient, relayData.recipient, "UpdatedRecipient should match");
143
- assertSE(event.relayExecutionInfo.updatedMessageHash, (0, utils_2.hashNonEmptyMessage)(relayData.message), "UpdatedMessageHash should match");
142
+ assertSE(event.relayExecutionInfo.updatedMessageHash, (0, svm_1.hashNonEmptyMessage)(relayData.message), "UpdatedMessageHash should match");
144
143
  assertSE(event.relayExecutionInfo.updatedOutputAmount, relayData.outputAmount, "UpdatedOutputAmount should match");
145
144
  assert.equal(JSON.stringify(event.relayExecutionInfo.fillType), `{"fastFill":{}}`, "FillType should be FastFill");
146
145
  // These props below are not part of relayData.
@@ -149,7 +148,7 @@ describe("svm_spoke.fill", () => {
149
148
  });
150
149
  it("Fails to fill a V3 relay after the fill deadline", async () => {
151
150
  updateRelayData({ ...relayData, fillDeadline: Math.floor(Date.now() / 1000) - 69 }); // 69 seconds ago
152
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
151
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
153
152
  try {
154
153
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
155
154
  assert.fail("Fill should have failed due to fill deadline passed");
@@ -161,7 +160,7 @@ describe("svm_spoke.fill", () => {
161
160
  it("Fails to fill a V3 relay by non-exclusive relayer before exclusivity deadline", async () => {
162
161
  accounts.signer = otherRelayer.publicKey;
163
162
  accounts.relayerTokenAccount = otherRelayerTA;
164
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
163
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
165
164
  try {
166
165
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey], undefined, otherRelayer);
167
166
  assert.fail("Fill should have failed due to non-exclusive relayer before exclusivity deadline");
@@ -176,7 +175,7 @@ describe("svm_spoke.fill", () => {
176
175
  accounts.relayerTokenAccount = otherRelayerTA;
177
176
  const recipientAccountBefore = await (0, spl_token_1.getAccount)(connection, recipientTA);
178
177
  const relayerAccountBefore = await (0, spl_token_1.getAccount)(connection, otherRelayerTA);
179
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
178
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
180
179
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey], undefined, otherRelayer);
181
180
  // Verify relayer's balance after the fill
182
181
  const relayerAccountAfter = await (0, spl_token_1.getAccount)(connection, otherRelayerTA);
@@ -186,7 +185,7 @@ describe("svm_spoke.fill", () => {
186
185
  assertSE(recipientAccountAfter.amount, BigInt(recipientAccountBefore.amount) + BigInt(relayAmount), "Recipient's balance should be increased by the relay amount");
187
186
  });
188
187
  it("Fails to fill a V3 relay with the same deposit data multiple times", async () => {
189
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
188
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
190
189
  // First fill attempt
191
190
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
192
191
  // Second fill attempt with the same data
@@ -199,7 +198,7 @@ describe("svm_spoke.fill", () => {
199
198
  }
200
199
  });
201
200
  it("Closes the fill PDA after the fill", async () => {
202
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
201
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
203
202
  const closeFillPdaAccounts = {
204
203
  state,
205
204
  signer: relayer.publicKey,
@@ -213,7 +212,7 @@ describe("svm_spoke.fill", () => {
213
212
  assert.isNotNull(fillStatusAccountBefore, "Fill PDA should exist before closing");
214
213
  // Attempt to close the fill PDA before the fill deadline should fail.
215
214
  try {
216
- await program.methods.closeFillPda(relayHash, relayData).accounts(closeFillPdaAccounts).signers([relayer]).rpc();
215
+ await program.methods.closeFillPda().accounts(closeFillPdaAccounts).signers([relayer]).rpc();
217
216
  assert.fail("Closing fill PDA should have failed before fill deadline");
218
217
  }
219
218
  catch (err) {
@@ -222,13 +221,13 @@ describe("svm_spoke.fill", () => {
222
221
  // Set the current time to past the fill deadline
223
222
  await setCurrentTime(program, state, relayer, new anchor_1.BN(relayData.fillDeadline + 1));
224
223
  // Close the fill PDA
225
- await program.methods.closeFillPda(relayHash, relayData).accounts(closeFillPdaAccounts).signers([relayer]).rpc();
224
+ await program.methods.closeFillPda().accounts(closeFillPdaAccounts).signers([relayer]).rpc();
226
225
  // Verify the fill PDA is closed
227
226
  const fillStatusAccountAfter = await connection.getAccountInfo(accounts.fillStatus);
228
227
  assert.isNull(fillStatusAccountAfter, "Fill PDA should be closed after closing");
229
228
  });
230
229
  it("Fetches FillStatusAccount before and after fillV3Relay", async () => {
231
- const relayHash = (0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId);
230
+ const relayHash = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
232
231
  const [fillStatusPDA] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("fills"), relayHash], program.programId);
233
232
  // Fetch FillStatusAccount before fillV3Relay
234
233
  let fillStatusAccount = await program.account.fillStatusAccount.fetchNullable(fillStatusPDA);
@@ -248,7 +247,7 @@ describe("svm_spoke.fill", () => {
248
247
  const stateAccountData = await program.account.state.fetch(state);
249
248
  assert.isTrue(stateAccountData.pausedFills, "Fills should be paused");
250
249
  // Try to fill the relay. This should fail because fills are paused.
251
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
250
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
252
251
  try {
253
252
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
254
253
  assert.fail("Should not be able to fill relay when fills are paused");
@@ -258,7 +257,7 @@ describe("svm_spoke.fill", () => {
258
257
  }
259
258
  });
260
259
  it("Fails to fill a relay to wrong recipient token account", async () => {
261
- const relayHash = (0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId);
260
+ const relayHash = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
262
261
  // Create new accounts as derived from wrong recipient.
263
262
  const wrongRecipient = web3_js_1.Keypair.generate().publicKey;
264
263
  const wrongRecipientTA = (await (0, spl_token_1.getOrCreateAssociatedTokenAccount)(connection, payer, mint, wrongRecipient)).address;
@@ -276,7 +275,7 @@ describe("svm_spoke.fill", () => {
276
275
  }
277
276
  });
278
277
  it("Fails to fill a relay for mint inconsistent output_token", async () => {
279
- const relayHash = (0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId);
278
+ const relayHash = (0, svm_1.calculateRelayHashUint8Array)(relayData, chainId);
280
279
  // Create and fund new accounts as derived from wrong mint account.
281
280
  const wrongMint = await (0, spl_token_1.createMint)(connection, payer, owner, owner, tokenDecimals);
282
281
  const wrongRecipientTA = (await (0, spl_token_1.getOrCreateAssociatedTokenAccount)(connection, payer, wrongMint, recipient)).address;
@@ -302,7 +301,7 @@ describe("svm_spoke.fill", () => {
302
301
  accounts.recipientTokenAccount = relayerTA;
303
302
  // Store relayer's balance before the fill
304
303
  const iRelayerBalance = (await (0, spl_token_1.getAccount)(connection, relayerTA)).amount;
305
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
304
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
306
305
  // No need for approval in self-relay.
307
306
  const txSignature = await program.methods
308
307
  .fillV3Relay(relayHash, relayData, new anchor_1.BN(1), relayer.publicKey)
@@ -334,7 +333,7 @@ describe("svm_spoke.fill", () => {
334
333
  const iRecipientBal = (await (0, spl_token_1.getAccount)(connection, recipientTA)).amount;
335
334
  // Fill relay from custom relayer token account
336
335
  accounts.relayerTokenAccount = customRelayerTA;
337
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
336
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
338
337
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
339
338
  // Verify balances after the fill
340
339
  const fRelayerBal = (await (0, spl_token_1.getAccount)(connection, customRelayerTA)).amount;
@@ -350,11 +349,11 @@ describe("svm_spoke.fill", () => {
350
349
  const newRelayData = {
351
350
  ...relayData,
352
351
  recipient: newRecipient,
353
- depositId: (0, utils_1.intToU8Array32)(Math.floor(Math.random() * 1000000)),
352
+ depositId: (0, svm_1.intToU8Array32)(Math.floor(Math.random() * 1000000)),
354
353
  };
355
354
  updateRelayData(newRelayData);
356
355
  accounts.recipientTokenAccount = newRecipientATA;
357
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(newRelayData, chainId));
356
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(newRelayData, chainId));
358
357
  try {
359
358
  await approvedFillV3Relay([relayHash, newRelayData, new anchor_1.BN(1), relayer.publicKey]);
360
359
  assert.fail("Fill should have failed due to missing ATA");
@@ -409,12 +408,12 @@ describe("svm_spoke.fill", () => {
409
408
  const newRelayData = {
410
409
  ...relayData,
411
410
  recipient: recipientAuthorities[i],
412
- depositId: (0, utils_1.intToU8Array32)(Math.floor(Math.random() * 1000000)),
411
+ depositId: (0, svm_1.intToU8Array32)(Math.floor(Math.random() * 1000000)),
413
412
  };
414
413
  totalFillAmount = totalFillAmount.add(newRelayData.outputAmount);
415
414
  updateRelayData(newRelayData);
416
415
  accounts.recipientTokenAccount = recipientAssociatedTokens[i];
417
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(newRelayData, chainId));
416
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(newRelayData, chainId));
418
417
  const fillInstruction = await program.methods
419
418
  .fillV3Relay(relayHash, newRelayData, new anchor_1.BN(1), relayer.publicKey)
420
419
  .accounts(accounts)
@@ -424,9 +423,9 @@ describe("svm_spoke.fill", () => {
424
423
  }
425
424
  const approveInstruction = await (0, spl_token_1.createApproveCheckedInstruction)(accounts.relayerTokenAccount, accounts.mint, accounts.state, accounts.signer, BigInt(totalFillAmount.toString()), tokenDecimals, undefined, tokenProgram);
426
425
  // Fill using the ALT.
427
- await (0, SvmUtils_1.sendTransactionWithLookupTable)(connection, [createTokenAccountsInstruction, approveInstruction, ...fillInstructions], relayer);
426
+ await (0, svm_1.sendTransactionWithLookupTable)(connection, [createTokenAccountsInstruction, approveInstruction, ...fillInstructions], relayer);
428
427
  // Verify balances after the fill
429
- await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for tx processing
428
+ await new Promise((resolve) => setTimeout(resolve, 500)); // Wait for tx processing
430
429
  const fRelayerBal = (await (0, spl_token_1.getAccount)(connection, relayerTA)).amount;
431
430
  assertSE(fRelayerBal, iRelayerBal - BigInt(relayAmount * numberOfFills), "Relayer's balance should be reduced by total relay amount");
432
431
  recipientAssociatedTokens.forEach(async (recipientAssociatedToken) => {
@@ -454,7 +453,7 @@ describe("svm_spoke.fill", () => {
454
453
  // Verify relayer's balance before the fill
455
454
  let relayerAccount = await (0, spl_token_1.getAccount)(connection, relayerTA, undefined, tokenProgram);
456
455
  assertSE(relayerAccount.amount, seedBalance, "Relayer's balance should be equal to seed balance before the fill");
457
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
456
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
458
457
  await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(1), relayer.publicKey]);
459
458
  // Verify relayer's balance after the fill
460
459
  relayerAccount = await (0, spl_token_1.getAccount)(connection, relayerTA, undefined, tokenProgram);
@@ -465,12 +464,11 @@ describe("svm_spoke.fill", () => {
465
464
  });
466
465
  it("Emits zeroed hash for empty message", async () => {
467
466
  updateRelayData({ ...relayData, message: Buffer.alloc(0) });
468
- const relayHash = Array.from((0, SvmUtils_1.calculateRelayHashUint8Array)(relayData, chainId));
469
- await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(420), otherRelayer.publicKey]);
467
+ const relayHash = Array.from((0, svm_1.calculateRelayHashUint8Array)(relayData, chainId));
468
+ const tx = await approvedFillV3Relay([relayHash, relayData, new anchor_1.BN(420), otherRelayer.publicKey]);
470
469
  // Fetch and verify the FilledV3Relay event
471
- await new Promise((resolve) => setTimeout(resolve, 500));
472
- const events = await (0, SvmUtils_1.readProgramEvents)(connection, program);
473
- const event = events.find((event) => event.name === "filledV3Relay").data;
470
+ const events = await (0, svm_1.readEventsUntilFound)(connection, tx, [program]);
471
+ const event = events.find((event) => event.name === "filledV3Relay")?.data;
474
472
  assert.isNotNull(event, "FilledV3Relay event should be emitted");
475
473
  // Verify that the event data has zeroed message hash.
476
474
  assertSE(event.messageHash, new Uint8Array(32), `MessageHash should be zeroed`);
@@ -30,7 +30,7 @@ const spl_token_1 = require("@solana/spl-token");
30
30
  const web3_js_1 = require("@solana/web3.js");
31
31
  const chai_1 = require("chai");
32
32
  const ethers_1 = require("ethers");
33
- const SvmUtils_1 = require("../../src/SvmUtils");
33
+ const svm_1 = require("../../src/svm");
34
34
  const cctpHelpers_1 = require("./cctpHelpers");
35
35
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
36
36
  const { createRoutePda, getVaultAta, initializeState, crossDomainAdmin, remoteDomain, localDomain } = SvmSpoke_common_1.common;
@@ -262,7 +262,7 @@ describe("svm_spoke.handle_receive_message", () => {
262
262
  });
263
263
  it("Sets cross-domain admin remotely", async () => {
264
264
  const newCrossDomainAdminAddress = ethers_1.ethers.Wallet.createRandom().address;
265
- const newCrossDomainAdminPubkey = (0, SvmUtils_1.evmAddressToPublicKey)(newCrossDomainAdminAddress);
265
+ const newCrossDomainAdminPubkey = (0, svm_1.evmAddressToPublicKey)(newCrossDomainAdminAddress);
266
266
  let calldata = ethereumIface.encodeFunctionData("setCrossDomainAdmin", [newCrossDomainAdminAddress]);
267
267
  let messageBody = Buffer.from(calldata.slice(2), "hex");
268
268
  let message = (0, cctpHelpers_1.encodeMessageHeader)({
@@ -28,7 +28,7 @@ const anchor_1 = require("@coral-xyz/anchor");
28
28
  const web3_js_1 = require("@solana/web3.js");
29
29
  const chai_1 = require("chai");
30
30
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
31
- const utils_1 = require("./utils");
31
+ const svm_1 = require("../../src/svm");
32
32
  const { provider, program, owner, initializeState, crossDomainAdmin, assertSE } = SvmSpoke_common_1.common;
33
33
  describe("svm_spoke.ownership", () => {
34
34
  anchor.setProvider(provider);
@@ -62,23 +62,21 @@ describe("svm_spoke.ownership", () => {
62
62
  chai_1.assert.isFalse((await program.account.state.fetch(state)).pausedDeposits, "Deposits should not be paused");
63
63
  // Pause deposits as owner
64
64
  const pauseDepositsAccounts = { state, signer: owner, program: program.programId };
65
- await program.methods.pauseDeposits(true).accounts(pauseDepositsAccounts).rpc();
66
- await new Promise((resolve) => setTimeout(resolve, 500));
65
+ const tx = await program.methods.pauseDeposits(true).accounts(pauseDepositsAccounts).rpc();
67
66
  // Fetch the updated state
68
67
  let stateAccountData = await program.account.state.fetch(state);
69
68
  chai_1.assert.isTrue(stateAccountData.pausedDeposits, "Deposits should be paused");
70
69
  // Verify the PausedDeposits event
71
- let events = await (0, utils_1.readProgramEvents)(provider.connection, program);
70
+ let events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx, [program]);
72
71
  let pausedDepositEvents = events.filter((event) => event.name === "pausedDeposits");
73
72
  chai_1.assert.isTrue(pausedDepositEvents[0].data.isPaused, "PausedDeposits event should indicate deposits are paused");
74
73
  // Unpause deposits as owner
75
- await program.methods.pauseDeposits(false).accounts(pauseDepositsAccounts).rpc();
76
- await new Promise((resolve) => setTimeout(resolve, 500));
74
+ const tx2 = await program.methods.pauseDeposits(false).accounts(pauseDepositsAccounts).rpc();
77
75
  // Fetch the updated state
78
76
  stateAccountData = await program.account.state.fetch(state);
79
77
  chai_1.assert.isFalse(stateAccountData.pausedDeposits, "Deposits should not be paused");
80
78
  // Verify the PausedDeposits event
81
- events = await (0, utils_1.readProgramEvents)(provider.connection, program);
79
+ events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx2, [program]);
82
80
  pausedDepositEvents = events.filter((event) => event.name === "pausedDeposits");
83
81
  chai_1.assert.isFalse(pausedDepositEvents[0].data.isPaused, "PausedDeposits event should indicate deposits are unpaused");
84
82
  // Try to pause deposits as non-owner
@@ -95,23 +93,21 @@ describe("svm_spoke.ownership", () => {
95
93
  chai_1.assert.isFalse((await program.account.state.fetch(state)).pausedFills, "Fills should not be paused");
96
94
  // Pause fills as owner
97
95
  const pauseFillsAccounts = { state, signer: owner, program: program.programId };
98
- await program.methods.pauseFills(true).accounts(pauseFillsAccounts).rpc();
99
- await new Promise((resolve) => setTimeout(resolve, 500));
96
+ const tx = await program.methods.pauseFills(true).accounts(pauseFillsAccounts).rpc();
100
97
  // Fetch the updated state
101
98
  let stateAccountData = await program.account.state.fetch(state);
102
99
  chai_1.assert.isTrue(stateAccountData.pausedFills, "Fills should be paused");
103
100
  // Verify the PausedFills event
104
- let events = await (0, utils_1.readProgramEvents)(provider.connection, program);
101
+ let events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx, [program]);
105
102
  let pausedFillEvents = events.filter((event) => event.name === "pausedFills");
106
103
  chai_1.assert.isTrue(pausedFillEvents[0].data.isPaused, "PausedFills event should indicate fills are paused");
107
104
  // Unpause fills as owner
108
- await program.methods.pauseFills(false).accounts(pauseFillsAccounts).rpc();
109
- await new Promise((resolve) => setTimeout(resolve, 500));
105
+ const tx2 = await program.methods.pauseFills(false).accounts(pauseFillsAccounts).rpc();
110
106
  // Fetch the updated state
111
107
  stateAccountData = await program.account.state.fetch(state);
112
108
  chai_1.assert.isFalse(stateAccountData.pausedFills, "Fills should not be paused");
113
109
  // Verify the PausedFills event
114
- events = await (0, utils_1.readProgramEvents)(provider.connection, program);
110
+ events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx2, [program]);
115
111
  pausedFillEvents = events.filter((event) => event.name === "pausedFills");
116
112
  chai_1.assert.isFalse(pausedFillEvents[0].data.isPaused, "PausedFills event should indicate fills are unpaused");
117
113
  // Try to pause fills as non-owner
@@ -128,7 +124,6 @@ describe("svm_spoke.ownership", () => {
128
124
  // Transfer ownership to newOwner
129
125
  const transferOwnershipAccounts = { state, signer: owner };
130
126
  await program.methods.transferOwnership(newOwner.publicKey).accounts(transferOwnershipAccounts).rpc();
131
- await new Promise((resolve) => setTimeout(resolve, 500));
132
127
  // Verify the new owner
133
128
  let stateAccountData = await program.account.state.fetch(state);
134
129
  chai_1.assert.equal(stateAccountData.owner.toString(), newOwner.publicKey.toString(), "Ownership should be transferred");
@@ -149,16 +144,15 @@ describe("svm_spoke.ownership", () => {
149
144
  it("Sets cross-domain admin", async () => {
150
145
  // Set cross-domain admin as owner
151
146
  const setCrossDomainAdminAccounts = { state, signer: owner, program: program.programId };
152
- await program.methods
147
+ const tx = await program.methods
153
148
  .setCrossDomainAdmin(newCrossDomainAdmin.publicKey)
154
149
  .accounts(setCrossDomainAdminAccounts)
155
150
  .rpc();
156
- await new Promise((resolve) => setTimeout(resolve, 500));
157
151
  // Verify the new cross-domain admin
158
152
  let stateAccountData = await program.account.state.fetch(state);
159
153
  chai_1.assert.equal(stateAccountData.crossDomainAdmin.toString(), newCrossDomainAdmin.publicKey.toString(), "Cross-domain admin should be set");
160
154
  // Verify the SetXDomainAdmin event
161
- let events = await (0, utils_1.readProgramEvents)(provider.connection, program);
155
+ let events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx, [program]);
162
156
  let setXDomainAdminEvents = events.filter((event) => event.name === "setXDomainAdmin");
163
157
  chai_1.assert.equal(setXDomainAdminEvents[0].data.newAdmin.toString(), newCrossDomainAdmin.publicKey.toString(), "SetXDomainAdmin event should indicate the new admin");
164
158
  // Try to set cross-domain admin as non-owner
@@ -30,7 +30,7 @@ const chai_1 = require("chai");
30
30
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
31
31
  const MerkleTree_1 = require("@uma/common/dist/MerkleTree");
32
32
  const spl_token_1 = require("@solana/spl-token");
33
- const utils_1 = require("./utils");
33
+ const svm_1 = require("../../src/svm");
34
34
  const { provider, program, owner, initializeState, connection, chainId, assertSE } = SvmSpoke_common_1.common;
35
35
  describe("svm_spoke.refund_claims", () => {
36
36
  anchor.setProvider(provider);
@@ -69,7 +69,7 @@ describe("svm_spoke.refund_claims", () => {
69
69
  refundAddresses: [relayer.publicKey],
70
70
  refundAmounts: [relayerRefund],
71
71
  });
72
- const merkleTree = new MerkleTree_1.MerkleTree(relayerRefundLeaves, utils_1.relayerRefundHashFn);
72
+ const merkleTree = new MerkleTree_1.MerkleTree(relayerRefundLeaves, svm_1.relayerRefundHashFn);
73
73
  const root = merkleTree.getRoot();
74
74
  const proof = merkleTree.getProof(relayerRefundLeaves[0]);
75
75
  const leaf = relayerRefundLeaves[0];
@@ -99,7 +99,7 @@ describe("svm_spoke.refund_claims", () => {
99
99
  program: program.programId,
100
100
  };
101
101
  const proofAsNumbers = proof.map((p) => Array.from(p));
102
- await (0, utils_1.loadExecuteRelayerRefundLeafParams)(program, owner, stateAccountData.rootBundleId, leaf, proofAsNumbers);
102
+ await (0, svm_1.loadExecuteRelayerRefundLeafParams)(program, owner, stateAccountData.rootBundleId, leaf, proofAsNumbers);
103
103
  await program.methods
104
104
  .executeRelayerRefundLeafDeferred()
105
105
  .accounts(executeRelayerRefundLeafAccounts)
@@ -142,16 +142,18 @@ describe("svm_spoke.refund_claims", () => {
142
142
  const iVaultBal = (await connection.getTokenAccountBalance(vault)).value.amount;
143
143
  const iRelayerBal = (await connection.getTokenAccountBalance(tokenAccount)).value.amount;
144
144
  // Claim refund for the relayer.
145
- await program.methods.claimRelayerRefundFor(relayer.publicKey).accounts(claimRelayerRefundAccounts).rpc();
145
+ const tx = await program.methods
146
+ .claimRelayerRefundFor(relayer.publicKey)
147
+ .accounts(claimRelayerRefundAccounts)
148
+ .rpc();
146
149
  // The relayer should have received funds from the vault.
147
150
  const fVaultBal = (await connection.getTokenAccountBalance(vault)).value.amount;
148
151
  const fRelayerBal = (await connection.getTokenAccountBalance(tokenAccount)).value.amount;
149
152
  assertSE(BigInt(iVaultBal) - BigInt(fVaultBal), relayerRefund, "Vault balance");
150
153
  assertSE(BigInt(fRelayerBal) - BigInt(iRelayerBal), relayerRefund, "Relayer balance");
151
154
  // Verify the ClaimedRelayerRefund event
152
- await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for event processing
153
- const events = await (0, utils_1.readProgramEvents)(connection, program);
154
- const event = events.find((event) => event.name === "claimedRelayerRefund").data;
155
+ const events = await (0, svm_1.readEventsUntilFound)(connection, tx, [program]);
156
+ const event = events.find((event) => event.name === "claimedRelayerRefund")?.data;
155
157
  assertSE(event.l2TokenAddress, mint, "l2TokenAddress should match");
156
158
  assertSE(event.claimAmount, relayerRefund, "Relayer refund amount should match");
157
159
  assertSE(event.refundAddress, relayer.publicKey, "Relayer refund address should match");
@@ -300,16 +302,15 @@ describe("svm_spoke.refund_claims", () => {
300
302
  claimRelayerRefundAccounts.tokenAccount = customTokenAccount;
301
303
  claimRelayerRefundAccounts.signer = relayer.publicKey; // Only relayer itself should be able to do this.
302
304
  // Relayer can claim refund to custom token account.
303
- await program.methods.claimRelayerRefund().accounts(claimRelayerRefundAccounts).signers([relayer]).rpc();
305
+ const tx = await program.methods.claimRelayerRefund().accounts(claimRelayerRefundAccounts).signers([relayer]).rpc();
304
306
  // The relayer should have received funds from the vault.
305
307
  const fVaultBal = (await connection.getTokenAccountBalance(vault)).value.amount;
306
308
  const fRelayerBal = (await connection.getTokenAccountBalance(customTokenAccount)).value.amount;
307
309
  assertSE(BigInt(iVaultBal) - BigInt(fVaultBal), relayerRefund, "Vault balance");
308
310
  assertSE(BigInt(fRelayerBal) - BigInt(iRelayerBal), relayerRefund, "Relayer balance");
309
311
  // Verify the ClaimedRelayerRefund event
310
- await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for event processing
311
- const events = await (0, utils_1.readProgramEvents)(connection, program);
312
- const event = events.find((event) => event.name === "claimedRelayerRefund").data;
312
+ const events = await (0, svm_1.readEventsUntilFound)(connection, tx, [program]);
313
+ const event = events.find((event) => event.name === "claimedRelayerRefund")?.data;
313
314
  assertSE(event.l2TokenAddress, mint, "l2TokenAddress should match");
314
315
  assertSE(event.claimAmount, relayerRefund, "Relayer refund amount should match");
315
316
  assertSE(event.refundAddress, relayer.publicKey, "Relayer refund address should match");
@@ -29,7 +29,7 @@ const spl_token_1 = require("@solana/spl-token");
29
29
  const web3_js_1 = require("@solana/web3.js");
30
30
  const chai_1 = require("chai");
31
31
  const SvmSpoke_common_1 = require("./SvmSpoke.common");
32
- const utils_1 = require("./utils");
32
+ const svm_1 = require("../../src/svm");
33
33
  const { provider, program, owner, initializeState, createRoutePda, getVaultAta } = SvmSpoke_common_1.common;
34
34
  describe("svm_spoke.routes", () => {
35
35
  anchor.setProvider(provider);
@@ -60,25 +60,29 @@ describe("svm_spoke.routes", () => {
60
60
  });
61
61
  it("Sets, retrieves, and controls access to route enablement", async () => {
62
62
  // Enable the route as owner
63
- await program.methods.setEnableRoute(tokenMint, routeChainId, true).accounts(setEnableRouteAccounts).rpc();
64
- await new Promise((resolve) => setTimeout(resolve, 500));
63
+ const tx = await program.methods
64
+ .setEnableRoute(tokenMint, routeChainId, true)
65
+ .accounts(setEnableRouteAccounts)
66
+ .rpc();
65
67
  // Retrieve and verify the route is enabled
66
68
  let routeAccount = await program.account.route.fetch(routePda);
67
69
  chai_1.assert.isTrue(routeAccount.enabled, "Route should be enabled");
68
70
  // Verify the enabledDepositRoute event
69
- let events = (await (0, utils_1.readProgramEvents)(provider.connection, program)).filter((event) => event.name === "enabledDepositRoute");
71
+ let events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx, [program]);
70
72
  let event = events[0].data;
71
73
  chai_1.assert.strictEqual(event.originToken.toString(), tokenMint.toString(), "originToken event match");
72
74
  chai_1.assert.strictEqual(event.destinationChainId.toString(), routeChainId.toString(), "destinationChainId should match");
73
75
  chai_1.assert.isTrue(event.enabled, "enabledDepositRoute enabled");
74
76
  // Disable the route as owner
75
- await program.methods.setEnableRoute(tokenMint, routeChainId, false).accounts(setEnableRouteAccounts).rpc();
76
- await new Promise((resolve) => setTimeout(resolve, 500));
77
+ const tx2 = await program.methods
78
+ .setEnableRoute(tokenMint, routeChainId, false)
79
+ .accounts(setEnableRouteAccounts)
80
+ .rpc();
77
81
  // Retrieve and verify the route is disabled
78
82
  routeAccount = await program.account.route.fetch(routePda);
79
83
  chai_1.assert.isFalse(routeAccount.enabled, "Route should be disabled");
80
84
  // Verify the enabledDepositRoute event
81
- events = (await (0, utils_1.readProgramEvents)(provider.connection, program)).filter((event) => event.name === "enabledDepositRoute");
85
+ events = await (0, svm_1.readEventsUntilFound)(provider.connection, tx2, [program]);
82
86
  event = events[0].data; // take most recent event, index 0.
83
87
  chai_1.assert.strictEqual(event.originToken.toString(), tokenMint.toString(), "originToken event match");
84
88
  chai_1.assert.strictEqual(event.destinationChainId.toString(), routeChainId.toString(), "destinationChainId should match");