nulltrace-sdk 1.0.4 → 1.0.5

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 (3) hide show
  1. package/dist/index.cjs +146 -115
  2. package/dist/index.mjs +27 -19
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -33,16 +33,43 @@ __export(src_exports, {
33
33
  default: () => src_default
34
34
  });
35
35
  module.exports = __toCommonJS(src_exports);
36
- var import_web3 = require("@solana/web3.js");
37
- var import_spl_token = require("@solana/spl-token");
38
- var import_stateless = require("@lightprotocol/stateless.js");
39
- var import_compressed_token = require("@lightprotocol/compressed-token");
36
+ var web3 = __toESM(require("@solana/web3.js"), 1);
37
+ var splToken = __toESM(require("@solana/spl-token"), 1);
38
+ var stateless = __toESM(require("@lightprotocol/stateless.js"), 1);
39
+ var compressedToken = __toESM(require("@lightprotocol/compressed-token"), 1);
40
40
  var import_bs58 = __toESM(require("bs58"), 1);
41
41
  var import_crypto = require("crypto");
42
42
  var import_tweetnacl = __toESM(require("tweetnacl"), 1);
43
+ var {
44
+ VersionedTransaction,
45
+ PublicKey,
46
+ TransactionMessage,
47
+ ComputeBudgetProgram,
48
+ Keypair
49
+ } = web3;
50
+ var {
51
+ TOKEN_PROGRAM_ID,
52
+ TOKEN_2022_PROGRAM_ID,
53
+ getAssociatedTokenAddress,
54
+ createAssociatedTokenAccountInstruction,
55
+ createTransferCheckedInstruction,
56
+ NATIVE_MINT
57
+ } = splToken;
58
+ var {
59
+ createRpc,
60
+ bn,
61
+ LightSystemProgram,
62
+ COMPRESSED_TOKEN_PROGRAM_ID,
63
+ selectStateTreeInfo
64
+ } = stateless;
65
+ var {
66
+ getTokenPoolInfos,
67
+ selectTokenPoolInfosForDecompression,
68
+ CompressedTokenProgram
69
+ } = compressedToken;
43
70
  var OPERATOR_KEY = "5STUuhrL8kJ4up9spEY39VJ6ibQCFrg8x8cRV5UeEcfv";
44
- var OPERATOR_PUBLIC_KEY = new import_web3.PublicKey(OPERATOR_KEY);
45
- var ALT_ADDRESS = new import_web3.PublicKey("9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ");
71
+ var OPERATOR_PUBLIC_KEY = new PublicKey(OPERATOR_KEY);
72
+ var ALT_ADDRESS = new PublicKey("9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ");
46
73
  var REMOTE_OPERATOR_URL = "http://34.68.76.183:3333";
47
74
  var SHARED_SECRET = "NULL_TRACE_OPERATOR_SECRET_BASE_V1";
48
75
  var FEE_BPS = 1e-3;
@@ -78,19 +105,19 @@ function _sleep(ms) {
78
105
  return new Promise((r) => setTimeout(r, ms));
79
106
  }
