@capxul/sdk 0.1.0-alpha.9 → 0.2.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { componentsGeneric, anyApi } from 'convex/server';
2
- import { getAddress, parseUnits, createPublicClient, http, encodeFunctionData } from 'viem';
3
2
  import { toSafeSmartAccount } from 'permissionless/accounts';
3
+ import { getAddress, parseUnits, createPublicClient, http, encodeFunctionData } from 'viem';
4
4
  import { entryPoint07Address, createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
5
5
  import { baseSepolia } from 'viem/chains';
6
+ import { deriveSafeAddress as deriveSafeAddress$1, defaultSafeDeriveConfig } from '@repo/safe-derive';
7
+ import { ConvexHttpClient } from 'convex/browser';
6
8
  import { setup, fromPromise, assign } from 'xstate';
7
- import { privateKeyToAccount } from 'viem/accounts';
9
+ import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
8
10
 
9
11
  // src/_generated/api.js
10
12
  var api = anyApi;
@@ -121,6 +123,160 @@ function identify(userId, traits) {
121
123
  debugLog(`[IDENTIFY] ${userId} ${formatDebugValue2(traits ?? "")}`);
122
124
  }
123
125
 
126
+ // ../config/src/chain.ts
127
+ var CAPXUL_PAYMENTS_ADDRESS = "0xe740ea65521edc9bef0ea75d30b5334711db99f4";
128
+ var TEST_USDC_ADDRESS = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
129
+ var CAPXUL_API_BASE_URL = "https://elated-oyster-269.convex.site";
130
+
131
+ // ../config/src/timing.ts
132
+ var FLOW_INVOKE_TIMEOUT_MS = 3e4;
133
+ var WEBHOOK_FRESHNESS_WINDOW_MS = 5 * 60 * 1e3;
134
+
135
+ // ../config/src/errors.ts
136
+ var CapxulError2 = class extends Error {
137
+ code;
138
+ details;
139
+ correlationId;
140
+ layer;
141
+ constructor(code, message, options) {
142
+ super(message, options?.cause ? { cause: options.cause } : void 0);
143
+ this.code = code;
144
+ this.details = options?.details;
145
+ this.correlationId = options?.correlationId;
146
+ this.layer = options?.layer;
147
+ }
148
+ };
149
+ var Errors = {
150
+ notAuthenticated: () => new CapxulError2("NOT_AUTHENTICATED", "Not authenticated"),
151
+ profileNotFound: (authUserId) => new CapxulError2("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`),
152
+ smartAccountMissing: (authUserId) => new CapxulError2("SMART_ACCOUNT_MISSING", `Smart account not provisioned for user ${authUserId}`),
153
+ envMissing: (name) => new CapxulError2("ENV_MISSING", `Environment variable ${name} not configured`),
154
+ openfortApi: (operation, cause) => new CapxulError2(
155
+ "PROVIDER_ERROR",
156
+ `Openfort ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
157
+ { cause, details: { provider: "openfort", operation } }
158
+ ),
159
+ shieldApi: (status, detail) => new CapxulError2(
160
+ "PROVIDER_ERROR",
161
+ `Shield API error (${status}): ${detail}`,
162
+ { details: { provider: "shield", status } }
163
+ ),
164
+ providerError: (provider, operation, cause) => (
165
+ // Public `message` is redacted to a fixed shape so provider-side
166
+ // exception text never leaks to the client. The original `cause`
167
+ // is preserved on `Error.cause` for server-side debugging via
168
+ // observability sinks (Sentry, console traces).
169
+ new CapxulError2(
170
+ "PROVIDER_ERROR",
171
+ `Provider error: ${provider} ${operation}`,
172
+ { cause, details: { provider, operation } }
173
+ )
174
+ ),
175
+ invalidInput: (field, reason) => new CapxulError2(
176
+ "INVALID_INPUT",
177
+ `Invalid ${field}: ${reason}`,
178
+ { details: { field, reason } }
179
+ ),
180
+ playerNotFound: (playerId) => new CapxulError2(
181
+ "PLAYER_NOT_FOUND",
182
+ playerId ? `Openfort player ${playerId} not found` : "Openfort player not found"
183
+ ),
184
+ accountNotFound: (accountId) => new CapxulError2(
185
+ "ACCOUNT_NOT_FOUND",
186
+ accountId ? `Openfort account ${accountId} not found` : "Openfort smart account not found"
187
+ ),
188
+ invalidRecipient: (reason) => new CapxulError2("INVALID_RECIPIENT", reason),
189
+ permissionDenied: (reason = "Permission denied") => new CapxulError2("PERMISSION_DENIED", reason),
190
+ notFound: (resource, id) => new CapxulError2(
191
+ "NOT_FOUND",
192
+ id ? `${resource} ${id} not found` : `${resource} not found`
193
+ ),
194
+ idempotencyConflict: (details) => new CapxulError2(
195
+ "IDEMPOTENCY_CONFLICT",
196
+ "Idempotency key was already used for a different request",
197
+ { details }
198
+ ),
199
+ emailDeliveryFailed: (detail, details) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
200
+ details
201
+ }),
202
+ rateLimited: (details) => new CapxulError2("RATE_LIMITED", "Request was rate limited", {
203
+ details: { ...details }
204
+ }),
205
+ internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
206
+ /**
207
+ * Verification gate. Surfaced when a request hits a verification
208
+ * boundary the actor cannot cross under their current state. Two
209
+ * variants share this code:
210
+ *
211
+ * - Rail gate (Withdrawals v1 W2, #465): the resolved
212
+ * `external_account.kind` routes to a withdrawal rail (e.g.
213
+ * `fiat_offramp`, `card_payout`) that is not yet supported. Carries
214
+ * `details.rail` + `details.currentKind`.
215
+ * - KYC tier gate (legacy / future): the actor's KYC tier is below
216
+ * the required tier. Carries `details.requiredTier`.
217
+ *
218
+ * Code is shared because both expose the same UX shape ("you cannot
219
+ * proceed until verification advances"); the `details.*` keys
220
+ * differentiate the route.
221
+ */
222
+ verificationRequired: (details) => {
223
+ const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
224
+ return new CapxulError2("VERIFICATION_REQUIRED", message, {
225
+ details: { ...details }
226
+ });
227
+ }
228
+ };
229
+
230
+ // ../config/src/safe.ts
231
+ var SAFE_PROXY_FACTORY = "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67";
232
+ var SAFE_L2_SINGLETON = "0x29fcb43b46531bca003ddc8fcb67ffe91900c762";
233
+ var SAFE_MODULE_SETUP = "0x2dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47";
234
+ var SAFE_4337_MODULE = "0x75cf11467937ce3f2f357ce24ffc3dbf8fd5c226";
235
+
236
+ // ../config/src/org-roles.ts
237
+ function roleKeyFromLabel(label) {
238
+ const bytes = new TextEncoder().encode(label);
239
+ const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
240
+ return "0x" + hex.padEnd(64, "0");
241
+ }
242
+ roleKeyFromLabel("OWNER");
243
+ roleKeyFromLabel("FINANCE_MANAGER");
244
+ roleKeyFromLabel("PAYMENTS_OPERATOR");
245
+ async function buildSafeAccount(signer, chain) {
246
+ try {
247
+ const publicClient = createPublicClient({
248
+ chain: baseSepolia,
249
+ transport: http(chain.rpcUrl)
250
+ });
251
+ return await toSafeSmartAccount({
252
+ client: publicClient,
253
+ entryPoint: { address: entryPoint07Address, version: "0.7" },
254
+ version: "1.4.1",
255
+ owners: [signer],
256
+ saltNonce: computeSaltNonce(signer.address),
257
+ safeSingletonAddress: SAFE_L2_SINGLETON,
258
+ safeProxyFactoryAddress: SAFE_PROXY_FACTORY,
259
+ safeModuleSetupAddress: SAFE_MODULE_SETUP,
260
+ safe4337ModuleAddress: SAFE_4337_MODULE,
261
+ safeModules: [],
262
+ setupTransactions: []
263
+ });
264
+ } catch (cause) {
265
+ throw new CapxulError({
266
+ code: "NETWORK_ERROR",
267
+ message: cause instanceof Error ? cause.message : String(cause),
268
+ cause,
269
+ details: { chainId: chain.chainId }
270
+ });
271
+ }
272
+ }
273
+ function computeSaltNonce(ownerAddress) {
274
+ return BigInt(`0x${ownerAddress.toLowerCase().slice(2).padEnd(64, "0")}`);
275
+ }
276
+ function deriveSafeAddress(signerAddress) {
277
+ return deriveSafeAddress$1(signerAddress, defaultSafeDeriveConfig);
278
+ }
279
+
124
280
  // ../platform-kernel/src/ids.ts
125
281
  function makePrefixedIdConstructor(prefix, fieldName) {
126
282
  const re = new RegExp(`^${prefix}_[A-Za-z0-9_\\-]+$`);
@@ -139,7 +295,7 @@ var toAccountId = makePrefixedIdConstructor(
139
295
  );
140
296
  var toOrganizationId = makePrefixedIdConstructor("org", "organizationId");
141
297
  var toMemberId = makePrefixedIdConstructor(
142
- "mem",
298
+ "mb",
143
299
  "memberId"
144
300
  );
145
301
  var toSafeId = makePrefixedIdConstructor(
@@ -253,13 +409,13 @@ function brandExternalAccount(raw) {
253
409
  function createExternalAccountsClient(config = {}) {
254
410
  return {
255
411
  retrieve: async (externalAccountId) => {
256
- if (!config.data) {
412
+ if (!config._data) {
257
413
  return stub(
258
414
  "externalAccounts.retrieve"
259
415
  );
260
416
  }
261
417
  const [err, raw] = await tryCatch(
262
- config.data.query(api.externalAccounts.queries.retrievePersonal, {
418
+ config._data.query(api.externalAccounts.queries.retrievePersonal, {
263
419
  externalAccountId
264
420
  })
265
421
  );
@@ -281,11 +437,11 @@ function createExternalAccountsClient(config = {}) {
281
437
  return [null, brandExternalAccount(raw)];
282
438
  },
283
439
  remove: async (externalAccountId) => {
284
- if (!config.data) {
440
+ if (!config._data) {
285
441
  return stub("externalAccounts.remove");
286
442
  }
287
443
  const [err] = await tryCatch(
288
- config.data.mutation(api.externalAccounts.mutations.removePersonal, {
444
+ config._data.mutation(api.externalAccounts.mutations.removePersonal, {
289
445
  externalAccountId
290
446
  })
291
447
  );
@@ -300,17 +456,203 @@ function createExternalAccountsClient(config = {}) {
300
456
  };
301
457
  }
302
458
 
459
+ // src/core/sub-accounts.ts
460
+ function malformedWireError(reason, raw) {
461
+ return new CapxulError({
462
+ code: "PROVIDER_ERROR",
463
+ message: `convex brandSubAccount failed: ${reason}`,
464
+ details: {
465
+ provider: "convex",
466
+ operation: "brandSubAccount",
467
+ reason,
468
+ // PII discipline (`.claude/rules/posthog.md`): user-authored
469
+ // strings on the wire (`name`, `purpose`) are customer-confidential
470
+ // — sub-account names like "Q3 Acquisition Reserve" or
471
+ // "Vendor ABC payments" must not flow into telemetry. We emit a
472
+ // structural keys-only sample via a strict ALLOWLIST so any future
473
+ // wire-shape addition (e.g. `recipientEmail`, `tags`) is dropped
474
+ // by construction rather than leaked through a denylist gap.
475
+ sample: safeSampleShape(raw)
476
+ }
477
+ });
478
+ }
479
+ function safeSampleShape(raw) {
480
+ if (raw === null || typeof raw !== "object") {
481
+ return { type: typeof raw };
482
+ }
483
+ const r = raw;
484
+ const balance = r.balance;
485
+ return {
486
+ object: typeof r.object === "string" ? r.object : typeof r.object,
487
+ idPresent: typeof r.id === "string" && r.id.length > 0,
488
+ // First 4 chars only — enough to distinguish "sub_" prefixed IDs
489
+ // from accidental other resource IDs without leaking the full ID.
490
+ idPrefix: typeof r.id === "string" ? r.id.slice(0, 4) : void 0,
491
+ parentKind: r.parent !== null && typeof r.parent === "object" ? r.parent.kind : typeof r.parent,
492
+ status: r.status,
493
+ hasName: typeof r.name === "string",
494
+ hasPurpose: r.purpose !== void 0,
495
+ balanceShape: balance !== null && typeof balance === "object" ? Object.keys(balance).sort() : typeof balance,
496
+ createdAtType: typeof r.createdAt,
497
+ updatedAtType: typeof r.updatedAt
498
+ };
499
+ }
500
+ function isMoneyShape(v) {
501
+ if (typeof v !== "object" || v === null) return false;
502
+ const m = v;
503
+ return typeof m.value === "string" && typeof m.currency === "string";
504
+ }
505
+ function isParentShape(v) {
506
+ if (typeof v !== "object" || v === null) return false;
507
+ const p = v;
508
+ return (p.kind === "account" || p.kind === "organization") && typeof p.id === "string";
509
+ }
510
+ function isFiniteNonNegativeInteger(v) {
511
+ return typeof v === "number" && Number.isFinite(v) && Number.isInteger(v) && v >= 0;
512
+ }
513
+ function validateWireSubAccount(raw) {
514
+ if (typeof raw !== "object" || raw === null) {
515
+ return { ok: false, reason: "not an object" };
516
+ }
517
+ const r = raw;
518
+ if (r.object !== "sub_account") {
519
+ return { ok: false, reason: `object must be "sub_account" (got ${String(r.object)})` };
520
+ }
521
+ if (typeof r.id !== "string" || r.id.length === 0) {
522
+ return { ok: false, reason: "id must be a non-empty string" };
523
+ }
524
+ if (!isParentShape(r.parent)) {
525
+ return { ok: false, reason: "parent must be { kind: 'account' | 'organization', id: string }" };
526
+ }
527
+ if (typeof r.name !== "string") {
528
+ return { ok: false, reason: "name must be a string" };
529
+ }
530
+ if (r.purpose !== void 0 && typeof r.purpose !== "string") {
531
+ return { ok: false, reason: "purpose must be a string when present" };
532
+ }
533
+ if (r.status !== "active" && r.status !== "archived") {
534
+ return { ok: false, reason: `status must be "active" | "archived" (got ${String(r.status)})` };
535
+ }
536
+ if (!isMoneyShape(r.balance)) {
537
+ return { ok: false, reason: "balance must be { value: string, currency: string }" };
538
+ }
539
+ if (!isFiniteNonNegativeInteger(r.createdAt)) {
540
+ return { ok: false, reason: "createdAt must be a finite non-negative integer (epoch ms)" };
541
+ }
542
+ if (r.updatedAt !== void 0 && !isFiniteNonNegativeInteger(r.updatedAt)) {
543
+ return { ok: false, reason: "updatedAt must be a finite non-negative integer when present" };
544
+ }
545
+ return { ok: true, value: r };
546
+ }
547
+ function brandSubAccount(raw) {
548
+ const result = validateWireSubAccount(raw);
549
+ if (!result.ok) {
550
+ throw malformedWireError(result.reason, raw);
551
+ }
552
+ const wire = result.value;
553
+ return {
554
+ object: wire.object,
555
+ id: toSubAccountId(wire.id),
556
+ parent: wire.parent,
557
+ name: wire.name,
558
+ ...wire.purpose !== void 0 ? { purpose: wire.purpose } : {},
559
+ status: wire.status,
560
+ balance: wire.balance,
561
+ createdAt: new Date(wire.createdAt).toISOString()
562
+ };
563
+ }
564
+ function tryBrandSubAccount(raw) {
565
+ try {
566
+ return [null, brandSubAccount(raw)];
567
+ } catch (err) {
568
+ if (err instanceof CapxulError && err.code === "PROVIDER_ERROR") {
569
+ return [err, null];
570
+ }
571
+ return [
572
+ malformedWireError(
573
+ err instanceof Error ? err.message : String(err),
574
+ raw
575
+ ),
576
+ null
577
+ ];
578
+ }
579
+ }
580
+ function createSubAccountsClient(config = {}) {
581
+ return {
582
+ retrieve: async (subAccountId) => {
583
+ if (!config._data) {
584
+ return stub("subAccounts.retrieve");
585
+ }
586
+ const [err, raw] = await tryCatch(
587
+ config._data.query(api.subAccounts.queries.retrieve, {
588
+ subAccountId
589
+ })
590
+ );
591
+ if (err) {
592
+ return [
593
+ fromConvexError(err),
594
+ null
595
+ ];
596
+ }
597
+ if (!raw) {
598
+ return [
599
+ new CapxulError({
600
+ code: "NOT_FOUND",
601
+ message: `sub_account ${subAccountId} not found`
602
+ }),
603
+ null
604
+ ];
605
+ }
606
+ const [brandErr, branded] = tryBrandSubAccount(raw);
607
+ if (brandErr) {
608
+ return [brandErr, null];
609
+ }
610
+ return [null, branded];
611
+ },
612
+ remove: async (subAccountId) => {
613
+ if (!config._data) {
614
+ return stub("subAccounts.remove");
615
+ }
616
+ const [err, raw] = await tryCatch(
617
+ config._data.mutation(api.subAccounts.mutations.archive, {
618
+ subAccountId
619
+ })
620
+ );
621
+ if (err) {
622
+ return [
623
+ fromConvexError(err),
624
+ null
625
+ ];
626
+ }
627
+ if (!raw) {
628
+ return [
629
+ new CapxulError({
630
+ code: "NOT_FOUND",
631
+ message: `sub_account ${subAccountId} not found`
632
+ }),
633
+ null
634
+ ];
635
+ }
636
+ const [brandErr, branded] = tryBrandSubAccount(raw);
637
+ if (brandErr) {
638
+ return [brandErr, null];
639
+ }
640
+ return [null, branded];
641
+ }
642
+ };
643
+ }
644
+
303
645
  // src/core/accounts.ts
304
646
  function createAccountExternalAccountsClient(config) {
305
647
  return {
306
648
  create: async (input) => {
307
- if (!config.data) {
649
+ if (!config._data) {
308
650
  return stub(
309
651
  "accounts.externalAccounts.create"
310
652
  );
311
653
  }
312
654
  const [err, raw] = await tryCatch(
313
- config.data.mutation(
655
+ config._data.mutation(
314
656
  api.externalAccounts.mutations.createPersonal,
315
657
  {
316
658
  kind: input.kind,
@@ -348,13 +690,13 @@ function createAccountExternalAccountsClient(config) {
348
690
  ];
349
691
  },
350
692
  list: async (input) => {
351
- if (!config.data) {
693
+ if (!config._data) {
352
694
  return stub(
353
695
  "accounts.externalAccounts.list"
354
696
  );
355
697
  }
356
698
  const [err, result] = await tryCatch(
357
- config.data.query(api.externalAccounts.queries.listPersonal, {
699
+ config._data.query(api.externalAccounts.queries.listPersonal, {
358
700
  limit: input.limit,
359
701
  cursor: input.cursor
360
702
  })
@@ -377,13 +719,13 @@ function createAccountExternalAccountsClient(config) {
377
719
  ];
378
720
  },
379
721
  retrieve: async (externalAccountId) => {
380
- if (!config.data) {
722
+ if (!config._data) {
381
723
  return stub(
382
724
  "accounts.externalAccounts.retrieve"
383
725
  );
384
726
  }
385
727
  const [err, raw] = await tryCatch(
386
- config.data.query(api.externalAccounts.queries.retrievePersonal, {
728
+ config._data.query(api.externalAccounts.queries.retrievePersonal, {
387
729
  externalAccountId
388
730
  })
389
731
  );
@@ -410,11 +752,11 @@ function createAccountExternalAccountsClient(config) {
410
752
  ];
411
753
  },
412
754
  remove: async (externalAccountId) => {
413
- if (!config.data) {
755
+ if (!config._data) {
414
756
  return stub("accounts.externalAccounts.remove");
415
757
  }
416
758
  const [err] = await tryCatch(
417
- config.data.mutation(api.externalAccounts.mutations.removePersonal, {
759
+ config._data.mutation(api.externalAccounts.mutations.removePersonal, {
418
760
  externalAccountId
419
761
  })
420
762
  );
@@ -428,14 +770,162 @@ function createAccountExternalAccountsClient(config) {
428
770
  }
429
771
  };
430
772
  }
773
+ function createAccountSubAccountsClient(config) {
774
+ return {
775
+ create: async (input) => {
776
+ if (!config._data) {
777
+ return stub(
778
+ "accounts.subAccounts.create"
779
+ );
780
+ }
781
+ const [err, raw] = await tryCatch(
782
+ config._data.mutation(api.subAccounts.mutations.create, {
783
+ parent: { kind: "account", id: input.accountId },
784
+ name: input.name,
785
+ purpose: input.purpose
786
+ })
787
+ );
788
+ if (err) {
789
+ return [
790
+ fromConvexError(err),
791
+ null
792
+ ];
793
+ }
794
+ if (!raw) {
795
+ return [
796
+ new CapxulError({
797
+ code: "NOT_FOUND",
798
+ message: "sub_account creation returned no resource"
799
+ }),
800
+ null
801
+ ];
802
+ }
803
+ const [brandErr, branded] = tryBrandSubAccount(raw);
804
+ if (brandErr) {
805
+ return [
806
+ brandErr,
807
+ null
808
+ ];
809
+ }
810
+ return [null, branded];
811
+ },
812
+ list: async (input) => {
813
+ if (!config._data) {
814
+ return stub(
815
+ "accounts.subAccounts.list"
816
+ );
817
+ }
818
+ const [err, rows] = await tryCatch(
819
+ config._data.query(api.subAccounts.queries.listByAccount, {
820
+ accountId: input.accountId
821
+ })
822
+ );
823
+ if (err) {
824
+ return [
825
+ fromConvexError(err),
826
+ null
827
+ ];
828
+ }
829
+ const branded = [];
830
+ for (const row of rows) {
831
+ const [brandErr, value] = tryBrandSubAccount(row);
832
+ if (brandErr) {
833
+ return [
834
+ brandErr,
835
+ null
836
+ ];
837
+ }
838
+ branded.push(value);
839
+ }
840
+ return [
841
+ null,
842
+ {
843
+ object: "list",
844
+ data: branded,
845
+ page: { hasMore: false }
846
+ }
847
+ ];
848
+ },
849
+ retrieve: async (subAccountId) => {
850
+ if (!config._data) {
851
+ return stub(
852
+ "accounts.subAccounts.retrieve"
853
+ );
854
+ }
855
+ const [err, raw] = await tryCatch(
856
+ config._data.query(api.subAccounts.queries.retrieve, {
857
+ subAccountId
858
+ })
859
+ );
860
+ if (err) {
861
+ return [
862
+ fromConvexError(err),
863
+ null
864
+ ];
865
+ }
866
+ if (!raw) {
867
+ return [
868
+ new CapxulError({
869
+ code: "NOT_FOUND",
870
+ message: `sub_account ${subAccountId} not found`
871
+ }),
872
+ null
873
+ ];
874
+ }
875
+ const [brandErr, branded] = tryBrandSubAccount(raw);
876
+ if (brandErr) {
877
+ return [
878
+ brandErr,
879
+ null
880
+ ];
881
+ }
882
+ return [null, branded];
883
+ },
884
+ remove: async (subAccountId) => {
885
+ if (!config._data) {
886
+ return stub(
887
+ "accounts.subAccounts.remove"
888
+ );
889
+ }
890
+ const [err, raw] = await tryCatch(
891
+ config._data.mutation(api.subAccounts.mutations.archive, {
892
+ subAccountId
893
+ })
894
+ );
895
+ if (err) {
896
+ return [
897
+ fromConvexError(err),
898
+ null
899
+ ];
900
+ }
901
+ if (!raw) {
902
+ return [
903
+ new CapxulError({
904
+ code: "NOT_FOUND",
905
+ message: `sub_account ${subAccountId} not found`
906
+ }),
907
+ null
908
+ ];
909
+ }
910
+ const [brandErr, branded] = tryBrandSubAccount(raw);
911
+ if (brandErr) {
912
+ return [
913
+ brandErr,
914
+ null
915
+ ];
916
+ }
917
+ return [null, branded];
918
+ }
919
+ };
920
+ }
431
921
  function createAccountsClient(config = {}) {
432
922
  return {
433
923
  retrieve: async (accountId) => {
434
- if (!config.data) {
924
+ if (!config._data) {
435
925
  return stub("accounts.retrieve");
436
926
  }
437
927
  try {
438
- const account = await config.data.query(
928
+ const account = await config._data.query(
439
929
  api.openfort.queries.getMyAccount,
440
930
  {}
441
931
  );
@@ -459,7 +949,7 @@ function createAccountsClient(config = {}) {
459
949
  },
460
950
  lookup: async () => stub("accounts.lookup"),
461
951
  update: async (input) => {
462
- if (!config.data) {
952
+ if (!config._data) {
463
953
  return stub("accounts.update");
464
954
  }
465
955
  if (input.countryCode !== void 0) {
@@ -473,7 +963,7 @@ function createAccountsClient(config = {}) {
473
963
  ];
474
964
  }
475
965
  try {
476
- const current = await config.data.query(
966
+ const current = await config._data.query(
477
967
  api.openfort.queries.getMyAccount,
478
968
  {}
479
969
  );
@@ -490,11 +980,11 @@ function createAccountsClient(config = {}) {
490
980
  null
491
981
  ];
492
982
  }
493
- await config.data.mutation(api.openfort.mutations.updateProfile, {
983
+ await config._data.mutation(api.openfort.mutations.updateProfile, {
494
984
  displayName: input.name,
495
985
  username: input.username
496
986
  });
497
- const updated = await config.data.query(
987
+ const updated = await config._data.query(
498
988
  api.openfort.queries.getMyAccount,
499
989
  {}
500
990
  );
@@ -504,7 +994,7 @@ function createAccountsClient(config = {}) {
504
994
  }
505
995
  },
506
996
  provisionPersonal: async (input) => {
507
- if (!config.data) {
997
+ if (!config._data) {
508
998
  return stub(
509
999
  "accounts.provisionPersonal"
510
1000
  );
@@ -519,17 +1009,17 @@ function createAccountsClient(config = {}) {
519
1009
  ];
520
1010
  }
521
1011
  try {
522
- await config.data.mutation(
1012
+ await config._data.mutation(
523
1013
  api.safe.mutations.provisionLocalPersonalAccount,
524
1014
  {
525
1015
  displayName: input.displayName,
526
1016
  username: input.username,
527
1017
  countryCode: input.countryCode,
528
1018
  eoaAddress: input.signerProvider.signerAddress,
529
- safeAddress: input.signerProvider.safeAddress
1019
+ safeAddress: deriveSafeAddress(input.signerProvider.signerAddress)
530
1020
  }
531
1021
  );
532
- const account = await config.data.query(
1022
+ const account = await config._data.query(
533
1023
  api.openfort.queries.getMyAccount,
534
1024
  {}
535
1025
  );
@@ -552,177 +1042,99 @@ function createAccountsClient(config = {}) {
552
1042
  },
553
1043
  safes: {
554
1044
  retrieve: async (safeId) => {
555
- if (!config.data) {
556
- return stub("accounts.safes.retrieve");
557
- }
558
- try {
559
- const safe = await config.data.query(
560
- api.safe.queries.retrieveAccountSafe,
561
- { safeId }
562
- );
563
- if (!safe) {
564
- return [
565
- new CapxulError({
566
- code: "NOT_FOUND",
567
- message: `safe ${safeId} not found`
568
- }),
569
- null
570
- ];
571
- }
572
- return [null, safe];
573
- } catch (cause) {
574
- return [
575
- fromConvexError(cause),
576
- null
577
- ];
578
- }
579
- }
580
- },
581
- kycProfiles: {
582
- create: async () => stub("accounts.kycProfiles.create"),
583
- retrieve: async () => stub("accounts.kycProfiles.retrieve")
584
- },
585
- externalAccounts: createAccountExternalAccountsClient(config),
586
- subAccounts: {
587
- create: async () => stub("accounts.subAccounts.create"),
588
- list: async () => stub("accounts.subAccounts.list"),
589
- retrieve: async () => stub("accounts.subAccounts.retrieve"),
590
- remove: async () => stub("accounts.subAccounts.remove")
591
- },
592
- balanceLedger: {
593
- list: async () => stub(
594
- "accounts.balanceLedger.list"
595
- ),
596
- retrieve: async () => stub(
597
- "accounts.balanceLedger.retrieve"
598
- )
599
- }
600
- };
601
- }
602
-
603
- // src/core/api-keys.ts
604
- function createApiKeysClient() {
605
- return {
606
- create: async () => stub("apiKeys.create"),
607
- retrieve: async () => stub("apiKeys.retrieve"),
608
- list: async () => stub("apiKeys.list"),
609
- revoke: async () => stub("apiKeys.revoke")
610
- };
611
- }
612
-
613
- // ../config/src/chain.ts
614
- var CAPXUL_PAYMENTS_ADDRESS = "0xe740ea65521edc9bef0ea75d30b5334711db99f4";
615
- var TEST_USDC_ADDRESS = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
616
- var CAPXUL_API_BASE_URL = "https://elated-oyster-269.convex.site";
617
-
618
- // ../config/src/timing.ts
619
- var FLOW_INVOKE_TIMEOUT_MS = 3e4;
620
- var WEBHOOK_FRESHNESS_WINDOW_MS = 5 * 60 * 1e3;
621
-
622
- // ../config/src/errors.ts
623
- var CapxulError2 = class extends Error {
624
- code;
625
- details;
626
- correlationId;
627
- layer;
628
- constructor(code, message, options) {
629
- super(message, options?.cause ? { cause: options.cause } : void 0);
630
- this.code = code;
631
- this.details = options?.details;
632
- this.correlationId = options?.correlationId;
633
- this.layer = options?.layer;
634
- }
635
- };
636
- var Errors = {
637
- notAuthenticated: () => new CapxulError2("NOT_AUTHENTICATED", "Not authenticated"),
638
- profileNotFound: (authUserId) => new CapxulError2("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`),
639
- smartAccountMissing: (authUserId) => new CapxulError2("SMART_ACCOUNT_MISSING", `Smart account not provisioned for user ${authUserId}`),
640
- envMissing: (name) => new CapxulError2("ENV_MISSING", `Environment variable ${name} not configured`),
641
- openfortApi: (operation, cause) => new CapxulError2(
642
- "PROVIDER_ERROR",
643
- `Openfort ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
644
- { cause, details: { provider: "openfort", operation } }
645
- ),
646
- shieldApi: (status, detail) => new CapxulError2(
647
- "PROVIDER_ERROR",
648
- `Shield API error (${status}): ${detail}`,
649
- { details: { provider: "shield", status } }
650
- ),
651
- providerError: (provider, operation, cause) => new CapxulError2(
652
- "PROVIDER_ERROR",
653
- `${provider} ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
654
- { cause, details: { provider, operation } }
655
- ),
656
- invalidInput: (field, reason) => new CapxulError2(
657
- "INVALID_INPUT",
658
- `Invalid ${field}: ${reason}`,
659
- { details: { field, reason } }
660
- ),
661
- playerNotFound: (playerId) => new CapxulError2(
662
- "PLAYER_NOT_FOUND",
663
- playerId ? `Openfort player ${playerId} not found` : "Openfort player not found"
664
- ),
665
- accountNotFound: (accountId) => new CapxulError2(
666
- "ACCOUNT_NOT_FOUND",
667
- accountId ? `Openfort account ${accountId} not found` : "Openfort smart account not found"
668
- ),
669
- invalidRecipient: (reason) => new CapxulError2("INVALID_RECIPIENT", reason),
670
- permissionDenied: (reason = "Permission denied") => new CapxulError2("PERMISSION_DENIED", reason),
671
- notFound: (resource, id) => new CapxulError2(
672
- "NOT_FOUND",
673
- id ? `${resource} ${id} not found` : `${resource} not found`
674
- ),
675
- idempotencyConflict: (details) => new CapxulError2(
676
- "IDEMPOTENCY_CONFLICT",
677
- "Idempotency key was already used for a different request",
678
- { details }
679
- ),
680
- emailDeliveryFailed: (detail, details) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
681
- details
682
- }),
683
- rateLimited: (details) => new CapxulError2("RATE_LIMITED", "Request was rate limited", {
684
- details: { ...details }
685
- }),
686
- internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
687
- /**
688
- * Verification gate. Surfaced when a request hits a verification
689
- * boundary the actor cannot cross under their current state. Two
690
- * variants share this code:
691
- *
692
- * - Rail gate (Withdrawals v1 W2, #465): the resolved
693
- * `external_account.kind` routes to a withdrawal rail (e.g.
694
- * `fiat_offramp`, `card_payout`) that is not yet supported. Carries
695
- * `details.rail` + `details.currentKind`.
696
- * - KYC tier gate (legacy / future): the actor's KYC tier is below
697
- * the required tier. Carries `details.requiredTier`.
698
- *
699
- * Code is shared because both expose the same UX shape ("you cannot
700
- * proceed until verification advances"); the `details.*` keys
701
- * differentiate the route.
702
- */
703
- verificationRequired: (details) => {
704
- const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
705
- return new CapxulError2("VERIFICATION_REQUIRED", message, {
706
- details: { ...details }
707
- });
708
- }
709
- };
710
-
711
- // ../config/src/safe.ts
712
- var SAFE_PROXY_FACTORY = "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67";
713
- var SAFE_L2_SINGLETON = "0x29fcb43b46531bca003ddc8fcb67ffe91900c762";
714
- var SAFE_MODULE_SETUP = "0x2dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47";
715
- var SAFE_4337_MODULE = "0x75cf11467937ce3f2f357ce24ffc3dbf8fd5c226";
1045
+ if (!config._data) {
1046
+ return stub("accounts.safes.retrieve");
1047
+ }
1048
+ try {
1049
+ const safe = await config._data.query(
1050
+ api.safe.queries.retrieveAccountSafe,
1051
+ { safeId }
1052
+ );
1053
+ if (!safe) {
1054
+ return [
1055
+ new CapxulError({
1056
+ code: "NOT_FOUND",
1057
+ message: `safe ${safeId} not found`
1058
+ }),
1059
+ null
1060
+ ];
1061
+ }
1062
+ return [null, safe];
1063
+ } catch (cause) {
1064
+ return [
1065
+ fromConvexError(cause),
1066
+ null
1067
+ ];
1068
+ }
1069
+ }
1070
+ },
1071
+ kycProfiles: {
1072
+ create: async () => stub("accounts.kycProfiles.create"),
1073
+ retrieve: async () => stub("accounts.kycProfiles.retrieve")
1074
+ },
1075
+ externalAccounts: createAccountExternalAccountsClient(config),
1076
+ subAccounts: createAccountSubAccountsClient(config),
1077
+ balanceLedger: {
1078
+ list: async (input) => {
1079
+ if (!config._data) {
1080
+ return stub(
1081
+ "accounts.balanceLedger.list"
1082
+ );
1083
+ }
1084
+ try {
1085
+ const accountId = input.accountId.replace(/^acct_/, "");
1086
+ const page = await config._data.query(
1087
+ api.balanceLedger.queries.listForAccount,
1088
+ { accountId, limit: input.limit, cursor: input.cursor }
1089
+ );
1090
+ return [null, page];
1091
+ } catch (cause) {
1092
+ return [fromConvexError(cause), null];
1093
+ }
1094
+ },
1095
+ retrieve: async (entryId) => {
1096
+ if (!config._data) {
1097
+ return stub(
1098
+ "accounts.balanceLedger.retrieve"
1099
+ );
1100
+ }
1101
+ try {
1102
+ const entry = await config._data.query(
1103
+ api.balanceLedger.queries.retrieve,
1104
+ { entryId }
1105
+ );
1106
+ if (!entry) {
1107
+ return [
1108
+ new CapxulError({
1109
+ code: "NOT_FOUND",
1110
+ message: `balance_ledger_entry ${entryId} not found`
1111
+ }),
1112
+ null
1113
+ ];
1114
+ }
1115
+ return [null, entry];
1116
+ } catch (cause) {
1117
+ return [fromConvexError(cause), null];
1118
+ }
1119
+ }
1120
+ }
1121
+ };
1122
+ }
716
1123
 
