@buildonspark/issuer-sdk 0.1.0 → 0.1.2

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.
@@ -38,6 +38,8 @@ type IssuerTokenMetadata = {
38
38
  maxSupply: bigint;
39
39
  /** Whether the token is freezable */
40
40
  isFreezable: boolean;
41
+ /** Extra metadata of the token */
42
+ extraMetadata?: Uint8Array;
41
43
  };
42
44
  interface TokenDistribution {
43
45
  totalCirculatingSupply: bigint;
@@ -90,18 +92,20 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
90
92
  * @param params.decimals - The number of decimal places for the token.
91
93
  * @param params.isFreezable - Whether the token can be frozen.
92
94
  * @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
95
+ * @param params.extraMetadata - (Optional) This can be used to store additional bytes data to be associated with a token, like image data.
93
96
  *
94
97
  * @returns The transaction ID of the announcement.
95
98
  *
96
99
  * @throws {SparkValidationError} If `decimals` is not a safe integer or other validation fails.
97
100
  * @throws {SparkRequestError} If the announcement transaction cannot be broadcast.
98
101
  */
99
- createToken({ tokenName, tokenTicker, decimals, isFreezable, maxSupply, }: {
102
+ createToken({ tokenName, tokenTicker, decimals, isFreezable, maxSupply, extraMetadata, }: {
100
103
  tokenName: string;
101
104
  tokenTicker: string;
102
105
  decimals: number;
103
106
  isFreezable: boolean;
104
107
  maxSupply?: bigint;
108
+ extraMetadata?: Uint8Array;
105
109
  }): Promise<string>;
106
110
  /**
107
111
  * Mints new tokens
@@ -215,7 +215,7 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
215
215
  ]
216
216
  };
217
217
  }
218
- async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
218
+ async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable, extraMetadata) {
219
219
  return {
220
220
  version: 2,
221
221
  network: this.config.getNetworkProto(),
@@ -227,7 +227,8 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
227
227
  tokenTicker,
228
228
  decimals,
229
229
  maxSupply: numberToBytesBE(maxSupply, 16),
230
- isFreezable
230
+ isFreezable,
231
+ extraMetadata
231
232
  }
232
233
  },
233
234
  tokenOutputs: [],
@@ -237,7 +238,7 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
237
238
  invoiceAttachments: []
238
239
  };
239
240
  }
240
- async constructPartialCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
241
+ async constructPartialCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable, extraMetadata) {
241
242
  return {
242
243
  version: 3,
243
244
  tokenTransactionMetadata: {
@@ -255,7 +256,8 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
255
256
  tokenTicker,
256
257
  decimals,
257
258
  maxSupply: numberToBytesBE(maxSupply, 16),
258
- isFreezable
259
+ isFreezable,
260
+ extraMetadata
259
261
  }
260
262
  },
261
263
  partialTokenOutputs: []
@@ -274,7 +276,8 @@ var MIN_SYMBOL_SIZE = 3;
274
276
  var MAX_SYMBOL_SIZE = 6;
275
277
  var MAX_DECIMALS = 255;
276
278
  var MAXIMUM_MAX_SUPPLY = (1n << 128n) - 1n;
277
- function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
279
+ var MAX_TOKEN_CONTENT_SIZE = 1024;
280
+ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply, extraMetadata) {
278
281
  if (!isNfcNormalized(tokenName)) {
279
282
  throw new SparkValidationError2("Token name must be NFC-normalised UTF-8", {
280
283
  field: "tokenName",
@@ -333,6 +336,16 @@ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
333
336
  expected: `>=0 and <=${MAXIMUM_MAX_SUPPLY.toString()}`
334
337
  });
335
338
  }
339
+ if (extraMetadata && extraMetadata.length > MAX_TOKEN_CONTENT_SIZE) {
340
+ throw new SparkValidationError2(
341
+ `Extra metadata must be less than ${MAX_TOKEN_CONTENT_SIZE} bytes`,
342
+ {
343
+ field: "extraMetadata",
344
+ value: extraMetadata.length,
345
+ expected: `<${MAX_TOKEN_CONTENT_SIZE}`
346
+ }
347
+ );
348
+ }
336
349
  }
337
350
 
338
351
  // src/issuer-wallet/issuer-spark-wallet.ts
@@ -398,7 +411,8 @@ var IssuerSparkWallet = class extends SparkWallet {
398
411
  tokenTicker: metadata.tokenTicker,
399
412
  decimals: metadata.decimals,
400
413
  maxSupply: bytesToNumberBE(metadata.maxSupply),
401
- isFreezable: metadata.isFreezable
414
+ isFreezable: metadata.isFreezable,
415
+ extraMetadata: metadata.extraMetadata ? new Uint8Array(metadata.extraMetadata) : void 0
402
416
  };
403
417
  }
404
418
  const sparkTokenClient = await this.connectionManager.createSparkTokenClient(
@@ -433,7 +447,8 @@ var IssuerSparkWallet = class extends SparkWallet {
433
447
  tokenTicker: metadata.tokenTicker,
434
448
  decimals: metadata.decimals,
435
449
  maxSupply: bytesToNumberBE(metadata.maxSupply),
436
- isFreezable: metadata.isFreezable
450
+ isFreezable: metadata.isFreezable,
451
+ extraMetadata: metadata.extraMetadata
437
452
  };
438
453
  } catch (error) {
439
454
  throw new SparkRequestError2("Failed to fetch token metadata", { error });
@@ -460,6 +475,7 @@ var IssuerSparkWallet = class extends SparkWallet {
460
475
  * @param params.decimals - The number of decimal places for the token.
461
476
  * @param params.isFreezable - Whether the token can be frozen.
462
477
  * @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
478
+ * @param params.extraMetadata - (Optional) This can be used to store additional bytes data to be associated with a token, like image data.
463
479
  *
464
480
  * @returns The transaction ID of the announcement.
465
481
  *
@@ -471,9 +487,16 @@ var IssuerSparkWallet = class extends SparkWallet {
471
487
  tokenTicker,
472
488
  decimals,
473
489
  isFreezable,
474
- maxSupply = 0n
490
+ maxSupply = 0n,
491
+ extraMetadata
475
492
  }) {
476
- validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply);
493
+ validateTokenParameters(
494
+ tokenName,
495
+ tokenTicker,
496
+ decimals,
497
+ maxSupply,
498
+ extraMetadata
499
+ );
477
500
  const issuerPublicKey = await super.getIdentityPublicKey();
478
501
  if (this.config.getTokenTransactionVersion() === "V2") {
479
502
  const tokenTransaction = await this.issuerTokenTransactionService.constructCreateTokenTransaction(
@@ -482,7 +505,8 @@ var IssuerSparkWallet = class extends SparkWallet {
482
505
  tokenTicker,
483
506
  decimals,
484
507
  maxSupply,
485
- isFreezable
508
+ isFreezable,
509
+ extraMetadata
486
510
  );
487
511
  return await this.issuerTokenTransactionService.broadcastTokenTransaction(
488
512
  tokenTransaction
@@ -494,7 +518,8 @@ var IssuerSparkWallet = class extends SparkWallet {
494
518
  tokenTicker,
495
519
  decimals,
496
520
  maxSupply,
497
- isFreezable
521
+ isFreezable,
522
+ extraMetadata
498
523
  );
499
524
  return await this.issuerTokenTransactionService.broadcastTokenTransactionV3(
500
525
  partialTokenTransaction
@@ -1,4 +1,4 @@
1
1
  export * from '@buildonspark/spark-sdk/proto/spark';
2
2
  import '@buildonspark/spark-sdk/proto/spark_token';
3
- import '@buildonspark/spark-sdk/types';
4
3
  import '@buildonspark/spark-sdk/test-utils';
4
+ import '@buildonspark/spark-sdk/types';
@@ -1,4 +1,4 @@
1
1
  export * from '@buildonspark/spark-sdk/proto/spark';
2
2
  import '@buildonspark/spark-sdk/proto/spark_token';
3
- import '@buildonspark/spark-sdk/types';
4
3
  import '@buildonspark/spark-sdk/test-utils';
4
+ import '@buildonspark/spark-sdk/types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildonspark/issuer-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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.0",
79
+ "@buildonspark/spark-sdk": "0.5.2",
80
80
  "@noble/curves": "^1.8.0",
81
81
  "@scure/btc-signer": "^1.5.0",
82
82
  "buffer": "^6.0.3"
@@ -90,7 +90,7 @@
90
90
  "jest": "^29.7.0",
91
91
  "madge": "^8.0.0",
92
92
  "node-fetch": "^3.3.2",
93
- "prettier": "^3.6.2",
93
+ "prettier": "^3.7.4",
94
94
  "publint": "^0.3.9",
95
95
  "react": "19.0.0",
96
96
  "react-native": "0.79.4",
@@ -97,6 +97,9 @@ export abstract class IssuerSparkWallet extends SparkWallet {
97
97
  decimals: metadata.decimals,
98
98
  maxSupply: bytesToNumberBE(metadata.maxSupply),
99
99
  isFreezable: metadata.isFreezable,
100
+ extraMetadata: metadata.extraMetadata
101
+ ? new Uint8Array(metadata.extraMetadata)
102
+ : undefined,
100
103
  };
101
104
  }
102
105
 
@@ -135,6 +138,7 @@ export abstract class IssuerSparkWallet extends SparkWallet {
135
138
  decimals: metadata.decimals,
136
139
  maxSupply: bytesToNumberBE(metadata.maxSupply),
137
140
  isFreezable: metadata.isFreezable,
141
+ extraMetadata: metadata.extraMetadata,
138
142
  };
139
143
  } catch (error) {
140
144
  throw new SparkRequestError("Failed to fetch token metadata", { error });
@@ -164,6 +168,7 @@ export abstract class IssuerSparkWallet extends SparkWallet {
164
168
  * @param params.decimals - The number of decimal places for the token.
165
169
  * @param params.isFreezable - Whether the token can be frozen.
166
170
  * @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
171
+ * @param params.extraMetadata - (Optional) This can be used to store additional bytes data to be associated with a token, like image data.
167
172
  *
168
173
  * @returns The transaction ID of the announcement.
169
174
  *
@@ -176,14 +181,22 @@ export abstract class IssuerSparkWallet extends SparkWallet {
176
181
  decimals,
177
182
  isFreezable,
178
183
  maxSupply = 0n,
184
+ extraMetadata,
179
185
  }: {
180
186
  tokenName: string;
181
187
  tokenTicker: string;
182
188
  decimals: number;
183
189
  isFreezable: boolean;
184
190
  maxSupply?: bigint;
191
+ extraMetadata?: Uint8Array;
185
192
  }): Promise<string> {
186
- validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply);
193
+ validateTokenParameters(
194
+ tokenName,
195
+ tokenTicker,
196
+ decimals,
197
+ maxSupply,
198
+ extraMetadata,
199
+ );
187
200
 
188
201
  const issuerPublicKey = await super.getIdentityPublicKey();
189
202
 
@@ -196,6 +209,7 @@ export abstract class IssuerSparkWallet extends SparkWallet {
196
209
  decimals,
197
210
  maxSupply,
198
211
  isFreezable,
212
+ extraMetadata,
199
213
  );
200
214
 
201
215
  return await this.issuerTokenTransactionService.broadcastTokenTransaction(
@@ -210,6 +224,7 @@ export abstract class IssuerSparkWallet extends SparkWallet {
210
224
  decimals,
211
225
  maxSupply,
212
226
  isFreezable,
227
+ extraMetadata,
213
228
  );
214
229
 
215
230
  return await this.issuerTokenTransactionService.broadcastTokenTransactionV3(
@@ -34,6 +34,8 @@ export type IssuerTokenMetadata = {
34
34
  maxSupply: bigint;
35
35
  /** Whether the token is freezable */
36
36
  isFreezable: boolean;
37
+ /** Extra metadata of the token */
38
+ extraMetadata?: Uint8Array;
37
39
  };
38
40
 
39
41
  export interface TokenDistribution {
@@ -90,6 +90,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
90
90
  decimals: number,
91
91
  maxSupply: bigint,
92
92
  isFreezable: boolean,
93
+ extraMetadata: Uint8Array | undefined,
93
94
  ): Promise<TokenTransaction> {
94
95
  return {
95
96
  version: 2,
@@ -103,6 +104,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
103
104
  decimals: decimals,
104
105
  maxSupply: numberToBytesBE(maxSupply, 16),
105
106
  isFreezable: isFreezable,
107
+ extraMetadata: extraMetadata,
106
108
  },
107
109
  },
108
110
  tokenOutputs: [],
@@ -121,6 +123,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
121
123
  decimals: number,
122
124
  maxSupply: bigint,
123
125
  isFreezable: boolean,
126
+ extraMetadata?: Uint8Array,
124
127
  ): Promise<PartialTokenTransaction> {
125
128
  return {
126
129
  version: 3,
@@ -142,6 +145,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
142
145
  decimals: decimals,
143
146
  maxSupply: numberToBytesBE(maxSupply, 16),
144
147
  isFreezable: isFreezable,
148
+ extraMetadata: extraMetadata,
145
149
  },
146
150
  },
147
151
  partialTokenOutputs: [],
@@ -0,0 +1,86 @@
1
+ import { jest } from "@jest/globals";
2
+ import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
3
+ import { TEST_CONFIGS } from "./test-configs.js";
4
+ import { MAX_TOKEN_CONTENT_SIZE } from "../../utils/create-validation.js";
5
+
6
+ describe.each(TEST_CONFIGS)(
7
+ "nft creation tests - $name",
8
+ ({ name, config }) => {
9
+ jest.setTimeout(80000);
10
+
11
+ it("should create an nft", async () => {
12
+ const { wallet: issuerWallet } =
13
+ await IssuerSparkWalletTesting.initialize({
14
+ options: config,
15
+ });
16
+
17
+ const tokenName = `${name}NFT`;
18
+ const tokenTicker = "NFT";
19
+ const extraMetadata = new Uint8Array([1, 2, 3]);
20
+ const createTransactionId = await issuerWallet.createToken({
21
+ tokenName,
22
+ tokenTicker,
23
+ decimals: 0,
24
+ isFreezable: false,
25
+ maxSupply: 1n,
26
+ extraMetadata,
27
+ });
28
+
29
+ expect(typeof createTransactionId).toBe("string");
30
+ expect(createTransactionId.length).toBeGreaterThan(0);
31
+
32
+ const metadata = await issuerWallet.getIssuerTokenMetadata();
33
+ expect(metadata.tokenName).toEqual(tokenName);
34
+ expect(metadata.tokenTicker).toEqual(tokenTicker);
35
+ expect(metadata.maxSupply).toEqual(1n);
36
+ expect(metadata.decimals).toEqual(0);
37
+ expect(Array.from(metadata.extraMetadata!)).toEqual(
38
+ Array.from(extraMetadata),
39
+ );
40
+
41
+ const txId = await issuerWallet.mintTokens(1n);
42
+ expect(typeof txId).toBe("string");
43
+ expect(txId.length).toBeGreaterThan(0);
44
+
45
+ const tokenIdentifier = await issuerWallet.getIssuerTokenIdentifier();
46
+ expect(tokenIdentifier).toBeDefined();
47
+ expect(tokenIdentifier!.length).toBeGreaterThan(0);
48
+
49
+ const { balance: satsBalance, tokenBalances: tokenBalancesMap } =
50
+ await issuerWallet.getBalance();
51
+ expect(satsBalance).toEqual(0n);
52
+ expect(tokenBalancesMap.size).toEqual(1);
53
+ expect(tokenBalancesMap.get(tokenIdentifier)).toBeDefined();
54
+ expect(tokenBalancesMap.get(tokenIdentifier)?.balance).toEqual(1n);
55
+
56
+ const tokenMetadata =
57
+ tokenBalancesMap.get(tokenIdentifier)?.tokenMetadata;
58
+ expect(tokenMetadata).toBeDefined();
59
+ expect(tokenMetadata?.tokenName).toEqual(tokenName);
60
+ expect(tokenMetadata?.tokenTicker).toEqual(tokenTicker);
61
+ expect(tokenMetadata?.maxSupply).toEqual(1n);
62
+ expect(tokenMetadata?.decimals).toEqual(0);
63
+ expect(tokenMetadata?.extraMetadata).toEqual(extraMetadata);
64
+ });
65
+
66
+ it("should fail to create an nft with extra metadata longer than MAX_TOKEN_CONTENT_SIZE bytes", async () => {
67
+ const { wallet: issuerWallet } =
68
+ await IssuerSparkWalletTesting.initialize({
69
+ options: config,
70
+ });
71
+
72
+ const extraMetadata = new Uint8Array(MAX_TOKEN_CONTENT_SIZE + 1);
73
+
74
+ await expect(
75
+ issuerWallet.createToken({
76
+ tokenName: "NFTLONGMETADATA",
77
+ tokenTicker: "NFTLONG",
78
+ decimals: 0,
79
+ isFreezable: false,
80
+ maxSupply: 1n,
81
+ extraMetadata,
82
+ }),
83
+ ).rejects.toThrow();
84
+ });
85
+ },
86
+ );
@@ -0,0 +1,32 @@
1
+ import { ConfigOptions, WalletConfig } from "@buildonspark/spark-sdk";
2
+
3
+ export const TOKENS_SCHNORR_V2_CONFIG: Required<ConfigOptions> = {
4
+ ...WalletConfig.LOCAL,
5
+ tokenSignatures: "SCHNORR",
6
+ tokenTransactionVersion: "V2",
7
+ };
8
+
9
+ export const TOKENS_SCHNORR_V3_CONFIG: Required<ConfigOptions> = {
10
+ ...WalletConfig.LOCAL,
11
+ tokenSignatures: "SCHNORR",
12
+ tokenTransactionVersion: "V3",
13
+ };
14
+
15
+ export const TOKENS_ECDSA_V2_CONFIG: Required<ConfigOptions> = {
16
+ ...WalletConfig.LOCAL,
17
+ tokenSignatures: "ECDSA",
18
+ tokenTransactionVersion: "V2",
19
+ };
20
+
21
+ export const TOKENS_ECDSA_V3_CONFIG: Required<ConfigOptions> = {
22
+ ...WalletConfig.LOCAL,
23
+ tokenSignatures: "ECDSA",
24
+ tokenTransactionVersion: "V3",
25
+ };
26
+
27
+ export const TEST_CONFIGS = [
28
+ { name: "E2", config: TOKENS_ECDSA_V2_CONFIG },
29
+ { name: "E3", config: TOKENS_ECDSA_V3_CONFIG },
30
+ { name: "S2", config: TOKENS_SCHNORR_V2_CONFIG },
31
+ { name: "S3", config: TOKENS_SCHNORR_V3_CONFIG },
32
+ ];
@@ -1,21 +1,6 @@
1
- import { ConfigOptions, WalletConfig } from "@buildonspark/spark-sdk";
2
1
  import { jest } from "@jest/globals";
3
2
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
4
-
5
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
6
- ...WalletConfig.LOCAL,
7
- tokenSignatures: "SCHNORR",
8
- };
9
-
10
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
11
- ...WalletConfig.LOCAL,
12
- tokenSignatures: "ECDSA",
13
- };
14
-
15
- const TEST_CONFIGS = [
16
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
17
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
18
- ];
3
+ import { TEST_CONFIGS } from "./test-configs.js";
19
4
 
