fibx 0.1.1 → 0.1.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 (129) hide show
  1. package/README.md +35 -31
  2. package/dist/commands/auth/login.d.ts +3 -0
  3. package/dist/commands/auth/login.d.ts.map +1 -0
  4. package/dist/commands/auth/login.js +34 -0
  5. package/dist/commands/auth/login.js.map +1 -0
  6. package/dist/commands/auth/verify.d.ts +3 -0
  7. package/dist/commands/auth/verify.d.ts.map +1 -0
  8. package/dist/commands/auth/verify.js +61 -0
  9. package/dist/commands/auth/verify.js.map +1 -0
  10. package/dist/commands/balance.d.ts.map +1 -1
  11. package/dist/commands/balance.js +27 -8
  12. package/dist/commands/balance.js.map +1 -1
  13. package/dist/commands/chain/transaction.d.ts +3 -0
  14. package/dist/commands/chain/transaction.d.ts.map +1 -0
  15. package/dist/commands/chain/transaction.js +31 -0
  16. package/dist/commands/chain/transaction.js.map +1 -0
  17. package/dist/commands/trade/status.d.ts +3 -0
  18. package/dist/commands/trade/status.d.ts.map +1 -0
  19. package/dist/commands/trade/status.js +32 -0
  20. package/dist/commands/trade/status.js.map +1 -0
  21. package/dist/commands/trade/swap.d.ts +8 -0
  22. package/dist/commands/trade/swap.d.ts.map +1 -0
  23. package/dist/commands/trade/swap.js +74 -0
  24. package/dist/commands/trade/swap.js.map +1 -0
  25. package/dist/commands/wallet/address.d.ts +3 -0
  26. package/dist/commands/wallet/address.d.ts.map +1 -0
  27. package/dist/commands/wallet/address.js +15 -0
  28. package/dist/commands/wallet/address.js.map +1 -0
  29. package/dist/commands/wallet/balance.d.ts +3 -0
  30. package/dist/commands/wallet/balance.d.ts.map +1 -0
  31. package/dist/commands/wallet/balance.js +53 -0
  32. package/dist/commands/wallet/balance.js.map +1 -0
  33. package/dist/commands/wallet/list.d.ts +3 -0
  34. package/dist/commands/wallet/list.d.ts.map +1 -0
  35. package/dist/commands/wallet/list.js +39 -0
  36. package/dist/commands/wallet/list.js.map +1 -0
  37. package/dist/commands/wallet/send.d.ts +3 -0
  38. package/dist/commands/wallet/send.d.ts.map +1 -0
  39. package/dist/commands/wallet/send.js +57 -0
  40. package/dist/commands/wallet/send.js.map +1 -0
  41. package/dist/fibrous/balances.d.ts +14 -0
  42. package/dist/fibrous/balances.d.ts.map +1 -0
  43. package/dist/fibrous/balances.js +26 -0
  44. package/dist/fibrous/balances.js.map +1 -0
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +98 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/lib/cache.d.ts +3 -0
  50. package/dist/lib/cache.d.ts.map +1 -0
  51. package/dist/lib/cache.js +23 -0
  52. package/dist/lib/cache.js.map +1 -0
  53. package/dist/lib/config.d.ts +6 -0
  54. package/dist/lib/config.d.ts.map +1 -0
  55. package/dist/lib/config.js +7 -0
  56. package/dist/lib/config.js.map +1 -0
  57. package/dist/lib/errors.d.ts +22 -0
  58. package/dist/lib/errors.d.ts.map +1 -0
  59. package/dist/lib/errors.js +29 -0
  60. package/dist/lib/errors.js.map +1 -0
  61. package/dist/lib/format.d.ts +8 -0
  62. package/dist/lib/format.d.ts.map +1 -0
  63. package/dist/lib/format.js +69 -0
  64. package/dist/lib/format.js.map +1 -0
  65. package/dist/lib/parseAmount.d.ts +3 -0
  66. package/dist/lib/parseAmount.d.ts.map +1 -0
  67. package/dist/lib/parseAmount.js +10 -0
  68. package/dist/lib/parseAmount.js.map +1 -0
  69. package/dist/lib/validation.d.ts +6 -0
  70. package/dist/lib/validation.d.ts.map +1 -0
  71. package/dist/lib/validation.js +24 -0
  72. package/dist/lib/validation.js.map +1 -0
  73. package/dist/services/auth/policy.d.ts +2 -0
  74. package/dist/services/auth/policy.d.ts.map +1 -0
  75. package/dist/services/auth/policy.js +3 -0
  76. package/dist/services/auth/policy.js.map +1 -0
  77. package/dist/services/auth/session.d.ts +15 -0
  78. package/dist/services/auth/session.d.ts.map +1 -0
  79. package/dist/services/auth/session.js +47 -0
  80. package/dist/services/auth/session.js.map +1 -0
  81. package/dist/services/chain/client.d.ts +8358 -0
  82. package/dist/services/chain/client.d.ts.map +1 -0
  83. package/dist/services/chain/client.js +78 -0
  84. package/dist/services/chain/client.js.map +1 -0
  85. package/dist/services/chain/constants.d.ts +158 -0
  86. package/dist/services/chain/constants.d.ts.map +1 -0
  87. package/dist/services/chain/constants.js +100 -0
  88. package/dist/services/chain/constants.js.map +1 -0
  89. package/dist/services/chain/erc20.d.ts +6 -0
  90. package/dist/services/chain/erc20.d.ts.map +1 -0
  91. package/dist/services/chain/erc20.js +71 -0
  92. package/dist/services/chain/erc20.js.map +1 -0
  93. package/dist/services/fibrous/abi/base.d.ts +768 -0
  94. package/dist/services/fibrous/abi/base.d.ts.map +1 -0
  95. package/dist/services/fibrous/abi/base.js +984 -0
  96. package/dist/services/fibrous/abi/base.js.map +1 -0
  97. package/dist/services/fibrous/abi/citrea.d.ts +64 -0
  98. package/dist/services/fibrous/abi/citrea.d.ts.map +1 -0
  99. package/dist/services/fibrous/abi/citrea.js +990 -0
  100. package/dist/services/fibrous/abi/citrea.js.map +1 -0
  101. package/dist/services/fibrous/abi/hyperevm.d.ts +64 -0
  102. package/dist/services/fibrous/abi/hyperevm.d.ts.map +1 -0
  103. package/dist/services/fibrous/abi/hyperevm.js +990 -0
  104. package/dist/services/fibrous/abi/hyperevm.js.map +1 -0
  105. package/dist/services/fibrous/abi/monad.d.ts +64 -0
  106. package/dist/services/fibrous/abi/monad.d.ts.map +1 -0
  107. package/dist/services/fibrous/abi/monad.js +990 -0
  108. package/dist/services/fibrous/abi/monad.js.map +1 -0
  109. package/dist/services/fibrous/balances.d.ts +15 -0
  110. package/dist/services/fibrous/balances.d.ts.map +1 -0
  111. package/dist/services/fibrous/balances.js +24 -0
  112. package/dist/services/fibrous/balances.js.map +1 -0
  113. package/dist/services/fibrous/health.d.ts +12 -0
  114. package/dist/services/fibrous/health.d.ts.map +1 -0
  115. package/dist/services/fibrous/health.js +16 -0
  116. package/dist/services/fibrous/health.js.map +1 -0
  117. package/dist/services/fibrous/route.d.ts +48 -0
  118. package/dist/services/fibrous/route.d.ts.map +1 -0
  119. package/dist/services/fibrous/route.js +57 -0
  120. package/dist/services/fibrous/route.js.map +1 -0
  121. package/dist/services/fibrous/tokens.d.ts +11 -0
  122. package/dist/services/fibrous/tokens.d.ts.map +1 -0
  123. package/dist/services/fibrous/tokens.js +35 -0
  124. package/dist/services/fibrous/tokens.js.map +1 -0
  125. package/dist/services/privy/client.d.ts +15 -0
  126. package/dist/services/privy/client.d.ts.map +1 -0
  127. package/dist/services/privy/client.js +63 -0
  128. package/dist/services/privy/client.js.map +1 -0
  129. package/package.json +6 -6