717
- // ../config/src/org-roles.ts
718
- function roleKeyFromLabel(label) {
719
- const bytes = new TextEncoder().encode(label);
720
- const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
721
- return "0x" + hex.padEnd(64, "0");
1124
+ // src/core/api-keys.ts
1125
+ function createApiKeysClient() {
1126
+ return {
1127
+ create: async () => stub("apiKeys.create"),
1128
+ retrieve: async () => stub("apiKeys.retrieve"),
1129
+ list: async () => stub("apiKeys.list"),
1130
+ revoke: async () => stub("apiKeys.revoke")
1131
+ };
1132
+ }
1133
+ function createDefaultDataClient(convexUrl, jwt) {
1134
+ const client = new ConvexHttpClient(convexUrl);
1135
+ client.setAuth(jwt);
1136
+ return client;
722
1137
  }
723
- roleKeyFromLabel("OWNER");
724
- roleKeyFromLabel("FINANCE_MANAGER");
725
- roleKeyFromLabel("TEAM_LEAD");
726
1138
 
727
1139
  // src/transport.ts
728
1140
  function makeHttpTransport(config) {
@@ -1053,7 +1465,7 @@ function readNonEmptyString(value) {
1053
1465
 
1054
1466
  // src/core/auth.ts
1055
1467
  function createAuthClient(config = {}) {
1056
- let dataClient = config.data ?? null;
1468
+ let dataClient = config._data ?? null;
1057
1469
  const sessionStore = config.auth?.sessionStore ?? createMemorySessionStore();
1058
1470
  const getTransport = createTransportProvider(config);
1059
1471
  return {
@@ -1109,11 +1521,20 @@ function createAuthClient(config = {}) {
1109
1521
  ).toISOString()
1110
1522
  };
1111
1523
  sessionStore.set(session);
1112
- if (config.auth?.createDataClient) {
1524
+ if (!dataClient) {
1113
1525
  try {
1114
- dataClient = await config.auth.createDataClient(session);
1115
- mutableConfig(config).data = dataClient;
1116
- transport.markAuthenticated({ dataClient });
1526
+ const convexUrl = transport.convexUrl;
1527
+ if (!convexUrl || !session.convexJwt) {
1528
+ return [
1529
+ new CapxulError({
1530
+ code: "NETWORK_ERROR",
1531
+ message: "Cannot create data client: missing convex URL or JWT."
1532
+ }),
1533
+ null
1534
+ ];
1535
+ }
1536
+ dataClient = createDefaultDataClient(convexUrl, session.convexJwt);
1537
+ mutableConfig(config)._data = dataClient;
1117
1538
  } catch (cause) {
1118
1539
  return [
1119
1540
  new CapxulError({
@@ -1124,7 +1545,15 @@ function createAuthClient(config = {}) {
1124
1545
  null
1125
1546
  ];
1126
1547
  }
1548
+ } else {
1549
+ const injected = dataClient;
1550
+ if (typeof injected.refreshAuth === "function") {
1551
+ injected.refreshAuth();
1552
+ } else if (typeof injected.setAuth === "function" && session.convexJwt) {
1553
+ injected.setAuth(session.convexJwt);
1554
+ }
1127
1555
  }
1556
+ transport.markAuthenticated({ dataClient });
1128
1557
  if (!dataClient) {
1129
1558
  return [
1130
1559
  new CapxulError({
@@ -1152,7 +1581,7 @@ function createAuthClient(config = {}) {
1152
1581
  },
1153
1582
  completeBootstrap: async (input) => {
1154
1583
  const session = sessionStore.get();
1155
- const data = dataClient ?? config.data;
1584
+ const data = dataClient ?? config._data;
1156
1585
  if (!session || !data) {
1157
1586
  return [
1158
1587
  new CapxulError({
@@ -1162,23 +1591,29 @@ function createAuthClient(config = {}) {
1162
1591
  null
1163
1592
  ];
1164
1593
  }
1165
- if (input.signerProvider.kind !== "local-private-key") {
1594
+ const signerAddress = config.signer?.address;
1595
+ if (!signerAddress) {
1166
1596
  return [
1167
1597
  new CapxulError({
1168
1598
  code: "INVALID_INPUT",
1169
- message: "completeBootstrap currently supports local-private-key signer providers only."
1599
+ message: "completeBootstrap requires a signer to be configured on the client."
1170
1600
  }),
1171
1601
  null
1172
1602
  ];
1173
1603
  }
1174
1604
  try {
1605
+ const safeAddress = deriveSafeAddress(signerAddress);
1175
1606
  const result = await data.mutation(api.authBootstrap.completeBootstrap, {
1176
1607
  bootstrapToken: input.bootstrapToken,
1177
1608
  sessionToken: session.token,
1178
1609
  username: input.username,
1179
1610
  displayName: input.displayName,
1180
1611
  countryCode: input.countryCode,
1181
- signerProvider: input.signerProvider
1612
+ signerProvider: {
1613
+ kind: "local-private-key",
1614
+ signerAddress,
1615
+ safeAddress
1616
+ }
1182
1617
  });
1183
1618
  return [null, { kind: "authenticated", session, ...result }];
1184
1619
  } catch (cause) {
@@ -1192,7 +1627,7 @@ function createAuthClient(config = {}) {
1192
1627
  signOut: async () => {
1193
1628
  sessionStore.clear();
1194
1629
  dataClient = null;
1195
- mutableConfig(config).data = void 0;
1630
+ mutableConfig(config)._data = void 0;
1196
1631
  const transport = getTransport();
1197
1632
  transport?.clearAuth();
1198
1633
  return [null, void 0];
@@ -1263,6 +1698,9 @@ async function postBetterAuth(transport, path, body, code, signal) {
1263
1698
  }
1264
1699
  return [null, text ? JSON.parse(text) : void 0];
1265
1700
  } catch (cause) {
1701
+ if (cause instanceof CapxulError) {
1702
+ return [cause, null];
1703
+ }
1266
1704
  return [
1267
1705
  new CapxulError({
1268
1706
  code: "NETWORK_ERROR",
@@ -1301,7 +1739,7 @@ function parseBetterAuthError(text) {
1301
1739
  }
1302
1740
  }
1303
1741
  function isCapxulErrorCode2(code) {
1304
- return code === "NOT_AUTHENTICATED" || code === "EMAIL_DELIVERY_FAILED" || code === "INVALID_INPUT" || code === "RATE_LIMITED" || code === "NETWORK_ERROR" || code === "API_KEY_INVALID" || code === "API_KEY_EXPIRED";
1742
+ return code === "NOT_AUTHENTICATED" || code === "EMAIL_DELIVERY_FAILED" || code === "INVALID_INPUT" || code === "RATE_LIMITED" || code === "NETWORK_ERROR" || code === "API_KEY_INVALID" || code === "API_KEY_EXPIRED" || code === "INTERNAL_ERROR" || code === "ENV_MISSING" || code === "UNKNOWN" || code === "PROVIDER_ERROR";
1305
1743
  }
1306
1744
  async function exchangeConvexToken(transport, config, token, signal) {
1307
1745
  const path = config.auth?.convexTokenUrl ?? "/convex/token";
@@ -1331,6 +1769,9 @@ async function exchangeConvexToken(transport, config, token, signal) {
1331
1769
  }
1332
1770
  return [null, body.token];
1333
1771
  } catch (cause) {
1772
+ if (cause instanceof CapxulError) {
1773
+ return [cause, null];
1774
+ }
1334
1775
  return [
1335
1776
  new CapxulError({
1336
1777
  code: "NETWORK_ERROR",
@@ -1367,11 +1808,11 @@ function createOrgDocumentsClient() {
1367
1808
  function createMeClient(config = {}) {
1368
1809
  return {
1369
1810
  get: async () => {
1370
- if (!config.data) {
1811
+ if (!config._data) {
1371
1812
  return stub("me.get");
1372
1813
  }
1373
1814
  try {
1374
- const account = await config.data.query(
1815
+ const account = await config._data.query(
1375
1816
  api.openfort.queries.getMyAccount,
1376
1817
  {}
1377
1818
  );
@@ -1381,7 +1822,7 @@ function createMeClient(config = {}) {
1381
1822
  }
1382
1823
  },
1383
1824
  update: async (input) => {
1384
- if (!config.data) {
1825
+ if (!config._data) {
1385
1826
  return stub("me.update");
1386
1827
  }
1387
1828
  if (input.countryCode !== void 0) {
@@ -1395,11 +1836,11 @@ function createMeClient(config = {}) {
1395
1836
  ];
1396
1837
  }
1397
1838
  try {
1398
- await config.data.mutation(api.openfort.mutations.updateProfile, {
1839
+ await config._data.mutation(api.openfort.mutations.updateProfile, {
1399
1840
  displayName: input.name,
1400
1841
  username: input.username
1401
1842
  });
1402
- const account = await config.data.query(
1843
+ const account = await config._data.query(
1403
1844
  api.openfort.queries.getMyAccount,
1404
1845
  {}
1405
1846
  );
@@ -1414,11 +1855,11 @@ function createMeClient(config = {}) {
1414
1855
  // src/core/operations.ts
1415
1856
  function createOperationsClient(config = {}) {
1416
1857
  const retrieve = async (operationId) => {
1417
- if (!config.data) {
1858
+ if (!config._data) {
1418
1859
  return stub("operations.retrieve");
1419
1860
  }
1420
1861
  try {
1421
- const operation = await config.data.query(api.operations.queries.retrieve, {
1862
+ const operation = await config._data.query(api.operations.queries.retrieve, {
1422
1863
  operationId
1423
1864
  });
1424
1865
  if (!operation) {
@@ -1435,7 +1876,7 @@ function createOperationsClient(config = {}) {
1435
1876
  return {
1436
1877
  retrieve,
1437
1878
  wait: async (operationId, input = {}) => {
1438
- if (!config.data) {
1879
+ if (!config._data) {
1439
1880
  return stub("operations.wait");
1440
1881
  }
1441
1882
  const until = new Set(
@@ -1470,49 +1911,22 @@ function toTokenUnits(value, decimals = 6) {
1470
1911
  return parseUnits(value, decimals);
1471
1912
  }
1472
1913
 
1473
- // src/internal/payment-token.ts
1474
- function resolvePaymentTokenAddress(currency) {
1914
+ // src/core/token-registry.ts
1915
+ function resolvePaymentToken(currency) {
1475
1916
  const normalized = currency.trim().toUpperCase();
1476
1917
  if (normalized === "USD" || normalized === "USDC") {
1477
- return TEST_USDC_ADDRESS.toLowerCase();
1918
+ return {
1919
+ address: TEST_USDC_ADDRESS.toLowerCase(),
1920
+ decimals: 6,
1921
+ symbol: "USDC"
1922
+ };
1478
1923
  }
1479
1924
  throw new CapxulError({
1480
- code: "NETWORK_ERROR",
1481
- message: `Currency ${currency} is not configured for on-chain payment submission.`,
1925
+ code: "NOT_IMPLEMENTED",
1926
+ message: `Currency ${currency} is not yet supported by the token registry.`,
1482
1927
  details: { currency: normalized }
1483
1928
  });
1484
1929
  }
1485
- async function buildSafeAccount(signer, chain) {
1486
- try {
1487
- const publicClient = createPublicClient({
1488
- chain: baseSepolia,
1489
- transport: http(chain.rpcUrl)
1490
- });
1491
- return await toSafeSmartAccount({
1492
- client: publicClient,
1493
- entryPoint: { address: entryPoint07Address, version: "0.7" },
1494
- version: "1.4.1",
1495
- owners: [signer],
1496
- saltNonce: computeSaltNonce(signer.address),
1497
- safeSingletonAddress: SAFE_L2_SINGLETON,
1498
- safeProxyFactoryAddress: SAFE_PROXY_FACTORY,
1499
- safeModuleSetupAddress: SAFE_MODULE_SETUP,
1500
- safe4337ModuleAddress: SAFE_4337_MODULE,
1501
- safeModules: [],
1502
- setupTransactions: []
1503
- });
1504
- } catch (cause) {
1505
- throw new CapxulError({
1506
- code: "NETWORK_ERROR",
1507
- message: cause instanceof Error ? cause.message : String(cause),
1508
- cause,
1509
- details: { chainId: chain.chainId }
1510
- });
1511
- }
1512
- }
1513
- function computeSaltNonce(ownerAddress) {
1514
- return BigInt(`0x${ownerAddress.toLowerCase().slice(2).padEnd(64, "0")}`);
1515
- }
1516
1930
  function createCapxulBundler(config) {
1517
1931
  const paymaster = createPaymasterClient({
1518
1932
  transport: http(config.rpcUrl)
@@ -1619,13 +2033,13 @@ async function transferAsOwner(config, params) {
1619
2033
  function createPaymentsClient(config = {}) {
1620
2034
  return {
1621
2035
  create: async (input) => {
1622
- if (!config.data || !config.signer || !config.signing) {
2036
+ if (!config._data || !config.signer || !config.signing) {
1623
2037
  return stub("payments.create");
1624
2038
  }
1625
2039
  let created = null;
1626
2040
  let submitted = null;
1627
2041
  try {
1628
- created = await config.data.mutation(api.payments.mutations.create, {
2042
+ created = await config._data.mutation(api.payments.mutations.create, {
1629
2043
  to: input.to,
1630
2044
  amount: input.amount,
1631
2045
  reference: input.reference,
@@ -1633,15 +2047,21 @@ function createPaymentsClient(config = {}) {
1633
2047
  source: input.source
1634
2048
  });
1635
2049
  if (!created) {
1636
- return [new CapxulError({
1637
- code: "NETWORK_ERROR",
1638
- message: "payments.create returned no payment resource"
1639
- }), null];
2050
+ return [
2051
+ new CapxulError({
2052
+ code: "NETWORK_ERROR",
2053
+ message: "payments.create returned no payment resource"
2054
+ }),
2055
+ null
2056
+ ];
1640
2057
  }
1641
2058
  if (created.status !== "processing" || created.operation.status !== "processing") {
1642
2059
  return [null, created];
1643
2060
  }
1644
- const currentSigner = await config.data.query(api.safe.queries.getMySignerAddress, {});
2061
+ const currentSigner = await config._data.query(
2062
+ api.safe.queries.getMySignerAddress,
2063
+ {}
2064
+ );
1645
2065
  if (!currentSigner?.address) {
1646
2066
  throw new CapxulError({
1647
2067
  code: "PERMISSION_DENIED",
@@ -1660,9 +2080,12 @@ function createPaymentsClient(config = {}) {
1660
2080
  }
1661
2081
  });
1662
2082
  }
1663
- const submission = await config.data.query(api.payments.queries.prepareSubmission, {
1664
- paymentId: created.id
1665
- });
2083
+ const submission = await config._data.query(
2084
+ api.payments.queries.prepareSubmission,
2085
+ {
2086
+ paymentId: created.id
2087
+ }
2088
+ );
1666
2089
  if (!submission?.recipientAddress) {
1667
2090
  throw new CapxulError({
1668
2091
  code: "NETWORK_ERROR",
@@ -1670,15 +2093,16 @@ function createPaymentsClient(config = {}) {
1670
2093
  details: { paymentId: created.id }
1671
2094
  });
1672
2095
  }
2096
+ const token = resolvePaymentToken(submission.amount.currency);
1673
2097
  const transfer = await transferAsOwner(
1674
2098
  {
1675
2099
  signer: config.signer,
1676
2100
  signing: config.signing
1677
2101
  },
1678
2102
  {
1679
- tokenAddress: resolvePaymentTokenAddress(submission.amount.currency),
2103
+ tokenAddress: token.address,
1680
2104
  recipientAddress: submission.recipientAddress,
1681
- amount: toTokenUnits(submission.amount.value, 6)
2105
+ amount: toTokenUnits(submission.amount.value, token.decimals)
1682
2106
  }
1683
2107
  );
1684
2108
  if (!transfer.success) {
@@ -1696,7 +2120,7 @@ function createPaymentsClient(config = {}) {
1696
2120
  txHash: transfer.txHash,
1697
2121
  userOpHash: transfer.userOpHash
1698
2122
  };
1699
- await config.data.mutation(api.payments.mutations.recordSubmitted, {
2123
+ await config._data.mutation(api.payments.mutations.recordSubmitted, {
1700
2124
  paymentId: created.id,
1701
2125
  txHash: transfer.txHash,
1702
2126
  userOpHash: transfer.userOpHash,
@@ -1706,43 +2130,65 @@ function createPaymentsClient(config = {}) {
1706
2130
  } catch (cause) {
1707
2131
  const error = mapCreateError(fromConvexError(cause));
1708
2132
  if (created?.id && created.status === "processing" && !submitted) {
1709
- await bestEffortMarkFailed({ data: config.data }, created.id, error);
2133
+ await bestEffortMarkFailed({ _data: config._data }, created.id, error);
1710
2134
  }
1711
2135
  if (submitted && created?.id) {
1712
- return [new CapxulError({
1713
- code: "NETWORK_ERROR",
1714
- message: "Payment was submitted on-chain, but backend submission tracking failed.",
1715
- cause,
1716
- details: {
1717
- paymentId: created.id,
1718
- txHash: submitted.txHash,
1719
- userOpHash: submitted.userOpHash
1720
- }
1721
- }), null];
2136
+ return [
2137
+ new CapxulError({
2138
+ code: "NETWORK_ERROR",
2139
+ message: "Payment was submitted on-chain, but backend submission tracking failed.",
2140
+ cause,
2141
+ details: {
2142
+ paymentId: created.id,
2143
+ txHash: submitted.txHash,
2144
+ userOpHash: submitted.userOpHash
2145
+ }
2146
+ }),
2147
+ null
2148
+ ];
1722
2149
  }
1723
2150
  return [error, null];
1724
2151
  }
1725
2152
  },
1726
2153
  retrieve: async (paymentId) => {
1727
- if (!config.data) {
2154
+ if (!config._data) {
1728
2155
  return stub("payments.retrieve");
1729
2156
  }
1730
2157
  try {
1731
- const payment = await config.data.query(api.payments.queries.retrieve, {
1732
- paymentId
1733
- });
2158
+ const payment = await config._data.query(
2159
+ api.payments.queries.retrieve,
2160
+ {
2161
+ paymentId
2162
+ }
2163
+ );
1734
2164
  if (!payment) {
1735
- return [new CapxulError({
1736
- code: "NOT_FOUND",
1737
- message: `payment ${paymentId} not found`
1738
- }), null];
2165
+ return [
2166
+ new CapxulError({
2167
+ code: "NOT_FOUND",
2168
+ message: `payment ${paymentId} not found`
2169
+ }),
2170
+ null
2171
+ ];
1739
2172
  }
1740
2173
  return [null, payment];
1741
2174
  } catch (cause) {
1742
2175
  return [fromConvexError(cause), null];
1743
2176
  }
1744
2177
  },
1745
- list: async () => stub("payments.list")
2178
+ list: async (input) => {
2179
+ if (!config._data) {
2180
+ return stub("payments.list");
2181
+ }
2182
+ try {
2183
+ const page = await config._data.query(api.payments.queries.list, {
2184
+ limit: input?.limit,
2185
+ cursor: input?.cursor
2186
+ });
2187
+ return [null, page];
2188
+ } catch (cause) {
2189
+ return [fromConvexError(cause), null];
2190
+ }
2191
+ }
1746
2192
  };
1747
2193
  }
1748
2194
  function createOrgPaymentsClient() {
@@ -1756,7 +2202,7 @@ function createOrgPaymentsClient() {
1756
2202
  }
1757
2203
  async function bestEffortMarkFailed(config, paymentId, error) {
1758
2204
  try {
1759
- await config.data.mutation(api.payments.mutations.markFailed, {
2205
+ await config._data.mutation(api.payments.mutations.markFailed, {
1760
2206
  paymentId,
1761
2207
  errorCode: error.code,
1762
2208
  errorMessage: error.message,
@@ -1813,11 +2259,11 @@ function createOrgTransfersClient() {
1813
2259
  function createWithdrawalsClient(config = {}) {
1814
2260
  return {
1815
2261
  create: async (input) => {
1816
- if (!config.data) {
2262
+ if (!config._data) {
1817
2263
  return stub("withdrawals.create");
1818
2264
  }
1819
2265
  const [createErr, createdRaw] = await tryCatch(
1820
- config.data.mutation(api.withdrawals.mutations.create, {
2266
+ config._data.mutation(api.withdrawals.mutations.create, {
1821
2267
  amount: input.amount,
1822
2268
  destination: {
1823
2269
  externalAccountId: input.destination.externalAccountId
@@ -1847,18 +2293,18 @@ function createWithdrawalsClient(config = {}) {
1847
2293
  return [null, created];
1848
2294
  }
1849
2295
  const [signerErr, currentSigner] = await tryCatch(
1850
- config.data.query(api.safe.queries.getMySignerAddress, {})
2296
+ config._data.query(api.safe.queries.getMySignerAddress, {})
1851
2297
  );
1852
2298
  if (signerErr) {
1853
2299
  return await handleSubmissionFailure(
1854
- { data: config.data },
2300
+ { _data: config._data },
1855
2301
  created.id,
1856
2302
  mapCreateError2(fromConvexError(signerErr))
1857
2303
  );
1858
2304
  }
1859
2305
  if (!currentSigner?.address) {
1860
2306
  return await handleSubmissionFailure(
1861
- { data: config.data },
2307
+ { _data: config._data },
1862
2308
  created.id,
1863
2309
  new CapxulError({
1864
2310
  code: "PERMISSION_DENIED",
@@ -1869,7 +2315,7 @@ function createWithdrawalsClient(config = {}) {
1869
2315
  }
1870
2316
  if (getAddress(currentSigner.address) !== getAddress(config.signer.address)) {
1871
2317
  return await handleSubmissionFailure(
1872
- { data: config.data },
2318
+ { _data: config._data },
1873
2319
  created.id,
1874
2320
  new CapxulError({
1875
2321
  code: "PERMISSION_DENIED",
@@ -1883,13 +2329,13 @@ function createWithdrawalsClient(config = {}) {
1883
2329
  );
1884
2330
  }
1885
2331
  const [prepErr, submission] = await tryCatch(
1886
- config.data.query(api.withdrawals.queries.prepareSubmission, {
2332
+ config._data.query(api.withdrawals.queries.prepareSubmission, {
1887
2333
  withdrawalId: created.id
1888
2334
  })
1889
2335
  );
1890
2336
  if (prepErr) {
1891
2337
  return await handleSubmissionFailure(
1892
- { data: config.data },
2338
+ { _data: config._data },
1893
2339
  created.id,
1894
2340
  mapCreateError2(fromConvexError(prepErr))
1895
2341
  );
@@ -1897,7 +2343,7 @@ function createWithdrawalsClient(config = {}) {
1897
2343
  const destinationAddress = submission?.destinationAddress;
1898
2344
  if (!submission || !destinationAddress) {
1899
2345
  return await handleSubmissionFailure(
1900
- { data: config.data },
2346
+ { _data: config._data },
1901
2347
  created.id,
1902
2348
  new CapxulError({
1903
2349
  code: "NETWORK_ERROR",
@@ -1906,6 +2352,7 @@ function createWithdrawalsClient(config = {}) {
1906
2352
  })
1907
2353
  );
1908
2354
  }
2355
+ const token = resolvePaymentToken(submission.amount.currency);
1909
2356
  const [transferErr, transferOk] = await tryCatch(
1910
2357
  transferAsOwner(
1911
2358
  {
@@ -1913,22 +2360,22 @@ function createWithdrawalsClient(config = {}) {
1913
2360
  signing: config.signing
1914
2361
  },
1915
2362
  {
1916
- tokenAddress: resolvePaymentTokenAddress(submission.amount.currency),
2363
+ tokenAddress: token.address,
1917
2364
  recipientAddress: destinationAddress,
1918
- amount: toTokenUnits(submission.amount.value, 6)
2365
+ amount: toTokenUnits(submission.amount.value, token.decimals)
1919
2366
  }
1920
2367
  )
1921
2368
  );
1922
2369
  if (transferErr) {
1923
2370
  return await handleSubmissionFailure(
1924
- { data: config.data },
2371
+ { _data: config._data },
1925
2372
  created.id,
1926
2373
  mapCreateError2(fromConvexError(transferErr))
1927
2374
  );
1928
2375
  }
1929
2376
  if (!transferOk.success) {
1930
2377
  return await handleSubmissionFailure(
1931
- { data: config.data },
2378
+ { _data: config._data },
1932
2379
  created.id,
1933
2380
  new CapxulError({
1934
2381
  code: "NETWORK_ERROR",
@@ -1942,7 +2389,7 @@ function createWithdrawalsClient(config = {}) {
1942
2389
  );
1943
2390
  }
1944
2391
  const [recordErr] = await tryCatch(
1945
- config.data.mutation(api.withdrawals.mutations.recordSubmitted, {
2392
+ config._data.mutation(api.withdrawals.mutations.recordSubmitted, {
1946
2393
  withdrawalId: created.id,
1947
2394
  txHash: transferOk.txHash,
1948
2395
  userOpHash: transferOk.userOpHash
@@ -1966,11 +2413,11 @@ function createWithdrawalsClient(config = {}) {
1966
2413
  return [null, created];
1967
2414
  },
1968
2415
  retrieve: async (withdrawalId) => {
1969
- if (!config.data) {
2416
+ if (!config._data) {
1970
2417
  return stub("withdrawals.retrieve");
1971
2418
  }
1972
2419
  const [err, raw] = await tryCatch(
1973
- config.data.query(api.withdrawals.queries.retrieve, { withdrawalId })
2420
+ config._data.query(api.withdrawals.queries.retrieve, { withdrawalId })
1974
2421
  );
1975
2422
  if (err) {
1976
2423
  return [fromConvexError(err), null];
@@ -1988,11 +2435,11 @@ function createWithdrawalsClient(config = {}) {
1988
2435
  return [null, withdrawal];
1989
2436
  },
1990
2437
  list: async (input) => {
1991
- if (!config.data) {
2438
+ if (!config._data) {
1992
2439
  return stub("withdrawals.list");
1993
2440
  }
1994
2441
  const [err, raw] = await tryCatch(
1995
- config.data.query(api.withdrawals.queries.list, {
2442
+ config._data.query(api.withdrawals.queries.list, {
1996
2443
  limit: input?.limit,
1997
2444
  cursor: input?.cursor
1998
2445
  })
@@ -2003,13 +2450,13 @@ function createWithdrawalsClient(config = {}) {
2003
2450
  return [null, raw];
2004
2451
  },
2005
2452
  recordCompleted: async (input) => {
2006
- if (!config.data) {
2453
+ if (!config._data) {
2007
2454
  return stub(
2008
2455
  "withdrawals.recordCompleted"
2009
2456
  );
2010
2457
  }
2011
2458
  const [err] = await tryCatch(
2012
- config.data.mutation(api.withdrawals.mutations.recordCompleted, {
2459
+ config._data.mutation(api.withdrawals.mutations.recordCompleted, {
2013
2460
  withdrawalId: input.withdrawalId,
2014
2461
  txHash: input.txHash
2015
2462
  })
@@ -2034,13 +2481,13 @@ function createOrgWithdrawalsClient(config = {}) {
2034
2481
  * orchestration ships in W3+.
2035
2482
  */
2036
2483
  create: async (input) => {
2037
- if (!config.data) {
2484
+ if (!config._data) {
2038
2485
  return stub(
2039
2486
  "organizations.withdrawals.create"
2040
2487
  );
2041
2488
  }
2042
2489
  const [err, raw] = await tryCatch(
2043
- config.data.mutation(api.withdrawals.mutations.createOrg, {
2490
+ config._data.mutation(api.withdrawals.mutations.createOrg, {
2044
2491
  organizationId: input.organizationId,
2045
2492
  amount: input.amount,
2046
2493
  destination: {
@@ -2067,13 +2514,13 @@ function createOrgWithdrawalsClient(config = {}) {
2067
2514
  return [null, created];
2068
2515
  },
2069
2516
  retrieve: async (input) => {
2070
- if (!config.data) {
2517
+ if (!config._data) {
2071
2518
  return stub(
2072
2519
  "organizations.withdrawals.retrieve"
2073
2520
  );
2074
2521
  }
2075
2522
  const [err, raw] = await tryCatch(
2076
- config.data.query(api.withdrawals.queries.retrieve, {
2523
+ config._data.query(api.withdrawals.queries.retrieve, {
2077
2524
  withdrawalId: input.withdrawalId
2078
2525
  })
2079
2526
  );
@@ -2103,13 +2550,13 @@ function createOrgWithdrawalsClient(config = {}) {
2103
2550
  return [null, withdrawal];
2104
2551
  },
2105
2552
  list: async (input) => {
2106
- if (!config.data) {
2553
+ if (!config._data) {
2107
2554
  return stub(
2108
2555
  "organizations.withdrawals.list"
2109
2556
  );
2110
2557
  }
2111
2558
  const [err, raw] = await tryCatch(
2112
- config.data.query(api.withdrawals.queries.listOrg, {
2559
+ config._data.query(api.withdrawals.queries.listOrg, {
2113
2560
  organizationId: input.organizationId,
2114
2561
  limit: input.limit,
2115
2562
  cursor: input.cursor
@@ -2128,7 +2575,7 @@ async function handleSubmissionFailure(config, withdrawalId, error) {
2128
2575
  }
2129
2576
  async function bestEffortMarkFailed2(config, withdrawalId, error) {
2130
2577
  await tryCatch(
2131
- config.data.mutation(api.withdrawals.mutations.markFailed, {
2578
+ config._data.mutation(api.withdrawals.mutations.markFailed, {
2132
2579
  withdrawalId,
2133
2580
  errorCode: error.code,
2134
2581
  errorMessage: error.message
@@ -2207,13 +2654,13 @@ function createWebhookEventsClient() {
2207
2654
  function createOrgExternalAccountsClient(config) {
2208
2655
  return {
2209
2656
  create: async (input) => {
2210
- if (!config.data) {
2657
+ if (!config._data) {
2211
2658
  return stub(
2212
2659
  "organizations.externalAccounts.create"
2213
2660
  );
2214
2661
  }
2215
2662
  const [err, raw] = await tryCatch(
2216
- config.data.mutation(api.externalAccounts.mutations.createOrg, {
2663
+ config._data.mutation(api.externalAccounts.mutations.createOrg, {
2217
2664
  organizationId: input.organizationId,
2218
2665
  kind: input.kind,
2219
2666
  label: input.label,
@@ -2227,10 +2674,7 @@ function createOrgExternalAccountsClient(config) {
2227
2674
  })
2228
2675
  );
2229
2676
  if (err) {
2230
- return [
2231
- fromConvexError(err),
2232
- null
2233
- ];
2677
+ return [fromConvexError(err), null];
2234
2678
  }
2235
2679
  if (!raw) {
2236
2680
  return [
@@ -2241,53 +2685,161 @@ function createOrgExternalAccountsClient(config) {
2241
2685
  null
2242
2686
  ];
2243
2687
  }
2244
- return [
2245
- null,
2246
- brandExternalAccount(
2247
- raw
2248
- )
2249
- ];
2688
+ return [null, brandExternalAccount(raw)];
2250
2689
  },
2251
2690
  list: async (input) => {
2252
- if (!config.data) {
2691
+ if (!config._data) {
2253
2692
  return stub(
2254
2693
  "organizations.externalAccounts.list"
2255
2694
  );
2256
2695
  }
2257
2696
  const [err, result] = await tryCatch(
2258
- config.data.query(api.externalAccounts.queries.listOrg, {
2697
+ config._data.query(api.externalAccounts.queries.listOrg, {
2259
2698
  organizationId: input.organizationId,
2260
2699
  limit: input.limit,
2261
2700
  cursor: input.cursor
2262
2701
  })
2263
2702
  );
2264
2703
  if (err) {
2265
- return [fromConvexError(err), null];
2704
+ return [fromConvexError(err), null];
2705
+ }
2706
+ const branded = result.data.map(
2707
+ (row) => brandExternalAccount(row)
2708
+ );
2709
+ return [
2710
+ null,
2711
+ {
2712
+ object: "list",
2713
+ data: branded,
2714
+ page: result.page
2715
+ }
2716
+ ];
2717
+ },
2718
+ retrieve: async (input) => {
2719
+ if (!config._data) {
2720
+ return stub(
2721
+ "organizations.externalAccounts.retrieve"
2722
+ );
2723
+ }
2724
+ const [err, raw] = await tryCatch(
2725
+ config._data.query(api.externalAccounts.queries.retrieveOrg, {
2726
+ organizationId: input.organizationId,
2727
+ externalAccountId: input.externalAccountId
2728
+ })
2729
+ );
2730
+ if (err) {
2731
+ return [fromConvexError(err), null];
2732
+ }
2733
+ if (!raw) {
2734
+ return [
2735
+ new CapxulError({
2736
+ code: "NOT_FOUND",
2737
+ message: `external_account ${input.externalAccountId} not found`
2738
+ }),
2739
+ null
2740
+ ];
2741
+ }
2742
+ return [null, brandExternalAccount(raw)];
2743
+ },
2744
+ remove: async (input) => {
2745
+ if (!config._data) {
2746
+ return stub("organizations.externalAccounts.remove");
2747
+ }
2748
+ const [err] = await tryCatch(
2749
+ config._data.mutation(api.externalAccounts.mutations.removeOrg, {
2750
+ organizationId: input.organizationId,
2751
+ externalAccountId: input.externalAccountId
2752
+ })
2753
+ );
2754
+ if (err) {
2755
+ return [fromConvexError(err), null];
2756
+ }
2757
+ return [null, void 0];
2758
+ }
2759
+ };
2760
+ }
2761
+ function createOrgSubAccountsClient(config) {
2762
+ return {
2763
+ create: async (input) => {
2764
+ if (!config._data) {
2765
+ return stub(
2766
+ "organizations.subAccounts.create"
2767
+ );
2768
+ }
2769
+ const [err, raw] = await tryCatch(
2770
+ config._data.mutation(api.subAccounts.mutations.create, {
2771
+ parent: {
2772
+ kind: "organization",
2773
+ id: input.organizationId
2774
+ },
2775
+ name: input.name,
2776
+ purpose: input.purpose
2777
+ })
2778
+ );
2779
+ if (err) {
2780
+ return [
2781
+ fromConvexError(err),
2782
+ null
2783
+ ];
2784
+ }
2785
+ if (!raw) {
2786
+ return [
2787
+ new CapxulError({
2788
+ code: "NOT_FOUND",
2789
+ message: "sub_account creation returned no resource"
2790
+ }),
2791
+ null
2792
+ ];
2793
+ }
2794
+ const [brandErr, branded] = tryBrandSubAccount(raw);
2795
+ if (brandErr) {
2796
+ return [brandErr, null];
2797
+ }
2798
+ return [null, branded];
2799
+ },
2800
+ list: async (input) => {
2801
+ if (!config._data) {
2802
+ return stub(
2803
+ "organizations.subAccounts.list"
2804
+ );
2805
+ }
2806
+ const [err, rows] = await tryCatch(
2807
+ config._data.query(api.subAccounts.queries.listByOrganization, {
2808
+ organizationId: input.organizationId
2809
+ })
2810
+ );
2811
+ if (err) {
2812
+ return [
2813
+ fromConvexError(err),
2814
+ null
2815
+ ];
2816
+ }
2817
+ const branded = [];
2818
+ for (const row of rows) {
2819
+ const [brandErr, value] = tryBrandSubAccount(row);
2820
+ if (brandErr) {
2821
+ return [brandErr, null];
2822
+ }
2823
+ branded.push(value);
2266
2824
  }
2267
- const branded = result.data.map(
2268
- (row) => brandExternalAccount(
2269
- row
2270
- )
2271
- );
2272
2825
  return [
2273
2826
  null,
2274
2827
  {
2275
2828
  object: "list",
2276
2829
  data: branded,
2277
- page: result.page
2830
+ page: { hasMore: false }
2278
2831
  }
2279
2832
  ];
2280
2833
  },
2281
2834
  retrieve: async (input) => {
2282
- if (!config.data) {
2835
+ if (!config._data) {
2283
2836
  return stub(
2284
- "organizations.externalAccounts.retrieve"
2837
+ "organizations.subAccounts.retrieve"
2285
2838
  );
2286
2839
  }
2287
2840
  const [err, raw] = await tryCatch(
2288
- config.data.query(api.externalAccounts.queries.retrieveOrg, {
2289
- organizationId: input.organizationId,
2290
- externalAccountId: input.externalAccountId
2841
+ config._data.query(api.subAccounts.queries.retrieve, {
2842
+ subAccountId: input.subAccountId
2291
2843
  })
2292
2844
  );
2293
2845
  if (err) {
@@ -2300,28 +2852,29 @@ function createOrgExternalAccountsClient(config) {
2300
2852
  return [
2301
2853
  new CapxulError({
2302
2854
  code: "NOT_FOUND",
2303
- message: `external_account ${input.externalAccountId} not found`
2855
+ message: `sub_account ${input.subAccountId} not found`
2304
2856
  }),
2305
2857
  null
2306
2858
  ];
2307
2859
  }
2308
- return [
2309
- null,
2310
- brandExternalAccount(
2311
- raw
2312
- )
2313
- ];
2860
+ const [brandErr, branded] = tryBrandSubAccount(raw);
2861
+ if (brandErr) {
2862
+ return [
2863
+ brandErr,
2864
+ null
2865
+ ];
2866
+ }
2867
+ return [null, branded];
2314
2868
  },
2315
2869
  remove: async (input) => {
2316
- if (!config.data) {
2870
+ if (!config._data) {
2317
2871
  return stub(
2318
- "organizations.externalAccounts.remove"
2872
+ "organizations.subAccounts.remove"
2319
2873
  );
2320
2874
  }
2321
- const [err] = await tryCatch(
2322
- config.data.mutation(api.externalAccounts.mutations.removeOrg, {
2323
- organizationId: input.organizationId,
2324
- externalAccountId: input.externalAccountId
2875
+ const [err, raw] = await tryCatch(
2876
+ config._data.mutation(api.subAccounts.mutations.archive, {
2877
+ subAccountId: input.subAccountId
2325
2878
  })
2326
2879
  );
2327
2880
  if (err) {
@@ -2330,23 +2883,139 @@ function createOrgExternalAccountsClient(config) {
2330
2883
  null
2331
2884
  ];
2332
2885
  }
2333
- return [null, void 0];
2886
+ if (!raw) {
2887
+ return [
2888
+ new CapxulError({
2889
+ code: "NOT_FOUND",
2890
+ message: `sub_account ${input.subAccountId} not found`
2891
+ }),
2892
+ null
2893
+ ];
2894
+ }
2895
+ const [brandErr, branded] = tryBrandSubAccount(raw);
2896
+ if (brandErr) {
2897
+ return [
2898
+ brandErr,
2899
+ null
2900
+ ];
2901
+ }
2902
+ return [null, branded];
2334
2903
  }
2335
2904
  };
2336
2905
  }
2337
2906
  function createOrganizationsClient(config = {}) {
2338
2907
  return {
2339
- create: async () => stub("organizations.create"),
2340
- retrieve: async () => stub("organizations.retrieve"),
2341
- list: async () => stub("organizations.list"),
2342
- update: async () => stub("organizations.update"),
2908
+ create: async (input) => {
2909
+ if (!config._data) {
2910
+ return stub("organizations.create");
2911
+ }
2912
+ if (input.country !== void 0) {
2913
+ return [
2914
+ new CapxulError({
2915
+ code: "INVALID_INPUT",
2916
+ message: "organizations.create does not support country yet \u2014 backend mutation only accepts name.",
2917
+ details: { field: "country" }
2918
+ }),
2919
+ null
2920
+ ];
2921
+ }
2922
+ try {
2923
+ const orgId = await config._data.mutation(api.org.mutations.create, {
2924
+ name: input.name
2925
+ });
2926
+ const org = await config._data.query(api.org.queries.retrieve, {
2927
+ orgId
2928
+ });
2929
+ if (!org) {
2930
+ return [
2931
+ new CapxulError({
2932
+ code: "NETWORK_ERROR",
2933
+ message: "organization created but could not be retrieved"
2934
+ }),
2935
+ null
2936
+ ];
2937
+ }
2938
+ return [null, org];
2939
+ } catch (cause) {
2940
+ return [fromConvexError(cause), null];
2941
+ }
2942
+ },
2943
+ retrieve: async (organizationId) => {
2944
+ if (!config._data) {
2945
+ return stub("organizations.retrieve");
2946
+ }
2947
+ try {
2948
+ const orgId = organizationId.replace(/^org_/, "");
2949
+ const org = await config._data.query(api.org.queries.retrieve, {
2950
+ orgId
2951
+ });
2952
+ if (!org) {
2953
+ return [
2954
+ new CapxulError({
2955
+ code: "NOT_FOUND",
2956
+ message: `organization ${organizationId} not found`
2957
+ }),
2958
+ null
2959
+ ];
2960
+ }
2961
+ return [null, org];
2962
+ } catch (cause) {
2963
+ return [fromConvexError(cause), null];
2964
+ }
2965
+ },
2966
+ list: async (input) => {
2967
+ if (!config._data) {
2968
+ return stub("organizations.list");
2969
+ }
2970
+ try {
2971
+ const page = await config._data.query(api.org.queries.list, {
2972
+ limit: input?.limit,
2973
+ cursor: input?.cursor
2974
+ });
2975
+ const result = {
2976
+ object: "list",
2977
+ data: page.data,
2978
+ page: {
2979
+ hasMore: page.hasMore,
2980
+ cursor: page.nextCursor
2981
+ }
2982
+ };
2983
+ return [null, result];
2984
+ } catch (cause) {
2985
+ return [fromConvexError(cause), null];
2986
+ }
2987
+ },
2988
+ update: async (input) => {
2989
+ if (!config._data) {
2990
+ return stub("organizations.update");
2991
+ }
2992
+ try {
2993
+ const orgId = input.organizationId.replace(/^org_/, "");
2994
+ const org = await config._data.mutation(api.org.mutations.update, {
2995
+ orgId,
2996
+ name: input.name
2997
+ });
2998
+ if (!org) {
2999
+ return [
3000
+ new CapxulError({
3001
+ code: "NOT_FOUND",
3002
+ message: `organization ${input.organizationId} not found`
3003
+ }),
3004
+ null
3005
+ ];
3006
+ }
3007
+ return [null, org];
3008
+ } catch (cause) {
3009
+ return [fromConvexError(cause), null];
3010
+ }
3011
+ },
2343
3012
  safes: {
2344
3013
  retrieve: async (input) => {
2345
- if (!config.data) {
3014
+ if (!config._data) {
2346
3015
  return stub("organizations.safes.retrieve");
2347
3016
  }
2348
3017
  try {
2349
- const safe = await config.data.query(
3018
+ const safe = await config._data.query(
2350
3019
  api.safe.queries.retrieveOrganizationSafe,
2351
3020
  input
2352
3021
  );
@@ -2369,34 +3038,243 @@ function createOrganizationsClient(config = {}) {
2369
3038
  }
2370
3039
  },
2371
3040
  treasury: {
2372
- retrieve: async () => stub("organizations.treasury.retrieve")
3041
+ retrieve: async (organizationId) => {
3042
+ if (!config._data) {
3043
+ return stub(
3044
+ "organizations.treasury.retrieve"
3045
+ );
3046
+ }
3047
+ try {
3048
+ const orgId = organizationId.replace(/^org_/, "");
3049
+ const raw = await config._data.query(
3050
+ api.safe.queries.getOrgTreasuryBalance,
3051
+ { orgId }
3052
+ );
3053
+ if (!raw) {
3054
+ return [
3055
+ new CapxulError({
3056
+ code: "NOT_FOUND",
3057
+ message: `treasury for organization ${organizationId} not found`
3058
+ }),
3059
+ null
3060
+ ];
3061
+ }
3062
+ const treasury = {
3063
+ object: "treasury",
3064
+ id: toTreasuryId(`try_${orgId}`),
3065
+ organizationId,
3066
+ status: "active",
3067
+ safeId: toSafeId(
3068
+ `safe_${raw.safeAddress.replace(/^0x/, "").toLowerCase()}`
3069
+ ),
3070
+ totalBalance: { value: "0", currency: "USD" },
3071
+ positions: raw.tokens.map((t) => ({
3072
+ symbol: t.symbol,
3073
+ contractAddress: t.tokenAddress,
3074
+ amount: t.balance
3075
+ })),
3076
+ asOf: raw.lastUpdatedAt ? new Date(raw.lastUpdatedAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
3077
+ };
3078
+ return [null, treasury];
3079
+ } catch (cause) {
3080
+ return [
3081
+ fromConvexError(cause),
3082
+ null
3083
+ ];
3084
+ }
3085
+ }
2373
3086
  },
2374
3087
  members: {
2375
- list: async () => stub("organizations.members.list"),
2376
- retrieve: async () => stub("organizations.members.retrieve"),
2377
- invite: async () => stub("organizations.members.invite"),
2378
- updateRole: async () => stub("organizations.members.updateRole"),
2379
- remove: async () => stub("organizations.members.remove")
3088
+ list: async (input) => {
3089
+ if (!config._data?.action) {
3090
+ return stub("organizations.members.list");
3091
+ }
3092
+ try {
3093
+ const orgId = input.organizationId.replace(/^org_/, "");
3094
+ const page = await config._data.action(api.org.actions.membersList, {
3095
+ organizationId: orgId,
3096
+ status: input.status,
3097
+ limit: input.limit,
3098
+ cursor: input.cursor
3099
+ });
3100
+ return [null, page];
3101
+ } catch (cause) {
3102
+ return [fromConvexError(cause), null];
3103
+ }
3104
+ },
3105
+ retrieve: async (input) => {
3106
+ if (!config._data?.action) {
3107
+ return stub("organizations.members.retrieve");
3108
+ }
3109
+ try {
3110
+ const orgId = input.organizationId.replace(/^org_/, "");
3111
+ const memberId = input.memberId.replace(/^mb_/, "");
3112
+ const member = await config._data.action(
3113
+ api.org.actions.retrieveMember,
3114
+ {
3115
+ organizationId: orgId,
3116
+ memberId
3117
+ }
3118
+ );
3119
+ return [null, member];
3120
+ } catch (cause) {
3121
+ return [fromConvexError(cause), null];
3122
+ }
3123
+ },
3124
+ invite: async (input) => {
3125
+ if (!config._data?.action) {
3126
+ return stub("organizations.members.invite");
3127
+ }
3128
+ try {
3129
+ const orgId = input.organizationId.replace(/^org_/, "");
3130
+ const result = await config._data.action(
3131
+ api.org.actions.inviteMember,
3132
+ {
3133
+ organizationId: orgId,
3134
+ email: input.email,
3135
+ role: input.role
3136
+ }
3137
+ );
3138
+ return [null, result];
3139
+ } catch (cause) {
3140
+ return [fromConvexError(cause), null];
3141
+ }
3142
+ },
3143
+ accept: async (input) => {
3144
+ if (!config._data?.action) {
3145
+ return stub("organizations.members.accept");
3146
+ }
3147
+ try {
3148
+ const member = await config._data.action(
3149
+ api.org.actions.acceptInvitation,
3150
+ { token: input.token }
3151
+ );
3152
+ return [null, member];
3153
+ } catch (cause) {
3154
+ return [fromConvexError(cause), null];
3155
+ }
3156
+ },
3157
+ updateRole: async (input) => {
3158
+ if (!config._data?.action) {
3159
+ return stub("organizations.members.updateRole");
3160
+ }
3161
+ try {
3162
+ const orgId = input.organizationId.replace(/^org_/, "");
3163
+ const memberId = input.memberId.replace(/^mb_/, "");
3164
+ const member = await config._data.action(
3165
+ api.org.actions.updateMemberRole,
3166
+ {
3167
+ organizationId: orgId,
3168
+ memberId,
3169
+ role: input.role
3170
+ }
3171
+ );
3172
+ return [null, member];
3173
+ } catch (cause) {
3174
+ return [fromConvexError(cause), null];
3175
+ }
3176
+ },
3177
+ revoke: async (input) => {
3178
+ if (!config._data?.action) {
3179
+ return stub("organizations.members.revoke");
3180
+ }
3181
+ try {
3182
+ const orgId = input.organizationId.replace(/^org_/, "");
3183
+ const memberId = input.memberId.replace(/^mb_/, "");
3184
+ const member = await config._data.action(
3185
+ api.org.actions.revokeMember,
3186
+ {
3187
+ organizationId: orgId,
3188
+ memberId
3189
+ }
3190
+ );
3191
+ return [null, member];
3192
+ } catch (cause) {
3193
+ return [fromConvexError(cause), null];
3194
+ }
3195
+ },
3196
+ remove: async (input) => {
3197
+ if (!config._data?.action) {
3198
+ return stub("organizations.members.remove");
3199
+ }
3200
+ try {
3201
+ const orgId = input.organizationId.replace(/^org_/, "");
3202
+ const memberId = input.memberId.replace(/^mb_/, "");
3203
+ await config._data.action(api.org.actions.removeMember, {
3204
+ organizationId: orgId,
3205
+ memberId
3206
+ });
3207
+ return [null, void 0];
3208
+ } catch (cause) {
3209
+ return [fromConvexError(cause), null];
3210
+ }
3211
+ },
3212
+ resend: async (input) => {
3213
+ if (!config._data?.action) {
3214
+ return stub("organizations.members.resend");
3215
+ }
3216
+ try {
3217
+ const orgId = input.organizationId.replace(/^org_/, "");
3218
+ const memberId = input.memberId.replace(/^mb_/, "");
3219
+ const result = await config._data.action(
3220
+ api.org.actions.resendInvitation,
3221
+ {
3222
+ organizationId: orgId,
3223
+ memberId
3224
+ }
3225
+ );
3226
+ return [null, result];
3227
+ } catch (cause) {
3228
+ return [fromConvexError(cause), null];
3229
+ }
3230
+ }
2380
3231
  },
2381
3232
  apiKeys: createApiKeysClient(),
2382
- kybProfile: {
2383
- start: async () => stub("organizations.kybProfile.start"),
2384
- retrieve: async () => stub("organizations.kybProfile.retrieve")
2385
- },
2386
- subAccounts: {
2387
- create: async () => stub("organizations.subAccounts.create"),
2388
- list: async () => stub("organizations.subAccounts.list"),
2389
- retrieve: async () => stub("organizations.subAccounts.retrieve"),
2390
- remove: async () => stub("organizations.subAccounts.remove")
2391
- },
3233
+ subAccounts: createOrgSubAccountsClient(config),
2392
3234
  externalAccounts: createOrgExternalAccountsClient(config),
2393
3235
  balanceLedger: {
2394
- list: async () => stub(
2395
- "organizations.balanceLedger.list"
2396
- ),
2397
- retrieve: async () => stub(
2398
- "organizations.balanceLedger.retrieve"
2399
- )
3236
+ list: async (input) => {
3237
+ if (!config._data) {
3238
+ return stub(
3239
+ "organizations.balanceLedger.list"
3240
+ );
3241
+ }
3242
+ try {
3243
+ const orgId = input.organizationId.replace(/^org_/, "");
3244
+ const page = await config._data.query(
3245
+ api.balanceLedger.queries.listForOrg,
3246
+ { orgId, limit: input.limit, cursor: input.cursor }
3247
+ );
3248
+ return [null, page];
3249
+ } catch (cause) {
3250
+ return [fromConvexError(cause), null];
3251
+ }
3252
+ },
3253
+ retrieve: async (input) => {
3254
+ if (!config._data) {
3255
+ return stub(
3256
+ "organizations.balanceLedger.retrieve"
3257
+ );
3258
+ }
3259
+ try {
3260
+ const entry = await config._data.query(
3261
+ api.balanceLedger.queries.retrieve,
3262
+ { entryId: input.entryId }
3263
+ );
3264
+ if (!entry) {
3265
+ return [
3266
+ new CapxulError({
3267
+ code: "NOT_FOUND",
3268
+ message: `balance_ledger_entry ${input.entryId} not found`
3269
+ }),
3270
+ null
3271
+ ];
3272
+ }
3273
+ return [null, entry];
3274
+ } catch (cause) {
3275
+ return [fromConvexError(cause), null];
3276
+ }
3277
+ }
2400
3278
  },
2401
3279
  payments: createOrgPaymentsClient(),
2402
3280
  transfers: createOrgTransfersClient(),
@@ -2407,14 +3285,6 @@ function createOrganizationsClient(config = {}) {
2407
3285
  };
2408
3286
  }
2409
3287
 
2410
- // src/core/sub-accounts.ts
2411
- function createSubAccountsClient() {
2412
- return {
2413
- retrieve: async () => stub("subAccounts.retrieve"),
2414
- remove: async () => stub("subAccounts.remove")
2415
- };
2416
- }
2417
-
2418
3288
  // src/core/token-transfers.ts
2419
3289
  var toTokenTransferId = (raw) => {
2420
3290
  if (typeof raw !== "string" || raw.length === 0) {
@@ -2433,11 +3303,11 @@ function brandRow(row) {
2433
3303
  function createTokenTransfersClient(config = {}) {
2434
3304
  return {
2435
3305
  list: async (input) => {
2436
- if (!config.data) {
3306
+ if (!config._data) {
2437
3307
  return stub("tokenTransfers.list");
2438
3308
  }
2439
3309
  try {
2440
- const raw = await config.data.query(
3310
+ const raw = await config._data.query(
2441
3311
  api.tokenTransfers.queries.list,
2442
3312
  {
2443
3313
  limit: input?.limit,
@@ -2471,11 +3341,11 @@ function createTokenTransfersClient(config = {}) {
2471
3341
  }
2472
3342
  },
2473
3343
  retrieve: async (input) => {
2474
- if (!config.data) {
3344
+ if (!config._data) {
2475
3345
  return stub("tokenTransfers.retrieve");
2476
3346
  }
2477
3347
  try {
2478
- const raw = await config.data.query(
3348
+ const raw = await config._data.query(
2479
3349
  api.tokenTransfers.queries.getByTxLogIndex,
2480
3350
  {
2481
3351
  txHash: input.txHash,
@@ -2812,7 +3682,6 @@ var initialContext = {
2812
3682
  email: null,
2813
3683
  code: null,
2814
3684
  username: null,
2815
- signerProvider: null,
2816
3685
  bootstrapToken: null,
2817
3686
  bootstrapReason: null,
2818
3687
  session: null,
@@ -3010,12 +3879,6 @@ function createAuthBootstrapFlowMachine(client) {
3010
3879
  error: () => null
3011
3880
  })
3012
3881
  },
3013
- ENTER_SIGNER_PROVIDER: {
3014
- actions: assign({
3015
- signerProvider: ({ event }) => event.signerProvider,
3016
- error: () => null
3017
- })
3018
- },
3019
3882
  COMPLETE_BOOTSTRAP: { target: "completing_bootstrap" },
3020
3883
  BACK: { target: "otp_requested" },
3021
3884
  RESET: { target: "email", actions: assign(() => initialContext) }
@@ -3026,8 +3889,7 @@ function createAuthBootstrapFlowMachine(client) {
3026
3889
  src: "completeBootstrap",
3027
3890
  input: ({ context }) => ({
3028
3891
  bootstrapToken: requireBootstrapToken(context),
3029
- username: requireUsername(context),
3030
- signerProvider: requireSignerProvider(context)
3892
+ username: requireUsername(context)
3031
3893
  }),
3032
3894
  onDone: {
3033
3895
  target: "authenticated",
@@ -3039,7 +3901,6 @@ function createAuthBootstrapFlowMachine(client) {
3039
3901
  safe: ({ event }) => event.output.safe,
3040
3902
  bootstrapToken: () => null,
3041
3903
  bootstrapReason: () => null,
3042
- signerProvider: () => null,
3043
3904
  email: () => null,
3044
3905
  error: () => null
3045
3906
  }),
@@ -3120,15 +3981,6 @@ function requireUsername(context) {
3120
3981
  }
3121
3982
  return context.username;
3122
3983
  }
3123
- function requireSignerProvider(context) {
3124
- if (!context.signerProvider) {
3125
- throw Errors.invalidInput(
3126
- "signerProvider",
3127
- "Auth bootstrap requires a signer provider."
3128
- );
3129
- }
3130
- return context.signerProvider;
3131
- }
3132
3984
  function errorFromEvent2(event) {
3133
3985
  const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
3134
3986
  if (cause instanceof CapxulError || cause instanceof CapxulError2) {
@@ -3174,7 +4026,7 @@ function createProvisioningMachine(client) {
3174
4026
  const provider = context.input?.signerProvider;
3175
4027
  if (!provider) return;
3176
4028
  track("provisioning_safe_created", {
3177
- safe_address: provider.safeAddress
4029
+ safe_address: deriveSafeAddress(provider.signerAddress)
3178
4030
  });
3179
4031
  }
3180
4032
  }
@@ -3536,7 +4388,7 @@ function createCapxulClient(config = {}) {
3536
4388
  tokenTransfers: createTokenTransfersClient(config),
3537
4389
  withdrawals: createWithdrawalsClient(config),
3538
4390
  documents: createDocumentsClient(),
3539
- subAccounts: createSubAccountsClient(),
4391
+ subAccounts: createSubAccountsClient(config),
3540
4392
  virtualAccounts: createVirtualAccountsClient(),
3541
4393
  virtualCards: createVirtualCardsClient(),
3542
4394
  externalAccounts: createExternalAccountsClient(config),
@@ -3653,4 +4505,81 @@ function isWebhookEvent(value) {
3653
4505
  return typeof candidate.id === "string" && typeof candidate.type === "string" && typeof candidate.createdAt === "string" && (candidate.operationId === void 0 || typeof candidate.operationId === "string") && (candidate.correlationId === void 0 || typeof candidate.correlationId === "string") && !!candidate.data && typeof candidate.data === "object" && !Array.isArray(candidate.data);
3654
4506
  }
3655
4507
 
3656
- export { CapxulError, createAuthBootstrapFlowMachine, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };
4508
+ // src/core/auth-service.ts
4509
+ var AuthService = class {
4510
+ authClient;
4511
+ sessionStore;
4512
+ config;
4513
+ constructor(config = {}) {
4514
+ this.config = config;
4515
+ this.sessionStore = config.auth?.sessionStore ?? createMemorySessionStore2();
4516
+ this.authClient = createAuthClient({
4517
+ ...config,
4518
+ auth: { ...config.auth, sessionStore: this.sessionStore }
4519
+ });
4520
+ }
4521
+ async sendOtp(email) {
4522
+ const [err] = await this.authClient.sendOtp({ email });
4523
+ if (err) throw err;
4524
+ }
4525
+ async verifyOtp(email, otp) {
4526
+ const [err, result] = await this.authClient.verifyOtp({ email, otp });
4527
+ if (err) throw err;
4528
+ return result;
4529
+ }
4530
+ async completeBootstrap(params, signer) {
4531
+ if (signer) {
4532
+ const tempClient = createAuthClient({
4533
+ ...this.config,
4534
+ signer
4535
+ });
4536
+ const [err2, result2] = await tempClient.completeBootstrap(params);
4537
+ if (err2) throw err2;
4538
+ return result2;
4539
+ }
4540
+ const [err, result] = await this.authClient.completeBootstrap(params);
4541
+ if (err) throw err;
4542
+ return result;
4543
+ }
4544
+ /**
4545
+ * Clears the persisted session and, when a transport was pre-injected,
4546
+ * drops the cached auth header.
4547
+ *
4548
+ * **Transport safety note:** `clearAuth()` is only invoked when
4549
+ * `config._transport` was supplied at construction (e.g. by the React
4550
+ * provider). If `AuthService` is instantiated directly in a Node/CLI
4551
+ * context without an injected transport, the transport-side auth cache
4552
+ * is the caller's responsibility.
4553
+ */
4554
+ async signOut() {
4555
+ this.sessionStore.clear();
4556
+ this.config._transport?.clearAuth();
4557
+ }
4558
+ async getSession() {
4559
+ const [err, session] = await this.authClient.getSession();
4560
+ if (err) throw err;
4561
+ return session;
4562
+ }
4563
+ };
4564
+ function createMemorySessionStore2() {
4565
+ let current = null;
4566
+ return {
4567
+ get: () => current,
4568
+ set: (session) => {
4569
+ current = session;
4570
+ },
4571
+ clear: () => {
4572
+ current = null;
4573
+ }
4574
+ };
4575
+ }
4576
+ var SignerProvisioner = class {
4577
+ provision() {
4578
+ const privateKey = generatePrivateKey();
4579
+ const signer = privateKeyToAccount(privateKey);
4580
+ const safeAddress = deriveSafeAddress(signer.address);
4581
+ return { signer, safeAddress };
4582
+ }
4583
+ };
4584
+
4585
+ export { AuthService, CapxulError, SignerProvisioner, createAuthBootstrapFlowMachine, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, resolvePaymentToken, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };