@capxul/sdk 1.0.0-alpha.18 → 1.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/{InMemoryAuthCacheAdapter-BuVZpnSx.mjs → InMemoryAuthCacheAdapter-CHYpYyk5.mjs} +2 -1
- package/dist/InMemoryAuthCacheAdapter-CHYpYyk5.mjs.map +1 -0
- package/dist/{index-D0SflScT.d.mts → index-D1rNjmof.d.mts} +3 -3
- package/dist/{index-D0SflScT.d.mts.map → index-D1rNjmof.d.mts.map} +1 -1
- package/dist/index.d.mts +69 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +324 -128
- package/dist/index.mjs.map +1 -1
- package/dist/node/index.d.mts +2 -2
- package/dist/node/index.mjs +1 -1
- package/dist/ports/safe-deployment.d.mts +1 -1
- package/dist/{safe-deployment-Bchp9bqb.d.mts → safe-deployment-BID2pXZN.d.mts} +2 -2
- package/dist/{safe-deployment-Bchp9bqb.d.mts.map → safe-deployment-BID2pXZN.d.mts.map} +1 -1
- package/dist/{signer-Cp2G98ZK.d.mts → signer-AXnBJuAN.d.mts} +2 -2
- package/dist/{signer-Cp2G98ZK.d.mts.map → signer-AXnBJuAN.d.mts.map} +1 -1
- package/package.json +6 -6
- package/dist/InMemoryAuthCacheAdapter-BuVZpnSx.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as toSessionToken, C as toEpochSeconds, D as toPublishableKey, E as toOrgId, F as Errors, I as isCapxulError, M as decodeConvexError, N as CapxulError, O as toPublishableKeyId, P as EXPECTED_OPERATION_OUTCOMES, S as toEpochMs, T as toKycTier, _ as toChainId, b as toDurationMs, c as BYTES32_RE, d as toAccountId, f as toAddress, g as toAuthUserId, h as toAppId, j as toSubAccountId, k as toRoleKey, l as EVM_ADDRESS_RE$1, m as toAnonymousDistinctId, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, p as toAllowedOrigin, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toCountryCode, w as toJwtToken, x as toEmail, y as toCurrencyCode } from "./InMemoryAuthCacheAdapter-
|
|
1
|
+
import { A as toSessionToken, C as toEpochSeconds, D as toPublishableKey, E as toOrgId, F as Errors, I as isCapxulError, M as decodeConvexError, N as CapxulError, O as toPublishableKeyId, P as EXPECTED_OPERATION_OUTCOMES, S as toEpochMs, T as toKycTier, _ as toChainId, b as toDurationMs, c as BYTES32_RE, d as toAccountId, f as toAddress, g as toAuthUserId, h as toAppId, j as toSubAccountId, k as toRoleKey, l as EVM_ADDRESS_RE$1, m as toAnonymousDistinctId, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, p as toAllowedOrigin, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toCountryCode, w as toJwtToken, x as toEmail, y as toCurrencyCode } from "./InMemoryAuthCacheAdapter-CHYpYyk5.mjs";
|
|
2
2
|
import { concat, formatUnits, keccak256, padHex, parseUnits, recoverAddress, stringToHex, toBytes, toEventSelector, toFunctionSelector } from "viem";
|
|
3
3
|
import { Context, Data, Deferred, Duration, Effect, Either, Exit, Layer, Ref, Request, Scope } from "effect";
|
|
4
4
|
import { getFunctionName, makeFunctionReference } from "convex/server";
|
|
@@ -249,13 +249,31 @@ function parseV8StackFrames(error) {
|
|
|
249
249
|
}
|
|
250
250
|
return frames;
|
|
251
251
|
}
|
|
252
|
+
/** Fixed, leak-safe frame used when the error carries no parseable stack. */
|
|
253
|
+
const SDK_BOUNDARY_FILENAME = "capxul-sdk-observation://boundary";
|
|
252
254
|
/**
|
|
253
|
-
* Build PostHog's `$exception_list`
|
|
254
|
-
*
|
|
255
|
+
* Build PostHog's `$exception_list` (always a single entry). Error Tracking
|
|
256
|
+
* groups on `type`, so it is ALWAYS present (the CapxulError code) — the
|
|
257
|
+
* previous `[{ frames }]` shape omitted it and PostHog dropped the event as
|
|
258
|
+
* "missing field `type`". When the error has no parseable stack, a synthetic
|
|
259
|
+
* boundary frame stands in so the event still ingests as a real Issue (#1031).
|
|
255
260
|
*/
|
|
256
|
-
function buildExceptionList(
|
|
257
|
-
|
|
258
|
-
|
|
261
|
+
function buildExceptionList(input) {
|
|
262
|
+
const frames = input.frames.length > 0 ? input.frames : [{
|
|
263
|
+
filename: SDK_BOUNDARY_FILENAME,
|
|
264
|
+
function: input.operation ?? "unknown",
|
|
265
|
+
lineno: 1,
|
|
266
|
+
colno: 1
|
|
267
|
+
}];
|
|
268
|
+
return [{
|
|
269
|
+
type: input.type,
|
|
270
|
+
value: input.value,
|
|
271
|
+
mechanism: {
|
|
272
|
+
handled: true,
|
|
273
|
+
type: "capxul_sdk_boundary"
|
|
274
|
+
},
|
|
275
|
+
stacktrace: { frames }
|
|
276
|
+
}];
|
|
259
277
|
}
|
|
260
278
|
//#endregion
|
|
261
279
|
//#region src/telemetry/get-failure-mode.ts
|
|
@@ -306,6 +324,8 @@ function resolveFailureMode(error, contextFailureMode) {
|
|
|
306
324
|
}
|
|
307
325
|
//#endregion
|
|
308
326
|
//#region src/telemetry/capture-exception.ts
|
|
327
|
+
/** Fixed, leak-safe message — the raw error message may carry PII and never ships. */
|
|
328
|
+
const EXCEPTION_MESSAGE = "Capxul SDK operation failed";
|
|
309
329
|
/**
|
|
310
330
|
* Capture an error as a `$exception` event through the telemetry port,
|
|
311
331
|
* formatted for PostHog Error Tracking.
|
|
@@ -319,16 +339,24 @@ function resolveFailureMode(error, contextFailureMode) {
|
|
|
319
339
|
*/
|
|
320
340
|
function captureException(telemetry, error, context) {
|
|
321
341
|
return Effect.catchAllDefect(Effect.sync(() => {
|
|
322
|
-
const
|
|
342
|
+
const frames = error instanceof Error ? parseV8StackFrames(error) : [];
|
|
323
343
|
const capxulError = isCapxulError(error) ? error : null;
|
|
344
|
+
const errorCode = capxulError?.code ?? context?.capxul_error_code ?? "UNKNOWN";
|
|
324
345
|
const props = {
|
|
325
|
-
capxul_error_code:
|
|
346
|
+
capxul_error_code: errorCode,
|
|
347
|
+
$exception_type: errorCode,
|
|
348
|
+
$exception_message: EXCEPTION_MESSAGE,
|
|
349
|
+
$exception_list: buildExceptionList({
|
|
350
|
+
type: errorCode,
|
|
351
|
+
value: EXCEPTION_MESSAGE,
|
|
352
|
+
...context?.operation === void 0 ? {} : { operation: context.operation },
|
|
353
|
+
frames
|
|
354
|
+
}),
|
|
326
355
|
layer: capxulError?.layer ?? context?.layer,
|
|
327
356
|
operation: context?.operation,
|
|
328
357
|
provider: context?.provider,
|
|
329
358
|
failure_mode: resolveFailureMode(error, context?.failure_mode)
|
|
330
359
|
};
|
|
331
|
-
if (exceptionList !== void 0) props.$exception_list = exceptionList;
|
|
332
360
|
if (capxulError?.details !== void 0) props.details = JSON.stringify(capxulError.details);
|
|
333
361
|
for (const key of Object.keys(props)) if (props[key] === void 0) delete props[key];
|
|
334
362
|
return telemetry.emit({
|
|
@@ -1258,10 +1286,10 @@ function makeAccountMethods(deps) {
|
|
|
1258
1286
|
value: await lane.retryProvisioning()
|
|
1259
1287
|
};
|
|
1260
1288
|
};
|
|
1261
|
-
const reportAndReturn = (error) => {
|
|
1289
|
+
const reportAndReturn = (error, operation = "getLifecycle") => {
|
|
1262
1290
|
if (deps.telemetry) captureExceptionSync(deps.telemetry, error, {
|
|
1263
1291
|
layer: "account",
|
|
1264
|
-
operation
|
|
1292
|
+
operation
|
|
1265
1293
|
});
|
|
1266
1294
|
return {
|
|
1267
1295
|
ok: false,
|
|
@@ -1292,6 +1320,12 @@ function makeAccountMethods(deps) {
|
|
|
1292
1320
|
};
|
|
1293
1321
|
const getLifecycle = () => resolveLifecycle();
|
|
1294
1322
|
const retrySetup = async () => {
|
|
1323
|
+
const resetSession = deps.signer?.resetSession;
|
|
1324
|
+
if (typeof resetSession === "function") try {
|
|
1325
|
+
resetSession.call(deps.signer);
|
|
1326
|
+
} catch (cause) {
|
|
1327
|
+
return reportAndReturn(cause instanceof CapxulError ? cause : Errors.providerError("openfort", "resetSession", cause, { failure_mode: "unknown" }), "retrySetup");
|
|
1328
|
+
}
|
|
1295
1329
|
await lane.retryProvisioning();
|
|
1296
1330
|
return resolveLifecycle();
|
|
1297
1331
|
};
|
|
@@ -1618,7 +1652,7 @@ async function recoverRawDigestSigner(input) {
|
|
|
1618
1652
|
}
|
|
1619
1653
|
//#endregion
|
|
1620
1654
|
//#region package.json
|
|
1621
|
-
var version = "1.0.0-alpha.
|
|
1655
|
+
var version = "1.0.0-alpha.20";
|
|
1622
1656
|
//#endregion
|
|
1623
1657
|
//#region src/ports/auth-client.ts
|
|
1624
1658
|
var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
|
|
@@ -3386,24 +3420,6 @@ const envFields = {
|
|
|
3386
3420
|
"required": false,
|
|
3387
3421
|
"example": "development"
|
|
3388
3422
|
},
|
|
3389
|
-
AUTH_DEV_OTP: {
|
|
3390
|
-
"runtime": "server",
|
|
3391
|
-
"kind": "nonempty",
|
|
3392
|
-
"required": false,
|
|
3393
|
-
"example": "000000"
|
|
3394
|
-
},
|
|
3395
|
-
SENTRY_DSN: {
|
|
3396
|
-
"runtime": "server",
|
|
3397
|
-
"kind": "url",
|
|
3398
|
-
"required": false,
|
|
3399
|
-
"example": "https://public@example.ingest.sentry.io/1"
|
|
3400
|
-
},
|
|
3401
|
-
POSTHOG_API_KEY: {
|
|
3402
|
-
"runtime": "server",
|
|
3403
|
-
"kind": "nonempty",
|
|
3404
|
-
"required": false,
|
|
3405
|
-
"example": "phx_test"
|
|
3406
|
-
},
|
|
3407
3423
|
POSTHOG_PROJECT_TOKEN: {
|
|
3408
3424
|
"runtime": "server",
|
|
3409
3425
|
"kind": "nonempty",
|
|
@@ -3434,24 +3450,12 @@ const envFields = {
|
|
|
3434
3450
|
"required": false,
|
|
3435
3451
|
"example": "12345"
|
|
3436
3452
|
},
|
|
3437
|
-
POSTHOG_ENV_ID: {
|
|
3438
|
-
"runtime": "server",
|
|
3439
|
-
"kind": "nonempty",
|
|
3440
|
-
"required": false,
|
|
3441
|
-
"example": "12345"
|
|
3442
|
-
},
|
|
3443
3453
|
SENDER_EMAIL: {
|
|
3444
3454
|
"runtime": "server",
|
|
3445
3455
|
"kind": "email",
|
|
3446
3456
|
"required": false,
|
|
3447
3457
|
"example": "noreply@capxul.test"
|
|
3448
3458
|
},
|
|
3449
|
-
SHIELD_API_URL: {
|
|
3450
|
-
"runtime": "server",
|
|
3451
|
-
"kind": "url",
|
|
3452
|
-
"required": false,
|
|
3453
|
-
"example": "https://api.shield.test"
|
|
3454
|
-
},
|
|
3455
3459
|
ALCHEMY_API_KEY: {
|
|
3456
3460
|
"runtime": "server",
|
|
3457
3461
|
"kind": "nonempty",
|
|
@@ -3470,24 +3474,6 @@ const envFields = {
|
|
|
3470
3474
|
"required": true,
|
|
3471
3475
|
"example": "alchemy_hmac"
|
|
3472
3476
|
},
|
|
3473
|
-
ALCHEMY_AUTH_TOKEN: {
|
|
3474
|
-
"runtime": "server",
|
|
3475
|
-
"kind": "nonempty",
|
|
3476
|
-
"required": false,
|
|
3477
|
-
"example": "alchemy_auth"
|
|
3478
|
-
},
|
|
3479
|
-
ALCHEMY_WEBHOOK_ID: {
|
|
3480
|
-
"runtime": "server",
|
|
3481
|
-
"kind": "nonempty",
|
|
3482
|
-
"required": false,
|
|
3483
|
-
"example": "wh_123"
|
|
3484
|
-
},
|
|
3485
|
-
GOLDSKY_WEBHOOK_SECRET: {
|
|
3486
|
-
"runtime": "server",
|
|
3487
|
-
"kind": "nonempty",
|
|
3488
|
-
"required": false,
|
|
3489
|
-
"example": "goldsky_secret"
|
|
3490
|
-
},
|
|
3491
3477
|
DEPLOYER_PRIVATE_KEY: {
|
|
3492
3478
|
"runtime": "server",
|
|
3493
3479
|
"kind": "privateKey",
|
|
@@ -4207,6 +4193,7 @@ const DEFAULT_FUNCTIONS$1 = {
|
|
|
4207
4193
|
prepareFounderAccount: makeFunctionReference("org/actions:prepareFounderAccount"),
|
|
4208
4194
|
prepareBootstrap: makeFunctionReference("org/actions:prepareBootstrap"),
|
|
4209
4195
|
submitBootstrap: makeFunctionReference("org/actions:submitBootstrap"),
|
|
4196
|
+
resumeBootstrapSubmission: makeFunctionReference("org/actions:resumeBootstrapSubmission"),
|
|
4210
4197
|
confirmBootstrap: makeFunctionReference("org/actions:confirmBootstrap"),
|
|
4211
4198
|
recordFailure: makeFunctionReference("org/lifecycle:recordFailure"),
|
|
4212
4199
|
load: makeFunctionReference("org/lifecycle:load"),
|
|
@@ -4268,14 +4255,22 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4268
4255
|
if (!submitted.ok) return submitted;
|
|
4269
4256
|
return parseLifecycle("submitBootstrap", submitted.value);
|
|
4270
4257
|
}
|
|
4258
|
+
resumeSubmittedBootstrap(input) {
|
|
4259
|
+
return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, { orgId: input.orgId }));
|
|
4260
|
+
}
|
|
4271
4261
|
confirmSubmittedBootstrap(input) {
|
|
4272
4262
|
return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, { orgId: input.orgId }));
|
|
4273
4263
|
}
|
|
4274
4264
|
async recordFailure(input) {
|
|
4265
|
+
const errorProvider = input.error.details?.provider;
|
|
4266
|
+
const errorOperation = input.error.details?.operation;
|
|
4275
4267
|
const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, {
|
|
4276
4268
|
orgId: input.orgId,
|
|
4277
|
-
at: input.at,
|
|
4278
4269
|
errorCode: input.error.code,
|
|
4270
|
+
...typeof errorProvider === "string" && typeof errorOperation === "string" ? {
|
|
4271
|
+
errorProvider,
|
|
4272
|
+
errorOperation
|
|
4273
|
+
} : {},
|
|
4279
4274
|
retryable: input.retryable
|
|
4280
4275
|
}));
|
|
4281
4276
|
return result.ok ? parseLifecycle("recordFailure", result.value) : result;
|
|
@@ -4289,8 +4284,15 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4289
4284
|
async retry(input) {
|
|
4290
4285
|
const cancelled = cancellation(input.signal);
|
|
4291
4286
|
if (cancelled !== void 0) return cancelled;
|
|
4287
|
+
const current = await this.loadLifecycle({ orgId: input.orgId });
|
|
4288
|
+
if (!current.ok) return current;
|
|
4289
|
+
if (current.value.status === "failed" && current.value.retryable && (current.value.at === "awaitingFounderAuthorization" || current.value.at === "submittingBootstrap")) {
|
|
4290
|
+
const reset = resetSignerSession(this.#signer);
|
|
4291
|
+
if (!reset.ok) return reset;
|
|
4292
|
+
}
|
|
4292
4293
|
const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, { orgId: input.orgId }));
|
|
4293
|
-
|
|
4294
|
+
if (!result.ok) return result;
|
|
4295
|
+
return parseLifecycle("retry", result.value);
|
|
4294
4296
|
}
|
|
4295
4297
|
async #lifecycleAction(operation, input, call) {
|
|
4296
4298
|
const cancelled = cancellation(input.signal);
|
|
@@ -4302,6 +4304,22 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4302
4304
|
return parseLifecycle(operation, result.value);
|
|
4303
4305
|
}
|
|
4304
4306
|
};
|
|
4307
|
+
function resetSignerSession(signer) {
|
|
4308
|
+
const resetSession = signer.resetSession;
|
|
4309
|
+
if (typeof resetSession !== "function") return {
|
|
4310
|
+
ok: true,
|
|
4311
|
+
value: void 0
|
|
4312
|
+
};
|
|
4313
|
+
try {
|
|
4314
|
+
resetSession.call(signer);
|
|
4315
|
+
return {
|
|
4316
|
+
ok: true,
|
|
4317
|
+
value: void 0
|
|
4318
|
+
};
|
|
4319
|
+
} catch (cause) {
|
|
4320
|
+
return fail$2(cause instanceof CapxulError ? cause : Errors.providerError("openfort", "resetSession", cause, { failure_mode: "unknown" }));
|
|
4321
|
+
}
|
|
4322
|
+
}
|
|
4305
4323
|
async function runCall(operation, effect) {
|
|
4306
4324
|
try {
|
|
4307
4325
|
const result = await Effect.runPromise(Effect.either(effect));
|
|
@@ -4328,7 +4346,7 @@ async function signerResult(operation, run) {
|
|
|
4328
4346
|
value: await run()
|
|
4329
4347
|
};
|
|
4330
4348
|
} catch (cause) {
|
|
4331
|
-
return fail$2(Errors.providerError("organization-signer", operation, cause));
|
|
4349
|
+
return fail$2(cause instanceof CapxulError ? cause : Errors.providerError("organization-signer", operation, cause));
|
|
4332
4350
|
}
|
|
4333
4351
|
}
|
|
4334
4352
|
function validatePreparedAuthorities(prepared, signerAddress) {
|
|
@@ -5249,7 +5267,22 @@ function transportErrorFromThrown(operation, request, cause) {
|
|
|
5249
5267
|
return transportErrorFromCapxul(operation, request, cause instanceof Error ? Errors.providerError("transport", request.name, cause) : Errors.providerError("transport", request.name, new Error(String(cause))), cause);
|
|
5250
5268
|
}
|
|
5251
5269
|
//#endregion
|
|
5270
|
+
//#region src/adapters/diagnostic/ConsoleDiagnosticAdapter.ts
|
|
5271
|
+
const DEFAULT_ACCOUNT_SETUP_LOG_PREFIX = "[capxul:account-setup]";
|
|
5272
|
+
var ConsoleDiagnosticAdapter = class {
|
|
5273
|
+
prefix;
|
|
5274
|
+
constructor(prefix = DEFAULT_ACCOUNT_SETUP_LOG_PREFIX) {
|
|
5275
|
+
this.prefix = prefix;
|
|
5276
|
+
}
|
|
5277
|
+
trace(scope, detail) {
|
|
5278
|
+
globalThis.console?.debug?.(`${this.prefix} ${scope}`, detail);
|
|
5279
|
+
}
|
|
5280
|
+
};
|
|
5281
|
+
//#endregion
|
|
5252
5282
|
//#region src/openfort/create-openfort-browser-signer.ts
|
|
5283
|
+
function openfortProviderError(operation, cause) {
|
|
5284
|
+
return cause instanceof CapxulError ? cause : Errors.providerError("openfort", operation, cause, { failure_mode: "unknown" });
|
|
5285
|
+
}
|
|
5253
5286
|
/**
|
|
5254
5287
|
* True when the browser cannot perform Web Crypto — sandboxed iframes, headless
|
|
5255
5288
|
* agent browsers, or non-HTTPS origins. OpenFort's embedded-wallet `configure`
|
|
@@ -5318,21 +5351,39 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
5318
5351
|
return `${authBaseUrl}/encryption-session`;
|
|
5319
5352
|
}
|
|
5320
5353
|
async function fetchBetterAuthAccessToken() {
|
|
5321
|
-
|
|
5322
|
-
|
|
5354
|
+
try {
|
|
5355
|
+
const response = await fetch(betterAuthSessionUrl(), { credentials: "include" });
|
|
5356
|
+
if (!response.ok) {
|
|
5357
|
+
diagnostic?.trace("openfort.token", {
|
|
5358
|
+
ok: false,
|
|
5359
|
+
tokenPresent: false,
|
|
5360
|
+
httpStatus: response.status,
|
|
5361
|
+
failure_mode: "unknown"
|
|
5362
|
+
});
|
|
5363
|
+
return null;
|
|
5364
|
+
}
|
|
5365
|
+
const token = (await response.json()).session?.token?.trim();
|
|
5366
|
+
if (token === void 0 || token.length === 0) {
|
|
5367
|
+
diagnostic?.trace("openfort.token", {
|
|
5368
|
+
ok: false,
|
|
5369
|
+
tokenPresent: false,
|
|
5370
|
+
failure_mode: "unknown"
|
|
5371
|
+
});
|
|
5372
|
+
return null;
|
|
5373
|
+
}
|
|
5323
5374
|
diagnostic?.trace("openfort.token", {
|
|
5375
|
+
ok: true,
|
|
5376
|
+
tokenPresent: true
|
|
5377
|
+
});
|
|
5378
|
+
return token;
|
|
5379
|
+
} catch (cause) {
|
|
5380
|
+
diagnostic?.trace("openfort.token", {
|
|
5381
|
+
ok: false,
|
|
5324
5382
|
tokenPresent: false,
|
|
5325
|
-
|
|
5383
|
+
failure_mode: "unknown"
|
|
5326
5384
|
});
|
|
5327
|
-
|
|
5328
|
-
}
|
|
5329
|
-
const token = (await response.json()).session?.token?.trim();
|
|
5330
|
-
if (token === void 0 || token.length === 0) {
|
|
5331
|
-
diagnostic?.trace("openfort.token", { tokenPresent: false });
|
|
5332
|
-
return null;
|
|
5385
|
+
throw openfortProviderError("token", cause);
|
|
5333
5386
|
}
|
|
5334
|
-
diagnostic?.trace("openfort.token", { tokenPresent: true });
|
|
5335
|
-
return token;
|
|
5336
5387
|
}
|
|
5337
5388
|
const openfort = new Openfort({
|
|
5338
5389
|
baseConfiguration: { publishableKey: bootstrap.openfortPublishableKey },
|
|
@@ -5348,25 +5399,60 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
5348
5399
|
if (isInsecureBrowserContext()) failNoSecureContext();
|
|
5349
5400
|
await openfort.waitForInitialization();
|
|
5350
5401
|
const accessToken = await fetchBetterAuthAccessToken();
|
|
5351
|
-
if (accessToken === null) throw
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5402
|
+
if (accessToken === null) throw openfortProviderError("token", /* @__PURE__ */ new Error("Better Auth access token unavailable for Openfort"));
|
|
5403
|
+
let encryptionResponse;
|
|
5404
|
+
try {
|
|
5405
|
+
encryptionResponse = await fetch(encryptionSessionUrl(), {
|
|
5406
|
+
method: "POST",
|
|
5407
|
+
credentials: "include",
|
|
5408
|
+
headers: {
|
|
5409
|
+
Authorization: `Bearer ${accessToken}`,
|
|
5410
|
+
"Content-Type": "application/json"
|
|
5411
|
+
},
|
|
5412
|
+
body: JSON.stringify({})
|
|
5413
|
+
});
|
|
5414
|
+
} catch (cause) {
|
|
5415
|
+
diagnostic?.trace("openfort.encryptionSession", {
|
|
5416
|
+
ok: false,
|
|
5417
|
+
failure_mode: "unknown"
|
|
5418
|
+
});
|
|
5419
|
+
throw openfortProviderError("encryptionSession", cause);
|
|
5420
|
+
}
|
|
5362
5421
|
if (!encryptionResponse.ok) {
|
|
5363
|
-
|
|
5364
|
-
|
|
5422
|
+
diagnostic?.trace("openfort.encryptionSession", {
|
|
5423
|
+
ok: false,
|
|
5424
|
+
httpStatus: encryptionResponse.status,
|
|
5425
|
+
failure_mode: "unknown"
|
|
5426
|
+
});
|
|
5427
|
+
throw Errors.providerError("openfort", "encryptionSession", /* @__PURE__ */ new Error(`Openfort encryption session failed (${encryptionResponse.status})`), { failure_mode: "unknown" });
|
|
5428
|
+
}
|
|
5429
|
+
let encryptionBody;
|
|
5430
|
+
try {
|
|
5431
|
+
encryptionBody = await encryptionResponse.json();
|
|
5432
|
+
if (typeof encryptionBody.sessionId !== "string" || encryptionBody.sessionId.length === 0) throw new Error("Openfort encryption session response missing sessionId");
|
|
5433
|
+
} catch (cause) {
|
|
5434
|
+
diagnostic?.trace("openfort.encryptionSession", {
|
|
5435
|
+
ok: false,
|
|
5436
|
+
httpStatus: encryptionResponse.status,
|
|
5437
|
+
failure_mode: "unknown"
|
|
5438
|
+
});
|
|
5439
|
+
throw openfortProviderError("encryptionSession", cause);
|
|
5440
|
+
}
|
|
5441
|
+
diagnostic?.trace("openfort.encryptionSession", {
|
|
5442
|
+
ok: true,
|
|
5443
|
+
httpStatus: encryptionResponse.status
|
|
5444
|
+
});
|
|
5445
|
+
let embeddedState;
|
|
5446
|
+
try {
|
|
5447
|
+
embeddedState = await openfort.embeddedWallet.getEmbeddedState();
|
|
5448
|
+
diagnostic?.trace("openfort.embeddedState", { state: embeddedState });
|
|
5449
|
+
} catch (cause) {
|
|
5450
|
+
diagnostic?.trace("openfort.embeddedState", {
|
|
5451
|
+
ok: false,
|
|
5452
|
+
failure_mode: "unknown"
|
|
5453
|
+
});
|
|
5454
|
+
throw openfortProviderError("embeddedState", cause);
|
|
5365
5455
|
}
|
|
5366
|
-
const encryptionBody = await encryptionResponse.json();
|
|
5367
|
-
if (typeof encryptionBody.sessionId !== "string" || encryptionBody.sessionId.length === 0) throw Errors.providerError("openfort", "encryptionSession", /* @__PURE__ */ new Error("Openfort encryption session response missing sessionId"));
|
|
5368
|
-
const embeddedState = await openfort.embeddedWallet.getEmbeddedState();
|
|
5369
|
-
diagnostic?.trace("openfort.embeddedState", { state: embeddedState });
|
|
5370
5456
|
if (embeddedState !== EmbeddedState.READY) {
|
|
5371
5457
|
clearStaleOpenfortBrowserStorage(bootstrap.openfortPublishableKey);
|
|
5372
5458
|
diagnostic?.trace("openfort.storageCleared", { beforeConfigure: true });
|
|
@@ -5383,9 +5469,9 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
5383
5469
|
} catch (cause) {
|
|
5384
5470
|
diagnostic?.trace("openfort.configure", {
|
|
5385
5471
|
ok: false,
|
|
5386
|
-
|
|
5472
|
+
failure_mode: "unknown"
|
|
5387
5473
|
});
|
|
5388
|
-
throw cause;
|
|
5474
|
+
throw openfortProviderError("configure", cause);
|
|
5389
5475
|
}
|
|
5390
5476
|
}
|
|
5391
5477
|
try {
|
|
@@ -5394,9 +5480,9 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
5394
5480
|
} catch (cause) {
|
|
5395
5481
|
diagnostic?.trace("openfort.get", {
|
|
5396
5482
|
ok: false,
|
|
5397
|
-
|
|
5483
|
+
failure_mode: "unknown"
|
|
5398
5484
|
});
|
|
5399
|
-
throw cause;
|
|
5485
|
+
throw openfortProviderError("get", cause);
|
|
5400
5486
|
}
|
|
5401
5487
|
})();
|
|
5402
5488
|
}
|
|
@@ -5415,6 +5501,19 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
|
|
|
5415
5501
|
});
|
|
5416
5502
|
return {
|
|
5417
5503
|
...signer,
|
|
5504
|
+
getAddress: async () => {
|
|
5505
|
+
try {
|
|
5506
|
+
const address = await signer.getAddress();
|
|
5507
|
+
diagnostic?.trace("openfort.address", { ok: true });
|
|
5508
|
+
return address;
|
|
5509
|
+
} catch (cause) {
|
|
5510
|
+
diagnostic?.trace("openfort.address", {
|
|
5511
|
+
ok: false,
|
|
5512
|
+
failure_mode: "unknown"
|
|
5513
|
+
});
|
|
5514
|
+
throw openfortProviderError("getAddress", cause);
|
|
5515
|
+
}
|
|
5516
|
+
},
|
|
5418
5517
|
resetSession: () => {
|
|
5419
5518
|
walletReadyPromise = null;
|
|
5420
5519
|
clearStaleOpenfortBrowserStorage(bootstrap.openfortPublishableKey);
|
|
@@ -6540,10 +6639,6 @@ function makeCurrentUserMethods(deps) {
|
|
|
6540
6639
|
deps.smartAccount.loadCurrent(options),
|
|
6541
6640
|
deps.orgs(options)
|
|
6542
6641
|
]);
|
|
6543
|
-
if (!account.ok) return {
|
|
6544
|
-
ok: false,
|
|
6545
|
-
error: account.error
|
|
6546
|
-
};
|
|
6547
6642
|
if (!smartAccount.ok) return {
|
|
6548
6643
|
ok: false,
|
|
6549
6644
|
error: smartAccount.error
|
|
@@ -6552,6 +6647,10 @@ function makeCurrentUserMethods(deps) {
|
|
|
6552
6647
|
ok: false,
|
|
6553
6648
|
error: organizations.error
|
|
6554
6649
|
};
|
|
6650
|
+
if (!account.ok && account.error.code !== "SMART_ACCOUNT_MISSING") return {
|
|
6651
|
+
ok: false,
|
|
6652
|
+
error: account.error
|
|
6653
|
+
};
|
|
6555
6654
|
return {
|
|
6556
6655
|
ok: true,
|
|
6557
6656
|
value: {
|
|
@@ -6562,10 +6661,10 @@ function makeCurrentUserMethods(deps) {
|
|
|
6562
6661
|
handle: null,
|
|
6563
6662
|
paymentLink: null
|
|
6564
6663
|
},
|
|
6565
|
-
personalAccount: {
|
|
6664
|
+
personalAccount: account.ok ? {
|
|
6566
6665
|
id: account.value.id,
|
|
6567
6666
|
address: smartAccount.value?.smartAccountAddress ?? null
|
|
6568
|
-
},
|
|
6667
|
+
} : null,
|
|
6569
6668
|
organizations: organizations.value.map((organization) => ({
|
|
6570
6669
|
id: organization.id,
|
|
6571
6670
|
name: organization.name,
|
|
@@ -7921,16 +8020,17 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
|
7921
8020
|
value: lifecycle
|
|
7922
8021
|
};
|
|
7923
8022
|
const currentStep = lifecycle.step;
|
|
7924
|
-
if (signal?.aborted) {
|
|
7925
|
-
const cancelled = Errors.cancelled({ operation: "organization.setup" });
|
|
7926
|
-
return recordRetryableCancellation(setup, orgId, lifecycle.step, cancelled);
|
|
7927
|
-
}
|
|
8023
|
+
if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true);
|
|
7928
8024
|
const stepInput = {
|
|
7929
8025
|
orgId,
|
|
7930
8026
|
...signal === void 0 ? {} : { signal }
|
|
7931
8027
|
};
|
|
7932
|
-
const next = lifecycle.step === "preparingFounderAccount" ? await setup.prepareFounderAccount(stepInput) : lifecycle.step === "awaitingFounderAuthorization"
|
|
7933
|
-
if (!next.ok)
|
|
8028
|
+
const next = lifecycle.step === "preparingFounderAccount" ? await setup.prepareFounderAccount(stepInput) : lifecycle.step === "awaitingFounderAuthorization" ? await setup.authorizeAndSubmitBootstrap(stepInput) : lifecycle.step === "submittingBootstrap" ? await setup.resumeSubmittedBootstrap(stepInput) : await setup.confirmSubmittedBootstrap(stepInput);
|
|
8029
|
+
if (!next.ok) {
|
|
8030
|
+
if (next.error.code === "CANCELLED") return recordSetupFailure(setup, orgId, next.error, true);
|
|
8031
|
+
if (next.error.code === "PROVIDER_ERROR") return recordSetupFailure(setup, orgId, next.error, isRetryableProviderFailure(next.error));
|
|
8032
|
+
return next;
|
|
8033
|
+
}
|
|
7934
8034
|
const scopedNext = validateOrganizationLifecycleScope(orgId, next.value);
|
|
7935
8035
|
if (!scopedNext.ok) return scopedNext;
|
|
7936
8036
|
lifecycle = scopedNext.value;
|
|
@@ -7953,17 +8053,20 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
|
7953
8053
|
]
|
|
7954
8054
|
}));
|
|
7955
8055
|
}
|
|
7956
|
-
async function
|
|
8056
|
+
async function recordSetupFailure(setup, orgId, error, retryable) {
|
|
7957
8057
|
const recorded = await setup.recordFailure({
|
|
7958
8058
|
orgId,
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
retryable: true
|
|
8059
|
+
error,
|
|
8060
|
+
retryable
|
|
7962
8061
|
});
|
|
7963
8062
|
if (!recorded.ok) return recorded;
|
|
7964
8063
|
const scopedRecorded = validateOrganizationLifecycleScope(orgId, recorded.value);
|
|
7965
8064
|
if (!scopedRecorded.ok) return scopedRecorded;
|
|
7966
|
-
return fail$1(
|
|
8065
|
+
return fail$1(error);
|
|
8066
|
+
}
|
|
8067
|
+
function isRetryableProviderFailure(error) {
|
|
8068
|
+
const mode = error.details?.failure_mode;
|
|
8069
|
+
return mode !== "auth-origin-mismatch" && mode !== "app-env-allowlist" && mode !== "no-secure-context";
|
|
7967
8070
|
}
|
|
7968
8071
|
//#endregion
|
|
7969
8072
|
//#region src/client/org.ts
|
|
@@ -8314,7 +8417,18 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
|
|
|
8314
8417
|
});
|
|
8315
8418
|
if (!started.ok) return fail(started.error);
|
|
8316
8419
|
const lifecycle = await advanceOrganizationSetup(setup, started.value.orgId, started.value.lifecycle, options?.signal);
|
|
8317
|
-
if (!lifecycle.ok)
|
|
8420
|
+
if (!lifecycle.ok) {
|
|
8421
|
+
const error = lifecycle.error;
|
|
8422
|
+
return fail(new CapxulError(error.code, error.message, {
|
|
8423
|
+
cause: error.cause,
|
|
8424
|
+
details: {
|
|
8425
|
+
...error.details,
|
|
8426
|
+
orgId: started.value.orgId
|
|
8427
|
+
},
|
|
8428
|
+
...error.correlationId === void 0 ? {} : { correlationId: error.correlationId },
|
|
8429
|
+
...error.layer === void 0 ? {} : { layer: error.layer }
|
|
8430
|
+
}));
|
|
8431
|
+
}
|
|
8318
8432
|
return {
|
|
8319
8433
|
ok: true,
|
|
8320
8434
|
value: {
|
|
@@ -8438,6 +8552,7 @@ function detectAuthCacheAdapter() {
|
|
|
8438
8552
|
}
|
|
8439
8553
|
//#endregion
|
|
8440
8554
|
//#region src/client/create-capxul-client.ts
|
|
8555
|
+
const GET_ORGANIZATION_SETUP_PROOF_RECEIPT = makeFunctionReference("org/lifecycle:getProofReceipt");
|
|
8441
8556
|
function assembleCapxulClient(input) {
|
|
8442
8557
|
const authCache = input.authCache ?? detectAuthCacheAdapter();
|
|
8443
8558
|
const layer = Layer.mergeAll(Layer.succeed(AuthClientPortTag, input.ports.authClient), Layer.succeed(ClockPortTag, input.ports.clock), Layer.succeed(TelemetryPortTag, input.ports.telemetry));
|
|
@@ -8561,6 +8676,7 @@ function assembleCapxulClient(input) {
|
|
|
8561
8676
|
},
|
|
8562
8677
|
bootstrap: input.bootstrap,
|
|
8563
8678
|
accounts: { fund: accounts.fund },
|
|
8679
|
+
organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(GET_ORGANIZATION_SETUP_PROOF_RECEIPT, { orgId })) },
|
|
8564
8680
|
telemetry: input.ports.telemetry
|
|
8565
8681
|
}
|
|
8566
8682
|
};
|
|
@@ -8762,24 +8878,34 @@ function ignoreDeliveryFailure(delivery) {
|
|
|
8762
8878
|
Promise.resolve(delivery).catch(() => void 0);
|
|
8763
8879
|
} catch {}
|
|
8764
8880
|
}
|
|
8881
|
+
/**
|
|
8882
|
+
* Map an ALREADY-sanitized observation context to the snake_case PostHog
|
|
8883
|
+
* property keys. Shared by the failure boundary here and the host
|
|
8884
|
+
* success-telemetry seam (`telemetry/from-posthog.ts`) so both attach identical
|
|
8885
|
+
* correlation fields from one definition.
|
|
8886
|
+
*/
|
|
8887
|
+
function observationContextProps(context) {
|
|
8888
|
+
const props = {};
|
|
8889
|
+
if (context?.application !== void 0) props.application = context.application;
|
|
8890
|
+
if (context?.release !== void 0) props.release = context.release;
|
|
8891
|
+
if (context?.sessionId !== void 0) props.session_id = context.sessionId;
|
|
8892
|
+
if (context?.organizationId !== void 0) props.organization_id = context.organizationId;
|
|
8893
|
+
if (context?.correlationId !== void 0) props.correlation_id = context.correlationId;
|
|
8894
|
+
if (context?.anonymousId !== void 0) props.anonymous_id = context.anonymousId;
|
|
8895
|
+
return props;
|
|
8896
|
+
}
|
|
8765
8897
|
function postHogProperties(failure, context) {
|
|
8766
|
-
const properties = {
|
|
8767
|
-
sdk_version: failure.sdkVersion,
|
|
8768
|
-
operation: failure.operation,
|
|
8769
|
-
error_kind: failure.errorKind,
|
|
8770
|
-
handled: true
|
|
8771
|
-
};
|
|
8772
8898
|
const merged = sanitizeObservationContext({
|
|
8773
8899
|
...context,
|
|
8774
8900
|
...failure.context
|
|
8775
8901
|
});
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8902
|
+
return {
|
|
8903
|
+
sdk_version: failure.sdkVersion,
|
|
8904
|
+
operation: failure.operation,
|
|
8905
|
+
error_kind: failure.errorKind,
|
|
8906
|
+
handled: true,
|
|
8907
|
+
...observationContextProps(merged)
|
|
8908
|
+
};
|
|
8783
8909
|
}
|
|
8784
8910
|
function resolveContext(context) {
|
|
8785
8911
|
return sanitizeObservationContext(resolveRawContext(context));
|
|
@@ -8830,7 +8956,7 @@ function normalizeErrorKind(value) {
|
|
|
8830
8956
|
return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u.test(value) ? value : "Error";
|
|
8831
8957
|
}
|
|
8832
8958
|
function syntheticException(operation, kind) {
|
|
8833
|
-
const error = /* @__PURE__ */ new Error(
|
|
8959
|
+
const error = /* @__PURE__ */ new Error(EXCEPTION_MESSAGE);
|
|
8834
8960
|
error.name = kind;
|
|
8835
8961
|
error.stack = `${kind}: ${error.message}\n at CapxulSdkBoundary.${operation} (capxul-sdk-observation://boundary/${operation}:1:1)`;
|
|
8836
8962
|
return error;
|
|
@@ -9176,6 +9302,9 @@ async function createCapxulClient$1(input) {
|
|
|
9176
9302
|
if (signer === void 0 && runtime === "browser") signer = createOpenfortBrowserSignerFromBootstrap({
|
|
9177
9303
|
...adapters.value.bootstrap,
|
|
9178
9304
|
authBaseUrl: resolvedAuthBaseUrl
|
|
9305
|
+
}, {
|
|
9306
|
+
diagnostic: new ConsoleDiagnosticAdapter(),
|
|
9307
|
+
telemetry: adapters.value.ports.telemetry
|
|
9179
9308
|
});
|
|
9180
9309
|
const client = wireOpenfortSignerLifecycle(assembleCapxulClient({
|
|
9181
9310
|
ports: adapters.value.ports,
|
|
@@ -9390,6 +9519,73 @@ async function createCapxulClient(input) {
|
|
|
9390
9519
|
return createCapxulClient$1(input);
|
|
9391
9520
|
}
|
|
9392
9521
|
//#endregion
|
|
9393
|
-
|
|
9522
|
+
//#region src/telemetry/from-posthog.ts
|
|
9523
|
+
/**
|
|
9524
|
+
* Drop props that must never cross to a host-owned external sink. Today that is
|
|
9525
|
+
* the `$exception` `details` blob: `captureException` serializes
|
|
9526
|
+
* `CapxulError.details` (e.g. `{ asset, available, required }`, `{ name }`,
|
|
9527
|
+
* `{ accountId }` — errors.ts) into it, and the shared redactor has no
|
|
9528
|
+
* `$exception` rule, so it is stripped here at the boundary (infra#1037). The
|
|
9529
|
+
* safe fields (error code, operation, failure_mode, the fixed leak-safe message,
|
|
9530
|
+
* stack frames) are preserved.
|
|
9531
|
+
*/
|
|
9532
|
+
function stripHostUnsafeProps(props) {
|
|
9533
|
+
if (props === void 0) return void 0;
|
|
9534
|
+
const { details: _details, ...safe } = props;
|
|
9535
|
+
return safe;
|
|
9536
|
+
}
|
|
9537
|
+
/**
|
|
9538
|
+
* Adapt the host's already-initialized posthog-like client into a
|
|
9539
|
+
* `TelemetryPort` for the `telemetry` prop / input. This port SUPPLANTS the
|
|
9540
|
+
* SDK's no-op default telemetry sink (`production.ts` binds it via
|
|
9541
|
+
* `Layer.succeed`, not `compose` — there is no client-side success relay to
|
|
9542
|
+
* compose with); it is additive to Capxul's backend first-party record and
|
|
9543
|
+
* never owns the client.
|
|
9544
|
+
*/
|
|
9545
|
+
function telemetryFromPostHog(client, options = {}) {
|
|
9546
|
+
const active = () => {
|
|
9547
|
+
if (client === null || client === void 0) return false;
|
|
9548
|
+
try {
|
|
9549
|
+
return typeof options.enabled === "function" ? options.enabled() : options.enabled ?? true;
|
|
9550
|
+
} catch {
|
|
9551
|
+
return false;
|
|
9552
|
+
}
|
|
9553
|
+
};
|
|
9554
|
+
const contextProps = () => {
|
|
9555
|
+
let raw;
|
|
9556
|
+
try {
|
|
9557
|
+
raw = typeof options.context === "function" ? options.context() : options.context;
|
|
9558
|
+
} catch {
|
|
9559
|
+
return {};
|
|
9560
|
+
}
|
|
9561
|
+
return observationContextProps(sanitizeObservationContext(raw));
|
|
9562
|
+
};
|
|
9563
|
+
return new PostHogTelemetryAdapter({
|
|
9564
|
+
capture: (name, props) => {
|
|
9565
|
+
if (!active() || client === null || client === void 0) return;
|
|
9566
|
+
client.capture(name, {
|
|
9567
|
+
...stripHostUnsafeProps(props),
|
|
9568
|
+
...contextProps()
|
|
9569
|
+
});
|
|
9570
|
+
},
|
|
9571
|
+
identify: (input) => {
|
|
9572
|
+
if (!active() || client?.identify === void 0) return;
|
|
9573
|
+
client.identify(input.distinctId, {
|
|
9574
|
+
...input.traits,
|
|
9575
|
+
...input.properties
|
|
9576
|
+
});
|
|
9577
|
+
},
|
|
9578
|
+
group: (input) => {
|
|
9579
|
+
if (!active() || client?.group === void 0) return;
|
|
9580
|
+
client.group(input.groupType, input.groupKey, input.properties === void 0 ? void 0 : { ...input.properties });
|
|
9581
|
+
},
|
|
9582
|
+
reset: () => {
|
|
9583
|
+
if (!active() || client?.reset === void 0) return;
|
|
9584
|
+
client.reset();
|
|
9585
|
+
}
|
|
9586
|
+
});
|
|
9587
|
+
}
|
|
9588
|
+
//#endregion
|
|
9589
|
+
export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort, telemetryFromPostHog };
|
|
9394
9590
|
|
|
9395
9591
|
//# sourceMappingURL=index.mjs.map
|