@rozoai/checkout 0.1.5 → 0.1.7

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.
@@ -10310,9 +10310,9 @@ function assertNoTrackedDotEnv(cwd = process.cwd()) {
10310
10310
  }
10311
10311
 
10312
10312
  // scripts/src/lib/key-source.mjs
10313
- import fs2 from "node:fs";
10314
- import path2 from "node:path";
10315
- import os from "node:os";
10313
+ import fs3 from "node:fs";
10314
+ import path3 from "node:path";
10315
+ import os2 from "node:os";
10316
10316
  import crypto3 from "node:crypto";
10317
10317
 
10318
10318
  // node_modules/viem/_esm/utils/getAction.js
@@ -21278,18 +21278,121 @@ function http(url, config = {}) {
21278
21278
  init_encodeFunctionData();
21279
21279
  init_keccak256();
21280
21280
 
21281
+ // scripts/src/lib/dotenv.mjs
21282
+ import fs2 from "node:fs";
21283
+ import os from "node:os";
21284
+ import path2 from "node:path";
21285
+ var ALLOWED_KEYS = [
21286
+ "ROZO_CHECKOUT_EVM_KEY",
21287
+ "ROZO_CHECKOUT_SOL_KEY",
21288
+ "ROZO_CHECKOUT_EVM_KEYSTORE",
21289
+ "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE"
21290
+ ];
21291
+ var ALLOWED_PATTERN = /^ROZO_CHECKOUT_RPC_[A-Za-z0-9_]+$/;
21292
+ function isAllowedKey(key) {
21293
+ return ALLOWED_KEYS.includes(key) || ALLOWED_PATTERN.test(key);
21294
+ }
21295
+ function parseDotenv(text) {
21296
+ const vars = {};
21297
+ const lines = String(text).split(/\r?\n/);
21298
+ lines.forEach((rawLine, i) => {
21299
+ const lineNo = i + 1;
21300
+ const line = rawLine.trim();
21301
+ if (!line || line.startsWith("#")) return;
21302
+ const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
21303
+ const eq = withoutExport.indexOf("=");
21304
+ if (eq === -1) {
21305
+ throw new SkillError(
21306
+ "BAD_ENV_FILE",
21307
+ `Malformed .env: line ${lineNo} is not KEY=VALUE. (Content withheld \u2014 it may be a secret.)`
21308
+ );
21309
+ }
21310
+ const key = withoutExport.slice(0, eq).trim();
21311
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
21312
+ throw new SkillError(
21313
+ "BAD_ENV_FILE",
21314
+ `Malformed .env: line ${lineNo} has an invalid key name. (Content withheld.)`
21315
+ );
21316
+ }
21317
+ let value = withoutExport.slice(eq + 1).trim();
21318
+ if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
21319
+ value = value.slice(1, -1);
21320
+ }
21321
+ vars[key] = value;
21322
+ });
21323
+ return vars;
21324
+ }
21325
+ function filterAllowed(vars) {
21326
+ const out = {};
21327
+ for (const [k, v] of Object.entries(vars)) if (isAllowedKey(k)) out[k] = v;
21328
+ return out;
21329
+ }
21330
+ function envFileCandidates({ cwd = process.cwd(), home = os.homedir() } = {}) {
21331
+ const candidates = [path2.join(cwd, ".env")];
21332
+ const owned = path2.join(home, ".rozo-checkout", ".env");
21333
+ if (owned !== candidates[0]) candidates.push(owned);
21334
+ return candidates;
21335
+ }
21336
+ function resolveEnvFile({ file, cwd = process.cwd(), home = os.homedir() } = {}) {
21337
+ if (file) {
21338
+ const p = path2.resolve(file);
21339
+ if (!fs2.existsSync(p)) {
21340
+ throw new SkillError("ENV_FILE_MISSING", `No such env file: ${file}`);
21341
+ }
21342
+ return p;
21343
+ }
21344
+ return envFileCandidates({ cwd, home }).find((p) => fs2.existsSync(p)) ?? null;
21345
+ }
21346
+ function applyDotenv({
21347
+ file,
21348
+ cwd = process.cwd(),
21349
+ home = os.homedir(),
21350
+ env = process.env
21351
+ } = {}) {
21352
+ const target = resolveEnvFile({ file, cwd, home });
21353
+ if (!target) return null;
21354
+ let stat;
21355
+ try {
21356
+ stat = fs2.statSync(target);
21357
+ } catch (err) {
21358
+ throw new SkillError("ENV_FILE_MISSING", `Cannot read env file (${err.code || "error"}).`);
21359
+ }
21360
+ if (process.platform !== "win32" && stat.mode & 63) {
21361
+ const mode = (stat.mode & 511).toString(8).padStart(3, "0");
21362
+ throw new SkillError(
21363
+ "ENV_FILE_PERMISSIONS",
21364
+ `That .env is readable by other users (mode ${mode}). Run: chmod 600 ${target}`
21365
+ );
21366
+ }
21367
+ assertNotTrackedByGit(target);
21368
+ const parsed = parseDotenv(fs2.readFileSync(target, "utf8"));
21369
+ const allowed = filterAllowed(parsed);
21370
+ const applied = [];
21371
+ for (const [k, v] of Object.entries(allowed)) {
21372
+ const existing = env[k];
21373
+ if (existing !== void 0 && String(existing).trim() !== "") continue;
21374
+ env[k] = v;
21375
+ applied.push(k);
21376
+ }
21377
+ return {
21378
+ path: target,
21379
+ applied,
21380
+ ignored: Object.keys(parsed).length - Object.keys(allowed).length
21381
+ };
21382
+ }
21383
+
21281
21384
  // scripts/src/lib/key-source.mjs
