@devlab.group/agent-commerce 2.2.1 → 2.4.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/README.md +20 -16
- package/dist/ap2.d.ts +6 -5
- package/dist/ap2.js +3 -3
- package/dist/{authorization-CMkIuAkO.d.ts → authorization-DjAecwuW.d.ts} +1 -1
- package/dist/{chunk-REBY2IEP.js → chunk-4OEXK3YG.js} +4 -4
- package/dist/{chunk-REBY2IEP.js.map → chunk-4OEXK3YG.js.map} +1 -1
- package/dist/{chunk-2DAJAJI7.js → chunk-6WACRJVT.js} +3 -3
- package/dist/{chunk-2DAJAJI7.js.map → chunk-6WACRJVT.js.map} +1 -1
- package/dist/{chunk-XYHDQ22D.js → chunk-AITMDXKW.js} +3 -3
- package/dist/{chunk-XYHDQ22D.js.map → chunk-AITMDXKW.js.map} +1 -1
- package/dist/{chunk-BNUD4RBN.js → chunk-WUIAUAA7.js} +200 -8
- package/dist/chunk-WUIAUAA7.js.map +1 -0
- package/dist/cli/{ap2-HLBIUSTK.js → ap2-QDHPRSTF.js} +3 -3
- package/dist/cli/{ap2-HLBIUSTK.js.map → ap2-QDHPRSTF.js.map} +1 -1
- package/dist/cli/{chunk-QZ6TOMX6.js → chunk-AZDWFVDW.js} +200 -8
- package/dist/cli/chunk-AZDWFVDW.js.map +1 -0
- package/dist/cli/{chunk-SNM3OVCY.js → chunk-DCMW67JM.js} +19 -5
- package/dist/cli/chunk-DCMW67JM.js.map +1 -0
- package/dist/cli/{chunk-ILUYEQSV.js → chunk-G2JEY7MB.js} +26 -9
- package/dist/cli/chunk-G2JEY7MB.js.map +1 -0
- package/dist/cli/{chunk-2LN5PO5I.js → chunk-PIMFPCNZ.js} +3 -2
- package/dist/cli/chunk-PIMFPCNZ.js.map +1 -0
- package/dist/cli/chunk-UXB65XCS.js +8 -0
- package/dist/cli/{chunk-QY3K6PEQ.js.map → chunk-UXB65XCS.js.map} +1 -1
- package/dist/cli/{chunk-KTV52MCU.js → chunk-WYOGIANL.js} +3 -3
- package/dist/cli/{chunk-KTV52MCU.js.map → chunk-WYOGIANL.js.map} +1 -1
- package/dist/cli/{config-VYAJGZXE.js → config-UI4EDG4L.js} +5 -5
- package/dist/cli/{config-VYAJGZXE.js.map → config-UI4EDG4L.js.map} +1 -1
- package/dist/cli/index.js +98 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-HFD7ZNCQ.js → mcp-26LJMN4N.js} +3 -3
- package/dist/cli/{mcp-HFD7ZNCQ.js.map → mcp-26LJMN4N.js.map} +1 -1
- package/dist/cli/{provider-JV5HCQGR.js → provider-Z4OJNAYI.js} +5 -5
- package/dist/cli/{provider-JV5HCQGR.js.map → provider-Z4OJNAYI.js.map} +1 -1
- package/dist/cli/{run-WV44B62Y.js → run-TEPYJUHG.js} +33 -12
- package/dist/cli/run-TEPYJUHG.js.map +1 -0
- package/dist/cli/{x402-NADFV5CD.js → x402-BMVONZKA.js} +6 -6
- package/dist/cli/{x402-NADFV5CD.js.map → x402-BMVONZKA.js.map} +1 -1
- package/dist/{constants-nackLItD.d.ts → constants-BG22tE8S.d.ts} +2 -1
- package/dist/index.d.ts +35 -12
- package/dist/index.js +61 -11
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +5 -4
- package/dist/mcp.js +1 -1
- package/dist/mpp.d.ts +5 -4
- package/dist/mpp.js +3 -3
- package/dist/{networks-DTWRlj-K.d.ts → networks-DDHYJLcg.d.ts} +2 -1
- package/dist/{protocol-adapter-CfxU8Z2T.d.ts → protocol-adapter-C9odYl6l.d.ts} +4 -3
- package/dist/{runtime-7vLNYvmU.d.ts → runtime-Cl_BLVZV.d.ts} +8 -1
- package/dist/{types-CVw6Sf46.d.ts → types-j7MnUXYN.d.ts} +2 -1
- package/dist/x402.d.ts +27 -18
- package/dist/x402.js +4 -4
- package/package.json +6 -6
- package/dist/chunk-BNUD4RBN.js.map +0 -1
- package/dist/cli/chunk-2LN5PO5I.js.map +0 -1
- package/dist/cli/chunk-ILUYEQSV.js.map +0 -1
- package/dist/cli/chunk-QY3K6PEQ.js +0 -8
- package/dist/cli/chunk-QZ6TOMX6.js.map +0 -1
- package/dist/cli/chunk-SNM3OVCY.js.map +0 -1
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/run-WV44B62Y.js.map +0 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, x402OfferName } from './chunk-
|
|
1
|
+
import { isWellKnownDevKey, assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, x402OfferName } from './chunk-WYOGIANL.js';
|
|
2
2
|
import { findX402Network, normalizeAddress, X402_DEFAULT_PAYMENT_FLOW, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY, SETTLE_AFTER_BACKEND_METADATA_KEY, sameAddress, LOCAL_CHAIN_ID, isTransactionReference, isEvmAddress, describeDeploymentMode } from './chunk-OZ4LAWBK.js';
|
|
3
3
|
import { computeReplayKey, computePermit2ReplayKey } from './chunk-OSTCU6ZK.js';
|
|
4
|
-
import { PACKAGE_VERSION } from './chunk-
|
|
4
|
+
import { PACKAGE_VERSION } from './chunk-UXB65XCS.js';
|
|
5
5
|
import { CommerceError, systemClock, NOOP_LOGGER, redactedErrorText } from './chunk-QQ3WY5L3.js';
|
|
6
6
|
import { isRecord } from './chunk-3M6U7ILB.js';
|
|
7
7
|
import { x402ExactPermit2ProxyAddress, toFacilitatorEvmSigner, PERMIT2_ADDRESS } from '@x402/evm';
|
|
8
|
-
import { isAddress, getAddress, formatUnits, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, BaseError, ContractFunctionRevertedError, erc20Abi } from 'viem';
|
|
8
|
+
import { isAddress, keccak256, stringToBytes, getAddress, formatUnits, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, BaseError, ContractFunctionRevertedError, erc20Abi } from 'viem';
|
|
9
9
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
10
|
import { HTTPFacilitatorClient } from '@x402/core/http';
|
|
11
11
|
import { SettleError, VerifyError } from '@x402/core/types';
|
|
12
12
|
import { x402Facilitator } from '@x402/core/facilitator';
|
|
13
13
|
import { registerExactEvmScheme } from '@x402/evm/exact/facilitator';
|
|
14
|
+
import { randomBytes } from 'crypto';
|
|
14
15
|
import { PaymentPayloadV2Schema } from '@x402/core/schemas';
|
|
15
16
|
|
|
16
17
|
// src/payments/x402/provider/constants.ts
|
|
@@ -799,6 +800,172 @@ function offerCurrency(offer, quoted) {
|
|
|
799
800
|
const canonical = offer.profile.canonicalAsset;
|
|
800
801
|
return canonical !== void 0 && sameAddress(offer.profile, offer.asset, canonical.address) ? canonical.symbol : quoted;
|
|
801
802
|
}
|
|
803
|
+
|
|
804
|
+
// src/core/canonical-json.ts
|
|
805
|
+
var LONE_SURROGATE = new RegExp("\\p{Cs}", "u");
|
|
806
|
+
function canonicalJson(value) {
|
|
807
|
+
if (typeof value === "string")
|
|
808
|
+
return LONE_SURROGATE.test(value) ? void 0 : JSON.stringify(value);
|
|
809
|
+
if (typeof value === "number") return Number.isFinite(value) ? JSON.stringify(value) : void 0;
|
|
810
|
+
if (value === null || typeof value === "boolean") return JSON.stringify(value);
|
|
811
|
+
if (Array.isArray(value)) {
|
|
812
|
+
const items = value.map(canonicalJson);
|
|
813
|
+
return items.includes(void 0) ? void 0 : `[${items.join(",")}]`;
|
|
814
|
+
}
|
|
815
|
+
if (typeof value !== "object") return void 0;
|
|
816
|
+
const members = [];
|
|
817
|
+
for (const key of Object.keys(value).sort()) {
|
|
818
|
+
const member = canonicalJson(value[key]);
|
|
819
|
+
if (member === void 0 || LONE_SURROGATE.test(key)) return void 0;
|
|
820
|
+
members.push(`${JSON.stringify(key)}:${member}`);
|
|
821
|
+
}
|
|
822
|
+
return `{${members.join(",")}}`;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/payments/x402/provider/quote.ts
|
|
826
|
+
var QUOTE_EXTENSION = "erc-8409";
|
|
827
|
+
var QUOTE_REQUEST_SCHEME = "agent-commerce/request/v1";
|
|
828
|
+
var QUOTE_DOMAIN = { name: "Signed Service Payment Quotes", version: "1" };
|
|
829
|
+
var QUOTE_TYPES = {
|
|
830
|
+
ServicePaymentQuote: [
|
|
831
|
+
{ name: "issuer", type: "address" },
|
|
832
|
+
{ name: "payer", type: "address" },
|
|
833
|
+
{ name: "recipient", type: "address" },
|
|
834
|
+
{ name: "asset", type: "address" },
|
|
835
|
+
{ name: "amount", type: "uint256" },
|
|
836
|
+
{ name: "requestScheme", type: "string" },
|
|
837
|
+
{ name: "requestHash", type: "bytes32" },
|
|
838
|
+
{ name: "quoteId", type: "bytes32" },
|
|
839
|
+
{ name: "validAfter", type: "uint64" },
|
|
840
|
+
{ name: "validUntil", type: "uint64" }
|
|
841
|
+
]
|
|
842
|
+
};
|
|
843
|
+
var BEARER = "0x0000000000000000000000000000000000000000";
|
|
844
|
+
var QUOTE_INFO_SCHEMA = {
|
|
845
|
+
type: "object",
|
|
846
|
+
required: ["quotes"],
|
|
847
|
+
properties: {
|
|
848
|
+
quotes: {
|
|
849
|
+
type: "array",
|
|
850
|
+
items: {
|
|
851
|
+
type: "object",
|
|
852
|
+
required: ["chainId", "quote", "signature"],
|
|
853
|
+
properties: {
|
|
854
|
+
chainId: { type: "string" },
|
|
855
|
+
// Every field is a string in the ERC's JSON encoding
|
|
856
|
+
quote: {
|
|
857
|
+
type: "object",
|
|
858
|
+
required: QUOTE_TYPES.ServicePaymentQuote.map((field) => field.name),
|
|
859
|
+
properties: Object.fromEntries(
|
|
860
|
+
QUOTE_TYPES.ServicePaymentQuote.map((field) => [field.name, { type: "string" }])
|
|
861
|
+
)
|
|
862
|
+
},
|
|
863
|
+
signature: { type: "string" }
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
var QUOTE_CACHE_LIMIT = 1024;
|
|
870
|
+
function createQuoteIssuer(options) {
|
|
871
|
+
const { signerPrivateKey, offers, deploymentMode, clock, maxTimeoutSeconds } = options;
|
|
872
|
+
let account;
|
|
873
|
+
try {
|
|
874
|
+
account = privateKeyToAccount(signerPrivateKey);
|
|
875
|
+
} catch (cause) {
|
|
876
|
+
throw new CommerceError(
|
|
877
|
+
"CONFIG_INVALID",
|
|
878
|
+
'x402 provider: quote.signerPrivateKey is not a valid private key (expected "0x" followed by 64 hex characters)',
|
|
879
|
+
{ cause }
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
if (deploymentMode !== "local" && isWellKnownDevKey(signerPrivateKey)) {
|
|
883
|
+
throw new CommerceError(
|
|
884
|
+
"CONFIG_INVALID",
|
|
885
|
+
"x402 provider: quote.signerPrivateKey is a well-known Anvil development key, so anyone could sign quotes as this gateway. Use a dedicated key outside the local chain."
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
const evmOffers = offers.filter((offer) => offer.family === "evm");
|
|
889
|
+
if (evmOffers.length === 0) {
|
|
890
|
+
throw new CommerceError(
|
|
891
|
+
"CONFIG_INVALID",
|
|
892
|
+
"x402 provider: quote needs an EVM offer; ERC-8409 quotes cover EVM networks only"
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
const issuer = account.address;
|
|
896
|
+
if (evmOffers.some((offer) => offer.payTo.toLowerCase() === issuer.toLowerCase())) {
|
|
897
|
+
throw new CommerceError(
|
|
898
|
+
"CONFIG_INVALID",
|
|
899
|
+
"x402 provider: quote.signerPrivateKey controls a payTo address. Use a dedicated key, not the merchant wallet."
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
const cache = /* @__PURE__ */ new Map();
|
|
903
|
+
async function quoteFor(offer, amount, requestHash) {
|
|
904
|
+
const now = Math.floor(clock.now().getTime() / 1e3);
|
|
905
|
+
const { chainId } = offer.profile;
|
|
906
|
+
const key = [
|
|
907
|
+
chainId,
|
|
908
|
+
offer.payTo.toLowerCase(),
|
|
909
|
+
offer.asset.toLowerCase(),
|
|
910
|
+
amount,
|
|
911
|
+
requestHash
|
|
912
|
+
].join("|");
|
|
913
|
+
const cached = cache.get(key);
|
|
914
|
+
if (cached !== void 0 && Number(cached.quote.validUntil) - now >= maxTimeoutSeconds) {
|
|
915
|
+
return cached;
|
|
916
|
+
}
|
|
917
|
+
const validUntil = now + 2 * maxTimeoutSeconds;
|
|
918
|
+
const quote = {
|
|
919
|
+
issuer,
|
|
920
|
+
payer: BEARER,
|
|
921
|
+
recipient: offer.payTo,
|
|
922
|
+
asset: offer.asset,
|
|
923
|
+
amount,
|
|
924
|
+
requestScheme: QUOTE_REQUEST_SCHEME,
|
|
925
|
+
requestHash,
|
|
926
|
+
// Use a new ID for each signed body, as the ERC requires
|
|
927
|
+
quoteId: `0x${randomBytes(32).toString("hex")}`,
|
|
928
|
+
validAfter: String(now),
|
|
929
|
+
validUntil: String(validUntil)
|
|
930
|
+
};
|
|
931
|
+
const signature = await account.signTypedData({
|
|
932
|
+
domain: { ...QUOTE_DOMAIN, chainId },
|
|
933
|
+
types: QUOTE_TYPES,
|
|
934
|
+
primaryType: "ServicePaymentQuote",
|
|
935
|
+
message: {
|
|
936
|
+
...quote,
|
|
937
|
+
amount: BigInt(amount),
|
|
938
|
+
validAfter: BigInt(now),
|
|
939
|
+
validUntil: BigInt(validUntil)
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
const signed = { chainId: String(chainId), quote, signature };
|
|
943
|
+
cache.delete(key);
|
|
944
|
+
if (cache.size >= QUOTE_CACHE_LIMIT) {
|
|
945
|
+
const oldest = cache.keys().next().value;
|
|
946
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
947
|
+
}
|
|
948
|
+
cache.set(key, signed);
|
|
949
|
+
return signed;
|
|
950
|
+
}
|
|
951
|
+
return {
|
|
952
|
+
issuer,
|
|
953
|
+
async extensionsFor(resourceId, input, quoted) {
|
|
954
|
+
if (quoted.length === 0) return void 0;
|
|
955
|
+
const requestHash = quoteRequestHash(resourceId, input);
|
|
956
|
+
if (requestHash === void 0) return void 0;
|
|
957
|
+
const quotes = [];
|
|
958
|
+
for (const { offer, amount } of quoted) {
|
|
959
|
+
quotes.push(await quoteFor(offer, amount, requestHash));
|
|
960
|
+
}
|
|
961
|
+
return { [QUOTE_EXTENSION]: { info: { quotes }, schema: QUOTE_INFO_SCHEMA } };
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
function quoteRequestHash(resourceId, input) {
|
|
966
|
+
const canonical = canonicalJson({ input, resource: resourceId });
|
|
967
|
+
return canonical === void 0 ? void 0 : keccak256(stringToBytes(canonical));
|
|
968
|
+
}
|
|
802
969
|
function decodePaymentSubmission(payloadBase64) {
|
|
803
970
|
const json = decodeJson(payloadBase64);
|
|
804
971
|
if (json === void 0) return void 0;
|
|
@@ -885,6 +1052,14 @@ function createRequirementBuilders(ctx, svmFeePayer) {
|
|
|
885
1052
|
}))
|
|
886
1053
|
);
|
|
887
1054
|
const single = offers.length === 1 ? offers[0] : void 0;
|
|
1055
|
+
const extensions = await ctx.quotes?.extensionsFor(
|
|
1056
|
+
context.resource.id,
|
|
1057
|
+
context.input,
|
|
1058
|
+
offers.flatMap((offer, index) => {
|
|
1059
|
+
const accepted = accepts[index];
|
|
1060
|
+
return offer.family === "evm" && accepted ? [{ offer, amount: accepted.amount }] : [];
|
|
1061
|
+
})
|
|
1062
|
+
);
|
|
888
1063
|
const resourceId = encodeURIComponent(context.resource.id);
|
|
889
1064
|
const envelope = {
|
|
890
1065
|
x402Version: X402_VERSION,
|
|
@@ -895,7 +1070,8 @@ function createRequirementBuilders(ctx, svmFeePayer) {
|
|
|
895
1070
|
// delivery carries the backend's own type when it is text and fits the body
|
|
896
1071
|
mimeType: options.resourceMimeTypes?.[context.resource.id] ?? DEFAULT_MIME_TYPE
|
|
897
1072
|
},
|
|
898
|
-
accepts
|
|
1073
|
+
accepts,
|
|
1074
|
+
...extensions !== void 0 ? { extensions } : {}
|
|
899
1075
|
};
|
|
900
1076
|
const expiresAt = new Date(clock.now().getTime() + maxTimeoutSeconds * 1e3).toISOString();
|
|
901
1077
|
return {
|
|
@@ -1321,6 +1497,13 @@ function createX402PaymentProvider(options) {
|
|
|
1321
1497
|
const ids = options.ids ?? DEFAULT_IDS;
|
|
1322
1498
|
const logger = options.logger ?? NOOP_LOGGER;
|
|
1323
1499
|
const maxTimeoutSeconds = options.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;
|
|
1500
|
+
const quotes = options.quote ? createQuoteIssuer({
|
|
1501
|
+
signerPrivateKey: options.quote.signerPrivateKey,
|
|
1502
|
+
offers,
|
|
1503
|
+
deploymentMode,
|
|
1504
|
+
clock,
|
|
1505
|
+
maxTimeoutSeconds
|
|
1506
|
+
}) : void 0;
|
|
1324
1507
|
const evmOffers = offers.filter((offer) => offer.family === "evm");
|
|
1325
1508
|
const hasSvm = offers.some((offer) => offer.family === "svm");
|
|
1326
1509
|
const hasNear = offers.some((offer) => offer.family === "near");
|
|
@@ -1344,7 +1527,8 @@ function createX402PaymentProvider(options) {
|
|
|
1344
1527
|
`mode=${deploymentMode}`,
|
|
1345
1528
|
"authorization-flow",
|
|
1346
1529
|
"upfront-flow",
|
|
1347
|
-
...severalOffers ? ["multiple-offers"] : []
|
|
1530
|
+
...severalOffers ? ["multiple-offers"] : [],
|
|
1531
|
+
...quotes ? ["erc-8409-quotes"] : []
|
|
1348
1532
|
],
|
|
1349
1533
|
status: "stable",
|
|
1350
1534
|
unsupported: [
|
|
@@ -1376,6 +1560,7 @@ function createX402PaymentProvider(options) {
|
|
|
1376
1560
|
ids,
|
|
1377
1561
|
logger,
|
|
1378
1562
|
maxTimeoutSeconds,
|
|
1563
|
+
quotes,
|
|
1379
1564
|
svm,
|
|
1380
1565
|
near
|
|
1381
1566
|
};
|
|
@@ -1394,7 +1579,14 @@ function createX402PaymentProvider(options) {
|
|
|
1394
1579
|
...severalOffers ? { selectRequirement } : {},
|
|
1395
1580
|
verify,
|
|
1396
1581
|
settle,
|
|
1397
|
-
health
|
|
1582
|
+
health,
|
|
1583
|
+
...quotes ? {
|
|
1584
|
+
quote: {
|
|
1585
|
+
issuer: quotes.issuer,
|
|
1586
|
+
requestScheme: QUOTE_REQUEST_SCHEME,
|
|
1587
|
+
extension: QUOTE_EXTENSION
|
|
1588
|
+
}
|
|
1589
|
+
} : {}
|
|
1398
1590
|
};
|
|
1399
1591
|
}
|
|
1400
1592
|
function loadOptionalModule(load, missing) {
|
|
@@ -1409,5 +1601,5 @@ function loadOptionalModule(load, missing) {
|
|
|
1409
1601
|
}
|
|
1410
1602
|
|
|
1411
1603
|
export { DEFAULT_IDS, chainIdFromCaip2, createX402PaymentProvider, parseCanonicalAmount };
|
|
1412
|
-
//# sourceMappingURL=chunk-
|
|
1413
|
-
//# sourceMappingURL=chunk-
|
|
1604
|
+
//# sourceMappingURL=chunk-AZDWFVDW.js.map
|
|
1605
|
+
//# sourceMappingURL=chunk-AZDWFVDW.js.map
|