@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 +22 -43
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +12 -39
- package/package.json +4 -4
- package/src/issuer-spark-wallet.ts +19 -43
- package/src/proto/spark.ts +34 -34
- package/src/tests/integration/spark.test.ts +32 -48
- package/src/tests/stress/transfers.test.ts +92 -0
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("@
|
|
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.
|
|
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,
|
|
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,
|
|
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,
|
|
443
|
-
(0,
|
|
417
|
+
(0, import_utils5.hexToBytes)(decodedOwnerPubkey),
|
|
418
|
+
(0, import_utils5.hexToBytes)(tokenPublicKey)
|
|
444
419
|
);
|
|
445
|
-
const tokenAmount = (0,
|
|
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,
|
|
456
|
-
(0,
|
|
434
|
+
(0, import_utils5.hexToBytes)(decodedOwnerPubkey),
|
|
435
|
+
(0, import_utils5.hexToBytes)(tokenPublicKey)
|
|
457
436
|
);
|
|
458
|
-
const tokenAmount = (0,
|
|
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,
|
|
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,
|
|
480
|
-
ownerPublicKey: (0,
|
|
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
package/dist/index.d.ts
CHANGED
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.
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
58
|
-
"@buildonspark/spark-sdk": "0.0.
|
|
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 {
|
|
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.
|
|
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(
|
|
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(
|
|
167
|
+
hexToBytes(decodedOwnerPubkey),
|
|
192
168
|
hexToBytes(tokenPublicKey),
|
|
193
169
|
);
|
|
194
170
|
const tokenAmount = bytesToNumberBE(response.impactedTokenAmount);
|
package/src/proto/spark.ts
CHANGED
|
@@ -204,14 +204,14 @@ export interface NodeSignatures {
|
|
|
204
204
|
refundTxSignature: Uint8Array;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
export interface
|
|
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
|
|
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
|
|
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
|
|
2272
|
-
encode(message:
|
|
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):
|
|
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 =
|
|
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):
|
|
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:
|
|
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<
|
|
2365
|
-
return
|
|
2364
|
+
create(base?: DeepPartial<StartDepositTreeCreationRequest>): StartDepositTreeCreationRequest {
|
|
2365
|
+
return StartDepositTreeCreationRequest.fromPartial(base ?? {});
|
|
2366
2366
|
},
|
|
2367
|
-
fromPartial(object: DeepPartial<
|
|
2368
|
-
const message =
|
|
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
|
|
2383
|
+
function createBaseStartDepositTreeCreationResponse(): StartDepositTreeCreationResponse {
|
|
2384
2384
|
return { treeId: "", rootNodeSignatureShares: undefined };
|
|
2385
2385
|
}
|
|
2386
2386
|
|
|
2387
|
-
export const
|
|
2388
|
-
encode(message:
|
|
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):
|
|
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 =
|
|
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):
|
|
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:
|
|
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<
|
|
2451
|
-
return
|
|
2450
|
+
create(base?: DeepPartial<StartDepositTreeCreationResponse>): StartDepositTreeCreationResponse {
|
|
2451
|
+
return StartDepositTreeCreationResponse.fromPartial(base ?? {});
|
|
2452
2452
|
},
|
|
2453
|
-
fromPartial(object: DeepPartial<
|
|
2454
|
-
const message =
|
|
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
|
-
|
|
10997
|
-
name: "
|
|
10998
|
-
requestType:
|
|
10996
|
+
start_deposit_tree_creation: {
|
|
10997
|
+
name: "start_deposit_tree_creation",
|
|
10998
|
+
requestType: StartDepositTreeCreationRequest,
|
|
10999
10999
|
requestStream: false,
|
|
11000
|
-
responseType:
|
|
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
|
-
|
|
11246
|
-
request:
|
|
11245
|
+
start_deposit_tree_creation(
|
|
11246
|
+
request: StartDepositTreeCreationRequest,
|
|
11247
11247
|
context: CallContext & CallContextExt,
|
|
11248
|
-
): Promise<DeepPartial<
|
|
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
|
-
|
|
11371
|
-
request: DeepPartial<
|
|
11370
|
+
start_deposit_tree_creation(
|
|
11371
|
+
request: DeepPartial<StartDepositTreeCreationRequest>,
|
|
11372
11372
|
options?: CallOptions & CallOptionsExt,
|
|
11373
|
-
): Promise<
|
|
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
|
-
|
|
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
|
|
195
|
-
|
|
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
|
|
223
|
-
|
|
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
|
|
259
|
-
|
|
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
|
|
294
|
-
|
|
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
|
|
340
|
-
|
|
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
|
|
420
|
-
|
|
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:
|
|
426
|
+
receiverSparkAddress: await issuerWallet.getSparkAddress(),
|
|
429
427
|
});
|
|
430
428
|
|
|
431
|
-
const
|
|
432
|
-
|
|
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
|
|
478
|
-
const userBalanceAfterTransfer =
|
|
479
|
-
|
|
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:
|
|
485
|
+
receiverSparkAddress: await issuerWallet.getSparkAddress(),
|
|
488
486
|
});
|
|
489
487
|
|
|
490
|
-
const
|
|
491
|
-
|
|
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
|
+
});
|