openbroker 1.0.68 → 1.0.70
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/SKILL.md +78 -7
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/scripts/core/client.ts +28 -6
- package/scripts/info/account.ts +7 -0
- package/scripts/info/positions.ts +4 -0
- package/scripts/plugin/tools.ts +5 -0
- package/scripts/setup/onboard.ts +71 -20
package/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Hyperliquid trading plugin with background position monitoring and
|
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Requires Node.js 22+, network access to api.hyperliquid.xyz
|
|
6
6
|
homepage: https://www.npmjs.com/package/openbroker
|
|
7
|
-
metadata: {"author": "monemetrics", "version": "1.0.
|
|
7
|
+
metadata: {"author": "monemetrics", "version": "1.0.70", "openclaw": {"requires": {"bins": ["openbroker"], "env": ["HYPERLIQUID_PRIVATE_KEY"]}, "primaryEnv": "HYPERLIQUID_PRIVATE_KEY", "install": [{"id": "node", "kind": "node", "package": "openbroker", "bins": ["openbroker"], "label": "Install openbroker (npm)"}]}}
|
|
8
8
|
allowed-tools: ob_account ob_positions ob_funding ob_markets ob_search ob_spot ob_fills ob_orders ob_order_status ob_fees ob_candles ob_funding_history ob_trades ob_rate_limit ob_funding_scan ob_buy ob_sell ob_limit ob_trigger ob_tpsl ob_cancel ob_twap ob_bracket ob_chase ob_watcher_status ob_auto_run ob_auto_stop ob_auto_list Bash(openbroker:*)
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -732,15 +732,86 @@ api.on('margin_warning', async ({ marginUsedPct, equity }) => {
|
|
|
732
732
|
|
|
733
733
|
### Client Methods Available
|
|
734
734
|
|
|
735
|
-
The `api.client` object exposes the full
|
|
735
|
+
The `api.client` object exposes the full `HyperliquidClient`. All `coin` params accept HIP-3 prefixed tickers (e.g. `xyz:CL`). Optional `user` params default to the configured wallet address.
|
|
736
|
+
|
|
737
|
+
#### Trading
|
|
738
|
+
|
|
739
|
+
| Method | Description |
|
|
740
|
+
|--------|-------------|
|
|
741
|
+
| `marketOrder(coin, isBuy, size, slippageBps?, leverage?)` | Market order via IOC limit at mid ± slippage. Returns `OrderResponse` |
|
|
742
|
+
| `limitOrder(coin, isBuy, size, price, tif?, reduceOnly?, leverage?)` | Limit order. `tif`: `'Gtc'` (default), `'Ioc'`, `'Alo'`. Returns `OrderResponse` |
|
|
743
|
+
| `triggerOrder(coin, isBuy, size, triggerPrice, limitPrice, tpsl, reduceOnly?, leverage?)` | Trigger (conditional) order. `tpsl`: `'tp'` or `'sl'`. Activates when price hits `triggerPrice`, then fills as limit at `limitPrice`. Returns `OrderResponse` |
|
|
744
|
+
| `stopLoss(coin, isBuy, size, triggerPrice, slippageBps?)` | Stop loss shortcut. Sets limit price with slippage buffer (default 100 bps / 1%) to ensure fill. `reduceOnly` is always true. Returns `OrderResponse` |
|
|
745
|
+
| `takeProfit(coin, isBuy, size, triggerPrice)` | Take profit shortcut. Limit price = trigger price (favorable direction). `reduceOnly` is always true. Returns `OrderResponse` |
|
|
746
|
+
| `cancel(coin, oid)` | Cancel a single order by numeric OID. Returns `CancelResponse` |
|
|
747
|
+
| `cancelAll(coin?)` | Cancel all open orders. If `coin` is provided, only cancels orders for that asset. Returns `CancelResponse[]` |
|
|
748
|
+
| `order(coin, isBuy, size, price, orderType, reduceOnly?, includeBuilder?, leverage?)` | Low-level order placement. `orderType`: `{ limit: { tif: 'Gtc' | 'Ioc' | 'Alo' } }`. Automatically injects builder fee, rounds price/size, and handles HIP-3 margin setup. Returns `OrderResponse` |
|
|
749
|
+
|
|
750
|
+
#### Market Data
|
|
751
|
+
|
|
752
|
+
| Method | Returns |
|
|
753
|
+
|--------|---------|
|
|
754
|
+
| `getAllMids()` | `Record<string, string>` — mid prices for all assets (main + HIP-3). Key = coin name, value = price string |
|
|
755
|
+
| `getMetaAndAssetCtxs()` | `MetaAndAssetCtxs` — market metadata (universe of assets with `szDecimals`, `maxLeverage`) and asset contexts (funding, open interest, volume, mark/oracle prices) |
|
|
756
|
+
| `getL2Book(coin)` | `{ bids, asks, bestBid, bestAsk, midPrice, spread, spreadBps }` — L2 order book with computed spread |
|
|
757
|
+
| `getRecentTrades(coin)` | `Array<{ coin, side, px, sz, time, hash, tid }>` — recent trade tape. `side`: `'B'` (buy) or `'A'` (sell) |
|
|
758
|
+
| `getCandleSnapshot(coin, interval, startTime, endTime?)` | `Array<{ t, T, s, i, o, c, h, l, v, n }>` — OHLCV candles. `interval`: `'1m'`, `'5m'`, `'15m'`, `'1h'`, `'4h'`, `'1d'`. Times are Unix ms |
|
|
759
|
+
| `getFundingHistory(coin, startTime, endTime?)` | `Array<{ coin, fundingRate, premium, time }>` — historical hourly funding rates |
|
|
760
|
+
| `getPredictedFundings()` | `Array<[coin, Array<[venue, { fundingRate, nextFundingTime }]>]>` — predicted funding rates across all venues |
|
|
761
|
+
| `getPerpDexs()` | `Array<{ name, fullName, deployer } | null>` — list of perp DEXs. Index 0 is `null` (main), rest are HIP-3 |
|
|
762
|
+
| `getAllPerpMetas()` | `Array<{ dexName, meta, assetCtxs }>` — metadata + contexts for every perp DEX (main + all HIP-3) |
|
|
763
|
+
| `getSpotMeta()` | `{ tokens, universe }` — spot market metadata (token info, trading pairs) |
|
|
764
|
+
| `getSpotMetaAndAssetCtxs()` | `{ meta, assetCtxs }` — spot metadata + price/volume contexts |
|
|
765
|
+
| `getTokenDetails(tokenId)` | Token details: supply, deployer, prices. Returns `null` if not found |
|
|
766
|
+
|
|
767
|
+
#### Account
|
|
768
|
+
|
|
769
|
+
| Method | Returns |
|
|
770
|
+
|--------|---------|
|
|
771
|
+
| `getUserStateAll(user?)` | `ClearinghouseState` — full account state across all dexes: `marginSummary` (accountValue, totalMarginUsed, withdrawable), `crossMarginSummary`, and `assetPositions[]` (each with `position.coin`, `.szi`, `.entryPx`, `.unrealizedPnl`, `.positionValue`, `.leverage`, `.marginUsed`, `.liquidationPx`) |
|
|
772
|
+
| `getUserState(user?, dex?)` | `ClearinghouseState` — account state for a single dex (omit `dex` for main perps) |
|
|
773
|
+
| `getOpenOrders(user?)` | `OpenOrder[]` — all open orders across all dexes. Each: `{ coin, side, limitPx, sz, oid, timestamp, orderType }` |
|
|
774
|
+
| `getUserFills(user?, aggregateByTime?)` | `Array<{ coin, px, sz, side, time, closedPnl, fee, oid, tid, crossed, builderFee }>` — trade fill history. `side`: `'B'` (buy) or `'A'` (sell) |
|
|
775
|
+
| `getHistoricalOrders(user?)` | `Array<{ order: { coin, side, limitPx, sz, origSz, oid, timestamp, orderType, tif, triggerCondition, triggerPx, isTrigger, isPositionTpsl, reduceOnly }, status, statusTimestamp }>` — all orders (filled, cancelled, etc.) |
|
|
776
|
+
| `getOrderStatus(oid, user?)` | `{ status, order? }` — status of a specific order by numeric OID or string CLOID |
|
|
777
|
+
| `getUserFunding(user?, startTime?, endTime?)` | `Array<{ time, hash, delta: { coin, usdc, szi, fundingRate } }>` — funding payments received/paid |
|
|
778
|
+
| `getUserFees(user?)` | `{ dailyUserVlm, feeSchedule, userCrossRate, userAddRate, activeReferralDiscount, activeStakingDiscount }` — fee tier, rates, and volume |
|
|
779
|
+
| `getUserRateLimit(user?)` | `{ cumVlm, nRequestsUsed, nRequestsCap, nRequestsSurplus }` — API rate limit status |
|
|
780
|
+
| `getSpotBalances(user?)` | `{ balances: Array<{ coin, token, hold, total, entryNtl }> }` — spot token balances |
|
|
781
|
+
| `getSubAccounts(user?)` | `Array<{ subAccountUser, name }>` — sub-accounts for a master wallet |
|
|
782
|
+
| `getAccountMode(user?)` | `string` — account abstraction mode: `'standard'`, `'unified'`, `'portfolio'`, or `'dexAbstraction'` |
|
|
783
|
+
| `isUnifiedAccount(user?)` | `boolean` — `true` if unified or portfolio margin (shared USDC across dexes) |
|
|
784
|
+
|
|
785
|
+
#### Leverage & Config
|
|
786
|
+
|
|
787
|
+
| Method | Description |
|
|
788
|
+
|--------|-------------|
|
|
789
|
+
| `updateLeverage(coin, leverage, isCross?)` | Set leverage. `isCross` defaults to `true` (cross margin). HIP-3 assets are forced to isolated and clamped to their max leverage |
|
|
790
|
+
| `approveBuilderFee(maxFeeRate?, builder?)` | Approve builder fee (must be called from main wallet, not API wallet). Default rate: `'0.1%'` |
|
|
791
|
+
| `getMaxBuilderFee(user?, builder?)` | Check approved builder fee. Returns fee string (e.g. `'0.01%'`) or `null` if not approved |
|
|
792
|
+
|
|
793
|
+
#### Utility Properties
|
|
736
794
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
795
|
+
| Property / Method | Description |
|
|
796
|
+
|-------------------|-------------|
|
|
797
|
+
| `getAssetIndex(coin)` | Get numeric asset index for a coin (used internally for order wire) |
|
|
798
|
+
| `getSzDecimals(coin)` | Get size decimal precision for a coin |
|
|
799
|
+
| `isHip3(coin)` | Check if a coin is a HIP-3 asset |
|
|
800
|
+
| `getCoinDex(coin)` | Get dex name for a coin (`null` for main perps) |
|
|
801
|
+
| `getAllAssetNames()` | Get all known asset names (main + HIP-3) |
|
|
802
|
+
| `getHip3AssetNames()` | Get only HIP-3 asset names |
|
|
803
|
+
| `invalidateMetaCache()` | Force refresh of market metadata on next call |
|
|
740
804
|
|
|
741
|
-
|
|
805
|
+
#### Utility Functions (`api.utils`)
|
|
742
806
|
|
|
743
|
-
|
|
807
|
+
| Function | Description |
|
|
808
|
+
|----------|-------------|
|
|
809
|
+
| `roundPrice(price, szDecimals, isSpot?)` | Round price to 5 significant figures (max 6 decimals perp, 8 spot) |
|
|
810
|
+
| `roundSize(size, szDecimals)` | Round size to asset-specific decimal precision |
|
|
811
|
+
| `sleep(ms)` | Promise-based delay |
|
|
812
|
+
| `normalizeCoin(coin)` | Normalize coin name (uppercase, trim whitespace) |
|
|
813
|
+
| `formatUsd(amount)` | Format number as USD string (e.g. `$1,234.56`) |
|
|
814
|
+
| `annualizeFundingRate(hourlyRate)` | Convert hourly funding rate to annualized percentage |
|
|
744
815
|
|
|
745
816
|
### Example: Price Breakout
|
|
746
817
|
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/scripts/core/client.ts
CHANGED
|
@@ -1126,7 +1126,18 @@ export class HyperliquidClient {
|
|
|
1126
1126
|
const params: { user: string; dex?: string } = { user: user ?? this.address };
|
|
1127
1127
|
if (dex !== undefined) params.dex = dex;
|
|
1128
1128
|
const response = await this.info.clearinghouseState(params as any);
|
|
1129
|
-
|
|
1129
|
+
|
|
1130
|
+
// The SDK response has `withdrawable` as a top-level field, not inside
|
|
1131
|
+
// marginSummary/crossMarginSummary. Copy it into our MarginSummary shape.
|
|
1132
|
+
const state = response as unknown as ClearinghouseState;
|
|
1133
|
+
const withdrawable = (response as any).withdrawable ?? '0';
|
|
1134
|
+
if (state.marginSummary) {
|
|
1135
|
+
state.marginSummary.withdrawable = withdrawable;
|
|
1136
|
+
}
|
|
1137
|
+
if (state.crossMarginSummary) {
|
|
1138
|
+
state.crossMarginSummary.withdrawable = withdrawable;
|
|
1139
|
+
}
|
|
1140
|
+
return state;
|
|
1130
1141
|
}
|
|
1131
1142
|
|
|
1132
1143
|
/**
|
|
@@ -1142,6 +1153,7 @@ export class HyperliquidClient {
|
|
|
1142
1153
|
const dexs = await this.getPerpDexs();
|
|
1143
1154
|
|
|
1144
1155
|
// Collect positions from all HIP-3 dexes
|
|
1156
|
+
let hip3Errors = 0;
|
|
1145
1157
|
for (let i = 1; i < dexs.length; i++) {
|
|
1146
1158
|
const dex = dexs[i];
|
|
1147
1159
|
if (!dex) continue;
|
|
@@ -1156,22 +1168,32 @@ export class HyperliquidClient {
|
|
|
1156
1168
|
if (!unified) {
|
|
1157
1169
|
const dexMargin = dexState.marginSummary;
|
|
1158
1170
|
if (dexMargin) {
|
|
1171
|
+
const safeAdd = (a: string | undefined, b: string | undefined): string => {
|
|
1172
|
+
const va = parseFloat(a ?? '0') || 0;
|
|
1173
|
+
const vb = parseFloat(b ?? '0') || 0;
|
|
1174
|
+
return String(va + vb);
|
|
1175
|
+
};
|
|
1159
1176
|
const addToSummary = (summary: { accountValue: string; totalNtlPos: string; totalRawUsd: string; totalMarginUsed: string; withdrawable: string }) => {
|
|
1160
|
-
summary.accountValue =
|
|
1161
|
-
summary.totalNtlPos =
|
|
1162
|
-
summary.totalRawUsd =
|
|
1163
|
-
summary.totalMarginUsed =
|
|
1164
|
-
summary.withdrawable =
|
|
1177
|
+
summary.accountValue = safeAdd(summary.accountValue, dexMargin.accountValue);
|
|
1178
|
+
summary.totalNtlPos = safeAdd(summary.totalNtlPos, dexMargin.totalNtlPos);
|
|
1179
|
+
summary.totalRawUsd = safeAdd(summary.totalRawUsd, dexMargin.totalRawUsd);
|
|
1180
|
+
summary.totalMarginUsed = safeAdd(summary.totalMarginUsed, dexMargin.totalMarginUsed);
|
|
1181
|
+
summary.withdrawable = safeAdd(summary.withdrawable, dexMargin.withdrawable);
|
|
1165
1182
|
};
|
|
1166
1183
|
addToSummary(mainState.marginSummary);
|
|
1167
1184
|
addToSummary(mainState.crossMarginSummary);
|
|
1168
1185
|
}
|
|
1169
1186
|
}
|
|
1170
1187
|
} catch (err) {
|
|
1188
|
+
hip3Errors++;
|
|
1171
1189
|
this.log(`Failed to fetch state for dex ${dex.name}:`, err instanceof Error ? err.message : String(err));
|
|
1172
1190
|
}
|
|
1173
1191
|
}
|
|
1174
1192
|
|
|
1193
|
+
if (hip3Errors > 0) {
|
|
1194
|
+
this.log(`Warning: ${hip3Errors} HIP-3 dex queries failed — some positions may be missing. Use --verbose for details.`);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1175
1197
|
// For unified accounts: equity is the USDC balance from spot clearinghouse
|
|
1176
1198
|
if (unified) {
|
|
1177
1199
|
try {
|
package/scripts/info/account.ts
CHANGED
|
@@ -109,6 +109,13 @@ async function main() {
|
|
|
109
109
|
console.log(`Builder Approved: ❌ No`);
|
|
110
110
|
console.log(`\n⚠️ Run: npx tsx scripts/setup/approve-builder.ts`);
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
// Warn if API wallet setup looks misconfigured
|
|
114
|
+
if (!client.isApiWallet && accountValue === 0 && positions.length === 0) {
|
|
115
|
+
console.log('\n⚠️ No positions and $0 equity.');
|
|
116
|
+
console.log(' If this account is traded via an API wallet, set HYPERLIQUID_ACCOUNT_ADDRESS');
|
|
117
|
+
console.log(' in ~/.openbroker/.env to the master account address (the wallet that holds funds).');
|
|
118
|
+
}
|
|
112
119
|
console.log('');
|
|
113
120
|
|
|
114
121
|
console.log('Margin Summary');
|
|
@@ -71,6 +71,10 @@ async function main() {
|
|
|
71
71
|
|
|
72
72
|
if (positions.length === 0) {
|
|
73
73
|
console.log(filterCoin ? `No position in ${filterCoin}` : 'No open positions');
|
|
74
|
+
if (!filterCoin && !client.isApiWallet) {
|
|
75
|
+
console.log('\n⚠️ If this account is traded via an API wallet, set HYPERLIQUID_ACCOUNT_ADDRESS');
|
|
76
|
+
console.log(' in ~/.openbroker/.env to the master account address.');
|
|
77
|
+
}
|
|
74
78
|
return;
|
|
75
79
|
}
|
|
76
80
|
|
package/scripts/plugin/tools.ts
CHANGED
|
@@ -89,6 +89,11 @@ export function createTools(watcherOrCtx: PositionWatcher | null | ToolsContext)
|
|
|
89
89
|
}));
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// Warn if likely misconfigured API wallet (querying the API wallet address instead of master)
|
|
93
|
+
if (!client.isApiWallet && accountValue === 0 && state.assetPositions.filter(ap => parseFloat(ap.position.szi) !== 0).length === 0) {
|
|
94
|
+
result.warning = 'No positions and $0 equity. If using an API wallet, ensure HYPERLIQUID_ACCOUNT_ADDRESS is set to the master account address in ~/.openbroker/.env or plugin config.';
|
|
95
|
+
}
|
|
96
|
+
|
|
92
97
|
return json(result);
|
|
93
98
|
},
|
|
94
99
|
},
|
package/scripts/setup/onboard.ts
CHANGED
|
@@ -231,34 +231,85 @@ async function main(): Promise<OnboardResult> {
|
|
|
231
231
|
|
|
232
232
|
// Check if config already exists
|
|
233
233
|
if (fs.existsSync(CONFIG_PATH)) {
|
|
234
|
-
console.log('⚠️ Config already exists!');
|
|
235
|
-
console.log(` Location: ${CONFIG_PATH}\n`);
|
|
236
|
-
|
|
237
|
-
// Read existing config and show wallet address
|
|
238
234
|
const envContent = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
239
235
|
const keyMatch = envContent.match(/HYPERLIQUID_PRIVATE_KEY=0x([a-fA-F0-9]{64})/);
|
|
240
236
|
|
|
241
|
-
if (keyMatch) {
|
|
242
|
-
const existingKey = `0x${keyMatch[1]}` as `0x${string}`;
|
|
243
|
-
const account = privateKeyToAccount(existingKey);
|
|
244
|
-
console.log('Current Configuration');
|
|
245
|
-
console.log('---------------------');
|
|
246
|
-
console.log(`Wallet Address: ${account.address}`);
|
|
247
|
-
console.log(`Config File: ${CONFIG_PATH}`);
|
|
248
|
-
console.log(`\nTo reconfigure, delete the config file first:`);
|
|
249
|
-
console.log(` rm ${CONFIG_PATH}`);
|
|
250
|
-
console.log(`\nTo fund this wallet, send USDC on Arbitrum, then deposit at:`);
|
|
251
|
-
console.log(` https://app.hyperliquid.xyz/`);
|
|
252
|
-
|
|
237
|
+
if (!keyMatch) {
|
|
253
238
|
return {
|
|
254
|
-
success:
|
|
255
|
-
|
|
239
|
+
success: false,
|
|
240
|
+
error: 'Invalid config file - missing or malformed private key',
|
|
256
241
|
};
|
|
257
242
|
}
|
|
258
243
|
|
|
244
|
+
const existingKey = `0x${keyMatch[1]}` as `0x${string}`;
|
|
245
|
+
const account = privateKeyToAccount(existingKey);
|
|
246
|
+
|
|
247
|
+
// Check if this is an incomplete API wallet setup (HYPERLIQUID_ACCOUNT_ADDRESS missing or commented out)
|
|
248
|
+
const hasAccountAddress = /^HYPERLIQUID_ACCOUNT_ADDRESS=0x[a-fA-F0-9]{40}/m.test(envContent);
|
|
249
|
+
const isIncompleteApiWallet = envContent.includes('INCOMPLETE') || envContent.includes('# HYPERLIQUID_ACCOUNT_ADDRESS');
|
|
250
|
+
|
|
251
|
+
if (!hasAccountAddress && isIncompleteApiWallet) {
|
|
252
|
+
console.log('⚠️ Incomplete API wallet setup detected!');
|
|
253
|
+
console.log(` API Wallet: ${account.address}`);
|
|
254
|
+
console.log(` Master account address is missing — re-polling for approval...\n`);
|
|
255
|
+
|
|
256
|
+
const approveUrl = `${OPENBROKER_URL}/approve?agent=${account.address}`;
|
|
257
|
+
console.log(` If not yet approved, visit: ${approveUrl}\n`);
|
|
258
|
+
|
|
259
|
+
const masterAddress = await pollForApproval(account.address);
|
|
260
|
+
|
|
261
|
+
if (masterAddress) {
|
|
262
|
+
console.log(`\n✅ Master wallet detected: ${masterAddress}`);
|
|
263
|
+
|
|
264
|
+
// Verify builder fee on-chain
|
|
265
|
+
console.log(' Verifying builder fee approval...');
|
|
266
|
+
const feeApproved = await verifyBuilderFee(masterAddress);
|
|
267
|
+
if (feeApproved) {
|
|
268
|
+
console.log(' ✅ Builder fee: approved on-chain');
|
|
269
|
+
} else {
|
|
270
|
+
console.log(' ⚠️ Builder fee not yet confirmed on-chain (may take a moment)');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Save complete config
|
|
274
|
+
const completeEnv = buildApiWalletEnvContent(existingKey, masterAddress);
|
|
275
|
+
fs.writeFileSync(CONFIG_PATH, completeEnv, { mode: 0o600 });
|
|
276
|
+
|
|
277
|
+
console.log(`\n✅ Config updated: ${CONFIG_PATH}`);
|
|
278
|
+
console.log(` API Wallet: ${account.address}`);
|
|
279
|
+
console.log(` Master Account: ${masterAddress}`);
|
|
280
|
+
console.log('\n Start trading: openbroker account');
|
|
281
|
+
|
|
282
|
+
return { success: true, walletAddress: account.address };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
console.log('\n⚠️ Approval still not completed.');
|
|
286
|
+
console.log(` Visit: ${approveUrl}`);
|
|
287
|
+
console.log(' Then re-run: openbroker setup\n');
|
|
288
|
+
return { success: false, error: 'Approval not completed' };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Config exists and is complete
|
|
292
|
+
console.log('⚠️ Config already exists!');
|
|
293
|
+
console.log(` Location: ${CONFIG_PATH}\n`);
|
|
294
|
+
console.log('Current Configuration');
|
|
295
|
+
console.log('---------------------');
|
|
296
|
+
console.log(`Wallet Address: ${account.address}`);
|
|
297
|
+
if (hasAccountAddress) {
|
|
298
|
+
const addrMatch = envContent.match(/HYPERLIQUID_ACCOUNT_ADDRESS=(0x[a-fA-F0-9]+)/);
|
|
299
|
+
if (addrMatch) {
|
|
300
|
+
console.log(`Master Account: ${addrMatch[1]}`);
|
|
301
|
+
console.log(`Wallet Type: API Wallet`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
console.log(`Config File: ${CONFIG_PATH}`);
|
|
305
|
+
console.log(`\nTo reconfigure, delete the config file first:`);
|
|
306
|
+
console.log(` rm ${CONFIG_PATH}`);
|
|
307
|
+
console.log(`\nTo fund this wallet, send USDC on Arbitrum, then deposit at:`);
|
|
308
|
+
console.log(` https://app.hyperliquid.xyz/`);
|
|
309
|
+
|
|
259
310
|
return {
|
|
260
|
-
success:
|
|
261
|
-
|
|
311
|
+
success: true,
|
|
312
|
+
walletAddress: account.address,
|
|
262
313
|
};
|
|
263
314
|
}
|
|
264
315
|
|