20
5
  describe.each(TEST_CONFIGS)(
21
6
  "token creation tests - $name",
@@ -1,8 +1,6 @@
1
1
  import {
2
- ConfigOptions,
3
2
  filterTokenBalanceForTokenIdentifier,
4
3
  SparkRequestError,
5
- WalletConfig,
6
4
  } from "@buildonspark/spark-sdk";
7
5
  import { jest } from "@jest/globals";
8
6
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
@@ -11,21 +9,7 @@ import {
11
9
  SparkWalletTesting,
12
10
  } from "@buildonspark/spark-sdk/test-utils";
13
11
  import { InvoiceStatus } from "@buildonspark/spark-sdk/proto/spark";
14
-
15
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
16
- ...WalletConfig.LOCAL,
17
- tokenSignatures: "SCHNORR",
18
- };
19
-
20
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
21
- ...WalletConfig.LOCAL,
22
- tokenSignatures: "ECDSA",
23
- };
24
-
25
- const TEST_CONFIGS = [
26
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
27
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
28
- ];
12
+ import { TEST_CONFIGS } from "./test-configs.js";
29
13
 
30
14
  describe.each(TEST_CONFIGS)(
31
15
  "token invoice tests - $name",
@@ -1,26 +1,8 @@
1
- import {
2
- ConfigOptions,
3
- filterTokenBalanceForTokenIdentifier,
4
- WalletConfig,
5
- } from "@buildonspark/spark-sdk";
1
+ import { filterTokenBalanceForTokenIdentifier } from "@buildonspark/spark-sdk";
6
2
  import { jest } from "@jest/globals";
7
3
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
8
4
  import { SparkWalletTesting } from "@buildonspark/spark-sdk/test-utils";
9
-
10
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
11
- ...WalletConfig.LOCAL,
12
- tokenSignatures: "SCHNORR",
13
- };
14
-
15
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
16
- ...WalletConfig.LOCAL,
17
- tokenSignatures: "ECDSA",
18
- };
19
-
20
- const TEST_CONFIGS = [
21
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
22
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
23
- ];
5
+ import { TEST_CONFIGS } from "./test-configs.js";
24
6
 
