@metaflux-dex/client 0.0.1
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/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/client.d.ts +32 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +344 -0
- package/dist/client.js.map +1 -0
- package/dist/http.d.ts +17 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +106 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/info-types.d.ts +380 -0
- package/dist/info-types.d.ts.map +1 -0
- package/dist/info-types.js +16 -0
- package/dist/info-types.js.map +1 -0
- package/dist/info.d.ts +65 -0
- package/dist/info.d.ts.map +1 -0
- package/dist/info.js +252 -0
- package/dist/info.js.map +1 -0
- package/dist/native.d.ts +10 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +252 -0
- package/dist/native.js.map +1 -0
- package/dist/types.d.ts +143 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/wasm.d.ts +28 -0
- package/dist/wasm.d.ts.map +1 -0
- package/dist/wasm.js +279 -0
- package/dist/wasm.js.map +1 -0
- package/dist/ws.d.ts +43 -0
- package/dist/ws.d.ts.map +1 -0
- package/dist/ws.js +221 -0
- package/dist/ws.js.map +1 -0
- package/package.json +65 -0
- package/src/client.ts +454 -0
- package/src/http.ts +153 -0
- package/src/index.ts +144 -0
- package/src/info-types.ts +783 -0
- package/src/info.ts +355 -0
- package/src/native.ts +307 -0
- package/src/types.ts +305 -0
- package/src/wasm.ts +384 -0
- package/src/ws.ts +279 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MetaFlux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# @metaflux-dex/client
|
|
2
|
+
|
|
3
|
+
TypeScript client SDK for the [MetaFlux (MTF)](https://github.com/mtf-exchange) L1.
|
|
4
|
+
CPU-heavy work (secp256k1 signing, keccak256, msgpack canonical encoding) is
|
|
5
|
+
pushed into a wasm-bindgen WASM module — the pure-TS surface is a thin,
|
|
6
|
+
type-safe `fetch` wrapper that speaks the **MTF-native** protocol directly
|
|
7
|
+
(`POST /info` reads, `POST /exchange` signed writes, `wss://…/ws` streams).
|
|
8
|
+
|
|
9
|
+
> MetaFlux-native only. HL-compatible and CCXT endpoints live on the gateway;
|
|
10
|
+
> this SDK targets the node/gateway's first-class MTF-native surface.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @metaflux-dex/client
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The published package ships the compiled `dist/` (TypeScript) and `pkg/` (WASM)
|
|
19
|
+
artifacts — no Rust toolchain needed to **consume** it. You only need Rust +
|
|
20
|
+
`wasm-pack` to build from source (see [Develop](#develop)).
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { Client } from '@metaflux-dex/client';
|
|
26
|
+
|
|
27
|
+
const client = new Client({
|
|
28
|
+
baseUrl: 'http://localhost:8080',
|
|
29
|
+
// Optional. Without a private key the Client is read-only.
|
|
30
|
+
privateKey: new Uint8Array(32).fill(0x42),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// ---- Reads (no key required) — POST /info, {type,data} envelope unwrapped ----
|
|
34
|
+
const markets = await client.info.markets();
|
|
35
|
+
console.log(markets.map((m) => `${m.name} @ ${m.mark_px}`));
|
|
36
|
+
|
|
37
|
+
const acct = await client.info.accountState(
|
|
38
|
+
'0x17c5185167401ed00cf5f5b2fc97d9bbfdb7d025',
|
|
39
|
+
);
|
|
40
|
+
console.log(acct.account_value, acct.positions);
|
|
41
|
+
|
|
42
|
+
// ---- Signed order — POST /exchange (MTF-native signed action) ----
|
|
43
|
+
const ack = await client.submitOrderNative({
|
|
44
|
+
owner: '0x17c5185167401ed00cf5f5b2fc97d9bbfdb7d025', // must equal the signer
|
|
45
|
+
market: 0, // BTC perp (asset id)
|
|
46
|
+
side: 'bid', // 'bid' = buy, 'ask' = sell
|
|
47
|
+
kind: 'limit',
|
|
48
|
+
size: 1_000, // fixed-point tick units
|
|
49
|
+
limit_px: 5_000_000_000_000, // fixed-point tick units
|
|
50
|
+
tif: 'gtc', // 'gtc' | 'ioc' | 'aon' | 'alo'
|
|
51
|
+
stp_mode: 'cancel_newest',
|
|
52
|
+
reduce_only: false,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Synchronous per-order status — the oid is assigned at admission.
|
|
56
|
+
// statuses[i] is one of { resting:{oid} } | { filled:{oid,total_sz,avg_px} } | { error }
|
|
57
|
+
console.log(ack.statuses?.[0]);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The signing flow (EIP-712 over the canonical action bytes, nonce auto-assigned,
|
|
61
|
+
`chainId` defaults to `MTF_CHAIN_ID`) is handled inside `submitOrderNative`. The
|
|
62
|
+
recovered signer is checked against `owner` locally before the request leaves the
|
|
63
|
+
process. Cancel via `client.cancelOrderNative({ … })`.
|
|
64
|
+
|
|
65
|
+
### WebSocket streams
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { WsClient } from '@metaflux-dex/client';
|
|
69
|
+
|
|
70
|
+
const ws = new WsClient('ws://localhost:8080/ws');
|
|
71
|
+
ws.onMessage((f) => {
|
|
72
|
+
if (f.channel === 'l2Book') handleBook(f.data);
|
|
73
|
+
});
|
|
74
|
+
await ws.connect();
|
|
75
|
+
await ws.subscribe({ type: 'l2Book', coin: 'BTC' });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Power-user exports
|
|
79
|
+
|
|
80
|
+
The barrel also exports the low-level pieces so you can build custom flows —
|
|
81
|
+
`InfoApi` (standalone read client), the `buildNativeOrderAction` /
|
|
82
|
+
`signNativeAction` / `nativeActionDigest` action builders, and the WASM crypto
|
|
83
|
+
primitives (`keccak256`, `signSecp256k1`, `recoverPubkey`, …). See
|
|
84
|
+
[`src/index.ts`](src/index.ts) for the full surface.
|
|
85
|
+
|
|
86
|
+
## What's WASM-backed vs pure-TS
|
|
87
|
+
|
|
88
|
+
| Operation | Layer |
|
|
89
|
+
| ---------------------------------- | ---------------------------------------- |
|
|
90
|
+
| keccak256 (any input length) | WASM (`sha3::Keccak256`) |
|
|
91
|
+
| secp256k1 sign / recover / verify | WASM (`k256` 0.13.x) |
|
|
92
|
+
| EIP-712 envelope hash composition | WASM (single keccak call, fewer FFI hops)|
|
|
93
|
+
| msgpack encoding of action bodies | WASM (`rmp_serde::to_vec_named`) |
|
|
94
|
+
| EVM address derivation | WASM (keccak + low-20-bytes slice) |
|
|
95
|
+
| HTTP fetch wrapper | TS |
|
|
96
|
+
| `{type,data}` envelope unwrap | TS |
|
|
97
|
+
| JSON request/response coercion | TS |
|
|
98
|
+
| WebSocket framing + reconnect | TS |
|
|
99
|
+
|
|
100
|
+
The split is intentional: every byte the gateway/node *parses* is produced by
|
|
101
|
+
Rust on both sides. The TS layer only assembles JSON envelopes around
|
|
102
|
+
already-canonical WASM outputs, so the wire format has a single source of truth.
|
|
103
|
+
|
|
104
|
+
## Wire conventions
|
|
105
|
+
|
|
106
|
+
- **Signature**: 65-byte recoverable ECDSA, `r (32) || s (32) || v (1)`, where
|
|
107
|
+
`v` is the raw recovery id (0 or 1).
|
|
108
|
+
- **EIP-712 digest**: `keccak256(0x1901 || domain_separator || message_hash)`,
|
|
109
|
+
`domain = { name: "MetaFlux", version: "1", chainId, verifyingContract: 0x0 }`.
|
|
110
|
+
- **MTF-native action**: a canonical snake_case JSON action
|
|
111
|
+
(`{"type":"submit_order","order":{…}}`) signed verbatim; the request body is
|
|
112
|
+
`{ action, nonce, signature }` to `POST /exchange`.
|
|
113
|
+
|
|
114
|
+
Field shapes are mirrored from the authoritative API spec in
|
|
115
|
+
[`metaflux-knowledges`](https://github.com/mtf-exchange/metaflux-knowledges) and
|
|
116
|
+
the node handlers under `metaflux/crates/api-node/src/rest/`.
|
|
117
|
+
|
|
118
|
+
## Develop
|
|
119
|
+
|
|
120
|
+
This repo uses [pnpm](https://pnpm.io) (see `packageManager` in package.json).
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Rust toolchain + wasm-pack (to build the WASM module).
|
|
124
|
+
brew install rust wasm-pack
|
|
125
|
+
|
|
126
|
+
pnpm install
|
|
127
|
+
pnpm build # wasm-pack -> pkg/, then tsc -> dist/
|
|
128
|
+
pnpm test # vitest
|
|
129
|
+
pnpm typecheck # tsc --noEmit
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Build the artifacts separately with `pnpm build:wasm` / `pnpm build:ts`.
|
|
133
|
+
|
|
134
|
+
## Repository layout
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
.
|
|
138
|
+
├── package.json # @metaflux-dex/client
|
|
139
|
+
├── src/
|
|
140
|
+
│ ├── index.ts # public barrel
|
|
141
|
+
│ ├── client.ts # Client class — reads + signed writes
|
|
142
|
+
│ ├── info.ts # InfoApi — POST /info read methods
|
|
143
|
+
│ ├── info-types.ts # /info response shapes ({type,data}.data)
|
|
144
|
+
│ ├── native.ts # MTF-native action build + sign + digest
|
|
145
|
+
│ ├── ws.ts # WsClient — subscriptions + reconnect
|
|
146
|
+
│ ├── wasm.ts # WASM loader + typed crypto wrappers
|
|
147
|
+
│ ├── http.ts # fetch wrapper + MetaFluxApiError
|
|
148
|
+
│ └── types.ts # Order / NativeOrder / acks / shared enums
|
|
149
|
+
├── __tests__/ # vitest: info / native / sign / ws
|
|
150
|
+
├── wasm/ # standalone wasm-bindgen crate (+ native tests)
|
|
151
|
+
├── pkg/ # wasm-pack output (gitignored)
|
|
152
|
+
└── dist/ # tsc output (gitignored)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
[MIT](LICENSE) © MetaFlux
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { InfoApi } from './info.js';
|
|
2
|
+
import { WsClient, type WsConfig } from './ws.js';
|
|
3
|
+
import type { Market, NativeCancel, NativeExchangeAck, NativeOrder, Order, OrderAck, Position, SignedOrder } from './types.js';
|
|
4
|
+
export interface ClientOpts {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
privateKey?: Uint8Array;
|
|
7
|
+
chainId?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class Client {
|
|
10
|
+
private readonly baseUrl;
|
|
11
|
+
private readonly privateKey;
|
|
12
|
+
private readonly chainId;
|
|
13
|
+
private jwt;
|
|
14
|
+
readonly info: InfoApi;
|
|
15
|
+
constructor(opts: ClientOpts);
|
|
16
|
+
get canSign(): boolean;
|
|
17
|
+
signOrder(order: Order): Promise<SignedOrder>;
|
|
18
|
+
submitOrder(signed: SignedOrder): Promise<OrderAck>;
|
|
19
|
+
submitOrderNative(order: NativeOrder, opts?: {
|
|
20
|
+
nonce?: bigint;
|
|
21
|
+
chainId?: number;
|
|
22
|
+
}): Promise<NativeExchangeAck>;
|
|
23
|
+
cancelOrderNative(cancel: NativeCancel, opts?: {
|
|
24
|
+
nonce?: bigint;
|
|
25
|
+
chainId?: number;
|
|
26
|
+
}): Promise<NativeExchangeAck>;
|
|
27
|
+
connectWs(config?: Partial<WsConfig>): Promise<WsClient>;
|
|
28
|
+
getMarkets(): Promise<Market[]>;
|
|
29
|
+
getPositions(account: string): Promise<Position[]>;
|
|
30
|
+
setJwt(token: string): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACZ,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,UAAU;IAIzB,OAAO,EAAE,MAAM,CAAC;IAIhB,UAAU,CAAC,EAAE,UAAU,CAAC;IAGxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAwFD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAGjC,OAAO,CAAC,GAAG,CAAqB;IAEhC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,IAAI,EAAE,UAAU;IAe5B,IAAI,OAAO,IAAI,OAAO,CAErB;IAoBK,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC;IAgD7C,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyCnD,iBAAiB,CACrB,KAAK,EAAE,WAAW,EAClB,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAC9C,OAAO,CAAC,iBAAiB,CAAC;IA0CvB,iBAAiB,CACrB,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAC9C,OAAO,CAAC,iBAAiB,CAAC;IAmCvB,SAAS,CAAC,MAAM,GAAE,OAAO,CAAC,QAAQ,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ5D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQ/B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAcxD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAG5B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
// `Client` — primary entry point for the @metaflux-dex/client SDK.
|
|
2
|
+
//
|
|
3
|
+
// Heavy lifting: order signing (msgpack encode -> EIP-712 hash ->
|
|
4
|
+
// secp256k1 sign -> address derive) runs through WASM. Pure-TS
|
|
5
|
+
// responsibilities: HTTP plumbing, type coercion, optional JWT
|
|
6
|
+
// session bookkeeping.
|
|
7
|
+
//
|
|
8
|
+
// Naming note: exported as `Client` (NOT `MtfClient`) per session
|
|
9
|
+
// direction. Consumers import as `import { Client } from '@metaflux-dex/client'`.
|
|
10
|
+
import { deriveAddressFromPubkey, eip712TypedDataHash, encodeLimitOrder, keccak256, recoverPubkey, signSecp256k1, } from './wasm.js';
|
|
11
|
+
import { httpRequest } from './http.js';
|
|
12
|
+
import { buildNativeCancelAction, buildNativeOrderAction, nativeRequestBody, nextNonce, recoverNativeSigner, signNativeAction, } from './native.js';
|
|
13
|
+
import { InfoApi } from './info.js';
|
|
14
|
+
import { WsClient } from './ws.js';
|
|
15
|
+
/// Default chain ID for the EIP-712 domain. The MetaFlux mainnet ID is
|
|
16
|
+
/// reserved-but-not-yet-assigned (PLAN.md §M.1 — "TBD pre-mainnet, avoid
|
|
17
|
+
/// 999 which is HL"); the devnet default `31337` matches what the
|
|
18
|
+
/// existing core-state tests use.
|
|
19
|
+
const DEFAULT_CHAIN_ID = 31337;
|
|
20
|
+
/// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`
|
|
21
|
+
/// pre-computed at module load. Static across the SDK lifetime so we
|
|
22
|
+
/// don't re-keccak it for every signing call.
|
|
23
|
+
let cachedDomainTypeHash;
|
|
24
|
+
async function domainTypeHash() {
|
|
25
|
+
if (cachedDomainTypeHash === undefined) {
|
|
26
|
+
cachedDomainTypeHash = await keccak256(new TextEncoder().encode('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'));
|
|
27
|
+
}
|
|
28
|
+
return cachedDomainTypeHash;
|
|
29
|
+
}
|
|
30
|
+
/// Pre-computed type-hash for the limit-order action. The string mirrors
|
|
31
|
+
/// what the node will register for the `Order` action — locked in by
|
|
32
|
+
/// RFC-001 §D once the on-chain registry lands. The shape here matches
|
|
33
|
+
/// what `encode_limit_order` produces.
|
|
34
|
+
let cachedOrderTypeHash;
|
|
35
|
+
async function orderTypeHash() {
|
|
36
|
+
if (cachedOrderTypeHash === undefined) {
|
|
37
|
+
cachedOrderTypeHash = await keccak256(new TextEncoder().encode('Order(uint32 asset,uint8 side,uint128 px,uint128 size,uint8 tif)'));
|
|
38
|
+
}
|
|
39
|
+
return cachedOrderTypeHash;
|
|
40
|
+
}
|
|
41
|
+
/// Compute the EIP-712 domain separator for a given chain id.
|
|
42
|
+
///
|
|
43
|
+
/// Mirrors `core_state::signing::EipDomain::separator` — the canonical
|
|
44
|
+
/// 5-segment keccak input is
|
|
45
|
+
/// `(domain_type_hash, name_hash, version_hash, chain_id_be32, verifying_contract_padded)`.
|
|
46
|
+
async function computeDomainSeparator(chainId) {
|
|
47
|
+
const dth = await domainTypeHash();
|
|
48
|
+
const nameHash = await keccak256(new TextEncoder().encode('MetaFlux'));
|
|
49
|
+
const versionHash = await keccak256(new TextEncoder().encode('1'));
|
|
50
|
+
// uint256 chainId big-endian, 32 bytes.
|
|
51
|
+
const chainIdBe = new Uint8Array(32);
|
|
52
|
+
// JS bitwise ops are signed 32-bit; use BigInt for the conversion.
|
|
53
|
+
const view = new DataView(chainIdBe.buffer);
|
|
54
|
+
view.setBigUint64(24, BigInt(chainId)); // low 8 bytes carry the value.
|
|
55
|
+
// Verifying contract == Address::ZERO, left-padded to 32 bytes -> all zeros.
|
|
56
|
+
const verifyingPadded = new Uint8Array(32);
|
|
57
|
+
// Concat + keccak. Allocating one Uint8Array beats 5 hasher.update calls
|
|
58
|
+
// because the WASM keccak primitive takes a single slice — the
|
|
59
|
+
// call-overhead of multiple FFI hops would outweigh the copy.
|
|
60
|
+
const concat = new Uint8Array(5 * 32);
|
|
61
|
+
concat.set(dth, 0);
|
|
62
|
+
concat.set(nameHash, 32);
|
|
63
|
+
concat.set(versionHash, 64);
|
|
64
|
+
concat.set(chainIdBe, 96);
|
|
65
|
+
concat.set(verifyingPadded, 128);
|
|
66
|
+
return keccak256(concat);
|
|
67
|
+
}
|
|
68
|
+
/// Primary client surface. Construct once per session.
|
|
69
|
+
///
|
|
70
|
+
/// Read-only example:
|
|
71
|
+
/// ```ts
|
|
72
|
+
/// const c = new Client({ baseUrl: 'http://localhost:8080' });
|
|
73
|
+
/// const markets = await c.getMarkets();
|
|
74
|
+
/// ```
|
|
75
|
+
///
|
|
76
|
+
/// Signing example:
|
|
77
|
+
/// ```ts
|
|
78
|
+
/// const c = new Client({
|
|
79
|
+
/// baseUrl: 'http://localhost:8080',
|
|
80
|
+
/// privateKey: hexToBytes('...'),
|
|
81
|
+
/// });
|
|
82
|
+
/// const signed = await c.signOrder({ asset: 0, side: 0, sizeE8: 100_000_000n,
|
|
83
|
+
/// priceE8: 50_000_00000000n, tif: 0 });
|
|
84
|
+
/// const ack = await c.submitOrder(signed);
|
|
85
|
+
/// ```
|
|
86
|
+
export class Client {
|
|
87
|
+
baseUrl;
|
|
88
|
+
privateKey;
|
|
89
|
+
chainId;
|
|
90
|
+
/// Cached gateway-issued JWT (`/auth`). The session is established
|
|
91
|
+
/// lazily on the first authenticated call.
|
|
92
|
+
jwt;
|
|
93
|
+
/// MTF-native read API (`POST /info`). Read-only; no key required.
|
|
94
|
+
info;
|
|
95
|
+
constructor(opts) {
|
|
96
|
+
if (opts.baseUrl.length === 0) {
|
|
97
|
+
throw new RangeError('Client baseUrl must be non-empty');
|
|
98
|
+
}
|
|
99
|
+
if (opts.privateKey !== undefined && opts.privateKey.length !== 32) {
|
|
100
|
+
throw new RangeError('Client privateKey must be exactly 32 bytes');
|
|
101
|
+
}
|
|
102
|
+
this.baseUrl = opts.baseUrl;
|
|
103
|
+
this.privateKey = opts.privateKey;
|
|
104
|
+
this.chainId = opts.chainId ?? DEFAULT_CHAIN_ID;
|
|
105
|
+
this.info = new InfoApi(this.baseUrl);
|
|
106
|
+
}
|
|
107
|
+
/// Whether this client has a private key available for signing
|
|
108
|
+
/// operations. Read-only data calls work regardless.
|
|
109
|
+
get canSign() {
|
|
110
|
+
return this.privateKey !== undefined;
|
|
111
|
+
}
|
|
112
|
+
/// Sign an order body. Returns the `(payload, signature, signer)`
|
|
113
|
+
/// triplet ready for `submitOrder`.
|
|
114
|
+
///
|
|
115
|
+
/// All heavy lifting (msgpack encode, keccak, ECDSA) is in WASM.
|
|
116
|
+
/// The signing flow:
|
|
117
|
+
///
|
|
118
|
+
/// 1. `payload = encode_limit_order(...)` — msgpack body matching the
|
|
119
|
+
/// node's `OrderParams` decoder.
|
|
120
|
+
/// 2. `messageHash = keccak256(orderTypeHash || payload)` — the
|
|
121
|
+
/// EIP-712 "struct hash" of the action.
|
|
122
|
+
/// 3. `domainSeparator = keccak256(EIP712Domain(...))` — cached.
|
|
123
|
+
/// 4. `digest = keccak256(0x1901 || domainSeparator || messageHash)`.
|
|
124
|
+
/// 5. `signature = sign_secp256k1(privateKey, digest)`.
|
|
125
|
+
/// 6. `signer = derive_address_from_pubkey(recover_pubkey(signature, digest))`.
|
|
126
|
+
///
|
|
127
|
+
/// Step 6 derives the signer locally rather than trusting the gateway
|
|
128
|
+
/// to recover it; that way the SDK ships the address upfront and the
|
|
129
|
+
/// gateway can reject obviously-replayed envelopes before doing ECDSA.
|
|
130
|
+
async signOrder(order) {
|
|
131
|
+
if (this.privateKey === undefined) {
|
|
132
|
+
throw new Error('signOrder requires a privateKey in ClientOpts (this Client is read-only)');
|
|
133
|
+
}
|
|
134
|
+
const payload = await encodeLimitOrder(order.asset, order.side, order.sizeE8, order.priceE8, order.tif, order.stp ?? 0, order.cloid, order.reduceOnly ?? false, order.builder);
|
|
135
|
+
const typeHash = await orderTypeHash();
|
|
136
|
+
// message_hash = keccak256(type_hash || payload).
|
|
137
|
+
const msgBuffer = new Uint8Array(typeHash.length + payload.length);
|
|
138
|
+
msgBuffer.set(typeHash, 0);
|
|
139
|
+
msgBuffer.set(payload, typeHash.length);
|
|
140
|
+
const messageHash = await keccak256(msgBuffer);
|
|
141
|
+
const domainSeparator = await computeDomainSeparator(this.chainId);
|
|
142
|
+
const digest = await eip712TypedDataHash(domainSeparator, messageHash);
|
|
143
|
+
const signature = await signSecp256k1(this.privateKey, digest);
|
|
144
|
+
const pubkey = await recoverPubkey(signature, digest);
|
|
145
|
+
const signer = await deriveAddressFromPubkey(pubkey);
|
|
146
|
+
return { payload, signature, signer };
|
|
147
|
+
}
|
|
148
|
+
/// Submit a pre-signed order to the gateway.
|
|
149
|
+
///
|
|
150
|
+
/// DEPRECATED / LEGACY: this targets the old `{payload,signature,signer}` →
|
|
151
|
+
/// `/v1/orders` envelope with a msgpack body and an `Order(...)` typehash.
|
|
152
|
+
/// The server now accepts the MTF-native `{action,nonce,signature}` →
|
|
153
|
+
/// `/exchange` envelope instead — use `submitOrderNative`. Retained
|
|
154
|
+
/// only for any consumer still on the old gateway adapter.
|
|
155
|
+
///
|
|
156
|
+
/// Wire shape: POSTs the `SignedOrder` as a msgpack-friendly JSON
|
|
157
|
+
/// envelope — `payload` and `signature` go as base64url strings (the
|
|
158
|
+
/// gateway's existing `LoginEnvelope` shape uses base64; we mirror
|
|
159
|
+
/// that), `signer` goes as a 0x-hex address. The gateway adapter
|
|
160
|
+
/// (TODO on the server side) decodes and forwards to the node via
|
|
161
|
+
/// gRPC; for now the SDK targets the CCXT createOrder response shape.
|
|
162
|
+
async submitOrder(signed) {
|
|
163
|
+
return httpRequest(this.baseUrl, '/v1/orders', {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
json: {
|
|
166
|
+
payload: bytesToBase64Url(signed.payload),
|
|
167
|
+
signature: bytesToBase64Url(signed.signature),
|
|
168
|
+
signer: bytesToHex(signed.signer, '0x'),
|
|
169
|
+
},
|
|
170
|
+
bearer: this.jwt,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/// Submit an order via the MTF-native signed-action front door
|
|
174
|
+
/// (`POST /exchange`).
|
|
175
|
+
///
|
|
176
|
+
/// This is the path the server now accepts. It supersedes the legacy
|
|
177
|
+
/// `signOrder` + `submitOrder` flow (msgpack body + `Order(...)` typehash +
|
|
178
|
+
/// `{payload,signature,signer}` → `/v1/orders`), which targeted an
|
|
179
|
+
/// envelope the node no longer recognizes.
|
|
180
|
+
///
|
|
181
|
+
/// Flow:
|
|
182
|
+
/// 1. `buildNativeOrderAction` produces the canonical snake_case action JSON
|
|
183
|
+
/// string (`{"type":"submit_order","order":{...}}`), field order matching
|
|
184
|
+
/// the server `NativeOrder`.
|
|
185
|
+
/// 2. `signNativeAction` computes the native EIP-712 digest over the EXACT
|
|
186
|
+
/// action bytes (`MetaFluxAction(string action,uint64 nonce)` struct hash,
|
|
187
|
+
/// 5-field domain) and signs it.
|
|
188
|
+
/// 3. The action string is POSTed VERBATIM inside `{action, nonce, signature}`
|
|
189
|
+
/// — the server recovers the signer over the raw `action` bytes, so the
|
|
190
|
+
/// signed bytes and the sent bytes are identical.
|
|
191
|
+
///
|
|
192
|
+
/// `order.owner` MUST equal the signing wallet's address; we recover the
|
|
193
|
+
/// signer locally and reject a mismatch before hitting the network (the
|
|
194
|
+
/// server enforces the same).
|
|
195
|
+
///
|
|
196
|
+
/// `nonce` is the per-owner replay nonce bound into the digest. Defaults to
|
|
197
|
+
/// `Date.now()` (unix-ms) — supply an explicit monotonically-increasing
|
|
198
|
+
/// value for back-to-back submissions in the same millisecond.
|
|
199
|
+
///
|
|
200
|
+
/// `chainId` defaults to the MTF-native chain id (998), independent of the
|
|
201
|
+
/// legacy `ClientOpts.chainId` (which is the wrong domain for this path).
|
|
202
|
+
async submitOrderNative(order, opts = {}) {
|
|
203
|
+
if (this.privateKey === undefined) {
|
|
204
|
+
throw new Error('submitOrderNative requires a privateKey in ClientOpts (this Client is read-only)');
|
|
205
|
+
}
|
|
206
|
+
const nonce = opts.nonce ?? nextNonce();
|
|
207
|
+
const actionJson = buildNativeOrderAction(order);
|
|
208
|
+
const signed = await signNativeAction(this.privateKey, actionJson, nonce, opts.chainId);
|
|
209
|
+
// Local guard: the recovered signer must equal the claimed owner. The
|
|
210
|
+
// server enforces this too (401 on mismatch), but failing here saves a
|
|
211
|
+
// round-trip and surfaces a key/owner mismatch with a clear message.
|
|
212
|
+
const signer = await recoverNativeSigner(signed, opts.chainId);
|
|
213
|
+
if (signer.toLowerCase() !== order.owner.toLowerCase()) {
|
|
214
|
+
throw new Error(`order.owner ${order.owner} != recovered signer ${signer}`);
|
|
215
|
+
}
|
|
216
|
+
return httpRequest(this.baseUrl, '/exchange', {
|
|
217
|
+
method: 'POST',
|
|
218
|
+
rawJson: nativeRequestBody(signed),
|
|
219
|
+
bearer: this.jwt,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/// Cancel an order via the MTF-native signed-action front door
|
|
223
|
+
/// (`POST /exchange`).
|
|
224
|
+
///
|
|
225
|
+
/// Same envelope + verification model as `submitOrderNative`: the
|
|
226
|
+
/// `cancel_order` action JSON is built canonically, signed over the EIP-712
|
|
227
|
+
/// native digest, and POSTed verbatim. The server cancels by `oid`, so
|
|
228
|
+
/// `cancel.oid` must be set (a `cloid`-only cancel is rejected at lowering).
|
|
229
|
+
///
|
|
230
|
+
/// `cancel.owner` MUST equal the signing wallet; we recover the signer
|
|
231
|
+
/// locally and reject a mismatch before hitting the network.
|
|
232
|
+
async cancelOrderNative(cancel, opts = {}) {
|
|
233
|
+
if (this.privateKey === undefined) {
|
|
234
|
+
throw new Error('cancelOrderNative requires a privateKey in ClientOpts (this Client is read-only)');
|
|
235
|
+
}
|
|
236
|
+
const nonce = opts.nonce ?? nextNonce();
|
|
237
|
+
const actionJson = buildNativeCancelAction(cancel);
|
|
238
|
+
const signed = await signNativeAction(this.privateKey, actionJson, nonce, opts.chainId);
|
|
239
|
+
const signer = await recoverNativeSigner(signed, opts.chainId);
|
|
240
|
+
if (signer.toLowerCase() !== cancel.owner.toLowerCase()) {
|
|
241
|
+
throw new Error(`cancel.owner ${cancel.owner} != recovered signer ${signer}`);
|
|
242
|
+
}
|
|
243
|
+
return httpRequest(this.baseUrl, '/exchange', {
|
|
244
|
+
method: 'POST',
|
|
245
|
+
rawJson: nativeRequestBody(signed),
|
|
246
|
+
bearer: this.jwt,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/// Open an MTF-native WebSocket connection to `<baseUrl>/ws`.
|
|
250
|
+
///
|
|
251
|
+
/// Derives the `ws(s)://` URL from the client's `http(s)://` base, mounts the
|
|
252
|
+
/// `/ws` path (the node's upgrade route), and returns a connected
|
|
253
|
+
/// [`WsClient`]. Register handlers via `ws.onMessage` and subscribe with
|
|
254
|
+
/// `ws.subscribe({ type: 'l2Book', coin: 'BTC' })`.
|
|
255
|
+
async connectWs(config = {}) {
|
|
256
|
+
const ws = new WsClient(httpToWsUrl(this.baseUrl), config);
|
|
257
|
+
await ws.connect();
|
|
258
|
+
return ws;
|
|
259
|
+
}
|
|
260
|
+
/// `fetchMarkets` — list of all CCXT-compat market descriptors.
|
|
261
|
+
/// Unauthenticated.
|
|
262
|
+
async getMarkets() {
|
|
263
|
+
return httpRequest(this.baseUrl, '/ccxt/markets');
|
|
264
|
+
}
|
|
265
|
+
/// `fetchPositions` for a given account. Authenticated. The CCXT
|
|
266
|
+
/// surface defines `fetchPositions(symbols?)`; the MTF gateway
|
|
267
|
+
/// adapter accepts an explicit `account` query parameter so the
|
|
268
|
+
/// caller can fetch positions for sub-accounts they control.
|
|
269
|
+
async getPositions(account) {
|
|
270
|
+
if (!isHexAddress(account)) {
|
|
271
|
+
throw new RangeError(`getPositions: account must be a 0x-prefixed 20-byte hex string, got '${account}'`);
|
|
272
|
+
}
|
|
273
|
+
return httpRequest(this.baseUrl, '/ccxt/positions', {
|
|
274
|
+
query: { account },
|
|
275
|
+
bearer: this.jwt,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/// Internal: set the JWT after a successful `/auth` exchange. Exposed
|
|
279
|
+
/// so an external auth flow (wallet popup, etc.) can plant a token.
|
|
280
|
+
setJwt(token) {
|
|
281
|
+
this.jwt = token;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ============================================================================
|
|
285
|
+
// Encoding helpers — narrow + private
|
|
286
|
+
// ============================================================================
|
|
287
|
+
/// Encode a `Uint8Array` as a base64url string (no padding).
|
|
288
|
+
///
|
|
289
|
+
/// Matches the encoding the gateway's `LoginEnvelope.signature` field
|
|
290
|
+
/// expects (see `metaflux/crates/api-gateway/src/ccxt/auth.rs`). We
|
|
291
|
+
/// avoid Buffer/global polyfills here because the SDK targets both
|
|
292
|
+
/// node and the browser; manual base64 is small and avoids the
|
|
293
|
+
/// dependency.
|
|
294
|
+
function bytesToBase64Url(bytes) {
|
|
295
|
+
// Build a binary string of the bytes. `String.fromCharCode` is
|
|
296
|
+
// bounded to ~65k arguments per call — safe for any signature
|
|
297
|
+
// (65 bytes) or payload (under 1KB).
|
|
298
|
+
let binary = '';
|
|
299
|
+
for (const b of bytes)
|
|
300
|
+
binary += String.fromCharCode(b);
|
|
301
|
+
const b64 = btoa(binary);
|
|
302
|
+
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
303
|
+
}
|
|
304
|
+
/// Encode a `Uint8Array` as a hex string with optional `0x` prefix.
|
|
305
|
+
function bytesToHex(bytes, prefix = '') {
|
|
306
|
+
let out = prefix;
|
|
307
|
+
for (const b of bytes) {
|
|
308
|
+
out += b.toString(16).padStart(2, '0');
|
|
309
|
+
}
|
|
310
|
+
return out;
|
|
311
|
+
}
|
|
312
|
+
/// Derive the WS endpoint URL from the client's HTTP base URL: map the scheme
|
|
313
|
+
/// (`http`→`ws`, `https`→`wss`), strip any trailing slash, and append `/ws`
|
|
314
|
+
/// (the node's upgrade route). A base that is already `ws(s)://` is passed
|
|
315
|
+
/// through (only the `/ws` suffix is ensured).
|
|
316
|
+
function httpToWsUrl(baseUrl) {
|
|
317
|
+
let url = baseUrl;
|
|
318
|
+
if (url.startsWith('https://')) {
|
|
319
|
+
url = `wss://${url.slice('https://'.length)}`;
|
|
320
|
+
}
|
|
321
|
+
else if (url.startsWith('http://')) {
|
|
322
|
+
url = `ws://${url.slice('http://'.length)}`;
|
|
323
|
+
}
|
|
324
|
+
if (url.endsWith('/'))
|
|
325
|
+
url = url.slice(0, -1);
|
|
326
|
+
return url.endsWith('/ws') ? url : `${url}/ws`;
|
|
327
|
+
}
|
|
328
|
+
/// Validate that a string is a `0x` + 40 hex chars EVM address.
|
|
329
|
+
function isHexAddress(s) {
|
|
330
|
+
if (s.length !== 42)
|
|
331
|
+
return false;
|
|
332
|
+
if (!s.startsWith('0x'))
|
|
333
|
+
return false;
|
|
334
|
+
for (let i = 2; i < s.length; i++) {
|
|
335
|
+
const c = s.charCodeAt(i);
|
|
336
|
+
const isHex = (c >= 0x30 && c <= 0x39) ||
|
|
337
|
+
(c >= 0x41 && c <= 0x46) ||
|
|
338
|
+
(c >= 0x61 && c <= 0x66);
|
|
339
|
+
if (!isHex)
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class MetaFluxApiError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly bodyText: string;
|
|
4
|
+
constructor(status: number, bodyText: string, message: string);
|
|
5
|
+
}
|
|
6
|
+
export interface HttpRequestInit {
|
|
7
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
8
|
+
json?: unknown;
|
|
9
|
+
bytes?: Uint8Array;
|
|
10
|
+
rawJson?: string;
|
|
11
|
+
bearer?: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
query?: Record<string, string>;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}
|
|
16
|
+
export declare function httpRequest<T>(baseUrl: string, path: string, init?: HttpRequestInit): Promise<T>;
|
|
17
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAaA,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;gBADhB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM;CAKlB;AAID,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAG3C,IAAI,CAAC,EAAE,OAAO,CAAC;IAIf,KAAK,CAAC,EAAE,UAAU,CAAC;IAOnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAGjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG/B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAUD,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,CAAC,CAAC,CAmDZ"}
|