@mysten/deepbook-v3 2.6.4 → 2.8.0
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/CHANGELOG.md +153 -0
- package/PREDICT.md +389 -61
- package/dist/contracts/account/account.d.mts +23 -23
- package/dist/contracts/account/account.d.mts.map +1 -1
- package/dist/contracts/account/account_registry.d.mts +13 -13
- package/dist/contracts/deepbook/account.d.mts +18 -18
- package/dist/contracts/deepbook/balances.d.mts +4 -4
- package/dist/contracts/deepbook/deep_price.d.mts +3 -3
- package/dist/contracts/deepbook/order.d.mts +12 -12
- package/dist/contracts/deepbook_predict/admin.d.mts +4 -4
- package/dist/contracts/deepbook_predict/builder_code.d.mts +11 -11
- package/dist/contracts/deepbook_predict/builder_code_events.d.mts +10 -10
- package/dist/contracts/deepbook_predict/config_events.d.mts +93 -68
- package/dist/contracts/deepbook_predict/config_events.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/config_events.mjs +45 -1
- package/dist/contracts/deepbook_predict/config_events.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/deps/std/type_name.mjs +17 -0
- package/dist/contracts/deepbook_predict/deps/std/type_name.mjs.map +1 -0
- package/dist/contracts/deepbook_predict/expiry_market.d.mts +652 -235
- package/dist/contracts/deepbook_predict/expiry_market.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/expiry_market.mjs +652 -186
- package/dist/contracts/deepbook_predict/expiry_market.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/lp_book.mjs +1 -1
- package/dist/contracts/deepbook_predict/market_lifecycle_cap.d.mts +5 -5
- package/dist/contracts/deepbook_predict/market_manager.d.mts +27 -27
- package/dist/contracts/deepbook_predict/order_events.d.mts +50 -50
- package/dist/contracts/deepbook_predict/order_events.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/order_events.mjs +3 -1
- package/dist/contracts/deepbook_predict/order_events.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/pause_cap.d.mts +5 -5
- package/dist/contracts/deepbook_predict/plp.d.mts +184 -82
- package/dist/contracts/deepbook_predict/plp.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/plp.mjs +126 -7
- package/dist/contracts/deepbook_predict/plp.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/pool_accounting.mjs +1 -1
- package/dist/contracts/deepbook_predict/pool_valuation_cap.d.mts +5 -5
- package/dist/contracts/deepbook_predict/predict_account.d.mts +14 -14
- package/dist/contracts/deepbook_predict/pricing.d.mts +91 -58
- package/dist/contracts/deepbook_predict/pricing.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/pricing.mjs +30 -3
- package/dist/contracts/deepbook_predict/pricing.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/pricing_config.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/protocol_config.d.mts +400 -92
- package/dist/contracts/deepbook_predict/protocol_config.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/protocol_config.mjs +451 -61
- package/dist/contracts/deepbook_predict/protocol_config.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/range_codec.d.mts +2 -2
- package/dist/contracts/deepbook_predict/registry.d.mts +28 -28
- package/dist/contracts/deepbook_predict/strike_exposure.mjs +1 -1
- package/dist/contracts/deepbook_predict/strike_payout_tree.mjs +17 -12
- package/dist/contracts/deepbook_predict/strike_payout_tree.mjs.map +1 -1
- package/dist/contracts/deepbook_predict/vault_events.d.mts +154 -106
- package/dist/contracts/deepbook_predict/vault_events.d.mts.map +1 -1
- package/dist/contracts/deepbook_predict/vault_events.mjs +57 -1
- package/dist/contracts/deepbook_predict/vault_events.mjs.map +1 -1
- package/dist/contracts/deepbook_predict_math/config-arguments.d.mts +10 -0
- package/dist/contracts/deepbook_predict_math/config-arguments.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_math/lazer_price.d.mts +106 -0
- package/dist/contracts/deepbook_predict_math/lazer_price.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_math/lazer_price.mjs +125 -0
- package/dist/contracts/deepbook_predict_math/lazer_price.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_math/math.d.mts +284 -0
- package/dist/contracts/deepbook_predict_math/math.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_math/math.mjs +364 -0
- package/dist/contracts/deepbook_predict_math/math.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/config-arguments.d.mts +13 -0
- package/dist/contracts/deepbook_predict_orders/config-arguments.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/delayed_execution_config.d.mts +215 -0
- package/dist/contracts/deepbook_predict_orders/delayed_execution_config.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/delayed_execution_config.mjs +215 -0
- package/dist/contracts/deepbook_predict_orders/delayed_execution_config.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.mjs +87 -0
- package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.mjs +52 -0
- package/dist/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/deps/fixed_math/i64.mjs +25 -0
- package/dist/contracts/deepbook_predict_orders/deps/fixed_math/i64.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/deps/sui/balance.mjs +21 -0
- package/dist/contracts/deepbook_predict_orders/deps/sui/balance.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/deps/sui/table.mjs +39 -0
- package/dist/contracts/deepbook_predict_orders/deps/sui/table.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/desk.d.mts +187 -0
- package/dist/contracts/deepbook_predict_orders/desk.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/desk.mjs +261 -0
- package/dist/contracts/deepbook_predict_orders/desk.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/order_queue.d.mts +1042 -0
- package/dist/contracts/deepbook_predict_orders/order_queue.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/order_queue.mjs +849 -0
- package/dist/contracts/deepbook_predict_orders/order_queue.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/queue.d.mts +683 -0
- package/dist/contracts/deepbook_predict_orders/queue.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/queue.mjs +912 -0
- package/dist/contracts/deepbook_predict_orders/queue.mjs.map +1 -0
- package/dist/contracts/deepbook_predict_orders/queue_events.d.mts +195 -0
- package/dist/contracts/deepbook_predict_orders/queue_events.d.mts.map +1 -0
- package/dist/contracts/deepbook_predict_orders/queue_events.mjs +187 -0
- package/dist/contracts/deepbook_predict_orders/queue_events.mjs.map +1 -0
- package/dist/contracts/deepbook_sessions/session_config.d.mts +8 -8
- package/dist/contracts/deepbook_sessions/sessions.d.mts +163 -28
- package/dist/contracts/deepbook_sessions/sessions.d.mts.map +1 -1
- package/dist/contracts/deepbook_sessions/sessions.mjs +234 -5
- package/dist/contracts/deepbook_sessions/sessions.mjs.map +1 -1
- package/dist/deployments/mainnet.mjs +7 -4
- package/dist/deployments/mainnet.mjs.map +1 -1
- package/dist/deployments/testnet.mjs +7 -4
- package/dist/deployments/testnet.mjs.map +1 -1
- package/dist/predict/bindings/expiry-market.d.mts +77 -0
- package/dist/predict/bindings/expiry-market.d.mts.map +1 -0
- package/dist/predict/bindings/expiry-market.mjs +139 -0
- package/dist/predict/bindings/expiry-market.mjs.map +1 -0
- package/dist/predict/bindings/protocol-config.d.mts +39 -0
- package/dist/predict/bindings/protocol-config.d.mts.map +1 -0
- package/dist/predict/bindings/protocol-config.mjs +90 -0
- package/dist/predict/bindings/protocol-config.mjs.map +1 -0
- package/dist/predict/bindings/rename.mjs +9 -0
- package/dist/predict/bindings/rename.mjs.map +1 -0
- package/dist/predict/client.d.mts +595 -16
- package/dist/predict/client.d.mts.map +1 -1
- package/dist/predict/client.mjs +986 -10
- package/dist/predict/client.mjs.map +1 -1
- package/dist/predict/config/generated.d.mts +22 -1
- package/dist/predict/config/generated.d.mts.map +1 -1
- package/dist/predict/config/generated.mjs +30 -1
- package/dist/predict/config/generated.mjs.map +1 -1
- package/dist/predict/config/mainnet.mjs +11 -3
- package/dist/predict/config/mainnet.mjs.map +1 -1
- package/dist/predict/config/testnet.mjs +11 -3
- package/dist/predict/config/testnet.mjs.map +1 -1
- package/dist/predict/config/types.d.mts +50 -1
- package/dist/predict/config/types.d.mts.map +1 -1
- package/dist/predict/cost.d.mts +38 -11
- package/dist/predict/cost.d.mts.map +1 -1
- package/dist/predict/cost.mjs +37 -11
- package/dist/predict/cost.mjs.map +1 -1
- package/dist/predict/decode.d.mts +251 -1
- package/dist/predict/decode.d.mts.map +1 -1
- package/dist/predict/decode.mjs +342 -4
- package/dist/predict/decode.mjs.map +1 -1
- package/dist/predict/errors.d.mts +69 -6
- package/dist/predict/errors.d.mts.map +1 -1
- package/dist/predict/errors.mjs +277 -4
- package/dist/predict/errors.mjs.map +1 -1
- package/dist/predict/index.d.mts +21 -10
- package/dist/predict/index.mjs +24 -12
- package/dist/predict/queue-id.d.mts +13 -0
- package/dist/predict/queue-id.d.mts.map +1 -0
- package/dist/predict/queue-id.mjs +19 -0
- package/dist/predict/queue-id.mjs.map +1 -0
- package/dist/predict/queue.d.mts +505 -0
- package/dist/predict/queue.d.mts.map +1 -0
- package/dist/predict/queue.mjs +774 -0
- package/dist/predict/queue.mjs.map +1 -0
- package/dist/predict/reads/balances.mjs +1 -1
- package/dist/predict/reads/markets.mjs +46 -5
- package/dist/predict/reads/markets.mjs.map +1 -1
- package/dist/predict/reads/pool.mjs +1 -1
- package/dist/predict/reads/pricing.d.mts +1 -1
- package/dist/predict/reads/queue.d.mts +105 -0
- package/dist/predict/reads/queue.d.mts.map +1 -0
- package/dist/predict/reads/queue.mjs +445 -0
- package/dist/predict/reads/queue.mjs.map +1 -0
- package/dist/predict/ticks.d.mts +9 -1
- package/dist/predict/ticks.d.mts.map +1 -1
- package/dist/predict/ticks.mjs +18 -1
- package/dist/predict/ticks.mjs.map +1 -1
- package/dist/predict/tx/authed.mjs +1 -1
- package/dist/predict/tx/common.d.mts.map +1 -1
- package/dist/predict/tx/common.mjs +12 -1
- package/dist/predict/tx/common.mjs.map +1 -1
- package/dist/predict/tx/queue.d.mts +220 -0
- package/dist/predict/tx/queue.d.mts.map +1 -0
- package/dist/predict/tx/queue.mjs +399 -0
- package/dist/predict/tx/queue.mjs.map +1 -0
- package/dist/predict/tx/trade.d.mts.map +1 -1
- package/dist/predict/tx/trade.mjs +61 -43
- package/dist/predict/tx/trade.mjs.map +1 -1
- package/dist/sessions.d.mts +90 -2
- package/dist/sessions.d.mts.map +1 -1
- package/dist/sessions.mjs +107 -2
- package/dist/sessions.mjs.map +1 -1
- package/dist/transactions/balanceManager.d.mts +12 -12
- package/dist/transactions/balanceManager.d.mts.map +1 -1
- package/dist/transactions/deepbook.d.mts +20 -20
- package/dist/transactions/deepbook.d.mts.map +1 -1
- package/dist/transactions/deepbookAdmin.d.mts +4 -4
- package/dist/transactions/deepbookAdmin.d.mts.map +1 -1
- package/dist/transactions/marginAdmin.d.mts +7 -7
- package/dist/transactions/marginAdmin.d.mts.map +1 -1
- package/dist/transactions/marginLiquidations.d.mts +3 -3
- package/dist/transactions/marginMaintainer.d.mts +5 -5
- package/dist/transactions/marginMaintainer.d.mts.map +1 -1
- package/dist/transactions/marginManager.d.mts +32 -32
- package/dist/transactions/marginManager.d.mts.map +1 -1
- package/dist/transactions/marginPool.d.mts +18 -18
- package/dist/transactions/marginRegistry.d.mts +16 -16
- package/dist/transactions/marginTPSL.d.mts +10 -10
- package/dist/transactions/marginTPSL.d.mts.map +1 -1
- package/dist/transactions/poolProxy.d.mts +8 -8
- package/dist/transactions/poolProxy.d.mts.map +1 -1
- package/package.json +4 -4
- package/src/contracts/deepbook_predict/config_events.ts +39 -0
- package/src/contracts/deepbook_predict/deps/std/type_name.ts +24 -0
- package/src/contracts/deepbook_predict/expiry_market.ts +960 -169
- package/src/contracts/deepbook_predict/order_events.ts +3 -1
- package/src/contracts/deepbook_predict/plp.ts +150 -9
- package/src/contracts/deepbook_predict/pricing.ts +46 -7
- package/src/contracts/deepbook_predict/pricing_config.ts +3 -1
- package/src/contracts/deepbook_predict/protocol_config.ts +648 -33
- package/src/contracts/deepbook_predict/strike_payout_tree.ts +25 -21
- package/src/contracts/deepbook_predict/vault_events.ts +65 -0
- package/src/contracts/deepbook_predict_math/config-arguments.ts +6 -0
- package/src/contracts/deepbook_predict_math/lazer_price.ts +196 -0
- package/src/contracts/deepbook_predict_math/math.ts +553 -0
- package/src/contracts/deepbook_predict_orders/config-arguments.ts +11 -0
- package/src/contracts/deepbook_predict_orders/delayed_execution_config.ts +430 -0
- package/src/contracts/deepbook_predict_orders/deps/deepbook_predict/expiry_market.ts +108 -0
- package/src/contracts/deepbook_predict_orders/deps/deepbook_predict/pricing.ts +58 -0
- package/src/contracts/deepbook_predict_orders/deps/fixed_math/i64.ts +21 -0
- package/src/contracts/deepbook_predict_orders/deps/sui/balance.ts +19 -0
- package/src/contracts/deepbook_predict_orders/deps/sui/table.ts +37 -0
- package/src/contracts/deepbook_predict_orders/desk.ts +419 -0
- package/src/contracts/deepbook_predict_orders/order_flow.ts +19 -0
- package/src/contracts/deepbook_predict_orders/order_queue.ts +1670 -0
- package/src/contracts/deepbook_predict_orders/queue.ts +1394 -0
- package/src/contracts/deepbook_predict_orders/queue_events.ts +189 -0
- package/src/contracts/deepbook_sessions/sessions.ts +355 -4
- package/src/deployments/mainnet.ts +7 -2
- package/src/deployments/testnet.ts +7 -2
- package/src/deployments/types.ts +14 -1
- package/src/predict/bindings/expiry-market.ts +127 -0
- package/src/predict/bindings/protocol-config.ts +59 -0
- package/src/predict/bindings/rename.ts +14 -0
- package/src/predict/client.ts +2076 -13
- package/src/predict/config/generated.ts +50 -0
- package/src/predict/config/mainnet.ts +16 -2
- package/src/predict/config/testnet.ts +16 -2
- package/src/predict/config/types.ts +51 -1
- package/src/predict/cost.ts +62 -14
- package/src/predict/decode.ts +691 -2
- package/src/predict/errors.ts +391 -14
- package/src/predict/index.ts +87 -6
- package/src/predict/queue-id.ts +22 -0
- package/src/predict/queue.ts +1231 -0
- package/src/predict/reads/markets.ts +30 -0
- package/src/predict/reads/queue.ts +606 -0
- package/src/predict/ticks.ts +35 -0
- package/src/predict/tx/common.ts +25 -1
- package/src/predict/tx/queue.ts +525 -0
- package/src/predict/tx/trade.ts +80 -49
- package/src/sessions.ts +206 -1
package/src/predict/decode.ts
CHANGED
|
@@ -4,9 +4,23 @@ import { fromBase64, normalizeSuiAddress } from '@mysten/sui/utils';
|
|
|
4
4
|
import type { PredictConfig } from './config/index.js';
|
|
5
5
|
import { accountEvents } from '../account.js';
|
|
6
6
|
import * as builderCodeEvents from '../contracts/deepbook_predict/builder_code_events.js';
|
|
7
|
+
import * as configEvents from '../contracts/deepbook_predict/config_events.js';
|
|
7
8
|
import * as orderEvents from '../contracts/deepbook_predict/order_events.js';
|
|
8
9
|
import * as vaultEvents from '../contracts/deepbook_predict/vault_events.js';
|
|
10
|
+
import * as queueEvents from '../contracts/deepbook_predict_orders/queue_events.js';
|
|
9
11
|
import { PredictInputError } from './errors.js';
|
|
12
|
+
import {
|
|
13
|
+
isMintKind,
|
|
14
|
+
isSellKind,
|
|
15
|
+
orderKindName,
|
|
16
|
+
policyFromBcs,
|
|
17
|
+
refundReason,
|
|
18
|
+
type DelayedExecutionPolicy,
|
|
19
|
+
type HeldPosition,
|
|
20
|
+
type OrderKindName,
|
|
21
|
+
type RefundReasonInfo,
|
|
22
|
+
} from './queue.js';
|
|
23
|
+
import { decodeOrderRange } from './cost.js';
|
|
10
24
|
import { fromRaw } from './units.js';
|
|
11
25
|
|
|
12
26
|
// ============================================================================
|
|
@@ -20,7 +34,7 @@ import { fromRaw } from './units.js';
|
|
|
20
34
|
// Decoding uses each event's BCS bytes, not its `json`: the client typings
|
|
21
35
|
// warn the JSON rendering varies across transports (JSON-RPC/gRPC/GraphQL),
|
|
22
36
|
// while BCS is canonical. Layouts come from the GENERATED event MoveStructs
|
|
23
|
-
// (src/contracts/{deepbook_predict,account}/*_events.ts), whose field order
|
|
37
|
+
// (src/contracts/{deepbook_predict,deepbook_predict_orders,account}/*_events.ts), whose field order
|
|
24
38
|
// mirrors the deployed Move — regenerate the bindings if the package changes.
|
|
25
39
|
// ============================================================================
|
|
26
40
|
|
|
@@ -51,7 +65,9 @@ function eventBytes(e: DecodableEvent): Uint8Array | null {
|
|
|
51
65
|
|
|
52
66
|
// Match by defining package + module + struct name. Events are typed by the
|
|
53
67
|
// package version that introduced their struct, not the latest Move-call target.
|
|
54
|
-
//
|
|
68
|
+
// The pre-queue events were introduced in v1 (`predictV1`); the Predict events the
|
|
69
|
+
// delayed-execution upgrade added in `predictDelayedExecution`; and the queue events
|
|
70
|
+
// in the order-flow companion's original ID (`predictOrdersV1 ?? predictOrders`).
|
|
55
71
|
function matches(e: DecodableEvent, pkg: string, module: string, name: string): boolean {
|
|
56
72
|
const tag = e.eventType ?? e.type;
|
|
57
73
|
if (tag) {
|
|
@@ -473,4 +489,677 @@ export function decodeBuilderCodeSets(
|
|
|
473
489
|
}));
|
|
474
490
|
}
|
|
475
491
|
|
|
492
|
+
// --- delayed execution (DBU-885) ---------------------------------------------
|
|
493
|
+
//
|
|
494
|
+
// Delayed execution spans two packages. The queue events and the desk's
|
|
495
|
+
// `DelayedExecutionPolicyUpdated` belong to the order-flow companion,
|
|
496
|
+
// `deepbook_predict_orders` (`queue_events`), typed by its ORIGINAL ID. A fill also emits
|
|
497
|
+
// Predict's `OrderMinted` or `LiveOrderRedeemed` (v1 layouts, `decodeMints`/`decodeRedeems`),
|
|
498
|
+
// so match events by type, never by the package a transaction called. The Predict events the
|
|
499
|
+
// delayed-execution upgrade added (`ExpiryPnlRealized`, `FlushOperatorUpdated`,
|
|
500
|
+
// `OrderFlowUpdated`) are typed by `packages.predictDelayedExecution`.
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* The defining package of the Predict types and events the delayed-execution upgrade added.
|
|
504
|
+
* Throws rather than guessing: matching against the latest package would silently decode nothing
|
|
505
|
+
* once the package is upgraded again.
|
|
506
|
+
*/
|
|
507
|
+
export function delayedExecutionOrigin(cfg: PredictConfig): string {
|
|
508
|
+
const pkg = cfg.packages.predictDelayedExecution;
|
|
509
|
+
if (!pkg) {
|
|
510
|
+
throw new PredictInputError(
|
|
511
|
+
`delayed execution isn't recorded for ${cfg.network} in this SDK version: pass a ` +
|
|
512
|
+
'`config` whose `packages.predictDelayedExecution` names the package that introduced it',
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
return pkg;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* The original ID of the order-flow companion (`deepbook_predict_orders`), which types the queue
|
|
520
|
+
* events. Throws while the config doesn't record the companion.
|
|
521
|
+
*/
|
|
522
|
+
export function predictOrdersOrigin(cfg: PredictConfig): string {
|
|
523
|
+
const pkg = cfg.packages.predictOrdersV1 ?? cfg.packages.predictOrders;
|
|
524
|
+
if (!pkg) {
|
|
525
|
+
throw new PredictInputError(
|
|
526
|
+
`the order-flow package isn't recorded for ${cfg.network} in this SDK version: pass a ` +
|
|
527
|
+
'`config` whose `packages.predictOrders` names `deepbook_predict_orders`',
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
return pkg;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function side(kind: number): 'mint' | 'sell' | 'unknown' {
|
|
534
|
+
return isMintKind(kind) ? 'mint' : isSellKind(kind) ? 'sell' : 'unknown';
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function heldPosition(
|
|
538
|
+
p: {
|
|
539
|
+
order_id: bigint;
|
|
540
|
+
root_id: bigint;
|
|
541
|
+
opened_at_ms: bigint;
|
|
542
|
+
},
|
|
543
|
+
lotSize: bigint,
|
|
544
|
+
): HeldPosition | null {
|
|
545
|
+
return p.order_id === 0n
|
|
546
|
+
? null
|
|
547
|
+
: {
|
|
548
|
+
orderId: p.order_id,
|
|
549
|
+
rootId: p.root_id,
|
|
550
|
+
openedAtMs: p.opened_at_ms,
|
|
551
|
+
quantityRaw: decodeOrderRange(p.order_id, lotSize).quantity,
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/** The market's cash figures after the call, as the queue events report them. */
|
|
556
|
+
export interface QueueCashFigures {
|
|
557
|
+
marketCash: bigint;
|
|
558
|
+
requiredCash: bigint;
|
|
559
|
+
waitingCashNeed: bigint;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/** `OrderEnqueued`: the trader's own receipt for a queued mint or sell. Drives "Placed". */
|
|
563
|
+
export interface EnqueueReceipt {
|
|
564
|
+
type: 'enqueued';
|
|
565
|
+
marketId: string;
|
|
566
|
+
/** The record ID: what `read.order`, `quoteSell` and `enqueueSell` take. Persist it. */
|
|
567
|
+
recordId: bigint;
|
|
568
|
+
accountId: string;
|
|
569
|
+
kind: number;
|
|
570
|
+
kindName: OrderKindName;
|
|
571
|
+
side: 'mint' | 'sell' | 'unknown';
|
|
572
|
+
request: {
|
|
573
|
+
lowerTick: bigint;
|
|
574
|
+
higherTick: bigint;
|
|
575
|
+
quantity: bigint;
|
|
576
|
+
maxPremium: bigint;
|
|
577
|
+
minQuantity: bigint;
|
|
578
|
+
maxCost: bigint;
|
|
579
|
+
maxProbability: bigint;
|
|
580
|
+
minProbability: bigint;
|
|
581
|
+
minProceeds: bigint;
|
|
582
|
+
};
|
|
583
|
+
/** The position a sell moved into the record. Null for a mint. */
|
|
584
|
+
position: HeldPosition | null;
|
|
585
|
+
timing: {
|
|
586
|
+
placedAtMs: bigint;
|
|
587
|
+
earliestPriceMs: bigint;
|
|
588
|
+
tauMs: bigint;
|
|
589
|
+
deadlineMs: bigint;
|
|
590
|
+
cutoffMs: bigint;
|
|
591
|
+
pythChannel: number;
|
|
592
|
+
};
|
|
593
|
+
/** The Open record a sell took its position from. Null for a mint. */
|
|
594
|
+
sourceRecordId: bigint | null;
|
|
595
|
+
builderCodeId: string | null;
|
|
596
|
+
referrerAccountId: string | null;
|
|
597
|
+
/** USDC escrowed for the premium and fees (0 for a sell). */
|
|
598
|
+
budget: number;
|
|
599
|
+
orderFee: number;
|
|
600
|
+
cash: QueueCashFigures;
|
|
601
|
+
/** `onchain_timestamp_ms`: the placement transaction's clock. */
|
|
602
|
+
timestampMs: bigint;
|
|
603
|
+
raw: { budget: bigint; orderFee: bigint; cashNeed: bigint; subsidyBound: bigint };
|
|
604
|
+
/** The volatility snapshot the fill prices with, as the generated layout parses it. */
|
|
605
|
+
vol: (typeof queueEvents.OrderEnqueued)['$inferType']['vol'];
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/** `CohortCommitted`: a price attached to the records `firstRecordId..=lastRecordId`. Drives "Priced". */
|
|
609
|
+
export interface CohortCommitReceipt {
|
|
610
|
+
type: 'cohort-committed';
|
|
611
|
+
marketId: string;
|
|
612
|
+
tauMs: bigint;
|
|
613
|
+
/** The update's envelope: τ, or the backup tick one channel tick later. */
|
|
614
|
+
tickMs: bigint;
|
|
615
|
+
firstRecordId: bigint;
|
|
616
|
+
/** Inclusive. */
|
|
617
|
+
lastRecordId: bigint;
|
|
618
|
+
/** The committed price of the cohort's first order as a float: `spotRaw / 1e9`. */
|
|
619
|
+
price: number;
|
|
620
|
+
/** The committed price, normalized to 1e9. */
|
|
621
|
+
spotRaw: bigint;
|
|
622
|
+
/** That price's own update time, in µs. */
|
|
623
|
+
generationUs: bigint;
|
|
624
|
+
pythSourceId: number;
|
|
625
|
+
pythChannel: number;
|
|
626
|
+
/** Who committed: a keeper, or any third-party filler. */
|
|
627
|
+
sender: string;
|
|
628
|
+
/** `onchain_timestamp_ms`. */
|
|
629
|
+
timestampMs: bigint;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** `QueuedOrderFilled`. Report "Filled" only from this event (or the record). */
|
|
633
|
+
export interface QueuedFillReceipt {
|
|
634
|
+
type: 'filled';
|
|
635
|
+
marketId: string;
|
|
636
|
+
recordId: bigint;
|
|
637
|
+
accountId: string;
|
|
638
|
+
kind: number;
|
|
639
|
+
side: 'mint' | 'sell' | 'unknown';
|
|
640
|
+
/** Filled quantity (mint) or closed quantity (sell). */
|
|
641
|
+
quantity: number;
|
|
642
|
+
/** Cost paid (mint) or proceeds before the order fee (sell). */
|
|
643
|
+
amount: number;
|
|
644
|
+
fees: {
|
|
645
|
+
trading: number;
|
|
646
|
+
builder: number;
|
|
647
|
+
referral: number;
|
|
648
|
+
order: number;
|
|
649
|
+
subsidyUsed: number;
|
|
650
|
+
inventoryImpact: number;
|
|
651
|
+
};
|
|
652
|
+
tauMs: bigint;
|
|
653
|
+
tickMs: bigint;
|
|
654
|
+
/** The record's position now: a mint's new position, a partial sell's remainder, or null. */
|
|
655
|
+
position: HeldPosition | null;
|
|
656
|
+
sender: string;
|
|
657
|
+
timestampMs: bigint;
|
|
658
|
+
cash: QueueCashFigures;
|
|
659
|
+
raw: {
|
|
660
|
+
quantity: bigint;
|
|
661
|
+
amount: bigint;
|
|
662
|
+
tradingFee: bigint;
|
|
663
|
+
builderFee: bigint;
|
|
664
|
+
referralFee: bigint;
|
|
665
|
+
orderFee: bigint;
|
|
666
|
+
subsidyUsed: bigint;
|
|
667
|
+
inventoryImpact: bigint;
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* `QueuedOrderRefunded`, from whichever path refunded the order: resolve, a deadline refund, an
|
|
673
|
+
* admin refund, or the settlement drain (`settle_step`, reason 5). `sender` is always the
|
|
674
|
+
* transaction's sender.
|
|
675
|
+
*/
|
|
676
|
+
export interface QueuedRefundReceipt {
|
|
677
|
+
type: 'refunded';
|
|
678
|
+
marketId: string;
|
|
679
|
+
recordId: bigint;
|
|
680
|
+
accountId: string;
|
|
681
|
+
kind: number;
|
|
682
|
+
side: 'mint' | 'sell' | 'unknown';
|
|
683
|
+
reason: RefundReasonInfo;
|
|
684
|
+
escrowReturned: number;
|
|
685
|
+
orderFeeReturned: number;
|
|
686
|
+
subsidyReturned: number;
|
|
687
|
+
/** True when a sell's record went back to Open holding its position. */
|
|
688
|
+
positionReturned: boolean;
|
|
689
|
+
sender: string;
|
|
690
|
+
timestampMs: bigint;
|
|
691
|
+
cash: QueueCashFigures;
|
|
692
|
+
raw: { escrowReturned: bigint; orderFeeReturned: bigint; subsidyReturned: bigint };
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* `OpenRecordSettled` (paid, 0 for a loser) or `OpenRecordPayoutSkipped` (stays Open, for a later
|
|
697
|
+
* `pay_open`), from `settle_step`'s payout walk or `pay_open`.
|
|
698
|
+
*/
|
|
699
|
+
export interface OpenRecordPayoutReceipt {
|
|
700
|
+
type: 'open-record-settled' | 'open-record-payout-skipped';
|
|
701
|
+
marketId: string;
|
|
702
|
+
recordId: bigint;
|
|
703
|
+
accountId: string;
|
|
704
|
+
orderId: bigint;
|
|
705
|
+
payout: number;
|
|
706
|
+
/** True for `OpenRecordPayoutSkipped`: the market couldn't pay it yet. */
|
|
707
|
+
skipped: boolean;
|
|
708
|
+
timestampMs: bigint;
|
|
709
|
+
raw: { payout: bigint };
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/** `MarketPayoutsCompleted`: the settlement payout walk is done. */
|
|
713
|
+
export interface MarketPayoutsCompletedReceipt {
|
|
714
|
+
type: 'market-payouts-completed';
|
|
715
|
+
marketId: string;
|
|
716
|
+
timestampMs: bigint;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* `RecordFundsParked`: a record kept USDC it couldn't send to its receive address (on USDC's deny
|
|
721
|
+
* list, or USDC paused). `RecordFundsClaimed`: `claim_parked` sent a record's parked funds.
|
|
722
|
+
*/
|
|
723
|
+
export interface RecordFundsReceipt {
|
|
724
|
+
type: 'record-funds-parked' | 'record-funds-claimed';
|
|
725
|
+
marketId: string;
|
|
726
|
+
recordId: bigint;
|
|
727
|
+
accountId: string;
|
|
728
|
+
receiveAddress: string;
|
|
729
|
+
/** Parked: this call's parked change or refund. Claimed: everything the record had parked. */
|
|
730
|
+
amount: number;
|
|
731
|
+
timestampMs: bigint;
|
|
732
|
+
raw: { amount: bigint };
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/** Queue housekeeping events, for ops and alerts. */
|
|
736
|
+
export type QueueOpsReceipt = {
|
|
737
|
+
type: 'queued-orders-cleaned';
|
|
738
|
+
marketId: string;
|
|
739
|
+
recordIds: bigint[];
|
|
740
|
+
timestampMs: bigint;
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
/** Delayed-execution admin events, for the multisig scripts and monitors. */
|
|
744
|
+
export type PolicyUpdateReceipt =
|
|
745
|
+
| {
|
|
746
|
+
/**
|
|
747
|
+
* The companion desk's `DelayedExecutionPolicyUpdated`, from every policy setter with the
|
|
748
|
+
* full post-state. The desk's `init` at publish emits none: the launch policy is only the
|
|
749
|
+
* desk's state.
|
|
750
|
+
*/
|
|
751
|
+
type: 'policy-updated';
|
|
752
|
+
deskId: string;
|
|
753
|
+
policy: DelayedExecutionPolicy;
|
|
754
|
+
timestampMs: bigint;
|
|
755
|
+
}
|
|
756
|
+
| { type: 'flush-operator-updated'; operator: string; added: boolean; timestampMs: bigint }
|
|
757
|
+
| {
|
|
758
|
+
/** Predict's `OrderFlowUpdated`: an order-flow witness allowlisted or removed. */
|
|
759
|
+
type: 'order-flow-updated';
|
|
760
|
+
/** The witness type, as Move's `type_name` renders it (no `0x` prefix). */
|
|
761
|
+
orderFlow: string;
|
|
762
|
+
enabled: boolean;
|
|
763
|
+
timestampMs: bigint;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
/** Every delayed-execution order event, tagged, in chain order. Feed it to `queue.reduceOrderEvents`. */
|
|
767
|
+
export type QueueEvent =
|
|
768
|
+
| EnqueueReceipt
|
|
769
|
+
| CohortCommitReceipt
|
|
770
|
+
| QueuedFillReceipt
|
|
771
|
+
| QueuedRefundReceipt
|
|
772
|
+
| OpenRecordPayoutReceipt
|
|
773
|
+
| MarketPayoutsCompletedReceipt
|
|
774
|
+
| RecordFundsReceipt
|
|
775
|
+
| QueueOpsReceipt;
|
|
776
|
+
|
|
777
|
+
const cashOf = (e: { market_cash: bigint; required_cash: bigint; waiting_cash_need: bigint }) => ({
|
|
778
|
+
marketCash: e.market_cash,
|
|
779
|
+
requiredCash: e.required_cash,
|
|
780
|
+
waitingCashNeed: e.waiting_cash_need,
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
function enqueueReceipt(
|
|
784
|
+
e: (typeof queueEvents.OrderEnqueued)['$inferType'],
|
|
785
|
+
lotSize: bigint,
|
|
786
|
+
): EnqueueReceipt {
|
|
787
|
+
return {
|
|
788
|
+
type: 'enqueued',
|
|
789
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
790
|
+
recordId: e.record_id,
|
|
791
|
+
accountId: normalizeSuiAddress(e.account_id),
|
|
792
|
+
kind: e.kind,
|
|
793
|
+
kindName: orderKindName(e.kind),
|
|
794
|
+
side: side(e.kind),
|
|
795
|
+
request: {
|
|
796
|
+
lowerTick: e.request.lower_tick,
|
|
797
|
+
higherTick: e.request.higher_tick,
|
|
798
|
+
quantity: e.request.quantity,
|
|
799
|
+
maxPremium: e.request.max_premium,
|
|
800
|
+
minQuantity: e.request.min_quantity,
|
|
801
|
+
maxCost: e.request.max_cost,
|
|
802
|
+
maxProbability: e.request.max_probability,
|
|
803
|
+
minProbability: e.request.min_probability,
|
|
804
|
+
minProceeds: e.request.min_proceeds,
|
|
805
|
+
},
|
|
806
|
+
position: heldPosition(e.position, lotSize),
|
|
807
|
+
timing: {
|
|
808
|
+
placedAtMs: e.timing.placed_at_ms,
|
|
809
|
+
earliestPriceMs: e.timing.earliest_price_ms,
|
|
810
|
+
tauMs: e.timing.tau_ms,
|
|
811
|
+
deadlineMs: e.timing.deadline_ms,
|
|
812
|
+
cutoffMs: e.timing.cutoff_ms,
|
|
813
|
+
pythChannel: e.timing.pyth_channel,
|
|
814
|
+
},
|
|
815
|
+
sourceRecordId: e.source_record_id ?? null,
|
|
816
|
+
builderCodeId: optId(e.builder_code_id),
|
|
817
|
+
referrerAccountId: optId(e.referrer_account_id),
|
|
818
|
+
budget: fromRaw(e.budget, 6),
|
|
819
|
+
orderFee: fromRaw(e.order_fee, 6),
|
|
820
|
+
cash: cashOf(e),
|
|
821
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
822
|
+
raw: {
|
|
823
|
+
budget: e.budget,
|
|
824
|
+
orderFee: e.order_fee,
|
|
825
|
+
cashNeed: e.cash_need,
|
|
826
|
+
subsidyBound: e.subsidy_bound,
|
|
827
|
+
},
|
|
828
|
+
vol: e.vol,
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function cohortCommitReceipt(
|
|
833
|
+
e: (typeof queueEvents.CohortCommitted)['$inferType'],
|
|
834
|
+
): CohortCommitReceipt {
|
|
835
|
+
return {
|
|
836
|
+
type: 'cohort-committed',
|
|
837
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
838
|
+
tauMs: e.tau_ms,
|
|
839
|
+
tickMs: e.tick_ms,
|
|
840
|
+
firstRecordId: e.first_record_id,
|
|
841
|
+
lastRecordId: e.last_record_id,
|
|
842
|
+
price: fromRaw(e.spot, 9),
|
|
843
|
+
spotRaw: e.spot,
|
|
844
|
+
generationUs: e.generation_us,
|
|
845
|
+
pythSourceId: e.pyth_source_id,
|
|
846
|
+
pythChannel: e.pyth_channel,
|
|
847
|
+
sender: normalizeSuiAddress(e.sender),
|
|
848
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
function fillReceipt(
|
|
853
|
+
e: (typeof queueEvents.QueuedOrderFilled)['$inferType'],
|
|
854
|
+
lotSize: bigint,
|
|
855
|
+
): QueuedFillReceipt {
|
|
856
|
+
return {
|
|
857
|
+
type: 'filled',
|
|
858
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
859
|
+
recordId: e.record_id,
|
|
860
|
+
accountId: normalizeSuiAddress(e.account_id),
|
|
861
|
+
kind: e.kind,
|
|
862
|
+
side: side(e.kind),
|
|
863
|
+
quantity: fromRaw(e.quantity, 6),
|
|
864
|
+
amount: fromRaw(e.amount, 6),
|
|
865
|
+
fees: {
|
|
866
|
+
trading: fromRaw(e.trading_fee, 6),
|
|
867
|
+
builder: fromRaw(e.builder_fee, 6),
|
|
868
|
+
referral: fromRaw(e.referral_fee, 6),
|
|
869
|
+
order: fromRaw(e.order_fee, 6),
|
|
870
|
+
subsidyUsed: fromRaw(e.subsidy_used, 6),
|
|
871
|
+
inventoryImpact: fromRaw(e.inventory_impact, 6),
|
|
872
|
+
},
|
|
873
|
+
tauMs: e.tau_ms,
|
|
874
|
+
tickMs: e.tick_ms,
|
|
875
|
+
position: heldPosition(e.position, lotSize),
|
|
876
|
+
sender: normalizeSuiAddress(e.sender),
|
|
877
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
878
|
+
cash: cashOf(e),
|
|
879
|
+
raw: {
|
|
880
|
+
quantity: e.quantity,
|
|
881
|
+
amount: e.amount,
|
|
882
|
+
tradingFee: e.trading_fee,
|
|
883
|
+
builderFee: e.builder_fee,
|
|
884
|
+
referralFee: e.referral_fee,
|
|
885
|
+
orderFee: e.order_fee,
|
|
886
|
+
subsidyUsed: e.subsidy_used,
|
|
887
|
+
inventoryImpact: e.inventory_impact,
|
|
888
|
+
},
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
function refundReceipt(
|
|
893
|
+
e: (typeof queueEvents.QueuedOrderRefunded)['$inferType'],
|
|
894
|
+
): QueuedRefundReceipt {
|
|
895
|
+
return {
|
|
896
|
+
type: 'refunded',
|
|
897
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
898
|
+
recordId: e.record_id,
|
|
899
|
+
accountId: normalizeSuiAddress(e.account_id),
|
|
900
|
+
kind: e.kind,
|
|
901
|
+
side: side(e.kind),
|
|
902
|
+
reason: refundReason(e.reason),
|
|
903
|
+
escrowReturned: fromRaw(e.escrow_returned, 6),
|
|
904
|
+
orderFeeReturned: fromRaw(e.order_fee_returned, 6),
|
|
905
|
+
subsidyReturned: fromRaw(e.subsidy_returned, 6),
|
|
906
|
+
positionReturned: e.position_returned,
|
|
907
|
+
sender: normalizeSuiAddress(e.sender),
|
|
908
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
909
|
+
cash: cashOf(e),
|
|
910
|
+
raw: {
|
|
911
|
+
escrowReturned: e.escrow_returned,
|
|
912
|
+
orderFeeReturned: e.order_fee_returned,
|
|
913
|
+
subsidyReturned: e.subsidy_returned,
|
|
914
|
+
},
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
function payoutReceipt(
|
|
919
|
+
skipped: boolean,
|
|
920
|
+
): (e: (typeof queueEvents.OpenRecordSettled)['$inferType']) => OpenRecordPayoutReceipt {
|
|
921
|
+
return (e) => ({
|
|
922
|
+
type: skipped ? 'open-record-payout-skipped' : 'open-record-settled',
|
|
923
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
924
|
+
recordId: e.record_id,
|
|
925
|
+
accountId: normalizeSuiAddress(e.account_id),
|
|
926
|
+
orderId: e.order_id,
|
|
927
|
+
payout: fromRaw(e.payout, 6),
|
|
928
|
+
skipped,
|
|
929
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
930
|
+
raw: { payout: e.payout },
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
function recordFundsReceipt(
|
|
935
|
+
type: RecordFundsReceipt['type'],
|
|
936
|
+
): (e: (typeof queueEvents.RecordFundsParked)['$inferType']) => RecordFundsReceipt {
|
|
937
|
+
return (e) => ({
|
|
938
|
+
type,
|
|
939
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
940
|
+
recordId: e.record_id,
|
|
941
|
+
accountId: normalizeSuiAddress(e.account_id),
|
|
942
|
+
receiveAddress: normalizeSuiAddress(e.receive_address),
|
|
943
|
+
amount: fromRaw(e.amount, 6),
|
|
944
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
945
|
+
raw: { amount: e.amount },
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Each order event the queue emits: its struct name, generated layout and receipt mapping.
|
|
950
|
+
// One table drives both the per-type decoders and `decodeQueueEvents`, so they can't disagree.
|
|
951
|
+
const QUEUE_EVENT_DECODERS: readonly {
|
|
952
|
+
name: string;
|
|
953
|
+
layout: { parse(bytes: Uint8Array): unknown };
|
|
954
|
+
// `lotSize` is the config's position lot, which decodes a held position's quantity.
|
|
955
|
+
map: (e: never, lotSize: bigint) => QueueEvent;
|
|
956
|
+
}[] = [
|
|
957
|
+
{ name: 'OrderEnqueued', layout: queueEvents.OrderEnqueued, map: enqueueReceipt },
|
|
958
|
+
{ name: 'CohortCommitted', layout: queueEvents.CohortCommitted, map: cohortCommitReceipt },
|
|
959
|
+
{ name: 'QueuedOrderFilled', layout: queueEvents.QueuedOrderFilled, map: fillReceipt },
|
|
960
|
+
{ name: 'QueuedOrderRefunded', layout: queueEvents.QueuedOrderRefunded, map: refundReceipt },
|
|
961
|
+
{ name: 'OpenRecordSettled', layout: queueEvents.OpenRecordSettled, map: payoutReceipt(false) },
|
|
962
|
+
{
|
|
963
|
+
name: 'OpenRecordPayoutSkipped',
|
|
964
|
+
layout: queueEvents.OpenRecordPayoutSkipped,
|
|
965
|
+
map: payoutReceipt(true),
|
|
966
|
+
},
|
|
967
|
+
{
|
|
968
|
+
name: 'MarketPayoutsCompleted',
|
|
969
|
+
layout: queueEvents.MarketPayoutsCompleted,
|
|
970
|
+
map: (e: (typeof queueEvents.MarketPayoutsCompleted)['$inferType']) => ({
|
|
971
|
+
type: 'market-payouts-completed',
|
|
972
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
973
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
974
|
+
}),
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
name: 'RecordFundsParked',
|
|
978
|
+
layout: queueEvents.RecordFundsParked,
|
|
979
|
+
map: recordFundsReceipt('record-funds-parked'),
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
name: 'RecordFundsClaimed',
|
|
983
|
+
layout: queueEvents.RecordFundsClaimed,
|
|
984
|
+
map: recordFundsReceipt('record-funds-claimed'),
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
name: 'QueuedOrdersCleaned',
|
|
988
|
+
layout: queueEvents.QueuedOrdersCleaned,
|
|
989
|
+
map: (e: (typeof queueEvents.QueuedOrdersCleaned)['$inferType']) => ({
|
|
990
|
+
type: 'queued-orders-cleaned',
|
|
991
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
992
|
+
recordIds: [...e.record_ids],
|
|
993
|
+
timestampMs: e.onchain_timestamp_ms,
|
|
994
|
+
}),
|
|
995
|
+
},
|
|
996
|
+
];
|
|
997
|
+
|
|
998
|
+
function eventPayload(e: DecodableEvent, module: string, name: string): Uint8Array {
|
|
999
|
+
const bytes = eventBytes(e);
|
|
1000
|
+
if (!bytes) {
|
|
1001
|
+
throw new PredictInputError(
|
|
1002
|
+
`${module}::${name} event has no BCS payload — execute/simulate with events included`,
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
return bytes;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Every delayed-execution order event in a result, tagged with `type`, in event order: the
|
|
1010
|
+
* companion's `queue_events`, matched against its original ID. The app's single entry point for
|
|
1011
|
+
* the queue: pass the list to `queue.reduceOrderEvents`.
|
|
1012
|
+
*/
|
|
1013
|
+
export function decodeQueueEvents(
|
|
1014
|
+
cfg: PredictConfig,
|
|
1015
|
+
result: DecodableTransactionResult,
|
|
1016
|
+
): QueueEvent[] {
|
|
1017
|
+
const pkg = predictOrdersOrigin(cfg);
|
|
1018
|
+
const lotSize = BigInt(cfg.units.positionLotSize);
|
|
1019
|
+
const out: QueueEvent[] = [];
|
|
1020
|
+
for (const e of result.events ?? []) {
|
|
1021
|
+
for (const d of QUEUE_EVENT_DECODERS) {
|
|
1022
|
+
if (!matches(e, pkg, 'queue_events', d.name)) continue;
|
|
1023
|
+
out.push(d.map(d.layout.parse(eventPayload(e, 'queue_events', d.name)) as never, lotSize));
|
|
1024
|
+
break;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
return out;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
function ofType<T extends QueueEvent['type']>(
|
|
1031
|
+
cfg: PredictConfig,
|
|
1032
|
+
result: DecodableTransactionResult,
|
|
1033
|
+
...types: T[]
|
|
1034
|
+
): Extract<QueueEvent, { type: T }>[] {
|
|
1035
|
+
return decodeQueueEvents(cfg, result).filter((e): e is Extract<QueueEvent, { type: T }> =>
|
|
1036
|
+
(types as string[]).includes(e.type),
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
export const decodeEnqueues = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1041
|
+
ofType(cfg, r, 'enqueued');
|
|
1042
|
+
export const decodeCohortCommits = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1043
|
+
ofType(cfg, r, 'cohort-committed');
|
|
1044
|
+
export const decodeQueuedFills = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1045
|
+
ofType(cfg, r, 'filled');
|
|
1046
|
+
export const decodeQueuedRefunds = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1047
|
+
ofType(cfg, r, 'refunded');
|
|
1048
|
+
export const decodeOpenRecordPayouts = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1049
|
+
ofType(cfg, r, 'open-record-settled', 'open-record-payout-skipped');
|
|
1050
|
+
export const decodeMarketPayoutsCompleted = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1051
|
+
ofType(cfg, r, 'market-payouts-completed');
|
|
1052
|
+
export const decodeRecordFunds = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1053
|
+
ofType(cfg, r, 'record-funds-parked', 'record-funds-claimed');
|
|
1054
|
+
export const decodeQueueOps = (cfg: PredictConfig, r: DecodableTransactionResult) =>
|
|
1055
|
+
ofType(cfg, r, 'queued-orders-cleaned');
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* The delayed-execution admin events, in event order: the companion desk's
|
|
1059
|
+
* `DelayedExecutionPolicyUpdated` (matched against the companion's original ID) and Predict's
|
|
1060
|
+
* `FlushOperatorUpdated` and `OrderFlowUpdated` (matched against `predictDelayedExecution`).
|
|
1061
|
+
* Throws while the config records neither package.
|
|
1062
|
+
*/
|
|
1063
|
+
export function decodePolicyUpdates(
|
|
1064
|
+
cfg: PredictConfig,
|
|
1065
|
+
result: DecodableTransactionResult,
|
|
1066
|
+
): PolicyUpdateReceipt[] {
|
|
1067
|
+
const orders = predictOrdersOrigin(cfg);
|
|
1068
|
+
const predict = delayedExecutionOrigin(cfg);
|
|
1069
|
+
const out: PolicyUpdateReceipt[] = [];
|
|
1070
|
+
for (const e of result.events ?? []) {
|
|
1071
|
+
if (matches(e, orders, 'queue_events', 'DelayedExecutionPolicyUpdated')) {
|
|
1072
|
+
const p = queueEvents.DelayedExecutionPolicyUpdated.parse(
|
|
1073
|
+
eventPayload(e, 'queue_events', 'DelayedExecutionPolicyUpdated'),
|
|
1074
|
+
);
|
|
1075
|
+
out.push({
|
|
1076
|
+
type: 'policy-updated',
|
|
1077
|
+
deskId: normalizeSuiAddress(p.desk_id),
|
|
1078
|
+
policy: policyFromBcs(p.policy),
|
|
1079
|
+
timestampMs: p.onchain_timestamp_ms,
|
|
1080
|
+
});
|
|
1081
|
+
} else if (matches(e, predict, 'config_events', 'FlushOperatorUpdated')) {
|
|
1082
|
+
const f = configEvents.FlushOperatorUpdated.parse(
|
|
1083
|
+
eventPayload(e, 'config_events', 'FlushOperatorUpdated'),
|
|
1084
|
+
);
|
|
1085
|
+
out.push({
|
|
1086
|
+
type: 'flush-operator-updated',
|
|
1087
|
+
operator: normalizeSuiAddress(f.operator),
|
|
1088
|
+
added: f.added,
|
|
1089
|
+
timestampMs: f.onchain_timestamp_ms,
|
|
1090
|
+
});
|
|
1091
|
+
} else if (matches(e, predict, 'config_events', 'OrderFlowUpdated')) {
|
|
1092
|
+
const o = configEvents.OrderFlowUpdated.parse(
|
|
1093
|
+
eventPayload(e, 'config_events', 'OrderFlowUpdated'),
|
|
1094
|
+
);
|
|
1095
|
+
out.push({
|
|
1096
|
+
type: 'order-flow-updated',
|
|
1097
|
+
orderFlow: o.order_flow.name,
|
|
1098
|
+
enabled: o.enabled,
|
|
1099
|
+
timestampMs: o.onchain_timestamp_ms,
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
return out;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* `vault_events::ExpiryPnlRealized`: the change in the pool's gross realized result on one expiry
|
|
1108
|
+
* since that expiry's previous emission, emitted with every `ExpiryPnl`. An expiry's first
|
|
1109
|
+
* emission (its first settled sweep) carries the lifetime result, which can be a loss. A later
|
|
1110
|
+
* one carries the extra cash a later sweep returned, always a profit. Gross: before the
|
|
1111
|
+
* protocol/LP split, and including the sponsor fee subsidies mints moved into expiry cash.
|
|
1112
|
+
*/
|
|
1113
|
+
export interface ExpiryPnlRealizedReceipt {
|
|
1114
|
+
vaultId: string;
|
|
1115
|
+
marketId: string;
|
|
1116
|
+
propbookUnderlyingId: number;
|
|
1117
|
+
expiryMs: bigint;
|
|
1118
|
+
/** The settlement price, 1e9-scaled. */
|
|
1119
|
+
settlementPriceRaw: bigint;
|
|
1120
|
+
/** False only for a loss, which only an expiry's first emission reports. */
|
|
1121
|
+
inProfit: boolean;
|
|
1122
|
+
/** The change's magnitude, in USDC. */
|
|
1123
|
+
amount: number;
|
|
1124
|
+
/** The change with its sign: `+amount` for a profit, `−amount` for a loss. */
|
|
1125
|
+
signedAmountRaw: bigint;
|
|
1126
|
+
raw: { amount: bigint };
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/** Every `ExpiryPnlRealized` in a result, in event order. Introduced with delayed execution. */
|
|
1130
|
+
export function decodeExpiryPnlRealized(
|
|
1131
|
+
cfg: PredictConfig,
|
|
1132
|
+
result: DecodableTransactionResult,
|
|
1133
|
+
): ExpiryPnlRealizedReceipt[] {
|
|
1134
|
+
return decodeAll(
|
|
1135
|
+
result,
|
|
1136
|
+
delayedExecutionOrigin(cfg),
|
|
1137
|
+
'vault_events',
|
|
1138
|
+
'ExpiryPnlRealized',
|
|
1139
|
+
vaultEvents.ExpiryPnlRealized,
|
|
1140
|
+
).map((e) => ({
|
|
1141
|
+
vaultId: normalizeSuiAddress(e.pool_vault_id),
|
|
1142
|
+
marketId: normalizeSuiAddress(e.expiry_market_id),
|
|
1143
|
+
propbookUnderlyingId: e.propbook_underlying_id,
|
|
1144
|
+
expiryMs: e.expiry,
|
|
1145
|
+
settlementPriceRaw: e.settlement_price,
|
|
1146
|
+
inProfit: e.in_profit,
|
|
1147
|
+
amount: fromRaw(e.amount, 6),
|
|
1148
|
+
signedAmountRaw: e.in_profit ? e.amount : -e.amount,
|
|
1149
|
+
raw: { amount: e.amount },
|
|
1150
|
+
}));
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* The pool's gross realized P&L in raw USDC: the signed sum of `ExpiryPnlRealized` changes. Over
|
|
1155
|
+
* every emission of every expiry it equals the sum of each expiry's latest `ExpiryPnl`, with no
|
|
1156
|
+
* per-expiry dedup. Subtract the `OrderMinted.fee_incentive_subsidy` totals to isolate the
|
|
1157
|
+
* trading result.
|
|
1158
|
+
*/
|
|
1159
|
+
export function realizedPnlRaw(
|
|
1160
|
+
receipts: readonly Pick<ExpiryPnlRealizedReceipt, 'signedAmountRaw'>[],
|
|
1161
|
+
): bigint {
|
|
1162
|
+
return receipts.reduce((sum, r) => sum + r.signedAmountRaw, 0n);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
476
1165
|
export { exactlyOne };
|