@dcasegr/amm-client 0.41.1 → 0.42.2
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 +7 -1
- package/dist/client.d.ts +34 -2
- package/dist/client.js +154 -2
- package/dist/lib/skein.d.ts +20 -0
- package/dist/lib/skein.js +15 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -72,7 +72,13 @@ The client (each an async function unless noted):
|
|
|
72
72
|
every sats row: txid, amount, BEEF, submit), `moveBackStagedSats` (the sats alone), `sendTokens`;
|
|
73
73
|
- settings (root): `deployBeef`, `enableToken`, `tokensToEnable`, `disableToken`, `defaults`,
|
|
74
74
|
`setDefaultTerms`, `clearDefaultTerms`, `setDefaultMarket`, `clearDefaultMarket`, `tokenTerms`,
|
|
75
|
-
`setTokenTerms` (0.40.0: the terms `{lpBps, validatorBps, commissionBps, minLegSats?}`), `discoveryState`, `setDiscovery
|
|
75
|
+
`setTokenTerms` (0.40.0: the terms `{lpBps, validatorBps, commissionBps, minLegSats?}`), `discoveryState`, `setDiscovery`,
|
|
76
|
+
`setEnablePrice`, `exchangeWallet`, `withdrawAll`, `settleWithdrawals` (0.42.x);
|
|
77
|
+
- the paid enable (0.42.2, anyone signed; open-exchange 0.15.3): `enableTokenPaid(tokenId, {deployBeef?})` — the price
|
|
78
|
+
from `/amm/defaults`, a BRC-29 payment to the exchange built with `noSend` (not sent: the exchange's take-in sends it),
|
|
79
|
+
ONE BEEF with the deploy and the payment, `POST /amm/enable?tokenId=&paymentTxid=&paymentVout=&derivationPrefix=
|
|
80
|
+
&derivationSuffix=` signed; the enabled row back; on any refusal or failure the unsent payment is aborted
|
|
81
|
+
(`abortAction`). Refusals are `ClientError` kind `refused`, the exchange's code first in the message.
|
|
76
82
|
|
|
77
83
|
Pure helpers beside it: `hostedFrom`, `parsePoolEventMessage`, `poolViews`, `poolFees`, `poolsWithMinimums`, `pairPrice`, `legCarrySats`, `hasTerms`,
|
|
78
84
|
`enableCandidates`, `topicOf`, `lookupOf`, `ammLookupOf`, `walletDeployBeef`, `exchangeBase`,
|
package/dist/client.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { type WalletInterface } from "@bsv/sdk";
|
|
|
45
45
|
import { type Send1ColorResult } from "@1sat/actions";
|
|
46
46
|
import { type Leg, type PoolState, type Plan, type PricePair } from "@dcasegr/amm-engine";
|
|
47
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";
|
|
48
|
-
import { type Defaults, type Discovery, type EnabledToken, type ListedToken } from "./lib/skein.js";
|
|
48
|
+
import { type Defaults, type Discovery, type EnabledToken, type ExchangeWallet, type ListedToken } from "./lib/skein.js";
|
|
49
49
|
import type { AuthFetchLike } from "./market/relay.js";
|
|
50
50
|
import { type MovedBack } from "./market/activeSwap.js";
|
|
51
51
|
import { type PositionRow } from "./lp/positions.js";
|
|
@@ -308,7 +308,7 @@ export interface RegisteredToken {
|
|
|
308
308
|
icon?: string;
|
|
309
309
|
status: EnabledToken["status"];
|
|
310
310
|
}
|
|
311
|
-
export type { EnabledToken, Defaults, Discovery, PoolRow, PoolsAnswer, Candle, CandleSeries, CandleTf, Holders, PoolAt, PoolHistoryPage, SpendAll, TokenPosition, TokenStats, Trade, TradesPage };
|
|
311
|
+
export type { EnabledToken, Defaults, Discovery, ExchangeWallet, PoolRow, PoolsAnswer, Candle, CandleSeries, CandleTf, Holders, PoolAt, PoolHistoryPage, SpendAll, TokenPosition, TokenStats, Trade, TradesPage };
|
|
312
312
|
export type { PoolEvent, PoolEventMessage, PoolRevert } from "./lib/overlay.js";
|
|
313
313
|
export type { Price } from "./lib/overlay.js";
|
|
314
314
|
export { parsePoolEventMessage } from "./lib/overlay.js";
|
|
@@ -591,6 +591,22 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
591
591
|
clearDefaultMarket: () => Promise<void>;
|
|
592
592
|
discoveryState: () => Promise<Discovery>;
|
|
593
593
|
setDiscovery: (on: boolean) => Promise<void>;
|
|
594
|
+
setEnablePrice: (sats: number | null) => Promise<void>;
|
|
595
|
+
exchangeWallet: () => Promise<ExchangeWallet>;
|
|
596
|
+
withdrawAll: () => Promise<{
|
|
597
|
+
n: number;
|
|
598
|
+
txid: string;
|
|
599
|
+
sats: number;
|
|
600
|
+
at: number;
|
|
601
|
+
outputIndex: number;
|
|
602
|
+
derivationPrefix: string;
|
|
603
|
+
derivationSuffix: string;
|
|
604
|
+
senderIdentityKey: string;
|
|
605
|
+
}>;
|
|
606
|
+
enableTokenPaid: (tokenId: string, o?: {
|
|
607
|
+
deployBeef?: number[];
|
|
608
|
+
} | undefined) => Promise<EnabledToken & Record<string, unknown>>;
|
|
609
|
+
settleWithdrawals: () => Promise<string[]>;
|
|
594
610
|
};
|
|
595
611
|
onDataChange: (fn: () => void) => () => void;
|
|
596
612
|
forgetReads: () => void;
|
|
@@ -675,4 +691,20 @@ declare function makeClient(opts: ClientOptions, s: Shared): {
|
|
|
675
691
|
clearDefaultMarket: () => Promise<void>;
|
|
676
692
|
discoveryState: () => Promise<Discovery>;
|
|
677
693
|
setDiscovery: (on: boolean) => Promise<void>;
|
|
694
|
+
setEnablePrice: (sats: number | null) => Promise<void>;
|
|
695
|
+
exchangeWallet: () => Promise<ExchangeWallet>;
|
|
696
|
+
withdrawAll: () => Promise<{
|
|
697
|
+
n: number;
|
|
698
|
+
txid: string;
|
|
699
|
+
sats: number;
|
|
700
|
+
at: number;
|
|
701
|
+
outputIndex: number;
|
|
702
|
+
derivationPrefix: string;
|
|
703
|
+
derivationSuffix: string;
|
|
704
|
+
senderIdentityKey: string;
|
|
705
|
+
}>;
|
|
706
|
+
enableTokenPaid: (tokenId: string, o?: {
|
|
707
|
+
deployBeef?: number[];
|
|
708
|
+
} | undefined) => Promise<EnabledToken & Record<string, unknown>>;
|
|
709
|
+
settleWithdrawals: () => Promise<string[]>;
|
|
678
710
|
};
|
package/dist/client.js
CHANGED
|
@@ -41,13 +41,14 @@
|
|
|
41
41
|
* an outpoint is `<txid>.<vout>`. Amounts are bigints in base units; prices
|
|
42
42
|
* are numbers: sats per whole token.
|
|
43
43
|
*/
|
|
44
|
-
import { Beef, Transaction } from "@bsv/sdk";
|
|
44
|
+
import { Beef, Transaction, createNonce } from "@bsv/sdk";
|
|
45
|
+
import { BRC29_PROTOCOL, WALLET_PAYMENT, p2pkhHexOf } from "./wallet/brc29.js";
|
|
45
46
|
import { send1Color } from "@1sat/actions";
|
|
46
47
|
import { nextLeg, priceOf } from "@dcasegr/amm-engine";
|
|
47
48
|
import { outpointText, parseOutpoint, parseTokenId, sdkTokenId, tokenIdText } from "./lib/tokenId.js";
|
|
48
49
|
import { DEFAULT_FEE_RATE_SATS_PER_KB, appName, exchangeBase, tokenBase } from "./lib/config.js";
|
|
49
50
|
import { ammLookupService, liveOfPools, parseTokenTopic, poolOutputOf, readDiscoveryDeploy, readDiscoveryIds, readDiscoveryList, readAllPositions, readAllStats, readCandles, readHolders, readPoolHistory, readPoolsAt, readPoolsBeef, readPools, readPositions, readSpendsAll, readStats, readTerms, readTrade, readTrades, readTx, eventsUrl, watchPoolEvents as watchFeed, } from "./lib/overlay.js";
|
|
50
|
-
import { authFetchPerInstance, instanceBase, readDefaults, readDiscovery, readTokens, sendMessage } from "./lib/skein.js";
|
|
51
|
+
import { authFetchPerInstance, instanceBase, readDefaults, readDiscovery, readTokens, readWallet, sendMessage } from "./lib/skein.js";
|
|
51
52
|
import { depthOf } from "./market/prices.js";
|
|
52
53
|
import { buildPlanRequest, legMinerFeeSats, quote as planQuote } from "./market/plan.js";
|
|
53
54
|
import { prepareSwap, selectLegInputs } from "./market/swapAction.js";
|
|
@@ -1286,6 +1287,152 @@ function makeClient(opts, s) {
|
|
|
1286
1287
|
async function clearDefaultMarket() {
|
|
1287
1288
|
await sendDefaults({ market: null });
|
|
1288
1289
|
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Sets the price to enable a token (0.42.0, open-exchange 0.15.0): the admin's `{fn: "price", args: {sats}}`
|
|
1292
|
+
* to swap's `<app>/admin`; the host sets it as the price of `POST /amm/enable` (any signed sender enables a
|
|
1293
|
+
* token for it). `null` turns the paid enable off. Refused here unless a whole number of sats, 1 or more.
|
|
1294
|
+
*/
|
|
1295
|
+
async function setEnablePrice(sats) {
|
|
1296
|
+
if (sats !== null && (!Number.isSafeInteger(sats) || sats < 1))
|
|
1297
|
+
throw new Error("sats: a whole number, 1 or more (or null: off)");
|
|
1298
|
+
const { signedFor } = needWallet();
|
|
1299
|
+
const me = await swapIdentity();
|
|
1300
|
+
await sendMessage(signedFor(swapBase), swapBase, me, `${app()}/admin`, { fn: "price", args: { sats } });
|
|
1301
|
+
emit();
|
|
1302
|
+
}
|
|
1303
|
+
/** The exchange's wallet (0.42.0, open-exchange 0.15.0; `GET <swap>/wallet`, the host's read): the sats swap's wallet holds and its coin count. */
|
|
1304
|
+
async function exchangeWallet() {
|
|
1305
|
+
return readWallet(swapBase, ff);
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Enables a token for the exchange's fee (0.42.2, open-exchange 0.15.3: a BEEF submission; anyone signed, not the
|
|
1309
|
+
* admin): the price from `GET <swap>/defaults` (`enablePriceSats`; none → refused, "paid enable is off"); the
|
|
1310
|
+
* exchange's identity from `GET <swap's origin>/.well-known/skein`; the deploy's BEEF given, else discovery's
|
|
1311
|
+
* (`GET <origin>/@discovery/1color/<token>/deploy`). The payment, ts-stack's standard (sdk BasicBRC29): a prefix and
|
|
1312
|
+
* a suffix from `createNonce`, the payee key `getPublicKey({protocolID: [2, "3241645161d8"], keyID: "<prefix>
|
|
1313
|
+
* <suffix>", counterparty: <the exchange>})`, ONE P2PKH output of exactly the price, `createAction` with
|
|
1314
|
+
* `{randomizeOutputs: false, noSend: true}` — built and signed, NOT sent: the exchange's take-in sends it. Then ONE
|
|
1315
|
+
* BEEF merging the deploy's and the payment's, `POST <swap>/enable?tokenId=&paymentTxid=&paymentVout=0
|
|
1316
|
+
* &derivationPrefix=&derivationSuffix=` signed (BRC-104). On any refusal or failure after the payment was built, the
|
|
1317
|
+
* unsent payment is aborted in the wallet (`abortAction`), so its coins are free again. → the enabled row.
|
|
1318
|
+
* Refusals are `ClientError` kind `refused` (the exchange's code first in the message); a fetch that does not get
|
|
1319
|
+
* through, `network`; the user declining in the wallet, `user_rejected`.
|
|
1320
|
+
*/
|
|
1321
|
+
async function enableTokenPaid(tokenId, o = {}) {
|
|
1322
|
+
const { wallet, signedFor } = needWallet();
|
|
1323
|
+
const id = parseOutpoint(sdkTokenId(tokenId).replace("_", "."));
|
|
1324
|
+
if (!id)
|
|
1325
|
+
throw new Error(`not a token id: ${tokenId}`);
|
|
1326
|
+
const canonical = tokenIdText(id);
|
|
1327
|
+
const price = (await readDefaults(swapBase, freshFetch)).enablePriceSats;
|
|
1328
|
+
if (!price)
|
|
1329
|
+
throw new ClientError("refused", "paid enable is off");
|
|
1330
|
+
const exchange = await swapIdentity();
|
|
1331
|
+
let deploy = o.deployBeef;
|
|
1332
|
+
if (!deploy) {
|
|
1333
|
+
const res = await freshFetch(`${discoveryBase()}/${canonical}/deploy`);
|
|
1334
|
+
if (!res.ok)
|
|
1335
|
+
throw new ClientError("refused", `no deploy for ${canonical} on discovery (${res.status}): pass deployBeef`);
|
|
1336
|
+
deploy = Array.from(new Uint8Array(await res.arrayBuffer()));
|
|
1337
|
+
}
|
|
1338
|
+
const derivationPrefix = await createNonce(wallet, "self");
|
|
1339
|
+
const derivationSuffix = await createNonce(wallet, "self");
|
|
1340
|
+
const { publicKey } = await wallet.getPublicKey({ protocolID: BRC29_PROTOCOL, keyID: `${derivationPrefix} ${derivationSuffix}`, counterparty: exchange });
|
|
1341
|
+
const created = await wallet.createAction({
|
|
1342
|
+
description: "Open Exchange: enable a token",
|
|
1343
|
+
outputs: [{ satoshis: price, lockingScript: p2pkhHexOf(publicKey), outputDescription: "Open Exchange enable fee", customInstructions: JSON.stringify({ derivationPrefix, derivationSuffix, payee: exchange }) }],
|
|
1344
|
+
options: { randomizeOutputs: false, noSend: true },
|
|
1345
|
+
});
|
|
1346
|
+
const txid = created.txid;
|
|
1347
|
+
if (!txid || !created.tx)
|
|
1348
|
+
throw new Error("the wallet built no payment");
|
|
1349
|
+
try {
|
|
1350
|
+
const b = new Beef();
|
|
1351
|
+
b.mergeBeef(deploy);
|
|
1352
|
+
b.mergeBeef(created.tx);
|
|
1353
|
+
const q = new URLSearchParams({ tokenId: canonical, paymentTxid: txid, paymentVout: "0", derivationPrefix, derivationSuffix });
|
|
1354
|
+
let res;
|
|
1355
|
+
try {
|
|
1356
|
+
res = await signedFor(swapBase).fetch(`${swapBase}/enable?${q.toString()}`, { method: "POST", headers: { "content-type": "application/octet-stream" }, body: Uint8Array.from(b.toBinary()) });
|
|
1357
|
+
}
|
|
1358
|
+
catch (e) {
|
|
1359
|
+
// The stock AuthFetch takes every 402 for its own payment wire and throws on this route's (no x-bsv-payment-* headers).
|
|
1360
|
+
if (/x-bsv-payment/.test(errText(e)))
|
|
1361
|
+
throw new ClientError("refused", "ERR_PAYMENT_REQUIRED: the exchange did not take this payment (402; its price may have changed)", { cause: e });
|
|
1362
|
+
throw e;
|
|
1363
|
+
}
|
|
1364
|
+
const v = (await res.json().catch(() => ({})));
|
|
1365
|
+
if (res.status !== 200)
|
|
1366
|
+
throw new ClientError("refused", `${String(v.code ?? res.status)}: ${String(v.description ?? v.message ?? "refused")}`);
|
|
1367
|
+
s.listRead = null;
|
|
1368
|
+
emit();
|
|
1369
|
+
return v.result;
|
|
1370
|
+
}
|
|
1371
|
+
catch (e) {
|
|
1372
|
+
await wallet.abortAction({ reference: txid }).catch(() => { });
|
|
1373
|
+
throw e;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
/** A withdrawal's payment taken in by the admin's wallet: `internalizeAction`, output `outputIndex` as a wallet payment from swap (BRC-29, ts-stack's recipient side). */
|
|
1377
|
+
async function takeInWithdrawal(wallet, x, tx) {
|
|
1378
|
+
const r = await wallet.internalizeAction({
|
|
1379
|
+
tx,
|
|
1380
|
+
outputs: [{ outputIndex: x.outputIndex, protocol: WALLET_PAYMENT, paymentRemittance: { derivationPrefix: x.derivationPrefix, derivationSuffix: x.derivationSuffix, senderIdentityKey: x.senderIdentityKey } }],
|
|
1381
|
+
description: `Open Exchange withdraw ${x.n}`,
|
|
1382
|
+
});
|
|
1383
|
+
return r.accepted;
|
|
1384
|
+
}
|
|
1385
|
+
/** Withdrawal `n`'s Atomic BEEF (`GET <swap>/wallet/tx?n=`). */
|
|
1386
|
+
async function withdrawalTx(n) {
|
|
1387
|
+
const res = await freshFetch(`${swapBase}/wallet/tx?n=${n}`);
|
|
1388
|
+
if (!res.ok)
|
|
1389
|
+
throw new Error(`GET ${swapBase}/wallet/tx?n=${n}: ${res.status}`);
|
|
1390
|
+
return Array.from(new Uint8Array(await res.arrayBuffer()));
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Withdraws everything in the exchange's wallet to the admin's own (0.42.1, open-exchange 0.15.2): the admin's
|
|
1394
|
+
* `{fn: "withdraw"}` to swap's `<app>/admin`. swap's program pays every coin to a BRC-29 key derived for the
|
|
1395
|
+
* sender and hands the transaction over unsent; this function waits for the read to list it (`GET <swap>/wallet`,
|
|
1396
|
+
* at most 10 s — the message's answer reaches no page), then takes it in (`internalizeAction`, a wallet payment:
|
|
1397
|
+
* that is what sends it). → the withdrawal.
|
|
1398
|
+
*/
|
|
1399
|
+
async function withdrawAll() {
|
|
1400
|
+
const { wallet, signedFor } = needWallet();
|
|
1401
|
+
const w = await readWallet(swapBase, freshFetch);
|
|
1402
|
+
if (w.sats <= 0)
|
|
1403
|
+
throw new Error("the exchange's wallet holds nothing to withdraw");
|
|
1404
|
+
const me = await swapIdentity();
|
|
1405
|
+
await sendMessage(signedFor(swapBase), swapBase, me, `${app()}/admin`, { fn: "withdraw" });
|
|
1406
|
+
let x;
|
|
1407
|
+
for (let i = 0; i < 40 && !x; i++) {
|
|
1408
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
1409
|
+
x = (await readWallet(swapBase, freshFetch)).withdrawals.find((y) => y.n > w.withdrawals.length);
|
|
1410
|
+
}
|
|
1411
|
+
if (!x)
|
|
1412
|
+
throw new Error("the exchange has not answered the withdraw yet: Settings takes it in when it does");
|
|
1413
|
+
if (!(await takeInWithdrawal(wallet, x, await withdrawalTx(x.n))))
|
|
1414
|
+
throw new Error("the wallet did not accept the withdrawal");
|
|
1415
|
+
emit();
|
|
1416
|
+
return x;
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* The latest withdrawal taken in again (0.42.1; on Settings load): for a page lost between the withdraw's answer
|
|
1420
|
+
* and its take-in (taking in a payment the wallet holds is harmless). Never throws. → its txid, or none.
|
|
1421
|
+
*/
|
|
1422
|
+
async function settleWithdrawals() {
|
|
1423
|
+
if (!boundWallet)
|
|
1424
|
+
return [];
|
|
1425
|
+
try {
|
|
1426
|
+
const w = await readWallet(swapBase, freshFetch);
|
|
1427
|
+
const x = w.withdrawals.at(-1);
|
|
1428
|
+
if (!x)
|
|
1429
|
+
return [];
|
|
1430
|
+
return (await takeInWithdrawal(boundWallet, x, await withdrawalTx(x.n))) ? [x.txid] : [];
|
|
1431
|
+
}
|
|
1432
|
+
catch {
|
|
1433
|
+
return [];
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1289
1436
|
/** The discovery instance's record (0.18.0, shruggr/skein#137; `GET <config>/discovery`): `{on: false}` until root turns it on. */
|
|
1290
1437
|
async function discoveryState() {
|
|
1291
1438
|
return readDiscovery(swapBase, ff);
|
|
@@ -1370,5 +1517,10 @@ function makeClient(opts, s) {
|
|
|
1370
1517
|
clearDefaultMarket: guard(clearDefaultMarket),
|
|
1371
1518
|
discoveryState: guard(discoveryState),
|
|
1372
1519
|
setDiscovery: guard(setDiscovery),
|
|
1520
|
+
setEnablePrice: guard(setEnablePrice),
|
|
1521
|
+
exchangeWallet: guard(exchangeWallet),
|
|
1522
|
+
withdrawAll: guard(withdrawAll),
|
|
1523
|
+
enableTokenPaid: guard(enableTokenPaid),
|
|
1524
|
+
settleWithdrawals,
|
|
1373
1525
|
};
|
|
1374
1526
|
}
|
package/dist/lib/skein.d.ts
CHANGED
|
@@ -73,7 +73,27 @@ export interface Defaults {
|
|
|
73
73
|
market?: {
|
|
74
74
|
minCommissionBps: number;
|
|
75
75
|
};
|
|
76
|
+
/** 0.42.0 (open-exchange 0.15.0): the price in sats to enable a token on `POST /amm/enable`, present when the admin set one. */
|
|
77
|
+
enablePriceSats?: number;
|
|
76
78
|
}
|
|
79
|
+
/** The exchange's wallet (0.42.0, open-exchange 0.15.0; `GET <swap>/wallet`, the host's read of swap's wallet): its sats and coin count. */
|
|
80
|
+
export interface ExchangeWallet {
|
|
81
|
+
sats: number;
|
|
82
|
+
outputs: number;
|
|
83
|
+
/** The admin's withdrawals, each kept by the swap app once proven; n counts from 1. */
|
|
84
|
+
withdrawals: {
|
|
85
|
+
n: number;
|
|
86
|
+
txid: string;
|
|
87
|
+
sats: number;
|
|
88
|
+
at: number;
|
|
89
|
+
outputIndex: number;
|
|
90
|
+
derivationPrefix: string;
|
|
91
|
+
derivationSuffix: string;
|
|
92
|
+
senderIdentityKey: string;
|
|
93
|
+
}[];
|
|
94
|
+
}
|
|
95
|
+
/** `GET <swap>/wallet`: `{sats, outputs, withdrawals}`. */
|
|
96
|
+
export declare function readWallet(base: string, fetchFn?: typeof fetch): Promise<ExchangeWallet>;
|
|
77
97
|
/** Discovery (`GET <swap>/discovery`): root's last decision, on or off, and since when (ms); the host starts or stops the discovery instance. */
|
|
78
98
|
export interface Discovery {
|
|
79
99
|
on: boolean;
|
package/dist/lib/skein.js
CHANGED
|
@@ -122,6 +122,19 @@ export async function readTokens(base, fetchFn = fetch) {
|
|
|
122
122
|
since: typeof t.since === "number" ? t.since : 0,
|
|
123
123
|
}));
|
|
124
124
|
}
|
|
125
|
+
/** `GET <swap>/wallet`: `{sats, outputs, withdrawals}`. */
|
|
126
|
+
export async function readWallet(base, fetchFn = fetch) {
|
|
127
|
+
const a = (await getJson(`${base}/wallet`, fetchFn));
|
|
128
|
+
const ws = Array.isArray(a?.withdrawals) ? a.withdrawals : [];
|
|
129
|
+
return {
|
|
130
|
+
sats: typeof a?.sats === "number" ? a.sats : 0,
|
|
131
|
+
outputs: typeof a?.outputs === "number" ? a.outputs : 0,
|
|
132
|
+
withdrawals: ws.filter((w) => typeof w.n === "number" && typeof w.txid === "string").map((w) => ({
|
|
133
|
+
n: w.n, txid: w.txid, sats: Number(w.sats ?? 0), at: Number(w.at ?? 0), outputIndex: Number(w.outputIndex ?? 0),
|
|
134
|
+
derivationPrefix: String(w.derivationPrefix ?? ""), derivationSuffix: String(w.derivationSuffix ?? ""), senderIdentityKey: String(w.senderIdentityKey ?? ""),
|
|
135
|
+
})),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
125
138
|
/** `GET <swap>/discovery`: `{on, since?}`, or `{on: false}` (none, or another shape). */
|
|
126
139
|
export async function readDiscovery(base, fetchFn = fetch) {
|
|
127
140
|
const a = (await getJson(`${base}/discovery`, fetchFn));
|
|
@@ -138,5 +151,7 @@ export async function readDefaults(base, fetchFn = fetch) {
|
|
|
138
151
|
const m = a?.market;
|
|
139
152
|
if (m && typeof m.minCommissionBps === "number")
|
|
140
153
|
out.market = { minCommissionBps: m.minCommissionBps };
|
|
154
|
+
if (typeof a?.enablePriceSats === "number" && a.enablePriceSats > 0)
|
|
155
|
+
out.enablePriceSats = a.enablePriceSats;
|
|
141
156
|
return out;
|
|
142
157
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcasegr/amm-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Open Exchange client (skein-amm): reads, swap, pool deploy / close / rebalance, move back and positions over a BRC-100 wallet, bound to one exchange by createClient. No React, no styles, no wallet provider.",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@1sat/actions": "0.1.3",
|
|
33
|
-
"@dcasegr/amm-engine": "0.
|
|
33
|
+
"@dcasegr/amm-engine": "0.42.2",
|
|
34
34
|
"cbor2": "^2.3.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|