25
7
  describe.each(TEST_CONFIGS)(
26
8
  "token lifecycle tests - $name",
@@ -1,21 +1,6 @@
1
- import { ConfigOptions, WalletConfig } from "@buildonspark/spark-sdk";
2
1
  import { jest } from "@jest/globals";
3
2
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
4
-
5
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
6
- ...WalletConfig.LOCAL,
7
- tokenSignatures: "SCHNORR",
8
- };
9
-
10
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
11
- ...WalletConfig.LOCAL,
12
- tokenSignatures: "ECDSA",
13
- };
14
-
15
- const TEST_CONFIGS = [
16
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
17
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
18
- ];
3
+ import { TEST_CONFIGS } from "./test-configs.js";
19
4
 
20
5
  describe.each(TEST_CONFIGS)(
21
6
  "token minting tests - $name",
@@ -1,27 +1,9 @@
1
- import {
2
- ConfigOptions,
3
- filterTokenBalanceForTokenIdentifier,
4
- WalletConfig,
5
- } from "@buildonspark/spark-sdk";
1
+ import { filterTokenBalanceForTokenIdentifier } from "@buildonspark/spark-sdk";
6
2
  import { jest } from "@jest/globals";
7
3
  import { bytesToHex } from "@noble/curves/utils";
8
4
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
9
5
  import { SparkWalletTesting } from "@buildonspark/spark-sdk/test-utils";
10
-
11
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
12
- ...WalletConfig.LOCAL,
13
- tokenSignatures: "SCHNORR",
14
- };
15
-
16
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
17
- ...WalletConfig.LOCAL,
18
- tokenSignatures: "ECDSA",
19
- };
20
-
21
- const TEST_CONFIGS = [
22
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
23
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
24
- ];
6
+ import { TEST_CONFIGS } from "./test-configs.js";
25
7
 
