@layerzerolabs/lz-v2-stellar-sdk 0.2.21 → 0.2.23

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 (54) hide show
  1. package/.turbo/turbo-test.log +662 -466
  2. package/LICENSE +23 -0
  3. package/dist/generated/bml.d.ts +101 -106
  4. package/dist/generated/bml.js +108 -26
  5. package/dist/generated/counter.d.ts +123 -484
  6. package/dist/generated/counter.js +103 -25
  7. package/dist/generated/dvn.d.ts +141 -699
  8. package/dist/generated/dvn.js +106 -28
  9. package/dist/generated/dvn_fee_lib.d.ts +31 -248
  10. package/dist/generated/dvn_fee_lib.js +27 -24
  11. package/dist/generated/endpoint.d.ts +158 -836
  12. package/dist/generated/endpoint.js +107 -29
  13. package/dist/generated/executor.d.ts +139 -671
  14. package/dist/generated/executor.js +106 -28
  15. package/dist/generated/executor_fee_lib.d.ts +109 -264
  16. package/dist/generated/executor_fee_lib.js +106 -28
  17. package/dist/generated/executor_helper.d.ts +95 -92
  18. package/dist/generated/executor_helper.js +103 -25
  19. package/dist/generated/layerzero_view.d.ts +178 -335
  20. package/dist/generated/layerzero_view.js +172 -33
  21. package/dist/generated/oft.d.ts +137 -680
  22. package/dist/generated/oft.js +103 -25
  23. package/dist/generated/price_feed.d.ts +45 -444
  24. package/dist/generated/price_feed.js +27 -24
  25. package/dist/generated/sml.d.ts +119 -428
  26. package/dist/generated/sml.js +103 -25
  27. package/dist/generated/treasury.d.ts +109 -288
  28. package/dist/generated/treasury.js +103 -25
  29. package/dist/generated/uln302.d.ts +190 -527
  30. package/dist/generated/uln302.js +170 -31
  31. package/dist/generated/upgrader.d.ts +14 -34
  32. package/dist/generated/upgrader.js +24 -21
  33. package/package.json +8 -9
  34. package/src/generated/bml.ts +120 -141
  35. package/src/generated/counter.ts +141 -572
  36. package/src/generated/dvn.ts +161 -819
  37. package/src/generated/dvn_fee_lib.ts +48 -301
  38. package/src/generated/endpoint.ts +171 -977
  39. package/src/generated/executor.ts +159 -787
  40. package/src/generated/executor_fee_lib.ts +130 -323
  41. package/src/generated/executor_helper.ts +113 -124
  42. package/src/generated/layerzero_view.ts +201 -408
  43. package/src/generated/oft.ts +155 -796
  44. package/src/generated/price_feed.ts +62 -525
  45. package/src/generated/sml.ts +137 -508
  46. package/src/generated/treasury.ts +127 -348
  47. package/src/generated/uln302.ts +212 -627
  48. package/src/generated/upgrader.ts +28 -54
  49. package/test/counter-sml.test.ts +218 -142
  50. package/test/counter-uln.test.ts +189 -145
  51. package/test/oft-sml.test.ts +173 -156
  52. package/test/suites/constants.ts +7 -1
  53. package/test/suites/globalSetup.ts +140 -74
  54. package/turbo.json +1 -1
@@ -20,12 +20,14 @@ import { Client as OFTClient, OftType, SendParam } from '../src/generated/oft';
20
20
  import { Client as SMLClient } from '../src/generated/sml';
21
21
  import {
22
22
  DEFAULT_DEPLOYER,
23
- EID,
23
+ EID_A,
24
+ EID_B,
24
25
  EXECUTOR_ADMIN,
25
26
  NETWORK_PASSPHRASE,
26
27
  RPC_URL,
27
28
  } from './suites/constants';
28
29
  import { deployAssetSac, deployContract } from './suites/deploy';
30
+ import type { ChainAddresses } from './suites/globalSetup';
29
31
  import { fundAccount } from './suites/localnet';
30
32
  import { PacketSentEvent, scanPacketSentEvents } from './suites/scan';