80
107
  async function _getMintInfo(connection, mintAddress) {
81
- if (mintAddress === import_spl_token.NATIVE_MINT.toBase58()) {
82
- return { decimals: 9, tokenProgram: import_spl_token.TOKEN_PROGRAM_ID };
108
+ if (mintAddress === NATIVE_MINT.toBase58()) {
109
+ return { decimals: 9, tokenProgram: TOKEN_PROGRAM_ID };
83
110
  }
84
- const mintInfo = await connection.getParsedAccountInfo(new import_web3.PublicKey(mintAddress));
111
+ const mintInfo = await connection.getParsedAccountInfo(new PublicKey(mintAddress));
85
112
  if (!mintInfo.value)
86
113
  throw new Error(`Mint not found: ${mintAddress}`);
87
114
  return {
88
115
  decimals: mintInfo.value.data.parsed.info.decimals,
89
- tokenProgram: new import_web3.PublicKey(mintInfo.value.owner)
116
+ tokenProgram: new PublicKey(mintInfo.value.owner)
90
117
  };
91
118
  }
92
119
  async function _getCompressedAccounts(connection, owner, mint, isSOL) {
93
- const accounts = isSOL ? await connection.getCompressedAccountsByOwner(owner) : await connection.getCompressedTokenAccountsByOwner(owner, { mint: new import_web3.PublicKey(mint) });
120
+ const accounts = isSOL ? await connection.getCompressedAccountsByOwner(owner) : await connection.getCompressedTokenAccountsByOwner(owner, { mint: new PublicKey(mint) });
94
121
  return accounts.items.sort((a, b) => {
95
122
  const aAmt = isSOL ? a.lamports : a.parsed.amount;
96
123
  const bAmt = isSOL ? b.lamports : b.parsed.amount;
@@ -122,15 +149,15 @@ function _batchAccounts(accounts) {
122
149
  async function _packTransactions(connection, payer, instructions, adl) {
123
150
  const { blockhash } = await connection.getLatestBlockhash();
124
151
  const computeIxs = [
125
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
126
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
152
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
153
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
127
154
  ];
128
155
  let current = [...computeIxs];
129
156
  const messages = [];
130
157
  for (const ix of instructions) {
131
158
  try {
132
159
  current.push(ix);
133
- const msg = new import_web3.TransactionMessage({
160
+ const msg = new TransactionMessage({
134
161
  payerKey: payer,
135
162
  recentBlockhash: blockhash,
136
163
  instructions: current
@@ -141,7 +168,7 @@ async function _packTransactions(connection, payer, instructions, adl) {
141
168
  current.pop();
142
169
  if (current.length > computeIxs.length) {
143
170
  messages.push(
144
- new import_web3.TransactionMessage({
171
+ new TransactionMessage({
145
172
  payerKey: payer,
146
173
  recentBlockhash: blockhash,
147
174
  instructions: current
@@ -153,14 +180,14 @@ async function _packTransactions(connection, payer, instructions, adl) {
153
180
  }
154
181
  if (current.length > computeIxs.length) {
155
182
  messages.push(
156
- new import_web3.TransactionMessage({
183
+ new TransactionMessage({
157
184
  payerKey: payer,
158
185
  recentBlockhash: blockhash,
159
186
  instructions: current
160
187
  }).compileToV0Message([adl])
161
188
  );
162
189
  }
163
- return messages.map((m) => new import_web3.VersionedTransaction(m));
190
+ return messages.map((m) => new VersionedTransaction(m));
164
191
  }
165
192
  async function _signSendConfirm(connection, wallet, transactions) {
166
193
  const signed = await wallet.signAllTransactions(transactions);
@@ -281,7 +308,7 @@ var NullTrace = class _NullTrace {
281
308
  throw new Error("NullTrace: a wallet, Keypair, secret key, or private key string is required");
282
309
  this.rpcUrl = rpcUrl;
283
310
  this.wallet = _NullTrace._resolveWallet(walletOrKey);
284
- this.connection = (0, import_stateless.createRpc)(rpcUrl, rpcUrl, rpcUrl, { commitment: "processed" });
311
+ this.connection = createRpc(rpcUrl, rpcUrl, rpcUrl, { commitment: "processed" });
285
312
  this._adlCache = null;
286
313
  this._sigCache = null;
287
314
  }
@@ -298,14 +325,17 @@ var NullTrace = class _NullTrace {
298
325
  if (!keypair?.publicKey || !keypair?.secretKey) {
299
326
  throw new Error("NullTrace.fromKeypair: invalid Keypair");
300
327
  }
328
+ const secretKeyBytes = new Uint8Array(keypair.secretKey);
329
+ const internalKeypair = Keypair.fromSecretKey(secretKeyBytes);
330
+ const pubkey = internalKeypair.publicKey;
301
331
  return {
302
- publicKey: keypair.publicKey,
332
+ publicKey: pubkey,
303
333
  signAllTransactions: async (txs) => {
304
334
  for (const tx of txs)
305
- tx.sign([keypair]);
335
+ tx.sign([internalKeypair]);
306
336
  return txs;
307
337
  },
308
- signMessage: async (msg) => import_tweetnacl.default.sign.detached(msg, keypair.secretKey)
338
+ signMessage: async (msg) => import_tweetnacl.default.sign.detached(msg, secretKeyBytes)
309
339
  };
310
340
  }
311
341
  /**
@@ -315,10 +345,10 @@ var NullTrace = class _NullTrace {
315
345
  * @returns {{ publicKey: PublicKey, signAllTransactions: Function, signMessage: Function }}
316
346
  */
317
347
  static fromSecretKey(secretKey) {
318
- if (!(secretKey instanceof Uint8Array) || secretKey.length !== 64) {
348
+ if (!secretKey || typeof secretKey.length !== "number" || secretKey.length !== 64) {
319
349
  throw new Error("NullTrace.fromSecretKey: expected a 64-byte Uint8Array");
320
350
  }
321
- return _NullTrace.fromKeypair(import_web3.Keypair.fromSecretKey(secretKey));
351
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(new Uint8Array(secretKey)));
322
352
  }
323
353
  /**
324
354
  * Create a wallet adapter interface from a base58-encoded private key string.
@@ -331,19 +361,20 @@ var NullTrace = class _NullTrace {
331
361
  throw new Error("NullTrace.fromPrivateKey: expected a base58-encoded private key string");
332
362
  }
333
363
  const decoded = import_bs58.default.decode(base58Key);
334
- return _NullTrace.fromKeypair(import_web3.Keypair.fromSecretKey(decoded));
364
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(decoded));
335
365
  }
336
366
  /**
337
367
  * @internal Resolve any supported wallet input into a wallet adapter interface.
368
+ * Uses duck-typing instead of instanceof to avoid cross-realm module boundary issues.
338
369
  */
339
370
  static _resolveWallet(input) {
340
371
  if (input?.publicKey && typeof input.signAllTransactions === "function") {
341
372
  return input;
342
373
  }
343
- if (input instanceof import_web3.Keypair) {
374
+ if (input?.publicKey?.toBytes && input?.secretKey?.length === 64) {
344
375
  return _NullTrace.fromKeypair(input);
345
376
  }
346
- if (input instanceof Uint8Array && input.length === 64) {
377
+ if (typeof input !== "string" && input?.length === 64 && typeof input[0] === "number") {
347
378
  return _NullTrace.fromSecretKey(input);
348
379
  }
349
380
  if (typeof input === "string") {
@@ -378,22 +409,22 @@ var NullTrace = class _NullTrace {
378
409
  if (!mint || !amount)
379
410
  throw new Error("NullTrace.nullify: mint and amount are required");
380
411
  const owner = this.wallet.publicKey;
381
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
412
+ const isSOL = mint === NATIVE_MINT.toBase58();
382
413
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
383
- const amountLamports = (0, import_stateless.bn)(Math.floor(parseFloat(amount) * 10 ** decimals).toString());
384
- const feeLamports = (0, import_stateless.bn)(Math.floor(parseInt(amountLamports.toString()) * FEE_BPS).toString());
414
+ const amountLamports = bn(Math.floor(parseFloat(amount) * 10 ** decimals).toString());
415
+ const feeLamports = bn(Math.floor(parseInt(amountLamports.toString()) * FEE_BPS).toString());
385
416
  const ixs = [];
386
417
  const activeStateTrees = await this.connection.getStateTreeInfos();
387
- const tree = (0, import_stateless.selectStateTreeInfo)(activeStateTrees);
418
+ const tree = selectStateTreeInfo(activeStateTrees);
388
419
  if (isSOL) {
389
420
  ixs.push(
390
- await import_stateless.LightSystemProgram.compress({
421
+ await LightSystemProgram.compress({
391
422
  payer: owner,
392
423
  toAddress: owner,
393
424
  lamports: amountLamports.sub(feeLamports),
394
425
  outputStateTreeInfo: tree
395
426
  }),
396
- await import_stateless.LightSystemProgram.compress({
427
+ await LightSystemProgram.compress({
397
428
  payer: owner,
398
429
  toAddress: OPERATOR_PUBLIC_KEY,
399
430
  lamports: feeLamports,
@@ -401,16 +432,16 @@ var NullTrace = class _NullTrace {
401
432
  })
402
433
  );
403
434
  } else {
404
- const mintPk = new import_web3.PublicKey(mint);
405
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(mintPk, owner, false, tokenProgram);
406
- const [tokenPoolPda] = import_web3.PublicKey.findProgramAddressSync(
435
+ const mintPk = new PublicKey(mint);
436
+ const sourceAta = await getAssociatedTokenAddress(mintPk, owner, false, tokenProgram);
437
+ const [tokenPoolPda] = PublicKey.findProgramAddressSync(
407
438
  [Buffer.from("pool"), mintPk.toBuffer()],
408
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
439
+ COMPRESSED_TOKEN_PROGRAM_ID
409
440
  );
410
441
  const poolInfo = await this.connection.getAccountInfo(tokenPoolPda);
411
442
  if (!poolInfo) {
412
443
  ixs.push(
413
- await import_compressed_token.CompressedTokenProgram.createTokenPool({
444
+ await CompressedTokenProgram.createTokenPool({
414
445
  feePayer: owner,
415
446
  mint: mintPk,
416
447
  tokenProgramId: tokenProgram
@@ -418,7 +449,7 @@ var NullTrace = class _NullTrace {
418
449
  );
419
450
  }
420
451
  ixs.push(
421
- await import_compressed_token.CompressedTokenProgram.compress({
452
+ await CompressedTokenProgram.compress({
422
453
  payer: owner,
423
454
  owner,
424
455
  source: sourceAta,
@@ -430,7 +461,7 @@ var NullTrace = class _NullTrace {
430
461
  tokenPoolPda,
431
462
  tokenProgram,
432
463
  isInitialized: true,
433
- balance: (0, import_stateless.bn)("0"),
464
+ balance: bn("0"),
434
465
  poolIndex: 0,
435
466
  mint: mintPk
436
467
  }
@@ -458,7 +489,7 @@ var NullTrace = class _NullTrace {
458
489
  if (!mint || !amount)
459
490
  throw new Error("NullTrace.reveal: mint and amount are required");
460
491
  const owner = this.wallet.publicKey;
461
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
492
+ const isSOL = mint === NATIVE_MINT.toBase58();
462
493
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
463
494
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
464
495
  const sorted = await _getCompressedAccounts(this.connection, owner, mint, isSOL);
@@ -470,12 +501,12 @@ var NullTrace = class _NullTrace {
470
501
  let selectedTokenPoolInfos;
471
502
  let destinationAta;
472
503
  if (!isSOL) {
473
- const tokenPoolInfos = await (0, import_compressed_token.getTokenPoolInfos)(this.connection, new import_web3.PublicKey(mint));
474
- selectedTokenPoolInfos = (0, import_compressed_token.selectTokenPoolInfosForDecompression)(tokenPoolInfos, amountLamports);
475
- destinationAta = await (0, import_spl_token.getAssociatedTokenAddress)(new import_web3.PublicKey(mint), owner, false, tokenProgram);
504
+ const tokenPoolInfos = await getTokenPoolInfos(this.connection, new PublicKey(mint));
505
+ selectedTokenPoolInfos = selectTokenPoolInfosForDecompression(tokenPoolInfos, amountLamports);
506
+ destinationAta = await getAssociatedTokenAddress(new PublicKey(mint), owner, false, tokenProgram);
476
507
  const info = await this.connection.getAccountInfo(destinationAta);
477
508
  if (!info) {
478
- ixs.push((0, import_spl_token.createAssociatedTokenAccountInstruction)(owner, destinationAta, owner, new import_web3.PublicKey(mint), tokenProgram));
509
+ ixs.push(createAssociatedTokenAccountInstruction(owner, destinationAta, owner, new PublicKey(mint), tokenProgram));
479
510
  }
480
511
  }
481
512
  let remaining = amountLamports;
@@ -489,18 +520,18 @@ var NullTrace = class _NullTrace {
489
520
  );
490
521
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
491
522
  ixs.push(
492
- await (isSOL ? import_stateless.LightSystemProgram.decompress({
523
+ await (isSOL ? LightSystemProgram.decompress({
493
524
  payer: owner,
494
525
  inputCompressedAccounts: batch,
495
526
  toAddress: owner,
496
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
527
+ lamports: bn(batchAmount.toString()),
497
528
  recentInputStateRootIndices: proof.rootIndices,
498
529
  recentValidityProof: proof.compressedProof
499
- }) : import_compressed_token.CompressedTokenProgram.decompress({
530
+ }) : CompressedTokenProgram.decompress({
500
531
  payer: owner,
501
532
  inputCompressedTokenAccounts: batch,
502
533
  toAddress: destinationAta,
503
- amount: (0, import_stateless.bn)(batchAmount.toString()),
534
+ amount: bn(batchAmount.toString()),
504
535
  recentInputStateRootIndices: proof.rootIndices,
505
536
  recentValidityProof: proof.compressedProof,
506
537
  tokenPoolInfos: selectedTokenPoolInfos
@@ -531,8 +562,8 @@ var NullTrace = class _NullTrace {
531
562
  throw new Error("NullTrace.transfer: mint, amount, and recipient are required");
532
563
  }
533
564
  const owner = this.wallet.publicKey;
534
- const recipientPk = new import_web3.PublicKey(recipient);
535
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
565
+ const recipientPk = new PublicKey(recipient);
566
+ const isSOL = mint === NATIVE_MINT.toBase58();
536
567
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
537
568
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
538
569
  const sorted = await _getCompressedAccounts(this.connection, owner, mint, isSOL);
@@ -542,87 +573,87 @@ var NullTrace = class _NullTrace {
542
573
  const preTransactions = [];
543
574
  if (total < amountLamports) {
544
575
  const deficit = amountLamports - total;
545
- const fee = (0, import_stateless.bn)(Math.floor(deficit * FEE_BPS).toString());
576
+ const fee = bn(Math.floor(deficit * FEE_BPS).toString());
546
577
  const trees = await this.connection.getStateTreeInfos();
547
- const tree = (0, import_stateless.selectStateTreeInfo)(trees);
578
+ const tree = selectStateTreeInfo(trees);
548
579
  if (isSOL) {
549
580
  const solBal = await this.connection.getBalance(owner);
550
581
  if (solBal < deficit + 1e5)
551
582
  throw new Error("Insufficient balance");
552
- const compressIx = await import_stateless.LightSystemProgram.compress({
583
+ const compressIx = await LightSystemProgram.compress({
553
584
  payer: owner,
554
585
  toAddress: recipientPk,
555
- lamports: (0, import_stateless.bn)(deficit.toString()).sub(fee),
586
+ lamports: bn(deficit.toString()).sub(fee),
556
587
  outputStateTreeInfo: tree
557
588
  });
558
- const feeIx = await import_stateless.LightSystemProgram.compress({
589
+ const feeIx = await LightSystemProgram.compress({
559
590
  payer: owner,
560
591
  toAddress: OPERATOR_PUBLIC_KEY,
561
592
  lamports: fee,
562
593
  outputStateTreeInfo: tree
563
594
  });
564
- const msg = new import_web3.TransactionMessage({
595
+ const msg = new TransactionMessage({
565
596
  payerKey: owner,
566
597
  recentBlockhash: blockhash,
567
598
  instructions: [
568
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
569
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
599
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
600
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
570
601
  compressIx,
571
602
  feeIx
572
603
  ]
573
604
  }).compileToV0Message([adl]);
574
- preTransactions.push(new import_web3.VersionedTransaction(msg));
605
+ preTransactions.push(new VersionedTransaction(msg));
575
606
  } else {
576
607
  let instructions = [
577
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
578
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
608
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
609
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
579
610
  ];
580
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(
581
- new import_web3.PublicKey(mint),
611
+ const sourceAta = await getAssociatedTokenAddress(
612
+ new PublicKey(mint),
582
613
  owner,
583
614
  false,
584
615
  tokenProgram
585
616
  );
586
617
  const tokenAccountInfos = await this.connection.getParsedTokenAccountsByOwner(
587
618
  owner,
588
- { programId: tokenProgram, mint: new import_web3.PublicKey(mint) },
619
+ { programId: tokenProgram, mint: new PublicKey(mint) },
589
620
  "processed"
590
621
  );
591
622
  const publicBalance = tokenAccountInfos.value?.[0].account.data.parsed.info.tokenAmount.amount ?? 0;
592
623
  if (publicBalance < deficit)
593
624
  throw new Error("Insufficient balance");
594
- const [tokenPoolPda] = import_web3.PublicKey.findProgramAddressSync(
595
- [Buffer.from("pool"), new import_web3.PublicKey(mint).toBuffer()],
596
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
625
+ const [tokenPoolPda] = PublicKey.findProgramAddressSync(
626
+ [Buffer.from("pool"), new PublicKey(mint).toBuffer()],
627
+ COMPRESSED_TOKEN_PROGRAM_ID
597
628
  );
598
629
  const tokenPoolInfo = await this.connection.getAccountInfo(tokenPoolPda, "processed");
599
630
  if (!tokenPoolInfo) {
600
- const createTokenPoolIx = await import_compressed_token.CompressedTokenProgram.createTokenPool({
631
+ const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({
601
632
  feePayer: owner,
602
- mint: new import_web3.PublicKey(mint),
633
+ mint: new PublicKey(mint),
603
634
  tokenProgramId: tokenProgram
604
635
  });
605
636
  instructions.push(createTokenPoolIx);
606
637
  }
607
- const compressInstruction = await import_compressed_token.CompressedTokenProgram.compress({
638
+ const compressInstruction = await CompressedTokenProgram.compress({
608
639
  payer: owner,
609
640
  owner,
610
641
  source: sourceAta,
611
642
  toAddress: [recipientPk, OPERATOR_PUBLIC_KEY],
612
- amount: [(0, import_stateless.bn)(deficit.toString()).sub(fee), fee],
613
- mint: new import_web3.PublicKey(mint),
643
+ amount: [bn(deficit.toString()).sub(fee), fee],
644
+ mint: new PublicKey(mint),
614
645
  outputStateTreeInfo: tree,
615
646
  tokenPoolInfo: {
616
647
  tokenPoolPda,
617
648
  tokenProgram,
618
649
  isInitialized: true,
619
- balance: (0, import_stateless.bn)("0"),
650
+ balance: bn("0"),
620
651
  poolIndex: 0,
621
- mint: new import_web3.PublicKey(mint)
652
+ mint: new PublicKey(mint)
622
653
  }
623
654
  });
624
655
  instructions.push(compressInstruction);
625
- let tx = new import_web3.VersionedTransaction(new import_web3.TransactionMessage({
656
+ let tx = new VersionedTransaction(new TransactionMessage({
626
657
  payerKey: owner,
627
658
  recentBlockhash: blockhash,
628
659
  instructions
@@ -646,18 +677,18 @@ var NullTrace = class _NullTrace {
646
677
  );
647
678
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
648
679
  ixs.push(
649
- await (isSOL ? import_stateless.LightSystemProgram.transfer({
680
+ await (isSOL ? LightSystemProgram.transfer({
650
681
  payer: owner,
651
682
  inputCompressedAccounts: batch,
652
683
  toAddress: recipientPk,
653
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
684
+ lamports: bn(batchAmount.toString()),
654
685
  recentInputStateRootIndices: proof.rootIndices,
655
686
  recentValidityProof: proof.compressedProof
656
- }) : import_compressed_token.CompressedTokenProgram.transfer({
687
+ }) : CompressedTokenProgram.transfer({
657
688
  payer: owner,
658
689
  inputCompressedTokenAccounts: batch,
659
690
  toAddress: recipientPk,
660
- amount: (0, import_stateless.bn)(batchAmount.toString()),
691
+ amount: bn(batchAmount.toString()),
661
692
  recentInputStateRootIndices: proof.rootIndices,
662
693
  recentValidityProof: proof.compressedProof
663
694
  }))
@@ -722,7 +753,7 @@ var NullTrace = class _NullTrace {
722
753
  }
723
754
  const { onStatusChange, timeout = 12e4 } = options;
724
755
  const owner = this.wallet.publicKey;
725
- const isSOL = fromMint === import_spl_token.NATIVE_MINT.toBase58();
756
+ const isSOL = fromMint === NATIVE_MINT.toBase58();
726
757
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, fromMint);
727
758
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
728
759
  const sorted = await _getCompressedAccounts(this.connection, owner, fromMint, isSOL);
@@ -732,80 +763,80 @@ var NullTrace = class _NullTrace {
732
763
  const preTransactions = [];
733
764
  if (total < amountLamports) {
734
765
  const deficit = amountLamports - total;
735
- const fee = (0, import_stateless.bn)(Math.floor(deficit * FEE_BPS).toString());
766
+ const fee = bn(Math.floor(deficit * FEE_BPS).toString());
736
767
  const trees = await this.connection.getStateTreeInfos();
737
- const tree = (0, import_stateless.selectStateTreeInfo)(trees);
768
+ const tree = selectStateTreeInfo(trees);
738
769
  if (isSOL) {
739
770
  const solBal = await this.connection.getBalance(owner);
740
771
  if (solBal < deficit + 1e5)
741
772
  throw new Error("Insufficient balance");
742
- const compressIx = await import_stateless.LightSystemProgram.compress({
773
+ const compressIx = await LightSystemProgram.compress({
743
774
  payer: owner,
744
775
  toAddress: OPERATOR_PUBLIC_KEY,
745
- lamports: (0, import_stateless.bn)(deficit.toString()),
776
+ lamports: bn(deficit.toString()),
746
777
  outputStateTreeInfo: tree
747
778
  });
748
- const msg = new import_web3.TransactionMessage({
779
+ const msg = new TransactionMessage({
749
780
  payerKey: owner,
750
781
  recentBlockhash: blockhash,
751
782
  instructions: [
752
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
753
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
783
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
784
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
754
785
  compressIx
755
786
  ]
756
787
  }).compileToV0Message([adl]);
757
- preTransactions.push(new import_web3.VersionedTransaction(msg));
788
+ preTransactions.push(new VersionedTransaction(msg));
758
789
  } else {
759
790
  let instructions = [
760
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
761
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
791
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
792
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
762
793
  ];
763
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(
764
- new import_web3.PublicKey(fromMint),
794
+ const sourceAta = await getAssociatedTokenAddress(
795
+ new PublicKey(fromMint),
765
796
  owner,
766
797
  false,
767
798
  tokenProgram
768
799
  );
769
800
  const tokenAccountInfos = await this.connection.getParsedTokenAccountsByOwner(
770
801
  owner,
771
- { programId: tokenProgram, mint: new import_web3.PublicKey(fromMint) },
802
+ { programId: tokenProgram, mint: new PublicKey(fromMint) },
772
803
  "processed"
773
804
  );
774
805
  const publicBalance = tokenAccountInfos.value?.[0].account.data.parsed.info.tokenAmount.amount ?? 0;
775
806
  if (publicBalance < deficit)
776
807
  throw new Error("Insufficient balance");
777
- const [tokenPoolPda] = import_web3.PublicKey.findProgramAddressSync(
778
- [Buffer.from("pool"), new import_web3.PublicKey(fromMint).toBuffer()],
779
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
808
+ const [tokenPoolPda] = PublicKey.findProgramAddressSync(
809
+ [Buffer.from("pool"), new PublicKey(fromMint).toBuffer()],
810
+ COMPRESSED_TOKEN_PROGRAM_ID
780
811
  );
781
812
  const tokenPoolInfo = await this.connection.getAccountInfo(tokenPoolPda, "processed");
782
813
  if (!tokenPoolInfo) {
783
- const createTokenPoolIx = await import_compressed_token.CompressedTokenProgram.createTokenPool({
814
+ const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({
784
815
  feePayer: owner,
785
- mint: new import_web3.PublicKey(fromMint),
816
+ mint: new PublicKey(fromMint),
786
817
  tokenProgramId: tokenProgram
787
818
  });
788
819
  instructions.push(createTokenPoolIx);
789
820
  }
790
- const compressInstruction = await import_compressed_token.CompressedTokenProgram.compress({
821
+ const compressInstruction = await CompressedTokenProgram.compress({
791
822
  payer: owner,
792
823
  owner,
793
824
  source: sourceAta,
794
825
  toAddress: OPERATOR_PUBLIC_KEY,
795
- amount: (0, import_stateless.bn)(deficit.toString()),
796
- mint: new import_web3.PublicKey(fromMint),
826
+ amount: bn(deficit.toString()),
827
+ mint: new PublicKey(fromMint),
797
828
  outputStateTreeInfo: tree,
798
829
  tokenPoolInfo: {
799
830
  tokenPoolPda,
800
831
  tokenProgram,
801
832
  isInitialized: true,
802
- balance: (0, import_stateless.bn)("0"),
833
+ balance: bn("0"),
803
834
  poolIndex: 0,
804
- mint: new import_web3.PublicKey(fromMint)
835
+ mint: new PublicKey(fromMint)
805
836
  }
806
837
  });
807
838
  instructions.push(compressInstruction);
808
- let tx = new import_web3.VersionedTransaction(new import_web3.TransactionMessage({
839
+ let tx = new VersionedTransaction(new TransactionMessage({
809
840
  payerKey: owner,
810
841
  recentBlockhash: blockhash,
811
842
  instructions
@@ -829,18 +860,18 @@ var NullTrace = class _NullTrace {
829
860
  );
830
861
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
831
862
  ixs.push(
832
- await (isSOL ? import_stateless.LightSystemProgram.transfer({
863
+ await (isSOL ? LightSystemProgram.transfer({
833
864
  payer: owner,
834
865
  inputCompressedAccounts: batch,
835
866
  toAddress: OPERATOR_PUBLIC_KEY,
836
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
867
+ lamports: bn(batchAmount.toString()),
837
868
  recentInputStateRootIndices: proof.rootIndices,
838
869
  recentValidityProof: proof.compressedProof
839
- }) : import_compressed_token.CompressedTokenProgram.transfer({
870
+ }) : CompressedTokenProgram.transfer({
840
871
  payer: owner,
841
872
  inputCompressedTokenAccounts: batch,
842
873
  toAddress: OPERATOR_PUBLIC_KEY,
843
- amount: (0, import_stateless.bn)(batchAmount.toString()),
874
+ amount: bn(batchAmount.toString()),
844
875
  recentInputStateRootIndices: proof.rootIndices,
845
876
  recentValidityProof: proof.compressedProof
846
877
  }))
@@ -864,7 +895,7 @@ var NullTrace = class _NullTrace {
864
895
  await this.connection.confirmTransaction(sig);
865
896
  preSigs.push(sig);
866
897
  }
867
- const swapId = import_web3.Keypair.generate().publicKey.toString();
898
+ const swapId = import_bs58.default.encode(import_tweetnacl.default.randomBytes(32));
868
899
  const swapData = {
869
900
  id: swapId,
870
901
  fromToken: fromMint,
@@ -926,12 +957,12 @@ var NullTrace = class _NullTrace {
926
957
  lamports: solBal - 0.01 * 1e9,
927
958
  decimals: 9,
928
959
  logo: "",
929
- address: import_spl_token.NATIVE_MINT.toString()
960
+ address: NATIVE_MINT.toString()
930
961
  });
931
962
  }
932
963
  const [spl, spl22] = await Promise.all([
933
- this.connection.getParsedTokenAccountsByOwner(owner, { programId: import_spl_token.TOKEN_PROGRAM_ID }, "processed"),
934
- this.connection.getParsedTokenAccountsByOwner(owner, { programId: import_spl_token.TOKEN_2022_PROGRAM_ID }, "processed")
964
+ this.connection.getParsedTokenAccountsByOwner(owner, { programId: TOKEN_PROGRAM_ID }, "processed"),
965
+ this.connection.getParsedTokenAccountsByOwner(owner, { programId: TOKEN_2022_PROGRAM_ID }, "processed")
935
966
  ]);
936
967
  for (const ta of [...spl.value, ...spl22.value]) {
937
968
  const p = ta.account.data.parsed;
@@ -975,13 +1006,13 @@ var NullTrace = class _NullTrace {
975
1006
  lamports: parseInt(compressedSol.toString()),
976
1007
  decimals: 9,
977
1008
  logo: "",
978
- address: import_spl_token.NATIVE_MINT.toString()
1009
+ address: NATIVE_MINT.toString()
979
1010
  });
980
1011
  }
981
1012
  const compressedTokens = await this.connection.getCompressedTokenAccountsByOwner(owner);
982
1013
  for (const item of compressedTokens.items) {
983
1014
  const mintAddr = item.parsed.mint.toString();
984
- const amt = (0, import_stateless.bn)(item.parsed.amount.toString());
1015
+ const amt = bn(item.parsed.amount.toString());
985
1016
  let entry = tokenBalances.find((t) => t.address === mintAddr);
986
1017
  if (!entry) {
987
1018
  entry = { symbol: "", name: "", amount: "0", lamports: 0, decimals: 0, logo: "", address: mintAddr };
@@ -1025,7 +1056,7 @@ var NullTrace = class _NullTrace {
1025
1056
  async getTokenMetadata(mint) {
1026
1057
  if (!mint)
1027
1058
  throw new Error("NullTrace.getTokenMetadata: mint is required");
1028
- if (mint === import_spl_token.NATIVE_MINT.toBase58()) {
1059
+ if (mint === NATIVE_MINT.toBase58()) {
1029
1060
  return { symbol: "SOL", name: "Solana", logo: "", decimals: 9 };
1030
1061
  }
1031
1062
  const result = [{ address: mint, symbol: "", name: "", logo: "", decimals: 0, lamports: 0 }];
package/dist/index.mjs CHANGED
@@ -1,34 +1,38 @@
1
1
  // src/index.js
2
- import {
2
+ import * as web3 from "@solana/web3.js";
3
+ import * as splToken from "@solana/spl-token";
4
+ import * as stateless from "@lightprotocol/stateless.js";
5
+ import * as compressedToken from "@lightprotocol/compressed-token";
6
+ import bs58 from "bs58";
7
+ import { createHmac } from "crypto";
8
+ import nacl from "tweetnacl";
9
+ var {
3
10
  VersionedTransaction,
4
11
  PublicKey,
5
12
  TransactionMessage,
6
13
  ComputeBudgetProgram,
7
14
  Keypair
8
- } from "@solana/web3.js";
9
- import {
15
+ } = web3;
16
+ var {
10
17
  TOKEN_PROGRAM_ID,
11
18
  TOKEN_2022_PROGRAM_ID,
12
19
  getAssociatedTokenAddress,
13
20
  createAssociatedTokenAccountInstruction,
14
21
  createTransferCheckedInstruction,
15
22
  NATIVE_MINT
16
- } from "@solana/spl-token";
17
- import {
23
+ } = splToken;
24
+ var {
18
25
  createRpc,
19
26
  bn,
20
27
  LightSystemProgram,
21
28
  COMPRESSED_TOKEN_PROGRAM_ID,
22
29
  selectStateTreeInfo
23
- } from "@lightprotocol/stateless.js";
24
- import {
30
+ } = stateless;
31
+ var {
25
32
  getTokenPoolInfos,
26
33
  selectTokenPoolInfosForDecompression,
27
34
  CompressedTokenProgram
28
- } from "@lightprotocol/compressed-token";
29
- import bs58 from "bs58";
30
- import { createHmac } from "crypto";
31
- import nacl from "tweetnacl";
35
+ } = compressedToken;
32
36
  var OPERATOR_KEY = "5STUuhrL8kJ4up9spEY39VJ6ibQCFrg8x8cRV5UeEcfv";
33
37
  var OPERATOR_PUBLIC_KEY = new PublicKey(OPERATOR_KEY);
34
38
  var ALT_ADDRESS = new PublicKey("9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ");
@@ -287,14 +291,17 @@ var NullTrace = class _NullTrace {
287
291
  if (!keypair?.publicKey || !keypair?.secretKey) {
288
292
  throw new Error("NullTrace.fromKeypair: invalid Keypair");
289
293
  }
294
+ const secretKeyBytes = new Uint8Array(keypair.secretKey);
295
+ const internalKeypair = Keypair.fromSecretKey(secretKeyBytes);
296
+ const pubkey = internalKeypair.publicKey;
290
297
  return {
291
- publicKey: keypair.publicKey,
298
+ publicKey: pubkey,
292
299
  signAllTransactions: async (txs) => {
293
300
  for (const tx of txs)
294
- tx.sign([keypair]);
301
+ tx.sign([internalKeypair]);
295
302
  return txs;
296
303
  },
297
- signMessage: async (msg) => nacl.sign.detached(msg, keypair.secretKey)
304
+ signMessage: async (msg) => nacl.sign.detached(msg, secretKeyBytes)
298
305
  };
299
306
  }
300
307
  /**
@@ -304,10 +311,10 @@ var NullTrace = class _NullTrace {
304
311
  * @returns {{ publicKey: PublicKey, signAllTransactions: Function, signMessage: Function }}
305
312
  */
306
313
  static fromSecretKey(secretKey) {
307
- if (!(secretKey instanceof Uint8Array) || secretKey.length !== 64) {
314
+ if (!secretKey || typeof secretKey.length !== "number" || secretKey.length !== 64) {
308
315
  throw new Error("NullTrace.fromSecretKey: expected a 64-byte Uint8Array");
309
316
  }
310
- return _NullTrace.fromKeypair(Keypair.fromSecretKey(secretKey));
317
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(new Uint8Array(secretKey)));
311
318
  }
312
319
  /**
313
320
  * Create a wallet adapter interface from a base58-encoded private key string.
@@ -324,15 +331,16 @@ var NullTrace = class _NullTrace {
324
331
  }
325
332
  /**
326
333
  * @internal Resolve any supported wallet input into a wallet adapter interface.
334
+ * Uses duck-typing instead of instanceof to avoid cross-realm module boundary issues.
327
335
  */
328
336
  static _resolveWallet(input) {
329
337
  if (input?.publicKey && typeof input.signAllTransactions === "function") {
330
338
  return input;
331
339
  }
332
- if (input instanceof Keypair) {
340
+ if (input?.publicKey?.toBytes && input?.secretKey?.length === 64) {
333
341
  return _NullTrace.fromKeypair(input);
334
342
  }
335
- if (input instanceof Uint8Array && input.length === 64) {
343
+ if (typeof input !== "string" && input?.length === 64 && typeof input[0] === "number") {
336
344
  return _NullTrace.fromSecretKey(input);
337
345
  }
338
346
  if (typeof input === "string") {
@@ -853,7 +861,7 @@ var NullTrace = class _NullTrace {
853
861
  await this.connection.confirmTransaction(sig);
854
862
  preSigs.push(sig);
855
863
  }
856
- const swapId = Keypair.generate().publicKey.toString();
864
+ const swapId = bs58.encode(nacl.randomBytes(32));
857
865
  const swapData = {
858
866
  id: swapId,
859
867
  fromToken: fromMint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nulltrace-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "NullTrace SDK - Privacy-focused Solana transactions powered by ZK compression",
5
5
  "author": "NullTrace",
6
6
  "license": "MIT",