@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.0...HEAD
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({
@@ -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));
@@ -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: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raintree-technology/perps",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Universal CLI for perpetual DEXes",
5
5
  "author": "Raintree Technology (https://raintree.technology)",
6
6
  "contributors": [