@candledottv/agent-sdk 0.4.5 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -16
- package/dist/client.d.ts +499 -22
- package/dist/client.d.ts.map +1 -1
- package/dist/hyperliquid-pnl.d.ts +34 -0
- package/dist/hyperliquid-pnl.d.ts.map +1 -0
- package/dist/hyperliquid.d.ts +116 -0
- package/dist/hyperliquid.d.ts.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +759 -1
- package/dist/plans.d.ts +103 -0
- package/dist/plans.d.ts.map +1 -0
- package/package.json +2 -1
package/dist/client.d.ts
CHANGED
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
* validation error). Backoff is 250ms * 2^n, jittered to 50-100% of that, capped at 8s,
|
|
27
27
|
* bounded by `maxRetries` (default 3 retries after the initial attempt).
|
|
28
28
|
*/
|
|
29
|
+
import { type HyperliquidNetwork, type HyperliquidTypedData } from "./hyperliquid";
|
|
30
|
+
import type { HyperliquidPnlSection } from "./hyperliquid-pnl";
|
|
31
|
+
import type { AgentPlansResult, PlanPrice, PlanTable } from "./plans";
|
|
29
32
|
import type { SecretStore } from "./secret-store";
|
|
30
33
|
import { type WalletChain } from "./wallet-import";
|
|
31
34
|
export type Chain = "solana" | "hood";
|
|
@@ -83,6 +86,16 @@ export interface CandleClientOptions {
|
|
|
83
86
|
* is unset, before any signing.
|
|
84
87
|
*/
|
|
85
88
|
evmRpcUrl?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Candle's Hyperliquid builder address, pinned by the caller. Every perps build is checked
|
|
91
|
+
* against it before signing: an order must name exactly this builder (or none, on a Max order),
|
|
92
|
+
* and setup must approve exactly it. Unset, the client uses `CANDLE_HYPERLIQUID_BUILDER_ADDRESS`
|
|
93
|
+
* when this release carries one, and otherwise trusts the builder `GET /agent/perps/config`
|
|
94
|
+
* reports the first time and holds every later build to that same address.
|
|
95
|
+
*/
|
|
96
|
+
hyperliquidBuilder?: string;
|
|
97
|
+
/** The Hyperliquid network this client trades on. Default mainnet; a build for another is refused. */
|
|
98
|
+
hyperliquidNetwork?: HyperliquidNetwork;
|
|
86
99
|
}
|
|
87
100
|
/** The bonding-curve terms of one (chain, quote asset, tier) cell. */
|
|
88
101
|
export interface CurveTerms {
|
|
@@ -398,21 +411,30 @@ export interface AgentProfile {
|
|
|
398
411
|
*/
|
|
399
412
|
export interface AgentTierInfo {
|
|
400
413
|
success: true;
|
|
401
|
-
/**
|
|
414
|
+
/**
|
|
415
|
+
* Display tier: max > pro > believer > free. From the three-plan launch the server sends only
|
|
416
|
+
* `free`, `pro` or `max`; `believer` stays in this type for one release after it, then goes.
|
|
417
|
+
*/
|
|
402
418
|
tier: "free" | "believer" | "pro" | "max";
|
|
403
419
|
/** Live-evaluated tier, independent of the Believer key-issuance label. */
|
|
404
420
|
liveTier: "free" | "pro" | "max";
|
|
405
421
|
stakedCndl: number;
|
|
406
422
|
heldCndl: number;
|
|
423
|
+
/** `graceMs` is 0 from the three-plan launch: Pro through CNDL then has no grace window. */
|
|
407
424
|
thresholds: {
|
|
408
425
|
minStakedCndl: number;
|
|
409
426
|
minHeldCndl: number;
|
|
410
427
|
graceMs: number;
|
|
411
428
|
};
|
|
412
|
-
/**
|
|
429
|
+
/**
|
|
430
|
+
* `startedAt` is null unless `active` (see the endpoint's own doc for why). `endsAt` is the
|
|
431
|
+
* server's deadline for an open window; absent from an older server. Never active from the
|
|
432
|
+
* three-plan launch.
|
|
433
|
+
*/
|
|
413
434
|
grace: {
|
|
414
435
|
active: boolean;
|
|
415
436
|
startedAt: number | null;
|
|
437
|
+
endsAt?: number | null;
|
|
416
438
|
};
|
|
417
439
|
maxTierExpiresAt: number | null;
|
|
418
440
|
/**
|
|
@@ -424,8 +446,12 @@ export interface AgentTierInfo {
|
|
|
424
446
|
maxExpired: boolean;
|
|
425
447
|
/** When the lapsed grant ended (ms). Present only when `maxExpired`. */
|
|
426
448
|
maxExpiredAt?: number;
|
|
427
|
-
/**
|
|
428
|
-
|
|
449
|
+
/**
|
|
450
|
+
* Which kind of grant lapsed. Present only when `maxExpired`. `"promo"` is the Max that came free
|
|
451
|
+
* with a first Pro purchase; while the account still pays for Pro, that lapse is not reported.
|
|
452
|
+
* Treat an unknown value as a generic Max expiry.
|
|
453
|
+
*/
|
|
454
|
+
maxExpiredSource?: "subscription" | "trial" | "team" | "promo";
|
|
429
455
|
/**
|
|
430
456
|
* The server's own sentence about the lapse, dated, with the renewal link. Relay it verbatim:
|
|
431
457
|
* it is the same copy the CLI doctor row, the MCP notice, and the tier refusals use, so every
|
|
@@ -442,6 +468,21 @@ export interface AgentTierInfo {
|
|
|
442
468
|
feeRawSum: string;
|
|
443
469
|
count: number;
|
|
444
470
|
}>;
|
|
471
|
+
/** The live tier's cap floors. Absent from an older server. */
|
|
472
|
+
tierCaps?: {
|
|
473
|
+
rateLimitPerMin: number;
|
|
474
|
+
dailyLaunchCap: number;
|
|
475
|
+
uploadsPerMin: number;
|
|
476
|
+
linkedWallets: number;
|
|
477
|
+
};
|
|
478
|
+
/** When the tier was evaluated (ms), so a caller can say how fresh it is. Absent from an older server. */
|
|
479
|
+
checkedAt?: number;
|
|
480
|
+
/** Max's price. Kept beside `planTable` for compatibility; read `planTable` for every plan. */
|
|
481
|
+
maxPricing?: PlanPrice;
|
|
482
|
+
/** Pro's price, null while Pro is not sold. Absent from a server before the plan table. */
|
|
483
|
+
proPricing?: PlanPrice | null;
|
|
484
|
+
/** The plan table in force, the same one `getPlans()` returns. Absent from an older server. */
|
|
485
|
+
planTable?: PlanTable;
|
|
445
486
|
}
|
|
446
487
|
/**
|
|
447
488
|
* One per-transaction spend cap, mirroring `SpendLimit` in `apps/api/src/lib/agent-policy.ts`
|
|
@@ -537,13 +578,70 @@ export interface ProfileOpenPosition {
|
|
|
537
578
|
unrealizedUsd?: number;
|
|
538
579
|
/** The chain this position was traded on. Optional: a server that predates it omits it. */
|
|
539
580
|
chain?: Chain;
|
|
581
|
+
/**
|
|
582
|
+
* The wallet holding it: positions live in wallets, so one token held in two wallets is two
|
|
583
|
+
* positions. `unknown:solana` or `unknown:hood` names the pool for fills no record places in a
|
|
584
|
+
* wallet, which is not an address. Optional: a server that predates 2026-10-02 omits it.
|
|
585
|
+
*/
|
|
586
|
+
wallet?: string;
|
|
587
|
+
/**
|
|
588
|
+
* The key this position belongs to, by prefix: the wallet's bound key, else the key whose buy
|
|
589
|
+
* opened it; null for Manual (web-app trades). Optional: a server that predates 2026-10-02 omits it.
|
|
590
|
+
*/
|
|
591
|
+
agent?: string | null;
|
|
592
|
+
/** When the round behind this position opened, epoch ms. Optional, as `wallet`. */
|
|
593
|
+
openedTs?: number;
|
|
594
|
+
/** Why there is no mark. Present exactly when `markPriceUsd` is absent, on a server that sends it. */
|
|
595
|
+
unpricedReason?: "no-market-row" | "unusable-price";
|
|
596
|
+
/**
|
|
597
|
+
* Worth under one cent at its mark. Still listed and still counted; `openPositionsExDust` leaves it
|
|
598
|
+
* out. An unpriced position is never dust. Optional: a server that predates 2026-10-02 omits it.
|
|
599
|
+
*/
|
|
600
|
+
dust?: true;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Closed positions as one equation (P&L spec PNL-ED-8): `madeUsd + lostUsd + partialSellsUsd`
|
|
604
|
+
* equals the scope's `realizedNetUsd`. A position is closed when its wallet's quantity returns to
|
|
605
|
+
* zero through a sale.
|
|
606
|
+
*/
|
|
607
|
+
export interface ProfileClosedSummary {
|
|
608
|
+
/** Closed positions, those with unknown cost included. */
|
|
609
|
+
closed: number;
|
|
610
|
+
/** Sum of the closed positions that made money, USD. */
|
|
611
|
+
madeUsd: number;
|
|
612
|
+
/** Sum of the closed positions that lost money, USD: zero or negative. */
|
|
613
|
+
lostUsd: number;
|
|
614
|
+
/**
|
|
615
|
+
* The rest of the realized net: partial sells of positions still open, and fees not in a closed
|
|
616
|
+
* position (a buy fee on an open position, a sell with nothing open).
|
|
617
|
+
*/
|
|
618
|
+
partialSellsUsd: number;
|
|
619
|
+
/** Closed positions won and lost, leaving out those with unknown cost. */
|
|
620
|
+
wins: number;
|
|
621
|
+
losses: number;
|
|
622
|
+
/** Closed positions with unknown cost: listed in `closed`, left out of `wins` and `losses`. */
|
|
623
|
+
costUnknown: number;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Fields every scope of `ProfilePnlResult` gained on 2026-10-02 (the total, each `byChain` entry
|
|
627
|
+
* and each `byWallet` row). Each is optional: a server that predates it omits it.
|
|
628
|
+
*/
|
|
629
|
+
export interface ProfilePnlEngineFields {
|
|
630
|
+
/** Realized net plus unrealized: the figure the console labels P&L, to the cent. */
|
|
631
|
+
totalUsd?: number;
|
|
632
|
+
/** Open positions that are not dust. */
|
|
633
|
+
openPositionsExDust?: number;
|
|
634
|
+
/** Closed positions this scope's sales closed. */
|
|
635
|
+
closedRounds?: number;
|
|
636
|
+
/** Money made, minus money lost, plus partial sells, equals `realizedNetUsd`. */
|
|
637
|
+
closed?: ProfileClosedSummary;
|
|
540
638
|
}
|
|
541
639
|
/**
|
|
542
640
|
* One chain's share of a profile's P&L (`ProfilePnlResult.pnl.byChain`): the total's figures over
|
|
543
641
|
* that chain's fills alone. `openPositions` is a COUNT here; the positions themselves are in
|
|
544
642
|
* `pnl.openPositions`, each carrying its `chain`.
|
|
545
643
|
*/
|
|
546
|
-
export interface ProfileChainPnl {
|
|
644
|
+
export interface ProfileChainPnl extends ProfilePnlEngineFields {
|
|
547
645
|
realizedGrossUsd: number;
|
|
548
646
|
feesUsd: number;
|
|
549
647
|
realizedNetUsd: number;
|
|
@@ -564,7 +662,7 @@ export interface ProfileChainPnl {
|
|
|
564
662
|
measured: number;
|
|
565
663
|
unmeasured: number;
|
|
566
664
|
};
|
|
567
|
-
/**
|
|
665
|
+
/** This key's ledger fills on this chain in the window. */
|
|
568
666
|
tradesConsidered: number;
|
|
569
667
|
}
|
|
570
668
|
/**
|
|
@@ -575,11 +673,27 @@ export interface ProfileChainPnl {
|
|
|
575
673
|
* that could be marked. A position with no price is counted in `unmarkedPositions` rather than
|
|
576
674
|
* valued at zero, and `oldestMarkAt` says how old the marks are, so a stale figure is visible.
|
|
577
675
|
* Deposits and withdrawals are excluded entirely: funding a wallet is not trading profit.
|
|
676
|
+
*
|
|
677
|
+
* Since 2026-10-02 (P&L spec R2) the figures are this key's share of the account's one P&L read,
|
|
678
|
+
* the read the console, the dashboard, `/books` and `/keys/pnl` share, so they agree with the
|
|
679
|
+
* console to the cent for the same moment:
|
|
680
|
+
* - realized and fees are on the fills this key placed; an open position belongs to the wallet's
|
|
681
|
+
* bound key, else to the key whose buy opened it; a closed position to the key whose sale closed it;
|
|
682
|
+
* - each wallet is its own average-cost pool, and the total is the sum of `byWallet`
|
|
683
|
+
* (it used to pool every wallet of the key);
|
|
684
|
+
* - a recorded move between two of the account's wallets carries its cost and realizes nothing;
|
|
685
|
+
* tokens that arrive with no cost anyone can state realize nothing when sold;
|
|
686
|
+
* - `openPositions` counts one per wallet and token, dust included;
|
|
687
|
+
* - `tradesConsidered` counts this key's ledger fills, and `lookback` / `truncated` are the
|
|
688
|
+
* account's activity bound, not 500 of this key's trades.
|
|
689
|
+
* Every account's realized figure can move on the day a server ships this.
|
|
578
690
|
*/
|
|
579
691
|
export interface ProfilePnlResult {
|
|
692
|
+
/** Optional while Hyperliquid is enabled; separate from spot totals. */
|
|
693
|
+
hyperliquid?: HyperliquidPnlSection;
|
|
580
694
|
success: true;
|
|
581
695
|
keyPrefix: string;
|
|
582
|
-
pnl: {
|
|
696
|
+
pnl: ProfilePnlEngineFields & {
|
|
583
697
|
realizedGrossUsd: number;
|
|
584
698
|
/** Candle fees over the counted fills. Reported separately, netted only into realizedNetUsd. */
|
|
585
699
|
feesUsd: number;
|
|
@@ -598,32 +712,51 @@ export interface ProfilePnlResult {
|
|
|
598
712
|
/** Fills counted, and fills that had no trusted USD price and so were left out entirely. */
|
|
599
713
|
counted: number;
|
|
600
714
|
unvalued: number;
|
|
715
|
+
/** Fills held out because their token has a fill of unknown size. Part of `unvalued`. Optional. */
|
|
716
|
+
unresolved?: number;
|
|
717
|
+
/** The tokens those fills belong to: their P&L is unknown, not zero. Optional. */
|
|
718
|
+
unresolvedMints?: string[];
|
|
719
|
+
/** Fees and measured slippage, reported and never netted a second time. Optional. */
|
|
720
|
+
friction?: {
|
|
721
|
+
feesUsd: number;
|
|
722
|
+
slippageUsd: number;
|
|
723
|
+
slippageBpsAvg?: number;
|
|
724
|
+
measured: number;
|
|
725
|
+
unmeasured: number;
|
|
726
|
+
};
|
|
727
|
+
/** This key's ledger fills in the window. */
|
|
601
728
|
tradesConsidered: number;
|
|
729
|
+
/** The account's activity bound, shared by every private P&L read (it was 500 of this key's trades). */
|
|
602
730
|
lookback: number;
|
|
603
731
|
/** True when the lookback window was full, so this is not a lifetime figure. */
|
|
604
732
|
truncated: boolean;
|
|
605
733
|
/**
|
|
606
|
-
* The same
|
|
607
|
-
*
|
|
734
|
+
* The same figures divided by wallet, ordered by `tradesConsidered` then address. Optional: a
|
|
735
|
+
* server that predates it omits it.
|
|
608
736
|
*
|
|
609
|
-
* Each
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
737
|
+
* Each wallet is its own average-cost pool, and the total above is the sum of its wallets: A
|
|
738
|
+
* buying 100 X for $100, B buying 100 X for $200 and A selling 100 X for $300 realizes $200.
|
|
739
|
+
* (Before 2026-10-02 the total pooled every wallet and realized $150 here.) A token moved
|
|
740
|
+
* between two of the account's wallets carries its cost once the move is recorded; until then
|
|
741
|
+
* the buyer still holds it and the seller's sale realizes nothing.
|
|
614
742
|
*/
|
|
615
743
|
byWallet?: ProfileWalletPnl[];
|
|
616
744
|
/**
|
|
617
|
-
* The same figures split by
|
|
618
|
-
*
|
|
619
|
-
* reason `byWallet` rows need not. Optional: a server that predates it omits it.
|
|
745
|
+
* The same figures split by chain, both chains always present. A token lives on one chain, so
|
|
746
|
+
* the two sum to the total above. Optional: a server that predates it omits it.
|
|
620
747
|
*/
|
|
621
748
|
byChain?: Record<Chain, ProfileChainPnl>;
|
|
622
749
|
};
|
|
623
750
|
}
|
|
624
|
-
/**
|
|
625
|
-
|
|
626
|
-
|
|
751
|
+
/**
|
|
752
|
+
* One row of `ProfilePnlResult.pnl.byWallet`: one wallet's share of a profile's P&L. A wallet two
|
|
753
|
+
* keys trade carries this key's share only.
|
|
754
|
+
*/
|
|
755
|
+
export interface ProfileWalletPnl extends ProfilePnlEngineFields {
|
|
756
|
+
/**
|
|
757
|
+
* The wallet's address as stored: base58, or EIP-55 on Hood. `unknown:solana` or `unknown:hood`
|
|
758
|
+
* is the pool for fills no record places in a wallet: a row, not an address.
|
|
759
|
+
*/
|
|
627
760
|
wallet: string;
|
|
628
761
|
payerType: "main" | "linked";
|
|
629
762
|
/**
|
|
@@ -657,7 +790,7 @@ export interface ProfileWalletPnl {
|
|
|
657
790
|
measured: number;
|
|
658
791
|
unmeasured: number;
|
|
659
792
|
};
|
|
660
|
-
/**
|
|
793
|
+
/** This key's ledger fills in the window from this wallet. */
|
|
661
794
|
tradesConsidered: number;
|
|
662
795
|
}
|
|
663
796
|
/**
|
|
@@ -895,6 +1028,20 @@ export interface TradeFee {
|
|
|
895
1028
|
/** Solana "built" artifacts: one unsigned transaction, the fee (if any) already embedded inside it. */
|
|
896
1029
|
export interface SolanaTradeArtifacts {
|
|
897
1030
|
venue: "curve" | "jupiter";
|
|
1031
|
+
/**
|
|
1032
|
+
* Which quoter built the transaction. On the `jupiter` venue Candle also asks DFlow for a quote and
|
|
1033
|
+
* uses it only when its output is strictly larger; otherwise this is `jupiter`. `curve` on the curve venue.
|
|
1034
|
+
*/
|
|
1035
|
+
quoteSource?: "curve" | "jupiter" | "dflow";
|
|
1036
|
+
/**
|
|
1037
|
+
* The Jupiter/DFlow race on a `jupiter` venue build: Jupiter's quoted output, DFlow's when it gave an
|
|
1038
|
+
* accepted quote, and why DFlow did not build the transaction when it did not. Absent on the curve venue.
|
|
1039
|
+
*/
|
|
1040
|
+
race?: {
|
|
1041
|
+
jupiterOutRaw: string;
|
|
1042
|
+
dflowOutRaw?: string;
|
|
1043
|
+
dflowRefusal?: string;
|
|
1044
|
+
};
|
|
898
1045
|
transactionBase64: string;
|
|
899
1046
|
quoteAsset: string;
|
|
900
1047
|
quoteMint: string;
|
|
@@ -1051,6 +1198,16 @@ export interface ExecutedTradeResult {
|
|
|
1051
1198
|
* server had already read. Present on the executed response since 2026-09-04.
|
|
1052
1199
|
*/
|
|
1053
1200
|
route?: TradeRoute;
|
|
1201
|
+
/**
|
|
1202
|
+
* Solana `jupiter` venue only: which quoter built the transaction that executed (`jupiter` or `dflow`),
|
|
1203
|
+
* and the Jupiter/DFlow race behind it. Absent on the curve venue, on Hood, and on an idempotent replay.
|
|
1204
|
+
*/
|
|
1205
|
+
quoteSource?: "jupiter" | "dflow";
|
|
1206
|
+
race?: {
|
|
1207
|
+
jupiterOutRaw: string;
|
|
1208
|
+
dflowOutRaw?: string;
|
|
1209
|
+
dflowRefusal?: string;
|
|
1210
|
+
};
|
|
1054
1211
|
}
|
|
1055
1212
|
/** POST /api/v1/trade/agent/build response: "built" for a linked payer, "executed" for a main payer (or an idempotent replay of an already-confirmed trade under the same clientTradeId). */
|
|
1056
1213
|
export type BuildTradeResult = BuildTradeBuiltResult | ExecutedTradeResult;
|
|
@@ -1161,6 +1318,249 @@ export interface SignLinkedTransactionResult {
|
|
|
1161
1318
|
signedTransaction: string;
|
|
1162
1319
|
encoding: string;
|
|
1163
1320
|
}
|
|
1321
|
+
/** The EVM TEE wallet a perps action signs from: its row id and its Privy wallet id. */
|
|
1322
|
+
export interface PerpsWalletRef {
|
|
1323
|
+
/** The linked wallet's row id (the relay's :id, and the secretStore key). */
|
|
1324
|
+
walletId: string;
|
|
1325
|
+
/** The same wallet's Privy wallet id, the authorization signature's URL target. */
|
|
1326
|
+
privyWalletId: string;
|
|
1327
|
+
/** Sign and submit (default), or stop after the build and its check and return the build. */
|
|
1328
|
+
submit?: boolean;
|
|
1329
|
+
}
|
|
1330
|
+
export type PerpsSide = "long" | "short";
|
|
1331
|
+
export interface PerpsOpenParams extends PerpsWalletRef {
|
|
1332
|
+
coin: string;
|
|
1333
|
+
side: PerpsSide;
|
|
1334
|
+
/** Size in the coin, a decimal string. */
|
|
1335
|
+
size: string;
|
|
1336
|
+
/** `market` (IOC at the mid moved by the slippage) or `limit`. Default: limit when `price` is set. */
|
|
1337
|
+
type?: "market" | "limit";
|
|
1338
|
+
price?: string;
|
|
1339
|
+
tif?: "Gtc" | "Alo" | "Ioc";
|
|
1340
|
+
slippageBps?: number;
|
|
1341
|
+
/** Optional reduce-only take-profit trigger price. */
|
|
1342
|
+
takeProfit?: string;
|
|
1343
|
+
/** Optional reduce-only stop-loss trigger price. */
|
|
1344
|
+
stopLoss?: string;
|
|
1345
|
+
}
|
|
1346
|
+
export interface PerpsCloseParams extends PerpsWalletRef {
|
|
1347
|
+
coin: string;
|
|
1348
|
+
/** Part of the position to close; the whole position when omitted. */
|
|
1349
|
+
size?: string;
|
|
1350
|
+
slippageBps?: number;
|
|
1351
|
+
}
|
|
1352
|
+
export interface PerpsCancelParams extends PerpsWalletRef {
|
|
1353
|
+
/** The cloid of an order Candle built (an open, or one of its take-profit / stop-loss legs). */
|
|
1354
|
+
cloid: string;
|
|
1355
|
+
}
|
|
1356
|
+
export interface PerpsModifyParams extends PerpsWalletRef {
|
|
1357
|
+
cloid: string;
|
|
1358
|
+
price?: string;
|
|
1359
|
+
size?: string;
|
|
1360
|
+
slippageBps?: number;
|
|
1361
|
+
}
|
|
1362
|
+
export interface PerpsLeverageParams extends PerpsWalletRef {
|
|
1363
|
+
coin: string;
|
|
1364
|
+
leverage: number;
|
|
1365
|
+
mode?: "cross" | "isolated";
|
|
1366
|
+
}
|
|
1367
|
+
export interface PerpsMarginParams extends PerpsWalletRef {
|
|
1368
|
+
coin: string;
|
|
1369
|
+
/** USD, up to 6 decimals; negative removes isolated margin. */
|
|
1370
|
+
amount: string;
|
|
1371
|
+
}
|
|
1372
|
+
/** What a perps build route returns: the plaintext action, its nonce, and the stamped typed data. */
|
|
1373
|
+
export interface PerpsBuild {
|
|
1374
|
+
success: true;
|
|
1375
|
+
perpOrderId: string;
|
|
1376
|
+
kind: "open" | "close" | "modify" | "cancel" | "leverage" | "margin" | "setup";
|
|
1377
|
+
network: HyperliquidNetwork;
|
|
1378
|
+
walletId: string;
|
|
1379
|
+
address: string;
|
|
1380
|
+
nonce: number;
|
|
1381
|
+
action: Record<string, unknown>;
|
|
1382
|
+
typedData: HyperliquidTypedData;
|
|
1383
|
+
claimHash: string;
|
|
1384
|
+
cloid?: string;
|
|
1385
|
+
childCloids?: string[];
|
|
1386
|
+
targetCloid?: string;
|
|
1387
|
+
notionalUsdMicros: number | null;
|
|
1388
|
+
reservedUsdMicros: number;
|
|
1389
|
+
windowKey: string | null;
|
|
1390
|
+
builder: {
|
|
1391
|
+
address: string;
|
|
1392
|
+
feeTenthsBps: number;
|
|
1393
|
+
} | null;
|
|
1394
|
+
exchangeUrl: string;
|
|
1395
|
+
preview: Record<string, unknown>;
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* The outcome of one perps action. `signature` is present once the relay signed; it stays valid
|
|
1399
|
+
* for resubmission until the nonce leaves Hyperliquid's two-day window, so a failed submit keeps
|
|
1400
|
+
* it. `exchange` is Hyperliquid's own answer, unchanged (`status: "ok"` or `"err"`, and per-order
|
|
1401
|
+
* statuses for an order).
|
|
1402
|
+
*/
|
|
1403
|
+
export interface PerpsActionResult {
|
|
1404
|
+
build: PerpsBuild;
|
|
1405
|
+
signature: string | null;
|
|
1406
|
+
submitted: boolean;
|
|
1407
|
+
exchange: unknown | null;
|
|
1408
|
+
submitError?: string;
|
|
1409
|
+
}
|
|
1410
|
+
export interface PerpsAccountStatus {
|
|
1411
|
+
walletId: string;
|
|
1412
|
+
address: string;
|
|
1413
|
+
network: HyperliquidNetwork;
|
|
1414
|
+
mode: string;
|
|
1415
|
+
standardMode: boolean;
|
|
1416
|
+
accountValue: string;
|
|
1417
|
+
withdrawable: string;
|
|
1418
|
+
builder: string;
|
|
1419
|
+
approvedFeeTenthsBps: number;
|
|
1420
|
+
}
|
|
1421
|
+
/** `ready: true` when the builder approval is already on Hyperliquid; otherwise the setup action's outcome. */
|
|
1422
|
+
export type PerpsSetupResult = PerpsAccountStatus & {
|
|
1423
|
+
ready: boolean;
|
|
1424
|
+
action?: PerpsActionResult;
|
|
1425
|
+
};
|
|
1426
|
+
export interface PerpsConfig {
|
|
1427
|
+
success: true;
|
|
1428
|
+
network: HyperliquidNetwork;
|
|
1429
|
+
exchangeUrl: string;
|
|
1430
|
+
builder: string | null;
|
|
1431
|
+
builderFeeTenthsBps: number;
|
|
1432
|
+
maxBuilderFeeRate: string;
|
|
1433
|
+
allowedActionTypes: string[];
|
|
1434
|
+
limits: Record<string, unknown>;
|
|
1435
|
+
}
|
|
1436
|
+
export interface PerpsPositions {
|
|
1437
|
+
success: true;
|
|
1438
|
+
walletId: string;
|
|
1439
|
+
address: string;
|
|
1440
|
+
network: HyperliquidNetwork;
|
|
1441
|
+
mode: string;
|
|
1442
|
+
standardMode: boolean;
|
|
1443
|
+
account: Record<string, string>;
|
|
1444
|
+
withdrawable: string;
|
|
1445
|
+
positions: Record<string, unknown>[];
|
|
1446
|
+
}
|
|
1447
|
+
export interface PerpsOrderRecord {
|
|
1448
|
+
perpOrderId: string;
|
|
1449
|
+
kind: PerpsBuild["kind"];
|
|
1450
|
+
actionType: string;
|
|
1451
|
+
coin: string | null;
|
|
1452
|
+
nonce: number;
|
|
1453
|
+
cloid: string | null;
|
|
1454
|
+
childCloids: string[];
|
|
1455
|
+
targetCloid: string | null;
|
|
1456
|
+
status: string;
|
|
1457
|
+
venueStatus: string | null;
|
|
1458
|
+
filledSz: string | null;
|
|
1459
|
+
notionalUsdMicros: number | null;
|
|
1460
|
+
reservedUsdMicros: number;
|
|
1461
|
+
releasedUsdMicros: number;
|
|
1462
|
+
windowKey: string | null;
|
|
1463
|
+
builtAt: number;
|
|
1464
|
+
settledAt: number | null;
|
|
1465
|
+
}
|
|
1466
|
+
export interface PerpsOrders {
|
|
1467
|
+
success: true;
|
|
1468
|
+
walletId: string;
|
|
1469
|
+
address: string;
|
|
1470
|
+
network: HyperliquidNetwork;
|
|
1471
|
+
/** Hyperliquid's open orders for the wallet's address. */
|
|
1472
|
+
open: Record<string, unknown>[];
|
|
1473
|
+
/** Candle's record of every action it built for this wallet, newest first. */
|
|
1474
|
+
recorded: PerpsOrderRecord[];
|
|
1475
|
+
settled: {
|
|
1476
|
+
perpOrderId: string;
|
|
1477
|
+
status: string;
|
|
1478
|
+
releasedUsdMicros: number;
|
|
1479
|
+
}[];
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Perps C (BE-647, HL-ED-8): `perpsDeposit()`. Relay moves funds from the key's Hood or Solana TEE
|
|
1483
|
+
* wallet onto Hyperliquid perps USDC at the key's EVM TEE wallet's own address. The asset decides
|
|
1484
|
+
* the paying chain: SOL or USDC from the Solana TEE wallet, ETH or USDG from the Hood one. Needs
|
|
1485
|
+
* `swap:write` and a raw cap on the asset. There is no withdrawal yet.
|
|
1486
|
+
*/
|
|
1487
|
+
export interface PerpsDepositParams {
|
|
1488
|
+
/** Idempotency id, 1 to 128 of `A-Za-z0-9._:-`. Rebuilding under the same id answers its job. */
|
|
1489
|
+
clientDepositId: string;
|
|
1490
|
+
asset: "SOL" | "USDC" | "ETH" | "USDG";
|
|
1491
|
+
/** Raw base units of `asset`, as a decimal string. */
|
|
1492
|
+
amountRaw: string;
|
|
1493
|
+
/** The paying TEE wallet's row id (the relay's :id, and the secretStore key). */
|
|
1494
|
+
walletId: string;
|
|
1495
|
+
/** The paying wallet's Privy wallet id. */
|
|
1496
|
+
privyWalletId: string;
|
|
1497
|
+
/** The Hyperliquid account: the EVM TEE wallet's address. The build is refused if it names another. */
|
|
1498
|
+
account: string;
|
|
1499
|
+
/** From Solana only: the EVM TEE wallet whose Hyperliquid account receives. Omit from Hood. */
|
|
1500
|
+
perpsWalletId?: string;
|
|
1501
|
+
/** Relay slippage, 1 to 1000 bps (default 100). */
|
|
1502
|
+
maxSlippageBps?: number;
|
|
1503
|
+
/** Sign and submit (default), or stop after the build and its check. */
|
|
1504
|
+
submit?: boolean;
|
|
1505
|
+
}
|
|
1506
|
+
/** What `POST /agent/perps/deposit` builds. A Hood build also carries the first sequenced leg. */
|
|
1507
|
+
export interface PerpsDepositBuild {
|
|
1508
|
+
success: true;
|
|
1509
|
+
status: "built";
|
|
1510
|
+
clientDepositId: string;
|
|
1511
|
+
depositId: string;
|
|
1512
|
+
chain: "solana" | "hood";
|
|
1513
|
+
venue: "relay";
|
|
1514
|
+
network: HyperliquidNetwork;
|
|
1515
|
+
asset: PerpsDepositParams["asset"];
|
|
1516
|
+
amountRaw: string;
|
|
1517
|
+
walletId: string;
|
|
1518
|
+
walletAddress: string;
|
|
1519
|
+
destination: {
|
|
1520
|
+
walletId: string;
|
|
1521
|
+
address: string;
|
|
1522
|
+
chainId: number;
|
|
1523
|
+
currency: string;
|
|
1524
|
+
};
|
|
1525
|
+
firstDeposit: boolean;
|
|
1526
|
+
expectedOutRaw: string;
|
|
1527
|
+
minimumOutRaw: string;
|
|
1528
|
+
outDecimals: number;
|
|
1529
|
+
floorUsdcMicros: string;
|
|
1530
|
+
minimumCreditUsdcMicros: string;
|
|
1531
|
+
fee: {
|
|
1532
|
+
bps: number;
|
|
1533
|
+
feeRaw: string;
|
|
1534
|
+
};
|
|
1535
|
+
statusChecks: string[];
|
|
1536
|
+
requestId: string | null;
|
|
1537
|
+
expiresAt: number;
|
|
1538
|
+
/** Solana: the one unsigned deposit. */
|
|
1539
|
+
transactionsBase64?: string[];
|
|
1540
|
+
/** Hood: the sequenced leg protocol's first body. */
|
|
1541
|
+
mode?: "sequenced";
|
|
1542
|
+
operationId?: string;
|
|
1543
|
+
legKind?: string;
|
|
1544
|
+
plannedLegCount?: number;
|
|
1545
|
+
nextLeg?: {
|
|
1546
|
+
chainId: number;
|
|
1547
|
+
nonce: number;
|
|
1548
|
+
gas: string;
|
|
1549
|
+
maxFeePerGas: string;
|
|
1550
|
+
maxPriorityFeePerGas: string;
|
|
1551
|
+
to: string;
|
|
1552
|
+
data: string;
|
|
1553
|
+
value: string;
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
export interface PerpsDepositResult {
|
|
1557
|
+
build: PerpsDepositBuild;
|
|
1558
|
+
submitted: boolean;
|
|
1559
|
+
/** `/perps/deposit/submit`'s final answer: `status: "submitted"` and the chain hashes. */
|
|
1560
|
+
result: Record<string, unknown> | null;
|
|
1561
|
+
}
|
|
1562
|
+
/** Why a deposit build must not be signed, or null. */
|
|
1563
|
+
export declare function perpsDepositProblem(build: PerpsDepositBuild, params: PerpsDepositParams): string | null;
|
|
1164
1564
|
/**
|
|
1165
1565
|
* The base assets `swap()` converts between. Inlined rather than imported from `@candle/shared`'s
|
|
1166
1566
|
* `BaseAssetKey`, for the same reason `packages/mcp` inlines its curve constants: this SDK is
|
|
@@ -1560,6 +1960,8 @@ export declare class CandleClient {
|
|
|
1560
1960
|
private readonly secretStore?;
|
|
1561
1961
|
private readonly solanaRpcUrl?;
|
|
1562
1962
|
private readonly evmRpcUrl?;
|
|
1963
|
+
private readonly hyperliquidNetwork;
|
|
1964
|
+
private hyperliquidBuilder?;
|
|
1563
1965
|
/** Reads scoped to what this key may spend: a one-shot swap's receipt, and spendable balances. */
|
|
1564
1966
|
readonly wallets: CandleWallets;
|
|
1565
1967
|
constructor(opts: CandleClientOptions);
|
|
@@ -1589,6 +1991,14 @@ export declare class CandleClient {
|
|
|
1589
1991
|
* with (possibly none) and lets the server's own auth middleware decide.
|
|
1590
1992
|
*/
|
|
1591
1993
|
getAgentTier(): Promise<AgentTierInfo>;
|
|
1994
|
+
/**
|
|
1995
|
+
* The plan table in force on this deployment (`GET /api/v1/agent/plans`, no credential): each
|
|
1996
|
+
* plan's price, agent fee, perps builder fee, the limits a new key gets, what it can do
|
|
1997
|
+
* (`capabilities`), and `promoMaxDays`. Quote prices and fees from here rather than hard-coding
|
|
1998
|
+
* them: they differ by deployment and change at the three-plan launch. `planTableRows()` renders
|
|
1999
|
+
* it. A server that predates the table answers 404 (`CandleApiError`).
|
|
2000
|
+
*/
|
|
2001
|
+
getPlans(): Promise<AgentPlansResult>;
|
|
1592
2002
|
dryRunLaunch(req: LaunchRequest): Promise<DryRunResult>;
|
|
1593
2003
|
/**
|
|
1594
2004
|
* Blocking launch with idempotent retries. Generates `clientLaunchId` when absent and
|
|
@@ -1652,6 +2062,11 @@ export declare class CandleClient {
|
|
|
1652
2062
|
* (GET /api/v1/agent/keys/{prefix}/pnl). Read `unrealizedUsd` with `unmarkedPositions` and
|
|
1653
2063
|
* `oldestMarkAt`: an unpriced position is counted there, never valued at zero.
|
|
1654
2064
|
*
|
|
2065
|
+
* The figures are the key's share of the account's one P&L read, the console's figures to the
|
|
2066
|
+
* cent (`pnl.totalUsd` is the console's P&L). Since 2026-10-02 the total is the sum of the key's
|
|
2067
|
+
* wallets, not one pool across them, and `lookback` is the account's activity bound; see
|
|
2068
|
+
* `ProfilePnlResult` for every meaning that changed.
|
|
2069
|
+
*
|
|
1655
2070
|
* Check `unvalued` and `truncated` before quoting the number: the first counts fills that had
|
|
1656
2071
|
* no trusted USD price and were left out rather than counted as zero, the second says the
|
|
1657
2072
|
* lookback window was full and this is not a lifetime figure.
|
|
@@ -2019,6 +2434,68 @@ export declare class CandleClient {
|
|
|
2019
2434
|
* depends on an earlier leg already being mined.
|
|
2020
2435
|
*/
|
|
2021
2436
|
private signBroadcastAndWaitEvmLeg;
|
|
2437
|
+
/** The server's perps settings: network, Candle's builder, this key's fee, and its limits. */
|
|
2438
|
+
perpsConfig(): Promise<PerpsConfig>;
|
|
2439
|
+
/**
|
|
2440
|
+
* One-time setup (R1): approves Candle's builder fee at 0.1% unless Hyperliquid already shows
|
|
2441
|
+
* it, and reports the account's mode and balance. Idempotent.
|
|
2442
|
+
*/
|
|
2443
|
+
perpsSetup(params: PerpsWalletRef): Promise<PerpsSetupResult>;
|
|
2444
|
+
/** Open (or add to) a position: build, check, sign through the relay, submit to Hyperliquid. */
|
|
2445
|
+
perpsOpen(params: PerpsOpenParams): Promise<PerpsActionResult>;
|
|
2446
|
+
/** Close all or part of a position with a reduce-only IOC order. Reserves nothing. */
|
|
2447
|
+
perpsClose(params: PerpsCloseParams): Promise<PerpsActionResult>;
|
|
2448
|
+
/** Cancel an order Candle built, by its cloid. */
|
|
2449
|
+
perpsCancel(params: PerpsCancelParams): Promise<PerpsActionResult>;
|
|
2450
|
+
/** Change a resting order's price or size. The replacement gets a new cloid. */
|
|
2451
|
+
perpsModify(params: PerpsModifyParams): Promise<PerpsActionResult>;
|
|
2452
|
+
/** Set a market's leverage and margin mode on the account, within the key's maxLeverage. */
|
|
2453
|
+
perpsLeverage(params: PerpsLeverageParams): Promise<PerpsActionResult>;
|
|
2454
|
+
/** Add (positive) or remove (negative) isolated margin on an isolated position. */
|
|
2455
|
+
perpsMargin(params: PerpsMarginParams): Promise<PerpsActionResult>;
|
|
2456
|
+
/** Positions and account value, read live from Hyperliquid by the wallet's address. */
|
|
2457
|
+
perpsPositions(walletId: string): Promise<PerpsPositions>;
|
|
2458
|
+
/** Open orders on Hyperliquid, and Candle's record of every action it built, settled first. */
|
|
2459
|
+
perpsOrders(walletId: string, opts?: {
|
|
2460
|
+
limit?: number;
|
|
2461
|
+
}): Promise<PerpsOrders>;
|
|
2462
|
+
/** Fills, read live from Hyperliquid by the wallet's address. */
|
|
2463
|
+
perpsFills(walletId: string): Promise<{
|
|
2464
|
+
success: true;
|
|
2465
|
+
fills: Record<string, unknown>[];
|
|
2466
|
+
}>;
|
|
2467
|
+
/** Funding payments since `startTime` (epoch ms; default the last 7 days). */
|
|
2468
|
+
perpsFunding(walletId: string, startTime?: number): Promise<{
|
|
2469
|
+
success: true;
|
|
2470
|
+
startTime: number;
|
|
2471
|
+
funding: Record<string, unknown>[];
|
|
2472
|
+
}>;
|
|
2473
|
+
/**
|
|
2474
|
+
* Deposit onto the key's Hyperliquid account through Relay (Perps C, HL-ED-8): build, check the
|
|
2475
|
+
* build names `account` on chain 1337 with no Candle fee, then sign through the relay and submit.
|
|
2476
|
+
* From Solana that is one deposit transaction; from Hood each sequenced leg (approve, then the
|
|
2477
|
+
* deposit) is signed and submitted in turn. The fill is Relay's, after the deposit lands: read it
|
|
2478
|
+
* with `perpsDepositStatus()`. Candle checks Relay's steps before it stamps them; `candle perps
|
|
2479
|
+
* deposit` additionally decodes them on the caller's machine.
|
|
2480
|
+
*/
|
|
2481
|
+
perpsDeposit(params: PerpsDepositParams): Promise<PerpsDepositResult>;
|
|
2482
|
+
/** A deposit's job: what was built and submitted, the Hood operation, and Relay's fill status. */
|
|
2483
|
+
perpsDepositStatus(clientDepositId: string): Promise<{
|
|
2484
|
+
success: true;
|
|
2485
|
+
job: Record<string, unknown>;
|
|
2486
|
+
}>;
|
|
2487
|
+
/** The builder every perps build is checked against (see `hyperliquidBuilder` in the options). */
|
|
2488
|
+
private perpsBuilder;
|
|
2489
|
+
/**
|
|
2490
|
+
* Check, sign, submit (HL-ED-2, HL-ED-5). The check runs before the relay is called; a build
|
|
2491
|
+
* that fails it is refused with nothing signed.
|
|
2492
|
+
*/
|
|
2493
|
+
private perpsComplete;
|
|
2494
|
+
/**
|
|
2495
|
+
* Sign EIP-712 typed data with a linked EVM TEE wallet through the relay
|
|
2496
|
+
* (`eth_signTypedData_v4`). The relay signs only typed data a perps build stamped.
|
|
2497
|
+
*/
|
|
2498
|
+
private signLinkedTypedData;
|
|
2022
2499
|
private requireKey;
|
|
2023
2500
|
private headers;
|
|
2024
2501
|
private requestJson;
|
|
@@ -2046,7 +2523,7 @@ export declare class CandleClient {
|
|
|
2046
2523
|
private jsonRpcCallRaw;
|
|
2047
2524
|
}
|
|
2048
2525
|
/** This build's own version. Kept in lockstep with package.json by the release-bump CI guard. */
|
|
2049
|
-
export declare const SDK_VERSION = "0.4.
|
|
2526
|
+
export declare const SDK_VERSION = "0.4.7";
|
|
2050
2527
|
/** Test seam: the once-per-process latch would otherwise weld the suite's first case to the rest. */
|
|
2051
2528
|
export declare function __resetSdkUpdateNoticeForTest(): void;
|
|
2052
2529
|
//# sourceMappingURL=client.d.ts.map
|