@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/CHANGELOG.md +108 -0
- package/README.md +45 -0
- package/dist/{client-DG6ODWu6.d.cts → client-B_Z3ThFO.d.cts} +49 -51
- package/dist/{client-ChZrdf3R.d.ts → client-pMBRFcsz.d.ts} +49 -51
- package/dist/client.cjs +1283 -419
- package/dist/client.d.cts +4 -4
- package/dist/client.d.ts +4 -4
- package/dist/client.js +1283 -419
- package/dist/{errors-QHD5Tlok.d.ts → errors-CwhCWGxm.d.ts} +1 -1
- package/dist/{errors-GgKrSUKp.d.cts → errors-rqxuUhQP.d.cts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/errors.d.ts +2 -2
- package/dist/index.cjs +1342 -410
- package/dist/index.d.cts +80 -9
- package/dist/index.d.ts +80 -9
- package/dist/index.js +1341 -412
- package/dist/{next-action-DkrwXYay.d.cts → next-action-CTGl8wpy.d.cts} +2 -2
- package/dist/{next-action-DkrwXYay.d.ts → next-action-CTGl8wpy.d.ts} +2 -2
- package/dist/{types-hfcOE7Oi.d.cts → types-Brucpq0Z.d.cts} +63 -8
- package/dist/{types-PM4AQRLP.d.ts → types-V_D7qjxY.d.ts} +63 -8
- package/dist/webhooks.cjs +1 -1
- package/dist/webhooks.d.cts +2 -2
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +1 -1
- package/package.json +7 -5
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
|
-
"
|
|
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.
|
|
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.
|
|
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.
|
|
440
|
+
if (!config._data) {
|
|
285
441
|
return stub("externalAccounts.remove");
|
|
286
442
|
}
|
|
287
443
|
const [err] = await tryCatch(
|
|
288
|
-
config.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
755
|
+
if (!config._data) {
|
|
414
756
|
return stub("accounts.externalAccounts.remove");
|
|
415
757
|
}
|
|
416
758
|
const [err] = await tryCatch(
|
|
417
|
-
config.
|
|
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.
|
|
924
|
+
if (!config._data) {
|
|
435
925
|
return stub("accounts.retrieve");
|
|
436
926
|
}
|
|
437
927
|
try {
|
|
438
|
-
const account = await config.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
1019
|
+
safeAddress: deriveSafeAddress(input.signerProvider.signerAddress)
|
|
530
1020
|
}
|
|
531
1021
|
);
|
|
532
|
-
const account = await config.
|
|
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.
|
|
556
|
-
return stub("accounts.safes.retrieve");
|
|
557
|
-
}
|
|
558
|
-
try {
|
|
559
|
-
const safe = await config.
|
|
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
|
-
|
|
588
|
-
list: async () =>
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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
|
-
//
|
|
718
|
-
function
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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.
|
|
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 (
|
|
1524
|
+
if (!dataClient) {
|
|
1113
1525
|
try {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
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.
|
|
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
|
-
|
|
1594
|
+
const signerAddress = config.signer?.address;
|
|
1595
|
+
if (!signerAddress) {
|
|
1166
1596
|
return [
|
|
1167
1597
|
new CapxulError({
|
|
1168
1598
|
code: "INVALID_INPUT",
|
|
1169
|
-
message: "completeBootstrap
|
|
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:
|
|
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).
|
|
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.
|
|
1811
|
+
if (!config._data) {
|
|
1371
1812
|
return stub("me.get");
|
|
1372
1813
|
}
|
|
1373
1814
|
try {
|
|
1374
|
-
const account = await config.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
1858
|
+
if (!config._data) {
|
|
1418
1859
|
return stub("operations.retrieve");
|
|
1419
1860
|
}
|
|
1420
1861
|
try {
|
|
1421
|
-
const operation = await config.
|
|
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.
|
|
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/
|
|
1474
|
-
function
|
|
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
|
|
1918
|
+
return {
|
|
1919
|
+
address: TEST_USDC_ADDRESS.toLowerCase(),
|
|
1920
|
+
decimals: 6,
|
|
1921
|
+
symbol: "USDC"
|
|
1922
|
+
};
|
|
1478
1923
|
}
|
|
1479
1924
|
throw new CapxulError({
|
|
1480
|
-
code: "
|
|
1481
|
-
message: `Currency ${currency} is not
|
|
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.
|
|
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.
|
|
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 [
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
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.
|
|
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.
|
|
1664
|
-
|
|
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:
|
|
2103
|
+
tokenAddress: token.address,
|
|
1680
2104
|
recipientAddress: submission.recipientAddress,
|
|
1681
|
-
amount: toTokenUnits(submission.amount.value,
|
|
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.
|
|
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({
|
|
2133
|
+
await bestEffortMarkFailed({ _data: config._data }, created.id, error);
|
|
1710
2134
|
}
|
|
1711
2135
|
if (submitted && created?.id) {
|
|
1712
|
-
return [
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
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.
|
|
2154
|
+
if (!config._data) {
|
|
1728
2155
|
return stub("payments.retrieve");
|
|
1729
2156
|
}
|
|
1730
2157
|
try {
|
|
1731
|
-
const payment = await config.
|
|
1732
|
-
|
|
1733
|
-
|
|
2158
|
+
const payment = await config._data.query(
|
|
2159
|
+
api.payments.queries.retrieve,
|
|
2160
|
+
{
|
|
2161
|
+
paymentId
|
|
2162
|
+
}
|
|
2163
|
+
);
|
|
1734
2164
|
if (!payment) {
|
|
1735
|
-
return [
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
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 () =>
|
|
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.
|
|
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.
|
|
2262
|
+
if (!config._data) {
|
|
1817
2263
|
return stub("withdrawals.create");
|
|
1818
2264
|
}
|
|
1819
2265
|
const [createErr, createdRaw] = await tryCatch(
|
|
1820
|
-
config.
|
|
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.
|
|
2296
|
+
config._data.query(api.safe.queries.getMySignerAddress, {})
|
|
1851
2297
|
);
|
|
1852
2298
|
if (signerErr) {
|
|
1853
2299
|
return await handleSubmissionFailure(
|
|
1854
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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.
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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:
|
|
2363
|
+
tokenAddress: token.address,
|
|
1917
2364
|
recipientAddress: destinationAddress,
|
|
1918
|
-
amount: toTokenUnits(submission.amount.value,
|
|
2365
|
+
amount: toTokenUnits(submission.amount.value, token.decimals)
|
|
1919
2366
|
}
|
|
1920
2367
|
)
|
|
1921
2368
|
);
|
|
1922
2369
|
if (transferErr) {
|
|
1923
2370
|
return await handleSubmissionFailure(
|
|
1924
|
-
{
|
|
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
|
-
{
|
|
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.
|
|
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.
|
|
2416
|
+
if (!config._data) {
|
|
1970
2417
|
return stub("withdrawals.retrieve");
|
|
1971
2418
|
}
|
|
1972
2419
|
const [err, raw] = await tryCatch(
|
|
1973
|
-
config.
|
|
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.
|
|
2438
|
+
if (!config._data) {
|
|
1992
2439
|
return stub("withdrawals.list");
|
|
1993
2440
|
}
|
|
1994
2441
|
const [err, raw] = await tryCatch(
|
|
1995
|
-
config.
|
|
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.
|
|
2453
|
+
if (!config._data) {
|
|
2007
2454
|
return stub(
|
|
2008
2455
|
"withdrawals.recordCompleted"
|
|
2009
2456
|
);
|
|
2010
2457
|
}
|
|
2011
2458
|
const [err] = await tryCatch(
|
|
2012
|
-
config.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
2830
|
+
page: { hasMore: false }
|
|
2278
2831
|
}
|
|
2279
2832
|
];
|
|
2280
2833
|
},
|
|
2281
2834
|
retrieve: async (input) => {
|
|
2282
|
-
if (!config.
|
|
2835
|
+
if (!config._data) {
|
|
2283
2836
|
return stub(
|
|
2284
|
-
"organizations.
|
|
2837
|
+
"organizations.subAccounts.retrieve"
|
|
2285
2838
|
);
|
|
2286
2839
|
}
|
|
2287
2840
|
const [err, raw] = await tryCatch(
|
|
2288
|
-
config.
|
|
2289
|
-
|
|
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: `
|
|
2855
|
+
message: `sub_account ${input.subAccountId} not found`
|
|
2304
2856
|
}),
|
|
2305
2857
|
null
|
|
2306
2858
|
];
|
|
2307
2859
|
}
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
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.
|
|
2870
|
+
if (!config._data) {
|
|
2317
2871
|
return stub(
|
|
2318
|
-
"organizations.
|
|
2872
|
+
"organizations.subAccounts.remove"
|
|
2319
2873
|
);
|
|
2320
2874
|
}
|
|
2321
|
-
const [err] = await tryCatch(
|
|
2322
|
-
config.
|
|
2323
|
-
|
|
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
|
-
|
|
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 () =>
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
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.
|
|
3014
|
+
if (!config._data) {
|
|
2346
3015
|
return stub("organizations.safes.retrieve");
|
|
2347
3016
|
}
|
|
2348
3017
|
try {
|
|
2349
|
-
const safe = await config.
|
|
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 () =>
|
|
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 () =>
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
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
|
-
|
|
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 () =>
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
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.
|
|
3306
|
+
if (!config._data) {
|
|
2437
3307
|
return stub("tokenTransfers.list");
|
|
2438
3308
|
}
|
|
2439
3309
|
try {
|
|
2440
|
-
const raw = await config.
|
|
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.
|
|
3344
|
+
if (!config._data) {
|
|
2475
3345
|
return stub("tokenTransfers.retrieve");
|
|
2476
3346
|
}
|
|
2477
3347
|
try {
|
|
2478
|
-
const raw = await config.
|
|
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.
|
|
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
|
-
|
|
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 };
|