@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/tx/common.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Copyright (c) Mysten Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { bcs } from '@mysten/sui/bcs';
|
|
3
4
|
import type { Transaction, TransactionArgument, TransactionResult } from '@mysten/sui/transactions';
|
|
5
|
+
import { deriveObjectID } from '@mysten/sui/utils';
|
|
4
6
|
import { toGeneratedConfig, type GeneratedConfig } from '../config/generated.js';
|
|
5
7
|
import type { PredictConfig } from '../config/index.js';
|
|
6
8
|
import { AccountContract, accountMoveCalls as account } from '../../account.js';
|
|
@@ -46,12 +48,14 @@ type NamedArguments<Options extends AuthCallOptions> = Extract<
|
|
|
46
48
|
/**
|
|
47
49
|
* The options {@link withAuth} leaves to the caller: the generated ones, minus the `auth`
|
|
48
50
|
* argument it supplies itself, with the projected config required (it is what mints the auth).
|
|
51
|
+
* The config must also carry every key the wrapped call resolves, so a call into the order-flow
|
|
52
|
+
* companion can't be handed a slice without its desk.
|
|
49
53
|
*/
|
|
50
54
|
export type WithAuthOptions<Options extends AuthCallOptions> = Omit<
|
|
51
55
|
Options,
|
|
52
56
|
'arguments' | 'config'
|
|
53
57
|
> & {
|
|
54
|
-
config: GeneratedConfig
|
|
58
|
+
config: GeneratedConfig & NonNullable<Options['config']>;
|
|
55
59
|
arguments: Omit<NamedArguments<Options>, 'auth'>;
|
|
56
60
|
};
|
|
57
61
|
|
|
@@ -90,3 +94,23 @@ export function deriveAccountWrapperIdFrom(
|
|
|
90
94
|
export function deriveAccountWrapperId(cfg: PredictConfig, owner: string): string {
|
|
91
95
|
return deriveAccountWrapperIdFrom(toGeneratedConfig(cfg), owner);
|
|
92
96
|
}
|
|
97
|
+
|
|
98
|
+
// `account_registry::AccountKey(owner)`: a one-field positional struct, so its BCS is the bare
|
|
99
|
+
// 32-byte address.
|
|
100
|
+
const AccountKey = bcs.struct('AccountKey', { pos0: bcs.Address });
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The owner's canonical ACCOUNT id (`Account.account_id`), a different derived object from the
|
|
104
|
+
* wrapper: `derive_address(registry, AccountKey(owner))`. Queue records and events name accounts
|
|
105
|
+
* by it, and `queue::waiting_orders` takes it.
|
|
106
|
+
*/
|
|
107
|
+
export function deriveAccountIdFrom(
|
|
108
|
+
config: Pick<GeneratedConfig, 'accountRegistry' | 'accountPackageId'>,
|
|
109
|
+
owner: string,
|
|
110
|
+
): string {
|
|
111
|
+
return deriveObjectID(
|
|
112
|
+
config.accountRegistry,
|
|
113
|
+
`${config.accountPackageId}::account_registry::AccountKey`,
|
|
114
|
+
AccountKey.serialize({ pos0: owner }).toBytes(),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
// Copyright (c) Mysten Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// Delayed execution (DBU-885): composable thunks for queued orders. Each is
|
|
4
|
+
// `(config, args) => (tx) => result`, like `tx/trade.ts`, so an app can put several into one
|
|
5
|
+
// PTB. The `PredictClient.tx.enqueue*` facade adds the chain preflight on top.
|
|
6
|
+
//
|
|
7
|
+
// Every queued-order entry point lives in the order-flow companion, `deepbook_predict_orders`
|
|
8
|
+
// (`queue::*`), and runs against one market's `MarketQueue` plus the companion's shared
|
|
9
|
+
// `OrderDesk`. The queue's ID is derived from the companion's `QueueRegistry` and the market, so
|
|
10
|
+
// each thunk takes it as an optional `queueId` and derives it otherwise. The thunks take
|
|
11
|
+
// `OrdersGeneratedConfig` (`toOrdersConfig(cfg)`), which supplies the companion package, the desk,
|
|
12
|
+
// the registry and Predict's shared objects.
|
|
13
|
+
//
|
|
14
|
+
// Every call that can send USDC (`resolve`, `refund`, `admin_refund`, `settle_step`, `pay_open`,
|
|
15
|
+
// `claim_parked`) also reads Sui's shared `DenyList` (0x403), which the generated bindings inject
|
|
16
|
+
// as a read-only shared input. Nothing sends USDC to an address on USDC's deny list, or while USDC
|
|
17
|
+
// is globally paused: a fill for such a receive address is refused (reason 9), a refund or change
|
|
18
|
+
// is parked in its record (`RecordFundsParked`), and a payout is skipped until `pay_open`.
|
|
19
|
+
//
|
|
20
|
+
// Queued orders read the oracle objects directly for their volatility snapshot, so unlike the
|
|
21
|
+
// retired immediate trades there is no `load_live_pricer` command before them.
|
|
22
|
+
import type { Transaction, TransactionResult } from '@mysten/sui/transactions';
|
|
23
|
+
import type { GeneratedConfig, OrdersGeneratedConfig } from '../config/generated.js';
|
|
24
|
+
import { MIN_PREMIUM } from '../cost.js';
|
|
25
|
+
import { PredictInputError } from '../errors.js';
|
|
26
|
+
import { deriveQueueId } from '../queue-id.js';
|
|
27
|
+
import { U64_MAX } from '../units.js';
|
|
28
|
+
import * as plp from '../../contracts/deepbook_predict/plp.js';
|
|
29
|
+
import * as delayedExecutionConfig from '../../contracts/deepbook_predict_orders/delayed_execution_config.js';
|
|
30
|
+
import * as desk from '../../contracts/deepbook_predict_orders/desk.js';
|
|
31
|
+
import * as queue from '../../contracts/deepbook_predict_orders/queue.js';
|
|
32
|
+
import { withAuth } from './common.js';
|
|
33
|
+
import type { MarketFeeds } from './trade.js';
|
|
34
|
+
|
|
35
|
+
const FLOAT_SCALING = 1_000_000_000n;
|
|
36
|
+
|
|
37
|
+
// The queued placements with their `auth` argument already supplied: auth → enqueue.
|
|
38
|
+
const authed = {
|
|
39
|
+
enqueueExactQuantity: withAuth(queue.enqueueExactQuantity),
|
|
40
|
+
enqueueExactAmount: withAuth(queue.enqueueExactAmount),
|
|
41
|
+
enqueueExactCost: withAuth(queue.enqueueExactCost),
|
|
42
|
+
enqueueRedeemOpen: withAuth(queue.enqueueRedeemOpen),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** One market's queue. */
|
|
46
|
+
export interface QueueTarget {
|
|
47
|
+
expiryMarketId: string;
|
|
48
|
+
/**
|
|
49
|
+
* The market's `MarketQueue`. Defaults to `deriveQueueId(config.queueRegistry, expiryMarketId)`,
|
|
50
|
+
* the ID `queue::create_and_share` gives it, so pass it only to address another registry's
|
|
51
|
+
* queue.
|
|
52
|
+
*/
|
|
53
|
+
queueId?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The queue ID a thunk addresses: the given one, or the one derived from the config's registry. */
|
|
57
|
+
export function queueIdOf(
|
|
58
|
+
config: Pick<OrdersGeneratedConfig, 'queueRegistry'>,
|
|
59
|
+
args: QueueTarget,
|
|
60
|
+
): string {
|
|
61
|
+
return args.queueId ?? deriveQueueId(config.queueRegistry, args.expiryMarketId);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The market, queue and account every queued order names. */
|
|
65
|
+
interface QueuedOrderTarget extends MarketFeeds, QueueTarget {
|
|
66
|
+
wrapperId: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// The leading arguments every placement shares, after `queue` and `market`.
|
|
70
|
+
function placement(config: OrdersGeneratedConfig, args: QueuedOrderTarget) {
|
|
71
|
+
return {
|
|
72
|
+
queue: queueIdOf(config, args),
|
|
73
|
+
market: args.expiryMarketId,
|
|
74
|
+
wrapper: args.wrapperId,
|
|
75
|
+
pyth: args.pythFeed,
|
|
76
|
+
bsValues: args.blockScholesValueStore,
|
|
77
|
+
bsSvi: args.blockScholesSviStore,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The chain refuses a zero or "unlimited" cap (`EMintCostCapRequired`), so a queued mint always
|
|
82
|
+
// carries a real one. Checked here so a bad cap never reaches a PTB.
|
|
83
|
+
function assertMaxCost(maxCostRaw: bigint): void {
|
|
84
|
+
if (typeof maxCostRaw !== 'bigint' || maxCostRaw <= 0n || maxCostRaw >= U64_MAX) {
|
|
85
|
+
throw new PredictInputError(
|
|
86
|
+
`maxCostRaw must be above 0 and below u64::MAX (a queued mint requires a real cap), got ${String(maxCostRaw)}`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function assertU64(value: bigint, name: string): void {
|
|
92
|
+
if (typeof value !== 'bigint' || value < 0n || value > U64_MAX) {
|
|
93
|
+
throw new PredictInputError(`${name} must be a u64 bigint, got ${String(value)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Queue a mint of an exact payout quantity, priced at Pyth's signed price for its τ
|
|
99
|
+
* (`queue::enqueue_exact_quantity`). Returns the record ID (u64). `maxCostRaw` (all-in cap) and
|
|
100
|
+
* `maxProbabilityRaw` (entry-probability cap, at most 1e9) are required: there is no "unlimited"
|
|
101
|
+
* default on the queued path. Escrows `min(max_cost, quantity, available − fee)` plus the order
|
|
102
|
+
* fee. Command order is auth → enqueue.
|
|
103
|
+
*/
|
|
104
|
+
export function enqueueExactQuantity(
|
|
105
|
+
config: OrdersGeneratedConfig,
|
|
106
|
+
args: QueuedOrderTarget & {
|
|
107
|
+
lowerTick: bigint;
|
|
108
|
+
higherTick: bigint;
|
|
109
|
+
quantityRaw: bigint;
|
|
110
|
+
maxCostRaw: bigint;
|
|
111
|
+
maxProbabilityRaw: bigint;
|
|
112
|
+
},
|
|
113
|
+
): (tx: Transaction) => TransactionResult {
|
|
114
|
+
assertMaxCost(args.maxCostRaw);
|
|
115
|
+
assertU64(args.quantityRaw, 'quantityRaw');
|
|
116
|
+
if (
|
|
117
|
+
typeof args.maxProbabilityRaw !== 'bigint' ||
|
|
118
|
+
args.maxProbabilityRaw <= 0n ||
|
|
119
|
+
args.maxProbabilityRaw > FLOAT_SCALING
|
|
120
|
+
) {
|
|
121
|
+
throw new PredictInputError(
|
|
122
|
+
`maxProbabilityRaw must be in (0, 1e9], got ${String(args.maxProbabilityRaw)}`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return authed.enqueueExactQuantity({
|
|
126
|
+
config,
|
|
127
|
+
arguments: {
|
|
128
|
+
...placement(config, args),
|
|
129
|
+
lowerTick: args.lowerTick,
|
|
130
|
+
higherTick: args.higherTick,
|
|
131
|
+
quantity: args.quantityRaw,
|
|
132
|
+
maxCost: args.maxCostRaw,
|
|
133
|
+
maxProbability: args.maxProbabilityRaw,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Queue a premium-budget mint (`queue::enqueue_exact_amount`): sized at τ under
|
|
140
|
+
* `maxPremiumRaw`, at least `minQuantityRaw`, with the all-in withdrawal capped by the required
|
|
141
|
+
* `maxCostRaw`. Escrows `min(max_cost, available − fee)` plus the order fee. Returns the record
|
|
142
|
+
* ID. Command order is auth → enqueue. `maxPremiumRaw` below the minimum premium (1 USDC) is
|
|
143
|
+
* refused: the fill could never buy enough premium, so Predict's admission dry run would abort
|
|
144
|
+
* `EOrderFailsLimits`.
|
|
145
|
+
*/
|
|
146
|
+
export function enqueueExactAmount(
|
|
147
|
+
config: OrdersGeneratedConfig,
|
|
148
|
+
args: QueuedOrderTarget & {
|
|
149
|
+
lowerTick: bigint;
|
|
150
|
+
higherTick: bigint;
|
|
151
|
+
maxPremiumRaw: bigint;
|
|
152
|
+
minQuantityRaw: bigint;
|
|
153
|
+
maxCostRaw: bigint;
|
|
154
|
+
},
|
|
155
|
+
): (tx: Transaction) => TransactionResult {
|
|
156
|
+
assertMaxCost(args.maxCostRaw);
|
|
157
|
+
assertU64(args.maxPremiumRaw, 'maxPremiumRaw');
|
|
158
|
+
assertU64(args.minQuantityRaw, 'minQuantityRaw');
|
|
159
|
+
if (args.maxPremiumRaw < MIN_PREMIUM) {
|
|
160
|
+
throw new PredictInputError(
|
|
161
|
+
`maxPremiumRaw ${args.maxPremiumRaw} is below the ${MIN_PREMIUM} minimum premium (EOrderFailsLimits)`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return authed.enqueueExactAmount({
|
|
165
|
+
config,
|
|
166
|
+
arguments: {
|
|
167
|
+
...placement(config, args),
|
|
168
|
+
lowerTick: args.lowerTick,
|
|
169
|
+
higherTick: args.higherTick,
|
|
170
|
+
maxPremium: args.maxPremiumRaw,
|
|
171
|
+
minQuantity: args.minQuantityRaw,
|
|
172
|
+
maxCost: args.maxCostRaw,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Queue an all-in-budget mint (`queue::enqueue_exact_cost`): sized at τ so the all-in cost fits
|
|
179
|
+
* `maxCostRaw`, at least `minQuantityRaw`. `maxCostRaw` is the budget and must be a real cap.
|
|
180
|
+
* Escrows `min(max_cost, available − fee)` plus the order fee. Returns the record ID. Command
|
|
181
|
+
* order is auth → enqueue.
|
|
182
|
+
*/
|
|
183
|
+
export function enqueueExactCost(
|
|
184
|
+
config: OrdersGeneratedConfig,
|
|
185
|
+
args: QueuedOrderTarget & {
|
|
186
|
+
lowerTick: bigint;
|
|
187
|
+
higherTick: bigint;
|
|
188
|
+
maxCostRaw: bigint;
|
|
189
|
+
minQuantityRaw: bigint;
|
|
190
|
+
},
|
|
191
|
+
): (tx: Transaction) => TransactionResult {
|
|
192
|
+
assertMaxCost(args.maxCostRaw);
|
|
193
|
+
assertU64(args.minQuantityRaw, 'minQuantityRaw');
|
|
194
|
+
return authed.enqueueExactCost({
|
|
195
|
+
config,
|
|
196
|
+
arguments: {
|
|
197
|
+
...placement(config, args),
|
|
198
|
+
lowerTick: args.lowerTick,
|
|
199
|
+
higherTick: args.higherTick,
|
|
200
|
+
maxCost: args.maxCostRaw,
|
|
201
|
+
minQuantity: args.minQuantityRaw,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Queue an early sell of `closeQuantityRaw` from the Open record `recordId`
|
|
208
|
+
* (`queue::enqueue_redeem_open`; the queue record ID, not the position's u256 order ID). The
|
|
209
|
+
* only early sell: a position held in the account can't be sold early. The record must be Open
|
|
210
|
+
* and belong to this account. `minProbabilityRaw` and `minProceedsRaw` are the close-side floors
|
|
211
|
+
* at τ and are required (`0n` disables either, so pass it on purpose). Escrows only the order
|
|
212
|
+
* fee. Returns the new record ID, which holds the position until the sell fills or refunds.
|
|
213
|
+
* Command order is auth → enqueue.
|
|
214
|
+
*/
|
|
215
|
+
export function enqueueRedeemOpen(
|
|
216
|
+
config: OrdersGeneratedConfig,
|
|
217
|
+
args: QueuedOrderTarget & {
|
|
218
|
+
recordId: bigint;
|
|
219
|
+
closeQuantityRaw: bigint;
|
|
220
|
+
minProbabilityRaw: bigint;
|
|
221
|
+
minProceedsRaw: bigint;
|
|
222
|
+
},
|
|
223
|
+
): (tx: Transaction) => TransactionResult {
|
|
224
|
+
assertU64(args.recordId, 'recordId');
|
|
225
|
+
assertU64(args.minProbabilityRaw, 'minProbabilityRaw');
|
|
226
|
+
assertU64(args.minProceedsRaw, 'minProceedsRaw');
|
|
227
|
+
if (typeof args.closeQuantityRaw !== 'bigint' || args.closeQuantityRaw <= 0n) {
|
|
228
|
+
throw new PredictInputError(
|
|
229
|
+
`closeQuantityRaw must be above 0, got ${String(args.closeQuantityRaw)}`,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
return authed.enqueueRedeemOpen({
|
|
233
|
+
config,
|
|
234
|
+
arguments: {
|
|
235
|
+
...placement(config, args),
|
|
236
|
+
recordId: args.recordId,
|
|
237
|
+
closeQuantity: args.closeQuantityRaw,
|
|
238
|
+
minProbability: args.minProbabilityRaw,
|
|
239
|
+
minProceeds: args.minProceedsRaw,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Abort the transaction unless the order desk's fee is at most `maxOrderFeeRaw` when it executes.
|
|
246
|
+
* The enqueues charge the desk's fee at execution and take no fee bound, so add this BEFORE an
|
|
247
|
+
* enqueue to hold it to the fee its preview showed. It reads the desk's policy, and
|
|
248
|
+
* `0x1::u64::checked_sub(max, fee)` is none once the fee is above the bound, so
|
|
249
|
+
* `0x1::option::destroy_some` aborts (`option::EOPTION_NOT_SET`, code 0x40001) before the
|
|
250
|
+
* enqueue debits anything. Read-only on the desk.
|
|
251
|
+
*/
|
|
252
|
+
export function assertOrderFeeAtMost(
|
|
253
|
+
config: OrdersGeneratedConfig,
|
|
254
|
+
maxOrderFeeRaw: bigint,
|
|
255
|
+
): (tx: Transaction) => void {
|
|
256
|
+
assertU64(maxOrderFeeRaw, 'maxOrderFeeRaw');
|
|
257
|
+
return (tx) => {
|
|
258
|
+
const policy = tx.add(desk.policy({ config }));
|
|
259
|
+
const fee = tx.add(delayedExecutionConfig.orderFee({ config, arguments: { policy } }));
|
|
260
|
+
const headroom = tx.moveCall({
|
|
261
|
+
target: '0x1::u64::checked_sub',
|
|
262
|
+
arguments: [tx.pure.u64(maxOrderFeeRaw), fee],
|
|
263
|
+
});
|
|
264
|
+
tx.moveCall({
|
|
265
|
+
target: '0x1::option::destroy_some',
|
|
266
|
+
typeArguments: ['u64'],
|
|
267
|
+
arguments: [headroom],
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Fund a live market from the pool vault to `max(required × (1 + rebalance %), initial cash,
|
|
274
|
+
* required + waiting_cash_need)` (Predict's `plp::rebalance_expiry_cash`). Permissionless, and
|
|
275
|
+
* takes no target. Add it AFTER a big sell's enqueue in the same PTB: the enqueue has already
|
|
276
|
+
* added the sell's cash need to Predict's waiting total, so the rebalance funds it at once. It
|
|
277
|
+
* takes the hot `PoolVault`, so add it only when a sell's cash need is above spare cash.
|
|
278
|
+
*/
|
|
279
|
+
export function rebalanceExpiryCash(
|
|
280
|
+
config: GeneratedConfig,
|
|
281
|
+
args: { expiryMarketId: string },
|
|
282
|
+
): (tx: Transaction) => TransactionResult {
|
|
283
|
+
return plp.rebalanceExpiryCash({ config, arguments: { market: args.expiryMarketId } });
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Create and share a market's `MarketQueue` (`queue::create_and_share(registry, desk, market)`),
|
|
288
|
+
* at the ID `deriveQueueId(config.queueRegistry, expiryMarketId)`. Takes the registry mutably and
|
|
289
|
+
* the desk read-only, so it never contends with trading. Permissionless and once per market (a
|
|
290
|
+
* second call aborts, since the ID is taken); the caller pays its storage. The market-creation
|
|
291
|
+
* keeper sends it after each new `ExpiryMarket`. Returns the queue ID.
|
|
292
|
+
*/
|
|
293
|
+
export function createQueue(
|
|
294
|
+
config: OrdersGeneratedConfig,
|
|
295
|
+
args: { expiryMarketId: string },
|
|
296
|
+
): (tx: Transaction) => TransactionResult {
|
|
297
|
+
return queue.createAndShare({ config, arguments: { market: args.expiryMarketId } });
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Refund this market's waiting orders at or past their deadline (`queue::refund`, reason 5),
|
|
302
|
+
* visiting at most `maxOrders` records (the chain caps one call at 450). Permissionless: no auth,
|
|
303
|
+
* session or Pyth key, and it works during a freeze. Returns how many it refunded, `0` without
|
|
304
|
+
* aborting when none is due. Send it only from the app's refund button, never prepended to other
|
|
305
|
+
* transactions: keepers refund on their own. Every visited record counts toward Sui's
|
|
306
|
+
* per-transaction object limit.
|
|
307
|
+
*/
|
|
308
|
+
export function refund(
|
|
309
|
+
config: OrdersGeneratedConfig,
|
|
310
|
+
args: QueueTarget & { maxOrders: bigint | number },
|
|
311
|
+
): (tx: Transaction) => TransactionResult {
|
|
312
|
+
return queue.refund({
|
|
313
|
+
config,
|
|
314
|
+
arguments: {
|
|
315
|
+
queue: queueIdOf(config, args),
|
|
316
|
+
market: args.expiryMarketId,
|
|
317
|
+
maxOrders: args.maxOrders,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Refund the listed waiting orders at once (`queue::admin_refund`, reason 7), wherever they sit
|
|
324
|
+
* in the queue. Takes Predict's `AdminCap`, and works while Predict is frozen. Missing and
|
|
325
|
+
* finished record IDs are skipped.
|
|
326
|
+
*/
|
|
327
|
+
export function adminRefund(
|
|
328
|
+
config: OrdersGeneratedConfig,
|
|
329
|
+
args: QueueTarget & { adminCapId: string; recordIds: readonly bigint[] },
|
|
330
|
+
): (tx: Transaction) => TransactionResult {
|
|
331
|
+
return queue.adminRefund({
|
|
332
|
+
config,
|
|
333
|
+
arguments: {
|
|
334
|
+
queue: queueIdOf(config, args),
|
|
335
|
+
market: args.expiryMarketId,
|
|
336
|
+
AdminCap: args.adminCapId,
|
|
337
|
+
recordIds: [...args.recordIds],
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Delete Refunded and Closed records of a settled market (`queue::cleanup`). Permissionless; the
|
|
344
|
+
* storage rebate goes to the sender. Missing IDs, other statuses and records still holding a
|
|
345
|
+
* receipt or funds (parked funds included, until `claimParked`) are skipped. Aborts
|
|
346
|
+
* `EMarketNotSettled` before settlement.
|
|
347
|
+
*/
|
|
348
|
+
export function cleanup(
|
|
349
|
+
config: OrdersGeneratedConfig,
|
|
350
|
+
args: QueueTarget & { recordIds: readonly bigint[] },
|
|
351
|
+
): (tx: Transaction) => TransactionResult {
|
|
352
|
+
return queue.cleanup({
|
|
353
|
+
config,
|
|
354
|
+
arguments: {
|
|
355
|
+
queue: queueIdOf(config, args),
|
|
356
|
+
market: args.expiryMarketId,
|
|
357
|
+
recordIds: [...args.recordIds],
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Run one bounded settlement phase on a market's queue (`queue::settle_step`) and return the
|
|
364
|
+
* phase the queue is in afterwards (u8, `queue.SETTLE_PHASE`): `0` DRAIN refunds the waiting
|
|
365
|
+
* orders, `1` PAY pays the Open records once Predict has settled the market, `2` DONE once the
|
|
366
|
+
* payout walk has reached the last record. Send one call per transaction until it returns `2` (or
|
|
367
|
+
* `MarketPayoutsCompleted` is emitted), after Predict's `try_settle`. A record the market couldn't
|
|
368
|
+
* pay stays Open with `OpenRecordPayoutSkipped`, even after DONE. Permissionless. Aborts
|
|
369
|
+
* `EMarketNotExpired` before expiry.
|
|
370
|
+
*/
|
|
371
|
+
export function settleStep(
|
|
372
|
+
config: OrdersGeneratedConfig,
|
|
373
|
+
args: QueueTarget,
|
|
374
|
+
): (tx: Transaction) => TransactionResult {
|
|
375
|
+
return queue.settleStep({
|
|
376
|
+
config,
|
|
377
|
+
arguments: { queue: queueIdOf(config, args), market: args.expiryMarketId },
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Pay one Open record of a settled market its settled payout (`queue::pay_open`), at any time
|
|
383
|
+
* after settlement, before or after `settle_step` completes: a record the payout walk skipped
|
|
384
|
+
* because the market was short of cash or its receive address was denied. Permissionless: the
|
|
385
|
+
* payout goes only to the record's own receive address. Emits `OpenRecordSettled`, or
|
|
386
|
+
* `OpenRecordPayoutSkipped` again while the cause persists. A missing or non-Open record is left
|
|
387
|
+
* alone. Aborts `EMarketNotSettled` before Predict settles the market.
|
|
388
|
+
*/
|
|
389
|
+
export function payOpen(
|
|
390
|
+
config: OrdersGeneratedConfig,
|
|
391
|
+
args: QueueTarget & { recordId: bigint },
|
|
392
|
+
): (tx: Transaction) => TransactionResult {
|
|
393
|
+
assertU64(args.recordId, 'recordId');
|
|
394
|
+
return queue.payOpen({
|
|
395
|
+
config,
|
|
396
|
+
arguments: {
|
|
397
|
+
queue: queueIdOf(config, args),
|
|
398
|
+
market: args.expiryMarketId,
|
|
399
|
+
recordId: args.recordId,
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Send a finished record's parked funds (`queue::claim_parked`): change or a refund its receive
|
|
406
|
+
* address couldn't take while it was on USDC's deny list or USDC was paused. Permissionless: the
|
|
407
|
+
* funds go only to the record's own receive address. Returns the amount sent (u64), or `0` and
|
|
408
|
+
* changes nothing for a missing or unfinished record, one with nothing parked, or an address still
|
|
409
|
+
* denied. Emits `RecordFundsClaimed`. Takes no market: `expiryMarketId` only derives the queue.
|
|
410
|
+
*/
|
|
411
|
+
export function claimParked(
|
|
412
|
+
config: OrdersGeneratedConfig,
|
|
413
|
+
args: QueueTarget & { recordId: bigint },
|
|
414
|
+
): (tx: Transaction) => TransactionResult {
|
|
415
|
+
assertU64(args.recordId, 'recordId');
|
|
416
|
+
return queue.claimParked({
|
|
417
|
+
config,
|
|
418
|
+
arguments: { queue: queueIdOf(config, args), recordId: args.recordId },
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** The current Pyth Lazer package and the original ID that types its `Update`. */
|
|
423
|
+
export interface LazerPackages {
|
|
424
|
+
/** Lazer's shared `State`. */
|
|
425
|
+
stateId: string;
|
|
426
|
+
/** The package to call `parse_and_verify_le_ecdsa_update` on: `State.upgrade_cap.package`. */
|
|
427
|
+
packageId: string;
|
|
428
|
+
/** The original package ID, which `update::Update` is typed by. */
|
|
429
|
+
originalId: string;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Verify one signed Lazer payload with the current Lazer package. A positional call on purpose:
|
|
434
|
+
* the oracle-construction packages are not generated (see `sui-codegen.config.ts`).
|
|
435
|
+
*/
|
|
436
|
+
export function parseLazerUpdate(
|
|
437
|
+
lazer: Pick<LazerPackages, 'stateId' | 'packageId'>,
|
|
438
|
+
payload: Uint8Array,
|
|
439
|
+
): (tx: Transaction) => TransactionResult {
|
|
440
|
+
return (tx) =>
|
|
441
|
+
tx.moveCall({
|
|
442
|
+
target: `${lazer.packageId}::pyth_lazer::parse_and_verify_le_ecdsa_update`,
|
|
443
|
+
arguments: [tx.object(lazer.stateId), tx.object.clock(), tx.pure.vector('u8', payload)],
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Verify the signed Lazer payloads and commit them to the market's waiting cohorts
|
|
449
|
+
* (`queue::commit`). Permissionless. Pass the payloads for a cohort's exact τ, or a backup tick
|
|
450
|
+
* once τ + gap wait has passed with τ uncommitted (when the policy's price buffer is on). Commit
|
|
451
|
+
* matches each update to its own cohort by τ and skips one that matches nothing, so no
|
|
452
|
+
* head-of-line ordering is assumed. Resolve `lazer` per batch with `read.lazerPackages` and never
|
|
453
|
+
* cache it: a Pyth upgrade retires the old package at once.
|
|
454
|
+
*/
|
|
455
|
+
export function commit(
|
|
456
|
+
config: OrdersGeneratedConfig,
|
|
457
|
+
args: QueueTarget & { payloads: readonly Uint8Array[]; lazer: LazerPackages },
|
|
458
|
+
): (tx: Transaction) => TransactionResult {
|
|
459
|
+
if (args.payloads.length === 0) {
|
|
460
|
+
throw new PredictInputError('commit needs at least one signed Lazer payload');
|
|
461
|
+
}
|
|
462
|
+
return (tx) => {
|
|
463
|
+
const updates = args.payloads.map((payload) => tx.add(parseLazerUpdate(args.lazer, payload)));
|
|
464
|
+
const vector = tx.makeMoveVec({
|
|
465
|
+
type: `${args.lazer.originalId}::update::Update`,
|
|
466
|
+
elements: updates,
|
|
467
|
+
});
|
|
468
|
+
return tx.add(
|
|
469
|
+
queue.commit({
|
|
470
|
+
config,
|
|
471
|
+
arguments: { queue: queueIdOf(config, args), market: args.expiryMarketId, updates: vector },
|
|
472
|
+
}),
|
|
473
|
+
);
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Fill or refund committed orders in τ order (`queue::resolve`), visiting at most `maxOrders`
|
|
479
|
+
* records (the chain caps one call at 450, since a fill emits two events and Sui allows 1,024
|
|
480
|
+
* per transaction). Permissionless. Returns how many orders it finished. An order the market
|
|
481
|
+
* can't cover is refunded with reason 8. Size `maxOrders` against the payout tree
|
|
482
|
+
* (`payoutTreeNodeCount`): about 10 to 15 fills fit one transaction in a full tree.
|
|
483
|
+
*/
|
|
484
|
+
export function resolve(
|
|
485
|
+
config: OrdersGeneratedConfig,
|
|
486
|
+
args: QueueTarget & { maxOrders: bigint | number },
|
|
487
|
+
): (tx: Transaction) => TransactionResult {
|
|
488
|
+
return queue.resolve({
|
|
489
|
+
config,
|
|
490
|
+
arguments: {
|
|
491
|
+
queue: queueIdOf(config, args),
|
|
492
|
+
market: args.expiryMarketId,
|
|
493
|
+
maxOrders: args.maxOrders,
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* The open filler (no cap exists): {@link commit} the signed Lazer payloads, then
|
|
500
|
+
* {@link resolve} up to `maxOrders` records. Anyone with Pyth Lazer access can run it. With
|
|
501
|
+
* `refundOverdue`, a final `refund` call sweeps orders past their deadline. Returns the resolve
|
|
502
|
+
* result. Split commit from resolve when the payout tree is large.
|
|
503
|
+
*/
|
|
504
|
+
export function fill(
|
|
505
|
+
config: OrdersGeneratedConfig,
|
|
506
|
+
args: QueueTarget & {
|
|
507
|
+
payloads: readonly Uint8Array[];
|
|
508
|
+
lazer: LazerPackages;
|
|
509
|
+
maxOrders: bigint | number;
|
|
510
|
+
refundOverdue?: boolean;
|
|
511
|
+
},
|
|
512
|
+
): (tx: Transaction) => TransactionResult {
|
|
513
|
+
if (args.payloads.length === 0) {
|
|
514
|
+
throw new PredictInputError('fill needs at least one signed Lazer payload');
|
|
515
|
+
}
|
|
516
|
+
const target = { expiryMarketId: args.expiryMarketId, queueId: queueIdOf(config, args) };
|
|
517
|
+
return (tx) => {
|
|
518
|
+
tx.add(commit(config, { ...target, payloads: args.payloads, lazer: args.lazer }));
|
|
519
|
+
const resolved = tx.add(resolve(config, { ...target, maxOrders: args.maxOrders }));
|
|
520
|
+
if (args.refundOverdue) {
|
|
521
|
+
tx.add(refund(config, { ...target, maxOrders: args.maxOrders }));
|
|
522
|
+
}
|
|
523
|
+
return resolved;
|
|
524
|
+
};
|
|
525
|
+
}
|