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