@rozoai/checkout 0.1.7 → 0.1.11
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 +61 -8
- package/docs/QUICKSTART.es.md +2 -0
- package/docs/QUICKSTART.ja.md +2 -0
- package/docs/QUICKSTART.md +2 -0
- package/docs/QUICKSTART.zh.md +2 -0
- package/docs/README.es.md +2 -0
- package/docs/README.ja.md +2 -0
- package/docs/README.zh.md +2 -0
- package/docs/review-history.md +77 -0
- package/docs/security-audit-notes.md +30 -0
- package/llms.txt +5 -3
- package/package.json +29 -9
- package/scripts/dist/cli.js +1426 -2931
- package/scripts/dist/create-order.js +19 -1
- package/scripts/dist/quote.js +16 -0
- package/scripts/dist/send-evm.js +231 -111
- package/scripts/dist/send-sol.js +1279 -2811
- package/scripts/dist/status.js +16 -0
|
@@ -153,6 +153,9 @@ function maskMemo(memo) {
|
|
|
153
153
|
return `${s.slice(0, 4)}...${s.slice(-3)}`;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// scripts/src/lib/api.mjs
|
|
157
|
+
import { createRequire } from "node:module";
|
|
158
|
+
|
|
156
159
|
// scripts/src/lib/http.mjs
|
|
157
160
|
var DEFAULT_TIMEOUT_MS = 2e4;
|
|
158
161
|
var USER_AGENT = "rozo-checkout-skill/1.0";
|
|
@@ -222,7 +225,20 @@ function postJson(url, body, opts) {
|
|
|
222
225
|
}
|
|
223
226
|
|
|
224
227
|
// scripts/src/lib/api.mjs
|
|
228
|
+
var PKG_VERSION = (() => {
|
|
229
|
+
const requireFrom = createRequire(import.meta.url);
|
|
230
|
+
for (const candidate of ["../../package.json", "../../../package.json"]) {
|
|
231
|
+
try {
|
|
232
|
+
const pkg = requireFrom(candidate);
|
|
233
|
+
if (pkg?.name === "@rozoai/checkout" && pkg.version) return pkg.version;
|
|
234
|
+
} catch {
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return "0.0.0";
|
|
238
|
+
})();
|
|
225
239
|
var MPP_BASE = process.env.ROZO_CHECKOUT_MPP_BASE || "https://apiserver.mpprouter.dev/v1/services/rozo-agent-api";
|
|
240
|
+
var CLIENT_LABEL = `rozo-checkout-cli/${PKG_VERSION}`;
|
|
241
|
+
var ATTRIBUTION_CLIENT = `rozo-checkout-skill/${PKG_VERSION}`;
|
|
226
242
|
var INTENTS_BASE = process.env.ROZO_CHECKOUT_INTENTS_BASE || "https://intentapiv4.rozo.ai/functions/v1/payment-api";
|
|
227
243
|
async function quoteInvoice({ url, linkId }) {
|
|
228
244
|
const body = url ? { url } : { payment_id: linkId };
|
|
@@ -232,7 +248,9 @@ async function createInvoice({ url, linkId, source, quoteReceipt }) {
|
|
|
232
248
|
const body = {
|
|
233
249
|
...url ? { url } : { payment_id: linkId },
|
|
234
250
|
source: { chainId: String(source.chainId), tokenSymbol: source.tokenSymbol },
|
|
235
|
-
...quoteReceipt ? { quoteReceipt } : {}
|
|
251
|
+
...quoteReceipt ? { quoteReceipt } : {},
|
|
252
|
+
client: CLIENT_LABEL,
|
|
253
|
+
attribution: { client: ATTRIBUTION_CLIENT }
|
|
236
254
|
};
|
|
237
255
|
return postJson(`${MPP_BASE}/create-invoice`, body);
|
|
238
256
|
}
|
package/scripts/dist/quote.js
CHANGED
|
@@ -133,6 +133,9 @@ function extractLinkId(urlOrId) {
|
|
|
133
133
|
);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
// scripts/src/lib/api.mjs
|
|
137
|
+
import { createRequire } from "node:module";
|
|
138
|
+
|
|
136
139
|
// scripts/src/lib/http.mjs
|
|
137
140
|
var DEFAULT_TIMEOUT_MS = 2e4;
|
|
138
141
|
var USER_AGENT = "rozo-checkout-skill/1.0";
|
|
@@ -199,7 +202,20 @@ function postJson(url, body, opts) {
|
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
// scripts/src/lib/api.mjs
|
|
205
|
+
var PKG_VERSION = (() => {
|
|
206
|
+
const requireFrom = createRequire(import.meta.url);
|
|
207
|
+
for (const candidate of ["../../package.json", "../../../package.json"]) {
|
|
208
|
+
try {
|
|
209
|
+
const pkg = requireFrom(candidate);
|
|
210
|
+
if (pkg?.name === "@rozoai/checkout" && pkg.version) return pkg.version;
|
|
211
|
+
} catch {
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return "0.0.0";
|
|
215
|
+
})();
|
|
202
216
|
var MPP_BASE = process.env.ROZO_CHECKOUT_MPP_BASE || "https://apiserver.mpprouter.dev/v1/services/rozo-agent-api";
|
|
217
|
+
var CLIENT_LABEL = `rozo-checkout-cli/${PKG_VERSION}`;
|
|
218
|
+
var ATTRIBUTION_CLIENT = `rozo-checkout-skill/${PKG_VERSION}`;
|
|
203
219
|
var INTENTS_BASE = process.env.ROZO_CHECKOUT_INTENTS_BASE || "https://intentapiv4.rozo.ai/functions/v1/payment-api";
|
|
204
220
|
async function quoteInvoice({ url, linkId }) {
|
|
205
221
|
const body = url ? { url } : { payment_id: linkId };
|
package/scripts/dist/send-evm.js
CHANGED
|
@@ -999,7 +999,7 @@ var init_size = __esm({
|
|
|
999
999
|
var version2;
|
|
1000
1000
|
var init_version2 = __esm({
|
|
1001
1001
|
"node_modules/viem/_esm/errors/version.js"() {
|
|
1002
|
-
version2 = "2.55.
|
|
1002
|
+
version2 = "2.55.13";
|
|
1003
1003
|
}
|
|
1004
1004
|
});
|
|
1005
1005
|
|
|
@@ -1759,10 +1759,10 @@ var init_u64 = __esm({
|
|
|
1759
1759
|
|
|
1760
1760
|
// node_modules/@noble/hashes/esm/cryptoNode.js
|
|
1761
1761
|
import * as nc from "node:crypto";
|
|
1762
|
-
var
|
|
1762
|
+
var crypto3;
|
|
1763
1763
|
var init_cryptoNode = __esm({
|
|
1764
1764
|
"node_modules/@noble/hashes/esm/cryptoNode.js"() {
|
|
1765
|
-
|
|
1765
|
+
crypto3 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
|
|
1766
1766
|
}
|
|
1767
1767
|
});
|
|
1768
1768
|
|
|
@@ -1857,11 +1857,11 @@ function createHasher(hashCons) {
|
|
|
1857
1857
|
return hashC;
|
|
1858
1858
|
}
|
|
1859
1859
|
function randomBytes(bytesLength = 32) {
|
|
1860
|
-
if (
|
|
1861
|
-
return
|
|
1860
|
+
if (crypto3 && typeof crypto3.getRandomValues === "function") {
|
|
1861
|
+
return crypto3.getRandomValues(new Uint8Array(bytesLength));
|
|
1862
1862
|
}
|
|
1863
|
-
if (
|
|
1864
|
-
return Uint8Array.from(
|
|
1863
|
+
if (crypto3 && typeof crypto3.randomBytes === "function") {
|
|
1864
|
+
return Uint8Array.from(crypto3.randomBytes(bytesLength));
|
|
1865
1865
|
}
|
|
1866
1866
|
throw new Error("crypto.getRandomValues must be defined");
|
|
1867
1867
|
}
|
|
@@ -10214,43 +10214,148 @@ function chainFamily(chainId) {
|
|
|
10214
10214
|
// scripts/src/lib/keys.mjs
|
|
10215
10215
|
import fs from "node:fs";
|
|
10216
10216
|
import path from "node:path";
|
|
10217
|
-
import
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10217
|
+
import crypto2 from "node:crypto";
|
|
10218
|
+
function findGitRepo(dir) {
|
|
10219
|
+
for (const v of ["GIT_DIR", "GIT_WORK_TREE", "GIT_INDEX_FILE"]) {
|
|
10220
|
+
if (process.env[v]) {
|
|
10221
|
+
throw new SkillError(
|
|
10222
|
+
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10223
|
+
`${v} is set, so the repository layout cannot be resolved by reading the filesystem alone. Unset it (or run from a plain checkout) before using hot-wallet keys.`
|
|
10224
|
+
);
|
|
10225
|
+
}
|
|
10226
|
+
}
|
|
10227
|
+
let cur = path.resolve(dir);
|
|
10228
|
+
for (; ; ) {
|
|
10229
|
+
const dotGit = path.join(cur, ".git");
|
|
10230
|
+
let st = null;
|
|
10231
|
+
try {
|
|
10232
|
+
st = fs.statSync(dotGit);
|
|
10233
|
+
} catch (err) {
|
|
10234
|
+
if (err?.code !== "ENOENT" && err?.code !== "ENOTDIR") {
|
|
10235
|
+
throw new SkillError(
|
|
10236
|
+
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10237
|
+
`A .git entry here could not be inspected (${err?.code || "error"}), so tracked status cannot be proved. Refusing.`
|
|
10238
|
+
);
|
|
10239
|
+
}
|
|
10240
|
+
st = null;
|
|
10241
|
+
}
|
|
10242
|
+
if (st) {
|
|
10243
|
+
if (st.isDirectory()) return { root: cur, gitDir: dotGit };
|
|
10244
|
+
let text;
|
|
10245
|
+
try {
|
|
10246
|
+
text = fs.readFileSync(dotGit, "utf8");
|
|
10247
|
+
} catch {
|
|
10248
|
+
throw new SkillError(
|
|
10249
|
+
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10250
|
+
"A .git entry exists here but could not be read, so tracked status cannot be proved. Refusing."
|
|
10251
|
+
);
|
|
10252
|
+
}
|
|
10253
|
+
const m = /^gitdir:\s*(.+)\s*$/m.exec(text);
|
|
10254
|
+
if (!m) {
|
|
10255
|
+
throw new SkillError(
|
|
10256
|
+
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10257
|
+
"A .git file exists here but is not a recognised gitdir pointer. Refusing."
|
|
10258
|
+
);
|
|
10259
|
+
}
|
|
10260
|
+
return { root: cur, gitDir: path.resolve(cur, m[1]) };
|
|
10261
|
+
}
|
|
10262
|
+
const parent = path.dirname(cur);
|
|
10263
|
+
if (parent === cur) return null;
|
|
10264
|
+
cur = parent;
|
|
10265
|
+
}
|
|
10266
|
+
}
|
|
10267
|
+
function trackedPathsFromIndex(buf, { hashLen = 20 } = {}) {
|
|
10268
|
+
const fail2 = (why) => new SkillError(
|
|
10269
|
+
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10270
|
+
`The git index could not be interpreted (${why}), so tracked status cannot be proved. Refusing.`
|
|
10271
|
+
);
|
|
10272
|
+
if (buf.length < 12 + hashLen || buf.toString("latin1", 0, 4) !== "DIRC") throw fail2("bad header");
|
|
10273
|
+
const algo = hashLen === 32 ? "sha256" : "sha1";
|
|
10274
|
+
const expected = buf.subarray(buf.length - hashLen);
|
|
10275
|
+
const actual = crypto2.createHash(algo).update(buf.subarray(0, buf.length - hashLen)).digest();
|
|
10276
|
+
if (!actual.equals(expected)) throw fail2(`${algo} checksum mismatch`);
|
|
10277
|
+
const version4 = buf.readUInt32BE(4);
|
|
10278
|
+
if (version4 !== 2 && version4 !== 3) throw fail2(`unsupported index version ${version4}`);
|
|
10279
|
+
const count = buf.readUInt32BE(8);
|
|
10280
|
+
const paths = /* @__PURE__ */ new Set();
|
|
10281
|
+
const fixed = 40 + hashLen + 2;
|
|
10282
|
+
let off = 12;
|
|
10283
|
+
for (let i = 0; i < count; i++) {
|
|
10284
|
+
const entryStart = off;
|
|
10285
|
+
if (off + fixed > buf.length - hashLen) throw fail2("truncated entry");
|
|
10286
|
+
const flags = buf.readUInt16BE(off + fixed - 2);
|
|
10287
|
+
let nameOff = off + fixed;
|
|
10288
|
+
if (flags & 16384) {
|
|
10289
|
+
if (version4 < 3) throw fail2("extended flags in v2 index");
|
|
10290
|
+
nameOff += 2;
|
|
10291
|
+
}
|
|
10292
|
+
const nameLen = flags & 4095;
|
|
10293
|
+
let end;
|
|
10294
|
+
if (nameLen < 4095) {
|
|
10295
|
+
end = nameOff + nameLen;
|
|
10296
|
+
if (end > buf.length - hashLen) throw fail2("truncated path");
|
|
10297
|
+
} else {
|
|
10298
|
+
end = buf.indexOf(0, nameOff);
|
|
10299
|
+
if (end === -1 || end > buf.length - hashLen) throw fail2("unterminated path");
|
|
10300
|
+
}
|
|
10301
|
+
paths.add(buf.toString("utf8", nameOff, end));
|
|
10302
|
+
const entryLen = end - entryStart;
|
|
10303
|
+
off = entryStart + (Math.floor(entryLen / 8) + 1) * 8;
|
|
10304
|
+
}
|
|
10305
|
+
while (off < buf.length - hashLen) {
|
|
10306
|
+
if (off + 8 > buf.length - hashLen) throw fail2("truncated extension header");
|
|
10307
|
+
const extName = buf.toString("latin1", off, off + 4);
|
|
10308
|
+
const extSize = buf.readUInt32BE(off + 4);
|
|
10309
|
+
const first = extName.charCodeAt(0);
|
|
10310
|
+
if (first >= 97 && first <= 122) {
|
|
10311
|
+
throw fail2(`mandatory index extension "${extName}" (e.g. core.splitIndex) is not supported`);
|
|
10312
|
+
}
|
|
10313
|
+
off += 8 + extSize;
|
|
10314
|
+
if (off > buf.length - hashLen) throw fail2("truncated extension");
|
|
10315
|
+
}
|
|
10316
|
+
return paths;
|
|
10317
|
+
}
|
|
10318
|
+
function repoHashLen(gitDir) {
|
|
10319
|
+
let configDir = gitDir;
|
|
10221
10320
|
try {
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10321
|
+
const common = fs.readFileSync(path.join(gitDir, "commondir"), "utf8").trim();
|
|
10322
|
+
if (common) configDir = path.resolve(gitDir, common);
|
|
10323
|
+
} catch {
|
|
10324
|
+
}
|
|
10325
|
+
try {
|
|
10326
|
+
const cfg = fs.readFileSync(path.join(configDir, "config"), "utf8");
|
|
10327
|
+
if (/^\s*objectformat\s*=\s*sha256\s*$/im.test(cfg)) return 32;
|
|
10328
|
+
} catch {
|
|
10329
|
+
}
|
|
10330
|
+
return 20;
|
|
10331
|
+
}
|
|
10332
|
+
function trackedAmong(repo, files) {
|
|
10333
|
+
const indexPath = path.join(repo.gitDir, "index");
|
|
10334
|
+
let buf;
|
|
10335
|
+
try {
|
|
10336
|
+
buf = fs.readFileSync(indexPath);
|
|
10227
10337
|
} catch (err) {
|
|
10228
|
-
|
|
10229
|
-
if (/not a git repository|does not appear to be a git repository/i.test(stderr)) return false;
|
|
10338
|
+
if (err?.code === "ENOENT") return [];
|
|
10230
10339
|
throw new SkillError(
|
|
10231
10340
|
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10232
|
-
|
|
10341
|
+
"The git index exists but could not be read, so tracked status cannot be proved. Refusing."
|
|
10233
10342
|
);
|
|
10234
10343
|
}
|
|
10344
|
+
const tracked = trackedPathsFromIndex(buf, { hashLen: repoHashLen(repo.gitDir) });
|
|
10345
|
+
return files.filter((f) => {
|
|
10346
|
+
const rel = path.relative(repo.root, path.resolve(f)).split(path.sep).join("/");
|
|
10347
|
+
return tracked.has(rel);
|
|
10348
|
+
});
|
|
10235
10349
|
}
|
|
10350
|
+
var ENV_FILE_RE = /^\.env(\..+)?$/;
|
|
10351
|
+
var PUBLIC_ENV_RE = /^\.env\.(example|sample|template)$/;
|
|
10236
10352
|
function assertNotTrackedByGit(file) {
|
|
10237
10353
|
const dir = path.dirname(path.resolve(file));
|
|
10238
|
-
const
|
|
10239
|
-
if (!
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10243
|
-
cwd: dir,
|
|
10244
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
10245
|
-
encoding: "utf8"
|
|
10246
|
-
});
|
|
10247
|
-
} catch {
|
|
10248
|
-
throw new SkillError(
|
|
10249
|
-
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10250
|
-
"git could not report whether this key file is tracked. Refusing to use it."
|
|
10251
|
-
);
|
|
10252
|
-
}
|
|
10253
|
-
if (out.split("\0").filter(Boolean).length) {
|
|
10354
|
+
const repo = findGitRepo(dir);
|
|
10355
|
+
if (!repo) return { checked: true, tracked: false };
|
|
10356
|
+
const hits = trackedAmong(repo, [file]);
|
|
10357
|
+
if (hits.length) {
|
|
10358
|
+
const base = path.basename(file);
|
|
10254
10359
|
throw new SkillError(
|
|
10255
10360
|
"TRACKED_KEYFILE",
|
|
10256
10361
|
`${base} is tracked by git. A committed key is one push from being public \u2014 untrack it (git rm --cached ${base}) and gitignore it before using it to sign.`
|
|
@@ -10269,37 +10374,11 @@ function assertNoTrackedDotEnv(cwd = process.cwd()) {
|
|
|
10269
10374
|
);
|
|
10270
10375
|
}
|
|
10271
10376
|
if (candidates.length === 0) return { checked: true, tracked: false, candidates: [] };
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
encoding: "utf8"
|
|
10278
|
-
}).trim() === "true";
|
|
10279
|
-
} catch (err) {
|
|
10280
|
-
const stderr = String(err?.stderr || "");
|
|
10281
|
-
const notARepo = /not a git repository|does not appear to be a git repository/i.test(stderr);
|
|
10282
|
-
if (notARepo) return { checked: true, tracked: false, candidates };
|
|
10283
|
-
throw new SkillError(
|
|
10284
|
-
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10285
|
-
`Found ${candidates.length} .env file(s) here, but git could not be consulted (${err?.code || "unknown error"}), so it cannot be proved they are untracked. Refusing to use hot-wallet keys in this directory.`
|
|
10286
|
-
);
|
|
10287
|
-
}
|
|
10288
|
-
if (!insideRepo) return { checked: true, tracked: false, candidates };
|
|
10289
|
-
let out;
|
|
10290
|
-
try {
|
|
10291
|
-
out = execFileSync("git", ["ls-files", "-z", "--", ...candidates], {
|
|
10292
|
-
cwd,
|
|
10293
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
10294
|
-
encoding: "utf8"
|
|
10295
|
-
});
|
|
10296
|
-
} catch {
|
|
10297
|
-
throw new SkillError(
|
|
10298
|
-
"TRACKED_DOTENV_UNVERIFIABLE",
|
|
10299
|
-
"git could not report whether the .env file(s) in this directory are tracked. Refusing to use hot-wallet keys rather than assuming they are safe."
|
|
10300
|
-
);
|
|
10301
|
-
}
|
|
10302
|
-
const tracked = out.split("\0").filter(Boolean);
|
|
10377
|
+
const repo = findGitRepo(cwd);
|
|
10378
|
+
if (!repo) return { checked: true, tracked: false, candidates };
|
|
10379
|
+
const tracked = trackedAmong(repo, candidates.map((f) => path.join(cwd, f))).map(
|
|
10380
|
+
(f) => path.basename(f)
|
|
10381
|
+
);
|
|
10303
10382
|
if (tracked.length) {
|
|
10304
10383
|
throw new SkillError(
|
|
10305
10384
|
"TRACKED_DOTENV",
|
|
@@ -10313,7 +10392,7 @@ function assertNoTrackedDotEnv(cwd = process.cwd()) {
|
|
|
10313
10392
|
import fs3 from "node:fs";
|
|
10314
10393
|
import path3 from "node:path";
|
|
10315
10394
|
import os2 from "node:os";
|
|
10316
|
-
import
|
|
10395
|
+
import crypto4 from "node:crypto";
|
|
10317
10396
|
|
|
10318
10397
|
// node_modules/viem/_esm/utils/getAction.js
|
|
10319
10398
|
function getAction(client, actionFn, name) {
|
|
@@ -11375,14 +11454,6 @@ async function prepareTransactionRequest(client, args) {
|
|
|
11375
11454
|
}
|
|
11376
11455
|
let account = account_ ? parseAccount(account_) : account_;
|
|
11377
11456
|
let nonce = request2.nonce;
|
|
11378
|
-
if (parameters.includes("nonce") && typeof nonce === "undefined" && account && nonceManager) {
|
|
11379
|
-
const chainId2 = await getChainId2();
|
|
11380
|
-
nonce = await nonceManager.consume({
|
|
11381
|
-
address: account.address,
|
|
11382
|
-
chainId: chainId2,
|
|
11383
|
-
client
|
|
11384
|
-
});
|
|
11385
|
-
}
|
|
11386
11457
|
if (prepareTransactionRequest2?.fn && prepareTransactionRequest2.runAt?.includes("beforeFillTransaction")) {
|
|
11387
11458
|
request2 = await prepareTransactionRequest2.fn({ ...request2, chain }, {
|
|
11388
11459
|
client,
|
|
@@ -11392,13 +11463,21 @@ async function prepareTransactionRequest(client, args) {
|
|
|
11392
11463
|
const sender = request2.account ?? request2.from;
|
|
11393
11464
|
account = sender ? parseAccount(sender) : void 0;
|
|
11394
11465
|
}
|
|
11466
|
+
if (parameters.includes("nonce") && typeof nonce === "undefined" && account && nonceManager) {
|
|
11467
|
+
const chainId2 = await getChainId2();
|
|
11468
|
+
nonce = await nonceManager.consume({
|
|
11469
|
+
address: account.address,
|
|
11470
|
+
chainId: chainId2,
|
|
11471
|
+
client
|
|
11472
|
+
});
|
|
11473
|
+
}
|
|
11395
11474
|
const attemptFill = (() => {
|
|
11396
11475
|
if ((parameters.includes("blobVersionedHashes") || parameters.includes("sidecars")) && request2.kzg && request2.blobs)
|
|
11397
11476
|
return false;
|
|
11398
|
-
if (supportsFillTransaction.get(client.uid) === false)
|
|
11399
|
-
return false;
|
|
11400
11477
|
if (parameters.length > 0 && "feePayer" in request2 && request2.feePayer && !("feePayerSignature" in request2 && request2.feePayerSignature))
|
|
11401
11478
|
return true;
|
|
11479
|
+
if (supportsFillTransaction.get(client.uid) === false)
|
|
11480
|
+
return false;
|
|
11402
11481
|
const shouldAttempt = ["fees", "gas"].some((parameter) => parameters.includes(parameter));
|
|
11403
11482
|
if (!shouldAttempt)
|
|
11404
11483
|
return false;
|
|
@@ -12530,17 +12609,29 @@ async function sendTransaction(client, parameters) {
|
|
|
12530
12609
|
}
|
|
12531
12610
|
}
|
|
12532
12611
|
if (account?.type === "local") {
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12612
|
+
const nonceManager = (() => {
|
|
12613
|
+
if (!account.nonceManager || typeof nonce !== "undefined")
|
|
12614
|
+
return account.nonceManager;
|
|
12615
|
+
const nonceManager2 = account.nonceManager;
|
|
12616
|
+
return {
|
|
12617
|
+
consume(parameters2) {
|
|
12618
|
+
nonceManagerParameters = {
|
|
12619
|
+
address: parameters2.address,
|
|
12620
|
+
chainId: parameters2.chainId
|
|
12621
|
+
};
|
|
12622
|
+
return nonceManager2.consume(parameters2);
|
|
12623
|
+
},
|
|
12624
|
+
get(parameters2) {
|
|
12625
|
+
return nonceManager2.get(parameters2);
|
|
12626
|
+
},
|
|
12627
|
+
increment(parameters2) {
|
|
12628
|
+
return nonceManager2.increment(parameters2);
|
|
12629
|
+
},
|
|
12630
|
+
reset(parameters2) {
|
|
12631
|
+
return nonceManager2.reset(parameters2);
|
|
12632
|
+
}
|
|
12633
|
+
};
|
|
12634
|
+
})();
|
|
12544
12635
|
const request2 = await getAction(client, prepareTransactionRequest, "prepareTransactionRequest")({
|
|
12545
12636
|
account,
|
|
12546
12637
|
accessList,
|
|
@@ -12554,7 +12645,7 @@ async function sendTransaction(client, parameters) {
|
|
|
12554
12645
|
maxFeePerGas,
|
|
12555
12646
|
maxPriorityFeePerGas,
|
|
12556
12647
|
nonce,
|
|
12557
|
-
nonceManager
|
|
12648
|
+
nonceManager,
|
|
12558
12649
|
parameters: [...defaultParameters, "sidecars"],
|
|
12559
12650
|
type,
|
|
12560
12651
|
value,
|
|
@@ -13059,6 +13150,7 @@ function bindActionDecorators(client, action) {
|
|
|
13059
13150
|
"estimateGas",
|
|
13060
13151
|
"prepare",
|
|
13061
13152
|
"prepareRecipient",
|
|
13153
|
+
"predict",
|
|
13062
13154
|
"simulate"
|
|
13063
13155
|
])
|
|
13064
13156
|
if (Object.hasOwn(action, key)) {
|
|
@@ -20454,17 +20546,29 @@ async function sendTransactionSync(client, parameters) {
|
|
|
20454
20546
|
return receipt;
|
|
20455
20547
|
}
|
|
20456
20548
|
if (account?.type === "local") {
|
|
20457
|
-
|
|
20458
|
-
|
|
20459
|
-
|
|
20460
|
-
|
|
20461
|
-
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20549
|
+
const nonceManager = (() => {
|
|
20550
|
+
if (!account.nonceManager || typeof nonce !== "undefined")
|
|
20551
|
+
return account.nonceManager;
|
|
20552
|
+
const nonceManager2 = account.nonceManager;
|
|
20553
|
+
return {
|
|
20554
|
+
consume(parameters2) {
|
|
20555
|
+
nonceManagerParameters = {
|
|
20556
|
+
address: parameters2.address,
|
|
20557
|
+
chainId: parameters2.chainId
|
|
20558
|
+
};
|
|
20559
|
+
return nonceManager2.consume(parameters2);
|
|
20560
|
+
},
|
|
20561
|
+
get(parameters2) {
|
|
20562
|
+
return nonceManager2.get(parameters2);
|
|
20563
|
+
},
|
|
20564
|
+
increment(parameters2) {
|
|
20565
|
+
return nonceManager2.increment(parameters2);
|
|
20566
|
+
},
|
|
20567
|
+
reset(parameters2) {
|
|
20568
|
+
return nonceManager2.reset(parameters2);
|
|
20569
|
+
}
|
|
20570
|
+
};
|
|
20571
|
+
})();
|
|
20468
20572
|
const request2 = await getAction(client, prepareTransactionRequest, "prepareTransactionRequest")({
|
|
20469
20573
|
account,
|
|
20470
20574
|
accessList,
|
|
@@ -20478,7 +20582,7 @@ async function sendTransactionSync(client, parameters) {
|
|
|
20478
20582
|
maxFeePerGas,
|
|
20479
20583
|
maxPriorityFeePerGas,
|
|
20480
20584
|
nonce,
|
|
20481
|
-
nonceManager
|
|
20585
|
+
nonceManager,
|
|
20482
20586
|
parameters: [...defaultParameters, "sidecars"],
|
|
20483
20587
|
type,
|
|
20484
20588
|
value,
|
|
@@ -21504,7 +21608,7 @@ function decryptKeystoreV3(keystore, passphrase) {
|
|
|
21504
21608
|
if (!n || !r || !p || !dklen || !salt) {
|
|
21505
21609
|
throw new SkillError("BAD_KEYSTORE", "The keystore scrypt parameters are incomplete.");
|
|
21506
21610
|
}
|
|
21507
|
-
derived =
|
|
21611
|
+
derived = crypto4.scryptSync(pass, Buffer.from(salt, "hex"), dklen, {
|
|
21508
21612
|
N: n,
|
|
21509
21613
|
r,
|
|
21510
21614
|
p,
|
|
@@ -21520,7 +21624,7 @@ function decryptKeystoreV3(keystore, passphrase) {
|
|
|
21520
21624
|
if (!iterations || !dklen || !salt) {
|
|
21521
21625
|
throw new SkillError("BAD_KEYSTORE", "The keystore pbkdf2 parameters are incomplete.");
|
|
21522
21626
|
}
|
|
21523
|
-
derived =
|
|
21627
|
+
derived = crypto4.pbkdf2Sync(pass, Buffer.from(salt, "hex"), iterations, dklen, "sha256");
|
|
21524
21628
|
} else {
|
|
21525
21629
|
throw new SkillError("BAD_KEYSTORE", `Unsupported keystore KDF "${c.kdf}".`);
|
|
21526
21630
|
}
|
|
@@ -21535,7 +21639,7 @@ function decryptKeystoreV3(keystore, passphrase) {
|
|
|
21535
21639
|
if (c.cipher !== "aes-128-ctr") {
|
|
21536
21640
|
throw new SkillError("BAD_KEYSTORE", `Unsupported keystore cipher "${c.cipher}".`);
|
|
21537
21641
|
}
|
|
21538
|
-
const decipher =
|
|
21642
|
+
const decipher = crypto4.createDecipheriv(
|
|
21539
21643
|
"aes-128-ctr",
|
|
21540
21644
|
derived.subarray(0, 16),
|
|
21541
21645
|
Buffer.from(c.cipherparams.iv, "hex")
|
|
@@ -21557,7 +21661,7 @@ function timingSafeEqualHex(a, b) {
|
|
|
21557
21661
|
const ab = Buffer.from(String(a).toLowerCase(), "hex");
|
|
21558
21662
|
const bb = Buffer.from(String(b).toLowerCase(), "hex");
|
|
21559
21663
|
if (ab.length === 0 || ab.length !== bb.length) return false;
|
|
21560
|
-
return
|
|
21664
|
+
return crypto4.timingSafeEqual(ab, bb);
|
|
21561
21665
|
}
|
|
21562
21666
|
function looksLikeKeystore(text) {
|
|
21563
21667
|
const t = String(text).trimStart();
|
|
@@ -21713,6 +21817,9 @@ function promptPassphrase(prompt = " Keystore passphrase: ") {
|
|
|
21713
21817
|
});
|
|
21714
21818
|
}
|
|
21715
21819
|
|
|
21820
|
+
// scripts/src/lib/api.mjs
|
|
21821
|
+
import { createRequire } from "node:module";
|
|
21822
|
+
|
|
21716
21823
|
// scripts/src/lib/http.mjs
|
|
21717
21824
|
var DEFAULT_TIMEOUT_MS = 2e4;
|
|
21718
21825
|
var USER_AGENT = "rozo-checkout-skill/1.0";
|
|
@@ -21779,7 +21886,20 @@ function getJson(url, opts) {
|
|
|
21779
21886
|
}
|
|
21780
21887
|
|
|
21781
21888
|
// scripts/src/lib/api.mjs
|
|
21889
|
+
var PKG_VERSION = (() => {
|
|
21890
|
+
const requireFrom = createRequire(import.meta.url);
|
|
21891
|
+
for (const candidate of ["../../package.json", "../../../package.json"]) {
|
|
21892
|
+
try {
|
|
21893
|
+
const pkg = requireFrom(candidate);
|
|
21894
|
+
if (pkg?.name === "@rozoai/checkout" && pkg.version) return pkg.version;
|
|
21895
|
+
} catch {
|
|
21896
|
+
}
|
|
21897
|
+
}
|
|
21898
|
+
return "0.0.0";
|
|
21899
|
+
})();
|
|
21782
21900
|
var MPP_BASE = process.env.ROZO_CHECKOUT_MPP_BASE || "https://apiserver.mpprouter.dev/v1/services/rozo-agent-api";
|
|
21901
|
+
var CLIENT_LABEL = `rozo-checkout-cli/${PKG_VERSION}`;
|
|
21902
|
+
var ATTRIBUTION_CLIENT = `rozo-checkout-skill/${PKG_VERSION}`;
|
|
21783
21903
|
var INTENTS_BASE = process.env.ROZO_CHECKOUT_INTENTS_BASE || "https://intentapiv4.rozo.ai/functions/v1/payment-api";
|
|
21784
21904
|
async function invoiceStatus({ linkId, rozoPaymentId }) {
|
|
21785
21905
|
const qs = new URLSearchParams();
|
|
@@ -22107,7 +22227,7 @@ function checkExpiry({
|
|
|
22107
22227
|
// scripts/src/lib/blacklist.mjs
|
|
22108
22228
|
import fs4 from "node:fs";
|
|
22109
22229
|
import path4 from "node:path";
|
|
22110
|
-
import
|
|
22230
|
+
import crypto5 from "node:crypto";
|
|
22111
22231
|
import { fileURLToPath } from "node:url";
|
|
22112
22232
|
var BlacklistError = class extends Error {
|
|
22113
22233
|
constructor(code, message) {
|
|
@@ -22142,7 +22262,7 @@ function parseBlacklist(doc) {
|
|
|
22142
22262
|
}
|
|
22143
22263
|
addresses.push(e.address);
|
|
22144
22264
|
}
|
|
22145
|
-
const digest =
|
|
22265
|
+
const digest = crypto5.createHash("sha256").update(JSON.stringify(addresses), "utf8").digest("hex");
|
|
22146
22266
|
if (typeof provenance.addressesSha256 !== "string" || !provenance.addressesSha256) {
|
|
22147
22267
|
throw new BlacklistError("BLACKLIST_UNAVAILABLE", "Blacklist provenance digest is missing.");
|
|
22148
22268
|
}
|
|
@@ -22231,7 +22351,7 @@ function assertNotBlacklisted(targets, blacklist) {
|
|
|
22231
22351
|
import fs5 from "node:fs";
|
|
22232
22352
|
import path5 from "node:path";
|
|
22233
22353
|
import os3 from "node:os";
|
|
22234
|
-
import
|
|
22354
|
+
import crypto6 from "node:crypto";
|
|
22235
22355
|
var LOCK_STALE_MS = 6e4;
|
|
22236
22356
|
var LOCK_WAIT_MS = 1e4;
|
|
22237
22357
|
var LOCK_POLL_MS = 25;
|
|
@@ -22261,7 +22381,7 @@ function withLock(fn) {
|
|
|
22261
22381
|
try {
|
|
22262
22382
|
const age = Date.now() - fs5.statSync(file).mtimeMs;
|
|
22263
22383
|
if (age > LOCK_STALE_MS) {
|
|
22264
|
-
const stolen = `${file}.stale.${
|
|
22384
|
+
const stolen = `${file}.stale.${crypto6.randomBytes(4).toString("hex")}`;
|
|
22265
22385
|
try {
|
|
22266
22386
|
fs5.renameSync(file, stolen);
|
|
22267
22387
|
fs5.unlinkSync(stolen);
|
|
@@ -22302,7 +22422,7 @@ function statePath(rozoPaymentId) {
|
|
|
22302
22422
|
function writeAtomic(file, data) {
|
|
22303
22423
|
const dir = path5.dirname(file);
|
|
22304
22424
|
fs5.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
22305
|
-
const tmp = path5.join(dir, `.${path5.basename(file)}.${
|
|
22425
|
+
const tmp = path5.join(dir, `.${path5.basename(file)}.${crypto6.randomBytes(6).toString("hex")}.tmp`);
|
|
22306
22426
|
const fd = fs5.openSync(tmp, "wx", 384);
|
|
22307
22427
|
try {
|
|
22308
22428
|
fs5.writeFileSync(fd, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
@@ -22341,7 +22461,7 @@ function depositDigest(source) {
|
|
|
22341
22461
|
amountUnit: source?.amountUnit ?? null,
|
|
22342
22462
|
lnInvoice: source?.lnInvoice ?? null
|
|
22343
22463
|
});
|
|
22344
|
-
return
|
|
22464
|
+
return crypto6.createHash("sha256").update(canonical, "utf8").digest("hex");
|
|
22345
22465
|
}
|
|
22346
22466
|
function claimSend(rozoPaymentId, intent, { skipCaps = false } = {}) {
|
|
22347
22467
|
return withLock(() => {
|