@madeinusmate/grvt-cli 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/README.md +1154 -0
- package/dist/chunk-I7C5KKUG.js +46 -0
- package/dist/chunk-I7C5KKUG.js.map +1 -0
- package/dist/cli.js +1880 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +771 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +462 -0
- package/dist/index.d.ts +462 -0
- package/dist/index.js +700 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-LBUHKB7A.js +14 -0
- package/dist/schema-LBUHKB7A.js.map +1 -0
- package/package.json +59 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,771 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
ENDPOINTS: () => ENDPOINTS,
|
|
34
|
+
buildDeriskTypedData: () => buildDeriskTypedData,
|
|
35
|
+
buildTransferTypedData: () => buildTransferTypedData,
|
|
36
|
+
buildWithdrawalTypedData: () => buildWithdrawalTypedData,
|
|
37
|
+
cancelAllOrders: () => cancelAllOrders,
|
|
38
|
+
cancelOrder: () => cancelOrder,
|
|
39
|
+
configSchema: () => configSchema,
|
|
40
|
+
createDeposit: () => createDeposit,
|
|
41
|
+
createHttpClient: () => createHttpClient,
|
|
42
|
+
createOrder: () => createOrder,
|
|
43
|
+
createTransfer: () => createTransfer,
|
|
44
|
+
createWithdrawal: () => createWithdrawal,
|
|
45
|
+
getAccountHistory: () => getAccountHistory,
|
|
46
|
+
getAggregatedAccountSummary: () => getAggregatedAccountSummary,
|
|
47
|
+
getCurrencies: () => getCurrencies,
|
|
48
|
+
getCurrencyDecimals: () => getCurrencyDecimals,
|
|
49
|
+
getCurrencyId: () => getCurrencyId,
|
|
50
|
+
getDepositHistory: () => getDepositHistory,
|
|
51
|
+
getFillHistory: () => getFillHistory,
|
|
52
|
+
getFundingAccountSummary: () => getFundingAccountSummary,
|
|
53
|
+
getFundingPayments: () => getFundingPayments,
|
|
54
|
+
getOpenOrders: () => getOpenOrders,
|
|
55
|
+
getOrder: () => getOrder,
|
|
56
|
+
getOrderHistory: () => getOrderHistory,
|
|
57
|
+
getPositions: () => getPositions,
|
|
58
|
+
getSubAccountHistory: () => getSubAccountHistory,
|
|
59
|
+
getSubAccountSummary: () => getSubAccountSummary,
|
|
60
|
+
getTransferHistory: () => getTransferHistory,
|
|
61
|
+
getWithdrawalHistory: () => getWithdrawalHistory,
|
|
62
|
+
loadConfig: () => loadConfig,
|
|
63
|
+
login: () => login,
|
|
64
|
+
logout: () => logout,
|
|
65
|
+
paginateCursor: () => paginateCursor,
|
|
66
|
+
saveConfig: () => saveConfig,
|
|
67
|
+
verifySession: () => verifySession
|
|
68
|
+
});
|
|
69
|
+
module.exports = __toCommonJS(src_exports);
|
|
70
|
+
|
|
71
|
+
// src/core/config/store.ts
|
|
72
|
+
var import_node_fs = require("fs");
|
|
73
|
+
var import_node_path = require("path");
|
|
74
|
+
var import_node_os = require("os");
|
|
75
|
+
var import_smol_toml = require("smol-toml");
|
|
76
|
+
|
|
77
|
+
// src/core/config/schema.ts
|
|
78
|
+
var import_zod = require("zod");
|
|
79
|
+
var environmentSchema = import_zod.z.enum(["dev", "staging", "testnet", "prod"]);
|
|
80
|
+
var httpConfigSchema = import_zod.z.object({
|
|
81
|
+
timeoutMs: import_zod.z.number().int().positive().default(1e4),
|
|
82
|
+
retries: import_zod.z.number().int().min(0).default(3),
|
|
83
|
+
backoffMs: import_zod.z.number().int().positive().default(200),
|
|
84
|
+
maxBackoffMs: import_zod.z.number().int().positive().default(1e4)
|
|
85
|
+
});
|
|
86
|
+
var outputDefaultsSchema = import_zod.z.object({
|
|
87
|
+
output: import_zod.z.enum(["json", "ndjson", "table", "raw"]).default("table"),
|
|
88
|
+
pretty: import_zod.z.boolean().default(false),
|
|
89
|
+
silent: import_zod.z.boolean().default(false)
|
|
90
|
+
});
|
|
91
|
+
var configSchema = import_zod.z.object({
|
|
92
|
+
env: environmentSchema.default("prod"),
|
|
93
|
+
apiKey: import_zod.z.string().optional(),
|
|
94
|
+
privateKey: import_zod.z.string().optional(),
|
|
95
|
+
subAccountId: import_zod.z.string().optional(),
|
|
96
|
+
accountId: import_zod.z.string().optional(),
|
|
97
|
+
cookie: import_zod.z.string().optional(),
|
|
98
|
+
outputDefaults: outputDefaultsSchema.default({}),
|
|
99
|
+
http: httpConfigSchema.default({})
|
|
100
|
+
});
|
|
101
|
+
var DEFAULT_CONFIG = configSchema.parse({});
|
|
102
|
+
|
|
103
|
+
// src/core/config/store.ts
|
|
104
|
+
var getConfigDir = () => {
|
|
105
|
+
const xdgConfig = process.env["XDG_CONFIG_HOME"];
|
|
106
|
+
const base = xdgConfig || (0, import_node_path.join)((0, import_node_os.homedir)(), ".config");
|
|
107
|
+
return (0, import_node_path.join)(base, "grvt");
|
|
108
|
+
};
|
|
109
|
+
var getConfigPath = () => (0, import_node_path.join)(getConfigDir(), "config.toml");
|
|
110
|
+
var loadConfig = () => {
|
|
111
|
+
const path = getConfigPath();
|
|
112
|
+
if (!(0, import_node_fs.existsSync)(path)) {
|
|
113
|
+
return DEFAULT_CONFIG;
|
|
114
|
+
}
|
|
115
|
+
const raw = (0, import_node_fs.readFileSync)(path, "utf-8");
|
|
116
|
+
const parsed = (0, import_smol_toml.parse)(raw);
|
|
117
|
+
return configSchema.parse(parsed);
|
|
118
|
+
};
|
|
119
|
+
var saveConfig = (config) => {
|
|
120
|
+
const dir = getConfigDir();
|
|
121
|
+
if (!(0, import_node_fs.existsSync)(dir)) {
|
|
122
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
const path = getConfigPath();
|
|
125
|
+
const toml = (0, import_smol_toml.stringify)(config);
|
|
126
|
+
(0, import_node_fs.writeFileSync)(path, toml, { mode: 384 });
|
|
127
|
+
try {
|
|
128
|
+
(0, import_node_fs.chmodSync)(path, 384);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/core/client/endpoints.ts
|
|
134
|
+
var BASE_URLS = {
|
|
135
|
+
dev: {
|
|
136
|
+
edge: "https://edge.dev.gravitymarkets.io",
|
|
137
|
+
marketData: "https://market-data.dev.gravitymarkets.io",
|
|
138
|
+
trading: "https://trades.dev.gravitymarkets.io"
|
|
139
|
+
},
|
|
140
|
+
staging: {
|
|
141
|
+
edge: "https://edge.staging.gravitymarkets.io",
|
|
142
|
+
marketData: "https://market-data.staging.gravitymarkets.io",
|
|
143
|
+
trading: "https://trades.staging.gravitymarkets.io"
|
|
144
|
+
},
|
|
145
|
+
testnet: {
|
|
146
|
+
edge: "https://edge.testnet.grvt.io",
|
|
147
|
+
marketData: "https://market-data.testnet.grvt.io",
|
|
148
|
+
trading: "https://trades.testnet.grvt.io"
|
|
149
|
+
},
|
|
150
|
+
prod: {
|
|
151
|
+
edge: "https://edge.grvt.io",
|
|
152
|
+
marketData: "https://market-data.grvt.io",
|
|
153
|
+
trading: "https://trades.grvt.io"
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var CHAIN_IDS = {
|
|
157
|
+
dev: { l1: 11155111, l2: 327 },
|
|
158
|
+
staging: { l1: 11155111, l2: 327 },
|
|
159
|
+
testnet: { l1: 11155111, l2: 326 },
|
|
160
|
+
prod: { l1: 1, l2: 325 }
|
|
161
|
+
};
|
|
162
|
+
var ENDPOINTS = {
|
|
163
|
+
auth: {
|
|
164
|
+
login: "/auth/api_key/login"
|
|
165
|
+
},
|
|
166
|
+
marketData: {
|
|
167
|
+
instrument: "/full/v1/instrument",
|
|
168
|
+
allInstruments: "/full/v1/all_instruments",
|
|
169
|
+
instruments: "/full/v1/instruments",
|
|
170
|
+
currency: "/full/v1/currency",
|
|
171
|
+
marginRules: "/full/v1/margin_rules",
|
|
172
|
+
mini: "/full/v1/mini",
|
|
173
|
+
ticker: "/full/v1/ticker",
|
|
174
|
+
tradeHistory: "/full/v1/trade_history",
|
|
175
|
+
kline: "/full/v1/kline",
|
|
176
|
+
funding: "/full/v1/funding",
|
|
177
|
+
book: "/full/v1/book"
|
|
178
|
+
},
|
|
179
|
+
trading: {
|
|
180
|
+
createOrder: "/full/v1/create_order",
|
|
181
|
+
cancelOrder: "/full/v1/cancel_order",
|
|
182
|
+
cancelAllOrders: "/full/v1/cancel_all_orders",
|
|
183
|
+
getOrder: "/full/v1/order",
|
|
184
|
+
openOrders: "/full/v1/open_orders",
|
|
185
|
+
orderHistory: "/full/v1/order_history",
|
|
186
|
+
cancelOnDisconnect: "/full/v1/cancel_on_disconnect",
|
|
187
|
+
fillHistory: "/full/v1/fill_history",
|
|
188
|
+
positions: "/full/v1/positions",
|
|
189
|
+
fundingPaymentHistory: "/full/v1/funding_payment_history",
|
|
190
|
+
getAllInitialLeverage: "/full/v1/get_all_initial_leverage",
|
|
191
|
+
setInitialLeverage: "/full/v1/set_initial_leverage",
|
|
192
|
+
setDeriskMmRatio: "/full/v1/set_derisk_mm_ratio"
|
|
193
|
+
},
|
|
194
|
+
account: {
|
|
195
|
+
accountSummary: "/full/v1/account_summary",
|
|
196
|
+
accountHistory: "/full/v1/account_history",
|
|
197
|
+
fundingAccountSummary: "/full/v1/funding_account_summary",
|
|
198
|
+
aggregatedAccountSummary: "/full/v1/aggregated_account_summary"
|
|
199
|
+
},
|
|
200
|
+
funds: {
|
|
201
|
+
depositHistory: "/full/v1/deposit_history",
|
|
202
|
+
transfer: "/full/v1/transfer",
|
|
203
|
+
transferHistory: "/full/v1/transfer_history",
|
|
204
|
+
withdrawal: "/full/v1/withdrawal",
|
|
205
|
+
withdrawalHistory: "/full/v1/withdrawal_history"
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
var getBaseUrls = (env) => BASE_URLS[env];
|
|
209
|
+
var getChainIds = (env) => CHAIN_IDS[env];
|
|
210
|
+
|
|
211
|
+
// src/core/client/http.ts
|
|
212
|
+
var createHttpClient = (options) => {
|
|
213
|
+
const {
|
|
214
|
+
env,
|
|
215
|
+
cookie,
|
|
216
|
+
accountId,
|
|
217
|
+
timeoutMs = 1e4,
|
|
218
|
+
retries = 3,
|
|
219
|
+
backoffMs = 200,
|
|
220
|
+
maxBackoffMs = 1e4
|
|
221
|
+
} = options;
|
|
222
|
+
const urls = getBaseUrls(env);
|
|
223
|
+
const post = async (baseType, path, body) => {
|
|
224
|
+
const url = `${urls[baseType]}${path}`;
|
|
225
|
+
const headers = {
|
|
226
|
+
"Content-Type": "application/json"
|
|
227
|
+
};
|
|
228
|
+
if (cookie) {
|
|
229
|
+
headers["Cookie"] = cookie;
|
|
230
|
+
}
|
|
231
|
+
if (accountId) {
|
|
232
|
+
headers["X-Grvt-Account-Id"] = accountId;
|
|
233
|
+
}
|
|
234
|
+
let lastError;
|
|
235
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
236
|
+
try {
|
|
237
|
+
const controller = new AbortController();
|
|
238
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
239
|
+
const response = await fetch(url, {
|
|
240
|
+
method: "POST",
|
|
241
|
+
headers,
|
|
242
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
243
|
+
signal: controller.signal
|
|
244
|
+
});
|
|
245
|
+
clearTimeout(timer);
|
|
246
|
+
if (response.status === 429 || response.status >= 500) {
|
|
247
|
+
const err = new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
248
|
+
err.statusCode = response.status;
|
|
249
|
+
throw err;
|
|
250
|
+
}
|
|
251
|
+
if (!response.ok) {
|
|
252
|
+
const text = await response.text().catch(() => "");
|
|
253
|
+
const err = new Error(`HTTP ${response.status}: ${text || response.statusText}`);
|
|
254
|
+
err.statusCode = response.status;
|
|
255
|
+
throw err;
|
|
256
|
+
}
|
|
257
|
+
return await response.json();
|
|
258
|
+
} catch (error) {
|
|
259
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
260
|
+
const isRetryable = lastError.statusCode === 429 || (lastError.statusCode ?? 0) >= 500 || lastError.name === "AbortError";
|
|
261
|
+
if (!isRetryable || attempt >= retries) {
|
|
262
|
+
throw lastError;
|
|
263
|
+
}
|
|
264
|
+
const delay = Math.min(backoffMs * Math.pow(2, attempt), maxBackoffMs);
|
|
265
|
+
await sleep(delay);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
throw lastError ?? new Error("Request failed");
|
|
269
|
+
};
|
|
270
|
+
return { post };
|
|
271
|
+
};
|
|
272
|
+
var extractAuthFromResponse = async (env, apiKey) => {
|
|
273
|
+
const urls = getBaseUrls(env);
|
|
274
|
+
const url = `${urls.edge}/auth/api_key/login`;
|
|
275
|
+
const response = await fetch(url, {
|
|
276
|
+
method: "POST",
|
|
277
|
+
headers: {
|
|
278
|
+
"Content-Type": "application/json",
|
|
279
|
+
Cookie: "rm=true;"
|
|
280
|
+
},
|
|
281
|
+
body: JSON.stringify({ api_key: apiKey }),
|
|
282
|
+
redirect: "manual"
|
|
283
|
+
});
|
|
284
|
+
const bodyText = await response.text().catch(() => "");
|
|
285
|
+
if (!response.ok && response.status !== 302) {
|
|
286
|
+
throw new Error(`Auth failed (HTTP ${response.status}): ${bodyText || response.statusText}`);
|
|
287
|
+
}
|
|
288
|
+
if (bodyText) {
|
|
289
|
+
try {
|
|
290
|
+
const bodyJson = JSON.parse(bodyText);
|
|
291
|
+
if (bodyJson["status"] === "failure" || bodyJson["error"]) {
|
|
292
|
+
throw new Error(`Auth failed: ${bodyJson["error"] ?? bodyJson["message"] ?? "unknown error"}`);
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
if (e instanceof Error && e.message.startsWith("Auth failed")) throw e;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
const setCookies = response.headers.getSetCookie?.() ?? [];
|
|
299
|
+
let gravityCookie = setCookies.map((c2) => c2.split(";")[0]).find((c2) => c2?.startsWith("gravity="));
|
|
300
|
+
if (!gravityCookie) {
|
|
301
|
+
const rawSetCookie = response.headers.get("set-cookie");
|
|
302
|
+
if (rawSetCookie) {
|
|
303
|
+
const match = rawSetCookie.match(/gravity=[^;]+/);
|
|
304
|
+
if (match) {
|
|
305
|
+
gravityCookie = match[0];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (!gravityCookie) {
|
|
310
|
+
throw new Error("Auth response did not contain gravity session cookie. Verify your API key is valid.");
|
|
311
|
+
}
|
|
312
|
+
const accountId = response.headers.get("x-grvt-account-id");
|
|
313
|
+
if (!accountId) {
|
|
314
|
+
throw new Error("Auth response did not contain X-Grvt-Account-Id header");
|
|
315
|
+
}
|
|
316
|
+
return { cookie: gravityCookie, accountId: accountId.trim() };
|
|
317
|
+
};
|
|
318
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
319
|
+
|
|
320
|
+
// src/core/auth/login.ts
|
|
321
|
+
var performLogin = async (options) => {
|
|
322
|
+
const config = loadConfig();
|
|
323
|
+
const env = options.env ?? config.env;
|
|
324
|
+
const { cookie, accountId } = await extractAuthFromResponse(env, options.apiKey);
|
|
325
|
+
saveConfig({
|
|
326
|
+
...config,
|
|
327
|
+
env,
|
|
328
|
+
apiKey: options.apiKey,
|
|
329
|
+
cookie,
|
|
330
|
+
accountId,
|
|
331
|
+
...options.privateKey ? { privateKey: options.privateKey } : {}
|
|
332
|
+
});
|
|
333
|
+
return { accountId, env };
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/core/auth/session.ts
|
|
337
|
+
var login = async (options) => performLogin(options);
|
|
338
|
+
var logout = () => {
|
|
339
|
+
const config = loadConfig();
|
|
340
|
+
saveConfig({
|
|
341
|
+
...config,
|
|
342
|
+
apiKey: void 0,
|
|
343
|
+
privateKey: void 0,
|
|
344
|
+
cookie: void 0,
|
|
345
|
+
accountId: void 0
|
|
346
|
+
});
|
|
347
|
+
};
|
|
348
|
+
var verifySession = async () => {
|
|
349
|
+
const config = loadConfig();
|
|
350
|
+
if (!config.cookie || !config.accountId) {
|
|
351
|
+
return { valid: false, env: config.env };
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
const client = createHttpClient({
|
|
355
|
+
env: config.env,
|
|
356
|
+
cookie: config.cookie,
|
|
357
|
+
accountId: config.accountId,
|
|
358
|
+
timeoutMs: config.http.timeoutMs
|
|
359
|
+
});
|
|
360
|
+
await client.post("trading", ENDPOINTS.account.fundingAccountSummary, {});
|
|
361
|
+
return { valid: true, env: config.env, accountId: config.accountId };
|
|
362
|
+
} catch {
|
|
363
|
+
return { valid: false, env: config.env, accountId: config.accountId };
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// src/commands/trade/orders.ts
|
|
368
|
+
var import_node_crypto = require("crypto");
|
|
369
|
+
|
|
370
|
+
// src/core/output/table.ts
|
|
371
|
+
var import_cli_table3 = __toESM(require("cli-table3"), 1);
|
|
372
|
+
|
|
373
|
+
// src/core/output/colors.ts
|
|
374
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
375
|
+
var _disabled = false;
|
|
376
|
+
var c = () => {
|
|
377
|
+
if (_disabled) {
|
|
378
|
+
return {
|
|
379
|
+
red: (s) => s,
|
|
380
|
+
green: (s) => s,
|
|
381
|
+
yellow: (s) => s,
|
|
382
|
+
cyan: { bold: (s) => s }
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
return import_chalk.default;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/core/output/table.ts
|
|
389
|
+
var renderTable = (data) => {
|
|
390
|
+
if (data.length === 0) return "No data";
|
|
391
|
+
const keys = Object.keys(data[0]);
|
|
392
|
+
const table = new import_cli_table3.default({
|
|
393
|
+
head: keys.map((k) => c().cyan.bold(k)),
|
|
394
|
+
style: { head: [], border: [] }
|
|
395
|
+
});
|
|
396
|
+
for (const row of data) {
|
|
397
|
+
table.push(keys.map((k) => formatCell(row[k])));
|
|
398
|
+
}
|
|
399
|
+
return table.toString();
|
|
400
|
+
};
|
|
401
|
+
var renderVerticalTable = (data) => {
|
|
402
|
+
const table = new import_cli_table3.default({
|
|
403
|
+
style: { head: [], border: [] }
|
|
404
|
+
});
|
|
405
|
+
for (const [key, value] of Object.entries(data)) {
|
|
406
|
+
table.push({ [c().cyan.bold(key)]: formatCell(value) });
|
|
407
|
+
}
|
|
408
|
+
return table.toString();
|
|
409
|
+
};
|
|
410
|
+
var formatCell = (value) => {
|
|
411
|
+
if (value === null || value === void 0) return "";
|
|
412
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
413
|
+
return String(value);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// src/core/output/format.ts
|
|
417
|
+
var formatOutput = (data, options) => {
|
|
418
|
+
switch (options.output) {
|
|
419
|
+
case "json":
|
|
420
|
+
return options.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
421
|
+
case "ndjson":
|
|
422
|
+
if (Array.isArray(data)) {
|
|
423
|
+
return data.map((item) => JSON.stringify(item)).join("\n");
|
|
424
|
+
}
|
|
425
|
+
return JSON.stringify(data);
|
|
426
|
+
case "raw":
|
|
427
|
+
if (typeof data === "string") return data;
|
|
428
|
+
return JSON.stringify(data);
|
|
429
|
+
case "table":
|
|
430
|
+
if (Array.isArray(data)) {
|
|
431
|
+
if (data.length === 0) return "No data";
|
|
432
|
+
if (typeof data[0] === "object" && data[0] !== null) {
|
|
433
|
+
return renderTable(data);
|
|
434
|
+
}
|
|
435
|
+
return data.map(String).join("\n");
|
|
436
|
+
}
|
|
437
|
+
if (typeof data === "object" && data !== null) {
|
|
438
|
+
return renderVerticalTable(data);
|
|
439
|
+
}
|
|
440
|
+
return String(data);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
// src/core/pagination/cursor.ts
|
|
445
|
+
var paginateCursor = async (options) => {
|
|
446
|
+
const { fetchPage, all, outputOptions } = options;
|
|
447
|
+
let { cursor } = options;
|
|
448
|
+
if (!all) {
|
|
449
|
+
const page = await fetchPage(cursor);
|
|
450
|
+
return page.result;
|
|
451
|
+
}
|
|
452
|
+
const isStreaming = outputOptions.output === "ndjson";
|
|
453
|
+
const collected = [];
|
|
454
|
+
while (true) {
|
|
455
|
+
const page = await fetchPage(cursor);
|
|
456
|
+
if (isStreaming) {
|
|
457
|
+
for (const item of page.result) {
|
|
458
|
+
process.stdout.write(formatOutput(item, outputOptions) + "\n");
|
|
459
|
+
}
|
|
460
|
+
} else {
|
|
461
|
+
collected.push(...page.result);
|
|
462
|
+
}
|
|
463
|
+
if (!page.next || page.result.length === 0) {
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
cursor = page.next;
|
|
467
|
+
}
|
|
468
|
+
return collected;
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/core/safety/confirm.ts
|
|
472
|
+
var import_node_readline = require("readline");
|
|
473
|
+
|
|
474
|
+
// src/core/safety/validate.ts
|
|
475
|
+
var import_node_fs2 = require("fs");
|
|
476
|
+
|
|
477
|
+
// src/core/instruments/cache.ts
|
|
478
|
+
var import_node_fs3 = require("fs");
|
|
479
|
+
var import_node_path2 = require("path");
|
|
480
|
+
var import_node_os2 = require("os");
|
|
481
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
482
|
+
|
|
483
|
+
// src/core/signing/eip712.ts
|
|
484
|
+
var PRICE_MULTIPLIER = 1000000000n;
|
|
485
|
+
var decimalToBigInt = (value, multiplier) => {
|
|
486
|
+
const parts = value.split(".");
|
|
487
|
+
const whole = parts[0] ?? "0";
|
|
488
|
+
const frac = parts[1] ?? "";
|
|
489
|
+
const multiplierDigits = multiplier.toString().length - 1;
|
|
490
|
+
const paddedFrac = frac.padEnd(multiplierDigits, "0").slice(0, multiplierDigits);
|
|
491
|
+
return BigInt(whole) * multiplier + BigInt(paddedFrac);
|
|
492
|
+
};
|
|
493
|
+
var buildTransferTypedData = (payload, env) => {
|
|
494
|
+
const chainIds = getChainIds(env);
|
|
495
|
+
const domain = {
|
|
496
|
+
name: "GRVT Exchange",
|
|
497
|
+
version: "0",
|
|
498
|
+
chainId: BigInt(chainIds.l2)
|
|
499
|
+
};
|
|
500
|
+
const types = {
|
|
501
|
+
Transfer: [
|
|
502
|
+
{ name: "fromAccount", type: "address" },
|
|
503
|
+
{ name: "fromSubAccount", type: "uint64" },
|
|
504
|
+
{ name: "toAccount", type: "address" },
|
|
505
|
+
{ name: "toSubAccount", type: "uint64" },
|
|
506
|
+
{ name: "tokenCurrency", type: "uint8" },
|
|
507
|
+
{ name: "numTokens", type: "uint64" },
|
|
508
|
+
{ name: "nonce", type: "uint32" },
|
|
509
|
+
{ name: "expiration", type: "int64" }
|
|
510
|
+
]
|
|
511
|
+
};
|
|
512
|
+
const tokenMultiplier = BigInt(10) ** BigInt(payload.balanceDecimals);
|
|
513
|
+
const message = {
|
|
514
|
+
fromAccount: payload.fromAccount,
|
|
515
|
+
fromSubAccount: BigInt(payload.fromSubAccount),
|
|
516
|
+
toAccount: payload.toAccount,
|
|
517
|
+
toSubAccount: BigInt(payload.toSubAccount),
|
|
518
|
+
tokenCurrency: payload.tokenCurrency,
|
|
519
|
+
numTokens: decimalToBigInt(payload.numTokens, tokenMultiplier),
|
|
520
|
+
nonce: payload.nonce,
|
|
521
|
+
expiration: BigInt(payload.expiration)
|
|
522
|
+
};
|
|
523
|
+
return { domain, types, primaryType: "Transfer", message };
|
|
524
|
+
};
|
|
525
|
+
var buildWithdrawalTypedData = (payload, env) => {
|
|
526
|
+
const chainIds = getChainIds(env);
|
|
527
|
+
const domain = {
|
|
528
|
+
name: "GRVT Exchange",
|
|
529
|
+
version: "0",
|
|
530
|
+
chainId: BigInt(chainIds.l2)
|
|
531
|
+
};
|
|
532
|
+
const types = {
|
|
533
|
+
Withdrawal: [
|
|
534
|
+
{ name: "fromAccount", type: "address" },
|
|
535
|
+
{ name: "toEthAddress", type: "address" },
|
|
536
|
+
{ name: "tokenCurrency", type: "uint8" },
|
|
537
|
+
{ name: "numTokens", type: "uint64" },
|
|
538
|
+
{ name: "nonce", type: "uint32" },
|
|
539
|
+
{ name: "expiration", type: "int64" }
|
|
540
|
+
]
|
|
541
|
+
};
|
|
542
|
+
const tokenMultiplier = BigInt(10) ** BigInt(payload.balanceDecimals);
|
|
543
|
+
const message = {
|
|
544
|
+
fromAccount: payload.fromAccount,
|
|
545
|
+
toEthAddress: payload.toEthAddress,
|
|
546
|
+
tokenCurrency: payload.tokenCurrency,
|
|
547
|
+
numTokens: decimalToBigInt(payload.numTokens, tokenMultiplier),
|
|
548
|
+
nonce: payload.nonce,
|
|
549
|
+
expiration: BigInt(payload.expiration)
|
|
550
|
+
};
|
|
551
|
+
return { domain, types, primaryType: "Withdrawal", message };
|
|
552
|
+
};
|
|
553
|
+
var buildDeriskTypedData = (payload, env) => {
|
|
554
|
+
const chainIds = getChainIds(env);
|
|
555
|
+
const domain = {
|
|
556
|
+
name: "GRVT Exchange",
|
|
557
|
+
version: "0",
|
|
558
|
+
chainId: BigInt(chainIds.l2)
|
|
559
|
+
};
|
|
560
|
+
const types = {
|
|
561
|
+
SetDeriskMMRatio: [
|
|
562
|
+
{ name: "subAccountID", type: "uint64" },
|
|
563
|
+
{ name: "ratio", type: "uint64" },
|
|
564
|
+
{ name: "nonce", type: "uint32" },
|
|
565
|
+
{ name: "expiration", type: "int64" }
|
|
566
|
+
]
|
|
567
|
+
};
|
|
568
|
+
const message = {
|
|
569
|
+
subAccountID: BigInt(payload.subAccountId),
|
|
570
|
+
ratio: decimalToBigInt(payload.ratio, PRICE_MULTIPLIER),
|
|
571
|
+
nonce: payload.nonce,
|
|
572
|
+
expiration: BigInt(payload.expiration)
|
|
573
|
+
};
|
|
574
|
+
return { domain, types, primaryType: "SetDeriskMMRatio", message };
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
// src/core/signing/signer.ts
|
|
578
|
+
var import_accounts = require("viem/accounts");
|
|
579
|
+
var import_viem = require("viem");
|
|
580
|
+
|
|
581
|
+
// src/commands/trade/orders.ts
|
|
582
|
+
var createOrder = async (client, order) => {
|
|
583
|
+
const body = { order };
|
|
584
|
+
const result = await client.post("trading", ENDPOINTS.trading.createOrder, body);
|
|
585
|
+
return result.result;
|
|
586
|
+
};
|
|
587
|
+
var cancelOrder = async (client, params) => {
|
|
588
|
+
const result = await client.post("trading", ENDPOINTS.trading.cancelOrder, params);
|
|
589
|
+
return result.result;
|
|
590
|
+
};
|
|
591
|
+
var cancelAllOrders = async (client, params) => {
|
|
592
|
+
const result = await client.post("trading", ENDPOINTS.trading.cancelAllOrders, params);
|
|
593
|
+
return result.result;
|
|
594
|
+
};
|
|
595
|
+
var getOrder = async (client, params) => {
|
|
596
|
+
const result = await client.post("trading", ENDPOINTS.trading.getOrder, params);
|
|
597
|
+
return result.result;
|
|
598
|
+
};
|
|
599
|
+
var getOpenOrders = async (client, params) => {
|
|
600
|
+
const result = await client.post("trading", ENDPOINTS.trading.openOrders, params);
|
|
601
|
+
return result.result;
|
|
602
|
+
};
|
|
603
|
+
var getOrderHistory = async (client, params) => {
|
|
604
|
+
return client.post("trading", ENDPOINTS.trading.orderHistory, params);
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
// src/commands/trade/fills.ts
|
|
608
|
+
var getFillHistory = async (client, params) => {
|
|
609
|
+
return client.post("trading", ENDPOINTS.trading.fillHistory, params);
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
// src/commands/trade/positions.ts
|
|
613
|
+
var getPositions = async (client, params) => {
|
|
614
|
+
const result = await client.post("trading", ENDPOINTS.trading.positions, params);
|
|
615
|
+
return result.result;
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
// src/commands/trade/funding-payments.ts
|
|
619
|
+
var getFundingPayments = async (client, params) => {
|
|
620
|
+
return client.post("trading", ENDPOINTS.trading.fundingPaymentHistory, params);
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
// src/commands/account.ts
|
|
624
|
+
var getFundingAccountSummary = async (client) => {
|
|
625
|
+
const result = await client.post("trading", ENDPOINTS.account.fundingAccountSummary, {});
|
|
626
|
+
return result.result;
|
|
627
|
+
};
|
|
628
|
+
var getSubAccountSummary = async (client, subAccountId) => {
|
|
629
|
+
const body = { sub_account_id: subAccountId };
|
|
630
|
+
const result = await client.post("trading", ENDPOINTS.account.accountSummary, body);
|
|
631
|
+
return result.result;
|
|
632
|
+
};
|
|
633
|
+
var getSubAccountHistory = getSubAccountSummary;
|
|
634
|
+
var getAccountHistory = async (client, params) => {
|
|
635
|
+
return client.post("trading", ENDPOINTS.account.accountHistory, params);
|
|
636
|
+
};
|
|
637
|
+
var getAggregatedAccountSummary = async (client) => {
|
|
638
|
+
const result = await client.post("trading", ENDPOINTS.account.aggregatedAccountSummary, {});
|
|
639
|
+
return result.result;
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// src/commands/funds/deposits.ts
|
|
643
|
+
var createDeposit = async (_client, _params) => {
|
|
644
|
+
throw new Error("Deposit creation is not available via REST API. Use the GRVT web interface.");
|
|
645
|
+
};
|
|
646
|
+
var getDepositHistory = async (client, params) => {
|
|
647
|
+
return client.post("trading", ENDPOINTS.funds.depositHistory, params);
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
// src/core/currencies/cache.ts
|
|
651
|
+
var import_node_fs4 = require("fs");
|
|
652
|
+
var import_node_path3 = require("path");
|
|
653
|
+
var import_node_os3 = require("os");
|
|
654
|
+
var CACHE_TTL_MS2 = 60 * 60 * 1e3;
|
|
655
|
+
var getCacheDir = () => {
|
|
656
|
+
const xdgCache = process.env["XDG_CACHE_HOME"];
|
|
657
|
+
const base = xdgCache || (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".cache");
|
|
658
|
+
return (0, import_node_path3.join)(base, "grvt");
|
|
659
|
+
};
|
|
660
|
+
var getCachePath = (env) => (0, import_node_path3.join)(getCacheDir(), `currencies-${env}.json`);
|
|
661
|
+
var loadCache = (env) => {
|
|
662
|
+
const path = getCachePath(env);
|
|
663
|
+
if (!(0, import_node_fs4.existsSync)(path)) return null;
|
|
664
|
+
try {
|
|
665
|
+
const raw = (0, import_node_fs4.readFileSync)(path, "utf-8");
|
|
666
|
+
const cache = JSON.parse(raw);
|
|
667
|
+
if (cache.env !== env || Date.now() - cache.fetched_at > CACHE_TTL_MS2) {
|
|
668
|
+
return null;
|
|
669
|
+
}
|
|
670
|
+
return cache;
|
|
671
|
+
} catch {
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
var saveCache = (env, currencies) => {
|
|
676
|
+
const dir = getCacheDir();
|
|
677
|
+
if (!(0, import_node_fs4.existsSync)(dir)) {
|
|
678
|
+
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
679
|
+
}
|
|
680
|
+
const cache = { env, fetched_at: Date.now(), currencies };
|
|
681
|
+
(0, import_node_fs4.writeFileSync)(getCachePath(env), JSON.stringify(cache), "utf-8");
|
|
682
|
+
};
|
|
683
|
+
var getCurrencies = async (env, cookie, accountId) => {
|
|
684
|
+
const cached = loadCache(env);
|
|
685
|
+
if (cached) return cached.currencies;
|
|
686
|
+
const client = createHttpClient({ env, cookie, accountId });
|
|
687
|
+
const response = await client.post(
|
|
688
|
+
"marketData",
|
|
689
|
+
ENDPOINTS.marketData.currency,
|
|
690
|
+
{}
|
|
691
|
+
);
|
|
692
|
+
const currencies = {};
|
|
693
|
+
for (const cur of response.result ?? []) {
|
|
694
|
+
currencies[cur.symbol] = cur;
|
|
695
|
+
}
|
|
696
|
+
saveCache(env, currencies);
|
|
697
|
+
return currencies;
|
|
698
|
+
};
|
|
699
|
+
var getCurrencyId = async (env, symbol, cookie, accountId) => {
|
|
700
|
+
const currencies = await getCurrencies(env, cookie, accountId);
|
|
701
|
+
const cur = currencies[symbol.toUpperCase()];
|
|
702
|
+
if (!cur) {
|
|
703
|
+
throw new Error(`Currency not found: ${symbol}. Run 'grvt market currency' to see available currencies.`);
|
|
704
|
+
}
|
|
705
|
+
return cur.id;
|
|
706
|
+
};
|
|
707
|
+
var getCurrencyDecimals = async (env, symbol, cookie, accountId) => {
|
|
708
|
+
const currencies = await getCurrencies(env, cookie, accountId);
|
|
709
|
+
const cur = currencies[symbol.toUpperCase()];
|
|
710
|
+
if (!cur) {
|
|
711
|
+
throw new Error(`Currency not found: ${symbol}. Run 'grvt market currency' to see available currencies.`);
|
|
712
|
+
}
|
|
713
|
+
return cur.balance_decimals;
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
// src/commands/funds/transfers.ts
|
|
717
|
+
var createTransfer = async (client, params) => {
|
|
718
|
+
const result = await client.post("trading", ENDPOINTS.funds.transfer, params);
|
|
719
|
+
return result.result;
|
|
720
|
+
};
|
|
721
|
+
var getTransferHistory = async (client, params) => {
|
|
722
|
+
return client.post("trading", ENDPOINTS.funds.transferHistory, params);
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/commands/funds/withdrawals.ts
|
|
726
|
+
var createWithdrawal = async (client, params) => {
|
|
727
|
+
const result = await client.post("trading", ENDPOINTS.funds.withdrawal, params);
|
|
728
|
+
return result.result;
|
|
729
|
+
};
|
|
730
|
+
var getWithdrawalHistory = async (client, params) => {
|
|
731
|
+
return client.post("trading", ENDPOINTS.funds.withdrawalHistory, params);
|
|
732
|
+
};
|
|
733
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
734
|
+
0 && (module.exports = {
|
|
735
|
+
ENDPOINTS,
|
|
736
|
+
buildDeriskTypedData,
|
|
737
|
+
buildTransferTypedData,
|
|
738
|
+
buildWithdrawalTypedData,
|
|
739
|
+
cancelAllOrders,
|
|
740
|
+
cancelOrder,
|
|
741
|
+
configSchema,
|
|
742
|
+
createDeposit,
|
|
743
|
+
createHttpClient,
|
|
744
|
+
createOrder,
|
|
745
|
+
createTransfer,
|
|
746
|
+
createWithdrawal,
|
|
747
|
+
getAccountHistory,
|
|
748
|
+
getAggregatedAccountSummary,
|
|
749
|
+
getCurrencies,
|
|
750
|
+
getCurrencyDecimals,
|
|
751
|
+
getCurrencyId,
|
|
752
|
+
getDepositHistory,
|
|
753
|
+
getFillHistory,
|
|
754
|
+
getFundingAccountSummary,
|
|
755
|
+
getFundingPayments,
|
|
756
|
+
getOpenOrders,
|
|
757
|
+
getOrder,
|
|
758
|
+
getOrderHistory,
|
|
759
|
+
getPositions,
|
|
760
|
+
getSubAccountHistory,
|
|
761
|
+
getSubAccountSummary,
|
|
762
|
+
getTransferHistory,
|
|
763
|
+
getWithdrawalHistory,
|
|
764
|
+
loadConfig,
|
|
765
|
+
login,
|
|
766
|
+
logout,
|
|
767
|
+
paginateCursor,
|
|
768
|
+
saveConfig,
|
|
769
|
+
verifySession
|
|
770
|
+
});
|
|
771
|
+
//# sourceMappingURL=index.cjs.map
|