26
8
  describe.each(TEST_CONFIGS)(
27
9
  "token monitoring tests - $name",
@@ -202,9 +184,10 @@ describe.each(TEST_CONFIGS)(
202
184
  }
203
185
 
204
186
  for (let index = 0; index < 100; ++index) {
205
- await issuerWallet.mintTokens(tokenAmount);
187
+ const dynamicAmount = BigInt(index + 1);
188
+ await issuerWallet.mintTokens(dynamicAmount);
206
189
  await issuerWallet.transferTokens({
207
- tokenAmount,
190
+ tokenAmount: dynamicAmount,
208
191
  tokenIdentifier: tokenIdentifier!,
209
192
  receiverSparkAddress: await userWallet.getSparkAddress(),
210
193
  });
@@ -1,26 +1,8 @@
1
- import {
2
- ConfigOptions,
3
- filterTokenBalanceForTokenIdentifier,
4
- WalletConfig,
5
- } from "@buildonspark/spark-sdk";
1
+ import { filterTokenBalanceForTokenIdentifier } from "@buildonspark/spark-sdk";
6
2
  import { jest } from "@jest/globals";
7
3
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
8
4
  import { SparkWalletTesting } from "@buildonspark/spark-sdk/test-utils";
9
-
10
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
11
- ...WalletConfig.LOCAL,
12
- tokenSignatures: "SCHNORR",
13
- };
14
-
15
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
16
- ...WalletConfig.LOCAL,
17
- tokenSignatures: "ECDSA",
18
- };
19
-
20
- const TEST_CONFIGS = [
21
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
22
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
23
- ];
5
+ import { TEST_CONFIGS } from "./test-configs.js";
24
6
 
