@dcasegr/amm-client 0.38.2 → 0.41.1
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 +64 -24
- package/dist/client.d.ts +206 -62
- package/dist/client.js +388 -333
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +6 -3
- package/dist/index.d.ts +16 -4
- package/dist/index.js +16 -4
- package/dist/lib/overlay.d.ts +226 -19
- package/dist/lib/overlay.js +278 -49
- package/dist/lib/skein.d.ts +2 -0
- package/dist/lib/skein.js +1 -1
- package/dist/market/activeSwap.d.ts +77 -96
- package/dist/market/activeSwap.js +146 -166
- package/dist/market/plan.d.ts +2 -1
- package/dist/market/plan.js +1 -1
- package/dist/market/prices.d.ts +4 -4
- package/dist/market/prices.js +4 -4
- package/dist/market/swapAction.d.ts +150 -145
- package/dist/market/swapAction.js +292 -213
- package/dist/market/swapFlow.d.ts +3 -6
- package/dist/market/swapFlow.js +4 -22
- package/dist/pool/pool.artifact.json +760 -528
- package/dist/pool/template.d.ts +10 -2
- package/dist/pool/template.js +16 -6
- package/dist/wallet/color.d.ts +13 -9
- package/dist/wallet/color.js +13 -10
- package/dist/wallet/swapPayouts.d.ts +45 -28
- package/dist/wallet/swapPayouts.js +129 -117
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -39,22 +39,42 @@ exchange with another wallet, keeping what was read and quoted.
|
|
|
39
39
|
|
|
40
40
|
The client (each an async function unless noted):
|
|
41
41
|
|
|
42
|
-
- the exchange: `enabledList`, `registeredTokens`, `tokenBaseOf`, `hostedTokens
|
|
43
|
-
`
|
|
42
|
+
- the exchange: `enabledList`, `registeredTokens`, `tokenBaseOf`, `hostedTokens` (the token list
|
|
43
|
+
and ONE `GET /amm/stats`), `tokenPools(tokenId)` (0.41.0: the token's pools route, a plain
|
|
44
|
+
read past the browser's cache), `watchPoolEvents(tokenId | "all", onEvent)` (0.41.0: the host's
|
|
45
|
+
pool event feed, `/@<token>/amm/events` or `<origin>/amm/events`; each message `{tokenId, …row}`,
|
|
46
|
+
a `/pools/history` row or a `revert`; signals for display, the pools route the truth; sync,
|
|
47
|
+
returns the unsubscribe; reconnect is the browser EventSource's),
|
|
44
48
|
`claimStatus`, `isRoot`, `claimExchange`, `discoveryBase` (sync), `onDataChange` (sync);
|
|
49
|
+
- history (plain GETs; 0.40.0: by pool id, `poolId` = the pool's deploy outpoint `<txid>_<vout>`):
|
|
50
|
+
`trades(tokenId, {from?, to?, limit?, before?, pool?})` → `{trades, next}` (each row its
|
|
51
|
+
`poolId` and `payoutPkh`), `trade(tokenId, txid)` → a `Trade` or null, `candles(tokenId, {tf,
|
|
52
|
+
from, to, series?})` (`series` `fill`, the default, or `market`), `stats(tokenId)` /
|
|
53
|
+
`statsAll({ids?, fresh?})` (`price` = the midpoint of what a buy and a sell of 1% of the pooled sats
|
|
54
|
+
would pay now, `buyPrice`, `sellPrice`, `lastTradePrice`), `holders(tokenId, {limit?, skip?})` →
|
|
55
|
+
`{count, rows}`, `positionsAll(poolIds)`, `poolsAt(tokenId, t)` (every pool listed at `t`),
|
|
56
|
+
`poolHistory(tokenId, {from?, to?, pool?, limit?, after?})` → `{events, next}` (oldest first;
|
|
57
|
+
forward paging: `next` as `after`), `spendsAll(outpoints)` (the host's `/amm/spends`); amounts
|
|
58
|
+
bigints, prices `{sats, tokens}` pairs of bigints (base units both);
|
|
45
59
|
- swap: `quoteSwap(request, poolsAnswer, {sym, dec})` (sync: the engine's plan over the pools the
|
|
46
|
-
token's pools
|
|
47
|
-
`
|
|
60
|
+
token's pools route gave, each pool with its validator's `minLegSats`; the quote's price and
|
|
61
|
+
impact from the engine's `priceOf`, each leg's own `fees`, `stage` = what Swap sets aside
|
|
62
|
+
(`amount`, `feeSats`: 0.40.2, exactly `maxSources` legs), `legMinerFeeSats`); the request's
|
|
63
|
+
`maxSources` (required, 0.40.2; replaces `allowPartial`) is the most pools the swap may draw on —
|
|
64
|
+
1 is exactly one leg; the Open Exchange pages send 1 or 5,
|
|
65
|
+
`executeSwap(quote, {onProgress, signal})` (below), `walletSats`;
|
|
48
66
|
- liquidity: `myPositions`, `validatorTerms`, `deployPosition({tokenId, tokens, sats})`,
|
|
49
67
|
`closePosition({outpoint})`, `rebalancePosition({outpoint, tokens, sats})` (the old pool closed
|
|
50
68
|
and a new one deployed in ONE wallet createAction);
|
|
51
|
-
- your tokens: `myTokens`, `settleSwaps` (the
|
|
52
|
-
|
|
69
|
+
- your tokens: `myTokens`, `settleSwaps` (the pass over the swap basket: a staged token output the
|
|
70
|
+
basket lacks filed from its action's description; then every row's spender, this wallet's legs
|
|
71
|
+
taken in: the txids), `swapBasketSats`, `moveBackTokens(tokenId)` (every row of the token and
|
|
72
|
+
every sats row: txid, amount, BEEF, submit), `moveBackStagedSats` (the sats alone), `sendTokens`;
|
|
53
73
|
- settings (root): `deployBeef`, `enableToken`, `tokensToEnable`, `disableToken`, `defaults`,
|
|
54
74
|
`setDefaultTerms`, `clearDefaultTerms`, `setDefaultMarket`, `clearDefaultMarket`, `tokenTerms`,
|
|
55
|
-
`setTokenTerms
|
|
75
|
+
`setTokenTerms` (0.40.0: the terms `{lpBps, validatorBps, commissionBps, minLegSats?}`), `discoveryState`, `setDiscovery`.
|
|
56
76
|
|
|
57
|
-
Pure helpers beside it: `hostedFrom`, `poolViews`, `poolFees`, `
|
|
77
|
+
Pure helpers beside it: `hostedFrom`, `parsePoolEventMessage`, `poolViews`, `poolFees`, `poolsWithMinimums`, `pairPrice`, `legCarrySats`, `hasTerms`,
|
|
58
78
|
`enableCandidates`, `topicOf`, `lookupOf`, `ammLookupOf`, `walletDeployBeef`, `exchangeBase`,
|
|
59
79
|
`tokenBase`; the types (`Quote`, `SwapResult`, `LegResult`, `Position`, `WalletToken`, …).
|
|
60
80
|
|
|
@@ -62,15 +82,19 @@ Pure helpers beside it: `hostedFrom`, `poolViews`, `poolFees`, `withLeg`, `hasTe
|
|
|
62
82
|
|
|
63
83
|
An error of one of `CLIENT_ERROR_KINDS` is a `ClientError` with `kind` and the message the pages
|
|
64
84
|
show: `stale_pool`, `fee_mismatch`, `quote_mismatch`, `slippage`, `pool_spent`, `user_rejected`,
|
|
65
|
-
`no_answer`, `
|
|
66
|
-
`
|
|
85
|
+
`no_answer`, `below_minimum` (0.40.0: under a validator's minimum leg; a quote no pool takes),
|
|
86
|
+
`refused`, `network`. `errorKind(e)` classifies any error; other errors stay plain `Error`s.
|
|
67
87
|
|
|
68
88
|
## The shared names
|
|
69
89
|
|
|
70
90
|
What two sites must use to file identical wallet rows: `POOLS_BASKET` (`amm-pools`, the LP's
|
|
71
91
|
position rows), `SWAP_BASKET` (`amm-swap`, what swap legs spend), `SWAP_PROTOCOL` (`[2, "amm
|
|
72
|
-
swap"]`), `SWAP_KEY_PREFIX` + `
|
|
73
|
-
`
|
|
92
|
+
swap"]`), `SWAP_KEY_PREFIX` + `newSwapKeyID` (a staged row's random keyID), `changeKeyID` (a leg's
|
|
93
|
+
change row: `amm-swap-<txid>.<vout>:change` of its first input of that kind), `SWAP_STAGE_LABEL`
|
|
94
|
+
(`amm-swap-stage`) + `SWAP_KEY_MARK` + `swapKeyDescription` / `swapKeyIdOfDescription` (a staged
|
|
95
|
+
token output's description naming its key), `legDerivation` (an order's payout, own commission and
|
|
96
|
+
last-leg change keys), `swapInstructions` / `swapSatsInstructions` (their customInstructions, a
|
|
97
|
+
change row's with `order`), `LP_KEY_PROTOCOL` (BRC-29) + `LP_KEY_MARK` +
|
|
74
98
|
`lpKeyDescription` / `lpKeyIdOfDescription` (the deploy's pool output description naming the LP
|
|
75
99
|
keyID), `POOL_TAG` / `POOL_OP` / `isPoolRow` / `poolCustomInstructions` (an `amm-pools` row),
|
|
76
100
|
`POOL_DEPLOY_LABEL` (`amm-pool-deploy`), `SWAP_TTL_MS` (15 s), `transferPlanLabels` (the `p color
|
|
@@ -85,20 +109,36 @@ import { createClient, ClientError } from "@dcasegr/amm-client";
|
|
|
85
109
|
const client = createClient({ origin: "https://swap.skein.nexus", wallet });
|
|
86
110
|
const tokenId = "<txid>_0";
|
|
87
111
|
|
|
88
|
-
// The token's pools route
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
112
|
+
// The token's pools route: the pools a swap may use, the market (read again on a pool event).
|
|
113
|
+
const pools = await client.tokenPools(tokenId);
|
|
114
|
+
const quote = client.quoteSwap({ tokenId, side: "buy", amountIn: 50_000n, maxSlippageBps: 50, maxSources: 1 }, pools, { sym: "TOK", dec: 0 });
|
|
115
|
+
try {
|
|
116
|
+
const cancel = new AbortController();
|
|
117
|
+
const result = await client.executeSwap(quote, { signal: cancel.signal, onProgress: (p) => console.log(p.phase) });
|
|
118
|
+
console.log(result.status, result.stop, result.legs, result.returned);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
if (e instanceof ClientError) console.log(e.kind, e.message);
|
|
121
|
+
else throw e;
|
|
122
|
+
}
|
|
100
123
|
```
|
|
101
124
|
|
|
125
|
+
`executeSwap` (0.40.0; 0.40.2: at most `maxSources` legs, the budget down by one per FILLED leg —
|
|
126
|
+
a refused or unanswered leg does not count, the last leg takes all that remains): ONE swap at a time. First the pass over the swap basket, then ONE wallet
|
|
127
|
+
action stages what `amm-swap` lacks of `quote.stage` (sats only: a plain createAction; a sell's
|
|
128
|
+
tokens: the module transfer). Then legs one at a time: the SERVER's pool list read fresh (0.41.0:
|
|
129
|
+
`GET /@<token>/amm/pools` before EACH leg; the client keeps no list of its own), the engine's
|
|
130
|
+
`nextLeg` over it (`minOut` = the quote's floor less what has filled), the pool's current output by
|
|
131
|
+
its id (`/pools/beef?pool=`), the staged rows that cover the leg (largest first), built, signed,
|
|
132
|
+
relayed; accepted → taken in (payout, own commission, change) before the next leg; refused
|
|
133
|
+
`pool_spent` → the list read again (the relaying host took the validator's state in before it
|
|
134
|
+
answered, 0.41.0); refused otherwise → that pool output excluded; no answer → the overlay
|
|
135
|
+
(a staged input spent: the leg landed), else sent once more, else raced on another pool. It stops
|
|
136
|
+
`filled | cancelled | floor | min | no_pool | fees`. Filled: the last leg's change went to the
|
|
137
|
+
wallet. Stopped early with rows left: `moveBack` runs itself (`result.returned`). Progress phases:
|
|
138
|
+
`staging`, `relaying` / `repricing` (the leg's pool, amounts and the legs filled so far),
|
|
139
|
+
`returning`, `done` / `failed`. The result: `{status, stop, legs: [{poolOutpoint, poolId,
|
|
140
|
+
amountIn, amountOut, txid}], totalIn, totalOut, unfilled, returned?}`.
|
|
141
|
+
|
|
102
142
|
## Build
|
|
103
143
|
|
|
104
144
|
From skein-amm's `web/`: `npm ci` in `ui` and in `engine`, then `npm pack` here (the build
|
package/dist/client.d.ts
CHANGED
|
@@ -11,23 +11,27 @@
|
|
|
11
11
|
*
|
|
12
12
|
* - **The token list** (`GET <swap>/tokens`): read ONCE per client (D4; `enabledList`), again
|
|
13
13
|
* only after its own enable or disable changed it.
|
|
14
|
-
* - **Prices** (
|
|
15
|
-
* `
|
|
16
|
-
* - **
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
14
|
+
* - **Prices** (0.39.0, D3, D7): ONE read of the host-wide stats `GET <origin>/amm/stats`
|
|
15
|
+
* (`hostedTokens`): each token's price, liquidity (TVL) and pool count; no host-wide stream.
|
|
16
|
+
* - **History** (0.39.0, D1–D6): `trades`, `trade`, `candles`, `stats`, `statsAll`, `holders`,
|
|
17
|
+
* `positionsAll` — plain GETs of the history routes (H1–H6, src/lib/overlay.ts).
|
|
18
|
+
* - **Swap** (D11–D16; 0.40.0; 0.41.0): the token's pools route `GET /@<token>/amm/pools`, a plain
|
|
19
|
+
* read (`tokenPools`): the pools whose validator is beating and whose commission meets the
|
|
20
|
+
* market's minimum (the host's filter), each validator's minimum leg, the market's commission key
|
|
21
|
+
* hash; a quote is the matching engine's plan over that list (no request); a swap (`executeSwap`)
|
|
22
|
+
* stages what the swap basket lacks by ONE wallet action, then per leg the pools route read fresh,
|
|
23
|
+
* ONE `GET /@<token>/amm/pools/beef?pool=` and the leg's relay request (`amm.swap.submit`, held by
|
|
24
|
+
* the host until the relay rests; 15 s expiry); no answer → the host's `GET /amm/spends`, once
|
|
25
|
+
* more, a race. The pool events (`watchPoolEvents`, 0.41.0: the host's feeds) are signals for
|
|
26
|
+
* display: a page reads the route again on one.
|
|
27
|
+
* - **Liquidity** (D9, D23; 0.40.0: by pool id): the wallet's pool rows and deploy history, then
|
|
28
|
+
* ONE `GET /@<token>/amm/positions?pool=` per token; a deploy the history has but the basket
|
|
29
|
+
* lacks is filed then; Close and Rebalance read their pool's BEEF by its id (`/pools/beef?pool=`);
|
|
30
|
+
* the deploy's terms `GET /@<token>/amm/terms`.
|
|
27
31
|
* - **Your tokens** (D17, D18, D19, D24): the wallet's module and the swap basket; the token list
|
|
28
|
-
* once and ONE discovery `GET /@discovery/1color/tokens?ids=` for held tokens the list lacks;
|
|
29
|
-
*
|
|
30
|
-
* at the host root.
|
|
32
|
+
* once and ONE discovery `GET /@discovery/1color/tokens?ids=` for held tokens the list lacks; the
|
|
33
|
+
* pass over the swap basket (0.40.0: ONE `GET /amm/spends` over every row,
|
|
34
|
+
* src/wallet/swapPayouts.ts); Move back submits at the host root.
|
|
31
35
|
* - **Settings** (D20, D21): the claim card (`claimStatus`: swap's identity, the recipient of
|
|
32
36
|
* root's messages), the token list once, discovery's list and ONE `?ids=` read; Enable's deploy
|
|
33
37
|
* BEEF from the wallet's basket else `GET /@discovery/1color/<token>/deploy`.
|
|
@@ -39,14 +43,13 @@
|
|
|
39
43
|
*/
|
|
40
44
|
import { type WalletInterface } from "@bsv/sdk";
|
|
41
45
|
import { type Send1ColorResult } from "@1sat/actions";
|
|
42
|
-
import { type PoolState, type Plan } from "@dcasegr/amm-engine";
|
|
43
|
-
import { type
|
|
46
|
+
import { type Leg, type PoolState, type Plan, type PricePair } from "@dcasegr/amm-engine";
|
|
47
|
+
import { type Candle, type CandleSeries, type CandleTf, type PoolAt, type PoolHistoryPage, type SpendAll, type Holders, type TokenPosition, type TokenStats, type Trade, type TradesPage, type PoolRow, type PoolsAnswer, type PoolEventMessage, type SignedFetch } from "./lib/overlay.js";
|
|
44
48
|
import { type Defaults, type Discovery, type EnabledToken, type ListedToken } from "./lib/skein.js";
|
|
45
49
|
import type { AuthFetchLike } from "./market/relay.js";
|
|
46
|
-
import { type PreparedSwap } from "./market/swapAction.js";
|
|
47
50
|
import { type MovedBack } from "./market/activeSwap.js";
|
|
48
51
|
import { type PositionRow } from "./lp/positions.js";
|
|
49
|
-
import { ClientError
|
|
52
|
+
import { ClientError } from "./errors.js";
|
|
50
53
|
/** A token id: the BRC-207 assetId `<txid>_<vout>`, `_0` included (src/lib/tokenId.ts). */
|
|
51
54
|
export type TokenId = string;
|
|
52
55
|
/** What a swap of 2% of the price costs: the sats a buy needs to move the marginal price up by `bps`. */
|
|
@@ -61,7 +64,10 @@ export interface HostedToken {
|
|
|
61
64
|
dec: number;
|
|
62
65
|
/** An image URL (a data: URL of the deploy's embedded icon, or an ORDFS URL). */
|
|
63
66
|
icon?: string;
|
|
64
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Sats per whole token (0.40.0: the stats' `price`, the midpoint of what a buy and a sell of 1% of
|
|
69
|
+
* the pooled sats would pay now). Null with no open pool.
|
|
70
|
+
*/
|
|
65
71
|
marginalPrice: number | null;
|
|
66
72
|
depth: Depth | null;
|
|
67
73
|
/** Number of open pools. */
|
|
@@ -78,6 +84,8 @@ export interface HostedToken {
|
|
|
78
84
|
export interface PoolView {
|
|
79
85
|
/** `<txid>.<vout>` */
|
|
80
86
|
outpoint: string;
|
|
87
|
+
/** The pool's id (0.40.0): its deploy outpoint, `<txid>_<vout>`. */
|
|
88
|
+
poolId: string;
|
|
81
89
|
tokenId: TokenId;
|
|
82
90
|
sats: bigint;
|
|
83
91
|
tokens: bigint;
|
|
@@ -96,11 +104,18 @@ export interface QuoteRequest {
|
|
|
96
104
|
amountIn: bigint;
|
|
97
105
|
/** Max slippage against the quoted amount out, basis points. */
|
|
98
106
|
maxSlippageBps: number;
|
|
99
|
-
|
|
107
|
+
/**
|
|
108
|
+
* 0.40.2: the most pools the order may draw on, filled legs counted — a positive integer the
|
|
109
|
+
* caller always gives; the fee sats staged are for exactly that many legs. 1: exactly one leg
|
|
110
|
+
* for the whole amount. Replaces `allowPartial` (`false` was 1).
|
|
111
|
+
*/
|
|
112
|
+
maxSources: number;
|
|
100
113
|
}
|
|
101
114
|
export interface QuoteLeg {
|
|
102
115
|
/** The pool, `<txid>.<vout>`. */
|
|
103
116
|
poolOutpoint: string;
|
|
117
|
+
/** The pool's id (0.40.0). */
|
|
118
|
+
poolId: string;
|
|
104
119
|
amountIn: bigint;
|
|
105
120
|
amountOut: bigint;
|
|
106
121
|
/** Share of the amount in, basis points (the legs sum to 10000). */
|
|
@@ -111,37 +126,64 @@ export interface QuoteLeg {
|
|
|
111
126
|
tokens: bigint;
|
|
112
127
|
};
|
|
113
128
|
validator: ValidatorRef;
|
|
129
|
+
/** The leg's own pool's fees (0.40.0: the fee line per leg). */
|
|
130
|
+
fees: Fees;
|
|
131
|
+
}
|
|
132
|
+
/** What Swap stages into the swap basket before its first leg (0.40.0): the swap amount exact, and the fee sats. */
|
|
133
|
+
export interface QuoteStage {
|
|
134
|
+
/** The swap amount: sats on a buy, token base units on a sell. */
|
|
135
|
+
amount: bigint;
|
|
136
|
+
/** The sats for the carriers and miner fees of `maxSources` legs (0.40.2). */
|
|
137
|
+
feeSats: bigint;
|
|
114
138
|
}
|
|
115
139
|
export interface Quote {
|
|
116
140
|
request: QuoteRequest;
|
|
117
141
|
legs: QuoteLeg[];
|
|
118
142
|
amountOut: bigint;
|
|
119
|
-
/** The least amount out the swap accepts:
|
|
143
|
+
/** The least amount out the swap accepts (the floor): the route's amount out less max slippage. */
|
|
120
144
|
minAmountOut: bigint;
|
|
121
145
|
/** Sats per whole token this swap pays (fees included). */
|
|
122
146
|
effectivePrice: number;
|
|
123
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Sats per whole token now (0.40.0: the engine's `priceOf` over the pools the page holds — what a
|
|
149
|
+
* buy of 1% of the pooled sats would pay on a buy, a sell of 1% of the pooled tokens on a sell).
|
|
150
|
+
*/
|
|
124
151
|
marginalPrice: number;
|
|
125
152
|
/** |effective − marginal| / marginal, basis points. */
|
|
126
153
|
impactBps: number;
|
|
127
|
-
/**
|
|
128
|
-
|
|
154
|
+
/** What Swap stages (0.40.0). */
|
|
155
|
+
stage: QuoteStage;
|
|
156
|
+
/** The miner fee estimate of one leg, sats. */
|
|
157
|
+
legMinerFeeSats: bigint;
|
|
129
158
|
}
|
|
159
|
+
/** One leg of a swap that filled (0.40.0). */
|
|
130
160
|
export interface LegResult {
|
|
161
|
+
/** The pool output it spent, `<txid>.<vout>`. */
|
|
131
162
|
poolOutpoint: string;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
repriced?: true;
|
|
137
|
-
/** 0.34.0 (D15): no answer yet — the swap's id, for "Check again" (`checkSwapAgain`). */
|
|
138
|
-
checkId?: string;
|
|
139
|
-
/** 0.38.0 (D13): the failure's kind, when it has one (`error` stays the text). */
|
|
140
|
-
kind?: ClientErrorKind;
|
|
163
|
+
poolId: string;
|
|
164
|
+
amountIn: bigint;
|
|
165
|
+
amountOut: bigint;
|
|
166
|
+
txid: string;
|
|
141
167
|
}
|
|
168
|
+
/** Why a swap stopped (0.40.0). */
|
|
169
|
+
export type SwapStop = "filled" | "cancelled" | "floor" | "min" | "no_pool" | "fees";
|
|
142
170
|
export interface SwapResult {
|
|
171
|
+
/** "filled": every unit filled; "partial": some; "failed": none. */
|
|
143
172
|
status: "filled" | "partial" | "failed";
|
|
173
|
+
stop: SwapStop;
|
|
174
|
+
/** The legs that filled, in order. */
|
|
144
175
|
legs: LegResult[];
|
|
176
|
+
totalIn: bigint;
|
|
177
|
+
totalOut: bigint;
|
|
178
|
+
/** The swap amount not filled. */
|
|
179
|
+
unfilled: bigint;
|
|
180
|
+
/** What went back to the wallet when the swap stopped early (the Move back's), or why it did not. */
|
|
181
|
+
returned?: {
|
|
182
|
+
txid: string;
|
|
183
|
+
tokens: bigint;
|
|
184
|
+
} | {
|
|
185
|
+
error: string;
|
|
186
|
+
};
|
|
145
187
|
}
|
|
146
188
|
/** The validator's fees, basis points of the amount in. The LP accepts them; there is no fee input. */
|
|
147
189
|
export interface Fees {
|
|
@@ -169,11 +211,17 @@ export interface ValidatorTerms {
|
|
|
169
211
|
/** "this exchange's" when the validator is this skein. */
|
|
170
212
|
isThisExchange: boolean;
|
|
171
213
|
fees: Fees;
|
|
214
|
+
/** The validator's minimum leg, sats on the leg's sats side (0.40.0; 0: none). */
|
|
215
|
+
minLegSats: number;
|
|
172
216
|
}
|
|
173
217
|
/** One of the user's pools. A position is only deployed or closed (no add, no partial remove). */
|
|
174
218
|
export interface Position {
|
|
175
219
|
/** The pool, `<txid>.<vout>`. */
|
|
176
220
|
outpoint: string;
|
|
221
|
+
/** The pool's id (0.40.0): its deploy outpoint, `<txid>_<vout>`. */
|
|
222
|
+
poolId: string;
|
|
223
|
+
/** The pool's swaps so far. */
|
|
224
|
+
swaps: number;
|
|
177
225
|
tokenId: TokenId;
|
|
178
226
|
sym: string;
|
|
179
227
|
dec: number;
|
|
@@ -241,8 +289,6 @@ export interface WalletToken {
|
|
|
241
289
|
outputs: number;
|
|
242
290
|
/** Held in the exchange's active swap basket (`amm-swap`): spent by swap legs, or moved back. */
|
|
243
291
|
inSwaps: bigint;
|
|
244
|
-
/** Sats staged in `amm-swap` for the token's swap legs (0.29.6): spent by swap legs, or moved back. */
|
|
245
|
-
swapSats: number;
|
|
246
292
|
/** Registered on this exchange. */
|
|
247
293
|
onExchange: boolean;
|
|
248
294
|
}
|
|
@@ -262,7 +308,10 @@ export interface RegisteredToken {
|
|
|
262
308
|
icon?: string;
|
|
263
309
|
status: EnabledToken["status"];
|
|
264
310
|
}
|
|
265
|
-
export type { EnabledToken, Defaults, Discovery, PoolRow, PoolsAnswer };
|
|
311
|
+
export type { EnabledToken, Defaults, Discovery, PoolRow, PoolsAnswer, Candle, CandleSeries, CandleTf, Holders, PoolAt, PoolHistoryPage, SpendAll, TokenPosition, TokenStats, Trade, TradesPage };
|
|
312
|
+
export type { PoolEvent, PoolEventMessage, PoolRevert } from "./lib/overlay.js";
|
|
313
|
+
export type { Price } from "./lib/overlay.js";
|
|
314
|
+
export { parsePoolEventMessage } from "./lib/overlay.js";
|
|
266
315
|
/** A token's symbol, decimals and icon, read off its deploy output. */
|
|
267
316
|
export interface DeployMeta {
|
|
268
317
|
sym?: string;
|
|
@@ -287,17 +336,29 @@ export interface ClaimStatus {
|
|
|
287
336
|
claimant?: string;
|
|
288
337
|
}
|
|
289
338
|
/**
|
|
290
|
-
* The hosted tokens (the enabled 1Color tokens at output 0), each
|
|
291
|
-
*
|
|
292
|
-
* `
|
|
339
|
+
* The hosted tokens (the enabled 1Color tokens at output 0), each with its record of the host-wide
|
|
340
|
+
* stats (0.39.0, D3, D7: H4): the price (`price`, sats per whole token), the liquidity (`tvlSats`,
|
|
341
|
+
* `tvlTokens`) and the pool count. `stats` null: not read yet (no prices); a token the stats lack:
|
|
342
|
+
* no price, no pools. Pure.
|
|
293
343
|
*/
|
|
294
|
-
export declare function hostedFrom(list: EnabledToken[],
|
|
344
|
+
export declare function hostedFrom(list: EnabledToken[], stats: TokenStats[] | null): HostedToken[];
|
|
295
345
|
/** The pools the Swap page lists (D11, D13): the token's pools route's rows, every validator live (the host lists no other). */
|
|
296
346
|
export declare function poolViews(answer: PoolsAnswer | null, tokenId: TokenId): PoolView[];
|
|
297
347
|
/** The fees a pool's own record names (D13: the Swap page's fee line), basis points. */
|
|
298
348
|
export declare function poolFees(p: Pick<PoolState, "liquidityFeeBps" | "validationFeeBps" | "commissionBps">): Fees;
|
|
299
|
-
/**
|
|
300
|
-
|
|
349
|
+
/**
|
|
350
|
+
* A pools answer's rows as the planner takes them (0.40.0): each pool with its validator's
|
|
351
|
+
* minimum leg (`validators[].minLegSats`, the validator's announced terms).
|
|
352
|
+
*/
|
|
353
|
+
export declare function poolsWithMinimums(answer: PoolsAnswer): PoolRow[];
|
|
354
|
+
/** Sats per whole token of an exact pair (`sats` per `tokens` base units), 0 when `tokens` is 0. */
|
|
355
|
+
export declare function pairPrice(p: PricePair, dec: number): number;
|
|
356
|
+
/**
|
|
357
|
+
* A leg's sats beyond its amount in (0.40.0, the stage's fee sats): the miner fee estimate plus its
|
|
358
|
+
* 1-sat carriers — on a buy the token payout; on a sell the token fee and commission outputs that
|
|
359
|
+
* are not zero, and the token change.
|
|
360
|
+
*/
|
|
361
|
+
export declare function legCarrySats(leg: Pick<Leg, "liquidityFee" | "validationFee" | "commission">, buy: boolean, minerFeeSats: bigint): bigint;
|
|
301
362
|
/**
|
|
302
363
|
* wallet-toolbox's `specOpWalletBalance` (`sdk.specOpWalletBalance`, @bsv/wallet-toolbox-client): the listOutputs "basket" of its
|
|
303
364
|
* balance special operation. Written out, not imported: the client package exports it only inside its `sdk` namespace, which
|
|
@@ -336,18 +397,17 @@ export interface EnableCandidate {
|
|
|
336
397
|
* instance's list (enabled or disabled) left out. Pure: the reads are `tokensToEnable`'s.
|
|
337
398
|
*/
|
|
338
399
|
export declare function enableCandidates(listed: ListedToken[], walletIds: string[], onList: string[]): EnableCandidate[];
|
|
339
|
-
/** The three fees root sets (basis points, integers 0 to 10 000). */
|
|
400
|
+
/** The three fees root sets (basis points, integers 0 to 10 000), and (0.40.0) the minimum leg in sats (absent or 0: none). */
|
|
340
401
|
export interface TermsInput {
|
|
341
402
|
lpBps: number;
|
|
342
403
|
validatorBps: number;
|
|
343
404
|
commissionBps: number;
|
|
405
|
+
minLegSats?: number;
|
|
344
406
|
}
|
|
345
407
|
/** What a quote was planned from: kept for its execution. */
|
|
346
408
|
interface Planned {
|
|
347
409
|
plan: Plan;
|
|
348
|
-
|
|
349
|
-
live: LiveAnswer;
|
|
350
|
-
market: PoolsAnswer["market"];
|
|
410
|
+
answer: PoolsAnswer;
|
|
351
411
|
dec: number;
|
|
352
412
|
sym: string;
|
|
353
413
|
}
|
|
@@ -372,15 +432,31 @@ export interface ClientOptions {
|
|
|
372
432
|
/** The wallet's identity key, when the caller has it (the claim's check). Default: read from the wallet when needed. */
|
|
373
433
|
identityKey?: string | null;
|
|
374
434
|
}
|
|
375
|
-
/**
|
|
435
|
+
/**
|
|
436
|
+
* Where a swap is (`executeSwap`'s `onProgress`, D12; 0.40.0): `staging` (what the swap basket
|
|
437
|
+
* lacks is staged), `relaying` (a leg sent: its pool outpoint `<txid>.<vout>` and amounts, and the
|
|
438
|
+
* legs filled so far), `repricing` (a leg refused `pool_spent`, the pool's row replaced),
|
|
439
|
+
* `returning` (a swap that stopped early moves its rows back), then `done` or `failed`.
|
|
440
|
+
*/
|
|
376
441
|
export type SwapProgress = {
|
|
377
442
|
phase: "staging";
|
|
443
|
+
sats: bigint;
|
|
444
|
+
tokens: bigint;
|
|
378
445
|
} | {
|
|
379
446
|
phase: "relaying";
|
|
380
447
|
leg: string;
|
|
448
|
+
amountIn: bigint;
|
|
449
|
+
amountOut: bigint;
|
|
450
|
+
filled: LegResult[];
|
|
381
451
|
} | {
|
|
382
452
|
phase: "repricing";
|
|
383
453
|
leg: string;
|
|
454
|
+
amountIn: bigint;
|
|
455
|
+
amountOut: bigint;
|
|
456
|
+
filled: LegResult[];
|
|
457
|
+
} | {
|
|
458
|
+
phase: "returning";
|
|
459
|
+
filled: LegResult[];
|
|
384
460
|
} | {
|
|
385
461
|
phase: "done";
|
|
386
462
|
result: SwapResult;
|
|
@@ -390,8 +466,10 @@ export type SwapProgress = {
|
|
|
390
466
|
error?: ClientError | Error;
|
|
391
467
|
};
|
|
392
468
|
export interface SwapOptions {
|
|
393
|
-
/** Called as the swap moves (
|
|
469
|
+
/** Called as the swap moves (see `SwapProgress`). */
|
|
394
470
|
onProgress?: (p: SwapProgress) => void;
|
|
471
|
+
/** Aborted: the swap stops before its next leg (`cancelled`). */
|
|
472
|
+
signal?: AbortSignal;
|
|
395
473
|
}
|
|
396
474
|
/** What a client remembers between calls; shared by `withWallet`'s clients. */
|
|
397
475
|
interface Shared {
|
|
@@ -401,12 +479,8 @@ interface Shared {
|
|
|
401
479
|
claimRead: ClaimStatus | null;
|
|
402
480
|
/** What each quote was planned from: kept for its execution. */
|
|
403
481
|
planned: WeakMap<Quote, Planned>;
|
|
404
|
-
/**
|
|
405
|
-
|
|
406
|
-
prepared: PreparedSwap;
|
|
407
|
-
base: string;
|
|
408
|
-
af: Signed;
|
|
409
|
-
}>;
|
|
482
|
+
/** A swap is running (0.40.0: one at a time). */
|
|
483
|
+
swapping: boolean;
|
|
410
484
|
/** The positions last loaded, by the output a Close acts on (`<txid>.<vout>`): the wallet's row (its LP key) and the token. */
|
|
411
485
|
loaded: Map<string, PositionRow>;
|
|
412
486
|
/** `onDataChange`'s listeners. */
|
|
@@ -444,15 +518,47 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
444
518
|
isRoot: (identityKey: string | null) => Promise<boolean>;
|
|
445
519
|
claimExchange: () => Promise<boolean>;
|
|
446
520
|
hostedTokens: () => Promise<HostedToken[]>;
|
|
447
|
-
|
|
448
|
-
|
|
521
|
+
tokenPools: (tokenId: string) => Promise<PoolsAnswer>;
|
|
522
|
+
watchPoolEvents: (tokenId: TokenId | "all", onEvent: (e: PoolEventMessage) => void, onError?: (e: unknown) => void) => () => void;
|
|
523
|
+
trades: (tokenId: string, o?: {
|
|
524
|
+
from?: number;
|
|
525
|
+
to?: number;
|
|
526
|
+
limit?: number;
|
|
527
|
+
before?: string;
|
|
528
|
+
pool?: string;
|
|
529
|
+
} | undefined) => Promise<TradesPage>;
|
|
530
|
+
trade: (tokenId: string, txid: string) => Promise<Trade | null>;
|
|
531
|
+
candles: (tokenId: string, o: {
|
|
532
|
+
tf: CandleTf;
|
|
533
|
+
from: number;
|
|
534
|
+
to: number;
|
|
535
|
+
series?: CandleSeries;
|
|
536
|
+
}) => Promise<Candle[]>;
|
|
537
|
+
poolsAt: (tokenId: string, t: number) => Promise<PoolAt[]>;
|
|
538
|
+
poolHistory: (tokenId: string, o?: {
|
|
539
|
+
from?: number;
|
|
540
|
+
to?: number;
|
|
541
|
+
pool?: string;
|
|
542
|
+
limit?: number;
|
|
543
|
+
after?: string;
|
|
544
|
+
} | undefined) => Promise<PoolHistoryPage>;
|
|
545
|
+
spendsAll: (outpoints: string[]) => Promise<SpendAll[]>;
|
|
546
|
+
stats: (tokenId: string) => Promise<TokenStats>;
|
|
547
|
+
statsAll: (o?: {
|
|
548
|
+
ids?: TokenId[];
|
|
549
|
+
fresh?: boolean;
|
|
550
|
+
} | undefined) => Promise<TokenStats[]>;
|
|
551
|
+
holders: (tokenId: string, o?: {
|
|
552
|
+
limit?: number;
|
|
553
|
+
skip?: number;
|
|
554
|
+
} | undefined) => Promise<Holders>;
|
|
555
|
+
positionsAll: (poolIds: string[]) => Promise<TokenPosition[]>;
|
|
449
556
|
registeredTokens: () => Promise<RegisteredToken[]>;
|
|
450
557
|
quoteSwap: (req: QuoteRequest, held: PoolsAnswer | null, meta: {
|
|
451
558
|
sym: string;
|
|
452
559
|
dec: number;
|
|
453
560
|
}) => Quote;
|
|
454
561
|
executeSwap: (quote: Quote, o?: SwapOptions) => Promise<SwapResult>;
|
|
455
|
-
checkSwapAgain: (leg: LegResult) => Promise<LegResult>;
|
|
456
562
|
walletSats: () => Promise<bigint>;
|
|
457
563
|
myPositions: () => Promise<Position[]>;
|
|
458
564
|
validatorTerms: (tokenId: string) => Promise<NoTerms | ValidatorTerms>;
|
|
@@ -461,6 +567,8 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
461
567
|
rebalancePosition: (req: RebalanceRequest) => Promise<RebalanceResult>;
|
|
462
568
|
myTokens: () => Promise<WalletToken[]>;
|
|
463
569
|
settleSwaps: () => Promise<string[]>;
|
|
570
|
+
swapBasketSats: () => Promise<number>;
|
|
571
|
+
moveBackStagedSats: () => Promise<MovedBack>;
|
|
464
572
|
moveBackTokens: (tokenId: string) => Promise<MovedBack>;
|
|
465
573
|
sendTokens: (tokenId: string, handle: string, amount: bigint, memo?: string | undefined) => Promise<Send1ColorResult>;
|
|
466
574
|
deployBeef: (tokenId: string, wallet?: WalletInterface | null | undefined) => Promise<DeployFound>;
|
|
@@ -475,6 +583,7 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
475
583
|
lpFeeBps: number;
|
|
476
584
|
validatorFeeBps: number;
|
|
477
585
|
commissionBps: number;
|
|
586
|
+
minLegSats: number;
|
|
478
587
|
} | null>;
|
|
479
588
|
setTokenTerms: (tokenId: string, t: TermsInput | null) => Promise<void>;
|
|
480
589
|
clearDefaultTerms: () => Promise<void>;
|
|
@@ -493,15 +602,47 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
493
602
|
isRoot: (identityKey: string | null) => Promise<boolean>;
|
|
494
603
|
claimExchange: () => Promise<boolean>;
|
|
495
604
|
hostedTokens: () => Promise<HostedToken[]>;
|
|
496
|
-
|
|
497
|
-
|
|
605
|
+
tokenPools: (tokenId: string) => Promise<PoolsAnswer>;
|
|
606
|
+
watchPoolEvents: (tokenId: TokenId | "all", onEvent: (e: PoolEventMessage) => void, onError?: (e: unknown) => void) => () => void;
|
|
607
|
+
trades: (tokenId: string, o?: {
|
|
608
|
+
from?: number;
|
|
609
|
+
to?: number;
|
|
610
|
+
limit?: number;
|
|
611
|
+
before?: string;
|
|
612
|
+
pool?: string;
|
|
613
|
+
} | undefined) => Promise<TradesPage>;
|
|
614
|
+
trade: (tokenId: string, txid: string) => Promise<Trade | null>;
|
|
615
|
+
candles: (tokenId: string, o: {
|
|
616
|
+
tf: CandleTf;
|
|
617
|
+
from: number;
|
|
618
|
+
to: number;
|
|
619
|
+
series?: CandleSeries;
|
|
620
|
+
}) => Promise<Candle[]>;
|
|
621
|
+
poolsAt: (tokenId: string, t: number) => Promise<PoolAt[]>;
|
|
622
|
+
poolHistory: (tokenId: string, o?: {
|
|
623
|
+
from?: number;
|
|
624
|
+
to?: number;
|
|
625
|
+
pool?: string;
|
|
626
|
+
limit?: number;
|
|
627
|
+
after?: string;
|
|
628
|
+
} | undefined) => Promise<PoolHistoryPage>;
|
|
629
|
+
spendsAll: (outpoints: string[]) => Promise<SpendAll[]>;
|
|
630
|
+
stats: (tokenId: string) => Promise<TokenStats>;
|
|
631
|
+
statsAll: (o?: {
|
|
632
|
+
ids?: TokenId[];
|
|
633
|
+
fresh?: boolean;
|
|
634
|
+
} | undefined) => Promise<TokenStats[]>;
|
|
635
|
+
holders: (tokenId: string, o?: {
|
|
636
|
+
limit?: number;
|
|
637
|
+
skip?: number;
|
|
638
|
+
} | undefined) => Promise<Holders>;
|
|
639
|
+
positionsAll: (poolIds: string[]) => Promise<TokenPosition[]>;
|
|
498
640
|
registeredTokens: () => Promise<RegisteredToken[]>;
|
|
499
641
|
quoteSwap: (req: QuoteRequest, held: PoolsAnswer | null, meta: {
|
|
500
642
|
sym: string;
|
|
501
643
|
dec: number;
|
|
502
644
|
}) => Quote;
|
|
503
645
|
executeSwap: (quote: Quote, o?: SwapOptions) => Promise<SwapResult>;
|
|
504
|
-
checkSwapAgain: (leg: LegResult) => Promise<LegResult>;
|
|
505
646
|
walletSats: () => Promise<bigint>;
|
|
506
647
|
myPositions: () => Promise<Position[]>;
|
|
507
648
|
validatorTerms: (tokenId: string) => Promise<NoTerms | ValidatorTerms>;
|
|
@@ -510,6 +651,8 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
510
651
|
rebalancePosition: (req: RebalanceRequest) => Promise<RebalanceResult>;
|
|
511
652
|
myTokens: () => Promise<WalletToken[]>;
|
|
512
653
|
settleSwaps: () => Promise<string[]>;
|
|
654
|
+
swapBasketSats: () => Promise<number>;
|
|
655
|
+
moveBackStagedSats: () => Promise<MovedBack>;
|
|
513
656
|
moveBackTokens: (tokenId: string) => Promise<MovedBack>;
|
|
514
657
|
sendTokens: (tokenId: string, handle: string, amount: bigint, memo?: string | undefined) => Promise<Send1ColorResult>;
|
|
515
658
|
deployBeef: (tokenId: string, wallet?: WalletInterface | null | undefined) => Promise<DeployFound>;
|
|
@@ -524,6 +667,7 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
524
667
|
lpFeeBps: number;
|
|
525
668
|
validatorFeeBps: number;
|
|
526
669
|
commissionBps: number;
|
|
670
|
+
minLegSats: number;
|
|
527
671
|
} | null>;
|
|
528
672
|
setTokenTerms: (tokenId: string, t: TermsInput | null) => Promise<void>;
|
|
529
673
|
clearDefaultTerms: () => Promise<void>;
|