@arkade-os/swap 0.0.3 → 0.0.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/README.md +88 -47
- package/dist/{chunk-HLMMA3LJ.js → chunk-DLM6BVTB.js} +54 -243
- package/dist/index.cjs +127 -278
- package/dist/index.d.cts +201 -9
- package/dist/index.d.ts +201 -9
- package/dist/index.js +87 -65
- package/dist/nostr.cjs +10 -14
- package/dist/nostr.d.cts +1 -2
- package/dist/nostr.d.ts +1 -2
- package/dist/nostr.js +2 -2
- package/dist/{rfq-CCAFoFtR.d.cts → rfq-DjZlesr4.d.cts} +15 -323
- package/dist/{rfq-CCAFoFtR.d.ts → rfq-DjZlesr4.d.ts} +15 -323
- package/package.json +2 -2
|
@@ -204,176 +204,11 @@ async function classifyOnchainHtlc(chain, input) {
|
|
|
204
204
|
return { phase: "claimable", utxo: best };
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
// src/secrets.ts
|
|
208
|
-
import { hex as hex2 } from "@scure/base";
|
|
209
|
-
import { sha256 as sha2562 } from "@noble/hashes/sha2.js";
|
|
210
|
-
import { randomBytes } from "@noble/hashes/utils.js";
|
|
211
|
-
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
212
|
-
import {
|
|
213
|
-
SingleKey,
|
|
214
|
-
isHDAllocationCapable,
|
|
215
|
-
isHDWalletCapable
|
|
216
|
-
} from "@arkade-os/sdk";
|
|
217
|
-
var RFQ_PREIMAGE_TAG = "Arkade-RFQ-Preimage-v1";
|
|
218
|
-
function buildPreimageMessage(xonly, index) {
|
|
219
|
-
if (xonly.length !== 32) {
|
|
220
|
-
throw new Error(`x-only pubkey must be 32 bytes, got ${xonly.length}`);
|
|
221
|
-
}
|
|
222
|
-
if (!Number.isInteger(index) || index < 0 || index > 4294967295) {
|
|
223
|
-
throw new Error(`index must be a u32, got ${index}`);
|
|
224
|
-
}
|
|
225
|
-
const tag = new TextEncoder().encode(RFQ_PREIMAGE_TAG);
|
|
226
|
-
const message = new Uint8Array(tag.length + 32 + 4);
|
|
227
|
-
message.set(tag, 0);
|
|
228
|
-
message.set(xonly, tag.length);
|
|
229
|
-
new DataView(message.buffer).setUint32(tag.length + 32, index, true);
|
|
230
|
-
return message;
|
|
231
|
-
}
|
|
232
|
-
var PREIMAGE_INDEX = 0;
|
|
233
|
-
async function deriveSwapSecrets(wallet) {
|
|
234
|
-
if (!isHDAllocationCapable(wallet)) return void 0;
|
|
235
|
-
const signingDescriptor = await wallet.getNextSigningDescriptor();
|
|
236
|
-
if (!signingDescriptor) return void 0;
|
|
237
|
-
return { derivable: true, signingDescriptor };
|
|
238
|
-
}
|
|
239
|
-
function randomSwapSecrets(opts = {}) {
|
|
240
|
-
if (opts.preimage instanceof Uint8Array && opts.preimage.length !== 32) {
|
|
241
|
-
throw new Error(`preimage must be 32 bytes, got ${opts.preimage.length}`);
|
|
242
|
-
}
|
|
243
|
-
const preimage = opts.preimage instanceof Uint8Array ? opts.preimage : opts.preimage ? randomBytes(32) : void 0;
|
|
244
|
-
return {
|
|
245
|
-
derivable: false,
|
|
246
|
-
senderPrivateKey: schnorr.utils.randomSecretKey(),
|
|
247
|
-
...preimage ? { preimage } : {}
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
function rfqSecretsToRecord(secrets) {
|
|
251
|
-
if (secrets.derivable) {
|
|
252
|
-
return {
|
|
253
|
-
signingDescriptor: secrets.signingDescriptor,
|
|
254
|
-
...secrets.preimage ? { preimageHex: hex2.encode(secrets.preimage) } : {}
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
fallbackSecrets: {
|
|
259
|
-
version: 1,
|
|
260
|
-
type: "stored",
|
|
261
|
-
senderPrivateKeyHex: hex2.encode(secrets.senderPrivateKey),
|
|
262
|
-
...secrets.preimage ? { preimageHex: hex2.encode(secrets.preimage) } : {}
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
function rfqSecretsOfRecord(record) {
|
|
267
|
-
if (record.signingDescriptor) {
|
|
268
|
-
return {
|
|
269
|
-
derivable: true,
|
|
270
|
-
signingDescriptor: record.signingDescriptor,
|
|
271
|
-
...record.preimageHex ? { preimage: decodeHex32(record.preimageHex, "preimageHex") } : {}
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
const fallback = record.fallbackSecrets;
|
|
275
|
-
if (!fallback) return void 0;
|
|
276
|
-
if (fallback.version !== 1 || fallback.type !== "stored") {
|
|
277
|
-
throw new Error("unsupported RFQ fallback secrets record");
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
280
|
-
derivable: false,
|
|
281
|
-
senderPrivateKey: decodeHex32(fallback.senderPrivateKeyHex, "senderPrivateKeyHex"),
|
|
282
|
-
...fallback.preimageHex ? { preimage: decodeHex32(fallback.preimageHex, "preimageHex") } : {}
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
function decodeHex32(value, label) {
|
|
286
|
-
const bytes = hex2.decode(value);
|
|
287
|
-
if (bytes.length !== 32) {
|
|
288
|
-
throw new Error(label + " must be 32 bytes, got " + bytes.length);
|
|
289
|
-
}
|
|
290
|
-
return bytes;
|
|
291
|
-
}
|
|
292
|
-
async function adoptSwapDescriptor(wallet, signingDescriptor) {
|
|
293
|
-
if (!isHDAllocationCapable(wallet)) return;
|
|
294
|
-
await wallet.advanceSigningDescriptorWatermark(signingDescriptor);
|
|
295
|
-
}
|
|
296
|
-
var RefundNotLocallyPossibleError = class extends Error {
|
|
297
|
-
constructor(reason, message, options) {
|
|
298
|
-
super(message, options);
|
|
299
|
-
this.reason = reason;
|
|
300
|
-
}
|
|
301
|
-
reason;
|
|
302
|
-
name = "RefundNotLocallyPossibleError";
|
|
303
|
-
};
|
|
304
|
-
async function senderIdentityForRfqSecrets(wallet, secrets) {
|
|
305
|
-
if (!secrets.derivable) return SingleKey.fromPrivateKey(secrets.senderPrivateKey);
|
|
306
|
-
const signer = isHDWalletCapable(wallet) ? await wallet.signerForDescriptor(secrets.signingDescriptor) : void 0;
|
|
307
|
-
if (!signer || !isDeterministicSigner(signer)) {
|
|
308
|
-
throw new RefundNotLocallyPossibleError(
|
|
309
|
-
"foreign-descriptor",
|
|
310
|
-
`this wallet cannot derive ${secrets.signingDescriptor}; the swap was created on another wallet`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
return signer;
|
|
314
|
-
}
|
|
315
|
-
async function senderIdentityForSwapRecord(wallet, record) {
|
|
316
|
-
let secrets;
|
|
317
|
-
try {
|
|
318
|
-
secrets = rfqSecretsOfRecord(record);
|
|
319
|
-
} catch (error) {
|
|
320
|
-
throw new RefundNotLocallyPossibleError(
|
|
321
|
-
"unreadable-secrets",
|
|
322
|
-
error instanceof Error ? error.message : String(error),
|
|
323
|
-
// the record's own diagnosis, kept for a caller that wants more
|
|
324
|
-
// than the message
|
|
325
|
-
{ cause: error }
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
if (!secrets) {
|
|
329
|
-
throw new RefundNotLocallyPossibleError(
|
|
330
|
-
"no-secrets",
|
|
331
|
-
"this swap record carries no signing descriptor and no fallback secrets"
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
return senderIdentityForRfqSecrets(wallet, secrets);
|
|
335
|
-
}
|
|
336
|
-
async function senderPubkeyForRfqSecrets(wallet, secrets) {
|
|
337
|
-
if (!secrets.derivable) return schnorr.getPublicKey(secrets.senderPrivateKey);
|
|
338
|
-
return (await senderIdentityForRfqSecrets(wallet, secrets)).xOnlyPublicKey();
|
|
339
|
-
}
|
|
340
|
-
function isDeterministicSigner(value) {
|
|
341
|
-
if (typeof value !== "object" || value === null) return false;
|
|
342
|
-
const v = value;
|
|
343
|
-
return typeof v.signSchnorrDeterministic === "function" && typeof v.xOnlyPublicKey === "function";
|
|
344
|
-
}
|
|
345
|
-
async function derivePreimage(signer) {
|
|
346
|
-
const xonly = await signer.xOnlyPublicKey();
|
|
347
|
-
const message = buildPreimageMessage(xonly, PREIMAGE_INDEX);
|
|
348
|
-
return sha2562(await signer.signSchnorrDeterministic(sha2562(message)));
|
|
349
|
-
}
|
|
350
|
-
async function preimageForRfqSecrets(wallet, secrets) {
|
|
351
|
-
if (!secrets.derivable) {
|
|
352
|
-
if (!secrets.preimage) throw new Error("this swap carries no stored preimage");
|
|
353
|
-
return secrets.preimage;
|
|
354
|
-
}
|
|
355
|
-
if (secrets.preimage) return secrets.preimage;
|
|
356
|
-
const signer = await senderIdentityForRfqSecrets(wallet, secrets);
|
|
357
|
-
if (!isDeterministicSigner(signer)) {
|
|
358
|
-
throw new Error(
|
|
359
|
-
`wallet cannot sign deterministically for ${secrets.signingDescriptor}; its preimage is not derivable`
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
return await derivePreimage(signer);
|
|
364
|
-
} catch (cause) {
|
|
365
|
-
throw new Error(
|
|
366
|
-
`wallet cannot sign deterministically for ${secrets.signingDescriptor}; its preimage is not derivable`,
|
|
367
|
-
{ cause }
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
207
|
// src/claimPacket.ts
|
|
373
208
|
import { base64 } from "@scure/base";
|
|
374
209
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
375
210
|
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
376
|
-
import { sha256 as
|
|
211
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha2.js";
|
|
377
212
|
var HKDF_INFO = new TextEncoder().encode("covclaimd/preimage/v1");
|
|
378
213
|
async function sealClaimPacket(input) {
|
|
379
214
|
return sealWithEntropy(
|
|
@@ -389,7 +224,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
|
|
|
389
224
|
}
|
|
390
225
|
const ephemeralPub = secp256k1.getPublicKey(ephemeralKey, true);
|
|
391
226
|
const sharedX = secp256k1.getSharedSecret(ephemeralKey, input.covclaimdPubkey, true).subarray(1);
|
|
392
|
-
const key = hkdf(
|
|
227
|
+
const key = hkdf(sha2562, sharedX, ephemeralPub, HKDF_INFO, 32);
|
|
393
228
|
if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
|
|
394
229
|
const aesKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, [
|
|
395
230
|
"encrypt"
|
|
@@ -413,7 +248,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
|
|
|
413
248
|
}
|
|
414
249
|
|
|
415
250
|
// src/lockupContract.ts
|
|
416
|
-
import { hex as
|
|
251
|
+
import { hex as hex2 } from "@scure/base";
|
|
417
252
|
import { VHTLCV2ContractHandler } from "@arkade-os/sdk";
|
|
418
253
|
var SWAP_LOCKUP_CONTRACT_TYPE = "vhtlc-v2";
|
|
419
254
|
var SWAP_LOCKUP_CONTRACT_LABEL = "Arkade RFQ swap lockup";
|
|
@@ -437,7 +272,7 @@ async function registerLockupContract(contracts, script, address) {
|
|
|
437
272
|
await contracts.createContract({
|
|
438
273
|
type: SWAP_LOCKUP_CONTRACT_TYPE,
|
|
439
274
|
params: VHTLCV2ContractHandler.serializeParams(script.options),
|
|
440
|
-
script:
|
|
275
|
+
script: hex2.encode(script.pkScript),
|
|
441
276
|
address,
|
|
442
277
|
label: SWAP_LOCKUP_CONTRACT_LABEL,
|
|
443
278
|
metadata: { genericallySpendable: false, kind: SWAP_LOCKUP_CONTRACT_KIND }
|
|
@@ -448,7 +283,7 @@ async function registerLockupContract(contracts, script, address) {
|
|
|
448
283
|
}
|
|
449
284
|
|
|
450
285
|
// src/rfq.ts
|
|
451
|
-
import { hex as
|
|
286
|
+
import { hex as hex3 } from "@scure/base";
|
|
452
287
|
import { ripemd160 as ripemd1602 } from "@noble/hashes/legacy.js";
|
|
453
288
|
import {
|
|
454
289
|
ArkAddress,
|
|
@@ -457,6 +292,10 @@ import {
|
|
|
457
292
|
getNetwork,
|
|
458
293
|
resolveEmulatorPubkey
|
|
459
294
|
} from "@arkade-os/sdk";
|
|
295
|
+
import {
|
|
296
|
+
provisionClaimSecret,
|
|
297
|
+
provisionRefundKey
|
|
298
|
+
} from "@arkade-os/sdk";
|
|
460
299
|
var xOnly = (key, label) => {
|
|
461
300
|
if (key.length === 32) return key;
|
|
462
301
|
if (key.length !== 33 || key[0] !== 2 && key[0] !== 3) {
|
|
@@ -466,7 +305,7 @@ var xOnly = (key, label) => {
|
|
|
466
305
|
};
|
|
467
306
|
var solverHex = (value, field) => {
|
|
468
307
|
try {
|
|
469
|
-
return
|
|
308
|
+
return hex3.decode(value);
|
|
470
309
|
} catch {
|
|
471
310
|
throw new Error(`solver sent malformed hex for ${field}`);
|
|
472
311
|
}
|
|
@@ -501,7 +340,7 @@ var AddressMismatch = class extends Error {
|
|
|
501
340
|
this.quoted = quoted;
|
|
502
341
|
}
|
|
503
342
|
};
|
|
504
|
-
var newRfqId = () =>
|
|
343
|
+
var newRfqId = () => hex3.encode(crypto.getRandomValues(new Uint8Array(32)));
|
|
505
344
|
var lightningSendRequest = (input) => ({
|
|
506
345
|
v: 1,
|
|
507
346
|
type: "rfq_request",
|
|
@@ -511,7 +350,7 @@ var lightningSendRequest = (input) => ({
|
|
|
511
350
|
profile: {
|
|
512
351
|
invoice: input.invoice,
|
|
513
352
|
refund_address: input.refundAddress,
|
|
514
|
-
client_refund_pubkey:
|
|
353
|
+
client_refund_pubkey: hex3.encode(input.senderPubkey)
|
|
515
354
|
}
|
|
516
355
|
});
|
|
517
356
|
var arkadeSwapRequest = (input) => {
|
|
@@ -529,8 +368,8 @@ var arkadeSwapRequest = (input) => {
|
|
|
529
368
|
amount_side: input.amountSide,
|
|
530
369
|
amount: input.amount,
|
|
531
370
|
profile: {
|
|
532
|
-
...input.offerAsset && { offer_asset:
|
|
533
|
-
...input.wantAsset && { want_asset:
|
|
371
|
+
...input.offerAsset && { offer_asset: hex3.encode(input.offerAsset.serialize()) },
|
|
372
|
+
...input.wantAsset && { want_asset: hex3.encode(input.wantAsset.serialize()) }
|
|
534
373
|
}
|
|
535
374
|
};
|
|
536
375
|
};
|
|
@@ -731,7 +570,7 @@ function lightningSendVtxoScript(params) {
|
|
|
731
570
|
sender: params.senderPubkey,
|
|
732
571
|
receiver: params.solverPubkey,
|
|
733
572
|
server: params.serverPubkey,
|
|
734
|
-
preimageHash: ripemd1602(
|
|
573
|
+
preimageHash: ripemd1602(hex3.decode(params.paymentHash)),
|
|
735
574
|
refundLocktime: BigInt(params.refundLocktime),
|
|
736
575
|
unilateralClaimDelay: seconds(params.claimDelay),
|
|
737
576
|
unilateralRefundDelay: seconds(unilateralRefundDelay(params.claimDelay)),
|
|
@@ -750,13 +589,8 @@ function lightningSendVtxoScript(params) {
|
|
|
750
589
|
}
|
|
751
590
|
async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
752
591
|
const rfqId = params.rfqId ?? newRfqId();
|
|
753
|
-
const secrets = await
|
|
754
|
-
|
|
755
|
-
console.warn(
|
|
756
|
-
"[swap] wallet cannot allocate an HD descriptor: the sender key is random and MUST be persisted before funding"
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
const senderPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
|
|
592
|
+
const secrets = await provisionRefundKey(wallet);
|
|
593
|
+
const senderPubkey = secrets.pubkey;
|
|
760
594
|
const [info, refundAddress] = await Promise.all([
|
|
761
595
|
new RestArkProvider(arkServerUrl).getInfo(),
|
|
762
596
|
wallet.getAddress()
|
|
@@ -781,16 +615,16 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
781
615
|
`quote from_amount ${quote.from_amount} is below the invoice amount \u2014 a negative spread is not a quote`
|
|
782
616
|
);
|
|
783
617
|
}
|
|
784
|
-
const serverPubkey = xOnly(
|
|
618
|
+
const serverPubkey = xOnly(hex3.decode(info.signerPubkey), "ark signer key");
|
|
785
619
|
const network = getNetwork(info.network);
|
|
786
620
|
const script = lightningSendVtxoScript({
|
|
787
|
-
solverPubkey: xOnly(
|
|
621
|
+
solverPubkey: xOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
788
622
|
refundLocktime: quote.refund_locktime,
|
|
789
623
|
serverPubkey,
|
|
790
624
|
paymentHash: params.invoice.paymentHash,
|
|
791
625
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
792
626
|
emulatorPubkey: xOnly(
|
|
793
|
-
|
|
627
|
+
hex3.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
|
|
794
628
|
"emulator signer key"
|
|
795
629
|
),
|
|
796
630
|
senderPubkey,
|
|
@@ -835,9 +669,9 @@ var onchainSendRequest = (input) => ({
|
|
|
835
669
|
amount: input.amount,
|
|
836
670
|
profile: {
|
|
837
671
|
payment_hash: input.paymentHash,
|
|
838
|
-
payout_pubkey:
|
|
672
|
+
payout_pubkey: hex3.encode(input.payoutPubkey),
|
|
839
673
|
refund_address: input.refundAddress,
|
|
840
|
-
client_refund_pubkey:
|
|
674
|
+
client_refund_pubkey: hex3.encode(input.senderPubkey)
|
|
841
675
|
}
|
|
842
676
|
});
|
|
843
677
|
var lightningReceiveRequest = (input) => ({
|
|
@@ -850,7 +684,7 @@ var lightningReceiveRequest = (input) => ({
|
|
|
850
684
|
profile: {
|
|
851
685
|
payment_hash: input.paymentHash,
|
|
852
686
|
payout_address: input.payoutAddress,
|
|
853
|
-
payout_pubkey:
|
|
687
|
+
payout_pubkey: hex3.encode(input.payoutPubkey),
|
|
854
688
|
claim_packet: input.claimPacket
|
|
855
689
|
}
|
|
856
690
|
});
|
|
@@ -864,9 +698,9 @@ var onchainReceiveRequest = (input) => ({
|
|
|
864
698
|
profile: {
|
|
865
699
|
payment_hash: input.paymentHash,
|
|
866
700
|
claim_packet: input.claimPacket,
|
|
867
|
-
refund_pubkey:
|
|
701
|
+
refund_pubkey: hex3.encode(input.refundPubkey),
|
|
868
702
|
payout_address: input.payoutAddress,
|
|
869
|
-
payout_pubkey:
|
|
703
|
+
payout_pubkey: hex3.encode(input.payoutPubkey)
|
|
870
704
|
}
|
|
871
705
|
});
|
|
872
706
|
function deriveOnchainSend(input) {
|
|
@@ -882,7 +716,7 @@ function deriveOnchainSend(input) {
|
|
|
882
716
|
throw new Error("onchain-send quote is missing a binding field");
|
|
883
717
|
}
|
|
884
718
|
const script = lightningSendVtxoScript({
|
|
885
|
-
solverPubkey: xOnly(
|
|
719
|
+
solverPubkey: xOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
886
720
|
refundLocktime,
|
|
887
721
|
serverPubkey: input.serverPubkey,
|
|
888
722
|
paymentHash: input.paymentHash,
|
|
@@ -898,7 +732,7 @@ function deriveOnchainSend(input) {
|
|
|
898
732
|
{
|
|
899
733
|
paymentHash: input.paymentHash,
|
|
900
734
|
claimKey: input.payoutPubkey,
|
|
901
|
-
refundKey: xOnly(
|
|
735
|
+
refundKey: xOnly(hex3.decode(htlcPubkey), "solver L1 htlc key"),
|
|
902
736
|
refundLocktime: htlcLocktime
|
|
903
737
|
},
|
|
904
738
|
input.l1Network
|
|
@@ -916,23 +750,14 @@ function deriveOnchainSend(input) {
|
|
|
916
750
|
}
|
|
917
751
|
async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
918
752
|
const rfqId = params.rfqId ?? newRfqId();
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
}
|
|
922
|
-
const derivedSecrets = await deriveSwapSecrets(wallet);
|
|
923
|
-
const secrets = derivedSecrets ? params.preimage ? { ...derivedSecrets, preimage: params.preimage } : derivedSecrets : randomSwapSecrets({ preimage: params.preimage ?? true });
|
|
924
|
-
if (!secrets.derivable) {
|
|
925
|
-
console.warn(
|
|
926
|
-
params.preimage ? "[swap] this swap's sender key is random; the supplied preimage and sender key MUST be persisted before funding" : "[swap] this swap's preimage and sender key are random and MUST be persisted before funding"
|
|
927
|
-
);
|
|
928
|
-
} else if (params.preimage) {
|
|
753
|
+
const secrets = await provisionClaimSecret(wallet, { preimage: params.preimage });
|
|
754
|
+
if (secrets.mustPersistPreimage) {
|
|
929
755
|
console.warn(
|
|
930
|
-
"[swap] this swap's preimage
|
|
756
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
931
757
|
);
|
|
932
758
|
}
|
|
933
|
-
const
|
|
934
|
-
const
|
|
935
|
-
const senderPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
|
|
759
|
+
const paymentHash = hex3.encode(secrets.paymentHash);
|
|
760
|
+
const senderPubkey = secrets.pubkey;
|
|
936
761
|
const [info, refundAddress] = await Promise.all([
|
|
937
762
|
new RestArkProvider(arkServerUrl).getInfo(),
|
|
938
763
|
wallet.getAddress()
|
|
@@ -953,9 +778,9 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
|
953
778
|
quote,
|
|
954
779
|
paymentHash,
|
|
955
780
|
payoutPubkey: params.payoutPubkey,
|
|
956
|
-
serverPubkey: xOnly(
|
|
781
|
+
serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
|
|
957
782
|
emulatorPubkey: xOnly(
|
|
958
|
-
|
|
783
|
+
hex3.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
|
|
959
784
|
"emulator signer key"
|
|
960
785
|
),
|
|
961
786
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -1067,7 +892,7 @@ function receiveVtxoScript(params) {
|
|
|
1067
892
|
sender: params.solverPubkey,
|
|
1068
893
|
receiver: params.payoutPubkey,
|
|
1069
894
|
server: params.serverPubkey,
|
|
1070
|
-
preimageHash: ripemd1602(
|
|
895
|
+
preimageHash: ripemd1602(hex3.decode(params.paymentHash)),
|
|
1071
896
|
refundLocktime: BigInt(params.refundLocktime),
|
|
1072
897
|
unilateralClaimDelay: seconds(params.claimDelay),
|
|
1073
898
|
unilateralRefundDelay: seconds(unilateralRefundDelay(params.claimDelay)),
|
|
@@ -1094,7 +919,7 @@ function deriveLightningReceive(input) {
|
|
|
1094
919
|
throw new Error("lightning-receive quote is missing a binding field");
|
|
1095
920
|
}
|
|
1096
921
|
const script = receiveVtxoScript({
|
|
1097
|
-
solverPubkey: xOnly(
|
|
922
|
+
solverPubkey: xOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
1098
923
|
refundLocktime,
|
|
1099
924
|
serverPubkey: input.serverPubkey,
|
|
1100
925
|
paymentHash: input.paymentHash,
|
|
@@ -1110,15 +935,15 @@ function deriveLightningReceive(input) {
|
|
|
1110
935
|
}
|
|
1111
936
|
async function requestLightningReceive(wallet, arkServerUrl, transport, params) {
|
|
1112
937
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1113
|
-
const secrets = await
|
|
1114
|
-
if (
|
|
938
|
+
const secrets = await provisionClaimSecret(wallet);
|
|
939
|
+
if (secrets.mustPersistPreimage) {
|
|
1115
940
|
console.warn(
|
|
1116
|
-
"[swap] this swap's preimage
|
|
941
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before paying"
|
|
1117
942
|
);
|
|
1118
943
|
}
|
|
1119
|
-
const preimage =
|
|
1120
|
-
const paymentHash =
|
|
1121
|
-
const payoutPubkey =
|
|
944
|
+
const preimage = secrets.preimage;
|
|
945
|
+
const paymentHash = hex3.encode(secrets.paymentHash);
|
|
946
|
+
const payoutPubkey = secrets.pubkey;
|
|
1122
947
|
const [info, payoutAddress] = await Promise.all([
|
|
1123
948
|
new RestArkProvider(arkServerUrl).getInfo(),
|
|
1124
949
|
wallet.getAddress()
|
|
@@ -1145,9 +970,9 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
|
|
|
1145
970
|
paymentHash,
|
|
1146
971
|
payoutPubkey,
|
|
1147
972
|
payoutAddress,
|
|
1148
|
-
serverPubkey: xOnly(
|
|
973
|
+
serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
|
|
1149
974
|
emulatorPubkey: xOnly(
|
|
1150
|
-
|
|
975
|
+
hex3.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
|
|
1151
976
|
"emulator signer key"
|
|
1152
977
|
),
|
|
1153
978
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -1194,7 +1019,7 @@ function deriveOnchainReceive(input) {
|
|
|
1194
1019
|
throw new Error("onchain-receive quote is missing a binding field");
|
|
1195
1020
|
}
|
|
1196
1021
|
const script = receiveVtxoScript({
|
|
1197
|
-
solverPubkey: xOnly(
|
|
1022
|
+
solverPubkey: xOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
1198
1023
|
refundLocktime,
|
|
1199
1024
|
serverPubkey: input.serverPubkey,
|
|
1200
1025
|
paymentHash: input.paymentHash,
|
|
@@ -1209,7 +1034,7 @@ function deriveOnchainReceive(input) {
|
|
|
1209
1034
|
const htlc = onchainHtlcScript(
|
|
1210
1035
|
{
|
|
1211
1036
|
paymentHash: input.paymentHash,
|
|
1212
|
-
claimKey: xOnly(
|
|
1037
|
+
claimKey: xOnly(hex3.decode(claimPubkey), "solver L1 claim key"),
|
|
1213
1038
|
refundKey: input.refundPubkey,
|
|
1214
1039
|
refundLocktime: htlcLocktime
|
|
1215
1040
|
},
|
|
@@ -1228,15 +1053,15 @@ function deriveOnchainReceive(input) {
|
|
|
1228
1053
|
}
|
|
1229
1054
|
async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
1230
1055
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1231
|
-
const secrets = await
|
|
1232
|
-
if (
|
|
1056
|
+
const secrets = await provisionClaimSecret(wallet);
|
|
1057
|
+
if (secrets.mustPersistPreimage) {
|
|
1233
1058
|
console.warn(
|
|
1234
|
-
"[swap] this swap's preimage
|
|
1059
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
1235
1060
|
);
|
|
1236
1061
|
}
|
|
1237
|
-
const preimage =
|
|
1238
|
-
const paymentHash =
|
|
1239
|
-
const payoutPubkey =
|
|
1062
|
+
const preimage = secrets.preimage;
|
|
1063
|
+
const paymentHash = hex3.encode(secrets.paymentHash);
|
|
1064
|
+
const payoutPubkey = secrets.pubkey;
|
|
1240
1065
|
const [info, payoutAddress] = await Promise.all([
|
|
1241
1066
|
new RestArkProvider(arkServerUrl).getInfo(),
|
|
1242
1067
|
wallet.getAddress()
|
|
@@ -1265,9 +1090,9 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
1265
1090
|
payoutPubkey,
|
|
1266
1091
|
payoutAddress,
|
|
1267
1092
|
refundPubkey: params.refundPubkey,
|
|
1268
|
-
serverPubkey: xOnly(
|
|
1093
|
+
serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
|
|
1269
1094
|
emulatorPubkey: xOnly(
|
|
1270
|
-
|
|
1095
|
+
hex3.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
|
|
1271
1096
|
"emulator signer key"
|
|
1272
1097
|
),
|
|
1273
1098
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -1318,20 +1143,6 @@ export {
|
|
|
1318
1143
|
awaitOnchainFill,
|
|
1319
1144
|
claimOnchainFill,
|
|
1320
1145
|
classifyOnchainHtlc,
|
|
1321
|
-
RFQ_PREIMAGE_TAG,
|
|
1322
|
-
buildPreimageMessage,
|
|
1323
|
-
deriveSwapSecrets,
|
|
1324
|
-
randomSwapSecrets,
|
|
1325
|
-
rfqSecretsToRecord,
|
|
1326
|
-
rfqSecretsOfRecord,
|
|
1327
|
-
adoptSwapDescriptor,
|
|
1328
|
-
RefundNotLocallyPossibleError,
|
|
1329
|
-
senderIdentityForRfqSecrets,
|
|
1330
|
-
senderIdentityForSwapRecord,
|
|
1331
|
-
senderPubkeyForRfqSecrets,
|
|
1332
|
-
isDeterministicSigner,
|
|
1333
|
-
derivePreimage,
|
|
1334
|
-
preimageForRfqSecrets,
|
|
1335
1146
|
sealClaimPacket,
|
|
1336
1147
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
1337
1148
|
SWAP_LOCKUP_CONTRACT_LABEL,
|