25
7
  describe.each(TEST_CONFIGS)(
26
8
  "token output tests - $name",
@@ -1,26 +1,8 @@
1
- import {
2
- ConfigOptions,
3
- filterTokenBalanceForTokenIdentifier,
4
- WalletConfig,
5
- } from "@buildonspark/spark-sdk";
1
+ import { filterTokenBalanceForTokenIdentifier } from "@buildonspark/spark-sdk";
6
2
  import { jest } from "@jest/globals";
7
3
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
8
4
  import { SparkWalletTesting } from "@buildonspark/spark-sdk/test-utils";
9
-
10
- export const TOKENS_SCHNORR_CONFIG: Required<ConfigOptions> = {
11
- ...WalletConfig.LOCAL,
12
- tokenSignatures: "SCHNORR",
13
- };
14
-
15
- export const TOKENS_ECDSA_CONFIG: Required<ConfigOptions> = {
16
- ...WalletConfig.LOCAL,
17
- tokenSignatures: "ECDSA",
18
- };
19
-
20
- const TEST_CONFIGS = [
21
- { name: "TE", config: TOKENS_ECDSA_CONFIG },
22
- { name: "TS", config: TOKENS_SCHNORR_CONFIG },
23
- ];
5
+ import { TEST_CONFIGS } from "./test-configs.js";
24
6
 
25
7
  describe.each(TEST_CONFIGS)(
26
8
  "token transfer tests - $name",
@@ -18,12 +18,14 @@ const MIN_SYMBOL_SIZE = 3; // bytes
18
18
  const MAX_SYMBOL_SIZE = 6; // bytes
19
19
  const MAX_DECIMALS = 255; // fits into single byte
20
20
  const MAXIMUM_MAX_SUPPLY = (1n << 128n) - 1n; // fits into 16 bytes (u128)
21
+ export const MAX_TOKEN_CONTENT_SIZE = 1024; // fits into 1024 bytes
21
22
 
22
23
  export function validateTokenParameters(
23
24
  tokenName: string,
24
25
  tokenTicker: string,
25
26
  decimals: number,
26
27
  maxSupply: bigint,
28
+ extraMetadata?: Uint8Array,
27
29
  ) {
28
30
  if (!isNfcNormalized(tokenName)) {
29
31
  throw new SparkValidationError("Token name must be NFC-normalised UTF-8", {
@@ -92,4 +94,15 @@ export function validateTokenParameters(
92
94
  expected: `>=0 and <=${MAXIMUM_MAX_SUPPLY.toString()}`,
93
95
  });
94
96
  }
97
+
98
+ if (extraMetadata && extraMetadata.length > MAX_TOKEN_CONTENT_SIZE) {
99
+ throw new SparkValidationError(
100
+ `Extra metadata must be less than ${MAX_TOKEN_CONTENT_SIZE} bytes`,
101
+ {
102
+ field: "extraMetadata",
103
+ value: extraMetadata.length,
104
+ expected: `<${MAX_TOKEN_CONTENT_SIZE}`,
105
+ },
106
+ );
107
+ }
95
108
  }