@capxul/observability 1.1.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.mjs ADDED
@@ -0,0 +1,1514 @@
1
+ import { Effect, Schema, SchemaGetter } from "effect";
2
+ new Set([
3
+ "NOT_AUTHENTICATED",
4
+ "EMAIL_DELIVERY_FAILED",
5
+ "PROFILE_NOT_FOUND",
6
+ "SMART_ACCOUNT_MISSING",
7
+ "PLAYER_NOT_FOUND",
8
+ "ACCOUNT_NOT_FOUND",
9
+ "PROVIDER_ERROR",
10
+ "INVALID_INPUT",
11
+ "ENV_MISSING",
12
+ "NOT_IMPLEMENTED",
13
+ "VERIFICATION_REQUIRED",
14
+ "INSUFFICIENT_BALANCE",
15
+ "INVALID_RECIPIENT",
16
+ "ROLE_PERMISSION_DENIED",
17
+ "TRANSACTION_FAILED",
18
+ "RATE_LIMITED",
19
+ "NETWORK_ERROR",
20
+ "UNKNOWN",
21
+ "OTP_EXPIRED",
22
+ "SIGNER_REJECTED",
23
+ "CANCELLED",
24
+ "WRONG_STATE",
25
+ "STALE_EPOCH",
26
+ "SUPERSEDED",
27
+ "WORK_DIED",
28
+ "ACTOR_STOPPED"
29
+ ]);
30
+ //#endregion
31
+ //#region ../types/src/index.ts
32
+ const EVM_ADDRESS_RE = /^0x[0-9a-f]{40}$/i;
33
+ const BYTES32_RE = /^0x[0-9a-f]{64}$/i;
34
+ const SUPPORTED_CURRENCIES = [
35
+ {
36
+ code: "USD",
37
+ symbol: "$",
38
+ name: "US Dollar"
39
+ },
40
+ {
41
+ code: "NGN",
42
+ symbol: "NGN",
43
+ name: "Nigerian Naira"
44
+ },
45
+ {
46
+ code: "GHS",
47
+ symbol: "GHS",
48
+ name: "Ghanaian Cedi"
49
+ },
50
+ {
51
+ code: "KES",
52
+ symbol: "KSh",
53
+ name: "Kenyan Shilling"
54
+ },
55
+ {
56
+ code: "UGX",
57
+ symbol: "USh",
58
+ name: "Ugandan Shilling"
59
+ }
60
+ ];
61
+ SUPPORTED_CURRENCIES.map((currency) => currency.code);
62
+ Object.fromEntries(SUPPORTED_CURRENCIES.map((currency) => [currency.code, currency.symbol]));
63
+ const APP_ID_RE = /^app_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
64
+ Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
65
+ //#endregion
66
+ //#region src/index.ts
67
+ const TELEMETRY_EVENT_NAMES = [
68
+ "auth_otp_requested",
69
+ "auth_otp_delivered",
70
+ "auth_otp_expired",
71
+ "auth_verified",
72
+ "auth_failed",
73
+ "auth_signed_out",
74
+ "provisioning_safe_created",
75
+ "provisioning_safe_confirmed",
76
+ "bootstrap_resolved",
77
+ "bootstrap_failed",
78
+ "member_activation_started",
79
+ "member_activation_ready",
80
+ "member_activation_failed",
81
+ "organization_creation_started",
82
+ "organization_creation_ready",
83
+ "organization_creation_failed",
84
+ "account_balance_read",
85
+ "account_balance_failed",
86
+ "faucet_requested",
87
+ "faucet_confirmed",
88
+ "faucet_failed",
89
+ "subaccount_created",
90
+ "subaccount_renamed",
91
+ "subaccount_deleted",
92
+ "subaccount_op_failed",
93
+ "transfer_requested",
94
+ "transfer_backend_received",
95
+ "transfer_confirmed",
96
+ "transfer_failed",
97
+ "org_create_started",
98
+ "org_safe_created",
99
+ "org_safe_confirmed",
100
+ "org_roles_seeded",
101
+ "org_created",
102
+ "org_create_failed",
103
+ "org_invite_sent",
104
+ "org_invite_accepted",
105
+ "org_role_granted",
106
+ "org_member_active",
107
+ "org_member_removed",
108
+ "org_invite_expired",
109
+ "org_role_grant_failed",
110
+ "payment_requested",
111
+ "payment_resolved",
112
+ "payment_document_attached",
113
+ "payment_submitted",
114
+ "payment_settled",
115
+ "payment_claimed",
116
+ "payment_cancelled",
117
+ "payment_redirected",
118
+ "payment_failed",
119
+ "stream_created",
120
+ "stream_claimed",
121
+ "stream_cancelled",
122
+ "stream_completed",
123
+ "stream_failed",
124
+ "withdrawal_requested",
125
+ "withdrawal_submitted",
126
+ "withdrawal_settled",
127
+ "withdrawal_failed"
128
+ ];
129
+ const TELEMETRY_JOURNEYS = {
130
+ returning_user_login: {
131
+ type: "funnel",
132
+ steps: [
133
+ "auth_otp_requested",
134
+ "auth_otp_delivered",
135
+ "auth_verified"
136
+ ],
137
+ drops_on: ["auth_otp_expired", "auth_failed"]
138
+ },
139
+ new_user_first_signin: {
140
+ type: "funnel",
141
+ steps: [
142
+ "auth_otp_requested",
143
+ "auth_otp_delivered",
144
+ "auth_verified",
145
+ "provisioning_safe_created",
146
+ "provisioning_safe_confirmed"
147
+ ],
148
+ drops_on: ["auth_otp_expired", "auth_failed"]
149
+ },
150
+ sign_out_session_close: {
151
+ type: "point_event",
152
+ point_event: "auth_signed_out"
153
+ },
154
+ member_activation: {
155
+ type: "funnel",
156
+ steps: ["member_activation_started", "member_activation_ready"],
157
+ drops_on: ["member_activation_failed"]
158
+ },
159
+ organization_creation_lifecycle: {
160
+ type: "funnel",
161
+ steps: ["organization_creation_started", "organization_creation_ready"],
162
+ drops_on: ["organization_creation_failed"]
163
+ },
164
+ money_on_screen: {
165
+ type: "point_event",
166
+ point_event: "account_balance_read"
167
+ },
168
+ fund_account: {
169
+ type: "funnel",
170
+ steps: ["faucet_requested", "faucet_confirmed"],
171
+ drops_on: ["faucet_failed"]
172
+ },
173
+ first_value_movement: {
174
+ type: "funnel",
175
+ steps: [
176
+ "account_balance_read",
177
+ "transfer_requested",
178
+ "transfer_confirmed"
179
+ ],
180
+ drops_on: ["transfer_failed"]
181
+ },
182
+ subaccount_lifecycle: {
183
+ type: "point_event",
184
+ point_event: "subaccount_created"
185
+ },
186
+ org_creation: {
187
+ type: "funnel",
188
+ steps: [
189
+ "org_create_started",
190
+ "org_safe_created",
191
+ "org_safe_confirmed",
192
+ "org_roles_seeded",
193
+ "org_created"
194
+ ],
195
+ drops_on: ["org_create_failed"]
196
+ },
197
+ org_member_onboarding: {
198
+ type: "funnel",
199
+ steps: [
200
+ "org_invite_sent",
201
+ "org_invite_accepted",
202
+ "org_role_granted",
203
+ "org_member_active"
204
+ ],
205
+ drops_on: ["org_invite_expired", "org_role_grant_failed"]
206
+ },
207
+ direct_payment: {
208
+ type: "funnel",
209
+ steps: [
210
+ "payment_requested",
211
+ "payment_resolved",
212
+ "payment_document_attached",
213
+ "payment_submitted",
214
+ "payment_settled"
215
+ ],
216
+ drops_on: ["payment_failed"]
217
+ },
218
+ commitment_claim: {
219
+ type: "funnel",
220
+ steps: ["payment_submitted", "payment_claimed"],
221
+ drops_on: ["payment_cancelled"]
222
+ },
223
+ commitment_redirect: {
224
+ type: "point_event",
225
+ point_event: "payment_redirected"
226
+ },
227
+ salary_stream: {
228
+ type: "funnel",
229
+ steps: [
230
+ "stream_created",
231
+ "stream_claimed",
232
+ "stream_completed"
233
+ ],
234
+ drops_on: ["stream_cancelled", "stream_failed"]
235
+ },
236
+ cash_out: {
237
+ type: "funnel",
238
+ steps: [
239
+ "withdrawal_requested",
240
+ "withdrawal_submitted",
241
+ "withdrawal_settled"
242
+ ],
243
+ drops_on: ["withdrawal_failed"]
244
+ }
245
+ };
246
+ const PII = Schema.String.pipe(Schema.brand("PII"));
247
+ const OptionalString = Schema.optional(Schema.String);
248
+ const AddressSchema = Schema.String.pipe(Schema.decodeTo(Schema.String, {
249
+ decode: SchemaGetter.transform((value) => value.toLowerCase()),
250
+ encode: SchemaGetter.transform((value) => value)
251
+ }), Schema.refine((value) => EVM_ADDRESS_RE.test(value), { message: "must be 0x + 40 hex chars" }));
252
+ const AppIdSchema = Schema.String.pipe(Schema.refine((value) => APP_ID_RE.test(value), { message: "must be app_ plus a ULID" }));
253
+ const BlockNumberSchema = Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value >= 0, { message: "must be a non-negative safe integer" }));
254
+ const ChainIdSchema = Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value > 0, { message: "must be a positive safe integer" }));
255
+ const DurationMsSchema = Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value >= 0, { message: "must be a non-negative safe integer" }));
256
+ const EpochMsSchema = Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value >= 0, { message: "must be a non-negative safe integer" }));
257
+ const PublishableKeyIdSchema = Schema.String.pipe(Schema.refine((value) => value.length > 0, { message: "must be a non-empty string" }));
258
+ const TxHashSchema = Schema.String.pipe(Schema.refine((value) => BYTES32_RE.test(value), { message: "must be 0x + 64 hex chars" }));
259
+ const ACCOUNT_ID_TELEMETRY_RE = /^account_[0-9A-Za-z]+$/;
260
+ const SUBACCOUNT_ID_TELEMETRY_RE = /^subaccount_[0-9A-Za-z]+$/;
261
+ const WEI_AMOUNT_TELEMETRY_RE = /^[0-9]+$/;
262
+ const AccountIdSchema = Schema.String.pipe(Schema.refine((value) => ACCOUNT_ID_TELEMETRY_RE.test(value), { message: "must be account_ plus an alphanumeric id" }));
263
+ const SubAccountIdSchema = Schema.String.pipe(Schema.refine((value) => SUBACCOUNT_ID_TELEMETRY_RE.test(value), { message: "must be subaccount_ plus an alphanumeric id" }));
264
+ const WeiAmountSchema = Schema.String.pipe(Schema.refine((value) => WEI_AMOUNT_TELEMETRY_RE.test(value), { message: "must be a non-negative integer string" }));
265
+ const CurrencyCodeSchema = Schema.String.pipe(Schema.refine((value) => value.length > 0, { message: "must be a non-empty currency code" }));
266
+ const BalanceBucketSchema = Schema.Literals(["zero", "nonzero"]);
267
+ const TransferDirectionSchema = Schema.Literals([
268
+ "add",
269
+ "out",
270
+ "between"
271
+ ]);
272
+ const SubAccountOpSchema = Schema.Literals([
273
+ "create",
274
+ "rename",
275
+ "delete"
276
+ ]);
277
+ const OptionalAccountId = Schema.optional(AccountIdSchema);
278
+ const OptionalSubAccountId = Schema.optional(SubAccountIdSchema);
279
+ const OptionalWeiAmount = Schema.optional(WeiAmountSchema);
280
+ const OptionalCurrencyCode = Schema.optional(CurrencyCodeSchema);
281
+ const OptionalBalanceBucket = Schema.optional(BalanceBucketSchema);
282
+ const OptionalTransferDirection = Schema.optional(TransferDirectionSchema);
283
+ const OptionalSubAccountOp = Schema.optional(SubAccountOpSchema);
284
+ const OptionalTrue = Schema.optional(Schema.Literal(true));
285
+ const OptionalAddress = Schema.optional(AddressSchema);
286
+ const OptionalAppId = Schema.optional(AppIdSchema);
287
+ const OptionalBlockNumber = Schema.optional(BlockNumberSchema);
288
+ const OptionalChainId = Schema.optional(ChainIdSchema);
289
+ const OptionalDurationMs = Schema.optional(DurationMsSchema);
290
+ const OptionalEpochMs = Schema.optional(EpochMsSchema);
291
+ const OptionalPublishableKeyId = Schema.optional(PublishableKeyIdSchema);
292
+ const OptionalTxHash = Schema.optional(TxHashSchema);
293
+ const PAYMENT_ID_TELEMETRY_RE = /^payment_[0-9A-Za-z]+$/;
294
+ const PAYEE_ID_TELEMETRY_RE = /^payee_[0-9A-Za-z]+$/;
295
+ const PaymentIdTelemetrySchema = Schema.String.pipe(Schema.refine((value) => PAYMENT_ID_TELEMETRY_RE.test(value), { message: "must be payment_ plus an alphanumeric id" }));
296
+ const PayeeIdTelemetrySchema = Schema.String.pipe(Schema.refine((value) => PAYEE_ID_TELEMETRY_RE.test(value), { message: "must be payee_ plus an alphanumeric id" }));
297
+ const DocumentHashSchema = Schema.String.pipe(Schema.refine((value) => BYTES32_RE.test(value), { message: "must be 0x + 64 hex chars" }));
298
+ /**
299
+ * Environment discriminator (ADR-0020 A1 amendment, 2026-08-07). PostHog
300
+ * project 368736 is the SINGLE sink for every environment, so `capxul_env` —
301
+ * not project isolation — is what keeps a production surface from reading dev
302
+ * traffic. It is REQUIRED on every catalog event and every synced artifact
303
+ * filters on it.
304
+ *
305
+ * `unknown` is a defect marker, not an environment: it means a producer
306
+ * reached the transport without declaring where it runs. It is in the union so
307
+ * the property is never ABSENT (an absent property is invisible to a filter,
308
+ * a present `unknown` is loud), and sync v2 never synthesizes an artifact for
309
+ * it.
310
+ */
311
+ const CAPXUL_ENVS = [
312
+ "development",
313
+ "e2e",
314
+ "staging",
315
+ "production",
316
+ "unknown"
317
+ ];
318
+ /** Environments a synced product surface may be built for (`unknown` cannot). */
319
+ const SYNCABLE_CAPXUL_ENVS = [
320
+ "development",
321
+ "e2e",
322
+ "staging",
323
+ "production"
324
+ ];
325
+ /**
326
+ * Which half of the system emitted the event. REQUIRED alongside `capxul_env`
327
+ * so a name that two halves can produce (settlement, auth) stays attributable.
328
+ */
329
+ const TELEMETRY_PRODUCERS = [
330
+ "server",
331
+ "browser",
332
+ "sdk",
333
+ "mcp",
334
+ "e2e"
335
+ ];
336
+ /**
337
+ * The canonical envelope (ADR-0020 A4): snake_case ONLY. `capxul_env` and
338
+ * `producer` are REQUIRED — a boundary that forgets to stamp them fails schema
339
+ * decode instead of silently shipping an unattributable event. Call sites do
340
+ * not pass them: `stampTelemetryEnvelope` injects them at the emit boundary,
341
+ * which is the only place that knows where the process runs.
342
+ */
343
+ const TelemetryEnvelopeProps = {
344
+ capxul_env: Schema.Literals(CAPXUL_ENVS),
345
+ producer: Schema.Literals(TELEMETRY_PRODUCERS),
346
+ capxul_e2e_run_id: OptionalString,
347
+ journey_id: OptionalString,
348
+ correlation_id: OptionalString,
349
+ sdk_version: OptionalString
350
+ };
351
+ /**
352
+ * Stamp the required envelope onto an event at its emit boundary. Call-site
353
+ * props win on conflict: a relay that already knows the true producer (the
354
+ * browser-failure relay stamps `browser` while running on the server) must not
355
+ * be overwritten by the transport's own default.
356
+ */
357
+ function stampTelemetryEnvelope(event, defaults) {
358
+ return {
359
+ name: event.name,
360
+ props: {
361
+ ...defaults,
362
+ ...event.props
363
+ }
364
+ };
365
+ }
366
+ const AuthOtpRequestedProps = Schema.Struct({
367
+ ...TelemetryEnvelopeProps,
368
+ email: Schema.optional(PII),
369
+ email_domain: OptionalString
370
+ });
371
+ const AuthOtpDeliveredProps = Schema.Struct({
372
+ ...TelemetryEnvelopeProps,
373
+ durationMs: OptionalDurationMs,
374
+ email: Schema.optional(PII),
375
+ email_domain: OptionalString,
376
+ resendMessageId: OptionalString
377
+ });
378
+ const AuthOtpExpiredProps = Schema.Struct({
379
+ ...TelemetryEnvelopeProps,
380
+ email: Schema.optional(PII),
381
+ email_domain: OptionalString
382
+ });
383
+ const AuthVerifiedProps = Schema.Struct({
384
+ ...TelemetryEnvelopeProps,
385
+ auth_type: OptionalString
386
+ });
387
+ const AuthFailedProps = Schema.Struct({
388
+ ...TelemetryEnvelopeProps,
389
+ email: Schema.optional(PII),
390
+ auth_type: OptionalString,
391
+ reason: OptionalString
392
+ });
393
+ const AuthSignedOutProps = Schema.Struct(TelemetryEnvelopeProps);
394
+ const ProvisioningSafeCreatedProps = Schema.Struct({
395
+ ...TelemetryEnvelopeProps,
396
+ safe_address: OptionalAddress
397
+ });
398
+ const ProvisioningSafeConfirmedProps = Schema.Struct({
399
+ ...TelemetryEnvelopeProps,
400
+ chainId: OptionalChainId,
401
+ deployedAt: OptionalEpochMs,
402
+ deployedAtBlock: OptionalBlockNumber,
403
+ deployTxHash: OptionalTxHash,
404
+ durationMs: OptionalDurationMs,
405
+ safe_address: OptionalAddress,
406
+ userOpHash: OptionalTxHash
407
+ });
408
+ const BootstrapResolvedProps = Schema.Struct({
409
+ ...TelemetryEnvelopeProps,
410
+ applicationId: OptionalAppId,
411
+ durationMs: OptionalDurationMs,
412
+ env: OptionalString,
413
+ keyId: OptionalPublishableKeyId,
414
+ origin: OptionalString
415
+ });
416
+ const BootstrapFailedProps = Schema.Struct({
417
+ ...TelemetryEnvelopeProps,
418
+ applicationId: OptionalAppId,
419
+ durationMs: OptionalDurationMs,
420
+ origin: OptionalString,
421
+ reason: OptionalString
422
+ });
423
+ const AccountBalanceReadProps = Schema.Struct({
424
+ ...TelemetryEnvelopeProps,
425
+ account_id: OptionalAccountId,
426
+ currency: OptionalCurrencyCode,
427
+ balance_bucket: OptionalBalanceBucket,
428
+ durationMs: OptionalDurationMs
429
+ });
430
+ const AccountBalanceFailedProps = Schema.Struct({
431
+ ...TelemetryEnvelopeProps,
432
+ reason: OptionalString
433
+ });
434
+ const FaucetRequestedProps = Schema.Struct({
435
+ ...TelemetryEnvelopeProps,
436
+ amount: OptionalWeiAmount,
437
+ chainId: OptionalChainId
438
+ });
439
+ const FaucetConfirmedProps = Schema.Struct({
440
+ ...TelemetryEnvelopeProps,
441
+ amount: OptionalWeiAmount,
442
+ chainId: OptionalChainId,
443
+ txHash: OptionalTxHash,
444
+ durationMs: OptionalDurationMs
445
+ });
446
+ const FaucetFailedProps = Schema.Struct({
447
+ ...TelemetryEnvelopeProps,
448
+ reason: OptionalString
449
+ });
450
+ const SubaccountCreatedProps = Schema.Struct({
451
+ ...TelemetryEnvelopeProps,
452
+ sub_account_id: OptionalSubAccountId,
453
+ durationMs: OptionalDurationMs
454
+ });
455
+ const SubaccountRenamedProps = Schema.Struct({
456
+ ...TelemetryEnvelopeProps,
457
+ sub_account_id: OptionalSubAccountId
458
+ });
459
+ const SubaccountDeletedProps = Schema.Struct({
460
+ ...TelemetryEnvelopeProps,
461
+ sub_account_id: OptionalSubAccountId
462
+ });
463
+ const SubaccountOpFailedProps = Schema.Struct({
464
+ ...TelemetryEnvelopeProps,
465
+ op: OptionalSubAccountOp,
466
+ reason: OptionalString
467
+ });
468
+ const TransferRequestedProps = Schema.Struct({
469
+ ...TelemetryEnvelopeProps,
470
+ amount: OptionalWeiAmount,
471
+ direction: OptionalTransferDirection
472
+ });
473
+ const TransferBackendReceivedProps = Schema.Struct({
474
+ ...TelemetryEnvelopeProps,
475
+ direction: OptionalTransferDirection
476
+ });
477
+ const TransferConfirmedProps = Schema.Struct({
478
+ ...TelemetryEnvelopeProps,
479
+ amount: OptionalWeiAmount,
480
+ direction: OptionalTransferDirection,
481
+ available_bucket: OptionalBalanceBucket,
482
+ txless: OptionalTrue,
483
+ durationMs: OptionalDurationMs
484
+ });
485
+ const TransferFailedProps = Schema.Struct({
486
+ ...TelemetryEnvelopeProps,
487
+ reason: OptionalString
488
+ });
489
+ const ORG_ID_TELEMETRY_RE = /^org_[0-9A-Za-z]+$/;
490
+ const OrgIdTelemetrySchema = Schema.String.pipe(Schema.refine((value) => ORG_ID_TELEMETRY_RE.test(value), { message: "must be org_ plus an alphanumeric id" }));
491
+ const OptionalOrgId = Schema.optional(OrgIdTelemetrySchema);
492
+ const AttemptNumberSchema = Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value > 0, { message: "must be a positive safe integer" }));
493
+ const OnboardingStageSchema = Schema.Literals([
494
+ "profile",
495
+ "accountProvisioning",
496
+ "accountClaim",
497
+ "preparingFounderAccount",
498
+ "awaitingFounderAuthorization",
499
+ "submittingBootstrap",
500
+ "confirmingBootstrap"
501
+ ]);
502
+ const MemberActivationStartedProps = Schema.Struct({
503
+ ...TelemetryEnvelopeProps,
504
+ $insert_id: Schema.String
505
+ });
506
+ const MemberActivationReadyProps = Schema.Struct({
507
+ ...TelemetryEnvelopeProps,
508
+ $insert_id: Schema.String,
509
+ duration_ms: DurationMsSchema
510
+ });
511
+ const MemberActivationFailedProps = Schema.Struct({
512
+ ...TelemetryEnvelopeProps,
513
+ $insert_id: Schema.String,
514
+ stage: OnboardingStageSchema,
515
+ error_code: Schema.String,
516
+ retryable: Schema.Boolean
517
+ });
518
+ const OrganizationCreationStartedProps = Schema.Struct({
519
+ ...TelemetryEnvelopeProps,
520
+ $insert_id: Schema.String,
521
+ organization_id: OrgIdTelemetrySchema,
522
+ attempt_number: AttemptNumberSchema
523
+ });
524
+ const OrganizationCreationReadyProps = Schema.Struct({
525
+ ...TelemetryEnvelopeProps,
526
+ $insert_id: Schema.String,
527
+ organization_id: OrgIdTelemetrySchema,
528
+ attempt_number: AttemptNumberSchema,
529
+ duration_ms: DurationMsSchema
530
+ });
531
+ const OrganizationCreationFailedProps = Schema.Struct({
532
+ ...TelemetryEnvelopeProps,
533
+ $insert_id: Schema.String,
534
+ organization_id: OrgIdTelemetrySchema,
535
+ attempt_number: AttemptNumberSchema,
536
+ stage: OnboardingStageSchema,
537
+ error_code: Schema.String,
538
+ retryable: Schema.Boolean
539
+ });
540
+ const OrgCreateStartedProps = Schema.Struct({
541
+ ...TelemetryEnvelopeProps,
542
+ org_id: OptionalOrgId,
543
+ email_domain: OptionalString,
544
+ template: OptionalString
545
+ });
546
+ const OrgSafeCreatedProps = Schema.Struct({
547
+ ...TelemetryEnvelopeProps,
548
+ org_id: OptionalOrgId,
549
+ chainId: OptionalChainId,
550
+ safe_address: OptionalAddress
551
+ });
552
+ const OrgSafeConfirmedProps = Schema.Struct({
553
+ ...TelemetryEnvelopeProps,
554
+ org_id: OptionalOrgId,
555
+ chainId: OptionalChainId,
556
+ safe_address: OptionalAddress,
557
+ durationMs: OptionalDurationMs
558
+ });
559
+ const OrgRolesSeededProps = Schema.Struct({
560
+ ...TelemetryEnvelopeProps,
561
+ org_id: OptionalOrgId,
562
+ chainId: OptionalChainId,
563
+ role: OptionalString,
564
+ txHash: OptionalTxHash
565
+ });
566
+ const OrgCreatedProps = Schema.Struct({
567
+ ...TelemetryEnvelopeProps,
568
+ org_id: OptionalOrgId,
569
+ chainId: OptionalChainId,
570
+ safe_address: OptionalAddress,
571
+ durationMs: OptionalDurationMs
572
+ });
573
+ const OrgCreateFailedProps = Schema.Struct({
574
+ ...TelemetryEnvelopeProps,
575
+ org_id: OptionalOrgId,
576
+ reason: OptionalString
577
+ });
578
+ const OrgInviteSentProps = Schema.Struct({
579
+ ...TelemetryEnvelopeProps,
580
+ org_id: OptionalOrgId,
581
+ email_domain: OptionalString,
582
+ role: OptionalString,
583
+ status: OptionalString
584
+ });
585
+ const OrgInviteAcceptedProps = Schema.Struct({
586
+ ...TelemetryEnvelopeProps,
587
+ org_id: OptionalOrgId,
588
+ role: OptionalString,
589
+ status: OptionalString
590
+ });
591
+ const OrgRoleGrantedProps = Schema.Struct({
592
+ ...TelemetryEnvelopeProps,
593
+ org_id: OptionalOrgId,
594
+ role: OptionalString,
595
+ status: OptionalString,
596
+ txHash: OptionalTxHash
597
+ });
598
+ const OrgMemberActiveProps = Schema.Struct({
599
+ ...TelemetryEnvelopeProps,
600
+ org_id: OptionalOrgId,
601
+ role: OptionalString,
602
+ status: OptionalString,
603
+ durationMs: OptionalDurationMs
604
+ });
605
+ const OrgMemberRemovedProps = Schema.Struct({
606
+ ...TelemetryEnvelopeProps,
607
+ org_id: OptionalOrgId,
608
+ role: OptionalString,
609
+ status: OptionalString,
610
+ txHash: OptionalTxHash
611
+ });
612
+ const OrgInviteExpiredProps = Schema.Struct({
613
+ ...TelemetryEnvelopeProps,
614
+ org_id: OptionalOrgId,
615
+ email_domain: OptionalString,
616
+ reason: OptionalString,
617
+ role: OptionalString,
618
+ status: OptionalString
619
+ });
620
+ const OrgRoleGrantFailedProps = Schema.Struct({
621
+ ...TelemetryEnvelopeProps,
622
+ org_id: OptionalOrgId,
623
+ reason: OptionalString,
624
+ role: OptionalString
625
+ });
626
+ const OptionalPaymentId = Schema.optional(PaymentIdTelemetrySchema);
627
+ const OptionalPayeeId = Schema.optional(PayeeIdTelemetrySchema);
628
+ const OptionalDocumentHash = Schema.optional(DocumentHashSchema);
629
+ const PaymentTargetTelemetryProps = Schema.Struct({
630
+ ...TelemetryEnvelopeProps,
631
+ payment_id: OptionalPaymentId,
632
+ payee_id: OptionalPayeeId,
633
+ document_hash: OptionalDocumentHash,
634
+ amount: OptionalWeiAmount,
635
+ currency: OptionalCurrencyCode,
636
+ status: OptionalString,
637
+ reason: OptionalString,
638
+ durationMs: OptionalDurationMs
639
+ });
640
+ const StreamTargetTelemetryProps = Schema.Struct({
641
+ ...TelemetryEnvelopeProps,
642
+ payment_id: OptionalPaymentId,
643
+ document_hash: OptionalDocumentHash,
644
+ amount: OptionalWeiAmount,
645
+ currency: OptionalCurrencyCode,
646
+ status: OptionalString,
647
+ available_bucket: OptionalBalanceBucket,
648
+ reason: OptionalString,
649
+ durationMs: OptionalDurationMs
650
+ });
651
+ const WithdrawalTargetTelemetryProps = Schema.Struct({
652
+ ...TelemetryEnvelopeProps,
653
+ payment_id: OptionalPaymentId,
654
+ document_hash: OptionalDocumentHash,
655
+ amount: OptionalWeiAmount,
656
+ currency: OptionalCurrencyCode,
657
+ status: OptionalString,
658
+ reason: OptionalString,
659
+ durationMs: OptionalDurationMs
660
+ });
661
+ const AuthOtpRequestedTelemetryEventSchema = Schema.Struct({
662
+ name: Schema.Literal("auth_otp_requested"),
663
+ props: AuthOtpRequestedProps
664
+ });
665
+ const AuthOtpDeliveredTelemetryEventSchema = Schema.Struct({
666
+ name: Schema.Literal("auth_otp_delivered"),
667
+ props: AuthOtpDeliveredProps
668
+ });
669
+ const AuthOtpExpiredTelemetryEventSchema = Schema.Struct({
670
+ name: Schema.Literal("auth_otp_expired"),
671
+ props: AuthOtpExpiredProps
672
+ });
673
+ const AuthVerifiedTelemetryEventSchema = Schema.Struct({
674
+ name: Schema.Literal("auth_verified"),
675
+ props: AuthVerifiedProps
676
+ });
677
+ const AuthFailedTelemetryEventSchema = Schema.Struct({
678
+ name: Schema.Literal("auth_failed"),
679
+ props: AuthFailedProps
680
+ });
681
+ const AuthSignedOutTelemetryEventSchema = Schema.Struct({
682
+ name: Schema.Literal("auth_signed_out"),
683
+ props: AuthSignedOutProps
684
+ });
685
+ const ProvisioningSafeCreatedTelemetryEventSchema = Schema.Struct({
686
+ name: Schema.Literal("provisioning_safe_created"),
687
+ props: ProvisioningSafeCreatedProps
688
+ });
689
+ const ProvisioningSafeConfirmedTelemetryEventSchema = Schema.Struct({
690
+ name: Schema.Literal("provisioning_safe_confirmed"),
691
+ props: ProvisioningSafeConfirmedProps
692
+ });
693
+ const BootstrapResolvedTelemetryEventSchema = Schema.Struct({
694
+ name: Schema.Literal("bootstrap_resolved"),
695
+ props: BootstrapResolvedProps
696
+ });
697
+ const BootstrapFailedTelemetryEventSchema = Schema.Struct({
698
+ name: Schema.Literal("bootstrap_failed"),
699
+ props: BootstrapFailedProps
700
+ });
701
+ const MemberActivationStartedTelemetryEventSchema = Schema.Struct({
702
+ name: Schema.Literal("member_activation_started"),
703
+ props: MemberActivationStartedProps
704
+ });
705
+ const MemberActivationReadyTelemetryEventSchema = Schema.Struct({
706
+ name: Schema.Literal("member_activation_ready"),
707
+ props: MemberActivationReadyProps
708
+ });
709
+ const MemberActivationFailedTelemetryEventSchema = Schema.Struct({
710
+ name: Schema.Literal("member_activation_failed"),
711
+ props: MemberActivationFailedProps
712
+ });
713
+ const OrganizationCreationStartedTelemetryEventSchema = Schema.Struct({
714
+ name: Schema.Literal("organization_creation_started"),
715
+ props: OrganizationCreationStartedProps
716
+ });
717
+ const OrganizationCreationReadyTelemetryEventSchema = Schema.Struct({
718
+ name: Schema.Literal("organization_creation_ready"),
719
+ props: OrganizationCreationReadyProps
720
+ });
721
+ const OrganizationCreationFailedTelemetryEventSchema = Schema.Struct({
722
+ name: Schema.Literal("organization_creation_failed"),
723
+ props: OrganizationCreationFailedProps
724
+ });
725
+ const AccountBalanceReadTelemetryEventSchema = Schema.Struct({
726
+ name: Schema.Literal("account_balance_read"),
727
+ props: AccountBalanceReadProps
728
+ });
729
+ const AccountBalanceFailedTelemetryEventSchema = Schema.Struct({
730
+ name: Schema.Literal("account_balance_failed"),
731
+ props: AccountBalanceFailedProps
732
+ });
733
+ const FaucetRequestedTelemetryEventSchema = Schema.Struct({
734
+ name: Schema.Literal("faucet_requested"),
735
+ props: FaucetRequestedProps
736
+ });
737
+ const FaucetConfirmedTelemetryEventSchema = Schema.Struct({
738
+ name: Schema.Literal("faucet_confirmed"),
739
+ props: FaucetConfirmedProps
740
+ });
741
+ const FaucetFailedTelemetryEventSchema = Schema.Struct({
742
+ name: Schema.Literal("faucet_failed"),
743
+ props: FaucetFailedProps
744
+ });
745
+ const SubaccountCreatedTelemetryEventSchema = Schema.Struct({
746
+ name: Schema.Literal("subaccount_created"),
747
+ props: SubaccountCreatedProps
748
+ });
749
+ const SubaccountRenamedTelemetryEventSchema = Schema.Struct({
750
+ name: Schema.Literal("subaccount_renamed"),
751
+ props: SubaccountRenamedProps
752
+ });
753
+ const SubaccountDeletedTelemetryEventSchema = Schema.Struct({
754
+ name: Schema.Literal("subaccount_deleted"),
755
+ props: SubaccountDeletedProps
756
+ });
757
+ const SubaccountOpFailedTelemetryEventSchema = Schema.Struct({
758
+ name: Schema.Literal("subaccount_op_failed"),
759
+ props: SubaccountOpFailedProps
760
+ });
761
+ const TransferRequestedTelemetryEventSchema = Schema.Struct({
762
+ name: Schema.Literal("transfer_requested"),
763
+ props: TransferRequestedProps
764
+ });
765
+ const TransferBackendReceivedTelemetryEventSchema = Schema.Struct({
766
+ name: Schema.Literal("transfer_backend_received"),
767
+ props: TransferBackendReceivedProps
768
+ });
769
+ const TransferConfirmedTelemetryEventSchema = Schema.Struct({
770
+ name: Schema.Literal("transfer_confirmed"),
771
+ props: TransferConfirmedProps
772
+ });
773
+ const TransferFailedTelemetryEventSchema = Schema.Struct({
774
+ name: Schema.Literal("transfer_failed"),
775
+ props: TransferFailedProps
776
+ });
777
+ const OrgCreateStartedTelemetryEventSchema = Schema.Struct({
778
+ name: Schema.Literal("org_create_started"),
779
+ props: OrgCreateStartedProps
780
+ });
781
+ const OrgSafeCreatedTelemetryEventSchema = Schema.Struct({
782
+ name: Schema.Literal("org_safe_created"),
783
+ props: OrgSafeCreatedProps
784
+ });
785
+ const OrgSafeConfirmedTelemetryEventSchema = Schema.Struct({
786
+ name: Schema.Literal("org_safe_confirmed"),
787
+ props: OrgSafeConfirmedProps
788
+ });
789
+ const OrgRolesSeededTelemetryEventSchema = Schema.Struct({
790
+ name: Schema.Literal("org_roles_seeded"),
791
+ props: OrgRolesSeededProps
792
+ });
793
+ const OrgCreatedTelemetryEventSchema = Schema.Struct({
794
+ name: Schema.Literal("org_created"),
795
+ props: OrgCreatedProps
796
+ });
797
+ const OrgCreateFailedTelemetryEventSchema = Schema.Struct({
798
+ name: Schema.Literal("org_create_failed"),
799
+ props: OrgCreateFailedProps
800
+ });
801
+ const OrgInviteSentTelemetryEventSchema = Schema.Struct({
802
+ name: Schema.Literal("org_invite_sent"),
803
+ props: OrgInviteSentProps
804
+ });
805
+ const OrgInviteAcceptedTelemetryEventSchema = Schema.Struct({
806
+ name: Schema.Literal("org_invite_accepted"),
807
+ props: OrgInviteAcceptedProps
808
+ });
809
+ const OrgRoleGrantedTelemetryEventSchema = Schema.Struct({
810
+ name: Schema.Literal("org_role_granted"),
811
+ props: OrgRoleGrantedProps
812
+ });
813
+ const OrgMemberActiveTelemetryEventSchema = Schema.Struct({
814
+ name: Schema.Literal("org_member_active"),
815
+ props: OrgMemberActiveProps
816
+ });
817
+ const OrgMemberRemovedTelemetryEventSchema = Schema.Struct({
818
+ name: Schema.Literal("org_member_removed"),
819
+ props: OrgMemberRemovedProps
820
+ });
821
+ const OrgInviteExpiredTelemetryEventSchema = Schema.Struct({
822
+ name: Schema.Literal("org_invite_expired"),
823
+ props: OrgInviteExpiredProps
824
+ });
825
+ const OrgRoleGrantFailedTelemetryEventSchema = Schema.Struct({
826
+ name: Schema.Literal("org_role_grant_failed"),
827
+ props: OrgRoleGrantFailedProps
828
+ });
829
+ const PaymentRequestedTelemetryEventSchema = Schema.Struct({
830
+ name: Schema.Literal("payment_requested"),
831
+ props: PaymentTargetTelemetryProps
832
+ });
833
+ const PaymentResolvedTelemetryEventSchema = Schema.Struct({
834
+ name: Schema.Literal("payment_resolved"),
835
+ props: PaymentTargetTelemetryProps
836
+ });
837
+ const PaymentDocumentAttachedTelemetryEventSchema = Schema.Struct({
838
+ name: Schema.Literal("payment_document_attached"),
839
+ props: PaymentTargetTelemetryProps
840
+ });
841
+ const PaymentSubmittedTelemetryEventSchema = Schema.Struct({
842
+ name: Schema.Literal("payment_submitted"),
843
+ props: PaymentTargetTelemetryProps
844
+ });
845
+ const PaymentSettledTelemetryEventSchema = Schema.Struct({
846
+ name: Schema.Literal("payment_settled"),
847
+ props: PaymentTargetTelemetryProps
848
+ });
849
+ const PaymentClaimedTelemetryEventSchema = Schema.Struct({
850
+ name: Schema.Literal("payment_claimed"),
851
+ props: PaymentTargetTelemetryProps
852
+ });
853
+ const PaymentCancelledTelemetryEventSchema = Schema.Struct({
854
+ name: Schema.Literal("payment_cancelled"),
855
+ props: PaymentTargetTelemetryProps
856
+ });
857
+ const PaymentRedirectedTelemetryEventSchema = Schema.Struct({
858
+ name: Schema.Literal("payment_redirected"),
859
+ props: PaymentTargetTelemetryProps
860
+ });
861
+ const PaymentFailedTelemetryEventSchema = Schema.Struct({
862
+ name: Schema.Literal("payment_failed"),
863
+ props: PaymentTargetTelemetryProps
864
+ });
865
+ const StreamCreatedTelemetryEventSchema = Schema.Struct({
866
+ name: Schema.Literal("stream_created"),
867
+ props: StreamTargetTelemetryProps
868
+ });
869
+ const StreamClaimedTelemetryEventSchema = Schema.Struct({
870
+ name: Schema.Literal("stream_claimed"),
871
+ props: StreamTargetTelemetryProps
872
+ });
873
+ const StreamCancelledTelemetryEventSchema = Schema.Struct({
874
+ name: Schema.Literal("stream_cancelled"),
875
+ props: StreamTargetTelemetryProps
876
+ });
877
+ const StreamCompletedTelemetryEventSchema = Schema.Struct({
878
+ name: Schema.Literal("stream_completed"),
879
+ props: StreamTargetTelemetryProps
880
+ });
881
+ const StreamFailedTelemetryEventSchema = Schema.Struct({
882
+ name: Schema.Literal("stream_failed"),
883
+ props: StreamTargetTelemetryProps
884
+ });
885
+ const WithdrawalRequestedTelemetryEventSchema = Schema.Struct({
886
+ name: Schema.Literal("withdrawal_requested"),
887
+ props: WithdrawalTargetTelemetryProps
888
+ });
889
+ const WithdrawalSubmittedTelemetryEventSchema = Schema.Struct({
890
+ name: Schema.Literal("withdrawal_submitted"),
891
+ props: WithdrawalTargetTelemetryProps
892
+ });
893
+ const WithdrawalSettledTelemetryEventSchema = Schema.Struct({
894
+ name: Schema.Literal("withdrawal_settled"),
895
+ props: WithdrawalTargetTelemetryProps
896
+ });
897
+ const WithdrawalFailedTelemetryEventSchema = Schema.Struct({
898
+ name: Schema.Literal("withdrawal_failed"),
899
+ props: WithdrawalTargetTelemetryProps
900
+ });
901
+ const TELEMETRY_EVENT_SCHEMAS = {
902
+ auth_otp_requested: AuthOtpRequestedTelemetryEventSchema,
903
+ auth_otp_delivered: AuthOtpDeliveredTelemetryEventSchema,
904
+ auth_otp_expired: AuthOtpExpiredTelemetryEventSchema,
905
+ auth_verified: AuthVerifiedTelemetryEventSchema,
906
+ auth_failed: AuthFailedTelemetryEventSchema,
907
+ auth_signed_out: AuthSignedOutTelemetryEventSchema,
908
+ provisioning_safe_created: ProvisioningSafeCreatedTelemetryEventSchema,
909
+ provisioning_safe_confirmed: ProvisioningSafeConfirmedTelemetryEventSchema,
910
+ bootstrap_resolved: BootstrapResolvedTelemetryEventSchema,
911
+ bootstrap_failed: BootstrapFailedTelemetryEventSchema,
912
+ member_activation_started: MemberActivationStartedTelemetryEventSchema,
913
+ member_activation_ready: MemberActivationReadyTelemetryEventSchema,
914
+ member_activation_failed: MemberActivationFailedTelemetryEventSchema,
915
+ organization_creation_started: OrganizationCreationStartedTelemetryEventSchema,
916
+ organization_creation_ready: OrganizationCreationReadyTelemetryEventSchema,
917
+ organization_creation_failed: OrganizationCreationFailedTelemetryEventSchema,
918
+ account_balance_read: AccountBalanceReadTelemetryEventSchema,
919
+ account_balance_failed: AccountBalanceFailedTelemetryEventSchema,
920
+ faucet_requested: FaucetRequestedTelemetryEventSchema,
921
+ faucet_confirmed: FaucetConfirmedTelemetryEventSchema,
922
+ faucet_failed: FaucetFailedTelemetryEventSchema,
923
+ subaccount_created: SubaccountCreatedTelemetryEventSchema,
924
+ subaccount_renamed: SubaccountRenamedTelemetryEventSchema,
925
+ subaccount_deleted: SubaccountDeletedTelemetryEventSchema,
926
+ subaccount_op_failed: SubaccountOpFailedTelemetryEventSchema,
927
+ transfer_requested: TransferRequestedTelemetryEventSchema,
928
+ transfer_backend_received: TransferBackendReceivedTelemetryEventSchema,
929
+ transfer_confirmed: TransferConfirmedTelemetryEventSchema,
930
+ transfer_failed: TransferFailedTelemetryEventSchema,
931
+ org_create_started: OrgCreateStartedTelemetryEventSchema,
932
+ org_safe_created: OrgSafeCreatedTelemetryEventSchema,
933
+ org_safe_confirmed: OrgSafeConfirmedTelemetryEventSchema,
934
+ org_roles_seeded: OrgRolesSeededTelemetryEventSchema,
935
+ org_created: OrgCreatedTelemetryEventSchema,
936
+ org_create_failed: OrgCreateFailedTelemetryEventSchema,
937
+ org_invite_sent: OrgInviteSentTelemetryEventSchema,
938
+ org_invite_accepted: OrgInviteAcceptedTelemetryEventSchema,
939
+ org_role_granted: OrgRoleGrantedTelemetryEventSchema,
940
+ org_member_active: OrgMemberActiveTelemetryEventSchema,
941
+ org_member_removed: OrgMemberRemovedTelemetryEventSchema,
942
+ org_invite_expired: OrgInviteExpiredTelemetryEventSchema,
943
+ org_role_grant_failed: OrgRoleGrantFailedTelemetryEventSchema,
944
+ payment_requested: PaymentRequestedTelemetryEventSchema,
945
+ payment_resolved: PaymentResolvedTelemetryEventSchema,
946
+ payment_document_attached: PaymentDocumentAttachedTelemetryEventSchema,
947
+ payment_submitted: PaymentSubmittedTelemetryEventSchema,
948
+ payment_settled: PaymentSettledTelemetryEventSchema,
949
+ payment_claimed: PaymentClaimedTelemetryEventSchema,
950
+ payment_cancelled: PaymentCancelledTelemetryEventSchema,
951
+ payment_redirected: PaymentRedirectedTelemetryEventSchema,
952
+ payment_failed: PaymentFailedTelemetryEventSchema,
953
+ stream_created: StreamCreatedTelemetryEventSchema,
954
+ stream_claimed: StreamClaimedTelemetryEventSchema,
955
+ stream_cancelled: StreamCancelledTelemetryEventSchema,
956
+ stream_completed: StreamCompletedTelemetryEventSchema,
957
+ stream_failed: StreamFailedTelemetryEventSchema,
958
+ withdrawal_requested: WithdrawalRequestedTelemetryEventSchema,
959
+ withdrawal_submitted: WithdrawalSubmittedTelemetryEventSchema,
960
+ withdrawal_settled: WithdrawalSettledTelemetryEventSchema,
961
+ withdrawal_failed: WithdrawalFailedTelemetryEventSchema
962
+ };
963
+ const FINANCIAL_OPS_TARGET_TELEMETRY_PRODUCERS = [
964
+ {
965
+ eventName: "payment_requested",
966
+ ownerIssue: 410,
967
+ producer: "sdk-target"
968
+ },
969
+ {
970
+ eventName: "payment_resolved",
971
+ ownerIssue: 410,
972
+ producer: "sdk-target"
973
+ },
974
+ {
975
+ eventName: "payment_document_attached",
976
+ ownerIssue: 486,
977
+ producer: "sdk-target"
978
+ },
979
+ {
980
+ eventName: "payment_submitted",
981
+ ownerIssue: 410,
982
+ producer: "sdk-target"
983
+ },
984
+ {
985
+ eventName: "payment_failed",
986
+ ownerIssue: 410,
987
+ producer: "sdk-target"
988
+ },
989
+ {
990
+ eventName: "stream_created",
991
+ ownerIssue: 411,
992
+ producer: "sdk-target"
993
+ },
994
+ {
995
+ eventName: "stream_failed",
996
+ ownerIssue: 411,
997
+ producer: "sdk-target"
998
+ },
999
+ {
1000
+ eventName: "withdrawal_requested",
1001
+ ownerIssue: 410,
1002
+ producer: "sdk-target"
1003
+ },
1004
+ {
1005
+ eventName: "withdrawal_submitted",
1006
+ ownerIssue: 410,
1007
+ producer: "sdk-target"
1008
+ },
1009
+ {
1010
+ eventName: "withdrawal_failed",
1011
+ ownerIssue: 410,
1012
+ producer: "sdk-target"
1013
+ }
1014
+ ];
1015
+ /**
1016
+ * Catalog events whose product mapper remains gated on the #1150 frontend
1017
+ * adoption. L1 S1 removes their retired SDK-flow producers without inventing
1018
+ * replacements inside the identity actor. The telemetry-spine gate enforces
1019
+ * planned-XOR-wired: a name must leave this list in the same change that adds
1020
+ * its real product-boundary producer.
1021
+ */
1022
+ const PRODUCT_MAPPER_GATED_TELEMETRY_EVENTS = [
1023
+ "auth_otp_requested",
1024
+ "auth_otp_expired",
1025
+ "auth_verified",
1026
+ "auth_failed",
1027
+ "auth_signed_out"
1028
+ ];
1029
+ let trackHandler = () => {};
1030
+ function setTrackHandler(handler) {
1031
+ const previous = trackHandler;
1032
+ trackHandler = handler;
1033
+ return previous;
1034
+ }
1035
+ function getTrackHandler() {
1036
+ return trackHandler;
1037
+ }
1038
+ function track(name, props) {
1039
+ trackHandler(name, props);
1040
+ }
1041
+ function redactTelemetryEvent(event, options = {}) {
1042
+ const props = redactTelemetryProps(event.name, event.props, options);
1043
+ return props === void 0 ? { name: event.name } : {
1044
+ name: event.name,
1045
+ props
1046
+ };
1047
+ }
1048
+ function redactTelemetryProps(name, props, options = {}) {
1049
+ if (props === void 0) return void 0;
1050
+ const clone = cloneProps(props);
1051
+ if (options.rawMode === true) return clone;
1052
+ for (const key of PII_PROP_KEYS_BY_EVENT[name] ?? []) redactProperty(clone, key);
1053
+ return clone;
1054
+ }
1055
+ /**
1056
+ * Remove query strings and fragments from every PostHog URL/referrer/path
1057
+ * property before transport. Browser applications may carry emails, draft ids,
1058
+ * or other capabilities in the URL; those values must never leave the origin.
1059
+ *
1060
+ * The callback mutates and returns the supplied event, matching PostHog's
1061
+ * `before_send` contract while preserving the event's full structural type.
1062
+ */
1063
+ function sanitizePostHogBrowserEvent(event) {
1064
+ if (event === null) return event;
1065
+ const seen = /* @__PURE__ */ new WeakSet();
1066
+ sanitizePostHogBrowserValue(event.properties, seen);
1067
+ if (event.$set !== void 0) sanitizePostHogBrowserValue(event.$set, seen);
1068
+ if (event.$set_once !== void 0) sanitizePostHogBrowserValue(event.$set_once, seen);
1069
+ return event;
1070
+ }
1071
+ /**
1072
+ * Sanitize AND stamp. Every browser event leaves with `capxul_env` and
1073
+ * `producer: "browser"` on it, because the browser half has no transport of
1074
+ * its own to stamp at — `before_send` is the one funnel every capture,
1075
+ * pageview, exception and replay-meta event passes through. Forgetting to
1076
+ * register a super-property is therefore not a failure mode.
1077
+ */
1078
+ function createCapxulBeforeSend(capxulEnv) {
1079
+ return (event) => {
1080
+ const sanitized = sanitizePostHogBrowserEvent(event);
1081
+ if (sanitized === null) return sanitized;
1082
+ sanitized.properties.capxul_env = capxulEnv;
1083
+ sanitized.properties.producer ??= "browser";
1084
+ return sanitized;
1085
+ };
1086
+ }
1087
+ function utilityAppAnalytics(input) {
1088
+ return {
1089
+ api_host: input.host,
1090
+ defaults: "2026-01-30",
1091
+ autocapture: false,
1092
+ capture_pageview: false,
1093
+ capture_pageleave: true,
1094
+ disable_session_recording: true,
1095
+ disable_persistence: true,
1096
+ capture_heatmaps: false,
1097
+ capture_exceptions: false,
1098
+ capture_performance: false,
1099
+ disable_surveys: true,
1100
+ disable_web_experiments: true,
1101
+ disable_product_tours: true,
1102
+ disable_conversations: true,
1103
+ disable_external_dependency_loading: true,
1104
+ person_profiles: "identified_only",
1105
+ advanced_disable_flags: true,
1106
+ save_campaign_params: false,
1107
+ save_referrer: false,
1108
+ before_send: createCapxulBeforeSend(input.capxulEnv)
1109
+ };
1110
+ }
1111
+ function productAppAnalytics(input) {
1112
+ const replay = input.capxulEnv === "production";
1113
+ return {
1114
+ api_host: input.host,
1115
+ defaults: "2026-01-30",
1116
+ autocapture: false,
1117
+ capture_pageview: false,
1118
+ capture_pageleave: true,
1119
+ disable_session_recording: !replay,
1120
+ disable_persistence: false,
1121
+ capture_heatmaps: false,
1122
+ capture_exceptions: true,
1123
+ capture_performance: false,
1124
+ disable_surveys: true,
1125
+ disable_web_experiments: true,
1126
+ disable_product_tours: true,
1127
+ disable_conversations: true,
1128
+ disable_external_dependency_loading: !replay,
1129
+ person_profiles: "identified_only",
1130
+ advanced_disable_flags: true,
1131
+ save_campaign_params: false,
1132
+ save_referrer: false,
1133
+ session_recording: {
1134
+ maskAllInputs: true,
1135
+ maskTextSelector: "*",
1136
+ captureCanvas: { recordCanvas: false },
1137
+ recordHeaders: false,
1138
+ recordBody: false
1139
+ },
1140
+ before_send: createCapxulBeforeSend(input.capxulEnv)
1141
+ };
1142
+ }
1143
+ /**
1144
+ * Apply a named privacy profile before an application-owned PostHog client
1145
+ * initializes. Hosts still own the vendor client and lifecycle; this helper
1146
+ * centralizes the security-relevant options and the missing-key opt-out (no
1147
+ * key ⇒ no client ⇒ no network call).
1148
+ */
1149
+ function initializeCapxulBrowserAnalytics(profile, input, initialize) {
1150
+ const key = input.key?.trim();
1151
+ if (key === void 0 || key.length === 0) return void 0;
1152
+ try {
1153
+ return initialize(key, profile(input));
1154
+ } catch {
1155
+ return;
1156
+ }
1157
+ }
1158
+ /** The utility profile, pre-bound — the shape ADR-0016's consumers already use. */
1159
+ function initializePostHogBrowserAnalytics(input, initialize) {
1160
+ return initializeCapxulBrowserAnalytics(utilityAppAnalytics, input, initialize);
1161
+ }
1162
+ /**
1163
+ * Build an explicit SPA pageview sink for toolbar-free PostHog clients. The
1164
+ * pathname-only input avoids query capabilities, repeated pathnames are
1165
+ * deduplicated, and vendor failures remain best-effort.
1166
+ */
1167
+ function createPostHogBrowserPageviewTracker(client) {
1168
+ let previousPathname;
1169
+ return (pathname) => {
1170
+ if (client === null || client === void 0) return;
1171
+ const safePathname = stripUrlQueryAndFragment(pathname);
1172
+ if (safePathname === previousPathname) return;
1173
+ try {
1174
+ Promise.resolve(client.capture("$pageview", { $pathname: safePathname })).catch(() => {});
1175
+ previousPathname = safePathname;
1176
+ } catch {}
1177
+ };
1178
+ }
1179
+ function sanitizePostHogBrowserValue(value, seen) {
1180
+ if (typeof value !== "object" || value === null || seen.has(value)) return;
1181
+ seen.add(value);
1182
+ if (Array.isArray(value)) {
1183
+ for (const item of value) sanitizePostHogBrowserValue(item, seen);
1184
+ return;
1185
+ }
1186
+ const properties = value;
1187
+ for (const [key, nestedValue] of Object.entries(properties)) {
1188
+ if (isPostHogQueryDerivedProperty(key)) {
1189
+ delete properties[key];
1190
+ continue;
1191
+ }
1192
+ if (typeof nestedValue === "string" && isPostHogUrlProperty(key)) {
1193
+ properties[key] = stripUrlQueryAndFragment(nestedValue);
1194
+ continue;
1195
+ }
1196
+ sanitizePostHogBrowserValue(nestedValue, seen);
1197
+ }
1198
+ }
1199
+ const POSTHOG_QUERY_DERIVED_PROPERTY_NAMES = [
1200
+ "utm_source",
1201
+ "utm_medium",
1202
+ "utm_campaign",
1203
+ "utm_content",
1204
+ "utm_term",
1205
+ "gad_source",
1206
+ "mc_cid",
1207
+ "gclid",
1208
+ "gclsrc",
1209
+ "dclid",
1210
+ "gbraid",
1211
+ "wbraid",
1212
+ "fbclid",
1213
+ "msclkid",
1214
+ "twclid",
1215
+ "li_fat_id",
1216
+ "igshid",
1217
+ "ttclid",
1218
+ "rdt_cid",
1219
+ "epik",
1220
+ "qclid",
1221
+ "sccid",
1222
+ "irclid",
1223
+ "_kx",
1224
+ "ph_keyword"
1225
+ ];
1226
+ function isPostHogQueryDerivedProperty(key) {
1227
+ const normalized = key.toLowerCase();
1228
+ return POSTHOG_QUERY_DERIVED_PROPERTY_NAMES.some((propertyName) => normalized === propertyName || normalized.endsWith(`_${propertyName}`) || normalized.endsWith(`$${propertyName}`));
1229
+ }
1230
+ function isPostHogUrlProperty(key) {
1231
+ const normalized = key.toLowerCase();
1232
+ return normalized.includes("url") || normalized.includes("referrer") || normalized.includes("path") || normalized.includes("filename");
1233
+ }
1234
+ function stripUrlQueryAndFragment(value) {
1235
+ const queryIndex = value.indexOf("?");
1236
+ const fragmentIndex = value.indexOf("#");
1237
+ if (queryIndex === -1 && fragmentIndex === -1) return value;
1238
+ if (queryIndex === -1) return value.slice(0, fragmentIndex);
1239
+ if (fragmentIndex === -1) return value.slice(0, queryIndex);
1240
+ return value.slice(0, Math.min(queryIndex, fragmentIndex));
1241
+ }
1242
+ var RecordingTelemetryAdapter = class {
1243
+ #events = [];
1244
+ #rawMode;
1245
+ constructor(options = {}) {
1246
+ this.#rawMode = options.rawMode === true;
1247
+ }
1248
+ get events() {
1249
+ return this.#events.map((event) => cloneEvent(event));
1250
+ }
1251
+ emit(event) {
1252
+ return Effect.sync(() => {
1253
+ this.#events.push(redactTelemetryEvent(event, { rawMode: this.#rawMode }));
1254
+ });
1255
+ }
1256
+ identify(_input) {
1257
+ return Effect.void;
1258
+ }
1259
+ group(_input) {
1260
+ return Effect.void;
1261
+ }
1262
+ reset() {
1263
+ return Effect.void;
1264
+ }
1265
+ reportHandledError(_error, _context) {
1266
+ return Effect.void;
1267
+ }
1268
+ clear() {
1269
+ this.#events.length = 0;
1270
+ }
1271
+ };
1272
+ var PostHogTelemetryAdapter = class {
1273
+ #capture;
1274
+ constructor(deps) {
1275
+ this.#capture = deps.capture;
1276
+ }
1277
+ emit(event) {
1278
+ return Effect.sync(() => {
1279
+ try {
1280
+ Promise.resolve(this.#capture(event.name, redactTelemetryProps(event.name, event.props))).catch(() => {});
1281
+ } catch {}
1282
+ });
1283
+ }
1284
+ identify(_input) {
1285
+ return Effect.void;
1286
+ }
1287
+ group(_input) {
1288
+ return Effect.void;
1289
+ }
1290
+ reset() {
1291
+ return Effect.void;
1292
+ }
1293
+ reportHandledError(_error, _context) {
1294
+ return Effect.void;
1295
+ }
1296
+ };
1297
+ var InMemoryTelemetryBusAdapter = class {
1298
+ #subscribers = /* @__PURE__ */ new Set();
1299
+ #rawMode;
1300
+ constructor(options = {}) {
1301
+ this.#rawMode = options.rawMode === true;
1302
+ }
1303
+ subscribe(handler) {
1304
+ this.#subscribers.add(handler);
1305
+ return () => {
1306
+ this.#subscribers.delete(handler);
1307
+ };
1308
+ }
1309
+ emit(event) {
1310
+ return Effect.sync(() => {
1311
+ const delivered = redactTelemetryEvent(event, { rawMode: this.#rawMode });
1312
+ for (const handler of this.#subscribers) try {
1313
+ handler(cloneEvent(delivered));
1314
+ } catch {}
1315
+ });
1316
+ }
1317
+ identify(_input) {
1318
+ return Effect.void;
1319
+ }
1320
+ group(_input) {
1321
+ return Effect.void;
1322
+ }
1323
+ reset() {
1324
+ return Effect.void;
1325
+ }
1326
+ reportHandledError(_error, _context) {
1327
+ return Effect.void;
1328
+ }
1329
+ };
1330
+ const PII_PROP_KEYS_BY_EVENT = {
1331
+ auth_otp_requested: ["email"],
1332
+ auth_otp_delivered: ["email"],
1333
+ auth_otp_expired: ["email"],
1334
+ auth_failed: ["email"]
1335
+ };
1336
+ function redactProperty(props, key) {
1337
+ const value = props[key];
1338
+ if (typeof value === "string") props[key] = sha256Hex(value).slice(0, 12);
1339
+ }
1340
+ function cloneEvent(event) {
1341
+ if (event.props === void 0) return { name: event.name };
1342
+ return {
1343
+ name: event.name,
1344
+ props: cloneProps(event.props)
1345
+ };
1346
+ }
1347
+ function cloneProps(props) {
1348
+ const cloned = {};
1349
+ for (const [key, value] of Object.entries(props)) cloned[key] = cloneTelemetryValue(value);
1350
+ return cloned;
1351
+ }
1352
+ function cloneTelemetryValue(value) {
1353
+ if (Array.isArray(value)) return value.map(cloneTelemetryValue);
1354
+ if (value === null || typeof value !== "object") return value;
1355
+ if (Object.getPrototypeOf(value) !== Object.prototype) return value;
1356
+ const cloned = {};
1357
+ for (const [key, nested] of Object.entries(value)) cloned[key] = cloneTelemetryValue(nested);
1358
+ return cloned;
1359
+ }
1360
+ const SHA256_INITIAL_HASH = [
1361
+ 1779033703,
1362
+ 3144134277,
1363
+ 1013904242,
1364
+ 2773480762,
1365
+ 1359893119,
1366
+ 2600822924,
1367
+ 528734635,
1368
+ 1541459225
1369
+ ];
1370
+ const SHA256_K = [
1371
+ 1116352408,
1372
+ 1899447441,
1373
+ 3049323471,
1374
+ 3921009573,
1375
+ 961987163,
1376
+ 1508970993,
1377
+ 2453635748,
1378
+ 2870763221,
1379
+ 3624381080,
1380
+ 310598401,
1381
+ 607225278,
1382
+ 1426881987,
1383
+ 1925078388,
1384
+ 2162078206,
1385
+ 2614888103,
1386
+ 3248222580,
1387
+ 3835390401,
1388
+ 4022224774,
1389
+ 264347078,
1390
+ 604807628,
1391
+ 770255983,
1392
+ 1249150122,
1393
+ 1555081692,
1394
+ 1996064986,
1395
+ 2554220882,
1396
+ 2821834349,
1397
+ 2952996808,
1398
+ 3210313671,
1399
+ 3336571891,
1400
+ 3584528711,
1401
+ 113926993,
1402
+ 338241895,
1403
+ 666307205,
1404
+ 773529912,
1405
+ 1294757372,
1406
+ 1396182291,
1407
+ 1695183700,
1408
+ 1986661051,
1409
+ 2177026350,
1410
+ 2456956037,
1411
+ 2730485921,
1412
+ 2820302411,
1413
+ 3259730800,
1414
+ 3345764771,
1415
+ 3516065817,
1416
+ 3600352804,
1417
+ 4094571909,
1418
+ 275423344,
1419
+ 430227734,
1420
+ 506948616,
1421
+ 659060556,
1422
+ 883997877,
1423
+ 958139571,
1424
+ 1322822218,
1425
+ 1537002063,
1426
+ 1747873779,
1427
+ 1955562222,
1428
+ 2024104815,
1429
+ 2227730452,
1430
+ 2361852424,
1431
+ 2428436474,
1432
+ 2756734187,
1433
+ 3204031479,
1434
+ 3329325298
1435
+ ];
1436
+ function sha256Hex(input) {
1437
+ const padded = padSha256Message(new TextEncoder().encode(input));
1438
+ const view = new DataView(padded.buffer, padded.byteOffset, padded.byteLength);
1439
+ const words = new Uint32Array(64);
1440
+ let h0 = SHA256_INITIAL_HASH[0];
1441
+ let h1 = SHA256_INITIAL_HASH[1];
1442
+ let h2 = SHA256_INITIAL_HASH[2];
1443
+ let h3 = SHA256_INITIAL_HASH[3];
1444
+ let h4 = SHA256_INITIAL_HASH[4];
1445
+ let h5 = SHA256_INITIAL_HASH[5];
1446
+ let h6 = SHA256_INITIAL_HASH[6];
1447
+ let h7 = SHA256_INITIAL_HASH[7];
1448
+ for (let offset = 0; offset < padded.byteLength; offset += 64) {
1449
+ for (let i = 0; i < 16; i++) words[i] = view.getUint32(offset + i * 4);
1450
+ for (let i = 16; i < 64; i++) {
1451
+ const s0 = rotr(words[i - 15], 7) ^ rotr(words[i - 15], 18) ^ words[i - 15] >>> 3;
1452
+ const s1 = rotr(words[i - 2], 17) ^ rotr(words[i - 2], 19) ^ words[i - 2] >>> 10;
1453
+ words[i] = words[i - 16] + s0 + words[i - 7] + s1 >>> 0;
1454
+ }
1455
+ let a = h0;
1456
+ let b = h1;
1457
+ let c = h2;
1458
+ let d = h3;
1459
+ let e = h4;
1460
+ let f = h5;
1461
+ let g = h6;
1462
+ let h = h7;
1463
+ for (let i = 0; i < 64; i++) {
1464
+ const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
1465
+ const ch = e & f ^ ~e & g;
1466
+ const temp1 = h + s1 + ch + SHA256_K[i] + words[i] >>> 0;
1467
+ const temp2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
1468
+ h = g;
1469
+ g = f;
1470
+ f = e;
1471
+ e = d + temp1 >>> 0;
1472
+ d = c;
1473
+ c = b;
1474
+ b = a;
1475
+ a = temp1 + temp2 >>> 0;
1476
+ }
1477
+ h0 = h0 + a >>> 0;
1478
+ h1 = h1 + b >>> 0;
1479
+ h2 = h2 + c >>> 0;
1480
+ h3 = h3 + d >>> 0;
1481
+ h4 = h4 + e >>> 0;
1482
+ h5 = h5 + f >>> 0;
1483
+ h6 = h6 + g >>> 0;
1484
+ h7 = h7 + h >>> 0;
1485
+ }
1486
+ return [
1487
+ h0,
1488
+ h1,
1489
+ h2,
1490
+ h3,
1491
+ h4,
1492
+ h5,
1493
+ h6,
1494
+ h7
1495
+ ].map((word) => word.toString(16).padStart(8, "0")).join("");
1496
+ }
1497
+ function padSha256Message(bytes) {
1498
+ const bitLength = bytes.byteLength * 8;
1499
+ const zeroPadLength = (64 - (bytes.byteLength + 1 + 8) % 64) % 64;
1500
+ const output = new Uint8Array(bytes.byteLength + 1 + zeroPadLength + 8);
1501
+ output.set(bytes);
1502
+ output[bytes.byteLength] = 128;
1503
+ const view = new DataView(output.buffer);
1504
+ view.setUint32(output.byteLength - 8, Math.floor(bitLength / 4294967296));
1505
+ view.setUint32(output.byteLength - 4, bitLength >>> 0);
1506
+ return output;
1507
+ }
1508
+ function rotr(value, bits) {
1509
+ return value >>> bits | value << 32 - bits;
1510
+ }
1511
+ //#endregion
1512
+ export { AccountBalanceFailedTelemetryEventSchema, AccountBalanceReadTelemetryEventSchema, AuthFailedTelemetryEventSchema, AuthOtpDeliveredTelemetryEventSchema, AuthOtpExpiredTelemetryEventSchema, AuthOtpRequestedTelemetryEventSchema, AuthSignedOutTelemetryEventSchema, AuthVerifiedTelemetryEventSchema, BootstrapFailedTelemetryEventSchema, BootstrapResolvedTelemetryEventSchema, CAPXUL_ENVS, FINANCIAL_OPS_TARGET_TELEMETRY_PRODUCERS, FaucetConfirmedTelemetryEventSchema, FaucetFailedTelemetryEventSchema, FaucetRequestedTelemetryEventSchema, InMemoryTelemetryBusAdapter, MemberActivationFailedTelemetryEventSchema, MemberActivationReadyTelemetryEventSchema, MemberActivationStartedTelemetryEventSchema, OrgCreateFailedTelemetryEventSchema, OrgCreateStartedTelemetryEventSchema, OrgCreatedTelemetryEventSchema, OrgInviteAcceptedTelemetryEventSchema, OrgInviteExpiredTelemetryEventSchema, OrgInviteSentTelemetryEventSchema, OrgMemberActiveTelemetryEventSchema, OrgMemberRemovedTelemetryEventSchema, OrgRoleGrantFailedTelemetryEventSchema, OrgRoleGrantedTelemetryEventSchema, OrgRolesSeededTelemetryEventSchema, OrgSafeConfirmedTelemetryEventSchema, OrgSafeCreatedTelemetryEventSchema, OrganizationCreationFailedTelemetryEventSchema, OrganizationCreationReadyTelemetryEventSchema, OrganizationCreationStartedTelemetryEventSchema, PII, PRODUCT_MAPPER_GATED_TELEMETRY_EVENTS, PaymentCancelledTelemetryEventSchema, PaymentClaimedTelemetryEventSchema, PaymentDocumentAttachedTelemetryEventSchema, PaymentFailedTelemetryEventSchema, PaymentRedirectedTelemetryEventSchema, PaymentRequestedTelemetryEventSchema, PaymentResolvedTelemetryEventSchema, PaymentSettledTelemetryEventSchema, PaymentSubmittedTelemetryEventSchema, PostHogTelemetryAdapter, ProvisioningSafeConfirmedTelemetryEventSchema, ProvisioningSafeCreatedTelemetryEventSchema, RecordingTelemetryAdapter, SYNCABLE_CAPXUL_ENVS, StreamCancelledTelemetryEventSchema, StreamClaimedTelemetryEventSchema, StreamCompletedTelemetryEventSchema, StreamCreatedTelemetryEventSchema, StreamFailedTelemetryEventSchema, SubaccountCreatedTelemetryEventSchema, SubaccountDeletedTelemetryEventSchema, SubaccountOpFailedTelemetryEventSchema, SubaccountRenamedTelemetryEventSchema, TELEMETRY_EVENT_NAMES, TELEMETRY_EVENT_SCHEMAS, TELEMETRY_JOURNEYS, TELEMETRY_PRODUCERS, TransferBackendReceivedTelemetryEventSchema, TransferConfirmedTelemetryEventSchema, TransferFailedTelemetryEventSchema, TransferRequestedTelemetryEventSchema, WithdrawalFailedTelemetryEventSchema, WithdrawalRequestedTelemetryEventSchema, WithdrawalSettledTelemetryEventSchema, WithdrawalSubmittedTelemetryEventSchema, createCapxulBeforeSend, createPostHogBrowserPageviewTracker, getTrackHandler, initializeCapxulBrowserAnalytics, initializePostHogBrowserAnalytics, productAppAnalytics, redactTelemetryEvent, redactTelemetryProps, sanitizePostHogBrowserEvent, setTrackHandler, stampTelemetryEnvelope, track, utilityAppAnalytics };
1513
+
1514
+ //# sourceMappingURL=index.mjs.map