@arkade-os/swap 0.0.4 → 0.0.5
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 +125 -31
- package/dist/{chunk-DLM6BVTB.js → chunk-Q4FAYBXS.js} +6 -4
- package/dist/index.cjs +155 -93
- package/dist/index.d.cts +106 -25
- package/dist/index.d.ts +106 -25
- package/dist/index.js +67 -8
- package/dist/nostr.cjs +11 -0
- package/dist/nostr.d.cts +14 -2
- package/dist/nostr.d.ts +14 -2
- package/dist/nostr.js +9 -1
- package/dist/{rfq-DjZlesr4.d.cts → rfq-BH2yvo3O.d.cts} +36 -13
- package/dist/{rfq-DjZlesr4.d.ts → rfq-BH2yvo3O.d.ts} +36 -13
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,47 @@
|
|
|
1
|
-
import { ProvisionedKey, ProvisionedClaimSecret, asset,
|
|
1
|
+
import { IWallet, ProvisionedKey, ProvisionedClaimSecret, asset, arkade, RestIndexerProvider, Transaction, IContractManager, RestArkProvider, VHTLC, Identity } from '@arkade-os/sdk';
|
|
2
2
|
import { DiscoveredMarket, Network, LocalCardInput, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
3
|
-
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-
|
|
4
|
-
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
|
|
3
|
+
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-BH2yvo3O.cjs';
|
|
4
|
+
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 arkadeSwapRequest, y as assertFundable, z as assertReceivable, B as awaitOnchainFill, D as buildHtlcClaim, E as buildHtlcRefund, F as claimOnchainFill, G as classifyOnchainHtlc, J as deriveLightningReceive, K as deriveOnchainReceive, N as deriveOnchainSend, P as extractPreimage, Q as httpTransport, T as lightningReceiveRequest, U as lightningSendRequest, V as lightningSendVtxoScript, W as newPreimage, X as newRfqId, Y as offerTermsFromQuote, Z as onchainHtlcScript, _ as onchainReceiveRequest, $ as onchainSendRequest, a0 as paymentHashOf, a1 as receiveVtxoScript, a2 as relayTransport, a3 as requestLightningReceive, a4 as requestLightningSend, a5 as requestOnchainReceive, a6 as requestOnchainSend, a7 as rfqPair, a8 as unilateralClaimDelay, a9 as unilateralRefundDelay, aa as unilateralRefundWithoutReceiverDelay, ab as verifyLockupAddress, ac as verifyReceiveInvoice } from './rfq-BH2yvo3O.cjs';
|
|
5
5
|
|
|
6
6
|
type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
|
|
7
7
|
/** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
|
|
8
8
|
* Lives here with the {@link AssetSwap} fields it describes so the market and
|
|
9
9
|
* restore layers share one spelling instead of re-typing the literal. */
|
|
10
10
|
declare const BTC_ASSET_ID = "btc";
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The record fields a wallet-provisioned secret becomes — what
|
|
13
|
+
* {@link swapSecretsToRecord} emits, and what every record type carrying swap
|
|
14
|
+
* secrets embeds.
|
|
15
|
+
*
|
|
16
|
+
* A named type rather than four fields restated per record: the mapper and the
|
|
17
|
+
* records it feeds must agree exactly, and a record that silently omits one of
|
|
18
|
+
* these round-trips a swap whose preimage cannot be re-derived. Embedding makes
|
|
19
|
+
* the omission a compile error instead.
|
|
20
|
+
*
|
|
21
|
+
* **Only `preimageHex` is secret.** `signingDescriptor` and `preimageSaltHex`
|
|
22
|
+
* are public derivation inputs — they must survive a field-mapped backend, but
|
|
23
|
+
* they leak nothing without the seed.
|
|
24
|
+
*/
|
|
25
|
+
interface SwapSecretsProjection {
|
|
26
|
+
/**
|
|
27
|
+
* The wallet descriptor this swap's sender key comes from — a fresh HD
|
|
28
|
+
* child, or a static wallet's `tr(pubkey)`. Public — the signer
|
|
29
|
+
* re-derives from the wallet, so the record carries no key material.
|
|
30
|
+
*/
|
|
31
|
+
signingDescriptor?: string;
|
|
32
|
+
/** P, hex, when it cannot be re-derived from the seed at all: the user
|
|
33
|
+
* supplied it, or the signer cannot sign deterministically. The swap's only
|
|
34
|
+
* claim secret when present. */
|
|
35
|
+
preimageHex?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The salt P derives from, hex, on the salted arm — what a static wallet
|
|
38
|
+
* gets instead of storing P. **Public**, and unlike every other field here
|
|
39
|
+
* it is minted per swap: it is what stops one repeating key from handing
|
|
40
|
+
* every swap the same preimage.
|
|
41
|
+
*/
|
|
42
|
+
preimageSaltHex?: string;
|
|
43
|
+
}
|
|
44
|
+
interface AssetSwap extends SwapSecretsProjection {
|
|
12
45
|
/** Funding txid — the swap's identity. */
|
|
13
46
|
id: string;
|
|
14
47
|
/** 'btc' or a 68-hex asset id. */
|
|
@@ -33,16 +66,6 @@ interface AssetSwap {
|
|
|
33
66
|
/** `sha256(P)`, hex. Public, and how a restore confirms a candidate
|
|
34
67
|
* derivation is the right one. */
|
|
35
68
|
paymentHash?: string;
|
|
36
|
-
/**
|
|
37
|
-
* The wallet descriptor this swap's sender key comes from — a fresh HD
|
|
38
|
-
* child, or a static wallet's `tr(pubkey)`. Public — the signer
|
|
39
|
-
* re-derives from the wallet, so the record carries no key material.
|
|
40
|
-
*/
|
|
41
|
-
signingDescriptor?: string;
|
|
42
|
-
/** P, hex, when it cannot be re-derived from the seed: the user supplied
|
|
43
|
-
* it, or the descriptor is static (shared across swaps, so a derived
|
|
44
|
-
* preimage would collide). The swap's only claim secret when present. */
|
|
45
|
-
preimageHex?: string;
|
|
46
69
|
/** The L1 HTLC's pkScript, hex — the chain-watch key. */
|
|
47
70
|
htlcPkScriptHex?: string;
|
|
48
71
|
htlcLocktime?: number;
|
|
@@ -85,13 +108,70 @@ declare const updateAssetSwapBestEffort: (repository: AssetSwapRepository, id: s
|
|
|
85
108
|
* The record fields a wallet-provisioned secret becomes.
|
|
86
109
|
*
|
|
87
110
|
* `signingDescriptor` is public and always stored — it is what recovers the
|
|
88
|
-
* signer.
|
|
89
|
-
* re-derive P
|
|
111
|
+
* signer. Then at most one of: `preimageHex`, when the wallet says it cannot
|
|
112
|
+
* re-derive P and it becomes the swap's only claim secret; or
|
|
113
|
+
* `preimageSaltHex`, the public input a derivable-but-repeating key needs.
|
|
90
114
|
*/
|
|
91
|
-
declare const swapSecretsToRecord: (secrets: ProvisionedKey | ProvisionedClaimSecret) => {
|
|
115
|
+
declare const swapSecretsToRecord: (secrets: ProvisionedKey | ProvisionedClaimSecret) => SwapSecretsProjection & {
|
|
92
116
|
signingDescriptor: string;
|
|
93
|
-
preimageHex?: string;
|
|
94
117
|
};
|
|
118
|
+
/** Why a wallet cannot produce a swap's preimage. */
|
|
119
|
+
type PreimageBlockedReason =
|
|
120
|
+
/** The record carries no `signingDescriptor`. */
|
|
121
|
+
"no-secrets"
|
|
122
|
+
/** `preimageHex` or `preimageSaltHex` is present but not 32 bytes of hex. */
|
|
123
|
+
| "malformed-record"
|
|
124
|
+
/**
|
|
125
|
+
* Nothing to derive from: a descriptor that repeats across swaps, with
|
|
126
|
+
* neither a stored preimage nor a salt — or one this wallet holds no key
|
|
127
|
+
* for. Merged deliberately: `contractSigner` reports a key it does not
|
|
128
|
+
* hold as a plain `Error` for static wallets and a `ForeignDescriptorError`
|
|
129
|
+
* for HD ones, so splitting the two here would mean matching on message
|
|
130
|
+
* text, which is the thing this type exists to avoid. The `cause` carries
|
|
131
|
+
* whichever it was.
|
|
132
|
+
*/
|
|
133
|
+
| "not-derivable"
|
|
134
|
+
/** Derived, but it does not hash to the record's `paymentHash`. */
|
|
135
|
+
| "hash-mismatch";
|
|
136
|
+
/**
|
|
137
|
+
* The wallet cannot produce this swap's preimage, and which of the four ways
|
|
138
|
+
* is `reason`.
|
|
139
|
+
*
|
|
140
|
+
* Deliberately **not** {@link RefundNotLocallyPossibleError}: that one means
|
|
141
|
+
* "no local refund is possible", and `RfqSwapManager` acts on it by reporting
|
|
142
|
+
* `needs_counterparty`. A claim-path read failure is a different verdict, and
|
|
143
|
+
* borrowing the refund error would have the manager announce one for the
|
|
144
|
+
* other.
|
|
145
|
+
*/
|
|
146
|
+
declare class PreimageNotRecoverableError extends Error {
|
|
147
|
+
readonly reason: PreimageBlockedReason;
|
|
148
|
+
readonly name = "PreimageNotRecoverableError";
|
|
149
|
+
constructor(reason: PreimageBlockedReason, message: string, options?: {
|
|
150
|
+
cause?: unknown;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The preimage a swap record claims with — stored, or re-derived from the
|
|
155
|
+
* wallet.
|
|
156
|
+
*
|
|
157
|
+
* The record-shaped inverse of {@link swapSecretsToRecord}, and the one place
|
|
158
|
+
* that knows which of a record's fields `contractPreimage` needs. Wire claim
|
|
159
|
+
* paths here rather than composing it by hand: a caller that forgets to pass
|
|
160
|
+
* `preimageSaltHex` gets a *wrong* preimage from a wallet that can derive,
|
|
161
|
+
* not an error.
|
|
162
|
+
*
|
|
163
|
+
* Verifies the result against `paymentHash` when the record carries one. The
|
|
164
|
+
* salted arm has two inputs that can be wrong — the key and the salt — where
|
|
165
|
+
* the HD arm had one, and a wrong P otherwise surfaces as an opaque script
|
|
166
|
+
* failure at claim time, long after the mistake.
|
|
167
|
+
*
|
|
168
|
+
* Every refusal is a {@link PreimageNotRecoverableError} carrying a `reason`,
|
|
169
|
+
* so a caller can tell "this record predates the descriptor" from "the salt is
|
|
170
|
+
* corrupt" without reading message text.
|
|
171
|
+
*/
|
|
172
|
+
declare const preimageForSwapRecord: (wallet: IWallet, record: SwapSecretsProjection & {
|
|
173
|
+
paymentHash?: string;
|
|
174
|
+
}) => Promise<Uint8Array>;
|
|
95
175
|
|
|
96
176
|
/** A registry discovery result held for reuse. Refetchable — unlike a swap
|
|
97
177
|
* record, losing it costs one network round trip — but it must survive a cold
|
|
@@ -116,11 +196,12 @@ interface MarketsCacheEntry {
|
|
|
116
196
|
* subset queries.
|
|
117
197
|
*/
|
|
118
198
|
interface AssetSwapRepository extends AsyncDisposable {
|
|
119
|
-
readonly version:
|
|
199
|
+
readonly version: 2;
|
|
120
200
|
/** Insert or replace a swap by id. Store the record whole: `preimageHex`
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
201
|
+
* and `preimageSaltHex` both leave the swap unclaimable if a field-mapped
|
|
202
|
+
* backend drops them — the first is the only claim secret of a swap whose
|
|
203
|
+
* signer cannot derive, the second the public input every other static
|
|
204
|
+
* wallet's preimage derives from. */
|
|
124
205
|
saveSwap(swap: AssetSwap): Promise<void>;
|
|
125
206
|
/** All stored swaps, in no particular order — `getAssetSwaps` is the
|
|
126
207
|
* canonical newest-first read. */
|
|
@@ -134,7 +215,7 @@ interface AssetSwapRepository extends AsyncDisposable {
|
|
|
134
215
|
clear(): Promise<void>;
|
|
135
216
|
}
|
|
136
217
|
declare class InMemoryAssetSwapRepository implements AssetSwapRepository {
|
|
137
|
-
readonly version:
|
|
218
|
+
readonly version: 2;
|
|
138
219
|
private readonly swaps;
|
|
139
220
|
private readonly scanned;
|
|
140
221
|
private readonly markets;
|
|
@@ -363,7 +444,7 @@ declare const validatePlan: (plan: OfferPlan, giveBalance: bigint, dust: bigint)
|
|
|
363
444
|
* infrastructure the wallet already uses for its Boltz swap repository. */
|
|
364
445
|
declare class IndexedDbAssetSwapRepository implements AssetSwapRepository {
|
|
365
446
|
private readonly dbName;
|
|
366
|
-
readonly version:
|
|
447
|
+
readonly version: 2;
|
|
367
448
|
private dbPromise;
|
|
368
449
|
constructor(dbName?: string);
|
|
369
450
|
private ensureDb;
|
|
@@ -1929,4 +2010,4 @@ interface RfqSwapOutcome {
|
|
|
1929
2010
|
txid?: string;
|
|
1930
2011
|
}
|
|
1931
2012
|
|
|
1932
|
-
export { type ArkadeRefundResult, type AssetSwap, type AssetSwapRepository, type AssetSwapStatus, BTC_ASSET_ID, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, InMemoryAssetSwapRepository, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, type MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapContractRegistry, type Tx, type WatchOfferSwapsParams, addAssetSwap, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, getAssetSwaps, getAssetSwapsOrThrow, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapPrograms, swapSecretsToRecord, updateAssetSwap, updateAssetSwapBestEffort, validatePlan, watchOfferSwaps };
|
|
2013
|
+
export { type ArkadeRefundResult, type AssetSwap, type AssetSwapRepository, type AssetSwapStatus, BTC_ASSET_ID, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, InMemoryAssetSwapRepository, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, type MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, type PreimageBlockedReason, PreimageNotRecoverableError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapContractRegistry, type SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, addAssetSwap, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, getAssetSwaps, getAssetSwapsOrThrow, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, preimageForSwapRecord, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapPrograms, swapSecretsToRecord, updateAssetSwap, updateAssetSwapBestEffort, validatePlan, watchOfferSwaps };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,47 @@
|
|
|
1
|
-
import { ProvisionedKey, ProvisionedClaimSecret, asset,
|
|
1
|
+
import { IWallet, ProvisionedKey, ProvisionedClaimSecret, asset, arkade, RestIndexerProvider, Transaction, IContractManager, RestArkProvider, VHTLC, Identity } from '@arkade-os/sdk';
|
|
2
2
|
import { DiscoveredMarket, Network, LocalCardInput, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
3
|
-
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-
|
|
4
|
-
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
|
|
3
|
+
import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-BH2yvo3O.js';
|
|
4
|
+
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 arkadeSwapRequest, y as assertFundable, z as assertReceivable, B as awaitOnchainFill, D as buildHtlcClaim, E as buildHtlcRefund, F as claimOnchainFill, G as classifyOnchainHtlc, J as deriveLightningReceive, K as deriveOnchainReceive, N as deriveOnchainSend, P as extractPreimage, Q as httpTransport, T as lightningReceiveRequest, U as lightningSendRequest, V as lightningSendVtxoScript, W as newPreimage, X as newRfqId, Y as offerTermsFromQuote, Z as onchainHtlcScript, _ as onchainReceiveRequest, $ as onchainSendRequest, a0 as paymentHashOf, a1 as receiveVtxoScript, a2 as relayTransport, a3 as requestLightningReceive, a4 as requestLightningSend, a5 as requestOnchainReceive, a6 as requestOnchainSend, a7 as rfqPair, a8 as unilateralClaimDelay, a9 as unilateralRefundDelay, aa as unilateralRefundWithoutReceiverDelay, ab as verifyLockupAddress, ac as verifyReceiveInvoice } from './rfq-BH2yvo3O.js';
|
|
5
5
|
|
|
6
6
|
type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
|
|
7
7
|
/** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
|
|
8
8
|
* Lives here with the {@link AssetSwap} fields it describes so the market and
|
|
9
9
|
* restore layers share one spelling instead of re-typing the literal. */
|
|
10
10
|
declare const BTC_ASSET_ID = "btc";
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The record fields a wallet-provisioned secret becomes — what
|
|
13
|
+
* {@link swapSecretsToRecord} emits, and what every record type carrying swap
|
|
14
|
+
* secrets embeds.
|
|
15
|
+
*
|
|
16
|
+
* A named type rather than four fields restated per record: the mapper and the
|
|
17
|
+
* records it feeds must agree exactly, and a record that silently omits one of
|
|
18
|
+
* these round-trips a swap whose preimage cannot be re-derived. Embedding makes
|
|
19
|
+
* the omission a compile error instead.
|
|
20
|
+
*
|
|
21
|
+
* **Only `preimageHex` is secret.** `signingDescriptor` and `preimageSaltHex`
|
|
22
|
+
* are public derivation inputs — they must survive a field-mapped backend, but
|
|
23
|
+
* they leak nothing without the seed.
|
|
24
|
+
*/
|
|
25
|
+
interface SwapSecretsProjection {
|
|
26
|
+
/**
|
|
27
|
+
* The wallet descriptor this swap's sender key comes from — a fresh HD
|
|
28
|
+
* child, or a static wallet's `tr(pubkey)`. Public — the signer
|
|
29
|
+
* re-derives from the wallet, so the record carries no key material.
|
|
30
|
+
*/
|
|
31
|
+
signingDescriptor?: string;
|
|
32
|
+
/** P, hex, when it cannot be re-derived from the seed at all: the user
|
|
33
|
+
* supplied it, or the signer cannot sign deterministically. The swap's only
|
|
34
|
+
* claim secret when present. */
|
|
35
|
+
preimageHex?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The salt P derives from, hex, on the salted arm — what a static wallet
|
|
38
|
+
* gets instead of storing P. **Public**, and unlike every other field here
|
|
39
|
+
* it is minted per swap: it is what stops one repeating key from handing
|
|
40
|
+
* every swap the same preimage.
|
|
41
|
+
*/
|
|
42
|
+
preimageSaltHex?: string;
|
|
43
|
+
}
|
|
44
|
+
interface AssetSwap extends SwapSecretsProjection {
|
|
12
45
|
/** Funding txid — the swap's identity. */
|
|
13
46
|
id: string;
|
|
14
47
|
/** 'btc' or a 68-hex asset id. */
|
|
@@ -33,16 +66,6 @@ interface AssetSwap {
|
|
|
33
66
|
/** `sha256(P)`, hex. Public, and how a restore confirms a candidate
|
|
34
67
|
* derivation is the right one. */
|
|
35
68
|
paymentHash?: string;
|
|
36
|
-
/**
|
|
37
|
-
* The wallet descriptor this swap's sender key comes from — a fresh HD
|
|
38
|
-
* child, or a static wallet's `tr(pubkey)`. Public — the signer
|
|
39
|
-
* re-derives from the wallet, so the record carries no key material.
|
|
40
|
-
*/
|
|
41
|
-
signingDescriptor?: string;
|
|
42
|
-
/** P, hex, when it cannot be re-derived from the seed: the user supplied
|
|
43
|
-
* it, or the descriptor is static (shared across swaps, so a derived
|
|
44
|
-
* preimage would collide). The swap's only claim secret when present. */
|
|
45
|
-
preimageHex?: string;
|
|
46
69
|
/** The L1 HTLC's pkScript, hex — the chain-watch key. */
|
|
47
70
|
htlcPkScriptHex?: string;
|
|
48
71
|
htlcLocktime?: number;
|
|
@@ -85,13 +108,70 @@ declare const updateAssetSwapBestEffort: (repository: AssetSwapRepository, id: s
|
|
|
85
108
|
* The record fields a wallet-provisioned secret becomes.
|
|
86
109
|
*
|
|
87
110
|
* `signingDescriptor` is public and always stored — it is what recovers the
|
|
88
|
-
* signer.
|
|
89
|
-
* re-derive P
|
|
111
|
+
* signer. Then at most one of: `preimageHex`, when the wallet says it cannot
|
|
112
|
+
* re-derive P and it becomes the swap's only claim secret; or
|
|
113
|
+
* `preimageSaltHex`, the public input a derivable-but-repeating key needs.
|
|
90
114
|
*/
|
|
91
|
-
declare const swapSecretsToRecord: (secrets: ProvisionedKey | ProvisionedClaimSecret) => {
|
|
115
|
+
declare const swapSecretsToRecord: (secrets: ProvisionedKey | ProvisionedClaimSecret) => SwapSecretsProjection & {
|
|
92
116
|
signingDescriptor: string;
|
|
93
|
-
preimageHex?: string;
|
|
94
117
|
};
|
|
118
|
+
/** Why a wallet cannot produce a swap's preimage. */
|
|
119
|
+
type PreimageBlockedReason =
|
|
120
|
+
/** The record carries no `signingDescriptor`. */
|
|
121
|
+
"no-secrets"
|
|
122
|
+
/** `preimageHex` or `preimageSaltHex` is present but not 32 bytes of hex. */
|
|
123
|
+
| "malformed-record"
|
|
124
|
+
/**
|
|
125
|
+
* Nothing to derive from: a descriptor that repeats across swaps, with
|
|
126
|
+
* neither a stored preimage nor a salt — or one this wallet holds no key
|
|
127
|
+
* for. Merged deliberately: `contractSigner` reports a key it does not
|
|
128
|
+
* hold as a plain `Error` for static wallets and a `ForeignDescriptorError`
|
|
129
|
+
* for HD ones, so splitting the two here would mean matching on message
|
|
130
|
+
* text, which is the thing this type exists to avoid. The `cause` carries
|
|
131
|
+
* whichever it was.
|
|
132
|
+
*/
|
|
133
|
+
| "not-derivable"
|
|
134
|
+
/** Derived, but it does not hash to the record's `paymentHash`. */
|
|
135
|
+
| "hash-mismatch";
|
|
136
|
+
/**
|
|
137
|
+
* The wallet cannot produce this swap's preimage, and which of the four ways
|
|
138
|
+
* is `reason`.
|
|
139
|
+
*
|
|
140
|
+
* Deliberately **not** {@link RefundNotLocallyPossibleError}: that one means
|
|
141
|
+
* "no local refund is possible", and `RfqSwapManager` acts on it by reporting
|
|
142
|
+
* `needs_counterparty`. A claim-path read failure is a different verdict, and
|
|
143
|
+
* borrowing the refund error would have the manager announce one for the
|
|
144
|
+
* other.
|
|
145
|
+
*/
|
|
146
|
+
declare class PreimageNotRecoverableError extends Error {
|
|
147
|
+
readonly reason: PreimageBlockedReason;
|
|
148
|
+
readonly name = "PreimageNotRecoverableError";
|
|
149
|
+
constructor(reason: PreimageBlockedReason, message: string, options?: {
|
|
150
|
+
cause?: unknown;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The preimage a swap record claims with — stored, or re-derived from the
|
|
155
|
+
* wallet.
|
|
156
|
+
*
|
|
157
|
+
* The record-shaped inverse of {@link swapSecretsToRecord}, and the one place
|
|
158
|
+
* that knows which of a record's fields `contractPreimage` needs. Wire claim
|
|
159
|
+
* paths here rather than composing it by hand: a caller that forgets to pass
|
|
160
|
+
* `preimageSaltHex` gets a *wrong* preimage from a wallet that can derive,
|
|
161
|
+
* not an error.
|
|
162
|
+
*
|
|
163
|
+
* Verifies the result against `paymentHash` when the record carries one. The
|
|
164
|
+
* salted arm has two inputs that can be wrong — the key and the salt — where
|
|
165
|
+
* the HD arm had one, and a wrong P otherwise surfaces as an opaque script
|
|
166
|
+
* failure at claim time, long after the mistake.
|
|
167
|
+
*
|
|
168
|
+
* Every refusal is a {@link PreimageNotRecoverableError} carrying a `reason`,
|
|
169
|
+
* so a caller can tell "this record predates the descriptor" from "the salt is
|
|
170
|
+
* corrupt" without reading message text.
|
|
171
|
+
*/
|
|
172
|
+
declare const preimageForSwapRecord: (wallet: IWallet, record: SwapSecretsProjection & {
|
|
173
|
+
paymentHash?: string;
|
|
174
|
+
}) => Promise<Uint8Array>;
|
|
95
175
|
|
|
96
176
|
/** A registry discovery result held for reuse. Refetchable — unlike a swap
|
|
97
177
|
* record, losing it costs one network round trip — but it must survive a cold
|
|
@@ -116,11 +196,12 @@ interface MarketsCacheEntry {
|
|
|
116
196
|
* subset queries.
|
|
117
197
|
*/
|
|
118
198
|
interface AssetSwapRepository extends AsyncDisposable {
|
|
119
|
-
readonly version:
|
|
199
|
+
readonly version: 2;
|
|
120
200
|
/** Insert or replace a swap by id. Store the record whole: `preimageHex`
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
201
|
+
* and `preimageSaltHex` both leave the swap unclaimable if a field-mapped
|
|
202
|
+
* backend drops them — the first is the only claim secret of a swap whose
|
|
203
|
+
* signer cannot derive, the second the public input every other static
|
|
204
|
+
* wallet's preimage derives from. */
|
|
124
205
|
saveSwap(swap: AssetSwap): Promise<void>;
|
|
125
206
|
/** All stored swaps, in no particular order — `getAssetSwaps` is the
|
|
126
207
|
* canonical newest-first read. */
|
|
@@ -134,7 +215,7 @@ interface AssetSwapRepository extends AsyncDisposable {
|
|
|
134
215
|
clear(): Promise<void>;
|
|
135
216
|
}
|
|
136
217
|
declare class InMemoryAssetSwapRepository implements AssetSwapRepository {
|
|
137
|
-
readonly version:
|
|
218
|
+
readonly version: 2;
|
|
138
219
|
private readonly swaps;
|
|
139
220
|
private readonly scanned;
|
|
140
221
|
private readonly markets;
|
|
@@ -363,7 +444,7 @@ declare const validatePlan: (plan: OfferPlan, giveBalance: bigint, dust: bigint)
|
|
|
363
444
|
* infrastructure the wallet already uses for its Boltz swap repository. */
|
|
364
445
|
declare class IndexedDbAssetSwapRepository implements AssetSwapRepository {
|
|
365
446
|
private readonly dbName;
|
|
366
|
-
readonly version:
|
|
447
|
+
readonly version: 2;
|
|
367
448
|
private dbPromise;
|
|
368
449
|
constructor(dbName?: string);
|
|
369
450
|
private ensureDb;
|
|
@@ -1929,4 +2010,4 @@ interface RfqSwapOutcome {
|
|
|
1929
2010
|
txid?: string;
|
|
1930
2011
|
}
|
|
1931
2012
|
|
|
1932
|
-
export { type ArkadeRefundResult, type AssetSwap, type AssetSwapRepository, type AssetSwapStatus, BTC_ASSET_ID, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, InMemoryAssetSwapRepository, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, type MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapContractRegistry, type Tx, type WatchOfferSwapsParams, addAssetSwap, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, getAssetSwaps, getAssetSwapsOrThrow, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapPrograms, swapSecretsToRecord, updateAssetSwap, updateAssetSwapBestEffort, validatePlan, watchOfferSwaps };
|
|
2013
|
+
export { type ArkadeRefundResult, type AssetSwap, type AssetSwapRepository, type AssetSwapStatus, BTC_ASSET_ID, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, InMemoryAssetSwapRepository, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, type MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, type PreimageBlockedReason, PreimageNotRecoverableError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapContractRegistry, type SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, addAssetSwap, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, getAssetSwaps, getAssetSwapsOrThrow, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, preimageForSwapRecord, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapPrograms, swapSecretsToRecord, updateAssetSwap, updateAssetSwapBestEffort, validatePlan, watchOfferSwaps };
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
ONCHAIN_SECONDS_PER_BLOCK,
|
|
18
18
|
ONCHAIN_SEND_PAIR,
|
|
19
19
|
RFQ_TERMINAL_STATES,
|
|
20
|
+
SOLO_REFUND_HEADROOM_SECONDS,
|
|
20
21
|
SWAP_LOCKUP_CONTRACT_KIND,
|
|
21
22
|
SWAP_LOCKUP_CONTRACT_LABEL,
|
|
22
23
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
unilateralRefundWithoutReceiverDelay,
|
|
59
60
|
verifyLockupAddress,
|
|
60
61
|
verifyReceiveInvoice
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-Q4FAYBXS.js";
|
|
62
63
|
|
|
63
64
|
// src/offer.ts
|
|
64
65
|
import { hex as hex2 } from "@scure/base";
|
|
@@ -203,6 +204,8 @@ async function retireSettledOfferContracts(manager, swaps) {
|
|
|
203
204
|
|
|
204
205
|
// src/store.ts
|
|
205
206
|
import { hex } from "@scure/base";
|
|
207
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
208
|
+
import { contractPreimage } from "@arkade-os/sdk";
|
|
206
209
|
var BTC_ASSET_ID = "btc";
|
|
207
210
|
var byNewest = (a, b) => b.createdAt - a.createdAt;
|
|
208
211
|
var getAssetSwapsOrThrow = async (repository) => {
|
|
@@ -257,8 +260,61 @@ var updateAssetSwapBestEffort = async (repository, id, changes) => {
|
|
|
257
260
|
};
|
|
258
261
|
var swapSecretsToRecord = (secrets) => ({
|
|
259
262
|
signingDescriptor: secrets.descriptor,
|
|
260
|
-
..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: hex.encode(secrets.preimage) } : {}
|
|
263
|
+
..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: hex.encode(secrets.preimage) } : {},
|
|
264
|
+
..."preimageSalt" in secrets && secrets.preimageSalt ? { preimageSaltHex: hex.encode(secrets.preimageSalt) } : {}
|
|
261
265
|
});
|
|
266
|
+
var decodeHex32 = (value, field) => {
|
|
267
|
+
const bytes = hex.decode(value);
|
|
268
|
+
if (bytes.length !== 32) {
|
|
269
|
+
throw new Error(`${field} must be 32 bytes, got ${bytes.length}`);
|
|
270
|
+
}
|
|
271
|
+
return bytes;
|
|
272
|
+
};
|
|
273
|
+
var PreimageNotRecoverableError = class extends Error {
|
|
274
|
+
constructor(reason, message, options) {
|
|
275
|
+
super(message, options);
|
|
276
|
+
this.reason = reason;
|
|
277
|
+
}
|
|
278
|
+
reason;
|
|
279
|
+
name = "PreimageNotRecoverableError";
|
|
280
|
+
};
|
|
281
|
+
var preimageForSwapRecord = async (wallet, record) => {
|
|
282
|
+
if (!record.signingDescriptor) {
|
|
283
|
+
throw new PreimageNotRecoverableError(
|
|
284
|
+
"no-secrets",
|
|
285
|
+
"this swap record carries no signing descriptor"
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
let stored;
|
|
289
|
+
let salt;
|
|
290
|
+
try {
|
|
291
|
+
stored = record.preimageHex ? decodeHex32(record.preimageHex, "preimageHex") : void 0;
|
|
292
|
+
salt = record.preimageSaltHex ? decodeHex32(record.preimageSaltHex, "preimageSaltHex") : void 0;
|
|
293
|
+
} catch (cause) {
|
|
294
|
+
throw new PreimageNotRecoverableError(
|
|
295
|
+
"malformed-record",
|
|
296
|
+
`this swap record's secrets projection is unreadable: ${String(cause)}`,
|
|
297
|
+
{ cause }
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
let preimage;
|
|
301
|
+
try {
|
|
302
|
+
preimage = await contractPreimage(wallet, record.signingDescriptor, { stored, salt });
|
|
303
|
+
} catch (cause) {
|
|
304
|
+
throw new PreimageNotRecoverableError(
|
|
305
|
+
"not-derivable",
|
|
306
|
+
`this wallet cannot produce the preimage for ${record.signingDescriptor}`,
|
|
307
|
+
{ cause }
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
if (record.paymentHash && hex.encode(sha256(preimage)) !== record.paymentHash.toLowerCase()) {
|
|
311
|
+
throw new PreimageNotRecoverableError(
|
|
312
|
+
"hash-mismatch",
|
|
313
|
+
"the derived preimage does not match this swap's payment hash: wrong wallet, or a tampered salt"
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
return preimage;
|
|
317
|
+
};
|
|
262
318
|
|
|
263
319
|
// src/offer.ts
|
|
264
320
|
var swapPrograms = {
|
|
@@ -637,7 +693,7 @@ var validatePlan = (plan, giveBalance, dust) => {
|
|
|
637
693
|
// src/repository.ts
|
|
638
694
|
var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
|
|
639
695
|
var InMemoryAssetSwapRepository = class {
|
|
640
|
-
version =
|
|
696
|
+
version = 2;
|
|
641
697
|
swaps = /* @__PURE__ */ new Map();
|
|
642
698
|
scanned = /* @__PURE__ */ new Set();
|
|
643
699
|
markets = /* @__PURE__ */ new Map();
|
|
@@ -699,7 +755,7 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
699
755
|
this.dbName = dbName;
|
|
700
756
|
}
|
|
701
757
|
dbName;
|
|
702
|
-
version =
|
|
758
|
+
version = 2;
|
|
703
759
|
// the promise, not the resolved database: openDatabase bumps a refcount on
|
|
704
760
|
// every call including cache hits, while dispose closes once, so two
|
|
705
761
|
// concurrent first calls would strand the refcount above zero and leak the
|
|
@@ -1025,7 +1081,7 @@ async function watchOfferSwaps({
|
|
|
1025
1081
|
// src/claim.ts
|
|
1026
1082
|
import { hex as hex6 } from "@scure/base";
|
|
1027
1083
|
import { ripemd160 } from "@noble/hashes/legacy.js";
|
|
1028
|
-
import { sha256 as
|
|
1084
|
+
import { sha256 as sha2563 } from "@noble/hashes/sha2.js";
|
|
1029
1085
|
import {
|
|
1030
1086
|
CSVMultisigTapscript as CSVMultisigTapscript2,
|
|
1031
1087
|
claimWithPreimageIdentity,
|
|
@@ -1034,7 +1090,7 @@ import {
|
|
|
1034
1090
|
|
|
1035
1091
|
// src/refund.ts
|
|
1036
1092
|
import { base64 as base643, hex as hex5 } from "@scure/base";
|
|
1037
|
-
import { sha256 } from "@noble/hashes/sha2.js";
|
|
1093
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha2.js";
|
|
1038
1094
|
import {
|
|
1039
1095
|
CSVMultisigTapscript,
|
|
1040
1096
|
ConditionWitness,
|
|
@@ -1115,7 +1171,7 @@ async function findLockupVtxos(indexer, swapPkScript) {
|
|
|
1115
1171
|
}
|
|
1116
1172
|
return out;
|
|
1117
1173
|
}
|
|
1118
|
-
var hashesTo = (candidate, paymentHash) => hex5.encode(
|
|
1174
|
+
var hashesTo = (candidate, paymentHash) => hex5.encode(sha2562(candidate)) === paymentHash;
|
|
1119
1175
|
var candidateWitnessItems = (tx, inputIndex) => [
|
|
1120
1176
|
...getArkPsbtFields(tx, inputIndex, ConditionWitness).flat(),
|
|
1121
1177
|
...tx.getInput(inputIndex).finalScriptWitness ?? []
|
|
@@ -1284,7 +1340,7 @@ async function pushClaim(ark, input) {
|
|
|
1284
1340
|
}
|
|
1285
1341
|
}
|
|
1286
1342
|
const committed = input.script.options.preimageHash;
|
|
1287
|
-
if (hex6.encode(ripemd160(
|
|
1343
|
+
if (hex6.encode(ripemd160(sha2563(input.preimage))) !== hex6.encode(committed)) {
|
|
1288
1344
|
throw new Error("preimage does not match the covenant's payment hash");
|
|
1289
1345
|
}
|
|
1290
1346
|
const info = await ark.getInfo();
|
|
@@ -2175,6 +2231,7 @@ export {
|
|
|
2175
2231
|
ONCHAIN_RECEIVE_PAIR,
|
|
2176
2232
|
ONCHAIN_SECONDS_PER_BLOCK,
|
|
2177
2233
|
ONCHAIN_SEND_PAIR,
|
|
2234
|
+
PreimageNotRecoverableError,
|
|
2178
2235
|
QUOTE_OPTIONS,
|
|
2179
2236
|
REFUND_MTP_LAG_SECONDS,
|
|
2180
2237
|
RFQ_RESOLVED_STATES,
|
|
@@ -2182,6 +2239,7 @@ export {
|
|
|
2182
2239
|
RFQ_TERMINAL_STATES,
|
|
2183
2240
|
RefundNotLocallyPossibleError,
|
|
2184
2241
|
RfqSwapManager,
|
|
2242
|
+
SOLO_REFUND_HEADROOM_SECONDS,
|
|
2185
2243
|
SWAP_LOCKUP_CONTRACT_KIND,
|
|
2186
2244
|
SWAP_LOCKUP_CONTRACT_LABEL,
|
|
2187
2245
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
@@ -2229,6 +2287,7 @@ export {
|
|
|
2229
2287
|
onchainReceiveRequest,
|
|
2230
2288
|
onchainSendRequest,
|
|
2231
2289
|
paymentHashOf,
|
|
2290
|
+
preimageForSwapRecord,
|
|
2232
2291
|
pushClaim,
|
|
2233
2292
|
pushRefundWithoutReceiver,
|
|
2234
2293
|
readLockupFate,
|
package/dist/nostr.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(nostr_exports, {
|
|
|
33
33
|
RFQ_AD_KIND: () => RFQ_AD_KIND,
|
|
34
34
|
RFQ_DIRECTED_KIND: () => RFQ_DIRECTED_KIND,
|
|
35
35
|
RelayUnavailable: () => RelayUnavailable,
|
|
36
|
+
TransportClosed: () => TransportClosed,
|
|
36
37
|
nostrRfqTransport: () => nostrRfqTransport
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(nostr_exports);
|
|
@@ -90,6 +91,8 @@ var SwapRefusal = class extends Error {
|
|
|
90
91
|
}
|
|
91
92
|
};
|
|
92
93
|
var MIN_HEADROOM_SECONDS = 90 * 60;
|
|
94
|
+
var SEQUENCE_GRANULARITY_SECONDS = 512;
|
|
95
|
+
var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
|
|
93
96
|
var MIN_CLAIM_WINDOW_SECONDS = 30 * 60;
|
|
94
97
|
|
|
95
98
|
// src/nostr.ts
|
|
@@ -105,6 +108,12 @@ var RelayUnavailable = class extends Error {
|
|
|
105
108
|
this.reasons = reasons;
|
|
106
109
|
}
|
|
107
110
|
};
|
|
111
|
+
var TransportClosed = class extends Error {
|
|
112
|
+
constructor() {
|
|
113
|
+
super("transport closed before the solver replied");
|
|
114
|
+
this.name = "TransportClosed";
|
|
115
|
+
}
|
|
116
|
+
};
|
|
108
117
|
var closeReasons = (raw) => raw.map((entry) => {
|
|
109
118
|
if (typeof entry === "string") return entry;
|
|
110
119
|
const { url, reason } = entry ?? {};
|
|
@@ -204,6 +213,7 @@ var nostrRfqTransport = (options) => {
|
|
|
204
213
|
},
|
|
205
214
|
async close() {
|
|
206
215
|
closed = true;
|
|
216
|
+
for (const waiter of waiters.values()) waiter.reject(new TransportClosed());
|
|
207
217
|
waiters.clear();
|
|
208
218
|
if (ownsPool) pool.close(relays);
|
|
209
219
|
else subscription.close();
|
|
@@ -215,5 +225,6 @@ var nostrRfqTransport = (options) => {
|
|
|
215
225
|
RFQ_AD_KIND,
|
|
216
226
|
RFQ_DIRECTED_KIND,
|
|
217
227
|
RelayUnavailable,
|
|
228
|
+
TransportClosed,
|
|
218
229
|
nostrRfqTransport
|
|
219
230
|
});
|
package/dist/nostr.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as RfqTransport } from './rfq-
|
|
1
|
+
import { a as RfqTransport } from './rfq-BH2yvo3O.cjs';
|
|
2
2
|
import { SimplePool } from 'nostr-tools';
|
|
3
3
|
import '@arkade-os/sdk';
|
|
4
4
|
|
|
@@ -70,6 +70,18 @@ declare class RelayUnavailable extends Error {
|
|
|
70
70
|
readonly reasons: string[];
|
|
71
71
|
constructor(reasons: string[]);
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* `close()` was called while a negotiation was still waiting on a reply.
|
|
75
|
+
*
|
|
76
|
+
* Distinct from both a timeout and {@link RelayUnavailable}, which describe the
|
|
77
|
+
* wire; this describes a decision on our own side of it. A caller that closed
|
|
78
|
+
* deliberately — a user leaving the screen, a flow abandoning its request — can
|
|
79
|
+
* match on this and stay quiet, rather than reporting a solver failure that
|
|
80
|
+
* never happened.
|
|
81
|
+
*/
|
|
82
|
+
declare class TransportClosed extends Error {
|
|
83
|
+
constructor();
|
|
84
|
+
}
|
|
73
85
|
interface NostrRfqOptions {
|
|
74
86
|
/** Relay URLs from the solver's card. The rendezvous, not solver endpoints. */
|
|
75
87
|
relays: string[];
|
|
@@ -95,4 +107,4 @@ interface NostrRfqOptions {
|
|
|
95
107
|
*/
|
|
96
108
|
declare const nostrRfqTransport: (options: NostrRfqOptions) => RfqTransport;
|
|
97
109
|
|
|
98
|
-
export { type NostrRfqOptions, RFQ_AD_KIND, RFQ_DIRECTED_KIND, RelayUnavailable, nostrRfqTransport };
|
|
110
|
+
export { type NostrRfqOptions, RFQ_AD_KIND, RFQ_DIRECTED_KIND, RelayUnavailable, TransportClosed, nostrRfqTransport };
|
package/dist/nostr.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as RfqTransport } from './rfq-
|
|
1
|
+
import { a as RfqTransport } from './rfq-BH2yvo3O.js';
|
|
2
2
|
import { SimplePool } from 'nostr-tools';
|
|
3
3
|
import '@arkade-os/sdk';
|
|
4
4
|
|
|
@@ -70,6 +70,18 @@ declare class RelayUnavailable extends Error {
|
|
|
70
70
|
readonly reasons: string[];
|
|
71
71
|
constructor(reasons: string[]);
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* `close()` was called while a negotiation was still waiting on a reply.
|
|
75
|
+
*
|
|
76
|
+
* Distinct from both a timeout and {@link RelayUnavailable}, which describe the
|
|
77
|
+
* wire; this describes a decision on our own side of it. A caller that closed
|
|
78
|
+
* deliberately — a user leaving the screen, a flow abandoning its request — can
|
|
79
|
+
* match on this and stay quiet, rather than reporting a solver failure that
|
|
80
|
+
* never happened.
|
|
81
|
+
*/
|
|
82
|
+
declare class TransportClosed extends Error {
|
|
83
|
+
constructor();
|
|
84
|
+
}
|
|
73
85
|
interface NostrRfqOptions {
|
|
74
86
|
/** Relay URLs from the solver's card. The rendezvous, not solver endpoints. */
|
|
75
87
|
relays: string[];
|
|
@@ -95,4 +107,4 @@ interface NostrRfqOptions {
|
|
|
95
107
|
*/
|
|
96
108
|
declare const nostrRfqTransport: (options: NostrRfqOptions) => RfqTransport;
|
|
97
109
|
|
|
98
|
-
export { type NostrRfqOptions, RFQ_AD_KIND, RFQ_DIRECTED_KIND, RelayUnavailable, nostrRfqTransport };
|
|
110
|
+
export { type NostrRfqOptions, RFQ_AD_KIND, RFQ_DIRECTED_KIND, RelayUnavailable, TransportClosed, nostrRfqTransport };
|