fibx 0.1.4 → 0.2.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.
Files changed (61) hide show
  1. package/README.md +46 -6
  2. package/dist/commands/auth/import.d.ts +3 -0
  3. package/dist/commands/auth/import.d.ts.map +1 -0
  4. package/dist/commands/auth/import.js +44 -0
  5. package/dist/commands/auth/import.js.map +1 -0
  6. package/dist/commands/auth/logout.d.ts +3 -0
  7. package/dist/commands/auth/logout.d.ts.map +1 -0
  8. package/dist/commands/auth/logout.js +19 -0
  9. package/dist/commands/auth/logout.js.map +1 -0
  10. package/dist/commands/auth/verify.d.ts.map +1 -1
  11. package/dist/commands/auth/verify.js +1 -0
  12. package/dist/commands/auth/verify.js.map +1 -1
  13. package/dist/commands/defi/aave.d.ts +7 -0
  14. package/dist/commands/defi/aave.d.ts.map +1 -0
  15. package/dist/commands/defi/aave.js +218 -0
  16. package/dist/commands/defi/aave.js.map +1 -0
  17. package/dist/commands/trade/swap.d.ts.map +1 -1
  18. package/dist/commands/trade/swap.js +20 -4
  19. package/dist/commands/trade/swap.js.map +1 -1
  20. package/dist/commands/wallet/send.d.ts.map +1 -1
  21. package/dist/commands/wallet/send.js +24 -7
  22. package/dist/commands/wallet/send.js.map +1 -1
  23. package/dist/index.js +21 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/services/auth/session.d.ts +6 -1
  26. package/dist/services/auth/session.d.ts.map +1 -1
  27. package/dist/services/auth/session.js +3 -1
  28. package/dist/services/auth/session.js.map +1 -1
  29. package/dist/services/chain/client.d.ts +1 -1
  30. package/dist/services/chain/client.d.ts.map +1 -1
  31. package/dist/services/chain/client.js +17 -64
  32. package/dist/services/chain/client.js.map +1 -1
  33. package/dist/services/chain/constants.d.ts +6 -0
  34. package/dist/services/chain/constants.d.ts.map +1 -1
  35. package/dist/services/chain/constants.js +8 -1
  36. package/dist/services/chain/constants.js.map +1 -1
  37. package/dist/services/chain/erc20.d.ts +58 -1
  38. package/dist/services/chain/erc20.d.ts.map +1 -1
  39. package/dist/services/chain/erc20.js +1 -8
  40. package/dist/services/chain/erc20.js.map +1 -1
  41. package/dist/services/chain/nonceManager.d.ts +14 -0
  42. package/dist/services/chain/nonceManager.d.ts.map +1 -0
  43. package/dist/services/chain/nonceManager.js +50 -0
  44. package/dist/services/chain/nonceManager.js.map +1 -0
  45. package/dist/services/defi/aave.d.ts +30 -0
  46. package/dist/services/defi/aave.d.ts.map +1 -0
  47. package/dist/services/defi/aave.js +305 -0
  48. package/dist/services/defi/aave.js.map +1 -0
  49. package/dist/services/defi/abi/aave.d.ts +145 -0
  50. package/dist/services/defi/abi/aave.d.ts.map +1 -0
  51. package/dist/services/defi/abi/aave.js +100 -0
  52. package/dist/services/defi/abi/aave.js.map +1 -0
  53. package/dist/services/defi/constants.d.ts +16 -0
  54. package/dist/services/defi/constants.d.ts.map +1 -0
  55. package/dist/services/defi/constants.js +17 -0
  56. package/dist/services/defi/constants.js.map +1 -0
  57. package/dist/services/privy/account.d.ts +15 -0
  58. package/dist/services/privy/account.d.ts.map +1 -0
  59. package/dist/services/privy/account.js +64 -0
  60. package/dist/services/privy/account.js.map +1 -0
  61. package/package.json +4 -2
package/README.md CHANGED
@@ -11,7 +11,9 @@ A command-line tool for specialized DeFi operations on **Base, Citrea, HyperEVM,
11
11
  - **ETH & Token Transfers**: Send native assets or any ERC-20 token with a simple command.
