@buildonspark/spark-sdk 0.0.9 → 0.0.11
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/services/config.d.ts +20 -16
- package/dist/services/config.js +26 -18
- package/dist/services/config.js.map +1 -1
- package/dist/services/connection.js +1 -1
- package/dist/services/connection.js.map +1 -1
- package/dist/services/deposit.js +2 -2
- package/dist/services/deposit.js.map +1 -1
- package/dist/services/lightning.js +4 -4
- package/dist/services/lightning.js.map +1 -1
- package/dist/services/token-transactions.js +8 -7
- package/dist/services/token-transactions.js.map +1 -1
- package/dist/services/transfer.js +12 -10
- package/dist/services/transfer.js.map +1 -1
- package/dist/spark-sdk.d.ts +2 -3
- package/dist/spark-sdk.js +2 -7
- package/dist/spark-sdk.js.map +1 -1
- package/dist/tests/coop-exit.test.js +8 -5
- package/dist/tests/coop-exit.test.js.map +1 -1
- package/dist/tests/deposit.test.js +8 -10
- package/dist/tests/deposit.test.js.map +1 -1
- package/dist/tests/keys.test.js +0 -1
- package/dist/tests/keys.test.js.map +1 -1
- package/dist/tests/lightning.test.js +10 -7
- package/dist/tests/lightning.test.js.map +1 -1
- package/dist/tests/swap.test.js +8 -5
- package/dist/tests/swap.test.js.map +1 -1
- package/dist/tests/test-util.d.ts +8 -44
- package/dist/tests/test-util.js +10 -7
- package/dist/tests/test-util.js.map +1 -1
- package/dist/tests/transfer.test.js +30 -19
- package/dist/tests/transfer.test.js.map +1 -1
- package/package.json +2 -2
- package/dist/LightningSendRequest-CNJFhLVc.d.cts +0 -374
- package/dist/LightningSendRequest-CNJFhLVc.d.ts +0 -374
- package/dist/auto-bind.d.ts +0 -7
- package/dist/auto-bind.js +0 -41
- package/dist/auto-bind.js.map +0 -1
- package/dist/chunk-5SAJ52IV.js +0 -10309
- package/dist/chunk-COXVABEU.js +0 -1524
- package/dist/chunk-F4JW24C4.js +0 -78
- package/dist/chunk-H4A2WXR3.js +0 -331
- package/dist/chunk-HTNOFUHX.js +0 -1547
- package/dist/chunk-JQFHUW4I.js +0 -21
- package/dist/chunk-K3Y7DVLD.js +0 -19
- package/dist/chunk-NDKNVHGP.js +0 -127
- package/dist/chunk-PMVJGQCP.js +0 -627
- package/dist/chunk-QX3ZJH2S.js +0 -527
- package/dist/chunk-SL2YOBVM.js +0 -127
- package/dist/chunk-SWCOMKD6.js +0 -333
- package/dist/chunk-SWFFNBSR.js +0 -1244
- package/dist/chunk-WLK5POBV.js +0 -527
- package/dist/chunk-WZ74TD7N.js +0 -660
- package/dist/chunk-WZYVI3M3.js +0 -1244
- package/dist/chunk-ZGU3XW7W.js +0 -78
- package/dist/connection-BgWj7Hnd.d.cts +0 -77
- package/dist/connection-BgbVJtzh.d.ts +0 -77
- package/dist/connection-DX-9yFl8.d.ts +0 -77
- package/dist/connection-hITj9Mgk.d.cts +0 -77
- package/dist/graphql/objects/index.cjs +0 -626
- package/dist/graphql/objects/index.d.cts +0 -140
- package/dist/index.cjs +0 -17202
- package/dist/index.d.cts +0 -413
- package/dist/index.d.ts +0 -413
- package/dist/index.js +0 -3390
- package/dist/proto/spark.cjs +0 -10451
- package/dist/proto/spark.d.cts +0 -3
- package/dist/services/index.cjs +0 -12503
- package/dist/services/index.d.cts +0 -23
- package/dist/services/index.d.ts +0 -23
- package/dist/services/index.js +0 -17
- package/dist/signer/signer.cjs +0 -894
- package/dist/signer/signer.d.cts +0 -5
- package/dist/signer-BaC_ZP1g.d.ts +0 -138
- package/dist/signer-C6h1OnSQ.d.cts +0 -138
- package/dist/signer-CO4owhHI.d.ts +0 -154
- package/dist/signer-DDkpXvNZ.d.cts +0 -154
- package/dist/spark-BUTdOtMz.d.cts +0 -1170
- package/dist/spark-BUTdOtMz.d.ts +0 -1170
- package/dist/tests/test-util.cjs +0 -12269
- package/dist/tests/test-util.d.cts +0 -90
- package/dist/utils/index.cjs +0 -1825
- package/dist/utils/index.d.cts +0 -280
package/dist/chunk-SWFFNBSR.js
DELETED
|
@@ -1,1244 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DefaultSparkSigner
|
|
3
|
-
} from "./chunk-SWCOMKD6.js";
|
|
4
|
-
import {
|
|
5
|
-
getP2TRAddressFromPublicKey,
|
|
6
|
-
getSigHashFromTx,
|
|
7
|
-
getTxId,
|
|
8
|
-
proofOfPossessionMessageHashForDepositAddress
|
|
9
|
-
} from "./chunk-NDKNVHGP.js";
|
|
10
|
-
import {
|
|
11
|
-
NetworkToProto,
|
|
12
|
-
createWasmSigningCommitment,
|
|
13
|
-
getNetwork,
|
|
14
|
-
subtractPublicKeys
|
|
15
|
-
} from "./chunk-COXVABEU.js";
|
|
16
|
-
import {
|
|
17
|
-
BinaryReader,
|
|
18
|
-
BinaryWriter,
|
|
19
|
-
Empty,
|
|
20
|
-
SparkServiceDefinition
|
|
21
|
-
} from "./chunk-5SAJ52IV.js";
|
|
22
|
-
|
|
23
|
-
// src/tests/test-util.ts
|
|
24
|
-
import { hexToBytes } from "@noble/curves/abstract/utils";
|
|
25
|
-
import { secp256k1 as secp256k12 } from "@noble/curves/secp256k1";
|
|
26
|
-
import { Address as Address2, OutScript as OutScript2, Transaction as Transaction2 } from "@scure/btc-signer";
|
|
27
|
-
|
|
28
|
-
// src/services/config.ts
|
|
29
|
-
var WalletConfigService = class _WalletConfigService {
|
|
30
|
-
config;
|
|
31
|
-
signer;
|
|
32
|
-
constructor(network, signer) {
|
|
33
|
-
switch (network) {
|
|
34
|
-
case 0 /* MAINNET */:
|
|
35
|
-
this.config = MAINNET_WALLET_CONFIG;
|
|
36
|
-
break;
|
|
37
|
-
case 3 /* REGTEST */:
|
|
38
|
-
this.config = REGTEST_WALLET_CONFIG;
|
|
39
|
-
break;
|
|
40
|
-
default:
|
|
41
|
-
this.config = LOCAL_WALLET_CONFIG;
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
this.signer = signer || new DefaultSparkSigner();
|
|
45
|
-
}
|
|
46
|
-
static withConfig(config, signer) {
|
|
47
|
-
const service = new _WalletConfigService(config.network, signer);
|
|
48
|
-
service.config = config;
|
|
49
|
-
return service;
|
|
50
|
-
}
|
|
51
|
-
getCoordinatorAddress() {
|
|
52
|
-
const coordinator = this.config.signingOperators[this.config.coodinatorIdentifier];
|
|
53
|
-
if (!coordinator) {
|
|
54
|
-
throw new Error(
|
|
55
|
-
`Coordinator ${this.config.coodinatorIdentifier} not found`
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
return coordinator.address;
|
|
59
|
-
}
|
|
60
|
-
getConfig() {
|
|
61
|
-
return this.config;
|
|
62
|
-
}
|
|
63
|
-
getNetwork() {
|
|
64
|
-
return this.config.network;
|
|
65
|
-
}
|
|
66
|
-
getNetworkProto() {
|
|
67
|
-
return NetworkToProto[this.config.network];
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// src/services/connection.ts
|
|
72
|
-
import { sha256 } from "@scure/btc-signer/utils";
|
|
73
|
-
import * as fs from "fs";
|
|
74
|
-
import {
|
|
75
|
-
ChannelCredentials,
|
|
76
|
-
createChannel,
|
|
77
|
-
createClient,
|
|
78
|
-
createClientFactory,
|
|
79
|
-
Metadata
|
|
80
|
-
} from "nice-grpc";
|
|
81
|
-
import { retryMiddleware } from "nice-grpc-client-middleware-retry";
|
|
82
|
-
|
|
83
|
-
// src/proto/mock.ts
|
|
84
|
-
function createBaseCleanUpPreimageShareRequest() {
|
|
85
|
-
return { paymentHash: new Uint8Array(0) };
|
|
86
|
-
}
|
|
87
|
-
var CleanUpPreimageShareRequest = {
|
|
88
|
-
encode(message, writer = new BinaryWriter()) {
|
|
89
|
-
if (message.paymentHash.length !== 0) {
|
|
90
|
-
writer.uint32(10).bytes(message.paymentHash);
|
|
91
|
-
}
|
|
92
|
-
return writer;
|
|
93
|
-
},
|
|
94
|
-
decode(input, length) {
|
|
95
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
96
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
97
|
-
const message = createBaseCleanUpPreimageShareRequest();
|
|
98
|
-
while (reader.pos < end) {
|
|
99
|
-
const tag = reader.uint32();
|
|
100
|
-
switch (tag >>> 3) {
|
|
101
|
-
case 1: {
|
|
102
|
-
if (tag !== 10) {
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
message.paymentHash = reader.bytes();
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
reader.skip(tag & 7);
|
|
113
|
-
}
|
|
114
|
-
return message;
|
|
115
|
-
},
|
|
116
|
-
fromJSON(object) {
|
|
117
|
-
return { paymentHash: isSet(object.paymentHash) ? bytesFromBase64(object.paymentHash) : new Uint8Array(0) };
|
|
118
|
-
},
|
|
119
|
-
toJSON(message) {
|
|
120
|
-
const obj = {};
|
|
121
|
-
if (message.paymentHash.length !== 0) {
|
|
122
|
-
obj.paymentHash = base64FromBytes(message.paymentHash);
|
|
123
|
-
}
|
|
124
|
-
return obj;
|
|
125
|
-
},
|
|
126
|
-
create(base) {
|
|
127
|
-
return CleanUpPreimageShareRequest.fromPartial(base ?? {});
|
|
128
|
-
},
|
|
129
|
-
fromPartial(object) {
|
|
130
|
-
const message = createBaseCleanUpPreimageShareRequest();
|
|
131
|
-
message.paymentHash = object.paymentHash ?? new Uint8Array(0);
|
|
132
|
-
return message;
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
var MockServiceDefinition = {
|
|
136
|
-
name: "MockService",
|
|
137
|
-
fullName: "mock.MockService",
|
|
138
|
-
methods: {
|
|
139
|
-
clean_up_preimage_share: {
|
|
140
|
-
name: "clean_up_preimage_share",
|
|
141
|
-
requestType: CleanUpPreimageShareRequest,
|
|
142
|
-
requestStream: false,
|
|
143
|
-
responseType: Empty,
|
|
144
|
-
responseStream: false,
|
|
145
|
-
options: {}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
function bytesFromBase64(b64) {
|
|
150
|
-
if (globalThis.Buffer) {
|
|
151
|
-
return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
152
|
-
} else {
|
|
153
|
-
const bin = globalThis.atob(b64);
|
|
154
|
-
const arr = new Uint8Array(bin.length);
|
|
155
|
-
for (let i = 0; i < bin.length; ++i) {
|
|
156
|
-
arr[i] = bin.charCodeAt(i);
|
|
157
|
-
}
|
|
158
|
-
return arr;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function base64FromBytes(arr) {
|
|
162
|
-
if (globalThis.Buffer) {
|
|
163
|
-
return globalThis.Buffer.from(arr).toString("base64");
|
|
164
|
-
} else {
|
|
165
|
-
const bin = [];
|
|
166
|
-
arr.forEach((byte) => {
|
|
167
|
-
bin.push(globalThis.String.fromCharCode(byte));
|
|
168
|
-
});
|
|
169
|
-
return globalThis.btoa(bin.join(""));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function isSet(value) {
|
|
173
|
-
return value !== null && value !== void 0;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// src/proto/spark_authn.ts
|
|
177
|
-
function createBaseChallenge() {
|
|
178
|
-
return { version: 0, timestamp: 0, nonce: new Uint8Array(0), publicKey: new Uint8Array(0) };
|
|
179
|
-
}
|
|
180
|
-
var Challenge = {
|
|
181
|
-
encode(message, writer = new BinaryWriter()) {
|
|
182
|
-
if (message.version !== 0) {
|
|
183
|
-
writer.uint32(8).int32(message.version);
|
|
184
|
-
}
|
|
185
|
-
if (message.timestamp !== 0) {
|
|
186
|
-
writer.uint32(16).int64(message.timestamp);
|
|
187
|
-
}
|
|
188
|
-
if (message.nonce.length !== 0) {
|
|
189
|
-
writer.uint32(26).bytes(message.nonce);
|
|
190
|
-
}
|
|
191
|
-
if (message.publicKey.length !== 0) {
|
|
192
|
-
writer.uint32(34).bytes(message.publicKey);
|
|
193
|
-
}
|
|
194
|
-
return writer;
|
|
195
|
-
},
|
|
196
|
-
decode(input, length) {
|
|
197
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
198
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
199
|
-
const message = createBaseChallenge();
|
|
200
|
-
while (reader.pos < end) {
|
|
201
|
-
const tag = reader.uint32();
|
|
202
|
-
switch (tag >>> 3) {
|
|
203
|
-
case 1: {
|
|
204
|
-
if (tag !== 8) {
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
message.version = reader.int32();
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
case 2: {
|
|
211
|
-
if (tag !== 16) {
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
message.timestamp = longToNumber(reader.int64());
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
case 3: {
|
|
218
|
-
if (tag !== 26) {
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
message.nonce = reader.bytes();
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
case 4: {
|
|
225
|
-
if (tag !== 34) {
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
message.publicKey = reader.bytes();
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
reader.skip(tag & 7);
|
|
236
|
-
}
|
|
237
|
-
return message;
|
|
238
|
-
},
|
|
239
|
-
fromJSON(object) {
|
|
240
|
-
return {
|
|
241
|
-
version: isSet2(object.version) ? globalThis.Number(object.version) : 0,
|
|
242
|
-
timestamp: isSet2(object.timestamp) ? globalThis.Number(object.timestamp) : 0,
|
|
243
|
-
nonce: isSet2(object.nonce) ? bytesFromBase642(object.nonce) : new Uint8Array(0),
|
|
244
|
-
publicKey: isSet2(object.publicKey) ? bytesFromBase642(object.publicKey) : new Uint8Array(0)
|
|
245
|
-
};
|
|
246
|
-
},
|
|
247
|
-
toJSON(message) {
|
|
248
|
-
const obj = {};
|
|
249
|
-
if (message.version !== 0) {
|
|
250
|
-
obj.version = Math.round(message.version);
|
|
251
|
-
}
|
|
252
|
-
if (message.timestamp !== 0) {
|
|
253
|
-
obj.timestamp = Math.round(message.timestamp);
|
|
254
|
-
}
|
|
255
|
-
if (message.nonce.length !== 0) {
|
|
256
|
-
obj.nonce = base64FromBytes2(message.nonce);
|
|
257
|
-
}
|
|
258
|
-
if (message.publicKey.length !== 0) {
|
|
259
|
-
obj.publicKey = base64FromBytes2(message.publicKey);
|
|
260
|
-
}
|
|
261
|
-
return obj;
|
|
262
|
-
},
|
|
263
|
-
create(base) {
|
|
264
|
-
return Challenge.fromPartial(base ?? {});
|
|
265
|
-
},
|
|
266
|
-
fromPartial(object) {
|
|
267
|
-
const message = createBaseChallenge();
|
|
268
|
-
message.version = object.version ?? 0;
|
|
269
|
-
message.timestamp = object.timestamp ?? 0;
|
|
270
|
-
message.nonce = object.nonce ?? new Uint8Array(0);
|
|
271
|
-
message.publicKey = object.publicKey ?? new Uint8Array(0);
|
|
272
|
-
return message;
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
function createBaseProtectedChallenge() {
|
|
276
|
-
return { version: 0, challenge: void 0, serverHmac: new Uint8Array(0) };
|
|
277
|
-
}
|
|
278
|
-
var ProtectedChallenge = {
|
|
279
|
-
encode(message, writer = new BinaryWriter()) {
|
|
280
|
-
if (message.version !== 0) {
|
|
281
|
-
writer.uint32(8).int32(message.version);
|
|
282
|
-
}
|
|
283
|
-
if (message.challenge !== void 0) {
|
|
284
|
-
Challenge.encode(message.challenge, writer.uint32(18).fork()).join();
|
|
285
|
-
}
|
|
286
|
-
if (message.serverHmac.length !== 0) {
|
|
287
|
-
writer.uint32(26).bytes(message.serverHmac);
|
|
288
|
-
}
|
|
289
|
-
return writer;
|
|
290
|
-
},
|
|
291
|
-
decode(input, length) {
|
|
292
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
293
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
294
|
-
const message = createBaseProtectedChallenge();
|
|
295
|
-
while (reader.pos < end) {
|
|
296
|
-
const tag = reader.uint32();
|
|
297
|
-
switch (tag >>> 3) {
|
|
298
|
-
case 1: {
|
|
299
|
-
if (tag !== 8) {
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
message.version = reader.int32();
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
case 2: {
|
|
306
|
-
if (tag !== 18) {
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
message.challenge = Challenge.decode(reader, reader.uint32());
|
|
310
|
-
continue;
|
|
311
|
-
}
|
|
312
|
-
case 3: {
|
|
313
|
-
if (tag !== 26) {
|
|
314
|
-
break;
|
|
315
|
-
}
|
|
316
|
-
message.serverHmac = reader.bytes();
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
321
|
-
break;
|
|
322
|
-
}
|
|
323
|
-
reader.skip(tag & 7);
|
|
324
|
-
}
|
|
325
|
-
return message;
|
|
326
|
-
},
|
|
327
|
-
fromJSON(object) {
|
|
328
|
-
return {
|
|
329
|
-
version: isSet2(object.version) ? globalThis.Number(object.version) : 0,
|
|
330
|
-
challenge: isSet2(object.challenge) ? Challenge.fromJSON(object.challenge) : void 0,
|
|
331
|
-
serverHmac: isSet2(object.serverHmac) ? bytesFromBase642(object.serverHmac) : new Uint8Array(0)
|
|
332
|
-
};
|
|
333
|
-
},
|
|
334
|
-
toJSON(message) {
|
|
335
|
-
const obj = {};
|
|
336
|
-
if (message.version !== 0) {
|
|
337
|
-
obj.version = Math.round(message.version);
|
|
338
|
-
}
|
|
339
|
-
if (message.challenge !== void 0) {
|
|
340
|
-
obj.challenge = Challenge.toJSON(message.challenge);
|
|
341
|
-
}
|
|
342
|
-
if (message.serverHmac.length !== 0) {
|
|
343
|
-
obj.serverHmac = base64FromBytes2(message.serverHmac);
|
|
344
|
-
}
|
|
345
|
-
return obj;
|
|
346
|
-
},
|
|
347
|
-
create(base) {
|
|
348
|
-
return ProtectedChallenge.fromPartial(base ?? {});
|
|
349
|
-
},
|
|
350
|
-
fromPartial(object) {
|
|
351
|
-
const message = createBaseProtectedChallenge();
|
|
352
|
-
message.version = object.version ?? 0;
|
|
353
|
-
message.challenge = object.challenge !== void 0 && object.challenge !== null ? Challenge.fromPartial(object.challenge) : void 0;
|
|
354
|
-
message.serverHmac = object.serverHmac ?? new Uint8Array(0);
|
|
355
|
-
return message;
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
function createBaseGetChallengeRequest() {
|
|
359
|
-
return { publicKey: new Uint8Array(0) };
|
|
360
|
-
}
|
|
361
|
-
var GetChallengeRequest = {
|
|
362
|
-
encode(message, writer = new BinaryWriter()) {
|
|
363
|
-
if (message.publicKey.length !== 0) {
|
|
364
|
-
writer.uint32(10).bytes(message.publicKey);
|
|
365
|
-
}
|
|
366
|
-
return writer;
|
|
367
|
-
},
|
|
368
|
-
decode(input, length) {
|
|
369
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
370
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
371
|
-
const message = createBaseGetChallengeRequest();
|
|
372
|
-
while (reader.pos < end) {
|
|
373
|
-
const tag = reader.uint32();
|
|
374
|
-
switch (tag >>> 3) {
|
|
375
|
-
case 1: {
|
|
376
|
-
if (tag !== 10) {
|
|
377
|
-
break;
|
|
378
|
-
}
|
|
379
|
-
message.publicKey = reader.bytes();
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
384
|
-
break;
|
|
385
|
-
}
|
|
386
|
-
reader.skip(tag & 7);
|
|
387
|
-
}
|
|
388
|
-
return message;
|
|
389
|
-
},
|
|
390
|
-
fromJSON(object) {
|
|
391
|
-
return { publicKey: isSet2(object.publicKey) ? bytesFromBase642(object.publicKey) : new Uint8Array(0) };
|
|
392
|
-
},
|
|
393
|
-
toJSON(message) {
|
|
394
|
-
const obj = {};
|
|
395
|
-
if (message.publicKey.length !== 0) {
|
|
396
|
-
obj.publicKey = base64FromBytes2(message.publicKey);
|
|
397
|
-
}
|
|
398
|
-
return obj;
|
|
399
|
-
},
|
|
400
|
-
create(base) {
|
|
401
|
-
return GetChallengeRequest.fromPartial(base ?? {});
|
|
402
|
-
},
|
|
403
|
-
fromPartial(object) {
|
|
404
|
-
const message = createBaseGetChallengeRequest();
|
|
405
|
-
message.publicKey = object.publicKey ?? new Uint8Array(0);
|
|
406
|
-
return message;
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
function createBaseGetChallengeResponse() {
|
|
410
|
-
return { protectedChallenge: void 0 };
|
|
411
|
-
}
|
|
412
|
-
var GetChallengeResponse = {
|
|
413
|
-
encode(message, writer = new BinaryWriter()) {
|
|
414
|
-
if (message.protectedChallenge !== void 0) {
|
|
415
|
-
ProtectedChallenge.encode(message.protectedChallenge, writer.uint32(10).fork()).join();
|
|
416
|
-
}
|
|
417
|
-
return writer;
|
|
418
|
-
},
|
|
419
|
-
decode(input, length) {
|
|
420
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
421
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
422
|
-
const message = createBaseGetChallengeResponse();
|
|
423
|
-
while (reader.pos < end) {
|
|
424
|
-
const tag = reader.uint32();
|
|
425
|
-
switch (tag >>> 3) {
|
|
426
|
-
case 1: {
|
|
427
|
-
if (tag !== 10) {
|
|
428
|
-
break;
|
|
429
|
-
}
|
|
430
|
-
message.protectedChallenge = ProtectedChallenge.decode(reader, reader.uint32());
|
|
431
|
-
continue;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
reader.skip(tag & 7);
|
|
438
|
-
}
|
|
439
|
-
return message;
|
|
440
|
-
},
|
|
441
|
-
fromJSON(object) {
|
|
442
|
-
return {
|
|
443
|
-
protectedChallenge: isSet2(object.protectedChallenge) ? ProtectedChallenge.fromJSON(object.protectedChallenge) : void 0
|
|
444
|
-
};
|
|
445
|
-
},
|
|
446
|
-
toJSON(message) {
|
|
447
|
-
const obj = {};
|
|
448
|
-
if (message.protectedChallenge !== void 0) {
|
|
449
|
-
obj.protectedChallenge = ProtectedChallenge.toJSON(message.protectedChallenge);
|
|
450
|
-
}
|
|
451
|
-
return obj;
|
|
452
|
-
},
|
|
453
|
-
create(base) {
|
|
454
|
-
return GetChallengeResponse.fromPartial(base ?? {});
|
|
455
|
-
},
|
|
456
|
-
fromPartial(object) {
|
|
457
|
-
const message = createBaseGetChallengeResponse();
|
|
458
|
-
message.protectedChallenge = object.protectedChallenge !== void 0 && object.protectedChallenge !== null ? ProtectedChallenge.fromPartial(object.protectedChallenge) : void 0;
|
|
459
|
-
return message;
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
function createBaseVerifyChallengeRequest() {
|
|
463
|
-
return { protectedChallenge: void 0, signature: new Uint8Array(0), publicKey: new Uint8Array(0) };
|
|
464
|
-
}
|
|
465
|
-
var VerifyChallengeRequest = {
|
|
466
|
-
encode(message, writer = new BinaryWriter()) {
|
|
467
|
-
if (message.protectedChallenge !== void 0) {
|
|
468
|
-
ProtectedChallenge.encode(message.protectedChallenge, writer.uint32(10).fork()).join();
|
|
469
|
-
}
|
|
470
|
-
if (message.signature.length !== 0) {
|
|
471
|
-
writer.uint32(18).bytes(message.signature);
|
|
472
|
-
}
|
|
473
|
-
if (message.publicKey.length !== 0) {
|
|
474
|
-
writer.uint32(26).bytes(message.publicKey);
|
|
475
|
-
}
|
|
476
|
-
return writer;
|
|
477
|
-
},
|
|
478
|
-
decode(input, length) {
|
|
479
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
480
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
481
|
-
const message = createBaseVerifyChallengeRequest();
|
|
482
|
-
while (reader.pos < end) {
|
|
483
|
-
const tag = reader.uint32();
|
|
484
|
-
switch (tag >>> 3) {
|
|
485
|
-
case 1: {
|
|
486
|
-
if (tag !== 10) {
|
|
487
|
-
break;
|
|
488
|
-
}
|
|
489
|
-
message.protectedChallenge = ProtectedChallenge.decode(reader, reader.uint32());
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
case 2: {
|
|
493
|
-
if (tag !== 18) {
|
|
494
|
-
break;
|
|
495
|
-
}
|
|
496
|
-
message.signature = reader.bytes();
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
case 3: {
|
|
500
|
-
if (tag !== 26) {
|
|
501
|
-
break;
|
|
502
|
-
}
|
|
503
|
-
message.publicKey = reader.bytes();
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
508
|
-
break;
|
|
509
|
-
}
|
|
510
|
-
reader.skip(tag & 7);
|
|
511
|
-
}
|
|
512
|
-
return message;
|
|
513
|
-
},
|
|
514
|
-
fromJSON(object) {
|
|
515
|
-
return {
|
|
516
|
-
protectedChallenge: isSet2(object.protectedChallenge) ? ProtectedChallenge.fromJSON(object.protectedChallenge) : void 0,
|
|
517
|
-
signature: isSet2(object.signature) ? bytesFromBase642(object.signature) : new Uint8Array(0),
|
|
518
|
-
publicKey: isSet2(object.publicKey) ? bytesFromBase642(object.publicKey) : new Uint8Array(0)
|
|
519
|
-
};
|
|
520
|
-
},
|
|
521
|
-
toJSON(message) {
|
|
522
|
-
const obj = {};
|
|
523
|
-
if (message.protectedChallenge !== void 0) {
|
|
524
|
-
obj.protectedChallenge = ProtectedChallenge.toJSON(message.protectedChallenge);
|
|
525
|
-
}
|
|
526
|
-
if (message.signature.length !== 0) {
|
|
527
|
-
obj.signature = base64FromBytes2(message.signature);
|
|
528
|
-
}
|
|
529
|
-
if (message.publicKey.length !== 0) {
|
|
530
|
-
obj.publicKey = base64FromBytes2(message.publicKey);
|
|
531
|
-
}
|
|
532
|
-
return obj;
|
|
533
|
-
},
|
|
534
|
-
create(base) {
|
|
535
|
-
return VerifyChallengeRequest.fromPartial(base ?? {});
|
|
536
|
-
},
|
|
537
|
-
fromPartial(object) {
|
|
538
|
-
const message = createBaseVerifyChallengeRequest();
|
|
539
|
-
message.protectedChallenge = object.protectedChallenge !== void 0 && object.protectedChallenge !== null ? ProtectedChallenge.fromPartial(object.protectedChallenge) : void 0;
|
|
540
|
-
message.signature = object.signature ?? new Uint8Array(0);
|
|
541
|
-
message.publicKey = object.publicKey ?? new Uint8Array(0);
|
|
542
|
-
return message;
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
function createBaseVerifyChallengeResponse() {
|
|
546
|
-
return { sessionToken: "", expirationTimestamp: 0 };
|
|
547
|
-
}
|
|
548
|
-
var VerifyChallengeResponse = {
|
|
549
|
-
encode(message, writer = new BinaryWriter()) {
|
|
550
|
-
if (message.sessionToken !== "") {
|
|
551
|
-
writer.uint32(10).string(message.sessionToken);
|
|
552
|
-
}
|
|
553
|
-
if (message.expirationTimestamp !== 0) {
|
|
554
|
-
writer.uint32(16).int64(message.expirationTimestamp);
|
|
555
|
-
}
|
|
556
|
-
return writer;
|
|
557
|
-
},
|
|
558
|
-
decode(input, length) {
|
|
559
|
-
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
560
|
-
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
561
|
-
const message = createBaseVerifyChallengeResponse();
|
|
562
|
-
while (reader.pos < end) {
|
|
563
|
-
const tag = reader.uint32();
|
|
564
|
-
switch (tag >>> 3) {
|
|
565
|
-
case 1: {
|
|
566
|
-
if (tag !== 10) {
|
|
567
|
-
break;
|
|
568
|
-
}
|
|
569
|
-
message.sessionToken = reader.string();
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
572
|
-
case 2: {
|
|
573
|
-
if (tag !== 16) {
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
message.expirationTimestamp = longToNumber(reader.int64());
|
|
577
|
-
continue;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
if ((tag & 7) === 4 || tag === 0) {
|
|
581
|
-
break;
|
|
582
|
-
}
|
|
583
|
-
reader.skip(tag & 7);
|
|
584
|
-
}
|
|
585
|
-
return message;
|
|
586
|
-
},
|
|
587
|
-
fromJSON(object) {
|
|
588
|
-
return {
|
|
589
|
-
sessionToken: isSet2(object.sessionToken) ? globalThis.String(object.sessionToken) : "",
|
|
590
|
-
expirationTimestamp: isSet2(object.expirationTimestamp) ? globalThis.Number(object.expirationTimestamp) : 0
|
|
591
|
-
};
|
|
592
|
-
},
|
|
593
|
-
toJSON(message) {
|
|
594
|
-
const obj = {};
|
|
595
|
-
if (message.sessionToken !== "") {
|
|
596
|
-
obj.sessionToken = message.sessionToken;
|
|
597
|
-
}
|
|
598
|
-
if (message.expirationTimestamp !== 0) {
|
|
599
|
-
obj.expirationTimestamp = Math.round(message.expirationTimestamp);
|
|
600
|
-
}
|
|
601
|
-
return obj;
|
|
602
|
-
},
|
|
603
|
-
create(base) {
|
|
604
|
-
return VerifyChallengeResponse.fromPartial(base ?? {});
|
|
605
|
-
},
|
|
606
|
-
fromPartial(object) {
|
|
607
|
-
const message = createBaseVerifyChallengeResponse();
|
|
608
|
-
message.sessionToken = object.sessionToken ?? "";
|
|
609
|
-
message.expirationTimestamp = object.expirationTimestamp ?? 0;
|
|
610
|
-
return message;
|
|
611
|
-
}
|
|
612
|
-
};
|
|
613
|
-
var SparkAuthnServiceDefinition = {
|
|
614
|
-
name: "SparkAuthnService",
|
|
615
|
-
fullName: "spark_authn.SparkAuthnService",
|
|
616
|
-
methods: {
|
|
617
|
-
/** Request a new authentication challenge for a public key */
|
|
618
|
-
get_challenge: {
|
|
619
|
-
name: "get_challenge",
|
|
620
|
-
requestType: GetChallengeRequest,
|
|
621
|
-
requestStream: false,
|
|
622
|
-
responseType: GetChallengeResponse,
|
|
623
|
-
responseStream: false,
|
|
624
|
-
options: {}
|
|
625
|
-
},
|
|
626
|
-
/** Verify a signed challenge and return a session token */
|
|
627
|
-
verify_challenge: {
|
|
628
|
-
name: "verify_challenge",
|
|
629
|
-
requestType: VerifyChallengeRequest,
|
|
630
|
-
requestStream: false,
|
|
631
|
-
responseType: VerifyChallengeResponse,
|
|
632
|
-
responseStream: false,
|
|
633
|
-
options: {}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
};
|
|
637
|
-
function bytesFromBase642(b64) {
|
|
638
|
-
if (globalThis.Buffer) {
|
|
639
|
-
return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
640
|
-
} else {
|
|
641
|
-
const bin = globalThis.atob(b64);
|
|
642
|
-
const arr = new Uint8Array(bin.length);
|
|
643
|
-
for (let i = 0; i < bin.length; ++i) {
|
|
644
|
-
arr[i] = bin.charCodeAt(i);
|
|
645
|
-
}
|
|
646
|
-
return arr;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
function base64FromBytes2(arr) {
|
|
650
|
-
if (globalThis.Buffer) {
|
|
651
|
-
return globalThis.Buffer.from(arr).toString("base64");
|
|
652
|
-
} else {
|
|
653
|
-
const bin = [];
|
|
654
|
-
arr.forEach((byte) => {
|
|
655
|
-
bin.push(globalThis.String.fromCharCode(byte));
|
|
656
|
-
});
|
|
657
|
-
return globalThis.btoa(bin.join(""));
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
function longToNumber(int64) {
|
|
661
|
-
const num = globalThis.Number(int64.toString());
|
|
662
|
-
if (num > globalThis.Number.MAX_SAFE_INTEGER) {
|
|
663
|
-
throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
|
|
664
|
-
}
|
|
665
|
-
if (num < globalThis.Number.MIN_SAFE_INTEGER) {
|
|
666
|
-
throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
|
|
667
|
-
}
|
|
668
|
-
return num;
|
|
669
|
-
}
|
|
670
|
-
function isSet2(value) {
|
|
671
|
-
return value !== null && value !== void 0;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
// src/services/connection.ts
|
|
675
|
-
var ConnectionManager = class _ConnectionManager {
|
|
676
|
-
config;
|
|
677
|
-
clients = /* @__PURE__ */ new Map();
|
|
678
|
-
constructor(config) {
|
|
679
|
-
this.config = config;
|
|
680
|
-
}
|
|
681
|
-
// When initializing wallet, go ahead and instantiate all clients
|
|
682
|
-
async createClients() {
|
|
683
|
-
await Promise.all(
|
|
684
|
-
Object.values(this.config.getConfig().signingOperators).map(
|
|
685
|
-
(operator) => {
|
|
686
|
-
this.createSparkClient(operator.address);
|
|
687
|
-
}
|
|
688
|
-
)
|
|
689
|
-
);
|
|
690
|
-
}
|
|
691
|
-
static createMockClient(address) {
|
|
692
|
-
const channel = this.createChannelWithTLS(address);
|
|
693
|
-
const client = createClient(MockServiceDefinition, channel);
|
|
694
|
-
return { ...client, close: () => channel.close() };
|
|
695
|
-
}
|
|
696
|
-
// TODO: Web transport handles TLS differently, verify that we don't need to do anything
|
|
697
|
-
static createChannelWithTLS(address, certPath) {
|
|
698
|
-
try {
|
|
699
|
-
if (certPath && typeof window === "undefined") {
|
|
700
|
-
const cert = fs.readFileSync(certPath);
|
|
701
|
-
return createChannel(address, ChannelCredentials.createSsl(cert));
|
|
702
|
-
} else {
|
|
703
|
-
return createChannel(
|
|
704
|
-
address,
|
|
705
|
-
typeof window === "undefined" ? ChannelCredentials.createSsl(null, null, null, {
|
|
706
|
-
rejectUnauthorized: false
|
|
707
|
-
}) : void 0
|
|
708
|
-
);
|
|
709
|
-
}
|
|
710
|
-
} catch (error) {
|
|
711
|
-
console.error("Channel creation error:", error);
|
|
712
|
-
throw new Error("Failed to create channel");
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
async createSparkClient(address, certPath) {
|
|
716
|
-
if (this.clients.has(address)) {
|
|
717
|
-
return this.clients.get(address).client;
|
|
718
|
-
}
|
|
719
|
-
const authToken = await this.authenticate(address);
|
|
720
|
-
const channel = _ConnectionManager.createChannelWithTLS(address, certPath);
|
|
721
|
-
const authMiddleware = this.createAuthMiddleWare(address, authToken);
|
|
722
|
-
const client = this.createGrpcClient(
|
|
723
|
-
SparkServiceDefinition,
|
|
724
|
-
channel,
|
|
725
|
-
authMiddleware
|
|
726
|
-
);
|
|
727
|
-
this.clients.set(address, { client, authToken });
|
|
728
|
-
return client;
|
|
729
|
-
}
|
|
730
|
-
async authenticate(address) {
|
|
731
|
-
try {
|
|
732
|
-
const identityPublicKey = await this.config.signer.getIdentityPublicKey();
|
|
733
|
-
const sparkAuthnClient = this.createSparkAuthnGrpcConnection(address);
|
|
734
|
-
const challengeResp = await sparkAuthnClient.get_challenge({
|
|
735
|
-
publicKey: identityPublicKey
|
|
736
|
-
});
|
|
737
|
-
if (!challengeResp.protectedChallenge?.challenge) {
|
|
738
|
-
throw new Error("Invalid challenge response");
|
|
739
|
-
}
|
|
740
|
-
const challengeBytes = Challenge.encode(
|
|
741
|
-
challengeResp.protectedChallenge.challenge
|
|
742
|
-
).finish();
|
|
743
|
-
const hash = sha256(challengeBytes);
|
|
744
|
-
const derSignatureBytes = await this.config.signer.signMessageWithIdentityKey(hash);
|
|
745
|
-
const verifyResp = await sparkAuthnClient.verify_challenge({
|
|
746
|
-
protectedChallenge: challengeResp.protectedChallenge,
|
|
747
|
-
signature: derSignatureBytes,
|
|
748
|
-
publicKey: identityPublicKey
|
|
749
|
-
});
|
|
750
|
-
sparkAuthnClient.close?.();
|
|
751
|
-
return verifyResp.sessionToken;
|
|
752
|
-
} catch (error) {
|
|
753
|
-
console.error("Authentication error:", error);
|
|
754
|
-
throw new Error(`Authentication failed: ${error.message}`);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
createSparkAuthnGrpcConnection(address, certPath) {
|
|
758
|
-
const channel = _ConnectionManager.createChannelWithTLS(address, certPath);
|
|
759
|
-
return this.createGrpcClient(
|
|
760
|
-
SparkAuthnServiceDefinition,
|
|
761
|
-
channel
|
|
762
|
-
);
|
|
763
|
-
}
|
|
764
|
-
createAuthMiddleWare(address, authToken) {
|
|
765
|
-
if (typeof window === "undefined") {
|
|
766
|
-
return this.createNodeMiddleware(address, authToken);
|
|
767
|
-
} else {
|
|
768
|
-
return this.createBrowserMiddleware(address, authToken);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
createNodeMiddleware(address, initialAuthToken) {
|
|
772
|
-
return async function* (call, options) {
|
|
773
|
-
try {
|
|
774
|
-
yield* call.next(call.request, {
|
|
775
|
-
...options,
|
|
776
|
-
metadata: Metadata(options.metadata).set(
|
|
777
|
-
"Authorization",
|
|
778
|
-
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`
|
|
779
|
-
)
|
|
780
|
-
});
|
|
781
|
-
} catch (error) {
|
|
782
|
-
if (error.message?.includes("token has expired")) {
|
|
783
|
-
const newAuthToken = await this.authenticate(address);
|
|
784
|
-
this.clients.get(address).authToken = newAuthToken;
|
|
785
|
-
yield* call.next(call.request, {
|
|
786
|
-
...options,
|
|
787
|
-
metadata: Metadata(options.metadata).set(
|
|
788
|
-
"Authorization",
|
|
789
|
-
`Bearer ${newAuthToken}`
|
|
790
|
-
)
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
throw error;
|
|
794
|
-
}
|
|
795
|
-
}.bind(this);
|
|
796
|
-
}
|
|
797
|
-
createBrowserMiddleware(address, initialAuthToken) {
|
|
798
|
-
return async function* (call, options) {
|
|
799
|
-
try {
|
|
800
|
-
yield* call.next(call.request, {
|
|
801
|
-
...options,
|
|
802
|
-
metadata: Metadata(options.metadata).set(
|
|
803
|
-
"Authorization",
|
|
804
|
-
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`
|
|
805
|
-
).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto")
|
|
806
|
-
});
|
|
807
|
-
} catch (error) {
|
|
808
|
-
if (error.message?.includes("token has expired")) {
|
|
809
|
-
const newAuthToken = await this.authenticate(address);
|
|
810
|
-
this.clients.get(address).authToken = newAuthToken;
|
|
811
|
-
yield* call.next(call.request, {
|
|
812
|
-
...options,
|
|
813
|
-
metadata: Metadata(options.metadata).set("Authorization", `Bearer ${newAuthToken}`).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto")
|
|
814
|
-
});
|
|
815
|
-
}
|
|
816
|
-
throw error;
|
|
817
|
-
}
|
|
818
|
-
}.bind(this);
|
|
819
|
-
}
|
|
820
|
-
createGrpcClient(defintion, channel, middleware) {
|
|
821
|
-
const clientFactory = createClientFactory().use(retryMiddleware);
|
|
822
|
-
if (middleware) {
|
|
823
|
-
clientFactory.use(middleware);
|
|
824
|
-
}
|
|
825
|
-
const client = clientFactory.create(defintion, channel, {
|
|
826
|
-
"*": {
|
|
827
|
-
retry: true,
|
|
828
|
-
retryMaxAttempts: 3
|
|
829
|
-
}
|
|
830
|
-
});
|
|
831
|
-
return {
|
|
832
|
-
...client,
|
|
833
|
-
close: channel.close?.bind(channel)
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
};
|
|
837
|
-
|
|
838
|
-
// src/services/deposit.ts
|
|
839
|
-
import { schnorr, secp256k1 } from "@noble/curves/secp256k1";
|
|
840
|
-
import * as btc from "@scure/btc-signer";
|
|
841
|
-
import { p2tr, Transaction } from "@scure/btc-signer";
|
|
842
|
-
import { equalBytes, sha256 as sha2562 } from "@scure/btc-signer/utils";
|
|
843
|
-
var INITIAL_TIME_LOCK = 6e4;
|
|
844
|
-
var DepositService = class {
|
|
845
|
-
config;
|
|
846
|
-
connectionManager;
|
|
847
|
-
constructor(config, connectionManager) {
|
|
848
|
-
this.config = config;
|
|
849
|
-
this.connectionManager = connectionManager;
|
|
850
|
-
}
|
|
851
|
-
async validateDepositAddress({
|
|
852
|
-
address,
|
|
853
|
-
userPubkey
|
|
854
|
-
}) {
|
|
855
|
-
if (!address.depositAddressProof || !address.depositAddressProof.proofOfPossessionSignature || !address.depositAddressProof.addressSignatures) {
|
|
856
|
-
throw new Error(
|
|
857
|
-
"proof of possession signature or address signatures is null"
|
|
858
|
-
);
|
|
859
|
-
}
|
|
860
|
-
const operatorPubkey = subtractPublicKeys(address.verifyingKey, userPubkey);
|
|
861
|
-
const msg = proofOfPossessionMessageHashForDepositAddress(
|
|
862
|
-
await this.config.signer.getIdentityPublicKey(),
|
|
863
|
-
operatorPubkey,
|
|
864
|
-
address.address
|
|
865
|
-
);
|
|
866
|
-
const taprootKey = p2tr(
|
|
867
|
-
operatorPubkey.slice(1, 33),
|
|
868
|
-
void 0,
|
|
869
|
-
getNetwork(this.config.getNetwork())
|
|
870
|
-
).tweakedPubkey;
|
|
871
|
-
const isVerified = schnorr.verify(
|
|
872
|
-
address.depositAddressProof.proofOfPossessionSignature,
|
|
873
|
-
msg,
|
|
874
|
-
taprootKey
|
|
875
|
-
);
|
|
876
|
-
if (!isVerified) {
|
|
877
|
-
throw new Error("proof of possession signature verification failed");
|
|
878
|
-
}
|
|
879
|
-
const addrHash = sha2562(address.address);
|
|
880
|
-
for (const operator of Object.values(
|
|
881
|
-
this.config.getConfig().signingOperators
|
|
882
|
-
)) {
|
|
883
|
-
if (operator.identifier === this.config.getConfig().coodinatorIdentifier) {
|
|
884
|
-
continue;
|
|
885
|
-
}
|
|
886
|
-
const operatorPubkey2 = operator.identityPublicKey;
|
|
887
|
-
const operatorSig = address.depositAddressProof.addressSignatures[operator.identifier];
|
|
888
|
-
if (!operatorSig) {
|
|
889
|
-
throw new Error("operator signature not found");
|
|
890
|
-
}
|
|
891
|
-
const sig = secp256k1.Signature.fromDER(operatorSig);
|
|
892
|
-
const isVerified2 = secp256k1.verify(sig, addrHash, operatorPubkey2);
|
|
893
|
-
if (!isVerified2) {
|
|
894
|
-
throw new Error("signature verification failed");
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
async generateDepositAddress({
|
|
899
|
-
signingPubkey
|
|
900
|
-
}) {
|
|
901
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
902
|
-
this.config.getCoordinatorAddress()
|
|
903
|
-
);
|
|
904
|
-
let depositResp;
|
|
905
|
-
try {
|
|
906
|
-
depositResp = await sparkClient.generate_deposit_address({
|
|
907
|
-
signingPublicKey: signingPubkey,
|
|
908
|
-
identityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
909
|
-
network: this.config.getNetworkProto()
|
|
910
|
-
});
|
|
911
|
-
} catch (error) {
|
|
912
|
-
throw new Error(`Error generating deposit address: ${error}`);
|
|
913
|
-
}
|
|
914
|
-
if (!depositResp.depositAddress) {
|
|
915
|
-
throw new Error("No deposit address response from coordinator");
|
|
916
|
-
}
|
|
917
|
-
await this.validateDepositAddress({
|
|
918
|
-
address: depositResp.depositAddress,
|
|
919
|
-
userPubkey: signingPubkey
|
|
920
|
-
});
|
|
921
|
-
return depositResp;
|
|
922
|
-
}
|
|
923
|
-
async createTreeRoot({
|
|
924
|
-
signingPubKey,
|
|
925
|
-
verifyingKey,
|
|
926
|
-
depositTx,
|
|
927
|
-
vout
|
|
928
|
-
}) {
|
|
929
|
-
const rootTx = new Transaction();
|
|
930
|
-
const output = depositTx.getOutput(vout);
|
|
931
|
-
if (!output) {
|
|
932
|
-
throw new Error("No output found in deposit tx");
|
|
933
|
-
}
|
|
934
|
-
const script = output.script;
|
|
935
|
-
const amount = output.amount;
|
|
936
|
-
if (!script || !amount) {
|
|
937
|
-
throw new Error("No script or amount found in deposit tx");
|
|
938
|
-
}
|
|
939
|
-
rootTx.addInput({
|
|
940
|
-
txid: getTxId(depositTx),
|
|
941
|
-
index: vout
|
|
942
|
-
});
|
|
943
|
-
rootTx.addOutput({
|
|
944
|
-
script,
|
|
945
|
-
amount
|
|
946
|
-
});
|
|
947
|
-
const rootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
948
|
-
const rootTxSighash = getSigHashFromTx(rootTx, 0, output);
|
|
949
|
-
const refundTx = new Transaction();
|
|
950
|
-
const sequence = 1 << 30 | INITIAL_TIME_LOCK;
|
|
951
|
-
refundTx.addInput({
|
|
952
|
-
txid: getTxId(rootTx),
|
|
953
|
-
index: 0,
|
|
954
|
-
sequence
|
|
955
|
-
});
|
|
956
|
-
const refundP2trAddress = getP2TRAddressFromPublicKey(
|
|
957
|
-
signingPubKey,
|
|
958
|
-
this.config.getNetwork()
|
|
959
|
-
);
|
|
960
|
-
const refundAddress = btc.Address(getNetwork(this.config.getNetwork())).decode(refundP2trAddress);
|
|
961
|
-
const refundPkScript = btc.OutScript.encode(refundAddress);
|
|
962
|
-
refundTx.addOutput({
|
|
963
|
-
script: refundPkScript,
|
|
964
|
-
amount
|
|
965
|
-
});
|
|
966
|
-
const refundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
967
|
-
const refundTxSighash = getSigHashFromTx(refundTx, 0, output);
|
|
968
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
969
|
-
this.config.getCoordinatorAddress()
|
|
970
|
-
);
|
|
971
|
-
let treeResp;
|
|
972
|
-
try {
|
|
973
|
-
treeResp = await sparkClient.start_tree_creation({
|
|
974
|
-
identityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
975
|
-
onChainUtxo: {
|
|
976
|
-
vout,
|
|
977
|
-
rawTx: depositTx.toBytes(),
|
|
978
|
-
network: this.config.getNetworkProto()
|
|
979
|
-
},
|
|
980
|
-
rootTxSigningJob: {
|
|
981
|
-
rawTx: rootTx.toBytes(),
|
|
982
|
-
signingPublicKey: signingPubKey,
|
|
983
|
-
signingNonceCommitment: rootNonceCommitment
|
|
984
|
-
},
|
|
985
|
-
refundTxSigningJob: {
|
|
986
|
-
rawTx: refundTx.toBytes(),
|
|
987
|
-
signingPublicKey: signingPubKey,
|
|
988
|
-
signingNonceCommitment: refundNonceCommitment
|
|
989
|
-
}
|
|
990
|
-
});
|
|
991
|
-
} catch (error) {
|
|
992
|
-
throw new Error(`Error starting tree creation: ${error}`);
|
|
993
|
-
}
|
|
994
|
-
if (!treeResp.rootNodeSignatureShares?.verifyingKey) {
|
|
995
|
-
throw new Error("No verifying key found in tree response");
|
|
996
|
-
}
|
|
997
|
-
if (!treeResp.rootNodeSignatureShares.nodeTxSigningResult?.signingNonceCommitments) {
|
|
998
|
-
throw new Error("No signing nonce commitments found in tree response");
|
|
999
|
-
}
|
|
1000
|
-
if (!treeResp.rootNodeSignatureShares.refundTxSigningResult?.signingNonceCommitments) {
|
|
1001
|
-
throw new Error("No signing nonce commitments found in tree response");
|
|
1002
|
-
}
|
|
1003
|
-
if (!equalBytes(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
1004
|
-
throw new Error("Verifying key does not match");
|
|
1005
|
-
}
|
|
1006
|
-
const rootSignature = await this.config.signer.signFrost({
|
|
1007
|
-
message: rootTxSighash,
|
|
1008
|
-
publicKey: signingPubKey,
|
|
1009
|
-
privateAsPubKey: signingPubKey,
|
|
1010
|
-
verifyingKey,
|
|
1011
|
-
selfCommitment: rootNonceCommitment,
|
|
1012
|
-
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
1013
|
-
adaptorPubKey: new Uint8Array()
|
|
1014
|
-
});
|
|
1015
|
-
const refundSignature = await this.config.signer.signFrost({
|
|
1016
|
-
message: refundTxSighash,
|
|
1017
|
-
publicKey: signingPubKey,
|
|
1018
|
-
privateAsPubKey: signingPubKey,
|
|
1019
|
-
verifyingKey,
|
|
1020
|
-
selfCommitment: refundNonceCommitment,
|
|
1021
|
-
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
1022
|
-
adaptorPubKey: new Uint8Array()
|
|
1023
|
-
});
|
|
1024
|
-
const rootAggregate = await this.config.signer.aggregateFrost({
|
|
1025
|
-
message: rootTxSighash,
|
|
1026
|
-
statechainSignatures: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signatureShares,
|
|
1027
|
-
statechainPublicKeys: treeResp.rootNodeSignatureShares.nodeTxSigningResult.publicKeys,
|
|
1028
|
-
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
1029
|
-
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
1030
|
-
selfCommitment: createWasmSigningCommitment(rootNonceCommitment),
|
|
1031
|
-
publicKey: signingPubKey,
|
|
1032
|
-
selfSignature: rootSignature,
|
|
1033
|
-
adaptorPubKey: new Uint8Array()
|
|
1034
|
-
});
|
|
1035
|
-
const refundAggregate = await this.config.signer.aggregateFrost({
|
|
1036
|
-
message: refundTxSighash,
|
|
1037
|
-
statechainSignatures: treeResp.rootNodeSignatureShares.refundTxSigningResult.signatureShares,
|
|
1038
|
-
statechainPublicKeys: treeResp.rootNodeSignatureShares.refundTxSigningResult.publicKeys,
|
|
1039
|
-
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
1040
|
-
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
1041
|
-
selfCommitment: createWasmSigningCommitment(refundNonceCommitment),
|
|
1042
|
-
publicKey: signingPubKey,
|
|
1043
|
-
selfSignature: refundSignature,
|
|
1044
|
-
adaptorPubKey: new Uint8Array()
|
|
1045
|
-
});
|
|
1046
|
-
let finalizeResp;
|
|
1047
|
-
try {
|
|
1048
|
-
finalizeResp = await sparkClient.finalize_node_signatures({
|
|
1049
|
-
intent: 0 /* CREATION */,
|
|
1050
|
-
nodeSignatures: [
|
|
1051
|
-
{
|
|
1052
|
-
nodeId: treeResp.rootNodeSignatureShares.nodeId,
|
|
1053
|
-
nodeTxSignature: rootAggregate,
|
|
1054
|
-
refundTxSignature: refundAggregate
|
|
1055
|
-
}
|
|
1056
|
-
]
|
|
1057
|
-
});
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
throw new Error(`Error finalizing node signatures in deposit: ${error}`);
|
|
1060
|
-
}
|
|
1061
|
-
return finalizeResp;
|
|
1062
|
-
}
|
|
1063
|
-
};
|
|
1064
|
-
|
|
1065
|
-
// src/tests/test-util.ts
|
|
1066
|
-
var LOCAL_WALLET_CONFIG = {
|
|
1067
|
-
network: 3 /* REGTEST */,
|
|
1068
|
-
coodinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1069
|
-
frostSignerAddress: "unix:///tmp/frost_0.sock",
|
|
1070
|
-
threshold: 3,
|
|
1071
|
-
signingOperators: getLocalSigningOperators(),
|
|
1072
|
-
useTokenTransactionSchnorrSignatures: true
|
|
1073
|
-
};
|
|
1074
|
-
var LOCAL_WALLET_CONFIG_SCHNORR = {
|
|
1075
|
-
network: 3 /* REGTEST */,
|
|
1076
|
-
coodinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1077
|
-
frostSignerAddress: "unix:///tmp/frost_0.sock",
|
|
1078
|
-
threshold: 3,
|
|
1079
|
-
signingOperators: getLocalSigningOperators(),
|
|
1080
|
-
useTokenTransactionSchnorrSignatures: true
|
|
1081
|
-
};
|
|
1082
|
-
var LOCAL_WALLET_CONFIG_ECDSA = {
|
|
1083
|
-
network: 3 /* REGTEST */,
|
|
1084
|
-
coodinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1085
|
-
frostSignerAddress: "unix:///tmp/frost_0.sock",
|
|
1086
|
-
threshold: 3,
|
|
1087
|
-
signingOperators: getLocalSigningOperators(),
|
|
1088
|
-
useTokenTransactionSchnorrSignatures: false
|
|
1089
|
-
};
|
|
1090
|
-
var REGTEST_WALLET_CONFIG = {
|
|
1091
|
-
network: 3 /* REGTEST */,
|
|
1092
|
-
coodinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1093
|
-
frostSignerAddress: "unix:///tmp/frost_0.sock",
|
|
1094
|
-
threshold: 3,
|
|
1095
|
-
signingOperators: getRegtestSigningOperators(),
|
|
1096
|
-
useTokenTransactionSchnorrSignatures: true
|
|
1097
|
-
};
|
|
1098
|
-
var MAINNET_WALLET_CONFIG = {
|
|
1099
|
-
network: 0 /* MAINNET */,
|
|
1100
|
-
coodinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1101
|
-
frostSignerAddress: "unix:///tmp/frost_0.sock",
|
|
1102
|
-
threshold: 3,
|
|
1103
|
-
signingOperators: getRegtestSigningOperators(),
|
|
1104
|
-
useTokenTransactionSchnorrSignatures: true
|
|
1105
|
-
};
|
|
1106
|
-
function getRegtestSigningOperators() {
|
|
1107
|
-
const pubkeys = [
|
|
1108
|
-
"03acd9a5a88db102730ff83dee69d69088cc4c9d93bbee893e90fd5051b7da9651",
|
|
1109
|
-
"02d2d103cacb1d6355efeab27637c74484e2a7459e49110c3fe885210369782e23",
|
|
1110
|
-
"0350f07ffc21bfd59d31e0a7a600e2995273938444447cb9bc4c75b8a895dbb853"
|
|
1111
|
-
];
|
|
1112
|
-
const pubkeyBytesArray = pubkeys.map((pubkey) => hexToBytes(pubkey));
|
|
1113
|
-
return {
|
|
1114
|
-
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
1115
|
-
id: 0,
|
|
1116
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1117
|
-
address: "https://0.spark.dev.dev.sparkinfra.net",
|
|
1118
|
-
identityPublicKey: pubkeyBytesArray[0]
|
|
1119
|
-
},
|
|
1120
|
-
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
1121
|
-
id: 1,
|
|
1122
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
1123
|
-
address: "https://1.spark.dev.dev.sparkinfra.net",
|
|
1124
|
-
identityPublicKey: pubkeyBytesArray[1]
|
|
1125
|
-
},
|
|
1126
|
-
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
1127
|
-
id: 2,
|
|
1128
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
1129
|
-
address: "https://2.spark.dev.dev.sparkinfra.net",
|
|
1130
|
-
identityPublicKey: pubkeyBytesArray[2]
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
|
-
function getLocalSigningOperators() {
|
|
1135
|
-
const pubkeys = [
|
|
1136
|
-
"0322ca18fc489ae25418a0e768273c2c61cabb823edfb14feb891e9bec62016510",
|
|
1137
|
-
"0341727a6c41b168f07eb50865ab8c397a53c7eef628ac1020956b705e43b6cb27",
|
|
1138
|
-
"0305ab8d485cc752394de4981f8a5ae004f2becfea6f432c9a59d5022d8764f0a6",
|
|
1139
|
-
"0352aef4d49439dedd798ac4aef1e7ebef95f569545b647a25338398c1247ffdea",
|
|
1140
|
-
"02c05c88cc8fc181b1ba30006df6a4b0597de6490e24514fbdd0266d2b9cd3d0ba"
|
|
1141
|
-
];
|
|
1142
|
-
const pubkeyBytesArray = pubkeys.map((pubkey) => hexToBytes(pubkey));
|
|
1143
|
-
return {
|
|
1144
|
-
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
1145
|
-
id: 0,
|
|
1146
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
1147
|
-
address: "https://localhost:8535",
|
|
1148
|
-
identityPublicKey: pubkeyBytesArray[0]
|
|
1149
|
-
},
|
|
1150
|
-
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
1151
|
-
id: 1,
|
|
1152
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
1153
|
-
address: "https://localhost:8536",
|
|
1154
|
-
identityPublicKey: pubkeyBytesArray[1]
|
|
1155
|
-
},
|
|
1156
|
-
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
1157
|
-
id: 2,
|
|
1158
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
1159
|
-
address: "https://localhost:8537",
|
|
1160
|
-
identityPublicKey: pubkeyBytesArray[2]
|
|
1161
|
-
},
|
|
1162
|
-
"0000000000000000000000000000000000000000000000000000000000000004": {
|
|
1163
|
-
id: 3,
|
|
1164
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000004",
|
|
1165
|
-
address: "https://localhost:8538",
|
|
1166
|
-
identityPublicKey: pubkeyBytesArray[3]
|
|
1167
|
-
},
|
|
1168
|
-
"0000000000000000000000000000000000000000000000000000000000000005": {
|
|
1169
|
-
id: 4,
|
|
1170
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000005",
|
|
1171
|
-
address: "https://localhost:8539",
|
|
1172
|
-
identityPublicKey: pubkeyBytesArray[4]
|
|
1173
|
-
}
|
|
1174
|
-
};
|
|
1175
|
-
}
|
|
1176
|
-
function getTestWalletConfig() {
|
|
1177
|
-
const identityPrivateKey = secp256k12.utils.randomPrivateKey();
|
|
1178
|
-
return getTestWalletConfigWithIdentityKey(identityPrivateKey);
|
|
1179
|
-
}
|
|
1180
|
-
function getTestWalletConfigWithIdentityKey(identityPrivateKey) {
|
|
1181
|
-
return {
|
|
1182
|
-
...LOCAL_WALLET_CONFIG,
|
|
1183
|
-
identityPrivateKey
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
|
-
async function createNewTree(wallet, pubKey, faucet, amountSats = 100000n) {
|
|
1187
|
-
const faucetCoin = await faucet.fund();
|
|
1188
|
-
const configService = new WalletConfigService(
|
|
1189
|
-
4 /* LOCAL */,
|
|
1190
|
-
wallet.getSigner()
|
|
1191
|
-
);
|
|
1192
|
-
const connectionManager = new ConnectionManager(configService);
|
|
1193
|
-
const depositService = new DepositService(configService, connectionManager);
|
|
1194
|
-
const depositResp = await depositService.generateDepositAddress({
|
|
1195
|
-
signingPubkey: pubKey
|
|
1196
|
-
});
|
|
1197
|
-
if (!depositResp.depositAddress) {
|
|
1198
|
-
throw new Error("deposit address not found");
|
|
1199
|
-
}
|
|
1200
|
-
const depositTx = new Transaction2();
|
|
1201
|
-
depositTx.addInput(faucetCoin.outpoint);
|
|
1202
|
-
const addr = Address2(getNetwork(4 /* LOCAL */)).decode(
|
|
1203
|
-
depositResp.depositAddress.address
|
|
1204
|
-
);
|
|
1205
|
-
const script = OutScript2.encode(addr);
|
|
1206
|
-
depositTx.addOutput({ script, amount: amountSats });
|
|
1207
|
-
const treeResp = await depositService.createTreeRoot({
|
|
1208
|
-
signingPubKey: pubKey,
|
|
1209
|
-
verifyingKey: depositResp.depositAddress.verifyingKey,
|
|
1210
|
-
depositTx,
|
|
1211
|
-
vout: 0
|
|
1212
|
-
});
|
|
1213
|
-
const signedDepositTx = await faucet.signFaucetCoin(
|
|
1214
|
-
depositTx,
|
|
1215
|
-
faucetCoin.txout,
|
|
1216
|
-
faucetCoin.key
|
|
1217
|
-
);
|
|
1218
|
-
await faucet.broadcastTx(signedDepositTx.hex);
|
|
1219
|
-
const randomKey = secp256k12.utils.randomPrivateKey();
|
|
1220
|
-
const randomPubKey = secp256k12.getPublicKey(randomKey);
|
|
1221
|
-
const randomAddress = getP2TRAddressFromPublicKey(
|
|
1222
|
-
randomPubKey,
|
|
1223
|
-
4 /* LOCAL */
|
|
1224
|
-
);
|
|
1225
|
-
await faucet.generateToAddress(1, randomAddress);
|
|
1226
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1227
|
-
return treeResp.nodes[0];
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
export {
|
|
1231
|
-
ConnectionManager,
|
|
1232
|
-
DepositService,
|
|
1233
|
-
LOCAL_WALLET_CONFIG,
|
|
1234
|
-
LOCAL_WALLET_CONFIG_SCHNORR,
|
|
1235
|
-
LOCAL_WALLET_CONFIG_ECDSA,
|
|
1236
|
-
REGTEST_WALLET_CONFIG,
|
|
1237
|
-
MAINNET_WALLET_CONFIG,
|
|
1238
|
-
getRegtestSigningOperators,
|
|
1239
|
-
getLocalSigningOperators,
|
|
1240
|
-
getTestWalletConfig,
|
|
1241
|
-
getTestWalletConfigWithIdentityKey,
|
|
1242
|
-
createNewTree,
|
|
1243
|
-
WalletConfigService
|
|
1244
|
-
};
|