@raintree-technology/perps 0.1.0 → 0.1.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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.1] - 2026-02-25
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Restored Node 18 CI compatibility by deferring `@inquirer/prompts` loading to runtime and using shared prompt wrappers in arb commands
|
|
14
|
+
- Added a Node 18-safe `globalThis.crypto` fallback for onboarding key generation paths
|
|
15
|
+
- Updated README command-surface tests to strip inline shell comments before execution
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Exchange onboarding guides under `docs/exchanges/*` and README links to those guides
|
|
19
|
+
|
|
10
20
|
### Security
|
|
11
21
|
- Replaced `elliptic` and `keccak256` with `@noble/curves` and `@noble/hashes` in Orderly adapter (CVE-2025-14505, CVE-2026-2739)
|
|
12
22
|
- Removed `@types/elliptic` dev dependency
|
|
@@ -29,5 +39,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
29
39
|
- Risk management: limits, drawdown, position sizing
|
|
30
40
|
- Execution journal and safety checks
|
|
31
41
|
|
|
32
|
-
[Unreleased]: https://github.com/raintree-technology/perps/compare/v0.1.
|
|
42
|
+
[Unreleased]: https://github.com/raintree-technology/perps/compare/v0.1.1...HEAD
|
|
43
|
+
[0.1.1]: https://github.com/raintree-technology/perps/releases/tag/v0.1.1
|
|
33
44
|
[0.1.0]: https://github.com/raintree-technology/perps/releases/tag/v0.1.0
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Execute basis trades (cash-and-carry arbitrage) on a single exchange
|
|
4
4
|
*/
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
|
-
import { confirm } from "@inquirer/prompts";
|
|
7
6
|
import { getContext, getOutputOptions, getSelectedExchange } from "../../cli/program.js";
|
|
8
7
|
import { output, outputError } from "../../cli/output.js";
|
|
8
|
+
import { confirm } from "../../lib/prompts.js";
|
|
9
9
|
import { getExchangeAdapterById } from "../../lib/exchange.js";
|
|
10
10
|
import { DEFAULT_ARB_SIZE_USD } from "../../lib/constants.js";
|
|
11
11
|
import { validateAsset, validateSize } from "../../lib/validate.js";
|
|
@@ -178,10 +178,7 @@ export function registerArbBasisExecuteCommand(arb) {
|
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
180
|
if (!opts.yes) {
|
|
181
|
-
const confirmed = await confirm(
|
|
182
|
-
message: "Execute this basis trade?",
|
|
183
|
-
default: false,
|
|
184
|
-
});
|
|
181
|
+
const confirmed = await confirm("Execute this basis trade?", false);
|
|
185
182
|
if (!confirmed) {
|
|
186
183
|
if (isJson) {
|
|
187
184
|
emitJson({
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Arb Execute Command
|
|
3
3
|
* Execute delta-neutral funding arbitrage across exchanges
|
|
4
4
|
*/
|
|
5
|
-
import { confirm } from "@inquirer/prompts";
|
|
6
5
|
import { getContext, getOutputOptions } from "../../cli/program.js";
|
|
7
6
|
import { output, outputError } from "../../cli/output.js";
|
|
7
|
+
import { confirm } from "../../lib/prompts.js";
|
|
8
8
|
import { getExchangeAdapterById } from "../../lib/exchange.js";
|
|
9
9
|
import { getLatestFundingRates } from "../../lib/db/funding-history.js";
|
|
10
10
|
import { getExchangeIdByName, DEFAULT_ARB_SIZE_USD } from "../../lib/constants.js";
|
|
@@ -196,10 +196,7 @@ export function registerArbExecuteCommand(arb) {
|
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
198
|
if (!opts.yes) {
|
|
199
|
-
const confirmed = await confirm(
|
|
200
|
-
message: "Execute this arbitrage trade?",
|
|
201
|
-
default: false,
|
|
202
|
-
});
|
|
199
|
+
const confirmed = await confirm("Execute this arbitrage trade?", false);
|
|
203
200
|
if (!confirmed) {
|
|
204
201
|
if (isJson) {
|
|
205
202
|
emitJson({
|
package/dist/lib/onboarding.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
1
|
+
import { randomBytes, webcrypto } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
|
|
@@ -40,6 +40,10 @@ const AEVO_TESTNET_CHAIN_ID = 11155111;
|
|
|
40
40
|
const PARADEX_TESTNET_API = "https://api.testnet.paradex.trade/v1";
|
|
41
41
|
const SECONDS_PER_DAY = 86_400;
|
|
42
42
|
const MILLISECONDS_PER_DAY = 86_400_000;
|
|
43
|
+
// Node 18 may not expose globalThis.crypto in every runtime context.
|
|
44
|
+
if (!globalThis.crypto) {
|
|
45
|
+
globalThis.crypto = webcrypto;
|
|
46
|
+
}
|
|
43
47
|
function dedupe(values, order) {
|
|
44
48
|
const set = new Set(values);
|
|
45
49
|
return order.filter((item) => set.has(item));
|
package/dist/lib/prompts.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { input, select as inquirerSelect, confirm as inquirerConfirm, checkbox, } from "@inquirer/prompts";
|
|
2
1
|
import { inquirerTheme, highlighter } from "./ui-tokens.js";
|
|
2
|
+
let promptsModule = null;
|
|
3
|
+
async function loadPrompts() {
|
|
4
|
+
if (promptsModule)
|
|
5
|
+
return promptsModule;
|
|
6
|
+
promptsModule = await import("@inquirer/prompts");
|
|
7
|
+
return promptsModule;
|
|
8
|
+
}
|
|
3
9
|
/**
|
|
4
10
|
* Prompt for text input
|
|
5
11
|
*/
|
|
6
12
|
export async function prompt(question) {
|
|
13
|
+
const { input } = await loadPrompts();
|
|
7
14
|
const answer = await input({
|
|
8
15
|
message: question,
|
|
9
16
|
theme: inquirerTheme,
|
|
@@ -14,6 +21,7 @@ export async function prompt(question) {
|
|
|
14
21
|
* Prompt for selection from a list of options with arrow key navigation
|
|
15
22
|
*/
|
|
16
23
|
export async function select(question, options) {
|
|
24
|
+
const { select: inquirerSelect } = await loadPrompts();
|
|
17
25
|
const result = await inquirerSelect({
|
|
18
26
|
message: question,
|
|
19
27
|
choices: options.map((opt) => ({
|
|
@@ -29,6 +37,7 @@ export async function select(question, options) {
|
|
|
29
37
|
* Prompt for multiple selections with checkboxes
|
|
30
38
|
*/
|
|
31
39
|
export async function multiSelect(question, options) {
|
|
40
|
+
const { checkbox } = await loadPrompts();
|
|
32
41
|
const results = await checkbox({
|
|
33
42
|
message: question,
|
|
34
43
|
choices: options.map((opt) => ({
|
|
@@ -44,6 +53,7 @@ export async function multiSelect(question, options) {
|
|
|
44
53
|
* Prompt for yes/no confirmation
|
|
45
54
|
*/
|
|
46
55
|
export async function confirm(question, defaultValue = false) {
|
|
56
|
+
const { confirm: inquirerConfirm } = await loadPrompts();
|
|
47
57
|
return inquirerConfirm({
|
|
48
58
|
message: question,
|
|
49
59
|
default: defaultValue,
|
|
@@ -54,6 +64,7 @@ export async function confirm(question, defaultValue = false) {
|
|
|
54
64
|
* Wait for user to press Enter
|
|
55
65
|
*/
|
|
56
66
|
export async function waitForEnter(message = "Press Enter to continue...") {
|
|
67
|
+
const { input } = await loadPrompts();
|
|
57
68
|
await input({
|
|
58
69
|
message,
|
|
59
70
|
theme: {
|