@buildonspark/issuer-sdk 0.0.110 → 0.1.1
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 +47 -0
- package/dist/{issuer-spark-wallet-BdN--ywq.d.cts → index.browser.d.ts} +19 -10
- package/dist/{chunk-M6QULHGS.js → index.browser.js} +208 -80
- package/dist/index.node.cjs +181 -72
- package/dist/index.node.d.cts +150 -5
- package/dist/index.node.d.ts +150 -5
- package/dist/index.node.js +666 -4
- package/dist/native/index.react-native.cjs +181 -72
- package/dist/native/index.react-native.d.cts +13 -8
- package/dist/native/index.react-native.d.ts +13 -8
- package/dist/native/index.react-native.js +186 -77
- package/dist/proto/spark.d.cts +3 -0
- package/dist/proto/spark.d.ts +3 -0
- package/dist/proto/spark_token.cjs +40 -0
- package/dist/proto/spark_token.d.cts +1 -0
- package/dist/proto/spark_token.d.ts +1 -0
- package/dist/proto/spark_token.js +4 -0
- package/dist/tests/test-utils.cjs +40 -0
- package/dist/tests/test-utils.d.cts +1 -0
- package/dist/tests/test-utils.d.ts +1 -0
- package/dist/tests/test-utils.js +4 -0
- package/dist/types/index.cjs +40 -0
- package/dist/types/index.d.cts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +4 -0
- package/package.json +11 -19
- package/src/index-shared.ts +25 -0
- package/src/{index.ts → index.browser.ts} +1 -1
- package/src/index.node.ts +1 -1
- package/src/index.react-native.ts +1 -1
- package/src/issuer-wallet/issuer-spark-wallet.browser.ts +0 -8
- package/src/issuer-wallet/issuer-spark-wallet.ts +121 -57
- package/src/issuer-wallet/types.ts +2 -0
- package/src/services/freeze.ts +3 -8
- package/src/services/token-transactions.ts +78 -1
- package/src/tests/integration/nft-creation.test.ts +62 -0
- package/src/tests/integration/test-configs.ts +32 -0
- package/src/tests/integration/token-creation.test.ts +1 -16
- package/src/tests/integration/token-invoices.test.ts +5 -27
- package/src/tests/integration/token-lifecycle.test.ts +2 -20
- package/src/tests/integration/token-minting.test.ts +1 -16
- package/src/tests/integration/token-monitoring.test.ts +5 -22
- package/src/tests/integration/token-outputs.test.ts +2 -20
- package/src/tests/integration/token-transfers.test.ts +2 -20
- package/src/tests/test-utils.ts +1 -0
- package/src/tests/utils/issuer-test-wallet.ts +0 -1
- package/src/types/index.ts +1 -0
- package/src/utils/create-validation.ts +27 -11
- package/src/utils/token-hashing.ts +2 -2
- package/dist/index.cjs +0 -597
- package/dist/index.d.cts +0 -11
- package/dist/index.d.ts +0 -11
- package/dist/index.js +0 -24
- package/dist/issuer-spark-wallet-BdN--ywq.d.ts +0 -146
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @buildonspark/issuer-sdk
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- **Token transaction v3**
|
|
8
|
+
- Updated test configs and expanded test coverage to include both v2 and v3 token transactions
|
|
9
|
+
|
|
10
|
+
**Extra metadata field available when creating new tokens**
|
|
11
|
+
- Added a field to accept additional bytes data to attach to token creates
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @buildonspark/spark-sdk@0.5.1
|
|
15
|
+
|
|
16
|
+
## 0.1.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- - **Entry points & module resolution**
|
|
21
|
+
- The package now provides distinct entrypoints:
|
|
22
|
+
- `index.browser` (default `module`/`import` for browser/bundlers).
|
|
23
|
+
- `index.node` for Node environments.
|
|
24
|
+
- `index.react-native` for React Native.
|
|
25
|
+
- The `exports` map was simplified and modernized so:
|
|
26
|
+
- `import { IssuerSparkWallet } from "@buildonspark/issuer-sdk"` resolves correctly in Node ESM, bundlers, and React Native without manual path selection.
|
|
27
|
+
- Type definitions for browser/Node/React Native are correctly wired.
|
|
28
|
+
- **Shared API surface**
|
|
29
|
+
- A new `index-shared` consolidates type and helper re‑exports:
|
|
30
|
+
- Re‑exports signer types (`DefaultSparkSigner`, `UnsafeStatelessSparkSigner`, `SparkSigner` and related Frost types).
|
|
31
|
+
- Re‑exports `WalletConfig`, `ConfigOptions`, and issuer‑specific types (`IssuerTokenMetadata`, etc.).
|
|
32
|
+
- Public API usage for typical consumers (importing `IssuerSparkWallet` and issuer types) remains the same; only the internal file layout and `exports` map changed.
|
|
33
|
+
- **Token transaction v3 support**
|
|
34
|
+
- `IssuerTokenTransactionService` gained:
|
|
35
|
+
- `constructPartialCreateTokenTransaction(...)` and `constructPartialMintTokenTransaction(...)` that build v3 `PartialTokenTransaction` objects with metadata and withdraw parameters.
|
|
36
|
+
- These complement the existing v2 `constructCreateTokenTransaction` and `constructMintTokenTransaction`.
|
|
37
|
+
- `IssuerSparkWallet.createToken` and `mintTokens` now:
|
|
38
|
+
- Check `config.getTokenTransactionVersion()`.
|
|
39
|
+
- Use v2 full transactions and `broadcastTokenTransaction(...)` when `"V2"`.
|
|
40
|
+
- Use v3 partial transactions and `broadcastTokenTransactionV3(...)` when `"V3"`.
|
|
41
|
+
- **Error and method wrapping**
|
|
42
|
+
- Issuer services and `IssuerSparkWallet` now emit the same simplified `SparkError` family used in `spark-sdk`, aligning error handling semantics for issuers with the core wallet.
|
|
43
|
+
- Public issuer wallet methods are wrapped via `SparkWallet.wrapMethod`, so they benefit from the centralized error‑wrapping and consistent error surface.
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- Updated dependencies
|
|
48
|
+
- @buildonspark/spark-sdk@0.5.0
|
|
49
|
+
|
|
3
50
|
## 0.0.110
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SparkWallet, ConfigOptions, SparkSigner, Bech32mTokenIdentifier } from '@buildonspark/spark-sdk';
|
|
1
|
+
import { SparkWallet, ConfigOptions, SparkSigner, Bech32mTokenIdentifier, WalletConfigService, ConnectionManager } from '@buildonspark/spark-sdk';
|
|
2
|
+
export { AggregateFrostParams, ConfigOptions, DefaultSparkSigner, DerivedHDKey, DummyTx, IKeyPackage, KeyDerivation, KeyDerivationType, KeyPair, SignFrostParams, SigningCommitment, SigningCommitmentWithOptionalNonce, SigningNonce, SparkSigner, SplitSecretWithProofsParams, SubtractSplitAndEncryptParams, SubtractSplitAndEncryptResult, UnsafeStatelessSparkSigner, WalletConfig, WalletConfigService } from '@buildonspark/spark-sdk';
|
|
2
3
|
import { OutputWithPreviousTransactionData } from '@buildonspark/spark-sdk/proto/spark_token';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -37,6 +38,8 @@ type IssuerTokenMetadata = {
|
|
|
37
38
|
maxSupply: bigint;
|
|
38
39
|
/** Whether the token is freezable */
|
|
39
40
|
isFreezable: boolean;
|
|
41
|
+
/** Extra metadata of the token */
|
|
42
|
+
extraMetadata?: Uint8Array;
|
|
40
43
|
};
|
|
41
44
|
interface TokenDistribution {
|
|
42
45
|
totalCirculatingSupply: bigint;
|
|
@@ -71,13 +74,13 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
71
74
|
/**
|
|
72
75
|
* Retrieves information about the issuer's token.
|
|
73
76
|
* @returns An object containing token information including public key, name, symbol, decimals, max supply, and freeze status
|
|
74
|
-
* @throws {
|
|
77
|
+
* @throws {SparkRequestError} If the token metadata cannot be retrieved
|
|
75
78
|
*/
|
|
76
79
|
getIssuerTokenMetadata(): Promise<IssuerTokenMetadata>;
|
|
77
80
|
/**
|
|
78
81
|
* Retrieves the bech32m encoded token identifier for the issuer's token.
|
|
79
82
|
* @returns The bech32m encoded token identifier for the issuer's token
|
|
80
|
-
* @throws {
|
|
83
|
+
* @throws {SparkRequestError} If the token identifier cannot be retrieved
|
|
81
84
|
*/
|
|
82
85
|
getIssuerTokenIdentifier(): Promise<Bech32mTokenIdentifier>;
|
|
83
86
|
/**
|
|
@@ -89,18 +92,20 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
89
92
|
* @param params.decimals - The number of decimal places for the token.
|
|
90
93
|
* @param params.isFreezable - Whether the token can be frozen.
|
|
91
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.
|
|
92
96
|
*
|
|
93
97
|
* @returns The transaction ID of the announcement.
|
|
94
98
|
*
|
|
95
|
-
* @throws {
|
|
96
|
-
* @throws {
|
|
99
|
+
* @throws {SparkValidationError} If `decimals` is not a safe integer or other validation fails.
|
|
100
|
+
* @throws {SparkRequestError} If the announcement transaction cannot be broadcast.
|
|
97
101
|
*/
|
|
98
|
-
createToken({ tokenName, tokenTicker, decimals, isFreezable, maxSupply, }: {
|
|
102
|
+
createToken({ tokenName, tokenTicker, decimals, isFreezable, maxSupply, extraMetadata, }: {
|
|
99
103
|
tokenName: string;
|
|
100
104
|
tokenTicker: string;
|
|
101
105
|
decimals: number;
|
|
102
106
|
isFreezable: boolean;
|
|
103
107
|
maxSupply?: bigint;
|
|
108
|
+
extraMetadata?: Uint8Array;
|
|
104
109
|
}): Promise<string>;
|
|
105
110
|
/**
|
|
106
111
|
* Mints new tokens
|
|
@@ -135,12 +140,16 @@ declare abstract class IssuerSparkWallet extends SparkWallet {
|
|
|
135
140
|
}>;
|
|
136
141
|
/**
|
|
137
142
|
* Retrieves the distribution information for the issuer's token.
|
|
138
|
-
* @throws {
|
|
143
|
+
* @throws {SparkError} This feature is not yet supported
|
|
139
144
|
*/
|
|
140
145
|
getIssuerTokenDistribution(): Promise<TokenDistribution>;
|
|
141
146
|
protected getTraceName(methodName: string): string;
|
|
142
|
-
private
|
|
143
|
-
private
|
|
147
|
+
private wrapIssuerPublicMethod;
|
|
148
|
+
private wrapIssuerSparkWalletMethods;
|
|
144
149
|
}
|
|
145
150
|
|
|
146
|
-
|
|
151
|
+
declare class IssuerSparkWalletBrowser extends IssuerSparkWallet {
|
|
152
|
+
protected buildConnectionManager(config: WalletConfigService): ConnectionManager;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { IssuerSparkWalletBrowser as IssuerSparkWallet, type IssuerTokenMetadata, type TokenDistribution };
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// buffer.js
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
if (typeof globalThis.Buffer === "undefined") {
|
|
4
|
+
globalThis.Buffer = Buffer;
|
|
5
|
+
}
|
|
6
|
+
if (typeof window !== "undefined") {
|
|
7
|
+
if (typeof window.global === "undefined") {
|
|
8
|
+
window.global = window;
|
|
9
|
+
}
|
|
10
|
+
if (typeof window.globalThis === "undefined") {
|
|
11
|
+
window.globalThis = window;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
4
14
|
|
|
5
15
|
// src/issuer-wallet/issuer-spark-wallet.ts
|
|
6
16
|
import {
|
|
@@ -8,26 +18,26 @@ import {
|
|
|
8
18
|
decodeSparkAddress,
|
|
9
19
|
encodeBech32mTokenIdentifier,
|
|
10
20
|
encodeSparkAddress,
|
|
11
|
-
|
|
12
|
-
NotImplementedError,
|
|
21
|
+
SparkError,
|
|
13
22
|
SparkWallet,
|
|
14
|
-
|
|
23
|
+
SparkRequestError as SparkRequestError2,
|
|
24
|
+
SparkValidationError as SparkValidationError3
|
|
15
25
|
} from "@buildonspark/spark-sdk";
|
|
16
26
|
import { bytesToHex, bytesToNumberBE, hexToBytes as hexToBytes2 } from "@noble/curves/utils";
|
|
17
27
|
|
|
18
28
|
// src/services/freeze.ts
|
|
19
29
|
import {
|
|
20
|
-
|
|
30
|
+
SparkRequestError,
|
|
21
31
|
collectResponses
|
|
22
32
|
} from "@buildonspark/spark-sdk";
|
|
23
33
|
import { hexToBytes } from "@noble/curves/utils";
|
|
24
34
|
|
|
25
35
|
// src/utils/token-hashing.ts
|
|
26
36
|
import { sha256 } from "@scure/btc-signer/utils";
|
|
27
|
-
import {
|
|
37
|
+
import { SparkValidationError } from "@buildonspark/spark-sdk";
|
|
28
38
|
function hashFreezeTokensPayload(payload) {
|
|
29
39
|
if (!payload) {
|
|
30
|
-
throw new
|
|
40
|
+
throw new SparkValidationError("Freeze tokens payload cannot be nil", {
|
|
31
41
|
field: "payload",
|
|
32
42
|
value: payload,
|
|
33
43
|
expected: "valid freeze tokens payload"
|
|
@@ -127,14 +137,9 @@ var TokenFreezeService = class {
|
|
|
127
137
|
response
|
|
128
138
|
};
|
|
129
139
|
} catch (error) {
|
|
130
|
-
throw new
|
|
140
|
+
throw new SparkRequestError(
|
|
131
141
|
`Failed to send a freeze/unfreeze operation to operator: ${operator.address}`,
|
|
132
|
-
{
|
|
133
|
-
operation: "freeze_tokens",
|
|
134
|
-
errorCount: 1,
|
|
135
|
-
errors: error instanceof Error ? error.message : String(error)
|
|
136
|
-
},
|
|
137
|
-
error instanceof Error ? error : void 0
|
|
142
|
+
{ operation: "freeze_tokens", error }
|
|
138
143
|
);
|
|
139
144
|
}
|
|
140
145
|
})
|
|
@@ -177,7 +182,35 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
|
|
|
177
182
|
invoiceAttachments: []
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
|
-
async
|
|
185
|
+
async constructPartialMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
|
|
186
|
+
return {
|
|
187
|
+
version: 3,
|
|
188
|
+
tokenTransactionMetadata: {
|
|
189
|
+
network: this.config.getNetworkProto(),
|
|
190
|
+
sparkOperatorIdentityPublicKeys: this.collectOperatorIdentityPublicKeys(),
|
|
191
|
+
validityDurationSeconds: await this.config.getTokenValidityDurationSeconds(),
|
|
192
|
+
clientCreatedTimestamp: this.connectionManager.getCurrentServerTime(),
|
|
193
|
+
invoiceAttachments: []
|
|
194
|
+
},
|
|
195
|
+
tokenInputs: {
|
|
196
|
+
$case: "mintInput",
|
|
197
|
+
mintInput: {
|
|
198
|
+
issuerPublicKey: issuerTokenPublicKey,
|
|
199
|
+
tokenIdentifier: rawTokenIdentifierBytes
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
partialTokenOutputs: [
|
|
203
|
+
{
|
|
204
|
+
ownerPublicKey: issuerTokenPublicKey,
|
|
205
|
+
tokenIdentifier: rawTokenIdentifierBytes,
|
|
206
|
+
withdrawBondSats: this.config.getExpectedWithdrawBondSats(),
|
|
207
|
+
withdrawRelativeBlockLocktime: this.config.getExpectedWithdrawRelativeBlockLocktime(),
|
|
208
|
+
tokenAmount: numberToBytesBE(tokenAmount, 16)
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable, extraMetadata) {
|
|
181
214
|
return {
|
|
182
215
|
version: 2,
|
|
183
216
|
network: this.config.getNetworkProto(),
|
|
@@ -189,7 +222,8 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
|
|
|
189
222
|
tokenTicker,
|
|
190
223
|
decimals,
|
|
191
224
|
maxSupply: numberToBytesBE(maxSupply, 16),
|
|
192
|
-
isFreezable
|
|
225
|
+
isFreezable,
|
|
226
|
+
extraMetadata
|
|
193
227
|
}
|
|
194
228
|
},
|
|
195
229
|
tokenOutputs: [],
|
|
@@ -199,10 +233,35 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
|
|
|
199
233
|
invoiceAttachments: []
|
|
200
234
|
};
|
|
201
235
|
}
|
|
236
|
+
async constructPartialCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable, extraMetadata) {
|
|
237
|
+
return {
|
|
238
|
+
version: 3,
|
|
239
|
+
tokenTransactionMetadata: {
|
|
240
|
+
network: this.config.getNetworkProto(),
|
|
241
|
+
sparkOperatorIdentityPublicKeys: this.collectOperatorIdentityPublicKeys(),
|
|
242
|
+
validityDurationSeconds: await this.config.getTokenValidityDurationSeconds(),
|
|
243
|
+
clientCreatedTimestamp: this.connectionManager.getCurrentServerTime(),
|
|
244
|
+
invoiceAttachments: []
|
|
245
|
+
},
|
|
246
|
+
tokenInputs: {
|
|
247
|
+
$case: "createInput",
|
|
248
|
+
createInput: {
|
|
249
|
+
issuerPublicKey: tokenPublicKey,
|
|
250
|
+
tokenName,
|
|
251
|
+
tokenTicker,
|
|
252
|
+
decimals,
|
|
253
|
+
maxSupply: numberToBytesBE(maxSupply, 16),
|
|
254
|
+
isFreezable,
|
|
255
|
+
extraMetadata
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
partialTokenOutputs: []
|
|
259
|
+
};
|
|
260
|
+
}
|
|
202
261
|
};
|
|
203
262
|
|
|
204
263
|
// src/utils/create-validation.ts
|
|
205
|
-
import {
|
|
264
|
+
import { SparkValidationError as SparkValidationError2 } from "@buildonspark/spark-sdk";
|
|
206
265
|
function isNfcNormalized(value) {
|
|
207
266
|
return value.normalize("NFC") === value;
|
|
208
267
|
}
|
|
@@ -212,24 +271,28 @@ var MIN_SYMBOL_SIZE = 3;
|
|
|
212
271
|
var MAX_SYMBOL_SIZE = 6;
|
|
213
272
|
var MAX_DECIMALS = 255;
|
|
214
273
|
var MAXIMUM_MAX_SUPPLY = (1n << 128n) - 1n;
|
|
215
|
-
|
|
274
|
+
var MAX_TOKEN_CONTENT_SIZE = 1024;
|
|
275
|
+
function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply, extraMetadata) {
|
|
216
276
|
if (!isNfcNormalized(tokenName)) {
|
|
217
|
-
throw new
|
|
277
|
+
throw new SparkValidationError2("Token name must be NFC-normalised UTF-8", {
|
|
218
278
|
field: "tokenName",
|
|
219
279
|
value: tokenName,
|
|
220
280
|
expected: "NFC normalised string"
|
|
221
281
|
});
|
|
222
282
|
}
|
|
223
283
|
if (!isNfcNormalized(tokenTicker)) {
|
|
224
|
-
throw new
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
284
|
+
throw new SparkValidationError2(
|
|
285
|
+
"Token ticker must be NFC-normalised UTF-8",
|
|
286
|
+
{
|
|
287
|
+
field: "tokenTicker",
|
|
288
|
+
value: tokenTicker,
|
|
289
|
+
expected: "NFC normalised string"
|
|
290
|
+
}
|
|
291
|
+
);
|
|
229
292
|
}
|
|
230
293
|
const nameBytes = Buffer.from(tokenName, "utf-8").length;
|
|
231
294
|
if (nameBytes < MIN_NAME_SIZE || nameBytes > MAX_NAME_SIZE) {
|
|
232
|
-
throw new
|
|
295
|
+
throw new SparkValidationError2(
|
|
233
296
|
`Token name must be between ${MIN_NAME_SIZE} and ${MAX_NAME_SIZE} bytes`,
|
|
234
297
|
{
|
|
235
298
|
field: "tokenName",
|
|
@@ -241,7 +304,7 @@ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
|
|
|
241
304
|
}
|
|
242
305
|
const tickerBytes = Buffer.from(tokenTicker, "utf-8").length;
|
|
243
306
|
if (tickerBytes < MIN_SYMBOL_SIZE || tickerBytes > MAX_SYMBOL_SIZE) {
|
|
244
|
-
throw new
|
|
307
|
+
throw new SparkValidationError2(
|
|
245
308
|
`Token ticker must be between ${MIN_SYMBOL_SIZE} and ${MAX_SYMBOL_SIZE} bytes`,
|
|
246
309
|
{
|
|
247
310
|
field: "tokenTicker",
|
|
@@ -252,7 +315,7 @@ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
|
|
|
252
315
|
);
|
|
253
316
|
}
|
|
254
317
|
if (!Number.isSafeInteger(decimals) || decimals < 0 || decimals > MAX_DECIMALS) {
|
|
255
|
-
throw new
|
|
318
|
+
throw new SparkValidationError2(
|
|
256
319
|
`Decimals must be an integer between 0 and ${MAX_DECIMALS}`,
|
|
257
320
|
{
|
|
258
321
|
field: "decimals",
|
|
@@ -262,12 +325,22 @@ function validateTokenParameters(tokenName, tokenTicker, decimals, maxSupply) {
|
|
|
262
325
|
);
|
|
263
326
|
}
|
|
264
327
|
if (maxSupply < 0n || maxSupply > MAXIMUM_MAX_SUPPLY) {
|
|
265
|
-
throw new
|
|
328
|
+
throw new SparkValidationError2(`maxSupply must be between 0 and 2^128-1`, {
|
|
266
329
|
field: "maxSupply",
|
|
267
330
|
value: maxSupply.toString(),
|
|
268
331
|
expected: `>=0 and <=${MAXIMUM_MAX_SUPPLY.toString()}`
|
|
269
332
|
});
|
|
270
333
|
}
|
|
334
|
+
if (extraMetadata && extraMetadata.length > MAX_TOKEN_CONTENT_SIZE) {
|
|
335
|
+
throw new SparkValidationError2(
|
|
336
|
+
`Extra metadata must be less than ${MAX_TOKEN_CONTENT_SIZE} bytes`,
|
|
337
|
+
{
|
|
338
|
+
field: "extraMetadata",
|
|
339
|
+
value: extraMetadata.length,
|
|
340
|
+
expected: `<${MAX_TOKEN_CONTENT_SIZE}`
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
271
344
|
}
|
|
272
345
|
|
|
273
346
|
// src/issuer-wallet/issuer-spark-wallet.ts
|
|
@@ -290,7 +363,7 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
290
363
|
this.config,
|
|
291
364
|
this.connectionManager
|
|
292
365
|
);
|
|
293
|
-
this.
|
|
366
|
+
this.wrapIssuerSparkWalletMethods();
|
|
294
367
|
}
|
|
295
368
|
/**
|
|
296
369
|
* Gets the token balance for the issuer's token.
|
|
@@ -316,7 +389,7 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
316
389
|
/**
|
|
317
390
|
* Retrieves information about the issuer's token.
|
|
318
391
|
* @returns An object containing token information including public key, name, symbol, decimals, max supply, and freeze status
|
|
319
|
-
* @throws {
|
|
392
|
+
* @throws {SparkRequestError} If the token metadata cannot be retrieved
|
|
320
393
|
*/
|
|
321
394
|
async getIssuerTokenMetadata() {
|
|
322
395
|
const issuerPublicKey = await super.getIdentityPublicKey();
|
|
@@ -333,7 +406,8 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
333
406
|
tokenTicker: metadata.tokenTicker,
|
|
334
407
|
decimals: metadata.decimals,
|
|
335
408
|
maxSupply: bytesToNumberBE(metadata.maxSupply),
|
|
336
|
-
isFreezable: metadata.isFreezable
|
|
409
|
+
isFreezable: metadata.isFreezable,
|
|
410
|
+
extraMetadata: metadata.extraMetadata
|
|
337
411
|
};
|
|
338
412
|
}
|
|
339
413
|
const sparkTokenClient = await this.connectionManager.createSparkTokenClient(
|
|
@@ -344,7 +418,7 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
344
418
|
issuerPublicKeys: Array.of(hexToBytes2(issuerPublicKey))
|
|
345
419
|
});
|
|
346
420
|
if (response.tokenMetadata.length === 0) {
|
|
347
|
-
throw new
|
|
421
|
+
throw new SparkValidationError3(
|
|
348
422
|
"Token metadata not found - If a token has not yet been created, please create it first. Try again in a few seconds.",
|
|
349
423
|
{
|
|
350
424
|
field: "tokenMetadata",
|
|
@@ -368,19 +442,17 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
368
442
|
tokenTicker: metadata.tokenTicker,
|
|
369
443
|
decimals: metadata.decimals,
|
|
370
444
|
maxSupply: bytesToNumberBE(metadata.maxSupply),
|
|
371
|
-
isFreezable: metadata.isFreezable
|
|
445
|
+
isFreezable: metadata.isFreezable,
|
|
446
|
+
extraMetadata: metadata.extraMetadata
|
|
372
447
|
};
|
|
373
448
|
} catch (error) {
|
|
374
|
-
throw new
|
|
375
|
-
errorCount: 1,
|
|
376
|
-
errors: error instanceof Error ? error.message : String(error)
|
|
377
|
-
});
|
|
449
|
+
throw new SparkRequestError2("Failed to fetch token metadata", { error });
|
|
378
450
|
}
|
|
379
451
|
}
|
|
380
452
|
/**
|
|
381
453
|
* Retrieves the bech32m encoded token identifier for the issuer's token.
|
|
382
454
|
* @returns The bech32m encoded token identifier for the issuer's token
|
|
383
|
-
* @throws {
|
|
455
|
+
* @throws {SparkRequestError} If the token identifier cannot be retrieved
|
|
384
456
|
*/
|
|
385
457
|
async getIssuerTokenIdentifier() {
|
|
386
458
|
const tokenMetadata = await this.getIssuerTokenMetadata();
|
|
@@ -398,32 +470,56 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
398
470
|
* @param params.decimals - The number of decimal places for the token.
|
|
399
471
|
* @param params.isFreezable - Whether the token can be frozen.
|
|
400
472
|
* @param [params.maxSupply=0n] - (Optional) The maximum supply of the token. Defaults to <code>0n</code>.
|
|
473
|
+
* @param params.extraMetadata - (Optional) This can be used to store additional bytes data to be associated with a token, like image data.
|
|
401
474
|
*
|
|
402
475
|
* @returns The transaction ID of the announcement.
|
|
403
476
|
*
|
|
404
|
-
* @throws {
|
|
405
|
-
* @throws {
|
|
477
|
+
* @throws {SparkValidationError} If `decimals` is not a safe integer or other validation fails.
|
|
478
|
+
* @throws {SparkRequestError} If the announcement transaction cannot be broadcast.
|
|
406
479
|
*/
|
|
407
480
|
async createToken({
|
|
408
481
|
tokenName,
|
|
409
482
|
tokenTicker,
|
|
410
483
|
decimals,
|
|
411
484
|
isFreezable,
|
|
412
|
-
maxSupply = 0n
|
|
485
|
+
maxSupply = 0n,
|
|
486
|
+
extraMetadata
|
|
413
487
|
}) {
|
|
414
|
-
validateTokenParameters(
|
|
415
|
-
const issuerPublicKey = await super.getIdentityPublicKey();
|
|
416
|
-
const tokenTransaction = await this.issuerTokenTransactionService.constructCreateTokenTransaction(
|
|
417
|
-
hexToBytes2(issuerPublicKey),
|
|
488
|
+
validateTokenParameters(
|
|
418
489
|
tokenName,
|
|
419
490
|
tokenTicker,
|
|
420
491
|
decimals,
|
|
421
492
|
maxSupply,
|
|
422
|
-
|
|
423
|
-
);
|
|
424
|
-
return await this.issuerTokenTransactionService.broadcastTokenTransaction(
|
|
425
|
-
tokenTransaction
|
|
493
|
+
extraMetadata
|
|
426
494
|
);
|
|
495
|
+
const issuerPublicKey = await super.getIdentityPublicKey();
|
|
496
|
+
if (this.config.getTokenTransactionVersion() === "V2") {
|
|
497
|
+
const tokenTransaction = await this.issuerTokenTransactionService.constructCreateTokenTransaction(
|
|
498
|
+
hexToBytes2(issuerPublicKey),
|
|
499
|
+
tokenName,
|
|
500
|
+
tokenTicker,
|
|
501
|
+
decimals,
|
|
502
|
+
maxSupply,
|
|
503
|
+
isFreezable,
|
|
504
|
+
extraMetadata
|
|
505
|
+
);
|
|
506
|
+
return await this.issuerTokenTransactionService.broadcastTokenTransaction(
|
|
507
|
+
tokenTransaction
|
|
508
|
+
);
|
|
509
|
+
} else {
|
|
510
|
+
const partialTokenTransaction = await this.issuerTokenTransactionService.constructPartialCreateTokenTransaction(
|
|
511
|
+
hexToBytes2(issuerPublicKey),
|
|
512
|
+
tokenName,
|
|
513
|
+
tokenTicker,
|
|
514
|
+
decimals,
|
|
515
|
+
maxSupply,
|
|
516
|
+
isFreezable,
|
|
517
|
+
extraMetadata
|
|
518
|
+
);
|
|
519
|
+
return await this.issuerTokenTransactionService.broadcastTokenTransactionV3(
|
|
520
|
+
partialTokenTransaction
|
|
521
|
+
);
|
|
522
|
+
}
|
|
427
523
|
}
|
|
428
524
|
/**
|
|
429
525
|
* Mints new tokens
|
|
@@ -435,14 +531,25 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
435
531
|
const issuerTokenPublicKeyBytes = hexToBytes2(issuerTokenPublicKey);
|
|
436
532
|
const tokenMetadata = await this.getIssuerTokenMetadata();
|
|
437
533
|
const rawTokenIdentifier = tokenMetadata.rawTokenIdentifier;
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
534
|
+
if (this.config.getTokenTransactionVersion() === "V2") {
|
|
535
|
+
const tokenTransaction = await this.issuerTokenTransactionService.constructMintTokenTransaction(
|
|
536
|
+
rawTokenIdentifier,
|
|
537
|
+
issuerTokenPublicKeyBytes,
|
|
538
|
+
tokenAmount
|
|
539
|
+
);
|
|
540
|
+
return await this.issuerTokenTransactionService.broadcastTokenTransaction(
|
|
541
|
+
tokenTransaction
|
|
542
|
+
);
|
|
543
|
+
} else {
|
|
544
|
+
const partialTokenTransaction = await this.issuerTokenTransactionService.constructPartialMintTokenTransaction(
|
|
545
|
+
rawTokenIdentifier,
|
|
546
|
+
issuerTokenPublicKeyBytes,
|
|
547
|
+
tokenAmount
|
|
548
|
+
);
|
|
549
|
+
return await this.issuerTokenTransactionService.broadcastTokenTransactionV3(
|
|
550
|
+
partialTokenTransaction
|
|
551
|
+
);
|
|
552
|
+
}
|
|
446
553
|
}
|
|
447
554
|
/**
|
|
448
555
|
* Burns issuer's tokens
|
|
@@ -517,45 +624,66 @@ var IssuerSparkWallet = class extends SparkWallet {
|
|
|
517
624
|
}
|
|
518
625
|
/**
|
|
519
626
|
* Retrieves the distribution information for the issuer's token.
|
|
520
|
-
* @throws {
|
|
627
|
+
* @throws {SparkError} This feature is not yet supported
|
|
521
628
|
*/
|
|
522
629
|
async getIssuerTokenDistribution() {
|
|
523
|
-
throw new
|
|
630
|
+
throw new SparkError("Token distribution is not yet supported");
|
|
524
631
|
}
|
|
525
632
|
getTraceName(methodName) {
|
|
526
633
|
return `IssuerSparkWallet.${methodName}`;
|
|
527
634
|
}
|
|
528
|
-
|
|
635
|
+
wrapIssuerPublicMethod(methodName) {
|
|
529
636
|
const original = this[methodName];
|
|
530
637
|
if (typeof original !== "function") {
|
|
531
638
|
throw new Error(
|
|
532
639
|
`Method ${methodName} is not a function on IssuerSparkWallet.`
|
|
533
640
|
);
|
|
534
641
|
}
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
642
|
+
const originalFn = original;
|
|
643
|
+
const wrapped = SparkWallet.wrapMethod(
|
|
644
|
+
String(methodName),
|
|
645
|
+
originalFn,
|
|
646
|
+
this
|
|
538
647
|
);
|
|
539
648
|
this[methodName] = wrapped;
|
|
540
649
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
"getIssuerTokenMetadata",
|
|
545
|
-
"getIssuerTokenIdentifier",
|
|
546
|
-
"createToken",
|
|
547
|
-
"mintTokens",
|
|
548
|
-
"burnTokens",
|
|
549
|
-
"freezeTokens",
|
|
550
|
-
"unfreezeTokens",
|
|
551
|
-
"getIssuerTokenDistribution"
|
|
552
|
-
];
|
|
553
|
-
methods.forEach(
|
|
554
|
-
(m) => this.wrapPublicIssuerSparkWalletMethodWithOtelSpan(m)
|
|
650
|
+
wrapIssuerSparkWalletMethods() {
|
|
651
|
+
PUBLIC_ISSUER_SPARK_WALLET_METHODS.forEach(
|
|
652
|
+
(m) => this.wrapIssuerPublicMethod(m)
|
|
555
653
|
);
|
|
556
654
|
}
|
|
557
655
|
};
|
|
656
|
+
var PUBLIC_ISSUER_SPARK_WALLET_METHODS = [
|
|
657
|
+
"getIssuerTokenBalance",
|
|
658
|
+
"getIssuerTokenMetadata",
|
|
659
|
+
"getIssuerTokenIdentifier",
|
|
660
|
+
"createToken",
|
|
661
|
+
"mintTokens",
|
|
662
|
+
"burnTokens",
|
|
663
|
+
"freezeTokens",
|
|
664
|
+
"unfreezeTokens",
|
|
665
|
+
"getIssuerTokenDistribution"
|
|
666
|
+
];
|
|
667
|
+
|
|
668
|
+
// src/issuer-wallet/issuer-spark-wallet.browser.ts
|
|
669
|
+
import {
|
|
670
|
+
ConnectionManager
|
|
671
|
+
} from "@buildonspark/spark-sdk";
|
|
672
|
+
var IssuerSparkWalletBrowser = class extends IssuerSparkWallet {
|
|
673
|
+
buildConnectionManager(config) {
|
|
674
|
+
return new ConnectionManager(config);
|
|
675
|
+
}
|
|
676
|
+
};
|
|
558
677
|
|
|
678
|
+
// src/index-shared.ts
|
|
679
|
+
import {
|
|
680
|
+
DefaultSparkSigner,
|
|
681
|
+
UnsafeStatelessSparkSigner
|
|
682
|
+
} from "@buildonspark/spark-sdk";
|
|
683
|
+
import { WalletConfig } from "@buildonspark/spark-sdk";
|
|
559
684
|
export {
|
|
560
|
-
|
|
685
|
+
DefaultSparkSigner,
|
|
686
|
+
IssuerSparkWalletBrowser as IssuerSparkWallet,
|
|
687
|
+
UnsafeStatelessSparkSigner,
|
|
688
|
+
WalletConfig
|
|
561
689
|
};
|