@zeroxyz/cli 1.15.0 → 1.17.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/index.js +633 -344
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -78449,7 +78449,7 @@ init_esm_shims();
|
|
|
78449
78449
|
// ../sdk/dist/index.js
|
|
78450
78450
|
init_esm_shims();
|
|
78451
78451
|
|
|
78452
|
-
// ../sdk/dist/chunk-
|
|
78452
|
+
// ../sdk/dist/chunk-T77VVLOM.js
|
|
78453
78453
|
init_esm_shims();
|
|
78454
78454
|
|
|
78455
78455
|
// ../../node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@4.3.6/node_modules/viem/_esm/index.js
|
|
@@ -143831,7 +143831,7 @@ config(en_default2());
|
|
|
143831
143831
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js
|
|
143832
143832
|
var zod_default = external_exports3;
|
|
143833
143833
|
|
|
143834
|
-
// ../sdk/dist/chunk-
|
|
143834
|
+
// ../sdk/dist/chunk-T77VVLOM.js
|
|
143835
143835
|
var createManagedAccount = (client, address2) => toAccount({
|
|
143836
143836
|
address: address2,
|
|
143837
143837
|
async signMessage({ message: message2 }) {
|
|
@@ -143910,6 +143910,25 @@ var ZeroAuthError = class extends ZeroError {
|
|
|
143910
143910
|
this.name = "ZeroAuthError";
|
|
143911
143911
|
}
|
|
143912
143912
|
};
|
|
143913
|
+
var ZeroAgentAuthError = class extends ZeroError {
|
|
143914
|
+
status;
|
|
143915
|
+
body;
|
|
143916
|
+
constructor(message2, init) {
|
|
143917
|
+
super("auth_error", message2, { cause: init.cause });
|
|
143918
|
+
this.name = "ZeroAgentAuthError";
|
|
143919
|
+
this.status = init.status;
|
|
143920
|
+
this.body = init.body;
|
|
143921
|
+
}
|
|
143922
|
+
// The error code the SERVER sent, distinct from ZeroError's `code`
|
|
143923
|
+
// discriminator. WorkOS error bodies carry {code, message}; OAuth-style
|
|
143924
|
+
// ones carry {error}.
|
|
143925
|
+
get serverCode() {
|
|
143926
|
+
const body = this.body;
|
|
143927
|
+
if (typeof body?.code === "string") return body.code;
|
|
143928
|
+
if (typeof body?.error === "string") return body.error;
|
|
143929
|
+
return null;
|
|
143930
|
+
}
|
|
143931
|
+
};
|
|
143913
143932
|
var ZeroPaymentError = class extends ZeroError {
|
|
143914
143933
|
constructor(message2, options) {
|
|
143915
143934
|
super("payment_error", message2, options);
|
|
@@ -145267,16 +145286,89 @@ var extractUpstreamErrorMessage = (body) => {
|
|
|
145267
145286
|
}
|
|
145268
145287
|
return void 0;
|
|
145269
145288
|
};
|
|
145289
|
+
var extractFieldName = (message2) => {
|
|
145290
|
+
const patterns = [
|
|
145291
|
+
/(?:field|param(?:eter)?|property|key)[:\s]+["'`]?([a-z0-9_.[\]-]+)["'`]?/i,
|
|
145292
|
+
/["'`]([a-z0-9_.[\]-]+)["'`]\s*(?:is\s+)?(?:required|missing|expected)/i,
|
|
145293
|
+
// Quotes REQUIRED here — an unquoted token after "required"/"missing"
|
|
145294
|
+
// is usually a generic noun ("required parameters", "missing fields"),
|
|
145295
|
+
// not a field name. Only trust it when the seller quoted it.
|
|
145296
|
+
/(?:required|missing|expected)[:\s]+["'`]([a-z0-9_.[\]-]+)["'`]/i
|
|
145297
|
+
];
|
|
145298
|
+
for (const p of patterns) {
|
|
145299
|
+
const match = message2.match(p);
|
|
145300
|
+
if (match?.[1]) return match[1];
|
|
145301
|
+
}
|
|
145302
|
+
return void 0;
|
|
145303
|
+
};
|
|
145304
|
+
var extractAllowedMethod = (text) => {
|
|
145305
|
+
const listed = text.match(
|
|
145306
|
+
/allowed[^[]*\[\s*["'`]?(GET|POST|PUT|PATCH|DELETE|HEAD)/i
|
|
145307
|
+
);
|
|
145308
|
+
if (listed?.[1]) return listed[1].toUpperCase();
|
|
145309
|
+
const useVerb = text.match(/\buse\s+(GET|POST|PUT|PATCH|DELETE|HEAD)\b/i);
|
|
145310
|
+
if (useVerb?.[1]) return useVerb[1].toUpperCase();
|
|
145311
|
+
return void 0;
|
|
145312
|
+
};
|
|
145313
|
+
var extractUnrecognizedKeys = (bodyRaw) => {
|
|
145314
|
+
if (!bodyRaw) return [];
|
|
145315
|
+
const parsed = tryParseJson(bodyRaw);
|
|
145316
|
+
if (parsed === null || typeof parsed !== "object") return [];
|
|
145317
|
+
const out = [];
|
|
145318
|
+
const visit = (node) => {
|
|
145319
|
+
if (!node || typeof node !== "object") return;
|
|
145320
|
+
const o = node;
|
|
145321
|
+
if (Array.isArray(o.keys)) {
|
|
145322
|
+
for (const k of o.keys) if (typeof k === "string") out.push(k);
|
|
145323
|
+
}
|
|
145324
|
+
for (const v of Object.values(o)) {
|
|
145325
|
+
if (Array.isArray(v)) v.forEach(visit);
|
|
145326
|
+
else if (v && typeof v === "object") visit(v);
|
|
145327
|
+
}
|
|
145328
|
+
};
|
|
145329
|
+
visit(parsed);
|
|
145330
|
+
return [...new Set(out)].slice(0, 8);
|
|
145331
|
+
};
|
|
145332
|
+
var computeFixHint = (status, message2, bodyRaw) => {
|
|
145333
|
+
if (status < 400 || status >= 500) return void 0;
|
|
145334
|
+
const hay = `${message2 ?? ""} ${bodyRaw ?? ""}`.toLowerCase();
|
|
145335
|
+
if (status === 405 || /method not allowed|method_not_allowed/.test(hay)) {
|
|
145336
|
+
const allowed = extractAllowedMethod(`${bodyRaw ?? ""} ${message2 ?? ""}`);
|
|
145337
|
+
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";
|
|
145338
|
+
}
|
|
145339
|
+
if (/invalid json|not valid json|malformed|unexpected token|json ?parse|could not parse|failed to parse|jsondecode/.test(
|
|
145340
|
+
hay
|
|
145341
|
+
)) {
|
|
145342
|
+
return "the request body isn't valid JSON \u2014 check quoting/escaping (single-quote the -d value or use @file), then retry";
|
|
145343
|
+
}
|
|
145344
|
+
if (/unrecognized[_ ]?key|unexpected key|unknown (field|key|propert)|additional (?:propert|field)|not allowed in object/.test(
|
|
145345
|
+
hay
|
|
145346
|
+
)) {
|
|
145347
|
+
const keys = extractUnrecognizedKeys(bodyRaw ?? null);
|
|
145348
|
+
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";
|
|
145349
|
+
}
|
|
145350
|
+
if (status === 415 || /content-?type|unsupported media|media type/.test(hay)) {
|
|
145351
|
+
return "set the Content-Type header to what the capability expects (usually application/json), then retry";
|
|
145352
|
+
}
|
|
145353
|
+
if (/required|missing|must (include|provide|have|contain)|is expected/.test(hay)) {
|
|
145354
|
+
const field = extractFieldName(message2 ?? "");
|
|
145355
|
+
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";
|
|
145356
|
+
}
|
|
145357
|
+
return void 0;
|
|
145358
|
+
};
|
|
145270
145359
|
var buildUpstreamError = (status, bodyRaw, bodyEncoding) => {
|
|
145271
145360
|
if (status >= 200 && status < 300) return void 0;
|
|
145272
145361
|
if (bodyRaw === null || bodyRaw.length === 0) return void 0;
|
|
145273
145362
|
if (bodyEncoding === "base64") return void 0;
|
|
145274
145363
|
const snippet = bodyRaw.slice(0, ERROR_SNIPPET_BYTES);
|
|
145364
|
+
const message2 = extractUpstreamErrorMessage(bodyRaw);
|
|
145365
|
+
const fixHint = computeFixHint(status, message2, bodyRaw);
|
|
145275
145366
|
return {
|
|
145276
145367
|
status,
|
|
145277
|
-
message:
|
|
145368
|
+
message: message2,
|
|
145278
145369
|
snippetHash: createHash("sha256").update(snippet).digest("hex"),
|
|
145279
|
-
snippetLength: snippet.length
|
|
145370
|
+
snippetLength: snippet.length,
|
|
145371
|
+
...fixHint && { fixHint }
|
|
145280
145372
|
};
|
|
145281
145373
|
};
|
|
145282
145374
|
var computeOutcome = (status, payment, warnings) => {
|
|
@@ -145665,74 +145757,63 @@ var clientFetch = async (client, url4, opts = {}) => {
|
|
|
145665
145757
|
return result;
|
|
145666
145758
|
};
|
|
145667
145759
|
var package_default = {
|
|
145668
|
-
version: "0.
|
|
145760
|
+
version: "0.11.0"
|
|
145669
145761
|
};
|
|
145670
145762
|
var SDK_VERSION2 = package_default.version;
|
|
145671
|
-
var
|
|
145672
|
-
|
|
145673
|
-
|
|
145674
|
-
|
|
145675
|
-
|
|
145676
|
-
|
|
145677
|
-
|
|
145678
|
-
|
|
145679
|
-
maxTransactionUsdcBaseUnits: external_exports3.number().int().nullable()
|
|
145680
|
-
});
|
|
145681
|
-
var welcomeBonusSummarySchema = external_exports3.object({
|
|
145682
|
-
status: external_exports3.string(),
|
|
145683
|
-
amountUsd: external_exports3.number()
|
|
145684
|
-
});
|
|
145685
|
-
var internalUserDtoSchema = external_exports3.object({
|
|
145763
|
+
var agentAuthMetadataSchema = external_exports3.object({
|
|
145764
|
+
token_endpoint: external_exports3.string().optional(),
|
|
145765
|
+
agent_auth: external_exports3.object({
|
|
145766
|
+
identity_endpoint: external_exports3.string(),
|
|
145767
|
+
claim_endpoint: external_exports3.string().optional()
|
|
145768
|
+
}).loose()
|
|
145769
|
+
}).loose();
|
|
145770
|
+
var identityEnvelopeSchema = external_exports3.object({
|
|
145686
145771
|
id: external_exports3.string(),
|
|
145687
|
-
|
|
145688
|
-
|
|
145689
|
-
|
|
145690
|
-
|
|
145691
|
-
|
|
145692
|
-
|
|
145693
|
-
|
|
145694
|
-
|
|
145695
|
-
})
|
|
145696
|
-
|
|
145697
|
-
|
|
145698
|
-
|
|
145699
|
-
|
|
145700
|
-
|
|
145701
|
-
|
|
145702
|
-
|
|
145703
|
-
|
|
145704
|
-
});
|
|
145705
|
-
var
|
|
145706
|
-
|
|
145707
|
-
|
|
145708
|
-
|
|
145709
|
-
|
|
145710
|
-
|
|
145711
|
-
|
|
145712
|
-
|
|
145713
|
-
|
|
145714
|
-
|
|
145715
|
-
|
|
145716
|
-
|
|
145717
|
-
|
|
145718
|
-
|
|
145719
|
-
|
|
145720
|
-
|
|
145721
|
-
|
|
145722
|
-
|
|
145723
|
-
|
|
145724
|
-
|
|
145725
|
-
|
|
145726
|
-
|
|
145727
|
-
|
|
145728
|
-
|
|
145729
|
-
|
|
145730
|
-
|
|
145731
|
-
|
|
145732
|
-
var sessionExchangeResponseSchema = external_exports3.object({
|
|
145733
|
-
token: external_exports3.string(),
|
|
145734
|
-
expiresAt: external_exports3.number()
|
|
145735
|
-
});
|
|
145772
|
+
identity: external_exports3.object({
|
|
145773
|
+
assertion: external_exports3.string(),
|
|
145774
|
+
expires_at: external_exports3.string().optional(),
|
|
145775
|
+
refresh_token: external_exports3.object({ value: external_exports3.string() }).loose().optional()
|
|
145776
|
+
}).loose(),
|
|
145777
|
+
claim: external_exports3.object({
|
|
145778
|
+
token: external_exports3.string().optional(),
|
|
145779
|
+
expires_at: external_exports3.string().optional()
|
|
145780
|
+
}).loose().optional()
|
|
145781
|
+
}).loose().transform((raw) => ({
|
|
145782
|
+
registrationId: raw.id,
|
|
145783
|
+
identityAssertion: raw.identity.assertion,
|
|
145784
|
+
assertionExpires: raw.identity.expires_at ?? null,
|
|
145785
|
+
refreshToken: raw.identity.refresh_token?.value ?? null,
|
|
145786
|
+
claimToken: raw.claim?.token ?? null,
|
|
145787
|
+
claimTokenExpires: raw.claim?.expires_at ?? null
|
|
145788
|
+
}));
|
|
145789
|
+
var agentTokenResponseSchema = external_exports3.object({ access_token: external_exports3.string() }).loose().transform((raw) => ({ accessToken: raw.access_token }));
|
|
145790
|
+
var startClaimResponseSchema = external_exports3.object({
|
|
145791
|
+
attempt: external_exports3.object({
|
|
145792
|
+
verification_uri: external_exports3.string(),
|
|
145793
|
+
expires_at: external_exports3.string().optional()
|
|
145794
|
+
}).loose()
|
|
145795
|
+
}).loose().transform((raw) => ({
|
|
145796
|
+
verificationUri: raw.attempt.verification_uri,
|
|
145797
|
+
expiresAt: raw.attempt.expires_at ?? null
|
|
145798
|
+
}));
|
|
145799
|
+
var completeClaimResponseSchema = external_exports3.object({
|
|
145800
|
+
identity: external_exports3.object({
|
|
145801
|
+
assertion: external_exports3.string(),
|
|
145802
|
+
expires_at: external_exports3.string().optional(),
|
|
145803
|
+
refresh_token: external_exports3.object({ value: external_exports3.string() }).loose().optional()
|
|
145804
|
+
}).loose()
|
|
145805
|
+
}).loose().transform((raw) => ({
|
|
145806
|
+
identityAssertion: raw.identity.assertion,
|
|
145807
|
+
assertionExpires: raw.identity.expires_at ?? null,
|
|
145808
|
+
refreshToken: raw.identity.refresh_token?.value ?? null
|
|
145809
|
+
}));
|
|
145810
|
+
var agentZeroSessionSchema = external_exports3.object({
|
|
145811
|
+
accessToken: external_exports3.string(),
|
|
145812
|
+
refreshToken: external_exports3.string(),
|
|
145813
|
+
expiresIn: external_exports3.number(),
|
|
145814
|
+
user: external_exports3.object({ id: external_exports3.string() }).loose(),
|
|
145815
|
+
walletAddress: external_exports3.string().optional()
|
|
145816
|
+
}).loose();
|
|
145736
145817
|
var refreshResponseSchema = external_exports3.object({
|
|
145737
145818
|
accessToken: external_exports3.string(),
|
|
145738
145819
|
refreshToken: external_exports3.string()
|
|
@@ -145965,6 +146046,264 @@ var request2 = async (client, opts, schema) => {
|
|
|
145965
146046
|
cause: lastNetworkError
|
|
145966
146047
|
});
|
|
145967
146048
|
};
|
|
146049
|
+
var JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
146050
|
+
var trimSlash = (value) => value.replace(/\/$/, "");
|
|
146051
|
+
var wrapNetworkError = (url4, err) => {
|
|
146052
|
+
const cause = err?.cause;
|
|
146053
|
+
const causeMessage = cause instanceof Error ? cause.code ?? cause.message : err instanceof Error ? err.message : String(err);
|
|
146054
|
+
return new ZeroAgentAuthError(`Could not reach ${url4} (${causeMessage})`, {
|
|
146055
|
+
status: 0,
|
|
146056
|
+
cause: err
|
|
146057
|
+
});
|
|
146058
|
+
};
|
|
146059
|
+
var AuthAgent = class {
|
|
146060
|
+
constructor(client) {
|
|
146061
|
+
this.client = client;
|
|
146062
|
+
}
|
|
146063
|
+
endpointsPromise = null;
|
|
146064
|
+
// Fully autonomous signup: register anonymously at the AuthKit domain,
|
|
146065
|
+
// exchange the identity assertion for a WorkOS access token, exchange that
|
|
146066
|
+
// for a Zero session. The claim token and identity assertion are returned
|
|
146067
|
+
// exactly once — the caller persists them.
|
|
146068
|
+
signup = async () => {
|
|
146069
|
+
const registration = await this.register();
|
|
146070
|
+
const token = await this.exchangeAssertion(registration.identityAssertion);
|
|
146071
|
+
const session4 = await this.exchangeAtZero(token.accessToken);
|
|
146072
|
+
return { registration, session: session4 };
|
|
146073
|
+
};
|
|
146074
|
+
register = async () => {
|
|
146075
|
+
const endpoints = await this.endpoints();
|
|
146076
|
+
return this.postJson(
|
|
146077
|
+
endpoints.identityEndpoint,
|
|
146078
|
+
{ type: "anonymous" },
|
|
146079
|
+
identityEnvelopeSchema
|
|
146080
|
+
);
|
|
146081
|
+
};
|
|
146082
|
+
exchangeAssertion = async (identityAssertion) => {
|
|
146083
|
+
const endpoints = await this.endpoints();
|
|
146084
|
+
return this.postForm(
|
|
146085
|
+
endpoints.tokenEndpoint,
|
|
146086
|
+
{ grant_type: JWT_BEARER_GRANT_TYPE, assertion: identityAssertion },
|
|
146087
|
+
agentTokenResponseSchema
|
|
146088
|
+
);
|
|
146089
|
+
};
|
|
146090
|
+
// POST /v1/auth/agent/exchange — WorkOS agent access token → Zero session
|
|
146091
|
+
// pair (+ the implicitly provisioned wallet address). The post-claim token
|
|
146092
|
+
// goes through here too: the server binds the claiming human.
|
|
146093
|
+
exchangeAtZero = (accessToken, opts = {}) => request2(
|
|
146094
|
+
this.client,
|
|
146095
|
+
{
|
|
146096
|
+
method: "POST",
|
|
146097
|
+
path: "/v1/auth/agent/exchange",
|
|
146098
|
+
body: { accessToken },
|
|
146099
|
+
signal: opts.signal
|
|
146100
|
+
},
|
|
146101
|
+
agentZeroSessionSchema
|
|
146102
|
+
);
|
|
146103
|
+
// Mint a claim attempt. The human opens the returned verification URI,
|
|
146104
|
+
// signs in as `email`, and the page shows THEM a pairing code to read back
|
|
146105
|
+
// to the agent — completeClaim() submits it.
|
|
146106
|
+
startClaim = async (input) => {
|
|
146107
|
+
const endpoints = await this.endpoints();
|
|
146108
|
+
if (!endpoints.claimEndpoint) {
|
|
146109
|
+
throw new ZeroAgentAuthError(
|
|
146110
|
+
"The authorization server advertises no claim endpoint.",
|
|
146111
|
+
{ status: 0 }
|
|
146112
|
+
);
|
|
146113
|
+
}
|
|
146114
|
+
return this.postJson(
|
|
146115
|
+
endpoints.claimEndpoint,
|
|
146116
|
+
{
|
|
146117
|
+
type: "service_auth",
|
|
146118
|
+
claim_token: input.claimToken,
|
|
146119
|
+
login_hint: input.email
|
|
146120
|
+
},
|
|
146121
|
+
startClaimResponseSchema
|
|
146122
|
+
);
|
|
146123
|
+
};
|
|
146124
|
+
// Submit the pairing code the human read off the hosted page. Terminal
|
|
146125
|
+
// states map to a typed result; anything unexpected throws.
|
|
146126
|
+
completeClaim = async (input) => {
|
|
146127
|
+
const endpoints = await this.endpoints();
|
|
146128
|
+
if (!endpoints.claimEndpoint) {
|
|
146129
|
+
throw new ZeroAgentAuthError(
|
|
146130
|
+
"The authorization server advertises no claim endpoint.",
|
|
146131
|
+
{ status: 0 }
|
|
146132
|
+
);
|
|
146133
|
+
}
|
|
146134
|
+
try {
|
|
146135
|
+
const identity = await this.postJson(
|
|
146136
|
+
`${endpoints.claimEndpoint}/complete`,
|
|
146137
|
+
{ claim_token: input.claimToken, user_code: input.userCode },
|
|
146138
|
+
completeClaimResponseSchema
|
|
146139
|
+
);
|
|
146140
|
+
return { status: "ok", ...identity };
|
|
146141
|
+
} catch (err) {
|
|
146142
|
+
if (err instanceof ZeroAgentAuthError && err.serverCode) {
|
|
146143
|
+
if (err.serverCode === "claim_not_confirmed") {
|
|
146144
|
+
return { status: "not_confirmed" };
|
|
146145
|
+
}
|
|
146146
|
+
if (err.serverCode === "invalid_user_code") {
|
|
146147
|
+
return { status: "invalid_code" };
|
|
146148
|
+
}
|
|
146149
|
+
if ([
|
|
146150
|
+
"user_code_expired",
|
|
146151
|
+
"claim_expired",
|
|
146152
|
+
"claim_revoked",
|
|
146153
|
+
"already_claimed",
|
|
146154
|
+
"claim_denied"
|
|
146155
|
+
].includes(err.serverCode)) {
|
|
146156
|
+
return { status: "expired", code: err.serverCode };
|
|
146157
|
+
}
|
|
146158
|
+
}
|
|
146159
|
+
throw err;
|
|
146160
|
+
}
|
|
146161
|
+
};
|
|
146162
|
+
// Resolve (and cache) the agent-auth endpoints via discovery.
|
|
146163
|
+
endpoints = () => {
|
|
146164
|
+
if (!this.endpointsPromise) {
|
|
146165
|
+
this.endpointsPromise = this.discover().catch((err) => {
|
|
146166
|
+
this.endpointsPromise = null;
|
|
146167
|
+
throw err;
|
|
146168
|
+
});
|
|
146169
|
+
}
|
|
146170
|
+
return this.endpointsPromise;
|
|
146171
|
+
};
|
|
146172
|
+
discover = async () => {
|
|
146173
|
+
const resource = await this.getJson(
|
|
146174
|
+
`${trimSlash(this.client.baseUrl)}/.well-known/oauth-protected-resource`
|
|
146175
|
+
);
|
|
146176
|
+
let lastError = null;
|
|
146177
|
+
for (const server of resource.authorization_servers ?? []) {
|
|
146178
|
+
try {
|
|
146179
|
+
const raw = await this.getJson(
|
|
146180
|
+
`${trimSlash(server)}/.well-known/oauth-authorization-server`
|
|
146181
|
+
);
|
|
146182
|
+
const metadata = agentAuthMetadataSchema.parse(raw);
|
|
146183
|
+
return {
|
|
146184
|
+
authorizationServer: trimSlash(server),
|
|
146185
|
+
identityEndpoint: metadata.agent_auth.identity_endpoint,
|
|
146186
|
+
claimEndpoint: metadata.agent_auth.claim_endpoint ?? null,
|
|
146187
|
+
tokenEndpoint: metadata.token_endpoint ?? `${trimSlash(server)}/oauth2/token`
|
|
146188
|
+
};
|
|
146189
|
+
} catch (err) {
|
|
146190
|
+
lastError = err;
|
|
146191
|
+
}
|
|
146192
|
+
}
|
|
146193
|
+
throw new ZeroAgentAuthError(
|
|
146194
|
+
"No authorization server with an agent_auth block found \u2014 agent registration is not enabled for this service.",
|
|
146195
|
+
{ status: 0, cause: lastError }
|
|
146196
|
+
);
|
|
146197
|
+
};
|
|
146198
|
+
getJson = async (url4) => {
|
|
146199
|
+
const response = await this.client.fetchImpl(url4).catch((err) => {
|
|
146200
|
+
throw wrapNetworkError(url4, err);
|
|
146201
|
+
});
|
|
146202
|
+
if (!response.ok) {
|
|
146203
|
+
throw new ZeroAgentAuthError(`GET ${url4} failed (${response.status})`, {
|
|
146204
|
+
status: response.status
|
|
146205
|
+
});
|
|
146206
|
+
}
|
|
146207
|
+
return await response.json();
|
|
146208
|
+
};
|
|
146209
|
+
postJson = (url4, body, schema) => this.post(url4, "application/json", JSON.stringify(body), schema);
|
|
146210
|
+
postForm = (url4, fields, schema) => this.post(
|
|
146211
|
+
url4,
|
|
146212
|
+
"application/x-www-form-urlencoded",
|
|
146213
|
+
new URLSearchParams(fields).toString(),
|
|
146214
|
+
schema
|
|
146215
|
+
);
|
|
146216
|
+
post = async (url4, contentType, body, schema) => {
|
|
146217
|
+
const response = await this.client.fetchImpl(url4, {
|
|
146218
|
+
method: "POST",
|
|
146219
|
+
headers: { "content-type": contentType },
|
|
146220
|
+
body
|
|
146221
|
+
}).catch((err) => {
|
|
146222
|
+
throw wrapNetworkError(url4, err);
|
|
146223
|
+
});
|
|
146224
|
+
const text = await response.text();
|
|
146225
|
+
let parsed = null;
|
|
146226
|
+
try {
|
|
146227
|
+
parsed = text ? JSON.parse(text) : null;
|
|
146228
|
+
} catch {
|
|
146229
|
+
}
|
|
146230
|
+
if (!response.ok) {
|
|
146231
|
+
const errBody = parsed;
|
|
146232
|
+
const code = errBody?.code ?? errBody?.error;
|
|
146233
|
+
throw new ZeroAgentAuthError(
|
|
146234
|
+
`Agent auth request to ${url4} failed (${response.status}${typeof code === "string" ? `: ${code}` : ""})`,
|
|
146235
|
+
{ status: response.status, body: parsed ?? text }
|
|
146236
|
+
);
|
|
146237
|
+
}
|
|
146238
|
+
return schema.parse(parsed);
|
|
146239
|
+
};
|
|
146240
|
+
};
|
|
146241
|
+
var userWalletDtoSchema = external_exports3.object({
|
|
146242
|
+
walletAddress: external_exports3.string(),
|
|
146243
|
+
source: external_exports3.enum(["self_custody", "privy_embedded"]),
|
|
146244
|
+
isPrimary: external_exports3.boolean(),
|
|
146245
|
+
linkedAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).nullable().optional(),
|
|
146246
|
+
importedAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).nullable().optional(),
|
|
146247
|
+
delegationGranted: external_exports3.boolean(),
|
|
146248
|
+
signerQuorumId: external_exports3.string().nullable(),
|
|
146249
|
+
// Per-transaction USDC cap in base units (6 dp). null = unlimited, 0 = free-only.
|
|
146250
|
+
maxTransactionUsdcBaseUnits: external_exports3.number().int().nullable()
|
|
146251
|
+
});
|
|
146252
|
+
var welcomeBonusSummarySchema = external_exports3.object({
|
|
146253
|
+
status: external_exports3.string(),
|
|
146254
|
+
amountUsd: external_exports3.number()
|
|
146255
|
+
});
|
|
146256
|
+
var internalUserDtoSchema = external_exports3.object({
|
|
146257
|
+
id: external_exports3.string(),
|
|
146258
|
+
email: external_exports3.string().nullable(),
|
|
146259
|
+
createdAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).optional(),
|
|
146260
|
+
lastLoginAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).nullable().optional(),
|
|
146261
|
+
onboardingCompleted: external_exports3.boolean().optional(),
|
|
146262
|
+
delegationGranted: external_exports3.boolean().optional(),
|
|
146263
|
+
wallets: external_exports3.array(userWalletDtoSchema).optional(),
|
|
146264
|
+
balance: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string() }).nullable().optional(),
|
|
146265
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable().optional()
|
|
146266
|
+
});
|
|
146267
|
+
var publicUserDtoSchema = external_exports3.object({
|
|
146268
|
+
user: external_exports3.object({
|
|
146269
|
+
id: external_exports3.string(),
|
|
146270
|
+
email: external_exports3.string().nullable()
|
|
146271
|
+
}),
|
|
146272
|
+
walletAddress: external_exports3.string().nullable(),
|
|
146273
|
+
balance: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string() }).nullable(),
|
|
146274
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable()
|
|
146275
|
+
});
|
|
146276
|
+
var signResponseSchema = external_exports3.object({
|
|
146277
|
+
signature: external_exports3.string().regex(/^0x[0-9a-fA-F]+$/, "must be 0x-prefixed hex"),
|
|
146278
|
+
walletAddress: external_exports3.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be 0x-prefixed 40-char hex address")
|
|
146279
|
+
});
|
|
146280
|
+
var deviceStartResponseSchema = external_exports3.object({
|
|
146281
|
+
deviceCode: external_exports3.string(),
|
|
146282
|
+
userCode: external_exports3.string(),
|
|
146283
|
+
verificationUri: external_exports3.string(),
|
|
146284
|
+
pollInterval: external_exports3.number(),
|
|
146285
|
+
expiresAt: external_exports3.number()
|
|
146286
|
+
});
|
|
146287
|
+
var devicePollResponseSchema = external_exports3.union([
|
|
146288
|
+
// userCode + verificationUri are optional: older API deployments don't
|
|
146289
|
+
// echo them on pending.
|
|
146290
|
+
external_exports3.object({
|
|
146291
|
+
error: external_exports3.literal("authorization_pending"),
|
|
146292
|
+
userCode: external_exports3.string().optional(),
|
|
146293
|
+
verificationUri: external_exports3.string().optional()
|
|
146294
|
+
}),
|
|
146295
|
+
external_exports3.object({ error: external_exports3.literal("expired_token") }),
|
|
146296
|
+
external_exports3.object({
|
|
146297
|
+
accessToken: external_exports3.string(),
|
|
146298
|
+
refreshToken: external_exports3.string(),
|
|
146299
|
+
expiresIn: external_exports3.number(),
|
|
146300
|
+
user: internalUserDtoSchema
|
|
146301
|
+
})
|
|
146302
|
+
]);
|
|
146303
|
+
var sessionExchangeResponseSchema = external_exports3.object({
|
|
146304
|
+
token: external_exports3.string(),
|
|
146305
|
+
expiresAt: external_exports3.number()
|
|
146306
|
+
});
|
|
145968
146307
|
var AuthDevice = class {
|
|
145969
146308
|
constructor(client) {
|
|
145970
146309
|
this.client = client;
|
|
@@ -146025,8 +146364,10 @@ var repackageSignFailure = (err, op) => {
|
|
|
146025
146364
|
var Auth = class {
|
|
146026
146365
|
constructor(client) {
|
|
146027
146366
|
this.client = client;
|
|
146367
|
+
this.agent = new AuthAgent(client);
|
|
146028
146368
|
this.device = new AuthDevice(client);
|
|
146029
146369
|
}
|
|
146370
|
+
agent;
|
|
146030
146371
|
device;
|
|
146031
146372
|
// The internal (web-app facing) user profile. Richer than profile(): full
|
|
146032
146373
|
// wallet list with per-wallet delegation/signer/limit metadata.
|
|
@@ -146323,6 +146664,9 @@ var capabilityResponseSchema = external_exports3.object({
|
|
|
146323
146664
|
"unknown_unparsed",
|
|
146324
146665
|
"unprobed"
|
|
146325
146666
|
]).optional(),
|
|
146667
|
+
// ZERO-147 — provenance of displayCostAmount (settled | probe | registry |
|
|
146668
|
+
// unknown). `settled` means the shown price is reconciled from real charges.
|
|
146669
|
+
priceSource: external_exports3.string().nullable().optional(),
|
|
146326
146670
|
requiresHandshake: external_exports3.boolean().optional(),
|
|
146327
146671
|
reviewCount: external_exports3.number(),
|
|
146328
146672
|
rating: ratingSchema,
|
|
@@ -146675,6 +147019,48 @@ var Wallet = class {
|
|
|
146675
147019
|
},
|
|
146676
147020
|
userWalletDtoSchema
|
|
146677
147021
|
);
|
|
147022
|
+
// Link an existing self-custody wallet to the session user by private key.
|
|
147023
|
+
// Session-only. 409s when the wallet is already linked (to this or another
|
|
147024
|
+
// profile — the error message says which).
|
|
147025
|
+
import = (opts) => request2(
|
|
147026
|
+
this.client,
|
|
147027
|
+
{
|
|
147028
|
+
method: "POST",
|
|
147029
|
+
path: "/v1/users/me/wallets/import",
|
|
147030
|
+
body: {
|
|
147031
|
+
privateKey: opts.privateKey,
|
|
147032
|
+
...opts.makePrimary !== void 0 ? { makePrimary: opts.makePrimary } : {}
|
|
147033
|
+
},
|
|
147034
|
+
signal: opts.signal
|
|
147035
|
+
},
|
|
147036
|
+
userWalletDtoSchema
|
|
147037
|
+
);
|
|
147038
|
+
// Make one of the session user's linked wallets the primary payer.
|
|
147039
|
+
// Session-only. 404s when the address isn't linked to the user.
|
|
147040
|
+
setPrimary = (opts) => request2(
|
|
147041
|
+
this.client,
|
|
147042
|
+
{
|
|
147043
|
+
method: "PATCH",
|
|
147044
|
+
path: "/v1/users/me/wallets/primary",
|
|
147045
|
+
body: { walletAddress: opts.walletAddress },
|
|
147046
|
+
signal: opts.signal
|
|
147047
|
+
},
|
|
147048
|
+
userWalletDtoSchema
|
|
147049
|
+
);
|
|
147050
|
+
// Unlink a wallet from the session user. Session-only. 409s on the primary
|
|
147051
|
+
// wallet or a non-zero balance (the error message says which); 404s when
|
|
147052
|
+
// the address isn't linked. Responds 204 — resolves to void.
|
|
147053
|
+
remove = async (opts) => {
|
|
147054
|
+
await request2(
|
|
147055
|
+
this.client,
|
|
147056
|
+
{
|
|
147057
|
+
method: "DELETE",
|
|
147058
|
+
path: `/v1/users/me/wallets/${opts.walletAddress}`,
|
|
147059
|
+
signal: opts.signal
|
|
147060
|
+
},
|
|
147061
|
+
external_exports3.undefined()
|
|
147062
|
+
);
|
|
147063
|
+
};
|
|
146678
147064
|
// Routes by identity: account mode signs EIP-191 against /v1/wallet/fund-url,
|
|
146679
147065
|
// session mode hits /v1/users/me/fund-url (Bearer-authed, wallet resolved
|
|
146680
147066
|
// server-side). Both honor `provider` (coinbase | stripe).
|
|
@@ -147399,7 +147785,7 @@ var placeholderFor = (fieldName, propSchema) => String(sampleValueFor(fieldName,
|
|
|
147399
147785
|
|
|
147400
147786
|
// package.json
|
|
147401
147787
|
var package_default2 = {
|
|
147402
|
-
version: "1.
|
|
147788
|
+
version: "1.17.0"};
|
|
147403
147789
|
|
|
147404
147790
|
// src/app.ts
|
|
147405
147791
|
init_esm_shims();
|
|
@@ -148030,272 +148416,6 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
|
148030
148416
|
}));
|
|
148031
148417
|
var open_default = open2;
|
|
148032
148418
|
|
|
148033
|
-
// src/services/agent-auth.ts
|
|
148034
|
-
init_esm_shims();
|
|
148035
|
-
var JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
148036
|
-
var trimSlash = (value) => value.replace(/\/$/, "");
|
|
148037
|
-
var AgentAuthHttpError = class extends Error {
|
|
148038
|
-
constructor(message2, status, body) {
|
|
148039
|
-
super(message2);
|
|
148040
|
-
this.status = status;
|
|
148041
|
-
this.body = body;
|
|
148042
|
-
this.name = "AgentAuthHttpError";
|
|
148043
|
-
}
|
|
148044
|
-
// WorkOS error bodies carry {code, message}; OAuth-style ones carry {error}.
|
|
148045
|
-
get code() {
|
|
148046
|
-
const body = this.body;
|
|
148047
|
-
if (typeof body?.code === "string") return body.code;
|
|
148048
|
-
if (typeof body?.error === "string") return body.error;
|
|
148049
|
-
return null;
|
|
148050
|
-
}
|
|
148051
|
-
};
|
|
148052
|
-
var agentAuthMetadataSchema = external_exports3.object({
|
|
148053
|
-
token_endpoint: external_exports3.string().optional(),
|
|
148054
|
-
agent_auth: external_exports3.object({
|
|
148055
|
-
identity_endpoint: external_exports3.string(),
|
|
148056
|
-
claim_endpoint: external_exports3.string().optional()
|
|
148057
|
-
}).loose()
|
|
148058
|
-
}).loose();
|
|
148059
|
-
var identityEnvelopeSchema = external_exports3.object({
|
|
148060
|
-
id: external_exports3.string(),
|
|
148061
|
-
identity: external_exports3.object({
|
|
148062
|
-
assertion: external_exports3.string(),
|
|
148063
|
-
expires_at: external_exports3.string().optional(),
|
|
148064
|
-
refresh_token: external_exports3.object({ value: external_exports3.string() }).loose().optional()
|
|
148065
|
-
}).loose(),
|
|
148066
|
-
claim: external_exports3.object({
|
|
148067
|
-
token: external_exports3.string().optional(),
|
|
148068
|
-
expires_at: external_exports3.string().optional()
|
|
148069
|
-
}).loose().optional()
|
|
148070
|
-
}).loose().transform((raw) => ({
|
|
148071
|
-
registrationId: raw.id,
|
|
148072
|
-
identityAssertion: raw.identity.assertion,
|
|
148073
|
-
assertionExpires: raw.identity.expires_at ?? null,
|
|
148074
|
-
refreshToken: raw.identity.refresh_token?.value ?? null,
|
|
148075
|
-
claimToken: raw.claim?.token ?? null,
|
|
148076
|
-
claimTokenExpires: raw.claim?.expires_at ?? null
|
|
148077
|
-
}));
|
|
148078
|
-
var tokenResponseSchema = external_exports3.object({ access_token: external_exports3.string() }).loose().transform((raw) => ({ accessToken: raw.access_token }));
|
|
148079
|
-
var startClaimResponseSchema = external_exports3.object({
|
|
148080
|
-
attempt: external_exports3.object({
|
|
148081
|
-
verification_uri: external_exports3.string(),
|
|
148082
|
-
expires_at: external_exports3.string().optional()
|
|
148083
|
-
}).loose()
|
|
148084
|
-
}).loose().transform((raw) => ({
|
|
148085
|
-
verificationUri: raw.attempt.verification_uri,
|
|
148086
|
-
expiresAt: raw.attempt.expires_at ?? null
|
|
148087
|
-
}));
|
|
148088
|
-
var completeClaimResponseSchema = external_exports3.object({
|
|
148089
|
-
identity: external_exports3.object({
|
|
148090
|
-
assertion: external_exports3.string(),
|
|
148091
|
-
expires_at: external_exports3.string().optional(),
|
|
148092
|
-
refresh_token: external_exports3.object({ value: external_exports3.string() }).loose().optional()
|
|
148093
|
-
}).loose()
|
|
148094
|
-
}).loose().transform((raw) => ({
|
|
148095
|
-
identityAssertion: raw.identity.assertion,
|
|
148096
|
-
assertionExpires: raw.identity.expires_at ?? null,
|
|
148097
|
-
refreshToken: raw.identity.refresh_token?.value ?? null
|
|
148098
|
-
}));
|
|
148099
|
-
var zeroExchangeResponseSchema = external_exports3.object({
|
|
148100
|
-
accessToken: external_exports3.string(),
|
|
148101
|
-
refreshToken: external_exports3.string(),
|
|
148102
|
-
expiresIn: external_exports3.number(),
|
|
148103
|
-
user: external_exports3.object({ id: external_exports3.string() }).loose(),
|
|
148104
|
-
walletAddress: external_exports3.string().optional()
|
|
148105
|
-
}).loose();
|
|
148106
|
-
var AgentAuthClient = class {
|
|
148107
|
-
constructor(apiBaseUrl, fetchImpl = (...args) => globalThis.fetch(...args)) {
|
|
148108
|
-
this.fetchImpl = fetchImpl;
|
|
148109
|
-
this.apiBaseUrl = trimSlash(apiBaseUrl);
|
|
148110
|
-
}
|
|
148111
|
-
apiBaseUrl;
|
|
148112
|
-
endpointsPromise = null;
|
|
148113
|
-
// Fully autonomous signup: register anonymously at the AuthKit domain,
|
|
148114
|
-
// exchange the identity assertion for a WorkOS access token, exchange that
|
|
148115
|
-
// for a Zero session. The claim token and identity assertion are returned
|
|
148116
|
-
// exactly once — the caller persists them.
|
|
148117
|
-
signup = async () => {
|
|
148118
|
-
const registration = await this.register();
|
|
148119
|
-
const token = await this.exchangeAssertion(registration.identityAssertion);
|
|
148120
|
-
const session4 = await this.exchangeAtZero(token.accessToken);
|
|
148121
|
-
return { registration, session: session4 };
|
|
148122
|
-
};
|
|
148123
|
-
register = async () => {
|
|
148124
|
-
const endpoints = await this.endpoints();
|
|
148125
|
-
return this.postJson(
|
|
148126
|
-
endpoints.identityEndpoint,
|
|
148127
|
-
{ type: "anonymous" },
|
|
148128
|
-
identityEnvelopeSchema
|
|
148129
|
-
);
|
|
148130
|
-
};
|
|
148131
|
-
exchangeAssertion = async (identityAssertion) => {
|
|
148132
|
-
const endpoints = await this.endpoints();
|
|
148133
|
-
return this.postForm(
|
|
148134
|
-
endpoints.tokenEndpoint,
|
|
148135
|
-
{ grant_type: JWT_BEARER_GRANT_TYPE, assertion: identityAssertion },
|
|
148136
|
-
tokenResponseSchema
|
|
148137
|
-
);
|
|
148138
|
-
};
|
|
148139
|
-
// POST /v1/auth/agent/exchange — WorkOS agent access token → Zero session
|
|
148140
|
-
// pair (+ the implicitly provisioned wallet address). The post-claim token
|
|
148141
|
-
// goes through here too: the server binds the claiming human.
|
|
148142
|
-
exchangeAtZero = (accessToken) => this.postJson(
|
|
148143
|
-
`${this.apiBaseUrl}/v1/auth/agent/exchange`,
|
|
148144
|
-
{ accessToken },
|
|
148145
|
-
zeroExchangeResponseSchema
|
|
148146
|
-
);
|
|
148147
|
-
// Mint a claim attempt. The human opens the returned verification URI,
|
|
148148
|
-
// signs in as `email`, and the page shows THEM a pairing code to read back
|
|
148149
|
-
// to the agent — completeClaim() submits it.
|
|
148150
|
-
startClaim = async (input) => {
|
|
148151
|
-
const endpoints = await this.endpoints();
|
|
148152
|
-
if (!endpoints.claimEndpoint) {
|
|
148153
|
-
throw new AgentAuthHttpError(
|
|
148154
|
-
"The authorization server advertises no claim endpoint.",
|
|
148155
|
-
0,
|
|
148156
|
-
null
|
|
148157
|
-
);
|
|
148158
|
-
}
|
|
148159
|
-
return this.postJson(
|
|
148160
|
-
endpoints.claimEndpoint,
|
|
148161
|
-
{
|
|
148162
|
-
type: "service_auth",
|
|
148163
|
-
claim_token: input.claimToken,
|
|
148164
|
-
login_hint: input.email
|
|
148165
|
-
},
|
|
148166
|
-
startClaimResponseSchema
|
|
148167
|
-
);
|
|
148168
|
-
};
|
|
148169
|
-
// Submit the pairing code the human read off the hosted page. Terminal
|
|
148170
|
-
// states map to a typed result; anything unexpected throws.
|
|
148171
|
-
completeClaim = async (input) => {
|
|
148172
|
-
const endpoints = await this.endpoints();
|
|
148173
|
-
if (!endpoints.claimEndpoint) {
|
|
148174
|
-
throw new AgentAuthHttpError(
|
|
148175
|
-
"The authorization server advertises no claim endpoint.",
|
|
148176
|
-
0,
|
|
148177
|
-
null
|
|
148178
|
-
);
|
|
148179
|
-
}
|
|
148180
|
-
try {
|
|
148181
|
-
const identity = await this.postJson(
|
|
148182
|
-
`${endpoints.claimEndpoint}/complete`,
|
|
148183
|
-
{ claim_token: input.claimToken, user_code: input.userCode },
|
|
148184
|
-
completeClaimResponseSchema
|
|
148185
|
-
);
|
|
148186
|
-
return { status: "ok", ...identity };
|
|
148187
|
-
} catch (err) {
|
|
148188
|
-
if (err instanceof AgentAuthHttpError && err.code) {
|
|
148189
|
-
if (err.code === "claim_not_confirmed") {
|
|
148190
|
-
return { status: "not_confirmed" };
|
|
148191
|
-
}
|
|
148192
|
-
if (err.code === "invalid_user_code") {
|
|
148193
|
-
return { status: "invalid_code" };
|
|
148194
|
-
}
|
|
148195
|
-
if ([
|
|
148196
|
-
"user_code_expired",
|
|
148197
|
-
"claim_expired",
|
|
148198
|
-
"claim_revoked",
|
|
148199
|
-
"already_claimed",
|
|
148200
|
-
"claim_denied"
|
|
148201
|
-
].includes(err.code)) {
|
|
148202
|
-
return { status: "expired", code: err.code };
|
|
148203
|
-
}
|
|
148204
|
-
}
|
|
148205
|
-
throw err;
|
|
148206
|
-
}
|
|
148207
|
-
};
|
|
148208
|
-
// Resolve (and cache) the agent-auth endpoints via discovery.
|
|
148209
|
-
endpoints = () => {
|
|
148210
|
-
if (!this.endpointsPromise) {
|
|
148211
|
-
this.endpointsPromise = this.discover().catch((err) => {
|
|
148212
|
-
this.endpointsPromise = null;
|
|
148213
|
-
throw err;
|
|
148214
|
-
});
|
|
148215
|
-
}
|
|
148216
|
-
return this.endpointsPromise;
|
|
148217
|
-
};
|
|
148218
|
-
discover = async () => {
|
|
148219
|
-
const resource = await this.getJson(`${this.apiBaseUrl}/.well-known/oauth-protected-resource`);
|
|
148220
|
-
let lastError = null;
|
|
148221
|
-
for (const server of resource.authorization_servers ?? []) {
|
|
148222
|
-
try {
|
|
148223
|
-
const raw = await this.getJson(
|
|
148224
|
-
`${trimSlash(server)}/.well-known/oauth-authorization-server`
|
|
148225
|
-
);
|
|
148226
|
-
const metadata = agentAuthMetadataSchema.parse(raw);
|
|
148227
|
-
return {
|
|
148228
|
-
authorizationServer: trimSlash(server),
|
|
148229
|
-
identityEndpoint: metadata.agent_auth.identity_endpoint,
|
|
148230
|
-
claimEndpoint: metadata.agent_auth.claim_endpoint ?? null,
|
|
148231
|
-
tokenEndpoint: metadata.token_endpoint ?? `${trimSlash(server)}/oauth2/token`
|
|
148232
|
-
};
|
|
148233
|
-
} catch (err) {
|
|
148234
|
-
lastError = err;
|
|
148235
|
-
}
|
|
148236
|
-
}
|
|
148237
|
-
throw new AgentAuthHttpError(
|
|
148238
|
-
"No authorization server with an agent_auth block found \u2014 agent registration is not enabled for this service.",
|
|
148239
|
-
0,
|
|
148240
|
-
lastError
|
|
148241
|
-
);
|
|
148242
|
-
};
|
|
148243
|
-
getJson = async (url4) => {
|
|
148244
|
-
const response = await this.fetchImpl(url4).catch((err) => {
|
|
148245
|
-
throw wrapNetworkError(url4, err);
|
|
148246
|
-
});
|
|
148247
|
-
if (!response.ok) {
|
|
148248
|
-
throw new AgentAuthHttpError(
|
|
148249
|
-
`GET ${url4} failed (${response.status})`,
|
|
148250
|
-
response.status,
|
|
148251
|
-
null
|
|
148252
|
-
);
|
|
148253
|
-
}
|
|
148254
|
-
return await response.json();
|
|
148255
|
-
};
|
|
148256
|
-
postJson = (url4, body, schema) => this.post(url4, "application/json", JSON.stringify(body), schema);
|
|
148257
|
-
postForm = (url4, fields, schema) => this.post(
|
|
148258
|
-
url4,
|
|
148259
|
-
"application/x-www-form-urlencoded",
|
|
148260
|
-
new URLSearchParams(fields).toString(),
|
|
148261
|
-
schema
|
|
148262
|
-
);
|
|
148263
|
-
post = async (url4, contentType, body, schema) => {
|
|
148264
|
-
const response = await this.fetchImpl(url4, {
|
|
148265
|
-
method: "POST",
|
|
148266
|
-
headers: { "content-type": contentType },
|
|
148267
|
-
body
|
|
148268
|
-
}).catch((err) => {
|
|
148269
|
-
throw wrapNetworkError(url4, err);
|
|
148270
|
-
});
|
|
148271
|
-
const text = await response.text();
|
|
148272
|
-
let parsed = null;
|
|
148273
|
-
try {
|
|
148274
|
-
parsed = text ? JSON.parse(text) : null;
|
|
148275
|
-
} catch {
|
|
148276
|
-
}
|
|
148277
|
-
if (!response.ok) {
|
|
148278
|
-
const body2 = parsed;
|
|
148279
|
-
const code = body2?.code ?? body2?.error;
|
|
148280
|
-
throw new AgentAuthHttpError(
|
|
148281
|
-
`Agent auth request to ${url4} failed (${response.status}${typeof code === "string" ? `: ${code}` : ""})`,
|
|
148282
|
-
response.status,
|
|
148283
|
-
parsed ?? text
|
|
148284
|
-
);
|
|
148285
|
-
}
|
|
148286
|
-
return schema.parse(parsed);
|
|
148287
|
-
};
|
|
148288
|
-
};
|
|
148289
|
-
var wrapNetworkError = (url4, err) => {
|
|
148290
|
-
const cause = err?.cause;
|
|
148291
|
-
const causeMessage = cause instanceof Error ? cause.code ?? cause.message : err instanceof Error ? err.message : String(err);
|
|
148292
|
-
return new AgentAuthHttpError(
|
|
148293
|
-
`Could not reach ${url4} (${causeMessage})`,
|
|
148294
|
-
0,
|
|
148295
|
-
null
|
|
148296
|
-
);
|
|
148297
|
-
};
|
|
148298
|
-
|
|
148299
148419
|
// src/util/secure-config.ts
|
|
148300
148420
|
init_esm_shims();
|
|
148301
148421
|
var SECURE_DIR_MODE = 448;
|
|
@@ -148642,7 +148762,7 @@ var authAgentRegisterCommand = (appContext) => new Command("register").descripti
|
|
|
148642
148762
|
process.exitCode = 1;
|
|
148643
148763
|
return;
|
|
148644
148764
|
}
|
|
148645
|
-
const agentAuth =
|
|
148765
|
+
const agentAuth = client.auth.agent;
|
|
148646
148766
|
let result;
|
|
148647
148767
|
try {
|
|
148648
148768
|
result = await agentAuth.signup();
|
|
@@ -148809,7 +148929,7 @@ var authAgentClaimCommand = (appContext) => new Command("claim").description(
|
|
|
148809
148929
|
return;
|
|
148810
148930
|
}
|
|
148811
148931
|
const claimToken = registration.claimToken;
|
|
148812
|
-
const agentAuth =
|
|
148932
|
+
const agentAuth = client.auth.agent;
|
|
148813
148933
|
if (opts.code) {
|
|
148814
148934
|
const ok2 = await completeClaimAndExchange(
|
|
148815
148935
|
agentAuth,
|
|
@@ -148822,7 +148942,7 @@ var authAgentClaimCommand = (appContext) => new Command("claim").description(
|
|
|
148822
148942
|
return;
|
|
148823
148943
|
}
|
|
148824
148944
|
const started = await agentAuth.startClaim({ claimToken, email: email4 }).catch((err) => {
|
|
148825
|
-
const code = err instanceof
|
|
148945
|
+
const code = err instanceof ZeroAgentAuthError && err.serverCode ? err.serverCode : truncateError(err instanceof Error ? err.message : String(err));
|
|
148826
148946
|
process.stderr.write(
|
|
148827
148947
|
`Could not start the claim (${code}). The claim token may be expired \u2014 check \`claimTokenExpires\` in ~/.zero/config.json.
|
|
148828
148948
|
`
|
|
@@ -149225,7 +149345,11 @@ var OUTCOMES = {
|
|
|
149225
149345
|
errorClass: "insufficient_funds",
|
|
149226
149346
|
reviewable: false
|
|
149227
149347
|
},
|
|
149228
|
-
|
|
149348
|
+
// A capability returned a non-2xx (4xx/5xx). Exit 2 — distinct from a
|
|
149349
|
+
// transport failure (1) — so `zero fetch … && next` stops instead of
|
|
149350
|
+
// feeding an error body downstream as if it were a result. The body is
|
|
149351
|
+
// still printed and the run is reviewable; only the success signal changes.
|
|
149352
|
+
server_error: { exitCode: 2, errorClass: "upstream_4xx", reviewable: true }
|
|
149229
149353
|
};
|
|
149230
149354
|
var cliErrorClassFor = (outcome, status, walletAddress) => {
|
|
149231
149355
|
const info = OUTCOMES[outcome];
|
|
@@ -149657,6 +149781,9 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
149657
149781
|
);
|
|
149658
149782
|
} else if (outcome === "server_error" && typeof status === "number") {
|
|
149659
149783
|
console.error(` Upstream returned ${status}${messageSuffix}`);
|
|
149784
|
+
if (upstreamError?.fixHint) {
|
|
149785
|
+
console.error(` \u21B3 Fix: ${upstreamError.fixHint}`);
|
|
149786
|
+
}
|
|
149660
149787
|
}
|
|
149661
149788
|
}
|
|
149662
149789
|
if (options.json) {
|
|
@@ -149686,6 +149813,11 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
149686
149813
|
bodyRaw: status === null ? null : bodyRaw,
|
|
149687
149814
|
...isBinary && { bodyEncoding: "base64" },
|
|
149688
149815
|
...resultError && { error: resultError },
|
|
149816
|
+
// A non-2xx from the capability: surface the structured
|
|
149817
|
+
// upstream detail (status, message, and the caller-
|
|
149818
|
+
// fixable `fixHint`) in the envelope too. Agents run
|
|
149819
|
+
// `--json`, so without this the fixHint is invisible.
|
|
149820
|
+
...upstreamError && { upstreamError },
|
|
149689
149821
|
...legacyMigrateHint && { hint: legacyMigrateHint },
|
|
149690
149822
|
...combinedSkipReasons.length > 0 && {
|
|
149691
149823
|
runTrackingSkipped: combinedSkipReasons
|
|
@@ -149695,9 +149827,10 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
149695
149827
|
);
|
|
149696
149828
|
} else if (runId && outcomeInfo.reviewable) {
|
|
149697
149829
|
const isTTY = process.stderr.isTTY;
|
|
149830
|
+
const responded2xx = status !== null && status >= 200 && status < 300;
|
|
149698
149831
|
console.error(`
|
|
149699
149832
|
Run ID: ${runId}`);
|
|
149700
|
-
if (isTTY) {
|
|
149833
|
+
if (isTTY && responded2xx) {
|
|
149701
149834
|
console.error(
|
|
149702
149835
|
` Leave a review to help other agents discover great capabilities:`
|
|
149703
149836
|
);
|
|
@@ -149718,10 +149851,19 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
149718
149851
|
``
|
|
149719
149852
|
].join("\n")
|
|
149720
149853
|
);
|
|
149721
|
-
} else {
|
|
149854
|
+
} else if (responded2xx) {
|
|
149722
149855
|
console.error(
|
|
149723
149856
|
` zero review ${runId} --success --accuracy 5 --value 4 --reliability 5`
|
|
149724
149857
|
);
|
|
149858
|
+
} else if (isTTY) {
|
|
149859
|
+
console.error(
|
|
149860
|
+
` The call did not return a usable result. If the capability itself was at fault, record it:`
|
|
149861
|
+
);
|
|
149862
|
+
console.error(
|
|
149863
|
+
` zero review ${runId} --no-success --content "what went wrong"`
|
|
149864
|
+
);
|
|
149865
|
+
} else {
|
|
149866
|
+
console.error(` zero review ${runId} --no-success`);
|
|
149725
149867
|
}
|
|
149726
149868
|
} else if (!runId && cliSkipReasons.length > 0) {
|
|
149727
149869
|
console.error(
|
|
@@ -151696,17 +151838,20 @@ init_esm_shims();
|
|
|
151696
151838
|
|
|
151697
151839
|
// src/util/migrate-config.ts
|
|
151698
151840
|
init_esm_shims();
|
|
151699
|
-
var
|
|
151841
|
+
var backupAndStripConfigKeys = (zeroDir, keys) => {
|
|
151700
151842
|
const configPath = join$1(zeroDir, "config.json");
|
|
151701
151843
|
const backupPath = join$1(zeroDir, "config.backup.json");
|
|
151702
151844
|
const raw = readFileSync(configPath, "utf8");
|
|
151703
151845
|
ensureSecureDir(zeroDir);
|
|
151704
151846
|
writeSecureFile(backupPath, raw);
|
|
151705
151847
|
const parsed = JSON.parse(raw);
|
|
151706
|
-
|
|
151848
|
+
for (const key of keys) {
|
|
151849
|
+
delete parsed[key];
|
|
151850
|
+
}
|
|
151707
151851
|
writeSecureFile(configPath, JSON.stringify(parsed, null, 2));
|
|
151708
151852
|
return { backupPath, configPath };
|
|
151709
151853
|
};
|
|
151854
|
+
var backupAndStripPrivateKey = (zeroDir) => backupAndStripConfigKeys(zeroDir, ["privateKey"]);
|
|
151710
151855
|
|
|
151711
151856
|
// src/util/stdin.ts
|
|
151712
151857
|
init_esm_shims();
|
|
@@ -151935,6 +152080,148 @@ var walletSetCommand = (appContext) => new Command("set").description("Set walle
|
|
|
151935
152080
|
force: options.force ?? false
|
|
151936
152081
|
});
|
|
151937
152082
|
});
|
|
152083
|
+
var normalizeImportKey = (raw) => {
|
|
152084
|
+
const trimmed = raw.trim();
|
|
152085
|
+
const prefixed = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
152086
|
+
return PRIVATE_KEY_PATTERN.test(prefixed) ? prefixed : null;
|
|
152087
|
+
};
|
|
152088
|
+
var SIGN_IN_FIRST_MESSAGE = "This command requires a signed-in session. Run `zero auth login` first.";
|
|
152089
|
+
var walletImportCommand = (appContext) => new Command("import").description(
|
|
152090
|
+
"Link an existing self-custody wallet to your Zero profile by private key"
|
|
152091
|
+
).argument("[privateKey]", "Hex-encoded private key (0x prefix optional)").option(
|
|
152092
|
+
"--key-stdin",
|
|
152093
|
+
"Read the private key from stdin instead of an argument"
|
|
152094
|
+
).option("--primary", "Make the imported wallet your primary payer wallet").action(
|
|
152095
|
+
async (privateKeyArg, options) => {
|
|
152096
|
+
const { analyticsService, client } = appContext.services;
|
|
152097
|
+
if (privateKeyArg && options.keyStdin) {
|
|
152098
|
+
console.error(
|
|
152099
|
+
"Pass the key as an argument OR via --key-stdin, not both."
|
|
152100
|
+
);
|
|
152101
|
+
process.exitCode = 1;
|
|
152102
|
+
return;
|
|
152103
|
+
}
|
|
152104
|
+
if (!privateKeyArg && !options.keyStdin) {
|
|
152105
|
+
console.error(
|
|
152106
|
+
"Missing private key. Pass it as an argument or pipe it with --key-stdin."
|
|
152107
|
+
);
|
|
152108
|
+
process.exitCode = 1;
|
|
152109
|
+
return;
|
|
152110
|
+
}
|
|
152111
|
+
let rawKey;
|
|
152112
|
+
if (options.keyStdin) {
|
|
152113
|
+
if (process.stdin.isTTY) {
|
|
152114
|
+
console.error(
|
|
152115
|
+
"Expected a private key on stdin. Example:\n zero wallet generate --json | jq -r .privateKey | zero wallet import --key-stdin"
|
|
152116
|
+
);
|
|
152117
|
+
process.exitCode = 1;
|
|
152118
|
+
return;
|
|
152119
|
+
}
|
|
152120
|
+
rawKey = await readStdin();
|
|
152121
|
+
} else {
|
|
152122
|
+
rawKey = privateKeyArg;
|
|
152123
|
+
}
|
|
152124
|
+
const privateKey = normalizeImportKey(rawKey);
|
|
152125
|
+
if (!privateKey) {
|
|
152126
|
+
console.error(
|
|
152127
|
+
"Invalid private key (expected 64 hex chars, 0x prefix optional)."
|
|
152128
|
+
);
|
|
152129
|
+
process.exitCode = 1;
|
|
152130
|
+
return;
|
|
152131
|
+
}
|
|
152132
|
+
if (client.getCredentials().kind !== "session") {
|
|
152133
|
+
console.error(SIGN_IN_FIRST_MESSAGE);
|
|
152134
|
+
process.exitCode = 1;
|
|
152135
|
+
return;
|
|
152136
|
+
}
|
|
152137
|
+
let wallet;
|
|
152138
|
+
try {
|
|
152139
|
+
wallet = await client.wallet.import({
|
|
152140
|
+
privateKey,
|
|
152141
|
+
...options.primary ? { makePrimary: true } : {}
|
|
152142
|
+
});
|
|
152143
|
+
} catch (err) {
|
|
152144
|
+
if (err instanceof ZeroApiError) {
|
|
152145
|
+
if (err.status === 401) {
|
|
152146
|
+
console.error(
|
|
152147
|
+
"Session expired. Run `zero auth login` and try again."
|
|
152148
|
+
);
|
|
152149
|
+
} else {
|
|
152150
|
+
console.error(`Could not import wallet: ${err.message}`);
|
|
152151
|
+
}
|
|
152152
|
+
} else {
|
|
152153
|
+
console.error("Could not import wallet: network error.");
|
|
152154
|
+
}
|
|
152155
|
+
process.exitCode = 1;
|
|
152156
|
+
return;
|
|
152157
|
+
}
|
|
152158
|
+
analyticsService.setWalletAddress(wallet.walletAddress);
|
|
152159
|
+
console.log(
|
|
152160
|
+
`Wallet imported: ${wallet.walletAddress}${wallet.isPrimary ? " (primary)" : ""}`
|
|
152161
|
+
);
|
|
152162
|
+
let localKeyStripped = false;
|
|
152163
|
+
const zeroDir = join$1(homedir(), ".zero");
|
|
152164
|
+
const configPath = join$1(zeroDir, "config.json");
|
|
152165
|
+
const config2 = existsSync(configPath) ? readConfig(configPath) : {};
|
|
152166
|
+
const localByoKey = config2.byoPrivateKey ? normalizeImportKey(config2.byoPrivateKey) : null;
|
|
152167
|
+
if (localByoKey && localByoKey.toLowerCase() === privateKey.toLowerCase()) {
|
|
152168
|
+
try {
|
|
152169
|
+
const { backupPath } = backupAndStripConfigKeys(zeroDir, [
|
|
152170
|
+
"byoPrivateKey"
|
|
152171
|
+
]);
|
|
152172
|
+
localKeyStripped = true;
|
|
152173
|
+
console.log(
|
|
152174
|
+
`Local key backed up to ${backupPath} and removed from config \u2014 managed signing now applies.`
|
|
152175
|
+
);
|
|
152176
|
+
} catch {
|
|
152177
|
+
console.error(
|
|
152178
|
+
"Could not back up the local key; it was left in place in ~/.zero/config.json."
|
|
152179
|
+
);
|
|
152180
|
+
}
|
|
152181
|
+
}
|
|
152182
|
+
analyticsService.capture("wallet_imported", {
|
|
152183
|
+
primary: wallet.isPrimary,
|
|
152184
|
+
// biome-ignore lint/style/useNamingConvention: snake_case for analytics
|
|
152185
|
+
key_source: options.keyStdin ? "stdin" : "arg",
|
|
152186
|
+
// biome-ignore lint/style/useNamingConvention: snake_case for analytics
|
|
152187
|
+
local_key_stripped: localKeyStripped
|
|
152188
|
+
});
|
|
152189
|
+
}
|
|
152190
|
+
);
|
|
152191
|
+
var walletListCommand = (appContext) => new Command("list").description("List the wallets linked to your Zero profile").action(async () => {
|
|
152192
|
+
const { analyticsService, client } = appContext.services;
|
|
152193
|
+
if (client.getCredentials().kind !== "session") {
|
|
152194
|
+
console.error(SIGN_IN_FIRST_MESSAGE);
|
|
152195
|
+
process.exitCode = 1;
|
|
152196
|
+
return;
|
|
152197
|
+
}
|
|
152198
|
+
let wallets;
|
|
152199
|
+
try {
|
|
152200
|
+
wallets = await client.wallet.list();
|
|
152201
|
+
} catch (err) {
|
|
152202
|
+
const message2 = err instanceof ZeroApiError && err.status === 401 ? "Session expired. Run `zero auth login` and try again." : "Failed to list wallets.";
|
|
152203
|
+
console.error(message2);
|
|
152204
|
+
process.exitCode = 1;
|
|
152205
|
+
return;
|
|
152206
|
+
}
|
|
152207
|
+
if (wallets.length === 0) {
|
|
152208
|
+
console.log(
|
|
152209
|
+
"No wallets linked. One is provisioned automatically on your first paid call, or run `zero wallet import <key>`."
|
|
152210
|
+
);
|
|
152211
|
+
} else {
|
|
152212
|
+
for (const wallet of wallets) {
|
|
152213
|
+
const source = wallet.importedAt ? "imported" : wallet.source === "privy_embedded" ? "managed" : "byo";
|
|
152214
|
+
const columns = [
|
|
152215
|
+
wallet.walletAddress,
|
|
152216
|
+
source.padEnd(8),
|
|
152217
|
+
(wallet.isPrimary ? "PRIMARY" : "").padEnd(7),
|
|
152218
|
+
wallet.delegationGranted ? "delegated" : "not delegated"
|
|
152219
|
+
];
|
|
152220
|
+
console.log(columns.join(" ").trimEnd());
|
|
152221
|
+
}
|
|
152222
|
+
}
|
|
152223
|
+
analyticsService.capture("wallet_listed", { count: wallets.length });
|
|
152224
|
+
});
|
|
151938
152225
|
var walletGenerateCommand = (appContext) => new Command("generate").description(
|
|
151939
152226
|
"Generate a fresh wallet (address + private key) without touching your configured wallet"
|
|
151940
152227
|
).option("--json", "Emit { address, privateKey } as JSON").option(
|
|
@@ -152022,6 +152309,8 @@ var walletCommand = (appContext) => {
|
|
|
152022
152309
|
cmd.addCommand(walletAddressCommand(appContext));
|
|
152023
152310
|
cmd.addCommand(walletSetCommand(appContext));
|
|
152024
152311
|
cmd.addCommand(walletGenerateCommand(appContext));
|
|
152312
|
+
cmd.addCommand(walletImportCommand(appContext));
|
|
152313
|
+
cmd.addCommand(walletListCommand(appContext));
|
|
152025
152314
|
return cmd;
|
|
152026
152315
|
};
|
|
152027
152316
|
|