package/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # fibx
2
2
 
3
- A command-line tool for specialized DeFi operations on **Base**, powered by [Fibrous Finance](https://fibrous.finance) aggregation and [Privy](https://privy.io) Server Wallets.
3
+ A command-line tool for specialized DeFi operations on **Base, Citrea, HyperEVM, and Monad**, powered by [Fibrous Finance](https://fibrous.finance) aggregation and [Privy](https://privy.io) Server Wallets.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/fibx.svg)](https://badge.fury.io/js/fibx)
6
6
 
7
7
  ## Features
8
8
 
9
9
  - **Privy Server Wallets**: Uses "Agentic" server-side wallets (ownerless) for seamless, automated signing without user interaction.
10
- - **ETH & Token Transfers**: Send ETH or any ERC-20 token with a simple command.
10
+ - **Multi-Chain Support**: seamlessly interact with Base, Citrea, HyperEVM, and Monad.
11
+ - **ETH & Token Transfers**: Send native assets or any ERC-20 token with a simple command.
11
12
  - **Fibrous Aggregation**: Execute token swaps with optimal routing and auto-slippage protection.
13
+ - **Transaction Status**: Check the status of any transaction hash and get a block explorer link.
12
14
  - **Automated Auth Flow**: One-time email OTP login provisions a persistent server wallet linked to your user profile.
13
15
  - **JSON Output**: All commands support `--json` for easy integration into scripts and pipelines.
14
16
 
@@ -76,12 +78,23 @@ npx fibx status
76
78
 
77
79
  ## Usage
78
80
 
81
+ ### Global Options
82
+
83
+ You can specify the target chain for any command using the `-c` or `--chain` flag.
84
+
85
+ **Supported Chains:** `base` (default), `citrea`, `hyperevm`, `monad`
86
+
87
+ ```bash
88
+ npx fibx status --chain monad
89
+ ```
90
+
79
91
  ### Check Balance
80
92
 
81
- View your ETH and USDC balances on Base:
93
+ View your balances on the selected chain:
82
94
 
83
95
  ```bash
84
96
  npx fibx balance
97
+ npx fibx balance --chain citrea
85
98
  ```
86
99
 
87
100
  ### Send Tokens
@@ -114,15 +127,30 @@ npx fibx trade <amount> <from_token> <to_token>
114
127
  # Swap 0.0001 ETH to USDC
115
128
  npx fibx trade 0.0001 ETH USDC
116
129
 
117
- # Swap 20 USDC to DAI
130
+ # Swap 20 USDC to DAI on Base
118
131
  npx fibx trade 20 USDC DAI
132
+
133
+ # Swap on Monad
134
+ npx fibx trade 1 MON USDC --chain monad
119
135
  ```
120
136
 
121
137
  **Options:**
122
138
 
123
139
  - `--slippage <number>`: Set slippage tolerance (default: 0.5%)
140
+ - `--approve-max`: Approve maximum amount (infinite approval) instead of exact amount (default: false)
124
141
  - `--json`: Output result as JSON
125
142
 
143
+ ### Check Transaction Status
144
+
145
+ Check the status of a transaction and get the explorer link.
146
+
147
+ ```bash
148
+ npx fibx tx-status <hash>
149
+ # Example:
150
+ npx fibx tx-status 0x123...abc
151
+ npx fibx tx-status 0x456...def --chain monad
152
+ ```
153
+
126
154
  ### View Wallet Address
127
155
 
128
156
  Print your connected server wallet address:
@@ -133,7 +161,7 @@ npx fibx address
133
161
 
134
162
  ## Agent Skills
135
163
 
136
- Looking to use `fibx` with an AI Agent? Check out the [fibx-agentic-wallet-skills](./fibx-agentic-wallet-skills/README.md) package.
164
+ Looking to use `fibx` with an AI Agent? Check out the [fibx-agentic-wallet-skills](https://github.com/ahmetenesdur/fibx-agentic-wallet-skills) package.
137
165
 
138
166
  ## Development
139
167
 
@@ -147,29 +175,5 @@ Looking to use `fibx` with an AI Agent? Check out the [fibx-agentic-wallet-skill
147
175
  This CLI uses a **Server Wallet** architecture:
148
176
 
149
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.
150
- 2. **Viem**: Handles all blockchain interactions (RPC calls, transaction signing) using a custom Privy-backed account.
151
- 3. **Fibrous**: Provides the routing and calldata for optimal token swaps on Base.
152
-
153
- ## Project Structure
154
-
155
- ```
156
- src/
157
- ├── cli.ts # Entry point & Command definitions
158
- ├── commands/ # Command implementation logic
159
- │ ├── auth-login.ts # Step 1: Request OTP
160
- │ ├── auth-verify.ts # Step 2: Verify & Provision Wallet
161
- │ ├── trade.ts # Swap logic via Fibrous
162
- │ ├── send.ts # ETH/ERC20 transfer logic
163
- │ └── ...
164
- ├── chain/ # Blockchain layer
165
- │ └── viem.ts # Viem client & Custom Privy Account
166
- ├── wallet/ # Wallet management
167
- │ ├── privy.ts # Privy SDK integration (Server Wallets)
168
- │ └── session.ts # Local session management
169
- ├── fibrous/ # Fibrous API integration
170
- └── utils/ # Config, validation, and helpers
171
- ```
172
-
173
- ## License
174
-
175
- MIT
178
+ 2. **Viem**: Handles all blockchain interactions (RPC calls, transaction signing) using a custom Privy-backed account, abstracted in the `services/chain` module.
179
+ 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 authLoginCommand(email: string, opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCxF"}
@@ -0,0 +1,34 @@
1
+ import { getPrivyClient } from "../../services/privy/client.js";
2
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
3
+ export async function authLoginCommand(email, opts) {
4
+ try {
5
+ getPrivyClient();
6
+ await withSpinner("Sending OTP...", async () => {
7
+ const appId = process.env.PRIVY_APP_ID;
8
+ const appSecret = process.env.PRIVY_APP_SECRET;
9
+ const credentials = Buffer.from(`${appId}:${appSecret}`).toString("base64");
10
+ const res = await fetch("https://auth.privy.io/api/v1/passwordless/init", {
11
+ method: "POST",
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ Authorization: `Basic ${credentials}`,
15
+ "privy-app-id": appId,
16
+ },
17
+ body: JSON.stringify({ email }),
18
+ });
19
+ if (!res.ok) {
20
+ const body = await res.text().catch(() => "");
21
+ throw new Error(`OTP init failed (${res.status}): ${body}`);
22
+ }
23
+ return res.json();
24
+ }, opts);
25
+ outputResult({
26
+ email,
27
+ message: `OTP sent to ${email}. Run: fibx auth verify ${email} <code>`,
28
+ }, opts);
29
+ }
30
+ catch (error) {
31
+ outputError(error, opts);
32
+ }
33
+ }
34
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAa,EAAE,IAAmB;IACxE,IAAI,CAAC;QACJ,cAAc,EAAE,CAAC;QAEjB,MAAM,WAAW,CAChB,gBAAgB,EAChB,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,gDAAgD,EAAE;gBACzE,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,CAAC;aAC/B,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,oBAAoB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,YAAY,CACX;YACC,KAAK;YACL,OAAO,EAAE,eAAe,KAAK,2BAA2B,KAAK,SAAS;SACtE,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function authVerifyCommand(email: string, code: string, opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,61 @@
1
+ import { getPrivyClient, createAgentWallet, findExistingWallet, saveWalletIdToUser, } from "../../services/privy/client.js";
2
+ import { saveSession } from "../../services/auth/session.js";
3
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
4
+ export async function authVerifyCommand(email, code, opts) {
5
+ try {
6
+ const privy = getPrivyClient();
7
+ const { userId, userToken } = await withSpinner("Verifying OTP...", async () => {
8
+ const appId = process.env.PRIVY_APP_ID;
9
+ const appSecret = process.env.PRIVY_APP_SECRET;
10
+ const credentials = Buffer.from(`${appId}:${appSecret}`).toString("base64");
11
+ const res = await fetch("https://auth.privy.io/api/v1/passwordless/authenticate", {
12
+ method: "POST",
13
+ headers: {
14
+ "Content-Type": "application/json",
15
+ Authorization: `Basic ${credentials}`,
16
+ "privy-app-id": appId,
17
+ },
18
+ body: JSON.stringify({ email, code }),
19
+ });
20
+ if (!res.ok) {
21
+ const body = await res.text().catch(() => "");
22
+ throw new Error(`OTP verify failed (${res.status}): ${body}`);
23
+ }
24
+ const data = (await res.json());
25
+ return { userId: data.user.id, userToken: data.privy_access_token };
26
+ }, opts);
27
+ // Check for existing wallet
28
+ const existingWallet = await withSpinner("Checking for existing wallet...", async () => findExistingWallet(privy, email), opts);
29
+ let wallet;
30
+ let isExisting;
31
+ if (existingWallet) {
32
+ wallet = existingWallet;
33
+ isExisting = true;
34
+ }
35
+ else {
36
+ // Create new server wallet
37
+ wallet = await withSpinner("Creating server wallet...", async () => createAgentWallet(privy), opts);
38
+ // Link wallet to user
39
+ await withSpinner("Linking wallet to user...", async () => saveWalletIdToUser(privy, userId, wallet.id), opts);
40
+ isExisting = false;
41
+ }
42
+ await saveSession({
43
+ userId,
44
+ walletId: wallet.id,
45
+ walletAddress: wallet.address,
46
+ userJwt: userToken,
47
+ createdAt: new Date().toISOString(),
48
+ });
49
+ outputResult({
50
+ walletAddress: wallet.address,
51
+ walletId: wallet.id,
52
+ message: isExisting
53
+ ? "Existing wallet found and connected. You're ready to go!"
54
+ : "New wallet created and session saved. You're ready to go!",
55
+ }, opts);
56
+ }
57
+ catch (error) {
58
+ outputError(error, opts);
59
+ }
60
+ }
61
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/auth/verify.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AAQA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCvE"}
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AAQA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DvE"}
@@ -1,9 +1,9 @@
1
1
  import { requireSession } from "../wallet/session.js";
2
2
  import { publicClient } from "../chain/viem.js";
3
3
  import { getChainConfig } from "../chain/chains.js";
4
- import { getERC20Balance } from "../chain/erc20.js";
5
4
  import { ACTIVE_NETWORK } from "../utils/config.js";
6
- import { resolveToken } from "../fibrous/tokens.js";
5
+ import { getTokens } from "../fibrous/tokens.js";
6
+ import { getBalances } from "../fibrous/balances.js";
7
7
  import { formatAmount } from "../utils/parseAmount.js";
8
8
  import { outputResult, outputError, withSpinner } from "../format/output.js";
9
9
  export async function balanceCommand(opts) {
@@ -11,22 +11,41 @@ export async function balanceCommand(opts) {
11
11
  const chain = getChainConfig(ACTIVE_NETWORK);
12
12
  const session = requireSession();
13
13
  const wallet = session.walletAddress;
14
- const usdc = await resolveToken("USDC");
14
+ // 1. Fetch all supported tokens
15
+ const tokensMap = await getTokens();
16
+ const tokenList = Object.values(tokensMap);
15
17
  const balances = await withSpinner("Fetching balances...", async () => {
16
- const [ethBalance, usdcBalance] = await Promise.all([
18
+ // 2. Parallel fetch: Native ETH + All Token Balances
19
+ const [ethBalance, tokenBalances] = await Promise.all([
17
20
  publicClient.getBalance({ address: wallet }),
18
- getERC20Balance(usdc.address, wallet),
21
+ getBalances(tokenList, wallet),
19
22
  ]);
20
23
  return {
21
24
  eth: formatAmount(ethBalance, 18),
22
- usdc: formatAmount(usdcBalance, usdc.decimals),
25
+ tokens: tokenBalances,
23
26
  };
24
27
  }, opts);
28
+ // 3. Prepare Output
29
+ const result = {};
30
+ // Always show ETH first
31
+ result["ETH"] = balances.eth;
32
+ // 4. Filter and Map Tokens
33
+ for (const item of balances.tokens) {
34
+ // Filter out zero balances
35
+ // item.balance is a string string from the API, e.g., "0.0" or "10.5"
36
+ const balanceVal = parseFloat(item.balance);
37
+ if (balanceVal > 0) {
38
+ // Try to find the symbol for the token
39
+ const tokenAddr = item.token.address.toLowerCase();
40
+ const token = tokenList.find((t) => t.address.toLowerCase() === tokenAddr);
41
+ const symbol = token ? token.symbol : tokenAddr; // Fallback to address if symbol not found
42
+ result[symbol] = item.balance;
43
+ }
44
+ }
25
45
  outputResult({
26
46
  wallet: session.walletAddress,
27
47
  chain: chain.name,
28
- eth: balances.eth,
29
- usdc: balances.usdc,
48
+ ...result,
30
49
  }, opts);
31
50
  }
32
51
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAmB;IACvD,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,aAAwB,CAAC;QAEhD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QAExC,MAAM,QAAQ,GAAG,MAAM,WAAW,CACjC,sBAAsB,EACtB,KAAK,IAAI,EAAE;YACV,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACnD,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC5C,eAAe,CAAC,IAAI,CAAC,OAAkB,EAAE,MAAM,CAAC;aAChD,CAAC,CAAC;YAEH,OAAO;gBACN,GAAG,EAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;gBACjC,IAAI,EAAE,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;aAC9C,CAAC;QACH,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,YAAY,CACX;YACC,MAAM,EAAE,OAAO,CAAC,aAAa;YAC7B,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,GAAG,EAAE,QAAQ,CAAC,GAAG;YACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;SACnB,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":"balance.js","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAmB;IACvD,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,aAAwB,CAAC;QAEhD,gCAAgC;QAChC,MAAM,SAAS,GAAG,MAAM,SAAS,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,MAAM,WAAW,CACjC,sBAAsB,EACtB,KAAK,IAAI,EAAE;YACV,qDAAqD;YACrD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACrD,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC5C,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC;aAC9B,CAAC,CAAC;YAEH,OAAO;gBACN,GAAG,EAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;gBACjC,MAAM,EAAE,aAAa;aACrB,CAAC;QACH,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,oBAAoB;QACpB,MAAM,MAAM,GAA2B,EAAE,CAAC;QAE1C,wBAAwB;QACxB,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;QAE7B,2BAA2B;QAC3B,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpC,2BAA2B;YAC3B,sEAAsE;YACtE,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;gBACpB,uCAAuC;gBACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;gBAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,0CAA0C;gBAE3F,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC/B,CAAC;QACF,CAAC;QAED,YAAY,CACX;YACC,MAAM,EAAE,OAAO,CAAC,aAAa;YAC7B,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,GAAG,MAAM;SACT,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function txStatusCommand(hash: string, opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/commands/chain/transaction.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCtF"}
@@ -0,0 +1,31 @@
1
+ import { getPublicClient } from "../../services/chain/client.js";
2
+ import { getChainConfig } from "../../services/chain/constants.js";
3
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
4
+ export async function txStatusCommand(hash, opts) {
5
+ try {
6
+ const globalOpts = opts;
7
+ const chainName = globalOpts.chain || "base";
8
+ const chain = getChainConfig(chainName);
9
+ const publicClient = getPublicClient(chain);
10
+ const txHash = hash;
11
+ const receipt = await withSpinner(`Fetching transaction status for ${hash}...`, async () => {
12
+ return publicClient.waitForTransactionReceipt({ hash: txHash });
13
+ }, opts);
14
+ const explorerLink = chain.viemChain.blockExplorers?.default.url
15
+ ? `${chain.viemChain.blockExplorers.default.url}/tx/${hash}`
16
+ : "N/A";
17
+ outputResult({
18
+ status: receipt.status,
19
+ blockNumber: receipt.blockNumber.toString(),
20
+ gasUsed: receipt.gasUsed.toString(),
21
+ from: receipt.from,
22
+ to: receipt.to,
23
+ explorerLink,
24
+ chain: chain.name,
25
+ }, opts);
26
+ }
27
+ catch (error) {
28
+ outputError(error, opts);
29
+ }
30
+ }
31
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/commands/chain/transaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAAmB;IACtE,IAAI,CAAC;QACJ,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,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAY,CAAC;QAE5B,MAAM,OAAO,GAAG,MAAM,WAAW,CAChC,mCAAmC,IAAI,KAAK,EAC5C,KAAK,IAAI,EAAE;YACV,OAAO,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG;YAC/D,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,IAAI,EAAE;YAC5D,CAAC,CAAC,KAAK,CAAC;QAET,YAAY,CACX;YACC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE;YAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;YACnC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,YAAY;YACZ,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"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function statusCommand(opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/trade/status.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCtE"}
@@ -0,0 +1,32 @@
1
+ import { loadSession } from "../../services/auth/session.js";
2
+ import { checkHealth } from "../../services/fibrous/health.js";
3
+ import { getChainConfig } from "../../services/chain/constants.js";
4
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
5
+ export async function statusCommand(opts) {
6
+ try {
7
+ const globalOpts = opts;
8
+ const chainName = globalOpts.chain || "base";
9
+ const chain = getChainConfig(chainName);
10
+ const session = loadSession();
11
+ const fibrousHealth = await withSpinner("Checking Fibrous API...", async () => {
12
+ try {
13
+ const health = await checkHealth(chain);
14
+ return { ok: true, message: health.message };
15
+ }
16
+ catch {
17
+ return { ok: false, message: "unreachable" };
18
+ }
19
+ }, opts);
20
+ outputResult({
21
+ chain: chain.name,
22
+ chainId: chain.id,
23
+ authenticated: !!session,
24
+ wallet: session?.walletAddress ?? null,
25
+ fibrous: fibrousHealth,
26
+ }, opts);
27
+ }
28
+ catch (error) {
29
+ outputError(error, opts);
30
+ }
31
+ }
32
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/trade/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmB;IACtD,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,IAAqC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,IAAI,MAAM,CAAC;QAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAE9B,MAAM,aAAa,GAAG,MAAM,WAAW,CACtC,yBAAyB,EACzB,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;gBACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;YAC9C,CAAC;QACF,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,YAAY,CACX;YACC,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,aAAa,EAAE,CAAC,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,EAAE,aAAa,IAAI,IAAI;YACtC,OAAO,EAAE,aAAa;SACtB,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ interface TradeOptions extends OutputOptions {
3
+ slippage: number;
4
+ approveMax?: boolean;
5
+ }
6
+ export declare function tradeCommand(amount: string, from: string, to: string, opts: TradeOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=swap.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,74 @@
1
+ import { requireSession } from "../../services/auth/session.js";
2
+ import { getPrivyClient } from "../../services/privy/client.js";
3
+ import { getWalletClient, getPublicClient } from "../../services/chain/client.js";
4
+ import { getChainConfig } from "../../services/chain/constants.js";
5
+ import { getAllowance, encodeApprove } from "../../services/chain/erc20.js";
6
+ import { resolveToken } from "../../services/fibrous/tokens.js";
7
+ import { getRouteAndCallData, encodeSwapCalldata } from "../../services/fibrous/route.js";
8
+ import { DEFAULT_SLIPPAGE } from "../../lib/config.js";
9
+ import { validateAmount } from "../../lib/validation.js";
10
+ import { parseAmount, formatAmount } from "../../lib/parseAmount.js";
11
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
12
+ export async function tradeCommand(amount, from, to, opts) {
13
+ try {
14
+ validateAmount(amount);
15
+ const globalOpts = opts;
16
+ const chainName = globalOpts.chain || "base";
17
+ const chain = getChainConfig(chainName);
18
+ const session = requireSession();
19
+ const privy = getPrivyClient();
20
+ const wallet = session.walletAddress;
21
+ const [tokenIn, tokenOut] = await withSpinner(`Resolving tokens on ${chain.name}...`, async () => Promise.all([resolveToken(from, chain), resolveToken(to, chain)]), opts);
22
+ const amountBaseUnits = parseAmount(amount, tokenIn.decimals);
23
+ const isNativeInput = tokenIn.address.toLowerCase() === chain.nativeTokenAddress.toLowerCase();
24
+ const routeData = await withSpinner("Finding best route...", async () => {
25
+ return getRouteAndCallData({
26
+ amount: amountBaseUnits.toString(),
27
+ tokenInAddress: tokenIn.address,
28
+ tokenOutAddress: tokenOut.address,
29
+ slippage: opts.slippage ?? DEFAULT_SLIPPAGE,
30
+ destination: wallet,
31
+ }, chain);
32
+ }, opts);
33
+ const routerAddress = routeData.router_address;
34
+ const walletClient = getWalletClient(privy, session, chain);
35
+ if (!isNativeInput) {
36
+ const currentAllowance = await getAllowance(getPublicClient(chain), tokenIn.address, wallet, routerAddress);
37
+ if (currentAllowance < amountBaseUnits) {
38
+ await withSpinner("Approving token spend...", async () => {
39
+ const amountToApprove = opts.approveMax
40
+ ? 115792089237316195423570985008687907853269984665640564039457584007913129639935n // Max Uint256
41
+ : amountBaseUnits;
42
+ const approveData = encodeApprove(routerAddress, amountToApprove);
43
+ return walletClient.sendTransaction({
44
+ to: tokenIn.address,
45
+ data: approveData,
46
+ value: 0n,
47
+ });
48
+ }, opts);
49
+ }
50
+ }
51
+ const hash = await withSpinner(`Swapping ${amount} ${tokenIn.symbol} → ${tokenOut.symbol}...`, async () => {
52
+ const swapData = encodeSwapCalldata(routeData.calldata, chain);
53
+ return walletClient.sendTransaction({
54
+ to: routerAddress,
55
+ data: swapData,
56
+ value: isNativeInput ? amountBaseUnits : 0n,
57
+ });
58
+ }, opts);
59
+ const outputAmount = formatAmount(BigInt(routeData.route.outputAmount), tokenOut.decimals);
60
+ outputResult({
61
+ txHash: hash,
62
+ amountIn: amount,
63
+ amountOut: outputAmount,
64
+ tokenIn: tokenIn.symbol,
65
+ tokenOut: tokenOut.symbol,
66
+ router: routerAddress,
67
+ chain: chain.name,
68
+ }, opts);
69
+ }
70
+ catch (error) {
71
+ outputError(error, opts);
72
+ }
73
+ }
74
+ //# sourceMappingURL=swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../../src/commands/trade/swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function addressCommand(opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../src/commands/wallet/address.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpF,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE"}
@@ -0,0 +1,15 @@
1
+ import { requireSession } from "../../services/auth/session.js";
2
+ import { outputResult, outputError } from "../../lib/format.js";
3
+ export async function addressCommand(opts) {
4
+ try {
5
+ const session = requireSession();
6
+ outputResult({
7
+ address: session.walletAddress,
8
+ walletId: session.walletId,
9
+ }, opts);
10
+ }
11
+ catch (error) {
12
+ outputError(error, opts);
13
+ }
14
+ }
15
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../../src/commands/wallet/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAmB;IACvD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;QAEjC,YAAY,CACX;YACC,OAAO,EAAE,OAAO,CAAC,aAAa;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC1B,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function balanceCommand(opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=balance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../../src/commands/wallet/balance.ts"],"names":[],"mappings":"AAOA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DvE"}
@@ -0,0 +1,53 @@
1
+ import { loadSession } from "../../services/auth/session.js";
2
+ import { getPublicClient } from "../../services/chain/client.js";
3
+ import { getChainConfig } from "../../services/chain/constants.js";
4
+ import { getTokens } from "../../services/fibrous/tokens.js";
5
+ import { getBalances } from "../../services/fibrous/balances.js";
6
+ import { formatAmount } from "../../lib/parseAmount.js";
7
+ import { outputResult, outputError, withSpinner } from "../../lib/format.js";
8
+ export async function balanceCommand(opts) {
9
+ try {
10
+ const session = loadSession();
11
+ if (!session) {
12
+ outputError("No active session. Run 'fibx auth login <email>' first.", opts);
13
+ return;
14
+ }
15
+ const globalOpts = opts;
16
+ const chainName = globalOpts.chain || "base";
17
+ const chainConfig = getChainConfig(chainName);
18
+ const client = getPublicClient(chainConfig);
19
+ const wallet = session.walletAddress;
20
+ const tokensMap = await getTokens(chainConfig);
21
+ const tokenList = Object.values(tokensMap);
22
+ const balances = await withSpinner(`Fetching balances on ${chainConfig.name}...`, async () => {
23
+ const [ethBalance, tokenBalances] = await Promise.all([
24
+ client.getBalance({ address: wallet }),
25
+ getBalances(tokenList, wallet, chainConfig),
26
+ ]);
27
+ return {
28
+ eth: formatAmount(ethBalance, 18),
29
+ tokens: tokenBalances,
30
+ };
31
+ }, opts);
32
+ const result = {};
33
+ result["ETH"] = balances.eth;
34
+ for (const item of balances.tokens) {
35
+ const balanceVal = parseFloat(item.balance);
36
+ if (balanceVal > 0) {
37
+ const tokenAddr = item.token.address.toLowerCase();
38
+ const token = tokenList.find((t) => t.address.toLowerCase() === tokenAddr);
39
+ const symbol = token ? token.symbol : tokenAddr;
40
+ result[symbol] = item.balance;
41
+ }
42
+ }
43
+ outputResult({
44
+ wallet: session.walletAddress,
45
+ chain: chainConfig.name,
46
+ ...result,
47
+ }, opts);
48
+ }
49
+ catch (error) {
50
+ outputError(error, opts);
51
+ }
52
+ }
53
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/commands/wallet/balance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAmB;IACvD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,WAAW,CAAC,yDAAyD,EAAE,IAAI,CAAC,CAAC;YAC7E,OAAO;QACR,CAAC;QAED,MAAM,UAAU,GAAG,IAAqC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,IAAI,MAAM,CAAC;QAC7C,MAAM,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,aAAwB,CAAC;QAEhD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,MAAM,WAAW,CACjC,wBAAwB,WAAW,CAAC,IAAI,KAAK,EAC7C,KAAK,IAAI,EAAE;YACV,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACrD,MAAM,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBACtC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;aAC3C,CAAC,CAAC;YAEH,OAAO;gBACN,GAAG,EAAE,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;gBACjC,MAAM,EAAE,aAAa;aACrB,CAAC;QACH,CAAC,EACD,IAAI,CACJ,CAAC;QAEF,MAAM,MAAM,GAA2B,EAAE,CAAC;QAE1C,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;QAE7B,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpC,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;gBAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;gBAEhD,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC/B,CAAC;QACF,CAAC;QAED,YAAY,CACX;YACC,MAAM,EAAE,OAAO,CAAC,aAAa;YAC7B,KAAK,EAAE,WAAW,CAAC,IAAI;YACvB,GAAG,MAAM;SACT,EACD,IAAI,CACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type OutputOptions } from "../../lib/format.js";
2
+ export declare function walletsCommand(email: string, opts: OutputOptions): Promise<void>;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/wallet/list.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUjG,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CtF"}