@buildonspark/spark-sdk 0.2.5 → 0.2.6
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 +13 -0
- package/dist/chunk-AVI5E5VT.js +66 -0
- package/dist/{chunk-U7LRIWTF.js → chunk-GUZ3WCB4.js} +313 -143
- package/dist/{client-C88GCTPB.d.cts → client-CusuvuCe.d.cts} +2 -2
- package/dist/{client-Dg6vS_2I.d.ts → client-Dn4Ld8pD.d.ts} +2 -2
- package/dist/debug.cjs +452 -286
- package/dist/debug.d.cts +8 -6
- package/dist/debug.d.ts +8 -6
- package/dist/debug.js +1 -1
- package/dist/graphql/objects/index.d.cts +3 -3
- package/dist/graphql/objects/index.d.ts +3 -3
- package/dist/index.cjs +526 -303
- package/dist/index.d.cts +19 -187
- package/dist/index.d.ts +19 -187
- package/dist/index.js +11 -6
- package/dist/index.node.cjs +451 -328
- package/dist/index.node.d.cts +7 -6
- package/dist/index.node.d.ts +7 -6
- package/dist/index.node.js +55 -98
- package/dist/native/index.cjs +468 -301
- package/dist/native/index.d.cts +37 -18
- package/dist/native/index.d.ts +37 -18
- package/dist/native/index.js +317 -148
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark_token.d.cts +1 -1
- package/dist/proto/spark_token.d.ts +1 -1
- package/dist/{spark-ESAfZARg.d.cts → spark-Cj4brrP5.d.cts} +1 -1
- package/dist/{spark-ESAfZARg.d.ts → spark-Cj4brrP5.d.ts} +1 -1
- package/dist/{spark-wallet-B2WwKN8W.d.ts → spark-wallet-B6YthxDI.d.ts} +36 -17
- package/dist/{spark-wallet-Di65w0Us.d.cts → spark-wallet-BbOf2P2l.d.cts} +36 -17
- package/dist/spark-wallet.node-BBk1sGS2.d.cts +12 -0
- package/dist/spark-wallet.node-Bffethig.d.ts +12 -0
- package/dist/tests/test-utils.cjs +78 -50
- package/dist/tests/test-utils.d.cts +24 -23
- package/dist/tests/test-utils.d.ts +24 -23
- package/dist/tests/test-utils.js +2 -2
- package/dist/token-transactions-0_5XMWjs.d.ts +184 -0
- package/dist/token-transactions-CD-Adb5y.d.cts +184 -0
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/{xchain-address-CqRu3F21.d.cts → xchain-address-BnKZ0-dY.d.cts} +5 -5
- package/dist/{xchain-address-BsveIy5l.d.ts → xchain-address-Di3lu4Wy.d.ts} +5 -5
- package/package.json +7 -2
- package/src/index.node.ts +5 -1
- package/src/index.ts +4 -1
- package/src/services/config.ts +13 -2
- package/src/services/token-transactions.ts +22 -8
- package/src/services/wallet-config.ts +22 -13
- package/src/spark-wallet/spark-wallet.browser.ts +72 -0
- package/src/spark-wallet/spark-wallet.node.ts +60 -118
- package/src/spark-wallet/spark-wallet.ts +273 -146
- package/src/tests/integration/ssp/coop-exit-validation.test.ts +233 -0
- package/src/tests/integration/ssp/coop-exit.test.ts +112 -93
- package/src/tests/integration/ssp/static-deposit-validation.test.ts +145 -0
- package/src/tests/integration/ssp/static_deposit.test.ts +439 -132
- package/src/tests/integration/ssp/transfers.test.ts +7 -2
- package/src/tests/integration/static_deposit.test.ts +92 -0
- package/src/tests/integration/transfer.test.ts +1 -1
- package/src/tests/utils/regtest-test-faucet.ts +8 -0
- package/src/tests/utils/spark-testing-wallet.ts +42 -0
- package/src/tests/utils/test-faucet.ts +6 -2
- package/src/utils/token-identifier.ts +47 -4
- package/src/utils/token-transactions.ts +13 -9
- package/dist/chunk-LQZL2D3Y.js +0 -7
- package/dist/spark-wallet.node-7R0Rxyj9.d.cts +0 -13
- package/dist/spark-wallet.node-CSPWOWRu.d.ts +0 -13
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { Transaction } from "@scure/btc-signer";
|
|
2
|
+
import {
|
|
3
|
+
initWallet,
|
|
4
|
+
SparkWalletTesting,
|
|
5
|
+
} from "../../utils/spark-testing-wallet.js";
|
|
6
|
+
import { expect } from "@jest/globals";
|
|
7
|
+
import { ExitSpeed } from "../../../types/index.js";
|
|
8
|
+
import { ValidationError } from "../../../errors/types.js";
|
|
9
|
+
import { getNewAddress } from "../../utils/regtest-test-faucet.js";
|
|
10
|
+
|
|
11
|
+
const DEPOSIT_AMOUNT = 50_000n;
|
|
12
|
+
|
|
13
|
+
describe("SSP coop exit basic validation", () => {
|
|
14
|
+
let userWallet!: SparkWalletTesting;
|
|
15
|
+
let withdrawalAddress: string;
|
|
16
|
+
let quoteAmount: number;
|
|
17
|
+
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
const { wallet, depositAddress, signedTx, vout, faucet } = await initWallet(
|
|
20
|
+
DEPOSIT_AMOUNT,
|
|
21
|
+
"LOCAL",
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Wait for the transaction to be mined
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
26
|
+
|
|
27
|
+
expect(signedTx).toBeDefined();
|
|
28
|
+
|
|
29
|
+
const transactionId = signedTx.id;
|
|
30
|
+
|
|
31
|
+
userWallet = wallet;
|
|
32
|
+
|
|
33
|
+
console.log("Fetching claim quote for static deposit...");
|
|
34
|
+
const quote = await userWallet.getClaimStaticDepositQuote(
|
|
35
|
+
transactionId,
|
|
36
|
+
vout!,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
quoteAmount = quote!.creditAmountSats;
|
|
40
|
+
const sspSignature = quote!.signature;
|
|
41
|
+
|
|
42
|
+
console.log("Attempting to claim static deposit...");
|
|
43
|
+
await userWallet.claimStaticDeposit({
|
|
44
|
+
transactionId,
|
|
45
|
+
creditAmountSats: quoteAmount,
|
|
46
|
+
sspSignature,
|
|
47
|
+
outputIndex: vout!,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
51
|
+
|
|
52
|
+
const { balance } = await userWallet.getBalance();
|
|
53
|
+
expect(balance).toBe(BigInt(quoteAmount));
|
|
54
|
+
|
|
55
|
+
withdrawalAddress = await getNewAddress();
|
|
56
|
+
}, 600000);
|
|
57
|
+
|
|
58
|
+
it("should fail when amountSats is zero", async () => {
|
|
59
|
+
const { balance } = await userWallet.getBalance();
|
|
60
|
+
expect(balance).toBe(BigInt(quoteAmount));
|
|
61
|
+
|
|
62
|
+
await expect(
|
|
63
|
+
userWallet.getWithdrawalFeeQuote({
|
|
64
|
+
amountSats: 0,
|
|
65
|
+
withdrawalAddress,
|
|
66
|
+
}),
|
|
67
|
+
).rejects.toThrow("Target amount must be positive");
|
|
68
|
+
}, 600000);
|
|
69
|
+
|
|
70
|
+
it("should fail when amountSats is negative", async () => {
|
|
71
|
+
await expect(
|
|
72
|
+
userWallet.getWithdrawalFeeQuote({
|
|
73
|
+
amountSats: -1,
|
|
74
|
+
withdrawalAddress,
|
|
75
|
+
}),
|
|
76
|
+
).rejects.toThrow("Target amount must be positive");
|
|
77
|
+
}, 600000);
|
|
78
|
+
|
|
79
|
+
it("should fail when amountSats exceeds Number.MAX_SAFE_INTEGER", async () => {
|
|
80
|
+
await expect(
|
|
81
|
+
userWallet.getWithdrawalFeeQuote({
|
|
82
|
+
amountSats: Number.MAX_SAFE_INTEGER + 1,
|
|
83
|
+
withdrawalAddress,
|
|
84
|
+
}),
|
|
85
|
+
).rejects.toThrow("Sats amount must be less than 2^53");
|
|
86
|
+
}, 600000);
|
|
87
|
+
|
|
88
|
+
it("should fail when amountSats exceeds available balance", async () => {
|
|
89
|
+
const { balance } = await userWallet.getBalance();
|
|
90
|
+
expect(balance).toBe(BigInt(quoteAmount));
|
|
91
|
+
|
|
92
|
+
await expect(
|
|
93
|
+
userWallet.getWithdrawalFeeQuote({
|
|
94
|
+
amountSats: Number(balance) + 1,
|
|
95
|
+
withdrawalAddress,
|
|
96
|
+
}),
|
|
97
|
+
).rejects.toThrow("Total target amount exceeds available balance");
|
|
98
|
+
}, 600000);
|
|
99
|
+
|
|
100
|
+
it("should fail when withdrawalAddress is invalid", async () => {
|
|
101
|
+
await expect(
|
|
102
|
+
userWallet.getWithdrawalFeeQuote({
|
|
103
|
+
amountSats: 1000,
|
|
104
|
+
withdrawalAddress: "invalid address",
|
|
105
|
+
}),
|
|
106
|
+
).rejects.toThrow("Invalid address provided");
|
|
107
|
+
}, 600000);
|
|
108
|
+
|
|
109
|
+
it("should succeed when valid params are provided", async () => {
|
|
110
|
+
const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
111
|
+
amountSats: 5000,
|
|
112
|
+
withdrawalAddress,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(feeQuote).toBeDefined();
|
|
116
|
+
}, 600000);
|
|
117
|
+
|
|
118
|
+
it("should fail when withdrawalAddress is missing", async () => {
|
|
119
|
+
await expect(
|
|
120
|
+
userWallet.getWithdrawalFeeQuote({
|
|
121
|
+
amountSats: 1000,
|
|
122
|
+
withdrawalAddress: "" as unknown as string,
|
|
123
|
+
}),
|
|
124
|
+
).rejects.toThrow("Invalid address provided");
|
|
125
|
+
}, 600000);
|
|
126
|
+
|
|
127
|
+
it("should fail when amountSats is not a number", async () => {
|
|
128
|
+
await expect(
|
|
129
|
+
userWallet.getWithdrawalFeeQuote({
|
|
130
|
+
amountSats: "1000" as unknown as number,
|
|
131
|
+
withdrawalAddress,
|
|
132
|
+
}),
|
|
133
|
+
).rejects.toThrow("Sats amount must be less than 2^53");
|
|
134
|
+
}, 600000);
|
|
135
|
+
|
|
136
|
+
it("should fail if deductFeeFromWithdrawalAmount is true and amount is too small", async () => {
|
|
137
|
+
const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
138
|
+
amountSats: 100,
|
|
139
|
+
withdrawalAddress,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
await expect(
|
|
143
|
+
userWallet.withdraw({
|
|
144
|
+
amountSats: 100, // Fails if amount is less than the fee.
|
|
145
|
+
onchainAddress: withdrawalAddress,
|
|
146
|
+
feeQuote: feeQuote!,
|
|
147
|
+
exitSpeed: ExitSpeed.FAST,
|
|
148
|
+
deductFeeFromWithdrawalAmount: true,
|
|
149
|
+
}),
|
|
150
|
+
).rejects.toMatchObject({
|
|
151
|
+
name: ValidationError.name,
|
|
152
|
+
message: expect.stringContaining(
|
|
153
|
+
"The fee for the withdrawal is greater than the target withdrawal amount",
|
|
154
|
+
),
|
|
155
|
+
context: expect.objectContaining({
|
|
156
|
+
field: "fee",
|
|
157
|
+
expected: "less than or equal to the target amount",
|
|
158
|
+
}),
|
|
159
|
+
});
|
|
160
|
+
}, 600000);
|
|
161
|
+
|
|
162
|
+
it("should fail with invalid exitSpeed", async () => {
|
|
163
|
+
const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
164
|
+
amountSats: 5000,
|
|
165
|
+
withdrawalAddress,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await expect(
|
|
169
|
+
userWallet.withdraw({
|
|
170
|
+
amountSats: 5000,
|
|
171
|
+
onchainAddress: withdrawalAddress,
|
|
172
|
+
feeQuote: feeQuote!,
|
|
173
|
+
exitSpeed: "INVALID" as ExitSpeed,
|
|
174
|
+
deductFeeFromWithdrawalAmount: false,
|
|
175
|
+
}),
|
|
176
|
+
).rejects.toMatchObject({
|
|
177
|
+
name: ValidationError.name,
|
|
178
|
+
message: expect.stringContaining("Invalid exit speed"),
|
|
179
|
+
context: expect.objectContaining({
|
|
180
|
+
field: "exitSpeed",
|
|
181
|
+
value: "INVALID" as ExitSpeed,
|
|
182
|
+
expected: "FAST, MEDIUM, or SLOW",
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
}, 600000);
|
|
186
|
+
|
|
187
|
+
it("should fail if fee exceeds available balance (without deduction)", async () => {
|
|
188
|
+
await new Promise((resolve) => setTimeout(resolve, 40000));
|
|
189
|
+
|
|
190
|
+
const initialBalance = (await userWallet.getBalance()).balance;
|
|
191
|
+
|
|
192
|
+
const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
193
|
+
amountSats: Number(initialBalance),
|
|
194
|
+
withdrawalAddress,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
await expect(
|
|
198
|
+
userWallet.withdraw({
|
|
199
|
+
amountSats: Number(initialBalance) + 1,
|
|
200
|
+
onchainAddress: withdrawalAddress,
|
|
201
|
+
feeQuote: feeQuote!,
|
|
202
|
+
exitSpeed: ExitSpeed.FAST,
|
|
203
|
+
deductFeeFromWithdrawalAmount: true,
|
|
204
|
+
}),
|
|
205
|
+
).rejects.toThrow("Not enough leaves to swap for the target amount");
|
|
206
|
+
}, 600000);
|
|
207
|
+
|
|
208
|
+
// it("should correctly update balance after successful withdrawal", async () => {
|
|
209
|
+
// const initialBalance = (await userWallet.getBalance()).balance;
|
|
210
|
+
|
|
211
|
+
// const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
212
|
+
// amountSats: 3000,
|
|
213
|
+
// withdrawalAddress,
|
|
214
|
+
// });
|
|
215
|
+
|
|
216
|
+
// const result = await userWallet.withdraw({
|
|
217
|
+
// amountSats: 3000,
|
|
218
|
+
// onchainAddress: withdrawalAddress,
|
|
219
|
+
// feeQuote: feeQuote!,
|
|
220
|
+
// exitSpeed: ExitSpeed.SLOW,
|
|
221
|
+
// deductFeeFromWithdrawalAmount: false,
|
|
222
|
+
// });
|
|
223
|
+
|
|
224
|
+
// await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
225
|
+
|
|
226
|
+
// const finalBalance = (await userWallet.getBalance()).balance;
|
|
227
|
+
// const fee =
|
|
228
|
+
// (result?.l1BroadcastFee?.originalValue ?? 0) +
|
|
229
|
+
// (result?.fee?.originalValue ?? 0);
|
|
230
|
+
|
|
231
|
+
// expect(finalBalance).toBe(initialBalance - 3000n - BigInt(fee));
|
|
232
|
+
// }, 600000);
|
|
233
|
+
});
|
|
@@ -1,41 +1,61 @@
|
|
|
1
1
|
import { describe, expect, it } from "@jest/globals";
|
|
2
2
|
import { ExitSpeed } from "../../../types/index.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
initWallet,
|
|
5
|
+
SparkWalletTesting,
|
|
6
|
+
} from "../../utils/spark-testing-wallet.js";
|
|
7
|
+
import { getNewAddress } from "../../utils/regtest-test-faucet.js";
|
|
8
|
+
import { ValidationError } from "../../../index.node.js";
|
|
5
9
|
|
|
6
|
-
const DEPOSIT_AMOUNT =
|
|
10
|
+
export const DEPOSIT_AMOUNT = 30_000n;
|
|
7
11
|
|
|
8
12
|
describe("SSP coop exit integration", () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
false,
|
|
13
|
+
let userWallet!: SparkWalletTesting;
|
|
14
|
+
let withdrawalAddress: string;
|
|
15
|
+
let quoteAmount: number;
|
|
16
|
+
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
const { wallet, depositAddress, signedTx, vout, faucet } = await initWallet(
|
|
19
|
+
DEPOSIT_AMOUNT,
|
|
20
|
+
"LOCAL",
|
|
19
21
|
);
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
// Wait for the transaction to be mined
|
|
24
|
+
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
23
25
|
|
|
24
|
-
const signedTx = await faucet.sendToAddress(depositAddress, DEPOSIT_AMOUNT);
|
|
25
26
|
expect(signedTx).toBeDefined();
|
|
26
|
-
await faucet.mineBlocks(6);
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const transactionId = signedTx.id;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
userWallet = wallet;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
console.log("Fetching claim quote for static deposit...");
|
|
33
|
+
const quote = await userWallet.getClaimStaticDepositQuote(
|
|
34
|
+
transactionId,
|
|
35
|
+
vout!,
|
|
36
|
+
);
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
quoteAmount = quote!.creditAmountSats;
|
|
39
|
+
const sspSignature = quote!.signature;
|
|
40
|
+
|
|
41
|
+
console.log("Attempting to claim static deposit...");
|
|
42
|
+
await userWallet.claimStaticDeposit({
|
|
43
|
+
transactionId,
|
|
44
|
+
creditAmountSats: quoteAmount,
|
|
45
|
+
sspSignature,
|
|
46
|
+
outputIndex: vout!,
|
|
47
|
+
});
|
|
36
48
|
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
50
|
+
|
|
51
|
+
const { balance } = await userWallet.getBalance();
|
|
52
|
+
expect(balance).toBe(BigInt(quoteAmount));
|
|
53
|
+
|
|
54
|
+
withdrawalAddress = await getNewAddress();
|
|
55
|
+
}, 600000);
|
|
56
|
+
it("should estimate coop exit fee", async () => {
|
|
37
57
|
const feeEstimate = await userWallet.getWithdrawalFeeQuote({
|
|
38
|
-
amountSats: Number(
|
|
58
|
+
amountSats: Number(quoteAmount),
|
|
39
59
|
withdrawalAddress,
|
|
40
60
|
});
|
|
41
61
|
|
|
@@ -54,74 +74,73 @@ describe("SSP coop exit integration", () => {
|
|
|
54
74
|
expect(feeEstimate?.l1BroadcastFeeSlow.originalValue).toBeGreaterThan(0);
|
|
55
75
|
expect(feeEstimate?.userFeeSlow).toBeDefined();
|
|
56
76
|
expect(feeEstimate?.userFeeSlow.originalValue).toBeGreaterThan(0);
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
it
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}, 60000);
|
|
77
|
+
}, 600000);
|
|
78
|
+
|
|
79
|
+
// it("should complete coop exit without deducting fees from withdrawal amount", async () => {
|
|
80
|
+
// const { balance } = await userWallet.getBalance();
|
|
81
|
+
// expect(balance).toBe(BigInt(quoteAmount));
|
|
82
|
+
|
|
83
|
+
// const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
84
|
+
// amountSats: 5000,
|
|
85
|
+
// withdrawalAddress,
|
|
86
|
+
// });
|
|
87
|
+
|
|
88
|
+
// expect(feeQuote).toBeDefined();
|
|
89
|
+
|
|
90
|
+
// const coopExit = await userWallet.withdraw({
|
|
91
|
+
// amountSats: 5000,
|
|
92
|
+
// onchainAddress: withdrawalAddress,
|
|
93
|
+
// feeQuote: feeQuote!,
|
|
94
|
+
// exitSpeed: ExitSpeed.FAST,
|
|
95
|
+
// deductFeeFromWithdrawalAmount: false,
|
|
96
|
+
// });
|
|
97
|
+
|
|
98
|
+
// const fee =
|
|
99
|
+
// (coopExit?.l1BroadcastFee?.originalValue ?? 0) +
|
|
100
|
+
// (coopExit?.fee?.originalValue ?? 0);
|
|
101
|
+
|
|
102
|
+
// expect(fee).toBeGreaterThan(0);
|
|
103
|
+
|
|
104
|
+
// const { balance: balanceAfter } = await userWallet.getBalance();
|
|
105
|
+
|
|
106
|
+
// expect(balanceAfter).toBe(balance - 5000n - BigInt(fee));
|
|
107
|
+
// expect(coopExit).toBeDefined();
|
|
108
|
+
// expect(coopExit?.coopExitTxid).toBeDefined();
|
|
109
|
+
// }, 600000);
|
|
110
|
+
|
|
111
|
+
// it("CoopExit with spent leaves", async () => {
|
|
112
|
+
// const { balance } = await userWallet.getBalance();
|
|
113
|
+
|
|
114
|
+
// const feeQuote = await userWallet.getWithdrawalFeeQuote({
|
|
115
|
+
// amountSats: Number(balance),
|
|
116
|
+
// withdrawalAddress,
|
|
117
|
+
// });
|
|
118
|
+
|
|
119
|
+
// expect(feeQuote).toBeDefined();
|
|
120
|
+
|
|
121
|
+
// const coopExit = await userWallet.withdraw({
|
|
122
|
+
// amountSats: Number(balance),
|
|
123
|
+
// onchainAddress: withdrawalAddress,
|
|
124
|
+
// feeQuote: feeQuote!,
|
|
125
|
+
// exitSpeed: ExitSpeed.FAST,
|
|
126
|
+
// deductFeeFromWithdrawalAmount: true,
|
|
127
|
+
// });
|
|
128
|
+
|
|
129
|
+
// expect(coopExit).toBeDefined();
|
|
130
|
+
// expect(coopExit?.coopExitTxid).toBeDefined();
|
|
131
|
+
|
|
132
|
+
// const sparkAddress = await userWallet.getSparkAddress();
|
|
133
|
+
// await expect(
|
|
134
|
+
// userWallet.transfer({
|
|
135
|
+
// amountSats: Number(balance),
|
|
136
|
+
// receiverSparkAddress: sparkAddress,
|
|
137
|
+
// }),
|
|
138
|
+
// ).rejects.toMatchObject({
|
|
139
|
+
// name: ValidationError.name,
|
|
140
|
+
// message: expect.stringContaining("No owned leaves found"),
|
|
141
|
+
// context: expect.objectContaining({
|
|
142
|
+
// field: "leaves",
|
|
143
|
+
// }),
|
|
144
|
+
// });
|
|
145
|
+
// }, 600000);
|
|
127
146
|
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import {
|
|
2
|
+
initWallet,
|
|
3
|
+
SparkWalletTesting,
|
|
4
|
+
} from "../../utils/spark-testing-wallet.js";
|
|
5
|
+
import { sha256 } from "@noble/hashes/sha2";
|
|
6
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
7
|
+
import { BitcoinFaucet } from "../../utils/test-faucet.js";
|
|
8
|
+
|
|
9
|
+
const DEPOSIT_AMOUNT = 10000n;
|
|
10
|
+
|
|
11
|
+
describe("SSP static deposit validation tests", () => {
|
|
12
|
+
// it("should reject claiming deposits with insufficient confirmation", async () => {
|
|
13
|
+
// const faucet = BitcoinFaucet.getInstance();
|
|
14
|
+
|
|
15
|
+
// const { wallet: userWallet } = await SparkWalletTesting.initialize(
|
|
16
|
+
// {
|
|
17
|
+
// options: {
|
|
18
|
+
// network: "LOCAL",
|
|
19
|
+
// },
|
|
20
|
+
// },
|
|
21
|
+
// false,
|
|
22
|
+
// );
|
|
23
|
+
|
|
24
|
+
// const depositAddress = await userWallet.getStaticDepositAddress();
|
|
25
|
+
// expect(depositAddress).toBeDefined();
|
|
26
|
+
|
|
27
|
+
// const signedTx = await faucet.sendToAddress(
|
|
28
|
+
// depositAddress,
|
|
29
|
+
// DEPOSIT_AMOUNT,
|
|
30
|
+
// 0,
|
|
31
|
+
// );
|
|
32
|
+
|
|
33
|
+
// expect(signedTx).toBeDefined();
|
|
34
|
+
// const transactionId = signedTx.id;
|
|
35
|
+
|
|
36
|
+
// await expect(
|
|
37
|
+
// userWallet.getClaimStaticDepositQuote(transactionId),
|
|
38
|
+
// ).rejects.toThrow("Transaction not found");
|
|
39
|
+
|
|
40
|
+
// const vout = await (userWallet as any).getDepositTransactionVout(
|
|
41
|
+
// transactionId,
|
|
42
|
+
// );
|
|
43
|
+
|
|
44
|
+
// expect(transactionId).toBeDefined();
|
|
45
|
+
|
|
46
|
+
// await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
47
|
+
|
|
48
|
+
// const quote = await userWallet.getClaimStaticDepositQuote(
|
|
49
|
+
// transactionId,
|
|
50
|
+
// vout!,
|
|
51
|
+
// );
|
|
52
|
+
|
|
53
|
+
// expect(quote).toBeDefined();
|
|
54
|
+
// }, 600000);
|
|
55
|
+
|
|
56
|
+
it("should validate static deposit request parameters", async () => {
|
|
57
|
+
const {
|
|
58
|
+
wallet: userWallet,
|
|
59
|
+
depositAddress,
|
|
60
|
+
signedTx,
|
|
61
|
+
vout,
|
|
62
|
+
faucet,
|
|
63
|
+
} = await initWallet(DEPOSIT_AMOUNT, "LOCAL");
|
|
64
|
+
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 30000));
|
|
66
|
+
|
|
67
|
+
expect(signedTx).toBeDefined();
|
|
68
|
+
|
|
69
|
+
const transactionId = signedTx.id;
|
|
70
|
+
|
|
71
|
+
// Invalid transaction ID
|
|
72
|
+
await expect(
|
|
73
|
+
userWallet.getClaimStaticDepositQuote("invalid-txid", vout!),
|
|
74
|
+
).rejects.toThrow("Invalid transaction ID:");
|
|
75
|
+
|
|
76
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
77
|
+
|
|
78
|
+
// Valid transaction ID but not same as signedTx.id
|
|
79
|
+
await expect(
|
|
80
|
+
userWallet.getClaimStaticDepositQuote(
|
|
81
|
+
bytesToHex(sha256("invalid-txid")),
|
|
82
|
+
vout!,
|
|
83
|
+
),
|
|
84
|
+
).rejects.toThrow("Transaction not found");
|
|
85
|
+
|
|
86
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
87
|
+
|
|
88
|
+
// Missing output index
|
|
89
|
+
await expect(
|
|
90
|
+
userWallet.getClaimStaticDepositQuote(transactionId, vout! + 10),
|
|
91
|
+
).rejects.toThrow("UTXO is spent or not found.");
|
|
92
|
+
|
|
93
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
94
|
+
|
|
95
|
+
// Valid quote request for control
|
|
96
|
+
const quote = await userWallet.getClaimStaticDepositQuote(
|
|
97
|
+
transactionId,
|
|
98
|
+
vout!,
|
|
99
|
+
);
|
|
100
|
+
expect(quote).toBeDefined();
|
|
101
|
+
console.log(
|
|
102
|
+
"Static deposit quote validation passed for correct parameters.",
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
106
|
+
|
|
107
|
+
// Invalid claim: missing signature
|
|
108
|
+
await expect(
|
|
109
|
+
userWallet.claimStaticDeposit({
|
|
110
|
+
transactionId,
|
|
111
|
+
creditAmountSats: quote!.creditAmountSats,
|
|
112
|
+
outputIndex: vout!,
|
|
113
|
+
sspSignature: "",
|
|
114
|
+
}),
|
|
115
|
+
).rejects.toThrow(
|
|
116
|
+
'Request ClaimStaticDeposit failed. [{"message":"Something went wrong."',
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
120
|
+
|
|
121
|
+
// Invalid claim: invalid credit amount
|
|
122
|
+
await expect(
|
|
123
|
+
userWallet.claimStaticDeposit({
|
|
124
|
+
transactionId,
|
|
125
|
+
creditAmountSats: quote!.creditAmountSats + 1000,
|
|
126
|
+
outputIndex: vout!,
|
|
127
|
+
sspSignature: quote!.signature,
|
|
128
|
+
}),
|
|
129
|
+
).rejects.toThrow(
|
|
130
|
+
"The utxo amount is not enough to cover the claim amount",
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
134
|
+
|
|
135
|
+
// Invalid claim: wrong output index
|
|
136
|
+
await expect(
|
|
137
|
+
userWallet.claimStaticDeposit({
|
|
138
|
+
transactionId,
|
|
139
|
+
creditAmountSats: quote!.creditAmountSats,
|
|
140
|
+
outputIndex: vout! + 10,
|
|
141
|
+
sspSignature: quote!.signature,
|
|
142
|
+
}),
|
|
143
|
+
).rejects.toThrow("UTXO is spent or not found.");
|
|
144
|
+
}, 600000);
|
|
145
|
+
});
|