@buildonspark/spark-sdk 0.2.2 → 0.2.4
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 +15 -0
- package/dist/{chunk-TM6CHQXC.js → chunk-3SEOTO43.js} +1 -1
- package/dist/{chunk-2ENZX6LT.js → chunk-AAZWSPUK.js} +84 -8
- package/dist/{chunk-4JD4HIAN.js → chunk-G4MSZ6DE.js} +299 -1
- package/dist/{chunk-S2AL73MZ.js → chunk-TVUMSHWA.js} +1 -1
- package/dist/{chunk-2TUM3R6C.js → chunk-W4ZRBSWM.js} +2351 -797
- package/dist/{chunk-CDLETEDT.js → chunk-WAQKYSDI.js} +13 -1
- package/dist/{client-CGTRS23n.d.ts → client-BF4cn8F4.d.ts} +15 -3
- package/dist/{client-CcYzmpmj.d.cts → client-KhNkrXz4.d.cts} +15 -3
- package/dist/debug.cjs +2948 -1023
- package/dist/debug.d.cts +19 -6
- package/dist/debug.d.ts +19 -6
- package/dist/debug.js +5 -5
- package/dist/graphql/objects/index.cjs +13 -1
- package/dist/graphql/objects/index.d.cts +2 -2
- package/dist/graphql/objects/index.d.ts +2 -2
- package/dist/graphql/objects/index.js +1 -1
- package/dist/index.cjs +2794 -858
- package/dist/index.d.cts +190 -9
- package/dist/index.d.ts +190 -9
- package/dist/index.js +32 -6
- package/dist/index.node.cjs +2931 -892
- package/dist/index.node.d.cts +10 -188
- package/dist/index.node.d.ts +10 -188
- package/dist/index.node.js +134 -6
- package/dist/native/index.cjs +2794 -858
- package/dist/native/index.d.cts +148 -40
- package/dist/native/index.d.ts +148 -40
- package/dist/native/index.js +2799 -877
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/lrc20.js +1 -1
- package/dist/proto/spark.cjs +84 -8
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +1 -1
- package/dist/proto/spark_token.cjs +301 -0
- package/dist/proto/spark_token.d.cts +35 -2
- package/dist/proto/spark_token.d.ts +35 -2
- package/dist/proto/spark_token.js +8 -2
- package/dist/{sdk-types-DJ2ve9YY.d.cts → sdk-types-CB9HrW5O.d.cts} +1 -1
- package/dist/{sdk-types-DCIVdKUT.d.ts → sdk-types-CkRNraXT.d.ts} +1 -1
- package/dist/{spark-BUOx3U7Q.d.cts → spark-B_7nZx6T.d.cts} +112 -10
- package/dist/{spark-BUOx3U7Q.d.ts → spark-B_7nZx6T.d.ts} +112 -10
- package/dist/{spark-wallet-B_96y9BS.d.ts → spark-wallet-C1Tr_VKI.d.ts} +38 -28
- package/dist/{spark-wallet-CHwKQYJu.d.cts → spark-wallet-DG3x2obf.d.cts} +38 -28
- package/dist/spark-wallet.node-CGxoeCpH.d.ts +13 -0
- package/dist/spark-wallet.node-CN9LoB_O.d.cts +13 -0
- package/dist/tests/test-utils.cjs +1086 -218
- package/dist/tests/test-utils.d.cts +13 -13
- package/dist/tests/test-utils.d.ts +13 -13
- package/dist/tests/test-utils.js +56 -19
- package/dist/types/index.cjs +97 -9
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +3 -3
- package/dist/{xchain-address-D5MIHCDL.d.cts → xchain-address-BHu6CpZC.d.ts} +55 -8
- package/dist/{xchain-address-DLbW1iDh.d.ts → xchain-address-HBr6isnc.d.cts} +55 -8
- package/package.json +1 -1
- package/src/graphql/client.ts +8 -0
- package/src/graphql/mutations/CompleteLeavesSwap.ts +9 -1
- package/src/graphql/mutations/RequestSwapLeaves.ts +4 -0
- package/src/graphql/objects/CompleteLeavesSwapInput.ts +34 -34
- package/src/graphql/objects/LeavesSwapRequest.ts +4 -0
- package/src/graphql/objects/RequestLeavesSwapInput.ts +48 -47
- package/src/graphql/objects/SwapLeaf.ts +40 -32
- package/src/graphql/objects/UserLeafInput.ts +24 -0
- package/src/graphql/objects/UserRequest.ts +4 -0
- package/src/index.node.ts +1 -1
- package/src/native/index.ts +4 -5
- package/src/proto/spark.ts +172 -16
- package/src/proto/spark_token.ts +369 -0
- package/src/services/coop-exit.ts +171 -36
- package/src/services/deposit.ts +471 -74
- package/src/services/lightning.ts +18 -5
- package/src/services/signing.ts +162 -50
- package/src/services/token-transactions.ts +6 -2
- package/src/services/transfer.ts +950 -384
- package/src/services/tree-creation.ts +342 -121
- package/src/spark-wallet/spark-wallet.node.ts +71 -66
- package/src/spark-wallet/spark-wallet.ts +459 -166
- package/src/tests/integration/coop-exit.test.ts +3 -8
- package/src/tests/integration/deposit.test.ts +3 -3
- package/src/tests/integration/lightning.test.ts +521 -466
- package/src/tests/integration/swap.test.ts +559 -307
- package/src/tests/integration/transfer.test.ts +625 -623
- package/src/tests/integration/wallet.test.ts +2 -2
- package/src/tests/integration/watchtower.test.ts +211 -0
- package/src/tests/test-utils.ts +63 -14
- package/src/tests/utils/test-faucet.ts +4 -2
- package/src/utils/adaptor-signature.ts +15 -5
- package/src/utils/fetch.ts +75 -0
- package/src/utils/mempool.ts +9 -4
- package/src/utils/transaction.ts +388 -26
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
getTxFromRawTxBytes,
|
|
13
13
|
} from "../utils/bitcoin.js";
|
|
14
14
|
import { Network } from "../utils/network.js";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
getNextTransactionSequence,
|
|
17
|
+
maybeApplyFee,
|
|
18
|
+
} from "../utils/transaction.js";
|
|
16
19
|
import { WalletConfigService } from "./config.js";
|
|
17
20
|
import { ConnectionManager } from "./connection.js";
|
|
18
21
|
import { SigningService } from "./signing.js";
|
|
@@ -43,8 +46,15 @@ export class CoopExitService extends BaseTransferService {
|
|
|
43
46
|
}: GetConnectorRefundSignaturesParams): Promise<{
|
|
44
47
|
transfer: Transfer;
|
|
45
48
|
signaturesMap: Map<string, Uint8Array>;
|
|
49
|
+
directSignaturesMap: Map<string, Uint8Array>;
|
|
50
|
+
directFromCpfpSignaturesMap: Map<string, Uint8Array>;
|
|
46
51
|
}> {
|
|
47
|
-
const {
|
|
52
|
+
const {
|
|
53
|
+
transfer,
|
|
54
|
+
signaturesMap,
|
|
55
|
+
directSignaturesMap,
|
|
56
|
+
directFromCpfpSignaturesMap,
|
|
57
|
+
} = await this.signCoopExitRefunds(
|
|
48
58
|
leaves,
|
|
49
59
|
exitTxId,
|
|
50
60
|
connectorOutputs,
|
|
@@ -55,51 +65,116 @@ export class CoopExitService extends BaseTransferService {
|
|
|
55
65
|
transfer,
|
|
56
66
|
leaves,
|
|
57
67
|
signaturesMap,
|
|
68
|
+
directSignaturesMap,
|
|
69
|
+
directFromCpfpSignaturesMap,
|
|
58
70
|
);
|
|
59
71
|
|
|
60
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
transfer: transferTweak,
|
|
74
|
+
signaturesMap,
|
|
75
|
+
directSignaturesMap,
|
|
76
|
+
directFromCpfpSignaturesMap,
|
|
77
|
+
};
|
|
61
78
|
}
|
|
62
79
|
|
|
63
|
-
private
|
|
80
|
+
private createConnectorRefundTransactions(
|
|
64
81
|
sequence: number,
|
|
65
|
-
|
|
82
|
+
directSequence: number,
|
|
83
|
+
cpfpNodeOutPoint: TransactionInput,
|
|
84
|
+
directNodeOutPoint: TransactionInput | undefined,
|
|
66
85
|
connectorOutput: TransactionInput,
|
|
67
86
|
amountSats: bigint,
|
|
68
87
|
receiverPubKey: Uint8Array,
|
|
69
|
-
):
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
): {
|
|
89
|
+
cpfpRefundTx: Transaction;
|
|
90
|
+
directRefundTx?: Transaction;
|
|
91
|
+
directFromCpfpRefundTx?: Transaction;
|
|
92
|
+
} {
|
|
93
|
+
// Create CPFP refund transaction
|
|
94
|
+
const cpfpRefundTx = new Transaction();
|
|
95
|
+
if (!cpfpNodeOutPoint.txid || cpfpNodeOutPoint.index === undefined) {
|
|
96
|
+
throw new ValidationError("Invalid CPFP node outpoint", {
|
|
97
|
+
field: "cpfpNodeOutPoint",
|
|
98
|
+
value: { txid: cpfpNodeOutPoint.txid, index: cpfpNodeOutPoint.index },
|
|
75
99
|
expected: "Both txid and index must be defined",
|
|
76
100
|
});
|
|
77
101
|
}
|
|
78
|
-
|
|
79
|
-
txid:
|
|
80
|
-
index:
|
|
102
|
+
cpfpRefundTx.addInput({
|
|
103
|
+
txid: cpfpNodeOutPoint.txid,
|
|
104
|
+
index: cpfpNodeOutPoint.index,
|
|
81
105
|
sequence,
|
|
82
106
|
});
|
|
83
107
|
|
|
84
|
-
|
|
108
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
85
109
|
const receiverScript = getP2TRScriptFromPublicKey(
|
|
86
110
|
receiverPubKey,
|
|
87
111
|
this.config.getNetwork(),
|
|
88
112
|
);
|
|
89
113
|
|
|
90
|
-
|
|
114
|
+
cpfpRefundTx.addOutput({
|
|
91
115
|
script: receiverScript,
|
|
92
116
|
amount: amountSats,
|
|
93
117
|
});
|
|
94
118
|
|
|
95
|
-
|
|
119
|
+
// Create direct refund transaction
|
|
120
|
+
let directRefundTx: Transaction | undefined;
|
|
121
|
+
let directFromCpfpRefundTx: Transaction | undefined;
|
|
122
|
+
if (directNodeOutPoint) {
|
|
123
|
+
if (!directNodeOutPoint.txid || directNodeOutPoint.index === undefined) {
|
|
124
|
+
throw new ValidationError("Invalid direct node outpoint", {
|
|
125
|
+
field: "directNodeOutPoint",
|
|
126
|
+
value: {
|
|
127
|
+
txid: directNodeOutPoint.txid,
|
|
128
|
+
index: directNodeOutPoint.index,
|
|
129
|
+
},
|
|
130
|
+
expected: "Both txid and index must be defined",
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
directRefundTx = new Transaction();
|
|
134
|
+
directRefundTx.addInput({
|
|
135
|
+
txid: directNodeOutPoint.txid,
|
|
136
|
+
index: directNodeOutPoint.index,
|
|
137
|
+
sequence: directSequence,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
directRefundTx.addInput(connectorOutput);
|
|
141
|
+
directRefundTx.addOutput({
|
|
142
|
+
script: receiverScript,
|
|
143
|
+
amount: maybeApplyFee(amountSats),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
directFromCpfpRefundTx = new Transaction();
|
|
147
|
+
directFromCpfpRefundTx.addInput({
|
|
148
|
+
txid: cpfpNodeOutPoint.txid,
|
|
149
|
+
index: cpfpNodeOutPoint.index,
|
|
150
|
+
sequence: directSequence,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
directFromCpfpRefundTx.addInput(connectorOutput);
|
|
154
|
+
directFromCpfpRefundTx.addOutput({
|
|
155
|
+
script: receiverScript,
|
|
156
|
+
amount: maybeApplyFee(amountSats),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
cpfpRefundTx,
|
|
162
|
+
directRefundTx,
|
|
163
|
+
directFromCpfpRefundTx,
|
|
164
|
+
};
|
|
96
165
|
}
|
|
166
|
+
|
|
97
167
|
private async signCoopExitRefunds(
|
|
98
168
|
leaves: LeafKeyTweak[],
|
|
99
169
|
exitTxId: Uint8Array,
|
|
100
170
|
connectorOutputs: TransactionInput[],
|
|
101
171
|
receiverPubKey: Uint8Array,
|
|
102
|
-
): Promise<{
|
|
172
|
+
): Promise<{
|
|
173
|
+
transfer: Transfer;
|
|
174
|
+
signaturesMap: Map<string, Uint8Array>;
|
|
175
|
+
directSignaturesMap: Map<string, Uint8Array>;
|
|
176
|
+
directFromCpfpSignaturesMap: Map<string, Uint8Array>;
|
|
177
|
+
}> {
|
|
103
178
|
if (leaves.length !== connectorOutputs.length) {
|
|
104
179
|
throw new ValidationError(
|
|
105
180
|
"Mismatch between leaves and connector outputs",
|
|
@@ -136,43 +211,88 @@ export class CoopExitService extends BaseTransferService {
|
|
|
136
211
|
}
|
|
137
212
|
const currentRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
138
213
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
214
|
+
const sequence = currentRefundTx.getInput(0).sequence;
|
|
215
|
+
if (!sequence) {
|
|
216
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
217
|
+
field: "sequence",
|
|
218
|
+
value: currentRefundTx.getInput(0),
|
|
219
|
+
expected: "Non-null sequence",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const { nextSequence, nextDirectSequence } =
|
|
223
|
+
getNextTransactionSequence(sequence);
|
|
142
224
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
225
|
+
let currentDirectRefundTx: Transaction | undefined;
|
|
226
|
+
if (leaf.leaf.directRefundTx.length > 0) {
|
|
227
|
+
currentDirectRefundTx = getTxFromRawTxBytes(leaf.leaf.directRefundTx);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } =
|
|
231
|
+
this.createConnectorRefundTransactions(
|
|
232
|
+
nextSequence,
|
|
233
|
+
nextDirectSequence,
|
|
234
|
+
currentRefundTx.getInput(0),
|
|
235
|
+
currentDirectRefundTx?.getInput(0),
|
|
236
|
+
connectorOutput,
|
|
237
|
+
BigInt(leaf.leaf.value),
|
|
238
|
+
receiverPubKey,
|
|
239
|
+
);
|
|
150
240
|
|
|
151
241
|
const signingNonceCommitment =
|
|
152
242
|
await this.config.signer.getRandomSigningCommitment();
|
|
243
|
+
const directSigningNonceCommitment =
|
|
244
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
245
|
+
const directFromCpfpSigningNonceCommitment =
|
|
246
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
247
|
+
const signingPublicKey =
|
|
248
|
+
await this.config.signer.getPublicKeyFromDerivation(leaf.keyDerivation);
|
|
249
|
+
|
|
153
250
|
const signingJob: LeafRefundTxSigningJob = {
|
|
154
251
|
leafId: leaf.leaf.id,
|
|
155
252
|
refundTxSigningJob: {
|
|
156
253
|
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
157
254
|
leaf.keyDerivation,
|
|
158
255
|
),
|
|
159
|
-
rawTx:
|
|
256
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
160
257
|
signingNonceCommitment: signingNonceCommitment.commitment,
|
|
161
258
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
259
|
+
directRefundTxSigningJob: directRefundTx
|
|
260
|
+
? {
|
|
261
|
+
signingPublicKey,
|
|
262
|
+
rawTx: directRefundTx.toBytes(),
|
|
263
|
+
signingNonceCommitment: directSigningNonceCommitment.commitment,
|
|
264
|
+
}
|
|
265
|
+
: undefined,
|
|
266
|
+
directFromCpfpRefundTxSigningJob: directFromCpfpRefundTx
|
|
267
|
+
? {
|
|
268
|
+
signingPublicKey,
|
|
269
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
270
|
+
signingNonceCommitment:
|
|
271
|
+
directFromCpfpSigningNonceCommitment.commitment,
|
|
272
|
+
}
|
|
273
|
+
: undefined,
|
|
165
274
|
};
|
|
166
275
|
|
|
167
276
|
signingJobs.push(signingJob);
|
|
168
277
|
const tx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
278
|
+
const directTx =
|
|
279
|
+
leaf.leaf.directTx.length > 0
|
|
280
|
+
? getTxFromRawTxBytes(leaf.leaf.directTx)
|
|
281
|
+
: undefined;
|
|
282
|
+
|
|
169
283
|
leafDataMap.set(leaf.leaf.id, {
|
|
170
284
|
keyDerivation: leaf.keyDerivation,
|
|
171
|
-
|
|
285
|
+
receivingPubkey: receiverPubKey,
|
|
172
286
|
signingNonceCommitment,
|
|
287
|
+
directSigningNonceCommitment,
|
|
173
288
|
tx,
|
|
289
|
+
directTx,
|
|
290
|
+
refundTx: cpfpRefundTx,
|
|
291
|
+
directRefundTx: directRefundTx,
|
|
292
|
+
directFromCpfpRefundTx: directFromCpfpRefundTx,
|
|
293
|
+
directFromCpfpRefundSigningNonceCommitment:
|
|
294
|
+
directFromCpfpSigningNonceCommitment,
|
|
174
295
|
vout: leaf.leaf.vout,
|
|
175
|
-
receivingPubkey: receiverPubKey,
|
|
176
296
|
});
|
|
177
297
|
}
|
|
178
298
|
|
|
@@ -182,7 +302,7 @@ export class CoopExitService extends BaseTransferService {
|
|
|
182
302
|
|
|
183
303
|
let response: CooperativeExitResponse;
|
|
184
304
|
try {
|
|
185
|
-
response = await sparkClient.
|
|
305
|
+
response = await sparkClient.cooperative_exit_v2({
|
|
186
306
|
transfer: {
|
|
187
307
|
transferId: uuidv7(),
|
|
188
308
|
leavesToSend: signingJobs,
|
|
@@ -222,10 +342,25 @@ export class CoopExitService extends BaseTransferService {
|
|
|
222
342
|
);
|
|
223
343
|
|
|
224
344
|
const signaturesMap: Map<string, Uint8Array> = new Map();
|
|
345
|
+
const directSignaturesMap: Map<string, Uint8Array> = new Map();
|
|
346
|
+
const directFromCpfpSignaturesMap: Map<string, Uint8Array> = new Map();
|
|
225
347
|
for (const signature of signatures) {
|
|
226
348
|
signaturesMap.set(signature.nodeId, signature.refundTxSignature);
|
|
349
|
+
directSignaturesMap.set(
|
|
350
|
+
signature.nodeId,
|
|
351
|
+
signature.directRefundTxSignature,
|
|
352
|
+
);
|
|
353
|
+
directFromCpfpSignaturesMap.set(
|
|
354
|
+
signature.nodeId,
|
|
355
|
+
signature.directFromCpfpRefundTxSignature,
|
|
356
|
+
);
|
|
227
357
|
}
|
|
228
358
|
|
|
229
|
-
return {
|
|
359
|
+
return {
|
|
360
|
+
transfer: response.transfer,
|
|
361
|
+
signaturesMap,
|
|
362
|
+
directSignaturesMap,
|
|
363
|
+
directFromCpfpSignaturesMap,
|
|
364
|
+
};
|
|
230
365
|
}
|
|
231
366
|
}
|