@layerzerolabs/lz-v2-stellar-sdk 0.2.32 → 0.2.34

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.
@@ -17,6 +17,7 @@ import { PacketSerializer, PacketV1Codec } from '@layerzerolabs/lz-v2-utilities'
17
17
  import { Client as EndpointClient } from '../src/generated/endpoint';
18
18
  import { Client as ExecutorHelperClient } from '../src/generated/executor_helper';
19
19
  import { Client as OFTClient, SendParam } from '../src/generated/oft';
20
+ import { Client as SacManagerClient } from '../src/generated/sac_manager';
20
21
  import { Client as SMLClient } from '../src/generated/sml';
21
22
  import {
22
23
  DEFAULT_DEPLOYER,
@@ -43,6 +44,7 @@ let chainB: ChainAddresses;
43
44
 
44
45
  // OFT-specific addresses
45
46
  let oftTokenAddress = '';
47
+ let sacManagerAddress = ''; // Mintable for Mint/Burn OFT (Chain B)
46
48
  let lockUnlockOftAddress = ''; // Chain A
47
49
  let mintBurnOftAddress = ''; // Chain B
48
50
 
@@ -87,6 +89,7 @@ describe('OFT Cross-Chain E2E Testing with SAC (SML)', async () => {
87
89
  );
88
90
 
89
91
  const OFT_WASM_PATH = path.join(wasmDir, 'oft.wasm');
92
+ const SAC_MANAGER_WASM_PATH = path.join(wasmDir, 'sac_manager.wasm');
90
93
 
91
94
  beforeAll(async () => {
92
95
  // Inject chain addresses from globalSetup
@@ -180,6 +183,53 @@ describe('OFT Cross-Chain E2E Testing with SAC (SML)', async () => {
180
183
  console.log('✅ OFT Token SAC deployed:', oftTokenAddress);
181
184
  });
182
185
 
186
+ it('Deploy SAC Manager and set SAC admin (mintable for Mint/Burn OFT)', async () => {
187
+ const sacManagerClient = await deployContract<SacManagerClient>(
188
+ SacManagerClient,
189
+ SAC_MANAGER_WASM_PATH,
190
+ {
191
+ sac_token: oftTokenAddress,
192
+ owner: DEFAULT_DEPLOYER.publicKey(),
193
+ },
194
+ DEFAULT_DEPLOYER,
195
+ );
196
+ sacManagerAddress = sacManagerClient.options.contractId;
197
+ console.log('✅ SAC Manager deployed:', sacManagerAddress);
198
+
199
+ const server = new rpc.Server(RPC_URL, { allowHttp: true });
200
+ const account = await server.getAccount(TOKEN_ISSUER.publicKey());
201
+ const setAdminTx = new TransactionBuilder(account, {
202
+ fee: BASE_FEE,
203
+ networkPassphrase: NETWORK_PASSPHRASE,
204
+ })
205
+ .addOperation(
206
+ Operation.invokeContractFunction({
207
+ contract: oftTokenAddress,
208
+ function: 'set_admin',
209
+ args: [Address.fromString(sacManagerAddress).toScVal()],
210
+ }),
211
+ )
212
+ .setTimeout(30)
213
+ .build();
214
+
215
+ const simulated = await server.simulateTransaction(setAdminTx);
216
+ if (rpc.Api.isSimulationError(simulated)) {
217
+ throw new Error(`Simulation failed: ${JSON.stringify(simulated)}`);
218
+ }
219
+ const preparedTx = rpc.assembleTransaction(setAdminTx, simulated).build();
220
+ preparedTx.sign(TOKEN_ISSUER);
221
+
222
+ const sendResult = await server.sendTransaction(preparedTx);
223
+ if (sendResult.status !== 'PENDING') {
224
+ throw new Error(`Failed to set admin: ${JSON.stringify(sendResult)}`);
225
+ }
226
+ const txResult = await server.pollTransaction(sendResult.hash);
227
+ if (txResult.status !== 'SUCCESS') {
228
+ throw new Error(`Failed to set admin: ${JSON.stringify(txResult)}`);
229
+ }
230
+ console.log('✅ SAC admin set to SAC Manager');
231
+ });
232
+
183
233
  it('Deploy Lock/Unlock OFT on Chain A', async () => {
184
234
  lockUnlockOftClient = await deployContract<OFTClient>(
185
235
  OFTClient,
@@ -212,7 +262,7 @@ describe('OFT Cross-Chain E2E Testing with SAC (SML)', async () => {
212
262
  endpoint: chainB.endpointV2, // Chain B endpoint
213
263
  delegate: DEFAULT_DEPLOYER.publicKey(),
214
264
  shared_decimals: SHARED_DECIMALS,
215
- oft_type: { tag: 'MintBurn', values: [oftTokenAddress] },
265
+ oft_type: { tag: 'MintBurn', values: [sacManagerAddress] },
216
266
  },
217
267
  DEFAULT_DEPLOYER,
218
268
  );
@@ -328,42 +378,28 @@ describe('OFT Cross-Chain E2E Testing with SAC (SML)', async () => {
328
378
  console.log('✅ Mint/Burn OFT (Chain B) peer set to Lock/Unlock OFT for EID_A');
329
379
  });
330
380
 
331
- it('Set SAC Admin to Mint/Burn OFT (for minting)', async () => {
332
- const server = new rpc.Server(RPC_URL, { allowHttp: true });
333
-
334
- const account = await server.getAccount(TOKEN_ISSUER.publicKey());
335
-
336
- const setAdminTx = new TransactionBuilder(account, {
337
- fee: BASE_FEE,
381
+ it('Add Mint/Burn OFT as minter on SAC Manager (for receive/mint)', async () => {
382
+ const sacManagerClient = new SacManagerClient({
383
+ contractId: sacManagerAddress,
384
+ publicKey: DEFAULT_DEPLOYER.publicKey(),
385
+ signTransaction: async (tx: string) => {
386
+ const transaction = TransactionBuilder.fromXDR(tx, NETWORK_PASSPHRASE);
387
+ transaction.sign(DEFAULT_DEPLOYER);
388
+ return {
389
+ signedTxXdr: transaction.toXDR(),
390
+ signerAddress: DEFAULT_DEPLOYER.publicKey(),
391
+ };
392
+ },
393
+ rpcUrl: RPC_URL,
338
394
  networkPassphrase: NETWORK_PASSPHRASE,
339
- })
340
- .addOperation(
341
- Operation.invokeContractFunction({
342
- contract: oftTokenAddress,
343
- function: 'set_admin',
344
- args: [Address.fromString(mintBurnOftAddress).toScVal()],
345
- }),
346
- )
347
- .setTimeout(30)
348
- .build();
349
-
350
- const simulated = await server.simulateTransaction(setAdminTx);
351
- if (rpc.Api.isSimulationError(simulated)) {
352
- throw new Error(`Simulation failed: ${JSON.stringify(simulated)}`);
353
- }
354
- const preparedTx = rpc.assembleTransaction(setAdminTx, simulated).build();
355
- preparedTx.sign(TOKEN_ISSUER);
356
-
357
- const sendResult = await server.sendTransaction(preparedTx);
358
- if (sendResult.status !== 'PENDING') {
359
- throw new Error(`Failed to set admin: ${JSON.stringify(sendResult)}`);
360
- }
361
- const txResult = await server.pollTransaction(sendResult.hash);
362
- if (txResult.status !== 'SUCCESS') {
363
- throw new Error(`Failed to set admin: ${JSON.stringify(txResult)}`);
364
- }
365
-
366
- console.log('✅ SAC admin set to Mint/Burn OFT');
395
+ allowHttp: true,
396
+ });
397
+ const assembledTx = await sacManagerClient.set_minter({
398
+ minter: mintBurnOftAddress,
399
+ active: true,
400
+ });
401
+ await assembledTx.signAndSend();
402
+ console.log('✅ Mint/Burn OFT added as minter on SAC Manager');
367
403
  });
368
404
  });
369
405
 
@@ -26,7 +26,6 @@ import { getTokenAuthorized, getTokenBalance } from './utils';
26
26
  // ============================================================================
27
27
 
28
28
  const TOKEN_ISSUER = Keypair.random();
29
- const REDISTRIBUTION_ADMIN = Keypair.random();
30
29
  const USER_A = Keypair.random();
31
30
  const USER_B = Keypair.random();
32
31
  const USER_C = Keypair.random();
@@ -44,8 +43,7 @@ let sacManagerClient: SacManagerClient;
44
43
 
45
44
  // Initial token amounts
46
45
  const INITIAL_TOKEN_AMOUNT = '1000'; // 1000 tokens
47
- const TRANSFER_AMOUNT = 100_0000000n; // 100 tokens (7 decimals)
48
- const REDISTRIBUTE_AMOUNT = 50_0000000n; // 50 tokens (7 decimals)
46
+ const MINT_AMOUNT = 100_0000000n; // 100 tokens (7 decimals)
49
47
 
50
48
  // ============================================================================
51
49
  // Helper Functions
@@ -72,9 +70,6 @@ function createClientWithSigner(contractId: string, signer: Keypair): SacManager
72
70
  });
73
71
  }
74
72
 
75
- // Note: The old executeRedistributeFundsWithAuth function has been removed
76
- // because we now use the SacManagerClient directly which handles authorization properly
77
-
78
73
  /**
79
74
  * Invokes a SAC contract function using raw transaction building
80
75
  */
@@ -124,7 +119,7 @@ async function invokeSacFunction(
124
119
  // Test Suite
125
120
  // ============================================================================
126
121
 
127
- describe('SAC Manager Redistribution E2E Tests', async () => {
122
+ describe('SAC Manager E2E Tests', async () => {
128
123
  const repoRoot = await getFullyQualifiedRepoRootPath();
129
124
  const wasmDir = path.join(
130
125
  repoRoot,
@@ -140,25 +135,22 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
140
135
 
141
136
  beforeAll(async () => {
142
137
  console.log('\n====================================');
143
- console.log('SAC Manager Redistribution E2E Tests');
138
+ console.log('SAC Manager E2E Tests');
144
139
  console.log('====================================\n');
145
140
 
146
- // Fund test accounts (including DEFAULT_DEPLOYER which is normally funded by globalSetup)
147
141
  console.log('Funding test accounts...');
148
142
  await fundAccount(DEFAULT_DEPLOYER.publicKey());
149
143
  await fundAccount(TOKEN_ISSUER.publicKey());
150
- await fundAccount(REDISTRIBUTION_ADMIN.publicKey());
151
144
  await fundAccount(USER_A.publicKey());
152
145
  await fundAccount(USER_B.publicKey());
153
146
  await fundAccount(USER_C.publicKey());
154
147
  console.log('Test accounts funded');
155
148
 
156
- // Create the token asset
157
149
  TOKEN_ASSET = new Asset(TOKEN_CODE, TOKEN_ISSUER.publicKey());
158
150
  });
159
151
 
160
152
  // ========================================================================
161
- // Setup SAC Manager with SAC (redistribution enabled at construction)
153
+ // Setup SAC Manager with SAC
162
154
  // ========================================================================
163
155
 
164
156
  describe('Setup SAC Manager with SAC', () => {
@@ -166,9 +158,6 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
166
158
  const server = new rpc.Server(RPC_URL, { allowHttp: true });
167
159
  const issuerAccount = await server.getAccount(TOKEN_ISSUER.publicKey());
168
160
 
169
- // Set AUTH_REVOCABLE and AUTH_CLAWBACK_ENABLED flags on issuer
170
- // AUTH_REVOCABLE allows revoking authorization (blacklisting)
171
- // AUTH_CLAWBACK_ENABLED allows clawback operations (required for redistribute_funds)
172
161
  const authFlags = (AuthRevocableFlag | AuthClawbackEnabledFlag) as AuthFlag;
173
162
  const setOptionsTx = new TransactionBuilder(issuerAccount, {
174
163
  fee: BASE_FEE,
@@ -200,48 +189,35 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
200
189
  it('Deploy SAC with trustlines and issue tokens', async () => {
201
190
  const server = new rpc.Server(RPC_URL, { allowHttp: true });
202
191
 
203
- // Create trustlines for all test accounts and issue tokens
204
192
  const issuerAccount = await server.getAccount(TOKEN_ISSUER.publicKey());
205
193
  const issueTx = new TransactionBuilder(issuerAccount, {
206
194
  fee: BASE_FEE,
207
195
  networkPassphrase: NETWORK_PASSPHRASE,
208
196
  })
209
- // Trustline for DEFAULT_DEPLOYER (will be the SAC manager admin)
210
197
  .addOperation(
211
198
  Operation.changeTrust({
212
199
  asset: TOKEN_ASSET,
213
200
  source: DEFAULT_DEPLOYER.publicKey(),
214
201
  }),
215
202
  )
216
- // Trustline for REDISTRIBUTION_ADMIN
217
- .addOperation(
218
- Operation.changeTrust({
219
- asset: TOKEN_ASSET,
220
- source: REDISTRIBUTION_ADMIN.publicKey(),
221
- }),
222
- )
223
- // Trustline for USER_A
224
203
  .addOperation(
225
204
  Operation.changeTrust({
226
205
  asset: TOKEN_ASSET,
227
206
  source: USER_A.publicKey(),
228
207
  }),
229
208
  )
230
- // Trustline for USER_B
231
209
  .addOperation(
232
210
  Operation.changeTrust({
233
211
  asset: TOKEN_ASSET,
234
212
  source: USER_B.publicKey(),
235
213
  }),
236
214
  )
237
- // Trustline for USER_C
238
215
  .addOperation(
239
216
  Operation.changeTrust({
240
217
  asset: TOKEN_ASSET,
241
218
  source: USER_C.publicKey(),
242
219
  }),
243
220
  )
244
- // Issue tokens to USER_A (sender)
245
221
  .addOperation(
246
222
  Operation.payment({
247
223
  asset: TOKEN_ASSET,
@@ -249,7 +225,6 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
249
225
  destination: USER_A.publicKey(),
250
226
  }),
251
227
  )
252
- // Issue tokens to USER_B (will be blacklisted)
253
228
  .addOperation(
254
229
  Operation.payment({
255
230
  asset: TOKEN_ASSET,
@@ -260,14 +235,7 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
260
235
  .setTimeout(30)
261
236
  .build();
262
237
 
263
- issueTx.sign(
264
- TOKEN_ISSUER,
265
- DEFAULT_DEPLOYER,
266
- REDISTRIBUTION_ADMIN,
267
- USER_A,
268
- USER_B,
269
- USER_C,
270
- );
238
+ issueTx.sign(TOKEN_ISSUER, DEFAULT_DEPLOYER, USER_A, USER_B, USER_C);
271
239
 
272
240
  const sendResult = await server.sendTransaction(issueTx);
273
241
  if (sendResult.status !== 'PENDING') {
@@ -281,20 +249,17 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
281
249
 
282
250
  console.log('Trustlines created and tokens issued');
283
251
 
284
- // Deploy the SAC for the token
285
252
  sacTokenAddress = await deployAssetSac(TOKEN_ASSET);
286
253
  console.log('SAC deployed at:', sacTokenAddress);
287
254
  });
288
255
 
289
- it('Deploy SAC Manager contract with redistribution enabled', async () => {
256
+ it('Deploy SAC Manager contract', async () => {
290
257
  sacManagerClient = await deployContract<SacManagerClient>(
291
258
  SacManagerClient,
292
259
  SAC_MANAGER_WASM_PATH,
293
260
  {
294
261
  sac_token: sacTokenAddress,
295
262
  owner: DEFAULT_DEPLOYER.publicKey(),
296
- redistribution_enabled: true,
297
- supply_control_enabled: false,
298
263
  },
299
264
  DEFAULT_DEPLOYER,
300
265
  );
@@ -304,22 +269,25 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
304
269
  });
305
270
 
306
271
  it('Set SAC admin to SAC Manager', async () => {
307
- // Set the SAC admin to the SAC manager contract
308
- // This allows the SAC manager to call clawback, set_authorized, mint, etc.
309
272
  await invokeSacFunction(
310
273
  sacTokenAddress,
311
274
  'set_admin',
312
275
  [Address.fromString(sacManagerAddress).toScVal()],
313
276
  TOKEN_ISSUER,
314
277
  );
315
-
316
278
  console.log('SAC admin set to SAC Manager');
317
279
  });
318
280
 
319
- it('Verify redistribution is enabled at construction', async () => {
320
- const { result: enabled } = await sacManagerClient.redistribution_enabled();
321
- expect(enabled).toBe(true);
322
- console.log('Redistribution enabled:', enabled);
281
+ it('Add DEFAULT_DEPLOYER as minter', async () => {
282
+ const assembledTx = await sacManagerClient.set_minter({
283
+ minter: DEFAULT_DEPLOYER.publicKey(),
284
+ active: true,
285
+ });
286
+ await assembledTx.signAndSend();
287
+ const { result: minters } = await sacManagerClient.minters();
288
+ expect(minters).toBeDefined();
289
+ expect(minters?.length).toBeGreaterThanOrEqual(1);
290
+ console.log('DEFAULT_DEPLOYER added as minter');
323
291
  });
324
292
 
325
293
  it('Verify owner (DEFAULT_DEPLOYER) starts with zero balance', async () => {
@@ -337,8 +305,7 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
337
305
  // ========================================================================
338
306
 
339
307
  describe('Blacklist Management', () => {
340
- it('Verify all accounts start authorized (AUTH_REQUIRED=false)', async () => {
341
- // Check authorization status directly on the SAC
308
+ it('Verify all accounts start authorized', async () => {
342
309
  const userAAuthorized = await getTokenAuthorized(USER_A.publicKey(), sacTokenAddress);
343
310
  const userBAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
344
311
  const userCAuthorized = await getTokenAuthorized(USER_C.publicKey(), sacTokenAddress);
@@ -346,22 +313,19 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
346
313
  expect(userAAuthorized).toBe(true);
347
314
  expect(userBAuthorized).toBe(true);
348
315
  expect(userCAuthorized).toBe(true);
349
-
350
316
  console.log('All users start authorized');
351
317
  });
352
318
 
353
319
  it('Blacklist USER_B via set_authorized', async () => {
354
- // Use DEFAULT_DEPLOYER (owner) to blacklist USER_B
355
320
  const assembledTx = await sacManagerClient.set_authorized({
356
321
  id: USER_B.publicKey(),
357
322
  authorize: false,
358
323
  });
359
-
360
324
  await assembledTx.signAndSend();
361
325
  console.log('USER_B blacklisted (authorized=false)');
362
326
  });
363
327
 
364
- it('Verify USER_B is blacklisted (not authorized on SAC)', async () => {
328
+ it('Verify USER_B is blacklisted', async () => {
365
329
  const authorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
366
330
  expect(authorized).toBe(false);
367
331
  console.log('USER_B authorized:', authorized);
@@ -369,54 +333,31 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
369
333
 
370
334
  it('Non-admin cannot call set_authorized', async () => {
371
335
  const userClient = createClientWithSigner(sacManagerAddress, USER_A);
372
-
373
336
  const assembledTx = await userClient.set_authorized({
374
337
  id: USER_C.publicKey(),
375
338
  authorize: false,
376
339
  });
377
-
378
340
  await expect(assembledTx.signAndSend()).rejects.toThrow();
379
341
  console.log('Non-admin correctly rejected from calling set_authorized');
380
342
  });
381
343
 
382
344
  it('Un-blacklist USER_B via set_authorized', async () => {
383
- // Re-authorize USER_B
384
345
  const assembledTx = await sacManagerClient.set_authorized({
385
346
  id: USER_B.publicKey(),
386
347
  authorize: true,
387
348
  });
388
-
389
349
  await assembledTx.signAndSend();
390
-
391
- // Verify
392
350
  const authorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
393
351
  expect(authorized).toBe(true);
394
-
395
- const isAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
396
- expect(isAuthorized).toBe(true);
397
-
398
352
  console.log('USER_B un-blacklisted');
399
353
  });
400
-
401
- it('Re-blacklist USER_B for mint redirection tests', async () => {
402
- const assembledTx = await sacManagerClient.set_authorized({
403
- id: USER_B.publicKey(),
404
- authorize: false,
405
- });
406
-
407
- await assembledTx.signAndSend();
408
-
409
- const isAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
410
- expect(isAuthorized).toBe(false);
411
- console.log('USER_B re-blacklisted for transfer tests');
412
- });
413
354
  });
414
355
 
415
356
  // ========================================================================
416
- // Mint Redirection (redistribution enabled)
357
+ // Mint (Mintable interface – minter must be in minters list)
417
358
  // ========================================================================
418
359
 
419
- describe('Mint Redirection', () => {
360
+ describe('Mint', () => {
420
361
  it('Verify initial balances', async () => {
421
362
  const userABalance = await getTokenBalance(USER_A.publicKey(), sacTokenAddress);
422
363
  const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
@@ -430,122 +371,38 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
430
371
  console.log(` USER_A: ${userABalance}`);
431
372
  console.log(` USER_B: ${userBBalance}`);
432
373
  console.log(` USER_C: ${userCBalance}`);
433
- console.log(` Owner (DEFAULT_DEPLOYER): ${ownerBalance}`);
374
+ console.log(` Owner: ${ownerBalance}`);
434
375
 
435
- expect(userABalance).toBe(10000000000n); // 1000 tokens
436
- expect(userBBalance).toBe(10000000000n); // 1000 tokens
376
+ expect(userABalance).toBe(10000000000n);
377
+ expect(userBBalance).toBe(10000000000n);
437
378
  expect(userCBalance).toBe(0n);
438
379
  expect(ownerBalance).toBe(0n);
439
380
  });
440
381
 
441
- it('Admin mint to non-blacklisted address succeeds normally', async () => {
382
+ it('Minter can mint to non-blacklisted address', async () => {
442
383
  const userCBalanceBefore = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
443
384
 
444
- const assembledTx = await sacManagerClient.authorized_mint({
445
- sender: DEFAULT_DEPLOYER.publicKey(),
385
+ const assembledTx = await sacManagerClient.mint({
446
386
  to: USER_C.publicKey(),
447
- amount: TRANSFER_AMOUNT,
387
+ amount: MINT_AMOUNT,
388
+ operation: DEFAULT_DEPLOYER.publicKey(),
448
389
  });
449
390
  await assembledTx.signAndSend();
450
391
 
451
- // Verify balance increased
452
392
  const userCBalance = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
453
-
454
- console.log('\nAfter authorized_mint to non-blacklisted (USER_C):');
455
- console.log(` USER_C: ${userCBalance}`);
456
-
457
- expect(userCBalance).toBe(userCBalanceBefore + TRANSFER_AMOUNT);
458
- });
459
-
460
- it('Admin mint to blacklisted address redirects to redistribution target (owner)', async () => {
461
- const ownerBalanceBefore = await getTokenBalance(
462
- DEFAULT_DEPLOYER.publicKey(),
463
- sacTokenAddress,
464
- );
465
- const userBBalanceBefore = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
466
-
467
- const assembledTx = await sacManagerClient.authorized_mint({
468
- sender: DEFAULT_DEPLOYER.publicKey(),
469
- to: USER_B.publicKey(), // Blacklisted!
470
- amount: TRANSFER_AMOUNT,
471
- });
472
- await assembledTx.signAndSend();
473
-
474
- // Verify balances - USER_B should not receive, owner should
475
- const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
476
- const ownerBalance = await getTokenBalance(
477
- DEFAULT_DEPLOYER.publicKey(),
478
- sacTokenAddress,
479
- );
480
-
481
- console.log('\nAfter authorized_mint to blacklisted (USER_B):');
482
- console.log(` USER_B: ${userBBalance} (unchanged)`);
483
- console.log(` Owner (received redirected): ${ownerBalance}`);
484
-
485
- // USER_B balance should be unchanged
486
- expect(userBBalance).toBe(userBBalanceBefore);
487
- // Owner should receive the redirected tokens
488
- expect(ownerBalance).toBe(ownerBalanceBefore + TRANSFER_AMOUNT);
489
- });
490
- });
491
-
492
- // ========================================================================
493
- // Redistribute Funds
494
- // ========================================================================
495
-
496
- describe('Redistribute Funds', () => {
497
- it('Redistribute funds from blacklisted account', async () => {
498
- const ownerBalanceBefore = await getTokenBalance(
499
- DEFAULT_DEPLOYER.publicKey(),
500
- sacTokenAddress,
501
- );
502
- const userBBalanceBefore = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
503
-
504
- console.log('\nBefore redistribute_blacklisted_funds:');
505
- console.log(` USER_B: ${userBBalanceBefore}`);
506
- console.log(` Owner: ${ownerBalanceBefore}`);
507
-
508
- // Only owner can redistribute - use DEFAULT_DEPLOYER
509
- const assembledTx = await sacManagerClient.redistribute_blacklisted_funds({
510
- from: USER_B.publicKey(),
511
- amount: REDISTRIBUTE_AMOUNT,
512
- });
513
- await assembledTx.signAndSend();
514
-
515
- // Verify balances
516
- const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
517
- const ownerBalance = await getTokenBalance(
518
- DEFAULT_DEPLOYER.publicKey(),
519
- sacTokenAddress,
520
- );
521
-
522
- console.log('\nAfter redistribute_blacklisted_funds:');
523
- console.log(` USER_B: ${userBBalance}`);
524
- console.log(` Owner: ${ownerBalance}`);
525
-
526
- expect(userBBalance).toBe(userBBalanceBefore - REDISTRIBUTE_AMOUNT);
527
- expect(ownerBalance).toBe(ownerBalanceBefore + REDISTRIBUTE_AMOUNT);
528
- });
529
-
530
- it('Cannot redistribute from non-blacklisted account', async () => {
531
- // USER_A is not blacklisted - this should fail even for owner
532
- const assembledTx = await sacManagerClient.redistribute_blacklisted_funds({
533
- from: USER_A.publicKey(),
534
- amount: REDISTRIBUTE_AMOUNT,
535
- });
536
- await expect(assembledTx.signAndSend()).rejects.toThrow();
537
- console.log('Correctly rejected redistribution from non-blacklisted account');
393
+ console.log('\nAfter mint to USER_C:', userCBalance);
394
+ expect(userCBalance).toBe(userCBalanceBefore + MINT_AMOUNT);
538
395
  });
539
396
 
540
- it('Non-owner cannot redistribute', async () => {
541
- // USER_A is not the owner - this should fail
397
+ it('Non-minter cannot mint', async () => {
542
398
  const userClient = createClientWithSigner(sacManagerAddress, USER_A);
543
- const assembledTx = await userClient.redistribute_blacklisted_funds({
544
- from: USER_B.publicKey(),
545
- amount: REDISTRIBUTE_AMOUNT,
399
+ const assembledTx = await userClient.mint({
400
+ to: USER_C.publicKey(),
401
+ amount: MINT_AMOUNT,
402
+ operation: USER_A.publicKey(),
546
403
  });
547
404
  await expect(assembledTx.signAndSend()).rejects.toThrow();
548
- console.log('Non-owner correctly rejected from redistributing');
405
+ console.log('Non-minter correctly rejected');
549
406
  });
550
407
  });
551
408
 
@@ -567,12 +424,11 @@ describe('SAC Manager Redistribution E2E Tests', async () => {
567
424
  console.log('Final Balance Summary');
568
425
  console.log('========================================');
569
426
  console.log(` USER_A: ${userABalance}`);
570
- console.log(` USER_B (blacklisted): ${userBBalance}`);
427
+ console.log(` USER_B: ${userBBalance}`);
571
428
  console.log(` USER_C: ${userCBalance}`);
572
- console.log(` Owner (redistribution target): ${ownerBalance}`);
429
+ console.log(` Owner: ${ownerBalance}`);
573
430
  console.log('========================================\n');
574
-
575
- console.log('SAC Manager Redistribution E2E tests completed successfully!');
431
+ console.log('SAC Manager E2E tests completed successfully!');
576
432
  });
577
433
  });
578
434
  });