@capxul/sdk-react 0.1.0-alpha.2 → 0.1.0-alpha.4

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.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { HttpTransport, TransportState, CapxulConfig, BrowserCapxulConfig, AccountId, OrganizationId, ApiKeyId, BalanceLedgerEntryId, ExternalAccountId, MemberId, Account, ApiKey, BalanceLedgerEntry, DocumentId, Document, ExternalAccount, KybProfile, KycProfile, CapxulError as CapxulError$1, Member, OperationId, Operation, Organization, PaymentId, Payment, SafeId, Safe, SubAccountId, SubAccount, TransferId, Transfer, Treasury, VirtualAccountId, VirtualAccount, VirtualCardId, VirtualCard, WebhookEndpointId, WebhookEndpoint, WebhookEventId, WebhookEvent, WithdrawalId, Withdrawal, List, LocalPrivateKeySignerProvider } from '@capxul/sdk';
2
+ import { HttpTransport, TransportState, BrowserCapxulConfig, AccountId, OrganizationId, ApiKeyId, BalanceLedgerEntryId, ExternalAccountId, MemberId, Account, ApiKey, BalanceLedgerEntry, DocumentId, Document, ExternalAccount, KybProfile, KycProfile, CapxulError as CapxulError$1, Member, OperationId, Operation, Organization, PaymentId, Payment, SafeId, Safe, SubAccountId, SubAccount, TokenTransfer, TransferId, Transfer, Treasury, VirtualAccountId, VirtualAccount, VirtualCardId, VirtualCard, WebhookEndpointId, WebhookEndpoint, WebhookEventId, WebhookEvent, WithdrawalId, Withdrawal, List, TokenTransfersListInput, TokenTransfersListPage, LocalPrivateKeySignerProvider } from '@capxul/sdk';
3
3
  export { AuthFlowContext, AuthFlowEvent, BrowserCapxulConfig, OnboardingFlowContext, OnboardingFlowEvent, ProvisioningFlowContext, ProvisioningFlowEvent } from '@capxul/sdk';
4
4
  import { QueryClient, UseQueryResult } from '@tanstack/react-query';
5
5
  import { CapxulClient } from '@capxul/sdk/client';
