@0xmonaco/types 1.0.58 → 1.0.59

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.
@@ -31,10 +31,24 @@ export interface AuthAPI extends BaseAPI {
31
31
  /**
32
32
  * Signs a challenge message using the wallet client.
33
33
  *
34
- * Signs the provided message using the wallet's private key.
35
- * This is used in the authentication flow to prove ownership of the wallet.
34
+ * Asks the connected wallet to authorize the message, proving control of the
35
+ * address. An EOA signs it with its private key (EIP-191 `personal_sign`). A
36
+ * smart-contract wallet such as a Safe has no private key and returns a
37
+ * signature its own contract will accept, which the server checks under
38
+ * EIP-1271; the wallet client handles that difference, and the returned value
39
+ * is submitted unchanged either way.
36
40
  *
37
- * @param message - The message to sign
41
+ * The returned signature is therefore not guaranteed to be 65 bytes — a
42
+ * contract signature is usually longer — so callers must not assume the
43
+ * EOA shape.
44
+ *
45
+ * Note the scope. Server-side EIP-1271 verification is deliberately narrow:
46
+ * it is offered only to a wallet holding a BuilderCodes payout bucket, on a
47
+ * deployment with the contract-wallet flag on and a chain RPC endpoint
48
+ * configured. An ordinary smart-contract trading account is not covered — it
49
+ * still takes the recovery path, which it cannot satisfy.
50
+ *
51
+ * @param message - The message to authorize
38
52
  * @returns Promise resolving to the signature
39
53
  */
40
54
  signChallenge(message: string): Promise<string>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * BuilderCodes Types
3
+ *
4
+ * Types for the BuilderCodes API: reading and claiming an enrolled frontend's
5
+ * per-trade revenue share.
6
+ */
7
+ import type { BaseAPI } from "../api";
8
+ import type { ClaimBuildercodeRewardsParams, ClaimBuildercodeRewardsResponse, GetBuildercodePayoutSummaryResponse, GetBuildercodeRewardsBalanceResponse, GetBuildercodesConfigResponse, ListBuildercodePayoutsParams, ListBuildercodePayoutsResponse } from "./responses";
9
+ /**
10
+ * BuilderCodes payout API interface.
11
+ *
12
+ * BuilderCodes is Monaco's per-trade frontend revenue share: an enrolled
13
+ * frontend earns a configured share of the net take on every fill its users
14
+ * generate, accruing to a reserved payout bucket owned by the frontend's
15
+ * configured payout wallet. Accrual is internal accounting only — this API is
16
+ * how that balance is claimed into a tradeable (and then withdrawable) balance.
17
+ */
18
+ export interface BuildercodesAPI extends BaseAPI {
19
+ /** Read this authenticated frontend's enrollment, payout address, and live budget. */
20
+ getConfig(): Promise<GetBuildercodesConfigResponse>;
21
+ /** List this authenticated frontend's per-trade BuilderCodes credits. */
22
+ listPayouts(params?: ListBuildercodePayoutsParams): Promise<ListBuildercodePayoutsResponse>;
23
+ /** Summarize this authenticated frontend's BuilderCodes credits by token. */
24
+ getPayoutSummary(): Promise<GetBuildercodePayoutSummaryResponse>;
25
+ /** Read the authenticated wallet's available reserved reward balances. */
26
+ getRewardsBalance(): Promise<GetBuildercodeRewardsBalanceResponse>;
27
+ /**
28
+ * Claim accrued BuilderCodes payout balance into a trading balance.
29
+ *
30
+ * Moves the specified amount of a payout token out of the authenticated
31
+ * caller's reserved payout bucket and into their trading balance under the
32
+ * authenticated application, from where the ordinary withdrawal flow applies.
33
+ * Ledger-only — no on-chain transaction and no gas, and the funds are
34
+ * immediately tradeable.
35
+ *
36
+ * The payout wallet may be an EOA or a smart-contract wallet. An EOA answers
37
+ * the signature challenge directly; a multisig such as a Safe authenticates by
38
+ * EIP-1271 contract signature instead. That path is offered only to a wallet
39
+ * holding a BuilderCodes payout bucket, only while `contract_wallet_auth_enabled`
40
+ * is on, and only where the deployment has a chain RPC endpoint configured —
41
+ * otherwise login is EOA-only and a contract payout wallet can neither call
42
+ * this endpoint nor withdraw afterwards.
43
+ *
44
+ * The bucket is resolved from the authenticated caller's own wallet address,
45
+ * so a caller can only ever claim their own accrued balance. A wallet that
46
+ * has never been an enrolled frontend's payout address has nothing to claim.
47
+ * A wallet that *used to be* a payout address keeps what it accrued back then
48
+ * and can still claim it — payout-address changes are not retroactive.
49
+ *
50
+ * Throws 403 when the caller is refused: BuilderCodes is not enabled, or
51
+ * the session is a delegated agent — which is rejected before the feature is
52
+ * checked, so it is a permanent restriction on that session type, not a
53
+ * rollout state. Throws 409 when the payout balance is insufficient for the
54
+ * requested amount. Throws 503 when the matching engine is unreachable,
55
+ * restarting, or slow to answer — an UNKNOWN outcome, not a rejection: the
56
+ * claim is admitted to the sequencer before its reply is sent, so it may
57
+ * still commit, and with no idempotency key a blind retry can claim twice.
58
+ * Do not retry automatically: a balance read cannot settle it, because an
59
+ * admitted claim may still be queued. Ambiguous failures are thrown
60
+ * with `retryable: false` so retry logic driven off that flag cannot claim
61
+ * twice. Two pre-admission rejections stay retryable because they committed
62
+ * nothing: a maintenance block (`OPERATIONS_BLOCKED`) and a sequencer
63
+ * overload (`OVERLOADED`).
64
+ *
65
+ * @param params - Payout token address and raw-unit amount to claim
66
+ * @returns Promise resolving to the post-claim payout and trading balances
67
+ */
68
+ claimBuildercodeRewards(params: ClaimBuildercodeRewardsParams): Promise<ClaimBuildercodeRewardsResponse>;
69
+ }
70
+ export type { BuildercodePayout, BuildercodePayoutTokenTotal, BuildercodeRewardsBalance, ClaimBuildercodeRewardsParams, ClaimBuildercodeRewardsResponse, GetBuildercodePayoutSummaryResponse, GetBuildercodeRewardsBalanceResponse, GetBuildercodesConfigResponse, ListBuildercodePayoutsParams, ListBuildercodePayoutsResponse, } from "./responses";
71
+ export { BuildercodePayoutSchema, BuildercodePayoutTokenTotalSchema, BuildercodeRewardsBalanceSchema, ClaimBuildercodeRewardsParamsSchema, ClaimBuildercodeRewardsResponseSchema, GetBuildercodePayoutSummaryResponseSchema, GetBuildercodeRewardsBalanceResponseSchema, GetBuildercodesConfigResponseSchema, ListBuildercodePayoutsParamsSchema, ListBuildercodePayoutsResponseSchema, } from "./responses";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * BuilderCodes Types
3
+ *
4
+ * Types for the BuilderCodes API: reading and claiming an enrolled frontend's
5
+ * per-trade revenue share.
6
+ */
7
+ export { BuildercodePayoutSchema, BuildercodePayoutTokenTotalSchema, BuildercodeRewardsBalanceSchema, ClaimBuildercodeRewardsParamsSchema, ClaimBuildercodeRewardsResponseSchema, GetBuildercodePayoutSummaryResponseSchema, GetBuildercodeRewardsBalanceResponseSchema, GetBuildercodesConfigResponseSchema, ListBuildercodePayoutsParamsSchema, ListBuildercodePayoutsResponseSchema, } from "./responses";
@@ -0,0 +1,94 @@
1
+ /**
2
+ * BuilderCodes Response Types
3
+ *
4
+ * Types for the BuilderCodes earnings and payout API responses and requests.
5
+ * All types are derived from Zod schemas for runtime validation.
6
+ */
7
+ import { z } from "zod";
8
+ /** Schema for this frontend's current BuilderCodes program state. */
9
+ export declare const GetBuildercodesConfigResponseSchema: z.ZodObject<{
10
+ applicationId: z.ZodString;
11
+ enrolled: z.ZodBoolean;
12
+ payoutAddress: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ buildercodesEnabled: z.ZodBoolean;
14
+ buildercodesBudgetBps: z.ZodNumber;
15
+ }, z.core.$strip>;
16
+ /** Pagination accepted by the per-trade payout history endpoint. */
17
+ export declare const ListBuildercodePayoutsParamsSchema: z.ZodObject<{
18
+ page: z.ZodOptional<z.ZodNumber>;
19
+ pageSize: z.ZodOptional<z.ZodNumber>;
20
+ }, z.core.$strip>;
21
+ /** One per-trade BuilderCodes credit. Amounts are RAW atomic units. */
22
+ export declare const BuildercodePayoutSchema: z.ZodObject<{
23
+ tradeId: z.ZodString;
24
+ payoutAddress: z.ZodString;
25
+ token: z.ZodString;
26
+ amount: z.ZodString;
27
+ appliedBps: z.ZodNumber;
28
+ createdAt: z.ZodString;
29
+ }, z.core.$strip>;
30
+ /** Schema for the paginated per-trade payout history. */
31
+ export declare const ListBuildercodePayoutsResponseSchema: z.ZodObject<{
32
+ payouts: z.ZodArray<z.ZodObject<{
33
+ tradeId: z.ZodString;
34
+ payoutAddress: z.ZodString;
35
+ token: z.ZodString;
36
+ amount: z.ZodString;
37
+ appliedBps: z.ZodNumber;
38
+ createdAt: z.ZodString;
39
+ }, z.core.$strip>>;
40
+ total: z.ZodNumber;
41
+ page: z.ZodNumber;
42
+ pageSize: z.ZodNumber;
43
+ totalPages: z.ZodNumber;
44
+ }, z.core.$strip>;
45
+ /** One token-denominated BuilderCodes earnings total. */
46
+ export declare const BuildercodePayoutTokenTotalSchema: z.ZodObject<{
47
+ token: z.ZodString;
48
+ totalAmount: z.ZodString;
49
+ payoutCount: z.ZodNumber;
50
+ lastCreditedAt: z.ZodString;
51
+ }, z.core.$strip>;
52
+ /** Schema for this frontend's payout summary. */
53
+ export declare const GetBuildercodePayoutSummaryResponseSchema: z.ZodObject<{
54
+ totalPayouts: z.ZodNumber;
55
+ lastCreditedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
56
+ byToken: z.ZodArray<z.ZodObject<{
57
+ token: z.ZodString;
58
+ totalAmount: z.ZodString;
59
+ payoutCount: z.ZodNumber;
60
+ lastCreditedAt: z.ZodString;
61
+ }, z.core.$strip>>;
62
+ }, z.core.$strip>;
63
+ /** One available balance in the reserved BuilderCodes reward bucket. */
64
+ export declare const BuildercodeRewardsBalanceSchema: z.ZodObject<{
65
+ token: z.ZodString;
66
+ available: z.ZodString;
67
+ }, z.core.$strip>;
68
+ /** Schema for the caller wallet's reserved BuilderCodes balances. */
69
+ export declare const GetBuildercodeRewardsBalanceResponseSchema: z.ZodObject<{
70
+ balances: z.ZodArray<z.ZodObject<{
71
+ token: z.ZodString;
72
+ available: z.ZodString;
73
+ }, z.core.$strip>>;
74
+ }, z.core.$strip>;
75
+ /** Schema for the claim-BuilderCodes-rewards request body. */
76
+ export declare const ClaimBuildercodeRewardsParamsSchema: z.ZodObject<{
77
+ token: z.ZodString;
78
+ amount: z.ZodString;
79
+ }, z.core.$strip>;
80
+ /** Schema for the claim-BuilderCodes-rewards response. */
81
+ export declare const ClaimBuildercodeRewardsResponseSchema: z.ZodObject<{
82
+ payoutBalance: z.ZodString;
83
+ tradingBalance: z.ZodString;
84
+ }, z.core.$strip>;
85
+ export type ClaimBuildercodeRewardsParams = z.infer<typeof ClaimBuildercodeRewardsParamsSchema>;
86
+ export type ClaimBuildercodeRewardsResponse = z.infer<typeof ClaimBuildercodeRewardsResponseSchema>;
87
+ export type GetBuildercodesConfigResponse = z.infer<typeof GetBuildercodesConfigResponseSchema>;
88
+ export type ListBuildercodePayoutsParams = z.infer<typeof ListBuildercodePayoutsParamsSchema>;
89
+ export type BuildercodePayout = z.infer<typeof BuildercodePayoutSchema>;
90
+ export type ListBuildercodePayoutsResponse = z.infer<typeof ListBuildercodePayoutsResponseSchema>;
91
+ export type BuildercodePayoutTokenTotal = z.infer<typeof BuildercodePayoutTokenTotalSchema>;
92
+ export type GetBuildercodePayoutSummaryResponse = z.infer<typeof GetBuildercodePayoutSummaryResponseSchema>;
93
+ export type BuildercodeRewardsBalance = z.infer<typeof BuildercodeRewardsBalanceSchema>;
94
+ export type GetBuildercodeRewardsBalanceResponse = z.infer<typeof GetBuildercodeRewardsBalanceResponseSchema>;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * BuilderCodes Response Types
3
+ *
4
+ * Types for the BuilderCodes earnings and payout API responses and requests.
5
+ * All types are derived from Zod schemas for runtime validation.
6
+ */
7
+ import { z } from "zod";
8
+ /** Schema for this frontend's current BuilderCodes program state. */
9
+ export const GetBuildercodesConfigResponseSchema = z.object({
10
+ applicationId: z.string().uuid(),
11
+ enrolled: z.boolean(),
12
+ // Nullable, not merely absent: `payout_address` is an `optional` proto field
13
+ // with no skip-serializing, so the server sends an explicit `null` when no
14
+ // address is configured. `.optional()` alone accepts `undefined` and would
15
+ // throw on that valid response. Matches `lastCreditedAt` below.
16
+ payoutAddress: z.string().nullable().optional(),
17
+ buildercodesEnabled: z.boolean(),
18
+ buildercodesBudgetBps: z.number().int().min(0).max(10_000),
19
+ });
20
+ /** Pagination accepted by the per-trade payout history endpoint. */
21
+ export const ListBuildercodePayoutsParamsSchema = z.object({
22
+ page: z.number().int().min(1).max(10_000).optional(),
23
+ pageSize: z.number().int().min(1).max(100).optional(),
24
+ });
25
+ /** One per-trade BuilderCodes credit. Amounts are RAW atomic units. */
26
+ export const BuildercodePayoutSchema = z.object({
27
+ tradeId: z.string().uuid(),
28
+ payoutAddress: z.string(),
29
+ token: z.string(),
30
+ amount: z.string(),
31
+ appliedBps: z.number().int(),
32
+ createdAt: z.string(),
33
+ });
34
+ /** Schema for the paginated per-trade payout history. */
35
+ export const ListBuildercodePayoutsResponseSchema = z.object({
36
+ payouts: z.array(BuildercodePayoutSchema),
37
+ total: z.number().int().nonnegative(),
38
+ page: z.number().int().positive(),
39
+ pageSize: z.number().int().positive(),
40
+ totalPages: z.number().int().nonnegative(),
41
+ });
42
+ /** One token-denominated BuilderCodes earnings total. */
43
+ export const BuildercodePayoutTokenTotalSchema = z.object({
44
+ token: z.string(),
45
+ totalAmount: z.string(),
46
+ payoutCount: z.number().int().nonnegative(),
47
+ lastCreditedAt: z.string(),
48
+ });
49
+ /** Schema for this frontend's payout summary. */
50
+ export const GetBuildercodePayoutSummaryResponseSchema = z.object({
51
+ totalPayouts: z.number().int().nonnegative(),
52
+ lastCreditedAt: z.string().nullable().optional(),
53
+ byToken: z.array(BuildercodePayoutTokenTotalSchema),
54
+ });
55
+ /** One available balance in the reserved BuilderCodes reward bucket. */
56
+ export const BuildercodeRewardsBalanceSchema = z.object({
57
+ token: z.string(),
58
+ available: z.string(),
59
+ });
60
+ /** Schema for the caller wallet's reserved BuilderCodes balances. */
61
+ export const GetBuildercodeRewardsBalanceResponseSchema = z.object({
62
+ balances: z.array(BuildercodeRewardsBalanceSchema),
63
+ });
64
+ /** Schema for the claim-BuilderCodes-rewards request body. */
65
+ export const ClaimBuildercodeRewardsParamsSchema = z.object({
66
+ /**
67
+ * Payout token contract address (0x-prefixed) to claim. BuilderCodes shares
68
+ * accrue in the quote token of the traded pair.
69
+ */
70
+ token: z
71
+ .string()
72
+ .trim()
73
+ .min(1, "token is required")
74
+ .regex(/^0x[0-9a-fA-F]{40}$/, "token must be a 0x-prefixed EVM address"),
75
+ /**
76
+ * Amount to claim, in RAW atomic units of the token. Must be a positive
77
+ * integer string and no greater than the accrued payout balance — the server
78
+ * rejects an over-claim with 409 rather than moving a partial amount.
79
+ */
80
+ amount: z
81
+ .string()
82
+ .trim()
83
+ .min(1, "amount is required")
84
+ .refine((v) => /^\d+$/.test(v) && BigInt(v) > 0n, "amount must be a positive integer string"),
85
+ });
86
+ /** Schema for the claim-BuilderCodes-rewards response. */
87
+ export const ClaimBuildercodeRewardsResponseSchema = z.object({
88
+ /** Your BuilderCodes payout-bucket balance after the claim, RAW atomic units. */
89
+ payoutBalance: z.string(),
90
+ /** Your trading balance for the token after the claim, RAW atomic units. */
91
+ tradingBalance: z.string(),
92
+ });
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  export * from "./api";
8
8
  export * from "./applications";
9
9
  export * from "./auth";
10
+ export * from "./buildercodes";
10
11
  export * from "./contracts";
11
12
  export * from "./delegated-agents";
12
13
  export * from "./faucet";
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@
8
8
  export * from "./api";
9
9
  export * from "./applications";
10
10
  export * from "./auth";
11
+ export * from "./buildercodes";
11
12
  export * from "./contracts";
12
13
  export * from "./delegated-agents";
13
14
  export * from "./faucet";
@@ -107,6 +107,38 @@ export interface Position {
107
107
  * an understated partial.
108
108
  */
109
109
  cumFees?: string;
110
+ /**
111
+ * Opaque, non-negative producer-owned row version for this position
112
+ * (0XM-2673). Compare only within the same `positionId`; higher is newer.
113
+ *
114
+ * The same number the WebSocket `positions` snapshot and a RANKED live
115
+ * `position_update` frame carry, so this read can be ranked against them.
116
+ * Some live frames are deliberately unranked and omit `version` even when
117
+ * their state matches this row.
118
+ * `0` is the unranked legacy sentinel and never participates in ordering:
119
+ * treat it exactly as an absent version and fall back to a full field
120
+ * comparison rather than ranking it as oldest.
121
+ *
122
+ * The merge rule is PER FIELD GROUP, never per payload. On an EQUAL version
123
+ * skip the versioned fields as an idempotent redelivery — EXCEPT
124
+ * `isolatedMargin`, which the WebSocket positions snapshot overlays from an
125
+ * independent live matching-engine read rather than from the versioned row,
126
+ * so it can reflect a later command than the version names and must be
127
+ * taken from the newer payload. Also still take
128
+ * `markPrice`, `unrealizedPnl`, `liquidationPrice`, `leverage`,
129
+ * `maintenanceMarginRequired` and `initialMarginRequired` from the newer
130
+ * payload: those six are re-derived on every read rather than served from
131
+ * the versioned row, carry no version, and the version does not advance for
132
+ * them. Five move with the oracle mark; `leverage` does not, but the live
133
+ * surfaces derive it while the persisted row serves its stored column, so it
134
+ * can still disagree at an unchanged version.
135
+ * Discarding a whole payload on an equal version freezes displayed PnL
136
+ * until the position's next real mutation.
137
+ *
138
+ * A response served from live matching-engine state reports `0`: the engine
139
+ * holds the state but not the version, so it cannot rank itself.
140
+ */
141
+ version?: number;
110
142
  }
111
143
  export interface ListPositionsParams {
112
144
  marginAccountId?: string;
@@ -1,6 +1,7 @@
1
1
  import type { Address, PublicClient, TransactionReceipt, WalletClient } from "viem";
2
2
  import type { ApplicationsAPI } from "../applications";
3
3
  import type { AuthAPI, AuthState } from "../auth/index";
4
+ import type { BuildercodesAPI } from "../buildercodes";
4
5
  import type { DelegatedAgentsAPI } from "../delegated-agents";
5
6
  import type { FaucetAPI } from "../faucet";
6
7
  import type { FeesAPI } from "../fees";
@@ -111,6 +112,8 @@ export interface MonacoSDK {
111
112
  subAccounts: SubAccountsAPI;
112
113
  /** PitPass TraderCode referral and rewards API */
113
114
  pitpass: PitpassAPI;
115
+ /** BuilderCodes frontend revenue-share payout API */
116
+ buildercodes: BuildercodesAPI;
114
117
  /** Testnet faucet API */
115
118
  faucet: FaucetAPI;
116
119
  /** Deposit-address registration (sweeper) API; requires a session */
@@ -8,6 +8,7 @@
8
8
  * Detected broadcast lag closes the connection with 1013 and requires resync.
9
9
  * A lost terminal position update need not have a later replacement.
10
10
  */
11
+ import type { MarginMode } from "../../margin-accounts";
11
12
  /**
12
13
  * Position side. The server emits `LONG` or `SHORT` for an open position.
13
14
  */
@@ -55,6 +56,50 @@ export interface PositionEventData {
55
56
  isolatedMargin: string;
56
57
  /** Effective leverage (decimal string) */
57
58
  leverage: string;
59
+ /**
60
+ * Risk bucket that scopes this position's margin (UUID) — the same
61
+ * `riskBucketId` REST returns (0XM-2668). Omitted only for a legacy
62
+ * unbucketed position, and on a terminal frame whose close came back through
63
+ * the durable log rather than in-band.
64
+ */
65
+ riskBucketId?: string;
66
+ /**
67
+ * Margin mode of `riskBucketId`: `CROSS` or `ISOLATED`, the same `marginMode`
68
+ * REST returns (0XM-2668). Omitted for a position with no risk bucket, since
69
+ * there is then no mode to report.
70
+ *
71
+ * Do NOT infer it from `riskBucketId` in either direction. The two are
72
+ * resolved from different sources — the bucket id from the position, the mode
73
+ * from the risk engine when it holds the position and from the bucket row
74
+ * otherwise — so an id can arrive with no mode: a terminal row whose bucket
75
+ * record is unavailable, a read taken while the engine is unreachable, or a
76
+ * producer older than this field. Treat a missing mode as unknown and leave
77
+ * the position's mode unchanged; defaulting it to `CROSS` mis-renders an
78
+ * isolated position's backing.
79
+ *
80
+ * VERSIONED: a position's mode changes only on a real mutation, never on an
81
+ * oracle tick. See `version`.
82
+ */
83
+ marginMode?: MarginMode | (string & {});
84
+ /**
85
+ * Maintenance margin this position requires at `markPrice` (decimal string),
86
+ * the same `maintenanceMarginRequired` REST returns (0XM-2668). `"0"` when
87
+ * the position has no open exposure, so a terminal frame reports zero rather
88
+ * than omitting it.
89
+ *
90
+ * UNVERSIONED: re-derived from the oracle mark on every frame. See `version`
91
+ * for the whole unversioned group.
92
+ */
93
+ maintenanceMarginRequired?: string;
94
+ /**
95
+ * Initial margin this position requires at `markPrice` (decimal string),
96
+ * honoring both its effective leverage and the market initial-margin floor —
97
+ * the same `initialMarginRequired` REST returns (0XM-2668). `"0"` when the
98
+ * position has no open exposure.
99
+ *
100
+ * UNVERSIONED, for the same reason as `maintenanceMarginRequired`.
101
+ */
102
+ initialMarginRequired?: string;
58
103
  /** Trade that caused the update, when driven by a fill (UUID). Omitted otherwise. */
59
104
  tradeId?: string;
60
105
  /** Order that caused the update, when driven by an order (UUID). Omitted otherwise. */
@@ -65,8 +110,77 @@ export interface PositionEventData {
65
110
  * `margin_reduced`, `margin_collateral_transfer`.
66
111
  */
67
112
  reason: string;
68
- /** Timestamp when the position state was updated (ISO 8601) */
113
+ /**
114
+ * When the position was last MUTATED (ISO 8601) — a fill, collateral
115
+ * transfer, funding settlement or close.
116
+ *
117
+ * Read from the producer's own record of the mutation, never stamped while
118
+ * the frame is serialized (0XM-2668), so two frames for a position nothing
119
+ * has changed repeat one timestamp and a valuation-only oracle reprice does
120
+ * not move it. Do not use it as a reconciliation key — that is `version`'s
121
+ * job; this is display metadata.
122
+ *
123
+ * It matches a REST read of the same OPEN position exactly. Two cases come
124
+ * from the server's persistence clock instead and differ by the persistence
125
+ * lag: a TERMINAL row (this frame carries the engine's close instant, a
126
+ * terminal REST read carries the stored one), and any position read after a
127
+ * matching-engine restart. Accurate to that lag, not to the microsecond.
128
+ *
129
+ * A third case is not lag-bounded: while the server's matching engine is
130
+ * unreachable, a REST read of an OPEN position falls back to that row's
131
+ * lifecycle timestamps and can report the position's opening instant until
132
+ * funding settles. This frame is unaffected — it is built from engine state
133
+ * — so a REST value OLDER than a frame you already hold is expected during
134
+ * that window, and the frame is the fresher one.
135
+ */
69
136
  updatedAt: string;
137
+ /**
138
+ * Opaque, non-negative producer-owned row version for this position
139
+ * (0XM-2673). Compare only within the same `positionId`; higher is newer.
140
+ *
141
+ * Carried on RANKED live frames and on the subscribe-time `positions`
142
+ * snapshot, so a client can rank the two against each other on
143
+ * `positionId + version`. Not every live frame is ranked — see below — so
144
+ * an unranked frame is not comparable with a snapshot row even when their
145
+ * state matches.
146
+ * Absent means UNRANKED, never "oldest", and it does NOT tell you whether
147
+ * anything was persisted. Four cases reach it: the frame came from a
148
+ * producer that predates this field; the emit path wrote no row;
149
+ * the path DID write the row but re-reads live risk state after sequencing
150
+ * (funding, `margin_added`/`margin_reduced`), so the mutation did advance
151
+ * the persisted version; or the frame is a different projection of the row
152
+ * than persistence stores (terminal frames report `size` 0 and
153
+ * `LIQUIDATED`, while the stored row keeps its size and records `CLOSED`).
154
+ * In the last two, a REST read or a fresh snapshot ranks the mutation.
155
+ * Fall back to a full field comparison rather than ranking it lowest.
156
+ *
157
+ * The merge rule is PER FIELD GROUP, never per frame. On a higher version
158
+ * apply everything. On an EQUAL version skip the versioned fields as an
159
+ * idempotent redelivery — EXCEPT `isolatedMargin`, which the subscribe-time
160
+ * snapshot overlays from an independent live matching-engine read rather
161
+ * than from the versioned row, so it can reflect a later command than the
162
+ * version names and must be taken from the newer payload or you retain
163
+ * stale backing. Also still take `markPrice`, `unrealizedPnl`,
164
+ * `liquidationPrice`, `leverage`, `maintenanceMarginRequired` and
165
+ * `initialMarginRequired` from the newer frame: those six are re-derived
166
+ * per frame rather than served from the versioned row, carry no version,
167
+ * and the version does not advance for them. Five move with the oracle
168
+ * mark; `leverage` does not — it is opening notional over posted margin —
169
+ * but the live surfaces derive it while a persisted read serves the row's
170
+ * stored column, so it can still disagree at an unchanged version. Discarding an equal-version frame wholesale
171
+ * freezes displayed unrealized PnL until the position's next real
172
+ * mutation — up to the one-hour funding interval.
173
+ *
174
+ * A frame is ranked only when it is a faithful projection of the row
175
+ * persisted at that sequence: in practice the FILLS THAT LEAVE A POSITION
176
+ * OPEN. Unranked are (a) frames that re-read live risk state after their
177
+ * command was sequenced, since a later command can overtake that read —
178
+ * the `funding` and `margin_added`/`margin_reduced` frames — and (b)
179
+ * TERMINAL frames, which report `size` 0 and `LIQUIDATED` while the stored
180
+ * row keeps its size and records `CLOSED`. Those mutations still advance
181
+ * the persisted version, so REST and a fresh snapshot rank them.
182
+ */
183
+ version?: number;
70
184
  }
71
185
  /**
72
186
  * Position event emitted when a user's position state changes.
@@ -10,6 +10,6 @@
10
10
  * hand-written SDK surface. CI regenerates it and fails on a diff, identical to
11
11
  * the `schema.ts` wire-types tripwire (MON-1476), so it can never go stale.
12
12
  */
13
- export declare const OPERATION_IDS: readonly ["attach_position_tp_sl", "batch_cancel_all", "batch_cancel_all_by_pair", "batch_cancel_orders", "batch_close_all_positions", "batch_create_orders", "batch_replace_orders", "cancel_conditional_order", "cancel_order", "cancel_twap_order", "check_trader_code_availability", "clear_trader_code", "close_position", "create_challenge", "create_delegated_session", "create_order", "create_sub_account_limit", "create_twap_order", "delete_sub_account_limit", "get_application_config", "get_application_stats", "get_available_collateral", "get_candles", "get_conditional_order", "get_faucet_info", "get_funding_state", "get_index_price", "get_margin_account_movements", "get_margin_account_summary", "get_mark_price", "get_market_metadata", "get_market_stats", "get_my_fee_tier", "get_my_trader_code", "get_open_interest", "get_order_by_id", "get_orderbook_snapshot", "get_orders", "get_parent_margin_account_movements", "get_parent_margin_account_summary", "get_perp_market_config", "get_perp_market_summary", "get_portfolio_assets", "get_portfolio_chart", "get_portfolio_margin", "get_portfolio_performance", "get_portfolio_realized_pnl", "get_portfolio_stats", "get_portfolio_summary", "get_position", "get_position_pnl_history", "get_position_risk", "get_pulse", "get_rewards_balance", "get_screener", "get_self_trade_prevention_default", "get_sub_account_limits", "get_sweeper_chains", "get_trade_by_id", "get_trader_code_info", "get_trades", "get_trading_pair_by_id", "get_twap_order", "get_twap_order_tca", "get_user_balance_by_asset", "get_user_balances", "get_user_movements", "get_user_profile", "get_user_trades", "get_withdrawal", "health_check", "initiate_withdrawal", "list_all_funding_history", "list_application_balances", "list_application_movements", "list_application_orders", "list_application_users", "list_conditional_orders", "list_delegated_agent_owners", "list_delegated_agents", "list_funding_history", "list_funding_payments", "list_margin_accounts", "list_pending_withdrawals", "list_position_history", "list_positions", "list_sub_accounts_with_balances", "list_trading_pairs", "list_twap_orders", "mint_tokens", "refresh_session", "register_deposit_address", "replace_order", "revoke_delegated_agent", "revoke_session", "set_self_trade_prevention_default", "set_trader_code", "simulate_fees", "simulate_order_risk", "simulate_parent_margin_order_risk", "simulate_risk_bucket_order_risk", "submit_whitelist", "transfer_collateral_from_margin_account", "transfer_collateral_from_parent_margin_account", "transfer_collateral_to_margin_account", "transfer_collateral_to_parent_margin_account", "transfer_collateral_to_risk_bucket", "transfer_rewards", "update_sub_account_limit", "upsert_delegated_agent", "verify_signature"];
13
+ export declare const OPERATION_IDS: readonly ["attach_position_tp_sl", "batch_cancel_all", "batch_cancel_all_by_pair", "batch_cancel_orders", "batch_close_all_positions", "batch_create_orders", "batch_replace_orders", "cancel_conditional_order", "cancel_order", "cancel_twap_order", "check_trader_code_availability", "claim_buildercode_rewards", "clear_trader_code", "close_position", "create_challenge", "create_delegated_session", "create_order", "create_sub_account_limit", "create_twap_order", "delete_sub_account_limit", "get_application_config", "get_application_stats", "get_available_collateral", "get_buildercode_payout_summary", "get_buildercode_rewards_balance", "get_buildercodes_config", "get_candles", "get_conditional_order", "get_faucet_info", "get_funding_state", "get_index_price", "get_margin_account_movements", "get_margin_account_summary", "get_mark_price", "get_market_metadata", "get_market_stats", "get_my_fee_tier", "get_my_trader_code", "get_open_interest", "get_order_by_id", "get_orderbook_snapshot", "get_orders", "get_parent_margin_account_movements", "get_parent_margin_account_summary", "get_perp_market_config", "get_perp_market_summary", "get_portfolio_assets", "get_portfolio_chart", "get_portfolio_margin", "get_portfolio_performance", "get_portfolio_realized_pnl", "get_portfolio_stats", "get_portfolio_summary", "get_position", "get_position_pnl_history", "get_position_risk", "get_pulse", "get_rewards_balance", "get_screener", "get_self_trade_prevention_default", "get_sub_account_limits", "get_sweeper_chains", "get_trade_by_id", "get_trader_code_info", "get_trades", "get_trading_pair_by_id", "get_twap_order", "get_twap_order_tca", "get_user_balance_by_asset", "get_user_balances", "get_user_movements", "get_user_profile", "get_user_trades", "get_withdrawal", "health_check", "initiate_withdrawal", "list_all_funding_history", "list_application_balances", "list_application_movements", "list_application_orders", "list_application_users", "list_buildercode_payouts", "list_conditional_orders", "list_delegated_agent_owners", "list_delegated_agents", "list_funding_history", "list_funding_payments", "list_margin_accounts", "list_pending_withdrawals", "list_position_history", "list_positions", "list_sub_accounts_with_balances", "list_trading_pairs", "list_twap_orders", "mint_tokens", "refresh_session", "register_deposit_address", "replace_order", "revoke_delegated_agent", "revoke_session", "set_self_trade_prevention_default", "set_trader_code", "simulate_fees", "simulate_order_risk", "simulate_parent_margin_order_risk", "simulate_risk_bucket_order_risk", "submit_whitelist", "transfer_collateral_from_margin_account", "transfer_collateral_from_parent_margin_account", "transfer_collateral_to_margin_account", "transfer_collateral_to_parent_margin_account", "transfer_collateral_to_risk_bucket", "transfer_rewards", "update_sub_account_limit", "upsert_delegated_agent", "verify_signature"];
14
14
  /** Union of every OpenAPI operationId in the spec. */
15
15
  export type OperationId = (typeof OPERATION_IDS)[number];
@@ -22,6 +22,7 @@ export const OPERATION_IDS = [
22
22
  "cancel_order",
23
23
  "cancel_twap_order",
24
24
  "check_trader_code_availability",
25
+ "claim_buildercode_rewards",
25
26
  "clear_trader_code",
26
27
  "close_position",
27
28
  "create_challenge",
@@ -33,6 +34,9 @@ export const OPERATION_IDS = [
33
34
  "get_application_config",
34
35
  "get_application_stats",
35
36
  "get_available_collateral",
37
+ "get_buildercode_payout_summary",
38
+ "get_buildercode_rewards_balance",
39
+ "get_buildercodes_config",
36
40
  "get_candles",
37
41
  "get_conditional_order",
38
42
  "get_faucet_info",
@@ -88,6 +92,7 @@ export const OPERATION_IDS = [
88
92
  "list_application_movements",
89
93
  "list_application_orders",
90
94
  "list_application_users",
95
+ "list_buildercode_payouts",
91
96
  "list_conditional_orders",
92
97
  "list_delegated_agent_owners",
93
98
  "list_delegated_agents",