dipcoin-cli 1.1.1 → 1.2.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/dist/cli.cjs CHANGED
@@ -15,6 +15,7 @@ var transactions = require('@mysten/sui/transactions');
15
15
  var pythSuiJs = require('@pythnetwork/pyth-sui-js');
16
16
  var child_process = require('child_process');
17
17
  var Table = require('cli-table3');
18
+ var readline = require('readline');
18
19
 
19
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
20
21
 
@@ -24,6 +25,7 @@ var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
24
25
  var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
25
26
  var BigNumber__default = /*#__PURE__*/_interopDefaultLegacy(BigNumber);
26
27
  var Table__default = /*#__PURE__*/_interopDefaultLegacy(Table);
28
+ var readline__default = /*#__PURE__*/_interopDefaultLegacy(readline);
27
29
 
28
30
  const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
29
31
 
@@ -5972,6 +5974,9 @@ const bcs = {
5972
5974
  }
5973
5975
  };
5974
5976
 
5977
+ toBase58;
5978
+ fromBase58;
5979
+
5975
5980
  const SUI_NS_NAME_REGEX = /^(?!.*(^(?!@)|[-.@])($|[-.@]))(?:[a-z0-9-]{0,63}(?:\.[a-z0-9-]{0,63})*)?@[a-z0-9-]{0,63}$/i;
5976
5981
  const SUI_NS_DOMAIN_REGEX = /^(?!.*(^|[-.])($|[-.]))(?:[a-z0-9-]{0,63}\.)+sui$/i;
5977
5982
  const MAX_SUI_NS_NAME_LENGTH = 235;
@@ -20994,6 +20999,156 @@ function registerReferralCommands(program) {
20994
20999
  });
20995
21000
  }
20996
21001
 
