@persistenceone/bridgekitty 0.3.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/LICENSE +21 -0
- package/README.md +232 -0
- package/dist/backends/across.d.ts +10 -0
- package/dist/backends/across.js +285 -0
- package/dist/backends/debridge.d.ts +11 -0
- package/dist/backends/debridge.js +380 -0
- package/dist/backends/lifi.d.ts +19 -0
- package/dist/backends/lifi.js +295 -0
- package/dist/backends/persistence.d.ts +86 -0
- package/dist/backends/persistence.js +642 -0
- package/dist/backends/relay.d.ts +11 -0
- package/dist/backends/relay.js +292 -0
- package/dist/backends/squid.d.ts +31 -0
- package/dist/backends/squid.js +476 -0
- package/dist/backends/types.d.ts +125 -0
- package/dist/backends/types.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +154 -0
- package/dist/routing/engine.d.ts +49 -0
- package/dist/routing/engine.js +336 -0
- package/dist/tools/check-status.d.ts +3 -0
- package/dist/tools/check-status.js +93 -0
- package/dist/tools/execute-bridge.d.ts +3 -0
- package/dist/tools/execute-bridge.js +428 -0
- package/dist/tools/get-chains.d.ts +3 -0
- package/dist/tools/get-chains.js +162 -0
- package/dist/tools/get-quote.d.ts +3 -0
- package/dist/tools/get-quote.js +534 -0
- package/dist/tools/get-tokens.d.ts +3 -0
- package/dist/tools/get-tokens.js +128 -0
- package/dist/tools/help.d.ts +2 -0
- package/dist/tools/help.js +204 -0
- package/dist/tools/multi-quote.d.ts +3 -0
- package/dist/tools/multi-quote.js +310 -0
- package/dist/tools/onboard.d.ts +3 -0
- package/dist/tools/onboard.js +218 -0
- package/dist/tools/wallet.d.ts +14 -0
- package/dist/tools/wallet.js +744 -0
- package/dist/tools/xprt-farm.d.ts +3 -0
- package/dist/tools/xprt-farm.js +1308 -0
- package/dist/tools/xprt-rewards.d.ts +2 -0
- package/dist/tools/xprt-rewards.js +177 -0
- package/dist/tools/xprt-staking.d.ts +2 -0
- package/dist/tools/xprt-staking.js +565 -0
- package/dist/utils/chains.d.ts +22 -0
- package/dist/utils/chains.js +154 -0
- package/dist/utils/circuit-breaker.d.ts +64 -0
- package/dist/utils/circuit-breaker.js +160 -0
- package/dist/utils/evm.d.ts +18 -0
- package/dist/utils/evm.js +46 -0
- package/dist/utils/fill-detector.d.ts +70 -0
- package/dist/utils/fill-detector.js +298 -0
- package/dist/utils/gas-estimator.d.ts +67 -0
- package/dist/utils/gas-estimator.js +340 -0
- package/dist/utils/sanitize-error.d.ts +23 -0
- package/dist/utils/sanitize-error.js +101 -0
- package/dist/utils/token-registry.d.ts +70 -0
- package/dist/utils/token-registry.js +669 -0
- package/dist/utils/tokens.d.ts +17 -0
- package/dist/utils/tokens.js +37 -0
- package/dist/utils/tx-simulator.d.ts +27 -0
- package/dist/utils/tx-simulator.js +105 -0
- package/package.json +75 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Token resolution and amount formatting utilities
|
|
2
|
+
// Symbol resolution delegates to the verified token registry.
|
|
3
|
+
import { resolveToken } from "./token-registry.js";
|
|
4
|
+
// Re-export registry types and functions for convenience
|
|
5
|
+
export { resolveToken, lookupByAddress } from "./token-registry.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a token symbol or address to { address, decimals }.
|
|
8
|
+
*
|
|
9
|
+
* Returns null if:
|
|
10
|
+
* - Symbol is unknown in the verified registry for this chain
|
|
11
|
+
* - Address is already a 0x address (still returns result with known/default decimals)
|
|
12
|
+
*
|
|
13
|
+
* @deprecated Use `resolveToken()` for better error messages.
|
|
14
|
+
* This function is kept for backward compatibility.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveTokenAddress(symbol, chainId) {
|
|
17
|
+
const result = resolveToken(symbol, chainId);
|
|
18
|
+
if (result.ok) {
|
|
19
|
+
return { address: result.address, decimals: result.decimals };
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
export function formatTokenAmount(amountRaw, decimals) {
|
|
24
|
+
if (!amountRaw || amountRaw === "0")
|
|
25
|
+
return "0";
|
|
26
|
+
const str = amountRaw.padStart(decimals + 1, "0");
|
|
27
|
+
const intPart = str.slice(0, str.length - decimals) || "0";
|
|
28
|
+
const fracPart = str.slice(str.length - decimals);
|
|
29
|
+
const trimmed = fracPart.replace(/0+$/, "").slice(0, 8);
|
|
30
|
+
return trimmed ? `${intPart}.${trimmed}` : intPart;
|
|
31
|
+
}
|
|
32
|
+
export function parseTokenAmount(amount, decimals) {
|
|
33
|
+
const [intPart, fracPart = ""] = amount.split(".");
|
|
34
|
+
const padded = fracPart.padEnd(decimals, "0").slice(0, decimals);
|
|
35
|
+
const raw = intPart + padded;
|
|
36
|
+
return raw.replace(/^0+/, "") || "0";
|
|
37
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction simulation via eth_estimateGas.
|
|
3
|
+
* Verifies transactions won't revert before returning them to the user.
|
|
4
|
+
* Uses multi-RPC failover for reliability.
|
|
5
|
+
*/
|
|
6
|
+
export interface SimulationResult {
|
|
7
|
+
success: boolean;
|
|
8
|
+
/** Estimated gas units if simulation succeeded */
|
|
9
|
+
estimatedGas?: string;
|
|
10
|
+
/** Error message if simulation failed */
|
|
11
|
+
error?: string;
|
|
12
|
+
/** Warning message for non-fatal issues */
|
|
13
|
+
warning?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Simulate a transaction via eth_estimateGas.
|
|
17
|
+
* Returns success/failure with gas estimate or error details.
|
|
18
|
+
* Tries multiple RPCs with failover for reliability.
|
|
19
|
+
*
|
|
20
|
+
* If all RPCs are unavailable, returns a warning rather than blocking the transaction.
|
|
21
|
+
*/
|
|
22
|
+
export declare function simulateTransaction(chainId: number, tx: {
|
|
23
|
+
to: string;
|
|
24
|
+
data: string;
|
|
25
|
+
value: string;
|
|
26
|
+
from?: string;
|
|
27
|
+
}): Promise<SimulationResult>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction simulation via eth_estimateGas.
|
|
3
|
+
* Verifies transactions won't revert before returning them to the user.
|
|
4
|
+
* Uses multi-RPC failover for reliability.
|
|
5
|
+
*/
|
|
6
|
+
import { getChainRpcUrls } from "./gas-estimator.js";
|
|
7
|
+
const SIMULATION_TIMEOUT_MS = 8_000;
|
|
8
|
+
/**
|
|
9
|
+
* Simulate a transaction via eth_estimateGas.
|
|
10
|
+
* Returns success/failure with gas estimate or error details.
|
|
11
|
+
* Tries multiple RPCs with failover for reliability.
|
|
12
|
+
*
|
|
13
|
+
* If all RPCs are unavailable, returns a warning rather than blocking the transaction.
|
|
14
|
+
*/
|
|
15
|
+
export async function simulateTransaction(chainId, tx) {
|
|
16
|
+
const rpcUrls = getChainRpcUrls(chainId);
|
|
17
|
+
if (rpcUrls.length === 0) {
|
|
18
|
+
console.warn(`[tx-simulator] MEDIUM-003: Simulation bypassed — no RPC configured for chainId=${chainId}. ` +
|
|
19
|
+
`Transaction will proceed without pre-flight simulation.`);
|
|
20
|
+
return {
|
|
21
|
+
success: true,
|
|
22
|
+
warning: `No RPC configured for chain ${chainId} — could not simulate. Proceed with caution.`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// Build the eth_estimateGas params (reused across RPC attempts)
|
|
26
|
+
const txParam = {
|
|
27
|
+
to: tx.to,
|
|
28
|
+
data: tx.data,
|
|
29
|
+
};
|
|
30
|
+
if (tx.value && tx.value !== "0x0" && tx.value !== "0x00") {
|
|
31
|
+
txParam.value = tx.value.startsWith("0x") ? tx.value : `0x${BigInt(tx.value).toString(16)}`;
|
|
32
|
+
}
|
|
33
|
+
if (tx.from) {
|
|
34
|
+
txParam.from = tx.from;
|
|
35
|
+
}
|
|
36
|
+
const requestBody = JSON.stringify({
|
|
37
|
+
jsonrpc: "2.0",
|
|
38
|
+
method: "eth_estimateGas",
|
|
39
|
+
params: [txParam],
|
|
40
|
+
id: 1,
|
|
41
|
+
});
|
|
42
|
+
// Try each RPC in order — return first definitive result
|
|
43
|
+
let lastWarning;
|
|
44
|
+
for (const rpcUrl of rpcUrls) {
|
|
45
|
+
try {
|
|
46
|
+
const controller = new AbortController();
|
|
47
|
+
const timer = setTimeout(() => controller.abort(), SIMULATION_TIMEOUT_MS);
|
|
48
|
+
const res = await fetch(rpcUrl, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: requestBody,
|
|
52
|
+
signal: controller.signal,
|
|
53
|
+
});
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
lastWarning = `RPC returned ${res.status} during simulation`;
|
|
57
|
+
continue; // Try next RPC
|
|
58
|
+
}
|
|
59
|
+
const data = await res.json();
|
|
60
|
+
if (data.error) {
|
|
61
|
+
const errorMsg = data.error.message ?? JSON.stringify(data.error);
|
|
62
|
+
// Definitive revert — don't try other RPCs
|
|
63
|
+
if (errorMsg.includes("execution reverted") ||
|
|
64
|
+
errorMsg.includes("revert") ||
|
|
65
|
+
errorMsg.includes("UNPREDICTABLE_GAS_LIMIT")) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: `Transaction would revert: ${errorMsg.slice(0, 300)}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Insufficient funds is expected (simulating without user's actual balance)
|
|
72
|
+
if (errorMsg.includes("insufficient funds") ||
|
|
73
|
+
errorMsg.includes("insufficient balance")) {
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
warning: "Could not fully simulate (insufficient balance in simulation) — transaction structure appears valid.",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Other RPC-specific errors — try next RPC
|
|
80
|
+
lastWarning = `Simulation inconclusive: ${errorMsg.slice(0, 200)}`;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (data.result) {
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
estimatedGas: data.result,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
lastWarning = "Simulation returned no result";
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const errMsg = err.message;
|
|
94
|
+
lastWarning = errMsg.includes("abort")
|
|
95
|
+
? "Simulation timed out"
|
|
96
|
+
: `Simulation failed: ${errMsg.slice(0, 200)}`;
|
|
97
|
+
continue; // Try next RPC
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// All RPCs exhausted without a definitive result
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
warning: `${lastWarning ?? "All RPCs failed"} (tried ${rpcUrls.length} RPCs). Proceed with caution.`,
|
|
104
|
+
};
|
|
105
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@persistenceone/bridgekitty",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "BridgeKitty 🐱 — Cross-chain bridge aggregator MCP server for AI agents. One tool, all bridges, best routes.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"bridgekitty": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "rm -rf dist && tsc",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"model-context-protocol",
|
|
26
|
+
"bridge",
|
|
27
|
+
"cross-chain",
|
|
28
|
+
"defi",
|
|
29
|
+
"ai-agent",
|
|
30
|
+
"lifi",
|
|
31
|
+
"debridge",
|
|
32
|
+
"across",
|
|
33
|
+
"relay",
|
|
34
|
+
"squid",
|
|
35
|
+
"cosmos",
|
|
36
|
+
"solana-bridge",
|
|
37
|
+
"persistence",
|
|
38
|
+
"xprt",
|
|
39
|
+
"evm",
|
|
40
|
+
"ethereum",
|
|
41
|
+
"arbitrum",
|
|
42
|
+
"optimism",
|
|
43
|
+
"base"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/persistenceOne/bridgekitty"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@cosmjs/amino": "^0.38.1",
|
|
51
|
+
"@cosmjs/crypto": "^0.38.1",
|
|
52
|
+
"@cosmjs/proto-signing": "^0.38.1",
|
|
53
|
+
"@cosmjs/stargate": "^0.38.1",
|
|
54
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
55
|
+
"@scure/bip39": "^2.0.1",
|
|
56
|
+
"@solana/spl-token": "^0.4.14",
|
|
57
|
+
"@solana/web3.js": "^1.98.0",
|
|
58
|
+
"bs58": "^6.0.0",
|
|
59
|
+
"ed25519-hd-key": "^1.3.0",
|
|
60
|
+
"ethers": "^6.16.0",
|
|
61
|
+
"ws": "^8.19.0",
|
|
62
|
+
"zod": "^3.24.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/node": "^22.0.0",
|
|
66
|
+
"@types/ws": "^8.18.1",
|
|
67
|
+
"tsx": "^4.19.0",
|
|
68
|
+
"typescript": "^5.7.0",
|
|
69
|
+
"vitest": "^4.0.18"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=18.0.0"
|
|
73
|
+
},
|
|
74
|
+
"license": "MIT"
|
|
75
|
+
}
|