@rozoai/checkout 0.1.10 → 0.1.12

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.
@@ -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";
@@ -190,7 +193,7 @@ async function request(method, url, { body, timeoutMs = DEFAULT_TIMEOUT_MS } = {
190
193
  }
191
194
  }
192
195
  if (!res.ok) {
193
- const code = json?.code || json?.error?.code || (typeof json?.error === "string" ? null : null) || `HTTP_${res.status}`;
196
+ const code = json?.code || json?.error?.code || (typeof json?.error === "string" && /^[A-Z][A-Z0-9_]+$/.test(json.error) ? json.error : null) || `HTTP_${res.status}`;
194
197
  const message = json?.message || (typeof json?.error === "string" ? json.error : json?.error?.message) || `HTTP ${res.status}`;
195
198
  throw new SkillError(code, redact(String(message)), {
196
199
  httpStatus: res.status,
@@ -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
  }
@@ -1040,12 +1058,23 @@ function readState(rozoPaymentId) {
1040
1058
  function createOrderRecord(record) {
1041
1059
  return withLock(() => createOrderRecordUnlocked(record));
1042
1060
  }
1061
+ function mergeBitrefill(prev, next) {
1062
+ if (!next) return prev ?? null;
1063
+ if (!prev?.expiresAt || !next.expiresAt) return { ...next, expiresAt: next.expiresAt ?? prev?.expiresAt ?? null };
1064
+ const a = Date.parse(prev.expiresAt);
1065
+ const b = Date.parse(next.expiresAt);
1066
+ return { ...next, expiresAt: Number.isFinite(a) && (!Number.isFinite(b) || a < b) ? prev.expiresAt : next.expiresAt };
1067
+ }
1043
1068
  function createOrderRecordUnlocked(record) {
1044
1069
  const { rozoPaymentId } = record;
1045
1070
  const existing = readState(rozoPaymentId);
1046
1071
  const next = {
1047
1072
  version: 1,
1048
1073
  rozoPaymentId,
1074
+ // 'coinbase' (default, historical records) or 'bitrefill'. Drives which
1075
+ // payability checks presend and status run.
1076
+ provider: record.provider ?? existing?.provider ?? "coinbase",
1077
+ bitrefill: mergeBitrefill(existing?.bitrefill, record.bitrefill),
1049
1078
  linkId: record.linkId,
1050
1079
  paymentLink: record.paymentLink ?? null,
1051
1080
  merchant: record.merchant ?? null,
@@ -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";
@@ -170,7 +173,7 @@ async function request(method, url, { body, timeoutMs = DEFAULT_TIMEOUT_MS } = {
170
173
  }
171
174
  }
172
175
  if (!res.ok) {
173
- const code = json?.code || json?.error?.code || (typeof json?.error === "string" ? null : null) || `HTTP_${res.status}`;
176
+ const code = json?.code || json?.error?.code || (typeof json?.error === "string" && /^[A-Z][A-Z0-9_]+$/.test(json.error) ? json.error : null) || `HTTP_${res.status}`;
174
177
  const message = json?.message || (typeof json?.error === "string" ? json.error : json?.error?.message) || `HTTP ${res.status}`;
175
178
  throw new SkillError(code, redact(String(message)), {
176
179
  httpStatus: res.status,
@@ -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 };
@@ -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.11";
1002
+ version2 = "2.55.13";
1003
1003
  }
1004
1004
  });
1005
1005
 
@@ -11454,14 +11454,6 @@ async function prepareTransactionRequest(client, args) {
11454
11454
  }
11455
11455
  let account = account_ ? parseAccount(account_) : account_;
11456
11456
  let nonce = request2.nonce;
11457
- if (parameters.includes("nonce") && typeof nonce === "undefined" && account && nonceManager) {
11458
- const chainId2 = await getChainId2();
11459
- nonce = await nonceManager.consume({
11460
- address: account.address,
11461
- chainId: chainId2,
11462
- client
11463
- });
11464
- }
11465
11457
  if (prepareTransactionRequest2?.fn && prepareTransactionRequest2.runAt?.includes("beforeFillTransaction")) {
11466
11458
  request2 = await prepareTransactionRequest2.fn({ ...request2, chain }, {
11467
11459
  client,
@@ -11471,13 +11463,21 @@ async function prepareTransactionRequest(client, args) {
11471
11463
  const sender = request2.account ?? request2.from;
11472
11464
  account = sender ? parseAccount(sender) : void 0;
11473
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
+ }
11474
11474
  const attemptFill = (() => {
11475
11475
  if ((parameters.includes("blobVersionedHashes") || parameters.includes("sidecars")) && request2.kzg && request2.blobs)
11476
11476
  return false;
11477
- if (supportsFillTransaction.get(client.uid) === false)
11478
- return false;
11479
11477
  if (parameters.length > 0 && "feePayer" in request2 && request2.feePayer && !("feePayerSignature" in request2 && request2.feePayerSignature))
11480
11478
  return true;
11479
+ if (supportsFillTransaction.get(client.uid) === false)
11480
+ return false;
11481
11481
  const shouldAttempt = ["fees", "gas"].some((parameter) => parameters.includes(parameter));
11482
11482
  if (!shouldAttempt)
11483
11483
  return false;
@@ -12609,17 +12609,29 @@ async function sendTransaction(client, parameters) {
12609
12609
  }
12610
12610
  }
12611
12611
  if (account?.type === "local") {
12612
- if (account.nonceManager && typeof nonce === "undefined") {
12613
- const requestChainId = rest.chainId;
12614
- const chainId = await (async () => {
12615
- if (typeof requestChainId === "number")
12616
- return requestChainId;
12617
- if (chain)
12618
- return chain.id;
12619
- return getAction(client, getChainId, "getChainId")({});
12620
- })();
12621
- nonceManagerParameters = { address: account.address, chainId };
12622
- }
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
+ })();
12623
12635
  const request2 = await getAction(client, prepareTransactionRequest, "prepareTransactionRequest")({
12624
12636
  account,
12625
12637
  accessList,
@@ -12633,7 +12645,7 @@ async function sendTransaction(client, parameters) {
12633
12645
  maxFeePerGas,
12634
12646
  maxPriorityFeePerGas,
12635
12647
  nonce,
12636
- nonceManager: account.nonceManager,
12648
+ nonceManager,
12637
12649
  parameters: [...defaultParameters, "sidecars"],
12638
12650
  type,
12639
12651
  value,
@@ -13138,6 +13150,7 @@ function bindActionDecorators(client, action) {
13138
13150
  "estimateGas",
13139
13151
  "prepare",
13140
13152
  "prepareRecipient",
13153
+ "predict",
13141
13154
  "simulate"
13142
13155
  ])
13143
13156
  if (Object.hasOwn(action, key)) {
@@ -20533,17 +20546,29 @@ async function sendTransactionSync(client, parameters) {
20533
20546
  return receipt;
20534
20547
  }
20535
20548
  if (account?.type === "local") {
20536
- if (account.nonceManager && typeof nonce === "undefined") {
20537
- const requestChainId = rest.chainId;
20538
- const chainId = await (async () => {
20539
- if (typeof requestChainId === "number")
20540
- return requestChainId;
20541
- if (chain)
20542
- return chain.id;
20543
- return getAction(client, getChainId, "getChainId")({});
20544
- })();
20545
- nonceManagerParameters = { address: account.address, chainId };
20546
- }
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
+ })();
20547
20572
  const request2 = await getAction(client, prepareTransactionRequest, "prepareTransactionRequest")({
20548
20573
  account,
20549
20574
  accessList,
@@ -20557,7 +20582,7 @@ async function sendTransactionSync(client, parameters) {
20557
20582
  maxFeePerGas,
20558
20583
  maxPriorityFeePerGas,
20559
20584
  nonce,
20560
- nonceManager: account.nonceManager,
20585
+ nonceManager,
20561
20586
  parameters: [...defaultParameters, "sidecars"],
20562
20587
  type,
20563
20588
  value,
@@ -21792,6 +21817,9 @@ function promptPassphrase(prompt = " Keystore passphrase: ") {
21792
21817
  });
21793
21818
  }
21794
21819
 
21820
+ // scripts/src/lib/api.mjs
21821
+ import { createRequire } from "node:module";
21822
+
21795
21823
  // scripts/src/lib/http.mjs
21796
21824
  var DEFAULT_TIMEOUT_MS = 2e4;
21797
21825
  var USER_AGENT = "rozo-checkout-skill/1.0";
@@ -21829,7 +21857,7 @@ async function request(method, url, { body, timeoutMs = DEFAULT_TIMEOUT_MS } = {
21829
21857
  }
21830
21858
  }
21831
21859
  if (!res.ok) {
21832
- const code = json?.code || json?.error?.code || (typeof json?.error === "string" ? null : null) || `HTTP_${res.status}`;
21860
+ const code = json?.code || json?.error?.code || (typeof json?.error === "string" && /^[A-Z][A-Z0-9_]+$/.test(json.error) ? json.error : null) || `HTTP_${res.status}`;
21833
21861
  const message = json?.message || (typeof json?.error === "string" ? json.error : json?.error?.message) || `HTTP ${res.status}`;
21834
21862
  throw new SkillError(code, redact(String(message)), {
21835
21863
  httpStatus: res.status,
@@ -21858,7 +21886,20 @@ function getJson(url, opts) {
21858
21886
  }
21859
21887
 
21860
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
+ })();
21861
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}`;
21862
21903
  var INTENTS_BASE = process.env.ROZO_CHECKOUT_INTENTS_BASE || "https://intentapiv4.rozo.ai/functions/v1/payment-api";
21863
21904
  async function invoiceStatus({ linkId, rozoPaymentId }) {
21864
21905
  const qs = new URLSearchParams();
@@ -22004,6 +22045,15 @@ function reuseGuard({ payment, requested, reused = false }) {
22004
22045
  }
22005
22046
  return { ok: true, code: null, reason: null, moneyDetected: false, evidence, deposit };
22006
22047
  }
22048
+ function normalizeDecimal(v) {
22049
+ if (v === null || v === void 0) return null;
22050
+ const s = String(v).trim();
22051
+ if (!/^\d+(\.\d+)?$/.test(s)) return s;
22052
+ const [w, f = ""] = s.split(".");
22053
+ const frac = f.replace(/0+$/, "");
22054
+ const whole = w.replace(/^0+(?=\d)/, "");
22055
+ return frac ? `${whole}.${frac}` : whole;
22056
+ }
22007
22057
  function checkPayable(statusResponse, now = Date.now()) {
22008
22058
  const cb = statusResponse?.coinbase;
22009
22059
  if (!cb) {
@@ -22499,7 +22549,67 @@ function assertPaymentLimit(invoiceUsd) {
22499
22549
  return { usd, limitUsd: MAX_PAYMENT_USD };
22500
22550
  }
22501
22551
 
22552
+ // scripts/src/lib/bitrefill.mjs
22553
+ var BITREFILL_DESTINATION = Object.freeze({ chainId: "8453", tokenSymbol: "USDC" });
22554
+ var BITREFILL_MIN_EXPIRY_MS = 5 * 60 * 1e3;
22555
+ var BITREFILL_MIN_PAY_WINDOW_MS = 2 * 60 * 1e3;
22556
+ var BITREFILL_MAX_EXPIRY_AHEAD_MS = 30 * 60 * 1e3;
22557
+ function checkBitrefillExpiry(expiresAt, now = Date.now(), minMs = BITREFILL_MIN_PAY_WINDOW_MS) {
22558
+ const ms = parseDeadline(expiresAt);
22559
+ const base = { marginMs: minMs, deadlines: { invoiceMs: ms } };
22560
+ if (ms === null) {
22561
+ return { ...base, ok: false, code: "EXPIRY_UNPARSABLE", reason: "The Bitrefill invoice expiry is missing or unreadable.", effectiveDeadlineMs: null, msRemaining: null, msOfSlack: null };
22562
+ }
22563
+ const msRemaining = ms - now;
22564
+ const out = { ...base, effectiveDeadlineMs: ms, msRemaining, msOfSlack: msRemaining - minMs };
22565
+ if (msRemaining <= 0) return { ...out, ok: false, code: "EXPIRED", reason: "The Bitrefill invoice has expired." };
22566
+ if (msRemaining < minMs) {
22567
+ return {
22568
+ ...out,
22569
+ ok: false,
22570
+ code: "INVOICE_EXPIRING",
22571
+ reason: `Only ${Math.floor(msRemaining / 1e3)}s left on the Bitrefill invoice; at least ${Math.round(minMs / 6e4)} min is required. Create a fresh invoice.`
22572
+ };
22573
+ }
22574
+ return { ...out, ok: true, code: null, reason: null };
22575
+ }
22576
+ var sameAddress = (a, b) => typeof a === "string" && typeof b === "string" && a.trim().toLowerCase() === b.trim().toLowerCase();
22577
+ function verifyBitrefillDestination({ requested, payment }) {
22578
+ const dest = payment?.destination || {};
22579
+ const drift = [];
22580
+ if (String(dest.chainId ?? "") !== BITREFILL_DESTINATION.chainId) {
22581
+ drift.push({ field: "destination.chainId", requested: "8453", live: dest.chainId ?? null });
22582
+ }
22583
+ if (String(dest.tokenSymbol ?? "").toUpperCase() !== BITREFILL_DESTINATION.tokenSymbol) {
22584
+ drift.push({ field: "destination.tokenSymbol", requested: "USDC", live: dest.tokenSymbol ?? null });
22585
+ }
22586
+ if (normalizeDecimal(dest.amount) !== normalizeDecimal(requested.amount)) {
22587
+ drift.push({ field: "destination.amount", requested: requested.amount, live: dest.amount ?? null });
22588
+ }
22589
+ const liveAddress = dest.receiverAddress ?? dest.address ?? null;
22590
+ if (!sameAddress(liveAddress, requested.address)) {
22591
+ drift.push({ field: "destination.address", requested: requested.address, live: liveAddress });
22592
+ }
22593
+ return drift.length ? {
22594
+ ok: false,
22595
+ code: "BITREFILL_ECHO_MISMATCH",
22596
+ reason: "The live order does not deliver to the Bitrefill invoice. Refusing to continue.",
22597
+ drift,
22598
+ addressVerified: false
22599
+ } : { ok: true, code: null, reason: null, drift, addressVerified: true };
22600
+ }
22601
+
22502
22602
  // scripts/src/lib/presend.mjs
22603
+ function assertBitrefillLive(state, payment) {
22604
+ if (!state.bitrefill) {
22605
+ throw new SkillError("BITREFILL_ECHO_MISMATCH", "This Bitrefill order has no recorded invoice. Refusing to send.");
22606
+ }
22607
+ const dest = verifyBitrefillDestination({ requested: state.bitrefill, payment });
22608
+ if (!dest.ok) throw new SkillError(dest.code, dest.reason, { drift: dest.drift });
22609
+ const expiry = checkBitrefillExpiry(state.bitrefill.expiresAt, Date.now());
22610
+ if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
22611
+ return expiry;
22612
+ }
22503
22613
  async function preflight({
22504
22614
  rozoPaymentId,
22505
22615
  expectFamily,
@@ -22585,16 +22695,22 @@ async function preflight({
22585
22695
  if ((source.receiverMemo ?? null) !== (state.receiverMemo ?? null)) {
22586
22696
  throw new SkillError("DEPOSIT_CHANGED", "The live deposit memo differs from the recorded one.");
22587
22697
  }
22588
- const statusNow = await invoiceStatus({ linkId: state.linkId });
22589
- const expiry = checkExpiry({
22590
- now: Date.now(),
22591
- chainId: source.chainId,
22592
- intentExpiresAt: payment?.expiresAt,
22593
- coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry
22594
- });
22595
- if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
22596
- const payable = checkPayable(statusNow, Date.now());
22597
- if (!payable.ok) throw new SkillError(payable.code, payable.reason, payable.derived);
22698
+ let statusNow = null;
22699
+ let expiry;
22700
+ if (state.provider === "bitrefill") {
22701
+ expiry = assertBitrefillLive(state, payment);
22702
+ } else {
22703
+ statusNow = await invoiceStatus({ linkId: state.linkId });
22704
+ expiry = checkExpiry({
22705
+ now: Date.now(),
22706
+ chainId: source.chainId,
22707
+ intentExpiresAt: payment?.expiresAt,
22708
+ coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry
22709
+ });
22710
+ if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
22711
+ const payable = checkPayable(statusNow, Date.now());
22712
+ if (!payable.ok) throw new SkillError(payable.code, payable.reason, payable.derived);
22713
+ }
22598
22714
  assertNotBlacklisted(
22599
22715
  [
22600
22716
  { address: source.receiverAddress, family, role: "deposit address" },
@@ -22613,7 +22729,17 @@ async function preflight({
22613
22729
  statusNow
22614
22730
  };
22615
22731
  }
22616
- async function finalPayabilityCheck({ linkId, chainId, intentExpiresAt }) {
22732
+ async function finalPayabilityCheck({ linkId, chainId, intentExpiresAt, state = null, rozoPaymentId = null }) {
22733
+ if (state?.provider === "bitrefill") {
22734
+ const id = rozoPaymentId ?? state.rozoPaymentId;
22735
+ const payment = await getPayment(id);
22736
+ const guard = reuseGuard({ payment, requested: state.source });
22737
+ if (!guard.ok) {
22738
+ throw new SkillError(guard.code, guard.reason, { ...guard.evidence, moneyDetected: guard.moneyDetected });
22739
+ }
22740
+ const expiry2 = assertBitrefillLive(state, payment);
22741
+ return { statusNow: null, payable: { ok: true }, expiry: expiry2 };
22742
+ }
22617
22743
  const statusNow = await invoiceStatus({ linkId });
22618
22744
  const payable = checkPayable(statusNow, Date.now());
22619
22745
  if (!payable.ok) throw new SkillError(payable.code, payable.reason, payable.derived);
@@ -22977,7 +23103,9 @@ async function main(argv) {
22977
23103
  await finalPayabilityCheck({
22978
23104
  linkId: state.linkId,
22979
23105
  chainId: source.chainId,
22980
- intentExpiresAt: payment?.expiresAt
23106
+ intentExpiresAt: payment?.expiresAt,
23107
+ state,
23108
+ rozoPaymentId
22981
23109
  });
22982
23110
  claimSend(
22983
23111
  rozoPaymentId,