@clawnch/clawncher-sdk 0.1.2 → 0.1.3
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 +59 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/wayfinder-types.d.ts +324 -0
- package/dist/wayfinder-types.d.ts.map +1 -0
- package/dist/wayfinder-types.js +30 -0
- package/dist/wayfinder-types.js.map +1 -0
- package/dist/wayfinder.d.ts +175 -0
- package/dist/wayfinder.d.ts.map +1 -0
- package/dist/wayfinder.js +638 -0
- package/dist/wayfinder.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WayfinderClient - Cross-chain DeFi via Wayfinder Paths
|
|
3
|
+
*
|
|
4
|
+
* Two-tier integration:
|
|
5
|
+
* - Tier 1 (REST): Swap quotes, token resolution, balances, pool data.
|
|
6
|
+
* Always available — calls the Wayfinder API directly.
|
|
7
|
+
* - Tier 2 (CLI bridge): Execute swaps, run strategies, Hyperliquid trading.
|
|
8
|
+
* Requires Python 3.12+ and the wayfinder-paths pip package installed locally.
|
|
9
|
+
* Shells out to the `wayfinder` CLI for operations that need local tx signing.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { WayfinderClient } from '@clawnch/clawncher-sdk';
|
|
14
|
+
*
|
|
15
|
+
* const wf = new WayfinderClient({
|
|
16
|
+
* apiKey: 'wk_...',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Tier 1: Get a cross-chain swap quote (no Python needed)
|
|
20
|
+
* const quote = await wf.quoteSwap({
|
|
21
|
+
* fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
|
|
22
|
+
* toToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
|
|
23
|
+
* fromChain: 1,
|
|
24
|
+
* toChain: 8453,
|
|
25
|
+
* fromWallet: '0x...',
|
|
26
|
+
* amount: '5000000', // 5 USDC in raw units (6 decimals)
|
|
27
|
+
* });
|
|
28
|
+
* console.log('Best route:', quote.bestQuote?.provider);
|
|
29
|
+
*
|
|
30
|
+
* // Tier 1: Get multi-chain balances
|
|
31
|
+
* const balances = await wf.getBalances('0x...');
|
|
32
|
+
* console.log('Total value:', balances.totalValueUsd);
|
|
33
|
+
*
|
|
34
|
+
* // Tier 2: Execute a swap (requires Python + wayfinder-paths)
|
|
35
|
+
* const status = await wf.checkPython();
|
|
36
|
+
* if (status.wayfinderInstalled) {
|
|
37
|
+
* const result = await wf.executeSwap({
|
|
38
|
+
* kind: 'swap',
|
|
39
|
+
* walletLabel: 'main',
|
|
40
|
+
* amount: '5',
|
|
41
|
+
* fromToken: 'usd-coin',
|
|
42
|
+
* toToken: 'ethereum',
|
|
43
|
+
* });
|
|
44
|
+
* console.log('Tx:', result.result?.effects);
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
import { execFile } from 'node:child_process';
|
|
49
|
+
import { promisify } from 'node:util';
|
|
50
|
+
const execFileAsync = promisify(execFile);
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Constants
|
|
53
|
+
// ============================================================================
|
|
54
|
+
const DEFAULT_API_URL = 'https://strategies.wayfinder.ai/api/v1';
|
|
55
|
+
const DEFAULT_TIMEOUT = 30_000;
|
|
56
|
+
const CLI_TIMEOUT = 120_000; // strategies can take a while
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Error class
|
|
59
|
+
// ============================================================================
|
|
60
|
+
export class WayfinderError extends Error {
|
|
61
|
+
code;
|
|
62
|
+
details;
|
|
63
|
+
constructor(message, code, details) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.code = code;
|
|
66
|
+
this.details = details;
|
|
67
|
+
this.name = 'WayfinderError';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// WayfinderClient
|
|
72
|
+
// ============================================================================
|
|
73
|
+
export class WayfinderClient {
|
|
74
|
+
apiKey;
|
|
75
|
+
apiUrl;
|
|
76
|
+
timeout;
|
|
77
|
+
pythonPathOverride;
|
|
78
|
+
pythonStatusCache = null;
|
|
79
|
+
constructor(config) {
|
|
80
|
+
if (!config.apiKey) {
|
|
81
|
+
throw new WayfinderError('Wayfinder API key is required', 'MISSING_API_KEY');
|
|
82
|
+
}
|
|
83
|
+
this.apiKey = config.apiKey;
|
|
84
|
+
this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, '');
|
|
85
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
86
|
+
this.pythonPathOverride = config.pythonPath;
|
|
87
|
+
}
|
|
88
|
+
// ==========================================================================
|
|
89
|
+
// Python detection
|
|
90
|
+
// ==========================================================================
|
|
91
|
+
/**
|
|
92
|
+
* Check whether Python 3 and wayfinder-paths are available.
|
|
93
|
+
* Results are cached after the first call.
|
|
94
|
+
*/
|
|
95
|
+
async checkPython() {
|
|
96
|
+
if (this.pythonStatusCache)
|
|
97
|
+
return this.pythonStatusCache;
|
|
98
|
+
const status = {
|
|
99
|
+
available: false,
|
|
100
|
+
wayfinderInstalled: false,
|
|
101
|
+
};
|
|
102
|
+
// Find python3 binary
|
|
103
|
+
const pythonCmd = this.pythonPathOverride ?? 'python3';
|
|
104
|
+
try {
|
|
105
|
+
const { stdout: whichOut } = await execFileAsync('which', [pythonCmd], {
|
|
106
|
+
timeout: 5_000,
|
|
107
|
+
});
|
|
108
|
+
status.pythonPath = whichOut.trim();
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// python3 not on PATH
|
|
112
|
+
this.pythonStatusCache = status;
|
|
113
|
+
return status;
|
|
114
|
+
}
|
|
115
|
+
// Get python version
|
|
116
|
+
try {
|
|
117
|
+
const { stdout: versionOut } = await execFileAsync(pythonCmd, ['--version'], { timeout: 5_000 });
|
|
118
|
+
const match = versionOut.trim().match(/Python\s+(\S+)/);
|
|
119
|
+
if (match) {
|
|
120
|
+
status.version = match[1];
|
|
121
|
+
status.available = true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
this.pythonStatusCache = status;
|
|
126
|
+
return status;
|
|
127
|
+
}
|
|
128
|
+
// Check wayfinder-paths installation
|
|
129
|
+
try {
|
|
130
|
+
const { stdout: wfOut } = await execFileAsync(pythonCmd, ['-c', 'import wayfinder_paths; print(wayfinder_paths.__version__)'], { timeout: 10_000 });
|
|
131
|
+
const version = wfOut.trim();
|
|
132
|
+
if (version) {
|
|
133
|
+
status.wayfinderInstalled = true;
|
|
134
|
+
status.wayfinderVersion = version;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// wayfinder-paths not installed
|
|
139
|
+
}
|
|
140
|
+
// Check wayfinder CLI binary
|
|
141
|
+
try {
|
|
142
|
+
const { stdout: cliOut } = await execFileAsync('which', ['wayfinder'], {
|
|
143
|
+
timeout: 5_000,
|
|
144
|
+
});
|
|
145
|
+
status.wayfinderCliPath = cliOut.trim();
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// wayfinder CLI not on PATH
|
|
149
|
+
}
|
|
150
|
+
this.pythonStatusCache = status;
|
|
151
|
+
return status;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Clear the cached Python status (e.g. after installing wayfinder-paths).
|
|
155
|
+
*/
|
|
156
|
+
clearPythonCache() {
|
|
157
|
+
this.pythonStatusCache = null;
|
|
158
|
+
}
|
|
159
|
+
// ==========================================================================
|
|
160
|
+
// Tier 1: REST API (always available)
|
|
161
|
+
// ==========================================================================
|
|
162
|
+
/**
|
|
163
|
+
* Resolve a token by name, symbol, address, or CoinGecko ID.
|
|
164
|
+
*
|
|
165
|
+
* @param query - Token identifier (e.g. "USDC", "0xA0b8...", "usd-coin")
|
|
166
|
+
* @param chainId - Optional chain ID filter
|
|
167
|
+
* @param marketData - Include market data (price, market cap)
|
|
168
|
+
*/
|
|
169
|
+
async resolveToken(query, chainId, marketData = true) {
|
|
170
|
+
const params = {
|
|
171
|
+
query,
|
|
172
|
+
market_data: marketData.toString(),
|
|
173
|
+
};
|
|
174
|
+
if (chainId !== undefined)
|
|
175
|
+
params.chain_id = chainId.toString();
|
|
176
|
+
const raw = await this.restRequest('/blockchain/tokens/detail/', params);
|
|
177
|
+
return this.parseTokenDetail(raw);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Fuzzy search for tokens across chains.
|
|
181
|
+
*
|
|
182
|
+
* @param query - Search term
|
|
183
|
+
* @param chain - Chain code (e.g. "base", "ethereum")
|
|
184
|
+
*/
|
|
185
|
+
async searchTokens(query, chain) {
|
|
186
|
+
const raw = await this.restRequest('/blockchain/tokens/fuzzy/', { query, chain }, 'text');
|
|
187
|
+
// Wayfinder fuzzy search returns XML — parse it
|
|
188
|
+
return this.parseFuzzySearchResults(raw, chain);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get the gas token for a chain.
|
|
192
|
+
*
|
|
193
|
+
* @param chain - Chain code (e.g. "base", "ethereum")
|
|
194
|
+
*/
|
|
195
|
+
async getGasToken(chain) {
|
|
196
|
+
const raw = await this.restRequest('/blockchain/tokens/gas/', { query: chain });
|
|
197
|
+
return this.parseTokenDetail(raw);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get a cross-chain swap quote via the BRAP aggregator.
|
|
201
|
+
* Compares routes from multiple providers (LiFi, Squid, etc.)
|
|
202
|
+
* and returns the best option.
|
|
203
|
+
*
|
|
204
|
+
* @param params - Quote parameters (tokens, chains, amount in WEI)
|
|
205
|
+
*/
|
|
206
|
+
async quoteSwap(params) {
|
|
207
|
+
const queryParams = {
|
|
208
|
+
from_token: params.fromToken,
|
|
209
|
+
to_token: params.toToken,
|
|
210
|
+
from_chain: params.fromChain.toString(),
|
|
211
|
+
to_chain: params.toChain.toString(),
|
|
212
|
+
from_wallet: params.fromWallet,
|
|
213
|
+
from_amount: params.amount,
|
|
214
|
+
};
|
|
215
|
+
if (params.slippage !== undefined) {
|
|
216
|
+
queryParams.slippage = params.slippage.toString();
|
|
217
|
+
}
|
|
218
|
+
const raw = await this.restRequest('/blockchain/braps/quote/', queryParams);
|
|
219
|
+
return this.parseBRAPQuoteResponse(raw);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get enriched multi-chain wallet balances.
|
|
223
|
+
*
|
|
224
|
+
* @param walletAddress - Ethereum wallet address
|
|
225
|
+
* @param excludeSpam - Exclude spam tokens (default: true)
|
|
226
|
+
*/
|
|
227
|
+
async getBalances(walletAddress, excludeSpam = true) {
|
|
228
|
+
const raw = await this.restRequest('/blockchain/balances/enriched/', {
|
|
229
|
+
address: walletAddress,
|
|
230
|
+
exclude_spam_tokens: excludeSpam.toString(),
|
|
231
|
+
});
|
|
232
|
+
return this.parseBalancesResponse(walletAddress, raw);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get wallet transaction activity.
|
|
236
|
+
*
|
|
237
|
+
* @param walletAddress - Ethereum wallet address
|
|
238
|
+
* @param limit - Max results (default: 20)
|
|
239
|
+
* @param offset - Pagination offset
|
|
240
|
+
*/
|
|
241
|
+
async getWalletActivity(walletAddress, limit = 20, offset = 0) {
|
|
242
|
+
const raw = await this.restRequest('/blockchain/balances/activity/', {
|
|
243
|
+
address: walletAddress,
|
|
244
|
+
limit: limit.toString(),
|
|
245
|
+
offset: offset.toString(),
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
address: walletAddress,
|
|
249
|
+
activities: Array.isArray(raw.activities) ? raw.activities : [],
|
|
250
|
+
total: typeof raw.total === 'number' ? raw.total : 0,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get DeFi pool data (Moonwell, Aave, Morpho, etc.)
|
|
255
|
+
*
|
|
256
|
+
* @param chainId - Optional chain ID filter
|
|
257
|
+
* @param protocol - Optional protocol filter (e.g. "moonwell", "aave")
|
|
258
|
+
*/
|
|
259
|
+
async getPools(chainId, protocol) {
|
|
260
|
+
const params = {};
|
|
261
|
+
if (chainId !== undefined)
|
|
262
|
+
params.chain_id = chainId.toString();
|
|
263
|
+
if (protocol)
|
|
264
|
+
params.project = protocol;
|
|
265
|
+
const raw = await this.restRequest('/blockchain/pools/', params);
|
|
266
|
+
return Array.isArray(raw) ? raw : [];
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get Hyperliquid funding rate history.
|
|
270
|
+
*
|
|
271
|
+
* @param coin - Coin symbol (e.g. "BTC", "ETH")
|
|
272
|
+
* @param startMs - Start timestamp in milliseconds
|
|
273
|
+
* @param endMs - End timestamp in milliseconds
|
|
274
|
+
*/
|
|
275
|
+
async getHyperliquidFunding(coin, startMs, endMs) {
|
|
276
|
+
const params = { coin };
|
|
277
|
+
if (startMs !== undefined)
|
|
278
|
+
params.start_ms = startMs.toString();
|
|
279
|
+
if (endMs !== undefined)
|
|
280
|
+
params.end_ms = endMs.toString();
|
|
281
|
+
return this.restRequest('/blockchain/hyperliquid/funding/', params);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get Hyperliquid OHLCV candle data.
|
|
285
|
+
*
|
|
286
|
+
* @param coin - Coin symbol
|
|
287
|
+
* @param interval - Candle interval (e.g. "1h", "4h", "1d")
|
|
288
|
+
* @param startMs - Start timestamp in milliseconds
|
|
289
|
+
* @param endMs - End timestamp in milliseconds
|
|
290
|
+
*/
|
|
291
|
+
async getHyperliquidCandles(coin, interval, startMs, endMs) {
|
|
292
|
+
const params = { coin, interval };
|
|
293
|
+
if (startMs !== undefined)
|
|
294
|
+
params.start_ms = startMs.toString();
|
|
295
|
+
if (endMs !== undefined)
|
|
296
|
+
params.end_ms = endMs.toString();
|
|
297
|
+
return this.restRequest('/blockchain/hyperliquid/candles/', params);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get HyperLend stable market data.
|
|
301
|
+
*/
|
|
302
|
+
async getHyperLendMarkets() {
|
|
303
|
+
return this.restRequest('/blockchain/hyperlend/stable_markets_headroom/');
|
|
304
|
+
}
|
|
305
|
+
// ==========================================================================
|
|
306
|
+
// Tier 2: CLI bridge (requires Python + wayfinder-paths)
|
|
307
|
+
// ==========================================================================
|
|
308
|
+
/**
|
|
309
|
+
* Execute a swap, send, or Hyperliquid deposit via the Wayfinder CLI.
|
|
310
|
+
* Signs transactions locally using wallets from wayfinder config.json.
|
|
311
|
+
*
|
|
312
|
+
* Requires Python 3.12+ and wayfinder-paths installed.
|
|
313
|
+
*/
|
|
314
|
+
async executeSwap(params) {
|
|
315
|
+
const args = ['execute', '--kind', params.kind, '--wallet-label', params.walletLabel, '--amount', params.amount];
|
|
316
|
+
if (params.fromToken)
|
|
317
|
+
args.push('--from-token', params.fromToken);
|
|
318
|
+
if (params.toToken)
|
|
319
|
+
args.push('--to-token', params.toToken);
|
|
320
|
+
if (params.recipient)
|
|
321
|
+
args.push('--recipient', params.recipient);
|
|
322
|
+
if (params.token)
|
|
323
|
+
args.push('--token', params.token);
|
|
324
|
+
if (params.slippageBps !== undefined)
|
|
325
|
+
args.push('--slippage-bps', params.slippageBps.toString());
|
|
326
|
+
if (params.deadlineSeconds !== undefined)
|
|
327
|
+
args.push('--deadline-seconds', params.deadlineSeconds.toString());
|
|
328
|
+
if (params.chainId !== undefined)
|
|
329
|
+
args.push('--chain-id', params.chainId.toString());
|
|
330
|
+
const output = await this.cliExec(args);
|
|
331
|
+
try {
|
|
332
|
+
return JSON.parse(output);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return { ok: false, error: output };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Run a Wayfinder strategy action (status, deposit, update, exit, etc.)
|
|
340
|
+
*
|
|
341
|
+
* Requires Python 3.12+ and wayfinder-paths installed.
|
|
342
|
+
*/
|
|
343
|
+
async runStrategy(params) {
|
|
344
|
+
const args = ['run_strategy', '--strategy', params.strategy, '--action', params.action];
|
|
345
|
+
if (params.mainTokenAmount !== undefined)
|
|
346
|
+
args.push('--main-token-amount', params.mainTokenAmount.toString());
|
|
347
|
+
if (params.gasTokenAmount !== undefined)
|
|
348
|
+
args.push('--gas-token-amount', params.gasTokenAmount.toString());
|
|
349
|
+
if (params.walletLabel)
|
|
350
|
+
args.push('--wallet-label', params.walletLabel);
|
|
351
|
+
if (params.dryRun)
|
|
352
|
+
args.push('--gorlami');
|
|
353
|
+
if (params.config)
|
|
354
|
+
args.push('--config', params.config);
|
|
355
|
+
const output = await this.cliExec(args, CLI_TIMEOUT);
|
|
356
|
+
try {
|
|
357
|
+
const parsed = JSON.parse(output);
|
|
358
|
+
return {
|
|
359
|
+
success: true,
|
|
360
|
+
action: params.action,
|
|
361
|
+
output: parsed,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// Strategy output may not be JSON — return as string
|
|
366
|
+
return {
|
|
367
|
+
success: true,
|
|
368
|
+
action: params.action,
|
|
369
|
+
output: output,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* List available Wayfinder strategies.
|
|
375
|
+
*
|
|
376
|
+
* Requires Python 3.12+ and wayfinder-paths installed.
|
|
377
|
+
*/
|
|
378
|
+
async listStrategies() {
|
|
379
|
+
const output = await this.cliExec(['resource', 'wayfinder://strategies']);
|
|
380
|
+
try {
|
|
381
|
+
const parsed = JSON.parse(output);
|
|
382
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// Parse text output
|
|
386
|
+
return this.parseStrategyList(output);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Get the status of a specific strategy.
|
|
391
|
+
*
|
|
392
|
+
* Requires Python 3.12+ and wayfinder-paths installed.
|
|
393
|
+
*/
|
|
394
|
+
async getStrategyStatus(name) {
|
|
395
|
+
const result = await this.runStrategy({ strategy: name, action: 'status' });
|
|
396
|
+
return result.output;
|
|
397
|
+
}
|
|
398
|
+
// ==========================================================================
|
|
399
|
+
// Private: REST helper
|
|
400
|
+
// ==========================================================================
|
|
401
|
+
async restRequest(path, params, responseType = 'json') {
|
|
402
|
+
let url = `${this.apiUrl}${path}`;
|
|
403
|
+
if (params && Object.keys(params).length > 0) {
|
|
404
|
+
const qs = new URLSearchParams(params).toString();
|
|
405
|
+
url += `?${qs}`;
|
|
406
|
+
}
|
|
407
|
+
const controller = new AbortController();
|
|
408
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
409
|
+
try {
|
|
410
|
+
const response = await fetch(url, {
|
|
411
|
+
method: 'GET',
|
|
412
|
+
headers: {
|
|
413
|
+
'X-API-KEY': this.apiKey,
|
|
414
|
+
'Accept': responseType === 'json' ? 'application/json' : 'text/plain',
|
|
415
|
+
},
|
|
416
|
+
signal: controller.signal,
|
|
417
|
+
});
|
|
418
|
+
clearTimeout(timeoutId);
|
|
419
|
+
if (!response.ok) {
|
|
420
|
+
let errorMsg;
|
|
421
|
+
try {
|
|
422
|
+
const body = await response.json();
|
|
423
|
+
errorMsg = body.detail || body.error || JSON.stringify(body);
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
errorMsg = `HTTP ${response.status}: ${response.statusText}`;
|
|
427
|
+
}
|
|
428
|
+
throw new WayfinderError(`Wayfinder API error: ${errorMsg}`, 'API_ERROR', { status: response.status, path });
|
|
429
|
+
}
|
|
430
|
+
if (responseType === 'text') {
|
|
431
|
+
return (await response.text());
|
|
432
|
+
}
|
|
433
|
+
return (await response.json());
|
|
434
|
+
}
|
|
435
|
+
catch (err) {
|
|
436
|
+
clearTimeout(timeoutId);
|
|
437
|
+
if (err instanceof WayfinderError)
|
|
438
|
+
throw err;
|
|
439
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
440
|
+
throw new WayfinderError('Wayfinder API request timeout', 'TIMEOUT', { path });
|
|
441
|
+
}
|
|
442
|
+
throw new WayfinderError(err instanceof Error ? err.message : 'Unknown error', 'NETWORK_ERROR', { path });
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
// ==========================================================================
|
|
446
|
+
// Private: CLI bridge helper
|
|
447
|
+
// ==========================================================================
|
|
448
|
+
async cliExec(args, timeout = 60_000) {
|
|
449
|
+
const status = await this.checkPython();
|
|
450
|
+
if (!status.available) {
|
|
451
|
+
throw new WayfinderError('Python 3 is not installed. Install it with: brew install python@3.12 (macOS) or apt install python3 (Linux)', 'PYTHON_NOT_FOUND');
|
|
452
|
+
}
|
|
453
|
+
if (!status.wayfinderInstalled) {
|
|
454
|
+
throw new WayfinderError('wayfinder-paths is not installed. Install it with: pip3 install wayfinder-paths', 'WAYFINDER_NOT_INSTALLED');
|
|
455
|
+
}
|
|
456
|
+
const cliPath = status.wayfinderCliPath ?? 'wayfinder';
|
|
457
|
+
try {
|
|
458
|
+
const { stdout, stderr } = await execFileAsync(cliPath, args, {
|
|
459
|
+
timeout,
|
|
460
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
461
|
+
env: {
|
|
462
|
+
...process.env,
|
|
463
|
+
// Ensure the Wayfinder API key is available
|
|
464
|
+
WAYFINDER_API_KEY: this.apiKey,
|
|
465
|
+
},
|
|
466
|
+
});
|
|
467
|
+
if (stderr && !stdout) {
|
|
468
|
+
throw new WayfinderError(`Wayfinder CLI error: ${stderr.trim()}`, 'CLI_ERROR', { args });
|
|
469
|
+
}
|
|
470
|
+
return stdout.trim();
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
if (err instanceof WayfinderError)
|
|
474
|
+
throw err;
|
|
475
|
+
const error = err;
|
|
476
|
+
if (error.killed) {
|
|
477
|
+
throw new WayfinderError(`Wayfinder CLI timed out after ${timeout / 1000}s`, 'CLI_TIMEOUT', { args });
|
|
478
|
+
}
|
|
479
|
+
throw new WayfinderError(`Wayfinder CLI failed: ${error.stderr?.trim() || error.message}`, 'CLI_ERROR', { args, exitCode: error.code });
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// ==========================================================================
|
|
483
|
+
// Private: Response parsers
|
|
484
|
+
// ==========================================================================
|
|
485
|
+
parseTokenDetail(raw) {
|
|
486
|
+
return {
|
|
487
|
+
name: raw.name ?? '',
|
|
488
|
+
symbol: raw.symbol ?? '',
|
|
489
|
+
address: raw.address ?? raw.contract_address ?? '',
|
|
490
|
+
chainId: raw.chain_id ?? raw.chainId ?? 0,
|
|
491
|
+
decimals: raw.decimals ?? 18,
|
|
492
|
+
coingeckoId: raw.coingecko_id,
|
|
493
|
+
logoUrl: raw.logo_url ?? raw.image,
|
|
494
|
+
priceUsd: raw.current_price ?? raw.price_usd,
|
|
495
|
+
priceChange24h: raw.price_change_percentage_24h,
|
|
496
|
+
marketCapUsd: raw.market_cap,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
parseFuzzySearchResults(xmlOrText, chain) {
|
|
500
|
+
// Wayfinder fuzzy search can return XML like:
|
|
501
|
+
// <token id="usd-coin" name="USD Coin" symbol="USDC" address="0x..." />
|
|
502
|
+
const results = [];
|
|
503
|
+
const tokenRegex = /<token\s+([^>]+)\/>/g;
|
|
504
|
+
let match;
|
|
505
|
+
while ((match = tokenRegex.exec(xmlOrText)) !== null) {
|
|
506
|
+
const attrs = match[1];
|
|
507
|
+
const getAttr = (name) => {
|
|
508
|
+
const m = new RegExp(`${name}="([^"]*)"`).exec(attrs);
|
|
509
|
+
return m ? m[1] : '';
|
|
510
|
+
};
|
|
511
|
+
results.push({
|
|
512
|
+
tokenId: getAttr('id'),
|
|
513
|
+
name: getAttr('name'),
|
|
514
|
+
symbol: getAttr('symbol'),
|
|
515
|
+
address: getAttr('address'),
|
|
516
|
+
chain,
|
|
517
|
+
chainId: parseInt(getAttr('chain_id')) || 0,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
// Also try JSON fallback
|
|
521
|
+
if (results.length === 0) {
|
|
522
|
+
try {
|
|
523
|
+
const parsed = JSON.parse(xmlOrText);
|
|
524
|
+
if (Array.isArray(parsed)) {
|
|
525
|
+
return parsed.map((t) => ({
|
|
526
|
+
tokenId: t.id ?? '',
|
|
527
|
+
name: t.name ?? '',
|
|
528
|
+
symbol: t.symbol ?? '',
|
|
529
|
+
address: t.address ?? '',
|
|
530
|
+
chain,
|
|
531
|
+
chainId: t.chain_id ?? 0,
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
// not JSON, not XML — return empty
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return results;
|
|
540
|
+
}
|
|
541
|
+
parseBRAPQuoteResponse(raw) {
|
|
542
|
+
// Wayfinder BRAP response can have two shapes:
|
|
543
|
+
// 1. { quotes: [...], best_quote: {...} }
|
|
544
|
+
// 2. { quotes: { all_quotes: [...], best_quote: {...}, quote_count: N } }
|
|
545
|
+
let allQuotes = [];
|
|
546
|
+
let bestQuote = null;
|
|
547
|
+
let quoteCount = 0;
|
|
548
|
+
if (Array.isArray(raw.quotes)) {
|
|
549
|
+
allQuotes = raw.quotes;
|
|
550
|
+
bestQuote = raw.best_quote;
|
|
551
|
+
quoteCount = allQuotes.length;
|
|
552
|
+
}
|
|
553
|
+
else if (raw.quotes && typeof raw.quotes === 'object') {
|
|
554
|
+
const quotesObj = raw.quotes;
|
|
555
|
+
allQuotes = Array.isArray(quotesObj.all_quotes) ? quotesObj.all_quotes : [];
|
|
556
|
+
bestQuote = quotesObj.best_quote ?? null;
|
|
557
|
+
quoteCount = quotesObj.quote_count ?? allQuotes.length;
|
|
558
|
+
}
|
|
559
|
+
const parseEntry = (q) => {
|
|
560
|
+
if (!q || typeof q !== 'object')
|
|
561
|
+
return null;
|
|
562
|
+
const entry = q;
|
|
563
|
+
const feeEst = (entry.fee_estimate ?? {});
|
|
564
|
+
return {
|
|
565
|
+
provider: entry.provider ?? 'unknown',
|
|
566
|
+
outputAmount: String(entry.output_amount ?? '0'),
|
|
567
|
+
inputAmount: String(entry.input_amount ?? '0'),
|
|
568
|
+
gasEstimate: entry.gas_estimate ?? null,
|
|
569
|
+
error: entry.error ?? null,
|
|
570
|
+
inputAmountUsd: entry.input_amount_usd ?? 0,
|
|
571
|
+
outputAmountUsd: entry.output_amount_usd ?? 0,
|
|
572
|
+
feeEstimate: {
|
|
573
|
+
feeTotalUsd: feeEst.fee_total_usd ?? 0,
|
|
574
|
+
feeBreakdown: Array.isArray(feeEst.fee_breakdown) ? feeEst.fee_breakdown : [],
|
|
575
|
+
},
|
|
576
|
+
calldata: entry.calldata ?? null,
|
|
577
|
+
wrapTransaction: entry.wrap_transaction ?? null,
|
|
578
|
+
unwrapTransaction: entry.unwrap_transaction ?? null,
|
|
579
|
+
nativeInput: entry.native_input ?? false,
|
|
580
|
+
nativeOutput: entry.native_output ?? false,
|
|
581
|
+
};
|
|
582
|
+
};
|
|
583
|
+
const parsedQuotes = allQuotes
|
|
584
|
+
.map(parseEntry)
|
|
585
|
+
.filter((q) => q !== null);
|
|
586
|
+
return {
|
|
587
|
+
quotes: parsedQuotes,
|
|
588
|
+
bestQuote: bestQuote ? parseEntry(bestQuote) : (parsedQuotes[0] ?? null),
|
|
589
|
+
quoteCount,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
parseBalancesResponse(address, raw) {
|
|
593
|
+
// enriched balances returns a list of tokens with chain info
|
|
594
|
+
const tokens = Array.isArray(raw.tokens) ? raw.tokens : [];
|
|
595
|
+
let totalValueUsd = 0;
|
|
596
|
+
const parsed = tokens.map((t) => {
|
|
597
|
+
const balUsd = t.balance_usd ?? t.balanceUsd ?? 0;
|
|
598
|
+
totalValueUsd += balUsd;
|
|
599
|
+
return {
|
|
600
|
+
name: t.name ?? '',
|
|
601
|
+
symbol: t.symbol ?? '',
|
|
602
|
+
address: t.address ?? t.contract_address ?? '',
|
|
603
|
+
chainId: t.chain_id ?? t.chainId ?? 0,
|
|
604
|
+
chainName: t.chain_name ?? t.chainName ?? '',
|
|
605
|
+
balance: String(t.balance ?? '0'),
|
|
606
|
+
balanceFormatted: t.balance_formatted ?? t.balanceFormatted ?? '0',
|
|
607
|
+
balanceUsd: balUsd,
|
|
608
|
+
decimals: t.decimals ?? 18,
|
|
609
|
+
logoUrl: t.logo_url,
|
|
610
|
+
isSpam: t.is_spam ?? t.isSpam,
|
|
611
|
+
};
|
|
612
|
+
});
|
|
613
|
+
return {
|
|
614
|
+
address,
|
|
615
|
+
totalValueUsd: raw.total_value_usd ?? totalValueUsd,
|
|
616
|
+
tokens: parsed,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
parseStrategyList(output) {
|
|
620
|
+
// Best-effort parse of text output from wayfinder resource
|
|
621
|
+
const strategies = [];
|
|
622
|
+
const lines = output.split('\n').filter((l) => l.trim());
|
|
623
|
+
for (const line of lines) {
|
|
624
|
+
const name = line.trim().replace(/^[-*]\s*/, '');
|
|
625
|
+
if (name) {
|
|
626
|
+
strategies.push({
|
|
627
|
+
name,
|
|
628
|
+
description: '',
|
|
629
|
+
chains: [],
|
|
630
|
+
riskLevel: 'unknown',
|
|
631
|
+
adapters: [],
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return strategies;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
//# sourceMappingURL=wayfinder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wayfinder.js","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"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"}
|