@agether/sdk 1.5.5 → 1.6.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/cli.js CHANGED
@@ -862,27 +862,23 @@ var X402Client_exports = {};
862
862
  __export(X402Client_exports, {
863
863
  X402Client: () => X402Client
864
864
  });
865
- function chainIdFromNetwork(network) {
866
- const m = network.match(/^eip155:(\d+)$/);
867
- return m ? Number(m[1]) : 1;
868
- }
869
- var import_ethers2, USDC_DOMAINS, X402Client;
865
+ var import_fetch, import_client, import_client2, import_accounts, X402Client;
870
866
  var init_X402Client = __esm({
871
867
  "src/clients/X402Client.ts"() {
872
868
  "use strict";
873
- import_ethers2 = require("ethers");
874
- USDC_DOMAINS = {
875
- "eip155:1": { name: "USD Coin", version: "2", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
876
- "eip155:8453": { name: "USD Coin", version: "2", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
877
- "eip155:84532": { name: "USD Coin", version: "2", address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e" },
878
- "eip155:42161": { name: "USD Coin", version: "2", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" },
879
- "eip155:10": { name: "USD Coin", version: "2", address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
880
- };
869
+ import_fetch = require("@x402/fetch");
870
+ import_client = require("@x402/core/client");
871
+ import_client2 = require("@x402/evm/exact/client");
872
+ import_accounts = require("viem/accounts");
881
873
  X402Client = class {
882
874
  constructor(config) {
883
875
  this.config = config;
884
- const provider = new import_ethers2.ethers.JsonRpcProvider(config.rpcUrl);
885
- this.wallet = new import_ethers2.ethers.Wallet(config.privateKey, provider);
876
+ const privateKey = config.privateKey.startsWith("0x") ? config.privateKey : `0x${config.privateKey}`;
877
+ const signer = (0, import_accounts.privateKeyToAccount)(privateKey);
878
+ this.address = signer.address;
879
+ const client = new import_client.x402Client();
880
+ (0, import_client2.registerExactEvmScheme)(client, { signer });
881
+ this.paidFetch = (0, import_fetch.wrapFetchWithPayment)(fetch, client);
886
882
  }
887
883
  async get(url, opts) {
888
884
  return this.request(url, { ...opts, method: "GET" });
@@ -896,13 +892,13 @@ var init_X402Client = __esm({
896
892
  });
897
893
  }
898
894
  getAddress() {
899
- return this.wallet.address;
895
+ return this.address;
900
896
  }
901
- // ──────────── Core request / 402-retry loop ────────────
897
+ // ──────────── Core request — @x402/fetch handles 402 automatically ────────────
902
898
  async request(url, options) {
903
899
  try {
904
- console.log(" [1/4] Calling resource server\u2026");
905
- const response = await fetch(url, {
900
+ console.log(` [x402] ${options?.method || "GET"} ${url}`);
901
+ const response = await this.paidFetch(url, {
906
902
  ...options,
907
903
  headers: {
908
904
  ...options?.headers,
@@ -911,45 +907,13 @@ var init_X402Client = __esm({
911
907
  });
912
908
  if (response.ok) {
913
909
  const data = await response.json();
914
- return { success: true, data };
915
- }
916
- if (response.status !== 402) {
917
- return { success: false, error: `HTTP ${response.status}: ${await response.text()}` };
918
- }
919
- console.log(" [2/4] 402 received \u2014 parsing payment requirements\u2026");
920
- const parsed = await this.parsePaymentRequired(response);
921
- if (!parsed) {
922
- return { success: false, error: "Could not parse payment requirements from 402 response" };
923
- }
924
- const { requirements, resource } = parsed;
925
- console.log(` scheme : ${requirements.scheme}`);
926
- console.log(` network : ${requirements.network}`);
927
- console.log(` amount : ${requirements.amount} (atomic)`);
928
- console.log(` asset : ${requirements.asset}`);
929
- console.log(` payTo : ${requirements.payTo}`);
930
- console.log(" [3/4] Signing EIP-3009 transferWithAuthorization\u2026");
931
- const paymentPayload = await this.buildPaymentPayload(requirements, resource, url);
932
- const paymentB64 = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
933
- await this.riskCheck(paymentPayload, requirements);
934
- console.log(" [4/4] Retrying with PAYMENT-SIGNATURE header\u2026");
935
- const paidResponse = await fetch(url, {
936
- ...options,
937
- headers: {
938
- ...options?.headers,
939
- "X-Agent-Id": this.config.agentId || "",
940
- // v2 header
941
- "PAYMENT-SIGNATURE": paymentB64,
942
- // v1 compat header (some servers still use this)
943
- "X-PAYMENT": paymentB64
944
- }
945
- });
946
- if (paidResponse.ok) {
947
- const data = await paidResponse.json();
948
- const settlementHeader = paidResponse.headers.get("PAYMENT-RESPONSE") || paidResponse.headers.get("X-PAYMENT-RESPONSE");
910
+ const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
949
911
  let txHash;
950
- if (settlementHeader) {
912
+ if (paymentResponse) {
951
913
  try {
952
- const settlement = JSON.parse(Buffer.from(settlementHeader, "base64").toString("utf-8"));
914
+ const settlement = JSON.parse(
915
+ Buffer.from(paymentResponse, "base64").toString("utf-8")
916
+ );
953
917
  txHash = settlement.transaction;
954
918
  } catch {
955
919
  }
@@ -957,164 +921,26 @@ var init_X402Client = __esm({
957
921
  return {
958
922
  success: true,
959
923
  data,
960
- paymentInfo: {
961
- amount: requirements.amount,
962
- asset: requirements.extra?.name || "USDC",
963
- network: requirements.network,
964
- txHash
965
- }
924
+ ...txHash ? {
925
+ paymentInfo: {
926
+ amount: "",
927
+ asset: "USDC",
928
+ network: "eip155:8453",
929
+ txHash
930
+ }
931
+ } : {}
966
932
  };
967
933
  }
968
- const errBody = await paidResponse.text();
969
- return { success: false, error: `Payment rejected (HTTP ${paidResponse.status}): ${errBody}` };
934
+ const errBody = await response.text();
935
+ return {
936
+ success: false,
937
+ error: `HTTP ${response.status}: ${errBody}`
938
+ };
970
939
  } catch (error) {
971
- return { success: false, error: `Request failed: ${error instanceof Error ? error.message : String(error)}` };
972
- }
973
- }
974
- // ──────────── Parse 402 response ────────────
975
- async parsePaymentRequired(response) {
976
- const prHeader = response.headers.get("PAYMENT-REQUIRED") || response.headers.get("x-payment-required");
977
- if (prHeader) {
978
- try {
979
- const decoded = JSON.parse(Buffer.from(prHeader, "base64").toString("utf-8"));
980
- if (decoded.accepts?.length) {
981
- return { requirements: decoded.accepts[0], resource: decoded.resource };
982
- }
983
- } catch {
984
- }
985
- }
986
- try {
987
- const body = await response.json();
988
- if (body.accepts && Array.isArray(body.accepts) && body.accepts.length > 0) {
989
- return { requirements: body.accepts[0], resource: body.resource };
990
- }
991
- if (body.paymentRequirements) {
992
- const pr = Array.isArray(body.paymentRequirements) ? body.paymentRequirements[0] : body.paymentRequirements;
993
- return { requirements: pr, resource: body.resource };
994
- }
995
- if (body.scheme && body.network) {
996
- return { requirements: body, resource: body.resource };
997
- }
998
- } catch {
999
- }
1000
- const wwwAuth = response.headers.get("WWW-Authenticate");
1001
- if (wwwAuth) {
1002
- const m = wwwAuth.match(/x402[^"]*"([^"]+)"/);
1003
- if (m) {
1004
- try {
1005
- const decoded = JSON.parse(Buffer.from(m[1], "base64").toString("utf-8"));
1006
- const reqs = Array.isArray(decoded) ? decoded[0] : decoded;
1007
- return { requirements: reqs };
1008
- } catch {
1009
- }
1010
- }
1011
- }
1012
- return null;
1013
- }
1014
- // ──────────── Build x402 v2 PaymentPayload with EIP-3009 ────────────
1015
- //
1016
- // If an AgentAccount is configured, we use it as the `from` address
1017
- // (smart wallet pays directly). The AgentAccount implements EIP-1271
1018
- // so USDC's transferWithAuthorization will call isValidSignature()
1019
- // to verify the owner's ECDSA signature. The facilitator detects
1020
- // the >65-byte or smart-wallet case and uses the bytes overload.
1021
- async buildPaymentPayload(reqs, resource, url) {
1022
- const now = Math.floor(Date.now() / 1e3);
1023
- const validAfter = String(now - 60);
1024
- const validBefore = String(now + (reqs.maxTimeoutSeconds || 300));
1025
- const nonce = import_ethers2.ethers.hexlify(import_ethers2.ethers.randomBytes(32));
1026
- const chainId = chainIdFromNetwork(reqs.network);
1027
- const usdcDomain = USDC_DOMAINS[reqs.network] || USDC_DOMAINS["eip155:1"];
1028
- const payerAddress = this.config.accountAddress || this.wallet.address;
1029
- const isSmartWallet = !!this.config.accountAddress;
1030
- const domain = {
1031
- name: usdcDomain.name,
1032
- version: usdcDomain.version,
1033
- chainId,
1034
- verifyingContract: reqs.asset || usdcDomain.address
1035
- };
1036
- const types = {
1037
- TransferWithAuthorization: [
1038
- { name: "from", type: "address" },
1039
- { name: "to", type: "address" },
1040
- { name: "value", type: "uint256" },
1041
- { name: "validAfter", type: "uint256" },
1042
- { name: "validBefore", type: "uint256" },
1043
- { name: "nonce", type: "bytes32" }
1044
- ]
1045
- };
1046
- const value = {
1047
- from: payerAddress,
1048
- // AgentAccount or EOA
1049
- to: reqs.payTo,
1050
- value: reqs.amount,
1051
- validAfter,
1052
- validBefore,
1053
- nonce
1054
- };
1055
- let signature = await this.wallet.signTypedData(domain, types, value);
1056
- if (isSmartWallet) {
1057
- signature = signature + "00";
1058
- }
1059
- if (isSmartWallet) {
1060
- console.log(` \u2713 Signed for AgentAccount ${payerAddress.slice(0, 10)}\u2026 (EIP-1271, chain=${chainId})`);
1061
- } else {
1062
- console.log(` \u2713 Signed (from=${payerAddress.slice(0, 10)}\u2026, chain=${chainId})`);
1063
- }
1064
- return {
1065
- x402Version: 2,
1066
- resource: resource || { url, description: "", mimeType: "application/json" },
1067
- accepted: {
1068
- scheme: reqs.scheme,
1069
- network: reqs.network,
1070
- amount: reqs.amount,
1071
- asset: reqs.asset,
1072
- payTo: reqs.payTo,
1073
- maxTimeoutSeconds: reqs.maxTimeoutSeconds,
1074
- extra: reqs.extra || {}
1075
- },
1076
- payload: {
1077
- signature,
1078
- authorization: {
1079
- from: payerAddress,
1080
- // AgentAccount address — facilitator checks balance here
1081
- to: reqs.payTo,
1082
- value: reqs.amount,
1083
- validAfter,
1084
- validBefore,
1085
- nonce
1086
- }
1087
- }
1088
- };
1089
- }
1090
- // ──────────── Risk check via our backend ────────────
1091
- async riskCheck(paymentPayload, reqs) {
1092
- try {
1093
- const verifyUrl = `${this.config.backendUrl}/x402/verify`;
1094
- const resp = await fetch(verifyUrl, {
1095
- method: "POST",
1096
- headers: {
1097
- "Content-Type": "application/json",
1098
- "X-Agent-Id": this.config.agentId || "",
1099
- ...this.config.accountAddress ? { "X-Agent-Account": this.config.accountAddress } : {}
1100
- },
1101
- body: JSON.stringify({
1102
- x402Version: 2,
1103
- paymentPayload,
1104
- paymentRequirements: reqs
1105
- }),
1106
- signal: AbortSignal.timeout(5e3)
1107
- });
1108
- if (resp.ok) {
1109
- const result = await resp.json();
1110
- const decision = resp.headers.get("X-Risk-Decision") || (result.isValid ? "allow" : "unknown");
1111
- const score = resp.headers.get("X-Risk-Score") || "?";
1112
- console.log(` \u2713 Risk check: ${decision} (score=${score})`);
1113
- } else {
1114
- console.log(` \u26A0 Risk check failed (HTTP ${resp.status}) \u2014 continuing anyway`);
1115
- }
1116
- } catch {
1117
- console.log(" \u26A0 Risk check unavailable \u2014 continuing");
940
+ return {
941
+ success: false,
942
+ error: `Request failed: ${error instanceof Error ? error.message : String(error)}`
943
+ };
1118
944
  }
1119
945
  }
1120
946
  };
@@ -1122,7 +948,7 @@ var init_X402Client = __esm({
1122
948
  });
1123
949
 
1124
950
  // src/cli.ts
1125
- var import_ethers3 = require("ethers");
951
+ var import_ethers2 = require("ethers");
1126
952
  var fs = __toESM(require("fs"));
1127
953
  var path = __toESM(require("path"));
1128
954
  var os = __toESM(require("os"));
@@ -1228,7 +1054,7 @@ async function cmdInit(privateKey, agentId) {
1228
1054
  const backendUrl = process.env.AGETHER_BACKEND_URL || DEFAULT_BACKEND;
1229
1055
  let wallet;
1230
1056
  try {
1231
- wallet = new import_ethers3.ethers.Wallet(privateKey);
1057
+ wallet = new import_ethers2.ethers.Wallet(privateKey);
1232
1058
  } catch {
1233
1059
  console.error("\u274C Invalid private key");
1234
1060
  process.exit(1);
@@ -1243,8 +1069,8 @@ async function cmdInit(privateKey, agentId) {
1243
1069
  }
1244
1070
  async function cmdRegister(name) {
1245
1071
  const config = requireConfig();
1246
- const provider = new import_ethers3.ethers.JsonRpcProvider(config.rpcUrl);
1247
- const signer = new import_ethers3.ethers.Wallet(config.privateKey, provider);
1072
+ const provider = new import_ethers2.ethers.JsonRpcProvider(config.rpcUrl);
1073
+ const signer = new import_ethers2.ethers.Wallet(config.privateKey, provider);
1248
1074
  const agentName = name || `Agent-${signer.address.slice(0, 8)}`;
1249
1075
  console.log(`\u{1F916} Registering agent: ${agentName}
1250
1076
  `);
@@ -1267,7 +1093,7 @@ async function cmdRegister(name) {
1267
1093
  process.exit(1);
1268
1094
  }
1269
1095
  console.log(" [2/4] Registering on ERC-8004 IdentityRegistry...");
1270
- const agentRegistry = new import_ethers3.ethers.Contract(registryAddr, ERC8004_ABI, signer);
1096
+ const agentRegistry = new import_ethers2.ethers.Contract(registryAddr, ERC8004_ABI, signer);
1271
1097
  let agentId;
1272
1098
  if (config.agentId && config.agentId !== "0") {
1273
1099
  agentId = BigInt(config.agentId);
@@ -1298,7 +1124,7 @@ async function cmdRegister(name) {
1298
1124
  const agentURI = `data:application/json;base64,${Buffer.from(registrationFile).toString("base64")}`;
1299
1125
  const tx = await agentRegistry["register(string)"](agentURI);
1300
1126
  const receipt = await waitForTx(tx);
1301
- const transferTopic = import_ethers3.ethers.id("Transfer(address,address,uint256)");
1127
+ const transferTopic = import_ethers2.ethers.id("Transfer(address,address,uint256)");
1302
1128
  const transferLog = receipt.logs.find((log) => log.topics[0] === transferTopic);
1303
1129
  if (transferLog && transferLog.topics.length >= 4) {
1304
1130
  agentId = BigInt(transferLog.topics[3]);
@@ -1331,11 +1157,11 @@ async function cmdRegister(name) {
1331
1157
  if (chainId === 31337 || chainId === 1) {
1332
1158
  console.log(" [3/4] Minting test USDC (Hardhat fork)...");
1333
1159
  const deployerPk = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
1334
- const deployer = new import_ethers3.ethers.Wallet(deployerPk, provider);
1160
+ const deployer = new import_ethers2.ethers.Wallet(deployerPk, provider);
1335
1161
  const usdcAddr = contracts.usdc;
1336
1162
  if (usdcAddr) {
1337
1163
  try {
1338
- const usdc = new import_ethers3.ethers.Contract(usdcAddr, MOCK_ERC20_ABI, deployer);
1164
+ const usdc = new import_ethers2.ethers.Contract(usdcAddr, MOCK_ERC20_ABI, deployer);
1339
1165
  const tx = await usdc.mint(signer.address, BigInt(5e10));
1340
1166
  await waitForTx(tx);
1341
1167
  console.log(" \u2713 Minted $50,000 USDC");
@@ -1348,7 +1174,7 @@ async function cmdRegister(name) {
1348
1174
  }
1349
1175
  console.log(" [4/4] Creating AgentAccount...");
1350
1176
  if (factoryAddr) {
1351
- const factory = new import_ethers3.ethers.Contract(factoryAddr, ACCOUNT_FACTORY_ABI2, signer);
1177
+ const factory = new import_ethers2.ethers.Contract(factoryAddr, ACCOUNT_FACTORY_ABI2, signer);
1352
1178
  try {
1353
1179
  const exists = await factory.accountExists(agentId);
1354
1180
  if (exists) {
@@ -1366,7 +1192,7 @@ async function cmdRegister(name) {
1366
1192
  }
1367
1193
  }
1368
1194
  if (validationAddr) {
1369
- const vr = new import_ethers3.ethers.Contract(validationAddr, VALIDATION_REGISTRY_ABI, provider);
1195
+ const vr = new import_ethers2.ethers.Contract(validationAddr, VALIDATION_REGISTRY_ABI, provider);
1370
1196
  try {
1371
1197
  const approved = await vr.isAgentCodeApproved(agentId);
1372
1198
  console.log(`
@@ -1587,7 +1413,7 @@ async function cmdX402Call(url, method = "GET", body) {
1587
1413
  const config = requireConfig();
1588
1414
  console.log("\n\u{1F510} x402 Paid API Call\n");
1589
1415
  const x402 = await getX402Client(config);
1590
- console.log(` Wallet: ${new import_ethers3.ethers.Wallet(config.privateKey).address}`);
1416
+ console.log(` Wallet: ${new import_ethers2.ethers.Wallet(config.privateKey).address}`);
1591
1417
  console.log(`
1592
1418
  \u{1F4E1} ${method} ${url}`);
1593
1419
  if (body) console.log(`\u{1F4E6} Body: ${body}`);
package/dist/index.d.mts CHANGED
@@ -399,22 +399,17 @@ declare class MorphoClient {
399
399
  /**
400
400
  * x402 HTTP Client — Make paid API calls via the x402 protocol (v2)
401
401
  *
402
- * Implements the Coinbase x402 spec:
403
- * https://github.com/coinbase/x402
402
+ * Built on top of the official @x402/fetch + @x402/evm SDK.
403
+ * https://docs.x402.org/getting-started/quickstart-for-buyers
404
404
  *
405
405
  * Flow:
406
406
  * 1. Client → Resource Server (normal request)
407
- * 2. Resource Server → 402 with PaymentRequired JSON body
408
- * Body: { x402Version, error, resource, accepts: [PaymentRequirements…] }
409
- * 3. Client picks a PaymentRequirements from `accepts`,
410
- * signs an EIP-3009 transferWithAuthorization (EIP-712 typed data),
411
- * builds a PaymentPayload, base64-encodes it as PAYMENT-SIGNATURE header
412
- * 4. Client → Resource Server (retries with PAYMENT-SIGNATURE)
413
- * 5. Resource Server forwards to Facilitator /verify → /settle
414
- * 6. Resource Server → 200 + data (or error)
407
+ * 2. Resource Server → 402 with PAYMENT-REQUIRED header (base64 JSON)
408
+ * 3. @x402/fetch auto-picks PaymentRequirements, signs EIP-3009 via EVM scheme
409
+ * 4. Client Resource Server (retries with PAYMENT-SIGNATURE header)
410
+ * 5. Resource Server verifies via facilitator → settles → 200 + data
415
411
  *
416
- * Chain support: Base (8453), Ethereum (1), and Hardhat fork (31337).
417
- * USDC domain is resolved per-chain from USDC_DOMAINS map.
412
+ * Chain support: Base (8453), Base Sepolia (84532), Ethereum (1).
418
413
  */
419
414
  interface X402Config {
420
415
  privateKey: string;
@@ -445,16 +440,14 @@ interface PaymentRequirements {
445
440
  extra?: Record<string, unknown>;
446
441
  }
447
442
  declare class X402Client {
448
- private wallet;
449
443
  private config;
444
+ private paidFetch;
445
+ private address;
450
446
  constructor(config: X402Config);
451
447
  get<T = unknown>(url: string, opts?: RequestInit): Promise<X402Response<T>>;
452
448
  post<T = unknown>(url: string, body?: unknown, opts?: RequestInit): Promise<X402Response<T>>;
453
449
  getAddress(): string;
454
450
  private request;
455
- private parsePaymentRequired;
456
- private buildPaymentPayload;
457
- private riskCheck;
458
451
  }
459
452
 
460
453
  /**
package/dist/index.d.ts CHANGED
@@ -399,22 +399,17 @@ declare class MorphoClient {
399
399
  /**
400
400
  * x402 HTTP Client — Make paid API calls via the x402 protocol (v2)
401
401
  *
402
- * Implements the Coinbase x402 spec:
403
- * https://github.com/coinbase/x402
402
+ * Built on top of the official @x402/fetch + @x402/evm SDK.
403
+ * https://docs.x402.org/getting-started/quickstart-for-buyers
404
404
  *
405
405
  * Flow:
406
406
  * 1. Client → Resource Server (normal request)
407
- * 2. Resource Server → 402 with PaymentRequired JSON body
408
- * Body: { x402Version, error, resource, accepts: [PaymentRequirements…] }
409
- * 3. Client picks a PaymentRequirements from `accepts`,
410
- * signs an EIP-3009 transferWithAuthorization (EIP-712 typed data),
411
- * builds a PaymentPayload, base64-encodes it as PAYMENT-SIGNATURE header
412
- * 4. Client → Resource Server (retries with PAYMENT-SIGNATURE)
413
- * 5. Resource Server forwards to Facilitator /verify → /settle
414
- * 6. Resource Server → 200 + data (or error)
407
+ * 2. Resource Server → 402 with PAYMENT-REQUIRED header (base64 JSON)
408
+ * 3. @x402/fetch auto-picks PaymentRequirements, signs EIP-3009 via EVM scheme
409
+ * 4. Client Resource Server (retries with PAYMENT-SIGNATURE header)
410
+ * 5. Resource Server verifies via facilitator → settles → 200 + data
415
411
  *
416
- * Chain support: Base (8453), Ethereum (1), and Hardhat fork (31337).
417
- * USDC domain is resolved per-chain from USDC_DOMAINS map.
412
+ * Chain support: Base (8453), Base Sepolia (84532), Ethereum (1).
418
413
  */
419
414
  interface X402Config {
420
415
  privateKey: string;
@@ -445,16 +440,14 @@ interface PaymentRequirements {
445
440
  extra?: Record<string, unknown>;
446
441
  }
447
442
  declare class X402Client {
448
- private wallet;
449
443
  private config;
444
+ private paidFetch;
445
+ private address;
450
446
  constructor(config: X402Config);
451
447
  get<T = unknown>(url: string, opts?: RequestInit): Promise<X402Response<T>>;
452
448
  post<T = unknown>(url: string, body?: unknown, opts?: RequestInit): Promise<X402Response<T>>;
453
449
  getAddress(): string;
454
450
  private request;
455
- private parsePaymentRequired;
456
- private buildPaymentPayload;
457
- private riskCheck;
458
451
  }
459
452
 
460
453
  /**