@aifinpay/agent 1.7.0 → 1.8.1
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/aifp1.d.ts +308 -0
- package/dist/aifp1.d.ts.map +1 -0
- package/dist/aifp1.js +681 -0
- package/dist/aifp1.js.map +1 -0
- package/dist/crossChain.d.ts +0 -8
- package/dist/crossChain.d.ts.map +1 -1
- package/dist/crossChain.js +66 -0
- package/dist/crossChain.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/spendLedger.d.ts +54 -0
- package/dist/spendLedger.d.ts.map +1 -0
- package/dist/spendLedger.js +185 -0
- package/dist/spendLedger.js.map +1 -0
- package/dist/unifiedAgent.d.ts +67 -0
- package/dist/unifiedAgent.d.ts.map +1 -1
- package/dist/unifiedAgent.js +338 -140
- package/dist/unifiedAgent.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unifiedAgent.d.ts","sourceRoot":"","sources":["../src/unifiedAgent.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"unifiedAgent.d.ts","sourceRoot":"","sources":["../src/unifiedAgent.ts"],"names":[],"mappings":"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"}
|
package/dist/unifiedAgent.js
CHANGED
|
@@ -20,6 +20,8 @@ import { polygon, base, arbitrum, optimism, bsc, mainnet, unichain } from "viem/
|
|
|
20
20
|
import { Connection, Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction, sendAndConfirmTransaction, } from "@solana/web3.js";
|
|
21
21
|
import { AiFinPayError, X402Error, } from "./errors.js";
|
|
22
22
|
import { Agent } from "./agent.js";
|
|
23
|
+
import { MemorySpendLedger, FileSpendLedger } from "./spendLedger.js";
|
|
24
|
+
import { aifp1Fetch, Aifp1ReceiptCache, } from "./aifp1.js";
|
|
23
25
|
import { bridgeQuote as crossChainQuote, bridgeExecute as crossChainExecute, bridgeWaitForArrival, USDC_NATIVE, } from "./crossChain.js";
|
|
24
26
|
// ── B2BSplitter contract ABI ─────────────────────────────────────────────
|
|
25
27
|
// `payMatic` is the splitter's generic NATIVE-token payment entrypoint —
|
|
@@ -291,7 +293,9 @@ export class AiFinPayAgent {
|
|
|
291
293
|
solanaRpc;
|
|
292
294
|
cachedRegistry;
|
|
293
295
|
budgetCaps;
|
|
294
|
-
spend24h = new SpendTracker();
|
|
296
|
+
spend24h = new SpendTracker(); // reporting only; the cap uses the ledger
|
|
297
|
+
_ledger;
|
|
298
|
+
ledgerOverride;
|
|
295
299
|
telemetry;
|
|
296
300
|
_polygonPublic;
|
|
297
301
|
_polygonWallet;
|
|
@@ -308,6 +312,14 @@ export class AiFinPayAgent {
|
|
|
308
312
|
? [opts.registryUrl]
|
|
309
313
|
: DEFAULT_REGISTRY_PATHS.map((path) => `${inner.baseUrl}${path}`);
|
|
310
314
|
this.budgetCaps = opts.budgetCaps ?? {};
|
|
315
|
+
// `spendLedger` was declared, documented ("pass your own when the agent
|
|
316
|
+
// runs on more than one host") and read by the `ledger` getter, but never
|
|
317
|
+
// assigned from the options — so the option was a no-op and every agent
|
|
318
|
+
// with a daily cap wrote to ~/.aifinpay regardless. A fleet that supplied
|
|
319
|
+
// a shared ledger silently got a per-host one instead, which is exactly
|
|
320
|
+
// the failure the option exists to prevent.
|
|
321
|
+
if (opts.spendLedger)
|
|
322
|
+
this.ledgerOverride = opts.spendLedger;
|
|
311
323
|
this.telemetry = opts.telemetry !== false;
|
|
312
324
|
this.polygonRpc = opts.polygonRpc ?? "https://polygon.drpc.org";
|
|
313
325
|
this.solanaRpc = opts.solanaRpc
|
|
@@ -615,6 +627,61 @@ export class AiFinPayAgent {
|
|
|
615
627
|
* without submitting an on-chain tx. Throws BudgetCapExceededError
|
|
616
628
|
* in the default "throw" mode.
|
|
617
629
|
*/
|
|
630
|
+
/**
|
|
631
|
+
* The ledger that enforces the daily cap.
|
|
632
|
+
*
|
|
633
|
+
* Chosen late, because setBudget() is usually called after construction and
|
|
634
|
+
* the choice depends on whether a daily cap exists at all. Durability is
|
|
635
|
+
* engaged only when one does: a library that writes to a user's disk because
|
|
636
|
+
* it was imported would be rude, and one that promises a daily limit and
|
|
637
|
+
* forgets it on restart is worse.
|
|
638
|
+
*/
|
|
639
|
+
get ledger() {
|
|
640
|
+
if (this.ledgerOverride)
|
|
641
|
+
return this.ledgerOverride;
|
|
642
|
+
if (!this._ledger) {
|
|
643
|
+
this._ledger = this.budgetCaps.daily_usd !== undefined
|
|
644
|
+
? FileSpendLedger.forAgent(this.evmAddress)
|
|
645
|
+
: new MemorySpendLedger();
|
|
646
|
+
}
|
|
647
|
+
return this._ledger;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Claim room in the daily cap before paying.
|
|
651
|
+
*
|
|
652
|
+
* Returns a reservation id, or "skip"/throws per on_limit_exceeded. The cap
|
|
653
|
+
* comparison happens inside the ledger, atomically: a caller that read the
|
|
654
|
+
* total and then reserved would have rebuilt the race this replaces, where
|
|
655
|
+
* two concurrent calls both read the same total, both passed, and both paid.
|
|
656
|
+
*/
|
|
657
|
+
async reserveDaily(costUsd) {
|
|
658
|
+
const cap = this.budgetCaps.daily_usd;
|
|
659
|
+
if (cap === undefined)
|
|
660
|
+
return null; // no daily cap to enforce
|
|
661
|
+
const id = await this.ledger.reserve(costUsd, cap, 24 * 3600 * 1000);
|
|
662
|
+
if (id)
|
|
663
|
+
return id;
|
|
664
|
+
const err = new BudgetCapExceededError("daily", `this call would take daily spend past the $${cap} cap`);
|
|
665
|
+
if ((this.budgetCaps.on_limit_exceeded ?? "throw") === "skip")
|
|
666
|
+
return "skip";
|
|
667
|
+
throw err;
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* The per-call cap, which needs no ledger.
|
|
671
|
+
*
|
|
672
|
+
* It is a property of one call and cannot be raced: nothing about a
|
|
673
|
+
* concurrent call changes whether THIS one is too expensive. Only the daily
|
|
674
|
+
* cap accumulates, and only it goes through reserve/commit.
|
|
675
|
+
*/
|
|
676
|
+
checkPerCall(costUsd) {
|
|
677
|
+
const cap = this.budgetCaps.per_call_usd;
|
|
678
|
+
if (cap === undefined || costUsd <= cap)
|
|
679
|
+
return true;
|
|
680
|
+
const err = new BudgetCapExceededError("per_call", `cost $${costUsd} exceeds per-call cap $${cap}`);
|
|
681
|
+
if ((this.budgetCaps.on_limit_exceeded ?? "throw") === "skip")
|
|
682
|
+
return false;
|
|
683
|
+
throw err;
|
|
684
|
+
}
|
|
618
685
|
checkBudget(costUsd) {
|
|
619
686
|
const mode = this.budgetCaps.on_limit_exceeded ?? "throw";
|
|
620
687
|
if (this.budgetCaps.per_call_usd !== undefined && costUsd > this.budgetCaps.per_call_usd) {
|
|
@@ -912,143 +979,216 @@ export class AiFinPayAgent {
|
|
|
912
979
|
// null/NaN cost can't poison the SpendTracker and silently disable caps.
|
|
913
980
|
const rawCost = opts.cost ?? provider.price_usd;
|
|
914
981
|
const cost = typeof rawCost === "number" && Number.isFinite(rawCost) ? rawCost : 0;
|
|
915
|
-
|
|
916
|
-
|
|
982
|
+
// The per-call cap still refuses outright; the daily one is reserved, so
|
|
983
|
+
// that two calls in flight cannot both be told there is room.
|
|
984
|
+
if (!this.checkPerCall(cost))
|
|
917
985
|
return null;
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
if (!url) {
|
|
923
|
-
throw new AiFinPayError(`Provider ${provider.name} has no bridge_url`);
|
|
924
|
-
}
|
|
925
|
-
const path = (() => {
|
|
926
|
-
if (provider.service_type === "search")
|
|
927
|
-
return "/search";
|
|
928
|
-
if (provider.service_type === "inference")
|
|
929
|
-
return "/chat/completions";
|
|
930
|
-
if (provider.service_type === "compute")
|
|
931
|
-
return "/run";
|
|
932
|
-
if (provider.service_type === "analytics")
|
|
933
|
-
return "/query";
|
|
934
|
-
return "/";
|
|
935
|
-
})();
|
|
936
|
-
const buildInit = (extraHeaders = {}) => ({
|
|
937
|
-
method: opts.method ?? "POST",
|
|
938
|
-
headers: { "content-type": "application/json", ...extraHeaders },
|
|
939
|
-
body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
|
|
940
|
-
// CallOptions.timeoutMs was previously declared but never applied.
|
|
941
|
-
signal: opts.signal
|
|
942
|
-
?? (opts.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined),
|
|
943
|
-
});
|
|
944
|
-
// 1. Initial unauthenticated POST → expect 402 challenge from the bridge.
|
|
945
|
-
const fullUrl = url.replace(/\/$/, "") + path;
|
|
946
|
-
const initialResp = await this.inner.fetchImpl(fullUrl, buildInit());
|
|
947
|
-
if (initialResp.status !== 402) {
|
|
948
|
-
// Bridge didn't ask for payment — pass response through unchanged.
|
|
949
|
-
// Nothing was paid, so the call does NOT count against budget caps.
|
|
950
|
-
if (this.telemetry)
|
|
951
|
-
this.reportTelemetry({ kind: "call", provider: provider.name, chain, cost, free: true });
|
|
952
|
-
return initialResp;
|
|
953
|
-
}
|
|
954
|
-
let challenge;
|
|
986
|
+
const reservation = await this.reserveDaily(cost);
|
|
987
|
+
if (reservation === "skip")
|
|
988
|
+
return null;
|
|
989
|
+
let settled = false;
|
|
955
990
|
try {
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
991
|
+
if (provider.mode === "session") {
|
|
992
|
+
throw new AiFinPayError(`Provider ${provider.name} requires session mode — use openSession() (phase-3 feature)`);
|
|
993
|
+
}
|
|
994
|
+
const url = opts.bridgeUrl ?? provider.bridge_url;
|
|
995
|
+
if (!url) {
|
|
996
|
+
throw new AiFinPayError(`Provider ${provider.name} has no bridge_url`);
|
|
997
|
+
}
|
|
998
|
+
const path = (() => {
|
|
999
|
+
if (provider.service_type === "search")
|
|
1000
|
+
return "/search";
|
|
1001
|
+
if (provider.service_type === "inference")
|
|
1002
|
+
return "/chat/completions";
|
|
1003
|
+
if (provider.service_type === "compute")
|
|
1004
|
+
return "/run";
|
|
1005
|
+
if (provider.service_type === "analytics")
|
|
1006
|
+
return "/query";
|
|
1007
|
+
return "/";
|
|
1008
|
+
})();
|
|
1009
|
+
const buildInit = (extraHeaders = {}) => ({
|
|
1010
|
+
method: opts.method ?? "POST",
|
|
1011
|
+
headers: { "content-type": "application/json", ...extraHeaders },
|
|
1012
|
+
body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
|
|
1013
|
+
// CallOptions.timeoutMs was previously declared but never applied.
|
|
1014
|
+
signal: opts.signal
|
|
1015
|
+
?? (opts.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined),
|
|
1016
|
+
});
|
|
1017
|
+
// 1. Initial unauthenticated POST → expect 402 challenge from the bridge.
|
|
1018
|
+
const fullUrl = url.replace(/\/$/, "") + path;
|
|
1019
|
+
const initialResp = await this.inner.fetchImpl(fullUrl, buildInit());
|
|
1020
|
+
if (initialResp.status !== 402) {
|
|
1021
|
+
// Bridge didn't ask for payment — pass response through unchanged.
|
|
1022
|
+
// Nothing was paid, so the call does NOT count against budget caps.
|
|
1023
|
+
if (this.telemetry)
|
|
1024
|
+
this.reportTelemetry({ kind: "call", provider: provider.name, chain, cost, free: true });
|
|
1025
|
+
return initialResp;
|
|
1026
|
+
}
|
|
1027
|
+
let challenge;
|
|
1028
|
+
try {
|
|
1029
|
+
challenge = (await initialResp.json());
|
|
1030
|
+
}
|
|
1031
|
+
catch (e) {
|
|
1032
|
+
throw new X402Error(`bridge returned 402 with non-JSON body`);
|
|
967
1033
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1034
|
+
// ── Solana branch (b2b_pay_with_split atomic split, live 2026-05-18) ──
|
|
1035
|
+
if (chain === "solana") {
|
|
1036
|
+
if (!challenge.pay_solana) {
|
|
1037
|
+
throw new X402Error(`Bridge ${provider.name} returned 402 without a pay_solana block. ` +
|
|
1038
|
+
`Either pick chain: "polygon" or ask the operator to set ` +
|
|
1039
|
+
`BRIDGE_MERCHANT_SOLANA on the bridge service.`);
|
|
1040
|
+
}
|
|
1041
|
+
const ps = challenge.pay_solana;
|
|
1042
|
+
// Guard: the bridge controls the challenge — verify the demanded
|
|
1043
|
+
// amount is in the same ballpark as the declared cost / caps before
|
|
1044
|
+
// signing anything. Stops a misquoting bridge from draining the agent.
|
|
1045
|
+
{
|
|
1046
|
+
const lamports = Number(ps.total_lamports ?? ps.merchant_amount_lamports);
|
|
1047
|
+
const solUsd = parseFloat(process.env.AIFINPAY_SOL_USD ?? "200");
|
|
1048
|
+
const estUsd = (Number.isFinite(lamports) ? lamports / 1e9 : 0) * solUsd;
|
|
1049
|
+
const guarded = this.guardChallengeAmount(estUsd, cost, provider.name);
|
|
1050
|
+
if (!guarded)
|
|
1051
|
+
return null;
|
|
1052
|
+
}
|
|
1053
|
+
const solTxSig = await this.submitSolanaB2BPayWithSplit(ps);
|
|
1054
|
+
const paidResp = await this.inner.fetchImpl(fullUrl, buildInit({
|
|
1055
|
+
"x-solana-tx": solTxSig,
|
|
1056
|
+
"x-order-id": ps.order_id,
|
|
1057
|
+
}));
|
|
1058
|
+
if (!paidResp.ok) {
|
|
1059
|
+
const detail = await paidResp.text().catch(() => "<unreadable>");
|
|
1060
|
+
throw new AiFinPayError(`Bridge retry failed ${paidResp.status} after Solana payment ${solTxSig}: ${detail.slice(0, 300)}`);
|
|
1061
|
+
}
|
|
1062
|
+
// Money moved here, and only here. The reservation becomes a
|
|
1063
|
+
// settled amount; the finally below then has nothing to release.
|
|
1064
|
+
this.spend24h.add(cost);
|
|
1065
|
+
if (typeof reservation === "string") {
|
|
1066
|
+
await this.ledger.commit(reservation, cost);
|
|
1067
|
+
}
|
|
1068
|
+
settled = true;
|
|
1069
|
+
if (this.telemetry)
|
|
1070
|
+
this.reportTelemetry({ kind: "call", provider: provider.name, chain, cost, tx: solTxSig });
|
|
1071
|
+
// @internal — attach settlement metadata for consumers (MCP, telemetry
|
|
1072
|
+
// dashboards) that need to surface the tx hash without an extra RPC
|
|
1073
|
+
// call. Response headers are read-only after construction so we use
|
|
1074
|
+
// an instance property + cast on the read side.
|
|
1075
|
+
paidResp.aifinpayTx = solTxSig;
|
|
1076
|
+
paidResp.aifinpayChain = "solana";
|
|
1077
|
+
return paidResp;
|
|
1078
|
+
}
|
|
1079
|
+
// ── EVM branch (B2BSplitter.payMatic — generic native-token atomic split) ──
|
|
1080
|
+
// Settles on any chain in SPLITTER_DEPLOYMENTS (polygon default; base,
|
|
1081
|
+
// optimism, unichain, botchain, xrplevm). Native token only — the
|
|
1082
|
+
// deployed splitter payment path has no ERC-20/USDC entrypoint.
|
|
1083
|
+
if (!challenge.pay_matic) {
|
|
1084
|
+
throw new X402Error(`bridge ${provider.name} returned 402 but no pay_matic block — only legacy AiFinPay/Coinbase facilitators not yet wired into AiFinPayAgent.call()`);
|
|
1085
|
+
}
|
|
1086
|
+
const pm = challenge.pay_matic;
|
|
1087
|
+
const deployment = SPLITTER_DEPLOYMENTS[chain];
|
|
1088
|
+
if (!deployment) {
|
|
1089
|
+
throw new AiFinPayError(`No B2BSplitter deployment registered for chain "${chain}" — supported: ${Object.keys(SPLITTER_DEPLOYMENTS).join(", ")}`);
|
|
1090
|
+
}
|
|
1091
|
+
// Refuse to pay a quote denominated for another chain's native token:
|
|
1092
|
+
// total_wei quoted for POL on Polygon would be a massive overpay if
|
|
1093
|
+
// blindly re-sent as ETH on Base. Legacy bridges always emit "polygon".
|
|
1094
|
+
if (pm.chain && pm.chain !== chain) {
|
|
1095
|
+
throw new X402Error(`bridge ${provider.name} quoted pay_matic for chain "${pm.chain}" but the call was routed to "${chain}" — refusing cross-denomination payment`);
|
|
1096
|
+
}
|
|
1097
|
+
// Guard: same ballpark check as the Solana branch — never sign for an
|
|
1098
|
+
// amount wildly above the declared cost / per-call cap. Native-token
|
|
1099
|
+
// USD price per chain via SPLITTER_DEPLOYMENTS.nativeUsdEnv.
|
|
972
1100
|
{
|
|
973
|
-
const
|
|
974
|
-
const
|
|
975
|
-
|
|
1101
|
+
const wei = Number(pm.total_wei);
|
|
1102
|
+
const { usd: nativeUsd } = await this.nativeUsdFor(deployment);
|
|
1103
|
+
// NaN when no price is known — guardChallengeAmount then declines to
|
|
1104
|
+
// block rather than blocking on a guess. See nativeUsdFor().
|
|
1105
|
+
const estUsd = (Number.isFinite(wei) ? wei / 1e18 : 0) * nativeUsd;
|
|
976
1106
|
const guarded = this.guardChallengeAmount(estUsd, cost, provider.name);
|
|
977
1107
|
if (!guarded)
|
|
978
1108
|
return null;
|
|
979
1109
|
}
|
|
980
|
-
|
|
1110
|
+
// 2. Submit the B2BSplitter payment on the selected chain's mainnet and
|
|
1111
|
+
// wait for it to land. Prefer the challenge's splitter address (current
|
|
1112
|
+
// bridge behaviour); fall back to the registry address for bridges that
|
|
1113
|
+
// omit it.
|
|
1114
|
+
const splitterAddress = pm.splitter
|
|
1115
|
+
?? deployment.splitter;
|
|
1116
|
+
const txHash = await this.settleSplitterNative({
|
|
1117
|
+
chain,
|
|
1118
|
+
splitter: splitterAddress,
|
|
1119
|
+
splitterVersion: pm.splitter_version,
|
|
1120
|
+
merchantWallet: pm.merchant_wallet,
|
|
1121
|
+
totalWei: BigInt(pm.total_wei),
|
|
1122
|
+
orderId: pm.order_id,
|
|
1123
|
+
ipCreator: pm.ip_creator,
|
|
1124
|
+
});
|
|
1125
|
+
// 3. Retry the bridge with payment proof.
|
|
981
1126
|
const paidResp = await this.inner.fetchImpl(fullUrl, buildInit({
|
|
982
|
-
"x-
|
|
983
|
-
"x-order-id":
|
|
1127
|
+
"x-tx-hash": txHash,
|
|
1128
|
+
"x-order-id": pm.order_id,
|
|
984
1129
|
}));
|
|
985
1130
|
if (!paidResp.ok) {
|
|
986
1131
|
const detail = await paidResp.text().catch(() => "<unreadable>");
|
|
987
|
-
throw new AiFinPayError(`Bridge retry failed ${paidResp.status} after
|
|
1132
|
+
throw new AiFinPayError(`Bridge retry failed ${paidResp.status} after on-chain payment ${txHash}: ${detail.slice(0, 300)}`);
|
|
988
1133
|
}
|
|
1134
|
+
// Money moved here, and only here. The reservation becomes a
|
|
1135
|
+
// settled amount; the finally below then has nothing to release.
|
|
989
1136
|
this.spend24h.add(cost);
|
|
1137
|
+
if (typeof reservation === "string") {
|
|
1138
|
+
await this.ledger.commit(reservation, cost);
|
|
1139
|
+
}
|
|
1140
|
+
settled = true;
|
|
990
1141
|
if (this.telemetry)
|
|
991
|
-
this.reportTelemetry({ kind: "call", provider: provider.name, chain, cost, tx:
|
|
992
|
-
// @internal —
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
// an instance property + cast on the read side.
|
|
996
|
-
paidResp.aifinpayTx = solTxSig;
|
|
997
|
-
paidResp.aifinpayChain = "solana";
|
|
1142
|
+
this.reportTelemetry({ kind: "call", provider: provider.name, chain, cost, tx: txHash });
|
|
1143
|
+
// @internal — see Solana branch above for rationale on property-attach.
|
|
1144
|
+
paidResp.aifinpayTx = txHash;
|
|
1145
|
+
paidResp.aifinpayChain = chain;
|
|
998
1146
|
return paidResp;
|
|
999
1147
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1148
|
+
finally {
|
|
1149
|
+
// Every path that did not move money gives the budget back now rather
|
|
1150
|
+
// than waiting for the reservation to expire — an early return, a
|
|
1151
|
+
// refused challenge, a revert, a thrown error. Missing one of them
|
|
1152
|
+
// would leak the cap and eventually stop the agent paying at all,
|
|
1153
|
+
// which is why this is a finally and not a branch.
|
|
1154
|
+
if (typeof reservation === "string" && !settled) {
|
|
1155
|
+
await this.ledger.release(reservation);
|
|
1156
|
+
}
|
|
1006
1157
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1158
|
+
}
|
|
1159
|
+
// ── EVM B2BSplitter native settlement — one quote in, one tx hash out ────
|
|
1160
|
+
//
|
|
1161
|
+
// Extracted from call() when a second caller needed the same settlement.
|
|
1162
|
+
// The version handling below is the reason it is one method and not two
|
|
1163
|
+
// copies: it was already wrong once, and a duplicate would only be fixed
|
|
1164
|
+
// in whichever copy the next revert happened to come from.
|
|
1165
|
+
//
|
|
1166
|
+
// Returns only after the transaction is included AND succeeded — a hash for
|
|
1167
|
+
// a reverted transaction would otherwise be handed to a merchant as proof of
|
|
1168
|
+
// a payment that never moved.
|
|
1169
|
+
async settleSplitterNative(p) {
|
|
1170
|
+
// call() has already checked this for the bridge flow; repeated here
|
|
1171
|
+
// because settlement is now reachable without going through call().
|
|
1172
|
+
const deployment = SPLITTER_DEPLOYMENTS[p.chain];
|
|
1009
1173
|
if (!deployment) {
|
|
1010
|
-
throw new AiFinPayError(`No B2BSplitter deployment registered for chain "${chain}" — supported: ${Object.keys(SPLITTER_DEPLOYMENTS).join(", ")}`);
|
|
1011
|
-
}
|
|
1012
|
-
// Refuse to pay a quote denominated for another chain's native token:
|
|
1013
|
-
// total_wei quoted for POL on Polygon would be a massive overpay if
|
|
1014
|
-
// blindly re-sent as ETH on Base. Legacy bridges always emit "polygon".
|
|
1015
|
-
if (pm.chain && pm.chain !== chain) {
|
|
1016
|
-
throw new X402Error(`bridge ${provider.name} quoted pay_matic for chain "${pm.chain}" but the call was routed to "${chain}" — refusing cross-denomination payment`);
|
|
1017
|
-
}
|
|
1018
|
-
// Guard: same ballpark check as the Solana branch — never sign for an
|
|
1019
|
-
// amount wildly above the declared cost / per-call cap. Native-token
|
|
1020
|
-
// USD price per chain via SPLITTER_DEPLOYMENTS.nativeUsdEnv.
|
|
1021
|
-
{
|
|
1022
|
-
const wei = Number(pm.total_wei);
|
|
1023
|
-
const { usd: nativeUsd } = await this.nativeUsdFor(deployment);
|
|
1024
|
-
// NaN when no price is known — guardChallengeAmount then declines to
|
|
1025
|
-
// block rather than blocking on a guess. See nativeUsdFor().
|
|
1026
|
-
const estUsd = (Number.isFinite(wei) ? wei / 1e18 : 0) * nativeUsd;
|
|
1027
|
-
const guarded = this.guardChallengeAmount(estUsd, cost, provider.name);
|
|
1028
|
-
if (!guarded)
|
|
1029
|
-
return null;
|
|
1174
|
+
throw new AiFinPayError(`No B2BSplitter deployment registered for chain "${p.chain}" — supported: ${Object.keys(SPLITTER_DEPLOYMENTS).join(", ")}`);
|
|
1030
1175
|
}
|
|
1031
|
-
//
|
|
1032
|
-
//
|
|
1033
|
-
//
|
|
1034
|
-
//
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
// strand the 1bp inside B2BSplitter — the contract has no sweep function.
|
|
1038
|
-
const splitterAddress = pm.splitter
|
|
1039
|
-
?? deployment.splitter;
|
|
1040
|
-
const ipCreator = pm.ip_creator
|
|
1041
|
-
?? await this.splitterTreasury(splitterAddress, chain)
|
|
1176
|
+
// ipCreator routing: prefer the caller's explicit ip_creator; else route
|
|
1177
|
+
// the royalty slot to the splitter's treasury (mirrors the Solana branch).
|
|
1178
|
+
// Passing address(0) would skip the transfer and permanently strand the
|
|
1179
|
+
// 1bp inside B2BSplitter — the contract has no sweep function.
|
|
1180
|
+
const ipCreator = p.ipCreator
|
|
1181
|
+
?? await this.splitterTreasury(p.splitter, p.chain)
|
|
1042
1182
|
?? "0x0000000000000000000000000000000000000000";
|
|
1043
|
-
const { publicClient, walletClient } = this.splitterClients(chain);
|
|
1183
|
+
const { publicClient, walletClient } = this.splitterClients(p.chain);
|
|
1044
1184
|
// The entrypoint follows the deployed contract, not the SDK release: v1.2
|
|
1045
1185
|
// (Polygon, Optimism, BOT Chain, XRPL EVM as of 2026-07-31) takes a bytes32
|
|
1046
1186
|
// paymentId and rejects one it has already settled, while Base and Unichain
|
|
1047
1187
|
// still run v1.1. Sending v1.2 calldata to a v1.1 contract reverts with no
|
|
1048
1188
|
// useful reason, so this must be decided per chain.
|
|
1049
|
-
// An explicit `
|
|
1189
|
+
// An explicit `splitterVersion` wins — a server that states it knows what
|
|
1050
1190
|
// it deployed. What it must NOT fall back to is this registry's
|
|
1051
|
-
// chain -> version entry, because the ADDRESS came from the
|
|
1191
|
+
// chain -> version entry, because the ADDRESS came from the server and
|
|
1052
1192
|
// the version would come from a table: two sources that can disagree.
|
|
1053
1193
|
//
|
|
1054
1194
|
// In production they did. The Exa bridge still hands out the pre-v1.2
|
|
@@ -1058,58 +1198,116 @@ export class AiFinPayAgent {
|
|
|
1058
1198
|
//
|
|
1059
1199
|
// So when the server is silent, ask the contract at the address we were
|
|
1060
1200
|
// actually handed. The registry is used only if the chain cannot be read.
|
|
1061
|
-
const splitterVersion =
|
|
1062
|
-
?? await this.detectSplitterVersion(
|
|
1063
|
-
await this.assertCanAffordNative(publicClient, deployment,
|
|
1201
|
+
const splitterVersion = p.splitterVersion
|
|
1202
|
+
?? await this.detectSplitterVersion(p.splitter, p.chain, deployment.version);
|
|
1203
|
+
await this.assertCanAffordNative(publicClient, deployment, p.totalWei);
|
|
1064
1204
|
const txHash = splitterVersion === "1.2"
|
|
1065
1205
|
? await walletClient.writeContract({
|
|
1066
|
-
address:
|
|
1206
|
+
address: p.splitter,
|
|
1067
1207
|
abi: SPLITTER_PAY_NATIVE_ABI,
|
|
1068
1208
|
functionName: "payNative",
|
|
1069
1209
|
args: [
|
|
1070
|
-
paymentIdFor(
|
|
1071
|
-
|
|
1210
|
+
paymentIdFor(p.orderId),
|
|
1211
|
+
p.merchantWallet,
|
|
1072
1212
|
ipCreator,
|
|
1073
|
-
|
|
1213
|
+
p.orderId,
|
|
1074
1214
|
],
|
|
1075
|
-
value:
|
|
1215
|
+
value: p.totalWei,
|
|
1076
1216
|
chain: deployment.chain,
|
|
1077
1217
|
account: this.evmAccount,
|
|
1078
1218
|
})
|
|
1079
1219
|
: await walletClient.writeContract({
|
|
1080
|
-
address:
|
|
1220
|
+
address: p.splitter,
|
|
1081
1221
|
abi: SPLITTER_PAY_MATIC_ABI,
|
|
1082
1222
|
functionName: "payMatic",
|
|
1083
1223
|
args: [
|
|
1084
|
-
|
|
1224
|
+
p.merchantWallet,
|
|
1085
1225
|
ipCreator,
|
|
1086
|
-
|
|
1226
|
+
p.orderId,
|
|
1087
1227
|
],
|
|
1088
|
-
value:
|
|
1228
|
+
value: p.totalWei,
|
|
1089
1229
|
chain: deployment.chain,
|
|
1090
1230
|
account: this.evmAccount,
|
|
1091
1231
|
});
|
|
1092
|
-
//
|
|
1232
|
+
// Wait for receipt (inclusion is enough on these fast-block chains).
|
|
1093
1233
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
1094
1234
|
if (receipt.status !== "success") {
|
|
1095
1235
|
throw new AiFinPayError(`${deployment.chain.name} tx reverted: ${txHash}`);
|
|
1096
1236
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1237
|
+
return txHash;
|
|
1238
|
+
}
|
|
1239
|
+
// ── AIFP-1 merchant paywall (gateway.aifinpay.io) ───────────────────────
|
|
1240
|
+
//
|
|
1241
|
+
// The protocol lives in aifp1.ts; this is the wiring. Two things only the
|
|
1242
|
+
// agent can supply: the on-chain settlement above, and the budget caps —
|
|
1243
|
+
// aifp1Fetch owns neither, exactly as call() owns them for the bridge flow.
|
|
1244
|
+
_aifp1Cache = new Aifp1ReceiptCache();
|
|
1245
|
+
/**
|
|
1246
|
+
* The prepaid batches this agent is holding.
|
|
1247
|
+
*
|
|
1248
|
+
* Exposed because a batch is money the agent has already spent and has not
|
|
1249
|
+
* finished using: an operator deciding whether to shut an agent down, or a
|
|
1250
|
+
* test asserting that a receipt was reused, both need to see it. The entries
|
|
1251
|
+
* contain bearer JWTs — treat them like keys, and do not log them.
|
|
1252
|
+
*/
|
|
1253
|
+
get aifp1Receipts() { return this._aifp1Cache; }
|
|
1254
|
+
/**
|
|
1255
|
+
* Fetch a paywalled URL, paying the AIFP-1 gateway if it asks.
|
|
1256
|
+
*
|
|
1257
|
+
* const res = await agent.fetchPaid("https://gateway.aifinpay.io/acme/articles/2026/x");
|
|
1258
|
+
*
|
|
1259
|
+
* A URL that is not paywalled — or that answers a 402 belonging to some
|
|
1260
|
+
* other protocol — comes back untouched and costs nothing. A paywalled one
|
|
1261
|
+
* is quoted, settled on-chain, exchanged for a receipt and retried, and the
|
|
1262
|
+
* receipt is kept: subsequent calls it covers cost a header rather than a
|
|
1263
|
+
* transaction. See aifp1.ts for why that reuse is the entire design.
|
|
1264
|
+
*
|
|
1265
|
+
* Returns `null` on the same terms as call(): a budget cap was hit and
|
|
1266
|
+
* `budgetCaps.on_limit_exceeded` is "skip".
|
|
1267
|
+
*/
|
|
1268
|
+
async fetchPaid(url, init = {}, opts = {}) {
|
|
1269
|
+
const deployment = SPLITTER_DEPLOYMENTS.polygon;
|
|
1270
|
+
const deps = {
|
|
1271
|
+
fetchImpl: this.inner.fetchImpl,
|
|
1272
|
+
cache: this._aifp1Cache,
|
|
1273
|
+
// A 0x address, because AIFP agent policies are address-keyed
|
|
1274
|
+
// (backend/aifp/agent-policy.js normalizeAddress) — a Solana pubkey here
|
|
1275
|
+
// would silently opt the agent out of its owner's own limits.
|
|
1276
|
+
agentId: opts.agentId ?? this.evmAddress,
|
|
1277
|
+
settle: (p) => this.settleSplitterNative({
|
|
1278
|
+
// Polygon-only, and not by preference: /v1/pay verifies the settlement
|
|
1279
|
+
// by reading the Splitter's Payment event, and that verifier implements
|
|
1280
|
+
// Polygon alone (backend/aifp/verify-settlement.js — Solana returns
|
|
1281
|
+
// notImplemented, anything else unsupported_chain). Settling elsewhere
|
|
1282
|
+
// would move real money for a receipt that can never be issued.
|
|
1283
|
+
chain: "polygon",
|
|
1284
|
+
// The address is not carried in the quote, so it comes from this SDK's
|
|
1285
|
+
// own verified registry. The backend checks the tx against its
|
|
1286
|
+
// configured SPLITTER_ADDRESS_POLYGON; if an operator has pointed that
|
|
1287
|
+
// somewhere else, /v1/pay answers no_splitter_payment_event, which is
|
|
1288
|
+
// loud. Override here if you are running against such a deployment.
|
|
1289
|
+
splitter: opts.splitter ?? deployment.splitter,
|
|
1290
|
+
// Left undetected on purpose — settleSplitterNative asks the contract,
|
|
1291
|
+
// which is the only source that cannot disagree with itself.
|
|
1292
|
+
merchantWallet: p.merchantWallet,
|
|
1293
|
+
totalWei: p.totalWei,
|
|
1294
|
+
orderId: p.orderId,
|
|
1295
|
+
}),
|
|
1296
|
+
checkPerCall: (usd) => this.checkPerCall(usd),
|
|
1297
|
+
reserveDaily: (usd) => this.reserveDaily(usd),
|
|
1298
|
+
commit: (id, usd) => this.ledger.commit(id, usd),
|
|
1299
|
+
release: (id) => this.ledger.release(id),
|
|
1300
|
+
onPaid: ({ merchantId, amountUsd, txRef }) => {
|
|
1301
|
+
this.spend24h.add(amountUsd);
|
|
1302
|
+
if (this.telemetry) {
|
|
1303
|
+
this.reportTelemetry({
|
|
1304
|
+
kind: "aifp1", merchant: merchantId, chain: "polygon",
|
|
1305
|
+
cost: amountUsd, tx: txRef,
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
},
|
|
1309
|
+
};
|
|
1310
|
+
return aifp1Fetch(deps, url, init, opts);
|
|
1113
1311
|
}
|
|
1114
1312
|
// ── Solana b2b_pay_with_split — build, sign, send via @solana/web3.js ───
|
|
1115
1313
|
//
|