paytaca-cli 0.6.1 → 0.7.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.
- package/README.md +153 -37
- package/dist/ai/autoRefill.d.ts +27 -0
- package/dist/ai/autoRefill.d.ts.map +1 -0
- package/dist/ai/autoRefill.js +75 -0
- package/dist/ai/autoRefill.js.map +1 -0
- package/dist/ai/client.d.ts +73 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +90 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/config.d.ts +7 -0
- package/dist/ai/config.d.ts.map +1 -0
- package/dist/ai/config.js +16 -0
- package/dist/ai/config.js.map +1 -0
- package/dist/ai/configure.d.ts +61 -0
- package/dist/ai/configure.d.ts.map +1 -0
- package/dist/ai/configure.js +452 -0
- package/dist/ai/configure.js.map +1 -0
- package/dist/ai/credits.d.ts +27 -0
- package/dist/ai/credits.d.ts.map +1 -0
- package/dist/ai/credits.js +99 -0
- package/dist/ai/credits.js.map +1 -0
- package/dist/ai/models.d.ts +13 -0
- package/dist/ai/models.d.ts.map +1 -0
- package/dist/ai/models.js +49 -0
- package/dist/ai/models.js.map +1 -0
- package/dist/ai/oauth.d.ts +45 -0
- package/dist/ai/oauth.d.ts.map +1 -0
- package/dist/ai/oauth.js +137 -0
- package/dist/ai/oauth.js.map +1 -0
- package/dist/ai/purchase.d.ts +30 -0
- package/dist/ai/purchase.d.ts.map +1 -0
- package/dist/ai/purchase.js +456 -0
- package/dist/ai/purchase.js.map +1 -0
- package/dist/commands/address.d.ts.map +1 -1
- package/dist/commands/address.js +88 -36
- package/dist/commands/address.js.map +1 -1
- package/dist/commands/ai.d.ts +9 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +675 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/balance.d.ts.map +1 -1
- package/dist/commands/balance.js +68 -129
- package/dist/commands/balance.js.map +1 -1
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +38 -78
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/mcp.d.ts +14 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +68 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pay.js +1 -1
- package/dist/commands/pay.js.map +1 -1
- package/dist/commands/receive.d.ts +1 -8
- package/dist/commands/receive.d.ts.map +1 -1
- package/dist/commands/receive.js +51 -124
- package/dist/commands/receive.js.map +1 -1
- package/dist/commands/send.d.ts +0 -10
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +40 -50
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/swap.js +1 -1
- package/dist/commands/swap.js.map +1 -1
- package/dist/commands/token.d.ts +1 -9
- package/dist/commands/token.d.ts.map +1 -1
- package/dist/commands/token.js +192 -289
- package/dist/commands/token.js.map +1 -1
- package/dist/core/context.d.ts +30 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +45 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/wallet.d.ts +130 -0
- package/dist/core/wallet.d.ts.map +1 -0
- package/dist/core/wallet.js +276 -0
- package/dist/core/wallet.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +24 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +5 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +473 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/utils/format.d.ts +23 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +62 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/x402.js +1 -1
- package/dist/utils/x402.js.map +1 -1
- package/dist/wallet/index.d.ts +13 -0
- package/dist/wallet/index.d.ts.map +1 -1
- package/dist/wallet/index.js +18 -0
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/keys.d.ts.map +1 -1
- package/dist/wallet/keys.js +2 -0
- package/dist/wallet/keys.js.map +1 -1
- package/package.json +7 -3
- package/dist/commands/wallet.test.d.ts +0 -2
- package/dist/commands/wallet.test.d.ts.map +0 -1
- package/dist/commands/wallet.test.js +0 -68
- package/dist/commands/wallet.test.js.map +0 -1
- package/dist/nostr/chat.test.d.ts +0 -2
- package/dist/nostr/chat.test.d.ts.map +0 -1
- package/dist/nostr/chat.test.js +0 -121
- package/dist/nostr/chat.test.js.map +0 -1
- package/dist/nostr/store.test.d.ts +0 -2
- package/dist/nostr/store.test.d.ts.map +0 -1
- package/dist/nostr/store.test.js +0 -456
- package/dist/nostr/store.test.js.map +0 -1
- package/dist/utils/prices.test.d.ts +0 -5
- package/dist/utils/prices.test.d.ts.map +0 -1
- package/dist/utils/prices.test.js +0 -62
- package/dist/utils/prices.test.js.map +0 -1
- package/dist/utils/x402.test.d.ts +0 -2
- package/dist/utils/x402.test.d.ts.map +0 -1
- package/dist/utils/x402.test.js +0 -216
- package/dist/utils/x402.test.js.map +0 -1
- package/dist/wallet/cauldron/pools.test.d.ts +0 -3
- package/dist/wallet/cauldron/pools.test.d.ts.map +0 -1
- package/dist/wallet/cauldron/pools.test.js +0 -149
- package/dist/wallet/cauldron/pools.test.js.map +0 -1
- package/dist/wallet/cauldron/swap.test.d.ts +0 -2
- package/dist/wallet/cauldron/swap.test.d.ts.map +0 -1
- package/dist/wallet/cauldron/swap.test.js +0 -179
- package/dist/wallet/cauldron/swap.test.js.map +0 -1
- package/skills/README.md +0 -68
- package/skills/paytaca-send/SKILL.md +0 -159
- package/skills/paytaca-wallet/SKILL.md +0 -164
- package/skills/paytaca-x402/SKILL.md +0 -130
package/dist/utils/x402.test.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { parsePaymentRequiredJson, selectBchPaymentRequirements, buildPaymentPayload, buildAuthorization, parsePaymentResponse, isBchNetwork, isChipnetNetwork, BCH_MAINNET_NETWORK, BCH_CHIPNET_NETWORK, BCH_ASSET_ID, } from './x402.js';
|
|
3
|
-
describe('x402 parsing', () => {
|
|
4
|
-
describe('parsePaymentRequiredJson', () => {
|
|
5
|
-
it('should parse valid PaymentRequired JSON', () => {
|
|
6
|
-
const input = {
|
|
7
|
-
x402Version: 2,
|
|
8
|
-
error: 'Payment required',
|
|
9
|
-
resource: { url: 'https://api.example.com/data' },
|
|
10
|
-
accepts: [
|
|
11
|
-
{
|
|
12
|
-
scheme: 'utxo',
|
|
13
|
-
network: BCH_MAINNET_NETWORK,
|
|
14
|
-
amount: '1000',
|
|
15
|
-
asset: BCH_ASSET_ID,
|
|
16
|
-
payTo: 'bitcoincash:qp2f5j6q3fj5gjwgk8rkq8xrk8q8q8q8q8q8q8q8q',
|
|
17
|
-
maxTimeoutSeconds: 300,
|
|
18
|
-
extra: {},
|
|
19
|
-
},
|
|
20
|
-
],
|
|
21
|
-
extensions: {},
|
|
22
|
-
};
|
|
23
|
-
const result = parsePaymentRequiredJson(input);
|
|
24
|
-
expect(result).not.toBeNull();
|
|
25
|
-
expect(result.x402Version).toBe(2);
|
|
26
|
-
expect(result.error).toBe('Payment required');
|
|
27
|
-
expect(result.resource.url).toBe('https://api.example.com/data');
|
|
28
|
-
expect(result.accepts).toHaveLength(1);
|
|
29
|
-
expect(result.accepts[0].scheme).toBe('utxo');
|
|
30
|
-
expect(result.accepts[0].amount).toBe('1000');
|
|
31
|
-
});
|
|
32
|
-
it('should return null for null input', () => {
|
|
33
|
-
expect(parsePaymentRequiredJson(null)).toBeNull();
|
|
34
|
-
});
|
|
35
|
-
it('should return null for non-object input', () => {
|
|
36
|
-
expect(parsePaymentRequiredJson('string')).toBeNull();
|
|
37
|
-
expect(parsePaymentRequiredJson(123)).toBeNull();
|
|
38
|
-
});
|
|
39
|
-
it('should return null for wrong x402Version', () => {
|
|
40
|
-
const input = { x402Version: 1, accepts: [] };
|
|
41
|
-
expect(parsePaymentRequiredJson(input)).toBeNull();
|
|
42
|
-
});
|
|
43
|
-
it('should use default values for missing optional fields', () => {
|
|
44
|
-
const input = {
|
|
45
|
-
x402Version: 2,
|
|
46
|
-
resource: {},
|
|
47
|
-
accepts: [
|
|
48
|
-
{
|
|
49
|
-
scheme: 'utxo',
|
|
50
|
-
network: BCH_MAINNET_NETWORK,
|
|
51
|
-
payTo: 'bitcoincash:qp2f5j6q3fj5gjwgk8rkq8xrk8q8q8q8q8q8q8q8',
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
};
|
|
55
|
-
const result = parsePaymentRequiredJson(input);
|
|
56
|
-
expect(result).not.toBeNull();
|
|
57
|
-
expect(result.accepts[0].asset).toBe(BCH_ASSET_ID);
|
|
58
|
-
expect(result.accepts[0].maxTimeoutSeconds).toBe(60);
|
|
59
|
-
});
|
|
60
|
-
it('should filter out invalid accepts entries', () => {
|
|
61
|
-
const input = {
|
|
62
|
-
x402Version: 2,
|
|
63
|
-
resource: { url: 'https://api.example.com' },
|
|
64
|
-
accepts: [
|
|
65
|
-
{ scheme: 'utxo', network: BCH_MAINNET_NETWORK, payTo: 'valid1' },
|
|
66
|
-
{ scheme: 'invalid' },
|
|
67
|
-
{ network: BCH_MAINNET_NETWORK, payTo: 'missing-scheme' },
|
|
68
|
-
{ scheme: 'utxo', payTo: 'missing-network' },
|
|
69
|
-
{ scheme: 'utxo', network: BCH_MAINNET_NETWORK },
|
|
70
|
-
],
|
|
71
|
-
};
|
|
72
|
-
const result = parsePaymentRequiredJson(input);
|
|
73
|
-
expect(result.accepts).toHaveLength(1);
|
|
74
|
-
expect(result.accepts[0].payTo).toBe('valid1');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
describe('selectBchPaymentRequirements', () => {
|
|
78
|
-
const paymentRequired = {
|
|
79
|
-
x402Version: 2,
|
|
80
|
-
resource: { url: 'https://api.example.com' },
|
|
81
|
-
accepts: [
|
|
82
|
-
{
|
|
83
|
-
scheme: 'utxo',
|
|
84
|
-
network: BCH_MAINNET_NETWORK,
|
|
85
|
-
amount: '1000',
|
|
86
|
-
asset: BCH_ASSET_ID,
|
|
87
|
-
payTo: 'bitcoincash:mainnet-address',
|
|
88
|
-
maxTimeoutSeconds: 300,
|
|
89
|
-
extra: {},
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
scheme: 'utxo',
|
|
93
|
-
network: BCH_CHIPNET_NETWORK,
|
|
94
|
-
amount: '1000',
|
|
95
|
-
asset: BCH_ASSET_ID,
|
|
96
|
-
payTo: 'bitcoincash:chipnet-address',
|
|
97
|
-
maxTimeoutSeconds: 300,
|
|
98
|
-
extra: {},
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
|
-
extensions: {},
|
|
102
|
-
};
|
|
103
|
-
it('should select mainnet requirements for mainnet client', () => {
|
|
104
|
-
const result = selectBchPaymentRequirements(paymentRequired, 'mainnet');
|
|
105
|
-
expect(result).not.toBeNull();
|
|
106
|
-
expect(result.network).toBe(BCH_MAINNET_NETWORK);
|
|
107
|
-
expect(result.payTo).toBe('bitcoincash:mainnet-address');
|
|
108
|
-
});
|
|
109
|
-
it('should select chipnet requirements for chipnet client', () => {
|
|
110
|
-
const result = selectBchPaymentRequirements(paymentRequired, 'chipnet');
|
|
111
|
-
expect(result).not.toBeNull();
|
|
112
|
-
expect(result.network).toBe(BCH_CHIPNET_NETWORK);
|
|
113
|
-
expect(result.payTo).toBe('bitcoincash:chipnet-address');
|
|
114
|
-
});
|
|
115
|
-
it('should return null when no matching network', () => {
|
|
116
|
-
const emptyAccepts = { ...paymentRequired, accepts: [paymentRequired.accepts[0]] };
|
|
117
|
-
const result = selectBchPaymentRequirements(emptyAccepts, 'chipnet');
|
|
118
|
-
expect(result).toBeNull();
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe('x402 building', () => {
|
|
123
|
-
describe('buildPaymentPayload', () => {
|
|
124
|
-
it('should build a valid PaymentPayload', () => {
|
|
125
|
-
const accepted = {
|
|
126
|
-
scheme: 'utxo',
|
|
127
|
-
network: BCH_MAINNET_NETWORK,
|
|
128
|
-
amount: '1000',
|
|
129
|
-
asset: BCH_ASSET_ID,
|
|
130
|
-
payTo: 'bitcoincash:qp2f5j6q3fj5gjwgk8rkq8xrk8q8q8q8q8q8q8q8',
|
|
131
|
-
maxTimeoutSeconds: 300,
|
|
132
|
-
extra: {},
|
|
133
|
-
};
|
|
134
|
-
const result = buildPaymentPayload(accepted, 'https://api.example.com/data', 'bitcoincash:payer-address', 'abc123txid', 0, '1000');
|
|
135
|
-
expect(result.x402Version).toBe(2);
|
|
136
|
-
expect(result.resource.url).toBe('https://api.example.com/data');
|
|
137
|
-
expect(result.accepted).toBe(accepted);
|
|
138
|
-
expect(result.payload.authorization.from).toBe('bitcoincash:payer-address');
|
|
139
|
-
expect(result.payload.authorization.to).toBe(accepted.payTo);
|
|
140
|
-
expect(result.payload.authorization.txid).toBe('abc123txid');
|
|
141
|
-
expect(result.payload.signature).toBe('');
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
describe('buildAuthorization', () => {
|
|
145
|
-
it('should build a valid Authorization', () => {
|
|
146
|
-
const accepted = {
|
|
147
|
-
scheme: 'utxo',
|
|
148
|
-
network: BCH_MAINNET_NETWORK,
|
|
149
|
-
amount: '1000',
|
|
150
|
-
asset: BCH_ASSET_ID,
|
|
151
|
-
payTo: 'bitcoincash:qp2f5j6q3fj5gjwgk8rkq8xrk8q8q8q8q8q8q8q8',
|
|
152
|
-
maxTimeoutSeconds: 300,
|
|
153
|
-
extra: {},
|
|
154
|
-
};
|
|
155
|
-
const result = buildAuthorization(accepted, 'https://api.example.com/data', 'bitcoincash:payer-address', 'abc123txid', 0, '1000');
|
|
156
|
-
expect(result.from).toBe('bitcoincash:payer-address');
|
|
157
|
-
expect(result.to).toBe(accepted.payTo);
|
|
158
|
-
expect(result.txid).toBe('abc123txid');
|
|
159
|
-
expect(result.vout).toBe(0);
|
|
160
|
-
expect(result.amount).toBe('1000');
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
describe('parsePaymentResponse', () => {
|
|
165
|
-
it('should parse valid isValid response', () => {
|
|
166
|
-
const data = {
|
|
167
|
-
isValid: true,
|
|
168
|
-
payer: 'bitcoincash:abc123',
|
|
169
|
-
remainingBalanceSat: '1000000',
|
|
170
|
-
};
|
|
171
|
-
const result = parsePaymentResponse(data);
|
|
172
|
-
expect(result.isValid).toBe(true);
|
|
173
|
-
expect(result.payer).toBe('bitcoincash:abc123');
|
|
174
|
-
expect(result.remainingBalanceSat).toBe('1000000');
|
|
175
|
-
});
|
|
176
|
-
it('should parse error response', () => {
|
|
177
|
-
const data = { error: 'Invalid signature' };
|
|
178
|
-
const result = parsePaymentResponse(data);
|
|
179
|
-
expect(result.isValid).toBe(false);
|
|
180
|
-
expect(result.invalidReason).toBe('Invalid signature');
|
|
181
|
-
});
|
|
182
|
-
it('should return no_response_data for null input', () => {
|
|
183
|
-
const result = parsePaymentResponse(null);
|
|
184
|
-
expect(result.isValid).toBe(false);
|
|
185
|
-
expect(result.invalidReason).toBe('no_response_data');
|
|
186
|
-
});
|
|
187
|
-
it('should return unknown_response_format for unrecognized data', () => {
|
|
188
|
-
const data = { some: 'unknown', format: true };
|
|
189
|
-
const result = parsePaymentResponse(data);
|
|
190
|
-
expect(result.isValid).toBe(false);
|
|
191
|
-
expect(result.invalidReason).toBe('unknown_response_format');
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('network helpers', () => {
|
|
195
|
-
describe('isBchNetwork', () => {
|
|
196
|
-
it('should return true for mainnet', () => {
|
|
197
|
-
expect(isBchNetwork(BCH_MAINNET_NETWORK)).toBe(true);
|
|
198
|
-
});
|
|
199
|
-
it('should return true for chipnet', () => {
|
|
200
|
-
expect(isBchNetwork(BCH_CHIPNET_NETWORK)).toBe(true);
|
|
201
|
-
});
|
|
202
|
-
it('should return false for other networks', () => {
|
|
203
|
-
expect(isBchNetwork('bitcoin')).toBe(false);
|
|
204
|
-
expect(isBchNetwork('litecoin')).toBe(false);
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
describe('isChipnetNetwork', () => {
|
|
208
|
-
it('should return true for chipnet', () => {
|
|
209
|
-
expect(isChipnetNetwork(BCH_CHIPNET_NETWORK)).toBe(true);
|
|
210
|
-
});
|
|
211
|
-
it('should return false for mainnet', () => {
|
|
212
|
-
expect(isChipnetNetwork(BCH_MAINNET_NETWORK)).toBe(false);
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
//# sourceMappingURL=x402.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"x402.test.js","sourceRoot":"","sources":["../../src/utils/x402.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,149 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pools.test.js","sourceRoot":"","sources":["../../../src/wallet/cauldron/pools.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"swap.test.d.ts","sourceRoot":"","sources":["../../../src/wallet/cauldron/swap.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { computePlatformFee, formatQuote, PLATFORM_FEE_DUST_LIMIT } from './swap.js';
|
|
3
|
-
import { fetchCauldronFee } from './api.js';
|
|
4
|
-
const FEE_ADDRESS = 'bitcoincash:qp9szr5k40z88m5jhmpytqt8pq5zfz0yvcs7q5lef7';
|
|
5
|
-
function fakeTradeResult(summary) {
|
|
6
|
-
return {
|
|
7
|
-
entries: [],
|
|
8
|
-
summary: { ...summary, rate: 0n },
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
const feeConfig = {
|
|
12
|
-
address: FEE_ADDRESS,
|
|
13
|
-
feeRateBps: 30,
|
|
14
|
-
maxUsd: 1,
|
|
15
|
-
};
|
|
16
|
-
describe('computePlatformFee', () => {
|
|
17
|
-
it('charges 0.3% of (demand - trade_fee) on sells', () => {
|
|
18
|
-
// 999_000 sats * 30/10000 = 2_997 sats; cap at $500/BCH = 200_000 sats
|
|
19
|
-
const fee = computePlatformFee({
|
|
20
|
-
tradeResult: fakeTradeResult({ supply: 500000n, demand: 1000000n, trade_fee: 1000n }),
|
|
21
|
-
isBuyingToken: false,
|
|
22
|
-
feeConfig,
|
|
23
|
-
bchUsdPrice: 500,
|
|
24
|
-
});
|
|
25
|
-
expect(fee).toEqual({ to: FEE_ADDRESS, amount: 2997n });
|
|
26
|
-
});
|
|
27
|
-
it('charges 0.3% of (supply - trade_fee) on buys', () => {
|
|
28
|
-
const fee = computePlatformFee({
|
|
29
|
-
tradeResult: fakeTradeResult({ supply: 2000000n, demand: 1000000n, trade_fee: 2000n }),
|
|
30
|
-
isBuyingToken: true,
|
|
31
|
-
feeConfig,
|
|
32
|
-
bchUsdPrice: 500,
|
|
33
|
-
});
|
|
34
|
-
// 1_998_000 * 30/10000 = 5_994
|
|
35
|
-
expect(fee?.amount).toBe(5994n);
|
|
36
|
-
});
|
|
37
|
-
it('caps the fee at max_usd worth of BCH at the current price', () => {
|
|
38
|
-
// 4 BCH trade -> 0.3% = 1_200_000 sats; $1 at $100/BCH = 1_000_000 sats
|
|
39
|
-
const fee = computePlatformFee({
|
|
40
|
-
tradeResult: fakeTradeResult({ supply: 400000000n, demand: 1n, trade_fee: 0n }),
|
|
41
|
-
isBuyingToken: true,
|
|
42
|
-
feeConfig,
|
|
43
|
-
bchUsdPrice: 100,
|
|
44
|
-
});
|
|
45
|
-
expect(fee?.amount).toBe(1000000n);
|
|
46
|
-
});
|
|
47
|
-
it('does not cap when 0.3% is below the cap', () => {
|
|
48
|
-
// 1 BCH trade -> 0.3% = 300_000 sats < cap 1_000_000 sats
|
|
49
|
-
const fee = computePlatformFee({
|
|
50
|
-
tradeResult: fakeTradeResult({ supply: 100000000n, demand: 1n, trade_fee: 0n }),
|
|
51
|
-
isBuyingToken: true,
|
|
52
|
-
feeConfig,
|
|
53
|
-
bchUsdPrice: 100,
|
|
54
|
-
});
|
|
55
|
-
expect(fee?.amount).toBe(300000n);
|
|
56
|
-
});
|
|
57
|
-
it('does not charge below the dust limit', () => {
|
|
58
|
-
// 100_000 sats * 1bp/10000 = 10 sats < 546 -> no fee at all
|
|
59
|
-
const fee = computePlatformFee({
|
|
60
|
-
tradeResult: fakeTradeResult({ supply: 100000n, demand: 1n, trade_fee: 0n }),
|
|
61
|
-
isBuyingToken: true,
|
|
62
|
-
feeConfig: { ...feeConfig, feeRateBps: 1 },
|
|
63
|
-
bchUsdPrice: 100,
|
|
64
|
-
});
|
|
65
|
-
expect(fee).toBeNull();
|
|
66
|
-
});
|
|
67
|
-
it('returns null when no fee address is configured', () => {
|
|
68
|
-
const fee = computePlatformFee({
|
|
69
|
-
tradeResult: fakeTradeResult({ supply: 100000000n, demand: 1n, trade_fee: 0n }),
|
|
70
|
-
isBuyingToken: true,
|
|
71
|
-
feeConfig: { ...feeConfig, address: null },
|
|
72
|
-
bchUsdPrice: 100,
|
|
73
|
-
});
|
|
74
|
-
expect(fee).toBeNull();
|
|
75
|
-
});
|
|
76
|
-
it('returns null when the BCH price is unavailable (no fee on price failure)', () => {
|
|
77
|
-
const fee = computePlatformFee({
|
|
78
|
-
tradeResult: fakeTradeResult({ supply: 100000000n, demand: 1n, trade_fee: 0n }),
|
|
79
|
-
isBuyingToken: true,
|
|
80
|
-
feeConfig,
|
|
81
|
-
bchUsdPrice: null,
|
|
82
|
-
});
|
|
83
|
-
expect(fee).toBeNull();
|
|
84
|
-
});
|
|
85
|
-
it('returns null for non-positive BCH prices', () => {
|
|
86
|
-
const fee = computePlatformFee({
|
|
87
|
-
tradeResult: fakeTradeResult({ supply: 100000000n, demand: 1n, trade_fee: 0n }),
|
|
88
|
-
isBuyingToken: true,
|
|
89
|
-
feeConfig,
|
|
90
|
-
bchUsdPrice: 0,
|
|
91
|
-
});
|
|
92
|
-
expect(fee).toBeNull();
|
|
93
|
-
});
|
|
94
|
-
it('returns null when a tiny price makes the cap itself dust', () => {
|
|
95
|
-
const fee = computePlatformFee({
|
|
96
|
-
tradeResult: fakeTradeResult({ supply: 100000000n, demand: 1n, trade_fee: 0n }),
|
|
97
|
-
isBuyingToken: true,
|
|
98
|
-
feeConfig,
|
|
99
|
-
bchUsdPrice: 1_000_000_000,
|
|
100
|
-
});
|
|
101
|
-
// cap = floor(1/1e9 * 1e8) = 0 sats -> no fee
|
|
102
|
-
expect(fee).toBeNull();
|
|
103
|
-
});
|
|
104
|
-
it('treats a zero or negative trade size as no fee', () => {
|
|
105
|
-
const fee = computePlatformFee({
|
|
106
|
-
tradeResult: fakeTradeResult({ supply: 0n, demand: 1n, trade_fee: 0n }),
|
|
107
|
-
isBuyingToken: true,
|
|
108
|
-
feeConfig,
|
|
109
|
-
bchUsdPrice: 100,
|
|
110
|
-
});
|
|
111
|
-
expect(fee).toBeNull();
|
|
112
|
-
});
|
|
113
|
-
it('exposes the dust limit constant as 546 sats', () => {
|
|
114
|
-
expect(PLATFORM_FEE_DUST_LIMIT).toBe(546n);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe('formatQuote', () => {
|
|
118
|
-
const tokenData = {
|
|
119
|
-
token_id: 'abc',
|
|
120
|
-
display_name: 'Test Token',
|
|
121
|
-
display_symbol: 'TT',
|
|
122
|
-
price_now: 1,
|
|
123
|
-
price_now_usd: 1,
|
|
124
|
-
tvl_sats: 1,
|
|
125
|
-
bcmr: {
|
|
126
|
-
name: 'Test Token',
|
|
127
|
-
description: '',
|
|
128
|
-
token: { category: 'abc', decimals: 2, symbol: 'TT' },
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
function quote(overrides = {}) {
|
|
132
|
-
return {
|
|
133
|
-
tokenId: 'abc',
|
|
134
|
-
tokenData,
|
|
135
|
-
direction: 'sell',
|
|
136
|
-
isBuyingToken: false,
|
|
137
|
-
pools: [],
|
|
138
|
-
tradeResult: fakeTradeResult({ supply: 500000n, demand: 1000000n, trade_fee: 1000n }),
|
|
139
|
-
rate: '2.0',
|
|
140
|
-
tokenAmount: 500000n,
|
|
141
|
-
bchAmount: 1000000n,
|
|
142
|
-
tradeFee: 1000n,
|
|
143
|
-
...overrides,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
it('lists the platform fee line when a fee is applied', () => {
|
|
147
|
-
const text = formatQuote(quote({
|
|
148
|
-
platformFee: { to: FEE_ADDRESS, amount: 2997n },
|
|
149
|
-
}));
|
|
150
|
-
expect(text).toContain('Platform fee: ~0.00002997 BCH');
|
|
151
|
-
expect(text).toContain('Trade fee: ~0.00001000 BCH');
|
|
152
|
-
});
|
|
153
|
-
it('omits the line entirely when no fee', () => {
|
|
154
|
-
const noFee = formatQuote(quote());
|
|
155
|
-
expect(noFee).not.toContain('Platform fee');
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
describe('fetchCauldronFee', () => {
|
|
159
|
-
afterEach(() => {
|
|
160
|
-
vi.unstubAllGlobals();
|
|
161
|
-
});
|
|
162
|
-
it('parses the watchtower response and defaults missing fields', async () => {
|
|
163
|
-
vi.stubGlobal('fetch', vi.fn(async () => new Response(JSON.stringify({ address: FEE_ADDRESS, fee_rate_bps: 30, max_usd: '1.00' }), { status: 200 })));
|
|
164
|
-
const config = await fetchCauldronFee();
|
|
165
|
-
expect(config).toEqual({ address: FEE_ADDRESS, feeRateBps: 30, maxUsd: 1 });
|
|
166
|
-
});
|
|
167
|
-
it('maps an empty address to null (feature disabled)', async () => {
|
|
168
|
-
vi.stubGlobal('fetch', vi.fn(async () => new Response(JSON.stringify({ address: '' }), { status: 200 })));
|
|
169
|
-
const config = await fetchCauldronFee();
|
|
170
|
-
expect(config.address).toBeNull();
|
|
171
|
-
expect(config.feeRateBps).toBe(30);
|
|
172
|
-
expect(config.maxUsd).toBe(1);
|
|
173
|
-
});
|
|
174
|
-
it('throws a CauldronApiError on http failure', async () => {
|
|
175
|
-
vi.stubGlobal('fetch', vi.fn(async () => new Response('nope', { status: 500 })));
|
|
176
|
-
await expect(fetchCauldronFee()).rejects.toThrow('cauldron-fee request failed (500');
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
//# sourceMappingURL=swap.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"swap.test.js","sourceRoot":"","sources":["../../../src/wallet/cauldron/swap.test.ts"],"names":[],"mappings":"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"}
|