@buildonspark/issuer-sdk 0.0.26 → 0.0.28

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.
package/dist/index.cjs CHANGED
@@ -37,10 +37,7 @@ if (typeof global === "undefined") {
37
37
  var import_lrc20_sdk2 = require("@buildonspark/lrc20-sdk");
38
38
  var import_spark_sdk = require("@buildonspark/spark-sdk");
39
39
  var import_address = require("@buildonspark/spark-sdk/address");
40
- var import_utils5 = require("@buildonspark/spark-sdk/utils");
41
- var import_utils6 = require("@noble/curves/abstract/utils");
42
- var import_bip39 = require("@scure/bip39");
43
- var import_english = require("@scure/bip39/wordlists/english");
40
+ var import_utils5 = require("@noble/curves/abstract/utils");
44
41
 
45
42
  // src/services/freeze.ts
46
43
  var import_utils2 = require("@buildonspark/spark-sdk/utils");
@@ -335,6 +332,7 @@ function convertTokenActivityToHexEncoded(rawTransactions) {
335
332
  }
336
333
 
337
334
  // src/issuer-spark-wallet.ts
335
+ var import_address2 = require("@buildonspark/spark-sdk/address");
338
336
  var BURN_ADDRESS = "02".repeat(33);
339
337
  var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkWallet {
340
338
  issuerTokenTransactionService;
@@ -342,7 +340,7 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
342
340
  tokenPublicKeyInfo;
343
341
  static async initialize(options) {
344
342
  const wallet = new _IssuerSparkWallet(options.options);
345
- const initResponse = await wallet.initIssuerWallet(options.mnemonicOrSeed);
343
+ const initResponse = await wallet.initWallet(options.mnemonicOrSeed);
346
344
  return {
347
345
  wallet,
348
346
  ...initResponse
@@ -359,33 +357,6 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
359
357
  this.connectionManager
360
358
  );
361
359
  }
362
- async initIssuerWallet(mnemonicOrSeed) {
363
- const initResponse = await super.initWallet(mnemonicOrSeed);
364
- mnemonicOrSeed = mnemonicOrSeed || initResponse?.mnemonic;
365
- if (mnemonicOrSeed) {
366
- let seed;
367
- if (typeof mnemonicOrSeed !== "string") {
368
- seed = mnemonicOrSeed;
369
- } else {
370
- if ((0, import_bip39.validateMnemonic)(mnemonicOrSeed, import_english.wordlist)) {
371
- seed = await this.config.signer.mnemonicToSeed(mnemonicOrSeed);
372
- } else {
373
- seed = (0, import_utils6.hexToBytes)(mnemonicOrSeed);
374
- }
375
- }
376
- const hdkey = (0, import_utils5.getMasterHDKeyFromSeed)(seed);
377
- const accountType = this.config.getNetwork() === import_utils5.Network.REGTEST ? 0 : 1;
378
- const identityKey = hdkey.derive(`m/8797555'/${accountType}'/0'`);
379
- const network = this.config.getNetwork();
380
- this.lrc20Wallet = new import_lrc20_sdk2.LRCWallet(
381
- (0, import_utils6.bytesToHex)(identityKey.privateKey),
382
- import_utils5.LRC_WALLET_NETWORK[network],
383
- import_utils5.LRC_WALLET_NETWORK_TYPE[network],
384
- this.config.lrc20ApiConfig
385
- );
386
- }
387
- return initResponse;
388
- }
389
360
  async getIssuerTokenBalance() {
390
361
  const publicKey = await super.getIdentityPublicKey();
391
362
  const balanceObj = await this.getBalance();
@@ -402,7 +373,7 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
402
373
  if (this.tokenPublicKeyInfo) {
403
374
  return convertToTokenPubKeyInfoResponse(this.tokenPublicKeyInfo);
404
375
  }
405
- const tokenPublicKey = (0, import_utils6.bytesToHex)(this.lrc20Wallet.pubkey);
376
+ const tokenPublicKey = (0, import_utils5.bytesToHex)(this.lrc20Wallet.pubkey);
406
377
  const rawTokenPubkeyInfo = await this.lrc20Wallet.getTokenPubkeyInfo(tokenPublicKey);
407
378
  this.tokenPublicKeyInfo = rawTokenPubkeyInfo;
408
379
  if (!rawTokenPubkeyInfo) {
@@ -416,7 +387,7 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
416
387
  async mintTokens(tokenAmount) {
417
388
  var tokenPublicKey = await super.getIdentityPublicKey();
418
389
  const tokenTransaction = await this.issuerTokenTransactionService.constructMintTokenTransaction(
419
- (0, import_utils6.hexToBytes)(tokenPublicKey),
390
+ (0, import_utils5.hexToBytes)(tokenPublicKey),
420
391
  tokenAmount
421
392
  );
422
393
  return await this.issuerTokenTransactionService.broadcastTokenTransaction(
@@ -438,11 +409,15 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
438
409
  async freezeTokens(ownerPublicKey) {
439
410
  await this.syncTokenLeaves();
440
411
  const tokenPublicKey = await super.getIdentityPublicKey();
412
+ const decodedOwnerPubkey = (0, import_address2.decodeSparkAddress)(
413
+ ownerPublicKey,
414
+ this.config.getNetworkType()
415
+ );
441
416
  const response = await this.tokenFreezeService.freezeTokens(
442
- (0, import_utils6.hexToBytes)(ownerPublicKey),
443
- (0, import_utils6.hexToBytes)(tokenPublicKey)
417
+ (0, import_utils5.hexToBytes)(decodedOwnerPubkey),
418
+ (0, import_utils5.hexToBytes)(tokenPublicKey)
444
419
  );
445
- const tokenAmount = (0, import_utils6.bytesToNumberBE)(response.impactedTokenAmount);
420
+ const tokenAmount = (0, import_utils5.bytesToNumberBE)(response.impactedTokenAmount);
446
421
  return {
447
422
  impactedLeafIds: response.impactedLeafIds,
448
423
  impactedTokenAmount: tokenAmount
@@ -451,11 +426,15 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
451
426
  async unfreezeTokens(ownerPublicKey) {
452
427
  await this.syncTokenLeaves();
453
428
  const tokenPublicKey = await super.getIdentityPublicKey();
429
+ const decodedOwnerPubkey = (0, import_address2.decodeSparkAddress)(
430
+ ownerPublicKey,
431
+ this.config.getNetworkType()
432
+ );
454
433
  const response = await this.tokenFreezeService.unfreezeTokens(
455
- (0, import_utils6.hexToBytes)(ownerPublicKey),
456
- (0, import_utils6.hexToBytes)(tokenPublicKey)
434
+ (0, import_utils5.hexToBytes)(decodedOwnerPubkey),
435
+ (0, import_utils5.hexToBytes)(tokenPublicKey)
457
436
  );
458
- const tokenAmount = (0, import_utils6.bytesToNumberBE)(response.impactedTokenAmount);
437
+ const tokenAmount = (0, import_utils5.bytesToNumberBE)(response.impactedTokenAmount);
459
438
  return {
460
439
  impactedLeafIds: response.impactedLeafIds,
461
440
  impactedTokenAmount: tokenAmount
@@ -464,7 +443,7 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
464
443
  async getTokenActivity(pageSize = 100, cursor, operationTypes, beforeTimestamp, afterTimestamp) {
465
444
  const lrc20Client = await this.lrc20ConnectionManager.createLrc20Client();
466
445
  const transactions = await lrc20Client.listTransactions({
467
- tokenPublicKey: (0, import_utils6.hexToBytes)(await super.getIdentityPublicKey()),
446
+ tokenPublicKey: (0, import_utils5.hexToBytes)(await super.getIdentityPublicKey()),
468
447
  cursor,
469
448
  pageSize,
470
449
  beforeTimestamp,
@@ -476,8 +455,8 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk.SparkW
476
455
  async getIssuerTokenActivity(pageSize = 100, cursor, operationTypes, beforeTimestamp, afterTimestamp) {
477
456
  const lrc20Client = await this.lrc20ConnectionManager.createLrc20Client();
478
457
  const transactions = await lrc20Client.listTransactions({
479
- tokenPublicKey: (0, import_utils6.hexToBytes)(await super.getIdentityPublicKey()),
480
- ownerPublicKey: (0, import_utils6.hexToBytes)(await super.getIdentityPublicKey()),
458
+ tokenPublicKey: (0, import_utils5.hexToBytes)(await super.getIdentityPublicKey()),
459
+ ownerPublicKey: (0, import_utils5.hexToBytes)(await super.getIdentityPublicKey()),
481
460
  cursor,
482
461
  pageSize,
483
462
  beforeTimestamp,
package/dist/index.d.cts CHANGED
@@ -77,7 +77,6 @@ declare class IssuerSparkWallet extends SparkWallet implements IssuerWalletInter
77
77
  wallet: IssuerSparkWallet;
78
78
  }>;
79
79
  private constructor();
80
- private initIssuerWallet;
81
80
  getIssuerTokenBalance(): Promise<{
82
81
  balance: bigint;
83
82
  }>;
package/dist/index.d.ts CHANGED
@@ -77,7 +77,6 @@ declare class IssuerSparkWallet extends SparkWallet implements IssuerWalletInter
77
77
  wallet: IssuerSparkWallet;
78
78
  }>;
79
79
  private constructor();
80
- private initIssuerWallet;
81
80
  getIssuerTokenBalance(): Promise<{
82
81
  balance: bigint;
83
82
  }>;
package/dist/index.js CHANGED
@@ -2,25 +2,16 @@ import "./chunk-GB7N6I5O.js";
2
2
 
3
3
  // src/issuer-spark-wallet.ts
4
4
  import {
5
- LRCWallet,
6
5
  TokenPubkey,
7
6
  TokenPubkeyAnnouncement
8
7
  } from "@buildonspark/lrc20-sdk";
9
8
  import { SparkWallet } from "@buildonspark/spark-sdk";
10
9
  import { encodeSparkAddress } from "@buildonspark/spark-sdk/address";
11
- import {
12
- getMasterHDKeyFromSeed,
13
- LRC_WALLET_NETWORK,
14
- LRC_WALLET_NETWORK_TYPE,
15
- Network
16
- } from "@buildonspark/spark-sdk/utils";
17
10
  import {
18
11
  bytesToHex as bytesToHex2,
19
12
  bytesToNumberBE as bytesToNumberBE2,
20
13
  hexToBytes
21
14
  } from "@noble/curves/abstract/utils";
22
- import { validateMnemonic } from "@scure/bip39";
23
- import { wordlist } from "@scure/bip39/wordlists/english";
24
15
 
25
16
  // src/services/freeze.ts
26
17
  import { validateResponses } from "@buildonspark/spark-sdk/utils";
@@ -315,6 +306,7 @@ function convertTokenActivityToHexEncoded(rawTransactions) {
315
306
  }
316
307
 
317
308
  // src/issuer-spark-wallet.ts
309
+ import { decodeSparkAddress } from "@buildonspark/spark-sdk/address";
318
310
  var BURN_ADDRESS = "02".repeat(33);
319
311
  var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
320
312
  issuerTokenTransactionService;
@@ -322,7 +314,7 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
322
314
  tokenPublicKeyInfo;
323
315
  static async initialize(options) {
324
316
  const wallet = new _IssuerSparkWallet(options.options);
325
- const initResponse = await wallet.initIssuerWallet(options.mnemonicOrSeed);
317
+ const initResponse = await wallet.initWallet(options.mnemonicOrSeed);
326
318
  return {
327
319
  wallet,
328
320
  ...initResponse
@@ -339,33 +331,6 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
339
331
  this.connectionManager
340
332
  );
341
333
  }
342
- async initIssuerWallet(mnemonicOrSeed) {
343
- const initResponse = await super.initWallet(mnemonicOrSeed);
344
- mnemonicOrSeed = mnemonicOrSeed || initResponse?.mnemonic;
345
- if (mnemonicOrSeed) {
346
- let seed;
347
- if (typeof mnemonicOrSeed !== "string") {
348
- seed = mnemonicOrSeed;
349
- } else {
350
- if (validateMnemonic(mnemonicOrSeed, wordlist)) {
351
- seed = await this.config.signer.mnemonicToSeed(mnemonicOrSeed);
352
- } else {
353
- seed = hexToBytes(mnemonicOrSeed);
354
- }
355
- }
356
- const hdkey = getMasterHDKeyFromSeed(seed);
357
- const accountType = this.config.getNetwork() === Network.REGTEST ? 0 : 1;
358
- const identityKey = hdkey.derive(`m/8797555'/${accountType}'/0'`);
359
- const network = this.config.getNetwork();
360
- this.lrc20Wallet = new LRCWallet(
361
- bytesToHex2(identityKey.privateKey),
362
- LRC_WALLET_NETWORK[network],
363
- LRC_WALLET_NETWORK_TYPE[network],
364
- this.config.lrc20ApiConfig
365
- );
366
- }
367
- return initResponse;
368
- }
369
334
  async getIssuerTokenBalance() {
370
335
  const publicKey = await super.getIdentityPublicKey();
371
336
  const balanceObj = await this.getBalance();
@@ -418,8 +383,12 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
418
383
  async freezeTokens(ownerPublicKey) {
419
384
  await this.syncTokenLeaves();
420
385
  const tokenPublicKey = await super.getIdentityPublicKey();
386
+ const decodedOwnerPubkey = decodeSparkAddress(
387
+ ownerPublicKey,
388
+ this.config.getNetworkType()
389
+ );
421
390
  const response = await this.tokenFreezeService.freezeTokens(
422
- hexToBytes(ownerPublicKey),
391
+ hexToBytes(decodedOwnerPubkey),
423
392
  hexToBytes(tokenPublicKey)
424
393
  );
425
394
  const tokenAmount = bytesToNumberBE2(response.impactedTokenAmount);
@@ -431,8 +400,12 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
431
400
  async unfreezeTokens(ownerPublicKey) {
432
401
  await this.syncTokenLeaves();
433
402
  const tokenPublicKey = await super.getIdentityPublicKey();
403
+ const decodedOwnerPubkey = decodeSparkAddress(
404
+ ownerPublicKey,
405
+ this.config.getNetworkType()
406
+ );
434
407
  const response = await this.tokenFreezeService.unfreezeTokens(
435
- hexToBytes(ownerPublicKey),
408
+ hexToBytes(decodedOwnerPubkey),
436
409
  hexToBytes(tokenPublicKey)
437
410
  );
438
411
  const tokenAmount = bytesToNumberBE2(response.impactedTokenAmount);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildonspark/issuer-sdk",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "Spark Issuer SDK for token issuance",
5
5
  "license": "Apache-2.0",
6
6
  "module": "./dist/index.js",
@@ -30,7 +30,6 @@
30
30
  ],
31
31
  "scripts": {
32
32
  "build": "yarn tsc && tsup",
33
- "prepare": "yarn run build",
34
33
  "build:watch": "yarn build --watch --clean=false",
35
34
  "clean": "rm -rf dist",
36
35
  "circular-deps": "madge --circular --extensions ts,tsx src",
@@ -48,14 +47,15 @@
48
47
  "test-cmd": "node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand",
49
48
  "test": "echo \"Error: no tests yet\"",
50
49
  "test:integration": "yarn test-cmd src/tests/integration/*.test.ts",
50
+ "test:stress": "yarn test-cmd src/tests/stress/*.test.ts",
51
51
  "types:watch": "tsc-absolute --watch",
52
52
  "types": "tsc",
53
53
  "generate:proto": "PATH=\"$PATH:./node_modules/.bin\" protoc --ts_proto_out=./src/proto --ts_proto_opt=outputServices=nice-grpc,useExactTypes=false,outputServices=generic-definitions,oneof=unions,importSuffix=.js --proto_path=../../protos spark.proto mock.proto spark_authn.proto"
54
54
  },
55
55
  "dependencies": {
56
56
  "@bufbuild/protobuf": "^2.2.5",
57
- "@buildonspark/lrc20-sdk": "0.0.24",
58
- "@buildonspark/spark-sdk": "0.0.26",
57
+ "@buildonspark/lrc20-sdk": "0.0.26",
58
+ "@buildonspark/spark-sdk": "0.0.28",
59
59
  "@noble/curves": "^1.8.0",
60
60
  "@scure/bip39": "^1.5.4",
61
61
  "@scure/btc-signer": "^1.5.0",
@@ -2,9 +2,12 @@ import {
2
2
  LRCWallet,
3
3
  TokenPubkey,
4
4
  TokenPubkeyAnnouncement,
5
- TokenPubkeyInfo
5
+ TokenPubkeyInfo,
6
6
  } from "@buildonspark/lrc20-sdk";
7
- import { ListAllTokenTransactionsCursor, OperationType } from "@buildonspark/lrc20-sdk/proto/rpc/v1/types";
7
+ import {
8
+ ListAllTokenTransactionsCursor,
9
+ OperationType,
10
+ } from "@buildonspark/lrc20-sdk/proto/rpc/v1/types";
8
11
  import { SparkWallet, SparkWalletProps } from "@buildonspark/spark-sdk";
9
12
  import { encodeSparkAddress } from "@buildonspark/spark-sdk/address";
10
13
  import { LeafWithPreviousTransactionData } from "@buildonspark/spark-sdk/proto/spark";
@@ -30,12 +33,14 @@ import {
30
33
  convertTokenActivityToHexEncoded,
31
34
  convertToTokenPubKeyInfoResponse,
32
35
  } from "./utils/type-mappers.js";
36
+ import { decodeSparkAddress } from "@buildonspark/spark-sdk/address";
33
37
 
34
38
  const BURN_ADDRESS = "02".repeat(33);
35
39
 
36
40
  export class IssuerSparkWallet
37
41
  extends SparkWallet
38
- implements IssuerWalletInterface {
42
+ implements IssuerWalletInterface
43
+ {
39
44
  private issuerTokenTransactionService: IssuerTokenTransactionService;
40
45
  private tokenFreezeService: TokenFreezeService;
41
46
  private tokenPublicKeyInfo?: TokenPubkeyInfo;
@@ -43,7 +48,7 @@ export class IssuerSparkWallet
43
48
  public static async initialize(options: SparkWalletProps) {
44
49
  const wallet = new IssuerSparkWallet(options.options);
45
50
 
46
- const initResponse = await wallet.initIssuerWallet(options.mnemonicOrSeed);
51
+ const initResponse = await wallet.initWallet(options.mnemonicOrSeed);
47
52
  return {
48
53
  wallet,
49
54
  ...initResponse,
@@ -62,39 +67,6 @@ export class IssuerSparkWallet
62
67
  );
63
68
  }
64
69
 
65
- private async initIssuerWallet(mnemonicOrSeed?: string | Uint8Array) {
66
- const initResponse = await super.initWallet(mnemonicOrSeed);
67
-
68
- // TODO: Remove this in subsequent PRs when LRC20Wallet has a proper signer interface
69
- mnemonicOrSeed = mnemonicOrSeed || initResponse?.mnemonic;
70
- if (mnemonicOrSeed) {
71
- let seed: Uint8Array;
72
- if (typeof mnemonicOrSeed !== "string") {
73
- seed = mnemonicOrSeed;
74
- } else {
75
- if (validateMnemonic(mnemonicOrSeed, wordlist)) {
76
- seed = await this.config.signer.mnemonicToSeed(mnemonicOrSeed);
77
- } else {
78
- seed = hexToBytes(mnemonicOrSeed);
79
- }
80
- }
81
-
82
- const hdkey = getMasterHDKeyFromSeed(seed);
83
- const accountType = this.config.getNetwork() === Network.REGTEST ? 0 : 1;
84
- const identityKey = hdkey.derive(`m/8797555'/${accountType}'/0'`);
85
-
86
- const network = this.config.getNetwork();
87
- this.lrc20Wallet = new LRCWallet(
88
- bytesToHex(identityKey.privateKey!),
89
- LRC_WALLET_NETWORK[network],
90
- LRC_WALLET_NETWORK_TYPE[network],
91
- this.config.lrc20ApiConfig
92
- );
93
- }
94
-
95
- return initResponse;
96
- }
97
-
98
70
  public async getIssuerTokenBalance(): Promise<{
99
71
  balance: bigint;
100
72
  }> {
@@ -115,11 +87,9 @@ export class IssuerSparkWallet
115
87
  if (this.tokenPublicKeyInfo) {
116
88
  return convertToTokenPubKeyInfoResponse(this.tokenPublicKeyInfo);
117
89
  }
118
-
119
90
  const tokenPublicKey = bytesToHex(this.lrc20Wallet!.pubkey);
120
91
  const rawTokenPubkeyInfo =
121
92
  await this.lrc20Wallet!.getTokenPubkeyInfo(tokenPublicKey);
122
-
123
93
  this.tokenPublicKeyInfo = rawTokenPubkeyInfo;
124
94
  if (!rawTokenPubkeyInfo) {
125
95
  return null;
@@ -166,9 +136,12 @@ export class IssuerSparkWallet
166
136
  ): Promise<{ impactedLeafIds: string[]; impactedTokenAmount: bigint }> {
167
137
  await this.syncTokenLeaves();
168
138
  const tokenPublicKey = await super.getIdentityPublicKey();
169
-
139
+ const decodedOwnerPubkey = decodeSparkAddress(
140
+ ownerPublicKey,
141
+ this.config.getNetworkType(),
142
+ );
170
143
  const response = await this.tokenFreezeService!.freezeTokens(
171
- hexToBytes(ownerPublicKey),
144
+ hexToBytes(decodedOwnerPubkey),
172
145
  hexToBytes(tokenPublicKey),
173
146
  );
174
147
 
@@ -186,9 +159,12 @@ export class IssuerSparkWallet
186
159
  ): Promise<{ impactedLeafIds: string[]; impactedTokenAmount: bigint }> {
187
160
  await this.syncTokenLeaves();
188
161
  const tokenPublicKey = await super.getIdentityPublicKey();
189
-
162
+ const decodedOwnerPubkey = decodeSparkAddress(
163
+ ownerPublicKey,
164
+ this.config.getNetworkType(),
165
+ );
190
166
  const response = await this.tokenFreezeService!.unfreezeTokens(
191
- hexToBytes(ownerPublicKey),
167
+ hexToBytes(decodedOwnerPubkey),
192
168
  hexToBytes(tokenPublicKey),
193
169
  );
194
170
  const tokenAmount = bytesToNumberBE(response.impactedTokenAmount);
@@ -204,14 +204,14 @@ export interface NodeSignatures {
204
204
  refundTxSignature: Uint8Array;
205
205
  }
206
206
 
207
- export interface StartTreeCreationRequest {
207
+ export interface StartDepositTreeCreationRequest {
208
208
  identityPublicKey: Uint8Array;
209
209
  onChainUtxo: UTXO | undefined;
210
210
  rootTxSigningJob: SigningJob | undefined;
211
211
  refundTxSigningJob: SigningJob | undefined;
212
212
  }
213
213
 
214
- export interface StartTreeCreationResponse {
214
+ export interface StartDepositTreeCreationResponse {
215
215
  treeId: string;
216
216
  rootNodeSignatureShares: NodeSignatureShares | undefined;
217
217
  }
@@ -2259,7 +2259,7 @@ export const NodeSignatures: MessageFns<NodeSignatures> = {
2259
2259
  },
2260
2260
  };
2261
2261
 
2262
- function createBaseStartTreeCreationRequest(): StartTreeCreationRequest {
2262
+ function createBaseStartDepositTreeCreationRequest(): StartDepositTreeCreationRequest {
2263
2263
  return {
2264
2264
  identityPublicKey: new Uint8Array(0),
2265
2265
  onChainUtxo: undefined,
@@ -2268,8 +2268,8 @@ function createBaseStartTreeCreationRequest(): StartTreeCreationRequest {
2268
2268
  };
2269
2269
  }
2270
2270
 
2271
- export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2272
- encode(message: StartTreeCreationRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
2271
+ export const StartDepositTreeCreationRequest: MessageFns<StartDepositTreeCreationRequest> = {
2272
+ encode(message: StartDepositTreeCreationRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
2273
2273
  if (message.identityPublicKey.length !== 0) {
2274
2274
  writer.uint32(10).bytes(message.identityPublicKey);
2275
2275
  }
@@ -2285,10 +2285,10 @@ export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2285
2285
  return writer;
2286
2286
  },
2287
2287
 
2288
- decode(input: BinaryReader | Uint8Array, length?: number): StartTreeCreationRequest {
2288
+ decode(input: BinaryReader | Uint8Array, length?: number): StartDepositTreeCreationRequest {
2289
2289
  const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
2290
2290
  let end = length === undefined ? reader.len : reader.pos + length;
2291
- const message = createBaseStartTreeCreationRequest();
2291
+ const message = createBaseStartDepositTreeCreationRequest();
2292
2292
  while (reader.pos < end) {
2293
2293
  const tag = reader.uint32();
2294
2294
  switch (tag >>> 3) {
@@ -2333,7 +2333,7 @@ export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2333
2333
  return message;
2334
2334
  },
2335
2335
 
2336
- fromJSON(object: any): StartTreeCreationRequest {
2336
+ fromJSON(object: any): StartDepositTreeCreationRequest {
2337
2337
  return {
2338
2338
  identityPublicKey: isSet(object.identityPublicKey)
2339
2339
  ? bytesFromBase64(object.identityPublicKey)
@@ -2344,7 +2344,7 @@ export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2344
2344
  };
2345
2345
  },
2346
2346
 
2347
- toJSON(message: StartTreeCreationRequest): unknown {
2347
+ toJSON(message: StartDepositTreeCreationRequest): unknown {
2348
2348
  const obj: any = {};
2349
2349
  if (message.identityPublicKey.length !== 0) {
2350
2350
  obj.identityPublicKey = base64FromBytes(message.identityPublicKey);
@@ -2361,11 +2361,11 @@ export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2361
2361
  return obj;
2362
2362
  },
2363
2363
 
2364
- create(base?: DeepPartial<StartTreeCreationRequest>): StartTreeCreationRequest {
2365
- return StartTreeCreationRequest.fromPartial(base ?? {});
2364
+ create(base?: DeepPartial<StartDepositTreeCreationRequest>): StartDepositTreeCreationRequest {
2365
+ return StartDepositTreeCreationRequest.fromPartial(base ?? {});
2366
2366
  },
2367
- fromPartial(object: DeepPartial<StartTreeCreationRequest>): StartTreeCreationRequest {
2368
- const message = createBaseStartTreeCreationRequest();
2367
+ fromPartial(object: DeepPartial<StartDepositTreeCreationRequest>): StartDepositTreeCreationRequest {
2368
+ const message = createBaseStartDepositTreeCreationRequest();
2369
2369
  message.identityPublicKey = object.identityPublicKey ?? new Uint8Array(0);
2370
2370
  message.onChainUtxo = (object.onChainUtxo !== undefined && object.onChainUtxo !== null)
2371
2371
  ? UTXO.fromPartial(object.onChainUtxo)
@@ -2380,12 +2380,12 @@ export const StartTreeCreationRequest: MessageFns<StartTreeCreationRequest> = {
2380
2380
  },
2381
2381
  };
2382
2382
 
2383
- function createBaseStartTreeCreationResponse(): StartTreeCreationResponse {
2383
+ function createBaseStartDepositTreeCreationResponse(): StartDepositTreeCreationResponse {
2384
2384
  return { treeId: "", rootNodeSignatureShares: undefined };
2385
2385
  }
2386
2386
 
2387
- export const StartTreeCreationResponse: MessageFns<StartTreeCreationResponse> = {
2388
- encode(message: StartTreeCreationResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
2387
+ export const StartDepositTreeCreationResponse: MessageFns<StartDepositTreeCreationResponse> = {
2388
+ encode(message: StartDepositTreeCreationResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
2389
2389
  if (message.treeId !== "") {
2390
2390
  writer.uint32(10).string(message.treeId);
2391
2391
  }
@@ -2395,10 +2395,10 @@ export const StartTreeCreationResponse: MessageFns<StartTreeCreationResponse> =
2395
2395
  return writer;
2396
2396
  },
2397
2397
 
2398
- decode(input: BinaryReader | Uint8Array, length?: number): StartTreeCreationResponse {
2398
+ decode(input: BinaryReader | Uint8Array, length?: number): StartDepositTreeCreationResponse {
2399
2399
  const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
2400
2400
  let end = length === undefined ? reader.len : reader.pos + length;
2401
- const message = createBaseStartTreeCreationResponse();
2401
+ const message = createBaseStartDepositTreeCreationResponse();
2402
2402
  while (reader.pos < end) {
2403
2403
  const tag = reader.uint32();
2404
2404
  switch (tag >>> 3) {
@@ -2427,7 +2427,7 @@ export const StartTreeCreationResponse: MessageFns<StartTreeCreationResponse> =
2427
2427
  return message;
2428
2428
  },
2429
2429
 
2430
- fromJSON(object: any): StartTreeCreationResponse {
2430
+ fromJSON(object: any): StartDepositTreeCreationResponse {
2431
2431
  return {
2432
2432
  treeId: isSet(object.treeId) ? globalThis.String(object.treeId) : "",
2433
2433
  rootNodeSignatureShares: isSet(object.rootNodeSignatureShares)
@@ -2436,7 +2436,7 @@ export const StartTreeCreationResponse: MessageFns<StartTreeCreationResponse> =
2436
2436
  };
2437
2437
  },
2438
2438
 
2439
- toJSON(message: StartTreeCreationResponse): unknown {
2439
+ toJSON(message: StartDepositTreeCreationResponse): unknown {
2440
2440
  const obj: any = {};
2441
2441
  if (message.treeId !== "") {
2442
2442
  obj.treeId = message.treeId;
@@ -2447,11 +2447,11 @@ export const StartTreeCreationResponse: MessageFns<StartTreeCreationResponse> =
2447
2447
  return obj;
2448
2448
  },
2449
2449
 
2450
- create(base?: DeepPartial<StartTreeCreationResponse>): StartTreeCreationResponse {
2451
- return StartTreeCreationResponse.fromPartial(base ?? {});
2450
+ create(base?: DeepPartial<StartDepositTreeCreationResponse>): StartDepositTreeCreationResponse {
2451
+ return StartDepositTreeCreationResponse.fromPartial(base ?? {});
2452
2452
  },
2453
- fromPartial(object: DeepPartial<StartTreeCreationResponse>): StartTreeCreationResponse {
2454
- const message = createBaseStartTreeCreationResponse();
2453
+ fromPartial(object: DeepPartial<StartDepositTreeCreationResponse>): StartDepositTreeCreationResponse {
2454
+ const message = createBaseStartDepositTreeCreationResponse();
2455
2455
  message.treeId = object.treeId ?? "";
2456
2456
  message.rootNodeSignatureShares =
2457
2457
  (object.rootNodeSignatureShares !== undefined && object.rootNodeSignatureShares !== null)
@@ -10993,11 +10993,11 @@ export const SparkServiceDefinition = {
10993
10993
  responseStream: false,
10994
10994
  options: {},
10995
10995
  },
10996
- start_tree_creation: {
10997
- name: "start_tree_creation",
10998
- requestType: StartTreeCreationRequest,
10996
+ start_deposit_tree_creation: {
10997
+ name: "start_deposit_tree_creation",
10998
+ requestType: StartDepositTreeCreationRequest,
10999
10999
  requestStream: false,
11000
- responseType: StartTreeCreationResponse,
11000
+ responseType: StartDepositTreeCreationResponse,
11001
11001
  responseStream: false,
11002
11002
  options: {},
11003
11003
  },
@@ -11242,10 +11242,10 @@ export interface SparkServiceImplementation<CallContextExt = {}> {
11242
11242
  request: GenerateDepositAddressRequest,
11243
11243
  context: CallContext & CallContextExt,
11244
11244
  ): Promise<DeepPartial<GenerateDepositAddressResponse>>;
11245
- start_tree_creation(
11246
- request: StartTreeCreationRequest,
11245
+ start_deposit_tree_creation(
11246
+ request: StartDepositTreeCreationRequest,
11247
11247
  context: CallContext & CallContextExt,
11248
- ): Promise<DeepPartial<StartTreeCreationResponse>>;
11248
+ ): Promise<DeepPartial<StartDepositTreeCreationResponse>>;
11249
11249
  finalize_node_signatures(
11250
11250
  request: FinalizeNodeSignaturesRequest,
11251
11251
  context: CallContext & CallContextExt,
@@ -11367,10 +11367,10 @@ export interface SparkServiceClient<CallOptionsExt = {}> {
11367
11367
  request: DeepPartial<GenerateDepositAddressRequest>,
11368
11368
  options?: CallOptions & CallOptionsExt,
11369
11369
  ): Promise<GenerateDepositAddressResponse>;
11370
- start_tree_creation(
11371
- request: DeepPartial<StartTreeCreationRequest>,
11370
+ start_deposit_tree_creation(
11371
+ request: DeepPartial<StartDepositTreeCreationRequest>,
11372
11372
  options?: CallOptions & CallOptionsExt,
11373
- ): Promise<StartTreeCreationResponse>;
11373
+ ): Promise<StartDepositTreeCreationResponse>;
11374
11374
  finalize_node_signatures(
11375
11375
  request: DeepPartial<FinalizeNodeSignaturesRequest>,
11376
11376
  options?: CallOptions & CallOptionsExt,
@@ -7,13 +7,10 @@ import {
7
7
  } from "../../../../spark-sdk/src/services/wallet-config.js";
8
8
  import { BitcoinFaucet } from "../../../../spark-sdk/src/tests/utils/test-faucet.js";
9
9
  import { IssuerSparkWallet } from "../../issuer-spark-wallet.js";
10
+ import { filterTokenBalanceForTokenPublicKey } from "@buildonspark/spark-sdk/utils";
10
11
 
11
12
  describe("token integration test", () => {
12
- // Skip all tests if running in GitHub Actions
13
- process.env.GITHUB_ACTIONS ? it.skip : it;
14
-
15
- // Increase timeout for all tests in this suite
16
- jest.setTimeout(60000);
13
+ jest.setTimeout(80000);
17
14
 
18
15
  it("should issue a single token with ECDSA", async () => {
19
16
  const tokenAmount: bigint = 1000n;
@@ -191,8 +188,9 @@ describe("token integration test", () => {
191
188
  expect(sourceBalance.balance).toEqual(0n);
192
189
 
193
190
  const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
194
- const destinationBalance = await getSparkWalletTokenBalanceOrZero(
195
- destinationWallet,
191
+ const balanceObj = await destinationWallet.getBalance();
192
+ const destinationBalance = filterTokenBalanceForTokenPublicKey(
193
+ balanceObj?.tokenBalances,
196
194
  tokenPublicKey,
197
195
  );
198
196
  expect(destinationBalance.balance).toEqual(tokenAmount);
@@ -219,8 +217,9 @@ describe("token integration test", () => {
219
217
  expect(sourceBalance.balance).toEqual(0n);
220
218
 
221
219
  const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
222
- const destinationBalance = await getSparkWalletTokenBalanceOrZero(
223
- destinationWallet,
220
+ const balanceObj = await destinationWallet.getBalance();
221
+ const destinationBalance = filterTokenBalanceForTokenPublicKey(
222
+ balanceObj?.tokenBalances,
224
223
  tokenPublicKey,
225
224
  );
226
225
  expect(destinationBalance.balance).toEqual(tokenAmount);
@@ -253,10 +252,10 @@ describe("token integration test", () => {
253
252
  });
254
253
  const sourceBalance = await issuerWallet.getIssuerTokenBalance();
255
254
  expect(sourceBalance.balance).toEqual(0n);
256
-
257
255
  const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
258
- const destinationBalance = await getSparkWalletTokenBalanceOrZero(
259
- destinationWallet,
256
+ const balanceObj = await destinationWallet.getBalance();
257
+ const destinationBalance = filterTokenBalanceForTokenPublicKey(
258
+ balanceObj?.tokenBalances,
260
259
  tokenPublicKey,
261
260
  );
262
261
  expect(destinationBalance.balance).toEqual(tokenAmount);
@@ -284,18 +283,17 @@ describe("token integration test", () => {
284
283
  tokenPublicKey: await issuerWallet.getIdentityPublicKey(),
285
284
  receiverSparkAddress: userWalletPublicKey,
286
285
  });
287
-
288
286
  const issuerBalanceAfterTransfer =
289
287
  await issuerWallet.getIssuerTokenBalance();
290
288
  expect(issuerBalanceAfterTransfer.balance).toEqual(0n);
291
289
 
292
290
  const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
293
- const userBalanceAfterTransfer = await getSparkWalletTokenBalanceOrZero(
294
- userWallet,
291
+ const userBalanceObj = await userWallet.getBalance();
292
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
293
+ userBalanceObj?.tokenBalances,
295
294
  tokenPublicKey,
296
295
  );
297
296
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
298
-
299
297
  // Freeze tokens
300
298
  const freezeResponse = await issuerWallet.freezeTokens(userWalletPublicKey);
301
299
  expect(freezeResponse.impactedLeafIds.length).toBeGreaterThan(0);
@@ -336,8 +334,9 @@ describe("token integration test", () => {
336
334
  expect(issuerBalanceAfterTransfer.balance).toEqual(0n);
337
335
 
338
336
  const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
339
- const userBalanceAfterTransfer = await getSparkWalletTokenBalanceOrZero(
340
- userWallet,
337
+ const userBalanceObj = await userWallet.getBalance();
338
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
339
+ userBalanceObj?.tokenBalances,
341
340
  tokenPublicKey,
342
341
  );
343
342
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
@@ -413,32 +412,31 @@ describe("token integration test", () => {
413
412
  const issuerBalanceAfterTransfer =
414
413
  await issuerWallet.getIssuerTokenBalance();
415
414
  expect(issuerBalanceAfterTransfer.balance).toEqual(0n);
416
-
417
415
  const tokenPublicKeyHex = await issuerWallet.getIdentityPublicKey();
418
416
  const userWalletPublicKeyHex = await userWallet.getSparkAddress();
419
- const userBalanceAfterTransfer = await getSparkWalletTokenBalanceOrZero(
420
- userWallet,
417
+ const userBalanceObj = await userWallet.getBalance();
418
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
419
+ userBalanceObj?.tokenBalances,
421
420
  tokenPublicKeyHex,
422
421
  );
423
422
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
424
-
425
423
  await userWallet.transferTokens({
426
424
  tokenPublicKey: tokenPublicKeyHex,
427
425
  tokenAmount,
428
- receiverSparkAddress: userWalletPublicKeyHex,
426
+ receiverSparkAddress: await issuerWallet.getSparkAddress(),
429
427
  });
430
428
 
431
- const userBalanceAfterTransferBack = await getSparkWalletTokenBalanceOrZero(
432
- userWallet,
429
+ const userBalanceObjAfterTransferBack = await userWallet.getBalance();
430
+ const userBalanceAfterTransferBack = filterTokenBalanceForTokenPublicKey(
431
+ userBalanceObjAfterTransferBack?.tokenBalances,
433
432
  tokenPublicKeyHex,
434
433
  );
434
+
435
435
  expect(userBalanceAfterTransferBack.balance).toEqual(0n);
436
436
 
437
437
  const issuerTokenBalance = await issuerWallet.getIssuerTokenBalance();
438
438
  expect(issuerTokenBalance.balance).toEqual(tokenAmount);
439
-
440
439
  await issuerWallet.burnTokens(tokenAmount);
441
-
442
440
  const issuerTokenBalanceAfterBurn =
443
441
  await issuerWallet.getIssuerTokenBalance();
444
442
  expect(issuerTokenBalanceAfterBurn.balance).toEqual(0n);
@@ -474,9 +472,9 @@ describe("token integration test", () => {
474
472
  expect(issuerBalanceAfterTransfer.balance).toEqual(0n);
475
473
 
476
474
  const tokenPublicKeyHex = await issuerWallet.getIdentityPublicKey();
477
- const userWalletPublicKeyHex = await userWallet.getSparkAddress();
478
- const userBalanceAfterTransfer = await getSparkWalletTokenBalanceOrZero(
479
- userWallet,
475
+ const userBalanceObj = await userWallet.getBalance();
476
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
477
+ userBalanceObj?.tokenBalances,
480
478
  tokenPublicKeyHex,
481
479
  );
482
480
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
@@ -484,11 +482,12 @@ describe("token integration test", () => {
484
482
  await userWallet.transferTokens({
485
483
  tokenPublicKey: tokenPublicKeyHex,
486
484
  tokenAmount,
487
- receiverSparkAddress: userWalletPublicKeyHex,
485
+ receiverSparkAddress: await issuerWallet.getSparkAddress(),
488
486
  });
489
487
 
490
- const userBalanceAfterTransferBack = await getSparkWalletTokenBalanceOrZero(
491
- userWallet,
488
+ const userBalanceObjAfterTransferBack = await userWallet.getBalance();
489
+ const userBalanceAfterTransferBack = filterTokenBalanceForTokenPublicKey(
490
+ userBalanceObjAfterTransferBack?.tokenBalances,
492
491
  tokenPublicKeyHex,
493
492
  );
494
493
  expect(userBalanceAfterTransferBack.balance).toEqual(0n);
@@ -503,18 +502,3 @@ describe("token integration test", () => {
503
502
  expect(issuerTokenBalanceAfterBurn.balance).toEqual(0n);
504
503
  });
505
504
  });
506
-
507
- async function getSparkWalletTokenBalanceOrZero(
508
- sparkWallet: SparkWallet,
509
- publicKey: string,
510
- ): Promise<{ balance: bigint }> {
511
- const balanceObj = await sparkWallet.getBalance();
512
- if (!balanceObj.tokenBalances || !balanceObj.tokenBalances.has(publicKey)) {
513
- return {
514
- balance: 0n,
515
- };
516
- }
517
- return {
518
- balance: balanceObj.tokenBalances.get(publicKey)!.balance,
519
- };
520
- }
@@ -0,0 +1,92 @@
1
+ import { IssuerSparkWallet } from "../../issuer-spark-wallet.js";
2
+ import { jest } from "@jest/globals";
3
+ import { LOCAL_WALLET_CONFIG_ECDSA } from "../../../../spark-sdk/src/services/wallet-config.js";
4
+ import { SparkWallet } from "@buildonspark/spark-sdk";
5
+ import { filterTokenBalanceForTokenPublicKey } from "@buildonspark/spark-sdk/utils";
6
+
7
+ const TEST_TIMEOUT = 80000; // 80 seconds
8
+
9
+ describe("Stress test for token transfers", () => {
10
+ jest.setTimeout(TEST_TIMEOUT);
11
+
12
+ let timeoutReached = false;
13
+ let timeoutId: NodeJS.Timeout;
14
+
15
+ beforeEach(() => {
16
+ timeoutReached = false;
17
+ timeoutId = setTimeout(() => {
18
+ timeoutReached = true;
19
+ }, TEST_TIMEOUT);
20
+ });
21
+
22
+ afterEach(() => {
23
+ clearTimeout(timeoutId);
24
+ });
25
+
26
+ it("[Spark] wallets should successfully complete multiple token transactions in rapid succession (5 TPS)", async () => {
27
+ // Iteration: IssuerSparkWallet -> SparkWallet -> IssuerSparkWallet
28
+ // 2 transactions per iteration
29
+ // (2 transactions * 200 iterations) / 80 seconds = 5 TPS
30
+ const MAX_ITERATIONS = 200;
31
+ const TOKEN_AMOUNT: bigint = 1000n;
32
+
33
+ const { wallet: issuerWallet } = await IssuerSparkWallet.initialize({
34
+ options: LOCAL_WALLET_CONFIG_ECDSA,
35
+ });
36
+ const { wallet: userWallet } = await SparkWallet.initialize({
37
+ options: LOCAL_WALLET_CONFIG_ECDSA,
38
+ });
39
+
40
+ await issuerWallet.mintTokens(TOKEN_AMOUNT);
41
+ const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
42
+ const userWalletSparkAddress = await userWallet.getSparkAddress();
43
+ const issuerWalletSparkAddress = await issuerWallet.getSparkAddress();
44
+
45
+ for (let i = 0; i < MAX_ITERATIONS; i++) {
46
+ if (timeoutReached) {
47
+ console.log(
48
+ "Timeout reached, stopping iterations at idx: " +
49
+ i +
50
+ " of " +
51
+ MAX_ITERATIONS,
52
+ );
53
+ break;
54
+ }
55
+ try {
56
+ // Transfer tokens from issuer to user
57
+ await issuerWallet.transferTokens({
58
+ tokenPublicKey,
59
+ tokenAmount: TOKEN_AMOUNT,
60
+ receiverSparkAddress: userWalletSparkAddress,
61
+ });
62
+ const issuerBalance = await issuerWallet.getIssuerTokenBalance();
63
+ const userBalanceObj = await userWallet.getBalance();
64
+ const userBalance = filterTokenBalanceForTokenPublicKey(
65
+ userBalanceObj?.tokenBalances,
66
+ tokenPublicKey,
67
+ );
68
+ expect(issuerBalance.balance).toEqual(0n);
69
+ expect(userBalance.balance).toEqual(TOKEN_AMOUNT);
70
+
71
+ // Transfer tokens from user to issuer
72
+ await userWallet.transferTokens({
73
+ tokenPublicKey,
74
+ tokenAmount: TOKEN_AMOUNT,
75
+ receiverSparkAddress: issuerWalletSparkAddress,
76
+ });
77
+ const userBalanceObjAfterTransferBack = await userWallet.getBalance();
78
+ const userBalanceAfterTransferBack =
79
+ filterTokenBalanceForTokenPublicKey(
80
+ userBalanceObjAfterTransferBack?.tokenBalances,
81
+ tokenPublicKey,
82
+ );
83
+ const issuerBalanceAfterTransferBack =
84
+ await issuerWallet.getIssuerTokenBalance();
85
+ expect(userBalanceAfterTransferBack.balance).toEqual(0n);
86
+ expect(issuerBalanceAfterTransferBack.balance).toEqual(TOKEN_AMOUNT);
87
+ } catch (error: any) {
88
+ throw new Error(`Test failed on iteration ${i}: ${error}`);
89
+ }
90
+ }
91
+ });
92
+ });