nulltrace-sdk 1.0.3 → 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 +152 -117
  2. package/dist/index.mjs +33 -21
  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,20 +180,22 @@ 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);
167
194
  const sigs = [];
168
195
  for (const tx of signed) {
169
- const sig = await connection.sendRawTransaction(tx.serialize());
196
+ const sig = await connection.sendRawTransaction(tx.serialize(), {
197
+ skipPreflight: true
198
+ });
170
199
  await connection.confirmTransaction(sig);
171
200
  sigs.push(sig);
172
201
  }
@@ -279,7 +308,7 @@ var NullTrace = class _NullTrace {
279
308
  throw new Error("NullTrace: a wallet, Keypair, secret key, or private key string is required");
280
309
  this.rpcUrl = rpcUrl;
281
310
  this.wallet = _NullTrace._resolveWallet(walletOrKey);
282
- this.connection = (0, import_stateless.createRpc)(rpcUrl, rpcUrl, rpcUrl, { commitment: "processed" });
311
+ this.connection = createRpc(rpcUrl, rpcUrl, rpcUrl, { commitment: "processed" });
283
312
  this._adlCache = null;
284
313
  this._sigCache = null;
285
314
  }
@@ -296,14 +325,17 @@ var NullTrace = class _NullTrace {
296
325
  if (!keypair?.publicKey || !keypair?.secretKey) {
297
326
  throw new Error("NullTrace.fromKeypair: invalid Keypair");
298
327
  }
328
+ const secretKeyBytes = new Uint8Array(keypair.secretKey);
329
+ const internalKeypair = Keypair.fromSecretKey(secretKeyBytes);
330
+ const pubkey = internalKeypair.publicKey;
299
331
  return {
300
- publicKey: keypair.publicKey,
332
+ publicKey: pubkey,
301
333
  signAllTransactions: async (txs) => {
302
334
  for (const tx of txs)
303
- tx.sign([keypair]);
335
+ tx.sign([internalKeypair]);
304
336
  return txs;
305
337
  },
306
- signMessage: async (msg) => import_tweetnacl.default.sign.detached(msg, keypair.secretKey)
338
+ signMessage: async (msg) => import_tweetnacl.default.sign.detached(msg, secretKeyBytes)
307
339
  };
308
340
  }
309
341
  /**
@@ -313,10 +345,10 @@ var NullTrace = class _NullTrace {
313
345
  * @returns {{ publicKey: PublicKey, signAllTransactions: Function, signMessage: Function }}
314
346
  */
315
347
  static fromSecretKey(secretKey) {
316
- if (!(secretKey instanceof Uint8Array) || secretKey.length !== 64) {
348
+ if (!secretKey || typeof secretKey.length !== "number" || secretKey.length !== 64) {
317
349
  throw new Error("NullTrace.fromSecretKey: expected a 64-byte Uint8Array");
318
350
  }
319
- return _NullTrace.fromKeypair(import_web3.Keypair.fromSecretKey(secretKey));
351
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(new Uint8Array(secretKey)));
320
352
  }
321
353
  /**
322
354
  * Create a wallet adapter interface from a base58-encoded private key string.
@@ -329,19 +361,20 @@ var NullTrace = class _NullTrace {
329
361
  throw new Error("NullTrace.fromPrivateKey: expected a base58-encoded private key string");
330
362
  }
331
363
  const decoded = import_bs58.default.decode(base58Key);
332
- return _NullTrace.fromKeypair(import_web3.Keypair.fromSecretKey(decoded));
364
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(decoded));
333
365
  }
334
366
  /**
335
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.
336
369
  */
