@buildonspark/issuer-sdk 0.0.30 → 0.0.32
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/dist/index.cjs +31 -39
- package/dist/index.d.cts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +31 -39
- package/package.json +4 -3
- package/src/index.ts +1 -1
- package/src/issuer-spark-wallet.ts +39 -28
- package/src/proto/common.ts +91 -38
- package/src/proto/google/protobuf/descriptor.ts +2308 -1439
- package/src/proto/google/protobuf/duration.ts +28 -10
- package/src/proto/google/protobuf/empty.ts +24 -10
- package/src/proto/google/protobuf/timestamp.ts +28 -10
- package/src/proto/mock.ts +84 -54
- package/src/proto/spark.ts +9718 -7485
- package/src/proto/spark_authn.ts +165 -60
- package/src/proto/validate/validate.ts +1157 -661
- package/src/services/token-transactions.ts +2 -2
- package/src/tests/integration/spark.test.ts +11 -82
- package/src/tests/stress/transfers.test.ts +101 -10
- package/src/types.ts +73 -70
- package/src/utils/enum-mappers.ts +16 -5
- package/src/utils/token-hashing.ts +2 -2
- package/src/utils/type-mappers.ts +136 -103
|
@@ -18,14 +18,14 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
|
|
|
18
18
|
): Promise<TokenTransaction> {
|
|
19
19
|
return {
|
|
20
20
|
network: this.config.getNetworkProto(),
|
|
21
|
-
|
|
21
|
+
tokenInputs: {
|
|
22
22
|
$case: "mintInput",
|
|
23
23
|
mintInput: {
|
|
24
24
|
issuerPublicKey: tokenPublicKey,
|
|
25
25
|
issuerProvidedTimestamp: Date.now(),
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
|
-
|
|
28
|
+
tokenOutputs: [
|
|
29
29
|
{
|
|
30
30
|
ownerPublicKey: tokenPublicKey,
|
|
31
31
|
tokenPublicKey: tokenPublicKey,
|
|
@@ -74,14 +74,14 @@ describe("token integration test", () => {
|
|
|
74
74
|
|
|
75
75
|
// Assert token public key info values
|
|
76
76
|
const identityPublicKey = await wallet.getIdentityPublicKey();
|
|
77
|
-
expect(publicKeyInfo?.
|
|
78
|
-
expect(publicKeyInfo?.
|
|
79
|
-
expect(publicKeyInfo?.
|
|
80
|
-
expect(publicKeyInfo?.
|
|
81
|
-
expect(publicKeyInfo?.
|
|
77
|
+
expect(publicKeyInfo?.tokenName).toEqual("TestToken1");
|
|
78
|
+
expect(publicKeyInfo?.tokenSymbol).toEqual("TT1");
|
|
79
|
+
expect(publicKeyInfo?.tokenDecimals).toEqual(0);
|
|
80
|
+
expect(publicKeyInfo?.maxSupply).toEqual(0);
|
|
81
|
+
expect(publicKeyInfo?.isFreezable).toEqual(false);
|
|
82
82
|
|
|
83
83
|
// Compare the public key using bytesToHex
|
|
84
|
-
const pubKeyHex = publicKeyInfo?.
|
|
84
|
+
const pubKeyHex = publicKeyInfo?.tokenPublicKey;
|
|
85
85
|
expect(pubKeyHex).toEqual(identityPublicKey);
|
|
86
86
|
|
|
87
87
|
await wallet.mintTokens(tokenAmount);
|
|
@@ -93,78 +93,7 @@ describe("token integration test", () => {
|
|
|
93
93
|
expect(tokenInfo[0].tokenName).toEqual("TestToken1");
|
|
94
94
|
expect(tokenInfo[0].tokenSymbol).toEqual("TT1");
|
|
95
95
|
expect(tokenInfo[0].tokenDecimals).toEqual(0);
|
|
96
|
-
expect(tokenInfo[0].
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("should announce, issue, and withdraw a single token", async () => {
|
|
100
|
-
const tokenAmount: bigint = 1000n;
|
|
101
|
-
const { wallet } = await IssuerSparkWallet.initialize({
|
|
102
|
-
options: LOCAL_WALLET_CONFIG_SCHNORR,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Faucet funds to the Issuer wallet because announcing a token
|
|
106
|
-
// requires ownership of an L1 UTXO.
|
|
107
|
-
const faucet = new BitcoinFaucet();
|
|
108
|
-
const l1WalletPubKey = await wallet.getIdentityPublicKey();
|
|
109
|
-
await faucet.sendFaucetCoinToP2WPKHAddress(hexToBytes(l1WalletPubKey));
|
|
110
|
-
await faucet.mineBlocks(6);
|
|
111
|
-
|
|
112
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
const response = await wallet.announceTokenL1({
|
|
116
|
-
tokenName: "TestToken2",
|
|
117
|
-
tokenTicker: "TT2",
|
|
118
|
-
decimals: 0,
|
|
119
|
-
maxSupply: 0,
|
|
120
|
-
isFreezable: false,
|
|
121
|
-
});
|
|
122
|
-
console.log("Announce token response: " + response);
|
|
123
|
-
} catch (error: any) {
|
|
124
|
-
console.error(
|
|
125
|
-
"Expected announceTokenL1() to succeed with fauceted funds: " + error,
|
|
126
|
-
);
|
|
127
|
-
fail();
|
|
128
|
-
}
|
|
129
|
-
await faucet.mineBlocks(6);
|
|
130
|
-
await wallet.mintTokens(tokenAmount);
|
|
131
|
-
// Mint a second time to ensure that multiple leaves are handled correctly
|
|
132
|
-
// (a self transfer should first be broadcast to enable withdrawal in a single TX).
|
|
133
|
-
await wallet.mintTokens(tokenAmount);
|
|
134
|
-
|
|
135
|
-
const sourceBalance = await wallet.getIssuerTokenBalance();
|
|
136
|
-
expect(sourceBalance.balance).toEqual(tokenAmount * 2n);
|
|
137
|
-
|
|
138
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
const response = await wallet.withdrawTokens(l1WalletPubKey);
|
|
142
|
-
console.log("Withdraw token txid: " + response?.txid);
|
|
143
|
-
} catch (error: any) {
|
|
144
|
-
fail("Expected withdrawTokens() to succeed: " + error);
|
|
145
|
-
}
|
|
146
|
-
// Wallet should update balance immediately by marking the leafs as withdrawn in memory in the wallet.
|
|
147
|
-
// (note that if re-initializing the wallet this will currently revert balance until confirmation).
|
|
148
|
-
const sourceBalanceImmediatelyAfterWithdrawal =
|
|
149
|
-
await wallet.getIssuerTokenBalance();
|
|
150
|
-
expect(sourceBalanceImmediatelyAfterWithdrawal.balance).toEqual(0n);
|
|
151
|
-
|
|
152
|
-
// Mine blocks to confirm the transaction and make LRC20 aware
|
|
153
|
-
// of the withdrawal.
|
|
154
|
-
await faucet.mineBlocks(6);
|
|
155
|
-
|
|
156
|
-
// Wait for LRC20 processing.
|
|
157
|
-
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
158
|
-
|
|
159
|
-
// Mine more blocks to trigger SO fetching of withdrawals from LRC.
|
|
160
|
-
await faucet.mineBlocks(6);
|
|
161
|
-
|
|
162
|
-
// Wait for SO processing.
|
|
163
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
164
|
-
|
|
165
|
-
// Ensure that after LRC20 processing that balance is still 0.
|
|
166
|
-
const sourceBalanceAfterWithdrawal = await wallet.getIssuerTokenBalance();
|
|
167
|
-
expect(sourceBalanceAfterWithdrawal.balance).toEqual(0n);
|
|
96
|
+
expect(tokenInfo[0].maxSupply).toEqual(tokenAmount);
|
|
168
97
|
});
|
|
169
98
|
|
|
170
99
|
it("should issue a single token and transfer it with ECDSA", async () => {
|
|
@@ -296,13 +225,13 @@ describe("token integration test", () => {
|
|
|
296
225
|
expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
|
|
297
226
|
// Freeze tokens
|
|
298
227
|
const freezeResponse = await issuerWallet.freezeTokens(userWalletPublicKey);
|
|
299
|
-
expect(freezeResponse.
|
|
228
|
+
expect(freezeResponse.impactedOutputIds.length).toBeGreaterThan(0);
|
|
300
229
|
expect(freezeResponse.impactedTokenAmount).toEqual(tokenAmount);
|
|
301
230
|
|
|
302
231
|
// Unfreeze tokens
|
|
303
232
|
const unfreezeResponse =
|
|
304
233
|
await issuerWallet.unfreezeTokens(userWalletPublicKey);
|
|
305
|
-
expect(unfreezeResponse.
|
|
234
|
+
expect(unfreezeResponse.impactedOutputIds.length).toBeGreaterThan(0);
|
|
306
235
|
expect(unfreezeResponse.impactedTokenAmount).toEqual(tokenAmount);
|
|
307
236
|
});
|
|
308
237
|
|
|
@@ -342,12 +271,12 @@ describe("token integration test", () => {
|
|
|
342
271
|
expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
|
|
343
272
|
|
|
344
273
|
const freezeResult = await issuerWallet.freezeTokens(userWalletPublicKey);
|
|
345
|
-
expect(freezeResult.
|
|
274
|
+
expect(freezeResult.impactedOutputIds.length).toBe(1);
|
|
346
275
|
expect(freezeResult.impactedTokenAmount).toBe(1000n);
|
|
347
276
|
|
|
348
277
|
const unfreezeResult =
|
|
349
278
|
await issuerWallet.unfreezeTokens(userWalletPublicKey);
|
|
350
|
-
expect(unfreezeResult.
|
|
279
|
+
expect(unfreezeResult.impactedOutputIds.length).toBe(1);
|
|
351
280
|
expect(unfreezeResult.impactedTokenAmount).toBe(1000n);
|
|
352
281
|
});
|
|
353
282
|
|
|
@@ -4,7 +4,10 @@ import { LOCAL_WALLET_CONFIG_ECDSA } from "../../../../spark-sdk/src/services/wa
|
|
|
4
4
|
import { SparkWallet } from "@buildonspark/spark-sdk";
|
|
5
5
|
import { filterTokenBalanceForTokenPublicKey } from "@buildonspark/spark-sdk/utils";
|
|
6
6
|
|
|
7
|
-
const TEST_TIMEOUT =
|
|
7
|
+
const TEST_TIMEOUT = 600_000; // 10 minutes
|
|
8
|
+
const TOKEN_AMOUNT: bigint = 1000n;
|
|
9
|
+
|
|
10
|
+
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
11
|
|
|
9
12
|
describe("Stress test for token transfers", () => {
|
|
10
13
|
jest.setTimeout(TEST_TIMEOUT);
|
|
@@ -23,13 +26,10 @@ describe("Stress test for token transfers", () => {
|
|
|
23
26
|
clearTimeout(timeoutId);
|
|
24
27
|
});
|
|
25
28
|
|
|
26
|
-
it("[Spark] wallets should
|
|
27
|
-
|
|
28
|
-
// 2 transactions per iteration
|
|
29
|
-
// (2 transactions * 200 iterations) / 80 seconds = 5 TPS
|
|
30
|
-
const MAX_ITERATIONS = 200;
|
|
31
|
-
const TOKEN_AMOUNT: bigint = 1000n;
|
|
29
|
+
it("[Spark] wallets should maintain state consistency through repeated token transfer cycles", async () => {
|
|
30
|
+
const maxTransactionCycles = 50;
|
|
32
31
|
|
|
32
|
+
const start_time = Date.now();
|
|
33
33
|
const { wallet: issuerWallet } = await IssuerSparkWallet.initialize({
|
|
34
34
|
options: LOCAL_WALLET_CONFIG_ECDSA,
|
|
35
35
|
});
|
|
@@ -38,17 +38,18 @@ describe("Stress test for token transfers", () => {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
await issuerWallet.mintTokens(TOKEN_AMOUNT);
|
|
41
|
+
await sleep(1000);
|
|
41
42
|
const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
|
|
42
43
|
const userWalletSparkAddress = await userWallet.getSparkAddress();
|
|
43
44
|
const issuerWalletSparkAddress = await issuerWallet.getSparkAddress();
|
|
44
45
|
|
|
45
|
-
for (let i = 0; i <
|
|
46
|
+
for (let i = 0; i < maxTransactionCycles; i++) {
|
|
46
47
|
if (timeoutReached) {
|
|
47
48
|
console.log(
|
|
48
49
|
"Timeout reached, stopping iterations at idx: " +
|
|
49
50
|
i +
|
|
50
51
|
" of " +
|
|
51
|
-
|
|
52
|
+
maxTransactionCycles,
|
|
52
53
|
);
|
|
53
54
|
break;
|
|
54
55
|
}
|
|
@@ -59,6 +60,7 @@ describe("Stress test for token transfers", () => {
|
|
|
59
60
|
tokenAmount: TOKEN_AMOUNT,
|
|
60
61
|
receiverSparkAddress: userWalletSparkAddress,
|
|
61
62
|
});
|
|
63
|
+
await sleep(1000);
|
|
62
64
|
const issuerBalance = await issuerWallet.getIssuerTokenBalance();
|
|
63
65
|
const userBalanceObj = await userWallet.getBalance();
|
|
64
66
|
const userBalance = filterTokenBalanceForTokenPublicKey(
|
|
@@ -74,6 +76,7 @@ describe("Stress test for token transfers", () => {
|
|
|
74
76
|
tokenAmount: TOKEN_AMOUNT,
|
|
75
77
|
receiverSparkAddress: issuerWalletSparkAddress,
|
|
76
78
|
});
|
|
79
|
+
await sleep(1000);
|
|
77
80
|
const userBalanceObjAfterTransferBack = await userWallet.getBalance();
|
|
78
81
|
const userBalanceAfterTransferBack =
|
|
79
82
|
filterTokenBalanceForTokenPublicKey(
|
|
@@ -85,8 +88,96 @@ describe("Stress test for token transfers", () => {
|
|
|
85
88
|
expect(userBalanceAfterTransferBack.balance).toEqual(0n);
|
|
86
89
|
expect(issuerBalanceAfterTransferBack.balance).toEqual(TOKEN_AMOUNT);
|
|
87
90
|
} catch (error: any) {
|
|
88
|
-
|
|
91
|
+
const end_time = Date.now();
|
|
92
|
+
const duration_ms = end_time - start_time;
|
|
93
|
+
const minutes = Math.floor(duration_ms / 60000);
|
|
94
|
+
const seconds = ((duration_ms % 60000) / 1000).toFixed(2);
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Test failed on iteration ${i}: ${error} in ${duration_ms}ms (${minutes}m ${seconds}s)`,
|
|
97
|
+
);
|
|
89
98
|
}
|
|
90
99
|
}
|
|
100
|
+
const end_time = Date.now();
|
|
101
|
+
const duration_ms = end_time - start_time;
|
|
102
|
+
const minutes = Math.floor(duration_ms / 60000);
|
|
103
|
+
const seconds = ((duration_ms % 60000) / 1000).toFixed(2);
|
|
104
|
+
console.log(
|
|
105
|
+
`Time taken to process ${maxTransactionCycles} transaction cycles: ${duration_ms}ms (${minutes}m ${seconds}s)`,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("should correctly process a small batch of concurrent transfer requests", async () => {
|
|
110
|
+
const minTargetTps = 1;
|
|
111
|
+
const minTargetSuccessPercentage = 50;
|
|
112
|
+
const concurrentWalletPairs = 30;
|
|
113
|
+
|
|
114
|
+
const walletPairs = await Promise.all(
|
|
115
|
+
Array(concurrentWalletPairs)
|
|
116
|
+
.fill(0)
|
|
117
|
+
.map(async () => {
|
|
118
|
+
const issuer = await IssuerSparkWallet.initialize({
|
|
119
|
+
options: LOCAL_WALLET_CONFIG_ECDSA,
|
|
120
|
+
});
|
|
121
|
+
const user = await SparkWallet.initialize({
|
|
122
|
+
options: LOCAL_WALLET_CONFIG_ECDSA,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await issuer.wallet.mintTokens(TOKEN_AMOUNT);
|
|
126
|
+
const tokenPublicKey = await issuer.wallet.getIdentityPublicKey();
|
|
127
|
+
const userAddress = await user.wallet.getSparkAddress();
|
|
128
|
+
|
|
129
|
+
return { issuer, tokenPublicKey, userAddress };
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const transactions = walletPairs.map(
|
|
134
|
+
({ issuer, tokenPublicKey, userAddress }) =>
|
|
135
|
+
async () => {
|
|
136
|
+
const start_time = Date.now();
|
|
137
|
+
try {
|
|
138
|
+
await issuer.wallet.transferTokens({
|
|
139
|
+
tokenPublicKey,
|
|
140
|
+
tokenAmount: TOKEN_AMOUNT,
|
|
141
|
+
receiverSparkAddress: userAddress,
|
|
142
|
+
});
|
|
143
|
+
const end_time = Date.now();
|
|
144
|
+
return { success: true, duration: end_time - start_time };
|
|
145
|
+
} catch (error) {
|
|
146
|
+
const end_time = Date.now();
|
|
147
|
+
return { success: false, error, duration: end_time - start_time };
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const startTime = Date.now();
|
|
153
|
+
const results = await Promise.all(transactions.map((tx) => tx()));
|
|
154
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
155
|
+
|
|
156
|
+
const errors = results.filter((r: { success: boolean }) => !r.success);
|
|
157
|
+
errors.forEach((e, i) => {
|
|
158
|
+
console.log(`Error ${i}: ${e.error} occurred in ${e.duration}ms`);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const numSuccessfulTransfers = results.filter(
|
|
162
|
+
(r: { success: boolean }) => r.success,
|
|
163
|
+
).length;
|
|
164
|
+
const averageSuccessDuration =
|
|
165
|
+
results
|
|
166
|
+
.filter((r: { success: boolean }) => r.success)
|
|
167
|
+
.reduce((acc, r) => acc + r.duration, 0) /
|
|
168
|
+
(numSuccessfulTransfers || 1);
|
|
169
|
+
const successRate = (numSuccessfulTransfers / transactions.length) * 100;
|
|
170
|
+
const transfersPerSecond = numSuccessfulTransfers / duration;
|
|
171
|
+
|
|
172
|
+
console.log(`Total transfers: ${transactions.length}`);
|
|
173
|
+
console.log(`Duration: ${duration.toFixed(2)}s`);
|
|
174
|
+
console.log(`Actual transfers/second: ${transfersPerSecond.toFixed(2)}`);
|
|
175
|
+
console.log(
|
|
176
|
+
`Average successful transfer duration: ${averageSuccessDuration}ms`,
|
|
177
|
+
);
|
|
178
|
+
console.log(`Success rate: ${successRate.toFixed(2)}%`);
|
|
179
|
+
|
|
180
|
+
expect(transfersPerSecond).toBeGreaterThanOrEqual(minTargetTps);
|
|
181
|
+
expect(successRate).toBeGreaterThanOrEqual(minTargetSuccessPercentage);
|
|
91
182
|
});
|
|
92
183
|
});
|
package/src/types.ts
CHANGED
|
@@ -2,107 +2,110 @@ import { Lrc20Protos } from "@buildonspark/lrc20-sdk";
|
|
|
2
2
|
|
|
3
3
|
// String enums to replace numeric enums
|
|
4
4
|
export enum LayerType {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
L1 = "L1",
|
|
6
|
+
SPARK = "SPARK",
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export enum OperationType {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
USER_TRANSFER = "USER_TRANSFER",
|
|
11
|
+
USER_BURN = "USER_BURN",
|
|
12
|
+
ISSUER_ANNOUNCE = "ISSUER_ANNOUNCE",
|
|
13
|
+
ISSUER_MINT = "ISSUER_MINT",
|
|
14
|
+
ISSUER_TRANSFER = "ISSUER_TRANSFER",
|
|
15
|
+
ISSUER_FREEZE = "ISSUER_FREEZE",
|
|
16
|
+
ISSUER_UNFREEZE = "ISSUER_UNFREEZE",
|
|
17
|
+
ISSUER_BURN = "ISSUER_BURN",
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export enum OnChainTransactionStatus {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
PENDING = "PENDING",
|
|
22
|
+
CONFIRMED = "CONFIRMED",
|
|
23
|
+
WAITING_MINED = "WAITING_MINED",
|
|
24
|
+
MINED = "MINED",
|
|
25
|
+
ATTACHING = "ATTACHING",
|
|
26
|
+
ATTACHED = "ATTACHED",
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export enum SparkTransactionStatus {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
STARTED = "STARTED",
|
|
31
|
+
SIGNED = "SIGNED",
|
|
32
|
+
FINALIZED = "FINALIZED",
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export type GetTokenActivityResponse = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
36
|
+
transactions: Transaction[];
|
|
37
|
+
nextCursor?: ListAllTokenTransactionsCursor | undefined;
|
|
38
|
+
};
|
|
39
39
|
|
|
40
40
|
export interface Transaction {
|
|
41
|
-
|
|
41
|
+
transaction?:
|
|
42
|
+
| {
|
|
42
43
|
$case: "onChain";
|
|
43
44
|
onChain: OnChainTransaction;
|
|
44
|
-
|
|
45
|
+
}
|
|
46
|
+
| {
|
|
45
47
|
$case: "spark";
|
|
46
48
|
spark: SparkTransaction;
|
|
47
|
-
|
|
49
|
+
}
|
|
50
|
+
| undefined;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
export interface TokenPubKeyInfoResponse {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
announcement: {
|
|
55
|
+
tokenPubkey: {
|
|
56
|
+
pubkey: string;
|
|
57
|
+
};
|
|
58
|
+
name: string;
|
|
59
|
+
symbol: string;
|
|
60
|
+
decimal: number;
|
|
61
|
+
maxSupply: bigint;
|
|
62
|
+
isFreezable: boolean;
|
|
63
|
+
} | null;
|
|
64
|
+
totalSupply: bigint;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
export interface OnChainTokenOutput {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
rawTx: string;
|
|
69
|
+
vout: number;
|
|
70
|
+
amountSats: number;
|
|
71
|
+
tokenPublicKey?: string | undefined;
|
|
72
|
+
tokenAmount?: string | undefined;
|
|
70
73
|
}
|
|
71
74
|
export interface OnChainTransaction {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
operationType: OperationType;
|
|
76
|
+
transactionHash: string;
|
|
77
|
+
rawtx: string;
|
|
78
|
+
status: OnChainTransactionStatus;
|
|
79
|
+
inputs: OnChainTokenOutput[];
|
|
80
|
+
outputs: OnChainTokenOutput[];
|
|
81
|
+
broadcastedAt: Date | undefined;
|
|
82
|
+
confirmedAt: Date | undefined;
|
|
80
83
|
}
|
|
81
84
|
export interface SparkTransaction {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
operationType: OperationType;
|
|
86
|
+
transactionHash: string;
|
|
87
|
+
status: SparkTransactionStatus;
|
|
88
|
+
confirmedAt: Date | undefined;
|
|
89
|
+
leavesToCreate: SparkLeaf[];
|
|
90
|
+
leavesToSpend: SparkLeaf[];
|
|
91
|
+
sparkOperatorIdentityPublicKeys: string[];
|
|
89
92
|
}
|
|
90
93
|
export interface SparkLeaf {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
tokenPublicKey: string;
|
|
95
|
+
id: string;
|
|
96
|
+
ownerPublicKey: string;
|
|
97
|
+
revocationPublicKey: string;
|
|
98
|
+
withdrawalBondSats: number;
|
|
99
|
+
withdrawalLocktime: number;
|
|
100
|
+
tokenAmount: string;
|
|
101
|
+
createTxHash: string;
|
|
102
|
+
createTxVoutIndex: number;
|
|
103
|
+
spendTxHash?: string | undefined;
|
|
104
|
+
spendTxVoutIndex?: number | undefined;
|
|
105
|
+
isFrozen?: boolean | undefined;
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
export interface ListAllTokenTransactionsCursor {
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
lastTransactionHash: string;
|
|
110
|
+
layer: LayerType;
|
|
108
111
|
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { Lrc20Protos } from "@buildonspark/lrc20-sdk";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
OperationType,
|
|
4
|
+
OnChainTransactionStatus,
|
|
5
|
+
SparkTransactionStatus,
|
|
6
|
+
LayerType,
|
|
7
|
+
} from "../types.js";
|
|
3
8
|
|
|
4
9
|
// Helper functions to map from numeric enums to string enums
|
|
5
|
-
export function mapOperationType(
|
|
10
|
+
export function mapOperationType(
|
|
11
|
+
type: Lrc20Protos.OperationType,
|
|
12
|
+
): OperationType {
|
|
6
13
|
switch (type) {
|
|
7
14
|
case Lrc20Protos.OperationType.USER_TRANSFER:
|
|
8
15
|
return OperationType.USER_TRANSFER;
|
|
@@ -25,7 +32,9 @@ export function mapOperationType(type: Lrc20Protos.OperationType): OperationType
|
|
|
25
32
|
}
|
|
26
33
|
}
|
|
27
34
|
|
|
28
|
-
export function mapOnChainTransactionStatus(
|
|
35
|
+
export function mapOnChainTransactionStatus(
|
|
36
|
+
status: Lrc20Protos.OnChainTransactionStatus,
|
|
37
|
+
): OnChainTransactionStatus {
|
|
29
38
|
switch (status) {
|
|
30
39
|
case Lrc20Protos.OnChainTransactionStatus.PENDING:
|
|
31
40
|
return OnChainTransactionStatus.PENDING;
|
|
@@ -44,7 +53,9 @@ export function mapOnChainTransactionStatus(status: Lrc20Protos.OnChainTransacti
|
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
export function mapSparkTransactionStatus(
|
|
56
|
+
export function mapSparkTransactionStatus(
|
|
57
|
+
status: Lrc20Protos.SparkTransactionStatus,
|
|
58
|
+
): SparkTransactionStatus {
|
|
48
59
|
switch (status) {
|
|
49
60
|
case Lrc20Protos.SparkTransactionStatus.STARTED:
|
|
50
61
|
return SparkTransactionStatus.STARTED;
|
|
@@ -66,4 +77,4 @@ export function mapLayer(layer: number): LayerType {
|
|
|
66
77
|
default:
|
|
67
78
|
return LayerType.L1; // Default case
|
|
68
79
|
}
|
|
69
|
-
}
|
|
80
|
+
}
|
|
@@ -2,7 +2,7 @@ import { sha256 } from "@scure/btc-signer/utils";
|
|
|
2
2
|
import { FreezeTokensPayload } from "@buildonspark/spark-sdk/proto/spark";
|
|
3
3
|
|
|
4
4
|
export function hashFreezeTokensPayload(
|
|
5
|
-
payload: FreezeTokensPayload
|
|
5
|
+
payload: FreezeTokensPayload,
|
|
6
6
|
): Uint8Array {
|
|
7
7
|
if (!payload) {
|
|
8
8
|
throw new Error("freeze tokens payload cannot be nil");
|
|
@@ -36,7 +36,7 @@ export function hashFreezeTokensPayload(
|
|
|
36
36
|
new DataView(timestampBytes.buffer).setBigUint64(
|
|
37
37
|
0,
|
|
38
38
|
BigInt(payload.issuerProvidedTimestamp),
|
|
39
|
-
true // true for little-endian
|
|
39
|
+
true, // true for little-endian
|
|
40
40
|
);
|
|
41
41
|
timestampHash.update(timestampBytes);
|
|
42
42
|
}
|