31
33
  import {
@@ -35,27 +37,33 @@ import {
35
37
  signAndSendWithExecutorAuth,
36
38
  } from './utils';
37
39
 
38
- // Protocol addresses (will be injected from globalSetup in beforeAll)
39
- let protocolAddresses: ReturnType<typeof inject<'protocolAddresses'>>;
40
+ // Chain addresses (injected from globalSetup)
41
+ let chainA: ChainAddresses;
42
+ let chainB: ChainAddresses;
40
43
 
41
44
  // OFT-specific addresses
42
45
  let oftTokenAddress = '';
43
- let lockUnlockOftAddress = '';
44
- let mintBurnOftAddress = '';
46
+ let lockUnlockOftAddress = ''; // Chain A
47
+ let mintBurnOftAddress = ''; // Chain B
45
48
 
46
- // Clients
47
- let endpointClient: EndpointClient;
48
- let smlClient: SMLClient;
49
- let executorHelperClient: ExecutorHelperClient;
49
+ // Chain A Clients
50
+ let endpointClientA: EndpointClient;
51
+ let smlClientA: SMLClient;
52
+ let executorHelperClientA: ExecutorHelperClient;
50
53
  let lockUnlockOftClient: OFTClient;
54
+
55
+ // Chain B Clients
56
+ let endpointClientB: EndpointClient;
57
+ let smlClientB: SMLClient;
58
+ let executorHelperClientB: ExecutorHelperClient;
51
59
  let mintBurnOftClient: OFTClient;
52
60
 
53
61
  // Test accounts
54
62
  const TOKEN_ISSUER = Keypair.random();
55
63
 
56
64
  // Recipients for each direction
57
- const RECIPIENT_A = Keypair.random(); // Receives tokens in Lock/Unlock -> Mint/Burn direction
58
- const RECIPIENT_B = Keypair.random(); // Receives tokens in Mint/Burn -> Lock/Unlock direction
65
+ const RECIPIENT_A = Keypair.random(); // Receives tokens on Chain A (unlocked)
66
+ const RECIPIENT_B = Keypair.random(); // Receives tokens on Chain B (minted)
59
67
 
60
68
  // OFT Token asset (custom token for testing)
61
69
  const OFT_TOKEN_CODE = 'OFT';
@@ -66,9 +74,7 @@ const SHARED_DECIMALS = 6;
66
74
  const INITIAL_TOKEN_AMOUNT = '1000'; // 1000 tokens
67
75
  const SEND_AMOUNT = 100_0000000n; // 100 tokens in local decimals (7 decimals)
68
76
 
69
- // NOTE: run `stellar contract build` before running the test
70
-
71
- describe('OFT E2E Testing with SAC (SML)', async () => {
77
+ describe('OFT Cross-Chain E2E Testing with SAC (SML)', async () => {
72
78
  const repoRoot = await getFullyQualifiedRepoRootPath();
73
79
  const wasmDir = path.join(
74
80
  repoRoot,
@@ -83,19 +89,29 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
83
89
  const OFT_WASM_PATH = path.join(wasmDir, 'oft.wasm');
84
90
 
85
91
  beforeAll(async () => {
86
- // Inject protocol addresses from globalSetup
87
- protocolAddresses = inject('protocolAddresses');
88
-
89
- console.log('\nšŸ“‹ Protocol addresses injected from globalSetup');
90
- console.log(' Endpoint:', protocolAddresses.endpointV2);
91
- console.log(' SML:', protocolAddresses.sml);
92
- console.log(' Executor:', protocolAddresses.executor);
93
- console.log(' Executor Helper:', protocolAddresses.executorHelper);
94
-
95
- // Create clients for protocol contracts
96
- endpointClient = createClient(EndpointClient, protocolAddresses.endpointV2);
97
- smlClient = createClient(SMLClient, protocolAddresses.sml);
98
- executorHelperClient = createClient(ExecutorHelperClient, protocolAddresses.executorHelper);
92
+ // Inject chain addresses from globalSetup
93
+ chainA = inject('chainA');
94
+ chainB = inject('chainB');
95
+
96
+ console.log('\nšŸ“‹ Chain A addresses (EID: ' + EID_A + ')');
97
+ console.log(' Endpoint:', chainA.endpointV2);
98
+ console.log(' SML:', chainA.sml);
99
+ console.log(' Executor:', chainA.executor);
100
+
101
+ console.log('\nšŸ“‹ Chain B addresses (EID: ' + EID_B + ')');
102
+ console.log(' Endpoint:', chainB.endpointV2);
103
+ console.log(' SML:', chainB.sml);
104
+ console.log(' Executor:', chainB.executor);
105
+
106
+ // Create clients for Chain A protocol contracts
107
+ endpointClientA = createClient(EndpointClient, chainA.endpointV2);
108
+ smlClientA = createClient(SMLClient, chainA.sml);
109
+ executorHelperClientA = createClient(ExecutorHelperClient, chainA.executorHelper);
110
+
111
+ // Create clients for Chain B protocol contracts
112
+ endpointClientB = createClient(EndpointClient, chainB.endpointV2);
113
+ smlClientB = createClient(SMLClient, chainB.sml);
114
+ executorHelperClientB = createClient(ExecutorHelperClient, chainB.executorHelper);
99
115
 
100
116
  // Fund test accounts
101
117
  await fundAccount(TOKEN_ISSUER.publicKey());
@@ -106,7 +122,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
106
122
  OFT_ASSET = new Asset(OFT_TOKEN_CODE, TOKEN_ISSUER.publicKey());
107
123
  });
108
124
 
109
- describe('Deploy OFT Contracts', () => {
125
+ describe('Deploy OFT Contracts on Both Chains', () => {
110
126
  it('Deploy OFT Token SAC', async () => {
111
127
  const server = new rpc.Server(RPC_URL, { allowHttp: true });
112
128
 
@@ -123,14 +139,14 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
123
139
  source: DEFAULT_DEPLOYER.publicKey(),
124
140
  }),
125
141
  )
126
- // Trustline for RECIPIENT_A (receives minted tokens)
142
+ // Trustline for RECIPIENT_A (receives unlocked tokens)
127
143
  .addOperation(
128
144
  Operation.changeTrust({
129
145
  asset: OFT_ASSET,
130
146
  source: RECIPIENT_A.publicKey(),
131
147
  }),
132
148
  )
133
- // Trustline for RECIPIENT_B (receives unlocked tokens)
149
+ // Trustline for RECIPIENT_B (receives minted tokens)
134
150
  .addOperation(
135
151
  Operation.changeTrust({
136
152
  asset: OFT_ASSET,
@@ -164,14 +180,14 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
164
180
  console.log('āœ… OFT Token SAC deployed:', oftTokenAddress);
165
181
  });
166
182
 
167
- it('Deploy Lock/Unlock OFT', async () => {
183
+ it('Deploy Lock/Unlock OFT on Chain A', async () => {
168
184
  lockUnlockOftClient = await deployContract<OFTClient>(
169
185
  OFTClient,
170
186
  OFT_WASM_PATH,
171
187
  {
172
188
  token: oftTokenAddress,
173
189
  owner: DEFAULT_DEPLOYER.publicKey(),
174
- endpoint: protocolAddresses.endpointV2,
190
+ endpoint: chainA.endpointV2, // Chain A endpoint
175
191
  delegate: DEFAULT_DEPLOYER.publicKey(),
176
192
  shared_decimals: SHARED_DECIMALS,
177
193
  oft_type: OftType.LockUnlock,
@@ -180,146 +196,139 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
180
196
  );
181
197
 
182
198
  lockUnlockOftAddress = lockUnlockOftClient.options.contractId;
183
- console.log('āœ… Lock/Unlock OFT deployed:', lockUnlockOftAddress);
199
+ console.log('āœ… Lock/Unlock OFT deployed on Chain A:', lockUnlockOftAddress);
184
200
 
185
- // Verify it's in lock/unlock mode
186
201
  const { result: oftType } = await lockUnlockOftClient.oft_type();
187
202
  expect(oftType).toEqual(OftType.LockUnlock);
188
203
  });
189
204
 
190
- it('Deploy Mint/Burn OFT', async () => {
205
+ it('Deploy Mint/Burn OFT on Chain B', async () => {
191
206
  mintBurnOftClient = await deployContract<OFTClient>(
192
207
  OFTClient,
193
208
  OFT_WASM_PATH,
194
209
  {
195
210
  token: oftTokenAddress,
196
211
  owner: DEFAULT_DEPLOYER.publicKey(),
197
- endpoint: protocolAddresses.endpointV2,
212
+ endpoint: chainB.endpointV2, // Chain B endpoint
198
213
  delegate: DEFAULT_DEPLOYER.publicKey(),
199
214
  shared_decimals: SHARED_DECIMALS,
200
- oft_type: OftType.MintBurn, // Mint/Burn mode
215
+ oft_type: OftType.MintBurn,
201
216
  },
202
217
  DEFAULT_DEPLOYER,
203
218
  );
204
219
 
205
220
  mintBurnOftAddress = mintBurnOftClient.options.contractId;
206
- console.log('āœ… Mint/Burn OFT deployed:', mintBurnOftAddress);
221
+ console.log('āœ… Mint/Burn OFT deployed on Chain B:', mintBurnOftAddress);
207
222
 
208
- // Verify it's in mint/burn mode
209
223
  const { result: oftType } = await mintBurnOftClient.oft_type();
210
224
  expect(oftType).toEqual(OftType.MintBurn);
211
225
  });
212
226
  });
213
227
 
214
- describe('Wire OFT Contracts to use SML', () => {
215
- it('Set Lock/Unlock OFT Send Library to SML', async () => {
216
- const assembledTx = await endpointClient.set_send_library({
228
+ describe('Wire OFT Contracts to use SML (Cross-Chain)', () => {
229
+ it('Set Lock/Unlock OFT (Chain A) Send Library to SML for Chain B', async () => {
230
+ const assembledTx = await endpointClientA.set_send_library({
217
231
  caller: DEFAULT_DEPLOYER.publicKey(),
218
232
  sender: lockUnlockOftAddress,
219
- dst_eid: EID,
220
- new_lib: protocolAddresses.sml,
233
+ dst_eid: EID_B,
234
+ new_lib: chainA.sml,
221
235
  });
222
236
  await assembledTx.signAndSend();
223
237
 
224
- const { result: sendLib } = await endpointClient.get_send_library({
238
+ const { result: sendLib } = await endpointClientA.get_send_library({
225
239
  sender: lockUnlockOftAddress,
226
- dst_eid: EID,
240
+ dst_eid: EID_B,
227
241
  });
228
- expect(sendLib.lib).toBe(protocolAddresses.sml);
229
- expect(sendLib.is_default).toBe(false);
230
- console.log('āœ… Lock/Unlock OFT send library set to SML');
242
+ expect(sendLib.lib).toBe(chainA.sml);
243
+ console.log('āœ… Lock/Unlock OFT (Chain A) send library set to SML for EID_B');
231
244
  });
232
245
 
233
- it('Set Lock/Unlock OFT Receive Library to SML', async () => {
234
- const assembledTx = await endpointClient.set_receive_library({
246
+ it('Set Lock/Unlock OFT (Chain A) Receive Library to SML for Chain B', async () => {
247
+ const assembledTx = await endpointClientA.set_receive_library({
235
248
  caller: DEFAULT_DEPLOYER.publicKey(),
236
249
  receiver: lockUnlockOftAddress,
237
- src_eid: EID,
238
- new_lib: protocolAddresses.sml,
250
+ src_eid: EID_B,
251
+ new_lib: chainA.sml,
239
252
  grace_period: 0n,
240
253
  });
241
254
  await assembledTx.signAndSend();
242
255
 
243
- const { result: receiveLib } = await endpointClient.get_receive_library({
256
+ const { result: receiveLib } = await endpointClientA.get_receive_library({
244
257
  receiver: lockUnlockOftAddress,
245
- src_eid: EID,
258
+ src_eid: EID_B,
246
259
  });
247
- expect(receiveLib.lib).toBe(protocolAddresses.sml);
248
- expect(receiveLib.is_default).toBe(false);
249
- console.log('āœ… Lock/Unlock OFT receive library set to SML');
260
+ expect(receiveLib.lib).toBe(chainA.sml);
261
+ console.log('āœ… Lock/Unlock OFT (Chain A) receive library set to SML for EID_B');
250
262
  });
251
263
 
252
- it('Set Mint/Burn OFT Send Library to SML', async () => {
253
- const assembledTx = await endpointClient.set_send_library({
264
+ it('Set Mint/Burn OFT (Chain B) Send Library to SML for Chain A', async () => {
265
+ const assembledTx = await endpointClientB.set_send_library({
254
266
  caller: DEFAULT_DEPLOYER.publicKey(),
255
267
  sender: mintBurnOftAddress,
256
- dst_eid: EID,
257
- new_lib: protocolAddresses.sml,
268
+ dst_eid: EID_A,
269
+ new_lib: chainB.sml,
258
270
  });
259
271
  await assembledTx.signAndSend();
260
272
 
261
- const { result: sendLib } = await endpointClient.get_send_library({
273
+ const { result: sendLib } = await endpointClientB.get_send_library({
262
274
  sender: mintBurnOftAddress,
263
- dst_eid: EID,
275
+ dst_eid: EID_A,
264
276
  });
265
- expect(sendLib.lib).toBe(protocolAddresses.sml);
266
- expect(sendLib.is_default).toBe(false);
267
- console.log('āœ… Mint/Burn OFT send library set to SML');
277
+ expect(sendLib.lib).toBe(chainB.sml);
278
+ console.log('āœ… Mint/Burn OFT (Chain B) send library set to SML for EID_A');
268
279
  });
269
280
 
270
- it('Set Mint/Burn OFT Receive Library to SML', async () => {
271
- const assembledTx = await endpointClient.set_receive_library({
281
+ it('Set Mint/Burn OFT (Chain B) Receive Library to SML for Chain A', async () => {
282
+ const assembledTx = await endpointClientB.set_receive_library({
272
283
  caller: DEFAULT_DEPLOYER.publicKey(),
273
284
  receiver: mintBurnOftAddress,
274
- src_eid: EID,
275
- new_lib: protocolAddresses.sml,
285
+ src_eid: EID_A,
286
+ new_lib: chainB.sml,
276
287
  grace_period: 0n,
277
288
  });
278
289
  await assembledTx.signAndSend();
279
290
 
280
- const { result: receiveLib } = await endpointClient.get_receive_library({
291
+ const { result: receiveLib } = await endpointClientB.get_receive_library({
281
292
  receiver: mintBurnOftAddress,
282
- src_eid: EID,
293
+ src_eid: EID_A,
283
294
  });
284
- expect(receiveLib.lib).toBe(protocolAddresses.sml);
285
- expect(receiveLib.is_default).toBe(false);
286
- console.log('āœ… Mint/Burn OFT receive library set to SML');
295
+ expect(receiveLib.lib).toBe(chainB.sml);
296
+ console.log('āœ… Mint/Burn OFT (Chain B) receive library set to SML for EID_A');
287
297
  });
288
298
 
289
- it('Set Lock/Unlock OFT Peer (to Mint/Burn OFT)', async () => {
299
+ it('Set Lock/Unlock OFT (Chain A) Peer to Mint/Burn OFT (Chain B)', async () => {
290
300
  const mintBurnPeerBytes = StrKey.decodeContract(mintBurnOftAddress);
291
301
 
292
302
  const assembledTx = await lockUnlockOftClient.set_peer({
293
- eid: EID,
303
+ eid: EID_B,
294
304
  peer: Buffer.from(mintBurnPeerBytes),
295
305
  });
296
306
  await assembledTx.signAndSend();
297
307
 
298
308
  const { result: peer } = await lockUnlockOftClient.peer({
299
- eid: EID,
309
+ eid: EID_B,
300
310
  });
301
311
  expect(peer?.toString()).toBe(Buffer.from(mintBurnPeerBytes).toString());
302
- console.log('āœ… Lock/Unlock OFT peer set to Mint/Burn OFT');
312
+ console.log('āœ… Lock/Unlock OFT (Chain A) peer set to Mint/Burn OFT for EID_B');
303
313
  });
304
314
 
305
- it('Set Mint/Burn OFT Peer (to Lock/Unlock OFT)', async () => {
315
+ it('Set Mint/Burn OFT (Chain B) Peer to Lock/Unlock OFT (Chain A)', async () => {
306
316
  const lockUnlockPeerBytes = StrKey.decodeContract(lockUnlockOftAddress);
307
317
 
308
318
  const assembledTx = await mintBurnOftClient.set_peer({
309
- eid: EID,
319
+ eid: EID_A,
310
320
  peer: Buffer.from(lockUnlockPeerBytes),
311
321
  });
312
322
  await assembledTx.signAndSend();
313
323
 
314
324
  const { result: peer } = await mintBurnOftClient.peer({
315
- eid: EID,
325
+ eid: EID_A,
316
326
  });
317
327
  expect(peer?.toString()).toBe(Buffer.from(lockUnlockPeerBytes).toString());
318
- console.log('āœ… Mint/Burn OFT peer set to Lock/Unlock OFT');
328
+ console.log('āœ… Mint/Burn OFT (Chain B) peer set to Lock/Unlock OFT for EID_A');
319
329
  });
320
330
 
321
331
  it('Set SAC Admin to Mint/Burn OFT (for minting)', async () => {
322
- // The Mint/Burn OFT needs to be the admin of the SAC to mint tokens
323
332
  const server = new rpc.Server(RPC_URL, { allowHttp: true });
324
333
 
325
334
  const account = await server.getAccount(TOKEN_ISSUER.publicKey());
@@ -358,7 +367,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
358
367
  });
359
368
  });
360
369
 
361
- describe('Send: Lock/Unlock -> Mint/Burn', () => {
370
+ describe('Send: Chain A (Lock) → Chain B (Mint)', () => {
362
371
  let sendLedger = 0;
363
372
  let packetSentEvent: PacketSentEvent;
364
373
  let guid: Buffer;
@@ -372,20 +381,20 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
372
381
  console.log('šŸ“Š Initial Balances:');
373
382
  console.log(` - Sender (DEFAULT_DEPLOYER): ${senderBalance} (expected: 10000000000)`);
374
383
 
375
- const recipientABalance = await getTokenBalance(
376
- RECIPIENT_A.publicKey(),
384
+ const recipientBBalance = await getTokenBalance(
385
+ RECIPIENT_B.publicKey(),
377
386
  oftTokenAddress,
378
387
  );
379
- console.log(` - RECIPIENT_A: ${recipientABalance} (expected: 0)`);
388
+ console.log(` - RECIPIENT_B (Chain B): ${recipientBBalance} (expected: 0)`);
380
389
 
381
390
  expect(senderBalance).toBe(10000000000n);
382
- expect(recipientABalance).toBe(0n);
391
+ expect(recipientBBalance).toBe(0n);
383
392
  });
384
393
 
385
- it('Quote OFT send', async () => {
386
- const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_A.publicKey());
394
+ it('Quote OFT send (A → B)', async () => {
395
+ const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_B.publicKey());
387
396
  const sendParam: SendParam = {
388
- dst_eid: EID,
397
+ dst_eid: EID_B,
389
398
  to: Buffer.from(receiverBytes),
390
399
  amount_ld: SEND_AMOUNT,
391
400
  min_amount_ld: SEND_AMOUNT,
@@ -398,7 +407,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
398
407
  send_param: sendParam,
399
408
  });
400
409
  const [limit, feeDetails, receipt] = quoteResult;
401
- console.log('šŸ“Š OFT Quote:');
410
+ console.log('šŸ“Š OFT Quote (A → B):');
402
411
  console.log(' Limit:', limit);
403
412
  console.log(' Fee Details:', feeDetails);
404
413
  console.log(' Receipt:', receipt);
@@ -406,10 +415,10 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
406
415
  expect(receipt.amount_sent_ld).toBe(SEND_AMOUNT);
407
416
  });
408
417
 
409
- it('Send tokens (Lock/Unlock -> Mint/Burn)', async () => {
410
- const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_A.publicKey());
418
+ it('Send tokens from Chain A to Chain B (Lock → Mint)', async () => {
419
+ const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_B.publicKey());
411
420
  const sendParam: SendParam = {
412
- dst_eid: EID,
421
+ dst_eid: EID_B,
413
422
  to: Buffer.from(receiverBytes),
414
423
  amount_ld: SEND_AMOUNT,
415
424
  min_amount_ld: SEND_AMOUNT,
@@ -423,7 +432,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
423
432
  send_param: sendParam,
424
433
  pay_in_zro: true,
425
434
  });
426
- console.log('šŸ“Š Messaging Fee:', fee);
435
+ console.log('šŸ“Š Messaging Fee (A → B):', fee);
427
436
 
428
437
  const assembledTx = await lockUnlockOftClient.send({
429
438
  from: DEFAULT_DEPLOYER.publicKey(),
@@ -440,22 +449,21 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
440
449
  }
441
450
 
442
451
  if (txResponse) {
443
- assertTransactionSucceeded(txResponse, 'OFT Send');
452
+ assertTransactionSucceeded(txResponse, 'OFT Send (A → B)');
444
453
  }
445
- console.log('āœ… Tokens sent, ledger:', sendLedger);
454
+ console.log('āœ… Tokens sent from Chain A, ledger:', sendLedger);
446
455
  });
447
456
 
448
- it('Scan PacketSent events', async () => {
449
- const packetSentEvents = await scanPacketSentEvents(
450
- protocolAddresses.endpointV2,
451
- sendLedger,
452
- );
457
+ it('Scan PacketSent events (A → B)', async () => {
458
+ const packetSentEvents = await scanPacketSentEvents(chainA.endpointV2, sendLedger);
453
459
  expect(packetSentEvents.length).toBeGreaterThan(0);
454
460
  packetSentEvent = packetSentEvents[0];
455
- console.log(`āœ… PacketSent events scanned. Found ${packetSentEvents.length} events`);
461
+ console.log(
462
+ `āœ… PacketSent events scanned from Chain A. Found ${packetSentEvents.length} events`,
463
+ );
456
464
  });
457
465
 
458
- it('Validate packet via SML', async () => {
466
+ it('Validate packet via SML on Chain B', async () => {
459
467
  const packet = PacketSerializer.deserialize(packetSentEvent.encoded_packet);
460
468
  guid = Buffer.from(packet.guid.replace('0x', ''), 'hex');
461
469
  message = Buffer.from(packet.message.replace('0x', ''), 'hex');
@@ -463,25 +471,25 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
463
471
  const packetHeader = codec.header();
464
472
  const payloadHash = codec.payloadHash();
465
473
 
466
- const assembledTx = await smlClient.validate_packet({
474
+ const assembledTx = await smlClientB.validate_packet({
467
475
  header_bytes: Buffer.from(packetHeader.replace('0x', ''), 'hex'),
468
476
  payload_hash: Buffer.from(payloadHash.replace('0x', ''), 'hex'),
469
477
  });
470
478
  await assembledTx.signAndSend();
471
- console.log('āœ… Packet validated via SML');
479
+ console.log('āœ… Packet validated via SML on Chain B');
472
480
  });
473
481
 
474
- it('Receive tokens (mint on Mint/Burn OFT)', async () => {
482
+ it('Receive tokens on Chain B (mint)', async () => {
475
483
  const lockUnlockPeerBytes = StrKey.decodeContract(lockUnlockOftAddress);
476
484
  const origin = {
477
485
  nonce: 1n,
478
486
  sender: Buffer.from(lockUnlockPeerBytes),
479
- src_eid: EID,
487
+ src_eid: EID_A,
480
488
  };
481
489
 
482
- const assembledTx = await executorHelperClient.execute(
490
+ const assembledTx = await executorHelperClientB.execute(
483
491
  {
484
- executor: protocolAddresses.executor,
492
+ executor: chainB.executor,
485
493
  params: {
486
494
  extra_data: Buffer.from([]),
487
495
  gas_limit: 0n,
@@ -499,18 +507,18 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
499
507
  );
500
508
 
501
509
  const txResult = await signAndSendWithExecutorAuth(
502
- protocolAddresses.executor,
510
+ chainB.executor,
503
511
  EXECUTOR_ADMIN,
504
512
  assembledTx,
505
513
  NETWORK_PASSPHRASE,
506
514
  );
507
515
 
508
- assertTransactionSucceeded(txResult, 'LzReceive (Mint)');
516
+ assertTransactionSucceeded(txResult, 'LzReceive on Chain B (Mint)');
509
517
 
510
- console.log('āœ… Tokens received and minted on Mint/Burn OFT');
518
+ console.log('āœ… Tokens received and minted on Chain B');
511
519
  });
512
520
 
513
- it('Verify balances after forward send', async () => {
521
+ it('Verify balances after forward send (A → B)', async () => {
514
522
  const senderBalance = await getTokenBalance(
515
523
  DEFAULT_DEPLOYER.publicKey(),
516
524
  oftTokenAddress,
@@ -519,35 +527,37 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
519
527
  lockUnlockOftAddress,
520
528
  oftTokenAddress,
521
529
  );
522
- const recipientABalance = await getTokenBalance(
523
- RECIPIENT_A.publicKey(),
530
+ const recipientBBalance = await getTokenBalance(
531
+ RECIPIENT_B.publicKey(),
524
532
  oftTokenAddress,
525
533
  );
526
534
 
527
- console.log('šŸ“Š Balances after forward send:');
535
+ console.log('šŸ“Š Balances after forward send (A → B):');
528
536
  console.log(` - Sender (DEFAULT_DEPLOYER): ${senderBalance} (expected: 9000000000)`);
529
537
  console.log(
530
- ` - Lock/Unlock OFT (locked): ${lockUnlockOftBalance} (expected: 1000000000)`,
538
+ ` - Lock/Unlock OFT (Chain A, locked): ${lockUnlockOftBalance} (expected: 1000000000)`,
539
+ );
540
+ console.log(
541
+ ` - RECIPIENT_B (Chain B, minted): ${recipientBBalance} (expected: 1000000000)`,
531
542
  );
532
- console.log(` - RECIPIENT_A (minted): ${recipientABalance} (expected: 1000000000)`);
533
543
 
534
544
  expect(senderBalance).toBe(9000000000n);
535
545
  expect(lockUnlockOftBalance).toBe(1000000000n);
536
- expect(recipientABalance).toBe(1000000000n);
546
+ expect(recipientBBalance).toBe(1000000000n);
537
547
  });
538
548
  });
539
549
 
540
- describe('Send: Mint/Burn -> Lock/Unlock (Reverse)', () => {
550
+ describe('Send: Chain B (Burn) → Chain A (Unlock)', () => {
541
551
  let sendLedger = 0;
542
552
  let packetSentEvent: PacketSentEvent;
543
553
  let guid: Buffer;
544
554
  let message: Buffer;
545
555
  const REVERSE_SEND_AMOUNT = 50_0000000n;
546
556
 
547
- it('Quote OFT send (reverse)', async () => {
548
- const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_B.publicKey());
557
+ it('Quote OFT send (B → A)', async () => {
558
+ const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_A.publicKey());
549
559
  const sendParam: SendParam = {
550
- dst_eid: EID,
560
+ dst_eid: EID_A,
551
561
  to: Buffer.from(receiverBytes),
552
562
  amount_ld: REVERSE_SEND_AMOUNT,
553
563
  min_amount_ld: REVERSE_SEND_AMOUNT,
@@ -560,7 +570,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
560
570
  send_param: sendParam,
561
571
  });
562
572
  const [limit, feeDetails, receipt] = quoteResult;
563
- console.log('šŸ“Š Reverse OFT Quote:');
573
+ console.log('šŸ“Š Reverse OFT Quote (B → A):');
564
574
  console.log(' Limit:', limit);
565
575
  console.log(' Fee Details:', feeDetails);
566
576
  console.log(' Receipt:', receipt);
@@ -568,10 +578,10 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
568
578
  expect(receipt.amount_sent_ld).toBe(REVERSE_SEND_AMOUNT);
569
579
  });
570
580
 
571
- it('Send tokens (Mint/Burn -> Lock/Unlock)', async () => {
572
- const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_B.publicKey());
581
+ it('Send tokens from Chain B to Chain A (Burn → Unlock)', async () => {
582
+ const receiverBytes = StrKey.decodeEd25519PublicKey(RECIPIENT_A.publicKey());
573
583
  const sendParam: SendParam = {
574
- dst_eid: EID,
584
+ dst_eid: EID_A,
575
585
  to: Buffer.from(receiverBytes),
576
586
  amount_ld: REVERSE_SEND_AMOUNT,
577
587
  min_amount_ld: REVERSE_SEND_AMOUNT,
@@ -585,7 +595,7 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
585
595
  send_param: sendParam,
586
596
  pay_in_zro: true,
587
597
  });
588
- console.log('šŸ“Š Reverse Messaging Fee:', fee);
598
+ console.log('šŸ“Š Reverse Messaging Fee (B → A):', fee);
589
599
 
590
600
  const assembledTx = await mintBurnOftClient.send({
591
601
  from: DEFAULT_DEPLOYER.publicKey(),
@@ -602,24 +612,21 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
602
612
  }
603
613
 
604
614
  if (txResponse) {
605
- assertTransactionSucceeded(txResponse, 'OFT Reverse Send');
615
+ assertTransactionSucceeded(txResponse, 'OFT Reverse Send (B → A)');
606
616
  }
607
- console.log('āœ… Tokens sent (reverse), ledger:', sendLedger);
617
+ console.log('āœ… Tokens sent from Chain B (reverse), ledger:', sendLedger);
608
618
  });
609
619
 
610
- it('Scan PacketSent events (reverse)', async () => {
611
- const packetSentEvents = await scanPacketSentEvents(
612
- protocolAddresses.endpointV2,
613
- sendLedger,
614
- );
620
+ it('Scan PacketSent events (B → A)', async () => {
621
+ const packetSentEvents = await scanPacketSentEvents(chainB.endpointV2, sendLedger);
615
622
  expect(packetSentEvents.length).toBeGreaterThan(0);
616
623
  packetSentEvent = packetSentEvents[0];
617
624
  console.log(
618
- `āœ… PacketSent events scanned (reverse). Found ${packetSentEvents.length} events`,
625
+ `āœ… PacketSent events scanned from Chain B (reverse). Found ${packetSentEvents.length} events`,
619
626
  );
620
627
  });
621
628
 
622
- it('Validate packet via SML (reverse)', async () => {
629
+ it('Validate packet via SML on Chain A (reverse)', async () => {
623
630
  const packet = PacketSerializer.deserialize(packetSentEvent.encoded_packet);
624
631
  guid = Buffer.from(packet.guid.replace('0x', ''), 'hex');
625
632
  message = Buffer.from(packet.message.replace('0x', ''), 'hex');
@@ -627,25 +634,25 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
627
634
  const packetHeader = codec.header();
628
635
  const payloadHash = codec.payloadHash();
629
636
 
630
- const assembledTx = await smlClient.validate_packet({
637
+ const assembledTx = await smlClientA.validate_packet({
631
638
  header_bytes: Buffer.from(packetHeader.replace('0x', ''), 'hex'),
632
639
  payload_hash: Buffer.from(payloadHash.replace('0x', ''), 'hex'),
633
640
  });
634
641
  await assembledTx.signAndSend();
635
- console.log('āœ… Packet validated via SML (reverse)');
642
+ console.log('āœ… Packet validated via SML on Chain A (reverse)');
636
643
  });
637
644
 
638
- it('Receive tokens (unlock on Lock/Unlock OFT)', async () => {
645
+ it('Receive tokens on Chain A (unlock)', async () => {
639
646
  const mintBurnPeerBytes = StrKey.decodeContract(mintBurnOftAddress);
640
647
  const origin = {
641
648
  nonce: 1n,
642
649
  sender: Buffer.from(mintBurnPeerBytes),
643
- src_eid: EID,
650
+ src_eid: EID_B,
644
651
  };
645
652
 
646
- const assembledTx = await executorHelperClient.execute(
653
+ const assembledTx = await executorHelperClientA.execute(
647
654
  {
648
- executor: protocolAddresses.executor,
655
+ executor: chainA.executor,
649
656
  params: {
650
657
  extra_data: Buffer.from([]),
651
658
  gas_limit: 0n,
@@ -663,15 +670,15 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
663
670
  );
664
671
 
665
672
  const txResult = await signAndSendWithExecutorAuth(
666
- protocolAddresses.executor,
673
+ chainA.executor,
667
674
  EXECUTOR_ADMIN,
668
675
  assembledTx,
669
676
  NETWORK_PASSPHRASE,
670
677
  );
671
678
 
672
- assertTransactionSucceeded(txResult, 'LzReceive (Unlock)');
679
+ assertTransactionSucceeded(txResult, 'LzReceive on Chain A (Unlock)');
673
680
 
674
- console.log('āœ… Tokens received and unlocked on Lock/Unlock OFT');
681
+ console.log('āœ… Tokens received and unlocked on Chain A');
675
682
  });
676
683
 
677
684
  it('Verify final balances', async () => {
@@ -695,17 +702,27 @@ describe('OFT E2E Testing with SAC (SML)', async () => {
695
702
  console.log('\nšŸ“Š Final Balance Summary:');
696
703
  console.log(` - Sender (DEFAULT_DEPLOYER): ${senderBalance} (expected: 8500000000)`);
697
704
  console.log(
698
- ` - Lock/Unlock OFT (locked): ${lockUnlockOftBalance} (expected: 500000000)`,
705
+ ` - Lock/Unlock OFT (Chain A, locked): ${lockUnlockOftBalance} (expected: 500000000)`,
706
+ );
707
+ console.log(
708
+ ` - RECIPIENT_A (Chain A, unlocked): ${recipientABalance} (expected: 500000000)`,
709
+ );
710
+ console.log(
711
+ ` - RECIPIENT_B (Chain B, minted): ${recipientBBalance} (expected: 1000000000)`,
699
712
  );
700
- console.log(` - RECIPIENT_A (minted): ${recipientABalance} (expected: 1000000000)`);
701
- console.log(` - RECIPIENT_B (unlocked): ${recipientBBalance} (expected: 500000000)`);
702
713
 
703
714
  expect(senderBalance).toBe(8500000000n);
704
715
  expect(lockUnlockOftBalance).toBe(500000000n);
705
- expect(recipientABalance).toBe(1000000000n);
706
- expect(recipientBBalance).toBe(500000000n);
716
+ expect(recipientABalance).toBe(500000000n);
717
+ expect(recipientBBalance).toBe(1000000000n);
707
718
 
708
- console.log('āœ… OFT E2E test completed successfully!');
719
+ console.log('\nšŸŽ‰ OFT Cross-Chain E2E test completed successfully!');
720
+ console.log(
721
+ ' Chain A (Lock/Unlock) → Chain B (Mint/Burn): 100 tokens locked, 100 minted',
722
+ );
723
+ console.log(
724
+ ' Chain B (Mint/Burn) → Chain A (Lock/Unlock): 50 tokens burned, 50 unlocked',
725
+ );
709
726
  });
710
727
  });
711
728
  });