@buildonspark/issuer-sdk 0.1.4 → 0.1.6
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/CHANGELOG.md +22 -0
- package/dist/index.browser.d.ts +13 -3
- package/dist/index.browser.js +107 -115
- package/dist/index.node.cjs +107 -115
- package/dist/index.node.d.cts +13 -3
- package/dist/index.node.d.ts +13 -3
- package/dist/index.node.js +107 -115
- package/dist/native/index.react-native.cjs +107 -115
- package/dist/native/index.react-native.d.cts +13 -3
- package/dist/native/index.react-native.d.ts +13 -3
- package/dist/native/index.react-native.js +107 -115
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/package.json +2 -2
- package/src/issuer-wallet/issuer-spark-wallet.ts +146 -124
- package/src/tests/integration/multi-token-issuer.test.ts +42 -0
- package/src/tests/integration/token-outputs.test.ts +6 -8
|
@@ -114,10 +114,12 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
114
114
|
getIssuerTokenMetadata(): Promise<IssuerTokenMetadata>;
|
|
115
115
|
/**
|
|
116
116
|
* Retrieves information about the tokens that were issued by this user.
|
|
117
|
+
* @param tokenIdentifiers - Optional array of specific token identifiers to fetch.
|
|
118
|
+
* If omitted, all tokens for this issuer are fetched.
|
|
117
119
|
* @returns An array of objects containing token information including public key, name, symbol, decimals, max supply, freeze status, and extra metadata
|
|
118
120
|
* @throws {SparkRequestError} If the token metadata cannot be retrieved
|
|
119
121
|
*/
|
|
120
|
-
getIssuerTokensMetadata(): Promise<IssuerTokenMetadata[]>;
|
|
122
|
+
getIssuerTokensMetadata(tokenIdentifiers?: Bech32mTokenIdentifier[]): Promise<IssuerTokenMetadata[]>;
|
|
121
123
|
/**
|
|
122
124
|
* Retrieves the bech32m encoded token identifier for the issuer's token.
|
|
123
125
|
* @deprecated Use getIssuerTokenIdentifiers() instead. This method will be removed in a future version.
|
|
@@ -183,7 +185,7 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
183
185
|
*/
|
|
184
186
|
mintTokens({ tokenAmount, tokenIdentifier, }: {
|
|
185
187
|
tokenAmount: bigint;
|
|
186
|
-
tokenIdentifier
|
|
188
|
+
tokenIdentifier: Bech32mTokenIdentifier;
|
|
187
189
|
}): Promise<string>;
|
|
188
190
|
/**
|
|
189
191
|
* Burns issuer's tokens
|
|
@@ -205,7 +207,7 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
205
207
|
*/
|
|
206
208
|
burnTokens({ tokenAmount, tokenIdentifier, selectedOutputs, }: {
|
|
207
209
|
tokenAmount: bigint;
|
|
208
|
-
tokenIdentifier
|
|
210
|
+
tokenIdentifier: Bech32mTokenIdentifier;
|
|
209
211
|
selectedOutputs?: OutputWithPreviousTransactionData[];
|
|
210
212
|
}): Promise<string>;
|
|
211
213
|
/**
|
|
@@ -267,6 +269,14 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
267
269
|
* @throws {SparkError} This feature is not yet supported
|
|
268
270
|
*/
|
|
269
271
|
getIssuerTokenDistribution(): Promise<TokenDistribution>;
|
|
272
|
+
/**
|
|
273
|
+
* This validates that the token belongs to this issuer.
|
|
274
|
+
* If a token is in the cache, it must belong to this issuer.
|
|
275
|
+
* @param tokenIdentifier - The bech32m encoded token identifier
|
|
276
|
+
* @throws {SparkValidationError} If the token is not found for this issuer
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
private validateTokenIssuer;
|
|
270
280
|
protected getTraceName(methodName: string): string;
|
|
271
281
|
private wrapIssuerPublicMethod;
|
|
272
282
|
private wrapIssuerSparkWalletMethods;
|
|
@@ -114,10 +114,12 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
114
114
|
getIssuerTokenMetadata(): Promise<IssuerTokenMetadata>;
|
|
115
115
|
/**
|
|
116
116
|
* Retrieves information about the tokens that were issued by this user.
|
|
117
|
+
* @param tokenIdentifiers - Optional array of specific token identifiers to fetch.
|
|
118
|
+
* If omitted, all tokens for this issuer are fetched.
|
|
117
119
|
* @returns An array of objects containing token information including public key, name, symbol, decimals, max supply, freeze status, and extra metadata
|
|
118
120
|
* @throws {SparkRequestError} If the token metadata cannot be retrieved
|
|
119
121
|
*/
|
|
120
|
-
getIssuerTokensMetadata(): Promise<IssuerTokenMetadata[]>;
|
|
122
|
+
getIssuerTokensMetadata(tokenIdentifiers?: Bech32mTokenIdentifier[]): Promise<IssuerTokenMetadata[]>;
|
|
121
123
|
/**
|
|
122
124
|
* Retrieves the bech32m encoded token identifier for the issuer's token.
|
|
123
125
|
* @deprecated Use getIssuerTokenIdentifiers() instead. This method will be removed in a future version.
|
|
@@ -183,7 +185,7 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
183
185
|
*/
|
|
184
186
|
mintTokens({ tokenAmount, tokenIdentifier, }: {
|
|
185
187
|
tokenAmount: bigint;
|
|
186
|
-
tokenIdentifier
|
|
188
|
+
tokenIdentifier: Bech32mTokenIdentifier;
|
|
187
189
|
}): Promise<string>;
|
|
188
190
|
/**
|
|
189
191
|
* Burns issuer's tokens
|
|
@@ -205,7 +207,7 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
205
207
|
*/
|
|
206
208
|
burnTokens({ tokenAmount, tokenIdentifier, selectedOutputs, }: {
|
|
207
209
|
tokenAmount: bigint;
|
|
208
|
-
tokenIdentifier
|
|
210
|
+
tokenIdentifier: Bech32mTokenIdentifier;
|
|
209
211
|
selectedOutputs?: OutputWithPreviousTransactionData[];
|
|
210
212
|
}): Promise<string>;
|
|
211
213
|
/**
|
|
@@ -267,6 +269,14 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
267
269
|
* @throws {SparkError} This feature is not yet supported
|
|
268
270
|
*/
|
|
269
271
|
getIssuerTokenDistribution(): Promise<TokenDistribution>;
|
|
272
|
+
/**
|
|
273
|
+
* This validates that the token belongs to this issuer.
|
|
274
|
+
* If a token is in the cache, it must belong to this issuer.
|
|
275
|
+
* @param tokenIdentifier - The bech32m encoded token identifier
|
|
276
|
+
* @throws {SparkValidationError} If the token is not found for this issuer
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
private validateTokenIssuer;
|
|
270
280
|
protected getTraceName(methodName: string): string;
|
|
271
281
|
private wrapIssuerPublicMethod;
|
|
272
282
|
private wrapIssuerSparkWalletMethods;
|
|
@@ -438,88 +438,57 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
438
438
|
* @throws {SparkValidationError} If multiple tokens are found for this issuer
|
|
439
439
|
*/
|
|
440
440
|
async getIssuerTokenMetadata() {
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
field: "tokenMetadata",
|
|
454
|
-
value: response.tokenMetadata,
|
|
455
|
-
expected: "non-empty array",
|
|
456
|
-
actualLength: response.tokenMetadata.length,
|
|
457
|
-
expectedLength: 1
|
|
458
|
-
}
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
if (response.tokenMetadata.length > 1) {
|
|
462
|
-
throw new SparkValidationError3(
|
|
463
|
-
"Multiple tokens found for this issuer. Please migrate to getIssuerTokensMetadata() instead.",
|
|
464
|
-
{
|
|
465
|
-
field: "tokenMetadata",
|
|
466
|
-
value: response.tokenMetadata
|
|
467
|
-
}
|
|
468
|
-
);
|
|
469
|
-
}
|
|
470
|
-
const metadata = response.tokenMetadata[0];
|
|
471
|
-
const bech32mTokenIdentifier = encodeBech32mTokenIdentifier({
|
|
472
|
-
tokenIdentifier: metadata.tokenIdentifier,
|
|
473
|
-
network: this.config.getNetworkType()
|
|
474
|
-
});
|
|
475
|
-
this.tokenMetadata.set(bech32mTokenIdentifier, metadata);
|
|
476
|
-
return {
|
|
477
|
-
tokenPublicKey: bytesToHex(metadata.issuerPublicKey),
|
|
478
|
-
rawTokenIdentifier: metadata.tokenIdentifier,
|
|
479
|
-
tokenName: metadata.tokenName,
|
|
480
|
-
tokenTicker: metadata.tokenTicker,
|
|
481
|
-
decimals: metadata.decimals,
|
|
482
|
-
maxSupply: bytesToNumberBE(metadata.maxSupply),
|
|
483
|
-
isFreezable: metadata.isFreezable,
|
|
484
|
-
extraMetadata: metadata.extraMetadata ? new Uint8Array(metadata.extraMetadata) : void 0,
|
|
485
|
-
bech32mTokenIdentifier
|
|
486
|
-
};
|
|
487
|
-
} catch (error) {
|
|
488
|
-
throw new SparkRequestError2("Failed to fetch token metadata", { error });
|
|
441
|
+
const tokensMetadata = await this.getIssuerTokensMetadata();
|
|
442
|
+
if (tokensMetadata.length === 0) {
|
|
443
|
+
throw new SparkValidationError3("No tokens found. Create a token first.");
|
|
444
|
+
}
|
|
445
|
+
if (tokensMetadata.length > 1) {
|
|
446
|
+
throw new SparkValidationError3(
|
|
447
|
+
"Multiple tokens found for this issuer. Please migrate to getIssuerTokensMetadata() instead.",
|
|
448
|
+
{
|
|
449
|
+
field: "tokenMetadata",
|
|
450
|
+
value: tokensMetadata
|
|
451
|
+
}
|
|
452
|
+
);
|
|
489
453
|
}
|
|
454
|
+
return tokensMetadata[0];
|
|
490
455
|
}
|
|
491
456
|
/**
|
|
492
457
|
* Retrieves information about the tokens that were issued by this user.
|
|
458
|
+
* @param tokenIdentifiers - Optional array of specific token identifiers to fetch.
|
|
459
|
+
* If omitted, all tokens for this issuer are fetched.
|
|
493
460
|
* @returns An array of objects containing token information including public key, name, symbol, decimals, max supply, freeze status, and extra metadata
|
|
494
461
|
* @throws {SparkRequestError} If the token metadata cannot be retrieved
|
|
495
462
|
*/
|
|
496
|
-
async getIssuerTokensMetadata() {
|
|
463
|
+
async getIssuerTokensMetadata(tokenIdentifiers) {
|
|
497
464
|
const issuerPublicKey = await super.getIdentityPublicKey();
|
|
498
465
|
const sparkTokenClient = await this.connectionManager.createSparkTokenClient(
|
|
499
466
|
this.config.getCoordinatorAddress()
|
|
500
467
|
);
|
|
468
|
+
const filterByIdentifiers = Array.isArray(tokenIdentifiers) && tokenIdentifiers.length > 0;
|
|
469
|
+
const tokenIdentifierSet = filterByIdentifiers ? new Set(tokenIdentifiers) : void 0;
|
|
470
|
+
const request = {};
|
|
471
|
+
if (filterByIdentifiers) {
|
|
472
|
+
request.tokenIdentifiers = tokenIdentifiers.map(
|
|
473
|
+
(id) => decodeBech32mTokenIdentifier(id, this.config.getNetworkType()).tokenIdentifier
|
|
474
|
+
);
|
|
475
|
+
} else {
|
|
476
|
+
request.issuerPublicKeys = Array.of(hexToBytes2(issuerPublicKey));
|
|
477
|
+
}
|
|
501
478
|
try {
|
|
502
|
-
const response = await sparkTokenClient.query_token_metadata(
|
|
503
|
-
issuerPublicKeys: Array.of(hexToBytes2(issuerPublicKey))
|
|
504
|
-
});
|
|
505
|
-
if (response.tokenMetadata.length === 0) {
|
|
506
|
-
throw new SparkValidationError3(
|
|
507
|
-
"Token metadata not found - If a token has not yet been created, please create it first. Try again in a few seconds.",
|
|
508
|
-
{
|
|
509
|
-
field: "tokenMetadata",
|
|
510
|
-
value: response.tokenMetadata,
|
|
511
|
-
expected: "non-empty array",
|
|
512
|
-
actualLength: response.tokenMetadata.length,
|
|
513
|
-
expectedLength: 1
|
|
514
|
-
}
|
|
515
|
-
);
|
|
516
|
-
}
|
|
479
|
+
const response = await sparkTokenClient.query_token_metadata(request);
|
|
517
480
|
const tokenMetadata = [];
|
|
518
481
|
for (const metadata of response.tokenMetadata) {
|
|
519
482
|
const bech32mTokenIdentifier = encodeBech32mTokenIdentifier({
|
|
520
483
|
tokenIdentifier: metadata.tokenIdentifier,
|
|
521
484
|
network: this.config.getNetworkType()
|
|
522
485
|
});
|
|
486
|
+
if (bytesToHex(metadata.issuerPublicKey) !== issuerPublicKey) {
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
if (filterByIdentifiers && !tokenIdentifierSet.has(bech32mTokenIdentifier)) {
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
523
492
|
this.tokenMetadata.set(bech32mTokenIdentifier, metadata);
|
|
524
493
|
tokenMetadata.push({
|
|
525
494
|
tokenPublicKey: bytesToHex(metadata.issuerPublicKey),
|
|
@@ -535,6 +504,9 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
535
504
|
}
|
|
536
505
|
return tokenMetadata;
|
|
537
506
|
} catch (error) {
|
|
507
|
+
if (error instanceof SparkError) {
|
|
508
|
+
throw error;
|
|
509
|
+
}
|
|
538
510
|
throw new SparkRequestError2("Failed to fetch token metadata", { error });
|
|
539
511
|
}
|
|
540
512
|
}
|
|
@@ -547,6 +519,9 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
547
519
|
*/
|
|
548
520
|
async getIssuerTokenIdentifier() {
|
|
549
521
|
const tokensMetadata = await this.getIssuerTokensMetadata();
|
|
522
|
+
if (tokensMetadata.length === 0) {
|
|
523
|
+
throw new SparkValidationError3("No tokens found. Create a token first.");
|
|
524
|
+
}
|
|
550
525
|
if (tokensMetadata.length > 1) {
|
|
551
526
|
throw new SparkValidationError3(
|
|
552
527
|
"Multiple tokens found. Use getIssuerTokenIdentifiers() instead.",
|
|
@@ -563,9 +538,6 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
563
538
|
}
|
|
564
539
|
);
|
|
565
540
|
}
|
|
566
|
-
if (tokensMetadata.length === 0) {
|
|
567
|
-
throw new SparkValidationError3("No tokens found. Create a token first.");
|
|
568
|
-
}
|
|
569
541
|
return tokensMetadata[0].bech32mTokenIdentifier;
|
|
570
542
|
}
|
|
571
543
|
/**
|
|
@@ -679,8 +651,13 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
679
651
|
}
|
|
680
652
|
const issuerTokenPublicKey = await super.getIdentityPublicKey();
|
|
681
653
|
const issuerTokenPublicKeyBytes = hexToBytes2(issuerTokenPublicKey);
|
|
682
|
-
const tokensMetadata = await this.getIssuerTokensMetadata();
|
|
683
654
|
if (bech32mTokenIdentifier === void 0) {
|
|
655
|
+
const tokensMetadata = await this.getIssuerTokensMetadata();
|
|
656
|
+
if (tokensMetadata.length === 0) {
|
|
657
|
+
throw new SparkValidationError3(
|
|
658
|
+
"No tokens found. Create a token first."
|
|
659
|
+
);
|
|
660
|
+
}
|
|
684
661
|
if (tokensMetadata.length > 1) {
|
|
685
662
|
throw new SparkValidationError3(
|
|
686
663
|
"Multiple tokens found. Please use mintTokens({ tokenAmount, tokenIdentifier }) instead.",
|
|
@@ -689,19 +666,14 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
689
666
|
availableTokens: tokensMetadata.map((t) => ({
|
|
690
667
|
tokenName: t.tokenName,
|
|
691
668
|
tokenTicker: t.tokenTicker,
|
|
692
|
-
bech32mTokenIdentifier:
|
|
693
|
-
tokenIdentifier: t.rawTokenIdentifier,
|
|
694
|
-
network: this.config.getNetworkType()
|
|
695
|
-
})
|
|
669
|
+
bech32mTokenIdentifier: t.bech32mTokenIdentifier
|
|
696
670
|
}))
|
|
697
671
|
}
|
|
698
672
|
);
|
|
699
673
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
});
|
|
704
|
-
bech32mTokenIdentifier = encodedTokenIdentifier;
|
|
674
|
+
bech32mTokenIdentifier = tokensMetadata[0].bech32mTokenIdentifier;
|
|
675
|
+
} else {
|
|
676
|
+
await this.validateTokenIssuer(bech32mTokenIdentifier);
|
|
705
677
|
}
|
|
706
678
|
const rawTokenIdentifier = decodeBech32mTokenIdentifier(
|
|
707
679
|
bech32mTokenIdentifier,
|
|
@@ -728,13 +700,18 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
728
700
|
}
|
|
729
701
|
}
|
|
730
702
|
async burnTokens(tokenAmountOrParams, selectedOutputs) {
|
|
731
|
-
let
|
|
703
|
+
let burnTokenIdentifier;
|
|
732
704
|
let tokenAmount;
|
|
733
705
|
let outputs;
|
|
734
706
|
if (typeof tokenAmountOrParams === "bigint") {
|
|
735
707
|
tokenAmount = tokenAmountOrParams;
|
|
736
708
|
outputs = selectedOutputs;
|
|
737
709
|
const tokenIdentifiers = await this.getIssuerTokenIdentifiers();
|
|
710
|
+
if (tokenIdentifiers.length === 0) {
|
|
711
|
+
throw new SparkValidationError3(
|
|
712
|
+
"No tokens found. Create a token first."
|
|
713
|
+
);
|
|
714
|
+
}
|
|
738
715
|
if (tokenIdentifiers.length > 1) {
|
|
739
716
|
throw new SparkValidationError3(
|
|
740
717
|
"Multiple tokens found. Use burnTokens({ tokenIdentifier, tokenAmount, selectedOutputs }) to specify which token to burn.",
|
|
@@ -744,52 +721,19 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
744
721
|
}
|
|
745
722
|
);
|
|
746
723
|
}
|
|
747
|
-
|
|
748
|
-
throw new SparkValidationError3(
|
|
749
|
-
"No tokens found. Create a token first."
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
bech32mTokenIdentifier = tokenIdentifiers[0];
|
|
724
|
+
burnTokenIdentifier = tokenIdentifiers[0];
|
|
753
725
|
} else {
|
|
754
726
|
tokenAmount = tokenAmountOrParams.tokenAmount;
|
|
755
727
|
outputs = tokenAmountOrParams.selectedOutputs;
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
const tokenIdentifier = tokenIdentifiers.find(
|
|
759
|
-
(identifier) => identifier === tokenAmountOrParams.tokenIdentifier
|
|
760
|
-
);
|
|
761
|
-
if (!tokenIdentifier) {
|
|
762
|
-
throw new SparkValidationError3("Token not found for this issuer", {
|
|
763
|
-
field: "tokenIdentifier",
|
|
764
|
-
value: tokenAmountOrParams.tokenIdentifier
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
bech32mTokenIdentifier = tokenAmountOrParams.tokenIdentifier;
|
|
768
|
-
} else {
|
|
769
|
-
const tokenIdentifiers = await this.getIssuerTokenIdentifiers();
|
|
770
|
-
if (tokenIdentifiers.length === 0) {
|
|
771
|
-
throw new SparkValidationError3(
|
|
772
|
-
"No tokens found. Create a token first."
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
if (tokenIdentifiers.length > 1) {
|
|
776
|
-
throw new SparkValidationError3(
|
|
777
|
-
"Multiple tokens found. Please specify tokenIdentifier in parameters.",
|
|
778
|
-
{
|
|
779
|
-
field: "tokenIdentifier",
|
|
780
|
-
availableTokens: tokenIdentifiers
|
|
781
|
-
}
|
|
782
|
-
);
|
|
783
|
-
}
|
|
784
|
-
bech32mTokenIdentifier = tokenIdentifiers[0];
|
|
785
|
-
}
|
|
728
|
+
await this.validateTokenIssuer(tokenAmountOrParams.tokenIdentifier);
|
|
729
|
+
burnTokenIdentifier = tokenAmountOrParams.tokenIdentifier;
|
|
786
730
|
}
|
|
787
731
|
const burnAddress = encodeSparkAddress({
|
|
788
732
|
identityPublicKey: BURN_ADDRESS,
|
|
789
733
|
network: this.config.getNetworkType()
|
|
790
734
|
});
|
|
791
735
|
return await this.transferTokens({
|
|
792
|
-
tokenIdentifier:
|
|
736
|
+
tokenIdentifier: burnTokenIdentifier,
|
|
793
737
|
tokenAmount,
|
|
794
738
|
receiverSparkAddress: burnAddress,
|
|
795
739
|
selectedOutputs: outputs
|
|
@@ -826,6 +770,8 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
826
770
|
);
|
|
827
771
|
}
|
|
828
772
|
bech32mTokenIdentifier = tokenIdentifiers[0];
|
|
773
|
+
} else {
|
|
774
|
+
await this.validateTokenIssuer(bech32mTokenIdentifier);
|
|
829
775
|
}
|
|
830
776
|
const rawTokenIdentifier = decodeBech32mTokenIdentifier(
|
|
831
777
|
bech32mTokenIdentifier,
|
|
@@ -853,6 +799,11 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
853
799
|
}
|
|
854
800
|
if (bech32mTokenIdentifier === void 0) {
|
|
855
801
|
const tokenIdentifiers = await this.getIssuerTokenIdentifiers();
|
|
802
|
+
if (tokenIdentifiers.length === 0) {
|
|
803
|
+
throw new SparkValidationError3(
|
|
804
|
+
"No tokens found. Create a token first."
|
|
805
|
+
);
|
|
806
|
+
}
|
|
856
807
|
if (tokenIdentifiers.length > 1) {
|
|
857
808
|
throw new SparkValidationError3(
|
|
858
809
|
"Multiple tokens found. Use unfreezeTokens({ tokenIdentifier, sparkAddress }) instead.",
|
|
@@ -863,6 +814,8 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
863
814
|
);
|
|
864
815
|
}
|
|
865
816
|
bech32mTokenIdentifier = tokenIdentifiers[0];
|
|
817
|
+
} else {
|
|
818
|
+
await this.validateTokenIssuer(bech32mTokenIdentifier);
|
|
866
819
|
}
|
|
867
820
|
const decodedOwnerPubkey = decodeSparkAddress(
|
|
868
821
|
sparkAddress,
|
|
@@ -889,6 +842,45 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
889
842
|
async getIssuerTokenDistribution() {
|
|
890
843
|
throw new SparkError("Token distribution is not yet supported");
|
|
891
844
|
}
|
|
845
|
+
/**
|
|
846
|
+
* This validates that the token belongs to this issuer.
|
|
847
|
+
* If a token is in the cache, it must belong to this issuer.
|
|
848
|
+
* @param tokenIdentifier - The bech32m encoded token identifier
|
|
849
|
+
* @throws {SparkValidationError} If the token is not found for this issuer
|
|
850
|
+
* @private
|
|
851
|
+
*/
|
|
852
|
+
async validateTokenIssuer(tokenIdentifier) {
|
|
853
|
+
const issuerPublicKey = await super.getIdentityPublicKey();
|
|
854
|
+
const cachedMetadata = this.tokenMetadata.get(tokenIdentifier);
|
|
855
|
+
if (cachedMetadata) {
|
|
856
|
+
if (bytesToHex(cachedMetadata.issuerPublicKey) !== issuerPublicKey) {
|
|
857
|
+
throw new SparkValidationError3("Token was not issued by this issuer", {
|
|
858
|
+
field: "issuerPublicKey",
|
|
859
|
+
tokenIdentifier,
|
|
860
|
+
expected: issuerPublicKey,
|
|
861
|
+
actual: bytesToHex(cachedMetadata.issuerPublicKey)
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
} else {
|
|
865
|
+
const tokensMetadata = await this.getIssuerTokensMetadata([
|
|
866
|
+
tokenIdentifier
|
|
867
|
+
]);
|
|
868
|
+
if (tokensMetadata.length === 0) {
|
|
869
|
+
throw new SparkValidationError3("Token not found for this issuer", {
|
|
870
|
+
field: "tokenIdentifier",
|
|
871
|
+
value: tokenIdentifier
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
if (tokensMetadata[0].tokenPublicKey !== issuerPublicKey) {
|
|
875
|
+
throw new SparkValidationError3("Token was not issued by this issuer", {
|
|
876
|
+
field: "issuerPublicKey",
|
|
877
|
+
tokenIdentifier,
|
|
878
|
+
expected: issuerPublicKey,
|
|
879
|
+
actual: tokensMetadata[0].tokenPublicKey
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
892
884
|
getTraceName(methodName) {
|
|
893
885
|
return `IssuerSparkWallet.${methodName}`;
|
|
894
886
|
}
|
package/dist/proto/spark.d.cts
CHANGED
package/dist/proto/spark.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buildonspark/issuer-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Spark Issuer SDK for token issuance",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index.browser.js",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"types": "tsc"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@buildonspark/spark-sdk": "0.5.
|
|
79
|
+
"@buildonspark/spark-sdk": "0.5.6",
|
|
80
80
|
"@noble/curves": "^1.8.0",
|
|
81
81
|
"@scure/btc-signer": "^1.5.0",
|
|
82
82
|
"buffer": "^6.0.3"
|