nyxora 26.6.19 → 26.6.21
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 +18 -1
- package/bin/nyxora.mjs +32 -0
- package/dist/packages/core/src/agent/reasoning.js +11 -1
- package/dist/packages/core/src/config/parser.js +121 -7
- package/dist/packages/core/src/gateway/chat.js +82 -0
- package/dist/packages/core/src/gateway/cli.js +63 -0
- package/dist/packages/core/src/gateway/server.js +117 -56
- package/dist/packages/core/src/gateway/setup.js +39 -22
- package/dist/packages/core/src/utils/formatter.test.js +40 -0
- package/dist/packages/core/src/utils/skillManager.js +91 -0
- package/dist/packages/core/src/utils/userWhitelistManager.js +41 -36
- package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +2 -2
- package/dist/packages/core/src/web3/aggregator/defiRouter.js +3 -0
- package/dist/packages/core/src/web3/skills/bridgeToken.js +4 -0
- package/dist/packages/core/src/web3/skills/checkRegistryStatus.js +13 -0
- package/dist/packages/core/src/web3/skills/customTx.js +2 -0
- package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
- package/dist/packages/core/src/web3/skills/getPrice.js +11 -6
- package/dist/packages/core/src/web3/skills/manageCustomTokens.js +18 -32
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +3 -1
- package/dist/packages/core/src/web3/skills/mintNft.js +2 -0
- package/dist/packages/core/src/web3/skills/provideLiquidity.js +2 -0
- package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
- package/dist/packages/core/src/web3/skills/swapToken.js +4 -2
- package/dist/packages/core/src/web3/skills/transfer.js +2 -0
- package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
- package/dist/packages/core/src/web3/utils/tokens.js +9 -1
- package/package.json +2 -1
- package/packages/core/package.json +1 -1
- package/packages/core/src/agent/reasoning.ts +12 -1
- package/packages/core/src/config/parser.ts +119 -9
- package/packages/core/src/gateway/chat.ts +85 -0
- package/packages/core/src/gateway/cli.ts +63 -0
- package/packages/core/src/gateway/server.ts +132 -60
- package/packages/core/src/gateway/setup.ts +39 -27
- package/packages/core/src/utils/formatter.test.ts +41 -0
- package/packages/core/src/utils/skillManager.ts +98 -0
- package/packages/core/src/utils/userWhitelistManager.ts +48 -39
- package/packages/core/src/web3/aggregator/aggregatorMainnet.ts +2 -2
- package/packages/core/src/web3/aggregator/defiRouter.ts +4 -0
- package/packages/core/src/web3/skills/bridgeToken.ts +3 -0
- package/packages/core/src/web3/skills/checkRegistryStatus.ts +13 -0
- package/packages/core/src/web3/skills/customTx.ts +1 -0
- package/packages/core/src/web3/skills/defiLending.ts +1 -0
- package/packages/core/src/web3/skills/getPrice.ts +11 -6
- package/packages/core/src/web3/skills/manageCustomTokens.ts +18 -29
- package/packages/core/src/web3/skills/marketAnalysis.ts +2 -1
- package/packages/core/src/web3/skills/mintNft.ts +1 -0
- package/packages/core/src/web3/skills/provideLiquidity.ts +1 -0
- package/packages/core/src/web3/skills/revokeApprovals.ts +1 -0
- package/packages/core/src/web3/skills/swapToken.ts +3 -2
- package/packages/core/src/web3/skills/transfer.ts +1 -0
- package/packages/core/src/web3/skills/yieldVault.ts +1 -0
- package/packages/core/src/web3/utils/tokens.ts +9 -1
- package/packages/dashboard/dist/assets/{index-DnQrbB4c.css → index-CQNHWZtN.css} +1 -1
- package/packages/dashboard/dist/assets/index-Di9x08yk.js +16 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +1 -1
- package/packages/mcp-server/package.json +1 -1
- package/packages/policy/package.json +1 -1
- package/packages/signer/package.json +1 -1
- package/dist/packages/core/src/agent/limitOrderManager.js +0 -124
- package/dist/packages/core/src/system/pluginManager.js +0 -91
- package/dist/packages/core/src/system/skills/installSkill.js +0 -52
- package/dist/packages/core/src/test-all-routers.js +0 -81
- package/dist/packages/core/src/test-router.js +0 -38
- package/dist/packages/core/src/web3/skills/autonomousDefi.js +0 -191
- package/dist/packages/core/src/web3/skills/createWallet.js +0 -34
- package/dist/packages/core/src/web3/skills/limitOrder.js +0 -106
- package/dist/packages/core/src/web3/utils/protocolRegistry.js +0 -46
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/packages/core/src/__tests__/reasoning.test.ts +0 -81
- package/packages/core/src/__tests__/tokens.test.ts +0 -55
- package/packages/core/src/__tests__/web3.test.ts +0 -50
- package/packages/core/src/agent/reasoning.d.ts.map +0 -1
- package/packages/core/src/config/parser.d.ts.map +0 -1
- package/packages/core/src/gateway/cli.d.ts.map +0 -1
- package/packages/core/src/memory/logger.d.ts.map +0 -1
- package/packages/core/src/test-all-routers.ts +0 -59
- package/packages/core/src/test-router.ts +0 -49
- package/packages/core/src/web3/config.d.ts.map +0 -1
- package/packages/core/src/web3/skills/getBalance.d.ts.map +0 -1
- package/packages/dashboard/dist/assets/index-BAXifdMN.js +0 -16
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.submitLimitOrder1inch = submitLimitOrder1inch;
|
|
37
|
-
const config_1 = require("../config");
|
|
38
|
-
const tokens_1 = require("../utils/tokens");
|
|
39
|
-
const vaultClient_1 = require("../utils/vaultClient");
|
|
40
|
-
const viem_1 = require("viem");
|
|
41
|
-
async function submitLimitOrder1inch(chainName, fromToken, toToken, amountStr, targetPriceUsd, condition) {
|
|
42
|
-
try {
|
|
43
|
-
const userAddress = await (0, config_1.getAddress)();
|
|
44
|
-
let makerAsset = (0, tokens_1.resolveToken)(fromToken, chainName);
|
|
45
|
-
let takerAsset = (0, tokens_1.resolveToken)(toToken, chainName);
|
|
46
|
-
// 1inch limit orders don't support native ETH directly, MUST use WETH
|
|
47
|
-
if (makerAsset === "0x0000000000000000000000000000000000000000") {
|
|
48
|
-
makerAsset = (0, tokens_1.resolveToken)("W" + fromToken, chainName);
|
|
49
|
-
}
|
|
50
|
-
if (takerAsset === "0x0000000000000000000000000000000000000000") {
|
|
51
|
-
takerAsset = (0, tokens_1.resolveToken)("W" + toToken, chainName);
|
|
52
|
-
}
|
|
53
|
-
// Fetch chain ID from config based on chainName
|
|
54
|
-
const chainMap = {
|
|
55
|
-
'mainnet': 1, 'base': 8453, 'arbitrum': 42161, 'polygon': 137, 'optimism': 10, 'bsc': 56
|
|
56
|
-
};
|
|
57
|
-
const chainId = chainMap[chainName.toLowerCase()] || 1;
|
|
58
|
-
// Mocking the amount. In reality we need to calculate exact makingAmount/takingAmount based on target price
|
|
59
|
-
const makingAmount = (0, viem_1.parseUnits)(amountStr, 18).toString();
|
|
60
|
-
const takingAmount = (0, viem_1.parseUnits)((parseFloat(amountStr) * targetPriceUsd).toString(), 18).toString();
|
|
61
|
-
const contractAddress = '0x1111111254eeb25477b68fb85ed929f73a960582'; // 1inch Limit Order Protocol V4 address
|
|
62
|
-
// Dynamically import to prevent ESM loader crash at startup
|
|
63
|
-
// @ts-ignore
|
|
64
|
-
const { LimitOrderBuilder, Web3ProviderConnector } = await Promise.resolve().then(() => __importStar(require('@1inch/limit-order-protocol-utils'))).catch(() => require('@1inch/limit-order-protocol-utils'));
|
|
65
|
-
// We use a dummy provider connector since we only need offline EIP-712 typing
|
|
66
|
-
const dummyProvider = {
|
|
67
|
-
signTypedData: async () => '',
|
|
68
|
-
ethCall: async () => ''
|
|
69
|
-
};
|
|
70
|
-
const connector = new Web3ProviderConnector(dummyProvider);
|
|
71
|
-
const limitOrderBuilder = new LimitOrderBuilder(connector, {
|
|
72
|
-
domainName: '1inch Limit Order Protocol',
|
|
73
|
-
version: '4'
|
|
74
|
-
});
|
|
75
|
-
const order = limitOrderBuilder.buildLimitOrder({
|
|
76
|
-
makerAsset,
|
|
77
|
-
takerAsset,
|
|
78
|
-
maker: userAddress,
|
|
79
|
-
makingAmount,
|
|
80
|
-
takingAmount,
|
|
81
|
-
});
|
|
82
|
-
const typedData = limitOrderBuilder.buildLimitOrderTypedData(order, BigInt(chainId), contractAddress);
|
|
83
|
-
// Sign offline using our secure vault
|
|
84
|
-
// @ts-ignore
|
|
85
|
-
const signature = await (0, vaultClient_1.signTypedData)(typedData.domain, typedData.types, typedData.primaryType, typedData.message);
|
|
86
|
-
const payload = {
|
|
87
|
-
orderHash: limitOrderBuilder.buildLimitOrderHash(typedData),
|
|
88
|
-
signature,
|
|
89
|
-
data: order
|
|
90
|
-
};
|
|
91
|
-
// Submit to 1inch API
|
|
92
|
-
const res = await fetch(`https://limit-orders.1inch.io/v4.0/${chainId}/limit-order`, {
|
|
93
|
-
method: 'POST',
|
|
94
|
-
headers: { 'Content-Type': 'application/json' },
|
|
95
|
-
body: JSON.stringify(payload)
|
|
96
|
-
});
|
|
97
|
-
if (!res.ok) {
|
|
98
|
-
const err = await res.text();
|
|
99
|
-
throw new Error(`1inch API Error: ${err}`);
|
|
100
|
-
}
|
|
101
|
-
return `Limit order successfully placed via 1inch. It is now off-chain and completely gasless. Order Hash: ${payload.orderHash}`;
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
throw new Error(`Failed to create 1inch limit order: ${error.message}`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadRegistry = loadRegistry;
|
|
7
|
-
exports.saveRegistry = saveRegistry;
|
|
8
|
-
exports.getProtocol = getProtocol;
|
|
9
|
-
exports.updateProtocol = updateProtocol;
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
|
-
const path_1 = __importDefault(require("path"));
|
|
12
|
-
const REGISTRY_PATH = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora', 'data', 'verified_protocols.json');
|
|
13
|
-
function loadRegistry() {
|
|
14
|
-
if (!fs_1.default.existsSync(REGISTRY_PATH)) {
|
|
15
|
-
return {};
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
const data = fs_1.default.readFileSync(REGISTRY_PATH, 'utf8');
|
|
19
|
-
return JSON.parse(data);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
console.error("Failed to load protocol registry:", error);
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function saveRegistry(data) {
|
|
27
|
-
try {
|
|
28
|
-
const dir = path_1.default.dirname(REGISTRY_PATH);
|
|
29
|
-
if (!fs_1.default.existsSync(dir)) {
|
|
30
|
-
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
31
|
-
}
|
|
32
|
-
fs_1.default.writeFileSync(REGISTRY_PATH, JSON.stringify(data, null, 2));
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
console.error("Failed to save protocol registry:", error);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function getProtocol(name) {
|
|
39
|
-
const registry = loadRegistry();
|
|
40
|
-
return registry[name.toLowerCase()] || null;
|
|
41
|
-
}
|
|
42
|
-
function updateProtocol(name, entry) {
|
|
43
|
-
const registry = loadRegistry();
|
|
44
|
-
registry[name.toLowerCase()] = entry;
|
|
45
|
-
saveRegistry(registry);
|
|
46
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../launcher.ts","../packages/core/src/test-all-routers.ts","../packages/core/src/test-router.ts","../packages/core/src/test_security.ts","../packages/core/src/agent/reasoning.ts","../packages/core/src/agent/transactionManager.ts","../packages/core/src/agent/updateProfile.ts","../packages/core/src/config/defiConfigManager.ts","../packages/core/src/config/parser.ts","../packages/core/src/config/paths.ts","../packages/core/src/gateway/cli.ts","../packages/core/src/gateway/doctor.ts","../packages/core/src/gateway/googleAuthModule.ts","../packages/core/src/gateway/legalGenerator.ts","../packages/core/src/gateway/server.ts","../packages/core/src/gateway/setup-cli.ts","../packages/core/src/gateway/setup.ts","../packages/core/src/gateway/telegram.ts","../packages/core/src/gateway/test.ts","../packages/core/src/gateway/tracker.ts","../packages/core/src/memory/episodic.ts","../packages/core/src/memory/logger.ts","../packages/core/src/memory/promotionEngine.ts","../packages/core/src/memory/reflection.ts","../packages/core/src/memory/validator.ts","../packages/core/src/system/pluginManager.ts","../packages/core/src/system/skills/analyzeDocument.ts","../packages/core/src/system/skills/audioTranscribe.ts","../packages/core/src/system/skills/browseWeb.ts","../packages/core/src/system/skills/editFile.ts","../packages/core/src/system/skills/executeShell.ts","../packages/core/src/system/skills/generateExcel.ts","../packages/core/src/system/skills/gitManager.ts","../packages/core/src/system/skills/googleWorkspace.ts","../packages/core/src/system/skills/installSkill.ts","../packages/core/src/system/skills/notionWorkspace.ts","../packages/core/src/system/skills/readFile.ts","../packages/core/src/system/skills/searchWeb.ts","../packages/core/src/system/skills/summarizeText.ts","../packages/core/src/system/skills/updateSecurityPolicy.ts","../packages/core/src/system/skills/writeFile.ts","../packages/core/src/system/skills/xManager.ts","../packages/core/src/utils/dynamicTokenUpdater.ts","../packages/core/src/utils/formatter.ts","../packages/core/src/utils/httpClient.ts","../packages/core/src/utils/safeLogger.ts","../packages/core/src/utils/skillManager.ts","../packages/core/src/utils/state.ts","../packages/core/src/utils/userWhitelistManager.ts","../packages/core/src/web3/config.ts","../packages/core/src/web3/aggregator/aggregatorMainnet.ts","../packages/core/src/web3/aggregator/aggregatorTestnet.ts","../packages/core/src/web3/aggregator/defiRouter.ts","../packages/core/src/web3/skills/bridgeToken.ts","../packages/core/src/web3/skills/checkAddress.ts","../packages/core/src/web3/skills/checkPortfolio.ts","../packages/core/src/web3/skills/checkRegistryStatus.ts","../packages/core/src/web3/skills/checkSecurity.ts","../packages/core/src/web3/skills/customTx.ts","../packages/core/src/web3/skills/defiLending.ts","../packages/core/src/web3/skills/executeDefi.ts","../packages/core/src/web3/skills/getBalance.ts","../packages/core/src/web3/skills/getMyAddress.ts","../packages/core/src/web3/skills/getPrice.ts","../packages/core/src/web3/skills/getTxHistory.ts","../packages/core/src/web3/skills/manageCustomTokens.ts","../packages/core/src/web3/skills/marketAnalysis.ts","../packages/core/src/web3/skills/mintNft.ts","../packages/core/src/web3/skills/provideLiquidity.ts","../packages/core/src/web3/skills/revokeApprovals.ts","../packages/core/src/web3/skills/swapToken.ts","../packages/core/src/web3/skills/transfer.ts","../packages/core/src/web3/skills/yieldVault.ts","../packages/core/src/web3/utils/chains.ts","../packages/core/src/web3/utils/marketEngine.ts","../packages/core/src/web3/utils/portfolioNormalizer.ts","../packages/core/src/web3/utils/routers.ts","../packages/core/src/web3/utils/rpcEngine.ts","../packages/core/src/web3/utils/tokens.ts","../packages/core/src/web3/utils/vaultClient.ts","../packages/core/src/web3/utils/zerionTracker.ts","../packages/policy/src/server.ts","../packages/signer/src/crypto.ts","../packages/signer/src/server.ts"],"version":"6.0.3"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { processUserInput } from '../agent/reasoning';
|
|
3
|
-
|
|
4
|
-
// Mock dependencies
|
|
5
|
-
vi.mock('../agent/openai', () => {
|
|
6
|
-
return {
|
|
7
|
-
getOpenAI: vi.fn().mockResolvedValue({
|
|
8
|
-
chat: {
|
|
9
|
-
completions: {
|
|
10
|
-
create: vi.fn().mockResolvedValue({
|
|
11
|
-
choices: [{
|
|
12
|
-
message: {
|
|
13
|
-
content: null,
|
|
14
|
-
tool_calls: [{
|
|
15
|
-
id: "call_123",
|
|
16
|
-
type: "function",
|
|
17
|
-
function: {
|
|
18
|
-
name: "transfer",
|
|
19
|
-
// Malformed JSON that would break JSON.parse
|
|
20
|
-
arguments: "{\"amount\": \"1\", \"toAddress\": \"0x123\""
|
|
21
|
-
}
|
|
22
|
-
}]
|
|
23
|
-
}
|
|
24
|
-
}]
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
};
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
vi.mock('../memory/logger', () => {
|
|
33
|
-
return {
|
|
34
|
-
logger: {
|
|
35
|
-
getHistory: vi.fn().mockReturnValue([]),
|
|
36
|
-
addEntry: vi.fn()
|
|
37
|
-
},
|
|
38
|
-
Logger: class MockLogger {
|
|
39
|
-
getHistory() { return []; }
|
|
40
|
-
addEntry() {}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
vi.mock('../memory/episodic', () => {
|
|
46
|
-
return {
|
|
47
|
-
episodicDB: {
|
|
48
|
-
getMemories: vi.fn().mockReturnValue([]),
|
|
49
|
-
addCandidateFact: vi.fn(),
|
|
50
|
-
decayMemories: vi.fn(),
|
|
51
|
-
deleteMemory: vi.fn()
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
vi.mock('../config', () => {
|
|
57
|
-
return {
|
|
58
|
-
loadConfig: vi.fn().mockReturnValue({ agent: { default_model: "gpt-4o" } })
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
vi.mock('../utils/userWhitelistManager', () => {
|
|
63
|
-
return {
|
|
64
|
-
getUserWhitelist: vi.fn().mockReturnValue({})
|
|
65
|
-
};
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('Agent Reasoning Pipeline', () => {
|
|
69
|
-
it('should not crash when LLM returns malformed JSON arguments', async () => {
|
|
70
|
-
// If it crashes, this promise will reject and the test will fail
|
|
71
|
-
// If the catch block in reasoning.ts works correctly, it should gracefully loop and return an error message string
|
|
72
|
-
|
|
73
|
-
const response = await processUserInput('transfer 1 eth to 0x123', 'user', undefined, 'test-session');
|
|
74
|
-
|
|
75
|
-
// The agent should detect the JSON error and feedback to the LLM or return an error string
|
|
76
|
-
// depending on the max iteration limit. Since we mocked the LLM to ALWAYS return bad JSON,
|
|
77
|
-
// it will hit the max iterations (5) and eventually return a fallback string or last message.
|
|
78
|
-
expect(typeof response).toBe('string');
|
|
79
|
-
// Ensure it doesn't throw a "TypeError: executeReasoningLoop is not a function"
|
|
80
|
-
}, 10000); // 10s timeout just in case it loops
|
|
81
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { getTokenMetadata } from '../web3/utils/tokens';
|
|
3
|
-
|
|
4
|
-
describe('Token Metadata Cache', () => {
|
|
5
|
-
it('should return native token metadata without RPC calls', async () => {
|
|
6
|
-
const mockClient = {
|
|
7
|
-
chain: { id: 1 },
|
|
8
|
-
readContract: vi.fn()
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const meta = await getTokenMetadata(mockClient as any, "0x0000000000000000000000000000000000000000");
|
|
12
|
-
expect(meta.decimals).toBe(18);
|
|
13
|
-
expect(meta.symbol).toBe("ETH/BNB/MATIC");
|
|
14
|
-
expect(mockClient.readContract).not.toHaveBeenCalled();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should fetch from RPC on first call and cache on subsequent calls', async () => {
|
|
18
|
-
const mockClient = {
|
|
19
|
-
chain: { id: 1 },
|
|
20
|
-
multicall: vi.fn().mockImplementation(async () => {
|
|
21
|
-
return [
|
|
22
|
-
{ status: 'success', result: 6 },
|
|
23
|
-
{ status: 'success', result: 'USDC' }
|
|
24
|
-
];
|
|
25
|
-
})
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const tokenAddr = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // USDC
|
|
29
|
-
|
|
30
|
-
// First call: Should hit RPC (1 multicall)
|
|
31
|
-
const meta1 = await getTokenMetadata(mockClient as any, tokenAddr);
|
|
32
|
-
expect(meta1.decimals).toBe(6);
|
|
33
|
-
expect(meta1.symbol).toBe("USDC");
|
|
34
|
-
expect(mockClient.multicall).toHaveBeenCalledTimes(1);
|
|
35
|
-
|
|
36
|
-
// Second call: Should return from cache instantly, no new RPC calls
|
|
37
|
-
const meta2 = await getTokenMetadata(mockClient as any, tokenAddr);
|
|
38
|
-
expect(meta2.decimals).toBe(6);
|
|
39
|
-
expect(meta2.symbol).toBe("USDC");
|
|
40
|
-
expect(mockClient.multicall).toHaveBeenCalledTimes(1); // Still 1
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should handle RPC failures gracefully by using fallback values', async () => {
|
|
44
|
-
const mockClient = {
|
|
45
|
-
chain: { id: 1 },
|
|
46
|
-
multicall: vi.fn().mockRejectedValue(new Error("RPC Error"))
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const tokenAddr = "0xunknown123456789012345678901234567890123";
|
|
50
|
-
|
|
51
|
-
const meta = await getTokenMetadata(mockClient as any, tokenAddr);
|
|
52
|
-
expect(meta.decimals).toBe(18); // Fallback
|
|
53
|
-
expect(meta.symbol).toBe("TOKEN"); // Fallback
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { executeTransfer } from '../web3/skills/transfer';
|
|
3
|
-
|
|
4
|
-
// Mock dependencies
|
|
5
|
-
vi.mock('../web3/config', async (importOriginal) => {
|
|
6
|
-
const actual: any = await importOriginal();
|
|
7
|
-
return {
|
|
8
|
-
...actual,
|
|
9
|
-
getPublicClient: vi.fn(),
|
|
10
|
-
getAddress: vi.fn().mockResolvedValue("0x123"),
|
|
11
|
-
CHAIN_IDS: { ethereum: 1 }
|
|
12
|
-
};
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('Web3 Action Safety Nets', () => {
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
|
|
18
|
-
ok: true,
|
|
19
|
-
json: vi.fn().mockResolvedValue({ signedHash: "0xabc" })
|
|
20
|
-
}));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
vi.restoreAllMocks();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('executeTransfer should include AbortSignal.timeout(30000)', async () => {
|
|
28
|
-
const params = {
|
|
29
|
-
toAddress: "0xabc",
|
|
30
|
-
amountStr: "1.0",
|
|
31
|
-
tokenAddress: "0x0000000000000000000000000000000000000000",
|
|
32
|
-
isNative: true,
|
|
33
|
-
decimals: 18
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
await executeTransfer('ethereum', params, false);
|
|
37
|
-
|
|
38
|
-
const fetchMock = global.fetch as any;
|
|
39
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
40
|
-
|
|
41
|
-
const callArgs = fetchMock.mock.calls[0];
|
|
42
|
-
const fetchOptions = callArgs[1];
|
|
43
|
-
|
|
44
|
-
expect(fetchOptions).toHaveProperty('signal');
|
|
45
|
-
// We cannot easily test AbortSignal instance type directly in jsdom without polyfills,
|
|
46
|
-
// but we can check if it's an object with aborted property (standard AbortSignal shape)
|
|
47
|
-
expect(typeof fetchOptions.signal).toBe('object');
|
|
48
|
-
expect('aborted' in fetchOptions.signal).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning.d.ts","sourceRoot":"","sources":["reasoning.ts"],"names":[],"mappings":"AAkBA,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFrE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["parser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,GAAG,EAAE;QACH,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;QAC5C,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,wBAAgB,UAAU,IAAI,aAAa,CAc1C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["logger.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;CACpB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAqB;;IAQnC,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,UAAU;IAQX,UAAU,IAAI,WAAW,EAAE;IAI3B,QAAQ,CAAC,KAAK,EAAE,WAAW;IAK3B,KAAK;CAIb"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { prepareSwapToken } from './web3/skills/swapToken';
|
|
2
|
-
import * as configModule from './web3/config';
|
|
3
|
-
|
|
4
|
-
// Mock getAddress to bypass Vault lock
|
|
5
|
-
(configModule as any).getAddress = async () => "0x28C6c06298d514Db089934071355E22Af1257125"; // dummy address
|
|
6
|
-
|
|
7
|
-
const CHAINS = ["ethereum", "bsc", "base", "arbitrum", "optimism", "polygon"] as const;
|
|
8
|
-
const ROUTERS = ["auto", "lifi", "relay", "uniswap_v2", "uniswap_v3", "pancakeswap", "1inch", "cowswap"] as const;
|
|
9
|
-
|
|
10
|
-
// Helper to get native and stablecoin addresses per chain
|
|
11
|
-
const TOKENS: Record<string, { in: string, out: string }> = {
|
|
12
|
-
ethereum: { in: "0x0000000000000000000000000000000000000000", out: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, // ETH to USDC
|
|
13
|
-
bsc: { in: "0x0000000000000000000000000000000000000000", out: "0x55d398326f99059fF775485246999027B3197955" }, // BNB to USDT
|
|
14
|
-
base: { in: "0x0000000000000000000000000000000000000000", out: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, // ETH to USDC
|
|
15
|
-
arbitrum: { in: "0x0000000000000000000000000000000000000000", out: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" }, // ETH to USDC
|
|
16
|
-
optimism: { in: "0x0000000000000000000000000000000000000000", out: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }, // ETH to USDC
|
|
17
|
-
polygon: { in: "0x0000000000000000000000000000000000000000", out: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359" } // MATIC to USDC
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
async function runAllTests() {
|
|
21
|
-
console.log("=== COMPREHENSIVE ROUTER TEST ===");
|
|
22
|
-
|
|
23
|
-
for (const chain of CHAINS) {
|
|
24
|
-
console.log(`\n--- 🌐 Testing Chain: ${chain.toUpperCase()} ---`);
|
|
25
|
-
const { in: fromToken, out: toToken } = TOKENS[chain];
|
|
26
|
-
|
|
27
|
-
const providers: Array<"auto" | "1inch" | "lifi" | "relay" | "openocean" | "kyberswap" | "0x"> = [
|
|
28
|
-
"1inch",
|
|
29
|
-
"0x",
|
|
30
|
-
"lifi",
|
|
31
|
-
"openocean",
|
|
32
|
-
"kyberswap"
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
for (const router of providers) {
|
|
36
|
-
try {
|
|
37
|
-
const res = await prepareSwapToken(
|
|
38
|
-
chain,
|
|
39
|
-
fromToken,
|
|
40
|
-
toToken,
|
|
41
|
-
"0.01",
|
|
42
|
-
"manual",
|
|
43
|
-
router
|
|
44
|
-
);
|
|
45
|
-
// Extract just the success info to keep logs readable
|
|
46
|
-
const outputMatch = res.match(/Expected Output: ~([\d.]+) /);
|
|
47
|
-
if (outputMatch) {
|
|
48
|
-
console.log(`[✅ SUCCESS] ${router.padEnd(15)} -> Quote: ~${outputMatch[1]} USDC/USDT`);
|
|
49
|
-
} else {
|
|
50
|
-
console.log(`[⚠️ PENDING] ${router.padEnd(15)} -> ${res.substring(0, 50)}...`);
|
|
51
|
-
}
|
|
52
|
-
} catch (err: any) {
|
|
53
|
-
console.log(`[❌ FAILED] ${router.padEnd(15)} -> ${err.message.split('\\n')[0]}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
runAllTests();
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { prepareSwapToken } from './web3/skills/swapToken';
|
|
2
|
-
|
|
3
|
-
async function runTest() {
|
|
4
|
-
console.log("=== Testing Native Routers ===");
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
// 1. Test Uniswap V2
|
|
8
|
-
// 1. Test 1inch
|
|
9
|
-
console.log("\n[Test 1] Testing 1inch route (ETH to USDC on Base)...");
|
|
10
|
-
const resV2 = await prepareSwapToken(
|
|
11
|
-
"base", // chain
|
|
12
|
-
"0x0000000000000000000000000000000000000000", // ETH native
|
|
13
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
|
|
14
|
-
"0.001", // amount
|
|
15
|
-
"manual", // mode
|
|
16
|
-
"1inch" // providerName
|
|
17
|
-
);
|
|
18
|
-
console.log("Result 1 (1inch):", resV2);
|
|
19
|
-
|
|
20
|
-
// 2. Test 0x
|
|
21
|
-
console.log("\n[Test 2] Testing 0x route (WETH to USDT on Ethereum)...");
|
|
22
|
-
const resCow = await prepareSwapToken(
|
|
23
|
-
"ethereum", // chain
|
|
24
|
-
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
|
|
25
|
-
"0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT
|
|
26
|
-
"0.1", // 0.1 ETH
|
|
27
|
-
"auto", // mode
|
|
28
|
-
"0x" // providerName
|
|
29
|
-
);
|
|
30
|
-
console.log("Result 0x:", resCow);
|
|
31
|
-
|
|
32
|
-
// 3. Test Auto
|
|
33
|
-
console.log("\n[Test 3] Testing Auto route...");
|
|
34
|
-
const resAuto = await prepareSwapToken(
|
|
35
|
-
"base",
|
|
36
|
-
"0x0000000000000000000000000000000000000000",
|
|
37
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
38
|
-
"0.001",
|
|
39
|
-
"auto"
|
|
40
|
-
);
|
|
41
|
-
console.log("Result Auto:", resAuto);
|
|
42
|
-
|
|
43
|
-
console.log("\\nAll tests completed!");
|
|
44
|
-
} catch (error: any) {
|
|
45
|
-
console.error("\\nTEST FAILED:", error.message);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
runTest();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,YAAY,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAOhG,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAyC4vC,CAAC;;;;;;;;;;;;;;yCAAqnB,CAAC;;;;;;;;;;;;+BAAgrB,CAAC;mCAAgG,CAAC;;;;;;kFAA0O,CAAC;;;kCAAuJ,CAAC;;;;;;;;;;;;;;4BAAumB,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA+B,CAAC;;;;;;;;;;;;;;kCAAykB,CAAC;;;;;8BAAyQ,CAAC;qCAA0D,CAAC;uCAA4D,CAAC;2BAAgD,CAAC;2BAA6C,CAAC;;;oCAA2H,CAAC;gCAAqD,CAAC;wCAA6D,CAAC;8BAAmD,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;uCAA4D,CAAC;;;;oCAA6J,CAAC;gCAAqD,CAAC;wCAA6D,CAAC;8BAAmD,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;uCAA4D,CAAC;;;4BAAmH,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;;;;4BAAiM,CAAC;;;;8BAAiL,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;;uCAAwwB,CAAC;;;4BAAmH,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;;;yFAA2P,CAAC;gCAAuD,CAAC;+BAAiD,CAAC;;;kCAAmJ,CAAC;;;;;;;;wBAAua,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAAjsU,CAAC;;;;;;;;;;;;;;yCAAqnB,CAAC;;;;;;;;;;;;+BAAgrB,CAAC;mCAAgG,CAAC;;;;;;kFAA0O,CAAC;;;kCAAuJ,CAAC;;;;;;;;;;;;;;4BAAumB,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA+B,CAAC;;;;;;;;;;;;;;kCAAykB,CAAC;;;;;8BAAyQ,CAAC;qCAA0D,CAAC;uCAA4D,CAAC;2BAAgD,CAAC;2BAA6C,CAAC;;;oCAA2H,CAAC;gCAAqD,CAAC;wCAA6D,CAAC;8BAAmD,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;uCAA4D,CAAC;;;;oCAA6J,CAAC;gCAAqD,CAAC;wCAA6D,CAAC;8BAAmD,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;uCAA4D,CAAC;;;4BAAmH,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;qCAAirB,CAAC;;;;4BAAiM,CAAC;;;;8BAAiL,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;kCAAsK,CAAC;;;;;;;;;;;;;;;;uCAAwwB,CAAC;;;4BAAmH,CAAC;oCAAyD,CAAC;;;8BAAuI,CAAC;wBAA6C,CAAC;8BAAmD,CAAC;;;;;;yFAA2P,CAAC;gCAAuD,CAAC;+BAAiD,CAAC;;;kCAAmJ,CAAC;;;;;;;;wBAAua,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CAnC92W,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,eAAe,CAAC;AAErD,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,CAQlE;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,YAAY,CAclE;AAED,wBAAgB,UAAU,kBAIzB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getBalance.d.ts","sourceRoot":"","sources":["getBalance.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,SAAS,EAAE,MAAM,WAAW,CAAC;AAEvD,wBAAsB,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB/F;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;CAqBpC,CAAC"}
|