@@ -55,55 +55,39 @@ declare function CapxulTransportProvider({ transport, children, }: CapxulTranspo
55
55
  declare function useCapxulStatus(): TransportState;
56
56
 
57
57
  /**
58
- * `CapxulProvider` — React context provider that wires both the
59
- * `@capxul/sdk` client AND a TanStack Query `QueryClient` for the
60
- * subtree.
58
+ * `CapxulProvider` — public React provider for `@capxul/sdk-react`.
61
59
  *
62
- * Two construction paths:
60
+ * Single-input contract: accepts ONLY `{ config: BrowserCapxulConfig,
61
+ * queryClient?, children }`. The browser config is the secret-safe
62
+ * discriminated union from `@capxul/sdk` — `apiKey`, `data`, `signer`,
63
+ * and other server-only fields are rejected at compile-time AND at
64
+ * runtime via `createCapxulConfig`'s allow-list validator.
63
65
  *
64
- * 1. **Legacy / harness path** pass an already-assembled
65
- * `config: CapxulConfig`. Used by the e2e harness and CLI-shaped
66
- * integrations that build their own auth/data adapters.
66
+ * The provider builds an `HttpTransport` synchronously and injects it
67
+ * into `createCapxulClient` via the internal `_transport` slot. The
68
+ * transport is exposed through `CapxulTransportContext` so
69
+ * `useCapxulStatus()` can subscribe to its lifecycle state machine.
67
70
  *
68
- * 2. **Lazy-DX path (ADR #14c)** pass either `publishableKey` or
69
- * `browserConfig`. The provider builds an `HttpTransport`
70
- * synchronously, injects it into `createCapxulClient` via the
71
- * internal `_transport` slot, and exposes the transport through
72
- * `CapxulTransportContext` so `useCapxulStatus()` can subscribe
73
- * to its lifecycle state machine.
74
- *
75
- * The lazy-DX provider mounts synchronously. There is no
76
- * `useState` mutating config, no `useMemo` rebuilding config when
77
- * state changes, and no Suspense gate at mount. State transitions
78
- * happen on the transport (a stable singleton); React subscribes
79
- * via `useSyncExternalStore` and re-renders only the components
80
- * that actually depend on the transport state.
71
+ * Tests and the e2e harness need the server-augmented `CapxulConfig`
72
+ * shape (with `data`, `signer`, `signing`). Those callers use
73
+ * `CapxulTestProvider` from `@capxul/sdk-react/proof` instead.
81
74
  *
82
75
  * Per ADR 4 in the API-first architecture stack PLAN, only
83
76
  * `QueryClientProvider` is allowed to live OUTSIDE the single
84
77
  * `CapxulContext`. The `QueryClientProvider` is the outermost wrap;
85
- * the SDK client provider sits inside it; the optional transport
86
- * provider sits between the two when the lazy-DX path is active.
78
+ * the SDK client provider sits inside it; the transport provider sits
79
+ * between the two.
87
80
  */
88
81
 
89
82
  type CapxulProviderProps = {
90
83
  /**
91
- * Pre-assembled `CapxulConfig` for the legacy / harness path.
92
- * Mutually exclusive with `publishableKey` / `browserConfig`.
93
- */
94
- readonly config?: CapxulConfig;
95
- /**
96
- * Shorthand for the publishable-key arm of `BrowserCapxulConfig`.
97
- * Provider builds the transport synchronously and injects it into
98
- * the SDK client — the canonical lazy-DX entry point per ADR #14c.
84
+ * Browser-safe Capxul config the discriminated union from
85
+ * `@capxul/sdk`. Either the `build-time-urls` arm or the
86
+ * `publishable-key` arm. Server-only fields (`apiKey`, `data`,
87
+ * `signer`, `signing`) are rejected at compile-time and at runtime
88
+ * via `createCapxulConfig`'s allow-list validator.
99
89
  */
100
- readonly publishableKey?: string;
101
- /**
102
- * Full `BrowserCapxulConfig` for callers that need
103
- * `mode: "build-time-urls"` or a custom `fetchImpl` (e.g. tests).
104
- * Mutually exclusive with `publishableKey` / `config`.
105
- */
106
- readonly browserConfig?: BrowserCapxulConfig;
90
+ readonly config: BrowserCapxulConfig;
107
91
  /**
108
92
  * Optional TanStack Query `QueryClient`. Pass your app's existing
109
93
  * client to share the cache across the SDK hooks and the host
@@ -113,7 +97,7 @@ type CapxulProviderProps = {
113
97
  readonly queryClient?: QueryClient;
114
98
  readonly children: ReactNode;
115
99
  };
116
- declare function CapxulProvider({ config, publishableKey, browserConfig, queryClient, children, }: CapxulProviderProps): ReactNode;
100
+ declare function CapxulProvider({ config, queryClient, children, }: CapxulProviderProps): ReactNode;
117
101
 
118
102
  /**
119
103
  * `QueryResult<T>` — the canonical three-state return shape for every
@@ -220,16 +204,27 @@ declare function useMe(): UseQueryResult<Account, CapxulError$1>;
220
204
  /**
221
205
  * Account by id. Omit `accountId` for the calling user (alias for
222
206
  * `useMe()` from a developer-perspective lens).
207
+ *
208
+ * Slice 2 (#457 story 1): wired via `capxul.accounts.retrieve` for
209
+ * the id-bearing call and `capxul.me.get()` for the self-lens
210
+ * shortcut. Returns the legacy `QueryResult<Account>` shape because
211
+ * only `useMe` has migrated to TanStack Query so far (PLAN.md task
212
+ * 1.8) — per-hook migration is the rollout pattern.
223
213
  */
224
- declare function useAccount(_accountId?: AccountId): QueryResult<Account>;
214
+ declare function useAccount(accountId?: AccountId): QueryResult<Account>;
225
215
  declare function useOrganization(_organizationId: OrganizationId): QueryResult<Organization>;
226
216
  declare function useMember(_args: UseMemberArgs): QueryResult<Member>;
227
217
  /**
228
218
  * Live; status advances as the indexer reconciles the on-chain
229
219
  * deployment. Consumers pattern-match on `data.status` via
230
220
  * `matchStatus` (see `@capxul/sdk`).
221
+ *
222
+ * Slice 2 (#457 story 1): wired via
223
+ * `capxul.accounts.safes.retrieve(safeId)`. The SDK method is real
224
+ * post-Withdrawals v1 slice 1; this hook closes the React-side
225
+ * stub so onboarding can subscribe to Safe deploy progress.
231
226
  */
232
- declare function useSafe(_safeId: SafeId): QueryResult<Safe>;
227
+ declare function useSafe(safeId: SafeId): QueryResult<Safe>;
233
228
  declare function useTreasury(_organizationId: OrganizationId): QueryResult<Treasury>;
234
229
  /**
235
230
  * Org-admin lens only — the hook NEVER returns `secret`.
@@ -243,6 +238,22 @@ declare function useVirtualAccount(_virtualAccountId: VirtualAccountId): QueryRe
243
238
  declare function useVirtualCard(_virtualCardId: VirtualCardId): QueryResult<VirtualCard>;
244
239
  declare function usePayment(_paymentId: PaymentId): QueryResult<Payment>;
245
240
  declare function useTransfer(_transferId: TransferId): QueryResult<Transfer>;
241
+ type UseTokenTransferArgs = {
242
+ readonly txHash: string;
243
+ readonly logIndex: number;
244
+ readonly chainId?: number;
245
+ };
246
+ /**
247
+ * **NON-CANONICAL** raw on-chain ERC-20 transfer detail. Wired through
248
+ * `capxul.tokenTransfers.retrieve` per slice/02-story2-balance
249
+ * Option-A verdict. Identifier is the canonical on-chain composite
250
+ * `(txHash, logIndex)` so consumers don't have to round-trip through
251
+ * the Convex doc id.
252
+ *
253
+ * Intentionally NOT in `packages/sdk-react/ops/proof/hook-manifest.ts`
254
+ * — the canonical proof manifest tracks canon-aligned hooks only.
255
+ */
256
+ declare function useTokenTransfer(args: UseTokenTransferArgs): QueryResult<TokenTransfer>;
246
257
  /**
247
258
  * Immutable once written; `live` semantically only for late
248
259
  * `paymentId` / `transferId` attachment per Doc 02 §"balance_ledger".
@@ -345,6 +356,17 @@ declare function usePayments(_filters?: PaymentsFilters): QueryResult<List<Payme
345
356
  declare function useOrgPayments(_args: OrgScopedFilters): QueryResult<List<Payment>>;
346
357
  declare function useTransfers(_filters?: TransfersFilters): QueryResult<List<Transfer>>;
347
358
  declare function useOrgTransfers(_args: OrgScopedFilters): QueryResult<List<Transfer>>;
359
+ /**
360
+ * **NON-CANONICAL** raw on-chain ERC-20 transfer feed. Wired through
361
+ * `capxul.tokenTransfers.list` per slice/02-story2-balance Option-A
362
+ * verdict. Will be subsumed by canonical `useTransfers` once the
363
+ * `transfers.*` shape alignment lands. See `core/token-transfers.ts`
364
+ * doc-comment for the full contract.
365
+ *
366
+ * Intentionally NOT in `packages/sdk-react/ops/proof/hook-manifest.ts`
367
+ * — the canonical proof manifest tracks canon-aligned hooks only.
368
+ */
369
+ declare function useTokenTransfers(filters?: TokenTransfersListInput): QueryResult<TokenTransfersListPage>;
348
370
  /**
349
371
  * Append-only per-owner balance-delta feed. Live for late
350
372
  * `paymentId` / `transferId` attachment per Doc 02.
@@ -470,4 +492,4 @@ declare function injectedConnector(options?: InjectedConnectorOptions): CapxulCo
470
492
  */
471
493
  declare function localPrivateKeyConnector(options: LocalPrivateKeyConnectorOptions): CapxulConnector;
472
494
 
473
- export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAccount, useApiKey, useApiKeys, useAuthFlow, useBalanceLedger, useBalanceLedgerEntry, useCapxul, useCapxulStatus, useDocument, useDocuments, useExternalAccount, useExternalAccounts, useKybProfile, useKycProfile, useMe, useMember, useMembers, useOnboardingFlow, useOperation, useOrgDocuments, useOrgPayments, useOrgTransfers, useOrgWithdrawals, useOrganization, useOrganizations, usePayment, usePayments, useProvisioningFlow, useSafe, useSubAccount, useSubAccounts, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };
495
+ export { CapxulClientProvider, type CapxulClientProviderProps, type CapxulConnector, type CapxulConnectorKind, type CapxulConnectorSession, CapxulProvider, type CapxulProviderProps, CapxulTransportProvider, type CapxulTransportProviderProps, type DocumentsFilters, type InjectedConnectorOptions, type LocalPrivateKeyConnectorOptions, type OrgDocumentsFilters, type OrgScopedFilters, type OwnerRef, type OwnerScopedFilters, type PaginationFilters, type PaymentsFilters, type QueryResult, type TransfersFilters, type UseApiKeyArgs, type UseBalanceLedgerEntryArgs, type UseExternalAccountArgs, type UseMemberArgs, type UseTokenTransferArgs, type VirtualAccountsFilters, type VirtualCardsFilters, type WithdrawalsFilters, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAccount, useApiKey, useApiKeys, useAuthFlow, useBalanceLedger, useBalanceLedgerEntry, useCapxul, useCapxulStatus, useDocument, useDocuments, useExternalAccount, useExternalAccounts, useKybProfile, useKycProfile, useMe, useMember, useMembers, useOnboardingFlow, useOperation, useOrgDocuments, useOrgPayments, useOrgTransfers, useOrgWithdrawals, useOrganization, useOrganizations, usePayment, usePayments, useProvisioningFlow, useSafe, useSubAccount, useSubAccounts, useTokenTransfer, useTokenTransfers, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { createContext, useContext, useSyncExternalStore, useMemo, useState, useEffect } from 'react';
3
- import { createCapxulClient, makeHttpTransport, CapxulError as CapxulError$1 } from '@capxul/sdk';
3
+ import { makeHttpTransport, createCapxulClient, CapxulError as CapxulError$1 } from '@capxul/sdk';
4
4
  import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
  import { CapxulError as CapxulError$2 } from '@capxul/sdk/errors';
@@ -9,6 +9,45 @@ import { getAddress } from 'viem';
9
9
  import { privateKeyToAccount } from 'viem/accounts';
10
10
 
11
11
  // src/provider.tsx
12
+ var CapxulClientContext = createContext(null);
13
+ function CapxulClientProvider({
14
+ client,
15
+ children
16
+ }) {
17
+ return /* @__PURE__ */ jsx(CapxulClientContext.Provider, { value: client, children });
18
+ }
19
+ function useCapxul() {
20
+ const client = useContext(CapxulClientContext);
21
+ if (!client) {
22
+ throw new Error(
23
+ "useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
24
+ );
25
+ }
26
+ return client;
27
+ }
28
+ var CapxulTransportContext = createContext(null);
29
+ function CapxulTransportProvider({
30
+ transport,
31
+ children
32
+ }) {
33
+ return /* @__PURE__ */ jsx(CapxulTransportContext.Provider, { value: transport, children });
34
+ }
35
+ function useCapxulStatus() {
36
+ const transport = useContext(CapxulTransportContext);
37
+ return useSyncExternalStore(
38
+ (listener) => {
39
+ if (!transport) return () => {
40
+ };
41
+ return transport.subscribe(listener);
42
+ },
43
+ () => transport?.getState() ?? FALLBACK_READY,
44
+ () => transport?.getState() ?? FALLBACK_READY
45
+ );
46
+ }
47
+ var FALLBACK_READY = Object.freeze({
48
+ status: "ready",
49
+ runtime: { authBaseUrl: "", convexUrl: "" }
50
+ });
12
51
 
13
52
  // ../config/src/errors.ts
14
53
  var CapxulError = class extends Error {
@@ -81,56 +120,62 @@ function roleKeyFromLabel(label) {
81
120
  roleKeyFromLabel("OWNER");
82
121
  roleKeyFromLabel("FINANCE_MANAGER");
83
122
  roleKeyFromLabel("TEAM_LEAD");
84
- var CapxulClientContext = createContext(null);
85
- function CapxulClientProvider({
86
- client,
87
- children
88
- }) {
89
- return /* @__PURE__ */ jsx(CapxulClientContext.Provider, { value: client, children });
90
- }
91
- function useCapxul() {
92
- const client = useContext(CapxulClientContext);
93
- if (!client) {
94
- throw new Error(
95
- "useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
96
- );
97
- }
98
- return client;
99
- }
100
- var CapxulTransportContext = createContext(null);
101
- function CapxulTransportProvider({
102
- transport,
103
- children
104
- }) {
105
- return /* @__PURE__ */ jsx(CapxulTransportContext.Provider, { value: transport, children });
123
+
124
+ // src/config.ts
125
+ function createCapxulConfig(input) {
126
+ assertOnlyKnownKeys(input);
127
+ assertModeRequiredFields(input);
128
+ return Object.freeze({ ...input });
106
129
  }
107
- function useCapxulStatus() {
108
- const transport = useContext(CapxulTransportContext);
109
- return useSyncExternalStore(
110
- (listener) => {
111
- if (!transport) return () => {
112
- };
113
- return transport.subscribe(listener);
114
- },
115
- () => transport?.getState() ?? FALLBACK_READY,
116
- () => transport?.getState() ?? FALLBACK_READY
130
+ var ALLOWED_BROWSER_CONFIG_KEYS = [
131
+ "mode",
132
+ "authBaseUrl",
133
+ "convexUrl",
134
+ "publishableKey",
135
+ "bootstrapUrl",
136
+ "fetchImpl"
137
+ ];
138
+ function assertOnlyKnownKeys(input) {
139
+ const candidate = input;
140
+ const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
141
+ const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
142
+ if (unknown.length === 0) return;
143
+ throw Errors.invalidInput(
144
+ "config",
145
+ `Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
117
146
  );
118
147
  }
119
- var FALLBACK_READY = Object.freeze({
120
- status: "ready",
121
- runtime: { authBaseUrl: "", convexUrl: "" }
122
- });
148
+ function assertModeRequiredFields(input) {
149
+ switch (input.mode) {
150
+ case "build-time-urls": {
151
+ if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
152
+ throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
153
+ }
154
+ if (!input.convexUrl || input.convexUrl.trim().length === 0) {
155
+ throw Errors.invalidInput("convexUrl", "non-empty string required.");
156
+ }
157
+ return;
158
+ }
159
+ case "publishable-key": {
160
+ if (!input.publishableKey || input.publishableKey.trim().length === 0) {
161
+ throw Errors.invalidInput("publishableKey", "non-empty string required.");
162
+ }
163
+ return;
164
+ }
165
+ default: {
166
+ const value = input;
167
+ throw Errors.internalError(
168
+ `Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
169
+ );
170
+ }
171
+ }
172
+ }
123
173
  function CapxulProvider({
124
174
  config,
125
- publishableKey,
126
- browserConfig,
127
175
  queryClient,
128
176
  children
129
177
  }) {
130
- const wiring = useMemo(
131
- () => buildWiring({ config, publishableKey, browserConfig }),
132
- [config, publishableKey, browserConfig]
133
- );
178
+ const wiring = useMemo(() => buildWiring(config), [config]);
134
179
  const defaultClient = useMemo(
135
180
  () => new QueryClient({
136
181
  defaultOptions: { queries: { staleTime: 3e4 } }
@@ -138,47 +183,14 @@ function CapxulProvider({
138
183
  []
139
184
  );
140
185
  const effectiveClient = queryClient ?? defaultClient;
141
- const inner = /* @__PURE__ */ jsx(CapxulClientProvider, { client: wiring.client, children });
142
- return /* @__PURE__ */ jsx(QueryClientProvider, { client: effectiveClient, children: wiring.transport ? /* @__PURE__ */ jsx(CapxulTransportProvider, { transport: wiring.transport, children: inner }) : inner });
186
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: effectiveClient, children: /* @__PURE__ */ jsx(CapxulTransportProvider, { transport: wiring.transport, children: /* @__PURE__ */ jsx(CapxulClientProvider, { client: wiring.client, children }) }) });
143
187
  }
144
- function buildWiring({
145
- config,
146
- publishableKey,
147
- browserConfig
148
- }) {
149
- const sources = [
150
- config !== void 0,
151
- publishableKey !== void 0,
152
- browserConfig !== void 0
153
- ].filter(Boolean).length;
154
- if (sources === 0) {
155
- throw Errors.invalidInput(
156
- "CapxulProvider",
157
- "Pass exactly one of `config`, `publishableKey`, or `browserConfig`."
158
- );
159
- }
160
- if (sources > 1) {
161
- throw Errors.invalidInput(
162
- "CapxulProvider",
163
- "`config`, `publishableKey`, and `browserConfig` are mutually exclusive \u2014 pass exactly one."
164
- );
165
- }
166
- if (config !== void 0) {
167
- return {
168
- client: createCapxulClient(config),
169
- transport: null
170
- };
171
- }
172
- const browserCfg = browserConfig ?? {
173
- mode: "publishable-key",
174
- // The narrowing above (`sources === 0` rejected; `config` not
175
- // present) guarantees `publishableKey` is set on this branch.
176
- publishableKey
177
- };
178
- const transport = makeHttpTransport(browserCfg);
188
+ function buildWiring(config) {
189
+ const validated = createCapxulConfig(config);
190
+ const transport = makeHttpTransport(validated);
179
191
  const sdkConfig = {
180
192
  _transport: transport,
181
- publishableKey: browserCfg.mode === "publishable-key" ? browserCfg.publishableKey : void 0
193
+ publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0
182
194
  };
183
195
  return {
184
196
  client: createCapxulClient(sdkConfig),
@@ -272,8 +284,12 @@ function useMe() {
272
284
  staleTime: 3e4
273
285
  });
274
286
  }
275
- function useAccount(_accountId) {
276
- return notImplementedQuery("useAccount");
287
+ function useAccount(accountId) {
288
+ const capxul = useCapxul();
289
+ return useSdkQuery(
290
+ () => accountId !== void 0 ? capxul.accounts.retrieve(accountId) : capxul.me.get(),
291
+ [capxul, accountId]
292
+ );
277
293
  }
278
294
  function useOrganization(_organizationId) {
279
295
  return notImplementedQuery("useOrganization");
@@ -281,8 +297,12 @@ function useOrganization(_organizationId) {
281
297
  function useMember(_args) {
282
298
  return notImplementedQuery("useMember");
283
299
  }
284
- function useSafe(_safeId) {
285
- return notImplementedQuery("useSafe");
300
+ function useSafe(safeId) {
301
+ const capxul = useCapxul();
302
+ return useSdkQuery(
303
+ () => capxul.accounts.safes.retrieve(safeId),
304
+ [capxul, safeId]
305
+ );
286
306
  }
287
307
  function useTreasury(_organizationId) {
288
308
  return notImplementedQuery("useTreasury");
@@ -314,6 +334,13 @@ function usePayment(_paymentId) {
314
334
  function useTransfer(_transferId) {
315
335
  return notImplementedQuery("useTransfer");
316
336
  }
337
+ function useTokenTransfer(args) {
338
+ const capxul = useCapxul();
339
+ return useSdkQuery(
340
+ () => capxul.tokenTransfers.retrieve(args),
341
+ [capxul, args.txHash, args.logIndex, args.chainId]
342
+ );
343
+ }
317
344
  function useBalanceLedgerEntry(_args) {
318
345
  return notImplementedQuery("useBalanceLedgerEntry");
319
346
  }
@@ -372,6 +399,13 @@ function useTransfers(_filters) {
372
399
  function useOrgTransfers(_args) {
373
400
  return notImplementedQuery("useOrgTransfers");
374
401
  }
402
+ function useTokenTransfers(filters) {
403
+ const capxul = useCapxul();
404
+ return useSdkQuery(
405
+ () => capxul.tokenTransfers.list(filters),
406
+ [capxul, filters?.limit, filters?.cursor, filters?.direction]
407
+ );
408
+ }
375
409
  function useBalanceLedger(_args) {
376
410
  return notImplementedQuery("useBalanceLedger");
377
411
  }
@@ -419,56 +453,6 @@ function useProvisioningFlow() {
419
453
  const [snapshot, send] = useActor(machine);
420
454
  return { snapshot, send };
421
455
  }
422
-
423
- // src/config.ts
424
- function createCapxulConfig(input) {
425
- assertOnlyKnownKeys(input);
426
- assertModeRequiredFields(input);
427
- return Object.freeze({ ...input });
428
- }
429
- var ALLOWED_BROWSER_CONFIG_KEYS = [
430
- "mode",
431
- "authBaseUrl",
432
- "convexUrl",
433
- "publishableKey",
434
- "bootstrapUrl",
435
- "fetchImpl"
436
- ];
437
- function assertOnlyKnownKeys(input) {
438
- const candidate = input;
439
- const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
440
- const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
441
- if (unknown.length === 0) return;
442
- throw Errors.invalidInput(
443
- "config",
444
- `Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
445
- );
446
- }
447
- function assertModeRequiredFields(input) {
448
- switch (input.mode) {
449
- case "build-time-urls": {
450
- if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
451
- throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
452
- }
453
- if (!input.convexUrl || input.convexUrl.trim().length === 0) {
454
- throw Errors.invalidInput("convexUrl", "non-empty string required.");
455
- }
456
- return;
457
- }
458
- case "publishable-key": {
459
- if (!input.publishableKey || input.publishableKey.trim().length === 0) {
460
- throw Errors.invalidInput("publishableKey", "non-empty string required.");
461
- }
462
- return;
463
- }
464
- default: {
465
- const value = input;
466
- throw Errors.internalError(
467
- `Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
468
- );
469
- }
470
- }
471
- }
472
456
  var PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
473
457
  var EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;
474
458
  function injectedConnector(options = {}) {
@@ -565,4 +549,4 @@ function validateAndNormalizeEvmAddress(field, raw) {
565
549
  }
566
550
  }
567
551
 
568
- export { CapxulClientProvider, CapxulProvider, CapxulTransportProvider, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAccount, useApiKey, useApiKeys, useAuthFlow, useBalanceLedger, useBalanceLedgerEntry, useCapxul, useCapxulStatus, useDocument, useDocuments, useExternalAccount, useExternalAccounts, useKybProfile, useKycProfile, useMe, useMember, useMembers, useOnboardingFlow, useOperation, useOrgDocuments, useOrgPayments, useOrgTransfers, useOrgWithdrawals, useOrganization, useOrganizations, usePayment, usePayments, useProvisioningFlow, useSafe, useSubAccount, useSubAccounts, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };
552
+ export { CapxulClientProvider, CapxulProvider, CapxulTransportProvider, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAccount, useApiKey, useApiKeys, useAuthFlow, useBalanceLedger, useBalanceLedgerEntry, useCapxul, useCapxulStatus, useDocument, useDocuments, useExternalAccount, useExternalAccounts, useKybProfile, useKycProfile, useMe, useMember, useMembers, useOnboardingFlow, useOperation, useOrgDocuments, useOrgPayments, useOrgTransfers, useOrgWithdrawals, useOrganization, useOrganizations, usePayment, usePayments, useProvisioningFlow, useSafe, useSubAccount, useSubAccounts, useTokenTransfer, useTokenTransfers, useTransfer, useTransfers, useTreasury, useVirtualAccount, useVirtualAccounts, useVirtualCard, useVirtualCards, useWebhookEndpoint, useWebhookEndpoints, useWebhookEvent, useWithdrawal, useWithdrawals };