paytaca-cli 0.4.0 → 0.5.0

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.
Files changed (48) hide show
  1. package/README.md +5 -3
  2. package/dist/commands/chat.d.ts.map +1 -1
  3. package/dist/commands/chat.js +40 -0
  4. package/dist/commands/chat.js.map +1 -1
  5. package/dist/commands/swap.d.ts +19 -0
  6. package/dist/commands/swap.d.ts.map +1 -0
  7. package/dist/commands/swap.js +129 -0
  8. package/dist/commands/swap.js.map +1 -0
  9. package/dist/commands/token.d.ts.map +1 -1
  10. package/dist/commands/token.js +140 -1
  11. package/dist/commands/token.js.map +1 -1
  12. package/dist/index.js +5 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/nostr/store.test.js +12 -4
  15. package/dist/nostr/store.test.js.map +1 -1
  16. package/dist/utils/prices.d.ts +46 -0
  17. package/dist/utils/prices.d.ts.map +1 -0
  18. package/dist/utils/prices.js +93 -0
  19. package/dist/utils/prices.js.map +1 -0
  20. package/dist/utils/prices.test.d.ts +5 -0
  21. package/dist/utils/prices.test.d.ts.map +1 -0
  22. package/dist/utils/prices.test.js +62 -0
  23. package/dist/utils/prices.test.js.map +1 -0
  24. package/dist/wallet/bch.d.ts +14 -0
  25. package/dist/wallet/bch.d.ts.map +1 -1
  26. package/dist/wallet/bch.js +24 -0
  27. package/dist/wallet/bch.js.map +1 -1
  28. package/dist/wallet/cauldron/api.d.ts +58 -0
  29. package/dist/wallet/cauldron/api.d.ts.map +1 -0
  30. package/dist/wallet/cauldron/api.js +60 -0
  31. package/dist/wallet/cauldron/api.js.map +1 -0
  32. package/dist/wallet/cauldron/pools.d.ts +66 -0
  33. package/dist/wallet/cauldron/pools.d.ts.map +1 -0
  34. package/dist/wallet/cauldron/pools.js +96 -0
  35. package/dist/wallet/cauldron/pools.js.map +1 -0
  36. package/dist/wallet/cauldron/pools.test.d.ts +3 -0
  37. package/dist/wallet/cauldron/pools.test.d.ts.map +1 -0
  38. package/dist/wallet/cauldron/pools.test.js +149 -0
  39. package/dist/wallet/cauldron/pools.test.js.map +1 -0
  40. package/dist/wallet/cauldron/swap.d.ts +69 -0
  41. package/dist/wallet/cauldron/swap.d.ts.map +1 -0
  42. package/dist/wallet/cauldron/swap.js +173 -0
  43. package/dist/wallet/cauldron/swap.js.map +1 -0
  44. package/dist/wallet/cauldron/transact.d.ts +98 -0
  45. package/dist/wallet/cauldron/transact.d.ts.map +1 -0
  46. package/dist/wallet/cauldron/transact.js +307 -0
  47. package/dist/wallet/cauldron/transact.js.map +1 -0
  48. package/package.json +3 -2
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Cauldron (riften indexer) REST client.
3
+ *
4
+ * Adapted from: paytaca-app/src/wallet/cauldron/api.js, tokens.js,
5
+ * and pool-tracker.ts. Uses the global fetch API (Node 20+) instead of axios.
6
+ */
7
+ /**
8
+ * An active pool as returned by the cauldron indexer.
9
+ * GET /cauldron/pool/active?token=<category>
10
+ */
11
+ export interface ApiPool {
12
+ owner_p2pkh_addr: string;
13
+ owner_pkh: string;
14
+ pool_id: string;
15
+ sats: number;
16
+ token_id: string;
17
+ tokens: number;
18
+ tx_pos: number;
19
+ txid: string;
20
+ }
21
+ /**
22
+ * A cauldron-listed token (market info + BCMR metadata).
23
+ * GET /cauldron/tokens/list_cached_by_ids?ids=<category>
24
+ */
25
+ export interface CauldronTokenData {
26
+ token_id: string;
27
+ display_name: string;
28
+ display_symbol: string;
29
+ price_now: number;
30
+ price_now_usd: number;
31
+ tvl_sats: number;
32
+ bcmr: {
33
+ name: string;
34
+ description: string;
35
+ token: {
36
+ category: string;
37
+ decimals: number;
38
+ symbol: string;
39
+ };
40
+ uris?: {
41
+ icon?: string;
42
+ web?: string;
43
+ };
44
+ };
45
+ }
46
+ export declare class CauldronApiError extends Error {
47
+ status?: number;
48
+ constructor(message: string, status?: number);
49
+ }
50
+ /**
51
+ * Fetch the active cauldron pools for a token category.
52
+ */
53
+ export declare function fetchPoolsForToken(tokenId: string): Promise<ApiPool[]>;
54
+ /**
55
+ * Fetch market + BCMR data for a single token category.
56
+ */
57
+ export declare function fetchTokenData(tokenId: string): Promise<CauldronTokenData | undefined>;
58
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/wallet/cauldron/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,KAAK,EAAE;YACL,QAAQ,EAAE,MAAM,CAAA;YAChB,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;SACf,CAAA;QACD,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACvC,CAAA;CACF;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,MAAM,CAAC,EAAE,MAAM,CAAA;gBACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAK7C;AA6BD;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQ5E;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAYxC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Cauldron (riften indexer) REST client.
3
+ *
4
+ * Adapted from: paytaca-app/src/wallet/cauldron/api.js, tokens.js,
5
+ * and pool-tracker.ts. Uses the global fetch API (Node 20+) instead of axios.
6
+ */
7
+ const CAULDRON_INDEXER_BASE_URL = 'https://indexer.riften.net';
8
+ export class CauldronApiError extends Error {
9
+ status;
10
+ constructor(message, status) {
11
+ super(message);
12
+ this.name = 'CauldronApiError';
13
+ this.status = status;
14
+ }
15
+ }
16
+ async function getJson(path, params = {}) {
17
+ const url = new URL(CAULDRON_INDEXER_BASE_URL + path);
18
+ for (const [key, value] of Object.entries(params)) {
19
+ if (value === undefined || value === null || value === '')
20
+ continue;
21
+ url.searchParams.set(key, String(value));
22
+ }
23
+ let response;
24
+ try {
25
+ response = await fetch(url.toString());
26
+ }
27
+ catch (err) {
28
+ throw new CauldronApiError(`Cauldron indexer unreachable: ${err?.message || err}`);
29
+ }
30
+ if (!response.ok) {
31
+ throw new CauldronApiError(`Cauldron indexer request failed (${response.status} ${response.statusText})`, response.status);
32
+ }
33
+ return response.json();
34
+ }
35
+ /**
36
+ * Fetch the active cauldron pools for a token category.
37
+ */
38
+ export async function fetchPoolsForToken(tokenId) {
39
+ const data = await getJson('/cauldron/pool/active', {
40
+ token: tokenId,
41
+ });
42
+ if (!Array.isArray(data.active)) {
43
+ throw new CauldronApiError('Unexpected response from cauldron pool endpoint');
44
+ }
45
+ return data.active;
46
+ }
47
+ /**
48
+ * Fetch market + BCMR data for a single token category.
49
+ */
50
+ export async function fetchTokenData(tokenId) {
51
+ const data = await getJson('/cauldron/tokens/list_cached_by_ids', {
52
+ ids: tokenId,
53
+ limit: 1,
54
+ offset: 0,
55
+ by: 'score',
56
+ order: 'desc',
57
+ });
58
+ return Array.isArray(data) ? data[0] : undefined;
59
+ }
60
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/wallet/cauldron/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,yBAAyB,GAAG,4BAA4B,CAAA;AAwC9D,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,MAAM,CAAS;IACf,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED,KAAK,UAAU,OAAO,CACpB,IAAY,EACZ,SAAsD,EAAE;IAExD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAA;IACrD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAQ;QACnE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IACxC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,gBAAgB,CAAC,iCAAiC,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;IACpF,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,GAAG,EAC7E,QAAQ,CAAC,MAAM,CAChB,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAuB,uBAAuB,EAAE;QACxE,KAAK,EAAE,OAAO;KACf,CAAC,CAAA;IACF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,gBAAgB,CAAC,iDAAiD,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,IAAI,CAAC,MAAmB,CAAA;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe;IAEf,MAAM,IAAI,GAAG,MAAM,OAAO,CACxB,qCAAqC,EACrC;QACE,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;QACT,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,MAAM;KACd,CACF,CAAA;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAClD,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Cauldron pool conversions and helpers.
3
+ *
4
+ * Adapted from: paytaca-app/src/wallet/cauldron/utils.js and pool-tracker.ts.
5
+ * Converts indexer ApiPool entries into @cashlab/cauldron PoolV0 objects.
6
+ */
7
+ import { type PoolV0 } from '@cashlab/cauldron';
8
+ import { type ApiPool } from './api.js';
9
+ export interface MicroPool {
10
+ pool_id: string;
11
+ pkh: string;
12
+ is_withdrawn: boolean;
13
+ spent_utxo_hash: string;
14
+ new_utxo_hash: string;
15
+ new_utxo_txid: string;
16
+ new_utxo_n: number;
17
+ token_id: string;
18
+ sats: number;
19
+ token_amount: number;
20
+ }
21
+ /**
22
+ * Convert an indexer ApiPool to a MicroPool.
23
+ */
24
+ export declare function apiPoolToMicroPool(pool: ApiPool): MicroPool;
25
+ /**
26
+ * Convert a MicroPool to a @cashlab/cauldron PoolV0.
27
+ */
28
+ export declare function microPoolToPoolV0(pool: MicroPool): PoolV0;
29
+ /**
30
+ * Fetch + convert active pools for a token category into PoolV0 objects.
31
+ */
32
+ export declare function fetchPoolV0ForToken(tokenId: string): Promise<PoolV0[]>;
33
+ /**
34
+ * Compute the post-trade state of a pool output (used for fee estimation).
35
+ * Mirrors paytaca-app poolTradeToCashscriptOutput().
36
+ */
37
+ export interface PoolTradeOutput {
38
+ to: Uint8Array;
39
+ amount: bigint;
40
+ token: {
41
+ amount: bigint;
42
+ category: string;
43
+ };
44
+ }
45
+ /**
46
+ * @param poolTrade A @cashlab/cauldron PoolTrade
47
+ * @returns The pool's resulting output after the trade
48
+ */
49
+ export declare function poolTradeToOutput(poolTrade: {
50
+ supply_token_id: string;
51
+ demand_token_id: string;
52
+ supply: bigint;
53
+ demand: bigint;
54
+ pool: PoolV0;
55
+ }): PoolTradeOutput;
56
+ /**
57
+ * Parse a trade rate (price) into a human-readable string.
58
+ * Mirrors paytaca-app parseRate().
59
+ *
60
+ * @param isBuyingToken true when BCH is spent to buy tokens (price in BCH per token)
61
+ */
62
+ export declare function parseRate(rate: {
63
+ numerator: bigint;
64
+ denominator: bigint;
65
+ }, tokenDecimals: number, isBuyingToken: boolean): string;
66
+ //# sourceMappingURL=pools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pools.d.ts","sourceRoot":"","sources":["../../../src/wallet/cauldron/pools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAG5D,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,UAAU,CAAA;AAE3D,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,OAAO,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAa3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAoBzD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5E;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,UAAU,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE;IAC3C,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,eAAe,CAclB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAChD,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,OAAO,GACrB,MAAM,CAcR"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Cauldron pool conversions and helpers.
3
+ *
4
+ * Adapted from: paytaca-app/src/wallet/cauldron/utils.js and pool-tracker.ts.
5
+ * Converts indexer ApiPool entries into @cashlab/cauldron PoolV0 objects.
6
+ */
7
+ import { ExchangeLab } from '@cashlab/cauldron';
8
+ import { NATIVE_BCH_TOKEN_ID } from '@cashlab/common';
9
+ import { hexToBin } from '@cashlab/common/libauth.js';
10
+ import { fetchPoolsForToken } from './api.js';
11
+ /**
12
+ * Convert an indexer ApiPool to a MicroPool.
13
+ */
14
+ export function apiPoolToMicroPool(pool) {
15
+ return {
16
+ pool_id: pool.pool_id,
17
+ pkh: pool.owner_pkh,
18
+ is_withdrawn: false,
19
+ spent_utxo_hash: '',
20
+ new_utxo_hash: pool.txid,
21
+ new_utxo_txid: pool.txid,
22
+ new_utxo_n: pool.tx_pos,
23
+ token_id: pool.token_id,
24
+ sats: pool.sats,
25
+ token_amount: pool.tokens,
26
+ };
27
+ }
28
+ /**
29
+ * Convert a MicroPool to a @cashlab/cauldron PoolV0.
30
+ */
31
+ export function microPoolToPoolV0(pool) {
32
+ const pool0Params = { withdraw_pubkey_hash: hexToBin(pool.pkh) };
33
+ const exlab = new ExchangeLab();
34
+ const pool0LockingBytecode = exlab.generatePoolV0LockingBytecode(pool0Params);
35
+ return {
36
+ version: '0',
37
+ parameters: pool0Params,
38
+ outpoint: {
39
+ index: pool.new_utxo_n,
40
+ txhash: hexToBin(pool.new_utxo_txid),
41
+ },
42
+ output: {
43
+ locking_bytecode: pool0LockingBytecode,
44
+ token: {
45
+ amount: BigInt(pool.token_amount),
46
+ token_id: pool.token_id,
47
+ },
48
+ amount: BigInt(pool.sats),
49
+ },
50
+ };
51
+ }
52
+ /**
53
+ * Fetch + convert active pools for a token category into PoolV0 objects.
54
+ */
55
+ export async function fetchPoolV0ForToken(tokenId) {
56
+ const pools = await fetchPoolsForToken(tokenId);
57
+ return pools.map(apiPoolToMicroPool).map(microPoolToPoolV0);
58
+ }
59
+ /**
60
+ * @param poolTrade A @cashlab/cauldron PoolTrade
61
+ * @returns The pool's resulting output after the trade
62
+ */
63
+ export function poolTradeToOutput(poolTrade) {
64
+ const isSupplyingBch = poolTrade.supply_token_id === NATIVE_BCH_TOKEN_ID;
65
+ const satoshisDelta = isSupplyingBch ? poolTrade.supply : poolTrade.demand * -1n;
66
+ const tokenDelta = isSupplyingBch ? poolTrade.demand * -1n : poolTrade.supply;
67
+ const poolOutput = poolTrade.pool.output;
68
+ return {
69
+ to: poolOutput.locking_bytecode,
70
+ amount: poolOutput.amount + satoshisDelta,
71
+ token: {
72
+ amount: poolOutput.token.amount + tokenDelta,
73
+ category: poolOutput.token.token_id,
74
+ },
75
+ };
76
+ }
77
+ /**
78
+ * Parse a trade rate (price) into a human-readable string.
79
+ * Mirrors paytaca-app parseRate().
80
+ *
81
+ * @param isBuyingToken true when BCH is spent to buy tokens (price in BCH per token)
82
+ */
83
+ export function parseRate(rate, tokenDecimals, isBuyingToken) {
84
+ let multiplierDecimals = 8;
85
+ let divisorDecimals = tokenDecimals;
86
+ if (isBuyingToken) {
87
+ multiplierDecimals = tokenDecimals;
88
+ divisorDecimals = 8;
89
+ }
90
+ const multiplier = 10n ** BigInt(multiplierDecimals);
91
+ const _price = (rate.numerator * multiplier) / rate.denominator;
92
+ const divisor = 10 ** divisorDecimals;
93
+ const price = Number(_price) / divisor;
94
+ return price.toFixed(divisorDecimals);
95
+ }
96
+ //# sourceMappingURL=pools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pools.js","sourceRoot":"","sources":["../../../src/wallet/cauldron/pools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type MicroPool } from './pools.js';
2
+ export type { MicroPool };
3
+ //# sourceMappingURL=pools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pools.test.d.ts","sourceRoot":"","sources":["../../../src/wallet/cauldron/pools.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,YAAY,CAAA;AAmKnB,YAAY,EAAE,SAAS,EAAE,CAAA"}
@@ -0,0 +1,149 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { NATIVE_BCH_TOKEN_ID } from '@cashlab/common';
3
+ import { binToHex } from '@cashlab/common/libauth.js';
4
+ import { apiPoolToMicroPool, microPoolToPoolV0, poolTradeToOutput, parseRate, } from './pools.js';
5
+ import { attemptTrade, getEntriesSize } from './transact.js';
6
+ // Real active LIFT pool from the riften indexer
7
+ const LIFT_TOKEN_ID = '5932b2fd4915d6a75d3ec53282cd49118149a2176ee67ed68b1111ff0786f7fc';
8
+ const apiPools = [
9
+ {
10
+ owner_p2pkh_addr: 'bitcoincash:zqytt7jjxds269xxm60lprpd8ea786xw3cjfh7pwpk',
11
+ owner_pkh: '08b5fa523360ad14c6de9ff08c2d3e7be3e8ce8e',
12
+ pool_id: '5a6a8da19aecf4198537ac006bcc32bb6c3be514338db813a5610a11ff8c9500',
13
+ sats: 7746405,
14
+ token_id: LIFT_TOKEN_ID,
15
+ tokens: 95698,
16
+ tx_pos: 5,
17
+ txid: 'd49d46592026c574e877c3d6cbad0bbd3302262ae08e318669eaa39d19b94ed5',
18
+ },
19
+ {
20
+ owner_p2pkh_addr: 'bitcoincash:zqwap58dm58cdvz9hgpg83lghd8rjjycn59gkys6cc',
21
+ owner_pkh: '1dd0d0eddd0f86b045ba0283c7e8bb4e3948989d',
22
+ pool_id: '6ac2944e341080772c4ed274033687fd4441d6e6ee976560dae9c83581b9f809',
23
+ sats: 10848211,
24
+ token_id: LIFT_TOKEN_ID,
25
+ tokens: 133950,
26
+ tx_pos: 1,
27
+ txid: '09b048f14763e4a4bba08e236c653e678b79991ec500f8d0a457874de62e3980',
28
+ },
29
+ ];
30
+ function pools() {
31
+ return apiPools.map(apiPoolToMicroPool).map(microPoolToPoolV0);
32
+ }
33
+ describe('apiPoolToMicroPool', () => {
34
+ it('maps indexer pool fields onto a MicroPool', () => {
35
+ const micro = apiPoolToMicroPool(apiPools[0]);
36
+ expect(micro.pkh).toBe(apiPools[0].owner_pkh);
37
+ expect(micro.new_utxo_txid).toBe(apiPools[0].txid);
38
+ expect(micro.new_utxo_n).toBe(apiPools[0].tx_pos);
39
+ expect(micro.token_id).toBe(LIFT_TOKEN_ID);
40
+ expect(micro.sats).toBe(apiPools[0].sats);
41
+ expect(micro.token_amount).toBe(apiPools[0].tokens);
42
+ expect(micro.is_withdrawn).toBe(false);
43
+ });
44
+ });
45
+ describe('microPoolToPoolV0', () => {
46
+ it('produces a valid PoolV0 with generated locking bytecode', () => {
47
+ const micro = apiPoolToMicroPool(apiPools[0]);
48
+ const poolV0 = microPoolToPoolV0(micro);
49
+ expect(poolV0.version).toBe('0');
50
+ expect(binToHex(poolV0.parameters.withdraw_pubkey_hash)).toBe(apiPools[0].owner_pkh);
51
+ expect(poolV0.outpoint.index).toBe(apiPools[0].tx_pos);
52
+ expect(binToHex(poolV0.outpoint.txhash)).toBe(apiPools[0].txid);
53
+ expect(poolV0.output.token.token_id).toBe(LIFT_TOKEN_ID);
54
+ expect(poolV0.output.token.amount).toBe(BigInt(apiPools[0].tokens));
55
+ expect(poolV0.output.amount).toBe(BigInt(apiPools[0].sats));
56
+ // Locking bytecode must be non-empty and start with a valid pool script
57
+ expect(poolV0.output.locking_bytecode.length).toBeGreaterThan(0);
58
+ });
59
+ });
60
+ describe('attemptTrade', () => {
61
+ it('computes a best-rate sell trade across pools', () => {
62
+ const result = attemptTrade({
63
+ pools: pools(),
64
+ isBuyingToken: false,
65
+ supply: 1000n, // 10.00 LIFT
66
+ });
67
+ expect(result.entries.length).toBeGreaterThan(0);
68
+ expect(result.summary.supply).toBe(1000n);
69
+ expect(result.summary.demand).toBeGreaterThan(0n);
70
+ expect(result.entries[0].supply_token_id).toBe(LIFT_TOKEN_ID);
71
+ expect(result.entries[0].demand_token_id).toBe(NATIVE_BCH_TOKEN_ID);
72
+ expect(result.summary.trade_fee).toBeGreaterThan(0n);
73
+ });
74
+ it('computes a best-rate buy trade across pools', () => {
75
+ const result = attemptTrade({
76
+ pools: pools(),
77
+ isBuyingToken: true,
78
+ demand: 1000n,
79
+ });
80
+ expect(result.entries[0].supply_token_id).toBe(NATIVE_BCH_TOKEN_ID);
81
+ expect(result.entries[0].demand_token_id).toBe(LIFT_TOKEN_ID);
82
+ expect(result.summary.supply).toBeGreaterThan(0n);
83
+ expect(result.summary.demand).toBe(1000n);
84
+ });
85
+ });
86
+ describe('getEntriesSize', () => {
87
+ it('returns positive input and output sizes', () => {
88
+ const tradeResult = attemptTrade({
89
+ pools: pools(),
90
+ isBuyingToken: false,
91
+ supply: 1000n,
92
+ });
93
+ const sizes = getEntriesSize(tradeResult);
94
+ expect(sizes.inputFees).toBeGreaterThan(0);
95
+ expect(sizes.outputFees).toBeGreaterThan(0);
96
+ });
97
+ });
98
+ describe('poolTradeToOutput', () => {
99
+ it('computes the post-trade pool output', () => {
100
+ const tradeResult = attemptTrade({
101
+ pools: pools(),
102
+ isBuyingToken: false,
103
+ supply: 1000n,
104
+ });
105
+ const entry = tradeResult.entries[0];
106
+ const output = poolTradeToOutput(entry);
107
+ expect(output.amount).toBe(entry.pool.output.amount - entry.demand);
108
+ expect(output.token.amount).toBe(entry.pool.output.token.amount + entry.supply);
109
+ expect(output.token.category).toBe(entry.pool.output.token.token_id);
110
+ });
111
+ });
112
+ describe('parseRate', () => {
113
+ it('formats a sell price (token→BCH)', () => {
114
+ // rate = supply/demand scaled to denominator 1e13.
115
+ // For a sell: price = (num*10^8/den) / 10^tokenDecimals
116
+ // num=3, den=1, decimals=2 → (3*10^8/1)/100 = 3000000
117
+ const rate = { numerator: 3n, denominator: 1n };
118
+ expect(parseRate(rate, 2, false)).toBe('3000000.00');
119
+ });
120
+ it('formats a buy price (BCH→token)', () => {
121
+ // For a buy: price = (num*10^tokenDecimals/den) / 10^8
122
+ // num=1, den=3, decimals=2 → (1*100/3)/10^8 = 0.00000033
123
+ const rate = { numerator: 1n, denominator: 3n };
124
+ expect(parseRate(rate, 2, true)).toBe('0.00000033');
125
+ });
126
+ it('matches the app formula on a real LIFT trade', () => {
127
+ // SELL: supply=1000 token base units → demand=80378 sats across 2 pools
128
+ const sellTrade = attemptTrade({
129
+ pools: pools(),
130
+ isBuyingToken: false,
131
+ supply: 1000n,
132
+ });
133
+ // rate = supply*1e13/demand
134
+ const sellRate = sellTrade.summary.rate;
135
+ expect(sellRate.denominator).toBe(10000000000000n);
136
+ expect(sellRate.numerator).toBe(124412152579n);
137
+ expect(parseRate(sellRate, 2, false)).toBe('12441.21');
138
+ // BUY: demand=1000 token base units → supply=81569 sats across 2 pools
139
+ const buyTrade = attemptTrade({
140
+ pools: pools(),
141
+ isBuyingToken: true,
142
+ demand: 1000n,
143
+ });
144
+ const buyRate = buyTrade.summary.rate;
145
+ expect(buyRate.numerator).toBe(815690000000000n);
146
+ expect(parseRate(buyRate, 2, true)).toBe('0.00008156');
147
+ });
148
+ });
149
+ //# sourceMappingURL=pools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pools.test.js","sourceRoot":"","sources":["../../../src/wallet/cauldron/pools.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Cauldron swap orchestration: quote estimation and on-chain execution.
3
+ *
4
+ * This is the generic swap primitive (token ⇄ BCH). Higher-level callers
5
+ * (e.g. an MCP payment wrapper) can use estimateSwap() to price a swap and
6
+ * executeSwap() to broadcast it, mirroring the paytaca-app cauldron flow.
7
+ */
8
+ import { type PoolV0, type TradeResult } from '@cashlab/cauldron';
9
+ import type { BchWallet } from '../bch.js';
10
+ import { type CauldronTokenData } from './api.js';
11
+ export type SwapDirection = 'buy' | 'sell';
12
+ export interface SwapQuote {
13
+ tokenId: string;
14
+ tokenData: CauldronTokenData;
15
+ direction: SwapDirection;
16
+ isBuyingToken: boolean;
17
+ pools: PoolV0[];
18
+ tradeResult: TradeResult;
19
+ /** Human-readable price. */
20
+ rate: string;
21
+ /** Token amount in base units. */
22
+ tokenAmount: bigint;
23
+ /** BCH amount involved in base units (satoshis). */
24
+ bchAmount: bigint;
25
+ /** Trade fee in satoshis. */
26
+ tradeFee: bigint;
27
+ }
28
+ export interface EstimateSwapOpts {
29
+ /** 64-char hex token category. */
30
+ tokenId: string;
31
+ /** 'buy' = spend BCH to receive tokens, 'sell' = spend tokens to receive BCH. */
32
+ direction: SwapDirection;
33
+ /** Token amount in base units (sell: amount supplied; buy: amount received). */
34
+ amount: bigint;
35
+ }
36
+ export interface ExecuteSwapOpts extends EstimateSwapOpts {
37
+ bchWallet: BchWallet;
38
+ mnemonic: string;
39
+ derivationPath: string;
40
+ }
41
+ export interface SwapResult {
42
+ success: boolean;
43
+ txid?: string;
44
+ transaction?: string;
45
+ error?: string;
46
+ quote?: SwapQuote;
47
+ }
48
+ /**
49
+ * Estimate a swap: fetch pools + token data and compute the best-rate trade.
50
+ */
51
+ export declare function estimateSwap(opts: EstimateSwapOpts): Promise<SwapQuote>;
52
+ /**
53
+ * Format a SwapQuote for human display.
54
+ */
55
+ export declare function formatQuote(quote: SwapQuote): string;
56
+ /**
57
+ * Execute a swap: build + sign the trade transaction and broadcast it.
58
+ */
59
+ export declare function executeSwap(opts: ExecuteSwapOpts): Promise<SwapResult>;
60
+ /**
61
+ * Build + sign the trade transaction (no broadcast).
62
+ */
63
+ export declare function buildSignedTradeTx(opts: {
64
+ bchWallet: BchWallet;
65
+ mnemonic: string;
66
+ derivationPath: string;
67
+ quote: SwapQuote;
68
+ }): Promise<import("@cashlab/cauldron").TradeTxResult>;
69
+ //# sourceMappingURL=swap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../../src/wallet/cauldron/swap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAe,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,UAAU,CAAA;AASjB,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAA;AAE1C,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,iBAAiB,CAAA;IAC5B,SAAS,EAAE,aAAa,CAAA;IACxB,aAAa,EAAE,OAAO,CAAA;IACtB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,WAAW,EAAE,WAAW,CAAA;IACxB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;IACjB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,iFAAiF;IACjF,SAAS,EAAE,aAAa,CAAA;IACxB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,SAAS,EAAE,SAAS,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,SAAS,CAAC,CA8CpB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAwBpD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAkD5E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,SAAS,EAAE,SAAS,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,SAAS,CAAA;CACjB,sDA+BA"}