12
12
  - **Fibrous Aggregation**: Execute token swaps with optimal routing and auto-slippage protection.
13
13
  - **Transaction Status**: Check the status of any transaction hash and get a block explorer link.
14
+ - **Aave V3 Integration**: Supply, borrow, repay, and withdraw assets on Base (DeFi).
14
15
  - **Automated Auth Flow**: One-time email OTP login provisions a persistent server wallet linked to your user profile.
16
+ - **Private Key Import**: Support for importing existing private keys for local execution.
15
17
  - **JSON Output**: All commands support `--json` for easy integration into scripts and pipelines.
16
18
 
17
19
  ## Requirements
@@ -46,7 +48,7 @@ export PRIVY_APP_ID="your_app_id"
46
48
  export PRIVY_APP_SECRET="your_app_secret"
47
49
  ```
48
50
 
49
- ### 3. Authenticate & Provision Wallet
51
+ ### 2. Authenticate & Provision Wallet
50
52
 
51
53
  This two-step process links your email to a server-side wallet.
52
54
 
@@ -68,6 +70,18 @@ npx fibx auth verify user@example.com 123456
68
70
 
69
71
  _Successfully verifying will create a local session file and provision a Server Wallet if one doesn't exist._
70
72
 
73
+ ### 3. Alternative: Import Private Key
74
+
75
+ If you prefer to use an existing private key (e.g., from Metamask or a generated wallet) instead of Privy:
76
+
77
+ ```bash
78
+ npx fibx auth import
79
+ ```
80
+
81
+ _This will securely prompt for your private key and store it locally in `session.json` for signing transactions._
82
+
83
+ > **Security Note:** Your private key is stored locally on your machine. Ensure your environment is secure.
84
+
71
85
  ### 4. Check Status
72
86
 
73
87
  Verify that you are authenticated and the API is healthy:
@@ -153,15 +167,39 @@ npx fibx tx-status 0x456...def --chain monad
153
167
 
154
168
  ### View Wallet Address
155
169
 
156
- Print your connected server wallet address:
170
+ Print your connected wallet address (Privy or Local):
157
171
 
158
172
  ```bash
159
173
  npx fibx address
