@metaflux-dex/client 0.0.6 → 0.1.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/dist/client.d.ts +33 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +74 -3
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/native/actions.d.ts +7 -1
- package/dist/native/actions.d.ts.map +1 -1
- package/dist/native/actions.js +113 -1
- package/dist/native/actions.js.map +1 -1
- package/dist/native/digest.d.ts +1 -0
- package/dist/native/digest.d.ts.map +1 -1
- package/dist/native/digest.js +11 -0
- package/dist/native/digest.js.map +1 -1
- package/dist/types/cross-chain.d.ts +8 -0
- package/dist/types/cross-chain.d.ts.map +1 -0
- package/dist/types/cross-chain.js +9 -0
- package/dist/types/cross-chain.js.map +1 -0
- package/dist/types/encrypted.d.ts +5 -0
- package/dist/types/encrypted.d.ts.map +1 -1
- package/dist/types/fba.d.ts +9 -0
- package/dist/types/fba.d.ts.map +1 -0
- package/dist/types/fba.js +8 -0
- package/dist/types/fba.js.map +1 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/info/core.d.ts +5 -1
- package/dist/types/info/core.d.ts.map +1 -1
- package/dist/types/info/index.d.ts +1 -1
- package/dist/types/info/index.d.ts.map +1 -1
- package/dist/types/info/reads.d.ts.map +1 -1
- package/dist/types/rfq.d.ts +15 -0
- package/dist/types/rfq.d.ts.map +1 -0
- package/dist/types/rfq.js +9 -0
- package/dist/types/rfq.js.map +1 -0
- package/dist/types/vault.d.ts +4 -0
- package/dist/types/vault.d.ts.map +1 -1
- package/dist/ws/ws.d.ts +33 -2
- package/dist/ws/ws.d.ts.map +1 -1
- package/dist/ws/ws.js +221 -2
- package/dist/ws/ws.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +120 -2
- package/src/index.ts +17 -0
- package/src/native/actions.ts +135 -0
- package/src/native/digest.ts +12 -0
- package/src/types/cross-chain.ts +32 -0
- package/src/types/encrypted.ts +23 -0
- package/src/types/fba.ts +32 -0
- package/src/types/index.ts +5 -1
- package/src/types/info/core.ts +28 -13
- package/src/types/info/index.ts +1 -0
- package/src/types/info/reads.ts +17 -5
- package/src/types/rfq.ts +55 -0
- package/src/types/vault.ts +21 -0
- package/src/ws/ws.ts +313 -6
package/src/native/actions.ts
CHANGED
|
@@ -14,11 +14,13 @@ import {
|
|
|
14
14
|
validateAddress,
|
|
15
15
|
validateCloid,
|
|
16
16
|
validateDecimalString,
|
|
17
|
+
validateI128,
|
|
17
18
|
validateMarket,
|
|
18
19
|
validateU8,
|
|
19
20
|
validateU16,
|
|
20
21
|
validateU32,
|
|
21
22
|
validateU64,
|
|
23
|
+
validateU128,
|
|
22
24
|
} from './digest.js';
|
|
23
25
|
import type {
|
|
24
26
|
AgentSetAbstraction,
|
|
@@ -31,7 +33,11 @@ import type {
|
|
|
31
33
|
CancelByCloid,
|
|
32
34
|
ClaimRewards,
|
|
33
35
|
ConvertToMultiSigUser,
|
|
36
|
+
CoreSide,
|
|
34
37
|
CreateVault,
|
|
38
|
+
CrossChainSend,
|
|
39
|
+
EncryptedOrderSubmit,
|
|
40
|
+
FbaSubmit,
|
|
35
41
|
LinkStakingUser,
|
|
36
42
|
MbWithdraw,
|
|
37
43
|
Modify,
|
|
@@ -49,6 +55,8 @@ import type {
|
|
|
49
55
|
NativeSpotOrder,
|
|
50
56
|
PriorityBid,
|
|
51
57
|
RegisterMetaliquidityOperator,
|
|
58
|
+
RfqAccept,
|
|
59
|
+
RfqRequest,
|
|
52
60
|
ScheduleCancel,
|
|
53
61
|
SetDisplayName,
|
|
54
62
|
SetMetaliquidityWhitelist,
|
|
@@ -63,6 +71,7 @@ import type {
|
|
|
63
71
|
UserDexAbstraction,
|
|
64
72
|
UserPortfolioMargin,
|
|
65
73
|
UserSetAbstraction,
|
|
74
|
+
VaultDistribute,
|
|
66
75
|
VaultModify,
|
|
67
76
|
VaultTransfer,
|
|
68
77
|
VaultWithdraw,
|
|
@@ -665,6 +674,19 @@ export function buildNativeVaultWithdrawAction(params: VaultWithdraw): string {
|
|
|
665
674
|
);
|
|
666
675
|
}
|
|
667
676
|
|
|
677
|
+
/// `vault_distribute` — follower deposits USD into a vault, minting shares at
|
|
678
|
+
/// the current NAV. The deposit amount rides the **`pnl`** field (a legacy node
|
|
679
|
+
/// name) as a positive decimal string; `vault_id` is a bare number. Wrapper key
|
|
680
|
+
/// is `params`. Forward-compat: see the module note on the RFQ/FBA builders.
|
|
681
|
+
export function buildNativeVaultDistributeAction(params: VaultDistribute): string {
|
|
682
|
+
validateU64(params.vault_id, 'vault_id');
|
|
683
|
+
validateDecimalString(params.pnl, 'pnl');
|
|
684
|
+
return wrapParams(
|
|
685
|
+
'vault_distribute',
|
|
686
|
+
`{${jsonStr('vault_id')}:${params.vault_id},${jsonStr('pnl')}:${jsonStr(params.pnl)}}`,
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
|
|
668
690
|
// ---- MetaBridge ----
|
|
669
691
|
|
|
670
692
|
/// `mb_withdraw` — withdraw cross-collateral to a destination chain. `dst_addr`
|
|
@@ -818,3 +840,116 @@ export function buildNativeEarnWithdrawAction(
|
|
|
818
840
|
const paramsJson = `{${jsonStr('asset')}:${params.asset},${jsonStr('shares')}:${jsonStr(params.shares)}}`;
|
|
819
841
|
return `{${jsonStr('type')}:${jsonStr('earn_withdraw')},${jsonStr('params')}:${paramsJson}}`;
|
|
820
842
|
}
|
|
843
|
+
|
|
844
|
+
// ============================================================================
|
|
845
|
+
// RFQ / FBA / cross-chain / encrypted (forward-compat).
|
|
846
|
+
//
|
|
847
|
+
// The node recognizes these action tags but currently lowers them to
|
|
848
|
+
// `UnsupportedAction` on the public `/exchange` path (the real handlers run on
|
|
849
|
+
// the EVM core-writer path). The SDK emits the byte-correct wire shape each core
|
|
850
|
+
// param struct expects, so these become live the moment the node bridges them —
|
|
851
|
+
// no SDK change required. Note the per-action wrapper keys differ:
|
|
852
|
+
// `rfq` / `accept` / `submit` / `msg` / `encrypted` (NOT `params`).
|
|
853
|
+
//
|
|
854
|
+
// Traps mirrored from the node's plain `#[derive(Serialize)]`:
|
|
855
|
+
// - `side` is PascalCase (`"Bid"`/`"Ask"`), distinct from the snake_case
|
|
856
|
+
// `"bid"`/`"ask"` the perp/spot order builders use.
|
|
857
|
+
// - `size` is a `u128` and `limit_px`/`price` are `i128`, emitted as bare JSON
|
|
858
|
+
// numbers (the size/px planes can exceed 2^53, so they ride as `bigint`).
|
|
859
|
+
// - `limit_px` (RFQ) / `stp_group` (RFQ + FBA) carry no serde default on the
|
|
860
|
+
// node, so the key MUST be present — emit `null` when absent, do NOT omit.
|
|
861
|
+
// - byte arrays (`recipient`, `ciphertext`, `commitment`) are JSON arrays of
|
|
862
|
+
// byte-numbers, NOT 0x-hex strings.
|
|
863
|
+
// ============================================================================
|
|
864
|
+
|
|
865
|
+
/// Render a PascalCase core side token (`"Bid"`/`"Ask"`), failing loud on any
|
|
866
|
+
/// other value (a snake_case `"bid"`/`"ask"` here would be silently rejected by
|
|
867
|
+
/// the core handler).
|
|
868
|
+
function coreSideToken(side: CoreSide, field: string): string {
|
|
869
|
+
if (side !== 'Bid' && side !== 'Ask') {
|
|
870
|
+
throw new RangeError(`${field} must be "Bid" or "Ask" (PascalCase CoreSide)`);
|
|
871
|
+
}
|
|
872
|
+
return jsonStr(side);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/// Serialize a byte buffer as a JSON array of unsigned byte-numbers, optionally
|
|
876
|
+
/// pinning an exact length.
|
|
877
|
+
function byteArrayJson(bytes: Uint8Array, field: string, len?: number): string {
|
|
878
|
+
if (!(bytes instanceof Uint8Array)) {
|
|
879
|
+
throw new RangeError(`${field} must be a Uint8Array`);
|
|
880
|
+
}
|
|
881
|
+
if (len !== undefined && bytes.length !== len) {
|
|
882
|
+
throw new RangeError(`${field} must be exactly ${len} bytes`);
|
|
883
|
+
}
|
|
884
|
+
return `[${Array.from(bytes).join(',')}]`;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/// `rfq_request` — taker opens an RFQ session. Wrapper key is **`rfq`**. `side`
|
|
888
|
+
/// is PascalCase; `limit_px` (`i128`) and `stp_group` (`u64`) keys are ALWAYS
|
|
889
|
+
/// present (`null` when absent — the node has no serde default).
|
|
890
|
+
export function buildNativeRfqRequestAction(params: RfqRequest): string {
|
|
891
|
+
validateMarket(params.market);
|
|
892
|
+
validateU128(params.size, 'size');
|
|
893
|
+
validateU64(params.expiry_ms, 'expiry_ms');
|
|
894
|
+
if (params.limit_px !== null) {
|
|
895
|
+
validateI128(params.limit_px, 'limit_px');
|
|
896
|
+
}
|
|
897
|
+
if (params.stp_group !== null) {
|
|
898
|
+
validateU64(params.stp_group, 'stp_group');
|
|
899
|
+
}
|
|
900
|
+
const limitPx = params.limit_px === null ? 'null' : params.limit_px.toString();
|
|
901
|
+
const stpGroup = params.stp_group === null ? 'null' : `${params.stp_group}`;
|
|
902
|
+
const rfqJson = `{${jsonStr('market')}:${params.market},${jsonStr('side')}:${coreSideToken(params.side, 'side')},${jsonStr('size')}:${params.size},${jsonStr('limit_px')}:${limitPx},${jsonStr('expiry_ms')}:${params.expiry_ms},${jsonStr('stp_group')}:${stpGroup}}`;
|
|
903
|
+
return `{${jsonStr('type')}:${jsonStr('rfq_request')},${jsonStr('rfq')}:${rfqJson}}`;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/// `rfq_accept` — taker crosses against a specific resting quote. Wrapper key is
|
|
907
|
+
/// **`accept`** (NOT `rfq`).
|
|
908
|
+
export function buildNativeRfqAcceptAction(params: RfqAccept): string {
|
|
909
|
+
validateU64(params.rfq_id, 'rfq_id');
|
|
910
|
+
validateU32(params.quote_idx, 'quote_idx');
|
|
911
|
+
validateU128(params.size, 'size');
|
|
912
|
+
const acceptJson = `{${jsonStr('rfq_id')}:${params.rfq_id},${jsonStr('quote_idx')}:${params.quote_idx},${jsonStr('size')}:${params.size}}`;
|
|
913
|
+
return `{${jsonStr('type')}:${jsonStr('rfq_accept')},${jsonStr('accept')}:${acceptJson}}`;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/// `fba_submit` — submit into a market's frequent-batch-auction pool. Wrapper
|
|
917
|
+
/// key is **`submit`**. The price field is **`price`** (NOT `limit_px`); `side`
|
|
918
|
+
/// is PascalCase; `stp_group` key is ALWAYS present (`null` when absent).
|
|
919
|
+
export function buildNativeFbaSubmitAction(params: FbaSubmit): string {
|
|
920
|
+
validateMarket(params.market);
|
|
921
|
+
validateU128(params.size, 'size');
|
|
922
|
+
validateI128(params.price, 'price');
|
|
923
|
+
if (params.stp_group !== null) {
|
|
924
|
+
validateU64(params.stp_group, 'stp_group');
|
|
925
|
+
}
|
|
926
|
+
const stpGroup = params.stp_group === null ? 'null' : `${params.stp_group}`;
|
|
927
|
+
const submitJson = `{${jsonStr('market')}:${params.market},${jsonStr('side')}:${coreSideToken(params.side, 'side')},${jsonStr('size')}:${params.size},${jsonStr('price')}:${params.price},${jsonStr('stp_group')}:${stpGroup}}`;
|
|
928
|
+
return `{${jsonStr('type')}:${jsonStr('fba_submit')},${jsonStr('submit')}:${submitJson}}`;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/// `cross_chain_send` — initiate a chain-agnostic cross-chain transfer. Wrapper
|
|
932
|
+
/// key is **`msg`**. `recipient` is a 32-byte array; `amount` (`u128`) is a bare
|
|
933
|
+
/// JSON number (NOT hex).
|
|
934
|
+
export function buildNativeCrossChainSendAction(params: CrossChainSend): string {
|
|
935
|
+
validateU32(params.dst_chain_id, 'dst_chain_id');
|
|
936
|
+
const recipient = byteArrayJson(params.recipient, 'recipient', 32);
|
|
937
|
+
validateU32(params.token, 'token');
|
|
938
|
+
validateU128(params.amount, 'amount');
|
|
939
|
+
validateU64(params.nonce, 'nonce');
|
|
940
|
+
const msgJson = `{${jsonStr('dst_chain_id')}:${params.dst_chain_id},${jsonStr('recipient')}:${recipient},${jsonStr('token')}:${params.token},${jsonStr('amount')}:${params.amount},${jsonStr('nonce')}:${params.nonce}}`;
|
|
941
|
+
return `{${jsonStr('type')}:${jsonStr('cross_chain_send')},${jsonStr('msg')}:${msgJson}}`;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/// `encrypted_order_submit` — submit a threshold-encrypted order. Wrapper key is
|
|
945
|
+
/// **`encrypted`**. Only 3 fields — DISTINCT from `submit_encrypted_order`
|
|
946
|
+
/// (5 fields, key `params`). `ciphertext`/`commitment` are byte arrays.
|
|
947
|
+
export function buildNativeEncryptedOrderSubmitAction(
|
|
948
|
+
params: EncryptedOrderSubmit,
|
|
949
|
+
): string {
|
|
950
|
+
const ct = byteArrayJson(params.ciphertext, 'ciphertext');
|
|
951
|
+
const cm = byteArrayJson(params.commitment, 'commitment', 32);
|
|
952
|
+
validateU64(params.reveal_deadline_ms, 'reveal_deadline_ms');
|
|
953
|
+
const encJson = `{${jsonStr('ciphertext')}:${ct},${jsonStr('commitment')}:${cm},${jsonStr('reveal_deadline_ms')}:${params.reveal_deadline_ms}}`;
|
|
954
|
+
return `{${jsonStr('type')}:${jsonStr('encrypted_order_submit')},${jsonStr('encrypted')}:${encJson}}`;
|
|
955
|
+
}
|
package/src/native/digest.ts
CHANGED
|
@@ -264,6 +264,18 @@ export function validateU128(value: bigint, field: string): void {
|
|
|
264
264
|
if (value >= 1n << 128n) throw new RangeError(`${field} overflows u128`);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
/// Validate an `i128` field passed as a `bigint`, emitted as a bare unquoted
|
|
268
|
+
/// integer literal on the wire (serde i128 JSON number form). Accepts the full
|
|
269
|
+
/// signed-128-bit range `[-2^127, 2^127)`.
|
|
270
|
+
export function validateI128(value: bigint, field: string): void {
|
|
271
|
+
if (typeof value !== 'bigint') {
|
|
272
|
+
throw new RangeError(`${field} must be a bigint`);
|
|
273
|
+
}
|
|
274
|
+
if (value < -(1n << 127n) || value >= 1n << 127n) {
|
|
275
|
+
throw new RangeError(`${field} overflows i128`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
267
279
|
/// Validate a decimal magnitude passed as a string and emitted as a JSON
|
|
268
280
|
/// **string** on the wire (e.g. spot-margin `amount` / `borrow`, Earn
|
|
269
281
|
/// `shares`). The server decodes these as a fixed-point `Decimal`, so they must
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// MTF-native cross-chain action payload type.
|
|
2
|
+
//
|
|
3
|
+
// Forward-compat: the node recognizes the `cross_chain_send` action tag but
|
|
4
|
+
// currently lowers it to `UnsupportedAction` on the public `/exchange` path
|
|
5
|
+
// (the real handler runs on the EVM core-writer path). The SDK emits the
|
|
6
|
+
// byte-correct shape the node's `evm_integration` `CrossChainSendParams`
|
|
7
|
+
// decoder expects, so it goes live the moment the node bridges it.
|
|
8
|
+
|
|
9
|
+
/// `cross_chain_send` — initiate a chain-agnostic cross-chain transfer (queued
|
|
10
|
+
/// to the bridge outbox). Mirrors the node's `evm_integration`
|
|
11
|
+
/// `CrossChainSendParams`. The action envelope wraps this under the key **`msg`**.
|
|
12
|
+
///
|
|
13
|
+
/// Traps: the action field is `dst_chain_id` (the read-only `CrossChainMsg`
|
|
14
|
+
/// snapshot uses `dst_chain`); under the node's plain `#[derive(Serialize)]`,
|
|
15
|
+
/// `recipient: [u8; 32]` is a JSON **array of 32 byte-numbers** and `amount`
|
|
16
|
+
/// (`u128`) is a JSON **number** — NOT 0x-hex strings.
|
|
17
|
+
export interface CrossChainSend {
|
|
18
|
+
/// Destination chain id (`u32`).
|
|
19
|
+
dst_chain_id: number;
|
|
20
|
+
/// Chain-agnostic 32-byte recipient (EVM = left-padded 20-byte address).
|
|
21
|
+
/// Serializes as a JSON array of 32 byte-numbers — pass a 32-byte
|
|
22
|
+
/// `Uint8Array`.
|
|
23
|
+
recipient: Uint8Array;
|
|
24
|
+
/// MTF asset id (`u32`) — NOT a destination-chain token address.
|
|
25
|
+
token: number;
|
|
26
|
+
/// Amount in the MTF asset's native fixed-point (`u128`). `bigint` — emitted
|
|
27
|
+
/// as a bare JSON number, NOT hex.
|
|
28
|
+
amount: bigint;
|
|
29
|
+
/// Application-supplied idempotency nonce (`u64`); `(sender, nonce)` is the
|
|
30
|
+
/// key.
|
|
31
|
+
nonce: number;
|
|
32
|
+
}
|
package/src/types/encrypted.ts
CHANGED
|
@@ -19,3 +19,26 @@ export interface SubmitEncryptedOrder {
|
|
|
19
19
|
/// (`u64`).
|
|
20
20
|
reveal_deadline_ms: number;
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
/// `encrypted_order_submit` — submit a threshold-encrypted order under the
|
|
24
|
+
/// node's `evm_integration` `EncryptedOrderSubmitParams`. The action envelope
|
|
25
|
+
/// wraps this under the key **`encrypted`**.
|
|
26
|
+
///
|
|
27
|
+
/// DISTINCT from `SubmitEncryptedOrder`: that 5-field type backs the *different*
|
|
28
|
+
/// `submit_encrypted_order` tag (key `params`, the real bridged handler). This
|
|
29
|
+
/// 3-field type has **no** `threshold` / `target_block`.
|
|
30
|
+
///
|
|
31
|
+
/// Forward-compat: the node currently answers this tag with `UnsupportedAction`
|
|
32
|
+
/// on the public `/exchange` path; the SDK emits the byte-correct shape the core
|
|
33
|
+
/// handler will accept once the bridge lands.
|
|
34
|
+
export interface EncryptedOrderSubmit {
|
|
35
|
+
/// Threshold-encrypted order bytes (node decoder bounds this at 4096).
|
|
36
|
+
/// Emitted as a JSON array of byte numbers — pass a `Uint8Array`.
|
|
37
|
+
ciphertext: Uint8Array;
|
|
38
|
+
/// 32-byte `keccak(plaintext‖salt)` commitment. Emitted as a JSON array of
|
|
39
|
+
/// 32 byte numbers — pass a 32-byte `Uint8Array`.
|
|
40
|
+
commitment: Uint8Array;
|
|
41
|
+
/// Absolute consensus-time ms by which a valid plaintext must be revealed
|
|
42
|
+
/// (`u64`).
|
|
43
|
+
reveal_deadline_ms: number;
|
|
44
|
+
}
|
package/src/types/fba.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// MTF-native FBA (Frequent Batch Auction) action payload type.
|
|
2
|
+
//
|
|
3
|
+
// Forward-compat: the node recognizes the `fba_submit` action tag but currently
|
|
4
|
+
// lowers it to `UnsupportedAction` on the public `/exchange` path. The SDK emits
|
|
5
|
+
// the byte-correct shape the core `FbaSubmitParams` decoder expects, so it goes
|
|
6
|
+
// live the moment the node bridges the handler — no SDK change required.
|
|
7
|
+
|
|
8
|
+
import type { CoreSide } from './rfq.js';
|
|
9
|
+
|
|
10
|
+
/// `fba_submit` — submit an order into a market's frequent-batch-auction pool.
|
|
11
|
+
/// Mirrors the node's `core_state` `FbaSubmitParams`. The action envelope wraps
|
|
12
|
+
/// this under the key **`submit`**.
|
|
13
|
+
///
|
|
14
|
+
/// Traps mirrored from the node: `side` is PascalCase (`CoreSide`), the price
|
|
15
|
+
/// field is named **`price`** (NOT `limit_px` as in spot/perp orders), and
|
|
16
|
+
/// `stp_group` carries no serde default so the key must be present (`null` when
|
|
17
|
+
/// absent).
|
|
18
|
+
export interface FbaSubmit {
|
|
19
|
+
/// Target market (`u32`).
|
|
20
|
+
market: number;
|
|
21
|
+
/// Side — serializes PascalCase (`"Bid"`/`"Ask"`).
|
|
22
|
+
side: CoreSide;
|
|
23
|
+
/// Submitted size (`u128`, `>= pool.min_lot`). `bigint` — emitted as a bare
|
|
24
|
+
/// JSON number.
|
|
25
|
+
size: bigint;
|
|
26
|
+
/// Limit / worst-acceptable price (`i128`, `> 0`). Field is **`price`** per
|
|
27
|
+
/// the core struct — NOT `limit_px`. `bigint` — emitted as a bare number.
|
|
28
|
+
price: bigint;
|
|
29
|
+
/// Optional STP group (`u64`). The key is ALWAYS present: `null` when absent
|
|
30
|
+
/// (do NOT omit).
|
|
31
|
+
stp_group: number | null;
|
|
32
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -75,5 +75,9 @@ export type {
|
|
|
75
75
|
VaultTransfer,
|
|
76
76
|
VaultModify,
|
|
77
77
|
VaultWithdraw,
|
|
78
|
+
VaultDistribute,
|
|
78
79
|
} from './vault.js';
|
|
79
|
-
export type { SubmitEncryptedOrder } from './encrypted.js';
|
|
80
|
+
export type { SubmitEncryptedOrder, EncryptedOrderSubmit } from './encrypted.js';
|
|
81
|
+
export type { CoreSide, RfqRequest, RfqAccept } from './rfq.js';
|
|
82
|
+
export type { FbaSubmit } from './fba.js';
|
|
83
|
+
export type { CrossChainSend } from './cross-chain.js';
|
package/src/types/info/core.ts
CHANGED
|
@@ -97,22 +97,28 @@ export interface Funding {
|
|
|
97
97
|
next_payment_ts: number;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/// Market kind. The deployed gateway emits lowercase `"perp"` / `"spot"`.
|
|
101
|
+
export type MarketKind = 'perp' | 'spot';
|
|
102
|
+
|
|
100
103
|
/// `market_info` / `markets` element — rich per-market metadata.
|
|
101
104
|
///
|
|
102
|
-
/// `mark_px`
|
|
103
|
-
///
|
|
104
|
-
///
|
|
105
|
-
///
|
|
105
|
+
/// `mark_px` and `oracle_px` are whole-USDC decimal strings (tick-snapped;
|
|
106
|
+
/// `"0"` fallback). `sz_decimals` is load-bearing for size encoding — raw
|
|
107
|
+
/// order/position `size` = `whole_units × 10^sz_decimals`, NOT derivable from
|
|
108
|
+
/// `step_size`.
|
|
106
109
|
export interface MarketInfo {
|
|
107
110
|
/// Canonical asset id.
|
|
108
111
|
asset_id: number;
|
|
109
112
|
/// Human-readable market name (e.g. `"BTC"`).
|
|
110
113
|
name: string;
|
|
111
|
-
/// Market kind —
|
|
112
|
-
kind:
|
|
113
|
-
///
|
|
114
|
+
/// Market kind — lowercase `"perp"` / `"spot"`.
|
|
115
|
+
kind: MarketKind;
|
|
116
|
+
/// Size precision: raw order/position `size` = `whole_units × 10^sz_decimals`.
|
|
117
|
+
/// Load-bearing for size encoding — NOT derivable from `step_size`.
|
|
118
|
+
sz_decimals: number;
|
|
119
|
+
/// Mark price, whole-USDC plane as a decimal string (`"0"` fallback).
|
|
114
120
|
mark_px: string;
|
|
115
|
-
/// Oracle/index price, whole-USDC plane as a decimal string.
|
|
121
|
+
/// Oracle/index price, whole-USDC plane as a decimal string (`"0"` fallback).
|
|
116
122
|
oracle_px: string;
|
|
117
123
|
/// Tick size (smallest price increment), fixed-point string.
|
|
118
124
|
tick_size: string;
|
|
@@ -201,14 +207,23 @@ export interface FeeTier {
|
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
/// `fee_schedule` — protocol fee schedule. Fee rates are decimal bps strings;
|
|
204
|
-
/// `burn_ratio` is a decimal fraction string (`"0.
|
|
210
|
+
/// `burn_ratio` is a decimal fraction string in `[0, 1]` (`"0.8"` = 80%) — NOT
|
|
211
|
+
/// bps, do not scale it by 10000. `tiers[0]` is the authoritative carrier of
|
|
212
|
+
/// maker/taker when the top-level pair is absent.
|
|
205
213
|
export interface FeeSchedule {
|
|
206
|
-
///
|
|
214
|
+
/// Top-level base maker fee, decimal bps string. Present on the deployed
|
|
215
|
+
/// gateway; ABSENT from a node built from current source — fall back to
|
|
216
|
+
/// `tiers[0].maker_bps` when `undefined`.
|
|
217
|
+
maker_bps?: string;
|
|
218
|
+
/// Top-level base taker fee, decimal bps string. See `maker_bps`.
|
|
219
|
+
taker_bps?: string;
|
|
220
|
+
/// Volume-tier ladder (authoritative carrier of maker/taker).
|
|
207
221
|
tiers: FeeTier[];
|
|
208
|
-
///
|
|
222
|
+
/// Max additional builder-code rebate, decimal bps string.
|
|
209
223
|
builder_rebate_bps: string;
|
|
210
|
-
///
|
|
224
|
+
/// Burn fraction of the non-referrer remainder, decimal fraction string in
|
|
225
|
+
/// `[0, 1]` (NOT bps).
|
|
211
226
|
burn_ratio: string;
|
|
212
|
-
/// Referrer share, decimal bps string.
|
|
227
|
+
/// Referrer share of the base taker take, decimal bps string.
|
|
213
228
|
referrer_share_bps: string;
|
|
214
229
|
}
|
package/src/types/info/index.ts
CHANGED
package/src/types/info/reads.ts
CHANGED
|
@@ -5,18 +5,30 @@
|
|
|
5
5
|
// Money magnitudes that can exceed 2^53 are typed `string`.
|
|
6
6
|
|
|
7
7
|
/// One resting order inside an `OpenOrders` response.
|
|
8
|
+
///
|
|
9
|
+
/// `px` is x1e8 fixed-point (positive canonical price for **both** sides);
|
|
10
|
+
/// `size` is raw lots (`whole × 10^sz_decimals`). `side` is lowercase
|
|
11
|
+
/// `"bid"`/`"ask"`. `oid` / `market_id` / `inserted_at_ms` are bare integers.
|
|
12
|
+
///
|
|
13
|
+
/// LIVE GATEWAY GAP: a resting order currently reads back with `oid: 0` and
|
|
14
|
+
/// `inserted_at_ms: 0` even though it is on the book — so an order is NOT
|
|
15
|
+
/// reliably cancellable by the `oid` from this snapshot, and it carries no
|
|
16
|
+
/// `cloid`. Until the gateway populates `oid`, the oid-independent workaround
|
|
17
|
+
/// for reconcile / ghost-sweep is the `cancel_all_orders` exchange action
|
|
18
|
+
/// (`Client.cancelAllOrders`, keyed by account / asset) rather than per-oid
|
|
19
|
+
/// cancels.
|
|
8
20
|
export interface OpenOrder {
|
|
9
|
-
/// Server order id.
|
|
21
|
+
/// Server order id. See the note: currently `0` on the gateway.
|
|
10
22
|
oid: number;
|
|
11
23
|
/// Asset / market id the order rests on.
|
|
12
24
|
market_id: number;
|
|
13
|
-
/// Order side
|
|
25
|
+
/// Order side, lowercase `"bid"` / `"ask"`.
|
|
14
26
|
side: 'bid' | 'ask';
|
|
15
|
-
/// Resting price, fixed-point decimal string.
|
|
27
|
+
/// Resting price, x1e8 fixed-point decimal string.
|
|
16
28
|
px: string;
|
|
17
|
-
/// Remaining size,
|
|
29
|
+
/// Remaining size, raw lots (`whole × 10^sz_decimals`) decimal string.
|
|
18
30
|
size: string;
|
|
19
|
-
/// Insertion timestamp (consensus ms).
|
|
31
|
+
/// Insertion timestamp (consensus ms). See the note: currently `0`.
|
|
20
32
|
inserted_at_ms: number;
|
|
21
33
|
}
|
|
22
34
|
|
package/src/types/rfq.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// MTF-native RFQ (Request-for-Quote) action payload types.
|
|
2
|
+
//
|
|
3
|
+
// Forward-compat: the node recognizes the `rfq_request` / `rfq_accept` action
|
|
4
|
+
// tags but currently lowers them to `UnsupportedAction` on the public
|
|
5
|
+
// `/exchange` path (the real handlers run on the EVM core-writer path). The SDK
|
|
6
|
+
// emits the byte-correct wire shape each core param struct expects, so these
|
|
7
|
+
// go live the moment the node bridges them — no SDK change required.
|
|
8
|
+
|
|
9
|
+
/// Order side as the **core** RFQ / FBA action handlers deserialize it:
|
|
10
|
+
/// PascalCase `"Bid"` / `"Ask"`.
|
|
11
|
+
///
|
|
12
|
+
/// Deliberately distinct from the snake_case `NativeSide` (`"bid"`/`"ask"`)
|
|
13
|
+
/// used by the perp/spot order builders: the node's `core_state::Side` enum
|
|
14
|
+
/// carries no `#[serde(rename_all)]`, so the `rfq_request` / `fba_submit`
|
|
15
|
+
/// payloads expect PascalCase tokens. Reusing the snake_case side would
|
|
16
|
+
/// silently emit `"bid"`/`"ask"` that the core handlers reject.
|
|
17
|
+
export type CoreSide = 'Bid' | 'Ask';
|
|
18
|
+
|
|
19
|
+
/// `rfq_request` — a taker opens an RFQ session asking MMs to quote. Mirrors the
|
|
20
|
+
/// node's `core_state` `RfqRequestParams`. The action envelope wraps this under
|
|
21
|
+
/// the key **`rfq`** (not `params`).
|
|
22
|
+
///
|
|
23
|
+
/// `limit_px` and `stp_group` carry NO serde default on the node, so the keys
|
|
24
|
+
/// must always be present — an absent value serializes as JSON `null` (the SDK
|
|
25
|
+
/// does NOT skip them).
|
|
26
|
+
export interface RfqRequest {
|
|
27
|
+
/// Market to request a quote on (`u32`).
|
|
28
|
+
market: number;
|
|
29
|
+
/// Taker side — serializes PascalCase (`"Bid"`/`"Ask"`).
|
|
30
|
+
side: CoreSide;
|
|
31
|
+
/// Requested size (`u128`, `> 0`). `bigint` — emitted as a bare JSON number.
|
|
32
|
+
size: bigint;
|
|
33
|
+
/// Optional worst-acceptable price (`i128`). The key is ALWAYS present:
|
|
34
|
+
/// `null` when absent (do NOT omit). `bigint` — emitted as a bare number.
|
|
35
|
+
limit_px: bigint | null;
|
|
36
|
+
/// Server-clock expiry (ms, `u64`). `0` lets the node default to `ts_ms + 5000`.
|
|
37
|
+
expiry_ms: number;
|
|
38
|
+
/// Optional STP group id (`u64`). The key is ALWAYS present: `null` when
|
|
39
|
+
/// absent (do NOT omit).
|
|
40
|
+
stp_group: number | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// `rfq_accept` — a taker crosses against a specific resting quote. Mirrors the
|
|
44
|
+
/// node's `RfqAcceptParams`. The action envelope wraps this under the key
|
|
45
|
+
/// **`accept`** — note the family inconsistency (`rfq_request` uses `rfq`,
|
|
46
|
+
/// `rfq_accept` uses `accept`).
|
|
47
|
+
export interface RfqAccept {
|
|
48
|
+
/// Parent RFQ session id (`u64`).
|
|
49
|
+
rfq_id: number;
|
|
50
|
+
/// Index of the accepted quote in the session's quote vector (`u32`).
|
|
51
|
+
quote_idx: number;
|
|
52
|
+
/// Accepted size (`u128`, `<= min(request.size, quote.max_size)`). `bigint` —
|
|
53
|
+
/// emitted as a bare JSON number.
|
|
54
|
+
size: bigint;
|
|
55
|
+
}
|
package/src/types/vault.ts
CHANGED
|
@@ -53,3 +53,24 @@ export interface VaultWithdraw {
|
|
|
53
53
|
/// Shares to redeem, as a decimal string.
|
|
54
54
|
shares: string;
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
/// `vault_distribute` — a follower deposits USD into a vault and receives shares
|
|
58
|
+
/// at the current NAV (subject to the per-vault withdrawal lock). Mirrors the
|
|
59
|
+
/// node's `core_state` `VaultDistributeParams`; the action envelope wraps this
|
|
60
|
+
/// under the key **`params`**.
|
|
61
|
+
///
|
|
62
|
+
/// **Trap:** the deposit-amount field is named **`pnl`** (a legacy name on the
|
|
63
|
+
/// node), NOT `amount`/`deposit`. It is a positive USD amount encoded as a
|
|
64
|
+
/// decimal string (the SDK's decimal-on-the-wire convention, matching
|
|
65
|
+
/// `vault_transfer` / `vault_withdraw`).
|
|
66
|
+
///
|
|
67
|
+
/// Forward-compat: the node currently answers this tag with `UnsupportedAction`
|
|
68
|
+
/// on the public `/exchange` path; the SDK emits the byte-correct shape the core
|
|
69
|
+
/// handler will accept once the bridge lands.
|
|
70
|
+
export interface VaultDistribute {
|
|
71
|
+
/// Target vault id (`u64`). Serializes as a bare JSON number.
|
|
72
|
+
vault_id: number;
|
|
73
|
+
/// Deposit amount in USD as a positive decimal string. Node field name is
|
|
74
|
+
/// `pnl` (legacy) — do NOT rename.
|
|
75
|
+
pnl: string;
|
|
76
|
+
}
|