@dvmkit/sdk 0.21.1 → 0.22.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/card-charge-journal-SKMBEPRM.js +44 -0
- package/dist/{chunk-ALTE7I6C.js → chunk-2WWVI32F.js} +56 -1
- package/dist/{chunk-C65P6MGZ.js → chunk-3DGIRHP2.js} +2 -2
- package/dist/{chunk-6RJAE332.js → chunk-5NMHZIIU.js} +1 -1
- package/dist/{chunk-34H4ZKBM.js → chunk-5YJWAJ4N.js} +1 -1
- package/dist/{chunk-2PN4DKZW.js → chunk-CUWSJQGT.js} +1 -1
- package/dist/{chunk-A6AOE63A.js → chunk-DLRPKEAM.js} +5 -1
- package/dist/{chunk-KRX7VNBG.js → chunk-DY5QIHJA.js} +1 -1
- package/dist/{chunk-RX6FT7XA.js → chunk-EHBUAJ5M.js} +1 -1
- package/dist/{chunk-7RWE6ELV.js → chunk-EQIP6TFD.js} +1 -1
- package/dist/{chunk-OTNHKRHA.js → chunk-GDZXGB43.js} +3 -3
- package/dist/{chunk-5RLNRLLB.js → chunk-HEH7YUGE.js} +1 -1
- package/dist/{chunk-DJRTYBEE.js → chunk-HVZIITWW.js} +27 -4
- package/dist/{chunk-MUMZPUYD.js → chunk-JINZMDNK.js} +1231 -85
- package/dist/{chunk-QTKGFG3I.js → chunk-JMTLK2SZ.js} +1 -1
- package/dist/{chunk-INYFUPXV.js → chunk-L35WYOH2.js} +1 -1
- package/dist/{chunk-MWDUGMN2.js → chunk-LCNRFKP7.js} +2 -2
- package/dist/{chunk-CVN2YNMG.js → chunk-QMKGYIBM.js} +1 -1
- package/dist/{chunk-I5MXADJS.js → chunk-SEIMPHIP.js} +225 -11
- package/dist/{chunk-QCZXKUS2.js → chunk-SQOVLAJ2.js} +1 -1
- package/dist/{chunk-72A4PHLD.js → chunk-UVRBD5GR.js} +1 -1
- package/dist/{chunk-5RGZN6WQ.js → chunk-XB644VN3.js} +1 -1
- package/dist/{chunk-CXRI4N4Y.js → chunk-YNHFJE6U.js} +1 -1
- package/dist/{chunk-LY2JYSJS.js → chunk-ZH5CLGO6.js} +1 -1
- package/dist/{content-retention-COnj0QKi.d.ts → content-retention-DEvY5vjM.d.ts} +1 -1
- package/dist/{credit-ledger-ZCJXJG6R.js → credit-ledger-S76KU53A.js} +11 -3
- package/dist/{credit-menu-DbjmA1vK.d.ts → credit-menu-BA2my6hE.d.ts} +229 -8
- package/dist/{fx-DfzQ0Lge.d.ts → fx-J5oXbv9A.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/internal/caller.d.ts +10 -9
- package/dist/internal/caller.js +11 -11
- package/dist/internal/server.d.ts +7 -7
- package/dist/internal/server.js +21 -21
- package/dist/{job-store-p45j28px.d.ts → job-store-CjPnf0dd.d.ts} +1 -1
- package/dist/{lightning-backend-DO7G7VqP.d.ts → lightning-backend-D9Q2KDS-.d.ts} +1 -1
- package/dist/{memory-credit-ledger-N4PZKTT5.js → memory-credit-ledger-5KXHOWB2.js} +4 -4
- package/dist/{mpp-setup-BLIYBORK.js → mpp-setup-3YZMURZL.js} +3 -3
- package/dist/{payout-reporter-5QAHCYIO.js → payout-reporter-KTLBNJJ7.js} +2 -2
- package/dist/{postgres-consumed-credential-store-4PCJEZBD.js → postgres-consumed-credential-store-Y336KNIB.js} +1 -1
- package/dist/{postgres-job-store-QKN5LGAH.js → postgres-job-store-ESEAN7JL.js} +2 -2
- package/dist/{postgres-replay-store-GH5AINQR.js → postgres-replay-store-6SVCZ475.js} +2 -2
- package/dist/{pricing-JJYLTTWK.js → pricing-RP5CGW6I.js} +3 -3
- package/dist/{revenue-reporter-6XARUEG6.js → revenue-reporter-FD3GDQZS.js} +2 -2
- package/dist/server/index.d.ts +20 -11
- package/dist/server/index.js +303 -30
- package/dist/{step-cache-CcCjpZm1.d.ts → step-cache-DXFftnAc.d.ts} +156 -13
- package/dist/{tempo-charge-store-A3CDF7D5.js → tempo-charge-store-SOIRMEFJ.js} +2 -2
- package/dist/{tempo-session-store-XJE6GIXN.js → tempo-session-store-UBDFFHDG.js} +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +6 -6
- package/dist/{usd-BnAFcUai.d.ts → usd-Bc_rva_K.d.ts} +1 -1
- package/dist/{x402-XLFD43RF.js → x402-MFBRORHG.js} +5 -5
- package/package.json +1 -1
- package/dist/{chunk-NUDHO4HV.js → chunk-LABJSMSJ.js} +48 -48
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/sdk/server/card-charge-journal.ts
|
|
2
|
+
async function createPostgresCardChargeJournal(pool, opts = {}) {
|
|
3
|
+
const now = opts.now ?? Date.now;
|
|
4
|
+
await pool.query(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS card_charge_attempts (
|
|
6
|
+
challenge_id TEXT PRIMARY KEY,
|
|
7
|
+
created_at BIGINT NOT NULL,
|
|
8
|
+
resolved_at BIGINT,
|
|
9
|
+
outcome TEXT
|
|
10
|
+
)
|
|
11
|
+
`);
|
|
12
|
+
await pool.query(
|
|
13
|
+
`CREATE INDEX IF NOT EXISTS idx_card_charge_attempts_open
|
|
14
|
+
ON card_charge_attempts(created_at) WHERE resolved_at IS NULL`
|
|
15
|
+
);
|
|
16
|
+
return {
|
|
17
|
+
async record(challengeId) {
|
|
18
|
+
await pool.query(
|
|
19
|
+
`INSERT INTO card_charge_attempts (challenge_id, created_at) VALUES ($1, $2)
|
|
20
|
+
ON CONFLICT (challenge_id) DO NOTHING`,
|
|
21
|
+
[challengeId, now()]
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
async listUnresolved({ olderThanMs, limit }) {
|
|
25
|
+
const { rows } = await pool.query(
|
|
26
|
+
`SELECT challenge_id, created_at FROM card_charge_attempts
|
|
27
|
+
WHERE resolved_at IS NULL AND created_at <= $1
|
|
28
|
+
ORDER BY created_at LIMIT $2`,
|
|
29
|
+
[olderThanMs, limit]
|
|
30
|
+
);
|
|
31
|
+
return rows.map((row) => ({ challengeId: row.challenge_id, createdAt: Number(row.created_at) }));
|
|
32
|
+
},
|
|
33
|
+
async resolve(challengeId, outcome) {
|
|
34
|
+
await pool.query(
|
|
35
|
+
`UPDATE card_charge_attempts SET resolved_at = $2, outcome = $3
|
|
36
|
+
WHERE challenge_id = $1 AND resolved_at IS NULL`,
|
|
37
|
+
[challengeId, now(), outcome]
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
createPostgresCardChargeJournal
|
|
44
|
+
};
|
|
@@ -496,7 +496,15 @@ var diagnostic_catalogue_v1_default = {
|
|
|
496
496
|
"x402_settlement_reconciliation_chain_unreachable",
|
|
497
497
|
"x402_settlement_reconciliation_facilitator_unavailable",
|
|
498
498
|
"x402_settlement_submission_failed",
|
|
499
|
-
"x402_settlement_written_off"
|
|
499
|
+
"x402_settlement_written_off",
|
|
500
|
+
"card_charge_journal_failed",
|
|
501
|
+
"card_charge_stranded_refunded",
|
|
502
|
+
"card_charge_unsettled",
|
|
503
|
+
"card_refund_pending",
|
|
504
|
+
"card_refund_sweep",
|
|
505
|
+
"card_refund_expiry_failed",
|
|
506
|
+
"card_refund_sweep_failed",
|
|
507
|
+
"card_refund_sweep_step_failed"
|
|
500
508
|
],
|
|
501
509
|
routeTemplates: [
|
|
502
510
|
"/",
|
|
@@ -769,13 +777,23 @@ var diagnostic_catalogue_v1_default = {
|
|
|
769
777
|
"/v1/request-resume/:requestId"
|
|
770
778
|
],
|
|
771
779
|
errorCodes: [
|
|
780
|
+
"amount_too_large",
|
|
781
|
+
"api_error",
|
|
772
782
|
"app_shell_detected",
|
|
773
783
|
"audio_source_required",
|
|
774
784
|
"auth_error",
|
|
775
785
|
"auth_required",
|
|
786
|
+
"authentication_error",
|
|
787
|
+
"balance_insufficient",
|
|
776
788
|
"bytes_cap",
|
|
777
789
|
"capability_required",
|
|
778
790
|
"captcha_unsolved",
|
|
791
|
+
"card_error",
|
|
792
|
+
"charge_already_refunded",
|
|
793
|
+
"charge_disputed",
|
|
794
|
+
"charge_expired_for_refund",
|
|
795
|
+
"charge_not_refundable",
|
|
796
|
+
"charges_exhausted",
|
|
779
797
|
"cloudflare_unsolved",
|
|
780
798
|
"content_rejected",
|
|
781
799
|
"cover_invalid",
|
|
@@ -793,6 +811,7 @@ var diagnostic_catalogue_v1_default = {
|
|
|
793
811
|
"extract_llm_failed",
|
|
794
812
|
"extract_schema_invalid",
|
|
795
813
|
"extract_validation_failed",
|
|
814
|
+
"fee_not_settled",
|
|
796
815
|
"feed_full",
|
|
797
816
|
"feed_not_found",
|
|
798
817
|
"feed_path_invalid",
|
|
@@ -807,6 +826,8 @@ var diagnostic_catalogue_v1_default = {
|
|
|
807
826
|
"head_status",
|
|
808
827
|
"hint",
|
|
809
828
|
"hosting_identity_revoke_failed",
|
|
829
|
+
"idempotency_error",
|
|
830
|
+
"idempotency_key_in_use",
|
|
810
831
|
"ingest_concurrency",
|
|
811
832
|
"ingest_global_concurrency",
|
|
812
833
|
"ingest_ip_concurrency",
|
|
@@ -817,6 +838,7 @@ var diagnostic_catalogue_v1_default = {
|
|
|
817
838
|
"invalid_menu",
|
|
818
839
|
"invalid_payment",
|
|
819
840
|
"invalid_quote_data",
|
|
841
|
+
"invalid_request_error",
|
|
820
842
|
"invalid_url",
|
|
821
843
|
"job_failed",
|
|
822
844
|
"job_timeout",
|
|
@@ -837,6 +859,7 @@ var diagnostic_catalogue_v1_default = {
|
|
|
837
859
|
"payment_invalid",
|
|
838
860
|
"payment_required",
|
|
839
861
|
"paywall_detected",
|
|
862
|
+
"permission_error",
|
|
840
863
|
"polish_input_too_large",
|
|
841
864
|
"polish_llm_failed",
|
|
842
865
|
"presign_failed",
|
|
@@ -854,11 +877,14 @@ var diagnostic_catalogue_v1_default = {
|
|
|
854
877
|
"provider_timeout",
|
|
855
878
|
"provider_unavailable",
|
|
856
879
|
"quota_exceeded",
|
|
880
|
+
"rate_limit_error",
|
|
857
881
|
"rate_limited",
|
|
858
882
|
"rate_limited_by_target",
|
|
883
|
+
"refund_disputed_payment",
|
|
859
884
|
"region_unavailable",
|
|
860
885
|
"replay_detected",
|
|
861
886
|
"request_integrity_failed",
|
|
887
|
+
"resource_missing",
|
|
862
888
|
"retry_hardened",
|
|
863
889
|
"retry_with_bounded_wait",
|
|
864
890
|
"retry_with_content_selector",
|
|
@@ -867,10 +893,12 @@ var diagnostic_catalogue_v1_default = {
|
|
|
867
893
|
"server_error",
|
|
868
894
|
"sha256_mismatch",
|
|
869
895
|
"signature_invalid",
|
|
896
|
+
"signature_required",
|
|
870
897
|
"size_mismatch",
|
|
871
898
|
"source_unreachable",
|
|
872
899
|
"ssrf_blocked",
|
|
873
900
|
"string",
|
|
901
|
+
"stripe_unreachable",
|
|
874
902
|
"substrate_unavailable",
|
|
875
903
|
"timeout",
|
|
876
904
|
"timestamp_drift",
|
|
@@ -1183,6 +1211,17 @@ var CAPABILITY_RE = /^[a-z][a-z0-9_-]{0,47}$/;
|
|
|
1183
1211
|
var CLIENT_VERSION_RE = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-rc\.(?:0|[1-9]\d*))?$/;
|
|
1184
1212
|
var HASH_RE = /^(?:[0-9a-f]{16}|[0-9a-f]{64})$/i;
|
|
1185
1213
|
var DECIMAL_RE = /^(?:0|[1-9]\d{0,77})$/;
|
|
1214
|
+
var CARD_REFUND_EVENTS = /* @__PURE__ */ new Set([
|
|
1215
|
+
"card_charge_stranded_refunded",
|
|
1216
|
+
"card_charge_unsettled",
|
|
1217
|
+
"card_refund_expiry_failed",
|
|
1218
|
+
"card_refund_pending",
|
|
1219
|
+
"card_refund_sweep",
|
|
1220
|
+
"card_refund_sweep_step_failed"
|
|
1221
|
+
]);
|
|
1222
|
+
var CARD_REFUND_COUNTS = /* @__PURE__ */ new Set(["frozen", "unfrozen", "expiry_refunds", "completed", "pending", "stranded_refunds"]);
|
|
1223
|
+
var CARD_REFUND_STAGES = /* @__PURE__ */ new Set(["plan", "refund", "disputes", "expiry", "retry", "stranded"]);
|
|
1224
|
+
var CARD_REFUND_STATUSES = /* @__PURE__ */ new Set(["planned", "pending", "requires_action", "succeeded", "failed", "canceled", "rejected"]);
|
|
1186
1225
|
var STRIPE_EVENT_RE = /^evt_[A-Za-z0-9]{1,64}$/;
|
|
1187
1226
|
var REDACTED_SEGMENT_RE = /^:(?:uuid|hex|n|b58|token)$/;
|
|
1188
1227
|
var SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -1354,6 +1393,10 @@ function projectField(key, value, dataset, authority, identityAuthority, eventNa
|
|
|
1354
1393
|
const closedEnum = Object.hasOwn(PAYMENT_ENUMS, key) ? PAYMENT_ENUMS[key] : Object.hasOwn(ROUTER_ENUMS, key) ? ROUTER_ENUMS[key] : void 0;
|
|
1355
1394
|
if (closedEnum)
|
|
1356
1395
|
return typeof value === "string" && closedEnum.has(value) ? value : void 0;
|
|
1396
|
+
if (eventName !== void 0 && CARD_REFUND_EVENTS.has(eventName)) {
|
|
1397
|
+
const projected = projectCardRefundField(key, value);
|
|
1398
|
+
if (projected !== void 0) return projected;
|
|
1399
|
+
}
|
|
1357
1400
|
if (dataset === "tempo") {
|
|
1358
1401
|
if (key === "prior_status")
|
|
1359
1402
|
return typeof value === "string" && TEMPO_CLOSE_REPORT_PRIOR_STATUSES.has(value) ? value : void 0;
|
|
@@ -1435,6 +1478,18 @@ function projectField(key, value, dataset, authority, identityAuthority, eventNa
|
|
|
1435
1478
|
return typeof value === "string" && SANCTIONS_REGIONS.has(value) ? value : void 0;
|
|
1436
1479
|
return void 0;
|
|
1437
1480
|
}
|
|
1481
|
+
function projectCardRefundField(key, value) {
|
|
1482
|
+
if (key === "credit_id" || key === "drain_id" || key === "challenge_id")
|
|
1483
|
+
return typeof value === "string" && /^[a-zA-Z0-9_.:-]{1,512}$/.test(value) ? value : void 0;
|
|
1484
|
+
if (key === "payment_intent")
|
|
1485
|
+
return typeof value === "string" && /^pi_[A-Za-z0-9]{1,64}$/.test(value) ? value : void 0;
|
|
1486
|
+
if (key === "stage")
|
|
1487
|
+
return typeof value === "string" && CARD_REFUND_STAGES.has(value) ? value : void 0;
|
|
1488
|
+
if (key === "refund_status")
|
|
1489
|
+
return typeof value === "string" && CARD_REFUND_STATUSES.has(value) ? value : void 0;
|
|
1490
|
+
if (CARD_REFUND_COUNTS.has(key)) return isNonnegativeSafeInteger(value) ? value : void 0;
|
|
1491
|
+
return void 0;
|
|
1492
|
+
}
|
|
1438
1493
|
function projectService(value) {
|
|
1439
1494
|
if (typeof value !== "string") return "unknown";
|
|
1440
1495
|
if (SERVICE_NAMES.has(value)) return value;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
X402_DEFAULT_FACILITATOR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LABJSMSJ.js";
|
|
4
4
|
import {
|
|
5
5
|
callerLoggers
|
|
6
6
|
} from "./chunk-66HGCPBU.js";
|
|
7
7
|
import {
|
|
8
8
|
diagnosticConsole
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2WWVI32F.js";
|
|
10
10
|
|
|
11
11
|
// src/observability/payment-diagnostics.ts
|
|
12
12
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-SXL44PL5.js";
|
|
8
8
|
import {
|
|
9
9
|
diagnosticConsole
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2WWVI32F.js";
|
|
11
11
|
|
|
12
12
|
// src/sdk/server/zod-error.ts
|
|
13
13
|
function humanizeZodError(err, opts) {
|
|
@@ -106,6 +106,9 @@ var SIGNED_ENVELOPE_TYPES = {
|
|
|
106
106
|
var SIGNED_ENVELOPE_FIELDS = Object.keys(
|
|
107
107
|
SIGNED_ENVELOPE_TYPES
|
|
108
108
|
);
|
|
109
|
+
function carriesSignedEnvelope(input) {
|
|
110
|
+
return input !== null && typeof input === "object" && !Array.isArray(input) && SIGNED_ENVELOPE_FIELDS.some((field) => field in input);
|
|
111
|
+
}
|
|
109
112
|
var SignedRequestError = class extends Error {
|
|
110
113
|
constructor(message, sub_reason, issues) {
|
|
111
114
|
super(message);
|
|
@@ -371,6 +374,7 @@ export {
|
|
|
371
374
|
zodIssuesOf,
|
|
372
375
|
SIGNED_ENVELOPE_TYPES,
|
|
373
376
|
SIGNED_ENVELOPE_FIELDS,
|
|
377
|
+
carriesSignedEnvelope,
|
|
374
378
|
SignedRequestError,
|
|
375
379
|
createSignedRequestVerifier,
|
|
376
380
|
signedRequestInput,
|
|
@@ -2,20 +2,20 @@ import {
|
|
|
2
2
|
createX402FacilitatorAuthHeaders,
|
|
3
3
|
settleWithFacilitator,
|
|
4
4
|
verifyWithFacilitator
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3DGIRHP2.js";
|
|
6
6
|
import {
|
|
7
7
|
buildPaymentRequirements,
|
|
8
8
|
decodePayment,
|
|
9
9
|
encodeSettleResponseHeader,
|
|
10
10
|
exactEvmAuthorization,
|
|
11
11
|
usdcToMsats
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-LABJSMSJ.js";
|
|
13
13
|
import {
|
|
14
14
|
callerLoggers
|
|
15
15
|
} from "./chunk-66HGCPBU.js";
|
|
16
16
|
import {
|
|
17
17
|
diagnosticConsole
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-2WWVI32F.js";
|
|
19
19
|
|
|
20
20
|
// src/lib/x402/verify.ts
|
|
21
21
|
async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resource, btcUsdRate, exactVersions = { v1: true, v2: true }) {
|
|
@@ -4,12 +4,15 @@ import {
|
|
|
4
4
|
X402_SPEND_BLOCKING_SETTLEMENT_STATUSES,
|
|
5
5
|
X402_WEDGED_SETTLEMENT_STATUSES,
|
|
6
6
|
allocateDrawValue,
|
|
7
|
+
assertCardDrainMatchesRail,
|
|
7
8
|
assertFundingBasis,
|
|
9
|
+
cardRefundPendingConflict,
|
|
8
10
|
clipEarmark,
|
|
9
11
|
depleteLots,
|
|
10
12
|
fifoOrder,
|
|
11
13
|
growthRailValue,
|
|
12
14
|
inKindDrawMsats,
|
|
15
|
+
isCardFundedRail,
|
|
13
16
|
isFundingRail,
|
|
14
17
|
isInKindDepletion,
|
|
15
18
|
isNonChannelBitcoinRail,
|
|
@@ -18,7 +21,7 @@ import {
|
|
|
18
21
|
refundAssetDelta,
|
|
19
22
|
refundRequest,
|
|
20
23
|
x402SettlementPending
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-SEIMPHIP.js";
|
|
22
25
|
|
|
23
26
|
// src/sdk/server/memory-credit-ledger.ts
|
|
24
27
|
import { randomUUID } from "crypto";
|
|
@@ -889,6 +892,7 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
|
|
|
889
892
|
`credit ${args.creditId} belongs to a different caller pubkey`
|
|
890
893
|
);
|
|
891
894
|
}
|
|
895
|
+
assertCardDrainMatchesRail(args.creditId, credit.rail, args.method);
|
|
892
896
|
const existing = credit.drains.get(args.drainId);
|
|
893
897
|
if (existing) {
|
|
894
898
|
if (existing.method !== args.method || JSON.stringify(existing.payout) !== JSON.stringify(args.payout)) {
|
|
@@ -904,6 +908,12 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
|
|
|
904
908
|
};
|
|
905
909
|
}
|
|
906
910
|
if (credit.status !== "active") throw terminalCreditError(args.creditId);
|
|
911
|
+
if (args.method === "stripe") {
|
|
912
|
+
const blocking = [...credit.drains.values()].find(
|
|
913
|
+
(drain2) => drain2.method === "stripe" && drain2.status === "pending"
|
|
914
|
+
);
|
|
915
|
+
if (blocking) throw cardRefundPendingConflict(args.creditId, blocking.drainId);
|
|
916
|
+
}
|
|
907
917
|
if (x402Refund) throw x402SettlementPending(args.creditId, x402Refund);
|
|
908
918
|
const pending = pendingSums(credit);
|
|
909
919
|
const availableMicro = credit.balanceMicro - pending.micro;
|
|
@@ -965,7 +975,8 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
|
|
|
965
975
|
writeOffNote: null,
|
|
966
976
|
writtenOffAt: null,
|
|
967
977
|
provenRefundNative: null,
|
|
968
|
-
refundPaymentProven: false
|
|
978
|
+
refundPaymentProven: false,
|
|
979
|
+
cardRefund: null
|
|
969
980
|
};
|
|
970
981
|
applyLotDebits(credit, drain.lotDebits, -1);
|
|
971
982
|
credit.drains.set(args.drainId, drain);
|
|
@@ -1208,6 +1219,17 @@ var MemoryCreditLedger = class _MemoryCreditLedger {
|
|
|
1208
1219
|
throw this.transitionRefusal(drain, "mark sent");
|
|
1209
1220
|
});
|
|
1210
1221
|
}
|
|
1222
|
+
saveCardRefund(args) {
|
|
1223
|
+
return run(() => {
|
|
1224
|
+
const drain = this.credits.get(args.creditId)?.drains.get(args.drainId);
|
|
1225
|
+
if (!drain) return null;
|
|
1226
|
+
const writable = drain.method === "stripe" && drain.status === "pending";
|
|
1227
|
+
if (writable && !(args.onlyIfUnset && drain.cardRefund)) {
|
|
1228
|
+
drain.cardRefund = structuredClone(args.plan);
|
|
1229
|
+
}
|
|
1230
|
+
return drain.cardRefund ? structuredClone(drain.cardRefund) : null;
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1211
1233
|
appendDrainReceipt(args) {
|
|
1212
1234
|
return run(() => {
|
|
1213
1235
|
const drain = this.credits.get(args.creditId)?.drains.get(args.drainId);
|
|
@@ -1326,7 +1348,7 @@ function applyBasis(credit, basis) {
|
|
|
1326
1348
|
}
|
|
1327
1349
|
}
|
|
1328
1350
|
function recordLot(credit, amountMicro, basis, nowMs) {
|
|
1329
|
-
if (!isNonChannelBitcoinRail(basis.rail)) return;
|
|
1351
|
+
if (!isNonChannelBitcoinRail(basis.rail) && !isCardFundedRail(basis.rail)) return;
|
|
1330
1352
|
if (basis.tempoSession || basis.x402Channel) return;
|
|
1331
1353
|
credit.lots.push({
|
|
1332
1354
|
lotId: `lot:${randomUUID()}`,
|
|
@@ -1441,7 +1463,8 @@ function drainRecord(drain, credit) {
|
|
|
1441
1463
|
writeOffNote: drain.writeOffNote,
|
|
1442
1464
|
writtenOffAt: drain.writtenOffAt,
|
|
1443
1465
|
provenRefundNative: drain.provenRefundNative,
|
|
1444
|
-
refundPaymentProven: drain.refundPaymentProven
|
|
1466
|
+
refundPaymentProven: drain.refundPaymentProven,
|
|
1467
|
+
cardRefund: drain.cardRefund ? structuredClone(drain.cardRefund) : null
|
|
1445
1468
|
};
|
|
1446
1469
|
}
|
|
1447
1470
|
function assertAmount(amountMicro, opts) {
|