@arkade-os/swap 0.0.4 → 0.0.6
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 +201 -40
- package/dist/{chunk-DLM6BVTB.js → chunk-Q4FAYBXS.js} +6 -4
- package/dist/chunk-WGRU2DBF.js +38 -0
- package/dist/index.cjs +211 -93
- package/dist/index.d.cts +47 -151
- package/dist/index.d.ts +47 -151
- package/dist/index.js +125 -41
- package/dist/nostr.cjs +11 -0
- package/dist/nostr.d.cts +17 -4
- package/dist/nostr.d.ts +17 -4
- package/dist/nostr.js +9 -1
- package/dist/repositories/realm/index.cjs +138 -0
- package/dist/repositories/realm/index.d.cts +103 -0
- package/dist/repositories/realm/index.d.ts +103 -0
- package/dist/repositories/realm/index.js +108 -0
- package/dist/repositories/sqlite/index.cjs +163 -0
- package/dist/repositories/sqlite/index.d.cts +63 -0
- package/dist/repositories/sqlite/index.d.ts +63 -0
- package/dist/repositories/sqlite/index.js +138 -0
- package/dist/repository-BwnZ8N62.d.cts +236 -0
- package/dist/repository-BwnZ8N62.d.ts +236 -0
- package/dist/{rfq-DjZlesr4.d.cts → rfq-3jWha5xA.d.cts} +40 -16
- package/dist/{rfq-DjZlesr4.d.ts → rfq-3jWha5xA.d.ts} +40 -16
- package/package.json +24 -4
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Client-side [Arkade Intents](https://arkade.money) asset swaps: discover markets, quote and
|
|
4
4
|
validate, create offers, track them, cancel them, and rebuild the whole record set from chain after
|
|
5
|
-
a wallet restore. Framework-free TypeScript over `@arkade-os/sdk`: the core API and
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
a wallet restore. Framework-free TypeScript over `@arkade-os/sdk`: the core API uses no DOM and no
|
|
6
|
+
Node-specific APIs, so it runs in Node, the browser, and React Native alike. Four storage backends
|
|
7
|
+
ship — in-memory (anywhere, nothing outlives the process), IndexedDB (browser), SQLite and Realm
|
|
8
|
+
(React Native, on subpath entry points) — see "Storage backends" below.
|
|
9
9
|
|
|
10
10
|
## Roles
|
|
11
11
|
|
|
@@ -100,11 +100,78 @@ arkade:BTC|asset` (quote, then take by funding an offer from layer 1).
|
|
|
100
100
|
|
|
101
101
|
Everything the package persists — swap records, the restore-scan cursor, and the markets cache —
|
|
102
102
|
goes through a single `AssetSwapRepository`, following the Arkade repository convention
|
|
103
|
-
(versioned interface, `AsyncDisposable`, one backend per platform).
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
(versioned interface, `AsyncDisposable`, one backend per platform). Construct one and pass it
|
|
104
|
+
wherever the package asks for a repository; `discoverMarkets` also accepts none, for a one-shot
|
|
105
|
+
uncached discovery.
|
|
106
|
+
|
|
107
|
+
## Storage backends
|
|
108
|
+
|
|
109
|
+
| Backend | Import from | For |
|
|
110
|
+
| ------------------------------ | ------------------------------------- | ----------------------------------------------- |
|
|
111
|
+
| `InMemoryAssetSwapRepository` | `@arkade-os/swap` | tests, one-shot scripts — nothing survives exit |
|
|
112
|
+
| `IndexedDbAssetSwapRepository` | `@arkade-os/swap` | the browser (or a polyfilled IndexedDB) |
|
|
113
|
+
| `SQLiteAssetSwapRepository` | `@arkade-os/swap/repositories/sqlite` | React Native, over your SQLite driver |
|
|
114
|
+
| `RealmAssetSwapRepository` | `@arkade-os/swap/repositories/realm` | React Native, over your Realm instance |
|
|
115
|
+
|
|
116
|
+
Neither subpath adds a dependency: they take the SDK's structural `SQLExecutor` / `RealmLike`
|
|
117
|
+
handles, so you pass the database you already opened.
|
|
118
|
+
|
|
119
|
+
**Records are stored whole.** The SQLite and Realm backends serialize each record to **JSON** in a
|
|
120
|
+
`data` column, with only `status` / `createdAt` mapped out for querying — so a field they do not
|
|
121
|
+
know about survives, which is what the `quote`-shaped extension in `MIGRATION.md` relies on. JSON is
|
|
122
|
+
the boundary, though, and it is narrower than IndexedDB's structured clone: a `Date` in a
|
|
123
|
+
consumer-added field comes back an ISO **string**, a `Set` or `Map` comes back empty, and a `bigint`
|
|
124
|
+
makes `saveSwap` **throw**. `AssetSwap` itself is JSON-safe by design (amounts are strings); keep
|
|
125
|
+
your own added fields that way too.
|
|
126
|
+
|
|
127
|
+
### SQLite
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { SQLiteAssetSwapRepository } from "@arkade-os/swap/repositories/sqlite";
|
|
131
|
+
import { SQLiteWalletRepository, type SQLExecutor } from "@arkade-os/sdk/repositories/sqlite";
|
|
132
|
+
|
|
133
|
+
const db = await SQLite.openDatabaseAsync("wallet.db"); // expo-sqlite
|
|
134
|
+
// Build the executor ONCE and hand this same instance to every repository on
|
|
135
|
+
// the database: the SDK serializes transactions in a chain keyed by this
|
|
136
|
+
// object, so a per-repository literal splits the chain and two BEGIN
|
|
137
|
+
// IMMEDIATEs can interleave.
|
|
138
|
+
const executor: SQLExecutor = {
|
|
139
|
+
run: (sql, params) => db.runAsync(sql, params ?? []),
|
|
140
|
+
get: (sql, params) => db.getFirstAsync(sql, params ?? []),
|
|
141
|
+
all: (sql, params) => db.getAllAsync(sql, params ?? []),
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const swaps = new SQLiteAssetSwapRepository(executor);
|
|
145
|
+
const wallet = new SQLiteWalletRepository(executor); // same instance
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Sharing the executor is **necessary** for that serialization, not sufficient for atomicity across
|
|
149
|
+
all wallet storage: it disciplines the repositories that enter the chain — this one,
|
|
150
|
+
`SQLiteIntentRepository`, `SQLiteVirtualTxRepository`, and the wallet repository's migration path —
|
|
151
|
+
and nothing else. `SQLiteWalletRepository` and `SQLiteContractRepository` still write raw, so their
|
|
152
|
+
writes can land inside whatever transaction happens to be open.
|
|
153
|
+
|
|
154
|
+
Three tables land in your database, prefixed `arkade_`: `arkade_asset_swaps`,
|
|
155
|
+
`arkade_asset_swap_scanned_txids`, `arkade_asset_swap_markets`. Pass `{ prefix: "myapp_" }` if your
|
|
156
|
+
app already owns those names.
|
|
157
|
+
|
|
158
|
+
### Realm
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import Realm from "realm";
|
|
162
|
+
import { AssetSwapRealmSchemas, RealmAssetSwapRepository } from "@arkade-os/swap/repositories/realm";
|
|
163
|
+
import { ArkRealmSchemas } from "@arkade-os/sdk/repositories/realm";
|
|
164
|
+
|
|
165
|
+
const realm = await Realm.open({
|
|
166
|
+
schema: [...ArkRealmSchemas, ...AssetSwapRealmSchemas, ...yourOwnSchemas],
|
|
167
|
+
schemaVersion: YOUR_VERSION, // these schemas are new: bump yours when adding them
|
|
168
|
+
});
|
|
169
|
+
const swaps = new RealmAssetSwapRepository(realm);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Three classes land in your Realm namespace: `ArkadeAssetSwap`, `ArkadeAssetSwapScannedTxid`,
|
|
173
|
+
`ArkadeAssetSwapMarketsCache`. Unlike SQLite there is no prefix option — a Realm schema name is
|
|
174
|
+
baked into the schema objects you register — so reconcile against your own models by name.
|
|
108
175
|
|
|
109
176
|
## Creating an offer
|
|
110
177
|
|
|
@@ -436,34 +503,42 @@ descriptor, which is public, and `contractSigner(wallet, descriptor)` recovers t
|
|
|
436
503
|
|
|
437
504
|
What each swap stores, and what is recoverable:
|
|
438
505
|
|
|
439
|
-
| Wallet answers with
|
|
440
|
-
|
|
|
441
|
-
| fresh HD descriptor
|
|
442
|
-
| static `tr(pubkey)`
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
506
|
+
| Wallet answers with | Spending key | Preimage (when the leg needs one) | Secret at rest |
|
|
507
|
+
| ------------------------- | --------------------- | ------------------------------------- | ----------------- |
|
|
508
|
+
| fresh HD descriptor | re-derives from seed | derives deterministically | none |
|
|
509
|
+
| static `tr(pubkey)` | the wallet's identity | derives from a public per-swap salt | none |
|
|
510
|
+
| a signer that cannot sign | | | |
|
|
511
|
+
| deterministically | the wallet's identity | random, stored on the record | the preimage only |
|
|
512
|
+
|
|
513
|
+
The preimage split follows the **descriptor's shape**, not the wallet's type. An HD child
|
|
514
|
+
descriptor is unique to its swap, so `sha256(sign_det(...))` over the key alone is safe. A static
|
|
515
|
+
descriptor is the same key for every swap, so that derivation would repeat across swaps — one
|
|
516
|
+
solver learning its own preimage would learn every other swap's — and the uniqueness has to come
|
|
517
|
+
from the message instead: the SDK mints 32 random bytes per swap, signs a **salted** message, and
|
|
518
|
+
stores the salt in the clear.
|
|
519
|
+
|
|
520
|
+
**The salt is not a secret.** Knowing it yields nothing without the seed, which is the whole
|
|
521
|
+
difference from the preimage it replaces: the record goes from carrying a per-swap _secret_ to a
|
|
522
|
+
per-swap _public_ value, exactly what `signingDescriptor` already is. Recoverability is unchanged
|
|
523
|
+
in shape — keep the record and the swap recovers from the seed.
|
|
524
|
+
|
|
525
|
+
Only a signer that cannot sign deterministically at all — an external or extension signer — still
|
|
526
|
+
gets a random stored preimage. `mustPersistPreimage` says which you got, and it is the only thing
|
|
527
|
+
to branch on. A stored preimage remains the one secret at rest in the design, and it is never a
|
|
528
|
+
private key.
|
|
450
529
|
|
|
451
530
|
```ts
|
|
452
531
|
const swap = await requestOnchainSend(/* … */);
|
|
453
|
-
// `swapSecretsToRecord` stores the public descriptor always,
|
|
454
|
-
//
|
|
532
|
+
// `swapSecretsToRecord` stores the public descriptor always, then whichever of
|
|
533
|
+
// `preimageSaltHex` (derivable) or `preimageHex` (not) the wallet produced.
|
|
455
534
|
await saveSwap({ ...record, ...swapSecretsToRecord(swap.secrets) });
|
|
456
535
|
|
|
457
|
-
// Later, from the seed plus
|
|
458
|
-
// corridor gave us one for: a lightning send's P belongs to the
|
|
459
|
-
// this throws on those records rather than inventing something the
|
|
460
|
-
// never match. `LIGHTNING_SEND_PAIR` is exported from this package.
|
|
461
|
-
if (record.
|
|
462
|
-
const preimage = await
|
|
463
|
-
wallet,
|
|
464
|
-
record.signingDescriptor,
|
|
465
|
-
record.preimageHex ? hex.decode(record.preimageHex) : undefined,
|
|
466
|
-
);
|
|
536
|
+
// Later, from the seed plus the record's public fields. Only ask for a
|
|
537
|
+
// preimage the corridor gave us one for: a lightning send's P belongs to the
|
|
538
|
+
// payee, so this throws on those records rather than inventing something the
|
|
539
|
+
// chain will never match. `LIGHTNING_SEND_PAIR` is exported from this package.
|
|
540
|
+
if (record.pair !== LIGHTNING_SEND_PAIR) {
|
|
541
|
+
const preimage = await preimageForSwapRecord(wallet, record);
|
|
467
542
|
}
|
|
468
543
|
|
|
469
544
|
// For a refund, take the composition instead of the guard: it turns all three
|
|
@@ -481,21 +556,45 @@ terminal: the lockup stays funded and watched, a solver claim still ends the swa
|
|
|
481
556
|
`pending`. The manager reports the same state when nothing is wired to act (`enableAutoActions:
|
|
482
557
|
false`, or no callbacks) and the window has passed.
|
|
483
558
|
|
|
559
|
+
`preimageForSwapRecord` is the read path to wire, not a hand-rolled `contractPreimage` call: it
|
|
560
|
+
knows which of the record's fields are derivation inputs, and it verifies the result against
|
|
561
|
+
`paymentHash`. A caller that forgets to pass the salt gets a _wrong_ preimage from a wallet that can
|
|
562
|
+
derive, not an error — and that surfaces as an opaque script failure at claim time.
|
|
563
|
+
|
|
564
|
+
Every refusal is a `PreimageNotRecoverableError` carrying a `reason`: `no-secrets` (the record
|
|
565
|
+
predates the descriptor), `malformed-record`, `not-derivable` (nothing to derive from, or a key this
|
|
566
|
+
wallet does not hold), or `hash-mismatch` (derived, but wrong — a tampered salt or the wrong seed).
|
|
567
|
+
Branch on `reason`, never on message text. It is deliberately **not**
|
|
568
|
+
`RefundNotLocallyPossibleError`: that one means no local refund is possible and `RfqSwapManager`
|
|
569
|
+
reports `needs_counterparty` for it, which is a different verdict from a claim-path read failing.
|
|
570
|
+
|
|
484
571
|
A caller-supplied preimage keeps `signingDescriptor` for the sender key and stores only
|
|
485
572
|
`preimageHex` as secret material.
|
|
486
573
|
|
|
487
574
|
On an HD wallet each swap **allocates** its own descriptor rather than peeking at the current one:
|
|
488
575
|
two swaps sharing a descriptor derive the _identical_ preimage, so one solver learning its own
|
|
489
|
-
preimage would learn the other swap's. (Static wallets share their one descriptor by design —
|
|
490
|
-
is
|
|
576
|
+
preimage would learn the other swap's. (Static wallets share their one descriptor by design — the
|
|
577
|
+
per-swap salt is what separates their preimages instead.) On restore, `adoptContractDescriptor`
|
|
491
578
|
(from `@arkade-os/sdk`) moves the wallet's watermark past a restored record's index so it cannot be
|
|
492
579
|
handed out twice; a static descriptor names no index and adopts as a no-op.
|
|
493
580
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
581
|
+
Two derivations, picked by the descriptor's shape:
|
|
582
|
+
|
|
583
|
+
```
|
|
584
|
+
HD child sha256(sign_det(sha256("Arkade-RFQ-Preimage-v1" ‖ xonly(32) ‖ u32le(0))))
|
|
585
|
+
static/salted sha256(sign_det(sha256("Arkade-Contract-Preimage-Salted-v1" ‖ xonly(32) ‖ salt(32))))
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
The first mirrors NArk's Boltz scheme (`SwapsManagementService.cs:128-160`) with an RFQ-scoped tag.
|
|
589
|
+
NArk has no RFQ corridor yet, so this tag defines the scheme rather than matching one; it is
|
|
590
|
+
deliberately distinct from the Boltz tag so one wallet key cannot derive the same preimage for both
|
|
591
|
+
corridors.
|
|
592
|
+
|
|
593
|
+
The salted tag is corridor-generic where the first is not, and that asymmetry is deliberate: the v1
|
|
594
|
+
tags must be per-corridor because v1 pins its message index, leaving the tag as the only separation
|
|
595
|
+
between two corridors reaching the same key. The salted form mints a fresh salt per swap, so no two
|
|
596
|
+
swaps share a message within a corridor or across two — the salt carries the separation, and the tag
|
|
597
|
+
names the layer rather than the corridor.
|
|
499
598
|
|
|
500
599
|
**Not covered:** seed-only discovery after the swap repository is wiped. An unspent L1 HTLC reveals
|
|
501
600
|
too little public quote data to rediscover, so the record remains required.
|
|
@@ -508,9 +607,71 @@ before later-funded addresses are found. Keep the swap repository in backups (re
|
|
|
508
607
|
each record's descriptor via `adoptContractDescriptor`), or raise `gapLimit` on seed-only restores
|
|
509
608
|
after heavy swap use.
|
|
510
609
|
|
|
610
|
+
## Upgrading from 0.0.3
|
|
611
|
+
|
|
612
|
+
0.0.1–0.0.3 are published. Under npm's 0.0.x rules `^0.0.3` resolves to exactly 0.0.3, so nothing
|
|
613
|
+
auto-upgrades into the changes below — but a consumer that does upgrade meets them all in one jump,
|
|
614
|
+
so they are written as one migration rather than per-release fragments.
|
|
615
|
+
|
|
616
|
+
**Key provisioning moved into the SDK.** `packages/swap/src/secrets.ts` is gone. `deriveSwapSecrets`,
|
|
617
|
+
`randomSwapSecrets`, `preimageForRfqSecrets`, `senderIdentityForRfqSecrets`, `rfqSecretsToRecord`,
|
|
618
|
+
`rfqSecretsOfRecord`, `isPerSwapDescriptor`, `RFQ_PREIMAGE_TAG` and `SwapSecrets` no longer exist.
|
|
619
|
+
Import `provisionRefundKey`, `provisionClaimSecret`, `contractSigner`, `contractPreimage`,
|
|
620
|
+
`isPerArtifactDescriptor` and `ARKADE_SWAP_PREIMAGE_TAG` from `@arkade-os/sdk` instead;
|
|
621
|
+
`swapSecretsToRecord` and `senderIdentityForSwapRecord` stay in this package. No consumer branches
|
|
622
|
+
on wallet type any more, and no swap record can carry a private key.
|
|
623
|
+
|
|
624
|
+
**`contractPreimage` takes an options object.** `contractPreimage(wallet, descriptor, stored?)`
|
|
625
|
+
became `contractPreimage(wallet, descriptor, { stored?, salt? })`. Prefer `preimageForSwapRecord`,
|
|
626
|
+
which reads both fields off the record and verifies against `paymentHash`.
|
|
627
|
+
|
|
628
|
+
**Static wallets derive their preimage instead of storing it.** New records from such wallets carry
|
|
629
|
+
`preimageSaltHex` and no `preimageHex`; `mustPersistPreimage` is now `false` for them, so the
|
|
630
|
+
"persist the preimage" warning stops firing. Nothing at rest is secret unless the signer cannot sign
|
|
631
|
+
deterministically at all.
|
|
632
|
+
|
|
633
|
+
**`AssetSwap` gains `preimageSaltHex?`, and `AssetSwapRepository.version` is `2`.** External
|
|
634
|
+
repository implementations must recompile — deliberately, because a field-mapped backend that drops
|
|
635
|
+
`preimageSaltHex` leaves the swap unclaimable exactly as one dropping `preimageHex` does. Records
|
|
636
|
+
written by 0.0.1–0.0.3 need no rewrite and no migration: the field is optional, older rows resolve
|
|
637
|
+
through their stored `preimageHex` or their HD descriptor, and `DB_VERSION` is unchanged.
|
|
638
|
+
|
|
511
639
|
## Breaking changes on this branch (pre-release migration notes)
|
|
512
640
|
|
|
513
|
-
|
|
641
|
+
Notes from before 0.0.1, kept for consumers who tracked the branch.
|
|
642
|
+
|
|
643
|
+
- **Every derived address changed again, in both corridors — the unilateral ladder was re-spaced.**
|
|
644
|
+
`unilateralRefundDelay` now sits **level with** `claimDelay` instead of one 512s step above it,
|
|
645
|
+
and `unilateralRefundWithoutReceiverDelay` sits `SOLO_REFUND_HEADROOM_SECONDS` (4096s, newly
|
|
646
|
+
exported) above it instead of two steps. The old ladder spaced all three leaves one step apart as
|
|
647
|
+
though they were interchangeable rungs; they are not. Only `unilateralRefundWithoutReceiver` is a
|
|
648
|
+
solo path for the funder, so it is the only one whose timing can steal, and one 512s tick was
|
|
649
|
+
never enough for a claimant to complete a unilateral exit in. The two-signature refund needs no
|
|
650
|
+
separation at all, since neither party can spend that leaf alone. This tracks the reference
|
|
651
|
+
solver's [lightning-swap-service#81](https://github.com/arkade-os/lightning-swap-service/pull/81);
|
|
652
|
+
the two derivations must produce **the same three delay values** for the same operator, which is
|
|
653
|
+
what keeps the derived addresses identical. **Deployment must be coordinated** on the same terms
|
|
654
|
+
as the entry below: for a quote not yet funded, a mismatch refuses it at `verifyLockupAddress`
|
|
655
|
+
rather than losing funds.
|
|
656
|
+
|
|
657
|
+
**An in-flight lockup funded before the upgrade needs care, and the entry below understates
|
|
658
|
+
this.** The delays are not quote fields and are not persisted on the swap record
|
|
659
|
+
(`AssetSwap` keeps `swapPkScript`, not `claimDelay`), and `RfqSwap`'s own doc tells callers to
|
|
660
|
+
*rebuild* the script on restart from the quote's binding fields — which re-derives the delays
|
|
661
|
+
under whatever ladder is compiled in. So a trader who funded on `0.0.4`, upgraded, and restarted
|
|
662
|
+
rebuilds a **new** address, and `refundIfUnresolved` finds no VTXOs there and returns
|
|
663
|
+
`nothing_to_refund` — a terminal-sounding answer for money still locked at the old script, with
|
|
664
|
+
`refundLocktime` still ticking. Until the delays are persisted and rebuilt from the stored value,
|
|
665
|
+
drain in-flight lockups before upgrading, or rebuild the old script from the pre-upgrade delays
|
|
666
|
+
by hand. This is a pre-existing gap that any address-moving change hits, not one this change
|
|
667
|
+
introduces.
|
|
668
|
+
|
|
669
|
+
`unilateralClaimDelay`'s BIP68 ceiling tightened to reserve the full headroom rather than two
|
|
670
|
+
steps. Note this guard alone is **not** mirrored in the reference solver, which still rejects
|
|
671
|
+
only above `0xffff * 512`: for an operator `unilateralExitDelay` in `(33549824, 33553920]`
|
|
672
|
+
seconds the trader throws here while the solver quotes and then fails deeper in its own script
|
|
673
|
+
build. Both refuse, at different seams with different messages, so it is a diagnosability wart
|
|
674
|
+
rather than a fund risk — and the window is unreachable in practice (~388 days).
|
|
514
675
|
|
|
515
676
|
- **`secrets.ts` is gone; key provisioning moved into `@arkade-os/sdk`.** This package no longer
|
|
516
677
|
derives, mints, or names keys. It asks the SDK for what the leg needs — `provisionRefundKey(wallet)`
|
|
@@ -546,21 +546,22 @@ var relayTransport = (relayUrl, options) => {
|
|
|
546
546
|
};
|
|
547
547
|
};
|
|
548
548
|
var SEQUENCE_GRANULARITY_SECONDS = 512;
|
|
549
|
+
var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
|
|
549
550
|
var unilateralClaimDelay = (serverExitDelaySeconds) => {
|
|
550
551
|
if (!Number.isFinite(serverExitDelaySeconds) || serverExitDelaySeconds < SEQUENCE_GRANULARITY_SECONDS) {
|
|
551
552
|
throw new Error(
|
|
552
553
|
`server exit delay must be at least ${SEQUENCE_GRANULARITY_SECONDS}s of seconds, got ${serverExitDelaySeconds}`
|
|
553
554
|
);
|
|
554
555
|
}
|
|
555
|
-
if (serverExitDelaySeconds >
|
|
556
|
+
if (serverExitDelaySeconds > 65535 * SEQUENCE_GRANULARITY_SECONDS - SOLO_REFUND_HEADROOM_SECONDS) {
|
|
556
557
|
throw new Error(
|
|
557
|
-
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the
|
|
558
|
+
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the solo refund's headroom is stacked above it`
|
|
558
559
|
);
|
|
559
560
|
}
|
|
560
561
|
return Math.ceil(serverExitDelaySeconds / SEQUENCE_GRANULARITY_SECONDS) * SEQUENCE_GRANULARITY_SECONDS;
|
|
561
562
|
};
|
|
562
|
-
var unilateralRefundDelay = (claimDelay) => claimDelay
|
|
563
|
-
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay +
|
|
563
|
+
var unilateralRefundDelay = (claimDelay) => claimDelay;
|
|
564
|
+
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay + SOLO_REFUND_HEADROOM_SECONDS;
|
|
564
565
|
function lightningSendVtxoScript(params) {
|
|
565
566
|
const seconds = (value) => ({
|
|
566
567
|
type: "seconds",
|
|
@@ -1169,6 +1170,7 @@ export {
|
|
|
1169
1170
|
assertFundable,
|
|
1170
1171
|
httpTransport,
|
|
1171
1172
|
relayTransport,
|
|
1173
|
+
SOLO_REFUND_HEADROOM_SECONDS,
|
|
1172
1174
|
unilateralClaimDelay,
|
|
1173
1175
|
unilateralRefundDelay,
|
|
1174
1176
|
unilateralRefundWithoutReceiverDelay,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/repository.ts
|
|
2
|
+
var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
|
|
3
|
+
var InMemoryAssetSwapRepository = class {
|
|
4
|
+
version = 2;
|
|
5
|
+
swaps = /* @__PURE__ */ new Map();
|
|
6
|
+
scanned = /* @__PURE__ */ new Set();
|
|
7
|
+
markets = /* @__PURE__ */ new Map();
|
|
8
|
+
async saveSwap(swap) {
|
|
9
|
+
this.swaps.set(swap.id, swap);
|
|
10
|
+
}
|
|
11
|
+
async getAllSwaps() {
|
|
12
|
+
return [...this.swaps.values()];
|
|
13
|
+
}
|
|
14
|
+
async getScannedTxids() {
|
|
15
|
+
return new Set(this.scanned);
|
|
16
|
+
}
|
|
17
|
+
async markTxidsScanned(txids) {
|
|
18
|
+
for (const txid of txids) this.scanned.add(txid);
|
|
19
|
+
}
|
|
20
|
+
async getCachedMarkets(network, registry) {
|
|
21
|
+
return this.markets.get(marketsCacheKey(network, registry));
|
|
22
|
+
}
|
|
23
|
+
async saveCachedMarkets(network, registry, entry) {
|
|
24
|
+
this.markets.set(marketsCacheKey(network, registry), entry);
|
|
25
|
+
}
|
|
26
|
+
async clear() {
|
|
27
|
+
this.swaps.clear();
|
|
28
|
+
this.scanned.clear();
|
|
29
|
+
this.markets.clear();
|
|
30
|
+
}
|
|
31
|
+
async [Symbol.asyncDispose]() {
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
marketsCacheKey,
|
|
37
|
+
InMemoryAssetSwapRepository
|
|
38
|
+
};
|