337
370
  static _resolveWallet(input) {
338
371
  if (input?.publicKey && typeof input.signAllTransactions === "function") {
339
372
  return input;
340
373
  }
341
- if (input instanceof import_web3.Keypair) {
374
+ if (input?.publicKey?.toBytes && input?.secretKey?.length === 64) {
342
375
  return _NullTrace.fromKeypair(input);
343
376
  }
344
- if (input instanceof Uint8Array && input.length === 64) {
377
+ if (typeof input !== "string" && input?.length === 64 && typeof input[0] === "number") {
345
378
  return _NullTrace.fromSecretKey(input);
346
379
  }
347
380
  if (typeof input === "string") {
@@ -376,22 +409,22 @@ var NullTrace = class _NullTrace {
376
409
  if (!mint || !amount)
377
410
  throw new Error("NullTrace.nullify: mint and amount are required");
378
411
  const owner = this.wallet.publicKey;
379
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
412
+ const isSOL = mint === NATIVE_MINT.toBase58();
380
413
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
381
- const amountLamports = (0, import_stateless.bn)(Math.floor(parseFloat(amount) * 10 ** decimals).toString());
382
- 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());
383
416
  const ixs = [];
384
417
  const activeStateTrees = await this.connection.getStateTreeInfos();
385
- const tree = (0, import_stateless.selectStateTreeInfo)(activeStateTrees);
418
+ const tree = selectStateTreeInfo(activeStateTrees);
386
419
  if (isSOL) {
387
420
  ixs.push(
388
- await import_stateless.LightSystemProgram.compress({
421
+ await LightSystemProgram.compress({
389
422
  payer: owner,
390
423
  toAddress: owner,
391
424
  lamports: amountLamports.sub(feeLamports),
392
425
  outputStateTreeInfo: tree
393
426
  }),
394
- await import_stateless.LightSystemProgram.compress({
427
+ await LightSystemProgram.compress({
395
428
  payer: owner,
396
429
  toAddress: OPERATOR_PUBLIC_KEY,
397
430
  lamports: feeLamports,
@@ -399,16 +432,16 @@ var NullTrace = class _NullTrace {
399
432
  })
400
433
  );
401
434
  } else {
402
- const mintPk = new import_web3.PublicKey(mint);
403
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(mintPk, owner, false, tokenProgram);
404
- 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(
405
438
  [Buffer.from("pool"), mintPk.toBuffer()],
406
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
439
+ COMPRESSED_TOKEN_PROGRAM_ID
407
440
  );
408
441
  const poolInfo = await this.connection.getAccountInfo(tokenPoolPda);
409
442
  if (!poolInfo) {
410
443
  ixs.push(
411
- await import_compressed_token.CompressedTokenProgram.createTokenPool({
444
+ await CompressedTokenProgram.createTokenPool({
412
445
  feePayer: owner,
413
446
  mint: mintPk,
414
447
  tokenProgramId: tokenProgram
@@ -416,7 +449,7 @@ var NullTrace = class _NullTrace {
416
449
  );
417
450
  }
418
451
  ixs.push(
419
- await import_compressed_token.CompressedTokenProgram.compress({
452
+ await CompressedTokenProgram.compress({
420
453
  payer: owner,
421
454
  owner,
422
455
  source: sourceAta,
@@ -428,7 +461,7 @@ var NullTrace = class _NullTrace {
428
461
  tokenPoolPda,
429
462
  tokenProgram,
430
463
  isInitialized: true,
431
- balance: (0, import_stateless.bn)("0"),
464
+ balance: bn("0"),
432
465
  poolIndex: 0,
433
466
  mint: mintPk
434
467
  }
@@ -456,7 +489,7 @@ var NullTrace = class _NullTrace {
456
489
  if (!mint || !amount)
457
490
  throw new Error("NullTrace.reveal: mint and amount are required");
458
491
  const owner = this.wallet.publicKey;
459
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
492
+ const isSOL = mint === NATIVE_MINT.toBase58();
460
493
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
461
494
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
462
495
  const sorted = await _getCompressedAccounts(this.connection, owner, mint, isSOL);
@@ -468,12 +501,12 @@ var NullTrace = class _NullTrace {
468
501
  let selectedTokenPoolInfos;
469
502
  let destinationAta;
470
503
  if (!isSOL) {
471
- const tokenPoolInfos = await (0, import_compressed_token.getTokenPoolInfos)(this.connection, new import_web3.PublicKey(mint));
472
- selectedTokenPoolInfos = (0, import_compressed_token.selectTokenPoolInfosForDecompression)(tokenPoolInfos, amountLamports);
473
- 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);
474
507
  const info = await this.connection.getAccountInfo(destinationAta);
475
508
  if (!info) {
476
- 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));
477
510
  }
478
511
  }
479
512
  let remaining = amountLamports;
@@ -487,18 +520,18 @@ var NullTrace = class _NullTrace {
487
520
  );
488
521
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
489
522
  ixs.push(
490
- await (isSOL ? import_stateless.LightSystemProgram.decompress({
523
+ await (isSOL ? LightSystemProgram.decompress({
491
524
  payer: owner,
492
525
  inputCompressedAccounts: batch,
493
526
  toAddress: owner,
494
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
527
+ lamports: bn(batchAmount.toString()),
495
528
  recentInputStateRootIndices: proof.rootIndices,
496
529
  recentValidityProof: proof.compressedProof
497
- }) : import_compressed_token.CompressedTokenProgram.decompress({
530
+ }) : CompressedTokenProgram.decompress({
498
531
  payer: owner,
499
532
  inputCompressedTokenAccounts: batch,
500
533
  toAddress: destinationAta,
501
- amount: (0, import_stateless.bn)(batchAmount.toString()),
534
+ amount: bn(batchAmount.toString()),
502
535
  recentInputStateRootIndices: proof.rootIndices,
503
536
  recentValidityProof: proof.compressedProof,
504
537
  tokenPoolInfos: selectedTokenPoolInfos
@@ -529,8 +562,8 @@ var NullTrace = class _NullTrace {
529
562
  throw new Error("NullTrace.transfer: mint, amount, and recipient are required");
530
563
  }
531
564
  const owner = this.wallet.publicKey;
532
- const recipientPk = new import_web3.PublicKey(recipient);
533
- const isSOL = mint === import_spl_token.NATIVE_MINT.toBase58();
565
+ const recipientPk = new PublicKey(recipient);
566
+ const isSOL = mint === NATIVE_MINT.toBase58();
534
567
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, mint);
535
568
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
536
569
  const sorted = await _getCompressedAccounts(this.connection, owner, mint, isSOL);
@@ -540,87 +573,87 @@ var NullTrace = class _NullTrace {
540
573
  const preTransactions = [];
541
574
  if (total < amountLamports) {
542
575
  const deficit = amountLamports - total;
543
- const fee = (0, import_stateless.bn)(Math.floor(deficit * FEE_BPS).toString());
576
+ const fee = bn(Math.floor(deficit * FEE_BPS).toString());
544
577
  const trees = await this.connection.getStateTreeInfos();
545
- const tree = (0, import_stateless.selectStateTreeInfo)(trees);
578
+ const tree = selectStateTreeInfo(trees);
546
579
  if (isSOL) {
547
580
  const solBal = await this.connection.getBalance(owner);
548
581
  if (solBal < deficit + 1e5)
549
582
  throw new Error("Insufficient balance");
550
- const compressIx = await import_stateless.LightSystemProgram.compress({
583
+ const compressIx = await LightSystemProgram.compress({
551
584
  payer: owner,
552
585
  toAddress: recipientPk,
553
- lamports: (0, import_stateless.bn)(deficit.toString()).sub(fee),
586
+ lamports: bn(deficit.toString()).sub(fee),
554
587
  outputStateTreeInfo: tree
555
588
  });
556
- const feeIx = await import_stateless.LightSystemProgram.compress({
589
+ const feeIx = await LightSystemProgram.compress({
557
590
  payer: owner,
558
591
  toAddress: OPERATOR_PUBLIC_KEY,
559
592
  lamports: fee,
560
593
  outputStateTreeInfo: tree
561
594
  });
562
- const msg = new import_web3.TransactionMessage({
595
+ const msg = new TransactionMessage({
563
596
  payerKey: owner,
564
597
  recentBlockhash: blockhash,
565
598
  instructions: [
566
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
567
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
599
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
600
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
568
601
  compressIx,
569
602
  feeIx
570
603
  ]
571
604
  }).compileToV0Message([adl]);
572
- preTransactions.push(new import_web3.VersionedTransaction(msg));
605
+ preTransactions.push(new VersionedTransaction(msg));
573
606
  } else {
574
607
  let instructions = [
575
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
576
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
608
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
609
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
577
610
  ];
578
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(
579
- new import_web3.PublicKey(mint),
611
+ const sourceAta = await getAssociatedTokenAddress(
612
+ new PublicKey(mint),
580
613
  owner,
581
614
  false,
582
615
  tokenProgram
583
616
  );
584
617
  const tokenAccountInfos = await this.connection.getParsedTokenAccountsByOwner(
585
618
  owner,
586
- { programId: tokenProgram, mint: new import_web3.PublicKey(mint) },
619
+ { programId: tokenProgram, mint: new PublicKey(mint) },
587
620
  "processed"
588
621
  );
589
622
  const publicBalance = tokenAccountInfos.value?.[0].account.data.parsed.info.tokenAmount.amount ?? 0;
590
623
  if (publicBalance < deficit)
591
624
  throw new Error("Insufficient balance");
592
- const [tokenPoolPda] = import_web3.PublicKey.findProgramAddressSync(
593
- [Buffer.from("pool"), new import_web3.PublicKey(mint).toBuffer()],
594
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
625
+ const [tokenPoolPda] = PublicKey.findProgramAddressSync(
626
+ [Buffer.from("pool"), new PublicKey(mint).toBuffer()],
627
+ COMPRESSED_TOKEN_PROGRAM_ID
595
628
  );
596
629
  const tokenPoolInfo = await this.connection.getAccountInfo(tokenPoolPda, "processed");
597
630
  if (!tokenPoolInfo) {
598
- const createTokenPoolIx = await import_compressed_token.CompressedTokenProgram.createTokenPool({
631
+ const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({
599
632
  feePayer: owner,
600
- mint: new import_web3.PublicKey(mint),
633
+ mint: new PublicKey(mint),
601
634
  tokenProgramId: tokenProgram
602
635
  });
603
636
  instructions.push(createTokenPoolIx);
604
637
  }
605
- const compressInstruction = await import_compressed_token.CompressedTokenProgram.compress({
638
+ const compressInstruction = await CompressedTokenProgram.compress({
606
639
  payer: owner,
607
640
  owner,
608
641
  source: sourceAta,
609
642
  toAddress: [recipientPk, OPERATOR_PUBLIC_KEY],
610
- amount: [(0, import_stateless.bn)(deficit.toString()).sub(fee), fee],
611
- mint: new import_web3.PublicKey(mint),
643
+ amount: [bn(deficit.toString()).sub(fee), fee],
644
+ mint: new PublicKey(mint),
612
645
  outputStateTreeInfo: tree,
613
646
  tokenPoolInfo: {
614
647
  tokenPoolPda,
615
648
  tokenProgram,
616
649
  isInitialized: true,
617
- balance: (0, import_stateless.bn)("0"),
650
+ balance: bn("0"),
618
651
  poolIndex: 0,
619
- mint: new import_web3.PublicKey(mint)
652
+ mint: new PublicKey(mint)
620
653
  }
621
654
  });
622
655
  instructions.push(compressInstruction);
623
- let tx = new import_web3.VersionedTransaction(new import_web3.TransactionMessage({
656
+ let tx = new VersionedTransaction(new TransactionMessage({
624
657
  payerKey: owner,
625
658
  recentBlockhash: blockhash,
626
659
  instructions
@@ -644,18 +677,18 @@ var NullTrace = class _NullTrace {
644
677
  );
645
678
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
646
679
  ixs.push(
647
- await (isSOL ? import_stateless.LightSystemProgram.transfer({
680
+ await (isSOL ? LightSystemProgram.transfer({
648
681
  payer: owner,
649
682
  inputCompressedAccounts: batch,
650
683
  toAddress: recipientPk,
651
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
684
+ lamports: bn(batchAmount.toString()),
652
685
  recentInputStateRootIndices: proof.rootIndices,
653
686
  recentValidityProof: proof.compressedProof
654
- }) : import_compressed_token.CompressedTokenProgram.transfer({
687
+ }) : CompressedTokenProgram.transfer({
655
688
  payer: owner,
656
689
  inputCompressedTokenAccounts: batch,
657
690
  toAddress: recipientPk,
658
- amount: (0, import_stateless.bn)(batchAmount.toString()),
691
+ amount: bn(batchAmount.toString()),
659
692
  recentInputStateRootIndices: proof.rootIndices,
660
693
  recentValidityProof: proof.compressedProof
661
694
  }))
@@ -720,7 +753,7 @@ var NullTrace = class _NullTrace {
720
753
  }
721
754
  const { onStatusChange, timeout = 12e4 } = options;
722
755
  const owner = this.wallet.publicKey;
723
- const isSOL = fromMint === import_spl_token.NATIVE_MINT.toBase58();
756
+ const isSOL = fromMint === NATIVE_MINT.toBase58();
724
757
  const { decimals, tokenProgram } = await _getMintInfo(this.connection, fromMint);
725
758
  const amountLamports = Math.floor(parseFloat(amount) * 10 ** decimals);
726
759
  const sorted = await _getCompressedAccounts(this.connection, owner, fromMint, isSOL);
@@ -730,80 +763,80 @@ var NullTrace = class _NullTrace {
730
763
  const preTransactions = [];
731
764
  if (total < amountLamports) {
732
765
  const deficit = amountLamports - total;
733
- const fee = (0, import_stateless.bn)(Math.floor(deficit * FEE_BPS).toString());
766
+ const fee = bn(Math.floor(deficit * FEE_BPS).toString());
734
767
  const trees = await this.connection.getStateTreeInfos();
735
- const tree = (0, import_stateless.selectStateTreeInfo)(trees);
768
+ const tree = selectStateTreeInfo(trees);
736
769
  if (isSOL) {
737
770
  const solBal = await this.connection.getBalance(owner);
738
771
  if (solBal < deficit + 1e5)
739
772
  throw new Error("Insufficient balance");
740
- const compressIx = await import_stateless.LightSystemProgram.compress({
773
+ const compressIx = await LightSystemProgram.compress({
741
774
  payer: owner,
742
775
  toAddress: OPERATOR_PUBLIC_KEY,
743
- lamports: (0, import_stateless.bn)(deficit.toString()),
776
+ lamports: bn(deficit.toString()),
744
777
  outputStateTreeInfo: tree
745
778
  });
746
- const msg = new import_web3.TransactionMessage({
779
+ const msg = new TransactionMessage({
747
780
  payerKey: owner,
748
781
  recentBlockhash: blockhash,
749
782
  instructions: [
750
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
751
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
783
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
784
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE }),
752
785
  compressIx
753
786
  ]
754
787
  }).compileToV0Message([adl]);
755
- preTransactions.push(new import_web3.VersionedTransaction(msg));
788
+ preTransactions.push(new VersionedTransaction(msg));
756
789
  } else {
757
790
  let instructions = [
758
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
759
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
791
+ ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
792
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: COMPUTE_PRICE })
760
793
  ];
761
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(
762
- new import_web3.PublicKey(fromMint),
794
+ const sourceAta = await getAssociatedTokenAddress(
795
+ new PublicKey(fromMint),
763
796
  owner,
764
797
  false,
765
798
  tokenProgram
766
799
  );
767
800
  const tokenAccountInfos = await this.connection.getParsedTokenAccountsByOwner(
768
801
  owner,
769
- { programId: tokenProgram, mint: new import_web3.PublicKey(fromMint) },
802
+ { programId: tokenProgram, mint: new PublicKey(fromMint) },
770
803
  "processed"
771
804
  );
772
805
  const publicBalance = tokenAccountInfos.value?.[0].account.data.parsed.info.tokenAmount.amount ?? 0;
773
806
  if (publicBalance < deficit)
774
807
  throw new Error("Insufficient balance");
775
- const [tokenPoolPda] = import_web3.PublicKey.findProgramAddressSync(
776
- [Buffer.from("pool"), new import_web3.PublicKey(fromMint).toBuffer()],
777
- import_stateless.COMPRESSED_TOKEN_PROGRAM_ID
808
+ const [tokenPoolPda] = PublicKey.findProgramAddressSync(
809
+ [Buffer.from("pool"), new PublicKey(fromMint).toBuffer()],
810
+ COMPRESSED_TOKEN_PROGRAM_ID
778
811
  );
779
812
  const tokenPoolInfo = await this.connection.getAccountInfo(tokenPoolPda, "processed");
780
813
  if (!tokenPoolInfo) {
781
- const createTokenPoolIx = await import_compressed_token.CompressedTokenProgram.createTokenPool({
814
+ const createTokenPoolIx = await CompressedTokenProgram.createTokenPool({
782
815
  feePayer: owner,
783
- mint: new import_web3.PublicKey(fromMint),
816
+ mint: new PublicKey(fromMint),
784
817
  tokenProgramId: tokenProgram
785
818
  });
786
819
  instructions.push(createTokenPoolIx);
787
820
  }
788
- const compressInstruction = await import_compressed_token.CompressedTokenProgram.compress({
821
+ const compressInstruction = await CompressedTokenProgram.compress({
789
822
  payer: owner,
790
823
  owner,
791
824
  source: sourceAta,
792
825
  toAddress: OPERATOR_PUBLIC_KEY,
793
- amount: (0, import_stateless.bn)(deficit.toString()),
794
- mint: new import_web3.PublicKey(fromMint),
826
+ amount: bn(deficit.toString()),
827
+ mint: new PublicKey(fromMint),
795
828
  outputStateTreeInfo: tree,
796
829
  tokenPoolInfo: {
797
830
  tokenPoolPda,
798
831
  tokenProgram,
799
832
  isInitialized: true,
800
- balance: (0, import_stateless.bn)("0"),
833
+ balance: bn("0"),
801
834
  poolIndex: 0,
802
- mint: new import_web3.PublicKey(fromMint)
835
+ mint: new PublicKey(fromMint)
803
836
  }
804
837
  });
805
838
  instructions.push(compressInstruction);
806
- let tx = new import_web3.VersionedTransaction(new import_web3.TransactionMessage({
839
+ let tx = new VersionedTransaction(new TransactionMessage({
807
840
  payerKey: owner,
808
841
  recentBlockhash: blockhash,
809
842
  instructions
@@ -827,18 +860,18 @@ var NullTrace = class _NullTrace {
827
860
  );
828
861
  const batchAmount = decimals === 0 ? 1 : Math.min(remaining, batch.reduce((s, a) => s + Number(isSOL ? a.lamports : a.parsed.amount), 0));
829
862
  ixs.push(
830
- await (isSOL ? import_stateless.LightSystemProgram.transfer({
863
+ await (isSOL ? LightSystemProgram.transfer({
831
864
  payer: owner,
832
865
  inputCompressedAccounts: batch,
833
866
  toAddress: OPERATOR_PUBLIC_KEY,
834
- lamports: (0, import_stateless.bn)(batchAmount.toString()),
867
+ lamports: bn(batchAmount.toString()),
835
868
  recentInputStateRootIndices: proof.rootIndices,
836
869
  recentValidityProof: proof.compressedProof
837
- }) : import_compressed_token.CompressedTokenProgram.transfer({
870
+ }) : CompressedTokenProgram.transfer({
838
871
  payer: owner,
839
872
  inputCompressedTokenAccounts: batch,
840
873
  toAddress: OPERATOR_PUBLIC_KEY,
841
- amount: (0, import_stateless.bn)(batchAmount.toString()),
874
+ amount: bn(batchAmount.toString()),
842
875
  recentInputStateRootIndices: proof.rootIndices,
843
876
  recentValidityProof: proof.compressedProof
844
877
  }))
@@ -856,11 +889,13 @@ var NullTrace = class _NullTrace {
856
889
  });
857
890
  const preSigs = [];
858
891
  for (let i = 0; i < preTransactions.length; i++) {
859
- const sig = await this.connection.sendRawTransaction(signed[i].serialize());
892
+ const sig = await this.connection.sendRawTransaction(signed[i].serialize(), {
893
+ skipPreflight: true
894
+ });
860
895
  await this.connection.confirmTransaction(sig);
861
896
  preSigs.push(sig);
862
897
  }
863
- const swapId = import_web3.Keypair.generate().publicKey.toString();
898
+ const swapId = import_bs58.default.encode(import_tweetnacl.default.randomBytes(32));
864
899
  const swapData = {
865
900
  id: swapId,
866
901
  fromToken: fromMint,
@@ -922,12 +957,12 @@ var NullTrace = class _NullTrace {
922
957
  lamports: solBal - 0.01 * 1e9,
923
958
  decimals: 9,
924
959
  logo: "",
925
- address: import_spl_token.NATIVE_MINT.toString()
960
+ address: NATIVE_MINT.toString()
926
961
  });
927
962
  }
928
963
  const [spl, spl22] = await Promise.all([
929
- this.connection.getParsedTokenAccountsByOwner(owner, { programId: import_spl_token.TOKEN_PROGRAM_ID }, "processed"),
930
- 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")
931
966
  ]);
932
967
  for (const ta of [...spl.value, ...spl22.value]) {
933
968
  const p = ta.account.data.parsed;
@@ -971,13 +1006,13 @@ var NullTrace = class _NullTrace {
971
1006
  lamports: parseInt(compressedSol.toString()),
972
1007
  decimals: 9,
973
1008
  logo: "",
974
- address: import_spl_token.NATIVE_MINT.toString()
1009
+ address: NATIVE_MINT.toString()
975
1010
  });
976
1011
  }
977
1012
  const compressedTokens = await this.connection.getCompressedTokenAccountsByOwner(owner);
978
1013
  for (const item of compressedTokens.items) {
979
1014
  const mintAddr = item.parsed.mint.toString();
980
- const amt = (0, import_stateless.bn)(item.parsed.amount.toString());
1015
+ const amt = bn(item.parsed.amount.toString());
981
1016
  let entry = tokenBalances.find((t) => t.address === mintAddr);
982
1017
  if (!entry) {
983
1018
  entry = { symbol: "", name: "", amount: "0", lamports: 0, decimals: 0, logo: "", address: mintAddr };
@@ -1021,7 +1056,7 @@ var NullTrace = class _NullTrace {
1021
1056
  async getTokenMetadata(mint) {
1022
1057
  if (!mint)
1023
1058
  throw new Error("NullTrace.getTokenMetadata: mint is required");
1024
- if (mint === import_spl_token.NATIVE_MINT.toBase58()) {
1059
+ if (mint === NATIVE_MINT.toBase58()) {
1025
1060
  return { symbol: "SOL", name: "Solana", logo: "", decimals: 9 };
1026
1061
  }
1027
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");
@@ -155,7 +159,9 @@ async function _signSendConfirm(connection, wallet, transactions) {
155
159
  const signed = await wallet.signAllTransactions(transactions);
156
160
  const sigs = [];
157
161
  for (const tx of signed) {
158
- const sig = await connection.sendRawTransaction(tx.serialize());
162
+ const sig = await connection.sendRawTransaction(tx.serialize(), {
163
+ skipPreflight: true
164
+ });
159
165
  await connection.confirmTransaction(sig);
160
166
  sigs.push(sig);
161
167
  }
@@ -285,14 +291,17 @@ var NullTrace = class _NullTrace {
285
291
  if (!keypair?.publicKey || !keypair?.secretKey) {
286
292
  throw new Error("NullTrace.fromKeypair: invalid Keypair");
287
293
  }
294
+ const secretKeyBytes = new Uint8Array(keypair.secretKey);
295
+ const internalKeypair = Keypair.fromSecretKey(secretKeyBytes);
296
+ const pubkey = internalKeypair.publicKey;
288
297
  return {
289
- publicKey: keypair.publicKey,
298
+ publicKey: pubkey,
290
299
  signAllTransactions: async (txs) => {
291
300
  for (const tx of txs)
292
- tx.sign([keypair]);
301
+ tx.sign([internalKeypair]);
293
302
  return txs;
294
303
  },
295
- signMessage: async (msg) => nacl.sign.detached(msg, keypair.secretKey)
304
+ signMessage: async (msg) => nacl.sign.detached(msg, secretKeyBytes)
296
305
  };
297
306
  }
298
307
  /**
@@ -302,10 +311,10 @@ var NullTrace = class _NullTrace {
302
311
  * @returns {{ publicKey: PublicKey, signAllTransactions: Function, signMessage: Function }}
303
312
  */
304
313
  static fromSecretKey(secretKey) {
305
- if (!(secretKey instanceof Uint8Array) || secretKey.length !== 64) {
314
+ if (!secretKey || typeof secretKey.length !== "number" || secretKey.length !== 64) {
306
315
  throw new Error("NullTrace.fromSecretKey: expected a 64-byte Uint8Array");
307
316
  }
308
- return _NullTrace.fromKeypair(Keypair.fromSecretKey(secretKey));
317
+ return _NullTrace.fromKeypair(Keypair.fromSecretKey(new Uint8Array(secretKey)));
309
318
  }
310
319
  /**
311
320
  * Create a wallet adapter interface from a base58-encoded private key string.
@@ -322,15 +331,16 @@ var NullTrace = class _NullTrace {
322
331
  }
323
332
  /**
324
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.
325
335
  */
326
336
  static _resolveWallet(input) {
327
337
  if (input?.publicKey && typeof input.signAllTransactions === "function") {
328
338
  return input;
329
339
  }
330
- if (input instanceof Keypair) {
340
+ if (input?.publicKey?.toBytes && input?.secretKey?.length === 64) {
331
341
  return _NullTrace.fromKeypair(input);
332
342
  }
333
- if (input instanceof Uint8Array && input.length === 64) {
343
+ if (typeof input !== "string" && input?.length === 64 && typeof input[0] === "number") {
334
344
  return _NullTrace.fromSecretKey(input);
335
345
  }
336
346
  if (typeof input === "string") {
@@ -845,11 +855,13 @@ var NullTrace = class _NullTrace {
845
855
  });
846
856
  const preSigs = [];
847
857
  for (let i = 0; i < preTransactions.length; i++) {
848
- const sig = await this.connection.sendRawTransaction(signed[i].serialize());
858
+ const sig = await this.connection.sendRawTransaction(signed[i].serialize(), {
859
+ skipPreflight: true
860
+ });
849
861
  await this.connection.confirmTransaction(sig);
850
862
  preSigs.push(sig);
851
863
  }
852
- const swapId = Keypair.generate().publicKey.toString();
864
+ const swapId = bs58.encode(nacl.randomBytes(32));
853
865
  const swapData = {
854
866
  id: swapId,
855
867
  fromToken: fromMint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nulltrace-sdk",
3
- "version": "1.0.3",
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",