@zeroxyz/sdk 0.8.0 → 0.10.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/CHANGELOG.md +21 -0
- package/README.md +43 -7
- package/dist/{chunk-NUBD543C.js → chunk-A7WZYQXS.js} +579 -151
- package/dist/chunk-A7WZYQXS.js.map +1 -0
- package/dist/{chunk-72WCE7HE.cjs → chunk-IFVGW4ZN.cjs} +584 -151
- package/dist/chunk-IFVGW4ZN.cjs.map +1 -0
- package/dist/{client-f6vDYSHb.d.cts → client-D_ohktBl.d.cts} +220 -19
- package/dist/{client-f6vDYSHb.d.ts → client-D_ohktBl.d.ts} +220 -19
- package/dist/index.cjs +303 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -3
- package/dist/index.d.ts +109 -3
- package/dist/index.js +232 -2
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +2 -2
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-72WCE7HE.cjs.map +0 -1
- package/dist/chunk-NUBD543C.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { serializeTransaction, parseSignature, formatUnits, isAddress, getAddress, parseUnits, createWalletClient, http, createPublicClient, bytesToHex } from 'viem';
|
|
2
2
|
import { toAccount, privateKeyToAccount, mnemonicToAccount } from 'viem/accounts';
|
|
3
|
+
import { base, baseSepolia } from 'viem/chains';
|
|
3
4
|
import { getClient, adaptViemWallet, createClient, convertViemChainToRelayChain, MAINNET_RELAY_API } from '@relayprotocol/relay-sdk';
|
|
4
5
|
import { x402Client } from '@x402/core/client';
|
|
5
6
|
import { x402HTTPClient, decodePaymentResponseHeader, encodePaymentRequiredHeader } from '@x402/core/http';
|
|
@@ -8,7 +9,6 @@ import { createSIWxClientHook } from '@x402/extensions/sign-in-with-x';
|
|
|
8
9
|
import { wrapFetchWithPayment } from '@x402/fetch';
|
|
9
10
|
import { Receipt, Challenge } from 'mppx';
|
|
10
11
|
import { Mppx, tempo } from 'mppx/client';
|
|
11
|
-
import { base, baseSepolia } from 'viem/chains';
|
|
12
12
|
import { createHash } from 'crypto';
|
|
13
13
|
import { z } from 'zod';
|
|
14
14
|
|
|
@@ -43,6 +43,28 @@ var createManagedAccount = (client, address) => toAccount({
|
|
|
43
43
|
return await serialize(transaction, parseSignature(signature));
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
|
+
var USDC_BASE = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
47
|
+
var USDC_TEMPO = "0x20c000000000000000000000b9537d11c60e8b50";
|
|
48
|
+
var TEMPO_CHAIN_ID = 4217;
|
|
49
|
+
var baseChain = base;
|
|
50
|
+
var tempoChain = {
|
|
51
|
+
id: TEMPO_CHAIN_ID,
|
|
52
|
+
name: "Tempo",
|
|
53
|
+
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
54
|
+
rpcUrls: {
|
|
55
|
+
default: { http: ["https://rpc.tempo.xyz"] }
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var ERC20_BALANCE_ABI = [
|
|
59
|
+
{
|
|
60
|
+
inputs: [{ name: "account", type: "address" }],
|
|
61
|
+
name: "balanceOf",
|
|
62
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
63
|
+
stateMutability: "view",
|
|
64
|
+
type: "function"
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
var USDC_DECIMALS = 6;
|
|
46
68
|
|
|
47
69
|
// src/errors.ts
|
|
48
70
|
var ZeroError = class extends Error {
|
|
@@ -71,6 +93,25 @@ var ZeroAuthError = class extends ZeroError {
|
|
|
71
93
|
this.name = "ZeroAuthError";
|
|
72
94
|
}
|
|
73
95
|
};
|
|
96
|
+
var ZeroAgentAuthError = class extends ZeroError {
|
|
97
|
+
status;
|
|
98
|
+
body;
|
|
99
|
+
constructor(message, init) {
|
|
100
|
+
super("auth_error", message, { cause: init.cause });
|
|
101
|
+
this.name = "ZeroAgentAuthError";
|
|
102
|
+
this.status = init.status;
|
|
103
|
+
this.body = init.body;
|
|
104
|
+
}
|
|
105
|
+
// The error code the SERVER sent, distinct from ZeroError's `code`
|
|
106
|
+
// discriminator. WorkOS error bodies carry {code, message}; OAuth-style
|
|
107
|
+
// ones carry {error}.
|
|
108
|
+
get serverCode() {
|
|
109
|
+
const body = this.body;
|
|
110
|
+
if (typeof body?.code === "string") return body.code;
|
|
111
|
+
if (typeof body?.error === "string") return body.error;
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
74
115
|
var ZeroPaymentError = class extends ZeroError {
|
|
75
116
|
constructor(message, options) {
|
|
76
117
|
super("payment_error", message, options);
|
|
@@ -430,15 +471,15 @@ var networkToChain = (network) => {
|
|
|
430
471
|
var MAX_PAY_RE = /^[0-9]+(\.[0-9]{1,6})?$/;
|
|
431
472
|
var UINT_RE = /^[0-9]+$/;
|
|
432
473
|
var MAX_AMOUNT_DIGITS = 30;
|
|
433
|
-
var
|
|
434
|
-
var
|
|
474
|
+
var USDC_BASE2 = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
475
|
+
var USDC_TEMPO2 = "0x20c000000000000000000000b9537d11c60e8b50";
|
|
435
476
|
var PATHUSD_TEMPO = "0x20c0000000000000000000000000000000000000";
|
|
436
477
|
var BASE_CHAIN_ID = 8453;
|
|
437
|
-
var
|
|
478
|
+
var TEMPO_CHAIN_ID2 = 4217;
|
|
438
479
|
var TEMPO_TESTNET_CHAIN_ID = 42431;
|
|
439
480
|
var DEFAULT_PREFUND = "1";
|
|
440
|
-
var
|
|
441
|
-
id:
|
|
481
|
+
var tempoChain2 = {
|
|
482
|
+
id: TEMPO_CHAIN_ID2,
|
|
442
483
|
name: "Tempo",
|
|
443
484
|
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
444
485
|
rpcUrls: { default: { http: ["https://rpc.tempo.xyz"] } }
|
|
@@ -449,7 +490,7 @@ var tempoTestnetChain = {
|
|
|
449
490
|
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
450
491
|
rpcUrls: { default: { http: ["https://rpc.moderato.tempo.xyz"] } }
|
|
451
492
|
};
|
|
452
|
-
var
|
|
493
|
+
var ERC20_BALANCE_ABI2 = [
|
|
453
494
|
{
|
|
454
495
|
inputs: [{ name: "account", type: "address" }],
|
|
455
496
|
name: "balanceOf",
|
|
@@ -478,7 +519,7 @@ var resolveDefaultPrefund = (displayCostAmount) => {
|
|
|
478
519
|
var isUintString = (v) => typeof v === "string" && v.length > 0 && v.length <= MAX_AMOUNT_DIGITS && UINT_RE.test(v);
|
|
479
520
|
var coerceTempoChainId = (raw) => {
|
|
480
521
|
const id = typeof raw === "number" && Number.isFinite(raw) ? raw : typeof raw === "string" && /^-?[0-9]+$/.test(raw) ? Number(raw) : null;
|
|
481
|
-
if (id ===
|
|
522
|
+
if (id === TEMPO_CHAIN_ID2) return { id, chain: "tempo" };
|
|
482
523
|
if (id === TEMPO_TESTNET_CHAIN_ID) return { id, chain: "tempo-testnet" };
|
|
483
524
|
return null;
|
|
484
525
|
};
|
|
@@ -965,7 +1006,7 @@ var Payments = class {
|
|
|
965
1006
|
);
|
|
966
1007
|
if (!coerced) {
|
|
967
1008
|
throw new ZeroPaymentError(
|
|
968
|
-
`MPP challenge has missing or unsupported chainId (expected ${
|
|
1009
|
+
`MPP challenge has missing or unsupported chainId (expected ${TEMPO_CHAIN_ID2} or ${TEMPO_TESTNET_CHAIN_ID})`
|
|
969
1010
|
);
|
|
970
1011
|
}
|
|
971
1012
|
const tempoBalance = await this.readUsdcBalance(
|
|
@@ -1009,9 +1050,9 @@ var Payments = class {
|
|
|
1009
1050
|
});
|
|
1010
1051
|
const quote = await getClient().actions.getQuote({
|
|
1011
1052
|
chainId: BASE_CHAIN_ID,
|
|
1012
|
-
toChainId:
|
|
1013
|
-
currency:
|
|
1014
|
-
toCurrency:
|
|
1053
|
+
toChainId: TEMPO_CHAIN_ID2,
|
|
1054
|
+
currency: USDC_BASE2,
|
|
1055
|
+
toCurrency: USDC_TEMPO2,
|
|
1015
1056
|
amount: bridgeAmount.toString(),
|
|
1016
1057
|
tradeType: "EXACT_INPUT",
|
|
1017
1058
|
user: account.address,
|
|
@@ -1042,7 +1083,7 @@ var Payments = class {
|
|
|
1042
1083
|
// Tempo tx hash on the Base transport.
|
|
1043
1084
|
chains: [
|
|
1044
1085
|
convertViemChainToRelayChain(base),
|
|
1045
|
-
convertViemChainToRelayChain(
|
|
1086
|
+
convertViemChainToRelayChain(tempoChain2)
|
|
1046
1087
|
]
|
|
1047
1088
|
});
|
|
1048
1089
|
this.relayInitialized = true;
|
|
@@ -1051,14 +1092,14 @@ var Payments = class {
|
|
|
1051
1092
|
const { viemChain, token } = (() => {
|
|
1052
1093
|
switch (chain) {
|
|
1053
1094
|
case "base":
|
|
1054
|
-
return { viemChain: base, token:
|
|
1095
|
+
return { viemChain: base, token: USDC_BASE2 };
|
|
1055
1096
|
case "base-sepolia":
|
|
1056
1097
|
return {
|
|
1057
1098
|
viemChain: baseSepolia,
|
|
1058
1099
|
token: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
1059
1100
|
};
|
|
1060
1101
|
case "tempo":
|
|
1061
|
-
return { viemChain:
|
|
1102
|
+
return { viemChain: tempoChain2, token: USDC_TEMPO2 };
|
|
1062
1103
|
case "tempo-testnet":
|
|
1063
1104
|
return { viemChain: tempoTestnetChain, token: PATHUSD_TEMPO };
|
|
1064
1105
|
}
|
|
@@ -1066,7 +1107,7 @@ var Payments = class {
|
|
|
1066
1107
|
const client = createPublicClient({ chain: viemChain, transport: http() });
|
|
1067
1108
|
return await client.readContract({
|
|
1068
1109
|
address: token,
|
|
1069
|
-
abi:
|
|
1110
|
+
abi: ERC20_BALANCE_ABI2,
|
|
1070
1111
|
functionName: "balanceOf",
|
|
1071
1112
|
args: [address]
|
|
1072
1113
|
});
|
|
@@ -1116,7 +1157,7 @@ var Payments = class {
|
|
|
1116
1157
|
}
|
|
1117
1158
|
if (!coercedChainId) {
|
|
1118
1159
|
throw buildOrphanFromChannelEntry(
|
|
1119
|
-
`MPP session challenge has unsupported chainId (expected ${
|
|
1160
|
+
`MPP session challenge has unsupported chainId (expected ${TEMPO_CHAIN_ID2} or ${TEMPO_TESTNET_CHAIN_ID}); channel ${channelId} is open and requires reconciliation.`
|
|
1120
1161
|
);
|
|
1121
1162
|
}
|
|
1122
1163
|
const receipt = readSessionReceipt(response);
|
|
@@ -1436,16 +1477,89 @@ var extractUpstreamErrorMessage = (body) => {
|
|
|
1436
1477
|
}
|
|
1437
1478
|
return void 0;
|
|
1438
1479
|
};
|
|
1480
|
+
var extractFieldName = (message) => {
|
|
1481
|
+
const patterns = [
|
|
1482
|
+
/(?:field|param(?:eter)?|property|key)[:\s]+["'`]?([a-z0-9_.[\]-]+)["'`]?/i,
|
|
1483
|
+
/["'`]([a-z0-9_.[\]-]+)["'`]\s*(?:is\s+)?(?:required|missing|expected)/i,
|
|
1484
|
+
// Quotes REQUIRED here — an unquoted token after "required"/"missing"
|
|
1485
|
+
// is usually a generic noun ("required parameters", "missing fields"),
|
|
1486
|
+
// not a field name. Only trust it when the seller quoted it.
|
|
1487
|
+
/(?:required|missing|expected)[:\s]+["'`]([a-z0-9_.[\]-]+)["'`]/i
|
|
1488
|
+
];
|
|
1489
|
+
for (const p of patterns) {
|
|
1490
|
+
const match = message.match(p);
|
|
1491
|
+
if (match?.[1]) return match[1];
|
|
1492
|
+
}
|
|
1493
|
+
return void 0;
|
|
1494
|
+
};
|
|
1495
|
+
var extractAllowedMethod = (text) => {
|
|
1496
|
+
const listed = text.match(
|
|
1497
|
+
/allowed[^[]*\[\s*["'`]?(GET|POST|PUT|PATCH|DELETE|HEAD)/i
|
|
1498
|
+
);
|
|
1499
|
+
if (listed?.[1]) return listed[1].toUpperCase();
|
|
1500
|
+
const useVerb = text.match(/\buse\s+(GET|POST|PUT|PATCH|DELETE|HEAD)\b/i);
|
|
1501
|
+
if (useVerb?.[1]) return useVerb[1].toUpperCase();
|
|
1502
|
+
return void 0;
|
|
1503
|
+
};
|
|
1504
|
+
var extractUnrecognizedKeys = (bodyRaw) => {
|
|
1505
|
+
if (!bodyRaw) return [];
|
|
1506
|
+
const parsed = tryParseJson(bodyRaw);
|
|
1507
|
+
if (parsed === null || typeof parsed !== "object") return [];
|
|
1508
|
+
const out = [];
|
|
1509
|
+
const visit = (node) => {
|
|
1510
|
+
if (!node || typeof node !== "object") return;
|
|
1511
|
+
const o = node;
|
|
1512
|
+
if (Array.isArray(o.keys)) {
|
|
1513
|
+
for (const k of o.keys) if (typeof k === "string") out.push(k);
|
|
1514
|
+
}
|
|
1515
|
+
for (const v of Object.values(o)) {
|
|
1516
|
+
if (Array.isArray(v)) v.forEach(visit);
|
|
1517
|
+
else if (v && typeof v === "object") visit(v);
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
visit(parsed);
|
|
1521
|
+
return [...new Set(out)].slice(0, 8);
|
|
1522
|
+
};
|
|
1523
|
+
var computeFixHint = (status, message, bodyRaw) => {
|
|
1524
|
+
if (status < 400 || status >= 500) return void 0;
|
|
1525
|
+
const hay = `${message ?? ""} ${bodyRaw ?? ""}`.toLowerCase();
|
|
1526
|
+
if (status === 405 || /method not allowed|method_not_allowed/.test(hay)) {
|
|
1527
|
+
const allowed = extractAllowedMethod(`${bodyRaw ?? ""} ${message ?? ""}`);
|
|
1528
|
+
return allowed ? `the endpoint expects ${allowed}, not the method you used \u2014 retry with -X ${allowed}` : "the endpoint rejected this HTTP method \u2014 check the capability's method (`zero get <slug>`) and retry with the right -X";
|
|
1529
|
+
}
|
|
1530
|
+
if (/invalid json|not valid json|malformed|unexpected token|json ?parse|could not parse|failed to parse|jsondecode/.test(
|
|
1531
|
+
hay
|
|
1532
|
+
)) {
|
|
1533
|
+
return "the request body isn't valid JSON \u2014 check quoting/escaping (single-quote the -d value or use @file), then retry";
|
|
1534
|
+
}
|
|
1535
|
+
if (/unrecognized[_ ]?key|unexpected key|unknown (field|key|propert)|additional (?:propert|field)|not allowed in object/.test(
|
|
1536
|
+
hay
|
|
1537
|
+
)) {
|
|
1538
|
+
const keys = extractUnrecognizedKeys(bodyRaw ?? null);
|
|
1539
|
+
return keys.length ? `remove the unexpected field(s) ${keys.map((k) => `'${k}'`).join(", ")} from the request body, then retry` : "the request body has fields the capability doesn't accept \u2014 send only the documented fields, then retry";
|
|
1540
|
+
}
|
|
1541
|
+
if (status === 415 || /content-?type|unsupported media|media type/.test(hay)) {
|
|
1542
|
+
return "set the Content-Type header to what the capability expects (usually application/json), then retry";
|
|
1543
|
+
}
|
|
1544
|
+
if (/required|missing|must (include|provide|have|contain)|is expected/.test(hay)) {
|
|
1545
|
+
const field = extractFieldName(message ?? "");
|
|
1546
|
+
return field ? `add the required field '${field}' to the request body, then retry` : "the request is missing one or more required fields \u2014 check the capability schema (`zero get <slug>`), then retry";
|
|
1547
|
+
}
|
|
1548
|
+
return void 0;
|
|
1549
|
+
};
|
|
1439
1550
|
var buildUpstreamError = (status, bodyRaw, bodyEncoding) => {
|
|
1440
1551
|
if (status >= 200 && status < 300) return void 0;
|
|
1441
1552
|
if (bodyRaw === null || bodyRaw.length === 0) return void 0;
|
|
1442
1553
|
if (bodyEncoding === "base64") return void 0;
|
|
1443
1554
|
const snippet = bodyRaw.slice(0, ERROR_SNIPPET_BYTES);
|
|
1555
|
+
const message = extractUpstreamErrorMessage(bodyRaw);
|
|
1556
|
+
const fixHint = computeFixHint(status, message, bodyRaw);
|
|
1444
1557
|
return {
|
|
1445
1558
|
status,
|
|
1446
|
-
message
|
|
1559
|
+
message,
|
|
1447
1560
|
snippetHash: createHash("sha256").update(snippet).digest("hex"),
|
|
1448
|
-
snippetLength: snippet.length
|
|
1561
|
+
snippetLength: snippet.length,
|
|
1562
|
+
...fixHint && { fixHint }
|
|
1449
1563
|
};
|
|
1450
1564
|
};
|
|
1451
1565
|
var computeOutcome = (status, payment, warnings) => {
|
|
@@ -1836,77 +1950,64 @@ var clientFetch = async (client, url, opts = {}) => {
|
|
|
1836
1950
|
|
|
1837
1951
|
// package.json
|
|
1838
1952
|
var package_default = {
|
|
1839
|
-
version: "0.
|
|
1953
|
+
version: "0.10.0"};
|
|
1840
1954
|
|
|
1841
1955
|
// src/version.ts
|
|
1842
1956
|
var SDK_VERSION = package_default.version;
|
|
1843
|
-
var
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
maxTransactionUsdcBaseUnits: z.number().int().nullable()
|
|
1852
|
-
});
|
|
1853
|
-
var welcomeBonusSummarySchema = z.object({
|
|
1854
|
-
status: z.string(),
|
|
1855
|
-
amountUsd: z.number()
|
|
1856
|
-
});
|
|
1857
|
-
var internalUserDtoSchema = z.object({
|
|
1957
|
+
var agentAuthMetadataSchema = z.object({
|
|
1958
|
+
token_endpoint: z.string().optional(),
|
|
1959
|
+
agent_auth: z.object({
|
|
1960
|
+
identity_endpoint: z.string(),
|
|
1961
|
+
claim_endpoint: z.string().optional()
|
|
1962
|
+
}).loose()
|
|
1963
|
+
}).loose();
|
|
1964
|
+
var identityEnvelopeSchema = z.object({
|
|
1858
1965
|
id: z.string(),
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
})
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
});
|
|
1877
|
-
var
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
z.
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
})
|
|
1905
|
-
]);
|
|
1906
|
-
var sessionExchangeResponseSchema = z.object({
|
|
1907
|
-
token: z.string(),
|
|
1908
|
-
expiresAt: z.number()
|
|
1909
|
-
});
|
|
1966
|
+
identity: z.object({
|
|
1967
|
+
assertion: z.string(),
|
|
1968
|
+
expires_at: z.string().optional(),
|
|
1969
|
+
refresh_token: z.object({ value: z.string() }).loose().optional()
|
|
1970
|
+
}).loose(),
|
|
1971
|
+
claim: z.object({
|
|
1972
|
+
token: z.string().optional(),
|
|
1973
|
+
expires_at: z.string().optional()
|
|
1974
|
+
}).loose().optional()
|
|
1975
|
+
}).loose().transform((raw) => ({
|
|
1976
|
+
registrationId: raw.id,
|
|
1977
|
+
identityAssertion: raw.identity.assertion,
|
|
1978
|
+
assertionExpires: raw.identity.expires_at ?? null,
|
|
1979
|
+
refreshToken: raw.identity.refresh_token?.value ?? null,
|
|
1980
|
+
claimToken: raw.claim?.token ?? null,
|
|
1981
|
+
claimTokenExpires: raw.claim?.expires_at ?? null
|
|
1982
|
+
}));
|
|
1983
|
+
var agentTokenResponseSchema = z.object({ access_token: z.string() }).loose().transform((raw) => ({ accessToken: raw.access_token }));
|
|
1984
|
+
var startClaimResponseSchema = z.object({
|
|
1985
|
+
attempt: z.object({
|
|
1986
|
+
verification_uri: z.string(),
|
|
1987
|
+
expires_at: z.string().optional()
|
|
1988
|
+
}).loose()
|
|
1989
|
+
}).loose().transform((raw) => ({
|
|
1990
|
+
verificationUri: raw.attempt.verification_uri,
|
|
1991
|
+
expiresAt: raw.attempt.expires_at ?? null
|
|
1992
|
+
}));
|
|
1993
|
+
var completeClaimResponseSchema = z.object({
|
|
1994
|
+
identity: z.object({
|
|
1995
|
+
assertion: z.string(),
|
|
1996
|
+
expires_at: z.string().optional(),
|
|
1997
|
+
refresh_token: z.object({ value: z.string() }).loose().optional()
|
|
1998
|
+
}).loose()
|
|
1999
|
+
}).loose().transform((raw) => ({
|
|
2000
|
+
identityAssertion: raw.identity.assertion,
|
|
2001
|
+
assertionExpires: raw.identity.expires_at ?? null,
|
|
2002
|
+
refreshToken: raw.identity.refresh_token?.value ?? null
|
|
2003
|
+
}));
|
|
2004
|
+
var agentZeroSessionSchema = z.object({
|
|
2005
|
+
accessToken: z.string(),
|
|
2006
|
+
refreshToken: z.string(),
|
|
2007
|
+
expiresIn: z.number(),
|
|
2008
|
+
user: z.object({ id: z.string() }).loose(),
|
|
2009
|
+
walletAddress: z.string().optional()
|
|
2010
|
+
}).loose();
|
|
1910
2011
|
var refreshResponseSchema = z.object({
|
|
1911
2012
|
accessToken: z.string(),
|
|
1912
2013
|
refreshToken: z.string()
|
|
@@ -2142,6 +2243,267 @@ var request = async (client, opts, schema) => {
|
|
|
2142
2243
|
});
|
|
2143
2244
|
};
|
|
2144
2245
|
|
|
2246
|
+
// src/namespaces/auth-agent.ts
|
|
2247
|
+
var JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
2248
|
+
var trimSlash = (value) => value.replace(/\/$/, "");
|
|
2249
|
+
var wrapNetworkError = (url, err) => {
|
|
2250
|
+
const cause = err?.cause;
|
|
2251
|
+
const causeMessage = cause instanceof Error ? cause.code ?? cause.message : err instanceof Error ? err.message : String(err);
|
|
2252
|
+
return new ZeroAgentAuthError(`Could not reach ${url} (${causeMessage})`, {
|
|
2253
|
+
status: 0,
|
|
2254
|
+
cause: err
|
|
2255
|
+
});
|
|
2256
|
+
};
|
|
2257
|
+
var AuthAgent = class {
|
|
2258
|
+
constructor(client) {
|
|
2259
|
+
this.client = client;
|
|
2260
|
+
}
|
|
2261
|
+
endpointsPromise = null;
|
|
2262
|
+
// Fully autonomous signup: register anonymously at the AuthKit domain,
|
|
2263
|
+
// exchange the identity assertion for a WorkOS access token, exchange that
|
|
2264
|
+
// for a Zero session. The claim token and identity assertion are returned
|
|
2265
|
+
// exactly once — the caller persists them.
|
|
2266
|
+
signup = async () => {
|
|
2267
|
+
const registration = await this.register();
|
|
2268
|
+
const token = await this.exchangeAssertion(registration.identityAssertion);
|
|
2269
|
+
const session = await this.exchangeAtZero(token.accessToken);
|
|
2270
|
+
return { registration, session };
|
|
2271
|
+
};
|
|
2272
|
+
register = async () => {
|
|
2273
|
+
const endpoints = await this.endpoints();
|
|
2274
|
+
return this.postJson(
|
|
2275
|
+
endpoints.identityEndpoint,
|
|
2276
|
+
{ type: "anonymous" },
|
|
2277
|
+
identityEnvelopeSchema
|
|
2278
|
+
);
|
|
2279
|
+
};
|
|
2280
|
+
exchangeAssertion = async (identityAssertion) => {
|
|
2281
|
+
const endpoints = await this.endpoints();
|
|
2282
|
+
return this.postForm(
|
|
2283
|
+
endpoints.tokenEndpoint,
|
|
2284
|
+
{ grant_type: JWT_BEARER_GRANT_TYPE, assertion: identityAssertion },
|
|
2285
|
+
agentTokenResponseSchema
|
|
2286
|
+
);
|
|
2287
|
+
};
|
|
2288
|
+
// POST /v1/auth/agent/exchange — WorkOS agent access token → Zero session
|
|
2289
|
+
// pair (+ the implicitly provisioned wallet address). The post-claim token
|
|
2290
|
+
// goes through here too: the server binds the claiming human.
|
|
2291
|
+
exchangeAtZero = (accessToken, opts = {}) => request(
|
|
2292
|
+
this.client,
|
|
2293
|
+
{
|
|
2294
|
+
method: "POST",
|
|
2295
|
+
path: "/v1/auth/agent/exchange",
|
|
2296
|
+
body: { accessToken },
|
|
2297
|
+
signal: opts.signal
|
|
2298
|
+
},
|
|
2299
|
+
agentZeroSessionSchema
|
|
2300
|
+
);
|
|
2301
|
+
// Mint a claim attempt. The human opens the returned verification URI,
|
|
2302
|
+
// signs in as `email`, and the page shows THEM a pairing code to read back
|
|
2303
|
+
// to the agent — completeClaim() submits it.
|
|
2304
|
+
startClaim = async (input) => {
|
|
2305
|
+
const endpoints = await this.endpoints();
|
|
2306
|
+
if (!endpoints.claimEndpoint) {
|
|
2307
|
+
throw new ZeroAgentAuthError(
|
|
2308
|
+
"The authorization server advertises no claim endpoint.",
|
|
2309
|
+
{ status: 0 }
|
|
2310
|
+
);
|
|
2311
|
+
}
|
|
2312
|
+
return this.postJson(
|
|
2313
|
+
endpoints.claimEndpoint,
|
|
2314
|
+
{
|
|
2315
|
+
type: "service_auth",
|
|
2316
|
+
claim_token: input.claimToken,
|
|
2317
|
+
login_hint: input.email
|
|
2318
|
+
},
|
|
2319
|
+
startClaimResponseSchema
|
|
2320
|
+
);
|
|
2321
|
+
};
|
|
2322
|
+
// Submit the pairing code the human read off the hosted page. Terminal
|
|
2323
|
+
// states map to a typed result; anything unexpected throws.
|
|
2324
|
+
completeClaim = async (input) => {
|
|
2325
|
+
const endpoints = await this.endpoints();
|
|
2326
|
+
if (!endpoints.claimEndpoint) {
|
|
2327
|
+
throw new ZeroAgentAuthError(
|
|
2328
|
+
"The authorization server advertises no claim endpoint.",
|
|
2329
|
+
{ status: 0 }
|
|
2330
|
+
);
|
|
2331
|
+
}
|
|
2332
|
+
try {
|
|
2333
|
+
const identity = await this.postJson(
|
|
2334
|
+
`${endpoints.claimEndpoint}/complete`,
|
|
2335
|
+
{ claim_token: input.claimToken, user_code: input.userCode },
|
|
2336
|
+
completeClaimResponseSchema
|
|
2337
|
+
);
|
|
2338
|
+
return { status: "ok", ...identity };
|
|
2339
|
+
} catch (err) {
|
|
2340
|
+
if (err instanceof ZeroAgentAuthError && err.serverCode) {
|
|
2341
|
+
if (err.serverCode === "claim_not_confirmed") {
|
|
2342
|
+
return { status: "not_confirmed" };
|
|
2343
|
+
}
|
|
2344
|
+
if (err.serverCode === "invalid_user_code") {
|
|
2345
|
+
return { status: "invalid_code" };
|
|
2346
|
+
}
|
|
2347
|
+
if ([
|
|
2348
|
+
"user_code_expired",
|
|
2349
|
+
"claim_expired",
|
|
2350
|
+
"claim_revoked",
|
|
2351
|
+
"already_claimed",
|
|
2352
|
+
"claim_denied"
|
|
2353
|
+
].includes(err.serverCode)) {
|
|
2354
|
+
return { status: "expired", code: err.serverCode };
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
throw err;
|
|
2358
|
+
}
|
|
2359
|
+
};
|
|
2360
|
+
// Resolve (and cache) the agent-auth endpoints via discovery.
|
|
2361
|
+
endpoints = () => {
|
|
2362
|
+
if (!this.endpointsPromise) {
|
|
2363
|
+
this.endpointsPromise = this.discover().catch((err) => {
|
|
2364
|
+
this.endpointsPromise = null;
|
|
2365
|
+
throw err;
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
return this.endpointsPromise;
|
|
2369
|
+
};
|
|
2370
|
+
discover = async () => {
|
|
2371
|
+
const resource = await this.getJson(
|
|
2372
|
+
`${trimSlash(this.client.baseUrl)}/.well-known/oauth-protected-resource`
|
|
2373
|
+
);
|
|
2374
|
+
let lastError = null;
|
|
2375
|
+
for (const server of resource.authorization_servers ?? []) {
|
|
2376
|
+
try {
|
|
2377
|
+
const raw = await this.getJson(
|
|
2378
|
+
`${trimSlash(server)}/.well-known/oauth-authorization-server`
|
|
2379
|
+
);
|
|
2380
|
+
const metadata = agentAuthMetadataSchema.parse(raw);
|
|
2381
|
+
return {
|
|
2382
|
+
authorizationServer: trimSlash(server),
|
|
2383
|
+
identityEndpoint: metadata.agent_auth.identity_endpoint,
|
|
2384
|
+
claimEndpoint: metadata.agent_auth.claim_endpoint ?? null,
|
|
2385
|
+
tokenEndpoint: metadata.token_endpoint ?? `${trimSlash(server)}/oauth2/token`
|
|
2386
|
+
};
|
|
2387
|
+
} catch (err) {
|
|
2388
|
+
lastError = err;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
throw new ZeroAgentAuthError(
|
|
2392
|
+
"No authorization server with an agent_auth block found \u2014 agent registration is not enabled for this service.",
|
|
2393
|
+
{ status: 0, cause: lastError }
|
|
2394
|
+
);
|
|
2395
|
+
};
|
|
2396
|
+
getJson = async (url) => {
|
|
2397
|
+
const response = await this.client.fetchImpl(url).catch((err) => {
|
|
2398
|
+
throw wrapNetworkError(url, err);
|
|
2399
|
+
});
|
|
2400
|
+
if (!response.ok) {
|
|
2401
|
+
throw new ZeroAgentAuthError(`GET ${url} failed (${response.status})`, {
|
|
2402
|
+
status: response.status
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
return await response.json();
|
|
2406
|
+
};
|
|
2407
|
+
postJson = (url, body, schema) => this.post(url, "application/json", JSON.stringify(body), schema);
|
|
2408
|
+
postForm = (url, fields, schema) => this.post(
|
|
2409
|
+
url,
|
|
2410
|
+
"application/x-www-form-urlencoded",
|
|
2411
|
+
new URLSearchParams(fields).toString(),
|
|
2412
|
+
schema
|
|
2413
|
+
);
|
|
2414
|
+
post = async (url, contentType, body, schema) => {
|
|
2415
|
+
const response = await this.client.fetchImpl(url, {
|
|
2416
|
+
method: "POST",
|
|
2417
|
+
headers: { "content-type": contentType },
|
|
2418
|
+
body
|
|
2419
|
+
}).catch((err) => {
|
|
2420
|
+
throw wrapNetworkError(url, err);
|
|
2421
|
+
});
|
|
2422
|
+
const text = await response.text();
|
|
2423
|
+
let parsed = null;
|
|
2424
|
+
try {
|
|
2425
|
+
parsed = text ? JSON.parse(text) : null;
|
|
2426
|
+
} catch {
|
|
2427
|
+
}
|
|
2428
|
+
if (!response.ok) {
|
|
2429
|
+
const errBody = parsed;
|
|
2430
|
+
const code = errBody?.code ?? errBody?.error;
|
|
2431
|
+
throw new ZeroAgentAuthError(
|
|
2432
|
+
`Agent auth request to ${url} failed (${response.status}${typeof code === "string" ? `: ${code}` : ""})`,
|
|
2433
|
+
{ status: response.status, body: parsed ?? text }
|
|
2434
|
+
);
|
|
2435
|
+
}
|
|
2436
|
+
return schema.parse(parsed);
|
|
2437
|
+
};
|
|
2438
|
+
};
|
|
2439
|
+
var userWalletDtoSchema = z.object({
|
|
2440
|
+
walletAddress: z.string(),
|
|
2441
|
+
source: z.enum(["self_custody", "privy_embedded"]),
|
|
2442
|
+
isPrimary: z.boolean(),
|
|
2443
|
+
linkedAt: z.union([z.string(), z.date()]).nullable().optional(),
|
|
2444
|
+
delegationGranted: z.boolean(),
|
|
2445
|
+
signerQuorumId: z.string().nullable(),
|
|
2446
|
+
// Per-transaction USDC cap in base units (6 dp). null = unlimited, 0 = free-only.
|
|
2447
|
+
maxTransactionUsdcBaseUnits: z.number().int().nullable()
|
|
2448
|
+
});
|
|
2449
|
+
var welcomeBonusSummarySchema = z.object({
|
|
2450
|
+
status: z.string(),
|
|
2451
|
+
amountUsd: z.number()
|
|
2452
|
+
});
|
|
2453
|
+
var internalUserDtoSchema = z.object({
|
|
2454
|
+
id: z.string(),
|
|
2455
|
+
email: z.string().nullable(),
|
|
2456
|
+
createdAt: z.union([z.string(), z.date()]).optional(),
|
|
2457
|
+
lastLoginAt: z.union([z.string(), z.date()]).nullable().optional(),
|
|
2458
|
+
onboardingCompleted: z.boolean().optional(),
|
|
2459
|
+
delegationGranted: z.boolean().optional(),
|
|
2460
|
+
wallets: z.array(userWalletDtoSchema).optional(),
|
|
2461
|
+
balance: z.object({ amount: z.string(), asset: z.string() }).nullable().optional(),
|
|
2462
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable().optional()
|
|
2463
|
+
});
|
|
2464
|
+
var publicUserDtoSchema = z.object({
|
|
2465
|
+
user: z.object({
|
|
2466
|
+
id: z.string(),
|
|
2467
|
+
email: z.string().nullable()
|
|
2468
|
+
}),
|
|
2469
|
+
walletAddress: z.string().nullable(),
|
|
2470
|
+
balance: z.object({ amount: z.string(), asset: z.string() }).nullable(),
|
|
2471
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable()
|
|
2472
|
+
});
|
|
2473
|
+
var signResponseSchema = z.object({
|
|
2474
|
+
signature: z.string().regex(/^0x[0-9a-fA-F]+$/, "must be 0x-prefixed hex"),
|
|
2475
|
+
walletAddress: z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be 0x-prefixed 40-char hex address")
|
|
2476
|
+
});
|
|
2477
|
+
|
|
2478
|
+
// src/schemas/device.ts
|
|
2479
|
+
var deviceStartResponseSchema = z.object({
|
|
2480
|
+
deviceCode: z.string(),
|
|
2481
|
+
userCode: z.string(),
|
|
2482
|
+
verificationUri: z.string(),
|
|
2483
|
+
pollInterval: z.number(),
|
|
2484
|
+
expiresAt: z.number()
|
|
2485
|
+
});
|
|
2486
|
+
var devicePollResponseSchema = z.union([
|
|
2487
|
+
// userCode + verificationUri are optional: older API deployments don't
|
|
2488
|
+
// echo them on pending.
|
|
2489
|
+
z.object({
|
|
2490
|
+
error: z.literal("authorization_pending"),
|
|
2491
|
+
userCode: z.string().optional(),
|
|
2492
|
+
verificationUri: z.string().optional()
|
|
2493
|
+
}),
|
|
2494
|
+
z.object({ error: z.literal("expired_token") }),
|
|
2495
|
+
z.object({
|
|
2496
|
+
accessToken: z.string(),
|
|
2497
|
+
refreshToken: z.string(),
|
|
2498
|
+
expiresIn: z.number(),
|
|
2499
|
+
user: internalUserDtoSchema
|
|
2500
|
+
})
|
|
2501
|
+
]);
|
|
2502
|
+
var sessionExchangeResponseSchema = z.object({
|
|
2503
|
+
token: z.string(),
|
|
2504
|
+
expiresAt: z.number()
|
|
2505
|
+
});
|
|
2506
|
+
|
|
2145
2507
|
// src/namespaces/auth-device.ts
|
|
2146
2508
|
var AuthDevice = class {
|
|
2147
2509
|
constructor(client) {
|
|
@@ -2203,8 +2565,10 @@ var repackageSignFailure = (err, op) => {
|
|
|
2203
2565
|
var Auth = class {
|
|
2204
2566
|
constructor(client) {
|
|
2205
2567
|
this.client = client;
|
|
2568
|
+
this.agent = new AuthAgent(client);
|
|
2206
2569
|
this.device = new AuthDevice(client);
|
|
2207
2570
|
}
|
|
2571
|
+
agent;
|
|
2208
2572
|
device;
|
|
2209
2573
|
// The internal (web-app facing) user profile. Richer than profile(): full
|
|
2210
2574
|
// wallet list with per-wallet delegation/signer/limit metadata.
|
|
@@ -2411,8 +2775,12 @@ var createBugReportResponseSchema = z.object({
|
|
|
2411
2775
|
searchId: z.number().nullable()
|
|
2412
2776
|
})
|
|
2413
2777
|
});
|
|
2414
|
-
|
|
2415
|
-
|
|
2778
|
+
var TEN_MIN_MS = 10 * 60 * 1e3;
|
|
2779
|
+
var autoIdempotencyKey = (description, contextSeed) => {
|
|
2780
|
+
const bucket = Math.floor(Date.now() / TEN_MIN_MS);
|
|
2781
|
+
const seed = `${description}|${contextSeed ?? ""}|${bucket}`;
|
|
2782
|
+
return `auto-${createHash("sha256").update(seed).digest("hex").slice(0, 16)}`;
|
|
2783
|
+
};
|
|
2416
2784
|
var BugReports = class {
|
|
2417
2785
|
constructor(client) {
|
|
2418
2786
|
this.client = client;
|
|
@@ -2420,16 +2788,26 @@ var BugReports = class {
|
|
|
2420
2788
|
// POST /v1/bug-reports. Wallet-attributed server-side; the SDK client's
|
|
2421
2789
|
// active credential drives attribution (account-mode → EIP-191 from the
|
|
2422
2790
|
// wallet, session-mode → Bearer + server resolves the user's wallet).
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2791
|
+
// When `idempotencyKey` is omitted, one is auto-derived from the description
|
|
2792
|
+
// and (optional) contextSeed, bucketed to 10-minute windows so accidental
|
|
2793
|
+
// retries within the window dedup naturally.
|
|
2794
|
+
create = (input, opts = {}) => {
|
|
2795
|
+
const { contextSeed, ...rest } = input;
|
|
2796
|
+
const withKey = {
|
|
2797
|
+
...rest,
|
|
2798
|
+
idempotencyKey: input.idempotencyKey ?? autoIdempotencyKey(input.description, contextSeed)
|
|
2799
|
+
};
|
|
2800
|
+
return request(
|
|
2801
|
+
this.client,
|
|
2802
|
+
{
|
|
2803
|
+
method: "POST",
|
|
2804
|
+
path: "/v1/bug-reports",
|
|
2805
|
+
body: withKey,
|
|
2806
|
+
signal: opts.signal
|
|
2807
|
+
},
|
|
2808
|
+
createBugReportResponseSchema
|
|
2809
|
+
);
|
|
2810
|
+
};
|
|
2433
2811
|
};
|
|
2434
2812
|
var ratingSchema = z.object({
|
|
2435
2813
|
score: z.string(),
|
|
@@ -2440,6 +2818,15 @@ var ratingSchema = z.object({
|
|
|
2440
2818
|
});
|
|
2441
2819
|
|
|
2442
2820
|
// src/schemas/capabilities.ts
|
|
2821
|
+
var pricingOptionSchema = z.object({
|
|
2822
|
+
kind: z.string(),
|
|
2823
|
+
protocol: z.string(),
|
|
2824
|
+
network: z.string().nullable(),
|
|
2825
|
+
amountUsd: z.string().nullable(),
|
|
2826
|
+
per: z.string(),
|
|
2827
|
+
confidence: z.string(),
|
|
2828
|
+
depositUsd: z.string().optional()
|
|
2829
|
+
});
|
|
2443
2830
|
var capabilityResponseSchema = z.object({
|
|
2444
2831
|
uid: z.string(),
|
|
2445
2832
|
slug: z.string(),
|
|
@@ -2464,6 +2851,26 @@ var capabilityResponseSchema = z.object({
|
|
|
2464
2851
|
instructions: z.string().nullable().optional(),
|
|
2465
2852
|
displayCostAmount: z.string(),
|
|
2466
2853
|
displayCostAsset: z.string(),
|
|
2854
|
+
// Whether the upstream advertises variable/usage-based pricing, and the raw
|
|
2855
|
+
// hint string (e.g. "$0.01/result"). The server emits both; without them an
|
|
2856
|
+
// agent sees a single scalar with no signal that the price scales with input
|
|
2857
|
+
// (ZERO-199). Optional so an older API deploy still parses.
|
|
2858
|
+
priceDynamic: z.boolean().optional(),
|
|
2859
|
+
priceHint: z.string().nullable().optional(),
|
|
2860
|
+
// ZERO-199: the authoritative price classification. Only `proven_free` may be
|
|
2861
|
+
// rendered "Free"; `unknown_unparsed` is a parse miss (never free); a parse
|
|
2862
|
+
// miss must not become "0"→Free. Optional so older deploys still parse.
|
|
2863
|
+
priceStatus: z.enum([
|
|
2864
|
+
"priced",
|
|
2865
|
+
"proven_free",
|
|
2866
|
+
"free_handshake",
|
|
2867
|
+
"unknown_unparsed",
|
|
2868
|
+
"unprobed"
|
|
2869
|
+
]).optional(),
|
|
2870
|
+
// ZERO-147 — provenance of displayCostAmount (settled | probe | registry |
|
|
2871
|
+
// unknown). `settled` means the shown price is reconciled from real charges.
|
|
2872
|
+
priceSource: z.string().nullable().optional(),
|
|
2873
|
+
requiresHandshake: z.boolean().optional(),
|
|
2467
2874
|
reviewCount: z.number(),
|
|
2468
2875
|
rating: ratingSchema,
|
|
2469
2876
|
priceObserved: z.object({
|
|
@@ -2486,9 +2893,27 @@ var capabilityResponseSchema = z.object({
|
|
|
2486
2893
|
mode: z.string(),
|
|
2487
2894
|
costAmount: z.string(),
|
|
2488
2895
|
costPer: z.string(),
|
|
2489
|
-
priority: z.number()
|
|
2896
|
+
priority: z.number(),
|
|
2897
|
+
// ZERO-199 rail-union fields (optional; older deploys omit them).
|
|
2898
|
+
asset: z.string().nullable().optional(),
|
|
2899
|
+
unit: z.string().optional(),
|
|
2900
|
+
depositMicros: z.number().nullable().optional(),
|
|
2901
|
+
planRef: z.string().nullable().optional()
|
|
2490
2902
|
})
|
|
2491
2903
|
).nullable(),
|
|
2904
|
+
// Recommended channel deposit for a `mode='session'` cap (the seller's
|
|
2905
|
+
// advertised `suggestedDeposit`). Without it an agent can't size an MPP
|
|
2906
|
+
// session channel. The server emits it; optional for older-deploy parsing
|
|
2907
|
+
// (ZERO-199).
|
|
2908
|
+
sessionDeposit: z.object({ amountUsd: z.string(), asset: z.string() }).nullable().optional(),
|
|
2909
|
+
// ZERO-199 P-B — the single resolved price. Prefer `pricing.summary`/`kind`
|
|
2910
|
+
// over re-deriving from the legacy fields. Optional so older deploys parse.
|
|
2911
|
+
pricing: z.object({
|
|
2912
|
+
kind: z.string(),
|
|
2913
|
+
summary: z.string(),
|
|
2914
|
+
primary: pricingOptionSchema.nullable(),
|
|
2915
|
+
accepted: z.array(pricingOptionSchema)
|
|
2916
|
+
}).optional(),
|
|
2492
2917
|
availabilityStatus: z.enum(["healthy", "unknown", "down"]).nullable().optional(),
|
|
2493
2918
|
/**
|
|
2494
2919
|
* @deprecated The API no longer emits `displayStatus`; it has been replaced
|
|
@@ -2709,50 +3134,39 @@ var Runs = class {
|
|
|
2709
3134
|
batchReviewResponseSchema
|
|
2710
3135
|
);
|
|
2711
3136
|
};
|
|
2712
|
-
var USDC_BASE2 = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
2713
|
-
var USDC_TEMPO2 = "0x20c000000000000000000000b9537d11c60e8b50";
|
|
2714
|
-
var TEMPO_CHAIN_ID2 = 4217;
|
|
2715
|
-
var baseChain = base;
|
|
2716
|
-
var tempoChain2 = {
|
|
2717
|
-
id: TEMPO_CHAIN_ID2,
|
|
2718
|
-
name: "Tempo",
|
|
2719
|
-
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
2720
|
-
rpcUrls: {
|
|
2721
|
-
default: { http: ["https://rpc.tempo.xyz"] }
|
|
2722
|
-
}
|
|
2723
|
-
};
|
|
2724
|
-
var ERC20_BALANCE_ABI2 = [
|
|
2725
|
-
{
|
|
2726
|
-
inputs: [{ name: "account", type: "address" }],
|
|
2727
|
-
name: "balanceOf",
|
|
2728
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
2729
|
-
stateMutability: "view",
|
|
2730
|
-
type: "function"
|
|
2731
|
-
}
|
|
2732
|
-
];
|
|
2733
|
-
var USDC_DECIMALS = 6;
|
|
2734
|
-
|
|
2735
|
-
// src/namespaces/wallet.ts
|
|
2736
3137
|
var fundingUrlResponseSchema = z.object({ url: z.string() });
|
|
2737
3138
|
var userWalletListSchema = z.array(userWalletDtoSchema);
|
|
2738
|
-
var migrateAuthorizationResponseSchema = z.object({
|
|
2739
|
-
transactionHash: z.string()
|
|
2740
|
-
});
|
|
2741
3139
|
var errorMessage = (reason) => reason instanceof Error ? reason.message : String(reason);
|
|
2742
3140
|
var Wallet = class {
|
|
2743
3141
|
constructor(client) {
|
|
2744
3142
|
this.client = client;
|
|
2745
3143
|
}
|
|
2746
3144
|
clients = {};
|
|
2747
|
-
// The configured
|
|
2748
|
-
//
|
|
2749
|
-
get
|
|
3145
|
+
// The configured account's address, or null when the client runs in
|
|
3146
|
+
// session/no-credential mode. Local read — never hits the network.
|
|
3147
|
+
get configuredAddress() {
|
|
2750
3148
|
const credentials = this.client.getCredentials();
|
|
2751
3149
|
if (credentials.kind !== "account") return null;
|
|
2752
3150
|
return credentials.account.address;
|
|
2753
3151
|
}
|
|
3152
|
+
// The wallet address this client acts as. Account mode resolves locally
|
|
3153
|
+
// (no network). Session mode resolves the user's managed (Privy-embedded)
|
|
3154
|
+
// wallet, provisioning one on first call if the user has none yet. Throws
|
|
3155
|
+
// on network/auth failure — callers that want a null-fallback should wrap
|
|
3156
|
+
// in try/catch (the CLI does this in `resolveManagedWalletAddress`).
|
|
3157
|
+
address = async (opts = {}) => {
|
|
3158
|
+
const configured = this.configuredAddress;
|
|
3159
|
+
if (configured) return configured;
|
|
3160
|
+
const wallets = await this.list(opts);
|
|
3161
|
+
const primary = wallets.find(
|
|
3162
|
+
(w) => w.source === "privy_embedded" && w.isPrimary
|
|
3163
|
+
);
|
|
3164
|
+
if (primary) return primary.walletAddress;
|
|
3165
|
+
const provisioned = await this.provision(opts);
|
|
3166
|
+
return provisioned.walletAddress;
|
|
3167
|
+
};
|
|
2754
3168
|
balance = async (opts = {}) => {
|
|
2755
|
-
const target = opts.address ?? this.
|
|
3169
|
+
const target = opts.address ?? this.configuredAddress;
|
|
2756
3170
|
if (!target) {
|
|
2757
3171
|
throw new ZeroWalletError(
|
|
2758
3172
|
"balance() requires either an `address` option or a client constructed with an account"
|
|
@@ -2812,21 +3226,6 @@ var Wallet = class {
|
|
|
2812
3226
|
},
|
|
2813
3227
|
userWalletDtoSchema
|
|
2814
3228
|
);
|
|
2815
|
-
// Relays a BYO-wallet-signed EIP-3009 ReceiveWithAuthorization, sweeping
|
|
2816
|
-
// USDC from the BYO wallet to the user's Zero wallet on Base via the
|
|
2817
|
-
// gas-paying relayer. The SDK does not author the authorization (chain
|
|
2818
|
-
// nonce + EIP-712 domain coupling stays caller-side); it only forwards
|
|
2819
|
-
// the signed payload. Session-only.
|
|
2820
|
-
migrateAuthorization = (authorization, opts = {}) => request(
|
|
2821
|
-
this.client,
|
|
2822
|
-
{
|
|
2823
|
-
method: "POST",
|
|
2824
|
-
path: "/v1/users/me/wallets/migrate",
|
|
2825
|
-
body: { authorization },
|
|
2826
|
-
signal: opts.signal
|
|
2827
|
-
},
|
|
2828
|
-
migrateAuthorizationResponseSchema
|
|
2829
|
-
);
|
|
2830
3229
|
// Routes by identity: account mode signs EIP-191 against /v1/wallet/fund-url,
|
|
2831
3230
|
// session mode hits /v1/users/me/fund-url (Bearer-authed, wallet resolved
|
|
2832
3231
|
// server-side). Both honor `provider` (coinbase | stripe).
|
|
@@ -2862,7 +3261,7 @@ var Wallet = class {
|
|
|
2862
3261
|
if (!this.clients.tempo) {
|
|
2863
3262
|
this.clients.tempo = createPublicClient({
|
|
2864
3263
|
// biome-ignore lint/suspicious/noExplicitAny: tempo is a custom chain object that viem's stricter Chain type rejects shape-wise but accepts at runtime
|
|
2865
|
-
chain:
|
|
3264
|
+
chain: tempoChain,
|
|
2866
3265
|
transport: http()
|
|
2867
3266
|
});
|
|
2868
3267
|
}
|
|
@@ -2878,10 +3277,10 @@ var Wallet = class {
|
|
|
2878
3277
|
*/
|
|
2879
3278
|
readChainBalance = async (chain, address) => {
|
|
2880
3279
|
const publicClient = this.getPublicClient(chain);
|
|
2881
|
-
const tokenAddress = chain === "base" ?
|
|
3280
|
+
const tokenAddress = chain === "base" ? USDC_BASE : USDC_TEMPO;
|
|
2882
3281
|
const balance = await publicClient.readContract({
|
|
2883
3282
|
address: tokenAddress,
|
|
2884
|
-
abi:
|
|
3283
|
+
abi: ERC20_BALANCE_ABI,
|
|
2885
3284
|
functionName: "balanceOf",
|
|
2886
3285
|
args: [address]
|
|
2887
3286
|
});
|
|
@@ -2919,6 +3318,15 @@ var searchResultSchema = z.object({
|
|
|
2919
3318
|
url: z.string(),
|
|
2920
3319
|
urlTemplate: z.string().nullable().optional(),
|
|
2921
3320
|
cost: z.object({ amount: z.string(), asset: z.string() }),
|
|
3321
|
+
// ZERO-199 — the server-resolved price. Prefer `pricing.summary` over
|
|
3322
|
+
// deriving a label from `cost.amount` (which flattens usage-priced caps).
|
|
3323
|
+
// Optional: absent on older API deploys.
|
|
3324
|
+
pricing: z.object({ kind: z.string(), summary: z.string() }).optional(),
|
|
3325
|
+
// Payment protocol (x402 | mpp) for this result. The server emits it; the SDK
|
|
3326
|
+
// previously stripped it, leaving an agent unable to tell which handshake to
|
|
3327
|
+
// engage from a search row. Optional/nullable so older deploys still parse
|
|
3328
|
+
// (ZERO-199).
|
|
3329
|
+
protocol: z.string().nullable().optional(),
|
|
2922
3330
|
reviewCount: z.number().optional(),
|
|
2923
3331
|
rating: ratingSchema,
|
|
2924
3332
|
// All-time activation count (non-deleted runs), mirroring capabilities.ts.
|
|
@@ -3307,6 +3715,26 @@ var ZeroClient = class _ZeroClient {
|
|
|
3307
3715
|
// path is flat on the client, same rationale as `search` above.
|
|
3308
3716
|
// Orchestration lives in fetch.ts so this class stays readable.
|
|
3309
3717
|
fetch = (url, opts = {}) => clientFetch(this, url, opts);
|
|
3718
|
+
// Poll the API server's /health endpoint until it responds OK. Useful for
|
|
3719
|
+
// warming up a cold container before spawning a subprocess that needs the
|
|
3720
|
+
// API ready. Resolves when healthy, resolves (silently) when maxAttempts
|
|
3721
|
+
// is exhausted — never throws, so callers proceed regardless of outcome.
|
|
3722
|
+
ping = async (opts = {}) => {
|
|
3723
|
+
const { maxAttempts = 20, timeoutMs = 2e3, retryDelayMs = 500 } = opts;
|
|
3724
|
+
const healthUrl = `${this.baseUrl}/health`;
|
|
3725
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
3726
|
+
try {
|
|
3727
|
+
const res = await this.fetchImpl(healthUrl, {
|
|
3728
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
3729
|
+
});
|
|
3730
|
+
if (res.ok) return;
|
|
3731
|
+
} catch {
|
|
3732
|
+
}
|
|
3733
|
+
if (i < maxAttempts - 1) {
|
|
3734
|
+
await new Promise((r) => setTimeout(r, retryDelayMs));
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
};
|
|
3310
3738
|
// No-op today. Reserved for an explicit drain/cancel handle once
|
|
3311
3739
|
// long-running consumers need one — do NOT rely on this to abort
|
|
3312
3740
|
// in-flight requests or flush recording. Consumers needing
|
|
@@ -3315,6 +3743,6 @@ var ZeroClient = class _ZeroClient {
|
|
|
3315
3743
|
};
|
|
3316
3744
|
};
|
|
3317
3745
|
|
|
3318
|
-
export { Auth, AuthDevice, BUG_REPORT_CATEGORIES, BugReports, Capabilities, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, FETCH_SKIP_REASONS, FETCH_WARNINGS, Payments, Runs, SDK_VERSION, TEMPO_CHAIN_ID, TEMPO_TESTNET_CHAIN_ID, Wallet, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, isShortToken, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope };
|
|
3319
|
-
//# sourceMappingURL=chunk-
|
|
3320
|
-
//# sourceMappingURL=chunk-
|
|
3746
|
+
export { Auth, AuthAgent, AuthDevice, BUG_REPORT_CATEGORIES, BugReports, Capabilities, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, FETCH_SKIP_REASONS, FETCH_WARNINGS, Payments, Runs, SDK_VERSION, TEMPO_CHAIN_ID2 as TEMPO_CHAIN_ID, TEMPO_TESTNET_CHAIN_ID, USDC_BASE, USDC_DECIMALS, USDC_TEMPO, Wallet, ZeroAgentAuthError, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, isShortToken, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope };
|
|
3747
|
+
//# sourceMappingURL=chunk-A7WZYQXS.js.map
|
|
3748
|
+
//# sourceMappingURL=chunk-A7WZYQXS.js.map
|