@buildonspark/issuer-sdk 0.0.84 → 0.0.85

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.
@@ -0,0 +1,708 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.node.ts
21
+ var index_node_exports = {};
22
+ __export(index_node_exports, {
23
+ IssuerSparkWallet: () => IssuerSparkWalletNodeJS
24
+ });
25
+ module.exports = __toCommonJS(index_node_exports);
26
+
27
+ // buffer.js
28
+ var import_buffer = require("buffer");
29
+ if (typeof globalThis.Buffer === "undefined") {
30
+ globalThis.Buffer = import_buffer.Buffer;
31
+ }
32
+ if (typeof window !== "undefined") {
33
+ if (typeof window.global === "undefined") {
34
+ window.global = window;
35
+ }
36
+ if (typeof window.globalThis === "undefined") {
37
+ window.globalThis = window;
38
+ }
39
+ }
40
+
41
+ // src/issuer-wallet/issuer-spark-wallet.ts
42
+ var import_lrc20_sdk = require("@buildonspark/lrc20-sdk");
43
+ var import_spark_sdk5 = require("@buildonspark/spark-sdk");
44
+ var import_spark_sdk6 = require("@buildonspark/spark-sdk");
45
+ var import_utils4 = require("@noble/curves/abstract/utils");
46
+ var import_spark_sdk7 = require("@buildonspark/spark-sdk");
47
+
48
+ // src/services/freeze.ts
49
+ var import_spark_sdk2 = require("@buildonspark/spark-sdk");
50
+
51
+ // src/utils/token-hashing.ts
52
+ var import_utils = require("@scure/btc-signer/utils");
53
+ var import_spark_sdk = require("@buildonspark/spark-sdk");
54
+ function hashFreezeTokensPayload(payload) {
55
+ if (!payload) {
56
+ throw new import_spark_sdk.ValidationError("Freeze tokens payload cannot be nil", {
57
+ field: "payload",
58
+ value: payload,
59
+ expected: "valid freeze tokens payload"
60
+ });
61
+ }
62
+ let allHashes = [];
63
+ const versionHashObj = import_utils.sha256.create();
64
+ const versionBytes = new Uint8Array(4);
65
+ new DataView(versionBytes.buffer).setUint32(
66
+ 0,
67
+ payload.version,
68
+ false
69
+ // false for big-endian
70
+ );
71
+ versionHashObj.update(versionBytes);
72
+ allHashes.push(versionHashObj.digest());
73
+ const ownerPubKeyHash = import_utils.sha256.create();
74
+ if (payload.ownerPublicKey) {
75
+ ownerPubKeyHash.update(payload.ownerPublicKey);
76
+ }
77
+ allHashes.push(ownerPubKeyHash.digest());
78
+ const tokenIdentifierHash = import_utils.sha256.create();
79
+ if (payload.tokenIdentifier) {
80
+ tokenIdentifierHash.update(payload.tokenIdentifier);
81
+ }
82
+ allHashes.push(tokenIdentifierHash.digest());
83
+ const shouldUnfreezeHash = import_utils.sha256.create();
84
+ shouldUnfreezeHash.update(new Uint8Array([payload.shouldUnfreeze ? 1 : 0]));
85
+ allHashes.push(shouldUnfreezeHash.digest());
86
+ const timestampHash = import_utils.sha256.create();
87
+ if (payload.issuerProvidedTimestamp) {
88
+ const timestampBytes = new Uint8Array(8);
89
+ new DataView(timestampBytes.buffer).setBigUint64(
90
+ 0,
91
+ BigInt(payload.issuerProvidedTimestamp),
92
+ true
93
+ // true for little-endian
94
+ );
95
+ timestampHash.update(timestampBytes);
96
+ }
97
+ allHashes.push(timestampHash.digest());
98
+ const operatorPubKeyHash = import_utils.sha256.create();
99
+ if (payload.operatorIdentityPublicKey) {
100
+ operatorPubKeyHash.update(payload.operatorIdentityPublicKey);
101
+ }
102
+ allHashes.push(operatorPubKeyHash.digest());
103
+ const finalHash = import_utils.sha256.create();
104
+ for (const hash of allHashes) {
105
+ finalHash.update(hash);
106
+ }
107
+ return finalHash.digest();
108
+ }
109
+
110
+ // src/services/freeze.ts
111
+ var import_utils2 = require("@noble/curves/abstract/utils");
112
+ var TokenFreezeService = class {
113
+ config;
114
+ connectionManager;
115
+ constructor(config, connectionManager) {
116
+ this.config = config;
117
+ this.connectionManager = connectionManager;
118
+ }
119
+ async freezeTokens({
120
+ ownerPublicKey,
121
+ tokenIdentifier
122
+ }) {
123
+ return this.freezeOperation(ownerPublicKey, false, tokenIdentifier);
124
+ }
125
+ async unfreezeTokens({
126
+ ownerPublicKey,
127
+ tokenIdentifier
128
+ }) {
129
+ return this.freezeOperation(ownerPublicKey, true, tokenIdentifier);
130
+ }
131
+ async freezeOperation(ownerPublicKey, shouldUnfreeze, tokenIdentifier) {
132
+ const signingOperators = this.config.getSigningOperators();
133
+ const issuerProvidedTimestamp = Date.now();
134
+ const freezeResponses = await Promise.allSettled(
135
+ Object.entries(signingOperators).map(async ([identifier, operator]) => {
136
+ const sparkTokenClient = await this.connectionManager.createSparkTokenClient(operator.address);
137
+ const freezeTokensPayload = {
138
+ version: 1,
139
+ ownerPublicKey,
140
+ tokenIdentifier,
141
+ shouldUnfreeze,
142
+ issuerProvidedTimestamp,
143
+ operatorIdentityPublicKey: (0, import_utils2.hexToBytes)(operator.identityPublicKey)
144
+ };
145
+ const hashedPayload = hashFreezeTokensPayload(freezeTokensPayload);
146
+ const issuerSignature = await this.config.signer.signMessageWithIdentityKey(hashedPayload);
147
+ try {
148
+ const response = await sparkTokenClient.freeze_tokens({
149
+ freezeTokensPayload,
150
+ issuerSignature
151
+ });
152
+ return {
153
+ identifier,
154
+ response
155
+ };
156
+ } catch (error) {
157
+ throw new import_spark_sdk2.NetworkError(
158
+ `Failed to send a freeze/unfreeze operation to operator: ${operator.address}`,
159
+ {
160
+ operation: "freeze_tokens",
161
+ errorCount: 1,
162
+ errors: error instanceof Error ? error.message : String(error)
163
+ },
164
+ error instanceof Error ? error : void 0
165
+ );
166
+ }
167
+ })
168
+ );
169
+ const successfulResponses = (0, import_spark_sdk2.collectResponses)(freezeResponses);
170
+ return successfulResponses[0].response;
171
+ }
172
+ };
173
+
174
+ // src/services/token-transactions.ts
175
+ var import_spark_sdk3 = require("@buildonspark/spark-sdk");
176
+ var import_utils3 = require("@noble/curves/abstract/utils");
177
+ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransactionService {
178
+ constructor(config, connectionManager) {
179
+ super(config, connectionManager);
180
+ }
181
+ async constructMintTokenTransactionV0(tokenPublicKey, tokenAmount) {
182
+ return {
183
+ network: this.config.getNetworkProto(),
184
+ tokenInputs: {
185
+ $case: "mintInput",
186
+ mintInput: {
187
+ issuerPublicKey: tokenPublicKey,
188
+ issuerProvidedTimestamp: Date.now()
189
+ }
190
+ },
191
+ tokenOutputs: [
192
+ {
193
+ ownerPublicKey: tokenPublicKey,
194
+ tokenPublicKey,
195
+ tokenAmount: (0, import_utils3.numberToBytesBE)(tokenAmount, 16)
196
+ }
197
+ ],
198
+ sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys()
199
+ };
200
+ }
201
+ async constructMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
202
+ return {
203
+ version: 1,
204
+ network: this.config.getNetworkProto(),
205
+ tokenInputs: {
206
+ $case: "mintInput",
207
+ mintInput: {
208
+ issuerPublicKey: issuerTokenPublicKey,
209
+ tokenIdentifier: rawTokenIdentifierBytes
210
+ }
211
+ },
212
+ tokenOutputs: [
213
+ {
214
+ ownerPublicKey: issuerTokenPublicKey,
215
+ tokenIdentifier: rawTokenIdentifierBytes,
216
+ tokenAmount: (0, import_utils3.numberToBytesBE)(tokenAmount, 16)
217
+ }
218
+ ],
219
+ clientCreatedTimestamp: /* @__PURE__ */ new Date(),
220
+ sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
221
+ expiryTime: void 0
222
+ };
223
+ }
224
+ async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
225
+ return {
226
+ version: 1,
227
+ network: this.config.getNetworkProto(),
228
+ tokenInputs: {
229
+ $case: "createInput",
230
+ createInput: {
231
+ issuerPublicKey: tokenPublicKey,
232
+ tokenName,
233
+ tokenTicker,
234
+ decimals,
235
+ maxSupply: (0, import_utils3.numberToBytesBE)(maxSupply, 16),
236
+ isFreezable
237
+ }
238
+ },
239
+ tokenOutputs: [],
240
+ clientCreatedTimestamp: /* @__PURE__ */ new Date(),
241
+ sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
242
+ expiryTime: void 0
243
+ };
244
+ }
245
+ };
246
+
247
+ // src/issuer-wallet/issuer-spark-wallet.ts
248
+ var import_spark_sdk8 = require("@buildonspark/spark-sdk");
249
+
250
+ // src/utils/create-validation.ts
251
+ var import_spark_sdk4 = require("@buildonspark/spark-sdk");
252
+ function isNfcNormalized(value) {
253
+ return value.normalize("NFC") === value;
254
+ }
255
+ var MIN_NAME_SIZE = 3;
256
+ var MAX_NAME_SIZE = 20;
257
+ var MIN_SYMBOL_SIZE = 3;
258
+ var MAX_SYMBOL_SIZE = 6;
259
+ var MAX_DECIMALS = 255;
260
+ var MAXIMUM_MAX_SUPPLY = (1n << 128n) - 1n;
261
+ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
262
+ if (!isNfcNormalized(tokenName)) {
263
+ throw new import_spark_sdk4.ValidationError("Token name must be NFC-normalised UTF-8", {
264
+ field: "tokenName",
265
+ value: tokenName,
266
+ expected: "NFC normalised string"
267
+ });
268
+ }
269
+ if (!isNfcNormalized(tokenTicker)) {
270
+ throw new import_spark_sdk4.ValidationError("Token ticker must be NFC-normalised UTF-8", {
271
+ field: "tokenTicker",
272
+ value: tokenTicker,
273
+ expected: "NFC normalised string"
274
+ });
275
+ }
276
+ const nameBytes = import_buffer.Buffer.from(tokenName, "utf-8").length;
277
+ if (nameBytes < MIN_NAME_SIZE || nameBytes > MAX_NAME_SIZE) {
278
+ throw new import_spark_sdk4.ValidationError(
279
+ `Token name must be between ${MIN_NAME_SIZE} and ${MAX_NAME_SIZE} bytes`,
280
+ {
281
+ field: "tokenName",
282
+ value: tokenName,
283
+ actualLength: nameBytes,
284
+ expected: `>=${MIN_NAME_SIZE} and <=${MAX_NAME_SIZE}`
285
+ }
286
+ );
287
+ }
288
+ const tickerBytes = import_buffer.Buffer.from(tokenTicker, "utf-8").length;
289
+ if (tickerBytes < MIN_SYMBOL_SIZE || tickerBytes > MAX_SYMBOL_SIZE) {
290
+ throw new import_spark_sdk4.ValidationError(
291
+ `Token ticker must be between ${MIN_SYMBOL_SIZE} and ${MAX_SYMBOL_SIZE} bytes`,
292
+ {
293
+ field: "tokenTicker",
294
+ value: tokenTicker,
295
+ actualLength: tickerBytes,
296
+ expected: `>=${MIN_SYMBOL_SIZE} and <=${MAX_SYMBOL_SIZE}`
297
+ }
298
+ );
299
+ }
300
+ if (!Number.isSafeInteger(decimals) || decimals < 0 || decimals > MAX_DECIMALS) {
301
+ throw new import_spark_sdk4.ValidationError(
302
+ `Decimals must be an integer between 0 and ${MAX_DECIMALS}`,
303
+ {
304
+ field: "decimals",
305
+ value: decimals,
306
+ expected: `>=0 and <=${MAX_DECIMALS}`
307
+ }
308
+ );
309
+ }
310
+ if (maxSupply < 0n || maxSupply > MAXIMUM_MAX_SUPPLY) {
311
+ throw new import_spark_sdk4.ValidationError(`maxSupply must be between 0 and 2^128-1`, {
312
+ field: "maxSupply",
313
+ value: maxSupply.toString(),
314
+ expected: `>=0 and <=${MAXIMUM_MAX_SUPPLY.toString()}`
315
+ });
316
+ }
317
+ }
318
+
319
+ // src/issuer-wallet/issuer-spark-wallet.ts
320
+ var import_spark_sdk9 = require("@buildonspark/spark-sdk");
321
+ var BURN_ADDRESS = "02".repeat(33);
322
+ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk5.SparkWallet {
323
+ issuerTokenTransactionService;
324
+ tokenFreezeService;
325
+ tracerId = "issuer-sdk";
326
+ /**
327
+ * Initializes a new IssuerSparkWallet instance.
328
+ * @param options - Configuration options for the wallet
329
+ * @returns An object containing the initialized wallet and initialization response
330
+ */
331
+ static async initialize({
332
+ mnemonicOrSeed,
333
+ accountNumber,
334
+ signer,
335
+ options
336
+ }) {
337
+ const wallet = new _IssuerSparkWallet(options, signer);
338
+ wallet.initializeTracer(wallet);
339
+ const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
340
+ return {
341
+ wallet,
342
+ ...initResponse
343
+ };
344
+ }
345
+ constructor(configOptions, signer) {
346
+ super(configOptions, signer);
347
+ this.issuerTokenTransactionService = new IssuerTokenTransactionService(
348
+ this.config,
349
+ this.connectionManager
350
+ );
351
+ this.tokenFreezeService = new TokenFreezeService(
352
+ this.config,
353
+ this.connectionManager
354
+ );
355
+ this.wrapIssuerSparkWalletMethodsWithTracing();
356
+ }
357
+ /**
358
+ * Gets the token balance for the issuer's token.
359
+ * @returns An object containing the token balance as a bigint
360
+ */
361
+ async getIssuerTokenBalance() {
362
+ const publicKey = await super.getIdentityPublicKey();
363
+ const balanceObj = await this.getBalance();
364
+ const issuerBalance = [...balanceObj.tokenBalances.entries()].find(
365
+ ([, info]) => info.tokenMetadata.tokenPublicKey === publicKey
366
+ );
367
+ if (!balanceObj.tokenBalances || issuerBalance === void 0) {
368
+ return {
369
+ tokenIdentifier: void 0,
370
+ balance: 0n
371
+ };
372
+ }
373
+ return {
374
+ tokenIdentifier: issuerBalance[0] ?? void 0,
375
+ balance: issuerBalance[1].balance
376
+ };
377
+ }
378
+ /**
379
+ * Retrieves information about the issuer's token.
380
+ * @returns An object containing token information including public key, name, symbol, decimals, max supply, and freeze status
381
+ * @throws {NetworkError} If the token metadata cannot be retrieved
382
+ */
383
+ async getIssuerTokenMetadata() {
384
+ const issuerPublicKey = await super.getIdentityPublicKey();
385
+ const tokenMetadata = this.tokenMetadata;
386
+ const cachedIssuerTokenMetadata = [...tokenMetadata.entries()].find(
387
+ ([, metadata]) => (0, import_utils4.bytesToHex)(metadata.issuerPublicKey) === issuerPublicKey
388
+ );
389
+ if (cachedIssuerTokenMetadata !== void 0) {
390
+ const metadata = cachedIssuerTokenMetadata[1];
391
+ return {
392
+ tokenPublicKey: (0, import_utils4.bytesToHex)(metadata.issuerPublicKey),
393
+ rawTokenIdentifier: metadata.tokenIdentifier,
394
+ tokenName: metadata.tokenName,
395
+ tokenTicker: metadata.tokenTicker,
396
+ decimals: metadata.decimals,
397
+ maxSupply: (0, import_utils4.bytesToNumberBE)(metadata.maxSupply),
398
+ isFreezable: metadata.isFreezable
399
+ };
400
+ }
401
+ const sparkTokenClient = await this.connectionManager.createSparkTokenClient(
402
+ this.config.getCoordinatorAddress()
403
+ );
404
+ try {
405
+ const response = await sparkTokenClient.query_token_metadata({
406
+ issuerPublicKeys: Array.of((0, import_utils4.hexToBytes)(issuerPublicKey))
407
+ });
408
+ if (response.tokenMetadata.length === 0) {
409
+ throw new import_spark_sdk5.ValidationError(
410
+ "Token metadata not found - If a token has not yet been announced, please announce. If a token was recently announced, it is being confirmed. Try again in a few seconds.",
411
+ {
412
+ field: "tokenMetadata",
413
+ value: response.tokenMetadata,
414
+ expected: "non-empty array",
415
+ actualLength: response.tokenMetadata.length,
416
+ expectedLength: 1
417
+ }
418
+ );
419
+ }
420
+ const metadata = response.tokenMetadata[0];
421
+ const tokenIdentifier = (0, import_spark_sdk9.encodeBech32mTokenIdentifier)({
422
+ tokenIdentifier: metadata.tokenIdentifier,
423
+ network: this.config.getNetworkType()
424
+ });
425
+ this.tokenMetadata.set(tokenIdentifier, metadata);
426
+ return {
427
+ tokenPublicKey: (0, import_utils4.bytesToHex)(metadata.issuerPublicKey),
428
+ rawTokenIdentifier: metadata.tokenIdentifier,
429
+ tokenName: metadata.tokenName,
430
+ tokenTicker: metadata.tokenTicker,
431
+ decimals: metadata.decimals,
432
+ maxSupply: (0, import_utils4.bytesToNumberBE)(metadata.maxSupply),
433
+ isFreezable: metadata.isFreezable
434
+ };
435
+ } catch (error) {
436
+ throw new import_spark_sdk5.NetworkError("Failed to fetch token metadata", {
437
+ errorCount: 1,
438
+ errors: error instanceof Error ? error.message : String(error)
439
+ });
440
+ }
441
+ }
442
+ /**
443
+ * Retrieves the bech32m encoded token identifier for the issuer's token.
444
+ * @returns The bech32m encoded token identifier for the issuer's token
445
+ * @throws {NetworkError} If the token identifier cannot be retrieved
446
+ */
447
+ async getIssuerTokenIdentifier() {
448
+ const tokenMetadata = await this.getIssuerTokenMetadata();
449
+ return (0, import_spark_sdk9.encodeBech32mTokenIdentifier)({
450
+ tokenIdentifier: tokenMetadata.rawTokenIdentifier,
451
+ network: this.config.getNetworkType()
452
+ });
453
+ }
454
+ /**
455
+ * Create a new token on Spark.
456
+ *
457
+ * @param params - Object containing token creation parameters.
458
+ * @param params.tokenName - The name of the token.
459
+ * @param params.tokenTicker - The ticker symbol for the token.
460
+ * @param params.decimals - The number of decimal places for the token.
461
+ * @param params.isFreezable - Whether the token can be frozen.
462
+ * @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
463
+ *
464
+ * @returns The transaction ID of the announcement.
465
+ *
466
+ * @throws {ValidationError} If `decimals` is not a safe integer or other validation fails.
467
+ * @throws {NetworkError} If the announcement transaction cannot be broadcast.
468
+ */
469
+ async createToken({
470
+ tokenName,
471
+ tokenTicker,
472
+ decimals,
473
+ isFreezable,
474
+ maxSupply = 0n
475
+ }) {
476
+ validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply);
477
+ const issuerPublicKey = await super.getIdentityPublicKey();
478
+ const tokenTransaction = await this.issuerTokenTransactionService.constructCreateTokenTransaction(
479
+ (0, import_utils4.hexToBytes)(issuerPublicKey),
480
+ tokenName,
481
+ tokenTicker,
482
+ decimals,
483
+ maxSupply,
484
+ isFreezable
485
+ );
486
+ return await this.issuerTokenTransactionService.broadcastTokenTransaction(
487
+ tokenTransaction
488
+ );
489
+ }
490
+ /**
491
+ * Mints new tokens
492
+ * @param tokenAmount - The amount of tokens to mint
493
+ * @returns The transaction ID of the mint operation
494
+ */
495
+ async mintTokens(tokenAmount) {
496
+ let tokenTransaction;
497
+ const issuerTokenPublicKey = await super.getIdentityPublicKey();
498
+ const issuerTokenPublicKeyBytes = (0, import_utils4.hexToBytes)(issuerTokenPublicKey);
499
+ const tokenMetadata = await this.getIssuerTokenMetadata();
500
+ const rawTokenIdentifier = tokenMetadata.rawTokenIdentifier;
501
+ if (this.config.getTokenTransactionVersion() === "V0") {
502
+ tokenTransaction = await this.issuerTokenTransactionService.constructMintTokenTransactionV0(
503
+ issuerTokenPublicKeyBytes,
504
+ tokenAmount
505
+ );
506
+ } else {
507
+ tokenTransaction = await this.issuerTokenTransactionService.constructMintTokenTransaction(
508
+ rawTokenIdentifier,
509
+ issuerTokenPublicKeyBytes,
510
+ tokenAmount
511
+ );
512
+ }
513
+ return await this.issuerTokenTransactionService.broadcastTokenTransaction(
514
+ tokenTransaction
515
+ );
516
+ }
517
+ /**
518
+ * Burns issuer's tokens
519
+ * @param tokenAmount - The amount of tokens to burn
520
+ * @param selectedOutputs - Optional array of outputs to use for the burn operation
521
+ * @returns The transaction ID of the burn operation
522
+ */
523
+ async burnTokens(tokenAmount, selectedOutputs) {
524
+ const burnAddress = (0, import_spark_sdk6.encodeSparkAddress)({
525
+ identityPublicKey: BURN_ADDRESS,
526
+ network: this.config.getNetworkType()
527
+ });
528
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
529
+ return await this.transferTokens({
530
+ tokenIdentifier: issuerTokenIdentifier,
531
+ tokenAmount,
532
+ receiverSparkAddress: burnAddress,
533
+ selectedOutputs
534
+ });
535
+ }
536
+ /**
537
+ * Freezes tokens associated with a specific Spark address.
538
+ * @param sparkAddress - The Spark address whose tokens should be frozen
539
+ * @returns An object containing the IDs of impacted outputs and the total amount of frozen tokens
540
+ */
541
+ async freezeTokens(sparkAddress) {
542
+ await this.syncTokenOutputs();
543
+ const decodedOwnerPubkey = (0, import_spark_sdk6.decodeSparkAddress)(
544
+ sparkAddress,
545
+ this.config.getNetworkType()
546
+ );
547
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
548
+ const rawTokenIdentifier = (0, import_spark_sdk7.decodeBech32mTokenIdentifier)(
549
+ issuerTokenIdentifier,
550
+ this.config.getNetworkType()
551
+ ).tokenIdentifier;
552
+ const response = await this.tokenFreezeService.freezeTokens({
553
+ ownerPublicKey: (0, import_utils4.hexToBytes)(decodedOwnerPubkey.identityPublicKey),
554
+ tokenIdentifier: rawTokenIdentifier
555
+ });
556
+ const tokenAmount = (0, import_utils4.bytesToNumberBE)(response.impactedTokenAmount);
557
+ return {
558
+ impactedOutputIds: response.impactedOutputIds,
559
+ impactedTokenAmount: tokenAmount
560
+ };
561
+ }
562
+ /**
563
+ * Unfreezes previously frozen tokens associated with a specific Spark address.
564
+ * @param sparkAddress - The Spark address whose tokens should be unfrozen
565
+ * @returns An object containing the IDs of impacted outputs and the total amount of unfrozen tokens
566
+ */
567
+ async unfreezeTokens(sparkAddress) {
568
+ await this.syncTokenOutputs();
569
+ const decodedOwnerPubkey = (0, import_spark_sdk6.decodeSparkAddress)(
570
+ sparkAddress,
571
+ this.config.getNetworkType()
572
+ );
573
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
574
+ const rawTokenIdentifier = (0, import_spark_sdk7.decodeBech32mTokenIdentifier)(
575
+ issuerTokenIdentifier,
576
+ this.config.getNetworkType()
577
+ ).tokenIdentifier;
578
+ const response = await this.tokenFreezeService.unfreezeTokens({
579
+ ownerPublicKey: (0, import_utils4.hexToBytes)(decodedOwnerPubkey.identityPublicKey),
580
+ tokenIdentifier: rawTokenIdentifier
581
+ });
582
+ const tokenAmount = (0, import_utils4.bytesToNumberBE)(response.impactedTokenAmount);
583
+ return {
584
+ impactedOutputIds: response.impactedOutputIds,
585
+ impactedTokenAmount: tokenAmount
586
+ };
587
+ }
588
+ /**
589
+ * Retrieves the distribution information for the issuer's token.
590
+ * @throws {NotImplementedError} This feature is not yet supported
591
+ */
592
+ async getIssuerTokenDistribution() {
593
+ throw new import_spark_sdk8.NotImplementedError("Token distribution is not yet supported");
594
+ }
595
+ /**
596
+ * Announces a new token on the L1 (Bitcoin) network.
597
+ * @param tokenName - The name of the token
598
+ * @param tokenTicker - The ticker symbol for the token
599
+ * @param decimals - The number of decimal places for the token
600
+ * @param maxSupply - The maximum supply of the token
601
+ * @param isFreezable - Whether the token can be frozen
602
+ * @param feeRateSatsPerVb - The fee rate in satoshis per virtual byte (default: 4.0)
603
+ * @returns The transaction ID of the announcement
604
+ * @throws {ValidationError} If decimals is not a safe integer
605
+ * @throws {NetworkError} If the announcement transaction cannot be broadcast
606
+ */
607
+ async announceTokenL1(tokenName, tokenTicker, decimals, maxSupply, isFreezable, feeRateSatsPerVb = 4) {
608
+ validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply);
609
+ if (!Number.isSafeInteger(decimals)) {
610
+ throw new import_spark_sdk5.ValidationError("Decimals must be less than 2^53", {
611
+ field: "decimals",
612
+ value: decimals,
613
+ expected: "smaller or equal to " + Number.MAX_SAFE_INTEGER
614
+ });
615
+ }
616
+ await this.lrc20Wallet.syncWallet();
617
+ const tokenPublicKey = new import_lrc20_sdk.TokenPubkey(this.lrc20Wallet.pubkey);
618
+ const announcement = new import_lrc20_sdk.TokenPubkeyAnnouncement(
619
+ tokenPublicKey,
620
+ tokenName,
621
+ tokenTicker,
622
+ decimals,
623
+ maxSupply,
624
+ isFreezable
625
+ );
626
+ try {
627
+ const tx = await this.lrc20Wallet.prepareAnnouncement(
628
+ announcement,
629
+ feeRateSatsPerVb
630
+ );
631
+ const txId = await this.lrc20Wallet.broadcastRawBtcTransaction(
632
+ tx.bitcoin_tx.toHex()
633
+ );
634
+ return txId;
635
+ } catch (error) {
636
+ throw new import_spark_sdk5.NetworkError(
637
+ "Failed to broadcast announcement transaction on L1",
638
+ {
639
+ operation: "broadcastRawBtcTransaction",
640
+ errorCount: 1,
641
+ errors: error instanceof Error ? error.message : String(error)
642
+ }
643
+ );
644
+ }
645
+ }
646
+ getTraceName(methodName) {
647
+ return `IssuerSparkWallet.${methodName}`;
648
+ }
649
+ wrapPublicIssuerSparkWalletMethodWithOtelSpan(methodName) {
650
+ const original = this[methodName];
651
+ if (typeof original !== "function") {
652
+ throw new Error(
653
+ `Method ${methodName} is not a function on IssuerSparkWallet.`
654
+ );
655
+ }
656
+ const wrapped = this.wrapWithOtelSpan(
657
+ this.getTraceName(methodName),
658
+ original.bind(this)
659
+ );
660
+ this[methodName] = wrapped;
661
+ }
662
+ wrapIssuerSparkWalletMethodsWithTracing() {
663
+ const methods = [
664
+ "getIssuerTokenBalance",
665
+ "getIssuerTokenMetadata",
666
+ "getIssuerTokenIdentifier",
667
+ "createToken",
668
+ "mintTokens",
669
+ "burnTokens",
670
+ "freezeTokens",
671
+ "unfreezeTokens",
672
+ "getIssuerTokenDistribution",
673
+ "announceTokenL1"
674
+ ];
675
+ methods.forEach(
676
+ (m) => this.wrapPublicIssuerSparkWalletMethodWithOtelSpan(m)
677
+ );
678
+ }
679
+ };
680
+
681
+ // src/issuer-wallet/issuer-spark-wallet.node.ts
682
+ var import_spark_sdk10 = require("@buildonspark/spark-sdk");
683
+ var IssuerSparkWalletNodeJS = class _IssuerSparkWalletNodeJS extends IssuerSparkWallet {
684
+ static async initialize({
685
+ mnemonicOrSeed,
686
+ accountNumber,
687
+ signer,
688
+ options
689
+ }) {
690
+ const wallet = new _IssuerSparkWalletNodeJS(options, signer);
691
+ wallet.initializeTracer(wallet);
692
+ const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
693
+ return {
694
+ wallet,
695
+ ...initResponse
696
+ };
697
+ }
698
+ initializeTracerEnv({
699
+ spanProcessors,
700
+ traceUrls
701
+ }) {
702
+ (0, import_spark_sdk10.initializeTracerEnv)({ spanProcessors, traceUrls });
703
+ }
704
+ };
705
+ // Annotate the CommonJS export names for ESM import in node:
706
+ 0 && (module.exports = {
707
+ IssuerSparkWallet
708
+ });