@zeroxyz/cli 0.0.8 → 0.0.10
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/index.js +168 -153
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command as Command8 } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@zeroxyz/cli",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.10",
|
|
10
10
|
type: "module",
|
|
11
11
|
bin: {
|
|
12
12
|
zero: "dist/index.js",
|
|
@@ -36,6 +36,8 @@ var package_default = {
|
|
|
36
36
|
"@relayprotocol/relay-sdk": "^5.2.1",
|
|
37
37
|
"@x402/core": "^2.9.0",
|
|
38
38
|
"@x402/evm": "^2.9.0",
|
|
39
|
+
"@x402/extensions": "^2.9.0",
|
|
40
|
+
"@x402/fetch": "^2.9.0",
|
|
39
41
|
commander: "^13.0.0",
|
|
40
42
|
mppx: "^0.5.9",
|
|
41
43
|
open: "^11.0.0",
|
|
@@ -149,11 +151,13 @@ var fetchCommand = (appContext2) => new Command2("fetch").description("Fetch a c
|
|
|
149
151
|
if (options.data && !headers["content-type"]) {
|
|
150
152
|
headers["content-type"] = "application/json";
|
|
151
153
|
}
|
|
154
|
+
const log = (msg) => console.error(` ${msg}`);
|
|
152
155
|
const requestInit = {
|
|
153
156
|
method: options.data ? "POST" : "GET",
|
|
154
157
|
headers,
|
|
155
158
|
body: options.data
|
|
156
159
|
};
|
|
160
|
+
log(`Calling ${url}...`);
|
|
157
161
|
const response = await fetch(url, requestInit);
|
|
158
162
|
const paymentReq = detectPaymentRequirement(
|
|
159
163
|
response.headers,
|
|
@@ -162,11 +166,15 @@ var fetchCommand = (appContext2) => new Command2("fetch").description("Fetch a c
|
|
|
162
166
|
let finalResponse;
|
|
163
167
|
let paymentMeta;
|
|
164
168
|
if (paymentReq) {
|
|
169
|
+
log(
|
|
170
|
+
`Payment required (${paymentReq.protocol}) \u2014 preparing payment...`
|
|
171
|
+
);
|
|
165
172
|
const result = await paymentService.handlePayment(
|
|
166
173
|
url,
|
|
167
174
|
requestInit,
|
|
168
175
|
paymentReq,
|
|
169
|
-
options.maxPay
|
|
176
|
+
options.maxPay,
|
|
177
|
+
log
|
|
170
178
|
);
|
|
171
179
|
finalResponse = result.response;
|
|
172
180
|
paymentMeta = {
|
|
@@ -176,6 +184,9 @@ var fetchCommand = (appContext2) => new Command2("fetch").description("Fetch a c
|
|
|
176
184
|
amount: result.amount,
|
|
177
185
|
asset: result.asset
|
|
178
186
|
};
|
|
187
|
+
log(
|
|
188
|
+
`Paid ${result.amount} ${result.asset} via ${result.protocol} on ${result.chain}`
|
|
189
|
+
);
|
|
179
190
|
} else {
|
|
180
191
|
finalResponse = response;
|
|
181
192
|
}
|
|
@@ -222,10 +233,25 @@ var fetchCommand = (appContext2) => new Command2("fetch").description("Fetch a c
|
|
|
222
233
|
paymentMode: "charge"
|
|
223
234
|
}
|
|
224
235
|
});
|
|
236
|
+
console.error(`
|
|
237
|
+
Run ID: ${runResult.runId}`);
|
|
225
238
|
console.error(
|
|
226
|
-
`
|
|
227
|
-
|
|
228
|
-
|
|
239
|
+
` Leave a review to help other agents discover great capabilities:`
|
|
240
|
+
);
|
|
241
|
+
console.error(
|
|
242
|
+
` zero review ${runResult.runId} --success --accuracy 5 --value 4 --reliability 5 --content "your feedback"`
|
|
243
|
+
);
|
|
244
|
+
console.error(
|
|
245
|
+
[
|
|
246
|
+
``,
|
|
247
|
+
` Tips for a great review:`,
|
|
248
|
+
` --success / --no-success Did the API return the result you expected?`,
|
|
249
|
+
` --accuracy 1-5 How correct was the response? (1 = wrong, 5 = perfect)`,
|
|
250
|
+
` --value 1-5 Was it worth the price? (1 = overpriced, 5 = great deal)`,
|
|
251
|
+
` --reliability 1-5 Did it respond quickly and without errors? (1 = flaky, 5 = rock solid)`,
|
|
252
|
+
` --content Free-text is optional but helps other agents pick the best capability.`,
|
|
253
|
+
``
|
|
254
|
+
].join("\n")
|
|
229
255
|
);
|
|
230
256
|
} catch {
|
|
231
257
|
}
|
|
@@ -502,7 +528,19 @@ var initCommand = (appContext2) => new Command4("init").description("Initialize
|
|
|
502
528
|
|
|
503
529
|
// src/commands/review-command.ts
|
|
504
530
|
import { Command as Command5 } from "commander";
|
|
505
|
-
var reviewCommand = (appContext2) => new Command5("review").description("Submit a review for a capability run").
|
|
531
|
+
var reviewCommand = (appContext2) => new Command5("review").description("Submit a review for a capability run").addHelpText(
|
|
532
|
+
"after",
|
|
533
|
+
`
|
|
534
|
+
Tips for a great review:
|
|
535
|
+
--success / --no-success Did the API return the result you expected?
|
|
536
|
+
--accuracy 1-5 How correct was the response? (1 = wrong, 5 = perfect)
|
|
537
|
+
--value 1-5 Was it worth the price? (1 = overpriced, 5 = great deal)
|
|
538
|
+
--reliability 1-5 Did it respond quickly and without errors? (1 = flaky, 5 = rock solid)
|
|
539
|
+
--content Free-text is optional but helps other agents pick the best capability.
|
|
540
|
+
|
|
541
|
+
Example:
|
|
542
|
+
zero review run_abc123 --success --accuracy 5 --value 4 --reliability 5 --content "Fast, accurate translation"`
|
|
543
|
+
).argument("<runId>", "Run ID to review").option("--success", "The capability succeeded").option("--no-success", "The capability failed").requiredOption("--accuracy <n>", "Accuracy rating (1-5)", Number.parseInt).requiredOption("--value <n>", "Value rating (1-5)", Number.parseInt).requiredOption(
|
|
506
544
|
"--reliability <n>",
|
|
507
545
|
"Reliability rating (1-5)",
|
|
508
546
|
Number.parseInt
|
|
@@ -621,6 +659,7 @@ ${address}`);
|
|
|
621
659
|
if (url) {
|
|
622
660
|
await open(url);
|
|
623
661
|
console.log("Opened funding page in your browser.");
|
|
662
|
+
console.log(`If it didn't open, visit: ${url}`);
|
|
624
663
|
console.log(`Your wallet address: ${address}`);
|
|
625
664
|
analyticsService.capture("wallet_funded", {
|
|
626
665
|
method: "browser",
|
|
@@ -810,6 +849,7 @@ var capabilityResponseSchema = z2.object({
|
|
|
810
849
|
method: z2.string(),
|
|
811
850
|
headers: z2.record(z2.string(), z2.string()).nullable(),
|
|
812
851
|
bodySchema: z2.record(z2.string(), z2.unknown()).nullable(),
|
|
852
|
+
responseSchema: z2.record(z2.string(), z2.unknown()).nullable(),
|
|
813
853
|
example: z2.object({ request: z2.unknown(), response: z2.unknown() }).nullable(),
|
|
814
854
|
tags: z2.array(z2.string()).nullable(),
|
|
815
855
|
displayCostAmount: z2.string(),
|
|
@@ -922,18 +962,17 @@ var ApiService = class {
|
|
|
922
962
|
// src/services/payment-service.ts
|
|
923
963
|
import {
|
|
924
964
|
adaptViemWallet,
|
|
965
|
+
convertViemChainToRelayChain,
|
|
925
966
|
createClient as createRelayClient,
|
|
926
967
|
getClient as getRelayClient,
|
|
927
968
|
MAINNET_RELAY_API
|
|
928
969
|
} from "@relayprotocol/relay-sdk";
|
|
929
970
|
import { x402Client as X402Client } from "@x402/core/client";
|
|
930
|
-
import {
|
|
931
|
-
decodePaymentRequiredHeader,
|
|
932
|
-
decodePaymentResponseHeader,
|
|
933
|
-
encodePaymentSignatureHeader
|
|
934
|
-
} from "@x402/core/http";
|
|
971
|
+
import { decodePaymentResponseHeader, x402HTTPClient } from "@x402/core/http";
|
|
935
972
|
import { ExactEvmScheme } from "@x402/evm/exact/client";
|
|
936
|
-
import {
|
|
973
|
+
import { createSIWxClientHook } from "@x402/extensions/sign-in-with-x";
|
|
974
|
+
import { wrapFetchWithPayment } from "@x402/fetch";
|
|
975
|
+
import { Receipt } from "mppx";
|
|
937
976
|
import { Mppx, tempo } from "mppx/client";
|
|
938
977
|
import {
|
|
939
978
|
createPublicClient,
|
|
@@ -949,8 +988,12 @@ var PATHUSD_TEMPO = "0x20c0000000000000000000000000000000000000";
|
|
|
949
988
|
var BASE_CHAIN_ID = 8453;
|
|
950
989
|
var TEMPO_CHAIN_ID = 4217;
|
|
951
990
|
var TEMPO_TESTNET_CHAIN_ID = 42431;
|
|
952
|
-
var
|
|
953
|
-
var
|
|
991
|
+
var DEFAULT_MAX_DEPOSIT = "100";
|
|
992
|
+
var buildRelayClientOptions = () => ({
|
|
993
|
+
baseApiUrl: MAINNET_RELAY_API,
|
|
994
|
+
source: "zero-cli",
|
|
995
|
+
chains: [convertViemChainToRelayChain(base)]
|
|
996
|
+
});
|
|
954
997
|
var calculateBuffer = (baseBalance) => {
|
|
955
998
|
const twentyFivePercent = baseBalance / 4n;
|
|
956
999
|
const twoDollars = 2000000n;
|
|
@@ -986,39 +1029,14 @@ var PaymentService = class {
|
|
|
986
1029
|
this.account = account;
|
|
987
1030
|
this.config = config;
|
|
988
1031
|
}
|
|
989
|
-
x402Client = null;
|
|
990
|
-
mppxClient = null;
|
|
991
1032
|
relayInitialized = false;
|
|
992
|
-
getX402Client = () => {
|
|
993
|
-
if (!this.x402Client) {
|
|
994
|
-
if (!this.account) throw new Error("No wallet configured");
|
|
995
|
-
this.x402Client = new X402Client().register(
|
|
996
|
-
"eip155:*",
|
|
997
|
-
new ExactEvmScheme(this.account)
|
|
998
|
-
);
|
|
999
|
-
}
|
|
1000
|
-
return this.x402Client;
|
|
1001
|
-
};
|
|
1002
|
-
getMppxClient = () => {
|
|
1003
|
-
if (!this.mppxClient) {
|
|
1004
|
-
if (!this.account) throw new Error("No wallet configured");
|
|
1005
|
-
this.mppxClient = Mppx.create({
|
|
1006
|
-
polyfill: false,
|
|
1007
|
-
methods: [tempo({ account: this.account })]
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
return this.mppxClient;
|
|
1011
|
-
};
|
|
1012
1033
|
ensureRelayClient = () => {
|
|
1013
1034
|
if (!this.relayInitialized) {
|
|
1014
|
-
createRelayClient(
|
|
1015
|
-
baseApiUrl: MAINNET_RELAY_API,
|
|
1016
|
-
source: "zero-cli"
|
|
1017
|
-
});
|
|
1035
|
+
createRelayClient(buildRelayClientOptions());
|
|
1018
1036
|
this.relayInitialized = true;
|
|
1019
1037
|
}
|
|
1020
1038
|
};
|
|
1021
|
-
bridgeToTempo = async (requiredAmount) => {
|
|
1039
|
+
bridgeToTempo = async (requiredAmount, onProgress) => {
|
|
1022
1040
|
if (!this.account) throw new Error("No wallet configured");
|
|
1023
1041
|
this.ensureRelayClient();
|
|
1024
1042
|
const baseBalance = await this.getBalanceRaw("base");
|
|
@@ -1029,6 +1047,9 @@ var PaymentService = class {
|
|
|
1029
1047
|
`Insufficient Base USDC to bridge: have ${formatUnits(baseBalance, 6)}, need ${formatUnits(bridgeAmount, 6)} (${formatUnits(requiredAmount, 6)} + ${formatUnits(buffer, 6)} buffer)`
|
|
1030
1048
|
);
|
|
1031
1049
|
}
|
|
1050
|
+
onProgress?.(
|
|
1051
|
+
`Bridging ${formatUnits(bridgeAmount, 6)} USDC from Base to Tempo...`
|
|
1052
|
+
);
|
|
1032
1053
|
const walletClient = createWalletClient({
|
|
1033
1054
|
account: this.account,
|
|
1034
1055
|
chain: base,
|
|
@@ -1042,7 +1063,10 @@ var PaymentService = class {
|
|
|
1042
1063
|
amount: bridgeAmount.toString(),
|
|
1043
1064
|
tradeType: "EXACT_INPUT",
|
|
1044
1065
|
user: this.account.address,
|
|
1045
|
-
recipient: this.account.address
|
|
1066
|
+
recipient: this.account.address,
|
|
1067
|
+
options: {
|
|
1068
|
+
usePermit: true
|
|
1069
|
+
}
|
|
1046
1070
|
});
|
|
1047
1071
|
let bridgeTxHash = null;
|
|
1048
1072
|
await getRelayClient().actions.execute({
|
|
@@ -1056,150 +1080,141 @@ var PaymentService = class {
|
|
|
1056
1080
|
});
|
|
1057
1081
|
return bridgeTxHash;
|
|
1058
1082
|
};
|
|
1059
|
-
handlePayment = async (url, request, paymentRequirement, maxPay) => {
|
|
1083
|
+
handlePayment = async (url, request, paymentRequirement, maxPay, onProgress) => {
|
|
1060
1084
|
if (!this.account) {
|
|
1061
1085
|
throw new Error(
|
|
1062
1086
|
"No wallet configured \u2014 run `zero init` or set ZERO_PRIVATE_KEY"
|
|
1063
1087
|
);
|
|
1064
1088
|
}
|
|
1065
1089
|
if (paymentRequirement.protocol === "x402") {
|
|
1090
|
+
onProgress?.("Paying via x402 on Base...");
|
|
1066
1091
|
return this.payX402(url, request, paymentRequirement.raw, maxPay);
|
|
1067
1092
|
}
|
|
1068
1093
|
if (paymentRequirement.protocol === "mpp") {
|
|
1069
|
-
|
|
1094
|
+
onProgress?.("Paying via MPP on Tempo...");
|
|
1095
|
+
return this.payMpp(
|
|
1096
|
+
url,
|
|
1097
|
+
request,
|
|
1098
|
+
paymentRequirement.raw,
|
|
1099
|
+
maxPay,
|
|
1100
|
+
onProgress
|
|
1101
|
+
);
|
|
1070
1102
|
}
|
|
1071
1103
|
throw new Error("Unrecognized 402 payment protocol");
|
|
1072
1104
|
};
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
let currentRaw = raw;
|
|
1090
|
-
let amountUsdc = "0";
|
|
1091
|
-
for (let attempt = 1; attempt <= X402_PAYMENT_MAX_ATTEMPTS; attempt++) {
|
|
1092
|
-
const headerValue = this.toX402HeaderValue(currentRaw);
|
|
1093
|
-
const paymentRequired = decodePaymentRequiredHeader(headerValue);
|
|
1094
|
-
const requirement = paymentRequired.accepts[0];
|
|
1095
|
-
if (!requirement) {
|
|
1096
|
-
throw new Error("No accepted payment methods in x402 challenge");
|
|
1105
|
+
payX402 = async (url, request, _raw, maxPay) => {
|
|
1106
|
+
if (!this.account) throw new Error("No wallet configured");
|
|
1107
|
+
let capturedAmount = "0";
|
|
1108
|
+
const client = new X402Client().register(
|
|
1109
|
+
"eip155:*",
|
|
1110
|
+
new ExactEvmScheme(this.account)
|
|
1111
|
+
);
|
|
1112
|
+
client.onBeforePaymentCreation(async (context) => {
|
|
1113
|
+
const requirement = context.paymentRequired.accepts[0];
|
|
1114
|
+
if (!requirement) return;
|
|
1115
|
+
capturedAmount = formatUnits(BigInt(requirement.amount), 6);
|
|
1116
|
+
if (maxPay && Number.parseFloat(capturedAmount) > Number.parseFloat(maxPay)) {
|
|
1117
|
+
return {
|
|
1118
|
+
abort: true,
|
|
1119
|
+
reason: `Payment of ${capturedAmount} USDC exceeds --max-pay ${maxPay}`
|
|
1120
|
+
};
|
|
1097
1121
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1122
|
+
});
|
|
1123
|
+
const httpClient = new x402HTTPClient(client).onPaymentRequired(
|
|
1124
|
+
createSIWxClientHook(this.account)
|
|
1125
|
+
);
|
|
1126
|
+
const wrappedFetch = wrapFetchWithPayment(fetch, httpClient);
|
|
1127
|
+
const response = await wrappedFetch(url, {
|
|
1128
|
+
method: request.method,
|
|
1129
|
+
headers: request.headers,
|
|
1130
|
+
body: request.body
|
|
1131
|
+
});
|
|
1132
|
+
let txHash = null;
|
|
1133
|
+
const paymentResponseHeader = response.headers.get("payment-response") ?? response.headers.get("x-payment-response");
|
|
1134
|
+
if (paymentResponseHeader) {
|
|
1135
|
+
try {
|
|
1136
|
+
const settlement = decodePaymentResponseHeader(paymentResponseHeader);
|
|
1137
|
+
txHash = settlement.transaction ?? null;
|
|
1138
|
+
} catch {
|
|
1103
1139
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1140
|
+
}
|
|
1141
|
+
return {
|
|
1142
|
+
response,
|
|
1143
|
+
protocol: "x402",
|
|
1144
|
+
chain: "base",
|
|
1145
|
+
txHash,
|
|
1146
|
+
amount: capturedAmount,
|
|
1147
|
+
asset: "USDC"
|
|
1148
|
+
};
|
|
1149
|
+
};
|
|
1150
|
+
payMpp = async (url, request, _raw, maxPay, onProgress) => {
|
|
1151
|
+
if (!this.account) throw new Error("No wallet configured");
|
|
1152
|
+
let capturedAmount = "0";
|
|
1153
|
+
const mppx = Mppx.create({
|
|
1154
|
+
polyfill: false,
|
|
1155
|
+
methods: [
|
|
1156
|
+
tempo({
|
|
1157
|
+
account: this.account,
|
|
1158
|
+
maxDeposit: maxPay ?? DEFAULT_MAX_DEPOSIT
|
|
1159
|
+
})
|
|
1160
|
+
],
|
|
1161
|
+
onChallenge: async (challenge) => {
|
|
1162
|
+
const challengeRequest = challenge.request;
|
|
1163
|
+
const intent = challenge.intent;
|
|
1164
|
+
let requiredRaw;
|
|
1165
|
+
if (intent === "session") {
|
|
1166
|
+
const suggestedDeposit = challengeRequest.suggestedDeposit;
|
|
1167
|
+
if (suggestedDeposit) {
|
|
1168
|
+
requiredRaw = BigInt(suggestedDeposit);
|
|
1169
|
+
} else {
|
|
1170
|
+
const depositStr = maxPay ?? DEFAULT_MAX_DEPOSIT;
|
|
1171
|
+
requiredRaw = BigInt(
|
|
1172
|
+
Math.floor(Number.parseFloat(depositStr) * 1e6)
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
} else {
|
|
1176
|
+
requiredRaw = BigInt(challengeRequest.amount);
|
|
1119
1177
|
}
|
|
1120
|
-
|
|
1121
|
-
if (
|
|
1178
|
+
capturedAmount = formatUnits(requiredRaw, 6);
|
|
1179
|
+
if (maxPay && Number.parseFloat(capturedAmount) > Number.parseFloat(maxPay)) {
|
|
1122
1180
|
throw new Error(
|
|
1123
|
-
|
|
1181
|
+
`Payment of ${capturedAmount} USDC exceeds --max-pay ${maxPay}`
|
|
1124
1182
|
);
|
|
1125
1183
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1184
|
+
const methodDetails = challengeRequest.methodDetails;
|
|
1185
|
+
const challengeChainId = challengeRequest.chainId ?? methodDetails?.chainId;
|
|
1186
|
+
const isTestnet = challengeChainId === TEMPO_TESTNET_CHAIN_ID;
|
|
1187
|
+
const balanceChain = isTestnet ? "tempo-testnet" : "tempo";
|
|
1188
|
+
onProgress?.(`Checking Tempo balance...`);
|
|
1189
|
+
const tempoBalance = await this.getBalanceRaw(balanceChain);
|
|
1190
|
+
if (tempoBalance < requiredRaw) {
|
|
1191
|
+
if (isTestnet) {
|
|
1192
|
+
throw new Error(
|
|
1193
|
+
`Insufficient pathUSD on Tempo testnet: have ${formatUnits(tempoBalance, 6)}, need ${capturedAmount}. Fund your wallet with the Tempo testnet faucet: https://docs.tempo.xyz/quickstart/faucet`
|
|
1194
|
+
);
|
|
1195
|
+
}
|
|
1196
|
+
await this.bridgeToTempo(requiredRaw, onProgress);
|
|
1139
1197
|
}
|
|
1198
|
+
return void 0;
|
|
1140
1199
|
}
|
|
1141
|
-
return {
|
|
1142
|
-
response: retryResponse,
|
|
1143
|
-
protocol: "x402",
|
|
1144
|
-
chain: "base",
|
|
1145
|
-
txHash,
|
|
1146
|
-
amount: amountUsdc,
|
|
1147
|
-
asset: "USDC"
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
throw new Error("x402 payment failed");
|
|
1151
|
-
};
|
|
1152
|
-
payMpp = async (url, request, raw, maxPay) => {
|
|
1153
|
-
const wwwAuth = raw?.["www-authenticate"] ?? "";
|
|
1154
|
-
const challengeResponse = new Response("Payment Required", {
|
|
1155
|
-
status: 402,
|
|
1156
|
-
headers: { "www-authenticate": wwwAuth }
|
|
1157
1200
|
});
|
|
1158
|
-
const
|
|
1159
|
-
const challengeRequest = challenge.request;
|
|
1160
|
-
const amountRaw = challengeRequest.amount;
|
|
1161
|
-
const amountUsdc = formatUnits(BigInt(amountRaw), 6);
|
|
1162
|
-
if (maxPay && Number.parseFloat(amountUsdc) > Number.parseFloat(maxPay)) {
|
|
1163
|
-
throw new Error(
|
|
1164
|
-
`Payment of ${amountUsdc} USDC exceeds --max-pay ${maxPay}`
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
const methodDetails = challengeRequest.methodDetails;
|
|
1168
|
-
const challengeChainId = challengeRequest.chainId ?? methodDetails?.chainId;
|
|
1169
|
-
const isTestnet = challengeChainId === TEMPO_TESTNET_CHAIN_ID;
|
|
1170
|
-
const balanceChain = isTestnet ? "tempo-testnet" : "tempo";
|
|
1171
|
-
const tempoBalance = await this.getBalanceRaw(balanceChain);
|
|
1172
|
-
if (tempoBalance < BigInt(amountRaw)) {
|
|
1173
|
-
if (isTestnet) {
|
|
1174
|
-
throw new Error(
|
|
1175
|
-
`Insufficient pathUSD on Tempo testnet: have ${formatUnits(tempoBalance, 6)}, need ${amountUsdc}. Fund your wallet with the Tempo testnet faucet: https://docs.tempo.xyz/quickstart/faucet`
|
|
1176
|
-
);
|
|
1177
|
-
}
|
|
1178
|
-
await this.bridgeToTempo(BigInt(amountRaw));
|
|
1179
|
-
}
|
|
1180
|
-
const mppx = this.getMppxClient();
|
|
1181
|
-
const credential = await mppx.createCredential(challengeResponse);
|
|
1182
|
-
const retryResponse = await fetch(url, {
|
|
1201
|
+
const response = await mppx.fetch(url, {
|
|
1183
1202
|
method: request.method,
|
|
1184
|
-
headers:
|
|
1185
|
-
...request.headers,
|
|
1186
|
-
// biome-ignore lint/style/useNamingConvention: HTTP header name
|
|
1187
|
-
Authorization: credential
|
|
1188
|
-
},
|
|
1203
|
+
headers: request.headers,
|
|
1189
1204
|
body: request.body
|
|
1190
1205
|
});
|
|
1191
1206
|
let txHash = null;
|
|
1192
1207
|
try {
|
|
1193
|
-
const receipt = Receipt.fromResponse(
|
|
1208
|
+
const receipt = Receipt.fromResponse(response);
|
|
1194
1209
|
txHash = receipt.reference ?? null;
|
|
1195
1210
|
} catch {
|
|
1196
1211
|
}
|
|
1197
1212
|
return {
|
|
1198
|
-
response
|
|
1213
|
+
response,
|
|
1199
1214
|
protocol: "mpp",
|
|
1200
1215
|
chain: "tempo",
|
|
1201
1216
|
txHash,
|
|
1202
|
-
amount:
|
|
1217
|
+
amount: capturedAmount,
|
|
1203
1218
|
asset: "USDC"
|
|
1204
1219
|
};
|
|
1205
1220
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeroxyz/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"zero": "dist/index.js",
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
"@relayprotocol/relay-sdk": "^5.2.1",
|
|
31
31
|
"@x402/core": "^2.9.0",
|
|
32
32
|
"@x402/evm": "^2.9.0",
|
|
33
|
+
"@x402/extensions": "^2.9.0",
|
|
34
|
+
"@x402/fetch": "^2.9.0",
|
|
33
35
|
"commander": "^13.0.0",
|
|
34
36
|
"mppx": "^0.5.9",
|
|
35
37
|
"open": "^11.0.0",
|