@buildonspark/issuer-sdk 0.0.99 → 0.0.100

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,576 @@
1
+ require("react-native-get-random-values");
2
+
3
+ // buffer.js
4
+ import { Buffer } from "buffer";
5
+ if (typeof globalThis.Buffer === "undefined") {
6
+ globalThis.Buffer = Buffer;
7
+ }
8
+ if (typeof window !== "undefined") {
9
+ if (typeof window.global === "undefined") {
10
+ window.global = window;
11
+ }
12
+ if (typeof window.globalThis === "undefined") {
13
+ window.globalThis = window;
14
+ }
15
+ }
16
+
17
+ // src/issuer-wallet/issuer-spark-wallet.ts
18
+ import {
19
+ decodeBech32mTokenIdentifier,
20
+ decodeSparkAddress,
21
+ encodeBech32mTokenIdentifier,
22
+ encodeSparkAddress,
23
+ NetworkError as NetworkError2,
24
+ NotImplementedError,
25
+ SparkWallet,
26
+ ValidationError as ValidationError3
27
+ } from "@buildonspark/spark-sdk";
28
+ import { bytesToHex, bytesToNumberBE, hexToBytes as hexToBytes2 } from "@noble/curves/utils";
29
+
30
+ // src/services/freeze.ts
31
+ import {
32
+ NetworkError,
33
+ collectResponses
34
+ } from "@buildonspark/spark-sdk";
35
+ import { hexToBytes } from "@noble/curves/utils";
36
+
37
+ // src/utils/token-hashing.ts
38
+ import { sha256 } from "@scure/btc-signer/utils";
39
+ import { ValidationError } from "@buildonspark/spark-sdk";
40
+ function hashFreezeTokensPayload(payload) {
41
+ if (!payload) {
42
+ throw new ValidationError("Freeze tokens payload cannot be nil", {
43
+ field: "payload",
44
+ value: payload,
45
+ expected: "valid freeze tokens payload"
46
+ });
47
+ }
48
+ let allHashes = [];
49
+ const versionHashObj = sha256.create();
50
+ const versionBytes = new Uint8Array(4);
51
+ new DataView(versionBytes.buffer).setUint32(
52
+ 0,
53
+ payload.version,
54
+ false
55
+ // false for big-endian
56
+ );
57
+ versionHashObj.update(versionBytes);
58
+ allHashes.push(versionHashObj.digest());
59
+ const ownerPubKeyHash = sha256.create();
60
+ if (payload.ownerPublicKey) {
61
+ ownerPubKeyHash.update(payload.ownerPublicKey);
62
+ }
63
+ allHashes.push(ownerPubKeyHash.digest());
64
+ const tokenIdentifierHash = sha256.create();
65
+ if (payload.tokenIdentifier) {
66
+ tokenIdentifierHash.update(payload.tokenIdentifier);
67
+ }
68
+ allHashes.push(tokenIdentifierHash.digest());
69
+ const shouldUnfreezeHash = sha256.create();
70
+ shouldUnfreezeHash.update(new Uint8Array([payload.shouldUnfreeze ? 1 : 0]));
71
+ allHashes.push(shouldUnfreezeHash.digest());
72
+ const timestampHash = sha256.create();
73
+ if (payload.issuerProvidedTimestamp) {
74
+ const timestampBytes = new Uint8Array(8);
75
+ new DataView(timestampBytes.buffer).setBigUint64(
76
+ 0,
77
+ BigInt(payload.issuerProvidedTimestamp),
78
+ true
79
+ // true for little-endian
80
+ );
81
+ timestampHash.update(timestampBytes);
82
+ }
83
+ allHashes.push(timestampHash.digest());
84
+ const operatorPubKeyHash = sha256.create();
85
+ if (payload.operatorIdentityPublicKey) {
86
+ operatorPubKeyHash.update(payload.operatorIdentityPublicKey);
87
+ }
88
+ allHashes.push(operatorPubKeyHash.digest());
89
+ const finalHash = sha256.create();
90
+ for (const hash of allHashes) {
91
+ finalHash.update(hash);
92
+ }
93
+ return finalHash.digest();
94
+ }
95
+
96
+ // src/services/freeze.ts
97
+ var TokenFreezeService = class {
98
+ config;
99
+ connectionManager;
100
+ constructor(config, connectionManager) {
101
+ this.config = config;
102
+ this.connectionManager = connectionManager;
103
+ }
104
+ async freezeTokens({
105
+ ownerPublicKey,
106
+ tokenIdentifier
107
+ }) {
108
+ return this.freezeOperation(ownerPublicKey, false, tokenIdentifier);
109
+ }
110
+ async unfreezeTokens({
111
+ ownerPublicKey,
112
+ tokenIdentifier
113
+ }) {
114
+ return this.freezeOperation(ownerPublicKey, true, tokenIdentifier);
115
+ }
116
+ async freezeOperation(ownerPublicKey, shouldUnfreeze, tokenIdentifier) {
117
+ const signingOperators = this.config.getSigningOperators();
118
+ const issuerProvidedTimestamp = Date.now();
119
+ const freezeResponses = await Promise.allSettled(
120
+ Object.entries(signingOperators).map(async ([identifier, operator]) => {
121
+ const sparkTokenClient = await this.connectionManager.createSparkTokenClient(operator.address);
122
+ const freezeTokensPayload = {
123
+ version: 1,
124
+ ownerPublicKey,
125
+ tokenIdentifier,
126
+ shouldUnfreeze,
127
+ issuerProvidedTimestamp,
128
+ operatorIdentityPublicKey: hexToBytes(operator.identityPublicKey)
129
+ };
130
+ const hashedPayload = hashFreezeTokensPayload(freezeTokensPayload);
131
+ const issuerSignature = await this.config.signer.signMessageWithIdentityKey(hashedPayload);
132
+ try {
133
+ const response = await sparkTokenClient.freeze_tokens({
134
+ freezeTokensPayload,
135
+ issuerSignature
136
+ });
137
+ return {
138
+ identifier,
139
+ response
140
+ };
141
+ } catch (error) {
142
+ throw new NetworkError(
143
+ `Failed to send a freeze/unfreeze operation to operator: ${operator.address}`,
144
+ {
145
+ operation: "freeze_tokens",
146
+ errorCount: 1,
147
+ errors: error instanceof Error ? error.message : String(error)
148
+ },
149
+ error instanceof Error ? error : void 0
150
+ );
151
+ }
152
+ })
153
+ );
154
+ const successfulResponses = collectResponses(freezeResponses);
155
+ return successfulResponses[0].response;
156
+ }
157
+ };
158
+
159
+ // src/services/token-transactions.ts
160
+ import {
161
+ TokenTransactionService
162
+ } from "@buildonspark/spark-sdk";
163
+ import { numberToBytesBE } from "@noble/curves/utils";
164
+ var IssuerTokenTransactionService = class extends TokenTransactionService {
165
+ constructor(config, connectionManager) {
166
+ super(config, connectionManager);
167
+ }
168
+ async constructMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
169
+ return {
170
+ version: 2,
171
+ network: this.config.getNetworkProto(),
172
+ tokenInputs: {
173
+ $case: "mintInput",
174
+ mintInput: {
175
+ issuerPublicKey: issuerTokenPublicKey,
176
+ tokenIdentifier: rawTokenIdentifierBytes
177
+ }
178
+ },
179
+ tokenOutputs: [
180
+ {
181
+ ownerPublicKey: issuerTokenPublicKey,
182
+ tokenIdentifier: rawTokenIdentifierBytes,
183
+ tokenAmount: numberToBytesBE(tokenAmount, 16)
184
+ }
185
+ ],
186
+ clientCreatedTimestamp: /* @__PURE__ */ new Date(),
187
+ sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
188
+ expiryTime: void 0,
189
+ invoiceAttachments: []
190
+ };
191
+ }
192
+ async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
193
+ return {
194
+ version: 2,
195
+ network: this.config.getNetworkProto(),
196
+ tokenInputs: {
197
+ $case: "createInput",
198
+ createInput: {
199
+ issuerPublicKey: tokenPublicKey,
200
+ tokenName,
201
+ tokenTicker,
202
+ decimals,
203
+ maxSupply: numberToBytesBE(maxSupply, 16),
204
+ isFreezable
205
+ }
206
+ },
207
+ tokenOutputs: [],
208
+ clientCreatedTimestamp: /* @__PURE__ */ new Date(),
209
+ sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
210
+ expiryTime: void 0,
211
+ invoiceAttachments: []
212
+ };
213
+ }
214
+ };
215
+
216
+ // src/utils/create-validation.ts
217
+ import { ValidationError as ValidationError2 } from "@buildonspark/spark-sdk";
218
+ function isNfcNormalized(value) {
219
+ return value.normalize("NFC") === value;
220
+ }
221
+ var MIN_NAME_SIZE = 3;
222
+ var MAX_NAME_SIZE = 20;
223
+ var MIN_SYMBOL_SIZE = 3;
224
+ var MAX_SYMBOL_SIZE = 6;
225
+ var MAX_DECIMALS = 255;
226
+ var MAXIMUM_MAX_SUPPLY = (1n << 128n) - 1n;
227
+ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
228
+ if (!isNfcNormalized(tokenName)) {
229
+ throw new ValidationError2("Token name must be NFC-normalised UTF-8", {
230
+ field: "tokenName",
231
+ value: tokenName,
232
+ expected: "NFC normalised string"
233
+ });
234
+ }
235
+ if (!isNfcNormalized(tokenTicker)) {
236
+ throw new ValidationError2("Token ticker must be NFC-normalised UTF-8", {
237
+ field: "tokenTicker",
238
+ value: tokenTicker,
239
+ expected: "NFC normalised string"
240
+ });
241
+ }
242
+ const nameBytes = Buffer.from(tokenName, "utf-8").length;
243
+ if (nameBytes < MIN_NAME_SIZE || nameBytes > MAX_NAME_SIZE) {
244
+ throw new ValidationError2(
245
+ `Token name must be between ${MIN_NAME_SIZE} and ${MAX_NAME_SIZE} bytes`,
246
+ {
247
+ field: "tokenName",
248
+ value: tokenName,
249
+ actualLength: nameBytes,
250
+ expected: `>=${MIN_NAME_SIZE} and <=${MAX_NAME_SIZE}`
251
+ }
252
+ );
253
+ }
254
+ const tickerBytes = Buffer.from(tokenTicker, "utf-8").length;
255
+ if (tickerBytes < MIN_SYMBOL_SIZE || tickerBytes > MAX_SYMBOL_SIZE) {
256
+ throw new ValidationError2(
257
+ `Token ticker must be between ${MIN_SYMBOL_SIZE} and ${MAX_SYMBOL_SIZE} bytes`,
258
+ {
259
+ field: "tokenTicker",
260
+ value: tokenTicker,
261
+ actualLength: tickerBytes,
262
+ expected: `>=${MIN_SYMBOL_SIZE} and <=${MAX_SYMBOL_SIZE}`
263
+ }
264
+ );
265
+ }
266
+ if (!Number.isSafeInteger(decimals) || decimals < 0 || decimals > MAX_DECIMALS) {
267
+ throw new ValidationError2(
268
+ `Decimals must be an integer between 0 and ${MAX_DECIMALS}`,
269
+ {
270
+ field: "decimals",
271
+ value: decimals,
272
+ expected: `>=0 and <=${MAX_DECIMALS}`
273
+ }
274
+ );
275
+ }
276
+ if (maxSupply < 0n || maxSupply > MAXIMUM_MAX_SUPPLY) {
277
+ throw new ValidationError2(`maxSupply must be between 0 and 2^128-1`, {
278
+ field: "maxSupply",
279
+ value: maxSupply.toString(),
280
+ expected: `>=0 and <=${MAXIMUM_MAX_SUPPLY.toString()}`
281
+ });
282
+ }
283
+ }
284
+
285
+ // src/issuer-wallet/issuer-spark-wallet.ts
286
+ var BURN_ADDRESS = "02".repeat(33);
287
+ var IssuerSparkWallet = class extends SparkWallet {
288
+ issuerTokenTransactionService;
289
+ tokenFreezeService;
290
+ tracerId = "issuer-sdk";
291
+ /**
292
+ * Initializes a new IssuerSparkWallet instance.
293
+ * Inherits the generic static initialize from the base class.
294
+ */
295
+ constructor(configOptions, signer) {
296
+ super(configOptions, signer);
297
+ this.issuerTokenTransactionService = new IssuerTokenTransactionService(
298
+ this.config,
299
+ this.connectionManager
300
+ );
301
+ this.tokenFreezeService = new TokenFreezeService(
302
+ this.config,
303
+ this.connectionManager
304
+ );
305
+ this.wrapIssuerSparkWalletMethodsWithTracing();
306
+ }
307
+ /**
308
+ * Gets the token balance for the issuer's token.
309
+ * @returns An object containing the token balance as a bigint
310
+ */
311
+ async getIssuerTokenBalance() {
312
+ const publicKey = await super.getIdentityPublicKey();
313
+ const balanceObj = await this.getBalance();
314
+ const issuerBalance = [...balanceObj.tokenBalances.entries()].find(
315
+ ([, info]) => info.tokenMetadata.tokenPublicKey === publicKey
316
+ );
317
+ if (!balanceObj.tokenBalances || issuerBalance === void 0) {
318
+ return {
319
+ tokenIdentifier: void 0,
320
+ balance: 0n
321
+ };
322
+ }
323
+ return {
324
+ tokenIdentifier: issuerBalance[0] ?? void 0,
325
+ balance: issuerBalance[1].balance
326
+ };
327
+ }
328
+ /**
329
+ * Retrieves information about the issuer's token.
330
+ * @returns An object containing token information including public key, name, symbol, decimals, max supply, and freeze status
331
+ * @throws {NetworkError} If the token metadata cannot be retrieved
332
+ */
333
+ async getIssuerTokenMetadata() {
334
+ const issuerPublicKey = await super.getIdentityPublicKey();
335
+ const tokenMetadata = this.tokenMetadata;
336
+ const cachedIssuerTokenMetadata = [...tokenMetadata.entries()].find(
337
+ ([, metadata]) => bytesToHex(metadata.issuerPublicKey) === issuerPublicKey
338
+ );
339
+ if (cachedIssuerTokenMetadata !== void 0) {
340
+ const metadata = cachedIssuerTokenMetadata[1];
341
+ return {
342
+ tokenPublicKey: bytesToHex(metadata.issuerPublicKey),
343
+ rawTokenIdentifier: metadata.tokenIdentifier,
344
+ tokenName: metadata.tokenName,
345
+ tokenTicker: metadata.tokenTicker,
346
+ decimals: metadata.decimals,
347
+ maxSupply: bytesToNumberBE(metadata.maxSupply),
348
+ isFreezable: metadata.isFreezable
349
+ };
350
+ }
351
+ const sparkTokenClient = await this.connectionManager.createSparkTokenClient(
352
+ this.config.getCoordinatorAddress()
353
+ );
354
+ try {
355
+ const response = await sparkTokenClient.query_token_metadata({
356
+ issuerPublicKeys: Array.of(hexToBytes2(issuerPublicKey))
357
+ });
358
+ if (response.tokenMetadata.length === 0) {
359
+ throw new ValidationError3(
360
+ "Token metadata not found - If a token has not yet been created, please create it first. Try again in a few seconds.",
361
+ {
362
+ field: "tokenMetadata",
363
+ value: response.tokenMetadata,
364
+ expected: "non-empty array",
365
+ actualLength: response.tokenMetadata.length,
366
+ expectedLength: 1
367
+ }
368
+ );
369
+ }
370
+ const metadata = response.tokenMetadata[0];
371
+ const tokenIdentifier = encodeBech32mTokenIdentifier({
372
+ tokenIdentifier: metadata.tokenIdentifier,
373
+ network: this.config.getNetworkType()
374
+ });
375
+ this.tokenMetadata.set(tokenIdentifier, metadata);
376
+ return {
377
+ tokenPublicKey: bytesToHex(metadata.issuerPublicKey),
378
+ rawTokenIdentifier: metadata.tokenIdentifier,
379
+ tokenName: metadata.tokenName,
380
+ tokenTicker: metadata.tokenTicker,
381
+ decimals: metadata.decimals,
382
+ maxSupply: bytesToNumberBE(metadata.maxSupply),
383
+ isFreezable: metadata.isFreezable
384
+ };
385
+ } catch (error) {
386
+ throw new NetworkError2("Failed to fetch token metadata", {
387
+ errorCount: 1,
388
+ errors: error instanceof Error ? error.message : String(error)
389
+ });
390
+ }
391
+ }
392
+ /**
393
+ * Retrieves the bech32m encoded token identifier for the issuer's token.
394
+ * @returns The bech32m encoded token identifier for the issuer's token
395
+ * @throws {NetworkError} If the token identifier cannot be retrieved
396
+ */
397
+ async getIssuerTokenIdentifier() {
398
+ const tokenMetadata = await this.getIssuerTokenMetadata();
399
+ return encodeBech32mTokenIdentifier({
400
+ tokenIdentifier: tokenMetadata.rawTokenIdentifier,
401
+ network: this.config.getNetworkType()
402
+ });
403
+ }
404
+ /**
405
+ * Create a new token on Spark.
406
+ *
407
+ * @param params - Object containing token creation parameters.
408
+ * @param params.tokenName - The name of the token.
409
+ * @param params.tokenTicker - The ticker symbol for the token.
410
+ * @param params.decimals - The number of decimal places for the token.
411
+ * @param params.isFreezable - Whether the token can be frozen.
412
+ * @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
413
+ *
414
+ * @returns The transaction ID of the announcement.
415
+ *
416
+ * @throws {ValidationError} If `decimals` is not a safe integer or other validation fails.
417
+ * @throws {NetworkError} If the announcement transaction cannot be broadcast.
418
+ */
419
+ async createToken({
420
+ tokenName,
421
+ tokenTicker,
422
+ decimals,
423
+ isFreezable,
424
+ maxSupply = 0n
425
+ }) {
426
+ validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply);
427
+ const issuerPublicKey = await super.getIdentityPublicKey();
428
+ const tokenTransaction = await this.issuerTokenTransactionService.constructCreateTokenTransaction(
429
+ hexToBytes2(issuerPublicKey),
430
+ tokenName,
431
+ tokenTicker,
432
+ decimals,
433
+ maxSupply,
434
+ isFreezable
435
+ );
436
+ return await this.issuerTokenTransactionService.broadcastTokenTransaction(
437
+ tokenTransaction
438
+ );
439
+ }
440
+ /**
441
+ * Mints new tokens
442
+ * @param tokenAmount - The amount of tokens to mint
443
+ * @returns The transaction ID of the mint operation
444
+ */
445
+ async mintTokens(tokenAmount) {
446
+ const issuerTokenPublicKey = await super.getIdentityPublicKey();
447
+ const issuerTokenPublicKeyBytes = hexToBytes2(issuerTokenPublicKey);
448
+ const tokenMetadata = await this.getIssuerTokenMetadata();
449
+ const rawTokenIdentifier = tokenMetadata.rawTokenIdentifier;
450
+ const tokenTransaction = await this.issuerTokenTransactionService.constructMintTokenTransaction(
451
+ rawTokenIdentifier,
452
+ issuerTokenPublicKeyBytes,
453
+ tokenAmount
454
+ );
455
+ return await this.issuerTokenTransactionService.broadcastTokenTransaction(
456
+ tokenTransaction
457
+ );
458
+ }
459
+ /**
460
+ * Burns issuer's tokens
461
+ * @param tokenAmount - The amount of tokens to burn
462
+ * @param selectedOutputs - Optional array of outputs to use for the burn operation
463
+ * @returns The transaction ID of the burn operation
464
+ */
465
+ async burnTokens(tokenAmount, selectedOutputs) {
466
+ const burnAddress = encodeSparkAddress({
467
+ identityPublicKey: BURN_ADDRESS,
468
+ network: this.config.getNetworkType()
469
+ });
470
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
471
+ return await this.transferTokens({
472
+ tokenIdentifier: issuerTokenIdentifier,
473
+ tokenAmount,
474
+ receiverSparkAddress: burnAddress,
475
+ selectedOutputs
476
+ });
477
+ }
478
+ /**
479
+ * Freezes tokens associated with a specific Spark address.
480
+ * @param sparkAddress - The Spark address whose tokens should be frozen
481
+ * @returns An object containing the IDs of impacted outputs and the total amount of frozen tokens
482
+ */
483
+ async freezeTokens(sparkAddress) {
484
+ await this.syncTokenOutputs();
485
+ const decodedOwnerPubkey = decodeSparkAddress(
486
+ sparkAddress,
487
+ this.config.getNetworkType()
488
+ );
489
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
490
+ const rawTokenIdentifier = decodeBech32mTokenIdentifier(
491
+ issuerTokenIdentifier,
492
+ this.config.getNetworkType()
493
+ ).tokenIdentifier;
494
+ const response = await this.tokenFreezeService.freezeTokens({
495
+ ownerPublicKey: hexToBytes2(decodedOwnerPubkey.identityPublicKey),
496
+ tokenIdentifier: rawTokenIdentifier
497
+ });
498
+ const tokenAmount = bytesToNumberBE(response.impactedTokenAmount);
499
+ return {
500
+ impactedOutputIds: response.impactedOutputIds,
501
+ impactedTokenAmount: tokenAmount
502
+ };
503
+ }
504
+ /**
505
+ * Unfreezes previously frozen tokens associated with a specific Spark address.
506
+ * @param sparkAddress - The Spark address whose tokens should be unfrozen
507
+ * @returns An object containing the IDs of impacted outputs and the total amount of unfrozen tokens
508
+ */
509
+ async unfreezeTokens(sparkAddress) {
510
+ await this.syncTokenOutputs();
511
+ const decodedOwnerPubkey = decodeSparkAddress(
512
+ sparkAddress,
513
+ this.config.getNetworkType()
514
+ );
515
+ const issuerTokenIdentifier = await this.getIssuerTokenIdentifier();
516
+ const rawTokenIdentifier = decodeBech32mTokenIdentifier(
517
+ issuerTokenIdentifier,
518
+ this.config.getNetworkType()
519
+ ).tokenIdentifier;
520
+ const response = await this.tokenFreezeService.unfreezeTokens({
521
+ ownerPublicKey: hexToBytes2(decodedOwnerPubkey.identityPublicKey),
522
+ tokenIdentifier: rawTokenIdentifier
523
+ });
524
+ const tokenAmount = bytesToNumberBE(response.impactedTokenAmount);
525
+ return {
526
+ impactedOutputIds: response.impactedOutputIds,
527
+ impactedTokenAmount: tokenAmount
528
+ };
529
+ }
530
+ /**
531
+ * Retrieves the distribution information for the issuer's token.
532
+ * @throws {NotImplementedError} This feature is not yet supported
533
+ */
534
+ async getIssuerTokenDistribution() {
535
+ throw new NotImplementedError("Token distribution is not yet supported");
536
+ }
537
+ getTraceName(methodName) {
538
+ return `IssuerSparkWallet.${methodName}`;
539
+ }
540
+ wrapPublicIssuerSparkWalletMethodWithOtelSpan(methodName) {
541
+ const original = this[methodName];
542
+ if (typeof original !== "function") {
543
+ throw new Error(
544
+ `Method ${methodName} is not a function on IssuerSparkWallet.`
545
+ );
546
+ }
547
+ const wrapped = this.wrapWithOtelSpan(
548
+ this.getTraceName(methodName),
549
+ original.bind(this)
550
+ );
551
+ this[methodName] = wrapped;
552
+ }
553
+ wrapIssuerSparkWalletMethodsWithTracing() {
554
+ const methods = [
555
+ "getIssuerTokenBalance",
556
+ "getIssuerTokenMetadata",
557
+ "getIssuerTokenIdentifier",
558
+ "createToken",
559
+ "mintTokens",
560
+ "burnTokens",
561
+ "freezeTokens",
562
+ "unfreezeTokens",
563
+ "getIssuerTokenDistribution"
564
+ ];
565
+ methods.forEach(
566
+ (m) => this.wrapPublicIssuerSparkWalletMethodWithOtelSpan(m)
567
+ );
568
+ }
569
+ };
570
+
571
+ // src/issuer-wallet/issuer-spark-wallet.react-native.ts
572
+ var IssuerSparkWalletReactNative = class extends IssuerSparkWallet {
573
+ };
574
+ export {
575
+ IssuerSparkWalletReactNative as IssuerSparkWallet
576
+ };
package/package.json CHANGED
@@ -1,15 +1,27 @@
1
1
  {
2
2
  "name": "@buildonspark/issuer-sdk",
3
- "version": "0.0.99",
3
+ "version": "0.0.100",
4
4
  "description": "Spark Issuer SDK for token issuance",
5
5
  "license": "Apache-2.0",
6
- "module": "./dist/index.js",
6
+ "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "module": "./dist/index.js",
9
+ "react-native": "./dist/native/index.react-native.js",
8
10
  "type": "module",
9
11
  "homepage": "https://github.com/buildonspark/spark",
10
12
  "exports": {
11
13
  ".": {
14
+ "react-native": {
15
+ "types": "./dist/native/index.react-native.d.ts",
16
+ "import": "./dist/native/index.react-native.js",
17
+ "require": "./dist/native/index.react-native.cjs",
18
+ "default": "./dist/native/index.react-native.js"
19
+ },
12
20
  "import": {
21
+ "bun": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ },
13
25
  "node": {
14
26
  "types": "./dist/index.node.d.ts",
15
27
  "default": "./dist/index.node.js"
@@ -20,6 +32,10 @@
20
32
  }
21
33
  },
22
34
  "require": {
35
+ "bun": {
36
+ "types": "./dist/index.d.cts",
37
+ "default": "./dist/index.cjs"
38
+ },
23
39
  "node": {
24
40
  "types": "./dist/index.node.d.cts",
25
41
  "default": "./dist/index.node.cjs"
@@ -33,6 +49,10 @@
33
49
  "./proto/spark": {
34
50
  "import": "./dist/proto/spark.js",
35
51
  "require": "./dist/proto/spark.cjs"
52
+ },
53
+ "./native": {
54
+ "import": "./dist/native/index.react-native.js",
55
+ "require": "./dist/native/index.react-native.cjs"
36
56
  }
37
57
  },
38
58
  "files": [
@@ -41,7 +61,7 @@
41
61
  "CHANGELOG.md"
42
62
  ],
43
63
  "scripts": {
44
- "build": "yarn tsc && tsup",
64
+ "build": "yarn tsc && rm -rf dist && tsup",
45
65
  "build:watch": "yarn build --watch --clean=false",
46
66
  "clean": "rm -rf dist",
47
67
  "circular-deps": "madge --circular --extensions ts,tsx src",
@@ -64,7 +84,7 @@
64
84
  "types": "tsc"
65
85
  },
66
86
  "dependencies": {
67
- "@buildonspark/spark-sdk": "0.3.6",
87
+ "@buildonspark/spark-sdk": "0.3.7",
68
88
  "@noble/curves": "^1.8.0",
69
89
  "@scure/btc-signer": "^1.5.0",
70
90
  "buffer": "^6.0.3"
@@ -80,10 +100,29 @@
80
100
  "node-fetch": "^3.3.2",
81
101
  "prettier": "^3.6.2",
82
102
  "publint": "^0.3.9",
103
+ "react": "19.0.0",
104
+ "react-native": "0.79.4",
105
+ "react-native-get-random-values": "^1.11.0",
83
106
  "ts-jest": "^29.2.5",
84
107
  "tsup": "^8.4.0",
85
108
  "typescript": "^5.7.3"
86
109
  },
110
+ "peerDependencies": {
111
+ "react": ">=18.2.0",
112
+ "react-native": ">=0.71.0",
113
+ "react-native-get-random-values": ">=1.11.0"
114
+ },
115
+ "peerDependenciesMeta": {
116
+ "react": {
117
+ "optional": true
118
+ },
119
+ "react-native": {
120
+ "optional": true
121
+ },
122
+ "react-native-get-random-values": {
123
+ "optional": true
124
+ }
125
+ },
87
126
  "engines": {
88
127
  "node": ">=18.0.0"
89
128
  },
@@ -0,0 +1,4 @@
1
+ /* Root React Native entrypoint */
2
+
3
+ export { IssuerSparkWalletReactNative as IssuerSparkWallet } from "./issuer-wallet/issuer-spark-wallet.react-native.js";
4
+ export * from "./issuer-wallet/types.js";
@@ -0,0 +1,8 @@
1
+ import { IssuerSparkWallet as BaseIssuerSparkWallet } from "./issuer-spark-wallet.js";
2
+ import type { WalletConfigService } from "@buildonspark/spark-sdk";
3
+
4
+ /* We just need this path to exist to prevent RN from importing the default browser version.
5
+ This extends @buildonspark/spark-sdk ReactNativeSparkWallet due to export paths there. */
6
+ export class IssuerSparkWalletReactNative extends BaseIssuerSparkWallet {}
7
+
8
+ export { IssuerSparkWalletReactNative as IssuerSparkWallet };