@capxul/sdk 1.0.0-alpha.19 → 1.0.0-alpha.21
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 +9 -0
- package/dist/{InMemoryAuthCacheAdapter-BuVZpnSx.mjs → InMemoryAuthCacheAdapter-CHYpYyk5.mjs} +2 -1
- package/dist/InMemoryAuthCacheAdapter-CHYpYyk5.mjs.map +1 -0
- package/dist/{index-D1rNjmof.d.mts → index-DsRoJ2Wc.d.mts} +6 -2
- package/dist/index-DsRoJ2Wc.d.mts.map +1 -0
- package/dist/index.d.mts +61 -17
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +394 -147
- 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-BID2pXZN.d.mts → safe-deployment-BbyXBMpR.d.mts} +2 -2
- package/dist/{safe-deployment-BID2pXZN.d.mts.map → safe-deployment-BbyXBMpR.d.mts.map} +1 -1
- package/dist/{signer-AXnBJuAN.d.mts → signer-CbC6igta.d.mts} +2 -2
- package/dist/{signer-AXnBJuAN.d.mts.map → signer-CbC6igta.d.mts.map} +1 -1
- package/package.json +6 -6
- package/dist/InMemoryAuthCacheAdapter-BuVZpnSx.mjs.map +0 -1
- package/dist/index-D1rNjmof.d.mts.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({
|
|
@@ -348,6 +376,45 @@ function captureExceptionSync(telemetry, error, context) {
|
|
|
348
376
|
} catch {}
|
|
349
377
|
}
|
|
350
378
|
//#endregion
|
|
379
|
+
//#region src/internal/invocation-observation.ts
|
|
380
|
+
const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
|
|
381
|
+
const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
|
|
382
|
+
/** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
|
|
383
|
+
function attachInvocationObservation(target, context) {
|
|
384
|
+
const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
|
|
385
|
+
Object.defineProperty(target, INVOCATION_OBSERVATION, {
|
|
386
|
+
configurable: false,
|
|
387
|
+
enumerable: false,
|
|
388
|
+
value: snapshot,
|
|
389
|
+
writable: false
|
|
390
|
+
});
|
|
391
|
+
return target;
|
|
392
|
+
}
|
|
393
|
+
/** @internal Read the snapshot without exposing its symbol or adding a wire field. */
|
|
394
|
+
function readInvocationObservation(source) {
|
|
395
|
+
if (typeof source !== "object" || source === null) return void 0;
|
|
396
|
+
return source[INVOCATION_OBSERVATION];
|
|
397
|
+
}
|
|
398
|
+
/** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
|
|
399
|
+
function copyInvocationObservation(source, target) {
|
|
400
|
+
const snapshot = readInvocationObservation(source);
|
|
401
|
+
return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
|
|
402
|
+
}
|
|
403
|
+
/** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
|
|
404
|
+
function markFailureInvocationSnapshot(failure) {
|
|
405
|
+
Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
|
|
406
|
+
configurable: false,
|
|
407
|
+
enumerable: false,
|
|
408
|
+
value: true,
|
|
409
|
+
writable: false
|
|
410
|
+
});
|
|
411
|
+
return failure;
|
|
412
|
+
}
|
|
413
|
+
/** @internal Distinguish public-boundary failures from direct adapter calls. */
|
|
414
|
+
function hasFailureInvocationSnapshot(failure) {
|
|
415
|
+
return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
|
|
416
|
+
}
|
|
417
|
+
//#endregion
|
|
351
418
|
//#region src/client/_shared/effect-actor-bridge.ts
|
|
352
419
|
/**
|
|
353
420
|
* Bridge an Effect whose typed failure carries `{ publicError: CapxulError }`
|
|
@@ -1193,7 +1260,7 @@ function makeAccountMethods(deps) {
|
|
|
1193
1260
|
};
|
|
1194
1261
|
};
|
|
1195
1262
|
const deployMutex = /* @__PURE__ */ new Map();
|
|
1196
|
-
const deploySafeImpl = async () => {
|
|
1263
|
+
const deploySafeImpl = async (observationSource) => {
|
|
1197
1264
|
const session = await currentSession(deps.actor, deps.authCache);
|
|
1198
1265
|
if (session === null) return {
|
|
1199
1266
|
ok: false,
|
|
@@ -1221,7 +1288,8 @@ function makeAccountMethods(deps) {
|
|
|
1221
1288
|
authUserId: session.authUserId,
|
|
1222
1289
|
chainId: deps.chainId,
|
|
1223
1290
|
signer,
|
|
1224
|
-
smartAccountPort: deps.smartAccountPort
|
|
1291
|
+
smartAccountPort: deps.smartAccountPort,
|
|
1292
|
+
observationSource
|
|
1225
1293
|
}).finally(() => {
|
|
1226
1294
|
deployMutex.delete(mutexKey);
|
|
1227
1295
|
});
|
|
@@ -1345,11 +1413,11 @@ async function runBackendClaim(input) {
|
|
|
1345
1413
|
error: Errors.providerError("signer", "getAddress", cause)
|
|
1346
1414
|
};
|
|
1347
1415
|
}
|
|
1348
|
-
const claimed = await runPortEffect(input.smartAccountPort.claim({
|
|
1416
|
+
const claimed = await runPortEffect(input.smartAccountPort.claim(copyInvocationObservation(input.observationSource, {
|
|
1349
1417
|
authUserId: input.authUserId,
|
|
1350
1418
|
chainId,
|
|
1351
1419
|
signerAddress
|
|
1352
|
-
}));
|
|
1420
|
+
})));
|
|
1353
1421
|
if (!claimed.ok) return claimed;
|
|
1354
1422
|
return {
|
|
1355
1423
|
ok: true,
|
|
@@ -1624,7 +1692,7 @@ async function recoverRawDigestSigner(input) {
|
|
|
1624
1692
|
}
|
|
1625
1693
|
//#endregion
|
|
1626
1694
|
//#region package.json
|
|
1627
|
-
var version = "1.0.0-alpha.
|
|
1695
|
+
var version = "1.0.0-alpha.21";
|
|
1628
1696
|
//#endregion
|
|
1629
1697
|
//#region src/ports/auth-client.ts
|
|
1630
1698
|
var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
|
|
@@ -1710,6 +1778,10 @@ const FIELD_RULES = {
|
|
|
1710
1778
|
maxLength: 128,
|
|
1711
1779
|
pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
|
|
1712
1780
|
},
|
|
1781
|
+
journeyId: {
|
|
1782
|
+
maxLength: 128,
|
|
1783
|
+
pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
|
|
1784
|
+
},
|
|
1713
1785
|
correlationId: {
|
|
1714
1786
|
maxLength: 128,
|
|
1715
1787
|
pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
|
|
@@ -2983,48 +3055,10 @@ function convexCallErrorFromCapxul(operation, error) {
|
|
|
2983
3055
|
}
|
|
2984
3056
|
var ConvexCallPortTag = class extends Context.Tag("@capxul/sdk/ports/ConvexCallPort")() {};
|
|
2985
3057
|
//#endregion
|
|
2986
|
-
//#region src/internal/invocation-observation.ts
|
|
2987
|
-
const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
|
|
2988
|
-
const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
|
|
2989
|
-
/** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
|
|
2990
|
-
function attachInvocationObservation(target, context) {
|
|
2991
|
-
const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
|
|
2992
|
-
Object.defineProperty(target, INVOCATION_OBSERVATION, {
|
|
2993
|
-
configurable: false,
|
|
2994
|
-
enumerable: false,
|
|
2995
|
-
value: snapshot,
|
|
2996
|
-
writable: false
|
|
2997
|
-
});
|
|
2998
|
-
return target;
|
|
2999
|
-
}
|
|
3000
|
-
/** @internal Read the snapshot without exposing its symbol or adding a wire field. */
|
|
3001
|
-
function readInvocationObservation(source) {
|
|
3002
|
-
if (typeof source !== "object" || source === null) return void 0;
|
|
3003
|
-
return source[INVOCATION_OBSERVATION];
|
|
3004
|
-
}
|
|
3005
|
-
/** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
|
|
3006
|
-
function copyInvocationObservation(source, target) {
|
|
3007
|
-
const snapshot = readInvocationObservation(source);
|
|
3008
|
-
return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
|
|
3009
|
-
}
|
|
3010
|
-
/** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
|
|
3011
|
-
function markFailureInvocationSnapshot(failure) {
|
|
3012
|
-
Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
|
|
3013
|
-
configurable: false,
|
|
3014
|
-
enumerable: false,
|
|
3015
|
-
value: true,
|
|
3016
|
-
writable: false
|
|
3017
|
-
});
|
|
3018
|
-
return failure;
|
|
3019
|
-
}
|
|
3020
|
-
/** @internal Distinguish public-boundary failures from direct adapter calls. */
|
|
3021
|
-
function hasFailureInvocationSnapshot(failure) {
|
|
3022
|
-
return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
|
|
3023
|
-
}
|
|
3024
|
-
//#endregion
|
|
3025
3058
|
//#region src/adapters/convex-call/ConvexCallAdapter.ts
|
|
3026
3059
|
/** Exact floor-first allowlist; every additional handler must migrate its validator first. */
|
|
3027
|
-
const OBSERVED_CONVEX_ACTIONS = new Set(["subAccount/actions:transfer"]);
|
|
3060
|
+
const OBSERVED_CONVEX_ACTIONS = new Set(["subAccount/actions:transfer", "smartAccount/actions:claim"]);
|
|
3061
|
+
const OBSERVED_CONVEX_MUTATIONS = new Set(["org/lifecycle:startOrResume", "org/lifecycle:retry"]);
|
|
3028
3062
|
var ConvexCallAdapter = class {
|
|
3029
3063
|
#client;
|
|
3030
3064
|
#tokenProvider;
|
|
@@ -3047,20 +3081,21 @@ var ConvexCallAdapter = class {
|
|
|
3047
3081
|
});
|
|
3048
3082
|
}
|
|
3049
3083
|
mutation(fn, args) {
|
|
3084
|
+
const path = getFunctionName(fn);
|
|
3050
3085
|
return Effect.tryPromise({
|
|
3051
|
-
try: () => this.#client.mutation(fn, args),
|
|
3052
|
-
catch: (cause) => mapToConvexCallError(
|
|
3086
|
+
try: () => this.#client.mutation(fn, this.#observedArgs(OBSERVED_CONVEX_MUTATIONS, path, args)),
|
|
3087
|
+
catch: (cause) => mapToConvexCallError(path, cause)
|
|
3053
3088
|
});
|
|
3054
3089
|
}
|
|
3055
3090
|
action(fn, args) {
|
|
3056
3091
|
const path = getFunctionName(fn);
|
|
3057
3092
|
return Effect.tryPromise({
|
|
3058
|
-
try: () => this.#client.action(fn, this.#
|
|
3093
|
+
try: () => this.#client.action(fn, this.#observedArgs(OBSERVED_CONVEX_ACTIONS, path, args)),
|
|
3059
3094
|
catch: (cause) => mapToConvexCallError(path, cause)
|
|
3060
3095
|
});
|
|
3061
3096
|
}
|
|
3062
|
-
#
|
|
3063
|
-
if (!
|
|
3097
|
+
#observedArgs(allowlist, path, args) {
|
|
3098
|
+
if (!allowlist.has(path)) return args;
|
|
3064
3099
|
let hostContext;
|
|
3065
3100
|
const invocationSnapshot = readInvocationObservation(args);
|
|
3066
3101
|
if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.context;
|
|
@@ -3650,6 +3685,8 @@ function brandProfile(raw) {
|
|
|
3650
3685
|
email: toEmail(raw.email),
|
|
3651
3686
|
displayName: raw.displayName,
|
|
3652
3687
|
country: raw.country === null ? null : toCountryCode(raw.country),
|
|
3688
|
+
onboarded: raw.onboarded ?? false,
|
|
3689
|
+
withdrawalAddress: raw.withdrawalAddress === null || raw.withdrawalAddress === void 0 ? null : toAddress(raw.withdrawalAddress),
|
|
3653
3690
|
kycTier: toKycTier(raw.kycTier),
|
|
3654
3691
|
createdAt: toEpochMs(raw.createdAt),
|
|
3655
3692
|
updatedAt: toEpochMs(raw.updatedAt)
|
|
@@ -3909,11 +3946,11 @@ var ConvexSmartAccountAdapter = class {
|
|
|
3909
3946
|
})), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("confirmDeployment", cause))));
|
|
3910
3947
|
}
|
|
3911
3948
|
claim(input) {
|
|
3912
|
-
return this.#convex.action(this.#fns.claim, {
|
|
3949
|
+
return this.#convex.action(this.#fns.claim, copyInvocationObservation(input, {
|
|
3913
3950
|
chainId: wireChainId(input.chainId),
|
|
3914
3951
|
signerAddress: input.signerAddress,
|
|
3915
3952
|
...input.telemetryRunId === void 0 ? {} : { telemetryRunId: input.telemetryRunId }
|
|
3916
|
-
}).pipe(Effect.mapError((error) => smartAccountErrorFromCapxul("claim", error.publicError, error)), Effect.flatMap((row) => Effect.try({
|
|
3953
|
+
})).pipe(Effect.mapError((error) => smartAccountErrorFromCapxul("claim", error.publicError, error)), Effect.flatMap((row) => Effect.try({
|
|
3917
3954
|
try: () => brandProvisionedSmartAccount(input.authUserId, row),
|
|
3918
3955
|
catch: (cause) => smartAccountErrorFromUnknown("claim", cause)
|
|
3919
3956
|
})), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("claim", cause))));
|
|
@@ -4175,14 +4212,19 @@ const DEFAULT_FUNCTIONS$1 = {
|
|
|
4175
4212
|
var ConvexOrganizationSetupAdapter = class {
|
|
4176
4213
|
#convex;
|
|
4177
4214
|
#signer;
|
|
4215
|
+
#chainId;
|
|
4178
4216
|
#fns;
|
|
4179
4217
|
constructor(input) {
|
|
4180
4218
|
this.#convex = input.convex;
|
|
4181
4219
|
this.#signer = input.signer;
|
|
4220
|
+
this.#chainId = input.chainId;
|
|
4182
4221
|
this.#fns = input.functions ?? DEFAULT_FUNCTIONS$1;
|
|
4183
4222
|
}
|
|
4184
4223
|
async startOrResume(input) {
|
|
4185
|
-
const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, input
|
|
4224
|
+
const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, copyInvocationObservation(input, {
|
|
4225
|
+
...input,
|
|
4226
|
+
chainId: this.#chainId
|
|
4227
|
+
})));
|
|
4186
4228
|
if (!result.ok) return result;
|
|
4187
4229
|
const lifecycle = parseLifecycle("startOrResume", result.value.lifecycle);
|
|
4188
4230
|
if (!lifecycle.ok) return lifecycle;
|
|
@@ -4198,17 +4240,17 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4198
4240
|
};
|
|
4199
4241
|
}
|
|
4200
4242
|
prepareFounderAccount(input) {
|
|
4201
|
-
return this.#lifecycleAction("prepareFounderAccount", input, () => this.#convex.action(this.#fns.prepareFounderAccount, { orgId: input.orgId }));
|
|
4243
|
+
return this.#lifecycleAction("prepareFounderAccount", input, () => this.#convex.action(this.#fns.prepareFounderAccount, copyInvocationObservation(input, { orgId: input.orgId })));
|
|
4202
4244
|
}
|
|
4203
4245
|
async authorizeAndSubmitBootstrap(input) {
|
|
4204
4246
|
const cancelled = cancellation(input.signal);
|
|
4205
4247
|
if (cancelled !== void 0) return cancelled;
|
|
4206
4248
|
const signerAddress = await signerResult("getAddress", () => this.#signer.getAddress());
|
|
4207
4249
|
if (!signerAddress.ok) return signerAddress;
|
|
4208
|
-
const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, {
|
|
4250
|
+
const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, copyInvocationObservation(input, {
|
|
4209
4251
|
orgId: input.orgId,
|
|
4210
4252
|
signerAddress: signerAddress.value
|
|
4211
|
-
}));
|
|
4253
|
+
})));
|
|
4212
4254
|
if (!prepared.ok) return prepared;
|
|
4213
4255
|
const authority = validatePreparedAuthorities(prepared.value, signerAddress.value);
|
|
4214
4256
|
if (!authority.ok) return authority;
|
|
@@ -4218,25 +4260,25 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4218
4260
|
if (!signature.ok) return signature;
|
|
4219
4261
|
const cancelledAfterSign = cancellation(input.signal);
|
|
4220
4262
|
if (cancelledAfterSign !== void 0) return cancelledAfterSign;
|
|
4221
|
-
const submitted = await runCall("submitBootstrap", this.#convex.action(this.#fns.submitBootstrap, {
|
|
4263
|
+
const submitted = await runCall("submitBootstrap", this.#convex.action(this.#fns.submitBootstrap, copyInvocationObservation(input, {
|
|
4222
4264
|
orgId: input.orgId,
|
|
4223
4265
|
signerAddress: signerAddress.value,
|
|
4224
4266
|
signature: signature.value,
|
|
4225
4267
|
userOp: prepared.value.userOp
|
|
4226
|
-
}));
|
|
4268
|
+
})));
|
|
4227
4269
|
if (!submitted.ok) return submitted;
|
|
4228
4270
|
return parseLifecycle("submitBootstrap", submitted.value);
|
|
4229
4271
|
}
|
|
4230
4272
|
resumeSubmittedBootstrap(input) {
|
|
4231
|
-
return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, { orgId: input.orgId }));
|
|
4273
|
+
return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, copyInvocationObservation(input, { orgId: input.orgId })));
|
|
4232
4274
|
}
|
|
4233
4275
|
confirmSubmittedBootstrap(input) {
|
|
4234
|
-
return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, { orgId: input.orgId }));
|
|
4276
|
+
return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, copyInvocationObservation(input, { orgId: input.orgId })));
|
|
4235
4277
|
}
|
|
4236
4278
|
async recordFailure(input) {
|
|
4237
4279
|
const errorProvider = input.error.details?.provider;
|
|
4238
4280
|
const errorOperation = input.error.details?.operation;
|
|
4239
|
-
const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, {
|
|
4281
|
+
const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, copyInvocationObservation(input, {
|
|
4240
4282
|
orgId: input.orgId,
|
|
4241
4283
|
errorCode: input.error.code,
|
|
4242
4284
|
...typeof errorProvider === "string" && typeof errorOperation === "string" ? {
|
|
@@ -4244,7 +4286,7 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4244
4286
|
errorOperation
|
|
4245
4287
|
} : {},
|
|
4246
4288
|
retryable: input.retryable
|
|
4247
|
-
}));
|
|
4289
|
+
})));
|
|
4248
4290
|
return result.ok ? parseLifecycle("recordFailure", result.value) : result;
|
|
4249
4291
|
}
|
|
4250
4292
|
async loadLifecycle(input) {
|
|
@@ -4262,7 +4304,7 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
4262
4304
|
const reset = resetSignerSession(this.#signer);
|
|
4263
4305
|
if (!reset.ok) return reset;
|
|
4264
4306
|
}
|
|
4265
|
-
const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, { orgId: input.orgId }));
|
|
4307
|
+
const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, copyInvocationObservation(input, { orgId: input.orgId })));
|
|
4266
4308
|
if (!result.ok) return result;
|
|
4267
4309
|
return parseLifecycle("retry", result.value);
|
|
4268
4310
|
}
|
|
@@ -4447,6 +4489,7 @@ const PayeeIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => PAYEE
|
|
|
4447
4489
|
const DocumentHashSchema = Schema.String.pipe(Schema.filter((value) => BYTES32_RE.test(value), { message: () => "must be 0x + 64 hex chars" }));
|
|
4448
4490
|
const TelemetryEnvelopeProps = {
|
|
4449
4491
|
capxul_e2e_run_id: OptionalString,
|
|
4492
|
+
journeyId: OptionalString,
|
|
4450
4493
|
correlationId: OptionalString,
|
|
4451
4494
|
capxulEnv: OptionalString,
|
|
4452
4495
|
sdkVersion: OptionalString,
|
|
@@ -4578,6 +4621,46 @@ const TransferFailedProps = Schema.Struct({
|
|
|
4578
4621
|
const ORG_ID_TELEMETRY_RE = /^org_[0-9A-Za-z]+$/;
|
|
4579
4622
|
const OrgIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => ORG_ID_TELEMETRY_RE.test(value), { message: () => "must be org_ plus an alphanumeric id" }));
|
|
4580
4623
|
const OptionalOrgId = Schema.optional(OrgIdTelemetrySchema);
|
|
4624
|
+
const AttemptNumberSchema = Schema.Number.pipe(Schema.filter((value) => Number.isSafeInteger(value) && value > 0, { message: () => "must be a positive safe integer" }));
|
|
4625
|
+
const OnboardingStageSchema = Schema.Literal("profile", "accountProvisioning", "accountClaim", "preparingFounderAccount", "awaitingFounderAuthorization", "submittingBootstrap", "confirmingBootstrap");
|
|
4626
|
+
const MemberActivationStartedProps = Schema.Struct({
|
|
4627
|
+
$insert_id: Schema.String,
|
|
4628
|
+
producer: Schema.Literal("server")
|
|
4629
|
+
});
|
|
4630
|
+
const MemberActivationReadyProps = Schema.Struct({
|
|
4631
|
+
$insert_id: Schema.String,
|
|
4632
|
+
duration_ms: DurationMsSchema,
|
|
4633
|
+
producer: Schema.Literal("server")
|
|
4634
|
+
});
|
|
4635
|
+
const MemberActivationFailedProps = Schema.Struct({
|
|
4636
|
+
$insert_id: Schema.String,
|
|
4637
|
+
stage: OnboardingStageSchema,
|
|
4638
|
+
error_code: Schema.String,
|
|
4639
|
+
retryable: Schema.Boolean,
|
|
4640
|
+
producer: Schema.Literal("server")
|
|
4641
|
+
});
|
|
4642
|
+
const OrganizationCreationStartedProps = Schema.Struct({
|
|
4643
|
+
$insert_id: Schema.String,
|
|
4644
|
+
organization_id: OrgIdTelemetrySchema,
|
|
4645
|
+
attempt_number: AttemptNumberSchema,
|
|
4646
|
+
producer: Schema.Literal("server")
|
|
4647
|
+
});
|
|
4648
|
+
const OrganizationCreationReadyProps = Schema.Struct({
|
|
4649
|
+
$insert_id: Schema.String,
|
|
4650
|
+
organization_id: OrgIdTelemetrySchema,
|
|
4651
|
+
attempt_number: AttemptNumberSchema,
|
|
4652
|
+
duration_ms: DurationMsSchema,
|
|
4653
|
+
producer: Schema.Literal("server")
|
|
4654
|
+
});
|
|
4655
|
+
const OrganizationCreationFailedProps = Schema.Struct({
|
|
4656
|
+
$insert_id: Schema.String,
|
|
4657
|
+
organization_id: OrgIdTelemetrySchema,
|
|
4658
|
+
attempt_number: AttemptNumberSchema,
|
|
4659
|
+
stage: OnboardingStageSchema,
|
|
4660
|
+
error_code: Schema.String,
|
|
4661
|
+
retryable: Schema.Boolean,
|
|
4662
|
+
producer: Schema.Literal("server")
|
|
4663
|
+
});
|
|
4581
4664
|
const OrgCreateStartedProps = Schema.Struct({
|
|
4582
4665
|
...TelemetryEnvelopeProps,
|
|
4583
4666
|
org_id: OptionalOrgId,
|
|
@@ -4739,6 +4822,30 @@ Schema.Struct({
|
|
|
4739
4822
|
name: Schema.Literal("bootstrap_failed"),
|
|
4740
4823
|
props: Schema.optional(BootstrapFailedProps)
|
|
4741
4824
|
});
|
|
4825
|
+
Schema.Struct({
|
|
4826
|
+
name: Schema.Literal("member_activation_started"),
|
|
4827
|
+
props: MemberActivationStartedProps
|
|
4828
|
+
});
|
|
4829
|
+
Schema.Struct({
|
|
4830
|
+
name: Schema.Literal("member_activation_ready"),
|
|
4831
|
+
props: MemberActivationReadyProps
|
|
4832
|
+
});
|
|
4833
|
+
Schema.Struct({
|
|
4834
|
+
name: Schema.Literal("member_activation_failed"),
|
|
4835
|
+
props: MemberActivationFailedProps
|
|
4836
|
+
});
|
|
4837
|
+
Schema.Struct({
|
|
4838
|
+
name: Schema.Literal("organization_creation_started"),
|
|
4839
|
+
props: OrganizationCreationStartedProps
|
|
4840
|
+
});
|
|
4841
|
+
Schema.Struct({
|
|
4842
|
+
name: Schema.Literal("organization_creation_ready"),
|
|
4843
|
+
props: OrganizationCreationReadyProps
|
|
4844
|
+
});
|
|
4845
|
+
Schema.Struct({
|
|
4846
|
+
name: Schema.Literal("organization_creation_failed"),
|
|
4847
|
+
props: OrganizationCreationFailedProps
|
|
4848
|
+
});
|
|
4742
4849
|
Schema.Struct({
|
|
4743
4850
|
name: Schema.Literal("account_balance_read"),
|
|
4744
4851
|
props: Schema.optional(AccountBalanceReadProps)
|
|
@@ -5239,6 +5346,18 @@ function transportErrorFromThrown(operation, request, cause) {
|
|
|
5239
5346
|
return transportErrorFromCapxul(operation, request, cause instanceof Error ? Errors.providerError("transport", request.name, cause) : Errors.providerError("transport", request.name, new Error(String(cause))), cause);
|
|
5240
5347
|
}
|
|
5241
5348
|
//#endregion
|
|
5349
|
+
//#region src/adapters/diagnostic/ConsoleDiagnosticAdapter.ts
|
|
5350
|
+
const DEFAULT_ACCOUNT_SETUP_LOG_PREFIX = "[capxul:account-setup]";
|
|
5351
|
+
var ConsoleDiagnosticAdapter = class {
|
|
5352
|
+
prefix;
|
|
5353
|
+
constructor(prefix = DEFAULT_ACCOUNT_SETUP_LOG_PREFIX) {
|
|
5354
|
+
this.prefix = prefix;
|
|
5355
|
+
}
|
|
5356
|
+
trace(scope, detail) {
|
|
5357
|
+
globalThis.console?.debug?.(`${this.prefix} ${scope}`, detail);
|
|
5358
|
+
}
|
|
5359
|
+
};
|
|
5360
|
+
//#endregion
|
|
5242
5361
|
//#region src/openfort/create-openfort-browser-signer.ts
|
|
5243
5362
|
function openfortProviderError(operation, cause) {
|
|
5244
5363
|
return cause instanceof CapxulError ? cause : Errors.providerError("openfort", operation, cause, { failure_mode: "unknown" });
|
|
@@ -6599,10 +6718,6 @@ function makeCurrentUserMethods(deps) {
|
|
|
6599
6718
|
deps.smartAccount.loadCurrent(options),
|
|
6600
6719
|
deps.orgs(options)
|
|
6601
6720
|
]);
|
|
6602
|
-
if (!account.ok) return {
|
|
6603
|
-
ok: false,
|
|
6604
|
-
error: account.error
|
|
6605
|
-
};
|
|
6606
6721
|
if (!smartAccount.ok) return {
|
|
6607
6722
|
ok: false,
|
|
6608
6723
|
error: smartAccount.error
|
|
@@ -6611,6 +6726,10 @@ function makeCurrentUserMethods(deps) {
|
|
|
6611
6726
|
ok: false,
|
|
6612
6727
|
error: organizations.error
|
|
6613
6728
|
};
|
|
6729
|
+
if (!account.ok && account.error.code !== "SMART_ACCOUNT_MISSING") return {
|
|
6730
|
+
ok: false,
|
|
6731
|
+
error: account.error
|
|
6732
|
+
};
|
|
6614
6733
|
return {
|
|
6615
6734
|
ok: true,
|
|
6616
6735
|
value: {
|
|
@@ -6621,10 +6740,10 @@ function makeCurrentUserMethods(deps) {
|
|
|
6621
6740
|
handle: null,
|
|
6622
6741
|
paymentLink: null
|
|
6623
6742
|
},
|
|
6624
|
-
personalAccount: {
|
|
6743
|
+
personalAccount: account.ok ? {
|
|
6625
6744
|
id: account.value.id,
|
|
6626
6745
|
address: smartAccount.value?.smartAccountAddress ?? null
|
|
6627
|
-
},
|
|
6746
|
+
} : null,
|
|
6628
6747
|
organizations: organizations.value.map((organization) => ({
|
|
6629
6748
|
id: organization.id,
|
|
6630
6749
|
name: organization.name,
|
|
@@ -7970,7 +8089,7 @@ function validateOrganizationLifecycleScope(orgId, lifecycle) {
|
|
|
7970
8089
|
};
|
|
7971
8090
|
}
|
|
7972
8091
|
/** Advance only the steps still required by one durable Organization lane. */
|
|
7973
|
-
async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
8092
|
+
async function advanceOrganizationSetup(setup, orgId, initial, signal, observationSource) {
|
|
7974
8093
|
const scopedInitial = validateOrganizationLifecycleScope(orgId, initial);
|
|
7975
8094
|
if (!scopedInitial.ok) return scopedInitial;
|
|
7976
8095
|
let lifecycle = scopedInitial.value;
|
|
@@ -7980,19 +8099,15 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
|
7980
8099
|
value: lifecycle
|
|
7981
8100
|
};
|
|
7982
8101
|
const currentStep = lifecycle.step;
|
|
7983
|
-
if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true);
|
|
7984
|
-
const stepInput = {
|
|
8102
|
+
if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true, observationSource);
|
|
8103
|
+
const stepInput = copyInvocationObservation(observationSource, {
|
|
7985
8104
|
orgId,
|
|
7986
8105
|
...signal === void 0 ? {} : { signal }
|
|
7987
|
-
};
|
|
8106
|
+
});
|
|
7988
8107
|
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);
|
|
7989
|
-
if (!next.ok)
|
|
7990
|
-
if (next.error.code === "CANCELLED") return recordSetupFailure(setup, orgId, next.error, true);
|
|
7991
|
-
if (next.error.code === "PROVIDER_ERROR") return recordSetupFailure(setup, orgId, next.error, isRetryableProviderFailure(next.error));
|
|
7992
|
-
return next;
|
|
7993
|
-
}
|
|
8108
|
+
if (!next.ok) return recordSetupFailure(setup, orgId, next.error, isRetryableOrganizationSetupFailure(next.error), observationSource);
|
|
7994
8109
|
const scopedNext = validateOrganizationLifecycleScope(orgId, next.value);
|
|
7995
|
-
if (!scopedNext.ok) return scopedNext;
|
|
8110
|
+
if (!scopedNext.ok) return recordSetupFailure(setup, orgId, scopedNext.error, false, observationSource);
|
|
7996
8111
|
lifecycle = scopedNext.value;
|
|
7997
8112
|
if (currentStep === "confirmingBootstrap") return {
|
|
7998
8113
|
ok: true,
|
|
@@ -8003,7 +8118,7 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
|
8003
8118
|
ok: true,
|
|
8004
8119
|
value: lifecycle
|
|
8005
8120
|
};
|
|
8006
|
-
return
|
|
8121
|
+
return recordSetupFailure(setup, orgId, Errors.wrongState({
|
|
8007
8122
|
method: "organization.setup",
|
|
8008
8123
|
currentState: lifecycle.step,
|
|
8009
8124
|
validStates: [
|
|
@@ -8011,23 +8126,28 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
|
|
|
8011
8126
|
"ready",
|
|
8012
8127
|
"failed"
|
|
8013
8128
|
]
|
|
8014
|
-
}));
|
|
8129
|
+
}), false, observationSource);
|
|
8015
8130
|
}
|
|
8016
|
-
async function recordSetupFailure(setup, orgId, error, retryable) {
|
|
8017
|
-
const recorded = await setup.recordFailure({
|
|
8131
|
+
async function recordSetupFailure(setup, orgId, error, retryable, observationSource) {
|
|
8132
|
+
const recorded = await setup.recordFailure(copyInvocationObservation(observationSource, {
|
|
8018
8133
|
orgId,
|
|
8019
8134
|
error,
|
|
8020
8135
|
retryable
|
|
8021
|
-
});
|
|
8136
|
+
}));
|
|
8022
8137
|
if (!recorded.ok) return recorded;
|
|
8023
8138
|
const scopedRecorded = validateOrganizationLifecycleScope(orgId, recorded.value);
|
|
8024
8139
|
if (!scopedRecorded.ok) return scopedRecorded;
|
|
8025
|
-
return
|
|
8140
|
+
return scopedRecorded;
|
|
8026
8141
|
}
|
|
8027
8142
|
function isRetryableProviderFailure(error) {
|
|
8028
8143
|
const mode = error.details?.failure_mode;
|
|
8029
8144
|
return mode !== "auth-origin-mismatch" && mode !== "app-env-allowlist" && mode !== "no-secure-context";
|
|
8030
8145
|
}
|
|
8146
|
+
function isRetryableOrganizationSetupFailure(error) {
|
|
8147
|
+
if (error.code === "CANCELLED" || error.code === "SIGNER_REJECTED") return true;
|
|
8148
|
+
if (error.code === "PROVIDER_ERROR") return isRetryableProviderFailure(error);
|
|
8149
|
+
return error.code === "NETWORK_ERROR" || error.code === "UNKNOWN";
|
|
8150
|
+
}
|
|
8031
8151
|
//#endregion
|
|
8032
8152
|
//#region src/client/org.ts
|
|
8033
8153
|
/**
|
|
@@ -8100,12 +8220,12 @@ function makeOrgMethods(deps) {
|
|
|
8100
8220
|
ok: false,
|
|
8101
8221
|
error: Errors.notImplemented("organizationSetup", "retrySetup")
|
|
8102
8222
|
};
|
|
8103
|
-
const retried = await setup.retry({
|
|
8223
|
+
const retried = await setup.retry(copyInvocationObservation(options, {
|
|
8104
8224
|
orgId,
|
|
8105
8225
|
...options?.signal === void 0 ? {} : { signal: options.signal }
|
|
8106
|
-
});
|
|
8226
|
+
}));
|
|
8107
8227
|
if (!retried.ok) return retried;
|
|
8108
|
-
return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal);
|
|
8228
|
+
return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal, options);
|
|
8109
8229
|
},
|
|
8110
8230
|
profile: {
|
|
8111
8231
|
get(_options) {
|
|
@@ -8366,17 +8486,21 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
|
|
|
8366
8486
|
const written = await ops.completeIdentityOnboarding({
|
|
8367
8487
|
authUserId: session.authUserId,
|
|
8368
8488
|
email: session.email,
|
|
8369
|
-
displayName: validated.value.
|
|
8370
|
-
country: validated.value.country
|
|
8489
|
+
displayName: validated.value.profile.displayName,
|
|
8490
|
+
country: validated.value.profile.country,
|
|
8491
|
+
...validated.value.profile.withdrawalAddress === void 0 ? {} : { withdrawalAddress: validated.value.profile.withdrawalAddress }
|
|
8371
8492
|
});
|
|
8372
8493
|
if (!written.ok) return fail(written.error);
|
|
8373
|
-
const
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8494
|
+
const founderAccount = await ops.ensureFounderAccountReady(input);
|
|
8495
|
+
if (!founderAccount.ok) return fail(founderAccount.error);
|
|
8496
|
+
if (options?.signal?.aborted === true) return fail(Errors.cancelled({ operation: "onboarding.completeOrganization" }));
|
|
8497
|
+
const started = await setup.startOrResume(copyInvocationObservation(input, {
|
|
8498
|
+
name: validated.value.organization.name,
|
|
8499
|
+
handle: validated.value.organization.handle,
|
|
8500
|
+
country: validated.value.organization.country
|
|
8501
|
+
}));
|
|
8378
8502
|
if (!started.ok) return fail(started.error);
|
|
8379
|
-
const lifecycle = await advanceOrganizationSetup(setup, started.value.orgId, started.value.lifecycle, options?.signal);
|
|
8503
|
+
const lifecycle = await advanceOrganizationSetup(setup, started.value.orgId, started.value.lifecycle, options?.signal, input);
|
|
8380
8504
|
if (!lifecycle.ok) {
|
|
8381
8505
|
const error = lifecycle.error;
|
|
8382
8506
|
return fail(new CapxulError(error.code, error.message, {
|
|
@@ -8398,9 +8522,36 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
|
|
|
8398
8522
|
};
|
|
8399
8523
|
}
|
|
8400
8524
|
function validatePersonalInput(input) {
|
|
8401
|
-
|
|
8525
|
+
if (!isRecord(input) || !isRecord(input.profile)) return fail(Errors.invalidInput("profile", "must be an object"));
|
|
8526
|
+
return validateProfileInput(input.profile);
|
|
8527
|
+
}
|
|
8528
|
+
function validateOrganizationInput(input) {
|
|
8529
|
+
if (!isRecord(input) || !isRecord(input.profile)) return fail(Errors.invalidInput("profile", "must be an object"));
|
|
8530
|
+
if (!isRecord(input.organization)) return fail(Errors.invalidInput("organization", "must be an object"));
|
|
8531
|
+
const profile = validateProfileInput(input.profile);
|
|
8532
|
+
if (!profile.ok) return profile;
|
|
8533
|
+
const name = requireNonEmpty(input.organization.name, "organization.name");
|
|
8534
|
+
if (!name.ok) return name;
|
|
8535
|
+
const handle = requireNonEmpty(input.organization.handle, "organization.handle");
|
|
8536
|
+
if (!handle.ok) return handle;
|
|
8537
|
+
const country = parseCountry(input.organization.country, "organization.country");
|
|
8538
|
+
if (!country.ok) return country;
|
|
8539
|
+
return {
|
|
8540
|
+
ok: true,
|
|
8541
|
+
value: {
|
|
8542
|
+
profile: profile.value,
|
|
8543
|
+
organization: {
|
|
8544
|
+
name: name.value,
|
|
8545
|
+
handle: handle.value,
|
|
8546
|
+
country: country.value
|
|
8547
|
+
}
|
|
8548
|
+
}
|
|
8549
|
+
};
|
|
8550
|
+
}
|
|
8551
|
+
function validateProfileInput(input) {
|
|
8552
|
+
const displayName = requireNonEmpty(input.displayName, "profile.displayName");
|
|
8402
8553
|
if (!displayName.ok) return displayName;
|
|
8403
|
-
const country = parseCountry(input.country);
|
|
8554
|
+
const country = parseCountry(input.country, "profile.country");
|
|
8404
8555
|
if (!country.ok) return country;
|
|
8405
8556
|
if (input.withdrawalAddress === void 0) return {
|
|
8406
8557
|
ok: true,
|
|
@@ -8409,7 +8560,7 @@ function validatePersonalInput(input) {
|
|
|
8409
8560
|
country: country.value
|
|
8410
8561
|
}
|
|
8411
8562
|
};
|
|
8412
|
-
const withdrawalAddress = parseAddress(input.withdrawalAddress, "withdrawalAddress");
|
|
8563
|
+
const withdrawalAddress = parseAddress(input.withdrawalAddress, "profile.withdrawalAddress");
|
|
8413
8564
|
if (!withdrawalAddress.ok) return withdrawalAddress;
|
|
8414
8565
|
return {
|
|
8415
8566
|
ok: true,
|
|
@@ -8420,25 +8571,6 @@ function validatePersonalInput(input) {
|
|
|
8420
8571
|
}
|
|
8421
8572
|
};
|
|
8422
8573
|
}
|
|
8423
|
-
function validateOrganizationInput(input) {
|
|
8424
|
-
const organizationName = requireNonEmpty(input.organizationName, "organizationName");
|
|
8425
|
-
if (!organizationName.ok) return organizationName;
|
|
8426
|
-
const handle = requireNonEmpty(input.handle, "handle");
|
|
8427
|
-
if (!handle.ok) return handle;
|
|
8428
|
-
const ownerDisplayName = requireNonEmpty(input.ownerDisplayName, "ownerDisplayName");
|
|
8429
|
-
if (!ownerDisplayName.ok) return ownerDisplayName;
|
|
8430
|
-
const country = parseCountry(input.country);
|
|
8431
|
-
if (!country.ok) return country;
|
|
8432
|
-
return {
|
|
8433
|
-
ok: true,
|
|
8434
|
-
value: {
|
|
8435
|
-
organizationName: organizationName.value,
|
|
8436
|
-
handle: handle.value,
|
|
8437
|
-
country: country.value,
|
|
8438
|
-
ownerDisplayName: ownerDisplayName.value
|
|
8439
|
-
}
|
|
8440
|
-
};
|
|
8441
|
-
}
|
|
8442
8574
|
function requireNonEmpty(value, field) {
|
|
8443
8575
|
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
8444
8576
|
if (trimmed.length === 0) return fail(Errors.invalidInput(field, "must be a non-empty string"));
|
|
@@ -8447,14 +8579,14 @@ function requireNonEmpty(value, field) {
|
|
|
8447
8579
|
value: trimmed
|
|
8448
8580
|
};
|
|
8449
8581
|
}
|
|
8450
|
-
function parseCountry(value) {
|
|
8582
|
+
function parseCountry(value, field = "country") {
|
|
8451
8583
|
try {
|
|
8452
8584
|
return {
|
|
8453
8585
|
ok: true,
|
|
8454
8586
|
value: toCountryCode(value)
|
|
8455
8587
|
};
|
|
8456
8588
|
} catch (cause) {
|
|
8457
|
-
return fail(invalidFrom(
|
|
8589
|
+
return fail(invalidFrom(field, cause, "must be an ISO-3166 alpha-2 code"));
|
|
8458
8590
|
}
|
|
8459
8591
|
}
|
|
8460
8592
|
function parseAddress(value, field) {
|
|
@@ -8471,6 +8603,9 @@ function invalidFrom(field, cause, fallback) {
|
|
|
8471
8603
|
const message = cause instanceof Error && cause.message.length > 0 ? cause.message : fallback;
|
|
8472
8604
|
return Errors.invalidInput(field, message);
|
|
8473
8605
|
}
|
|
8606
|
+
function isRecord(value) {
|
|
8607
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8608
|
+
}
|
|
8474
8609
|
function fail(error) {
|
|
8475
8610
|
return {
|
|
8476
8611
|
ok: false,
|
|
@@ -8600,6 +8735,22 @@ function assembleCapxulClient(input) {
|
|
|
8600
8735
|
};
|
|
8601
8736
|
},
|
|
8602
8737
|
completeIdentityOnboarding: (write) => runPortEffect(input.ports.identity.completeOnboarding(write)),
|
|
8738
|
+
ensureFounderAccountReady: async (observationSource) => {
|
|
8739
|
+
const deployed = await account._internal.deploySafe(observationSource);
|
|
8740
|
+
if (!deployed.ok) return deployed;
|
|
8741
|
+
if (deployed.value.deployedAt === null || deployed.value.claimedAt === null) return {
|
|
8742
|
+
ok: false,
|
|
8743
|
+
error: Errors.wrongState({
|
|
8744
|
+
method: "onboarding.completeOrganization",
|
|
8745
|
+
currentState: "founderAccountClaimPending",
|
|
8746
|
+
validStates: ["founderAccountDeployedAndClaimed"]
|
|
8747
|
+
})
|
|
8748
|
+
};
|
|
8749
|
+
return {
|
|
8750
|
+
ok: true,
|
|
8751
|
+
value: void 0
|
|
8752
|
+
};
|
|
8753
|
+
},
|
|
8603
8754
|
triggerProvisioning: () => account._internal.provision(),
|
|
8604
8755
|
kickProvisioning: () => kickProvisioning?.(),
|
|
8605
8756
|
readLifecycle: () => account.getLifecycle(),
|
|
@@ -8762,7 +8913,7 @@ function observeSdkClient(client, adapter) {
|
|
|
8762
8913
|
if (cached !== void 0) return cached;
|
|
8763
8914
|
const wrapped = new Proxy(callable, {
|
|
8764
8915
|
apply(currentTarget, _thisArg, args) {
|
|
8765
|
-
const invocationContext = resolveAdapterContext(adapter);
|
|
8916
|
+
const invocationContext = invocationObservationContext(resolveAdapterContext(adapter));
|
|
8766
8917
|
const invocationArgs = carryInvocationContext(operation, args, invocationContext);
|
|
8767
8918
|
let output;
|
|
8768
8919
|
try {
|
|
@@ -8799,9 +8950,23 @@ function observeSdkClient(client, adapter) {
|
|
|
8799
8950
|
return wrapObject(client, []);
|
|
8800
8951
|
}
|
|
8801
8952
|
function carryInvocationContext(operation, args, context) {
|
|
8802
|
-
if (
|
|
8953
|
+
if (!isPlainObject(args[0])) return args.length === 0 && operation === "org.retrySetup" ? [attachInvocationObservation({}, context)] : args;
|
|
8803
8954
|
return [attachInvocationObservation({ ...args[0] }, context), ...args.slice(1)];
|
|
8804
8955
|
}
|
|
8956
|
+
/** One stable correlation id per public call; the next call is an explicit retry. */
|
|
8957
|
+
function invocationObservationContext(context) {
|
|
8958
|
+
return {
|
|
8959
|
+
...context,
|
|
8960
|
+
correlationId: createInvocationCorrelationId()
|
|
8961
|
+
};
|
|
8962
|
+
}
|
|
8963
|
+
function createInvocationCorrelationId() {
|
|
8964
|
+
if (typeof globalThis.crypto?.randomUUID === "function") return `sdk_${globalThis.crypto.randomUUID()}`;
|
|
8965
|
+
const bytes = new Uint8Array(16);
|
|
8966
|
+
if (typeof globalThis.crypto?.getRandomValues === "function") globalThis.crypto.getRandomValues(bytes);
|
|
8967
|
+
else for (let index = 0; index < bytes.length; index += 1) bytes[index] = Math.floor(Math.random() * 256);
|
|
8968
|
+
return `sdk_${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
8969
|
+
}
|
|
8805
8970
|
/** @internal Reports a factory-level typed failure without changing its identity. */
|
|
8806
8971
|
function observeFailedResult(result, adapter, operation) {
|
|
8807
8972
|
if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error, resolveAdapterContext(adapter));
|
|
@@ -8838,24 +9003,35 @@ function ignoreDeliveryFailure(delivery) {
|
|
|
8838
9003
|
Promise.resolve(delivery).catch(() => void 0);
|
|
8839
9004
|
} catch {}
|
|
8840
9005
|
}
|
|
9006
|
+
/**
|
|
9007
|
+
* Map an ALREADY-sanitized observation context to the snake_case PostHog
|
|
9008
|
+
* property keys. Shared by the failure boundary here and the host
|
|
9009
|
+
* success-telemetry seam (`telemetry/from-posthog.ts`) so both attach identical
|
|
9010
|
+
* correlation fields from one definition.
|
|
9011
|
+
*/
|
|
9012
|
+
function observationContextProps(context) {
|
|
9013
|
+
const props = {};
|
|
9014
|
+
if (context?.application !== void 0) props.application = context.application;
|
|
9015
|
+
if (context?.release !== void 0) props.release = context.release;
|
|
9016
|
+
if (context?.sessionId !== void 0) props.session_id = context.sessionId;
|
|
9017
|
+
if (context?.organizationId !== void 0) props.organization_id = context.organizationId;
|
|
9018
|
+
if (context?.journeyId !== void 0) props.journey_id = context.journeyId;
|
|
9019
|
+
if (context?.correlationId !== void 0) props.correlation_id = context.correlationId;
|
|
9020
|
+
if (context?.anonymousId !== void 0) props.anonymous_id = context.anonymousId;
|
|
9021
|
+
return props;
|
|
9022
|
+
}
|
|
8841
9023
|
function postHogProperties(failure, context) {
|
|
8842
|
-
const properties = {
|
|
8843
|
-
sdk_version: failure.sdkVersion,
|
|
8844
|
-
operation: failure.operation,
|
|
8845
|
-
error_kind: failure.errorKind,
|
|
8846
|
-
handled: true
|
|
8847
|
-
};
|
|
8848
9024
|
const merged = sanitizeObservationContext({
|
|
8849
9025
|
...context,
|
|
8850
9026
|
...failure.context
|
|
8851
9027
|
});
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
9028
|
+
return {
|
|
9029
|
+
sdk_version: failure.sdkVersion,
|
|
9030
|
+
operation: failure.operation,
|
|
9031
|
+
error_kind: failure.errorKind,
|
|
9032
|
+
handled: true,
|
|
9033
|
+
...observationContextProps(merged)
|
|
9034
|
+
};
|
|
8859
9035
|
}
|
|
8860
9036
|
function resolveContext(context) {
|
|
8861
9037
|
return sanitizeObservationContext(resolveRawContext(context));
|
|
@@ -8906,7 +9082,7 @@ function normalizeErrorKind(value) {
|
|
|
8906
9082
|
return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u.test(value) ? value : "Error";
|
|
8907
9083
|
}
|
|
8908
9084
|
function syntheticException(operation, kind) {
|
|
8909
|
-
const error = /* @__PURE__ */ new Error(
|
|
9085
|
+
const error = /* @__PURE__ */ new Error(EXCEPTION_MESSAGE);
|
|
8910
9086
|
error.name = kind;
|
|
8911
9087
|
error.stack = `${kind}: ${error.message}\n at CapxulSdkBoundary.${operation} (capxul-sdk-observation://boundary/${operation}:1:1)`;
|
|
8912
9088
|
return error;
|
|
@@ -9252,6 +9428,9 @@ async function createCapxulClient$1(input) {
|
|
|
9252
9428
|
if (signer === void 0 && runtime === "browser") signer = createOpenfortBrowserSignerFromBootstrap({
|
|
9253
9429
|
...adapters.value.bootstrap,
|
|
9254
9430
|
authBaseUrl: resolvedAuthBaseUrl
|
|
9431
|
+
}, {
|
|
9432
|
+
diagnostic: new ConsoleDiagnosticAdapter(),
|
|
9433
|
+
telemetry: adapters.value.ports.telemetry
|
|
9255
9434
|
});
|
|
9256
9435
|
const client = wireOpenfortSignerLifecycle(assembleCapxulClient({
|
|
9257
9436
|
ports: adapters.value.ports,
|
|
@@ -9262,7 +9441,8 @@ async function createCapxulClient$1(input) {
|
|
|
9262
9441
|
orgPort: new ConvexOrganizationAdapter({ convex: adapters.value.ports.convexCall }),
|
|
9263
9442
|
...signer === void 0 ? {} : { organizationSetup: new ConvexOrganizationSetupAdapter({
|
|
9264
9443
|
convex: adapters.value.ports.convexCall,
|
|
9265
|
-
signer
|
|
9444
|
+
signer,
|
|
9445
|
+
chainId: adapters.value.bootstrap.chainId
|
|
9266
9446
|
}) },
|
|
9267
9447
|
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
9268
9448
|
...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
|
|
@@ -9466,6 +9646,73 @@ async function createCapxulClient(input) {
|
|
|
9466
9646
|
return createCapxulClient$1(input);
|
|
9467
9647
|
}
|
|
9468
9648
|
//#endregion
|
|
9469
|
-
|
|
9649
|
+
//#region src/telemetry/from-posthog.ts
|
|
9650
|
+
/**
|
|
9651
|
+
* Drop props that must never cross to a host-owned external sink. Today that is
|
|
9652
|
+
* the `$exception` `details` blob: `captureException` serializes
|
|
9653
|
+
* `CapxulError.details` (e.g. `{ asset, available, required }`, `{ name }`,
|
|
9654
|
+
* `{ accountId }` — errors.ts) into it, and the shared redactor has no
|
|
9655
|
+
* `$exception` rule, so it is stripped here at the boundary (infra#1037). The
|
|
9656
|
+
* safe fields (error code, operation, failure_mode, the fixed leak-safe message,
|
|
9657
|
+
* stack frames) are preserved.
|
|
9658
|
+
*/
|
|
9659
|
+
function stripHostUnsafeProps(props) {
|
|
9660
|
+
if (props === void 0) return void 0;
|
|
9661
|
+
const { details: _details, ...safe } = props;
|
|
9662
|
+
return safe;
|
|
9663
|
+
}
|
|
9664
|
+
/**
|
|
9665
|
+
* Adapt the host's already-initialized posthog-like client into a
|
|
9666
|
+
* `TelemetryPort` for the `telemetry` prop / input. This port SUPPLANTS the
|
|
9667
|
+
* SDK's no-op default telemetry sink (`production.ts` binds it via
|
|
9668
|
+
* `Layer.succeed`, not `compose` — there is no client-side success relay to
|
|
9669
|
+
* compose with); it is additive to Capxul's backend first-party record and
|
|
9670
|
+
* never owns the client.
|
|
9671
|
+
*/
|
|
9672
|
+
function telemetryFromPostHog(client, options = {}) {
|
|
9673
|
+
const active = () => {
|
|
9674
|
+
if (client === null || client === void 0) return false;
|
|
9675
|
+
try {
|
|
9676
|
+
return typeof options.enabled === "function" ? options.enabled() : options.enabled ?? true;
|
|
9677
|
+
} catch {
|
|
9678
|
+
return false;
|
|
9679
|
+
}
|
|
9680
|
+
};
|
|
9681
|
+
const contextProps = () => {
|
|
9682
|
+
let raw;
|
|
9683
|
+
try {
|
|
9684
|
+
raw = typeof options.context === "function" ? options.context() : options.context;
|
|
9685
|
+
} catch {
|
|
9686
|
+
return {};
|
|
9687
|
+
}
|
|
9688
|
+
return observationContextProps(sanitizeObservationContext(raw));
|
|
9689
|
+
};
|
|
9690
|
+
return new PostHogTelemetryAdapter({
|
|
9691
|
+
capture: (name, props) => {
|
|
9692
|
+
if (!active() || client === null || client === void 0) return;
|
|
9693
|
+
client.capture(name, {
|
|
9694
|
+
...stripHostUnsafeProps(props),
|
|
9695
|
+
...contextProps()
|
|
9696
|
+
});
|
|
9697
|
+
},
|
|
9698
|
+
identify: (input) => {
|
|
9699
|
+
if (!active() || client?.identify === void 0) return;
|
|
9700
|
+
client.identify(input.distinctId, {
|
|
9701
|
+
...input.traits,
|
|
9702
|
+
...input.properties
|
|
9703
|
+
});
|
|
9704
|
+
},
|
|
9705
|
+
group: (input) => {
|
|
9706
|
+
if (!active() || client?.group === void 0) return;
|
|
9707
|
+
client.group(input.groupType, input.groupKey, input.properties === void 0 ? void 0 : { ...input.properties });
|
|
9708
|
+
},
|
|
9709
|
+
reset: () => {
|
|
9710
|
+
if (!active() || client?.reset === void 0) return;
|
|
9711
|
+
client.reset();
|
|
9712
|
+
}
|
|
9713
|
+
});
|
|
9714
|
+
}
|
|
9715
|
+
//#endregion
|
|
9716
|
+
export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort, telemetryFromPostHog, toCountryCode, toAddress as toEvmAddress };
|
|
9470
9717
|
|
|
9471
9718
|
//# sourceMappingURL=index.mjs.map
|