safehands-pharos 1.2.0 → 1.2.4
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/.env.example +26 -0
- package/README.md +311 -350
- package/contracts/RiskRegistry.json +75 -1
- package/contracts/RiskRegistry.sol +29 -1
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +172 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.js +181 -169
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +2 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +66 -0
- package/dist/init.js.map +1 -0
- package/dist/lib/constants.d.ts +122 -7
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +139 -13
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/dodoApi.d.ts +14 -0
- package/dist/lib/dodoApi.d.ts.map +1 -1
- package/dist/lib/dodoApi.js +78 -22
- package/dist/lib/dodoApi.js.map +1 -1
- package/dist/lib/http.d.ts +15 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +119 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/pharosClient.d.ts +4 -3
- package/dist/lib/pharosClient.d.ts.map +1 -1
- package/dist/lib/pharosClient.js +8 -5
- package/dist/lib/pharosClient.js.map +1 -1
- package/dist/lib/policy/actionPolicyEngine.d.ts +54 -0
- package/dist/lib/policy/actionPolicyEngine.d.ts.map +1 -0
- package/dist/lib/policy/actionPolicyEngine.js +213 -0
- package/dist/lib/policy/actionPolicyEngine.js.map +1 -0
- package/dist/lib/signer/index.d.ts +25 -0
- package/dist/lib/signer/index.d.ts.map +1 -0
- package/dist/lib/signer/index.js +90 -0
- package/dist/lib/signer/index.js.map +1 -0
- package/dist/lib/testDodoLive.d.ts +2 -0
- package/dist/lib/testDodoLive.d.ts.map +1 -0
- package/dist/lib/testDodoLive.js +105 -0
- package/dist/lib/testDodoLive.js.map +1 -0
- package/dist/lib/testLiveSafehands.d.ts +2 -0
- package/dist/lib/testLiveSafehands.d.ts.map +1 -0
- package/dist/lib/testLiveSafehands.js +93 -0
- package/dist/lib/testLiveSafehands.js.map +1 -0
- package/dist/lib/testRpcLive.d.ts +2 -0
- package/dist/lib/testRpcLive.d.ts.map +1 -0
- package/dist/lib/testRpcLive.js +89 -0
- package/dist/lib/testRpcLive.js.map +1 -0
- package/dist/lib/testTools.js +363 -354
- package/dist/lib/testTools.js.map +1 -1
- package/dist/lib/testX402Live.d.ts +2 -0
- package/dist/lib/testX402Live.d.ts.map +1 -0
- package/dist/lib/testX402Live.js +160 -0
- package/dist/lib/testX402Live.js.map +1 -0
- package/dist/lib/toolResponse.d.ts +26 -0
- package/dist/lib/toolResponse.d.ts.map +1 -0
- package/dist/lib/toolResponse.js +54 -0
- package/dist/lib/toolResponse.js.map +1 -0
- package/dist/lib/wallet/index.d.ts +19 -0
- package/dist/lib/wallet/index.d.ts.map +1 -0
- package/dist/lib/wallet/index.js +71 -0
- package/dist/lib/wallet/index.js.map +1 -0
- package/dist/tools/approveToken.d.ts +19 -20
- package/dist/tools/approveToken.d.ts.map +1 -1
- package/dist/tools/approveToken.js +44 -21
- package/dist/tools/approveToken.js.map +1 -1
- package/dist/tools/assessRisk.d.ts +22 -9
- package/dist/tools/assessRisk.d.ts.map +1 -1
- package/dist/tools/assessRisk.js +32 -9
- package/dist/tools/assessRisk.js.map +1 -1
- package/dist/tools/checkAllowance.d.ts +6 -6
- package/dist/tools/checkTokenSecurity.d.ts +9 -16
- package/dist/tools/checkTokenSecurity.d.ts.map +1 -1
- package/dist/tools/checkTokenSecurity.js +17 -22
- package/dist/tools/checkTokenSecurity.js.map +1 -1
- package/dist/tools/createAgentWallet.d.ts +27 -0
- package/dist/tools/createAgentWallet.d.ts.map +1 -0
- package/dist/tools/createAgentWallet.js +60 -0
- package/dist/tools/createAgentWallet.js.map +1 -0
- package/dist/tools/estimateGas.d.ts +31 -21
- package/dist/tools/estimateGas.d.ts.map +1 -1
- package/dist/tools/estimateGas.js +91 -95
- package/dist/tools/estimateGas.js.map +1 -1
- package/dist/tools/executeSwap.d.ts +13 -29
- package/dist/tools/executeSwap.d.ts.map +1 -1
- package/dist/tools/executeSwap.js +68 -46
- package/dist/tools/executeSwap.js.map +1 -1
- package/dist/tools/explainRisk.d.ts +30 -0
- package/dist/tools/explainRisk.d.ts.map +1 -0
- package/dist/tools/explainRisk.js +33 -0
- package/dist/tools/explainRisk.js.map +1 -0
- package/dist/tools/getAgentWallet.d.ts +22 -0
- package/dist/tools/getAgentWallet.d.ts.map +1 -0
- package/dist/tools/getAgentWallet.js +28 -0
- package/dist/tools/getAgentWallet.js.map +1 -0
- package/dist/tools/getAgentWalletBalance.d.ts +12 -0
- package/dist/tools/getAgentWalletBalance.d.ts.map +1 -0
- package/dist/tools/getAgentWalletBalance.js +71 -0
- package/dist/tools/getAgentWalletBalance.js.map +1 -0
- package/dist/tools/getExecutionHistory.d.ts +4 -4
- package/dist/tools/getGasPrice.d.ts +26 -8
- package/dist/tools/getGasPrice.d.ts.map +1 -1
- package/dist/tools/getGasPrice.js +43 -35
- package/dist/tools/getGasPrice.js.map +1 -1
- package/dist/tools/getPoolInfo.d.ts +47 -59
- package/dist/tools/getPoolInfo.d.ts.map +1 -1
- package/dist/tools/getPoolInfo.js +96 -57
- package/dist/tools/getPoolInfo.js.map +1 -1
- package/dist/tools/getTokenPrice.d.ts +95 -9
- package/dist/tools/getTokenPrice.d.ts.map +1 -1
- package/dist/tools/getTokenPrice.js +95 -56
- package/dist/tools/getTokenPrice.js.map +1 -1
- package/dist/tools/getWalletBalance.d.ts +40 -11
- package/dist/tools/getWalletBalance.d.ts.map +1 -1
- package/dist/tools/getWalletBalance.js +64 -47
- package/dist/tools/getWalletBalance.js.map +1 -1
- package/dist/tools/publishRiskScore.d.ts +12 -10
- package/dist/tools/publishRiskScore.d.ts.map +1 -1
- package/dist/tools/publishRiskScore.js +33 -19
- package/dist/tools/publishRiskScore.js.map +1 -1
- package/dist/tools/queryRiskRegistry.d.ts +3 -3
- package/dist/tools/safehandsPreflightCheck.d.ts +78 -0
- package/dist/tools/safehandsPreflightCheck.d.ts.map +1 -0
- package/dist/tools/safehandsPreflightCheck.js +48 -0
- package/dist/tools/safehandsPreflightCheck.js.map +1 -0
- package/dist/tools/safehandsRiskReport.d.ts +82 -0
- package/dist/tools/safehandsRiskReport.d.ts.map +1 -0
- package/dist/tools/safehandsRiskReport.js +29 -0
- package/dist/tools/safehandsRiskReport.js.map +1 -0
- package/dist/tools/safehandsSafeExecute.d.ts +21 -0
- package/dist/tools/safehandsSafeExecute.d.ts.map +1 -0
- package/dist/tools/safehandsSafeExecute.js +76 -0
- package/dist/tools/safehandsSafeExecute.js.map +1 -0
- package/dist/tools/safehandsWalletHealth.d.ts +15 -0
- package/dist/tools/safehandsWalletHealth.d.ts.map +1 -0
- package/dist/tools/safehandsWalletHealth.js +104 -0
- package/dist/tools/safehandsWalletHealth.js.map +1 -0
- package/dist/tools/safehandsX402Preflight.d.ts +27 -0
- package/dist/tools/safehandsX402Preflight.d.ts.map +1 -0
- package/dist/tools/safehandsX402Preflight.js +66 -0
- package/dist/tools/safehandsX402Preflight.js.map +1 -0
- package/dist/tools/sendPayment.d.ts +13 -35
- package/dist/tools/sendPayment.d.ts.map +1 -1
- package/dist/tools/sendPayment.js +53 -47
- package/dist/tools/sendPayment.js.map +1 -1
- package/dist/tools/simulateTransaction.d.ts +4 -4
- package/dist/tools/tokenRegistryStatus.d.ts +27 -0
- package/dist/tools/tokenRegistryStatus.d.ts.map +1 -0
- package/dist/tools/tokenRegistryStatus.js +97 -0
- package/dist/tools/tokenRegistryStatus.js.map +1 -0
- package/dist/tools/x402PayAndFetch.d.ts +40 -16
- package/dist/tools/x402PayAndFetch.d.ts.map +1 -1
- package/dist/tools/x402PayAndFetch.js +115 -47
- package/dist/tools/x402PayAndFetch.js.map +1 -1
- package/dist/x402Server.js +149 -115
- package/dist/x402Server.js.map +1 -1
- package/examples/pharos-skill-engine/SKILL.safehands.md +85 -0
- package/examples/pharos-skill-engine/assets/safehands/example-actions.json +49 -0
- package/examples/pharos-skill-engine/assets/safehands/policy-defaults.json +11 -0
- package/examples/pharos-skill-engine/references/safehands.md +345 -0
- package/examples/scenario-hack.ts +38 -0
- package/package.json +19 -5
- package/skill/SKILL.md +127 -0
- package/skill/assets/safehands/example-actions.json +49 -0
- package/skill/assets/safehands/policy-defaults.json +11 -0
- package/skill/references/safehands.md +345 -0
- package/.agents/skill/safehands/SKILL.md +0 -200
- package/.agents/skill/safehands/assets/networks.json +0 -24
- package/.agents/skill/safehands/assets/tokens.json +0 -60
package/dist/lib/constants.d.ts
CHANGED
|
@@ -1,27 +1,142 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const CHAIN_ID
|
|
3
|
-
export declare const
|
|
1
|
+
export declare const PHAROS_ENVIRONMENT: string;
|
|
2
|
+
export declare const CHAIN_ID: number;
|
|
3
|
+
export declare const RPC_URL: string;
|
|
4
|
+
export declare const EXPLORER_BASE: string;
|
|
5
|
+
export declare const IS_MAINNET = false;
|
|
6
|
+
export declare const CHAIN_REGISTRY: {
|
|
7
|
+
readonly pharosAtlanticTestnet: {
|
|
8
|
+
readonly environment: "atlantic-testnet";
|
|
9
|
+
readonly chainId: 688689;
|
|
10
|
+
readonly isMainnet: false;
|
|
11
|
+
readonly rpcUrlEnv: "PHAROS_RPC_URL";
|
|
12
|
+
readonly defaultRpcUrl: "https://atlantic.dplabs-internal.com/";
|
|
13
|
+
readonly explorerUrl: "https://atlantic.pharosscan.xyz/";
|
|
14
|
+
readonly docsSource: "https://docs.pharosnetwork.xyz/developer-guide/hardhat/write-your-first-nft";
|
|
15
|
+
};
|
|
16
|
+
};
|
|
4
17
|
/** Native PHRS — sentinel address used by DODO API for native token */
|
|
5
18
|
export declare const PHRS_ADDRESS: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
6
19
|
export declare const USDT_ADDRESS: "0xE7E84B8B4f39C507499c40B4ac199B050e2882d5";
|
|
7
|
-
|
|
20
|
+
/** Primary USDC for Pharos Skill Engine (from official tokens.json) */
|
|
21
|
+
export declare const USDC_ADDRESS: "0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8";
|
|
22
|
+
/** Alternate USDC listed by Circle's contract addresses page (not in Skill Engine tokens.json) */
|
|
23
|
+
export declare const CIRCLE_USDC_ADDRESS: "0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B";
|
|
24
|
+
/** @deprecated Use USDC_ADDRESS instead. Kept for backward compatibility. */
|
|
25
|
+
export declare const X402_DEMO_USDC_ADDRESS: "0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8";
|
|
8
26
|
export declare const TEST_USDC_ADDRESS: "0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8";
|
|
9
27
|
export declare const WBTC_ADDRESS: "0x0c64F03EEa5c30946D5c55B4b532D08ad74638a4";
|
|
10
28
|
export declare const WETH_ADDRESS: "0x7d211F77525ea39A0592794f793cC1036eEaccD5";
|
|
11
29
|
export declare const WPHRS_ADDRESS: "0x838800b758277CC111B2d48Ab01e5E164f8E9471";
|
|
30
|
+
export declare const TOKEN_REGISTRY: {
|
|
31
|
+
readonly PHRS: {
|
|
32
|
+
readonly symbol: "PHRS";
|
|
33
|
+
readonly address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
34
|
+
readonly decimals: 18;
|
|
35
|
+
readonly chainId: number;
|
|
36
|
+
readonly environment: string;
|
|
37
|
+
readonly isMainnet: false;
|
|
38
|
+
readonly isCanonical: true;
|
|
39
|
+
readonly isTestToken: true;
|
|
40
|
+
readonly purpose: "native PHRS sentinel address for DODO route API";
|
|
41
|
+
readonly docsSource: "https://docs.pharos.xyz/";
|
|
42
|
+
};
|
|
43
|
+
readonly USDC: {
|
|
44
|
+
readonly symbol: "USDC";
|
|
45
|
+
readonly address: "0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8";
|
|
46
|
+
readonly decimals: 6;
|
|
47
|
+
readonly chainId: number;
|
|
48
|
+
readonly environment: string;
|
|
49
|
+
readonly isMainnet: false;
|
|
50
|
+
readonly isCanonical: true;
|
|
51
|
+
readonly isTestToken: true;
|
|
52
|
+
readonly purpose: "Pharos Skill Engine USDC — the USDC listed in the official pharos-skill-engine-0.1.0 assets/tokens.json for atlantic-testnet";
|
|
53
|
+
readonly docsSource: "pharos-skill-engine-0.1.0/assets/tokens.json";
|
|
54
|
+
readonly verificationStatus: "DOCS_VERIFIED_FROM_PHAROS_SKILL_ENGINE";
|
|
55
|
+
};
|
|
56
|
+
readonly CIRCLE_USDC: {
|
|
57
|
+
readonly symbol: "CIRCLE_USDC";
|
|
58
|
+
readonly address: "0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B";
|
|
59
|
+
readonly decimals: 6;
|
|
60
|
+
readonly chainId: number;
|
|
61
|
+
readonly environment: string;
|
|
62
|
+
readonly isMainnet: false;
|
|
63
|
+
readonly isCanonical: true;
|
|
64
|
+
readonly isTestToken: true;
|
|
65
|
+
readonly purpose: "Alternate USDC listed by Circle contract addresses page and Pharos docs token registry; not the primary token in Skill Engine tokens.json";
|
|
66
|
+
readonly docsSource: "https://developers.circle.com/stablecoins/usdc-contract-addresses and https://docs.pharos.xyz/getting-started/token-registry";
|
|
67
|
+
readonly verificationStatus: "CIRCLE_REFERENCED_USDC";
|
|
68
|
+
};
|
|
69
|
+
readonly USDT: {
|
|
70
|
+
readonly symbol: "USDT";
|
|
71
|
+
readonly address: "0xE7E84B8B4f39C507499c40B4ac199B050e2882d5";
|
|
72
|
+
readonly decimals: 6;
|
|
73
|
+
readonly chainId: number;
|
|
74
|
+
readonly environment: string;
|
|
75
|
+
readonly isMainnet: false;
|
|
76
|
+
readonly isCanonical: true;
|
|
77
|
+
readonly isTestToken: true;
|
|
78
|
+
readonly purpose: "canonical Pharos Atlantic Testnet USDT (Tether USD)";
|
|
79
|
+
readonly docsSource: "https://docs.pharos.xyz/getting-started/token-registry";
|
|
80
|
+
readonly verificationStatus: "DOCS_VERIFIED";
|
|
81
|
+
};
|
|
82
|
+
readonly WBTC: {
|
|
83
|
+
readonly symbol: "WBTC";
|
|
84
|
+
readonly address: "0x0c64F03EEa5c30946D5c55B4b532D08ad74638a4";
|
|
85
|
+
readonly decimals: 18;
|
|
86
|
+
readonly chainId: number;
|
|
87
|
+
readonly environment: string;
|
|
88
|
+
readonly isMainnet: false;
|
|
89
|
+
readonly isCanonical: true;
|
|
90
|
+
readonly isTestToken: true;
|
|
91
|
+
readonly purpose: "canonical Pharos Atlantic Testnet WBTC (Wrapped BTC)";
|
|
92
|
+
readonly docsSource: "https://docs.pharos.xyz/getting-started/token-registry";
|
|
93
|
+
readonly verificationStatus: "DOCS_VERIFIED";
|
|
94
|
+
};
|
|
95
|
+
readonly WETH: {
|
|
96
|
+
readonly symbol: "WETH";
|
|
97
|
+
readonly address: "0x7d211F77525ea39A0592794f793cC1036eEaccD5";
|
|
98
|
+
readonly decimals: 18;
|
|
99
|
+
readonly chainId: number;
|
|
100
|
+
readonly environment: string;
|
|
101
|
+
readonly isMainnet: false;
|
|
102
|
+
readonly isCanonical: true;
|
|
103
|
+
readonly isTestToken: true;
|
|
104
|
+
readonly purpose: "canonical Pharos Atlantic Testnet WETH (Wrapped ETH)";
|
|
105
|
+
readonly docsSource: "https://docs.pharos.xyz/getting-started/token-registry";
|
|
106
|
+
readonly verificationStatus: "DOCS_VERIFIED";
|
|
107
|
+
};
|
|
108
|
+
readonly WPHRS: {
|
|
109
|
+
readonly symbol: "WPHRS";
|
|
110
|
+
readonly address: "0x838800b758277CC111B2d48Ab01e5E164f8E9471";
|
|
111
|
+
readonly decimals: 18;
|
|
112
|
+
readonly chainId: number;
|
|
113
|
+
readonly environment: string;
|
|
114
|
+
readonly isMainnet: false;
|
|
115
|
+
readonly isCanonical: true;
|
|
116
|
+
readonly isTestToken: true;
|
|
117
|
+
readonly purpose: "canonical Pharos Atlantic Testnet WPHRS (Wrapped PHRS)";
|
|
118
|
+
readonly docsSource: "https://docs.pharos.xyz/getting-started/token-registry";
|
|
119
|
+
readonly verificationStatus: "DOCS_VERIFIED";
|
|
120
|
+
};
|
|
121
|
+
};
|
|
12
122
|
export declare const TOKEN_DECIMALS: Record<string, number>;
|
|
13
123
|
export declare const TOKEN_MAP: Record<string, `0x${string}`>;
|
|
14
124
|
export declare const DODO_APPROVE_ADDRESS: "0x4Cf317b8918FbE8A890c01eDAb7d548555Ac2cE9";
|
|
15
125
|
export declare const DODO_ROUTE_PROXY_ADDRESS: "0x819829e5CF6e19F9fED92F6b4CC1edF45a2cC4A2";
|
|
16
126
|
export declare const POSITION_MANAGER_ADDRESS: "0x1c430d84DD6185b1Ea2d4693e0033799d193542f";
|
|
17
|
-
export declare const DODO_API_BASE
|
|
18
|
-
export declare const DODO_API_KEY: string;
|
|
127
|
+
export declare const DODO_API_BASE: string;
|
|
128
|
+
export declare const DODO_API_KEY: string | undefined;
|
|
19
129
|
export declare const DODO_DEFAULT_SLIPPAGE = 3.225;
|
|
20
130
|
export declare const DODO_ROUTE_ENDPOINT = "/route-service/v2/widget/getdodoroute";
|
|
21
131
|
export declare const RISK_BLOCK_THRESHOLD = 80;
|
|
22
132
|
export declare const RISK_WARN_THRESHOLD = 60;
|
|
23
133
|
export declare const MAX_SLIPPAGE_PCT = 5;
|
|
24
134
|
export declare const MAX_BALANCE_USAGE_PCT = 90;
|
|
135
|
+
export declare const MAX_TX_AMOUNT_PHRS: string;
|
|
136
|
+
export declare const MAX_APPROVAL_AMOUNT_USDC: string;
|
|
137
|
+
export declare const MAX_DAILY_SPEND_USD: string;
|
|
138
|
+
export declare const MAX_X402_PAYMENT_USDC: string;
|
|
139
|
+
export declare const X402_PAYMENT_TOKEN_ADDRESS: `0x${string}`;
|
|
25
140
|
export declare const RISK_WEIGHTS: {
|
|
26
141
|
readonly liquidityRisk: 0.25;
|
|
27
142
|
readonly slippageRisk: 0.25;
|
|
@@ -105,7 +220,7 @@ export declare const ERC20_ABI: readonly [{
|
|
|
105
220
|
readonly type: "bool";
|
|
106
221
|
}];
|
|
107
222
|
}];
|
|
108
|
-
export declare const RISK_REGISTRY_ADDRESS:
|
|
223
|
+
export declare const RISK_REGISTRY_ADDRESS: `0x${string}`;
|
|
109
224
|
export declare const RISK_REGISTRY_ABI: readonly [{
|
|
110
225
|
readonly name: "publish";
|
|
111
226
|
readonly type: "function";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,kBAAkB,QAAuD,CAAC;AACvF,eAAO,MAAM,QAAQ,QAAkD,CAAC;AACxE,eAAO,MAAM,OAAO,QAAwE,CAAC;AAC7F,eAAO,MAAM,aAAa,QAA4E,CAAC;AACvG,eAAO,MAAM,UAAU,QAAQ,CAAC;AAEhC,eAAO,MAAM,cAAc;;;;;;;;;;CAUjB,CAAC;AASX,uEAAuE;AACvE,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAClF,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAElF,uEAAuE;AACvE,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAElF,kGAAkG;AAClG,eAAO,MAAM,mBAAmB,EAAG,4CAAqD,CAAC;AAEzF,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,8CAAe,CAAC;AACnD,eAAO,MAAM,iBAAiB,8CAAe,CAAC;AAE9C,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAClF,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAClF,eAAO,MAAM,aAAa,EAAG,4CAAqD,CAAC;AAEnF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FjB,CAAC;AAIX,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAejD,CAAC;AAIF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAQnD,CAAC;AAIF,eAAO,MAAM,oBAAoB,EAAG,4CAAqD,CAAC;AAC1F,eAAO,MAAM,wBAAwB,EAAG,4CAAqD,CAAC;AAC9F,eAAO,MAAM,wBAAwB,EAAG,4CAAqD,CAAC;AAI9F,eAAO,MAAM,aAAa,QAAuD,CAAC;AAClF,eAAO,MAAM,YAAY,oBAA2B,CAAC;AACrD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,mBAAmB,0CAA0C,CAAC;AAI3E,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAIxC,eAAO,MAAM,kBAAkB,QAA0C,CAAC;AAC1E,eAAO,MAAM,wBAAwB,QAA+C,CAAC;AACrF,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAC3E,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AACjF,eAAO,MAAM,0BAA0B,EAA+D,KAAK,MAAM,EAAE,CAAC;AAIpH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAIX,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDZ,CAAC;AAIX,eAAO,MAAM,qBAAqB,EACiB,KAAK,MAAM,EAAE,CAAC;AAEjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CpB,CAAC"}
|
package/dist/lib/constants.js
CHANGED
|
@@ -1,33 +1,152 @@
|
|
|
1
1
|
// ─── SafeHands Constants ───────────────────────────────────────────────
|
|
2
|
-
//
|
|
3
|
-
//
|
|
2
|
+
// Pharos Atlantic Testnet defaults. Values are labeled as testnet-only.
|
|
3
|
+
// Official references reviewed during QA:
|
|
4
|
+
// - Pharos Hardhat guide: Atlantic Testnet chain ID 688689, RPC https://atlantic.dplabs-internal.com
|
|
5
|
+
// - Official Pharos Skill Engine tokens.json: USDC = 0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8
|
|
6
|
+
// - Circle USDC contract addresses page: Pharos Testnet = 0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B
|
|
7
|
+
// - For Pharos Skill Engine compatibility, SafeHands defaults to the Skill Engine token list.
|
|
4
8
|
// ────────────────────────────────────────────────────────────────────────
|
|
5
9
|
// ─── Network ───────────────────────────────────────────────────────────
|
|
6
|
-
export const
|
|
7
|
-
export const CHAIN_ID = 688689;
|
|
8
|
-
export const
|
|
10
|
+
export const PHAROS_ENVIRONMENT = process.env.PHAROS_ENVIRONMENT || "atlantic-testnet";
|
|
11
|
+
export const CHAIN_ID = Number(process.env.PHAROS_CHAIN_ID || "688689");
|
|
12
|
+
export const RPC_URL = process.env.PHAROS_RPC_URL || "https://atlantic.dplabs-internal.com/";
|
|
13
|
+
export const EXPLORER_BASE = process.env.PHAROS_EXPLORER_BASE || "https://atlantic.pharosscan.xyz/tx/";
|
|
14
|
+
export const IS_MAINNET = false;
|
|
15
|
+
export const CHAIN_REGISTRY = {
|
|
16
|
+
pharosAtlanticTestnet: {
|
|
17
|
+
environment: "atlantic-testnet",
|
|
18
|
+
chainId: 688689,
|
|
19
|
+
isMainnet: false,
|
|
20
|
+
rpcUrlEnv: "PHAROS_RPC_URL",
|
|
21
|
+
defaultRpcUrl: "https://atlantic.dplabs-internal.com/",
|
|
22
|
+
explorerUrl: "https://atlantic.pharosscan.xyz/",
|
|
23
|
+
docsSource: "https://docs.pharosnetwork.xyz/developer-guide/hardhat/write-your-first-nft",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
9
26
|
// ─── Token Addresses ───────────────────────────────────────────────────
|
|
27
|
+
// The official Pharos Skill Engine (pharos-skill-engine-0.1.0) assets/tokens.json
|
|
28
|
+
// lists 0xE0BE... as USDC for atlantic-testnet.
|
|
29
|
+
// Circle's USDC contract addresses page lists 0xcfC8... for Pharos Testnet.
|
|
30
|
+
// For Skill Engine hackathon compatibility, SafeHands defaults to the Skill Engine list.
|
|
31
|
+
// Both addresses are documented; neither is deleted.
|
|
10
32
|
/** Native PHRS — sentinel address used by DODO API for native token */
|
|
11
33
|
export const PHRS_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
12
34
|
export const USDT_ADDRESS = "0xE7E84B8B4f39C507499c40B4ac199B050e2882d5";
|
|
13
|
-
|
|
14
|
-
export const
|
|
35
|
+
/** Primary USDC for Pharos Skill Engine (from official tokens.json) */
|
|
36
|
+
export const USDC_ADDRESS = "0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8";
|
|
37
|
+
/** Alternate USDC listed by Circle's contract addresses page (not in Skill Engine tokens.json) */
|
|
38
|
+
export const CIRCLE_USDC_ADDRESS = "0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B";
|
|
39
|
+
/** @deprecated Use USDC_ADDRESS instead. Kept for backward compatibility. */
|
|
40
|
+
export const X402_DEMO_USDC_ADDRESS = USDC_ADDRESS;
|
|
41
|
+
export const TEST_USDC_ADDRESS = USDC_ADDRESS;
|
|
15
42
|
export const WBTC_ADDRESS = "0x0c64F03EEa5c30946D5c55B4b532D08ad74638a4";
|
|
16
43
|
export const WETH_ADDRESS = "0x7d211F77525ea39A0592794f793cC1036eEaccD5";
|
|
17
44
|
export const WPHRS_ADDRESS = "0x838800b758277CC111B2d48Ab01e5E164f8E9471";
|
|
45
|
+
export const TOKEN_REGISTRY = {
|
|
46
|
+
PHRS: {
|
|
47
|
+
symbol: "PHRS",
|
|
48
|
+
address: PHRS_ADDRESS,
|
|
49
|
+
decimals: 18,
|
|
50
|
+
chainId: CHAIN_ID,
|
|
51
|
+
environment: PHAROS_ENVIRONMENT,
|
|
52
|
+
isMainnet: false,
|
|
53
|
+
isCanonical: true,
|
|
54
|
+
isTestToken: true,
|
|
55
|
+
purpose: "native PHRS sentinel address for DODO route API",
|
|
56
|
+
docsSource: "https://docs.pharos.xyz/",
|
|
57
|
+
},
|
|
58
|
+
USDC: {
|
|
59
|
+
symbol: "USDC",
|
|
60
|
+
address: USDC_ADDRESS,
|
|
61
|
+
decimals: 6,
|
|
62
|
+
chainId: CHAIN_ID,
|
|
63
|
+
environment: PHAROS_ENVIRONMENT,
|
|
64
|
+
isMainnet: false,
|
|
65
|
+
isCanonical: true,
|
|
66
|
+
isTestToken: true,
|
|
67
|
+
purpose: "Pharos Skill Engine USDC — the USDC listed in the official pharos-skill-engine-0.1.0 assets/tokens.json for atlantic-testnet",
|
|
68
|
+
docsSource: "pharos-skill-engine-0.1.0/assets/tokens.json",
|
|
69
|
+
verificationStatus: "DOCS_VERIFIED_FROM_PHAROS_SKILL_ENGINE",
|
|
70
|
+
},
|
|
71
|
+
CIRCLE_USDC: {
|
|
72
|
+
symbol: "CIRCLE_USDC",
|
|
73
|
+
address: CIRCLE_USDC_ADDRESS,
|
|
74
|
+
decimals: 6,
|
|
75
|
+
chainId: CHAIN_ID,
|
|
76
|
+
environment: PHAROS_ENVIRONMENT,
|
|
77
|
+
isMainnet: false,
|
|
78
|
+
isCanonical: true,
|
|
79
|
+
isTestToken: true,
|
|
80
|
+
purpose: "Alternate USDC listed by Circle contract addresses page and Pharos docs token registry; not the primary token in Skill Engine tokens.json",
|
|
81
|
+
docsSource: "https://developers.circle.com/stablecoins/usdc-contract-addresses and https://docs.pharos.xyz/getting-started/token-registry",
|
|
82
|
+
verificationStatus: "CIRCLE_REFERENCED_USDC",
|
|
83
|
+
},
|
|
84
|
+
USDT: {
|
|
85
|
+
symbol: "USDT",
|
|
86
|
+
address: USDT_ADDRESS,
|
|
87
|
+
decimals: 6,
|
|
88
|
+
chainId: CHAIN_ID,
|
|
89
|
+
environment: PHAROS_ENVIRONMENT,
|
|
90
|
+
isMainnet: false,
|
|
91
|
+
isCanonical: true,
|
|
92
|
+
isTestToken: true,
|
|
93
|
+
purpose: "canonical Pharos Atlantic Testnet USDT (Tether USD)",
|
|
94
|
+
docsSource: "https://docs.pharos.xyz/getting-started/token-registry",
|
|
95
|
+
verificationStatus: "DOCS_VERIFIED",
|
|
96
|
+
},
|
|
97
|
+
WBTC: {
|
|
98
|
+
symbol: "WBTC",
|
|
99
|
+
address: WBTC_ADDRESS,
|
|
100
|
+
decimals: 18,
|
|
101
|
+
chainId: CHAIN_ID,
|
|
102
|
+
environment: PHAROS_ENVIRONMENT,
|
|
103
|
+
isMainnet: false,
|
|
104
|
+
isCanonical: true,
|
|
105
|
+
isTestToken: true,
|
|
106
|
+
purpose: "canonical Pharos Atlantic Testnet WBTC (Wrapped BTC)",
|
|
107
|
+
docsSource: "https://docs.pharos.xyz/getting-started/token-registry",
|
|
108
|
+
verificationStatus: "DOCS_VERIFIED",
|
|
109
|
+
},
|
|
110
|
+
WETH: {
|
|
111
|
+
symbol: "WETH",
|
|
112
|
+
address: WETH_ADDRESS,
|
|
113
|
+
decimals: 18,
|
|
114
|
+
chainId: CHAIN_ID,
|
|
115
|
+
environment: PHAROS_ENVIRONMENT,
|
|
116
|
+
isMainnet: false,
|
|
117
|
+
isCanonical: true,
|
|
118
|
+
isTestToken: true,
|
|
119
|
+
purpose: "canonical Pharos Atlantic Testnet WETH (Wrapped ETH)",
|
|
120
|
+
docsSource: "https://docs.pharos.xyz/getting-started/token-registry",
|
|
121
|
+
verificationStatus: "DOCS_VERIFIED",
|
|
122
|
+
},
|
|
123
|
+
WPHRS: {
|
|
124
|
+
symbol: "WPHRS",
|
|
125
|
+
address: WPHRS_ADDRESS,
|
|
126
|
+
decimals: 18,
|
|
127
|
+
chainId: CHAIN_ID,
|
|
128
|
+
environment: PHAROS_ENVIRONMENT,
|
|
129
|
+
isMainnet: false,
|
|
130
|
+
isCanonical: true,
|
|
131
|
+
isTestToken: true,
|
|
132
|
+
purpose: "canonical Pharos Atlantic Testnet WPHRS (Wrapped PHRS)",
|
|
133
|
+
docsSource: "https://docs.pharos.xyz/getting-started/token-registry",
|
|
134
|
+
verificationStatus: "DOCS_VERIFIED",
|
|
135
|
+
},
|
|
136
|
+
};
|
|
18
137
|
// ─── Token Decimals ────────────────────────────────────────────────────
|
|
19
138
|
export const TOKEN_DECIMALS = {
|
|
20
139
|
PHRS: 18,
|
|
21
140
|
USDT: 6,
|
|
22
141
|
USDC: 6,
|
|
23
|
-
|
|
142
|
+
CIRCLE_USDC: 6,
|
|
24
143
|
WBTC: 18,
|
|
25
144
|
WETH: 18,
|
|
26
145
|
WPHRS: 18,
|
|
27
146
|
[PHRS_ADDRESS.toLowerCase()]: 18,
|
|
28
147
|
[USDT_ADDRESS.toLowerCase()]: 6,
|
|
29
148
|
[USDC_ADDRESS.toLowerCase()]: 6,
|
|
30
|
-
[
|
|
149
|
+
[CIRCLE_USDC_ADDRESS.toLowerCase()]: 6,
|
|
31
150
|
[WBTC_ADDRESS.toLowerCase()]: 18,
|
|
32
151
|
[WETH_ADDRESS.toLowerCase()]: 18,
|
|
33
152
|
[WPHRS_ADDRESS.toLowerCase()]: 18,
|
|
@@ -37,7 +156,7 @@ export const TOKEN_MAP = {
|
|
|
37
156
|
PHRS: PHRS_ADDRESS,
|
|
38
157
|
USDT: USDT_ADDRESS,
|
|
39
158
|
USDC: USDC_ADDRESS,
|
|
40
|
-
|
|
159
|
+
CIRCLE_USDC: CIRCLE_USDC_ADDRESS,
|
|
41
160
|
WBTC: WBTC_ADDRESS,
|
|
42
161
|
WETH: WETH_ADDRESS,
|
|
43
162
|
WPHRS: WPHRS_ADDRESS,
|
|
@@ -47,8 +166,8 @@ export const DODO_APPROVE_ADDRESS = "0x4Cf317b8918FbE8A890c01eDAb7d548555Ac2cE9"
|
|
|
47
166
|
export const DODO_ROUTE_PROXY_ADDRESS = "0x819829e5CF6e19F9fED92F6b4CC1edF45a2cC4A2";
|
|
48
167
|
export const POSITION_MANAGER_ADDRESS = "0x1c430d84DD6185b1Ea2d4693e0033799d193542f";
|
|
49
168
|
// ─── DODO API ──────────────────────────────────────────────────────────
|
|
50
|
-
export const DODO_API_BASE = "https://api.dodoex.io";
|
|
51
|
-
export const DODO_API_KEY = process.env.DODO_API_KEY
|
|
169
|
+
export const DODO_API_BASE = process.env.DODO_API_BASE || "https://api.dodoex.io";
|
|
170
|
+
export const DODO_API_KEY = process.env.DODO_API_KEY;
|
|
52
171
|
export const DODO_DEFAULT_SLIPPAGE = 3.225;
|
|
53
172
|
export const DODO_ROUTE_ENDPOINT = "/route-service/v2/widget/getdodoroute";
|
|
54
173
|
// ─── Risk Engine Thresholds ────────────────────────────────────────────
|
|
@@ -56,6 +175,12 @@ export const RISK_BLOCK_THRESHOLD = 80;
|
|
|
56
175
|
export const RISK_WARN_THRESHOLD = 60;
|
|
57
176
|
export const MAX_SLIPPAGE_PCT = 5;
|
|
58
177
|
export const MAX_BALANCE_USAGE_PCT = 90;
|
|
178
|
+
// ─── Safety Limits ─────────────────────────────────────────────────────
|
|
179
|
+
export const MAX_TX_AMOUNT_PHRS = process.env.MAX_TX_AMOUNT_PHRS || "0.1";
|
|
180
|
+
export const MAX_APPROVAL_AMOUNT_USDC = process.env.MAX_APPROVAL_AMOUNT_USDC || "10";
|
|
181
|
+
export const MAX_DAILY_SPEND_USD = process.env.MAX_DAILY_SPEND_USD || "10";
|
|
182
|
+
export const MAX_X402_PAYMENT_USDC = process.env.MAX_X402_PAYMENT_USDC || "0.01";
|
|
183
|
+
export const X402_PAYMENT_TOKEN_ADDRESS = (process.env.X402_PAYMENT_TOKEN_ADDRESS || USDC_ADDRESS);
|
|
59
184
|
// ─── Risk Weights ──────────────────────────────────────────────────────
|
|
60
185
|
export const RISK_WEIGHTS = {
|
|
61
186
|
liquidityRisk: 0.25,
|
|
@@ -119,7 +244,8 @@ export const ERC20_ABI = [
|
|
|
119
244
|
},
|
|
120
245
|
];
|
|
121
246
|
// ─── Risk Registry Contract ────────────────────────────────────────────
|
|
122
|
-
export const RISK_REGISTRY_ADDRESS =
|
|
247
|
+
export const RISK_REGISTRY_ADDRESS = (process.env.RISK_REGISTRY_ADDRESS ||
|
|
248
|
+
"0x61962a6c812ee9f57b207e1ea47c19ae70bb7141");
|
|
123
249
|
export const RISK_REGISTRY_ABI = [
|
|
124
250
|
{
|
|
125
251
|
name: "publish",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/dodoApi.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface DodoRouteResponse {
|
|
|
10
10
|
value: string | number;
|
|
11
11
|
gasLimit: string | number;
|
|
12
12
|
} | null;
|
|
13
|
+
message?: string;
|
|
13
14
|
}
|
|
14
15
|
export interface DodoQuote {
|
|
15
16
|
amountOut: string;
|
|
@@ -21,6 +22,8 @@ export interface DodoQuote {
|
|
|
21
22
|
to: string;
|
|
22
23
|
approveAddress: string;
|
|
23
24
|
routeAvailable: boolean;
|
|
25
|
+
sourceStatus: "ok" | "no_route_available" | "auth_required" | "unavailable";
|
|
26
|
+
usedApiKey: boolean;
|
|
24
27
|
rawResponse: DodoRouteResponse;
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
@@ -43,6 +46,17 @@ export declare function fromWei(weiInput: string | number, decimals: number): st
|
|
|
43
46
|
/**
|
|
44
47
|
* Fetches a swap route from the DODO aggregation API.
|
|
45
48
|
*/
|
|
49
|
+
export declare function _getDodoRouteCore(params: {
|
|
50
|
+
fromToken: string;
|
|
51
|
+
toToken: string;
|
|
52
|
+
amountHuman: string;
|
|
53
|
+
walletAddress: string;
|
|
54
|
+
slippage?: number;
|
|
55
|
+
}): Promise<DodoQuote>;
|
|
56
|
+
/**
|
|
57
|
+
* Smart wrapper around _getDodoRouteCore that automatically falls back to alternative token sources
|
|
58
|
+
* (like Circle USDC) if the canonical tokens have no liquidity on the testnet.
|
|
59
|
+
*/
|
|
46
60
|
export declare function getDodoRoute(params: {
|
|
47
61
|
fromToken: string;
|
|
48
62
|
toToken: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dodoApi.d.ts","sourceRoot":"","sources":["../../src/lib/dodoApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dodoApi.d.ts","sourceRoot":"","sources":["../../src/lib/dodoApi.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;KAC3B,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,IAAI,GAAG,oBAAoB,GAAG,eAAe,GAAG,aAAa,CAAC;IAC5E,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,iBAAiB,CAAC;CAChC;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,MAAM,EAAE,CAKhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU3E;AAID;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,SAAS,CAAC,CA6FrB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,SAAS,CAAC,CAqBrB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIpD"}
|
package/dist/lib/dodoApi.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Fetches swap routes from DODO's aggregation API for FaroSwap on
|
|
3
3
|
// Pharos Atlantic Testnet.
|
|
4
4
|
// ────────────────────────────────────────────────────────────────────────
|
|
5
|
-
import {
|
|
5
|
+
import { isAddress } from "viem";
|
|
6
|
+
import { DODO_API_BASE, DODO_API_KEY, DODO_DEFAULT_SLIPPAGE, DODO_ROUTE_ENDPOINT, CHAIN_ID, TOKEN_MAP, TOKEN_DECIMALS, PHRS_ADDRESS, USDC_ADDRESS, CIRCLE_USDC_ADDRESS, } from "./constants.js";
|
|
7
|
+
import { fetchWithTimeoutAndRetry } from "./http.js";
|
|
6
8
|
// ─── Helpers ───────────────────────────────────────────────────────────
|
|
7
9
|
/**
|
|
8
10
|
* Resolves a token symbol (e.g. "PHRS") or address to its on-chain address.
|
|
@@ -11,9 +13,9 @@ export function resolveTokenAddress(token) {
|
|
|
11
13
|
const upper = token.toUpperCase();
|
|
12
14
|
if (TOKEN_MAP[upper])
|
|
13
15
|
return TOKEN_MAP[upper];
|
|
14
|
-
if (
|
|
16
|
+
if (isAddress(token))
|
|
15
17
|
return token;
|
|
16
|
-
throw new Error(`Unknown token: ${token}`);
|
|
18
|
+
throw new Error(`INVALID_TOKEN_ADDRESS: Unknown token or invalid address: ${token}`);
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* Resolves the decimal count for a token symbol or address.
|
|
@@ -25,12 +27,15 @@ export function resolveTokenDecimals(token) {
|
|
|
25
27
|
const lower = token.toLowerCase();
|
|
26
28
|
if (TOKEN_DECIMALS[lower] !== undefined)
|
|
27
29
|
return TOKEN_DECIMALS[lower];
|
|
28
|
-
return 18; //
|
|
30
|
+
return 18; // unknown custom token fallback
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
33
|
* Converts a human-readable amount to wei string.
|
|
32
34
|
*/
|
|
33
35
|
export function toWei(amount, decimals) {
|
|
36
|
+
if (!/^\d+(\.\d+)?$/.test(amount)) {
|
|
37
|
+
throw new Error(`INVALID_AMOUNT: ${amount}`);
|
|
38
|
+
}
|
|
34
39
|
const [whole, frac = ""] = amount.split(".");
|
|
35
40
|
const paddedFrac = frac.padEnd(decimals, "0").slice(0, decimals);
|
|
36
41
|
return BigInt(whole + paddedFrac).toString();
|
|
@@ -41,12 +46,10 @@ export function toWei(amount, decimals) {
|
|
|
41
46
|
*/
|
|
42
47
|
export function fromWei(weiInput, decimals) {
|
|
43
48
|
const weiStr = String(weiInput);
|
|
44
|
-
|
|
45
|
-
if (weiStr.includes(".")) {
|
|
49
|
+
if (weiStr.includes("."))
|
|
46
50
|
return weiStr;
|
|
47
|
-
}
|
|
48
51
|
const wei = BigInt(weiStr);
|
|
49
|
-
const divisor = BigInt(10 ** decimals);
|
|
52
|
+
const divisor = BigInt(10) ** BigInt(decimals);
|
|
50
53
|
const whole = wei / divisor;
|
|
51
54
|
const remainder = wei % divisor;
|
|
52
55
|
if (remainder === 0n)
|
|
@@ -58,7 +61,12 @@ export function fromWei(weiInput, decimals) {
|
|
|
58
61
|
/**
|
|
59
62
|
* Fetches a swap route from the DODO aggregation API.
|
|
60
63
|
*/
|
|
61
|
-
export async function
|
|
64
|
+
export async function _getDodoRouteCore(params) {
|
|
65
|
+
const trimmedApiKey = DODO_API_KEY?.trim();
|
|
66
|
+
const usedApiKey = Boolean(trimmedApiKey);
|
|
67
|
+
if (!isAddress(params.walletAddress)) {
|
|
68
|
+
throw new Error(`INVALID_WALLET_ADDRESS: ${params.walletAddress}`);
|
|
69
|
+
}
|
|
62
70
|
const fromAddress = resolveTokenAddress(params.fromToken);
|
|
63
71
|
const toAddress = resolveTokenAddress(params.toToken);
|
|
64
72
|
const fromDecimals = resolveTokenDecimals(params.fromToken);
|
|
@@ -66,23 +74,43 @@ export async function getDodoRoute(params) {
|
|
|
66
74
|
const amountInWei = toWei(params.amountHuman, fromDecimals);
|
|
67
75
|
const slippage = params.slippage ?? DODO_DEFAULT_SLIPPAGE;
|
|
68
76
|
const deadline = Math.floor(Date.now() / 1000) + 600;
|
|
69
|
-
const url = `${DODO_API_BASE}${DODO_ROUTE_ENDPOINT}`
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
const url = new URL(`${DODO_API_BASE}${DODO_ROUTE_ENDPOINT}`);
|
|
78
|
+
url.searchParams.set("chainId", String(CHAIN_ID));
|
|
79
|
+
url.searchParams.set("fromTokenAddress", fromAddress);
|
|
80
|
+
url.searchParams.set("toTokenAddress", toAddress);
|
|
81
|
+
url.searchParams.set("fromAmount", amountInWei);
|
|
82
|
+
url.searchParams.set("userAddr", params.walletAddress);
|
|
83
|
+
url.searchParams.set("slippage", String(slippage));
|
|
84
|
+
url.searchParams.set("source", "dodoV2AndMixWasm");
|
|
85
|
+
url.searchParams.set("estimateGas", "true");
|
|
86
|
+
// DODO/FaroSwap read-only route queries should prefer public mode when no
|
|
87
|
+
// API key is configured. Never hardcode a default credential. If the
|
|
88
|
+
// provider rejects public mode, surface a structured auth-required error
|
|
89
|
+
// at the tool layer.
|
|
90
|
+
if (trimmedApiKey) {
|
|
91
|
+
url.searchParams.set("apikey", trimmedApiKey);
|
|
92
|
+
}
|
|
93
|
+
url.searchParams.set("deadLine", String(deadline));
|
|
94
|
+
const response = await fetchWithTimeoutAndRetry(url, {
|
|
95
|
+
timeoutMs: 10_000,
|
|
96
|
+
retries: 2,
|
|
97
|
+
retryDelayMs: 300,
|
|
98
|
+
});
|
|
81
99
|
if (!response.ok) {
|
|
82
|
-
|
|
100
|
+
if (response.status === 401 || response.status === 403) {
|
|
101
|
+
throw new Error(`DODO_API_AUTH_REQUIRED: DODO route API rejected public mode${usedApiKey ? " or provided key" : "; configure DODO_API_KEY if this endpoint requires authentication"}`);
|
|
102
|
+
}
|
|
103
|
+
if (response.status === 429) {
|
|
104
|
+
throw new Error(`DODO_API_RATE_LIMITED: ${response.status} ${response.statusText}`);
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`DODO_API_UNAVAILABLE: ${response.status} ${response.statusText}`);
|
|
83
107
|
}
|
|
84
108
|
const json = (await response.json());
|
|
85
109
|
if (!json.data || json.status !== 200) {
|
|
110
|
+
const message = (json.message || "").toLowerCase();
|
|
111
|
+
if (message.includes("api key") || message.includes("apikey") || message.includes("unauthorized") || message.includes("forbidden")) {
|
|
112
|
+
throw new Error(`DODO_API_AUTH_REQUIRED: DODO route API rejected public mode${usedApiKey ? " or provided key" : "; configure DODO_API_KEY if this endpoint requires authentication"}`);
|
|
113
|
+
}
|
|
86
114
|
return {
|
|
87
115
|
amountOut: "0",
|
|
88
116
|
amountOutWei: "0",
|
|
@@ -93,6 +121,8 @@ export async function getDodoRoute(params) {
|
|
|
93
121
|
to: "",
|
|
94
122
|
approveAddress: "",
|
|
95
123
|
routeAvailable: false,
|
|
124
|
+
sourceStatus: "no_route_available",
|
|
125
|
+
usedApiKey,
|
|
96
126
|
rawResponse: json,
|
|
97
127
|
};
|
|
98
128
|
}
|
|
@@ -108,9 +138,35 @@ export async function getDodoRoute(params) {
|
|
|
108
138
|
to: d.to,
|
|
109
139
|
approveAddress: d.targetApproveAddr,
|
|
110
140
|
routeAvailable: true,
|
|
141
|
+
sourceStatus: "ok",
|
|
142
|
+
usedApiKey,
|
|
111
143
|
rawResponse: json,
|
|
112
144
|
};
|
|
113
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Smart wrapper around _getDodoRouteCore that automatically falls back to alternative token sources
|
|
148
|
+
* (like Circle USDC) if the canonical tokens have no liquidity on the testnet.
|
|
149
|
+
*/
|
|
150
|
+
export async function getDodoRoute(params) {
|
|
151
|
+
let quote = await _getDodoRouteCore(params);
|
|
152
|
+
if (!quote.routeAvailable) {
|
|
153
|
+
const fromUpper = params.fromToken.toUpperCase();
|
|
154
|
+
const toUpper = params.toToken.toUpperCase();
|
|
155
|
+
// Smart Fallback: If swapping TO canonical USDC failed, try Alternate Circle USDC
|
|
156
|
+
if (toUpper === "USDC" || toUpper === USDC_ADDRESS.toUpperCase()) {
|
|
157
|
+
const fallbackQuote = await _getDodoRouteCore({ ...params, toToken: CIRCLE_USDC_ADDRESS });
|
|
158
|
+
if (fallbackQuote.routeAvailable)
|
|
159
|
+
return fallbackQuote;
|
|
160
|
+
}
|
|
161
|
+
// Smart Fallback: If swapping FROM canonical USDC failed, try Alternate Circle USDC
|
|
162
|
+
if (fromUpper === "USDC" || fromUpper === USDC_ADDRESS.toUpperCase()) {
|
|
163
|
+
const fallbackQuote = await _getDodoRouteCore({ ...params, fromToken: CIRCLE_USDC_ADDRESS });
|
|
164
|
+
if (fallbackQuote.routeAvailable)
|
|
165
|
+
return fallbackQuote;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return quote;
|
|
169
|
+
}
|
|
114
170
|
/**
|
|
115
171
|
* Checks whether a token is the native PHRS token.
|
|
116
172
|
*/
|