@capxul/sdk-react 0.1.0-alpha.1 → 0.1.0-alpha.11
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/CHANGELOG.md +150 -0
- package/README.md +21 -1
- package/dist/index.cjs +312 -145
- package/dist/index.d.cts +238 -44
- package/dist/index.d.ts +238 -44
- package/dist/index.js +312 -148
- package/dist/proof/index.cjs +12777 -0
- package/dist/proof/index.d.cts +753 -0
- package/dist/proof/index.d.ts +753 -0
- package/dist/proof/index.js +12750 -0
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1,14 +1,54 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, useContext, useSyncExternalStore, useMemo,
|
|
3
|
-
import {
|
|
2
|
+
import { createContext, useContext, useSyncExternalStore, useMemo, useEffect, useState } from 'react';
|
|
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
|
+
import { ConvexReactClient } from 'convex/react';
|
|
6
7
|
import { CapxulError as CapxulError$2 } from '@capxul/sdk/errors';
|
|
7
8
|
import { useActor } from '@xstate/react';
|
|
8
9
|
import { getAddress } from 'viem';
|
|
9
10
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
10
11
|
|
|
11
12
|
// src/provider.tsx
|
|
13
|
+
var CapxulClientContext = createContext(null);
|
|
14
|
+
function CapxulClientProvider({
|
|
15
|
+
client,
|
|
16
|
+
children
|
|
17
|
+
}) {
|
|
18
|
+
return /* @__PURE__ */ jsx(CapxulClientContext.Provider, { value: client, children });
|
|
19
|
+
}
|
|
20
|
+
function useCapxul() {
|
|
21
|
+
const client = useContext(CapxulClientContext);
|
|
22
|
+
if (!client) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
"useCapxul() was called outside a <CapxulProvider>. Wrap your app in <CapxulProvider config={...}> before rendering hooks from @capxul/sdk-react."
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return client;
|
|
28
|
+
}
|
|
29
|
+
var CapxulTransportContext = createContext(null);
|
|
30
|
+
function CapxulTransportProvider({
|
|
31
|
+
transport,
|
|
32
|
+
children
|
|
33
|
+
}) {
|
|
34
|
+
return /* @__PURE__ */ jsx(CapxulTransportContext.Provider, { value: transport, children });
|
|
35
|
+
}
|
|
36
|
+
function useCapxulStatus() {
|
|
37
|
+
const transport = useContext(CapxulTransportContext);
|
|
38
|
+
return useSyncExternalStore(
|
|
39
|
+
(listener) => {
|
|
40
|
+
if (!transport) return () => {
|
|
41
|
+
};
|
|
42
|
+
return transport.subscribe(listener);
|
|
43
|
+
},
|
|
44
|
+
() => transport?.getState() ?? FALLBACK_READY,
|
|
45
|
+
() => transport?.getState() ?? FALLBACK_READY
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
var FALLBACK_READY = Object.freeze({
|
|
49
|
+
status: "ready",
|
|
50
|
+
runtime: { authBaseUrl: "", convexUrl: "" }
|
|
51
|
+
});
|
|
12
52
|
|
|
13
53
|
// ../config/src/errors.ts
|
|
14
54
|
var CapxulError = class extends Error {
|
|
@@ -39,10 +79,16 @@ var Errors = {
|
|
|
39
79
|
`Shield API error (${status}): ${detail}`,
|
|
40
80
|
{ details: { provider: "shield", status } }
|
|
41
81
|
),
|
|
42
|
-
providerError: (provider, operation, cause) =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
82
|
+
providerError: (provider, operation, cause) => (
|
|
83
|
+
// Public `message` is redacted to a fixed shape so provider-side
|
|
84
|
+
// exception text never leaks to the client. The original `cause`
|
|
85
|
+
// is preserved on `Error.cause` for server-side debugging via
|
|
86
|
+
// observability sinks (Sentry, console traces).
|
|
87
|
+
new CapxulError(
|
|
88
|
+
"PROVIDER_ERROR",
|
|
89
|
+
`Provider error: ${provider} ${operation}`,
|
|
90
|
+
{ cause, details: { provider, operation } }
|
|
91
|
+
)
|
|
46
92
|
),
|
|
47
93
|
invalidInput: (field, reason) => new CapxulError(
|
|
48
94
|
"INVALID_INPUT",
|
|
@@ -68,8 +114,35 @@ var Errors = {
|
|
|
68
114
|
"Idempotency key was already used for a different request",
|
|
69
115
|
{ details }
|
|
70
116
|
),
|
|
71
|
-
emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}
|
|
72
|
-
|
|
117
|
+
emailDeliveryFailed: (detail, details) => new CapxulError("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
|
|
118
|
+
details
|
|
119
|
+
}),
|
|
120
|
+
rateLimited: (details) => new CapxulError("RATE_LIMITED", "Request was rate limited", {
|
|
121
|
+
details: { ...details }
|
|
122
|
+
}),
|
|
123
|
+
internalError: (reason) => new CapxulError("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
124
|
+
/**
|
|
125
|
+
* Verification gate. Surfaced when a request hits a verification
|
|
126
|
+
* boundary the actor cannot cross under their current state. Two
|
|
127
|
+
* variants share this code:
|
|
128
|
+
*
|
|
129
|
+
* - Rail gate (Withdrawals v1 W2, #465): the resolved
|
|
130
|
+
* `external_account.kind` routes to a withdrawal rail (e.g.
|
|
131
|
+
* `fiat_offramp`, `card_payout`) that is not yet supported. Carries
|
|
132
|
+
* `details.rail` + `details.currentKind`.
|
|
133
|
+
* - KYC tier gate (legacy / future): the actor's KYC tier is below
|
|
134
|
+
* the required tier. Carries `details.requiredTier`.
|
|
135
|
+
*
|
|
136
|
+
* Code is shared because both expose the same UX shape ("you cannot
|
|
137
|
+
* proceed until verification advances"); the `details.*` keys
|
|
138
|
+
* differentiate the route.
|
|
139
|
+
*/
|
|
140
|
+
verificationRequired: (details) => {
|
|
141
|
+
const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
|
|
142
|
+
return new CapxulError("VERIFICATION_REQUIRED", message, {
|
|
143
|
+
details: { ...details }
|
|
144
|
+
});
|
|
145
|
+
}
|
|
73
146
|
};
|
|
74
147
|
|
|
75
148
|
// ../config/src/org-roles.ts
|
|
@@ -81,56 +154,137 @@ function roleKeyFromLabel(label) {
|
|
|
81
154
|
roleKeyFromLabel("OWNER");
|
|
82
155
|
roleKeyFromLabel("FINANCE_MANAGER");
|
|
83
156
|
roleKeyFromLabel("TEAM_LEAD");
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
157
|
+
|
|
158
|
+
// src/config.ts
|
|
159
|
+
function createCapxulConfig(input) {
|
|
160
|
+
assertOnlyKnownKeys(input);
|
|
161
|
+
assertModeRequiredFields(input);
|
|
162
|
+
return Object.freeze({ ...input });
|
|
90
163
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
164
|
+
var ALLOWED_BROWSER_CONFIG_KEYS = [
|
|
165
|
+
"mode",
|
|
166
|
+
"authBaseUrl",
|
|
167
|
+
"convexUrl",
|
|
168
|
+
"publishableKey",
|
|
169
|
+
"bootstrapUrl",
|
|
170
|
+
"fetchImpl"
|
|
171
|
+
];
|
|
172
|
+
function assertOnlyKnownKeys(input) {
|
|
173
|
+
const candidate = input;
|
|
174
|
+
const allowed = new Set(ALLOWED_BROWSER_CONFIG_KEYS);
|
|
175
|
+
const unknown = Object.keys(candidate).filter((key) => !allowed.has(key));
|
|
176
|
+
if (unknown.length === 0) return;
|
|
177
|
+
throw Errors.invalidInput(
|
|
178
|
+
"config",
|
|
179
|
+
`Browser Capxul config contains unknown or secret/server-only fields: ${unknown.join(", ")}. Allowed keys: ${ALLOWED_BROWSER_CONFIG_KEYS.join(", ")}.`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
function assertModeRequiredFields(input) {
|
|
183
|
+
switch (input.mode) {
|
|
184
|
+
case "build-time-urls": {
|
|
185
|
+
if (!input.authBaseUrl || input.authBaseUrl.trim().length === 0) {
|
|
186
|
+
throw Errors.invalidInput("authBaseUrl", "non-empty string required.");
|
|
187
|
+
}
|
|
188
|
+
if (!input.convexUrl || input.convexUrl.trim().length === 0) {
|
|
189
|
+
throw Errors.invalidInput("convexUrl", "non-empty string required.");
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
case "publishable-key": {
|
|
194
|
+
if (!input.publishableKey || input.publishableKey.trim().length === 0) {
|
|
195
|
+
throw Errors.invalidInput("publishableKey", "non-empty string required.");
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
default: {
|
|
200
|
+
const value = input;
|
|
201
|
+
throw Errors.internalError(
|
|
202
|
+
`Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
97
205
|
}
|
|
98
|
-
return client;
|
|
99
206
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
207
|
+
function createReactDataClient(convexUrl, sessionStore) {
|
|
208
|
+
const client = new ConvexReactClient(convexUrl);
|
|
209
|
+
const refreshAuth = () => {
|
|
210
|
+
const session = sessionStore.get();
|
|
211
|
+
const jwt = session?.convexJwt;
|
|
212
|
+
if (jwt) {
|
|
213
|
+
client.setAuth(() => Promise.resolve(jwt));
|
|
214
|
+
} else {
|
|
215
|
+
client.clearAuth();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
refreshAuth();
|
|
219
|
+
return {
|
|
220
|
+
query: (name, args) => client.query(name, args),
|
|
221
|
+
mutation: (name, args) => client.mutation(name, args),
|
|
222
|
+
action: (name, args) => client.action(name, args),
|
|
223
|
+
refreshAuth,
|
|
224
|
+
close: () => {
|
|
225
|
+
void client.close();
|
|
226
|
+
}
|
|
227
|
+
};
|
|
106
228
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
229
|
+
function createLazyReactDataClient(transport, sessionStore, createClient = createReactDataClient) {
|
|
230
|
+
let client = null;
|
|
231
|
+
let initializeClient = null;
|
|
232
|
+
let closed = false;
|
|
233
|
+
function closedError() {
|
|
234
|
+
return new Error("Capxul React data client is closed");
|
|
235
|
+
}
|
|
236
|
+
async function getClient() {
|
|
237
|
+
if (closed) throw closedError();
|
|
238
|
+
if (client) return client;
|
|
239
|
+
initializeClient ??= (async () => {
|
|
240
|
+
const runtime = await transport.ensureRuntime();
|
|
241
|
+
if (closed) throw closedError();
|
|
242
|
+
const nextClient = createClient(runtime.convexUrl, sessionStore);
|
|
243
|
+
if (closed) {
|
|
244
|
+
nextClient.close();
|
|
245
|
+
throw closedError();
|
|
246
|
+
}
|
|
247
|
+
client = nextClient;
|
|
248
|
+
return nextClient;
|
|
249
|
+
})().catch((error) => {
|
|
250
|
+
if (!closed) {
|
|
251
|
+
initializeClient = null;
|
|
252
|
+
}
|
|
253
|
+
throw error;
|
|
254
|
+
});
|
|
255
|
+
return initializeClient;
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
query: async (name, args) => (await getClient()).query(name, args),
|
|
259
|
+
mutation: async (name, args) => (await getClient()).mutation(name, args),
|
|
260
|
+
action: async (name, args) => (await getClient()).action?.(name, args),
|
|
261
|
+
refreshAuth: () => {
|
|
262
|
+
client?.refreshAuth();
|
|
114
263
|
},
|
|
115
|
-
() =>
|
|
116
|
-
|
|
117
|
-
|
|
264
|
+
close: () => {
|
|
265
|
+
closed = true;
|
|
266
|
+
client?.close();
|
|
267
|
+
client = null;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
118
270
|
}
|
|
119
|
-
var FALLBACK_READY = Object.freeze({
|
|
120
|
-
status: "ready",
|
|
121
|
-
runtime: { authBaseUrl: "", convexUrl: "" }
|
|
122
|
-
});
|
|
123
271
|
function CapxulProvider({
|
|
124
272
|
config,
|
|
125
|
-
|
|
126
|
-
browserConfig,
|
|
273
|
+
sessionStore,
|
|
127
274
|
queryClient,
|
|
128
275
|
children
|
|
129
276
|
}) {
|
|
277
|
+
const defaultSessionStore = useMemo(() => createMemorySessionStore(), []);
|
|
278
|
+
const effectiveSessionStore = sessionStore ?? defaultSessionStore;
|
|
130
279
|
const wiring = useMemo(
|
|
131
|
-
() => buildWiring(
|
|
132
|
-
[config,
|
|
280
|
+
() => buildWiring(config, effectiveSessionStore),
|
|
281
|
+
[config, effectiveSessionStore]
|
|
133
282
|
);
|
|
283
|
+
useEffect(() => {
|
|
284
|
+
return () => {
|
|
285
|
+
wiring.dataClient?.close();
|
|
286
|
+
};
|
|
287
|
+
}, [wiring]);
|
|
134
288
|
const defaultClient = useMemo(
|
|
135
289
|
() => new QueryClient({
|
|
136
290
|
defaultOptions: { queries: { staleTime: 3e4 } }
|
|
@@ -138,51 +292,60 @@ function CapxulProvider({
|
|
|
138
292
|
[]
|
|
139
293
|
);
|
|
140
294
|
const effectiveClient = queryClient ?? defaultClient;
|
|
141
|
-
|
|
142
|
-
return /* @__PURE__ */ jsx(QueryClientProvider, { client: effectiveClient, children: wiring.transport ? /* @__PURE__ */ jsx(CapxulTransportProvider, { transport: wiring.transport, children: inner }) : inner });
|
|
295
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client: effectiveClient, children: /* @__PURE__ */ jsx(CapxulTransportProvider, { transport: wiring.transport, children: /* @__PURE__ */ jsx(CapxulClientProvider, { client: wiring.client, children }) }) });
|
|
143
296
|
}
|
|
144
|
-
function buildWiring({
|
|
145
|
-
config
|
|
146
|
-
|
|
147
|
-
|
|
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);
|
|
297
|
+
function buildWiring(config, sessionStore) {
|
|
298
|
+
const validated = createCapxulConfig(config);
|
|
299
|
+
const transport = makeHttpTransport(validated);
|
|
300
|
+
const dataClient = validated.mode === "build-time-urls" ? createReactDataClient(validated.convexUrl, sessionStore) : createLazyReactDataClient(transport, sessionStore);
|
|
179
301
|
const sdkConfig = {
|
|
180
302
|
_transport: transport,
|
|
181
|
-
publishableKey:
|
|
303
|
+
publishableKey: validated.mode === "publishable-key" ? validated.publishableKey : void 0,
|
|
304
|
+
data: dataClient ?? void 0,
|
|
305
|
+
auth: validated.mode === "build-time-urls" || validated.mode === "publishable-key" ? {
|
|
306
|
+
// The auth client builds the BetterAuth root URL from this
|
|
307
|
+
// value. Convex's `.cloud` URL is the wrong host (BetterAuth
|
|
308
|
+
// is mounted on the `.site` URL), but the build-time-urls
|
|
309
|
+
// transport already encodes the correct `authBaseUrl` via
|
|
310
|
+
// its discriminated union. We pass `convexUrl` here only so
|
|
311
|
+
// `core/auth.ts`'s `createTransportProvider` short-circuits
|
|
312
|
+
// to the externally-injected `_transport` cache slot.
|
|
313
|
+
baseUrl: transport.authBaseUrl,
|
|
314
|
+
sessionStore,
|
|
315
|
+
createDataClient: async (_session) => {
|
|
316
|
+
dataClient.refreshAuth();
|
|
317
|
+
return dataClient;
|
|
318
|
+
}
|
|
319
|
+
} : void 0
|
|
320
|
+
};
|
|
321
|
+
const client = createCapxulClient(sdkConfig);
|
|
322
|
+
if (dataClient) {
|
|
323
|
+
const originalSignOut = client.auth.signOut;
|
|
324
|
+
Object.assign(client.auth, {
|
|
325
|
+
signOut: async () => {
|
|
326
|
+
const result = await originalSignOut();
|
|
327
|
+
dataClient.refreshAuth();
|
|
328
|
+
sdkConfig.data = dataClient;
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
client,
|
|
335
|
+
transport,
|
|
336
|
+
dataClient
|
|
182
337
|
};
|
|
338
|
+
}
|
|
339
|
+
function createMemorySessionStore() {
|
|
340
|
+
let current = null;
|
|
183
341
|
return {
|
|
184
|
-
|
|
185
|
-
|
|
342
|
+
get: () => current,
|
|
343
|
+
set: (session) => {
|
|
344
|
+
current = session;
|
|
345
|
+
},
|
|
346
|
+
clear: () => {
|
|
347
|
+
current = null;
|
|
348
|
+
}
|
|
186
349
|
};
|
|
187
350
|
}
|
|
188
351
|
function notImplementedQuery(hookName) {
|
|
@@ -272,8 +435,12 @@ function useMe() {
|
|
|
272
435
|
staleTime: 3e4
|
|
273
436
|
});
|
|
274
437
|
}
|
|
275
|
-
function useAccount(
|
|
276
|
-
|
|
438
|
+
function useAccount(accountId) {
|
|
439
|
+
const capxul = useCapxul();
|
|
440
|
+
return useSdkQuery(
|
|
441
|
+
() => accountId !== void 0 ? capxul.accounts.retrieve(accountId) : capxul.me.get(),
|
|
442
|
+
[capxul, accountId]
|
|
443
|
+
);
|
|
277
444
|
}
|
|
278
445
|
function useOrganization(_organizationId) {
|
|
279
446
|
return notImplementedQuery("useOrganization");
|
|
@@ -281,8 +448,12 @@ function useOrganization(_organizationId) {
|
|
|
281
448
|
function useMember(_args) {
|
|
282
449
|
return notImplementedQuery("useMember");
|
|
283
450
|
}
|
|
284
|
-
function useSafe(
|
|
285
|
-
|
|
451
|
+
function useSafe(safeId) {
|
|
452
|
+
const capxul = useCapxul();
|
|
453
|
+
return useSdkQuery(
|
|
454
|
+
() => capxul.accounts.safes.retrieve(safeId),
|
|
455
|
+
[capxul, safeId]
|
|
456
|
+
);
|
|
286
457
|
}
|
|
287
458
|
function useTreasury(_organizationId) {
|
|
288
459
|
return notImplementedQuery("useTreasury");
|
|
@@ -296,11 +467,22 @@ function useKycProfile(_accountId) {
|
|
|
296
467
|
function useKybProfile(_organizationId) {
|
|
297
468
|
return notImplementedQuery("useKybProfile");
|
|
298
469
|
}
|
|
299
|
-
function useExternalAccount(
|
|
300
|
-
|
|
470
|
+
function useExternalAccount(args) {
|
|
471
|
+
const capxul = useCapxul();
|
|
472
|
+
return useSdkQuery(
|
|
473
|
+
() => args.ownerKind === "account" ? capxul.externalAccounts.retrieve(args.externalAccountId) : capxul.organizations.externalAccounts.retrieve({
|
|
474
|
+
organizationId: args.ownerId,
|
|
475
|
+
externalAccountId: args.externalAccountId
|
|
476
|
+
}),
|
|
477
|
+
[capxul, args.ownerKind, args.ownerId, args.externalAccountId]
|
|
478
|
+
);
|
|
301
479
|
}
|
|
302
|
-
function useSubAccount(
|
|
303
|
-
|
|
480
|
+
function useSubAccount(subAccountId) {
|
|
481
|
+
const capxul = useCapxul();
|
|
482
|
+
return useSdkQuery(
|
|
483
|
+
() => capxul.subAccounts.retrieve(subAccountId),
|
|
484
|
+
[capxul, subAccountId]
|
|
485
|
+
);
|
|
304
486
|
}
|
|
305
487
|
function useVirtualAccount(_virtualAccountId) {
|
|
306
488
|
return notImplementedQuery("useVirtualAccount");
|
|
@@ -314,6 +496,13 @@ function usePayment(_paymentId) {
|
|
|
314
496
|
function useTransfer(_transferId) {
|
|
315
497
|
return notImplementedQuery("useTransfer");
|
|
316
498
|
}
|
|
499
|
+
function useTokenTransfer(args) {
|
|
500
|
+
const capxul = useCapxul();
|
|
501
|
+
return useSdkQuery(
|
|
502
|
+
() => capxul.tokenTransfers.retrieve(args),
|
|
503
|
+
[capxul, args.txHash, args.logIndex, args.chainId]
|
|
504
|
+
);
|
|
505
|
+
}
|
|
317
506
|
function useBalanceLedgerEntry(_args) {
|
|
318
507
|
return notImplementedQuery("useBalanceLedgerEntry");
|
|
319
508
|
}
|
|
@@ -348,11 +537,23 @@ function useOrganizations() {
|
|
|
348
537
|
function useMembers(_organizationId) {
|
|
349
538
|
return notImplementedQuery("useMembers");
|
|
350
539
|
}
|
|
351
|
-
function useExternalAccounts(
|
|
352
|
-
|
|
540
|
+
function useExternalAccounts(args) {
|
|
541
|
+
const capxul = useCapxul();
|
|
542
|
+
return useSdkQuery(
|
|
543
|
+
() => args.ownerKind === "account" ? capxul.accounts.externalAccounts.list({ accountId: args.ownerId }) : capxul.organizations.externalAccounts.list({
|
|
544
|
+
organizationId: args.ownerId
|
|
545
|
+
}),
|
|
546
|
+
[capxul, args.ownerKind, args.ownerId]
|
|
547
|
+
);
|
|
353
548
|
}
|
|
354
|
-
function useSubAccounts(
|
|
355
|
-
|
|
549
|
+
function useSubAccounts(args) {
|
|
550
|
+
const capxul = useCapxul();
|
|
551
|
+
return useSdkQuery(
|
|
552
|
+
() => args.ownerKind === "account" ? capxul.accounts.subAccounts.list({ accountId: args.ownerId }) : capxul.organizations.subAccounts.list({
|
|
553
|
+
organizationId: args.ownerId
|
|
554
|
+
}),
|
|
555
|
+
[capxul, args.ownerKind, args.ownerId]
|
|
556
|
+
);
|
|
356
557
|
}
|
|
357
558
|
function useVirtualAccounts(_filters) {
|
|
358
559
|
return notImplementedQuery("useVirtualAccounts");
|
|
@@ -372,6 +573,13 @@ function useTransfers(_filters) {
|
|
|
372
573
|
function useOrgTransfers(_args) {
|
|
373
574
|
return notImplementedQuery("useOrgTransfers");
|
|
374
575
|
}
|
|
576
|
+
function useTokenTransfers(filters) {
|
|
577
|
+
const capxul = useCapxul();
|
|
578
|
+
return useSdkQuery(
|
|
579
|
+
() => capxul.tokenTransfers.list(filters),
|
|
580
|
+
[capxul, filters?.limit, filters?.cursor, filters?.direction]
|
|
581
|
+
);
|
|
582
|
+
}
|
|
375
583
|
function useBalanceLedger(_args) {
|
|
376
584
|
return notImplementedQuery("useBalanceLedger");
|
|
377
585
|
}
|
|
@@ -407,6 +615,12 @@ function useAuthFlow() {
|
|
|
407
615
|
const [snapshot, send] = useActor(machine);
|
|
408
616
|
return { snapshot, send };
|
|
409
617
|
}
|
|
618
|
+
function useAuthBootstrapFlow() {
|
|
619
|
+
const client = useCapxul();
|
|
620
|
+
const machine = useMemo(() => client.flows.authBootstrap(), [client]);
|
|
621
|
+
const [snapshot, send] = useActor(machine);
|
|
622
|
+
return { snapshot, send };
|
|
623
|
+
}
|
|
410
624
|
function useOnboardingFlow() {
|
|
411
625
|
const client = useCapxul();
|
|
412
626
|
const machine = useMemo(() => client.flows.onboarding(), [client]);
|
|
@@ -419,56 +633,6 @@ function useProvisioningFlow() {
|
|
|
419
633
|
const [snapshot, send] = useActor(machine);
|
|
420
634
|
return { snapshot, send };
|
|
421
635
|
}
|
|
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
636
|
var PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
473
637
|
var EVM_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;
|
|
474
638
|
function injectedConnector(options = {}) {
|
|
@@ -565,4 +729,4 @@ function validateAndNormalizeEvmAddress(field, raw) {
|
|
|
565
729
|
}
|
|
566
730
|
}
|
|
567
731
|
|
|
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 };
|
|
732
|
+
export { CapxulClientProvider, CapxulProvider, CapxulTransportProvider, createCapxulConfig, injectedConnector, localPrivateKeyConnector, useAccount, useApiKey, useApiKeys, useAuthBootstrapFlow, 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 };
|