@speculite/clob-client 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/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/client/baseClient.d.ts +93 -0
- package/dist/client/baseClient.js +374 -0
- package/dist/client/baseClient.js.map +1 -0
- package/dist/client/lifecycleClient.d.ts +48 -0
- package/dist/client/lifecycleClient.js +163 -0
- package/dist/client/lifecycleClient.js.map +1 -0
- package/dist/client/publicClient.d.ts +44 -0
- package/dist/client/publicClient.js +127 -0
- package/dist/client/publicClient.js.map +1 -0
- package/dist/client/tradingClient.d.ts +15 -0
- package/dist/client/tradingClient.js +75 -0
- package/dist/client/tradingClient.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +31 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/constants.d.ts +142 -0
- package/dist/internal/constants.js +84 -0
- package/dist/internal/constants.js.map +1 -0
- package/dist/internal/utils.d.ts +26 -0
- package/dist/internal/utils.js +115 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/speculiteClobClient.d.ts +16 -0
- package/dist/speculiteClobClient.js +17 -0
- package/dist/speculiteClobClient.js.map +1 -0
- package/dist/types.d.ts +353 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-712 typed-data schema used for off-chain order signatures.
|
|
3
|
+
*/
|
|
4
|
+
export declare const ORDER_TYPES: {
|
|
5
|
+
readonly Order: readonly [{
|
|
6
|
+
readonly name: "marketId";
|
|
7
|
+
readonly type: "uint256";
|
|
8
|
+
}, {
|
|
9
|
+
readonly name: "maker";
|
|
10
|
+
readonly type: "address";
|
|
11
|
+
}, {
|
|
12
|
+
readonly name: "isSell";
|
|
13
|
+
readonly type: "bool";
|
|
14
|
+
}, {
|
|
15
|
+
readonly name: "tokenId";
|
|
16
|
+
readonly type: "uint256";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "amount";
|
|
19
|
+
readonly type: "uint256";
|
|
20
|
+
}, {
|
|
21
|
+
readonly name: "price";
|
|
22
|
+
readonly type: "uint256";
|
|
23
|
+
}, {
|
|
24
|
+
readonly name: "feeBps";
|
|
25
|
+
readonly type: "uint256";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "nonce";
|
|
28
|
+
readonly type: "uint256";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "expiry";
|
|
31
|
+
readonly type: "uint256";
|
|
32
|
+
}];
|
|
33
|
+
};
|
|
34
|
+
export declare const SCALE = 1000000;
|
|
35
|
+
/** Minimum extra wei added when paying Pyth update fee to avoid edge underpayment. */
|
|
36
|
+
export declare const MIN_UPDATE_FEE_BUFFER_WEI = 1000n;
|
|
37
|
+
/** Default Hermes endpoint used to fetch Pyth update payloads. */
|
|
38
|
+
export declare const DEFAULT_PYTH_PRICE_SERVICE_URL = "https://hermes.pyth.network";
|
|
39
|
+
/** ERC20 ABI subset needed for USDC approvals. */
|
|
40
|
+
export declare const ERC20_ABI: readonly [{
|
|
41
|
+
readonly inputs: readonly [{
|
|
42
|
+
readonly internalType: "address";
|
|
43
|
+
readonly name: "spender";
|
|
44
|
+
readonly type: "address";
|
|
45
|
+
}, {
|
|
46
|
+
readonly internalType: "uint256";
|
|
47
|
+
readonly name: "value";
|
|
48
|
+
readonly type: "uint256";
|
|
49
|
+
}];
|
|
50
|
+
readonly name: "approve";
|
|
51
|
+
readonly outputs: readonly [{
|
|
52
|
+
readonly internalType: "bool";
|
|
53
|
+
readonly name: "";
|
|
54
|
+
readonly type: "bool";
|
|
55
|
+
}];
|
|
56
|
+
readonly stateMutability: "nonpayable";
|
|
57
|
+
readonly type: "function";
|
|
58
|
+
}];
|
|
59
|
+
/** Exchange ABI subset needed to mint paired outcome tokens. */
|
|
60
|
+
export declare const EXCHANGE_MINT_ABI: readonly [{
|
|
61
|
+
readonly inputs: readonly [{
|
|
62
|
+
readonly internalType: "uint256";
|
|
63
|
+
readonly name: "marketId";
|
|
64
|
+
readonly type: "uint256";
|
|
65
|
+
}, {
|
|
66
|
+
readonly internalType: "uint256";
|
|
67
|
+
readonly name: "amount";
|
|
68
|
+
readonly type: "uint256";
|
|
69
|
+
}];
|
|
70
|
+
readonly name: "mint";
|
|
71
|
+
readonly outputs: readonly [];
|
|
72
|
+
readonly stateMutability: "nonpayable";
|
|
73
|
+
readonly type: "function";
|
|
74
|
+
}];
|
|
75
|
+
/** Exchange ABI subset needed to merge paired tokens back into USDC. */
|
|
76
|
+
export declare const EXCHANGE_MERGE_ABI: readonly [{
|
|
77
|
+
readonly inputs: readonly [{
|
|
78
|
+
readonly internalType: "uint256";
|
|
79
|
+
readonly name: "marketId";
|
|
80
|
+
readonly type: "uint256";
|
|
81
|
+
}, {
|
|
82
|
+
readonly internalType: "address";
|
|
83
|
+
readonly name: "holder";
|
|
84
|
+
readonly type: "address";
|
|
85
|
+
}, {
|
|
86
|
+
readonly internalType: "uint256";
|
|
87
|
+
readonly name: "pairs";
|
|
88
|
+
readonly type: "uint256";
|
|
89
|
+
}];
|
|
90
|
+
readonly name: "mergeFor";
|
|
91
|
+
readonly outputs: readonly [];
|
|
92
|
+
readonly stateMutability: "nonpayable";
|
|
93
|
+
readonly type: "function";
|
|
94
|
+
}];
|
|
95
|
+
/** Exchange ABI subset needed to claim winnings on resolved markets. */
|
|
96
|
+
export declare const EXCHANGE_CLAIM_ABI: readonly [{
|
|
97
|
+
readonly inputs: readonly [{
|
|
98
|
+
readonly internalType: "uint256";
|
|
99
|
+
readonly name: "marketId";
|
|
100
|
+
readonly type: "uint256";
|
|
101
|
+
}];
|
|
102
|
+
readonly name: "claimWinnings";
|
|
103
|
+
readonly outputs: readonly [];
|
|
104
|
+
readonly stateMutability: "nonpayable";
|
|
105
|
+
readonly type: "function";
|
|
106
|
+
}];
|
|
107
|
+
/** Exchange ABI subset needed to resolve a market with Pyth updates. */
|
|
108
|
+
export declare const EXCHANGE_RESOLVE_ABI: readonly [{
|
|
109
|
+
readonly inputs: readonly [{
|
|
110
|
+
readonly internalType: "uint256";
|
|
111
|
+
readonly name: "marketId";
|
|
112
|
+
readonly type: "uint256";
|
|
113
|
+
}, {
|
|
114
|
+
readonly internalType: "address";
|
|
115
|
+
readonly name: "pyth";
|
|
116
|
+
readonly type: "address";
|
|
117
|
+
}, {
|
|
118
|
+
readonly internalType: "bytes[]";
|
|
119
|
+
readonly name: "updateData";
|
|
120
|
+
readonly type: "bytes[]";
|
|
121
|
+
}];
|
|
122
|
+
readonly name: "resolveMarketWithPyth";
|
|
123
|
+
readonly outputs: readonly [];
|
|
124
|
+
readonly stateMutability: "payable";
|
|
125
|
+
readonly type: "function";
|
|
126
|
+
}];
|
|
127
|
+
/** Pyth ABI subset needed to quote fee for a price update payload. */
|
|
128
|
+
export declare const PYTH_ABI: readonly [{
|
|
129
|
+
readonly inputs: readonly [{
|
|
130
|
+
readonly internalType: "bytes[]";
|
|
131
|
+
readonly name: "updateData";
|
|
132
|
+
readonly type: "bytes[]";
|
|
133
|
+
}];
|
|
134
|
+
readonly name: "getUpdateFee";
|
|
135
|
+
readonly outputs: readonly [{
|
|
136
|
+
readonly internalType: "uint256";
|
|
137
|
+
readonly name: "";
|
|
138
|
+
readonly type: "uint256";
|
|
139
|
+
}];
|
|
140
|
+
readonly stateMutability: "view";
|
|
141
|
+
readonly type: "function";
|
|
142
|
+
}];
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-712 typed-data schema used for off-chain order signatures.
|
|
3
|
+
*/
|
|
4
|
+
export const ORDER_TYPES = {
|
|
5
|
+
Order: [
|
|
6
|
+
{ name: 'marketId', type: 'uint256' },
|
|
7
|
+
{ name: 'maker', type: 'address' },
|
|
8
|
+
{ name: 'isSell', type: 'bool' },
|
|
9
|
+
{ name: 'tokenId', type: 'uint256' },
|
|
10
|
+
{ name: 'amount', type: 'uint256' },
|
|
11
|
+
{ name: 'price', type: 'uint256' },
|
|
12
|
+
{ name: 'feeBps', type: 'uint256' },
|
|
13
|
+
{ name: 'nonce', type: 'uint256' },
|
|
14
|
+
{ name: 'expiry', type: 'uint256' }
|
|
15
|
+
]
|
|
16
|
+
};
|
|
17
|
+
export const SCALE = 1_000_000;
|
|
18
|
+
/** Minimum extra wei added when paying Pyth update fee to avoid edge underpayment. */
|
|
19
|
+
export const MIN_UPDATE_FEE_BUFFER_WEI = 1000n;
|
|
20
|
+
/** Default Hermes endpoint used to fetch Pyth update payloads. */
|
|
21
|
+
export const DEFAULT_PYTH_PRICE_SERVICE_URL = 'https://hermes.pyth.network';
|
|
22
|
+
/** ERC20 ABI subset needed for USDC approvals. */
|
|
23
|
+
export const ERC20_ABI = [{
|
|
24
|
+
inputs: [
|
|
25
|
+
{ internalType: 'address', name: 'spender', type: 'address' },
|
|
26
|
+
{ internalType: 'uint256', name: 'value', type: 'uint256' }
|
|
27
|
+
],
|
|
28
|
+
name: 'approve',
|
|
29
|
+
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
|
|
30
|
+
stateMutability: 'nonpayable',
|
|
31
|
+
type: 'function'
|
|
32
|
+
}];
|
|
33
|
+
/** Exchange ABI subset needed to mint paired outcome tokens. */
|
|
34
|
+
export const EXCHANGE_MINT_ABI = [{
|
|
35
|
+
inputs: [
|
|
36
|
+
{ internalType: 'uint256', name: 'marketId', type: 'uint256' },
|
|
37
|
+
{ internalType: 'uint256', name: 'amount', type: 'uint256' }
|
|
38
|
+
],
|
|
39
|
+
name: 'mint',
|
|
40
|
+
outputs: [],
|
|
41
|
+
stateMutability: 'nonpayable',
|
|
42
|
+
type: 'function'
|
|
43
|
+
}];
|
|
44
|
+
/** Exchange ABI subset needed to merge paired tokens back into USDC. */
|
|
45
|
+
export const EXCHANGE_MERGE_ABI = [{
|
|
46
|
+
inputs: [
|
|
47
|
+
{ internalType: 'uint256', name: 'marketId', type: 'uint256' },
|
|
48
|
+
{ internalType: 'address', name: 'holder', type: 'address' },
|
|
49
|
+
{ internalType: 'uint256', name: 'pairs', type: 'uint256' }
|
|
50
|
+
],
|
|
51
|
+
name: 'mergeFor',
|
|
52
|
+
outputs: [],
|
|
53
|
+
stateMutability: 'nonpayable',
|
|
54
|
+
type: 'function'
|
|
55
|
+
}];
|
|
56
|
+
/** Exchange ABI subset needed to claim winnings on resolved markets. */
|
|
57
|
+
export const EXCHANGE_CLAIM_ABI = [{
|
|
58
|
+
inputs: [{ internalType: 'uint256', name: 'marketId', type: 'uint256' }],
|
|
59
|
+
name: 'claimWinnings',
|
|
60
|
+
outputs: [],
|
|
61
|
+
stateMutability: 'nonpayable',
|
|
62
|
+
type: 'function'
|
|
63
|
+
}];
|
|
64
|
+
/** Exchange ABI subset needed to resolve a market with Pyth updates. */
|
|
65
|
+
export const EXCHANGE_RESOLVE_ABI = [{
|
|
66
|
+
inputs: [
|
|
67
|
+
{ internalType: 'uint256', name: 'marketId', type: 'uint256' },
|
|
68
|
+
{ internalType: 'address', name: 'pyth', type: 'address' },
|
|
69
|
+
{ internalType: 'bytes[]', name: 'updateData', type: 'bytes[]' }
|
|
70
|
+
],
|
|
71
|
+
name: 'resolveMarketWithPyth',
|
|
72
|
+
outputs: [],
|
|
73
|
+
stateMutability: 'payable',
|
|
74
|
+
type: 'function'
|
|
75
|
+
}];
|
|
76
|
+
/** Pyth ABI subset needed to quote fee for a price update payload. */
|
|
77
|
+
export const PYTH_ABI = [{
|
|
78
|
+
inputs: [{ internalType: 'bytes[]', name: 'updateData', type: 'bytes[]' }],
|
|
79
|
+
name: 'getUpdateFee',
|
|
80
|
+
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
|
|
81
|
+
stateMutability: 'view',
|
|
82
|
+
type: 'function'
|
|
83
|
+
}];
|
|
84
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/internal/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Address, Hex } from 'viem';
|
|
2
|
+
import type { RequestOptions } from '../types.js';
|
|
3
|
+
/** Normalizes API host by trimming and removing trailing slash. */
|
|
4
|
+
export declare function normalizeHost(host: string): string;
|
|
5
|
+
/** Ensures a request path starts with `/`. */
|
|
6
|
+
export declare function ensureLeadingSlash(path: string): string;
|
|
7
|
+
/** Builds a URL with optional query params, skipping nullish values. */
|
|
8
|
+
export declare function buildUrl(baseHost: string, path: string, query?: RequestOptions['query']): URL;
|
|
9
|
+
/** Parses and validates a strictly positive decimal number. */
|
|
10
|
+
export declare function parsePositiveNumber(value: number | string, field: string): number;
|
|
11
|
+
/** Returns normalized decimal string after positive-number validation. */
|
|
12
|
+
export declare function toPositiveDecimalString(value: number | string, field: string): string;
|
|
13
|
+
/** Scales decimal to fixed integer precision used by the matching engine. */
|
|
14
|
+
export declare function scaleToInt(value: number | string, field: string): number;
|
|
15
|
+
/** Converts fixed integer precision back to compact decimal string. */
|
|
16
|
+
export declare function scaledToDecimalString(scaled: number): string;
|
|
17
|
+
/** Ensures signature has hex prefix and is non-empty. */
|
|
18
|
+
export declare function normalizeHexSignature(value: string): string;
|
|
19
|
+
/** Validates and returns a checksummed-like 20-byte hex address string. */
|
|
20
|
+
export declare function normalizeAddress(value: unknown, fieldName: string): Address;
|
|
21
|
+
/** Normalizes optional Pyth feed id to 32-byte hex format. */
|
|
22
|
+
export declare function normalizePythFeedId(value: unknown): Hex | null;
|
|
23
|
+
/** Parses mixed timestamp formats into unix seconds. */
|
|
24
|
+
export declare function parseExpiryTimestamp(value: unknown): number | null;
|
|
25
|
+
/** Converts raw bytes into hex-prefixed string. */
|
|
26
|
+
export declare function bytesToHex(bytes: Uint8Array): Hex;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { SCALE } from './constants.js';
|
|
2
|
+
/** Normalizes API host by trimming and removing trailing slash. */
|
|
3
|
+
export function normalizeHost(host) {
|
|
4
|
+
const trimmed = host.trim();
|
|
5
|
+
if (!trimmed)
|
|
6
|
+
throw new Error('host is required');
|
|
7
|
+
return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed;
|
|
8
|
+
}
|
|
9
|
+
/** Ensures a request path starts with `/`. */
|
|
10
|
+
export function ensureLeadingSlash(path) {
|
|
11
|
+
if (!path)
|
|
12
|
+
return '/';
|
|
13
|
+
return path.startsWith('/') ? path : `/${path}`;
|
|
14
|
+
}
|
|
15
|
+
/** Builds a URL with optional query params, skipping nullish values. */
|
|
16
|
+
export function buildUrl(baseHost, path, query) {
|
|
17
|
+
const url = new URL(`${baseHost}${ensureLeadingSlash(path)}`);
|
|
18
|
+
if (query) {
|
|
19
|
+
for (const [key, value] of Object.entries(query)) {
|
|
20
|
+
if (value === undefined || value === null)
|
|
21
|
+
continue;
|
|
22
|
+
url.searchParams.set(key, String(value));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
/** Parses and validates a strictly positive decimal number. */
|
|
28
|
+
export function parsePositiveNumber(value, field) {
|
|
29
|
+
const parsed = typeof value === 'number' ? value : Number.parseFloat(value.trim());
|
|
30
|
+
if (!Number.isFinite(parsed)) {
|
|
31
|
+
throw new Error(`${field} must be a valid number`);
|
|
32
|
+
}
|
|
33
|
+
if (parsed <= 0) {
|
|
34
|
+
throw new Error(`${field} must be greater than 0`);
|
|
35
|
+
}
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
38
|
+
/** Returns normalized decimal string after positive-number validation. */
|
|
39
|
+
export function toPositiveDecimalString(value, field) {
|
|
40
|
+
parsePositiveNumber(value, field);
|
|
41
|
+
return typeof value === 'number' ? value.toString() : value.trim();
|
|
42
|
+
}
|
|
43
|
+
/** Scales decimal to fixed integer precision used by the matching engine. */
|
|
44
|
+
export function scaleToInt(value, field) {
|
|
45
|
+
const parsed = parsePositiveNumber(value, field);
|
|
46
|
+
const scaled = Math.floor(parsed * SCALE);
|
|
47
|
+
if (!Number.isFinite(scaled) || scaled <= 0) {
|
|
48
|
+
throw new Error(`${field} is too small after scaling`);
|
|
49
|
+
}
|
|
50
|
+
return scaled;
|
|
51
|
+
}
|
|
52
|
+
/** Converts fixed integer precision back to compact decimal string. */
|
|
53
|
+
export function scaledToDecimalString(scaled) {
|
|
54
|
+
const whole = Math.floor(scaled / SCALE);
|
|
55
|
+
const frac = scaled % SCALE;
|
|
56
|
+
if (frac === 0)
|
|
57
|
+
return String(whole);
|
|
58
|
+
return `${whole}.${frac.toString().padStart(6, '0').replace(/0+$/, '')}`;
|
|
59
|
+
}
|
|
60
|
+
/** Ensures signature has hex prefix and is non-empty. */
|
|
61
|
+
export function normalizeHexSignature(value) {
|
|
62
|
+
const trimmed = value.trim();
|
|
63
|
+
if (!trimmed)
|
|
64
|
+
throw new Error('Signature is empty');
|
|
65
|
+
return trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`;
|
|
66
|
+
}
|
|
67
|
+
/** Validates and returns a checksummed-like 20-byte hex address string. */
|
|
68
|
+
export function normalizeAddress(value, fieldName) {
|
|
69
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
70
|
+
throw new Error(`${fieldName} is required`);
|
|
71
|
+
}
|
|
72
|
+
const trimmed = value.trim();
|
|
73
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(trimmed)) {
|
|
74
|
+
throw new Error(`${fieldName} must be a valid 20-byte hex address`);
|
|
75
|
+
}
|
|
76
|
+
return trimmed;
|
|
77
|
+
}
|
|
78
|
+
/** Normalizes optional Pyth feed id to 32-byte hex format. */
|
|
79
|
+
export function normalizePythFeedId(value) {
|
|
80
|
+
if (typeof value !== 'string')
|
|
81
|
+
return null;
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
if (!trimmed)
|
|
84
|
+
return null;
|
|
85
|
+
const withPrefix = trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`;
|
|
86
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(withPrefix)) {
|
|
87
|
+
throw new Error('market pyth_feed_id must be 32-byte hex');
|
|
88
|
+
}
|
|
89
|
+
return withPrefix;
|
|
90
|
+
}
|
|
91
|
+
/** Parses mixed timestamp formats into unix seconds. */
|
|
92
|
+
export function parseExpiryTimestamp(value) {
|
|
93
|
+
if (value === null || value === undefined)
|
|
94
|
+
return null;
|
|
95
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
96
|
+
return value > 1_000_000_000_000 ? Math.floor(value / 1000) : Math.floor(value);
|
|
97
|
+
}
|
|
98
|
+
if (typeof value === 'string') {
|
|
99
|
+
const numeric = Number(value);
|
|
100
|
+
if (Number.isFinite(numeric)) {
|
|
101
|
+
return numeric > 1_000_000_000_000 ? Math.floor(numeric / 1000) : Math.floor(numeric);
|
|
102
|
+
}
|
|
103
|
+
const dateMs = Date.parse(value);
|
|
104
|
+
if (Number.isFinite(dateMs)) {
|
|
105
|
+
return Math.floor(dateMs / 1000);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/** Converts raw bytes into hex-prefixed string. */
|
|
111
|
+
export function bytesToHex(bytes) {
|
|
112
|
+
const body = Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
113
|
+
return `0x${body}`;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LifecycleClient } from './client/lifecycleClient.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export { SpeculiteApiError } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Public SDK entry point.
|
|
6
|
+
*
|
|
7
|
+
* `SpeculiteClobClient` composes:
|
|
8
|
+
* - public market data methods
|
|
9
|
+
* - developer-key trading methods
|
|
10
|
+
* - wallet-native lifecycle transaction helpers
|
|
11
|
+
*
|
|
12
|
+
* The class intentionally has no extra logic; behavior is implemented
|
|
13
|
+
* in the layered client modules for easier maintenance.
|
|
14
|
+
*/
|
|
15
|
+
export declare class SpeculiteClobClient extends LifecycleClient {
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LifecycleClient } from './client/lifecycleClient.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export { SpeculiteApiError } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Public SDK entry point.
|
|
6
|
+
*
|
|
7
|
+
* `SpeculiteClobClient` composes:
|
|
8
|
+
* - public market data methods
|
|
9
|
+
* - developer-key trading methods
|
|
10
|
+
* - wallet-native lifecycle transaction helpers
|
|
11
|
+
*
|
|
12
|
+
* The class intentionally has no extra logic; behavior is implemented
|
|
13
|
+
* in the layered client modules for easier maintenance.
|
|
14
|
+
*/
|
|
15
|
+
export class SpeculiteClobClient extends LifecycleClient {
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=speculiteClobClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speculiteClobClient.js","sourceRoot":"","sources":["../src/speculiteClobClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;CAAG"}
|