@agentgrant.cash/cli 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/agent.d.ts +8 -0
- package/dist/cli/commands/auth.d.ts +20 -0
- package/dist/cli/commands/meta.d.ts +2 -0
- package/dist/cli/commands/money.d.ts +2 -0
- package/dist/cli/commands/onboard.d.ts +2 -0
- package/dist/cli/commands/portfolio.d.ts +14 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/money-helpers.d.ts +100 -0
- package/dist/cli/perfolio-commands/account.d.ts +35 -0
- package/dist/cli/perfolio-commands/borrow.d.ts +2 -0
- package/dist/cli/perfolio-commands/discover.d.ts +2 -0
- package/dist/cli/perfolio-commands/earn.d.ts +9 -0
- package/dist/cli/perfolio-commands/hyperliquid.d.ts +32 -0
- package/dist/cli/perfolio-commands/loans.d.ts +8 -0
- package/dist/cli/perfolio-commands/market.d.ts +11 -0
- package/dist/cli/perfolio-commands/polymarket.d.ts +29 -0
- package/dist/cli/perfolio-commands/session.d.ts +2 -0
- package/dist/cli/perfolio-commands/spending.d.ts +14 -0
- package/dist/cli/perfolio-commands/trade.d.ts +2 -0
- package/dist/cli/perfolio-commands/tx.d.ts +2 -0
- package/dist/lib/agent-client.d.ts +78 -0
- package/dist/lib/amounts.d.ts +14 -0
- package/dist/lib/assets.d.ts +12 -0
- package/dist/lib/auth-session.d.ts +57 -0
- package/dist/lib/client.d.ts +295 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/context.d.ts +21 -0
- package/dist/lib/currency.d.ts +70 -0
- package/dist/lib/device.d.ts +78 -0
- package/dist/lib/dotenv.d.ts +12 -0
- package/dist/lib/errors.d.ts +33 -0
- package/dist/lib/format.d.ts +5 -0
- package/dist/lib/index.d.ts +22 -0
- package/dist/lib/kyc-status.d.ts +10 -0
- package/dist/lib/money-client.d.ts +66 -0
- package/dist/lib/money-input.d.ts +97 -0
- package/dist/lib/output.d.ts +22 -0
- package/dist/lib/polygon-balance.d.ts +43 -0
- package/dist/lib/portfolio-format.d.ts +79 -0
- package/dist/lib/relay.d.ts +8 -0
- package/dist/lib/sign.d.ts +11 -0
- package/dist/lib/tx-wait.d.ts +19 -0
- package/dist/lib/types.d.ts +377 -0
- package/dist/lib/verify.d.ts +21 -0
- package/package.json +7 -1
- package/skills/grant-cash/SKILL.md +19 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import type { AssetDto, MarketDto, TxResult, TxStatusResult, PrepareResult, SignStart, SignTaskInput, HlSetup, FiatAccount, PortfolioSummary, PolymarketMarketsResult, PolymarketMarketDetail, PolymarketPositionsResult, PolymarketActivityResult, PolymarketTradingStatus, PolymarketBetResult, VaultDto, EarnPositionDto } from './types.js';
|
|
2
|
+
import type { TokenHolder } from './auth-session.js';
|
|
3
|
+
interface ClientOpts {
|
|
4
|
+
urls: {
|
|
5
|
+
api: string;
|
|
6
|
+
fiat: string;
|
|
7
|
+
widget: string;
|
|
8
|
+
app: string;
|
|
9
|
+
};
|
|
10
|
+
fetchImpl?: typeof fetch;
|
|
11
|
+
/** Shared holder of the perfolio access JWT + refresh (drives refresh-on-401). */
|
|
12
|
+
auth?: TokenHolder;
|
|
13
|
+
}
|
|
14
|
+
export declare class PerfolioClient {
|
|
15
|
+
private urls;
|
|
16
|
+
private auth?;
|
|
17
|
+
private f;
|
|
18
|
+
constructor(opts: ClientOpts);
|
|
19
|
+
private headers;
|
|
20
|
+
/** fetch with an abort-based timeout + one retry on a transient network failure. */
|
|
21
|
+
private fetchWithTimeout;
|
|
22
|
+
private request;
|
|
23
|
+
private get;
|
|
24
|
+
private post;
|
|
25
|
+
getUser(): Promise<Record<string, unknown>>;
|
|
26
|
+
getModuleStatus(): Promise<Record<string, unknown>>;
|
|
27
|
+
getAssets(): Promise<AssetDto[]>;
|
|
28
|
+
getMarkets(): Promise<MarketDto[]>;
|
|
29
|
+
/** Balances for the authenticated user's own wallet (no wallet-id needed). */
|
|
30
|
+
getBalance(): Promise<unknown>;
|
|
31
|
+
/**
|
|
32
|
+
* Portfolio summary. Pass `'full'` to additionally fetch the multi-asset +
|
|
33
|
+
* perps breakdown (`multiAsset` block) used by the CLI/MCP; the default
|
|
34
|
+
* (gold + cash) matches what the web app reads.
|
|
35
|
+
*/
|
|
36
|
+
getPortfolio(view?: 'full'): Promise<PortfolioSummary>;
|
|
37
|
+
getPosition(collateral: string, loan: string): Promise<unknown>;
|
|
38
|
+
getGoldPrice(): Promise<unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* FX rate for a fiat currency: local units per 1 USD (public endpoint).
|
|
41
|
+
* Used to convert USD-denominated amounts into the user's display currency.
|
|
42
|
+
*/
|
|
43
|
+
getFiatRate(currency: string): Promise<{
|
|
44
|
+
price: number;
|
|
45
|
+
currency: string;
|
|
46
|
+
baseCurrency: string;
|
|
47
|
+
}>;
|
|
48
|
+
getCryptoPrices(): Promise<unknown>;
|
|
49
|
+
getBorrowRate(): Promise<unknown>;
|
|
50
|
+
getMarketStats(): Promise<unknown>;
|
|
51
|
+
getTxHistory(limit?: number): Promise<unknown>;
|
|
52
|
+
/** Authoritative per-tx status — backend re-checks the MEE explorer for non-terminal states. */
|
|
53
|
+
getTxStatus(txHash: string): Promise<TxStatusResult>;
|
|
54
|
+
/** Discover/search active prediction markets (public). */
|
|
55
|
+
polymarketMarkets(query?: string, limit?: number): Promise<PolymarketMarketsResult>;
|
|
56
|
+
/** One market's detail + live prices (public). */
|
|
57
|
+
polymarketMarket(id: string): Promise<PolymarketMarketDetail>;
|
|
58
|
+
/** The authenticated user's open prediction positions + portfolio totals. */
|
|
59
|
+
polymarketPositions(): Promise<PolymarketPositionsResult>;
|
|
60
|
+
/** The authenticated user's prediction trade history (most recent first). */
|
|
61
|
+
polymarketActivity(limit?: number): Promise<PolymarketActivityResult>;
|
|
62
|
+
/** Whether the betting (write) path is provisioned + enabled. */
|
|
63
|
+
polymarketTradingStatus(): Promise<PolymarketTradingStatus>;
|
|
64
|
+
/** Place a bet (buy outcome shares). Returns 503 until trading is enabled. */
|
|
65
|
+
polymarketBet(b: {
|
|
66
|
+
marketId: string;
|
|
67
|
+
side: 'yes' | 'no';
|
|
68
|
+
amount: string;
|
|
69
|
+
limitPrice?: number;
|
|
70
|
+
maxSlippageBps?: number;
|
|
71
|
+
}): Promise<PolymarketBetResult>;
|
|
72
|
+
/** Sell shares (cash out). `shares` omitted = sell all. */
|
|
73
|
+
polymarketSell(b: {
|
|
74
|
+
marketId: string;
|
|
75
|
+
shares?: number;
|
|
76
|
+
}): Promise<PolymarketBetResult>;
|
|
77
|
+
/** Redeem winnings on a resolved market. */
|
|
78
|
+
polymarketRedeem(b: {
|
|
79
|
+
marketId: string;
|
|
80
|
+
}): Promise<{
|
|
81
|
+
status: string;
|
|
82
|
+
marketId: string;
|
|
83
|
+
}>;
|
|
84
|
+
/** Deposit-wallet address + deployed status (read-only). */
|
|
85
|
+
polymarketDepositWallet(): Promise<{
|
|
86
|
+
address: string;
|
|
87
|
+
deployed: boolean;
|
|
88
|
+
}>;
|
|
89
|
+
/** Deploy + approve the deposit wallet (gasless, autonomous via the signer). */
|
|
90
|
+
polymarketProvision(): Promise<{
|
|
91
|
+
address: string;
|
|
92
|
+
deployed: boolean;
|
|
93
|
+
provisioned: boolean;
|
|
94
|
+
}>;
|
|
95
|
+
/** Build a Relay USDT→pUSD funding quote to the deposit wallet (execution is separate). */
|
|
96
|
+
polymarketFundQuote(amount: string): Promise<{
|
|
97
|
+
depositWallet: string;
|
|
98
|
+
amountUsdt: string;
|
|
99
|
+
requestId?: string;
|
|
100
|
+
steps: unknown[];
|
|
101
|
+
}>;
|
|
102
|
+
/** Execute USDT→pUSD funding to the deposit wallet autonomously via the DeFi session. */
|
|
103
|
+
polymarketDeposit(amount: string): Promise<{
|
|
104
|
+
requestId?: string;
|
|
105
|
+
depositWallet: string;
|
|
106
|
+
}>;
|
|
107
|
+
/** Withdraw pUSD from the deposit wallet back to your wallet (USDT on Ethereum). */
|
|
108
|
+
polymarketWithdraw(amount: string): Promise<{
|
|
109
|
+
bridgeAddress: string;
|
|
110
|
+
recipient: string;
|
|
111
|
+
depositWallet: string;
|
|
112
|
+
txHash?: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** Poll a Relay funding intent (pUSD delivery on Polygon). */
|
|
115
|
+
polymarketFundStatus(requestId: string): Promise<unknown>;
|
|
116
|
+
swapQuote(b: {
|
|
117
|
+
sellToken: string;
|
|
118
|
+
buyToken: string;
|
|
119
|
+
sellAmount: string;
|
|
120
|
+
}): Promise<unknown>;
|
|
121
|
+
swap(b: {
|
|
122
|
+
sellToken: string;
|
|
123
|
+
buyToken: string;
|
|
124
|
+
sellAmount: string;
|
|
125
|
+
}): Promise<TxResult>;
|
|
126
|
+
supply(b: {
|
|
127
|
+
collateral: string;
|
|
128
|
+
amount: string;
|
|
129
|
+
}): Promise<TxResult>;
|
|
130
|
+
borrow(b: {
|
|
131
|
+
collateral: string;
|
|
132
|
+
loan: string;
|
|
133
|
+
amount: string;
|
|
134
|
+
}): Promise<TxResult>;
|
|
135
|
+
repay(b: {
|
|
136
|
+
collateral: string;
|
|
137
|
+
loan: string;
|
|
138
|
+
amount: string;
|
|
139
|
+
}): Promise<TxResult>;
|
|
140
|
+
withdrawCollateral(b: {
|
|
141
|
+
collateral: string;
|
|
142
|
+
amount: string;
|
|
143
|
+
}): Promise<TxResult>;
|
|
144
|
+
supplyAndBorrow(b: {
|
|
145
|
+
collateral: string;
|
|
146
|
+
loan: string;
|
|
147
|
+
collateralAmount: string;
|
|
148
|
+
borrowAmount: string;
|
|
149
|
+
}): Promise<TxResult>;
|
|
150
|
+
closePosition(b: {
|
|
151
|
+
collateral: string;
|
|
152
|
+
loan: string;
|
|
153
|
+
}): Promise<TxResult>;
|
|
154
|
+
/** List earn vaults (public read). Pass an asset symbol to filter. */
|
|
155
|
+
getVaults(asset?: string): Promise<{
|
|
156
|
+
vaults: VaultDto[];
|
|
157
|
+
}>;
|
|
158
|
+
/** The authenticated user's earn position for an asset (on-chain shares + value). */
|
|
159
|
+
getEarnPosition(asset: string): Promise<EarnPositionDto>;
|
|
160
|
+
/** Deposit an asset into its canonical earn vault (agent-signed via the DeFi session). */
|
|
161
|
+
earnDeposit(b: {
|
|
162
|
+
asset: string;
|
|
163
|
+
amount: string;
|
|
164
|
+
}): Promise<TxResult>;
|
|
165
|
+
/** Withdraw from an earn vault — exact `amount`, or the whole position with `all: true`. */
|
|
166
|
+
earnWithdraw(b: {
|
|
167
|
+
asset: string;
|
|
168
|
+
amount?: string;
|
|
169
|
+
all?: boolean;
|
|
170
|
+
}): Promise<TxResult>;
|
|
171
|
+
prepareWithdrawal(b: {
|
|
172
|
+
token: string;
|
|
173
|
+
recipient: string;
|
|
174
|
+
amount: string;
|
|
175
|
+
}): Promise<PrepareResult>;
|
|
176
|
+
prepareGiftSend(b: {
|
|
177
|
+
recipientEmail?: string;
|
|
178
|
+
recipientPhone?: string;
|
|
179
|
+
amountXaut: string;
|
|
180
|
+
message?: string;
|
|
181
|
+
}): Promise<PrepareResult>;
|
|
182
|
+
/** Hand a self-describing sign task to the browser-sign relay. Returns the approve URL + sid. */
|
|
183
|
+
signStart(b: SignTaskInput): Promise<SignStart>;
|
|
184
|
+
hlStatus(): Promise<Record<string, unknown>>;
|
|
185
|
+
/** Discover tradeable HL markets (crypto + equities/commodities/fx/indices). */
|
|
186
|
+
hlMarkets(search?: string): Promise<{
|
|
187
|
+
markets: Array<{
|
|
188
|
+
symbol: string;
|
|
189
|
+
fullName: string;
|
|
190
|
+
dex: string;
|
|
191
|
+
category: string;
|
|
192
|
+
maxLeverage: number;
|
|
193
|
+
}>;
|
|
194
|
+
count: number;
|
|
195
|
+
}>;
|
|
196
|
+
hlPositions(): Promise<{
|
|
197
|
+
positions: unknown[];
|
|
198
|
+
}>;
|
|
199
|
+
hlOrders(): Promise<{
|
|
200
|
+
orders: unknown[];
|
|
201
|
+
}>;
|
|
202
|
+
hlOrderHistory(): Promise<{
|
|
203
|
+
orders: unknown[];
|
|
204
|
+
}>;
|
|
205
|
+
hlTradeHistory(limit?: number): Promise<unknown>;
|
|
206
|
+
hlPrice(asset?: string): Promise<unknown>;
|
|
207
|
+
hlSetup(): Promise<HlSetup>;
|
|
208
|
+
hlOpen(b: {
|
|
209
|
+
side: 'long' | 'short';
|
|
210
|
+
sizeUsd: number;
|
|
211
|
+
leverage: number;
|
|
212
|
+
asset?: string;
|
|
213
|
+
}): Promise<unknown>;
|
|
214
|
+
hlClose(b: {
|
|
215
|
+
asset: string;
|
|
216
|
+
sizePct?: number;
|
|
217
|
+
}): Promise<unknown>;
|
|
218
|
+
hlSetLeverage(b: {
|
|
219
|
+
leverage: number;
|
|
220
|
+
isCross: boolean;
|
|
221
|
+
}): Promise<unknown>;
|
|
222
|
+
hlTpsl(b: {
|
|
223
|
+
asset: string;
|
|
224
|
+
side: 'long' | 'short';
|
|
225
|
+
size: string;
|
|
226
|
+
takeProfit?: number;
|
|
227
|
+
stopLoss?: number;
|
|
228
|
+
}): Promise<unknown>;
|
|
229
|
+
hlCancelOrder(b: {
|
|
230
|
+
oid: number;
|
|
231
|
+
asset?: string;
|
|
232
|
+
}): Promise<unknown>;
|
|
233
|
+
/**
|
|
234
|
+
* Autonomous USDT → Hyperliquid deposit. Hits POST /tx/bridge-deposit, which
|
|
235
|
+
* builds the USDT-approve + Across bridge calls and executes them via the
|
|
236
|
+
* Biconomy session grant (agent-signed) — no user signature, no browser.
|
|
237
|
+
* (The old /hl/deposit/one-click only PREPARED calldata and executed nothing,
|
|
238
|
+
* so its "submitted" was a false positive that moved no funds.)
|
|
239
|
+
*/
|
|
240
|
+
hlDeposit(b: {
|
|
241
|
+
amountUsdt: string;
|
|
242
|
+
}): Promise<TxResult>;
|
|
243
|
+
/**
|
|
244
|
+
* Autonomous cash → spending bridge. Hits POST /tx/bridge-base, which builds
|
|
245
|
+
* the USDT-approve + Across bridge (ETH USDT → Base USDC) and executes them via
|
|
246
|
+
* the Biconomy defi session grant (agent-signed) — no user signature, no
|
|
247
|
+
* browser. Funds the Grant Cash agent's USDC spending balance on Base. A
|
|
248
|
+
* returned txHash means the Ethereum leg was SUBMITTED; the spending balance
|
|
249
|
+
* updates on Base a few minutes later once Across fills. Mirrors hlDeposit
|
|
250
|
+
* (/tx/bridge-deposit) — same Across Swap API + session execution; only the
|
|
251
|
+
* destination (Base 8453) and output token (USDC) differ.
|
|
252
|
+
*/
|
|
253
|
+
bridgeToBase(b: {
|
|
254
|
+
amountUsdt: string;
|
|
255
|
+
}): Promise<{
|
|
256
|
+
txHash?: string;
|
|
257
|
+
status?: string;
|
|
258
|
+
quote?: {
|
|
259
|
+
inputAmount?: string;
|
|
260
|
+
outputAmount?: string;
|
|
261
|
+
estimatedTimeSec?: number;
|
|
262
|
+
};
|
|
263
|
+
}>;
|
|
264
|
+
/** Autonomous HL → Ethereum withdrawal (server-signs via Privy; no browser). */
|
|
265
|
+
hlWithdraw(b: {
|
|
266
|
+
amountUsdc: string;
|
|
267
|
+
}): Promise<{
|
|
268
|
+
amount?: string;
|
|
269
|
+
status?: string;
|
|
270
|
+
relayRequestId?: string;
|
|
271
|
+
expectedOutputUsdt?: string;
|
|
272
|
+
estimatedTimeSec?: number;
|
|
273
|
+
recipient?: string;
|
|
274
|
+
}>;
|
|
275
|
+
/** Poll a HL→Ethereum withdrawal to completion (Relay canonical status + delivery tx hashes). */
|
|
276
|
+
hlWithdrawStatus(requestId: string): Promise<{
|
|
277
|
+
status: string;
|
|
278
|
+
requestId: string;
|
|
279
|
+
inTxHashes?: string[];
|
|
280
|
+
outTxHashes?: string[];
|
|
281
|
+
}>;
|
|
282
|
+
kycStatus(): Promise<unknown>;
|
|
283
|
+
/** Provider (Roma) accounts — fiat accounts carry bankDetails for deposits. Auto-provisioned after KYC. */
|
|
284
|
+
getAccounts(): Promise<FiatAccount[]>;
|
|
285
|
+
beneficiaries(): Promise<unknown>;
|
|
286
|
+
fiatQuote(b: {
|
|
287
|
+
sourceAmount: string;
|
|
288
|
+
sourceCurrencyCode: string;
|
|
289
|
+
destinationCurrencyCode: string;
|
|
290
|
+
}): Promise<unknown>;
|
|
291
|
+
giftsSent(): Promise<unknown>;
|
|
292
|
+
giftsReceived(): Promise<unknown>;
|
|
293
|
+
updateSettings(b: Record<string, unknown>): Promise<unknown>;
|
|
294
|
+
}
|
|
295
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BaseUrls, Credentials } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Backend base URLs — env-overridable. Defaults point at the DEVELOP environment
|
|
4
|
+
* (this is an internal/testing CLI for now). Set the env vars (in a `.env` in the
|
|
5
|
+
* directory you run the CLI from, or as exported shell vars) to repoint at
|
|
6
|
+
* localhost/staging/production without touching code. The active backend is shown
|
|
7
|
+
* by `grant config show` / `grant status`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function baseUrls(env?: NodeJS.ProcessEnv): BaseUrls;
|
|
10
|
+
export declare function resolveCredsPath(flag?: string, env?: NodeJS.ProcessEnv): string;
|
|
11
|
+
export declare function loadCredentials(path: string): Credentials;
|
|
12
|
+
export declare function saveCredentials(creds: Credentials, path: string): void;
|
|
13
|
+
export declare function clearCredentials(path: string): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { BaseUrls, Credentials } from "./types.js";
|
|
3
|
+
import { MoneyClient } from "./money-client.js";
|
|
4
|
+
import { AgentClient } from "./agent-client.js";
|
|
5
|
+
/**
|
|
6
|
+
* Per-invocation runtime: resolved URLs, the credential, both backend clients, and
|
|
7
|
+
* the output mode. Built once per command from the global flags. Both clients share
|
|
8
|
+
* ONE {@link TokenHolder} (unified auth) so a 401 from either refreshes the single
|
|
9
|
+
* perfolio access JWT once and persists it back to the credentials file.
|
|
10
|
+
*/
|
|
11
|
+
export interface Ctx {
|
|
12
|
+
urls: BaseUrls;
|
|
13
|
+
creds: Credentials;
|
|
14
|
+
credsPath: string;
|
|
15
|
+
json: boolean;
|
|
16
|
+
money: MoneyClient;
|
|
17
|
+
agent: AgentClient;
|
|
18
|
+
/** Persist a credentials mutation back to disk. */
|
|
19
|
+
save: (next: Credentials) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function buildContext(cmd: Command): Ctx;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display-currency + experience-mode formatting — the single source of truth
|
|
3
|
+
* shared by the CLI and the MCP server.
|
|
4
|
+
*
|
|
5
|
+
* The platform stores all monetary values internally in USD. The user's profile
|
|
6
|
+
* (GET /api/user) carries their display preferences:
|
|
7
|
+
* - currency ISO code of their local currency (e.g. INR, AED, EUR)
|
|
8
|
+
* - displayCurrency 'USD' (show USD) | 'local' (convert to `currency`)
|
|
9
|
+
* - goldDisplayUnit 'oz' | 'g'
|
|
10
|
+
* - experienceMode 'simple' (plain language, local currency) | 'advanced'
|
|
11
|
+
*
|
|
12
|
+
* The FX rate (local units per 1 USD) comes from GET /api/prices/fiat/{currency}.
|
|
13
|
+
* Conversion is a single multiply; presentation is delegated to Intl so symbols
|
|
14
|
+
* and per-currency decimal conventions (e.g. JPY has 0) are correct and we don't
|
|
15
|
+
* hand-maintain a symbol table.
|
|
16
|
+
*/
|
|
17
|
+
export type ExperienceMode = 'simple' | 'advanced';
|
|
18
|
+
export type DisplayCurrencyMode = 'USD' | 'local';
|
|
19
|
+
export type GoldUnit = 'oz' | 'g';
|
|
20
|
+
/** 1 troy ounce = 31.1034768 grams (matches the web app's GRAMS_PER_TROY_OUNCE). */
|
|
21
|
+
export declare const GRAMS_PER_TROY_OUNCE = 31.1034768;
|
|
22
|
+
export interface DisplayPrefs {
|
|
23
|
+
/** ISO currency code of the user's local currency. */
|
|
24
|
+
currency: string;
|
|
25
|
+
/** Whether to render money in USD or the local `currency`. */
|
|
26
|
+
displayCurrency: DisplayCurrencyMode;
|
|
27
|
+
/** Whether to render gold weight in ounces or grams. */
|
|
28
|
+
goldUnit: GoldUnit;
|
|
29
|
+
/** Experience mode — drives jargon level and the USD-vs-local default. */
|
|
30
|
+
mode: ExperienceMode;
|
|
31
|
+
/** Local currency units per 1 USD. 1 means "no conversion / USD". */
|
|
32
|
+
rate: number;
|
|
33
|
+
}
|
|
34
|
+
/** Safe USD-only defaults — what every caller falls back to with no profile. */
|
|
35
|
+
export declare const DEFAULT_PREFS: DisplayPrefs;
|
|
36
|
+
/**
|
|
37
|
+
* Build DisplayPrefs from a raw GET /api/user payload (defensively — the field
|
|
38
|
+
* may be absent on legacy rows) plus a fetched FX rate. Unknown / malformed
|
|
39
|
+
* values fall back to the safe USD defaults rather than throwing.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveDisplayPrefs(user: unknown, rate?: number): DisplayPrefs;
|
|
42
|
+
/** True when money should be shown in the user's local currency (not USD). */
|
|
43
|
+
export declare function usesLocalCurrency(prefs: DisplayPrefs): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Format a USD amount for display per the user's preferences. Converts to the
|
|
46
|
+
* local currency when configured; otherwise renders USD. Always falls back to a
|
|
47
|
+
* valid USD string if the target currency code is not recognized by Intl.
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatMoney(amountUsd: number, prefs?: DisplayPrefs): string;
|
|
50
|
+
/**
|
|
51
|
+
* A compact, machine-readable descriptor of the user's money-display settings.
|
|
52
|
+
* Attach this to `--json` output so a consumer (e.g. an agent) knows the currency
|
|
53
|
+
* the user expects amounts in, and the FX rate (local units per 1 USD) needed to
|
|
54
|
+
* convert the USD figures the backend returns. Mirrors the MCP's display descriptor.
|
|
55
|
+
*/
|
|
56
|
+
export interface DisplayDescriptor {
|
|
57
|
+
currency: string;
|
|
58
|
+
displayCurrency: DisplayCurrencyMode;
|
|
59
|
+
goldUnit: GoldUnit;
|
|
60
|
+
/** Local units per 1 USD (1 when showing USD). */
|
|
61
|
+
rate: number;
|
|
62
|
+
/** True when amounts should be presented in `currency`, not USD. */
|
|
63
|
+
usesLocal: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare function displayDescriptor(prefs?: DisplayPrefs): DisplayDescriptor;
|
|
66
|
+
/**
|
|
67
|
+
* Format a gold amount (given in troy ounces) per the user's unit preference.
|
|
68
|
+
* Grams are shown with more precision than ounces since 1 oz ≈ 31 g.
|
|
69
|
+
*/
|
|
70
|
+
export declare function formatGold(ounces: number, prefs?: DisplayPrefs): string;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface DeviceStart {
|
|
2
|
+
sid: string;
|
|
3
|
+
connectUrl: string;
|
|
4
|
+
pollInterval: number;
|
|
5
|
+
expiresIn: number;
|
|
6
|
+
}
|
|
7
|
+
export interface DeviceCredentials {
|
|
8
|
+
/** perfolio-signed access JWT — the Bearer for BOTH backends (unified auth). */
|
|
9
|
+
accessJwt?: string;
|
|
10
|
+
refreshToken: string;
|
|
11
|
+
email: string;
|
|
12
|
+
walletAddress: string;
|
|
13
|
+
expiresAt: number;
|
|
14
|
+
deviceId: string;
|
|
15
|
+
/** @deprecated legacy `pfk_` token — still on the wire during migration; unused. */
|
|
16
|
+
token?: string;
|
|
17
|
+
}
|
|
18
|
+
export type DevicePoll = {
|
|
19
|
+
status: "pending" | "denied" | "expired";
|
|
20
|
+
} | {
|
|
21
|
+
status: "complete";
|
|
22
|
+
result: DeviceCredentials;
|
|
23
|
+
};
|
|
24
|
+
export interface CliDevice {
|
|
25
|
+
deviceId: string;
|
|
26
|
+
clientName: string;
|
|
27
|
+
deviceName: string;
|
|
28
|
+
createdAt: number;
|
|
29
|
+
lastUsedAt: number;
|
|
30
|
+
}
|
|
31
|
+
export declare function startDevice(api: string, clientName: string, deviceName: string, f?: typeof fetch): Promise<DeviceStart>;
|
|
32
|
+
/**
|
|
33
|
+
* One poll tick. Resolves only on a real backend answer (HTTP 200 + success
|
|
34
|
+
* envelope) — `pending` | `denied` | `expired` | `complete`. Any transient
|
|
35
|
+
* failure (429 from the shared `/api` limiter, a 5xx, a malformed body, or a
|
|
36
|
+
* thrown fetch when the dev backend restarts) is raised as an AppError so
|
|
37
|
+
* {@link waitForDevice} can back off and retry inside the window instead of
|
|
38
|
+
* mistaking a blip for a terminal "expired" and giving up. A 429 carries
|
|
39
|
+
* `retryInMs` (from the body or the `Retry-After` header) for the backoff.
|
|
40
|
+
*
|
|
41
|
+
* This mirrors the agent side (`pollAgentDevice`/`waitForAgentDevice`); the two
|
|
42
|
+
* halves of the handshake must be equally fault-tolerant.
|
|
43
|
+
*/
|
|
44
|
+
export declare function pollDevice(api: string, sid: string, f?: typeof fetch): Promise<DevicePoll>;
|
|
45
|
+
/**
|
|
46
|
+
* Poll until a genuine terminal status or the link expires.
|
|
47
|
+
*
|
|
48
|
+
* Never bails on a transient failure: network errors and rate-limits (honoring
|
|
49
|
+
* `retryInMs`) just back off and retry until the window closes. Only a real
|
|
50
|
+
* backend answer (`complete` / `denied` / `expired`) ends the loop early. On
|
|
51
|
+
* window exhaustion returns `{ status: "expired" }`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function waitForDevice(api: string, sid: string, intervalMs: number, timeoutMs: number, f?: typeof fetch): Promise<DevicePoll>;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the money-side poll interval in MILLISECONDS.
|
|
56
|
+
*
|
|
57
|
+
* The Perfolio money backend (`cli/device/start`) reports `pollInterval` already
|
|
58
|
+
* in milliseconds (e.g. 3000) — the same contract the published @perfolio/cli
|
|
59
|
+
* consumes as-is — so it is used verbatim. This deliberately differs from the
|
|
60
|
+
* agent backend, which reports SECONDS (see {@link agentPollIntervalMs}).
|
|
61
|
+
*
|
|
62
|
+
* Multiplying this value by 1000 was the cause of the "browser connected but CLI
|
|
63
|
+
* polls forever" bug: 3000 became 3,000,000ms (~50 min), so the CLI polled once
|
|
64
|
+
* and then slept past the whole login window. Falls back to 3s.
|
|
65
|
+
*/
|
|
66
|
+
export declare function moneyPollIntervalMs(pollInterval: number | undefined): number;
|
|
67
|
+
export declare function refreshCliToken(api: string, refreshToken: string, f?: typeof fetch): Promise<{
|
|
68
|
+
token: string;
|
|
69
|
+
refreshToken: string;
|
|
70
|
+
expiresAt: number;
|
|
71
|
+
}>;
|
|
72
|
+
/** List the devices/agents connected to this account (Bearer auth). */
|
|
73
|
+
export declare function listDevices(api: string, token: string, f?: typeof fetch): Promise<CliDevice[]>;
|
|
74
|
+
export declare function revokeDevice(api: string, token: string, deviceId: string | undefined, f?: typeof fetch): Promise<void>;
|
|
75
|
+
/** Best-effort label for the agent/client making the connection. */
|
|
76
|
+
export declare function detectClient(env?: NodeJS.ProcessEnv): string;
|
|
77
|
+
/** Open a URL in the user's default browser (best-effort; never throws). */
|
|
78
|
+
export declare function openBrowser(url: string): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal, dependency-free `.env` loader.
|
|
3
|
+
*
|
|
4
|
+
* Reads `path` and applies each `KEY=value` line into `env`, but ONLY for keys
|
|
5
|
+
* that are still unset — so an already-exported shell var (or an earlier-loaded
|
|
6
|
+
* file) always wins. Missing/unreadable files are a no-op. Supports quoted values
|
|
7
|
+
* (verbatim, including `#`) and strips trailing inline comments on unquoted values
|
|
8
|
+
* (the dotenv convention). Returns the keys it actually set (for logging/tests).
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyDotEnv(raw: string, env?: NodeJS.ProcessEnv): string[];
|
|
11
|
+
/** Load a `.env` file by path into `env` (no-op if the file is missing). */
|
|
12
|
+
export declare function loadDotEnvFile(path: string, env?: NodeJS.ProcessEnv): string[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified error model across both backends.
|
|
3
|
+
*
|
|
4
|
+
* Carries a machine `code` and a `recoverable` flag (from the agent side's LLM
|
|
5
|
+
* playbook) plus an HTTP `status` (from the money side). `friendlyError` maps the
|
|
6
|
+
* shared connection/availability states to one plain-language line so the same
|
|
7
|
+
* 401/403/428/503 reads the same no matter which backend produced it.
|
|
8
|
+
*/
|
|
9
|
+
export declare class AppError extends Error {
|
|
10
|
+
status?: number;
|
|
11
|
+
code?: string;
|
|
12
|
+
recoverable?: boolean;
|
|
13
|
+
details?: Record<string, unknown>;
|
|
14
|
+
constructor(message: string, opts?: {
|
|
15
|
+
status?: number;
|
|
16
|
+
code?: string;
|
|
17
|
+
recoverable?: boolean;
|
|
18
|
+
details?: Record<string, unknown>;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** Money side returns 428 when no spending session is installed. */
|
|
22
|
+
export declare class NoSessionError extends AppError {
|
|
23
|
+
constructor();
|
|
24
|
+
}
|
|
25
|
+
/** No credential of the kind a command needs. */
|
|
26
|
+
export declare class NotConnectedError extends AppError {
|
|
27
|
+
constructor(which: "money" | "agent" | "any");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Plain-language override for shared connection states. Returns null when there
|
|
31
|
+
* is no special-cased message (the caller then uses the backend's own message).
|
|
32
|
+
*/
|
|
33
|
+
export declare function friendlyError(status?: number, code?: string): string | null;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Display formatting. Plain money, no tickers/chains (Grant Cash house style). */
|
|
2
|
+
export declare function money(n: number, currency?: string): string;
|
|
3
|
+
/** Agent-side amounts arrive as USDC minor units (1e6). */
|
|
4
|
+
export declare function usdcMinor(minor: string | number | undefined): string;
|
|
5
|
+
export declare function pct(n: number, digits?: number): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./config.js";
|
|
3
|
+
export * from "./dotenv.js";
|
|
4
|
+
export * from "./errors.js";
|
|
5
|
+
export * from "./output.js";
|
|
6
|
+
export * from "./device.js";
|
|
7
|
+
export * from "./auth-session.js";
|
|
8
|
+
export * from "./money-client.js";
|
|
9
|
+
export * from "./agent-client.js";
|
|
10
|
+
export * from "./tx-wait.js";
|
|
11
|
+
export * from "./format.js";
|
|
12
|
+
export * from "./currency.js";
|
|
13
|
+
export * from "./portfolio-format.js";
|
|
14
|
+
export * from "./context.js";
|
|
15
|
+
export * from "./client.js";
|
|
16
|
+
export * from "./assets.js";
|
|
17
|
+
export * from "./amounts.js";
|
|
18
|
+
export * from "./money-input.js";
|
|
19
|
+
export * from "./kyc-status.js";
|
|
20
|
+
export * from "./polygon-balance.js";
|
|
21
|
+
export * from "./sign.js";
|
|
22
|
+
export * from "./relay.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Pure KYC status classifiers — mirror the web app's kyc-status semantics. */
|
|
2
|
+
export declare function isKycApproved(status: unknown): boolean;
|
|
3
|
+
export declare function isKycRejected(status: unknown): boolean;
|
|
4
|
+
export declare function isKycSubmitted(status: unknown): boolean;
|
|
5
|
+
export declare function isKycPending(status: unknown): boolean;
|
|
6
|
+
/** Extract a status string from a raw value (string | {status} | {data:{status}}) and classify it. */
|
|
7
|
+
export declare function classifyKyc(raw: unknown): {
|
|
8
|
+
status: string;
|
|
9
|
+
approved: boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { TxResult, TxStatusResult } from "./types.js";
|
|
2
|
+
import type { TokenHolder } from "./auth-session.js";
|
|
3
|
+
export interface MoneyClientOpts {
|
|
4
|
+
api: string;
|
|
5
|
+
fiat: string;
|
|
6
|
+
/** Shared holder of the perfolio access JWT + refresh (drives refresh-on-401). */
|
|
7
|
+
auth?: TokenHolder;
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
}
|
|
10
|
+
export declare class MoneyClient {
|
|
11
|
+
private api;
|
|
12
|
+
private fiat;
|
|
13
|
+
private auth?;
|
|
14
|
+
private f;
|
|
15
|
+
constructor(opts: MoneyClientOpts);
|
|
16
|
+
get connected(): boolean;
|
|
17
|
+
private headers;
|
|
18
|
+
private fetchWithTimeout;
|
|
19
|
+
private request;
|
|
20
|
+
private get;
|
|
21
|
+
private post;
|
|
22
|
+
getUser(): Promise<Record<string, unknown>>;
|
|
23
|
+
/** Portfolio summary; 'full' adds the multi-asset + perps breakdown. */
|
|
24
|
+
getPortfolio(view?: "full"): Promise<Record<string, unknown>>;
|
|
25
|
+
getBalance(): Promise<Record<string, unknown>>;
|
|
26
|
+
getGoldPrice(): Promise<Record<string, unknown>>;
|
|
27
|
+
getCryptoPrices(): Promise<Record<string, unknown>>;
|
|
28
|
+
/** Local units per 1 USD, for display-currency conversion. */
|
|
29
|
+
getFiatRate(currency: string): Promise<{
|
|
30
|
+
price: number;
|
|
31
|
+
currency: string;
|
|
32
|
+
baseCurrency: string;
|
|
33
|
+
}>;
|
|
34
|
+
getTxHistory(limit?: number): Promise<unknown>;
|
|
35
|
+
getTxStatus(txHash: string): Promise<TxStatusResult>;
|
|
36
|
+
/** Swap cash → gold (buy) or gold → cash (sell), via the DeFi session. */
|
|
37
|
+
swap(b: {
|
|
38
|
+
sellToken: string;
|
|
39
|
+
buyToken: string;
|
|
40
|
+
sellAmount: string;
|
|
41
|
+
}): Promise<TxResult>;
|
|
42
|
+
/** Prediction deposit-wallet address + deployed status. */
|
|
43
|
+
polymarketDepositWallet(): Promise<{
|
|
44
|
+
address: string;
|
|
45
|
+
deployed: boolean;
|
|
46
|
+
}>;
|
|
47
|
+
/** Open prediction positions + portfolio totals (incl. spendable cashUsd). */
|
|
48
|
+
polymarketPositions(): Promise<{
|
|
49
|
+
positions: unknown[];
|
|
50
|
+
count: number;
|
|
51
|
+
investedUsd: number;
|
|
52
|
+
valueUsd: number;
|
|
53
|
+
pnlUsd: number;
|
|
54
|
+
pnlPercent: number;
|
|
55
|
+
/**
|
|
56
|
+
* Spendable pUSD cash in the deposit wallet (deposited-but-unbet funds),
|
|
57
|
+
* read on-chain server-side — the value the predictions screen shows.
|
|
58
|
+
* Optional: older backends omit it (callers fall back to a direct read).
|
|
59
|
+
*/
|
|
60
|
+
cashUsd?: number;
|
|
61
|
+
}>;
|
|
62
|
+
/** The user's earn (vault) position for an asset symbol. */
|
|
63
|
+
getEarnPosition(asset: string): Promise<Record<string, unknown>>;
|
|
64
|
+
kycStatus(): Promise<Record<string, unknown>>;
|
|
65
|
+
getAccounts(): Promise<unknown>;
|
|
66
|
+
}
|