21282
21385
  var EVM_KEY_ENV = "ROZO_CHECKOUT_EVM_KEY";
21283
21386
  var SOL_KEY_ENV = "ROZO_CHECKOUT_SOL_KEY";
21284
21387
  var EVM_KEYSTORE_ENV = "ROZO_CHECKOUT_EVM_KEYSTORE";
21285
21388
  var KEYSTORE_PASSPHRASE_ENV = "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE";
21286
21389
  function defaultSolanaKeypairPath() {
21287
- return path2.join(os.homedir(), ".config", "solana", "id.json");
21390
+ return path3.join(os2.homedir(), ".config", "solana", "id.json");
21288
21391
  }
21289
21392
  function assertKeyfileSafe(file) {
21290
21393
  let stat;
21291
21394
  try {
21292
- stat = fs2.statSync(file);
21395
+ stat = fs3.statSync(file);
21293
21396
  } catch (err) {
21294
21397
  throw new SkillError(
21295
21398
  "KEYFILE_UNREADABLE",
@@ -21466,12 +21569,16 @@ function looksLikeKeystore(text) {
21466
21569
  return false;
21467
21570
  }
21468
21571
  }
21469
- function planKeySource({ family, keyfile, env = process.env }) {
21572
+ function searchedSuffix(searched) {
21573
+ if (!searched || !searched.length) return "";
21574
+ return ` Looked for a .env in: ${searched.map(displayPath).join(", ")}.`;
21575
+ }
21576
+ function planKeySource({ family, keyfile, env = process.env, searched }) {
21470
21577
  if (keyfile) {
21471
21578
  const resolved = expandHome(keyfile);
21472
21579
  let text;
21473
21580
  try {
21474
- text = fs2.readFileSync(resolved, "utf8");
21581
+ text = fs3.readFileSync(resolved, "utf8");
21475
21582
  } catch (err) {
21476
21583
  throw new SkillError(
21477
21584
  "KEYFILE_UNREADABLE",
@@ -21495,13 +21602,13 @@ function planKeySource({ family, keyfile, env = process.env }) {
21495
21602
  }
21496
21603
  if (family === "solana") {
21497
21604
  const standard = defaultSolanaKeypairPath();
21498
- if (fs2.existsSync(standard)) {
21605
+ if (fs3.existsSync(standard)) {
21499
21606
  return { kind: "keypair-file", path: standard, label: displayPath(standard) };
21500
21607
  }
21501
21608
  if (env[SOL_KEY_ENV]) return { kind: "env", label: SOL_KEY_ENV };
21502
21609
  throw new SkillError(
21503
21610
  "NO_KEY_SOURCE",
21504
- `No signing key found. Either create one with solana-keygen (writes ${displayPath(standard)}), pass --keyfile <path>, or set ${SOL_KEY_ENV}.`
21611
+ `No signing key found. Either create one with solana-keygen (writes ${displayPath(standard)}), pass --keyfile <path>, or set ${SOL_KEY_ENV}.` + searchedSuffix(searched)
21505
21612
  );
21506
21613
  }
21507
21614
  if (family === "evm") {
@@ -21513,7 +21620,7 @@ function planKeySource({ family, keyfile, env = process.env }) {
21513
21620
  if (env[EVM_KEY_ENV]) return { kind: "env", label: EVM_KEY_ENV };
21514
21621
  throw new SkillError(
21515
21622
  "NO_KEY_SOURCE",
21516
- `No signing key found. Either point ${EVM_KEYSTORE_ENV} at an encrypted JSON keystore, pass --keyfile <path>, or set ${EVM_KEY_ENV}.`
21623
+ `No signing key found. Either point ${EVM_KEYSTORE_ENV} at an encrypted JSON keystore, pass --keyfile <path>, or set ${EVM_KEY_ENV}.${searchedSuffix(searched)}`
21517
21624
  );
21518
21625
  }
21519
21626
  throw new SkillError("NO_KEY_SOURCE", `No key source for family "${family}".`);
@@ -21531,7 +21638,7 @@ async function loadKeySource(plan, { family, env = process.env, askPassphrase }
21531
21638
  return { secretKey: decodeSolanaEnvKey(raw), label: plan.label, kind: plan.kind };
21532
21639
  }
21533
21640
  assertKeyfileSafe(plan.path);
21534
- const text = fs2.readFileSync(plan.path, "utf8");
21641
+ const text = fs3.readFileSync(plan.path, "utf8");
21535
21642
  if (plan.kind === "keypair-file") {
21536
21643
  return { secretKey: parseSolanaKeypairJson(text), label: plan.label, kind: plan.kind };
21537
21644
  }
@@ -21550,106 +21657,14 @@ async function loadKeySource(plan, { family, env = process.env, askPassphrase }
21550
21657
  }
21551
21658
  function expandHome(p) {
21552
21659
  const s = String(p);
21553
- if (s === "~") return os.homedir();
21554
- if (s.startsWith("~/")) return path2.join(os.homedir(), s.slice(2));
21660
+ if (s === "~") return os2.homedir();
21661
+ if (s.startsWith("~/")) return path3.join(os2.homedir(), s.slice(2));
21555
21662
  return s;
21556
21663
  }
21557
21664
  function displayPath(p) {
21558
- const home = os.homedir();
21665
+ const home = os2.homedir();
21559
21666
  const s = String(p);
21560
- return s.startsWith(home + path2.sep) ? `~${s.slice(home.length)}` : s;
21561
- }
21562
-
21563
- // scripts/src/lib/dotenv.mjs
21564
- import fs3 from "node:fs";
21565
- import path3 from "node:path";
21566
- var ALLOWED_KEYS = [
21567
- "ROZO_CHECKOUT_EVM_KEY",
21568
- "ROZO_CHECKOUT_SOL_KEY",
21569
- "ROZO_CHECKOUT_EVM_KEYSTORE",
21570
- "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE"
21571
- ];
21572
- var ALLOWED_PATTERN = /^ROZO_CHECKOUT_RPC_[A-Za-z0-9_]+$/;
21573
- function isAllowedKey(key) {
21574
- return ALLOWED_KEYS.includes(key) || ALLOWED_PATTERN.test(key);
21575
- }
21576
- function parseDotenv(text) {
21577
- const vars = {};
21578
- const lines = String(text).split(/\r?\n/);
21579
- lines.forEach((rawLine, i) => {
21580
- const lineNo = i + 1;
21581
- const line = rawLine.trim();
21582
- if (!line || line.startsWith("#")) return;
21583
- const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
21584
- const eq = withoutExport.indexOf("=");
21585
- if (eq === -1) {
21586
- throw new SkillError(
21587
- "BAD_ENV_FILE",
21588
- `Malformed .env: line ${lineNo} is not KEY=VALUE. (Content withheld \u2014 it may be a secret.)`
21589
- );
21590
- }
21591
- const key = withoutExport.slice(0, eq).trim();
21592
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
21593
- throw new SkillError(
21594
- "BAD_ENV_FILE",
21595
- `Malformed .env: line ${lineNo} has an invalid key name. (Content withheld.)`
21596
- );
21597
- }
21598
- let value = withoutExport.slice(eq + 1).trim();
21599
- if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
21600
- value = value.slice(1, -1);
21601
- }
21602
- vars[key] = value;
21603
- });
21604
- return vars;
21605
- }
21606
- function filterAllowed(vars) {
21607
- const out = {};
21608
- for (const [k, v] of Object.entries(vars)) if (isAllowedKey(k)) out[k] = v;
21609
- return out;
21610
- }
21611
- function resolveEnvFile({ file, cwd = process.cwd() } = {}) {
21612
- if (file) {
21613
- const p = path3.resolve(file);
21614
- if (!fs3.existsSync(p)) {
21615
- throw new SkillError("ENV_FILE_MISSING", `No such env file: ${file}`);
21616
- }
21617
- return p;
21618
- }
21619
- const fallback = path3.join(cwd, ".env");
21620
- return fs3.existsSync(fallback) ? fallback : null;
21621
- }
21622
- function applyDotenv({ file, cwd = process.cwd(), env = process.env } = {}) {
21623
- const target = resolveEnvFile({ file, cwd });
21624
- if (!target) return null;
21625
- let stat;
21626
- try {
21627
- stat = fs3.statSync(target);
21628
- } catch (err) {
21629
- throw new SkillError("ENV_FILE_MISSING", `Cannot read env file (${err.code || "error"}).`);
21630
- }
21631
- if (process.platform !== "win32" && stat.mode & 63) {
21632
- const mode = (stat.mode & 511).toString(8).padStart(3, "0");
21633
- throw new SkillError(
21634
- "ENV_FILE_PERMISSIONS",
21635
- `That .env is readable by other users (mode ${mode}). Run: chmod 600 ${target}`
21636
- );
21637
- }
21638
- assertNotTrackedByGit(target);
21639
- const parsed = parseDotenv(fs3.readFileSync(target, "utf8"));
21640
- const allowed = filterAllowed(parsed);
21641
- const applied = [];
21642
- for (const [k, v] of Object.entries(allowed)) {
21643
- const existing = env[k];
21644
- if (existing !== void 0 && String(existing).trim() !== "") continue;
21645
- env[k] = v;
21646
- applied.push(k);
21647
- }
21648
- return {
21649
- path: target,
21650
- applied,
21651
- ignored: Object.keys(parsed).length - Object.keys(allowed).length
21652
- };
21667
+ return s.startsWith(home + path3.sep) ? `~${s.slice(home.length)}` : s;
21653
21668
  }
21654
21669
 
21655
21670
  // scripts/src/lib/passphrase.mjs
@@ -22215,7 +22230,7 @@ function assertNotBlacklisted(targets, blacklist) {
22215
22230
  // scripts/src/lib/state.mjs
22216
22231
  import fs5 from "node:fs";
22217
22232
  import path5 from "node:path";
22218
- import os2 from "node:os";
22233
+ import os3 from "node:os";
22219
22234
  import crypto5 from "node:crypto";
22220
22235
  var LOCK_STALE_MS = 6e4;
22221
22236
  var LOCK_WAIT_MS = 1e4;
@@ -22276,7 +22291,7 @@ function withLock(fn) {
22276
22291
  }
22277
22292
  }
22278
22293
  function stateRoot() {
22279
- return process.env.ROZO_CHECKOUT_STATE_DIR || path5.join(os2.homedir(), ".rozo-checkout", "state");
22294
+ return process.env.ROZO_CHECKOUT_STATE_DIR || path5.join(os3.homedir(), ".rozo-checkout", "state");
22280
22295
  }
22281
22296
  function statePath(rozoPaymentId) {
22282
22297
  if (!/^[A-Za-z0-9-]{8,64}$/.test(String(rozoPaymentId || ""))) {
@@ -22770,7 +22785,11 @@ async function main(argv) {
22770
22785
  const rozoPaymentId = assertRozoPaymentId(args["rozo-payment-id"] || args._[0]);
22771
22786
  assertNoTrackedDotEnv();
22772
22787
  const dotenv = applyDotenv({ file: args["env-file"] });
22773
- const plan = planKeySource({ family: "evm", keyfile: args.keyfile });
22788
+ const plan = planKeySource({
22789
+ family: "evm",
22790
+ keyfile: args.keyfile,
22791
+ searched: args["env-file"] ? null : envFileCandidates()
22792
+ });
22774
22793
  const loaded = await loadKeySource(plan, { family: "evm", askPassphrase: promptPassphrase });
22775
22794
  const account = privateKeyToAccount(loaded.privateKey);
22776
22795
  const sender = account.address;
@@ -15507,14 +15507,14 @@ var require_node_gyp_build = __commonJS({
15507
15507
  "node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
15508
15508
  var fs6 = __require("fs");
15509
15509
  var path6 = __require("path");
15510
- var os3 = __require("os");
15510
+ var os4 = __require("os");
15511
15511
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
15512
15512
  var vars = process.config && process.config.variables || {};
15513
15513
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
15514
15514
  var abi = process.versions.modules;
15515
15515
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
15516
- var arch = process.env.npm_config_arch || os3.arch();
15517
- var platform = process.env.npm_config_platform || os3.platform();
15516
+ var arch = process.env.npm_config_arch || os4.arch();
15517
+ var platform = process.env.npm_config_platform || os4.platform();
15518
15518
  var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
15519
15519
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
15520
15520
  var uv = (process.versions.uv || "").split(".")[0];
@@ -32455,26 +32455,129 @@ function assertNoTrackedDotEnv(cwd = process.cwd()) {
32455
32455
  }
32456
32456
 
32457
32457
  // scripts/src/lib/key-source.mjs
32458
- import fs2 from "node:fs";
32459
- import path2 from "node:path";
32460
- import os from "node:os";
32458
+ import fs3 from "node:fs";
32459
+ import path3 from "node:path";
32460
+ import os2 from "node:os";
32461
32461
  import crypto2 from "node:crypto";
32462
32462
 
32463
32463
  // node_modules/viem/_esm/index.js
32464
32464
  init_keccak256();
32465
32465
 
32466
+ // scripts/src/lib/dotenv.mjs
32467
+ import fs2 from "node:fs";
32468
+ import os from "node:os";
32469
+ import path2 from "node:path";
32470
+ var ALLOWED_KEYS = [
32471
+ "ROZO_CHECKOUT_EVM_KEY",
32472
+ "ROZO_CHECKOUT_SOL_KEY",
32473
+ "ROZO_CHECKOUT_EVM_KEYSTORE",
32474
+ "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE"
32475
+ ];
32476
+ var ALLOWED_PATTERN = /^ROZO_CHECKOUT_RPC_[A-Za-z0-9_]+$/;
32477
+ function isAllowedKey(key) {
32478
+ return ALLOWED_KEYS.includes(key) || ALLOWED_PATTERN.test(key);
32479
+ }
32480
+ function parseDotenv(text) {
32481
+ const vars = {};
32482
+ const lines = String(text).split(/\r?\n/);
32483
+ lines.forEach((rawLine, i) => {
32484
+ const lineNo = i + 1;
32485
+ const line = rawLine.trim();
32486
+ if (!line || line.startsWith("#")) return;
32487
+ const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
32488
+ const eq = withoutExport.indexOf("=");
32489
+ if (eq === -1) {
32490
+ throw new SkillError(
32491
+ "BAD_ENV_FILE",
32492
+ `Malformed .env: line ${lineNo} is not KEY=VALUE. (Content withheld \u2014 it may be a secret.)`
32493
+ );
32494
+ }
32495
+ const key = withoutExport.slice(0, eq).trim();
32496
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
32497
+ throw new SkillError(
32498
+ "BAD_ENV_FILE",
32499
+ `Malformed .env: line ${lineNo} has an invalid key name. (Content withheld.)`
32500
+ );
32501
+ }
32502
+ let value = withoutExport.slice(eq + 1).trim();
32503
+ if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
32504
+ value = value.slice(1, -1);
32505
+ }
32506
+ vars[key] = value;
32507
+ });
32508
+ return vars;
32509
+ }
32510
+ function filterAllowed(vars) {
32511
+ const out = {};
32512
+ for (const [k, v] of Object.entries(vars)) if (isAllowedKey(k)) out[k] = v;
32513
+ return out;
32514
+ }
32515
+ function envFileCandidates({ cwd = process.cwd(), home = os.homedir() } = {}) {
32516
+ const candidates = [path2.join(cwd, ".env")];
32517
+ const owned = path2.join(home, ".rozo-checkout", ".env");
32518
+ if (owned !== candidates[0]) candidates.push(owned);
32519
+ return candidates;
32520
+ }
32521
+ function resolveEnvFile({ file, cwd = process.cwd(), home = os.homedir() } = {}) {
32522
+ if (file) {
32523
+ const p = path2.resolve(file);
32524
+ if (!fs2.existsSync(p)) {
32525
+ throw new SkillError("ENV_FILE_MISSING", `No such env file: ${file}`);
32526
+ }
32527
+ return p;
32528
+ }
32529
+ return envFileCandidates({ cwd, home }).find((p) => fs2.existsSync(p)) ?? null;
32530
+ }
32531
+ function applyDotenv({
32532
+ file,
32533
+ cwd = process.cwd(),
32534
+ home = os.homedir(),
32535
+ env = process.env
32536
+ } = {}) {
32537
+ const target = resolveEnvFile({ file, cwd, home });
32538
+ if (!target) return null;
32539
+ let stat;
32540
+ try {
32541
+ stat = fs2.statSync(target);
32542
+ } catch (err) {
32543
+ throw new SkillError("ENV_FILE_MISSING", `Cannot read env file (${err.code || "error"}).`);
32544
+ }
32545
+ if (process.platform !== "win32" && stat.mode & 63) {
32546
+ const mode = (stat.mode & 511).toString(8).padStart(3, "0");
32547
+ throw new SkillError(
32548
+ "ENV_FILE_PERMISSIONS",
32549
+ `That .env is readable by other users (mode ${mode}). Run: chmod 600 ${target}`
32550
+ );
32551
+ }
32552
+ assertNotTrackedByGit(target);
32553
+ const parsed = parseDotenv(fs2.readFileSync(target, "utf8"));
32554
+ const allowed = filterAllowed(parsed);
32555
+ const applied = [];
32556
+ for (const [k, v] of Object.entries(allowed)) {
32557
+ const existing = env[k];
32558
+ if (existing !== void 0 && String(existing).trim() !== "") continue;
32559
+ env[k] = v;
32560
+ applied.push(k);
32561
+ }
32562
+ return {
32563
+ path: target,
32564
+ applied,
32565
+ ignored: Object.keys(parsed).length - Object.keys(allowed).length
32566
+ };
32567
+ }
32568
+
32466
32569
  // scripts/src/lib/key-source.mjs
32467
32570
  var EVM_KEY_ENV = "ROZO_CHECKOUT_EVM_KEY";
32468
32571
  var SOL_KEY_ENV = "ROZO_CHECKOUT_SOL_KEY";
32469
32572
  var EVM_KEYSTORE_ENV = "ROZO_CHECKOUT_EVM_KEYSTORE";
32470
32573
  var KEYSTORE_PASSPHRASE_ENV = "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE";
32471
32574
  function defaultSolanaKeypairPath() {
32472
- return path2.join(os.homedir(), ".config", "solana", "id.json");
32575
+ return path3.join(os2.homedir(), ".config", "solana", "id.json");
32473
32576
  }
32474
32577
  function assertKeyfileSafe(file) {
32475
32578
  let stat;
32476
32579
  try {
32477
- stat = fs2.statSync(file);
32580
+ stat = fs3.statSync(file);
32478
32581
  } catch (err) {
32479
32582
  throw new SkillError(
32480
32583
  "KEYFILE_UNREADABLE",
@@ -32651,12 +32754,16 @@ function looksLikeKeystore(text) {
32651
32754
  return false;
32652
32755
  }
32653
32756
  }
32654
- function planKeySource({ family, keyfile, env = process.env }) {
32757
+ function searchedSuffix(searched) {
32758
+ if (!searched || !searched.length) return "";
32759
+ return ` Looked for a .env in: ${searched.map(displayPath).join(", ")}.`;
32760
+ }
32761
+ function planKeySource({ family, keyfile, env = process.env, searched }) {
32655
32762
  if (keyfile) {
32656
32763
  const resolved = expandHome(keyfile);
32657
32764
  let text;
32658
32765
  try {
32659
- text = fs2.readFileSync(resolved, "utf8");
32766
+ text = fs3.readFileSync(resolved, "utf8");
32660
32767
  } catch (err) {
32661
32768
  throw new SkillError(
32662
32769
  "KEYFILE_UNREADABLE",
@@ -32680,13 +32787,13 @@ function planKeySource({ family, keyfile, env = process.env }) {
32680
32787
  }
32681
32788
  if (family === "solana") {
32682
32789
  const standard = defaultSolanaKeypairPath();
32683
- if (fs2.existsSync(standard)) {
32790
+ if (fs3.existsSync(standard)) {
32684
32791
  return { kind: "keypair-file", path: standard, label: displayPath(standard) };
32685
32792
  }
32686
32793
  if (env[SOL_KEY_ENV]) return { kind: "env", label: SOL_KEY_ENV };
32687
32794
  throw new SkillError(
32688
32795
  "NO_KEY_SOURCE",
32689
- `No signing key found. Either create one with solana-keygen (writes ${displayPath(standard)}), pass --keyfile <path>, or set ${SOL_KEY_ENV}.`
32796
+ `No signing key found. Either create one with solana-keygen (writes ${displayPath(standard)}), pass --keyfile <path>, or set ${SOL_KEY_ENV}.` + searchedSuffix(searched)
32690
32797
  );
32691
32798
  }
32692
32799
  if (family === "evm") {
@@ -32698,7 +32805,7 @@ function planKeySource({ family, keyfile, env = process.env }) {
32698
32805
  if (env[EVM_KEY_ENV]) return { kind: "env", label: EVM_KEY_ENV };
32699
32806
  throw new SkillError(
32700
32807
  "NO_KEY_SOURCE",
32701
- `No signing key found. Either point ${EVM_KEYSTORE_ENV} at an encrypted JSON keystore, pass --keyfile <path>, or set ${EVM_KEY_ENV}.`
32808
+ `No signing key found. Either point ${EVM_KEYSTORE_ENV} at an encrypted JSON keystore, pass --keyfile <path>, or set ${EVM_KEY_ENV}.${searchedSuffix(searched)}`
32702
32809
  );
32703
32810
  }
32704
32811
  throw new SkillError("NO_KEY_SOURCE", `No key source for family "${family}".`);
@@ -32716,7 +32823,7 @@ async function loadKeySource(plan, { family, env = process.env, askPassphrase }
32716
32823
  return { secretKey: decodeSolanaEnvKey(raw), label: plan.label, kind: plan.kind };
32717
32824
  }
32718
32825
  assertKeyfileSafe(plan.path);
32719
- const text = fs2.readFileSync(plan.path, "utf8");
32826
+ const text = fs3.readFileSync(plan.path, "utf8");
32720
32827
  if (plan.kind === "keypair-file") {
32721
32828
  return { secretKey: parseSolanaKeypairJson(text), label: plan.label, kind: plan.kind };
32722
32829
  }
@@ -32735,106 +32842,14 @@ async function loadKeySource(plan, { family, env = process.env, askPassphrase }
32735
32842
  }
32736
32843
  function expandHome(p) {
32737
32844
  const s = String(p);
32738
- if (s === "~") return os.homedir();
32739
- if (s.startsWith("~/")) return path2.join(os.homedir(), s.slice(2));
32845
+ if (s === "~") return os2.homedir();
32846
+ if (s.startsWith("~/")) return path3.join(os2.homedir(), s.slice(2));
32740
32847
  return s;
32741
32848
  }
32742
32849
  function displayPath(p) {
32743
- const home = os.homedir();
32850
+ const home = os2.homedir();
32744
32851
  const s = String(p);
32745
- return s.startsWith(home + path2.sep) ? `~${s.slice(home.length)}` : s;
32746
- }
32747
-
32748
- // scripts/src/lib/dotenv.mjs
32749
- import fs3 from "node:fs";
32750
- import path3 from "node:path";
32751
- var ALLOWED_KEYS = [
32752
- "ROZO_CHECKOUT_EVM_KEY",
32753
- "ROZO_CHECKOUT_SOL_KEY",
32754
- "ROZO_CHECKOUT_EVM_KEYSTORE",
32755
- "ROZO_CHECKOUT_KEYSTORE_PASSPHRASE"
32756
- ];
32757
- var ALLOWED_PATTERN = /^ROZO_CHECKOUT_RPC_[A-Za-z0-9_]+$/;
32758
- function isAllowedKey(key) {
32759
- return ALLOWED_KEYS.includes(key) || ALLOWED_PATTERN.test(key);
32760
- }
32761
- function parseDotenv(text) {
32762
- const vars = {};
32763
- const lines = String(text).split(/\r?\n/);
32764
- lines.forEach((rawLine, i) => {
32765
- const lineNo = i + 1;
32766
- const line = rawLine.trim();
32767
- if (!line || line.startsWith("#")) return;
32768
- const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
32769
- const eq = withoutExport.indexOf("=");
32770
- if (eq === -1) {
32771
- throw new SkillError(
32772
- "BAD_ENV_FILE",
32773
- `Malformed .env: line ${lineNo} is not KEY=VALUE. (Content withheld \u2014 it may be a secret.)`
32774
- );
32775
- }
32776
- const key = withoutExport.slice(0, eq).trim();
32777
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
32778
- throw new SkillError(
32779
- "BAD_ENV_FILE",
32780
- `Malformed .env: line ${lineNo} has an invalid key name. (Content withheld.)`
32781
- );
32782
- }
32783
- let value = withoutExport.slice(eq + 1).trim();
32784
- if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
32785
- value = value.slice(1, -1);
32786
- }
32787
- vars[key] = value;
32788
- });
32789
- return vars;
32790
- }
32791
- function filterAllowed(vars) {
32792
- const out = {};
32793
- for (const [k, v] of Object.entries(vars)) if (isAllowedKey(k)) out[k] = v;
32794
- return out;
32795
- }
32796
- function resolveEnvFile({ file, cwd = process.cwd() } = {}) {
32797
- if (file) {
32798
- const p = path3.resolve(file);
32799
- if (!fs3.existsSync(p)) {
32800
- throw new SkillError("ENV_FILE_MISSING", `No such env file: ${file}`);
32801
- }
32802
- return p;
32803
- }
32804
- const fallback = path3.join(cwd, ".env");
32805
- return fs3.existsSync(fallback) ? fallback : null;
32806
- }
32807
- function applyDotenv({ file, cwd = process.cwd(), env = process.env } = {}) {
32808
- const target = resolveEnvFile({ file, cwd });
32809
- if (!target) return null;
32810
- let stat;
32811
- try {
32812
- stat = fs3.statSync(target);
32813
- } catch (err) {
32814
- throw new SkillError("ENV_FILE_MISSING", `Cannot read env file (${err.code || "error"}).`);
32815
- }
32816
- if (process.platform !== "win32" && stat.mode & 63) {
32817
- const mode = (stat.mode & 511).toString(8).padStart(3, "0");
32818
- throw new SkillError(
32819
- "ENV_FILE_PERMISSIONS",
32820
- `That .env is readable by other users (mode ${mode}). Run: chmod 600 ${target}`
32821
- );
32822
- }
32823
- assertNotTrackedByGit(target);
32824
- const parsed = parseDotenv(fs3.readFileSync(target, "utf8"));
32825
- const allowed = filterAllowed(parsed);
32826
- const applied = [];
32827
- for (const [k, v] of Object.entries(allowed)) {
32828
- const existing = env[k];
32829
- if (existing !== void 0 && String(existing).trim() !== "") continue;
32830
- env[k] = v;
32831
- applied.push(k);
32832
- }
32833
- return {
32834
- path: target,
32835
- applied,
32836
- ignored: Object.keys(parsed).length - Object.keys(allowed).length
32837
- };
32852
+ return s.startsWith(home + path3.sep) ? `~${s.slice(home.length)}` : s;
32838
32853
  }
32839
32854
 
32840
32855
  // scripts/src/lib/passphrase.mjs
@@ -33400,7 +33415,7 @@ function assertNotBlacklisted(targets, blacklist) {
33400
33415
  // scripts/src/lib/state.mjs
33401
33416
  import fs5 from "node:fs";
33402
33417
  import path5 from "node:path";
33403
- import os2 from "node:os";
33418
+ import os3 from "node:os";
33404
33419
  import crypto4 from "node:crypto";
33405
33420
  var LOCK_STALE_MS = 6e4;
33406
33421
  var LOCK_WAIT_MS = 1e4;
@@ -33461,7 +33476,7 @@ function withLock(fn) {
33461
33476
  }
33462
33477
  }
33463
33478
  function stateRoot() {
33464
- return process.env.ROZO_CHECKOUT_STATE_DIR || path5.join(os2.homedir(), ".rozo-checkout", "state");
33479
+ return process.env.ROZO_CHECKOUT_STATE_DIR || path5.join(os3.homedir(), ".rozo-checkout", "state");
33465
33480
  }
33466
33481
  function statePath(rozoPaymentId) {
33467
33482
  if (!/^[A-Za-z0-9-]{8,64}$/.test(String(rozoPaymentId || ""))) {
@@ -35480,7 +35495,11 @@ async function main(argv) {
35480
35495
  const rozoPaymentId = assertRozoPaymentId(args["rozo-payment-id"] || args._[0]);
35481
35496
  assertNoTrackedDotEnv();
35482
35497
  const dotenv = applyDotenv({ file: args["env-file"] });
35483
- const plan = planKeySource({ family: "solana", keyfile: args.keyfile });
35498
+ const plan = planKeySource({
35499
+ family: "solana",
35500
+ keyfile: args.keyfile,
35501
+ searched: args["env-file"] ? null : envFileCandidates()
35502
+ });
35484
35503
  const loaded = await loadKeySource(plan, { family: "solana", askPassphrase: promptPassphrase });
35485
35504
  const secret = loaded.secretKey;
35486
35505
  const keypair = secret.length === 64 ? import_web36.Keypair.fromSecretKey(secret) : import_web36.Keypair.fromSeed(secret);