21002
+ const CONFIG_DIR = path__default["default"].join(os__default["default"].homedir(), ".config", "dipcoin");
21003
+ const ENV_PATH = path__default["default"].join(CONFIG_DIR, "env");
21004
+ function ask(question) {
21005
+ const rl = readline__default["default"].createInterface({ input: process.stdin, output: process.stdout });
21006
+ return new Promise((resolve) => rl.question(question, (answer) => {
21007
+ rl.close();
21008
+ resolve(answer);
21009
+ }));
21010
+ }
21011
+ async function confirmOverwrite() {
21012
+ if (!fs__default["default"].existsSync(ENV_PATH))
21013
+ return true;
21014
+ const answer = await ask(`${ENV_PATH} already exists. Overwrite? [y/N]: `);
21015
+ return /^y(es)?$/i.test(answer.trim());
21016
+ }
21017
+ function readHiddenInput(prompt) {
21018
+ return new Promise((resolve, reject) => {
21019
+ const stdin = process.stdin;
21020
+ if (!stdin.isTTY) {
21021
+ let buffer = "";
21022
+ stdin.setEncoding("utf8");
21023
+ stdin.on("data", (chunk) => {
21024
+ buffer += chunk;
21025
+ });
21026
+ stdin.on("end", () => {
21027
+ resolve(buffer.split(/\r?\n/)[0] || "");
21028
+ });
21029
+ return;
21030
+ }
21031
+ process.stdout.write(prompt);
21032
+ stdin.setRawMode(true);
21033
+ stdin.resume();
21034
+ stdin.setEncoding("utf8");
21035
+ let input = "";
21036
+ const onData = (chunk) => {
21037
+ for (const ch of chunk) {
21038
+ const code = ch.charCodeAt(0);
21039
+ if (ch === "\n" || ch === "\r") {
21040
+ stdin.setRawMode(false);
21041
+ stdin.pause();
21042
+ stdin.removeListener("data", onData);
21043
+ process.stdout.write("\n");
21044
+ resolve(input);
21045
+ return;
21046
+ }
21047
+ if (code === 3) {
21048
+ stdin.setRawMode(false);
21049
+ stdin.pause();
21050
+ process.stdout.write("\n");
21051
+ reject(new Error("Aborted"));
21052
+ return;
21053
+ }
21054
+ if (code === 127 || code === 8) {
21055
+ input = input.slice(0, -1);
21056
+ continue;
21057
+ }
21058
+ input += ch;
21059
+ }
21060
+ };
21061
+ stdin.on("data", onData);
21062
+ });
21063
+ }
21064
+ function writeEnvFile(privateKey, network) {
21065
+ fs__default["default"].mkdirSync(CONFIG_DIR, { recursive: true });
21066
+ const content = `DIPCOIN_PRIVATE_KEY=${privateKey}\nDIPCOIN_NETWORK=${network}\n`;
21067
+ fs__default["default"].writeFileSync(ENV_PATH, content, { mode: 0o600 });
21068
+ try {
21069
+ fs__default["default"].chmodSync(ENV_PATH, 0o600);
21070
+ }
21071
+ catch {
21072
+ // best-effort on platforms without POSIX perms
21073
+ }
21074
+ }
21075
+ function resolveNetwork(input) {
21076
+ return input === "testnet" ? "testnet" : "mainnet";
21077
+ }
21078
+ function registerSetupCommands(program) {
21079
+ const setup = program
21080
+ .command("setup")
21081
+ .description("Configure credentials (~/.config/dipcoin/env)");
21082
+ setup
21083
+ .command("import")
21084
+ .description("Import an existing Sui private key (interactive, hidden input)")
21085
+ .option("--network <network>", "mainnet | testnet", "mainnet")
21086
+ .action(async (opts) => {
21087
+ try {
21088
+ const network = resolveNetwork(opts.network);
21089
+ if (!(await confirmOverwrite())) {
21090
+ console.error("Aborted.");
21091
+ process.exit(1);
21092
+ }
21093
+ const key = (await readHiddenInput("Paste your Sui private key (suiprivkey1...): ")).trim();
21094
+ if (!key) {
21095
+ console.error("No input provided.");
21096
+ process.exit(1);
21097
+ }
21098
+ if (!key.startsWith("suiprivkey1")) {
21099
+ console.error("Invalid format. Sui private keys must start with 'suiprivkey1'.");
21100
+ process.exit(1);
21101
+ }
21102
+ let address;
21103
+ try {
21104
+ decodeSuiPrivateKey(key);
21105
+ address = fromExportedKeypair(key).toSuiAddress();
21106
+ }
21107
+ catch (e) {
21108
+ const msg = e instanceof Error ? e.message : String(e);
21109
+ console.error(`Failed to decode private key: ${msg}`);
21110
+ process.exit(1);
21111
+ }
21112
+ writeEnvFile(key, network);
21113
+ console.log(`Saved to ${ENV_PATH} (chmod 600).`);
21114
+ console.log(`Network: ${network}`);
21115
+ console.log(`Address: ${address}`);
21116
+ }
21117
+ catch (e) {
21118
+ const msg = e instanceof Error ? e.message : String(e);
21119
+ console.error("Error:", msg);
21120
+ process.exit(1);
21121
+ }
21122
+ });
21123
+ setup
21124
+ .command("generate")
21125
+ .description("Generate a new Sui keypair and save it as your credentials")
21126
+ .option("--network <network>", "mainnet | testnet", "mainnet")
21127
+ .action(async (opts) => {
21128
+ try {
21129
+ const network = resolveNetwork(opts.network);
21130
+ if (!(await confirmOverwrite())) {
21131
+ console.error("Aborted.");
21132
+ process.exit(1);
21133
+ }
21134
+ const kp = new ed25519.Ed25519Keypair();
21135
+ const privateKey = kp.getSecretKey();
21136
+ const address = kp.toSuiAddress();
21137
+ writeEnvFile(privateKey, network);
21138
+ console.log(`Generated new keypair and saved to ${ENV_PATH} (chmod 600).`);
21139
+ console.log(`Network: ${network}`);
21140
+ console.log(`Address: ${address}`);
21141
+ console.log("");
21142
+ console.log("Next: transfer USDC on Sui to the address above, then run: dipcoin-cli account deposit <amount>");
21143
+ }
21144
+ catch (e) {
21145
+ const msg = e instanceof Error ? e.message : String(e);
21146
+ console.error("Error:", msg);
21147
+ process.exit(1);
21148
+ }
21149
+ });
21150
+ }
21151
+
20997
21152
  function getPackageVersion() {
20998
21153
  try {
20999
21154
  // Works in both ESM and CJS after bundling
@@ -21016,6 +21171,7 @@ program
21016
21171
  .description("DipCoin Perpetual Trading CLI")
21017
21172
  .version(getPackageVersion())
21018
21173
  .option("--json", "Output in JSON format");
21174
+ registerSetupCommands(program);
21019
21175
  registerAccountCommands(program);
21020
21176
  registerTradeCommands(program);
21021
21177
  registerPositionCommands(program);