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.
- package/README.md +46 -6
- package/dist/commands/auth/import.d.ts +3 -0
- package/dist/commands/auth/import.d.ts.map +1 -0
- package/dist/commands/auth/import.js +44 -0
- package/dist/commands/auth/import.js.map +1 -0
- package/dist/commands/auth/logout.d.ts +3 -0
- package/dist/commands/auth/logout.d.ts.map +1 -0
- package/dist/commands/auth/logout.js +19 -0
- package/dist/commands/auth/logout.js.map +1 -0
- package/dist/commands/auth/verify.d.ts.map +1 -1
- package/dist/commands/auth/verify.js +1 -0
- package/dist/commands/auth/verify.js.map +1 -1
- package/dist/commands/defi/aave.d.ts +7 -0
- package/dist/commands/defi/aave.d.ts.map +1 -0
- package/dist/commands/defi/aave.js +218 -0
- package/dist/commands/defi/aave.js.map +1 -0
- package/dist/commands/trade/swap.d.ts.map +1 -1
- package/dist/commands/trade/swap.js +20 -4
- package/dist/commands/trade/swap.js.map +1 -1
- package/dist/commands/wallet/send.d.ts.map +1 -1
- package/dist/commands/wallet/send.js +24 -7
- package/dist/commands/wallet/send.js.map +1 -1
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/dist/services/auth/session.d.ts +6 -1
- package/dist/services/auth/session.d.ts.map +1 -1
- package/dist/services/auth/session.js +3 -1
- package/dist/services/auth/session.js.map +1 -1
- package/dist/services/chain/client.d.ts +1 -1
- package/dist/services/chain/client.d.ts.map +1 -1
- package/dist/services/chain/client.js +17 -64
- package/dist/services/chain/client.js.map +1 -1
- package/dist/services/chain/constants.d.ts +6 -0
- package/dist/services/chain/constants.d.ts.map +1 -1
- package/dist/services/chain/constants.js +8 -1
- package/dist/services/chain/constants.js.map +1 -1
- package/dist/services/chain/erc20.d.ts +58 -1
- package/dist/services/chain/erc20.d.ts.map +1 -1
- package/dist/services/chain/erc20.js +1 -8
- package/dist/services/chain/erc20.js.map +1 -1
- package/dist/services/chain/nonceManager.d.ts +14 -0
- package/dist/services/chain/nonceManager.d.ts.map +1 -0
- package/dist/services/chain/nonceManager.js +50 -0
- package/dist/services/chain/nonceManager.js.map +1 -0
- package/dist/services/defi/aave.d.ts +30 -0
- package/dist/services/defi/aave.d.ts.map +1 -0
- package/dist/services/defi/aave.js +305 -0
- package/dist/services/defi/aave.js.map +1 -0
- package/dist/services/defi/abi/aave.d.ts +145 -0
- package/dist/services/defi/abi/aave.d.ts.map +1 -0
- package/dist/services/defi/abi/aave.js +100 -0
- package/dist/services/defi/abi/aave.js.map +1 -0
- package/dist/services/defi/constants.d.ts +16 -0
- package/dist/services/defi/constants.d.ts.map +1 -0
- package/dist/services/defi/constants.js +17 -0
- package/dist/services/defi/constants.js.map +1 -0
- package/dist/services/privy/account.d.ts +15 -0
- package/dist/services/privy/account.d.ts.map +1 -0
- package/dist/services/privy/account.js +64 -0
- package/dist/services/privy/account.js.map +1 -0
- 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
|
-
###
|
|
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
|
|
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
|
-
|
|
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 **
|
|
213
|
+
This CLI uses a **Hybrid Wallet** architecture:
|
|
176
214
|
|
|
177
|
-
1. **
|
|
178
|
-
|
|
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 @@
|
|
|
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 @@
|
|
|
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,
|
|
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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAOjG,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,KAAa,EACb,IAAY,EACZ,IAAmB;IAEnB,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAE/B,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,WAAW,CAC9C,kBAAkB,EAClB,KAAK,IAAI,EAAE;YACV,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAa,CAAC;YACxC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAiB,CAAC;YAChD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAE5E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,wDAAwD,EAAE;gBACjF,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACR,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,SAAS,WAAW,EAAE;oBACrC,cAAc,EAAE,KAAK;iBACrB;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aACrC,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;YAC/D,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAC;YACrD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACrE,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,4BAA4B;QAC5B,MAAM,cAAc,GAAG,MAAM,WAAW,CACvC,iCAAiC,EACjC,KAAK,IAAI,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,EAC5C,IAAI,CACJ,CAAC;QAEF,IAAI,MAAuC,CAAC;QAC5C,IAAI,UAAmB,CAAC;QAExB,IAAI,cAAc,EAAE,CAAC;YACpB,MAAM,GAAG,cAAc,CAAC;YACxB,UAAU,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,CAAC;YACP,2BAA2B;YAC3B,MAAM,GAAG,MAAM,WAAW,CACzB,2BAA2B,EAC3B,KAAK,IAAI,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,EACpC,IAAI,CACJ,CAAC;YAEF,sBAAsB;YACtB,MAAM,WAAW,CAChB,2BAA2B,EAC3B,KAAK,IAAI,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EACxD,IAAI,CACJ,CAAC;YAEF,UAAU,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,MAAM,WAAW,CAAC;YACjB,MAAM;YACN,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,aAAa,EAAE,MAAM,CAAC,OAAwB;YAC9C,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,
|
|
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(
|
|
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:
|
|
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":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAOjG,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,MAAc,EACd,IAAY,EACZ,EAAU,EACV,IAAkB;IAElB,IAAI,CAAC;QACJ,cAAc,CAAC,MAAM,CAAC,CAAC;QAEvB,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,MAAM,GAAG,OAAO,CAAC,aAAwB,CAAC;QAEhD,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,WAAW,CAC5C,uBAAuB,KAAK,CAAC,IAAI,KAAK,EACtC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAC7E,IAAI,CACJ,CAAC;QAEF,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,aAAa,GAClB,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;
|
|
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,
|
|
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 {
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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;
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"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"}
|