@arkade-os/swap 0.0.6 → 0.0.7
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 +3 -1
- package/dist/{chunk-Q4FAYBXS.js → chunk-ZDTRQZE2.js} +49 -15
- package/dist/index.cjs +47 -14
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/nostr.cjs +15 -9
- package/dist/nostr.d.cts +1 -1
- package/dist/nostr.d.ts +1 -1
- package/dist/nostr.js +4 -11
- package/dist/{rfq-3jWha5xA.d.cts → rfq-DfT9dAss.d.cts} +20 -8
- package/dist/{rfq-3jWha5xA.d.ts → rfq-DfT9dAss.d.ts} +20 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -290,7 +290,9 @@ message anywhere: **acceptance is funding**.
|
|
|
290
290
|
offline. The solver observes the funding on-chain, pays the invoice, and claims with the
|
|
291
291
|
preimage — which lands publicly in the claim witness as the receipt. A failed swap refunds by
|
|
292
292
|
covenant to the trader's address, pushable by anyone, no trader keys or state.
|
|
293
|
-
- **Arkade ↔ arkade** (BTC↔asset, asset↔asset):
|
|
293
|
+
- **Arkade ↔ arkade** (BTC↔asset, asset↔asset): an arkade asset leg names the asset id itself —
|
|
294
|
+
`arkade:<68-hex>`, built with `arkadeAssetLeg` (the deprecated coarse `ARKADE_ASSET` is served by
|
|
295
|
+
no solver). The trader accepts a quote by creating and funding
|
|
294
296
|
an **offer** (layer 1) bound to the quoted terms before `valid_until`. The offer covenant only
|
|
295
297
|
releases the deposit to a fill that delivers the quoted amount, so the solver fills or nothing
|
|
296
298
|
moves; an unfilled offer is cancelled cooperatively. The quote wire shape ships here; the
|
|
@@ -311,9 +311,10 @@ var solverHex = (value, field) => {
|
|
|
311
311
|
}
|
|
312
312
|
};
|
|
313
313
|
var ARKADE_BTC = "arkade:BTC";
|
|
314
|
-
var ARKADE_ASSET = "arkade:ASSET";
|
|
315
314
|
var LIGHTNING_BTC = "lightning:BTC";
|
|
316
315
|
var ONCHAIN_BTC = "onchain:BTC";
|
|
316
|
+
var arkadeAssetLeg = (id) => `arkade:${id.toString()}`;
|
|
317
|
+
var ARKADE_ASSET = "arkade:ASSET";
|
|
317
318
|
var rfqPair = (from, to) => `${from}->${to}`;
|
|
318
319
|
var LIGHTNING_SEND_PAIR = rfqPair(ARKADE_BTC, LIGHTNING_BTC);
|
|
319
320
|
var LIGHTNING_RECEIVE_PAIR = rfqPair(LIGHTNING_BTC, ARKADE_BTC);
|
|
@@ -354,23 +355,34 @@ var lightningSendRequest = (input) => ({
|
|
|
354
355
|
}
|
|
355
356
|
});
|
|
356
357
|
var arkadeSwapRequest = (input) => {
|
|
357
|
-
if (
|
|
358
|
-
throw new Error(
|
|
358
|
+
if (!input.wantAsset && !input.offerAsset) {
|
|
359
|
+
throw new Error(
|
|
360
|
+
"set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC) \u2014 with neither set both legs are BTC, which is not a swap"
|
|
361
|
+
);
|
|
359
362
|
}
|
|
363
|
+
if (input.wantAsset && input.offerAsset) {
|
|
364
|
+
throw new Error(
|
|
365
|
+
"set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC) \u2014 asset->asset is nameable on the wire but no solver quotes it yet"
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
const pair = rfqPair(
|
|
369
|
+
input.offerAsset ? arkadeAssetLeg(input.offerAsset) : ARKADE_BTC,
|
|
370
|
+
input.wantAsset ? arkadeAssetLeg(input.wantAsset) : ARKADE_BTC
|
|
371
|
+
);
|
|
372
|
+
assertPairLength(pair);
|
|
360
373
|
return {
|
|
361
374
|
v: 1,
|
|
362
375
|
type: "rfq_request",
|
|
363
376
|
rfq_id: input.rfqId,
|
|
364
|
-
pair
|
|
365
|
-
input.offerAsset ? ARKADE_ASSET : ARKADE_BTC,
|
|
366
|
-
input.wantAsset ? ARKADE_ASSET : ARKADE_BTC
|
|
367
|
-
),
|
|
377
|
+
pair,
|
|
368
378
|
amount_side: input.amountSide,
|
|
369
379
|
amount: input.amount,
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
380
|
+
// The pair is the only place the asset ids appear. Repeating them here
|
|
381
|
+
// would be a key the solver's `.strict()` profile schema does not
|
|
382
|
+
// declare, and an undeclared key is `unsupported_payload` — a refusal,
|
|
383
|
+
// not an ignored extra. Empty, not absent: `profile` is required on
|
|
384
|
+
// every other request shape this wire carries.
|
|
385
|
+
profile: {}
|
|
374
386
|
};
|
|
375
387
|
};
|
|
376
388
|
var MIN_HEADROOM_SECONDS = 90 * 60;
|
|
@@ -384,6 +396,14 @@ var assertFinite = (value, reason, label) => {
|
|
|
384
396
|
throw gateError(reason, `${label} is not a finite number (${String(value)})`);
|
|
385
397
|
}
|
|
386
398
|
};
|
|
399
|
+
var MAX_PAIR_LENGTH = 158;
|
|
400
|
+
var assertPairLength = (pair) => {
|
|
401
|
+
if (pair.length > MAX_PAIR_LENGTH) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
`pair is ${pair.length} characters, over the wire's ${MAX_PAIR_LENGTH}-character limit`
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
};
|
|
387
407
|
var verifyLockupAddress = (quote, derivedAddress) => {
|
|
388
408
|
const quoted = quote.profile?.lockup_address;
|
|
389
409
|
if (derivedAddress !== quoted) throw new AddressMismatch(derivedAddress, quoted);
|
|
@@ -423,14 +443,20 @@ var assertFundable = (input) => {
|
|
|
423
443
|
}
|
|
424
444
|
}
|
|
425
445
|
};
|
|
426
|
-
var expectQuote = (payload, rfqId) => {
|
|
446
|
+
var expectQuote = (payload, rfqId, requestedPair) => {
|
|
427
447
|
const p = payload;
|
|
428
448
|
if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
|
|
429
449
|
if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
|
|
430
450
|
throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
|
|
431
451
|
}
|
|
452
|
+
if (requestedPair !== void 0 && p.pair !== requestedPair) {
|
|
453
|
+
throw new Error(
|
|
454
|
+
`solver quoted ${JSON.stringify(p.pair)}, not the requested ${requestedPair}`
|
|
455
|
+
);
|
|
456
|
+
}
|
|
432
457
|
return payload;
|
|
433
458
|
};
|
|
459
|
+
var pairOf = (payload) => typeof payload.pair === "string" ? payload.pair : void 0;
|
|
434
460
|
var httpTransport = (baseUrl, options = {}) => {
|
|
435
461
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
436
462
|
const readJson = async (response, what) => {
|
|
@@ -450,7 +476,11 @@ var httpTransport = (baseUrl, options = {}) => {
|
|
|
450
476
|
headers: { "content-type": "application/json" },
|
|
451
477
|
body: JSON.stringify(payload)
|
|
452
478
|
});
|
|
453
|
-
return expectQuote(
|
|
479
|
+
return expectQuote(
|
|
480
|
+
await readJson(response, "quote request"),
|
|
481
|
+
String(payload.rfq_id),
|
|
482
|
+
pairOf(payload)
|
|
483
|
+
);
|
|
454
484
|
},
|
|
455
485
|
async status(rfqId) {
|
|
456
486
|
const response = await fetchImpl(`${baseUrl}/v1/rfq/${rfqId}`, { method: "GET" });
|
|
@@ -527,7 +557,8 @@ var relayTransport = (relayUrl, options) => {
|
|
|
527
557
|
async requestQuote(payload) {
|
|
528
558
|
return expectQuote(
|
|
529
559
|
await roundTrip(payload, String(payload.rfq_id)),
|
|
530
|
-
String(payload.rfq_id)
|
|
560
|
+
String(payload.rfq_id),
|
|
561
|
+
pairOf(payload)
|
|
531
562
|
);
|
|
532
563
|
},
|
|
533
564
|
async status(rfqId) {
|
|
@@ -1151,9 +1182,10 @@ export {
|
|
|
1151
1182
|
LockupRegistrationFailed,
|
|
1152
1183
|
registerLockupContract,
|
|
1153
1184
|
ARKADE_BTC,
|
|
1154
|
-
ARKADE_ASSET,
|
|
1155
1185
|
LIGHTNING_BTC,
|
|
1156
1186
|
ONCHAIN_BTC,
|
|
1187
|
+
arkadeAssetLeg,
|
|
1188
|
+
ARKADE_ASSET,
|
|
1157
1189
|
rfqPair,
|
|
1158
1190
|
LIGHTNING_SEND_PAIR,
|
|
1159
1191
|
LIGHTNING_RECEIVE_PAIR,
|
|
@@ -1168,6 +1200,8 @@ export {
|
|
|
1168
1200
|
MIN_HEADROOM_SECONDS,
|
|
1169
1201
|
verifyLockupAddress,
|
|
1170
1202
|
assertFundable,
|
|
1203
|
+
expectQuote,
|
|
1204
|
+
pairOf,
|
|
1171
1205
|
httpTransport,
|
|
1172
1206
|
relayTransport,
|
|
1173
1207
|
SOLO_REFUND_HEADROOM_SECONDS,
|
package/dist/index.cjs
CHANGED
|
@@ -67,6 +67,7 @@ __export(index_exports, {
|
|
|
67
67
|
SWAP_LOCKUP_CONTRACT_TYPE: () => SWAP_LOCKUP_CONTRACT_TYPE,
|
|
68
68
|
SwapRefusal: () => SwapRefusal,
|
|
69
69
|
addAssetSwap: () => addAssetSwap,
|
|
70
|
+
arkadeAssetLeg: () => arkadeAssetLeg,
|
|
70
71
|
arkadeSwapRequest: () => arkadeSwapRequest,
|
|
71
72
|
assertFundable: () => assertFundable,
|
|
72
73
|
assertReceivable: () => assertReceivable,
|
|
@@ -1446,9 +1447,10 @@ var solverHex = (value, field) => {
|
|
|
1446
1447
|
}
|
|
1447
1448
|
};
|
|
1448
1449
|
var ARKADE_BTC = "arkade:BTC";
|
|
1449
|
-
var ARKADE_ASSET = "arkade:ASSET";
|
|
1450
1450
|
var LIGHTNING_BTC = "lightning:BTC";
|
|
1451
1451
|
var ONCHAIN_BTC = "onchain:BTC";
|
|
1452
|
+
var arkadeAssetLeg = (id) => `arkade:${id.toString()}`;
|
|
1453
|
+
var ARKADE_ASSET = "arkade:ASSET";
|
|
1452
1454
|
var rfqPair = (from, to) => `${from}->${to}`;
|
|
1453
1455
|
var LIGHTNING_SEND_PAIR = rfqPair(ARKADE_BTC, LIGHTNING_BTC);
|
|
1454
1456
|
var LIGHTNING_RECEIVE_PAIR = rfqPair(LIGHTNING_BTC, ARKADE_BTC);
|
|
@@ -1489,23 +1491,34 @@ var lightningSendRequest = (input) => ({
|
|
|
1489
1491
|
}
|
|
1490
1492
|
});
|
|
1491
1493
|
var arkadeSwapRequest = (input) => {
|
|
1492
|
-
if (
|
|
1493
|
-
throw new Error(
|
|
1494
|
+
if (!input.wantAsset && !input.offerAsset) {
|
|
1495
|
+
throw new Error(
|
|
1496
|
+
"set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC) \u2014 with neither set both legs are BTC, which is not a swap"
|
|
1497
|
+
);
|
|
1494
1498
|
}
|
|
1499
|
+
if (input.wantAsset && input.offerAsset) {
|
|
1500
|
+
throw new Error(
|
|
1501
|
+
"set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC) \u2014 asset->asset is nameable on the wire but no solver quotes it yet"
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
const pair = rfqPair(
|
|
1505
|
+
input.offerAsset ? arkadeAssetLeg(input.offerAsset) : ARKADE_BTC,
|
|
1506
|
+
input.wantAsset ? arkadeAssetLeg(input.wantAsset) : ARKADE_BTC
|
|
1507
|
+
);
|
|
1508
|
+
assertPairLength(pair);
|
|
1495
1509
|
return {
|
|
1496
1510
|
v: 1,
|
|
1497
1511
|
type: "rfq_request",
|
|
1498
1512
|
rfq_id: input.rfqId,
|
|
1499
|
-
pair
|
|
1500
|
-
input.offerAsset ? ARKADE_ASSET : ARKADE_BTC,
|
|
1501
|
-
input.wantAsset ? ARKADE_ASSET : ARKADE_BTC
|
|
1502
|
-
),
|
|
1513
|
+
pair,
|
|
1503
1514
|
amount_side: input.amountSide,
|
|
1504
1515
|
amount: input.amount,
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1516
|
+
// The pair is the only place the asset ids appear. Repeating them here
|
|
1517
|
+
// would be a key the solver's `.strict()` profile schema does not
|
|
1518
|
+
// declare, and an undeclared key is `unsupported_payload` — a refusal,
|
|
1519
|
+
// not an ignored extra. Empty, not absent: `profile` is required on
|
|
1520
|
+
// every other request shape this wire carries.
|
|
1521
|
+
profile: {}
|
|
1509
1522
|
};
|
|
1510
1523
|
};
|
|
1511
1524
|
var MIN_HEADROOM_SECONDS = 90 * 60;
|
|
@@ -1519,6 +1532,14 @@ var assertFinite = (value, reason, label) => {
|
|
|
1519
1532
|
throw gateError(reason, `${label} is not a finite number (${String(value)})`);
|
|
1520
1533
|
}
|
|
1521
1534
|
};
|
|
1535
|
+
var MAX_PAIR_LENGTH = 158;
|
|
1536
|
+
var assertPairLength = (pair) => {
|
|
1537
|
+
if (pair.length > MAX_PAIR_LENGTH) {
|
|
1538
|
+
throw new Error(
|
|
1539
|
+
`pair is ${pair.length} characters, over the wire's ${MAX_PAIR_LENGTH}-character limit`
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1522
1543
|
var verifyLockupAddress = (quote, derivedAddress) => {
|
|
1523
1544
|
const quoted = quote.profile?.lockup_address;
|
|
1524
1545
|
if (derivedAddress !== quoted) throw new AddressMismatch(derivedAddress, quoted);
|
|
@@ -1558,14 +1579,20 @@ var assertFundable = (input) => {
|
|
|
1558
1579
|
}
|
|
1559
1580
|
}
|
|
1560
1581
|
};
|
|
1561
|
-
var expectQuote = (payload, rfqId) => {
|
|
1582
|
+
var expectQuote = (payload, rfqId, requestedPair) => {
|
|
1562
1583
|
const p = payload;
|
|
1563
1584
|
if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
|
|
1564
1585
|
if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
|
|
1565
1586
|
throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
|
|
1566
1587
|
}
|
|
1588
|
+
if (requestedPair !== void 0 && p.pair !== requestedPair) {
|
|
1589
|
+
throw new Error(
|
|
1590
|
+
`solver quoted ${JSON.stringify(p.pair)}, not the requested ${requestedPair}`
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1567
1593
|
return payload;
|
|
1568
1594
|
};
|
|
1595
|
+
var pairOf = (payload) => typeof payload.pair === "string" ? payload.pair : void 0;
|
|
1569
1596
|
var httpTransport = (baseUrl, options = {}) => {
|
|
1570
1597
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
1571
1598
|
const readJson = async (response, what) => {
|
|
@@ -1585,7 +1612,11 @@ var httpTransport = (baseUrl, options = {}) => {
|
|
|
1585
1612
|
headers: { "content-type": "application/json" },
|
|
1586
1613
|
body: JSON.stringify(payload)
|
|
1587
1614
|
});
|
|
1588
|
-
return expectQuote(
|
|
1615
|
+
return expectQuote(
|
|
1616
|
+
await readJson(response, "quote request"),
|
|
1617
|
+
String(payload.rfq_id),
|
|
1618
|
+
pairOf(payload)
|
|
1619
|
+
);
|
|
1589
1620
|
},
|
|
1590
1621
|
async status(rfqId) {
|
|
1591
1622
|
const response = await fetchImpl(`${baseUrl}/v1/rfq/${rfqId}`, { method: "GET" });
|
|
@@ -1662,7 +1693,8 @@ var relayTransport = (relayUrl, options) => {
|
|
|
1662
1693
|
async requestQuote(payload) {
|
|
1663
1694
|
return expectQuote(
|
|
1664
1695
|
await roundTrip(payload, String(payload.rfq_id)),
|
|
1665
|
-
String(payload.rfq_id)
|
|
1696
|
+
String(payload.rfq_id),
|
|
1697
|
+
pairOf(payload)
|
|
1666
1698
|
);
|
|
1667
1699
|
},
|
|
1668
1700
|
async status(rfqId) {
|
|
@@ -3470,6 +3502,7 @@ function swapActivityResolver(deps) {
|
|
|
3470
3502
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
3471
3503
|
SwapRefusal,
|
|
3472
3504
|
addAssetSwap,
|
|
3505
|
+
arkadeAssetLeg,
|
|
3473
3506
|
arkadeSwapRequest,
|
|
3474
3507
|
assertFundable,
|
|
3475
3508
|
assertReceivable,
|
package/dist/index.d.cts
CHANGED
|
@@ -2,8 +2,8 @@ import { asset, IWallet, arkade, RestIndexerProvider, Transaction, IContractMana
|
|
|
2
2
|
import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from './repository-BwnZ8N62.cjs';
|
|
3
3
|
export { b as AssetSwapStatus, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, P as PreimageBlockedReason, c as PreimageNotRecoverableError, S as SwapSecretsProjection, d as addAssetSwap, g as getAssetSwaps, e as getAssetSwapsOrThrow, p as preimageForSwapRecord, s as swapSecretsToRecord, u as updateAssetSwap, f as updateAssetSwapBestEffort } from './repository-BwnZ8N62.cjs';
|
|
4
4
|
import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
5
|
-
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-
|
|
6
|
-
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as
|
|
5
|
+
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-DfT9dAss.cjs';
|
|
6
|
+
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as arkadeAssetLeg, y as arkadeSwapRequest, z as assertFundable, B as assertReceivable, D as awaitOnchainFill, E as buildHtlcClaim, F as buildHtlcRefund, G as claimOnchainFill, J as classifyOnchainHtlc, K as deriveLightningReceive, N as deriveOnchainReceive, P as deriveOnchainSend, Q as extractPreimage, T as httpTransport, U as lightningReceiveRequest, V as lightningSendRequest, W as lightningSendVtxoScript, X as newPreimage, Y as newRfqId, Z as offerTermsFromQuote, _ as onchainHtlcScript, $ as onchainReceiveRequest, a0 as onchainSendRequest, a1 as paymentHashOf, a2 as receiveVtxoScript, a3 as relayTransport, a4 as requestLightningReceive, a5 as requestLightningSend, a6 as requestOnchainReceive, a7 as requestOnchainSend, a8 as rfqPair, a9 as unilateralClaimDelay, aa as unilateralRefundDelay, ab as unilateralRefundWithoutReceiverDelay, ac as verifyLockupAddress, ad as verifyReceiveInvoice } from './rfq-DfT9dAss.cjs';
|
|
7
7
|
|
|
8
8
|
/** The contracts — pure data, shared verbatim with any other implementation. */
|
|
9
9
|
declare const swapPrograms: Record<"wantAsset" | "wantBtc", ReturnType<typeof arkade.parseArtifact>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { asset, IWallet, arkade, RestIndexerProvider, Transaction, IContractMana
|
|
|
2
2
|
import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from './repository-BwnZ8N62.js';
|
|
3
3
|
export { b as AssetSwapStatus, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, P as PreimageBlockedReason, c as PreimageNotRecoverableError, S as SwapSecretsProjection, d as addAssetSwap, g as getAssetSwaps, e as getAssetSwapsOrThrow, p as preimageForSwapRecord, s as swapSecretsToRecord, u as updateAssetSwap, f as updateAssetSwapBestEffort } from './repository-BwnZ8N62.js';
|
|
4
4
|
import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
5
|
-
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-
|
|
6
|
-
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as
|
|
5
|
+
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-DfT9dAss.js';
|
|
6
|
+
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as arkadeAssetLeg, y as arkadeSwapRequest, z as assertFundable, B as assertReceivable, D as awaitOnchainFill, E as buildHtlcClaim, F as buildHtlcRefund, G as claimOnchainFill, J as classifyOnchainHtlc, K as deriveLightningReceive, N as deriveOnchainReceive, P as deriveOnchainSend, Q as extractPreimage, T as httpTransport, U as lightningReceiveRequest, V as lightningSendRequest, W as lightningSendVtxoScript, X as newPreimage, Y as newRfqId, Z as offerTermsFromQuote, _ as onchainHtlcScript, $ as onchainReceiveRequest, a0 as onchainSendRequest, a1 as paymentHashOf, a2 as receiveVtxoScript, a3 as relayTransport, a4 as requestLightningReceive, a5 as requestLightningSend, a6 as requestOnchainReceive, a7 as requestOnchainSend, a8 as rfqPair, a9 as unilateralClaimDelay, aa as unilateralRefundDelay, ab as unilateralRefundWithoutReceiverDelay, ac as verifyLockupAddress, ad as verifyReceiveInvoice } from './rfq-DfT9dAss.js';
|
|
7
7
|
|
|
8
8
|
/** The contracts — pure data, shared verbatim with any other implementation. */
|
|
9
9
|
declare const swapPrograms: Record<"wantAsset" | "wantBtc", ReturnType<typeof arkade.parseArtifact>>;
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
SWAP_LOCKUP_CONTRACT_LABEL,
|
|
23
23
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
24
24
|
SwapRefusal,
|
|
25
|
+
arkadeAssetLeg,
|
|
25
26
|
arkadeSwapRequest,
|
|
26
27
|
assertFundable,
|
|
27
28
|
assertReceivable,
|
|
@@ -59,7 +60,7 @@ import {
|
|
|
59
60
|
unilateralRefundWithoutReceiverDelay,
|
|
60
61
|
verifyLockupAddress,
|
|
61
62
|
verifyReceiveInvoice
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-ZDTRQZE2.js";
|
|
63
64
|
import {
|
|
64
65
|
InMemoryAssetSwapRepository,
|
|
65
66
|
marketsCacheKey
|
|
@@ -2269,6 +2270,7 @@ export {
|
|
|
2269
2270
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
2270
2271
|
SwapRefusal,
|
|
2271
2272
|
addAssetSwap,
|
|
2273
|
+
arkadeAssetLeg,
|
|
2272
2274
|
arkadeSwapRequest,
|
|
2273
2275
|
assertFundable,
|
|
2274
2276
|
assertReceivable,
|
package/dist/nostr.cjs
CHANGED
|
@@ -91,6 +91,20 @@ var SwapRefusal = class extends Error {
|
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
var MIN_HEADROOM_SECONDS = 90 * 60;
|
|
94
|
+
var expectQuote = (payload, rfqId, requestedPair) => {
|
|
95
|
+
const p = payload;
|
|
96
|
+
if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
|
|
97
|
+
if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
|
|
98
|
+
throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
|
|
99
|
+
}
|
|
100
|
+
if (requestedPair !== void 0 && p.pair !== requestedPair) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`solver quoted ${JSON.stringify(p.pair)}, not the requested ${requestedPair}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return payload;
|
|
106
|
+
};
|
|
107
|
+
var pairOf = (payload) => typeof payload.pair === "string" ? payload.pair : void 0;
|
|
94
108
|
var SEQUENCE_GRANULARITY_SECONDS = 512;
|
|
95
109
|
var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
|
|
96
110
|
var MIN_CLAIM_WINDOW_SECONDS = 30 * 60;
|
|
@@ -119,14 +133,6 @@ var closeReasons = (raw) => raw.map((entry) => {
|
|
|
119
133
|
const { url, reason } = entry ?? {};
|
|
120
134
|
return url ? `${url}: ${reason ?? "closed"}` : reason ?? "closed";
|
|
121
135
|
});
|
|
122
|
-
var asQuote = (payload, rfqId) => {
|
|
123
|
-
const p = payload;
|
|
124
|
-
if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
|
|
125
|
-
if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
|
|
126
|
-
throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
|
|
127
|
-
}
|
|
128
|
-
return payload;
|
|
129
|
-
};
|
|
130
136
|
var nostrRfqTransport = (options) => {
|
|
131
137
|
const relays = options.relays;
|
|
132
138
|
const solverPubkey = options.solverPubkey;
|
|
@@ -202,7 +208,7 @@ var nostrRfqTransport = (options) => {
|
|
|
202
208
|
const rfqId = String(payload.rfq_id);
|
|
203
209
|
const reply = awaitReply(rfqId);
|
|
204
210
|
await send(payload);
|
|
205
|
-
return
|
|
211
|
+
return expectQuote(await reply, rfqId, pairOf(payload));
|
|
206
212
|
},
|
|
207
213
|
async status(rfqId) {
|
|
208
214
|
const reply = awaitReply(rfqId);
|
package/dist/nostr.d.cts
CHANGED
package/dist/nostr.d.ts
CHANGED
package/dist/nostr.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
expectQuote,
|
|
3
|
+
pairOf
|
|
4
|
+
} from "./chunk-ZDTRQZE2.js";
|
|
4
5
|
|
|
5
6
|
// src/nostr.ts
|
|
6
7
|
import {
|
|
@@ -32,14 +33,6 @@ var closeReasons = (raw) => raw.map((entry) => {
|
|
|
32
33
|
const { url, reason } = entry ?? {};
|
|
33
34
|
return url ? `${url}: ${reason ?? "closed"}` : reason ?? "closed";
|
|
34
35
|
});
|
|
35
|
-
var asQuote = (payload, rfqId) => {
|
|
36
|
-
const p = payload;
|
|
37
|
-
if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
|
|
38
|
-
if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
|
|
39
|
-
throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
|
|
40
|
-
}
|
|
41
|
-
return payload;
|
|
42
|
-
};
|
|
43
36
|
var nostrRfqTransport = (options) => {
|
|
44
37
|
const relays = options.relays;
|
|
45
38
|
const solverPubkey = options.solverPubkey;
|
|
@@ -115,7 +108,7 @@ var nostrRfqTransport = (options) => {
|
|
|
115
108
|
const rfqId = String(payload.rfq_id);
|
|
116
109
|
const reply = awaitReply(rfqId);
|
|
117
110
|
await send(payload);
|
|
118
|
-
return
|
|
111
|
+
return expectQuote(await reply, rfqId, pairOf(payload));
|
|
119
112
|
},
|
|
120
113
|
async status(rfqId) {
|
|
121
114
|
const reply = awaitReply(rfqId);
|
|
@@ -210,13 +210,25 @@ declare function classifyOnchainHtlc(chain: ChainSource, input: {
|
|
|
210
210
|
};
|
|
211
211
|
}): Promise<OnchainHtlcPhase>;
|
|
212
212
|
|
|
213
|
-
/** Legs are `<corridor>:<asset>`; a pair is directional, `from->to`.
|
|
214
|
-
* asset legs stay coarse (`arkade:ASSET`) — the exact asset ids ride the
|
|
215
|
-
* request profile, mirroring how the offer TLV identifies assets. */
|
|
213
|
+
/** Legs are `<corridor>:<asset>`; a pair is directional, `from->to`. */
|
|
216
214
|
declare const ARKADE_BTC = "arkade:BTC";
|
|
217
|
-
declare const ARKADE_ASSET = "arkade:ASSET";
|
|
218
215
|
declare const LIGHTNING_BTC = "lightning:BTC";
|
|
219
216
|
declare const ONCHAIN_BTC = "onchain:BTC";
|
|
217
|
+
/** The arkade leg for an asset: the asset id itself, 68 lowercase hex. The id
|
|
218
|
+
* lives in the pair rather than the profile because the pair is the field both
|
|
219
|
+
* sides route and subscribe on, and a coarse leg cannot say which asset a
|
|
220
|
+
* market key is for.
|
|
221
|
+
*
|
|
222
|
+
* Taking an `AssetId` rather than a string is what enforces the case rule:
|
|
223
|
+
* `hex.decode` accepts uppercase while `hex.encode` only emits lowercase, so a
|
|
224
|
+
* value that reached us as `A1B2…` leaves here as `a1b2…`. Solvers compare pair
|
|
225
|
+
* strings byte for byte — a sender that normalised only in its key derivation
|
|
226
|
+
* would reach the right subscription and then be skipped as an unserved pair. */
|
|
227
|
+
declare const arkadeAssetLeg: (id: asset.AssetId) => string;
|
|
228
|
+
/** @deprecated The coarse asset leg. No solver serves it: `ASSET` is neither a
|
|
229
|
+
* registered ticker nor a 68-hex asset id, so a solver's market-key derivation
|
|
230
|
+
* throws on it. Use {@link arkadeAssetLeg}. Removed next major. */
|
|
231
|
+
declare const ARKADE_ASSET = "arkade:ASSET";
|
|
220
232
|
declare const rfqPair: (from: string, to: string) => string;
|
|
221
233
|
/** The implemented pair: pay a BOLT11 invoice out of an Arkade balance. */
|
|
222
234
|
declare const LIGHTNING_SEND_PAIR: string;
|
|
@@ -287,9 +299,9 @@ declare const lightningSendRequest: (input: {
|
|
|
287
299
|
senderPubkey: Uint8Array;
|
|
288
300
|
}) => Record<string, unknown>;
|
|
289
301
|
/** The rfq_request for an arkade↔arkade swap. Exactly one side may name an
|
|
290
|
-
* asset id per direction (BTC has none)
|
|
291
|
-
*
|
|
292
|
-
*
|
|
302
|
+
* asset id per direction (BTC has none), and the id is the leg itself — see
|
|
303
|
+
* {@link arkadeAssetLeg}. Forward-looking: the wire shape is specified, the
|
|
304
|
+
* reference solver does not serve it yet. */
|
|
293
305
|
declare const arkadeSwapRequest: (input: {
|
|
294
306
|
rfqId: string;
|
|
295
307
|
/** Asset the trader deposits; omit when depositing BTC. */
|
|
@@ -920,4 +932,4 @@ declare function requestOnchainReceive(wallet: IWallet, arkServerUrl: string, tr
|
|
|
920
932
|
secrets: ProvisionedClaimSecret;
|
|
921
933
|
}>;
|
|
922
934
|
|
|
923
|
-
export {
|
|
935
|
+
export { onchainReceiveRequest as $, ARKADE_ASSET as A, assertReceivable as B, type ChainSource as C, awaitOnchainFill as D, buildHtlcClaim as E, buildHtlcRefund as F, claimOnchainFill as G, type HtlcUtxo as H, type InvoiceFacts as I, classifyOnchainHtlc as J, deriveLightningReceive as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, deriveOnchainReceive as N, type OnchainHtlc as O, deriveOnchainSend as P, extractPreimage as Q, type RfqStatus as R, SOLO_REFUND_HEADROOM_SECONDS as S, httpTransport as T, lightningReceiveRequest as U, lightningSendRequest as V, lightningSendVtxoScript as W, newPreimage as X, newRfqId as Y, offerTermsFromQuote as Z, onchainHtlcScript as _, type RfqTransport as a, onchainSendRequest as a0, paymentHashOf as a1, receiveVtxoScript as a2, relayTransport as a3, requestLightningReceive as a4, requestLightningSend as a5, requestOnchainReceive as a6, requestOnchainSend as a7, rfqPair as a8, unilateralClaimDelay as a9, unilateralRefundDelay as aa, unilateralRefundWithoutReceiverDelay as ab, verifyLockupAddress as ac, verifyReceiveInvoice as ad, type ChainUtxo as b, type OnchainHtlcPhase as c, ARKADE_BTC as d, AddressMismatch as e, LIGHTNING_RECEIVE_PAIR as f, LIGHTNING_SEND_PAIR as g, MIN_CLAIM_WINDOW_SECONDS as h, MIN_HEADROOM_SECONDS as i, ONCHAIN_BTC as j, ONCHAIN_CLAIM_MARGIN_SECONDS as k, ONCHAIN_DUST_SATS as l, ONCHAIN_ORDER_MARGIN_SECONDS as m, ONCHAIN_RECEIVE_PAIR as n, ONCHAIN_SECONDS_PER_BLOCK as o, ONCHAIN_SEND_PAIR as p, type OnchainHtlcParams as q, type OnchainNetwork as r, RFQ_TERMINAL_STATES as s, type RelaySocket as t, type RfqQuote as u, type RfqRefusalReason as v, SwapRefusal as w, arkadeAssetLeg as x, arkadeSwapRequest as y, assertFundable as z };
|
|
@@ -210,13 +210,25 @@ declare function classifyOnchainHtlc(chain: ChainSource, input: {
|
|
|
210
210
|
};
|
|
211
211
|
}): Promise<OnchainHtlcPhase>;
|
|
212
212
|
|
|
213
|
-
/** Legs are `<corridor>:<asset>`; a pair is directional, `from->to`.
|
|
214
|
-
* asset legs stay coarse (`arkade:ASSET`) — the exact asset ids ride the
|
|
215
|
-
* request profile, mirroring how the offer TLV identifies assets. */
|
|
213
|
+
/** Legs are `<corridor>:<asset>`; a pair is directional, `from->to`. */
|
|
216
214
|
declare const ARKADE_BTC = "arkade:BTC";
|
|
217
|
-
declare const ARKADE_ASSET = "arkade:ASSET";
|
|
218
215
|
declare const LIGHTNING_BTC = "lightning:BTC";
|
|
219
216
|
declare const ONCHAIN_BTC = "onchain:BTC";
|
|
217
|
+
/** The arkade leg for an asset: the asset id itself, 68 lowercase hex. The id
|
|
218
|
+
* lives in the pair rather than the profile because the pair is the field both
|
|
219
|
+
* sides route and subscribe on, and a coarse leg cannot say which asset a
|
|
220
|
+
* market key is for.
|
|
221
|
+
*
|
|
222
|
+
* Taking an `AssetId` rather than a string is what enforces the case rule:
|
|
223
|
+
* `hex.decode` accepts uppercase while `hex.encode` only emits lowercase, so a
|
|
224
|
+
* value that reached us as `A1B2…` leaves here as `a1b2…`. Solvers compare pair
|
|
225
|
+
* strings byte for byte — a sender that normalised only in its key derivation
|
|
226
|
+
* would reach the right subscription and then be skipped as an unserved pair. */
|
|
227
|
+
declare const arkadeAssetLeg: (id: asset.AssetId) => string;
|
|
228
|
+
/** @deprecated The coarse asset leg. No solver serves it: `ASSET` is neither a
|
|
229
|
+
* registered ticker nor a 68-hex asset id, so a solver's market-key derivation
|
|
230
|
+
* throws on it. Use {@link arkadeAssetLeg}. Removed next major. */
|
|
231
|
+
declare const ARKADE_ASSET = "arkade:ASSET";
|
|
220
232
|
declare const rfqPair: (from: string, to: string) => string;
|
|
221
233
|
/** The implemented pair: pay a BOLT11 invoice out of an Arkade balance. */
|
|
222
234
|
declare const LIGHTNING_SEND_PAIR: string;
|
|
@@ -287,9 +299,9 @@ declare const lightningSendRequest: (input: {
|
|
|
287
299
|
senderPubkey: Uint8Array;
|
|
288
300
|
}) => Record<string, unknown>;
|
|
289
301
|
/** The rfq_request for an arkade↔arkade swap. Exactly one side may name an
|
|
290
|
-
* asset id per direction (BTC has none)
|
|
291
|
-
*
|
|
292
|
-
*
|
|
302
|
+
* asset id per direction (BTC has none), and the id is the leg itself — see
|
|
303
|
+
* {@link arkadeAssetLeg}. Forward-looking: the wire shape is specified, the
|
|
304
|
+
* reference solver does not serve it yet. */
|
|
293
305
|
declare const arkadeSwapRequest: (input: {
|
|
294
306
|
rfqId: string;
|
|
295
307
|
/** Asset the trader deposits; omit when depositing BTC. */
|
|
@@ -920,4 +932,4 @@ declare function requestOnchainReceive(wallet: IWallet, arkServerUrl: string, tr
|
|
|
920
932
|
secrets: ProvisionedClaimSecret;
|
|
921
933
|
}>;
|
|
922
934
|
|
|
923
|
-
export {
|
|
935
|
+
export { onchainReceiveRequest as $, ARKADE_ASSET as A, assertReceivable as B, type ChainSource as C, awaitOnchainFill as D, buildHtlcClaim as E, buildHtlcRefund as F, claimOnchainFill as G, type HtlcUtxo as H, type InvoiceFacts as I, classifyOnchainHtlc as J, deriveLightningReceive as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, deriveOnchainReceive as N, type OnchainHtlc as O, deriveOnchainSend as P, extractPreimage as Q, type RfqStatus as R, SOLO_REFUND_HEADROOM_SECONDS as S, httpTransport as T, lightningReceiveRequest as U, lightningSendRequest as V, lightningSendVtxoScript as W, newPreimage as X, newRfqId as Y, offerTermsFromQuote as Z, onchainHtlcScript as _, type RfqTransport as a, onchainSendRequest as a0, paymentHashOf as a1, receiveVtxoScript as a2, relayTransport as a3, requestLightningReceive as a4, requestLightningSend as a5, requestOnchainReceive as a6, requestOnchainSend as a7, rfqPair as a8, unilateralClaimDelay as a9, unilateralRefundDelay as aa, unilateralRefundWithoutReceiverDelay as ab, verifyLockupAddress as ac, verifyReceiveInvoice as ad, type ChainUtxo as b, type OnchainHtlcPhase as c, ARKADE_BTC as d, AddressMismatch as e, LIGHTNING_RECEIVE_PAIR as f, LIGHTNING_SEND_PAIR as g, MIN_CLAIM_WINDOW_SECONDS as h, MIN_HEADROOM_SECONDS as i, ONCHAIN_BTC as j, ONCHAIN_CLAIM_MARGIN_SECONDS as k, ONCHAIN_DUST_SATS as l, ONCHAIN_ORDER_MARGIN_SECONDS as m, ONCHAIN_RECEIVE_PAIR as n, ONCHAIN_SECONDS_PER_BLOCK as o, ONCHAIN_SEND_PAIR as p, type OnchainHtlcParams as q, type OnchainNetwork as r, RFQ_TERMINAL_STATES as s, type RelaySocket as t, type RfqQuote as u, type RfqRefusalReason as v, SwapRefusal as w, arkadeAssetLeg as x, arkadeSwapRequest as y, assertFundable as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkade-os/swap",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Client-side Arkade Intents asset swaps: discover markets, quote, create/track/cancel offers, restore from chain.",
|
|
6
6
|
"repository": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@noble/hashes": "2.0.1",
|
|
70
70
|
"@scure/base": "2.0.0",
|
|
71
71
|
"@scure/btc-signer": "2.0.1",
|
|
72
|
-
"@arkade-os/sdk": "0.4.
|
|
72
|
+
"@arkade-os/sdk": "0.4.64"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"nostr-tools": "^2.12.0"
|