160
174
  ```
161
175
 
176
+ ### Aave V3 (Base Only)
177
+
178
+ Interact with Aave V3 protocols on the Base network.
179
+
180
+ ```bash
181
+ npx fibx aave <action> <amount> <token>
182
+ ```
183
+
184
+ **Actions:**
185
+
186
+ - `status`: Check account health (HF, LTV)
187
+ - `supply`: Deposit assets
188
+ - `borrow`: Borrow assets (requires collateral)
189
+ - `repay`: Repay debt
190
+ - `withdraw`: Withdraw assets
191
+
192
+ **Example:**
193
+
194
+ ```bash
195
+ npx fibx aave supply 100 USDC
196
+ ```
197
+
162
198
  ## Agent Skills
163
199
 
164
- Looking to use `fibx` with an AI Agent? Check out the [fibx Skills](https://github.com/ahmetenesdur/fibx-skills) package.
200
+ Building an AI Agent? We provide a **Standardized Skill Set** optimized for LLMs.
201
+
202
+ Check out the [fibx-skills](https://github.com/ahmetenesdur/fibx-skills) directory for:
165
203
 
166
204
  ## Development
167
205
 
@@ -172,8 +210,10 @@ Looking to use `fibx` with an AI Agent? Check out the [fibx Skills](https://gith
172
210
 
173
211
  # Architecture
174
212
 
175
- This CLI uses a **Server Wallet** architecture:
213
+ This CLI uses a **Hybrid Wallet** architecture:
176
214
 
177
- 1. **Privy**: Manages the embedded wallets. We use "Ownerless" wallets (Agents) that are controlled via the Privy App Secret, allowing the CLI to sign transactions programmatically without requiring a user-side browser or JWT.
178
- 2. **Viem**: Handles all blockchain interactions (RPC calls, transaction signing) using a custom Privy-backed account, abstracted in the `services/chain` module.
215
+ 1. **Authentication**:
216
+ - **Privy**: Uses "Agentic" server-side wallets (ownerless) for automated signing.
217
+ - **Local Key**: Direct private key import for standard execution without external dependencies.
218
+ 2. **Viem**: Handles all blockchain interactions (RPC calls, transaction signing) using a unified `WalletClient` interface, abstracting away the underlying signer (Privy vs. Local).
179
219
  3. **Fibrous**: Provides the routing and calldata for optimal token swaps on all supported chains, encapsulated in the `services/fibrous` module.
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function authImportCommand(opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOjG,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD1E"}
@@ -0,0 +1,44 @@
1
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
2
+ import { saveSession } from "../../services/auth/session.js";
3
+ import { privateKeyToAccount } from "viem/accounts";
4
+ import chalk from "chalk";
5
+ import inquirer from "inquirer";
6
+ export async function authImportCommand(opts) {
7
+ try {
8
+ const { privateKey } = await inquirer.prompt([
9
+ {
10
+ type: "password",
11
+ name: "privateKey",
12
+ message: "Enter your private key (0x...):",
13
+ validate: (input) => {
14
+ if (!/^0x[a-fA-F0-9]{64}$/.test(input)) {
15
+ return "Invalid private key format. Must start with 0x and be 66 chars long.";
16
+ }
17
+ return true;
18
+ },
19
+ },
20
+ ]);
21
+ const account = privateKeyToAccount(privateKey);
22
+ const address = account.address;
23
+ await withSpinner("Saving session...", async () => {
24
+ saveSession({
25
+ userId: "local-user",
26
+ walletAddress: address,
27
+ createdAt: new Date().toISOString(),
28
+ type: "private-key",
29
+ privateKey: privateKey,
30
+ });
31
+ }, opts);
32
+ outputResult({
33
+ message: "Private key imported successfully!",
34
+ address: address,
35
+ type: "private-key",
36
+ }, opts);
37
+ console.log(chalk.yellow("\n Security Warning: Your private key is stored locally in session.json."));
38
+ console.log(chalk.yellow(" Make sure your machine is secure."));
39
+ }
40
+ catch (error) {
41
+ outputError(error, opts);
42
+ }
43
+ }
44
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../../src/commands/auth/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAmB;IAC1D,IAAI,CAAC;QACJ,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YAC5C;gBACC,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,iCAAiC;gBAC1C,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;oBAC3B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBACxC,OAAO,sEAAsE,CAAC;oBAC/E,CAAC;oBACD,OAAO,IAAI,CAAC;gBACb,CAAC;aACD;SACD,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAiB,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAEhC,MAAM,WAAW,CAChB,mBAAmB,EACnB,KAAK,IAAI,EAAE;YACV,WAAW,CAAC;gBACX,MAAM,EAAE,YAAY;gBACpB,aAAa,EAAE,OAAO;gBACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,IAAI,EAAE,aAAa;gBACnB,UAAU,EAAE,UAAU;aACtB,CAAC,CAAC;QACJ,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,YAAY,CACX;YACC,OAAO,EAAE,oCAAoC;YAC7C,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,aAAa;SACnB,EACD,IAAI,CACJ,CAAC;QAEF,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,MAAM,CACX,6EAA6E,CAC7E,CACD,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uCAAuC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const logoutCommand: Command;
3
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAavB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Command } from "commander";
2
+ import { clearSession } from "../../services/auth/session.js";
3
+ import ora from "ora";
4
+ export const logoutCommand = new Command("logout")
5
+ .description("Log out and clear current session")
6
+ .action(async () => {
7
+ const spinner = ora("Logging out...").start();
8
+ try {
9
+ clearSession();
10
+ spinner.succeed("Logged out successfully. Session cleared.");
11
+ }
12
+ catch (error) {
13
+ spinner.fail("Logout failed.");
14
+ if (error instanceof Error) {
15
+ console.error(error.message);
16
+ }
17
+ }
18
+ });
19
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/commands/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAChD,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,KAAK,IAAI,EAAE;IAClB,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC;IAC9C,IAAI,CAAC;QACJ,YAAY,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC/B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"AAOA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOjG,wBAAsB,iBAAiB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GACjB,OAAO,CAAC,IAAI,CAAC,CAoFf"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"AAOA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOjG,wBAAsB,iBAAiB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GACjB,OAAO,CAAC,IAAI,CAAC,CAqFf"}
@@ -45,6 +45,7 @@ export async function authVerifyCommand(email, code, opts) {
45
45
  walletAddress: wallet.address,
46
46
  userJwt: userToken,
47
47
  createdAt: new Date().toISOString(),
48
+ type: "privy",
48
49
  });
49
50
  outputResult({
50
51
  walletAddress: wallet.address,
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface GlobalOptions {
2
+ json?: boolean;
3
+ chain?: string;
4
+ }
5
+ export declare const aaveCommand: (action: string, amount: string, tokenSymbol: string, opts: GlobalOptions) => Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=aave.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aave.d.ts","sourceRoot":"","sources":["../../../src/commands/defi/aave.ts"],"names":[],"mappings":"AAgBA,UAAU,aAAa;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAID,eAAO,MAAM,WAAW,GACvB,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,aAAa,MAAM,EACnB,MAAM,aAAa,kBAkGnB,CAAC"}
@@ -0,0 +1,218 @@
1
+ import ora from "ora";
2
+ import chalk from "chalk";
3
+ import { AaveService } from "../../services/defi/aave.js";
4
+ import { getChainConfig } from "../../services/chain/constants.js";
5
+ import { resolveToken } from "../../services/fibrous/tokens.js";
6
+ import { getBalances } from "../../services/fibrous/balances.js";
7
+ import { HEALTH_FACTOR_WARNING_THRESHOLD, HEALTH_FACTOR_CRITICAL_THRESHOLD, WETH_BASE_ADDRESS, } from "../../services/defi/constants.js";
8
+ import { outputError, outputResult } from "../../lib/format.js";
9
+ import { getPublicClient } from "../../services/chain/client.js";
10
+ import { formatUnits, parseUnits } from "viem";
11
+ export const aaveCommand = async (action, amount, tokenSymbol, opts) => {
12
+ const spinner = ora("Initializing Aave service...").start();
13
+ try {
14
+ // Aave V3 is currently Base-only
15
+ const chainConfig = getChainConfig("base");
16
+ // Initialize Service
17
+ const aave = new AaveService();
18
+ try {
19
+ // Try to load session (Privy or Private Key)
20
+ await attemptSessionLogin(aave, chainConfig);
21
+ }
22
+ catch {
23
+ // Ignore if no session, aave service handles missing wallet gracefully for read-only
24
+ }
25
+ const userAddress = aave.getAccountAddress();
26
+ if (!userAddress) {
27
+ if (action === "status") {
28
+ spinner.fail("No wallet connected. Run `fibx auth login` or `fibx auth import`.");
29
+ }
30
+ else {
31
+ spinner.fail("No active session found. Please login or import a private key.");
32
+ }
33
+ return;
34
+ }
35
+ if (action === "status") {
36
+ await handleStatus(aave, userAddress, opts, spinner);
37
+ return;
38
+ }
39
+ if (!isValidAction(action)) {
40
+ spinner.fail(`Unknown action: ${action}`);
41
+ console.log(chalk.gray("Available actions: status, supply, borrow, repay, withdraw"));
42
+ return;
43
+ }
44
+ if (!tokenSymbol) {
45
+ spinner.fail(`Token is required for action: ${action}`);
46
+ return;
47
+ }
48
+ if (!amount) {
49
+ spinner.fail(`Amount is required for action: ${action}`);
50
+ return;
51
+ }
52
+ // Resolve Token
53
+ spinner.text = `Resolving token ${tokenSymbol}...`;
54
+ let token = await resolveToken(tokenSymbol, chainConfig);
55
+ // Handle ETH -> WETH translation for Aave
56
+ if (token.address === chainConfig.nativeTokenAddress) {
57
+ token = {
58
+ ...token,
59
+ address: WETH_BASE_ADDRESS,
60
+ symbol: "WETH",
61
+ name: "Wrapped Ether",
62
+ };
63
+ }
64
+ spinner.text = "Interacting with Aave Protocol...";
65
+ switch (action) {
66
+ case "supply":
67
+ await handleSupply(aave, token, amount, userAddress, chainConfig, spinner, opts, tokenSymbol.toUpperCase() === "ETH");
68
+ break;
69
+ case "borrow":
70
+ await handleBorrow(aave, token, amount, spinner, opts);
71
+ break;
72
+ case "repay":
73
+ await handleRepay(aave, token, amount, spinner, opts);
74
+ break;
75
+ case "withdraw":
76
+ await handleWithdraw(aave, token, amount, spinner, opts, tokenSymbol.toUpperCase() === "ETH");
77
+ break;
78
+ }
79
+ }
80
+ catch (error) {
81
+ spinner.stop();
82
+ outputError(error, { json: !!opts.json });
83
+ }
84
+ };
85
+ // Helpers
86
+ function isValidAction(action) {
87
+ return ["status", "supply", "borrow", "repay", "withdraw"].includes(action);
88
+ }
89
+ async function attemptSessionLogin(aave, chainConfig) {
90
+ try {
91
+ const { loadSession } = await import("../../services/auth/session.js");
92
+ const { getPrivyClient } = await import("../../services/privy/client.js");
93
+ const { getWalletClient } = await import("../../services/chain/client.js");
94
+ const session = loadSession();
95
+ if (session) {
96
+ const privy = session.type === "privy" ? getPrivyClient() : null;
97
+ const walletClient = getWalletClient(privy, session, chainConfig);
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ aave.setWalletClient(walletClient);
100
+ }
101
+ }
102
+ catch {
103
+ // Session load failed, ignore
104
+ }
105
+ }
106
+ // Action Handlers
107
+ async function handleStatus(aave, userAddress, opts, spinner) {
108
+ spinner.text = `Fetching data for ${userAddress}...`;
109
+ const data = await aave.getUserAccountData(userAddress);
110
+ spinner.stop();
111
+ if (opts.json) {
112
+ console.log(JSON.stringify(data));
113
+ return;
114
+ }
115
+ const hf = parseFloat(data.healthFactor);
116
+ let hfColor = chalk.green;
117
+ if (hf < HEALTH_FACTOR_CRITICAL_THRESHOLD)
118
+ hfColor = chalk.red;
119
+ else if (hf < HEALTH_FACTOR_WARNING_THRESHOLD)
120
+ hfColor = chalk.yellow;
121
+ const hfDisplay = hf > 100 ? "Safe (>100)" : hf.toFixed(2);
122
+ console.log(chalk.bold("\nAave V3 Position (Base)"));
123
+ console.log(chalk.gray("---------------------------"));
124
+ outputResult({
125
+ "Health Factor": hfColor(hfDisplay),
126
+ Collateral: `$${parseFloat(data.totalCollateralUSD).toFixed(2)}`,
127
+ Debt: `$${parseFloat(data.totalDebtUSD).toFixed(2)}`,
128
+ "Available Borrow": `$${parseFloat(data.availableBorrowsUSD).toFixed(2)}`,
129
+ }, { json: !!opts.json });
130
+ }
131
+ async function handleSupply(aave, token, amount, userAddress, chainConfig, spinner, opts, isNativeETH = false) {
132
+ // Balance Check
133
+ spinner.text = "Checking balance...";
134
+ const balances = await getBalances([{ address: token.address, decimals: token.decimals }], userAddress, chainConfig);
135
+ const wethBalanceData = balances.find((b) => b.token.address.toLowerCase() === token.address.toLowerCase());
136
+ const amountBigInt = parseUnits(amount, token.decimals);
137
+ const wethBalanceBigInt = wethBalanceData
138
+ ? parseUnits(wethBalanceData.balance, token.decimals)
139
+ : 0n;
140
+ if (isNativeETH) {
141
+ const publicClient = getPublicClient(chainConfig);
142
+ const ethBalanceBigInt = await publicClient.getBalance({ address: userAddress });
143
+ const totalAvailable = ethBalanceBigInt + wethBalanceBigInt;
144
+ if (totalAvailable < amountBigInt) {
145
+ spinner.fail(chalk.red("Insufficient Balance"));
146
+ console.log(chalk.yellow(`You have ${formatUnits(ethBalanceBigInt, 18)} ETH + ${formatUnits(wethBalanceBigInt, 18)} WETH, but need ${amount}.`));
147
+ return;
148
+ }
149
+ // Check if we need to wrap
150
+ if (wethBalanceBigInt < amountBigInt) {
151
+ const neededWETH = amountBigInt - wethBalanceBigInt;
152
+ spinner.text = `Wrapping ${formatUnits(neededWETH, 18)} ETH to WETH...`;
153
+ await aave.wrapETH(formatUnits(neededWETH, 18));
154
+ spinner.succeed("Wrapped ETH successfully");
155
+ }
156
+ }
157
+ else {
158
+ if (wethBalanceBigInt < amountBigInt) {
159
+ spinner.fail(chalk.red("Insufficient Balance"));
160
+ console.log(chalk.yellow(`You have ${formatUnits(wethBalanceBigInt, token.decimals)} ${token.symbol}, but need ${amount}.`));
161
+ return;
162
+ }
163
+ }
164
+ spinner.text = "Signaling Aave Supply...";
165
+ const tx = await aave.supply(token.address, amount);
166
+ spinner.succeed("Supply transaction sent!");
167
+ outputResult({
168
+ action: "Supply",
169
+ amount,
170
+ token: token.symbol,
171
+ txHash: tx,
172
+ chain: "base",
173
+ }, { json: !!opts.json });
174
+ }
175
+ async function handleBorrow(aave, token, amount, spinner, opts) {
176
+ spinner.text = "Signaling Aave Borrow...";
177
+ const tx = await aave.borrow(token.address, amount);
178
+ spinner.succeed("Borrow transaction sent!");
179
+ outputResult({
180
+ action: "Borrow",
181
+ amount,
182
+ token: token.symbol,
183
+ txHash: tx,
184
+ chain: "base",
185
+ }, { json: !!opts.json });
186
+ }
187
+ async function handleRepay(aave, token, amount, spinner, opts) {
188
+ spinner.text = "Signaling Aave Repay...";
189
+ const tx = await aave.repay(token.address, amount);
190
+ spinner.succeed("Repay transaction sent!");
191
+ outputResult({
192
+ action: "Repay",
193
+ amount,
194
+ token: token.symbol,
195
+ txHash: tx,
196
+ chain: "base",
197
+ }, { json: !!opts.json });
198
+ }
199
+ async function handleWithdraw(aave, token, amount, spinner, opts, isNativeETH = false) {
200
+ spinner.text = "Signaling Aave Withdraw...";
201
+ const tx = await aave.withdraw(token.address, amount);
202
+ if (isNativeETH) {
203
+ spinner.text = "Unwrapping WETH to ETH...";
204
+ await aave.unwrapWETH(amount);
205
+ spinner.succeed("Withdraw & Unwrap transaction sent!");
206
+ }
207
+ else {
208
+ spinner.succeed("Withdraw transaction sent!");
209
+ }
210
+ outputResult({
211
+ action: "Withdraw",
212
+ amount,
213
+ token: isNativeETH ? "ETH" : token.symbol,
214
+ txHash: tx,
215
+ chain: "base",
216
+ }, { json: !!opts.json });
217
+ }
218
+ //# sourceMappingURL=aave.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aave.js","sourceRoot":"","sources":["../../../src/commands/defi/aave.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../../src/commands/trade/swap.ts"],"names":[],"mappings":"AAWA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,UAAU,YAAa,SAAQ,aAAa;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,YAAY,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAmGf"}
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../../src/commands/trade/swap.ts"],"names":[],"mappings":"AAWA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,UAAU,YAAa,SAAQ,aAAa;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,YAAY,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAsHf"}
@@ -17,10 +17,13 @@ export async function tradeCommand(amount, from, to, opts) {
17
17
  const chain = getChainConfig(chainName);
18
18
  const session = requireSession();
19
19
  const privy = getPrivyClient();
20
+ const walletClient = getWalletClient(privy, session, chain);
21
+ const publicClient = getPublicClient(chain);
20
22
  const wallet = session.walletAddress;
21
23
  const [tokenIn, tokenOut] = await withSpinner(`Resolving tokens on ${chain.name}...`, async () => Promise.all([resolveToken(from, chain), resolveToken(to, chain)]), opts);
22
24
  const amountBaseUnits = parseAmount(amount, tokenIn.decimals);
23
- const isNativeInput = tokenIn.address.toLowerCase() === chain.nativeTokenAddress.toLowerCase();
25
+ const isNativeInput = tokenIn.address.toLowerCase() === chain.nativeTokenAddress.toLowerCase() ||
26
+ tokenIn.symbol.toUpperCase() === "ETH";
24
27
  const routeData = await withSpinner("Finding best route...", async () => {
25
28
  return getRouteAndCallData({
26
29
  amount: amountBaseUnits.toString(),
@@ -31,9 +34,8 @@ export async function tradeCommand(amount, from, to, opts) {
31
34
  }, chain);
32
35
  }, opts);
33
36
  const routerAddress = routeData.router_address;
34
- const walletClient = getWalletClient(privy, session, chain);
35
37
  if (!isNativeInput) {
36
- const currentAllowance = await getAllowance(getPublicClient(chain), tokenIn.address, wallet, routerAddress);
38
+ const currentAllowance = await getAllowance(publicClient, tokenIn.address, wallet, routerAddress);
37
39
  if (currentAllowance < amountBaseUnits) {
38
40
  await withSpinner("Approving token spend...", async () => {
39
41
  const amountToApprove = opts.approveMax
@@ -50,10 +52,24 @@ export async function tradeCommand(amount, from, to, opts) {
50
52
  }
51
53
  const hash = await withSpinner(`Swapping ${amount} ${tokenIn.symbol} → ${tokenOut.symbol}...`, async () => {
52
54
  const swapData = encodeSwapCalldata(routeData.calldata, chain);
55
+ const value = isNativeInput ? amountBaseUnits : 0n;
56
+ // Simulate Swap (using estimateGas as we have raw calldata)
57
+ // We use call/estimateGas to ensure it doesn't revert
58
+ try {
59
+ await publicClient.estimateGas({
60
+ account: wallet,
61
+ to: routerAddress,
62
+ data: swapData,
63
+ value: value,
64
+ });
65
+ }
66
+ catch (error) {
67
+ throw new Error(`Simulation failed: ${error instanceof Error ? error.message : String(error)}`);
68
+ }
53
69
  return walletClient.sendTransaction({
54
70
  to: routerAddress,
55
71
  data: swapData,
56
- value: isNativeInput ? amountBaseUnits : 0n,
72
+ value: value,
57
73
  });
58
74
  }, opts);
59
75
  const outputAmount = formatAmount(BigInt(routeData.route.outputAmount), tokenOut.decimals);
@@ -1 +1 @@
1
- {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../../src/commands/trade/swap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../../src/commands/trade/swap.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"AASA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,WAAW,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,GACjB,OAAO,CAAC,IAAI,CAAC,CA6Df"}
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"AASA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,WAAW,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,GACjB,OAAO,CAAC,IAAI,CAAC,CAiFf"}
@@ -1,8 +1,8 @@
1
1
  import { requireSession } from "../../services/auth/session.js";
2
2
  import { getPrivyClient } from "../../services/privy/client.js";
3
- import { getWalletClient } from "../../services/chain/client.js";
3
+ import { getWalletClient, getPublicClient } from "../../services/chain/client.js";
4
4
  import { getChainConfig } from "../../services/chain/constants.js";
5
- import { encodeTransfer } from "../../services/chain/erc20.js";
5
+ import { ERC20_ABI } from "../../services/chain/erc20.js";
6
6
  import { resolveToken } from "../../services/fibrous/tokens.js";
7
7
  import { validateAddress, validateAmount } from "../../lib/validation.js";
8
8
  import { parseAmount } from "../../lib/parseAmount.js";
@@ -17,12 +17,26 @@ export async function sendCommand(amount, recipient, tokenSymbol, opts) {
17
17
  const session = requireSession();
18
18
  const privy = getPrivyClient();
19
19
  const walletClient = getWalletClient(privy, session, chain);
20
+ const publicClient = getPublicClient(chain);
21
+ const wallet = session.walletAddress;
20
22
  let txHash;
21
23
  let amountBigInt;
22
24
  const isEth = tokenSymbol.toUpperCase() === "ETH";
23
25
  if (isEth) {
24
26
  amountBigInt = parseAmount(amount, 18);
25
27
  txHash = await withSpinner(`Sending ${amount} ETH on ${chain.name}...`, async () => {
28
+ // Simulate ETH send (estimateGas)
29
+ try {
30
+ await publicClient.estimateGas({
31
+ account: wallet,
32
+ to: recipient,
33
+ value: amountBigInt,
34
+ data: undefined,
35
+ });
36
+ }
37
+ catch (error) {
38
+ throw new Error(`Simulation failed: ${error instanceof Error ? error.message : String(error)}`);
39
+ }
26
40
  return walletClient.sendTransaction({
27
41
  to: recipient,
28
42
  value: amountBigInt,
@@ -33,13 +47,16 @@ export async function sendCommand(amount, recipient, tokenSymbol, opts) {
33
47
  else {
34
48
  const token = await resolveToken(tokenSymbol, chain);
35
49
  amountBigInt = parseAmount(amount, token.decimals);
36
- const data = encodeTransfer(recipient, amountBigInt);
37
50
  txHash = await withSpinner(`Sending ${amount} ${token.symbol} on ${chain.name}...`, async () => {
38
- return walletClient.sendTransaction({
39
- to: token.address,
40
- data,
41
- value: 0n,
51
+ // Simulate ERC20 Transfer
52
+ const { request } = await publicClient.simulateContract({
53
+ address: token.address,
54
+ abi: ERC20_ABI,
55
+ functionName: "transfer",
56
+ args: [recipient, amountBigInt],
57
+ account: wallet,
42
58
  });
59
+ return walletClient.writeContract(request);
43
60
  }, opts);
44
61
  }
45
62
  outputResult({
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,MAAc,EACd,SAAiB,EACjB,WAAmB,EACnB,IAAmB;IAEnB,IAAI,CAAC;QACJ,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,eAAe,CAAC,SAAS,CAAC,CAAC;QAE3B,MAAM,UAAU,GAAG,IAAqC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,IAAI,MAAM,CAAC;QAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAE5D,IAAI,MAAqB,CAAC;QAC1B,IAAI,YAAoB,CAAC;QACzB,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;QAElD,IAAI,KAAK,EAAE,CAAC;YACX,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACvC,MAAM,GAAG,MAAM,WAAW,CACzB,WAAW,MAAM,WAAW,KAAK,CAAC,IAAI,KAAK,EAC3C,KAAK,IAAI,EAAE;gBACV,OAAO,YAAY,CAAC,eAAe,CAAC;oBACnC,EAAE,EAAE,SAAoB;oBACxB,KAAK,EAAE,YAAY;oBACnB,IAAI,EAAE,SAAS;iBACf,CAAC,CAAC;YACJ,CAAC,EACD,IAAI,CACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACP,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACrD,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,cAAc,CAAC,SAAoB,EAAE,YAAY,CAAC,CAAC;YAEhE,MAAM,GAAG,MAAM,WAAW,CACzB,WAAW,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,IAAI,KAAK,EACvD,KAAK,IAAI,EAAE;gBACV,OAAO,YAAY,CAAC,eAAe,CAAC;oBACnC,EAAE,EAAE,KAAK,CAAC,OAAkB;oBAC5B,IAAI;oBACJ,KAAK,EAAE,EAAE;iBACT,CAAC,CAAC;YACJ,CAAC,EACD,IAAI,CACJ,CAAC;QACH,CAAC;QAED,YAAY,CACX;YACC,MAAM;YACN,MAAM;YACN,SAAS;YACT,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE;YAChD,KAAK,EAAE,KAAK,CAAC,IAAI;SACjB,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"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"}