@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.
@@ -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 sha2563 } from "@noble/hashes/sha2.js";
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(sha2563, sharedX, ephemeralPub, HKDF_INFO, 32);
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 hex3 } from "@scure/base";
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: hex3.encode(script.pkScript),
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 hex4 } from "@scure/base";
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 hex4.decode(value);
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 = () => hex4.encode(crypto.getRandomValues(new Uint8Array(32)));
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: hex4.encode(input.senderPubkey)
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: hex4.encode(input.offerAsset.serialize()) },
533
- ...input.wantAsset && { want_asset: hex4.encode(input.wantAsset.serialize()) }
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(hex4.decode(params.paymentHash)),
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 deriveSwapSecrets(wallet) ?? randomSwapSecrets();
754
- if (!secrets.derivable) {
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(hex4.decode(info.signerPubkey), "ark signer key");
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(hex4.decode(quote.solver_pubkey), "solver key"),
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
- hex4.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
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: hex4.encode(input.payoutPubkey),
672
+ payout_pubkey: hex3.encode(input.payoutPubkey),
839
673
  refund_address: input.refundAddress,
840
- client_refund_pubkey: hex4.encode(input.senderPubkey)
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: hex4.encode(input.payoutPubkey),
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: hex4.encode(input.refundPubkey),
701
+ refund_pubkey: hex3.encode(input.refundPubkey),
868
702
  payout_address: input.payoutAddress,
869
- payout_pubkey: hex4.encode(input.payoutPubkey)
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(hex4.decode(quote.solver_pubkey), "solver key"),
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(hex4.decode(htlcPubkey), "solver L1 htlc key"),
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
- if (params.preimage && params.preimage.length !== 32) {
920
- throw new Error(`preimage must be 32 bytes, got ${params.preimage.length}`);
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 was supplied by the caller and MUST be persisted with the signing descriptor before funding"
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 preimage = await preimageForRfqSecrets(wallet, secrets);
934
- const paymentHash = paymentHashOf(preimage);
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(hex4.decode(info.signerPubkey), "ark signer key"),
781
+ serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
957
782
  emulatorPubkey: xOnly(
958
- hex4.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
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(hex4.decode(params.paymentHash)),
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(hex4.decode(quote.solver_pubkey), "solver key"),
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 deriveSwapSecrets(wallet) ?? randomSwapSecrets({ preimage: true });
1114
- if (!secrets.derivable) {
938
+ const secrets = await provisionClaimSecret(wallet);
939
+ if (secrets.mustPersistPreimage) {
1115
940
  console.warn(
1116
- "[swap] this swap's preimage and payout key are random and MUST be persisted before paying"
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 = await preimageForRfqSecrets(wallet, secrets);
1120
- const paymentHash = paymentHashOf(preimage);
1121
- const payoutPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
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(hex4.decode(info.signerPubkey), "ark signer key"),
973
+ serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
1149
974
  emulatorPubkey: xOnly(
1150
- hex4.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
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(hex4.decode(quote.solver_pubkey), "solver key"),
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(hex4.decode(claimPubkey), "solver L1 claim key"),
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 deriveSwapSecrets(wallet) ?? randomSwapSecrets({ preimage: true });
1232
- if (!secrets.derivable) {
1056
+ const secrets = await provisionClaimSecret(wallet);
1057
+ if (secrets.mustPersistPreimage) {
1233
1058
  console.warn(
1234
- "[swap] this swap's preimage and payout key are random and MUST be persisted before funding"
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 = await preimageForRfqSecrets(wallet, secrets);
1238
- const paymentHash = paymentHashOf(preimage);
1239
- const payoutPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
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(hex4.decode(info.signerPubkey), "ark signer key"),
1093
+ serverPubkey: xOnly(hex3.decode(info.signerPubkey), "ark signer key"),
1269
1094
  emulatorPubkey: xOnly(
1270
- hex4.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
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,