@candledottv/agent-sdk 0.4.6 → 0.4.8
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 +87 -16
- package/dist/client.d.ts +432 -36
- package/dist/client.d.ts.map +1 -1
- package/dist/errors.d.ts +47 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/hyperliquid-pnl.d.ts +34 -0
- package/dist/hyperliquid-pnl.d.ts.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +355 -18
- package/dist/plans.d.ts +103 -0
- package/dist/plans.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
* bounded by `maxRetries` (default 3 retries after the initial attempt).
|
|
28
28
|
*/
|
|
29
29
|
import { type HyperliquidNetwork, type HyperliquidTypedData } from "./hyperliquid";
|
|
30
|
+
import type { HyperliquidPnlSection } from "./hyperliquid-pnl";
|
|
31
|
+
import type { AgentPlansResult, PlanPrice, PlanTable } from "./plans";
|
|
30
32
|
import type { SecretStore } from "./secret-store";
|
|
31
33
|
import { type WalletChain } from "./wallet-import";
|
|
32
34
|
export type Chain = "solana" | "hood";
|
|
@@ -225,6 +227,8 @@ export interface ConfirmSelfLaunchResult extends LaunchResult {
|
|
|
225
227
|
export interface DryRunResult {
|
|
226
228
|
success: true;
|
|
227
229
|
dryRun: true;
|
|
230
|
+
/** Wallet the real launch pays from; null when no wallet is available for the resolved chain. */
|
|
231
|
+
launchWallet: string | null;
|
|
228
232
|
resolved: {
|
|
229
233
|
chain: Chain;
|
|
230
234
|
quoteAsset: string;
|
|
@@ -236,9 +240,36 @@ export interface DryRunResult {
|
|
|
236
240
|
};
|
|
237
241
|
checks: {
|
|
238
242
|
image: string;
|
|
239
|
-
|
|
243
|
+
/** `"ok"` when a `bannerUrl` was sent and checked; absent otherwise. */
|
|
244
|
+
banner?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Present only for an exclusive (or test-exclusive) mode, the modes that run the Believer
|
|
247
|
+
* check, and then `true`: an ineligible account gets EXCLUSIVE_NOT_ELIGIBLE instead. Absent in
|
|
248
|
+
* any other mode, where nothing was checked.
|
|
249
|
+
*/
|
|
250
|
+
exclusiveEligible?: boolean;
|
|
240
251
|
};
|
|
241
252
|
matrixVersion: number;
|
|
253
|
+
/**
|
|
254
|
+
* Solana only: the assembled launch transaction's size. Absent on Hood, and when the size
|
|
255
|
+
* computation itself failed transiently. A body that would not fit fails the dry run with
|
|
256
|
+
* TRANSACTION_TOO_LARGE instead, so `fits` is always true when present.
|
|
257
|
+
*/
|
|
258
|
+
size?: {
|
|
259
|
+
txBytes: number;
|
|
260
|
+
limit: number;
|
|
261
|
+
maxNameBytes: number;
|
|
262
|
+
fits: boolean;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* POST /api/v1/launch/self/dry-run response: the headless dry run's shape, with `launchWallet` the
|
|
267
|
+
* linked or TEE wallet `buildSelfLaunch()` would pay from, and `launchWalletId` its id. Never
|
|
268
|
+
* checks that wallet's balance.
|
|
269
|
+
*/
|
|
270
|
+
export interface SelfLaunchDryRunResult extends Omit<DryRunResult, "launchWallet"> {
|
|
271
|
+
launchWallet: string;
|
|
272
|
+
launchWalletId: string;
|
|
242
273
|
}
|
|
243
274
|
/** POST /api/v1/launch/headless blocking (or replayed) success response. */
|
|
244
275
|
export interface LaunchResult {
|
|
@@ -409,21 +440,30 @@ export interface AgentProfile {
|
|
|
409
440
|
*/
|
|
410
441
|
export interface AgentTierInfo {
|
|
411
442
|
success: true;
|
|
412
|
-
/**
|
|
443
|
+
/**
|
|
444
|
+
* Display tier: max > pro > believer > free. From the three-plan launch the server sends only
|
|
445
|
+
* `free`, `pro` or `max`; `believer` stays in this type for one release after it, then goes.
|
|
446
|
+
*/
|
|
413
447
|
tier: "free" | "believer" | "pro" | "max";
|
|
414
448
|
/** Live-evaluated tier, independent of the Believer key-issuance label. */
|
|
415
449
|
liveTier: "free" | "pro" | "max";
|
|
416
450
|
stakedCndl: number;
|
|
417
451
|
heldCndl: number;
|
|
452
|
+
/** `graceMs` is 0 from the three-plan launch: Pro through CNDL then has no grace window. */
|
|
418
453
|
thresholds: {
|
|
419
454
|
minStakedCndl: number;
|
|
420
455
|
minHeldCndl: number;
|
|
421
456
|
graceMs: number;
|
|
422
457
|
};
|
|
423
|
-
/**
|
|
458
|
+
/**
|
|
459
|
+
* `startedAt` is null unless `active` (see the endpoint's own doc for why). `endsAt` is the
|
|
460
|
+
* server's deadline for an open window; absent from an older server. Never active from the
|
|
461
|
+
* three-plan launch.
|
|
462
|
+
*/
|
|
424
463
|
grace: {
|
|
425
464
|
active: boolean;
|
|
426
465
|
startedAt: number | null;
|
|
466
|
+
endsAt?: number | null;
|
|
427
467
|
};
|
|
428
468
|
maxTierExpiresAt: number | null;
|
|
429
469
|
/**
|
|
@@ -435,8 +475,12 @@ export interface AgentTierInfo {
|
|
|
435
475
|
maxExpired: boolean;
|
|
436
476
|
/** When the lapsed grant ended (ms). Present only when `maxExpired`. */
|
|
437
477
|
maxExpiredAt?: number;
|
|
438
|
-
/**
|
|
439
|
-
|
|
478
|
+
/**
|
|
479
|
+
* Which kind of grant lapsed. Present only when `maxExpired`. `"promo"` is the Max that came free
|
|
480
|
+
* with a first Pro purchase; while the account still pays for Pro, that lapse is not reported.
|
|
481
|
+
* Treat an unknown value as a generic Max expiry.
|
|
482
|
+
*/
|
|
483
|
+
maxExpiredSource?: "subscription" | "trial" | "team" | "promo";
|
|
440
484
|
/**
|
|
441
485
|
* The server's own sentence about the lapse, dated, with the renewal link. Relay it verbatim:
|
|
442
486
|
* it is the same copy the CLI doctor row, the MCP notice, and the tier refusals use, so every
|
|
@@ -453,6 +497,21 @@ export interface AgentTierInfo {
|
|
|
453
497
|
feeRawSum: string;
|
|
454
498
|
count: number;
|
|
455
499
|
}>;
|
|
500
|
+
/** The live tier's cap floors. Absent from an older server. */
|
|
501
|
+
tierCaps?: {
|
|
502
|
+
rateLimitPerMin: number;
|
|
503
|
+
dailyLaunchCap: number;
|
|
504
|
+
uploadsPerMin: number;
|
|
505
|
+
linkedWallets: number;
|
|
506
|
+
};
|
|
507
|
+
/** When the tier was evaluated (ms), so a caller can say how fresh it is. Absent from an older server. */
|
|
508
|
+
checkedAt?: number;
|
|
509
|
+
/** Max's price. Kept beside `planTable` for compatibility; read `planTable` for every plan. */
|
|
510
|
+
maxPricing?: PlanPrice;
|
|
511
|
+
/** Pro's price, null while Pro is not sold. Absent from a server before the plan table. */
|
|
512
|
+
proPricing?: PlanPrice | null;
|
|
513
|
+
/** The plan table in force, the same one `getPlans()` returns. Absent from an older server. */
|
|
514
|
+
planTable?: PlanTable;
|
|
456
515
|
}
|
|
457
516
|
/**
|
|
458
517
|
* One per-transaction spend cap, mirroring `SpendLimit` in `apps/api/src/lib/agent-policy.ts`
|
|
@@ -487,22 +546,46 @@ export interface ImportWalletResult {
|
|
|
487
546
|
privyWalletId: string;
|
|
488
547
|
}
|
|
489
548
|
/**
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
549
|
+
* What a linked wallet can do, decided by the server (BE-860): `tee`, a TEE wallet bound to one
|
|
550
|
+
* key; `imported`, a spend-capable wallet from the import flow; `linked`, attribution-only, which
|
|
551
|
+
* cannot sign. Not `SelfWallet.kind`, whose `linked` covers both of the last two.
|
|
552
|
+
*/
|
|
553
|
+
export type WalletKind = "tee" | "imported" | "linked";
|
|
554
|
+
/**
|
|
555
|
+
* One row of `GET /api/v1/agent/wallets`'s `page` array. The server returns the whole linkedWallets
|
|
556
|
+
* row, so a page also carries fields this type does not name (`userAddress`, `addressLower`,
|
|
557
|
+
* `verifiedAt` and others); the type names the ones a caller acts on. Branch on `walletKind` for
|
|
558
|
+
* what a row can do. `revokedAt` set means the row is a tombstone -- `listWallets()` excludes these
|
|
559
|
+
* by default; pass `includeRevoked: true` to see them.
|
|
496
560
|
*/
|
|
497
561
|
export interface LinkedWalletRow {
|
|
498
562
|
_id: string;
|
|
499
563
|
chain: WalletChain;
|
|
500
564
|
address: string;
|
|
565
|
+
/** The wallet's Privy id: what `selfLaunch()`, `trade()` and `launchAtomic()` sign a linked leg with. */
|
|
566
|
+
privyWalletId: string;
|
|
501
567
|
label?: string;
|
|
502
568
|
privyPolicyId?: string;
|
|
503
569
|
signerQuorumId?: string;
|
|
504
570
|
revokedAt?: number;
|
|
505
571
|
addedVia: "agent" | "session";
|
|
572
|
+
/**
|
|
573
|
+
* What this wallet can do: `tee`, `imported` (spend-capable) or `linked` (attribution-only).
|
|
574
|
+
* Stable; derived by the server. Absent only from an API that predates it (before 2026-10), where
|
|
575
|
+
* `privyPolicyId` present meant spend-capable and its absence attribution-only.
|
|
576
|
+
*/
|
|
577
|
+
walletKind?: WalletKind;
|
|
578
|
+
/**
|
|
579
|
+
* Served, but its values are internal code names and not promised (today `"ember-tee"`, or the
|
|
580
|
+
* legacy `"ember-hot"`, on a TEE wallet; absent on every other row). Use `walletKind`.
|
|
581
|
+
*/
|
|
582
|
+
profile?: "ember-tee" | "ember-hot";
|
|
583
|
+
/**
|
|
584
|
+
* TEE wallets only: whether the account owner has allowed this wallet to pay for a launch.
|
|
585
|
+
* Absent reads as false. Only the owner can change it (`PUT /api/v1/agent/wallets/:id/capabilities`
|
|
586
|
+
* with a device token or session; the CLI's `candle wallets allow-launch`).
|
|
587
|
+
*/
|
|
588
|
+
allowLaunch?: boolean;
|
|
506
589
|
}
|
|
507
590
|
/** GET /api/v1/agent/wallets response: one page of the account's linked wallets. */
|
|
508
591
|
export interface ListWalletsResult {
|
|
@@ -548,13 +631,70 @@ export interface ProfileOpenPosition {
|
|
|
548
631
|
unrealizedUsd?: number;
|
|
549
632
|
/** The chain this position was traded on. Optional: a server that predates it omits it. */
|
|
550
633
|
chain?: Chain;
|
|
634
|
+
/**
|
|
635
|
+
* The wallet holding it: positions live in wallets, so one token held in two wallets is two
|
|
636
|
+
* positions. `unknown:solana` or `unknown:hood` names the pool for fills no record places in a
|
|
637
|
+
* wallet, which is not an address. Optional: a server that predates 2026-10-02 omits it.
|
|
638
|
+
*/
|
|
639
|
+
wallet?: string;
|
|
640
|
+
/**
|
|
641
|
+
* The key this position belongs to, by prefix: the wallet's bound key, else the key whose buy
|
|
642
|
+
* opened it; null for Manual (web-app trades). Optional: a server that predates 2026-10-02 omits it.
|
|
643
|
+
*/
|
|
644
|
+
agent?: string | null;
|
|
645
|
+
/** When the round behind this position opened, epoch ms. Optional, as `wallet`. */
|
|
646
|
+
openedTs?: number;
|
|
647
|
+
/** Why there is no mark. Present exactly when `markPriceUsd` is absent, on a server that sends it. */
|
|
648
|
+
unpricedReason?: "no-market-row" | "unusable-price";
|
|
649
|
+
/**
|
|
650
|
+
* Worth under one cent at its mark. Still listed and still counted; `openPositionsExDust` leaves it
|
|
651
|
+
* out. An unpriced position is never dust. Optional: a server that predates 2026-10-02 omits it.
|
|
652
|
+
*/
|
|
653
|
+
dust?: true;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Closed positions as one equation (P&L spec PNL-ED-8): `madeUsd + lostUsd + partialSellsUsd`
|
|
657
|
+
* equals the scope's `realizedNetUsd`. A position is closed when its wallet's quantity returns to
|
|
658
|
+
* zero through a sale.
|
|
659
|
+
*/
|
|
660
|
+
export interface ProfileClosedSummary {
|
|
661
|
+
/** Closed positions, those with unknown cost included. */
|
|
662
|
+
closed: number;
|
|
663
|
+
/** Sum of the closed positions that made money, USD. */
|
|
664
|
+
madeUsd: number;
|
|
665
|
+
/** Sum of the closed positions that lost money, USD: zero or negative. */
|
|
666
|
+
lostUsd: number;
|
|
667
|
+
/**
|
|
668
|
+
* The rest of the realized net: partial sells of positions still open, and fees not in a closed
|
|
669
|
+
* position (a buy fee on an open position, a sell with nothing open).
|
|
670
|
+
*/
|
|
671
|
+
partialSellsUsd: number;
|
|
672
|
+
/** Closed positions won and lost, leaving out those with unknown cost. */
|
|
673
|
+
wins: number;
|
|
674
|
+
losses: number;
|
|
675
|
+
/** Closed positions with unknown cost: listed in `closed`, left out of `wins` and `losses`. */
|
|
676
|
+
costUnknown: number;
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Fields every scope of `ProfilePnlResult` gained on 2026-10-02 (the total, each `byChain` entry
|
|
680
|
+
* and each `byWallet` row). Each is optional: a server that predates it omits it.
|
|
681
|
+
*/
|
|
682
|
+
export interface ProfilePnlEngineFields {
|
|
683
|
+
/** Realized net plus unrealized: the figure the console labels P&L, to the cent. */
|
|
684
|
+
totalUsd?: number;
|
|
685
|
+
/** Open positions that are not dust. */
|
|
686
|
+
openPositionsExDust?: number;
|
|
687
|
+
/** Closed positions this scope's sales closed. */
|
|
688
|
+
closedRounds?: number;
|
|
689
|
+
/** Money made, minus money lost, plus partial sells, equals `realizedNetUsd`. */
|
|
690
|
+
closed?: ProfileClosedSummary;
|
|
551
691
|
}
|
|
552
692
|
/**
|
|
553
693
|
* One chain's share of a profile's P&L (`ProfilePnlResult.pnl.byChain`): the total's figures over
|
|
554
694
|
* that chain's fills alone. `openPositions` is a COUNT here; the positions themselves are in
|
|
555
695
|
* `pnl.openPositions`, each carrying its `chain`.
|
|
556
696
|
*/
|
|
557
|
-
export interface ProfileChainPnl {
|
|
697
|
+
export interface ProfileChainPnl extends ProfilePnlEngineFields {
|
|
558
698
|
realizedGrossUsd: number;
|
|
559
699
|
feesUsd: number;
|
|
560
700
|
realizedNetUsd: number;
|
|
@@ -575,7 +715,7 @@ export interface ProfileChainPnl {
|
|
|
575
715
|
measured: number;
|
|
576
716
|
unmeasured: number;
|
|
577
717
|
};
|
|
578
|
-
/**
|
|
718
|
+
/** This key's ledger fills on this chain in the window. */
|
|
579
719
|
tradesConsidered: number;
|
|
580
720
|
}
|
|
581
721
|
/**
|
|
@@ -586,11 +726,27 @@ export interface ProfileChainPnl {
|
|
|
586
726
|
* that could be marked. A position with no price is counted in `unmarkedPositions` rather than
|
|
587
727
|
* valued at zero, and `oldestMarkAt` says how old the marks are, so a stale figure is visible.
|
|
588
728
|
* Deposits and withdrawals are excluded entirely: funding a wallet is not trading profit.
|
|
729
|
+
*
|
|
730
|
+
* Since 2026-10-02 (P&L spec R2) the figures are this key's share of the account's one P&L read,
|
|
731
|
+
* the read the console, the dashboard, `/books` and `/keys/pnl` share, so they agree with the
|
|
732
|
+
* console to the cent for the same moment:
|
|
733
|
+
* - realized and fees are on the fills this key placed; an open position belongs to the wallet's
|
|
734
|
+
* bound key, else to the key whose buy opened it; a closed position to the key whose sale closed it;
|
|
735
|
+
* - each wallet is its own average-cost pool, and the total is the sum of `byWallet`
|
|
736
|
+
* (it used to pool every wallet of the key);
|
|
737
|
+
* - a recorded move between two of the account's wallets carries its cost and realizes nothing;
|
|
738
|
+
* tokens that arrive with no cost anyone can state realize nothing when sold;
|
|
739
|
+
* - `openPositions` counts one per wallet and token, dust included;
|
|
740
|
+
* - `tradesConsidered` counts this key's ledger fills, and `lookback` / `truncated` are the
|
|
741
|
+
* account's activity bound, not 500 of this key's trades.
|
|
742
|
+
* Every account's realized figure can move on the day a server ships this.
|
|
589
743
|
*/
|
|
590
744
|
export interface ProfilePnlResult {
|
|
745
|
+
/** Optional while Hyperliquid is enabled; separate from spot totals. */
|
|
746
|
+
hyperliquid?: HyperliquidPnlSection;
|
|
591
747
|
success: true;
|
|
592
748
|
keyPrefix: string;
|
|
593
|
-
pnl: {
|
|
749
|
+
pnl: ProfilePnlEngineFields & {
|
|
594
750
|
realizedGrossUsd: number;
|
|
595
751
|
/** Candle fees over the counted fills. Reported separately, netted only into realizedNetUsd. */
|
|
596
752
|
feesUsd: number;
|
|
@@ -609,32 +765,51 @@ export interface ProfilePnlResult {
|
|
|
609
765
|
/** Fills counted, and fills that had no trusted USD price and so were left out entirely. */
|
|
610
766
|
counted: number;
|
|
611
767
|
unvalued: number;
|
|
768
|
+
/** Fills held out because their token has a fill of unknown size. Part of `unvalued`. Optional. */
|
|
769
|
+
unresolved?: number;
|
|
770
|
+
/** The tokens those fills belong to: their P&L is unknown, not zero. Optional. */
|
|
771
|
+
unresolvedMints?: string[];
|
|
772
|
+
/** Fees and measured slippage, reported and never netted a second time. Optional. */
|
|
773
|
+
friction?: {
|
|
774
|
+
feesUsd: number;
|
|
775
|
+
slippageUsd: number;
|
|
776
|
+
slippageBpsAvg?: number;
|
|
777
|
+
measured: number;
|
|
778
|
+
unmeasured: number;
|
|
779
|
+
};
|
|
780
|
+
/** This key's ledger fills in the window. */
|
|
612
781
|
tradesConsidered: number;
|
|
782
|
+
/** The account's activity bound, shared by every private P&L read (it was 500 of this key's trades). */
|
|
613
783
|
lookback: number;
|
|
614
784
|
/** True when the lookback window was full, so this is not a lifetime figure. */
|
|
615
785
|
truncated: boolean;
|
|
616
786
|
/**
|
|
617
|
-
* The same
|
|
618
|
-
*
|
|
787
|
+
* The same figures divided by wallet, ordered by `tradesConsidered` then address. Optional: a
|
|
788
|
+
* server that predates it omits it.
|
|
619
789
|
*
|
|
620
|
-
* Each
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
790
|
+
* Each wallet is its own average-cost pool, and the total above is the sum of its wallets: A
|
|
791
|
+
* buying 100 X for $100, B buying 100 X for $200 and A selling 100 X for $300 realizes $200.
|
|
792
|
+
* (Before 2026-10-02 the total pooled every wallet and realized $150 here.) A token moved
|
|
793
|
+
* between two of the account's wallets carries its cost once the move is recorded; until then
|
|
794
|
+
* the buyer still holds it and the seller's sale realizes nothing.
|
|
625
795
|
*/
|
|
626
796
|
byWallet?: ProfileWalletPnl[];
|
|
627
797
|
/**
|
|
628
|
-
* The same figures split by
|
|
629
|
-
*
|
|
630
|
-
* reason `byWallet` rows need not. Optional: a server that predates it omits it.
|
|
798
|
+
* The same figures split by chain, both chains always present. A token lives on one chain, so
|
|
799
|
+
* the two sum to the total above. Optional: a server that predates it omits it.
|
|
631
800
|
*/
|
|
632
801
|
byChain?: Record<Chain, ProfileChainPnl>;
|
|
633
802
|
};
|
|
634
803
|
}
|
|
635
|
-
/**
|
|
636
|
-
|
|
637
|
-
|
|
804
|
+
/**
|
|
805
|
+
* One row of `ProfilePnlResult.pnl.byWallet`: one wallet's share of a profile's P&L. A wallet two
|
|
806
|
+
* keys trade carries this key's share only.
|
|
807
|
+
*/
|
|
808
|
+
export interface ProfileWalletPnl extends ProfilePnlEngineFields {
|
|
809
|
+
/**
|
|
810
|
+
* The wallet's address as stored: base58, or EIP-55 on Hood. `unknown:solana` or `unknown:hood`
|
|
811
|
+
* is the pool for fills no record places in a wallet: a row, not an address.
|
|
812
|
+
*/
|
|
638
813
|
wallet: string;
|
|
639
814
|
payerType: "main" | "linked";
|
|
640
815
|
/**
|
|
@@ -668,7 +843,7 @@ export interface ProfileWalletPnl {
|
|
|
668
843
|
measured: number;
|
|
669
844
|
unmeasured: number;
|
|
670
845
|
};
|
|
671
|
-
/**
|
|
846
|
+
/** This key's ledger fills in the window from this wallet. */
|
|
672
847
|
tradesConsidered: number;
|
|
673
848
|
}
|
|
674
849
|
/**
|
|
@@ -775,8 +950,9 @@ export interface PortfolioHoodSection {
|
|
|
775
950
|
*
|
|
776
951
|
* `prices` keys a Solana mint by its address, Hood native ETH as `hood:native`, and a Hood token
|
|
777
952
|
* as `hood:<lowercased contract>`, so lowercase a Hood `mint` before the lookup. Read `complete`
|
|
778
|
-
* before quoting a total: it is false when the wallet list was cut off
|
|
779
|
-
* on either chain.
|
|
953
|
+
* before quoting a total: it is false when the wallet list was cut off, any wallet's read failed
|
|
954
|
+
* on either chain, or an LP position could not be read. `walletsComplete` is the list on its own.
|
|
955
|
+
* Absent on a server that predates it, in which case `complete: false` may be either cause.
|
|
780
956
|
*
|
|
781
957
|
* Not typed here: the `lp` section a deployment with LP enabled adds.
|
|
782
958
|
*/
|
|
@@ -790,6 +966,11 @@ export interface PortfolioResult {
|
|
|
790
966
|
/** Solana addresses whose read failed. Hood's are in `hood.unavailable`. */
|
|
791
967
|
unavailable: string[];
|
|
792
968
|
complete: boolean;
|
|
969
|
+
/**
|
|
970
|
+
* Whether every wallet Candle knows was listed. False only when that list was cut off.
|
|
971
|
+
* Independent of `complete`. Absent on a server that predates the field.
|
|
972
|
+
*/
|
|
973
|
+
walletsComplete?: boolean;
|
|
793
974
|
}
|
|
794
975
|
/**
|
|
795
976
|
* One row of a profile's trade history: what was ordered, what actually filled, what it cost,
|
|
@@ -813,7 +994,26 @@ export interface ProfileTradeRow {
|
|
|
813
994
|
filledAmount?: number;
|
|
814
995
|
usdValue?: number;
|
|
815
996
|
feeBps: number;
|
|
997
|
+
/**
|
|
998
|
+
* An estimate from the trade's size and rate, scaled by collected over planned fee. 0 when no fee
|
|
999
|
+
* was collected, including when the plan forgoes it.
|
|
1000
|
+
*/
|
|
816
1001
|
feeUsd?: number;
|
|
1002
|
+
/**
|
|
1003
|
+
* The fee the build planned, in raw units of `quoteAsset`: every venue pays its fee in the quote
|
|
1004
|
+
* asset. Absent on a server before 2026-10-05.
|
|
1005
|
+
*/
|
|
1006
|
+
feeRaw?: string;
|
|
1007
|
+
/**
|
|
1008
|
+
* What the treasury received, in raw units of `quoteAsset`. Confirmed rows only. Equal to
|
|
1009
|
+
* `feeRaw` unless it was measured otherwise.
|
|
1010
|
+
*/
|
|
1011
|
+
feeCollectedRaw?: string;
|
|
1012
|
+
/**
|
|
1013
|
+
* True for a `built` row that holds a signature: the trade is on chain but was not booked.
|
|
1014
|
+
* `errorCode` says why. Absent on a server before 2026-10-05.
|
|
1015
|
+
*/
|
|
1016
|
+
landedUnconfirmed?: boolean;
|
|
817
1017
|
payerWallet: string;
|
|
818
1018
|
venue?: "curve" | "jupiter" | "dex";
|
|
819
1019
|
signature?: string;
|
|
@@ -824,6 +1024,22 @@ export interface ProfileTradesResult {
|
|
|
824
1024
|
success: true;
|
|
825
1025
|
keyPrefix: string;
|
|
826
1026
|
trades: ProfileTradeRow[];
|
|
1027
|
+
/**
|
|
1028
|
+
* Pass back as `cursor` for the next, older page. Present whenever the page read a full `limit`,
|
|
1029
|
+
* so a short or even empty page can still have one: only its absence means the end.
|
|
1030
|
+
*/
|
|
1031
|
+
nextCursor?: string;
|
|
1032
|
+
}
|
|
1033
|
+
/** Options for `getProfileTrades`. */
|
|
1034
|
+
export interface ProfileTradesOptions {
|
|
1035
|
+
/** Rows to read, 1 to 1,000. Default 200. */
|
|
1036
|
+
limit?: number;
|
|
1037
|
+
/** Inclusive lower bound on `createdAt`: an ISO 8601 string, epoch milliseconds, or a `Date`. */
|
|
1038
|
+
since?: string | number | Date;
|
|
1039
|
+
/** Exclusive upper bound on `createdAt`, in the same forms as `since`. */
|
|
1040
|
+
until?: string | number | Date;
|
|
1041
|
+
/** A previous page's `nextCursor`, verbatim. */
|
|
1042
|
+
cursor?: string;
|
|
827
1043
|
}
|
|
828
1044
|
/** `GET /api/v1/agent/keys/{prefix}/wallets` response. */
|
|
829
1045
|
export interface ProfileWalletsResult {
|
|
@@ -845,6 +1061,27 @@ export type TradePayer = {
|
|
|
845
1061
|
type: "linked";
|
|
846
1062
|
linkedWalletId: string;
|
|
847
1063
|
};
|
|
1064
|
+
/**
|
|
1065
|
+
* The Jupiter/DFlow race one Solana `jupiter`-venue build ran. Raw amounts and lamports are decimal
|
|
1066
|
+
* strings. Present only while DFlow is enabled on the deployment, and never on paper or a replay.
|
|
1067
|
+
*/
|
|
1068
|
+
export interface TradeRace {
|
|
1069
|
+
jupiterOutRaw: string;
|
|
1070
|
+
/** DFlow's quoted output, when it gave an accepted quote. */
|
|
1071
|
+
dflowOutRaw?: string;
|
|
1072
|
+
/**
|
|
1073
|
+
* Why DFlow did not build the transaction: `quote:<reason>`, `build:<reason>` (including
|
|
1074
|
+
* `build:priority_fee_over_cap`), or `net:fee_exceeds_edge` when its larger output did not
|
|
1075
|
+
* cover its larger priority fee.
|
|
1076
|
+
*/
|
|
1077
|
+
dflowRefusal?: string;
|
|
1078
|
+
/** The priority-fee ceiling both builds were given, in lamports. Absent from an older server. */
|
|
1079
|
+
priorityFeeCapLamports?: string;
|
|
1080
|
+
/** The priority fee decoded from Jupiter's built transaction. Absent when Jupiter built none. */
|
|
1081
|
+
jupiterPriorityFeeLamports?: string;
|
|
1082
|
+
/** The priority fee decoded from DFlow's built transaction. Absent when DFlow returned none. */
|
|
1083
|
+
dflowPriorityFeeLamports?: string;
|
|
1084
|
+
}
|
|
848
1085
|
/** POST /api/v1/trade/agent/build request body. */
|
|
849
1086
|
export interface BuildTradeRequest {
|
|
850
1087
|
/** Idempotency key, unique per account; shared with the matching confirmTrade() call. */
|
|
@@ -856,6 +1093,18 @@ export interface BuildTradeRequest {
|
|
|
856
1093
|
payer: TradePayer;
|
|
857
1094
|
/** Bps, 0-10000. Server defaults to 100 (1%) when omitted. */
|
|
858
1095
|
maxSlippageBps?: number;
|
|
1096
|
+
/**
|
|
1097
|
+
* The most this build may bid as a Solana priority fee, in lamports: an integer from 0 to
|
|
1098
|
+
* 10,000,000. Replaces the default ceiling of 25 bps of the trade's SOL leg (floored at 100,000,
|
|
1099
|
+
* capped at 10,000,000), so it can raise the ceiling for a small trade that has to land as well
|
|
1100
|
+
* as lower it. `0` asks for no priority fee, and is not the same as omitting the field.
|
|
1101
|
+
*
|
|
1102
|
+
* Applies to Solana `jupiter`-venue builds and is ignored everywhere else (Hood, the curve
|
|
1103
|
+
* venue, paper). A hard limit on DFlow; a requested limit on Jupiter, whose paid figure is
|
|
1104
|
+
* `race.jupiterPriorityFeeLamports` when the response carries `race`. A very low value may not
|
|
1105
|
+
* land before its blockhash expires.
|
|
1106
|
+
*/
|
|
1107
|
+
maxPriorityFeeLamports?: number;
|
|
859
1108
|
/**
|
|
860
1109
|
* What the wallet spends on a buy, or receives on a sell. Safe to pass straight through from a
|
|
861
1110
|
* `POST /trade/agent/quote` response: the two endpoints take the same ids.
|
|
@@ -906,6 +1155,17 @@ export interface TradeFee {
|
|
|
906
1155
|
/** Solana "built" artifacts: one unsigned transaction, the fee (if any) already embedded inside it. */
|
|
907
1156
|
export interface SolanaTradeArtifacts {
|
|
908
1157
|
venue: "curve" | "jupiter";
|
|
1158
|
+
/**
|
|
1159
|
+
* Which quoter built the transaction. On the `jupiter` venue Candle also asks DFlow for a quote and
|
|
1160
|
+
* uses it only when its output is strictly larger: net of each venue's priority fee when a leg is
|
|
1161
|
+
* SOL, raw otherwise. Otherwise this is `jupiter`. `curve` on the curve venue.
|
|
1162
|
+
*/
|
|
1163
|
+
quoteSource?: "curve" | "jupiter" | "dflow";
|
|
1164
|
+
/**
|
|
1165
|
+
* The Jupiter/DFlow race on a `jupiter` venue build: Jupiter's quoted output, DFlow's when it gave an
|
|
1166
|
+
* accepted quote, and why DFlow did not build the transaction when it did not. Absent on the curve venue.
|
|
1167
|
+
*/
|
|
1168
|
+
race?: TradeRace;
|
|
909
1169
|
transactionBase64: string;
|
|
910
1170
|
quoteAsset: string;
|
|
911
1171
|
quoteMint: string;
|
|
@@ -1062,6 +1322,12 @@ export interface ExecutedTradeResult {
|
|
|
1062
1322
|
* server had already read. Present on the executed response since 2026-09-04.
|
|
1063
1323
|
*/
|
|
1064
1324
|
route?: TradeRoute;
|
|
1325
|
+
/**
|
|
1326
|
+
* Solana `jupiter` venue only: which quoter built the transaction that executed (`jupiter` or `dflow`),
|
|
1327
|
+
* and the Jupiter/DFlow race behind it. Absent on the curve venue, on Hood, and on an idempotent replay.
|
|
1328
|
+
*/
|
|
1329
|
+
quoteSource?: "jupiter" | "dflow";
|
|
1330
|
+
race?: TradeRace;
|
|
1065
1331
|
}
|
|
1066
1332
|
/** 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). */
|
|
1067
1333
|
export type BuildTradeResult = BuildTradeBuiltResult | ExecutedTradeResult;
|
|
@@ -1332,6 +1598,89 @@ export interface PerpsOrders {
|
|
|
1332
1598
|
releasedUsdMicros: number;
|
|
1333
1599
|
}[];
|
|
1334
1600
|
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Perps C (BE-647, HL-ED-8): `perpsDeposit()`. Relay moves funds from the key's Hood or Solana TEE
|
|
1603
|
+
* wallet onto Hyperliquid perps USDC at the key's EVM TEE wallet's own address. The asset decides
|
|
1604
|
+
* the paying chain: SOL or USDC from the Solana TEE wallet, ETH or USDG from the Hood one. Needs
|
|
1605
|
+
* `swap:write` and a raw cap on the asset. There is no withdrawal yet.
|
|
1606
|
+
*/
|
|
1607
|
+
export interface PerpsDepositParams {
|
|
1608
|
+
/** Idempotency id, 1 to 128 of `A-Za-z0-9._:-`. Rebuilding under the same id answers its job. */
|
|
1609
|
+
clientDepositId: string;
|
|
1610
|
+
asset: "SOL" | "USDC" | "ETH" | "USDG";
|
|
1611
|
+
/** Raw base units of `asset`, as a decimal string. */
|
|
1612
|
+
amountRaw: string;
|
|
1613
|
+
/** The paying TEE wallet's row id (the relay's :id, and the secretStore key). */
|
|
1614
|
+
walletId: string;
|
|
1615
|
+
/** The paying wallet's Privy wallet id. */
|
|
1616
|
+
privyWalletId: string;
|
|
1617
|
+
/** The Hyperliquid account: the EVM TEE wallet's address. The build is refused if it names another. */
|
|
1618
|
+
account: string;
|
|
1619
|
+
/** From Solana only: the EVM TEE wallet whose Hyperliquid account receives. Omit from Hood. */
|
|
1620
|
+
perpsWalletId?: string;
|
|
1621
|
+
/** Relay slippage, 1 to 1000 bps (default 100). */
|
|
1622
|
+
maxSlippageBps?: number;
|
|
1623
|
+
/** Sign and submit (default), or stop after the build and its check. */
|
|
1624
|
+
submit?: boolean;
|
|
1625
|
+
}
|
|
1626
|
+
/** What `POST /agent/perps/deposit` builds. A Hood build also carries the first sequenced leg. */
|
|
1627
|
+
export interface PerpsDepositBuild {
|
|
1628
|
+
success: true;
|
|
1629
|
+
status: "built";
|
|
1630
|
+
clientDepositId: string;
|
|
1631
|
+
depositId: string;
|
|
1632
|
+
chain: "solana" | "hood";
|
|
1633
|
+
venue: "relay";
|
|
1634
|
+
network: HyperliquidNetwork;
|
|
1635
|
+
asset: PerpsDepositParams["asset"];
|
|
1636
|
+
amountRaw: string;
|
|
1637
|
+
walletId: string;
|
|
1638
|
+
walletAddress: string;
|
|
1639
|
+
destination: {
|
|
1640
|
+
walletId: string;
|
|
1641
|
+
address: string;
|
|
1642
|
+
chainId: number;
|
|
1643
|
+
currency: string;
|
|
1644
|
+
};
|
|
1645
|
+
firstDeposit: boolean;
|
|
1646
|
+
expectedOutRaw: string;
|
|
1647
|
+
minimumOutRaw: string;
|
|
1648
|
+
outDecimals: number;
|
|
1649
|
+
floorUsdcMicros: string;
|
|
1650
|
+
minimumCreditUsdcMicros: string;
|
|
1651
|
+
fee: {
|
|
1652
|
+
bps: number;
|
|
1653
|
+
feeRaw: string;
|
|
1654
|
+
};
|
|
1655
|
+
statusChecks: string[];
|
|
1656
|
+
requestId: string | null;
|
|
1657
|
+
expiresAt: number;
|
|
1658
|
+
/** Solana: the one unsigned deposit. */
|
|
1659
|
+
transactionsBase64?: string[];
|
|
1660
|
+
/** Hood: the sequenced leg protocol's first body. */
|
|
1661
|
+
mode?: "sequenced";
|
|
1662
|
+
operationId?: string;
|
|
1663
|
+
legKind?: string;
|
|
1664
|
+
plannedLegCount?: number;
|
|
1665
|
+
nextLeg?: {
|
|
1666
|
+
chainId: number;
|
|
1667
|
+
nonce: number;
|
|
1668
|
+
gas: string;
|
|
1669
|
+
maxFeePerGas: string;
|
|
1670
|
+
maxPriorityFeePerGas: string;
|
|
1671
|
+
to: string;
|
|
1672
|
+
data: string;
|
|
1673
|
+
value: string;
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
export interface PerpsDepositResult {
|
|
1677
|
+
build: PerpsDepositBuild;
|
|
1678
|
+
submitted: boolean;
|
|
1679
|
+
/** `/perps/deposit/submit`'s final answer: `status: "submitted"` and the chain hashes. */
|
|
1680
|
+
result: Record<string, unknown> | null;
|
|
1681
|
+
}
|
|
1682
|
+
/** Why a deposit build must not be signed, or null. */
|
|
1683
|
+
export declare function perpsDepositProblem(build: PerpsDepositBuild, params: PerpsDepositParams): string | null;
|
|
1335
1684
|
/**
|
|
1336
1685
|
* The base assets `swap()` converts between. Inlined rather than imported from `@candle/shared`'s
|
|
1337
1686
|
* `BaseAssetKey`, for the same reason `packages/mcp` inlines its curve constants: this SDK is
|
|
@@ -1762,6 +2111,14 @@ export declare class CandleClient {
|
|
|
1762
2111
|
* with (possibly none) and lets the server's own auth middleware decide.
|
|
1763
2112
|
*/
|
|
1764
2113
|
getAgentTier(): Promise<AgentTierInfo>;
|
|
2114
|
+
/**
|
|
2115
|
+
* The plan table in force on this deployment (`GET /api/v1/agent/plans`, no credential): each
|
|
2116
|
+
* plan's price, agent fee, perps builder fee, the limits a new key gets, what it can do
|
|
2117
|
+
* (`capabilities`), and `promoMaxDays`. Quote prices and fees from here rather than hard-coding
|
|
2118
|
+
* them: they differ by deployment and change at the three-plan launch. `planTableRows()` renders
|
|
2119
|
+
* it. A server that predates the table answers 404 (`CandleApiError`).
|
|
2120
|
+
*/
|
|
2121
|
+
getPlans(): Promise<AgentPlansResult>;
|
|
1765
2122
|
dryRunLaunch(req: LaunchRequest): Promise<DryRunResult>;
|
|
1766
2123
|
/**
|
|
1767
2124
|
* Blocking launch with idempotent retries. Generates `clientLaunchId` when absent and
|
|
@@ -1816,15 +2173,21 @@ export declare class CandleClient {
|
|
|
1816
2173
|
* Includes FAILED trades, deliberately: a record that dropped them would misrepresent what the
|
|
1817
2174
|
* agent did, and `errorCode` is how you find out why one did not go through. For a spreadsheet
|
|
1818
2175
|
* instead of JSON, request the same path with `?format=csv`.
|
|
2176
|
+
*
|
|
2177
|
+
* Newest first. Narrow by `since` / `until` and page by passing `nextCursor` back as `cursor`
|
|
2178
|
+
* until it is absent; a short page is not the end.
|
|
1819
2179
|
*/
|
|
1820
|
-
getProfileTrades(keyPrefix: string, opts?:
|
|
1821
|
-
limit?: number;
|
|
1822
|
-
}): Promise<ProfileTradesResult>;
|
|
2180
|
+
getProfileTrades(keyPrefix: string, opts?: ProfileTradesOptions): Promise<ProfileTradesResult>;
|
|
1823
2181
|
/**
|
|
1824
2182
|
* One profile's realized P&L, fees, and open positions marked at current prices
|
|
1825
2183
|
* (GET /api/v1/agent/keys/{prefix}/pnl). Read `unrealizedUsd` with `unmarkedPositions` and
|
|
1826
2184
|
* `oldestMarkAt`: an unpriced position is counted there, never valued at zero.
|
|
1827
2185
|
*
|
|
2186
|
+
* The figures are the key's share of the account's one P&L read, the console's figures to the
|
|
2187
|
+
* cent (`pnl.totalUsd` is the console's P&L). Since 2026-10-02 the total is the sum of the key's
|
|
2188
|
+
* wallets, not one pool across them, and `lookback` is the account's activity bound; see
|
|
2189
|
+
* `ProfilePnlResult` for every meaning that changed.
|
|
2190
|
+
*
|
|
1828
2191
|
* Check `unvalued` and `truncated` before quoting the number: the first counts fills that had
|
|
1829
2192
|
* no trusted USD price and were left out rather than counted as zero, the second says the
|
|
1830
2193
|
* lookback window was full and this is not a lifetime figure.
|
|
@@ -1944,6 +2307,14 @@ export declare class CandleClient {
|
|
|
1944
2307
|
signerPublicKey: string;
|
|
1945
2308
|
label?: string;
|
|
1946
2309
|
}): Promise<ImportWalletResult>;
|
|
2310
|
+
/**
|
|
2311
|
+
* Self-signed launch dry run: the same body as `buildSelfLaunch()`, the same checks (payer and
|
|
2312
|
+
* TEE rules, plan, the key's caps), and the same refusals, without building, reserving or
|
|
2313
|
+
* recording anything; the `clientLaunchId` stays unused. Does not check the payer's balance, the
|
|
2314
|
+
* day cap, a `clientLaunchId` already used with another body or payer, or a Solana TEE wallet's
|
|
2315
|
+
* USD spend window; `buildSelfLaunch()` can still refuse for those.
|
|
2316
|
+
*/
|
|
2317
|
+
dryRunSelfLaunch(req: BuildSelfLaunchRequest): Promise<SelfLaunchDryRunResult>;
|
|
1947
2318
|
/**
|
|
1948
2319
|
* Self-signed launch build: returns an unsigned transaction for the agent to sign and
|
|
1949
2320
|
* broadcast itself. Candle never signs and never holds the signer key. Signing a linked wallet
|
|
@@ -2124,8 +2495,9 @@ export declare class CandleClient {
|
|
|
2124
2495
|
* Signs, broadcasts, and waits for its receipt, then -- when the build carried a `feeTransfer`
|
|
2125
2496
|
* leg (a platform fee applies) -- does that leg next at `nonce + 1` and captures `feeTxHash`.
|
|
2126
2497
|
* Requires `evmRpcUrl`; throws a clear error naming it when unset, before any signing. Does NOT
|
|
2127
|
-
* send a dev buy: a Hood self-launch's dev buy
|
|
2128
|
-
*
|
|
2498
|
+
* send a dev buy: a Hood self-launch's dev buy is a separate transaction the caller sends itself
|
|
2499
|
+
* and reports to `confirmSelfLaunch` as `devBuySignature`. The build response never includes a
|
|
2500
|
+
* dev-buy leg, and this method does not assemble one.
|
|
2129
2501
|
*/
|
|
2130
2502
|
selfLaunch(req: SelfLaunchRequest): Promise<ConfirmSelfLaunchResult>;
|
|
2131
2503
|
/**
|
|
@@ -2190,8 +2562,13 @@ export declare class CandleClient {
|
|
|
2190
2562
|
* transaction hash. Shared by trade()'s and selfLaunch()'s Hood branches, both of which must run
|
|
2191
2563
|
* their legs strictly sequentially -- see trade()'s jsdoc for why a later leg's `estimateGas`
|
|
2192
2564
|
* depends on an earlier leg already being mined.
|
|
2565
|
+
*
|
|
2566
|
+
* `surfaceLegOutcome` is the fee leg only. A receipt revert, a receipt read that fails, a
|
|
2567
|
+
* receipt timeout, or a broadcast whose result is ambiguous then throws `EvmLegOutcome` with
|
|
2568
|
+
* the hash once it is known. Every other caller gets the original error.
|
|
2193
2569
|
*/
|
|
2194
2570
|
private signBroadcastAndWaitEvmLeg;
|
|
2571
|
+
private broadcastAndWaitEvmLeg;
|
|
2195
2572
|
/** The server's perps settings: network, Candle's builder, this key's fee, and its limits. */
|
|
2196
2573
|
perpsConfig(): Promise<PerpsConfig>;
|
|
2197
2574
|
/**
|
|
@@ -2228,6 +2605,20 @@ export declare class CandleClient {
|
|
|
2228
2605
|
startTime: number;
|
|
2229
2606
|
funding: Record<string, unknown>[];
|
|
2230
2607
|
}>;
|
|
2608
|
+
/**
|
|
2609
|
+
* Deposit onto the key's Hyperliquid account through Relay (Perps C, HL-ED-8): build, check the
|
|
2610
|
+
* build names `account` on chain 1337 with no Candle fee, then sign through the relay and submit.
|
|
2611
|
+
* From Solana that is one deposit transaction; from Hood each sequenced leg (approve, then the
|
|
2612
|
+
* deposit) is signed and submitted in turn. The fill is Relay's, after the deposit lands: read it
|
|
2613
|
+
* with `perpsDepositStatus()`. Candle checks Relay's steps before it stamps them; `candle perps
|
|
2614
|
+
* deposit` additionally decodes them on the caller's machine.
|
|
2615
|
+
*/
|
|
2616
|
+
perpsDeposit(params: PerpsDepositParams): Promise<PerpsDepositResult>;
|
|
2617
|
+
/** A deposit's job: what was built and submitted, the Hood operation, and Relay's fill status. */
|
|
2618
|
+
perpsDepositStatus(clientDepositId: string): Promise<{
|
|
2619
|
+
success: true;
|
|
2620
|
+
job: Record<string, unknown>;
|
|
2621
|
+
}>;
|
|
2231
2622
|
/** The builder every perps build is checked against (see `hyperliquidBuilder` in the options). */
|
|
2232
2623
|
private perpsBuilder;
|
|
2233
2624
|
/**
|
|
@@ -2266,8 +2657,13 @@ export declare class CandleClient {
|
|
|
2266
2657
|
*/
|
|
2267
2658
|
private jsonRpcCallRaw;
|
|
2268
2659
|
}
|
|
2660
|
+
/** Test-only. Pass null to restore the production receipt wait. */
|
|
2661
|
+
export declare function __setEvmReceiptWaitForTest(opts: {
|
|
2662
|
+
timeoutMs?: number;
|
|
2663
|
+
pollMs?: number;
|
|
2664
|
+
} | null): void;
|
|
2269
2665
|
/** This build's own version. Kept in lockstep with package.json by the release-bump CI guard. */
|
|
2270
|
-
export declare const SDK_VERSION = "0.4.
|
|
2666
|
+
export declare const SDK_VERSION = "0.4.8";
|
|
2271
2667
|
/** Test seam: the once-per-process latch would otherwise weld the suite's first case to the rest. */
|
|
2272
2668
|
export declare function __resetSdkUpdateNoticeForTest(): void;
|
|
2273
2669
|
//# sourceMappingURL=client.d.ts.map
|