@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/client.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { componentsGeneric, anyApi } from 'convex/server';
|
|
2
|
-
import { getAddress, parseUnits, createPublicClient, http, encodeFunctionData } from 'viem';
|
|
3
2
|
import { toSafeSmartAccount } from 'permissionless/accounts';
|
|
3
|
+
import { getAddress, parseUnits, createPublicClient, http, encodeFunctionData } from 'viem';
|
|
4
4
|
import { entryPoint07Address, createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
|
|
5
5
|
import { baseSepolia } from 'viem/chains';
|
|
6
|
+
import { deriveSafeAddress as deriveSafeAddress$1, defaultSafeDeriveConfig } from '@repo/safe-derive';
|
|
7
|
+
import { ConvexHttpClient } from 'convex/browser';
|
|
6
8
|
import { setup, fromPromise, assign } from 'xstate';
|
|
7
9
|
|
|
8
10
|
// src/_generated/api.js
|
|
@@ -120,6 +122,159 @@ function identify(userId, traits) {
|
|
|
120
122
|
debugLog(`[IDENTIFY] ${userId} ${formatDebugValue2(traits ?? "")}`);
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
// ../config/src/chain.ts
|
|
126
|
+
var CAPXUL_PAYMENTS_ADDRESS = "0xe740ea65521edc9bef0ea75d30b5334711db99f4";
|
|
127
|
+
var TEST_USDC_ADDRESS = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
|
|
128
|
+
var CAPXUL_API_BASE_URL = "https://elated-oyster-269.convex.site";
|
|
129
|
+
|
|
130
|
+
// ../config/src/timing.ts
|
|
131
|
+
var FLOW_INVOKE_TIMEOUT_MS = 3e4;
|
|
132
|
+
|
|
133
|
+
// ../config/src/errors.ts
|
|
134
|
+
var CapxulError2 = class extends Error {
|
|
135
|
+
code;
|
|
136
|
+
details;
|
|
137
|
+
correlationId;
|
|
138
|
+
layer;
|
|
139
|
+
constructor(code, message, options) {
|
|
140
|
+
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
141
|
+
this.code = code;
|
|
142
|
+
this.details = options?.details;
|
|
143
|
+
this.correlationId = options?.correlationId;
|
|
144
|
+
this.layer = options?.layer;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
var Errors = {
|
|
148
|
+
notAuthenticated: () => new CapxulError2("NOT_AUTHENTICATED", "Not authenticated"),
|
|
149
|
+
profileNotFound: (authUserId) => new CapxulError2("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`),
|
|
150
|
+
smartAccountMissing: (authUserId) => new CapxulError2("SMART_ACCOUNT_MISSING", `Smart account not provisioned for user ${authUserId}`),
|
|
151
|
+
envMissing: (name) => new CapxulError2("ENV_MISSING", `Environment variable ${name} not configured`),
|
|
152
|
+
openfortApi: (operation, cause) => new CapxulError2(
|
|
153
|
+
"PROVIDER_ERROR",
|
|
154
|
+
`Openfort ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
155
|
+
{ cause, details: { provider: "openfort", operation } }
|
|
156
|
+
),
|
|
157
|
+
shieldApi: (status, detail) => new CapxulError2(
|
|
158
|
+
"PROVIDER_ERROR",
|
|
159
|
+
`Shield API error (${status}): ${detail}`,
|
|
160
|
+
{ details: { provider: "shield", status } }
|
|
161
|
+
),
|
|
162
|
+
providerError: (provider, operation, cause) => (
|
|
163
|
+
// Public `message` is redacted to a fixed shape so provider-side
|
|
164
|
+
// exception text never leaks to the client. The original `cause`
|
|
165
|
+
// is preserved on `Error.cause` for server-side debugging via
|
|
166
|
+
// observability sinks (Sentry, console traces).
|
|
167
|
+
new CapxulError2(
|
|
168
|
+
"PROVIDER_ERROR",
|
|
169
|
+
`Provider error: ${provider} ${operation}`,
|
|
170
|
+
{ cause, details: { provider, operation } }
|
|
171
|
+
)
|
|
172
|
+
),
|
|
173
|
+
invalidInput: (field, reason) => new CapxulError2(
|
|
174
|
+
"INVALID_INPUT",
|
|
175
|
+
`Invalid ${field}: ${reason}`,
|
|
176
|
+
{ details: { field, reason } }
|
|
177
|
+
),
|
|
178
|
+
playerNotFound: (playerId) => new CapxulError2(
|
|
179
|
+
"PLAYER_NOT_FOUND",
|
|
180
|
+
playerId ? `Openfort player ${playerId} not found` : "Openfort player not found"
|
|
181
|
+
),
|
|
182
|
+
accountNotFound: (accountId) => new CapxulError2(
|
|
183
|
+
"ACCOUNT_NOT_FOUND",
|
|
184
|
+
accountId ? `Openfort account ${accountId} not found` : "Openfort smart account not found"
|
|
185
|
+
),
|
|
186
|
+
invalidRecipient: (reason) => new CapxulError2("INVALID_RECIPIENT", reason),
|
|
187
|
+
permissionDenied: (reason = "Permission denied") => new CapxulError2("PERMISSION_DENIED", reason),
|
|
188
|
+
notFound: (resource, id) => new CapxulError2(
|
|
189
|
+
"NOT_FOUND",
|
|
190
|
+
id ? `${resource} ${id} not found` : `${resource} not found`
|
|
191
|
+
),
|
|
192
|
+
idempotencyConflict: (details) => new CapxulError2(
|
|
193
|
+
"IDEMPOTENCY_CONFLICT",
|
|
194
|
+
"Idempotency key was already used for a different request",
|
|
195
|
+
{ details }
|
|
196
|
+
),
|
|
197
|
+
emailDeliveryFailed: (detail, details) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
|
|
198
|
+
details
|
|
199
|
+
}),
|
|
200
|
+
rateLimited: (details) => new CapxulError2("RATE_LIMITED", "Request was rate limited", {
|
|
201
|
+
details: { ...details }
|
|
202
|
+
}),
|
|
203
|
+
internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
204
|
+
/**
|
|
205
|
+
* Verification gate. Surfaced when a request hits a verification
|
|
206
|
+
* boundary the actor cannot cross under their current state. Two
|
|
207
|
+
* variants share this code:
|
|
208
|
+
*
|
|
209
|
+
* - Rail gate (Withdrawals v1 W2, #465): the resolved
|
|
210
|
+
* `external_account.kind` routes to a withdrawal rail (e.g.
|
|
211
|
+
* `fiat_offramp`, `card_payout`) that is not yet supported. Carries
|
|
212
|
+
* `details.rail` + `details.currentKind`.
|
|
213
|
+
* - KYC tier gate (legacy / future): the actor's KYC tier is below
|
|
214
|
+
* the required tier. Carries `details.requiredTier`.
|
|
215
|
+
*
|
|
216
|
+
* Code is shared because both expose the same UX shape ("you cannot
|
|
217
|
+
* proceed until verification advances"); the `details.*` keys
|
|
218
|
+
* differentiate the route.
|
|
219
|
+
*/
|
|
220
|
+
verificationRequired: (details) => {
|
|
221
|
+
const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
|
|
222
|
+
return new CapxulError2("VERIFICATION_REQUIRED", message, {
|
|
223
|
+
details: { ...details }
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// ../config/src/safe.ts
|
|
229
|
+
var SAFE_PROXY_FACTORY = "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67";
|
|
230
|
+
var SAFE_L2_SINGLETON = "0x29fcb43b46531bca003ddc8fcb67ffe91900c762";
|
|
231
|
+
var SAFE_MODULE_SETUP = "0x2dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47";
|
|
232
|
+
var SAFE_4337_MODULE = "0x75cf11467937ce3f2f357ce24ffc3dbf8fd5c226";
|
|
233
|
+
|
|
234
|
+
// ../config/src/org-roles.ts
|
|
235
|
+
function roleKeyFromLabel(label) {
|
|
236
|
+
const bytes = new TextEncoder().encode(label);
|
|
237
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
238
|
+
return "0x" + hex.padEnd(64, "0");
|
|
239
|
+
}
|
|
240
|
+
roleKeyFromLabel("OWNER");
|
|
241
|
+
roleKeyFromLabel("FINANCE_MANAGER");
|
|
242
|
+
roleKeyFromLabel("PAYMENTS_OPERATOR");
|
|
243
|
+
async function buildSafeAccount(signer, chain) {
|
|
244
|
+
try {
|
|
245
|
+
const publicClient = createPublicClient({
|
|
246
|
+
chain: baseSepolia,
|
|
247
|
+
transport: http(chain.rpcUrl)
|
|
248
|
+
});
|
|
249
|
+
return await toSafeSmartAccount({
|
|
250
|
+
client: publicClient,
|
|
251
|
+
entryPoint: { address: entryPoint07Address, version: "0.7" },
|
|
252
|
+
version: "1.4.1",
|
|
253
|
+
owners: [signer],
|
|
254
|
+
saltNonce: computeSaltNonce(signer.address),
|
|
255
|
+
safeSingletonAddress: SAFE_L2_SINGLETON,
|
|
256
|
+
safeProxyFactoryAddress: SAFE_PROXY_FACTORY,
|
|
257
|
+
safeModuleSetupAddress: SAFE_MODULE_SETUP,
|
|
258
|
+
safe4337ModuleAddress: SAFE_4337_MODULE,
|
|
259
|
+
safeModules: [],
|
|
260
|
+
setupTransactions: []
|
|
261
|
+
});
|
|
262
|
+
} catch (cause) {
|
|
263
|
+
throw new CapxulError({
|
|
264
|
+
code: "NETWORK_ERROR",
|
|
265
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
266
|
+
cause,
|
|
267
|
+
details: { chainId: chain.chainId }
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function computeSaltNonce(ownerAddress) {
|
|
272
|
+
return BigInt(`0x${ownerAddress.toLowerCase().slice(2).padEnd(64, "0")}`);
|
|
273
|
+
}
|
|
274
|
+
function deriveSafeAddress(signerAddress) {
|
|
275
|
+
return deriveSafeAddress$1(signerAddress, defaultSafeDeriveConfig);
|
|
276
|
+
}
|
|
277
|
+
|
|
123
278
|
// ../platform-kernel/src/ids.ts
|
|
124
279
|
function makePrefixedIdConstructor(prefix, fieldName) {
|
|
125
280
|
const re = new RegExp(`^${prefix}_[A-Za-z0-9_\\-]+$`);
|
|
@@ -132,12 +287,24 @@ function makePrefixedIdConstructor(prefix, fieldName) {
|
|
|
132
287
|
return raw;
|
|
133
288
|
};
|
|
134
289
|
}
|
|
290
|
+
var toSafeId = makePrefixedIdConstructor(
|
|
291
|
+
"safe",
|
|
292
|
+
"safeId"
|
|
293
|
+
);
|
|
294
|
+
var toTreasuryId = makePrefixedIdConstructor(
|
|
295
|
+
"try",
|
|
296
|
+
"treasuryId"
|
|
297
|
+
);
|
|
135
298
|
var toOperationId = makePrefixedIdConstructor(
|
|
136
299
|
"op",
|
|
137
300
|
"operationId"
|
|
138
301
|
);
|
|
139
302
|
var toCorrelationId = makePrefixedIdConstructor("ctx", "correlationId");
|
|
140
303
|
var toExternalAccountId = makePrefixedIdConstructor("ext", "externalAccountId");
|
|
304
|
+
var toSubAccountId = makePrefixedIdConstructor(
|
|
305
|
+
"sub",
|
|
306
|
+
"subAccountId"
|
|
307
|
+
);
|
|
141
308
|
|
|
142
309
|
// src/core/external-accounts.ts
|
|
143
310
|
function brandExternalAccount(raw) {
|
|
@@ -154,13 +321,13 @@ function brandExternalAccount(raw) {
|
|
|
154
321
|
function createExternalAccountsClient(config = {}) {
|
|
155
322
|
return {
|
|
156
323
|
retrieve: async (externalAccountId) => {
|
|
157
|
-
if (!config.
|
|
324
|
+
if (!config._data) {
|
|
158
325
|
return stub(
|
|
159
326
|
"externalAccounts.retrieve"
|
|
160
327
|
);
|
|
161
328
|
}
|
|
162
329
|
const [err, raw] = await tryCatch(
|
|
163
|
-
config.
|
|
330
|
+
config._data.query(api.externalAccounts.queries.retrievePersonal, {
|
|
164
331
|
externalAccountId
|
|
165
332
|
})
|
|
166
333
|
);
|
|
@@ -182,11 +349,11 @@ function createExternalAccountsClient(config = {}) {
|
|
|
182
349
|
return [null, brandExternalAccount(raw)];
|
|
183
350
|
},
|
|
184
351
|
remove: async (externalAccountId) => {
|
|
185
|
-
if (!config.
|
|
352
|
+
if (!config._data) {
|
|
186
353
|
return stub("externalAccounts.remove");
|
|
187
354
|
}
|
|
188
355
|
const [err] = await tryCatch(
|
|
189
|
-
config.
|
|
356
|
+
config._data.mutation(api.externalAccounts.mutations.removePersonal, {
|
|
190
357
|
externalAccountId
|
|
191
358
|
})
|
|
192
359
|
);
|
|
@@ -201,17 +368,203 @@ function createExternalAccountsClient(config = {}) {
|
|
|
201
368
|
};
|
|
202
369
|
}
|
|
203
370
|
|
|
371
|
+
// src/core/sub-accounts.ts
|
|
372
|
+
function malformedWireError(reason, raw) {
|
|
373
|
+
return new CapxulError({
|
|
374
|
+
code: "PROVIDER_ERROR",
|
|
375
|
+
message: `convex brandSubAccount failed: ${reason}`,
|
|
376
|
+
details: {
|
|
377
|
+
provider: "convex",
|
|
378
|
+
operation: "brandSubAccount",
|
|
379
|
+
reason,
|
|
380
|
+
// PII discipline (`.claude/rules/posthog.md`): user-authored
|
|
381
|
+
// strings on the wire (`name`, `purpose`) are customer-confidential
|
|
382
|
+
// — sub-account names like "Q3 Acquisition Reserve" or
|
|
383
|
+
// "Vendor ABC payments" must not flow into telemetry. We emit a
|
|
384
|
+
// structural keys-only sample via a strict ALLOWLIST so any future
|
|
385
|
+
// wire-shape addition (e.g. `recipientEmail`, `tags`) is dropped
|
|
386
|
+
// by construction rather than leaked through a denylist gap.
|
|
387
|
+
sample: safeSampleShape(raw)
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
function safeSampleShape(raw) {
|
|
392
|
+
if (raw === null || typeof raw !== "object") {
|
|
393
|
+
return { type: typeof raw };
|
|
394
|
+
}
|
|
395
|
+
const r = raw;
|
|
396
|
+
const balance = r.balance;
|
|
397
|
+
return {
|
|
398
|
+
object: typeof r.object === "string" ? r.object : typeof r.object,
|
|
399
|
+
idPresent: typeof r.id === "string" && r.id.length > 0,
|
|
400
|
+
// First 4 chars only — enough to distinguish "sub_" prefixed IDs
|
|
401
|
+
// from accidental other resource IDs without leaking the full ID.
|
|
402
|
+
idPrefix: typeof r.id === "string" ? r.id.slice(0, 4) : void 0,
|
|
403
|
+
parentKind: r.parent !== null && typeof r.parent === "object" ? r.parent.kind : typeof r.parent,
|
|
404
|
+
status: r.status,
|
|
405
|
+
hasName: typeof r.name === "string",
|
|
406
|
+
hasPurpose: r.purpose !== void 0,
|
|
407
|
+
balanceShape: balance !== null && typeof balance === "object" ? Object.keys(balance).sort() : typeof balance,
|
|
408
|
+
createdAtType: typeof r.createdAt,
|
|
409
|
+
updatedAtType: typeof r.updatedAt
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function isMoneyShape(v) {
|
|
413
|
+
if (typeof v !== "object" || v === null) return false;
|
|
414
|
+
const m = v;
|
|
415
|
+
return typeof m.value === "string" && typeof m.currency === "string";
|
|
416
|
+
}
|
|
417
|
+
function isParentShape(v) {
|
|
418
|
+
if (typeof v !== "object" || v === null) return false;
|
|
419
|
+
const p = v;
|
|
420
|
+
return (p.kind === "account" || p.kind === "organization") && typeof p.id === "string";
|
|
421
|
+
}
|
|
422
|
+
function isFiniteNonNegativeInteger(v) {
|
|
423
|
+
return typeof v === "number" && Number.isFinite(v) && Number.isInteger(v) && v >= 0;
|
|
424
|
+
}
|
|
425
|
+
function validateWireSubAccount(raw) {
|
|
426
|
+
if (typeof raw !== "object" || raw === null) {
|
|
427
|
+
return { ok: false, reason: "not an object" };
|
|
428
|
+
}
|
|
429
|
+
const r = raw;
|
|
430
|
+
if (r.object !== "sub_account") {
|
|
431
|
+
return { ok: false, reason: `object must be "sub_account" (got ${String(r.object)})` };
|
|
432
|
+
}
|
|
433
|
+
if (typeof r.id !== "string" || r.id.length === 0) {
|
|
434
|
+
return { ok: false, reason: "id must be a non-empty string" };
|
|
435
|
+
}
|
|
436
|
+
if (!isParentShape(r.parent)) {
|
|
437
|
+
return { ok: false, reason: "parent must be { kind: 'account' | 'organization', id: string }" };
|
|
438
|
+
}
|
|
439
|
+
if (typeof r.name !== "string") {
|
|
440
|
+
return { ok: false, reason: "name must be a string" };
|
|
441
|
+
}
|
|
442
|
+
if (r.purpose !== void 0 && typeof r.purpose !== "string") {
|
|
443
|
+
return { ok: false, reason: "purpose must be a string when present" };
|
|
444
|
+
}
|
|
445
|
+
if (r.status !== "active" && r.status !== "archived") {
|
|
446
|
+
return { ok: false, reason: `status must be "active" | "archived" (got ${String(r.status)})` };
|
|
447
|
+
}
|
|
448
|
+
if (!isMoneyShape(r.balance)) {
|
|
449
|
+
return { ok: false, reason: "balance must be { value: string, currency: string }" };
|
|
450
|
+
}
|
|
451
|
+
if (!isFiniteNonNegativeInteger(r.createdAt)) {
|
|
452
|
+
return { ok: false, reason: "createdAt must be a finite non-negative integer (epoch ms)" };
|
|
453
|
+
}
|
|
454
|
+
if (r.updatedAt !== void 0 && !isFiniteNonNegativeInteger(r.updatedAt)) {
|
|
455
|
+
return { ok: false, reason: "updatedAt must be a finite non-negative integer when present" };
|
|
456
|
+
}
|
|
457
|
+
return { ok: true, value: r };
|
|
458
|
+
}
|
|
459
|
+
function brandSubAccount(raw) {
|
|
460
|
+
const result = validateWireSubAccount(raw);
|
|
461
|
+
if (!result.ok) {
|
|
462
|
+
throw malformedWireError(result.reason, raw);
|
|
463
|
+
}
|
|
464
|
+
const wire = result.value;
|
|
465
|
+
return {
|
|
466
|
+
object: wire.object,
|
|
467
|
+
id: toSubAccountId(wire.id),
|
|
468
|
+
parent: wire.parent,
|
|
469
|
+
name: wire.name,
|
|
470
|
+
...wire.purpose !== void 0 ? { purpose: wire.purpose } : {},
|
|
471
|
+
status: wire.status,
|
|
472
|
+
balance: wire.balance,
|
|
473
|
+
createdAt: new Date(wire.createdAt).toISOString()
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
function tryBrandSubAccount(raw) {
|
|
477
|
+
try {
|
|
478
|
+
return [null, brandSubAccount(raw)];
|
|
479
|
+
} catch (err) {
|
|
480
|
+
if (err instanceof CapxulError && err.code === "PROVIDER_ERROR") {
|
|
481
|
+
return [err, null];
|
|
482
|
+
}
|
|
483
|
+
return [
|
|
484
|
+
malformedWireError(
|
|
485
|
+
err instanceof Error ? err.message : String(err),
|
|
486
|
+
raw
|
|
487
|
+
),
|
|
488
|
+
null
|
|
489
|
+
];
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function createSubAccountsClient(config = {}) {
|
|
493
|
+
return {
|
|
494
|
+
retrieve: async (subAccountId) => {
|
|
495
|
+
if (!config._data) {
|
|
496
|
+
return stub("subAccounts.retrieve");
|
|
497
|
+
}
|
|
498
|
+
const [err, raw] = await tryCatch(
|
|
499
|
+
config._data.query(api.subAccounts.queries.retrieve, {
|
|
500
|
+
subAccountId
|
|
501
|
+
})
|
|
502
|
+
);
|
|
503
|
+
if (err) {
|
|
504
|
+
return [
|
|
505
|
+
fromConvexError(err),
|
|
506
|
+
null
|
|
507
|
+
];
|
|
508
|
+
}
|
|
509
|
+
if (!raw) {
|
|
510
|
+
return [
|
|
511
|
+
new CapxulError({
|
|
512
|
+
code: "NOT_FOUND",
|
|
513
|
+
message: `sub_account ${subAccountId} not found`
|
|
514
|
+
}),
|
|
515
|
+
null
|
|
516
|
+
];
|
|
517
|
+
}
|
|
518
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
519
|
+
if (brandErr) {
|
|
520
|
+
return [brandErr, null];
|
|
521
|
+
}
|
|
522
|
+
return [null, branded];
|
|
523
|
+
},
|
|
524
|
+
remove: async (subAccountId) => {
|
|
525
|
+
if (!config._data) {
|
|
526
|
+
return stub("subAccounts.remove");
|
|
527
|
+
}
|
|
528
|
+
const [err, raw] = await tryCatch(
|
|
529
|
+
config._data.mutation(api.subAccounts.mutations.archive, {
|
|
530
|
+
subAccountId
|
|
531
|
+
})
|
|
532
|
+
);
|
|
533
|
+
if (err) {
|
|
534
|
+
return [
|
|
535
|
+
fromConvexError(err),
|
|
536
|
+
null
|
|
537
|
+
];
|
|
538
|
+
}
|
|
539
|
+
if (!raw) {
|
|
540
|
+
return [
|
|
541
|
+
new CapxulError({
|
|
542
|
+
code: "NOT_FOUND",
|
|
543
|
+
message: `sub_account ${subAccountId} not found`
|
|
544
|
+
}),
|
|
545
|
+
null
|
|
546
|
+
];
|
|
547
|
+
}
|
|
548
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
549
|
+
if (brandErr) {
|
|
550
|
+
return [brandErr, null];
|
|
551
|
+
}
|
|
552
|
+
return [null, branded];
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
|
|
204
557
|
// src/core/accounts.ts
|
|
205
558
|
function createAccountExternalAccountsClient(config) {
|
|
206
559
|
return {
|
|
207
560
|
create: async (input) => {
|
|
208
|
-
if (!config.
|
|
561
|
+
if (!config._data) {
|
|
209
562
|
return stub(
|
|
210
563
|
"accounts.externalAccounts.create"
|
|
211
564
|
);
|
|
212
565
|
}
|
|
213
566
|
const [err, raw] = await tryCatch(
|
|
214
|
-
config.
|
|
567
|
+
config._data.mutation(
|
|
215
568
|
api.externalAccounts.mutations.createPersonal,
|
|
216
569
|
{
|
|
217
570
|
kind: input.kind,
|
|
@@ -249,13 +602,13 @@ function createAccountExternalAccountsClient(config) {
|
|
|
249
602
|
];
|
|
250
603
|
},
|
|
251
604
|
list: async (input) => {
|
|
252
|
-
if (!config.
|
|
605
|
+
if (!config._data) {
|
|
253
606
|
return stub(
|
|
254
607
|
"accounts.externalAccounts.list"
|
|
255
608
|
);
|
|
256
609
|
}
|
|
257
610
|
const [err, result] = await tryCatch(
|
|
258
|
-
config.
|
|
611
|
+
config._data.query(api.externalAccounts.queries.listPersonal, {
|
|
259
612
|
limit: input.limit,
|
|
260
613
|
cursor: input.cursor
|
|
261
614
|
})
|
|
@@ -278,13 +631,13 @@ function createAccountExternalAccountsClient(config) {
|
|
|
278
631
|
];
|
|
279
632
|
},
|
|
280
633
|
retrieve: async (externalAccountId) => {
|
|
281
|
-
if (!config.
|
|
634
|
+
if (!config._data) {
|
|
282
635
|
return stub(
|
|
283
636
|
"accounts.externalAccounts.retrieve"
|
|
284
637
|
);
|
|
285
638
|
}
|
|
286
639
|
const [err, raw] = await tryCatch(
|
|
287
|
-
config.
|
|
640
|
+
config._data.query(api.externalAccounts.queries.retrievePersonal, {
|
|
288
641
|
externalAccountId
|
|
289
642
|
})
|
|
290
643
|
);
|
|
@@ -311,11 +664,11 @@ function createAccountExternalAccountsClient(config) {
|
|
|
311
664
|
];
|
|
312
665
|
},
|
|
313
666
|
remove: async (externalAccountId) => {
|
|
314
|
-
if (!config.
|
|
667
|
+
if (!config._data) {
|
|
315
668
|
return stub("accounts.externalAccounts.remove");
|
|
316
669
|
}
|
|
317
670
|
const [err] = await tryCatch(
|
|
318
|
-
config.
|
|
671
|
+
config._data.mutation(api.externalAccounts.mutations.removePersonal, {
|
|
319
672
|
externalAccountId
|
|
320
673
|
})
|
|
321
674
|
);
|
|
@@ -329,14 +682,162 @@ function createAccountExternalAccountsClient(config) {
|
|
|
329
682
|
}
|
|
330
683
|
};
|
|
331
684
|
}
|
|
685
|
+
function createAccountSubAccountsClient(config) {
|
|
686
|
+
return {
|
|
687
|
+
create: async (input) => {
|
|
688
|
+
if (!config._data) {
|
|
689
|
+
return stub(
|
|
690
|
+
"accounts.subAccounts.create"
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
const [err, raw] = await tryCatch(
|
|
694
|
+
config._data.mutation(api.subAccounts.mutations.create, {
|
|
695
|
+
parent: { kind: "account", id: input.accountId },
|
|
696
|
+
name: input.name,
|
|
697
|
+
purpose: input.purpose
|
|
698
|
+
})
|
|
699
|
+
);
|
|
700
|
+
if (err) {
|
|
701
|
+
return [
|
|
702
|
+
fromConvexError(err),
|
|
703
|
+
null
|
|
704
|
+
];
|
|
705
|
+
}
|
|
706
|
+
if (!raw) {
|
|
707
|
+
return [
|
|
708
|
+
new CapxulError({
|
|
709
|
+
code: "NOT_FOUND",
|
|
710
|
+
message: "sub_account creation returned no resource"
|
|
711
|
+
}),
|
|
712
|
+
null
|
|
713
|
+
];
|
|
714
|
+
}
|
|
715
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
716
|
+
if (brandErr) {
|
|
717
|
+
return [
|
|
718
|
+
brandErr,
|
|
719
|
+
null
|
|
720
|
+
];
|
|
721
|
+
}
|
|
722
|
+
return [null, branded];
|
|
723
|
+
},
|
|
724
|
+
list: async (input) => {
|
|
725
|
+
if (!config._data) {
|
|
726
|
+
return stub(
|
|
727
|
+
"accounts.subAccounts.list"
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
const [err, rows] = await tryCatch(
|
|
731
|
+
config._data.query(api.subAccounts.queries.listByAccount, {
|
|
732
|
+
accountId: input.accountId
|
|
733
|
+
})
|
|
734
|
+
);
|
|
735
|
+
if (err) {
|
|
736
|
+
return [
|
|
737
|
+
fromConvexError(err),
|
|
738
|
+
null
|
|
739
|
+
];
|
|
740
|
+
}
|
|
741
|
+
const branded = [];
|
|
742
|
+
for (const row of rows) {
|
|
743
|
+
const [brandErr, value] = tryBrandSubAccount(row);
|
|
744
|
+
if (brandErr) {
|
|
745
|
+
return [
|
|
746
|
+
brandErr,
|
|
747
|
+
null
|
|
748
|
+
];
|
|
749
|
+
}
|
|
750
|
+
branded.push(value);
|
|
751
|
+
}
|
|
752
|
+
return [
|
|
753
|
+
null,
|
|
754
|
+
{
|
|
755
|
+
object: "list",
|
|
756
|
+
data: branded,
|
|
757
|
+
page: { hasMore: false }
|
|
758
|
+
}
|
|
759
|
+
];
|
|
760
|
+
},
|
|
761
|
+
retrieve: async (subAccountId) => {
|
|
762
|
+
if (!config._data) {
|
|
763
|
+
return stub(
|
|
764
|
+
"accounts.subAccounts.retrieve"
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
const [err, raw] = await tryCatch(
|
|
768
|
+
config._data.query(api.subAccounts.queries.retrieve, {
|
|
769
|
+
subAccountId
|
|
770
|
+
})
|
|
771
|
+
);
|
|
772
|
+
if (err) {
|
|
773
|
+
return [
|
|
774
|
+
fromConvexError(err),
|
|
775
|
+
null
|
|
776
|
+
];
|
|
777
|
+
}
|
|
778
|
+
if (!raw) {
|
|
779
|
+
return [
|
|
780
|
+
new CapxulError({
|
|
781
|
+
code: "NOT_FOUND",
|
|
782
|
+
message: `sub_account ${subAccountId} not found`
|
|
783
|
+
}),
|
|
784
|
+
null
|
|
785
|
+
];
|
|
786
|
+
}
|
|
787
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
788
|
+
if (brandErr) {
|
|
789
|
+
return [
|
|
790
|
+
brandErr,
|
|
791
|
+
null
|
|
792
|
+
];
|
|
793
|
+
}
|
|
794
|
+
return [null, branded];
|
|
795
|
+
},
|
|
796
|
+
remove: async (subAccountId) => {
|
|
797
|
+
if (!config._data) {
|
|
798
|
+
return stub(
|
|
799
|
+
"accounts.subAccounts.remove"
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
const [err, raw] = await tryCatch(
|
|
803
|
+
config._data.mutation(api.subAccounts.mutations.archive, {
|
|
804
|
+
subAccountId
|
|
805
|
+
})
|
|
806
|
+
);
|
|
807
|
+
if (err) {
|
|
808
|
+
return [
|
|
809
|
+
fromConvexError(err),
|
|
810
|
+
null
|
|
811
|
+
];
|
|
812
|
+
}
|
|
813
|
+
if (!raw) {
|
|
814
|
+
return [
|
|
815
|
+
new CapxulError({
|
|
816
|
+
code: "NOT_FOUND",
|
|
817
|
+
message: `sub_account ${subAccountId} not found`
|
|
818
|
+
}),
|
|
819
|
+
null
|
|
820
|
+
];
|
|
821
|
+
}
|
|
822
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
823
|
+
if (brandErr) {
|
|
824
|
+
return [
|
|
825
|
+
brandErr,
|
|
826
|
+
null
|
|
827
|
+
];
|
|
828
|
+
}
|
|
829
|
+
return [null, branded];
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
}
|
|
332
833
|
function createAccountsClient(config = {}) {
|
|
333
834
|
return {
|
|
334
835
|
retrieve: async (accountId) => {
|
|
335
|
-
if (!config.
|
|
836
|
+
if (!config._data) {
|
|
336
837
|
return stub("accounts.retrieve");
|
|
337
838
|
}
|
|
338
839
|
try {
|
|
339
|
-
const account = await config.
|
|
840
|
+
const account = await config._data.query(
|
|
340
841
|
api.openfort.queries.getMyAccount,
|
|
341
842
|
{}
|
|
342
843
|
);
|
|
@@ -360,7 +861,7 @@ function createAccountsClient(config = {}) {
|
|
|
360
861
|
},
|
|
361
862
|
lookup: async () => stub("accounts.lookup"),
|
|
362
863
|
update: async (input) => {
|
|
363
|
-
if (!config.
|
|
864
|
+
if (!config._data) {
|
|
364
865
|
return stub("accounts.update");
|
|
365
866
|
}
|
|
366
867
|
if (input.countryCode !== void 0) {
|
|
@@ -374,7 +875,7 @@ function createAccountsClient(config = {}) {
|
|
|
374
875
|
];
|
|
375
876
|
}
|
|
376
877
|
try {
|
|
377
|
-
const current = await config.
|
|
878
|
+
const current = await config._data.query(
|
|
378
879
|
api.openfort.queries.getMyAccount,
|
|
379
880
|
{}
|
|
380
881
|
);
|
|
@@ -391,11 +892,11 @@ function createAccountsClient(config = {}) {
|
|
|
391
892
|
null
|
|
392
893
|
];
|
|
393
894
|
}
|
|
394
|
-
await config.
|
|
895
|
+
await config._data.mutation(api.openfort.mutations.updateProfile, {
|
|
395
896
|
displayName: input.name,
|
|
396
897
|
username: input.username
|
|
397
898
|
});
|
|
398
|
-
const updated = await config.
|
|
899
|
+
const updated = await config._data.query(
|
|
399
900
|
api.openfort.queries.getMyAccount,
|
|
400
901
|
{}
|
|
401
902
|
);
|
|
@@ -405,7 +906,7 @@ function createAccountsClient(config = {}) {
|
|
|
405
906
|
}
|
|
406
907
|
},
|
|
407
908
|
provisionPersonal: async (input) => {
|
|
408
|
-
if (!config.
|
|
909
|
+
if (!config._data) {
|
|
409
910
|
return stub(
|
|
410
911
|
"accounts.provisionPersonal"
|
|
411
912
|
);
|
|
@@ -420,17 +921,17 @@ function createAccountsClient(config = {}) {
|
|
|
420
921
|
];
|
|
421
922
|
}
|
|
422
923
|
try {
|
|
423
|
-
await config.
|
|
924
|
+
await config._data.mutation(
|
|
424
925
|
api.safe.mutations.provisionLocalPersonalAccount,
|
|
425
926
|
{
|
|
426
927
|
displayName: input.displayName,
|
|
427
928
|
username: input.username,
|
|
428
929
|
countryCode: input.countryCode,
|
|
429
930
|
eoaAddress: input.signerProvider.signerAddress,
|
|
430
|
-
safeAddress: input.signerProvider.
|
|
931
|
+
safeAddress: deriveSafeAddress(input.signerProvider.signerAddress)
|
|
431
932
|
}
|
|
432
933
|
);
|
|
433
|
-
const account = await config.
|
|
934
|
+
const account = await config._data.query(
|
|
434
935
|
api.openfort.queries.getMyAccount,
|
|
435
936
|
{}
|
|
436
937
|
);
|
|
@@ -453,176 +954,99 @@ function createAccountsClient(config = {}) {
|
|
|
453
954
|
},
|
|
454
955
|
safes: {
|
|
455
956
|
retrieve: async (safeId) => {
|
|
456
|
-
if (!config.
|
|
957
|
+
if (!config._data) {
|
|
457
958
|
return stub("accounts.safes.retrieve");
|
|
458
959
|
}
|
|
459
960
|
try {
|
|
460
|
-
const safe = await config.
|
|
961
|
+
const safe = await config._data.query(
|
|
461
962
|
api.safe.queries.retrieveAccountSafe,
|
|
462
963
|
{ safeId }
|
|
463
|
-
);
|
|
464
|
-
if (!safe) {
|
|
465
|
-
return [
|
|
466
|
-
new CapxulError({
|
|
467
|
-
code: "NOT_FOUND",
|
|
468
|
-
message: `safe ${safeId} not found`
|
|
469
|
-
}),
|
|
470
|
-
null
|
|
471
|
-
];
|
|
472
|
-
}
|
|
473
|
-
return [null, safe];
|
|
474
|
-
} catch (cause) {
|
|
475
|
-
return [
|
|
476
|
-
fromConvexError(cause),
|
|
477
|
-
null
|
|
478
|
-
];
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
kycProfiles: {
|
|
483
|
-
create: async () => stub("accounts.kycProfiles.create"),
|
|
484
|
-
retrieve: async () => stub("accounts.kycProfiles.retrieve")
|
|
485
|
-
},
|
|
486
|
-
externalAccounts: createAccountExternalAccountsClient(config),
|
|
487
|
-
subAccounts:
|
|
488
|
-
|
|
489
|
-
list: async () =>
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
|
-
var Errors = {
|
|
537
|
-
notAuthenticated: () => new CapxulError2("NOT_AUTHENTICATED", "Not authenticated"),
|
|
538
|
-
profileNotFound: (authUserId) => new CapxulError2("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`),
|
|
539
|
-
smartAccountMissing: (authUserId) => new CapxulError2("SMART_ACCOUNT_MISSING", `Smart account not provisioned for user ${authUserId}`),
|
|
540
|
-
envMissing: (name) => new CapxulError2("ENV_MISSING", `Environment variable ${name} not configured`),
|
|
541
|
-
openfortApi: (operation, cause) => new CapxulError2(
|
|
542
|
-
"PROVIDER_ERROR",
|
|
543
|
-
`Openfort ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
544
|
-
{ cause, details: { provider: "openfort", operation } }
|
|
545
|
-
),
|
|
546
|
-
shieldApi: (status, detail) => new CapxulError2(
|
|
547
|
-
"PROVIDER_ERROR",
|
|
548
|
-
`Shield API error (${status}): ${detail}`,
|
|
549
|
-
{ details: { provider: "shield", status } }
|
|
550
|
-
),
|
|
551
|
-
providerError: (provider, operation, cause) => new CapxulError2(
|
|
552
|
-
"PROVIDER_ERROR",
|
|
553
|
-
`${provider} ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
554
|
-
{ cause, details: { provider, operation } }
|
|
555
|
-
),
|
|
556
|
-
invalidInput: (field, reason) => new CapxulError2(
|
|
557
|
-
"INVALID_INPUT",
|
|
558
|
-
`Invalid ${field}: ${reason}`,
|
|
559
|
-
{ details: { field, reason } }
|
|
560
|
-
),
|
|
561
|
-
playerNotFound: (playerId) => new CapxulError2(
|
|
562
|
-
"PLAYER_NOT_FOUND",
|
|
563
|
-
playerId ? `Openfort player ${playerId} not found` : "Openfort player not found"
|
|
564
|
-
),
|
|
565
|
-
accountNotFound: (accountId) => new CapxulError2(
|
|
566
|
-
"ACCOUNT_NOT_FOUND",
|
|
567
|
-
accountId ? `Openfort account ${accountId} not found` : "Openfort smart account not found"
|
|
568
|
-
),
|
|
569
|
-
invalidRecipient: (reason) => new CapxulError2("INVALID_RECIPIENT", reason),
|
|
570
|
-
permissionDenied: (reason = "Permission denied") => new CapxulError2("PERMISSION_DENIED", reason),
|
|
571
|
-
notFound: (resource, id) => new CapxulError2(
|
|
572
|
-
"NOT_FOUND",
|
|
573
|
-
id ? `${resource} ${id} not found` : `${resource} not found`
|
|
574
|
-
),
|
|
575
|
-
idempotencyConflict: (details) => new CapxulError2(
|
|
576
|
-
"IDEMPOTENCY_CONFLICT",
|
|
577
|
-
"Idempotency key was already used for a different request",
|
|
578
|
-
{ details }
|
|
579
|
-
),
|
|
580
|
-
emailDeliveryFailed: (detail, details) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
|
|
581
|
-
details
|
|
582
|
-
}),
|
|
583
|
-
rateLimited: (details) => new CapxulError2("RATE_LIMITED", "Request was rate limited", {
|
|
584
|
-
details: { ...details }
|
|
585
|
-
}),
|
|
586
|
-
internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
587
|
-
/**
|
|
588
|
-
* Verification gate. Surfaced when a request hits a verification
|
|
589
|
-
* boundary the actor cannot cross under their current state. Two
|
|
590
|
-
* variants share this code:
|
|
591
|
-
*
|
|
592
|
-
* - Rail gate (Withdrawals v1 W2, #465): the resolved
|
|
593
|
-
* `external_account.kind` routes to a withdrawal rail (e.g.
|
|
594
|
-
* `fiat_offramp`, `card_payout`) that is not yet supported. Carries
|
|
595
|
-
* `details.rail` + `details.currentKind`.
|
|
596
|
-
* - KYC tier gate (legacy / future): the actor's KYC tier is below
|
|
597
|
-
* the required tier. Carries `details.requiredTier`.
|
|
598
|
-
*
|
|
599
|
-
* Code is shared because both expose the same UX shape ("you cannot
|
|
600
|
-
* proceed until verification advances"); the `details.*` keys
|
|
601
|
-
* differentiate the route.
|
|
602
|
-
*/
|
|
603
|
-
verificationRequired: (details) => {
|
|
604
|
-
const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
|
|
605
|
-
return new CapxulError2("VERIFICATION_REQUIRED", message, {
|
|
606
|
-
details: { ...details }
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
// ../config/src/safe.ts
|
|
612
|
-
var SAFE_PROXY_FACTORY = "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67";
|
|
613
|
-
var SAFE_L2_SINGLETON = "0x29fcb43b46531bca003ddc8fcb67ffe91900c762";
|
|
614
|
-
var SAFE_MODULE_SETUP = "0x2dd68b007b46fbe91b9a7c3eda5a7a1063cb5b47";
|
|
615
|
-
var SAFE_4337_MODULE = "0x75cf11467937ce3f2f357ce24ffc3dbf8fd5c226";
|
|
964
|
+
);
|
|
965
|
+
if (!safe) {
|
|
966
|
+
return [
|
|
967
|
+
new CapxulError({
|
|
968
|
+
code: "NOT_FOUND",
|
|
969
|
+
message: `safe ${safeId} not found`
|
|
970
|
+
}),
|
|
971
|
+
null
|
|
972
|
+
];
|
|
973
|
+
}
|
|
974
|
+
return [null, safe];
|
|
975
|
+
} catch (cause) {
|
|
976
|
+
return [
|
|
977
|
+
fromConvexError(cause),
|
|
978
|
+
null
|
|
979
|
+
];
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
},
|
|
983
|
+
kycProfiles: {
|
|
984
|
+
create: async () => stub("accounts.kycProfiles.create"),
|
|
985
|
+
retrieve: async () => stub("accounts.kycProfiles.retrieve")
|
|
986
|
+
},
|
|
987
|
+
externalAccounts: createAccountExternalAccountsClient(config),
|
|
988
|
+
subAccounts: createAccountSubAccountsClient(config),
|
|
989
|
+
balanceLedger: {
|
|
990
|
+
list: async (input) => {
|
|
991
|
+
if (!config._data) {
|
|
992
|
+
return stub(
|
|
993
|
+
"accounts.balanceLedger.list"
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
try {
|
|
997
|
+
const accountId = input.accountId.replace(/^acct_/, "");
|
|
998
|
+
const page = await config._data.query(
|
|
999
|
+
api.balanceLedger.queries.listForAccount,
|
|
1000
|
+
{ accountId, limit: input.limit, cursor: input.cursor }
|
|
1001
|
+
);
|
|
1002
|
+
return [null, page];
|
|
1003
|
+
} catch (cause) {
|
|
1004
|
+
return [fromConvexError(cause), null];
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
retrieve: async (entryId) => {
|
|
1008
|
+
if (!config._data) {
|
|
1009
|
+
return stub(
|
|
1010
|
+
"accounts.balanceLedger.retrieve"
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
try {
|
|
1014
|
+
const entry = await config._data.query(
|
|
1015
|
+
api.balanceLedger.queries.retrieve,
|
|
1016
|
+
{ entryId }
|
|
1017
|
+
);
|
|
1018
|
+
if (!entry) {
|
|
1019
|
+
return [
|
|
1020
|
+
new CapxulError({
|
|
1021
|
+
code: "NOT_FOUND",
|
|
1022
|
+
message: `balance_ledger_entry ${entryId} not found`
|
|
1023
|
+
}),
|
|
1024
|
+
null
|
|
1025
|
+
];
|
|
1026
|
+
}
|
|
1027
|
+
return [null, entry];
|
|
1028
|
+
} catch (cause) {
|
|
1029
|
+
return [fromConvexError(cause), null];
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
616
1035
|
|
|
617
|
-
//
|
|
618
|
-
function
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
1036
|
+
// src/core/api-keys.ts
|
|
1037
|
+
function createApiKeysClient() {
|
|
1038
|
+
return {
|
|
1039
|
+
create: async () => stub("apiKeys.create"),
|
|
1040
|
+
retrieve: async () => stub("apiKeys.retrieve"),
|
|
1041
|
+
list: async () => stub("apiKeys.list"),
|
|
1042
|
+
revoke: async () => stub("apiKeys.revoke")
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
function createDefaultDataClient(convexUrl, jwt) {
|
|
1046
|
+
const client = new ConvexHttpClient(convexUrl);
|
|
1047
|
+
client.setAuth(jwt);
|
|
1048
|
+
return client;
|
|
622
1049
|
}
|
|
623
|
-
roleKeyFromLabel("OWNER");
|
|
624
|
-
roleKeyFromLabel("FINANCE_MANAGER");
|
|
625
|
-
roleKeyFromLabel("TEAM_LEAD");
|
|
626
1050
|
|
|
627
1051
|
// src/transport.ts
|
|
628
1052
|
function makeHttpTransport(config) {
|
|
@@ -953,7 +1377,7 @@ function readNonEmptyString(value) {
|
|
|
953
1377
|
|
|
954
1378
|
// src/core/auth.ts
|
|
955
1379
|
function createAuthClient(config = {}) {
|
|
956
|
-
let dataClient = config.
|
|
1380
|
+
let dataClient = config._data ?? null;
|
|
957
1381
|
const sessionStore = config.auth?.sessionStore ?? createMemorySessionStore();
|
|
958
1382
|
const getTransport = createTransportProvider(config);
|
|
959
1383
|
return {
|
|
@@ -1009,11 +1433,20 @@ function createAuthClient(config = {}) {
|
|
|
1009
1433
|
).toISOString()
|
|
1010
1434
|
};
|
|
1011
1435
|
sessionStore.set(session);
|
|
1012
|
-
if (
|
|
1436
|
+
if (!dataClient) {
|
|
1013
1437
|
try {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1438
|
+
const convexUrl = transport.convexUrl;
|
|
1439
|
+
if (!convexUrl || !session.convexJwt) {
|
|
1440
|
+
return [
|
|
1441
|
+
new CapxulError({
|
|
1442
|
+
code: "NETWORK_ERROR",
|
|
1443
|
+
message: "Cannot create data client: missing convex URL or JWT."
|
|
1444
|
+
}),
|
|
1445
|
+
null
|
|
1446
|
+
];
|
|
1447
|
+
}
|
|
1448
|
+
dataClient = createDefaultDataClient(convexUrl, session.convexJwt);
|
|
1449
|
+
mutableConfig(config)._data = dataClient;
|
|
1017
1450
|
} catch (cause) {
|
|
1018
1451
|
return [
|
|
1019
1452
|
new CapxulError({
|
|
@@ -1024,7 +1457,15 @@ function createAuthClient(config = {}) {
|
|
|
1024
1457
|
null
|
|
1025
1458
|
];
|
|
1026
1459
|
}
|
|
1460
|
+
} else {
|
|
1461
|
+
const injected = dataClient;
|
|
1462
|
+
if (typeof injected.refreshAuth === "function") {
|
|
1463
|
+
injected.refreshAuth();
|
|
1464
|
+
} else if (typeof injected.setAuth === "function" && session.convexJwt) {
|
|
1465
|
+
injected.setAuth(session.convexJwt);
|
|
1466
|
+
}
|
|
1027
1467
|
}
|
|
1468
|
+
transport.markAuthenticated({ dataClient });
|
|
1028
1469
|
if (!dataClient) {
|
|
1029
1470
|
return [
|
|
1030
1471
|
new CapxulError({
|
|
@@ -1052,7 +1493,7 @@ function createAuthClient(config = {}) {
|
|
|
1052
1493
|
},
|
|
1053
1494
|
completeBootstrap: async (input) => {
|
|
1054
1495
|
const session = sessionStore.get();
|
|
1055
|
-
const data = dataClient ?? config.
|
|
1496
|
+
const data = dataClient ?? config._data;
|
|
1056
1497
|
if (!session || !data) {
|
|
1057
1498
|
return [
|
|
1058
1499
|
new CapxulError({
|
|
@@ -1062,23 +1503,29 @@ function createAuthClient(config = {}) {
|
|
|
1062
1503
|
null
|
|
1063
1504
|
];
|
|
1064
1505
|
}
|
|
1065
|
-
|
|
1506
|
+
const signerAddress = config.signer?.address;
|
|
1507
|
+
if (!signerAddress) {
|
|
1066
1508
|
return [
|
|
1067
1509
|
new CapxulError({
|
|
1068
1510
|
code: "INVALID_INPUT",
|
|
1069
|
-
message: "completeBootstrap
|
|
1511
|
+
message: "completeBootstrap requires a signer to be configured on the client."
|
|
1070
1512
|
}),
|
|
1071
1513
|
null
|
|
1072
1514
|
];
|
|
1073
1515
|
}
|
|
1074
1516
|
try {
|
|
1517
|
+
const safeAddress = deriveSafeAddress(signerAddress);
|
|
1075
1518
|
const result = await data.mutation(api.authBootstrap.completeBootstrap, {
|
|
1076
1519
|
bootstrapToken: input.bootstrapToken,
|
|
1077
1520
|
sessionToken: session.token,
|
|
1078
1521
|
username: input.username,
|
|
1079
1522
|
displayName: input.displayName,
|
|
1080
1523
|
countryCode: input.countryCode,
|
|
1081
|
-
signerProvider:
|
|
1524
|
+
signerProvider: {
|
|
1525
|
+
kind: "local-private-key",
|
|
1526
|
+
signerAddress,
|
|
1527
|
+
safeAddress
|
|
1528
|
+
}
|
|
1082
1529
|
});
|
|
1083
1530
|
return [null, { kind: "authenticated", session, ...result }];
|
|
1084
1531
|
} catch (cause) {
|
|
@@ -1092,7 +1539,7 @@ function createAuthClient(config = {}) {
|
|
|
1092
1539
|
signOut: async () => {
|
|
1093
1540
|
sessionStore.clear();
|
|
1094
1541
|
dataClient = null;
|
|
1095
|
-
mutableConfig(config).
|
|
1542
|
+
mutableConfig(config)._data = void 0;
|
|
1096
1543
|
const transport = getTransport();
|
|
1097
1544
|
transport?.clearAuth();
|
|
1098
1545
|
return [null, void 0];
|
|
@@ -1163,6 +1610,9 @@ async function postBetterAuth(transport, path, body, code, signal) {
|
|
|
1163
1610
|
}
|
|
1164
1611
|
return [null, text ? JSON.parse(text) : void 0];
|
|
1165
1612
|
} catch (cause) {
|
|
1613
|
+
if (cause instanceof CapxulError) {
|
|
1614
|
+
return [cause, null];
|
|
1615
|
+
}
|
|
1166
1616
|
return [
|
|
1167
1617
|
new CapxulError({
|
|
1168
1618
|
code: "NETWORK_ERROR",
|
|
@@ -1201,7 +1651,7 @@ function parseBetterAuthError(text) {
|
|
|
1201
1651
|
}
|
|
1202
1652
|
}
|
|
1203
1653
|
function isCapxulErrorCode2(code) {
|
|
1204
|
-
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";
|
|
1654
|
+
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";
|
|
1205
1655
|
}
|
|
1206
1656
|
async function exchangeConvexToken(transport, config, token, signal) {
|
|
1207
1657
|
const path = config.auth?.convexTokenUrl ?? "/convex/token";
|
|
@@ -1231,6 +1681,9 @@ async function exchangeConvexToken(transport, config, token, signal) {
|
|
|
1231
1681
|
}
|
|
1232
1682
|
return [null, body.token];
|
|
1233
1683
|
} catch (cause) {
|
|
1684
|
+
if (cause instanceof CapxulError) {
|
|
1685
|
+
return [cause, null];
|
|
1686
|
+
}
|
|
1234
1687
|
return [
|
|
1235
1688
|
new CapxulError({
|
|
1236
1689
|
code: "NETWORK_ERROR",
|
|
@@ -1267,11 +1720,11 @@ function createOrgDocumentsClient() {
|
|
|
1267
1720
|
function createMeClient(config = {}) {
|
|
1268
1721
|
return {
|
|
1269
1722
|
get: async () => {
|
|
1270
|
-
if (!config.
|
|
1723
|
+
if (!config._data) {
|
|
1271
1724
|
return stub("me.get");
|
|
1272
1725
|
}
|
|
1273
1726
|
try {
|
|
1274
|
-
const account = await config.
|
|
1727
|
+
const account = await config._data.query(
|
|
1275
1728
|
api.openfort.queries.getMyAccount,
|
|
1276
1729
|
{}
|
|
1277
1730
|
);
|
|
@@ -1281,7 +1734,7 @@ function createMeClient(config = {}) {
|
|
|
1281
1734
|
}
|
|
1282
1735
|
},
|
|
1283
1736
|
update: async (input) => {
|
|
1284
|
-
if (!config.
|
|
1737
|
+
if (!config._data) {
|
|
1285
1738
|
return stub("me.update");
|
|
1286
1739
|
}
|
|
1287
1740
|
if (input.countryCode !== void 0) {
|
|
@@ -1295,11 +1748,11 @@ function createMeClient(config = {}) {
|
|
|
1295
1748
|
];
|
|
1296
1749
|
}
|
|
1297
1750
|
try {
|
|
1298
|
-
await config.
|
|
1751
|
+
await config._data.mutation(api.openfort.mutations.updateProfile, {
|
|
1299
1752
|
displayName: input.name,
|
|
1300
1753
|
username: input.username
|
|
1301
1754
|
});
|
|
1302
|
-
const account = await config.
|
|
1755
|
+
const account = await config._data.query(
|
|
1303
1756
|
api.openfort.queries.getMyAccount,
|
|
1304
1757
|
{}
|
|
1305
1758
|
);
|
|
@@ -1314,11 +1767,11 @@ function createMeClient(config = {}) {
|
|
|
1314
1767
|
// src/core/operations.ts
|
|
1315
1768
|
function createOperationsClient(config = {}) {
|
|
1316
1769
|
const retrieve = async (operationId) => {
|
|
1317
|
-
if (!config.
|
|
1770
|
+
if (!config._data) {
|
|
1318
1771
|
return stub("operations.retrieve");
|
|
1319
1772
|
}
|
|
1320
1773
|
try {
|
|
1321
|
-
const operation = await config.
|
|
1774
|
+
const operation = await config._data.query(api.operations.queries.retrieve, {
|
|
1322
1775
|
operationId
|
|
1323
1776
|
});
|
|
1324
1777
|
if (!operation) {
|
|
@@ -1335,7 +1788,7 @@ function createOperationsClient(config = {}) {
|
|
|
1335
1788
|
return {
|
|
1336
1789
|
retrieve,
|
|
1337
1790
|
wait: async (operationId, input = {}) => {
|
|
1338
|
-
if (!config.
|
|
1791
|
+
if (!config._data) {
|
|
1339
1792
|
return stub("operations.wait");
|
|
1340
1793
|
}
|
|
1341
1794
|
const until = new Set(
|
|
@@ -1370,49 +1823,22 @@ function toTokenUnits(value, decimals = 6) {
|
|
|
1370
1823
|
return parseUnits(value, decimals);
|
|
1371
1824
|
}
|
|
1372
1825
|
|
|
1373
|
-
// src/
|
|
1374
|
-
function
|
|
1826
|
+
// src/core/token-registry.ts
|
|
1827
|
+
function resolvePaymentToken(currency) {
|
|
1375
1828
|
const normalized = currency.trim().toUpperCase();
|
|
1376
1829
|
if (normalized === "USD" || normalized === "USDC") {
|
|
1377
|
-
return
|
|
1830
|
+
return {
|
|
1831
|
+
address: TEST_USDC_ADDRESS.toLowerCase(),
|
|
1832
|
+
decimals: 6,
|
|
1833
|
+
symbol: "USDC"
|
|
1834
|
+
};
|
|
1378
1835
|
}
|
|
1379
1836
|
throw new CapxulError({
|
|
1380
|
-
code: "
|
|
1381
|
-
message: `Currency ${currency} is not
|
|
1837
|
+
code: "NOT_IMPLEMENTED",
|
|
1838
|
+
message: `Currency ${currency} is not yet supported by the token registry.`,
|
|
1382
1839
|
details: { currency: normalized }
|
|
1383
1840
|
});
|
|
1384
1841
|
}
|
|
1385
|
-
async function buildSafeAccount(signer, chain) {
|
|
1386
|
-
try {
|
|
1387
|
-
const publicClient = createPublicClient({
|
|
1388
|
-
chain: baseSepolia,
|
|
1389
|
-
transport: http(chain.rpcUrl)
|
|
1390
|
-
});
|
|
1391
|
-
return await toSafeSmartAccount({
|
|
1392
|
-
client: publicClient,
|
|
1393
|
-
entryPoint: { address: entryPoint07Address, version: "0.7" },
|
|
1394
|
-
version: "1.4.1",
|
|
1395
|
-
owners: [signer],
|
|
1396
|
-
saltNonce: computeSaltNonce(signer.address),
|
|
1397
|
-
safeSingletonAddress: SAFE_L2_SINGLETON,
|
|
1398
|
-
safeProxyFactoryAddress: SAFE_PROXY_FACTORY,
|
|
1399
|
-
safeModuleSetupAddress: SAFE_MODULE_SETUP,
|
|
1400
|
-
safe4337ModuleAddress: SAFE_4337_MODULE,
|
|
1401
|
-
safeModules: [],
|
|
1402
|
-
setupTransactions: []
|
|
1403
|
-
});
|
|
1404
|
-
} catch (cause) {
|
|
1405
|
-
throw new CapxulError({
|
|
1406
|
-
code: "NETWORK_ERROR",
|
|
1407
|
-
message: cause instanceof Error ? cause.message : String(cause),
|
|
1408
|
-
cause,
|
|
1409
|
-
details: { chainId: chain.chainId }
|
|
1410
|
-
});
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
function computeSaltNonce(ownerAddress) {
|
|
1414
|
-
return BigInt(`0x${ownerAddress.toLowerCase().slice(2).padEnd(64, "0")}`);
|
|
1415
|
-
}
|
|
1416
1842
|
function createCapxulBundler(config) {
|
|
1417
1843
|
const paymaster = createPaymasterClient({
|
|
1418
1844
|
transport: http(config.rpcUrl)
|
|
@@ -1519,13 +1945,13 @@ async function transferAsOwner(config, params) {
|
|
|
1519
1945
|
function createPaymentsClient(config = {}) {
|
|
1520
1946
|
return {
|
|
1521
1947
|
create: async (input) => {
|
|
1522
|
-
if (!config.
|
|
1948
|
+
if (!config._data || !config.signer || !config.signing) {
|
|
1523
1949
|
return stub("payments.create");
|
|
1524
1950
|
}
|
|
1525
1951
|
let created = null;
|
|
1526
1952
|
let submitted = null;
|
|
1527
1953
|
try {
|
|
1528
|
-
created = await config.
|
|
1954
|
+
created = await config._data.mutation(api.payments.mutations.create, {
|
|
1529
1955
|
to: input.to,
|
|
1530
1956
|
amount: input.amount,
|
|
1531
1957
|
reference: input.reference,
|
|
@@ -1533,15 +1959,21 @@ function createPaymentsClient(config = {}) {
|
|
|
1533
1959
|
source: input.source
|
|
1534
1960
|
});
|
|
1535
1961
|
if (!created) {
|
|
1536
|
-
return [
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1962
|
+
return [
|
|
1963
|
+
new CapxulError({
|
|
1964
|
+
code: "NETWORK_ERROR",
|
|
1965
|
+
message: "payments.create returned no payment resource"
|
|
1966
|
+
}),
|
|
1967
|
+
null
|
|
1968
|
+
];
|
|
1540
1969
|
}
|
|
1541
1970
|
if (created.status !== "processing" || created.operation.status !== "processing") {
|
|
1542
1971
|
return [null, created];
|
|
1543
1972
|
}
|
|
1544
|
-
const currentSigner = await config.
|
|
1973
|
+
const currentSigner = await config._data.query(
|
|
1974
|
+
api.safe.queries.getMySignerAddress,
|
|
1975
|
+
{}
|
|
1976
|
+
);
|
|
1545
1977
|
if (!currentSigner?.address) {
|
|
1546
1978
|
throw new CapxulError({
|
|
1547
1979
|
code: "PERMISSION_DENIED",
|
|
@@ -1560,9 +1992,12 @@ function createPaymentsClient(config = {}) {
|
|
|
1560
1992
|
}
|
|
1561
1993
|
});
|
|
1562
1994
|
}
|
|
1563
|
-
const submission = await config.
|
|
1564
|
-
|
|
1565
|
-
|
|
1995
|
+
const submission = await config._data.query(
|
|
1996
|
+
api.payments.queries.prepareSubmission,
|
|
1997
|
+
{
|
|
1998
|
+
paymentId: created.id
|
|
1999
|
+
}
|
|
2000
|
+
);
|
|
1566
2001
|
if (!submission?.recipientAddress) {
|
|
1567
2002
|
throw new CapxulError({
|
|
1568
2003
|
code: "NETWORK_ERROR",
|
|
@@ -1570,15 +2005,16 @@ function createPaymentsClient(config = {}) {
|
|
|
1570
2005
|
details: { paymentId: created.id }
|
|
1571
2006
|
});
|
|
1572
2007
|
}
|
|
2008
|
+
const token = resolvePaymentToken(submission.amount.currency);
|
|
1573
2009
|
const transfer = await transferAsOwner(
|
|
1574
2010
|
{
|
|
1575
2011
|
signer: config.signer,
|
|
1576
2012
|
signing: config.signing
|
|
1577
2013
|
},
|
|
1578
2014
|
{
|
|
1579
|
-
tokenAddress:
|
|
2015
|
+
tokenAddress: token.address,
|
|
1580
2016
|
recipientAddress: submission.recipientAddress,
|
|
1581
|
-
amount: toTokenUnits(submission.amount.value,
|
|
2017
|
+
amount: toTokenUnits(submission.amount.value, token.decimals)
|
|
1582
2018
|
}
|
|
1583
2019
|
);
|
|
1584
2020
|
if (!transfer.success) {
|
|
@@ -1596,7 +2032,7 @@ function createPaymentsClient(config = {}) {
|
|
|
1596
2032
|
txHash: transfer.txHash,
|
|
1597
2033
|
userOpHash: transfer.userOpHash
|
|
1598
2034
|
};
|
|
1599
|
-
await config.
|
|
2035
|
+
await config._data.mutation(api.payments.mutations.recordSubmitted, {
|
|
1600
2036
|
paymentId: created.id,
|
|
1601
2037
|
txHash: transfer.txHash,
|
|
1602
2038
|
userOpHash: transfer.userOpHash,
|
|
@@ -1606,43 +2042,65 @@ function createPaymentsClient(config = {}) {
|
|
|
1606
2042
|
} catch (cause) {
|
|
1607
2043
|
const error = mapCreateError(fromConvexError(cause));
|
|
1608
2044
|
if (created?.id && created.status === "processing" && !submitted) {
|
|
1609
|
-
await bestEffortMarkFailed({
|
|
2045
|
+
await bestEffortMarkFailed({ _data: config._data }, created.id, error);
|
|
1610
2046
|
}
|
|
1611
2047
|
if (submitted && created?.id) {
|
|
1612
|
-
return [
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
2048
|
+
return [
|
|
2049
|
+
new CapxulError({
|
|
2050
|
+
code: "NETWORK_ERROR",
|
|
2051
|
+
message: "Payment was submitted on-chain, but backend submission tracking failed.",
|
|
2052
|
+
cause,
|
|
2053
|
+
details: {
|
|
2054
|
+
paymentId: created.id,
|
|
2055
|
+
txHash: submitted.txHash,
|
|
2056
|
+
userOpHash: submitted.userOpHash
|
|
2057
|
+
}
|
|
2058
|
+
}),
|
|
2059
|
+
null
|
|
2060
|
+
];
|
|
1622
2061
|
}
|
|
1623
2062
|
return [error, null];
|
|
1624
2063
|
}
|
|
1625
2064
|
},
|
|
1626
2065
|
retrieve: async (paymentId) => {
|
|
1627
|
-
if (!config.
|
|
2066
|
+
if (!config._data) {
|
|
1628
2067
|
return stub("payments.retrieve");
|
|
1629
2068
|
}
|
|
1630
2069
|
try {
|
|
1631
|
-
const payment = await config.
|
|
1632
|
-
|
|
1633
|
-
|
|
2070
|
+
const payment = await config._data.query(
|
|
2071
|
+
api.payments.queries.retrieve,
|
|
2072
|
+
{
|
|
2073
|
+
paymentId
|
|
2074
|
+
}
|
|
2075
|
+
);
|
|
1634
2076
|
if (!payment) {
|
|
1635
|
-
return [
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
2077
|
+
return [
|
|
2078
|
+
new CapxulError({
|
|
2079
|
+
code: "NOT_FOUND",
|
|
2080
|
+
message: `payment ${paymentId} not found`
|
|
2081
|
+
}),
|
|
2082
|
+
null
|
|
2083
|
+
];
|
|
1639
2084
|
}
|
|
1640
2085
|
return [null, payment];
|
|
1641
2086
|
} catch (cause) {
|
|
1642
2087
|
return [fromConvexError(cause), null];
|
|
1643
2088
|
}
|
|
1644
2089
|
},
|
|
1645
|
-
list: async () =>
|
|
2090
|
+
list: async (input) => {
|
|
2091
|
+
if (!config._data) {
|
|
2092
|
+
return stub("payments.list");
|
|
2093
|
+
}
|
|
2094
|
+
try {
|
|
2095
|
+
const page = await config._data.query(api.payments.queries.list, {
|
|
2096
|
+
limit: input?.limit,
|
|
2097
|
+
cursor: input?.cursor
|
|
2098
|
+
});
|
|
2099
|
+
return [null, page];
|
|
2100
|
+
} catch (cause) {
|
|
2101
|
+
return [fromConvexError(cause), null];
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
1646
2104
|
};
|
|
1647
2105
|
}
|
|
1648
2106
|
function createOrgPaymentsClient() {
|
|
@@ -1656,7 +2114,7 @@ function createOrgPaymentsClient() {
|
|
|
1656
2114
|
}
|
|
1657
2115
|
async function bestEffortMarkFailed(config, paymentId, error) {
|
|
1658
2116
|
try {
|
|
1659
|
-
await config.
|
|
2117
|
+
await config._data.mutation(api.payments.mutations.markFailed, {
|
|
1660
2118
|
paymentId,
|
|
1661
2119
|
errorCode: error.code,
|
|
1662
2120
|
errorMessage: error.message,
|
|
@@ -1713,11 +2171,11 @@ function createOrgTransfersClient() {
|
|
|
1713
2171
|
function createWithdrawalsClient(config = {}) {
|
|
1714
2172
|
return {
|
|
1715
2173
|
create: async (input) => {
|
|
1716
|
-
if (!config.
|
|
2174
|
+
if (!config._data) {
|
|
1717
2175
|
return stub("withdrawals.create");
|
|
1718
2176
|
}
|
|
1719
2177
|
const [createErr, createdRaw] = await tryCatch(
|
|
1720
|
-
config.
|
|
2178
|
+
config._data.mutation(api.withdrawals.mutations.create, {
|
|
1721
2179
|
amount: input.amount,
|
|
1722
2180
|
destination: {
|
|
1723
2181
|
externalAccountId: input.destination.externalAccountId
|
|
@@ -1747,18 +2205,18 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1747
2205
|
return [null, created];
|
|
1748
2206
|
}
|
|
1749
2207
|
const [signerErr, currentSigner] = await tryCatch(
|
|
1750
|
-
config.
|
|
2208
|
+
config._data.query(api.safe.queries.getMySignerAddress, {})
|
|
1751
2209
|
);
|
|
1752
2210
|
if (signerErr) {
|
|
1753
2211
|
return await handleSubmissionFailure(
|
|
1754
|
-
{
|
|
2212
|
+
{ _data: config._data },
|
|
1755
2213
|
created.id,
|
|
1756
2214
|
mapCreateError2(fromConvexError(signerErr))
|
|
1757
2215
|
);
|
|
1758
2216
|
}
|
|
1759
2217
|
if (!currentSigner?.address) {
|
|
1760
2218
|
return await handleSubmissionFailure(
|
|
1761
|
-
{
|
|
2219
|
+
{ _data: config._data },
|
|
1762
2220
|
created.id,
|
|
1763
2221
|
new CapxulError({
|
|
1764
2222
|
code: "PERMISSION_DENIED",
|
|
@@ -1769,7 +2227,7 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1769
2227
|
}
|
|
1770
2228
|
if (getAddress(currentSigner.address) !== getAddress(config.signer.address)) {
|
|
1771
2229
|
return await handleSubmissionFailure(
|
|
1772
|
-
{
|
|
2230
|
+
{ _data: config._data },
|
|
1773
2231
|
created.id,
|
|
1774
2232
|
new CapxulError({
|
|
1775
2233
|
code: "PERMISSION_DENIED",
|
|
@@ -1783,13 +2241,13 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1783
2241
|
);
|
|
1784
2242
|
}
|
|
1785
2243
|
const [prepErr, submission] = await tryCatch(
|
|
1786
|
-
config.
|
|
2244
|
+
config._data.query(api.withdrawals.queries.prepareSubmission, {
|
|
1787
2245
|
withdrawalId: created.id
|
|
1788
2246
|
})
|
|
1789
2247
|
);
|
|
1790
2248
|
if (prepErr) {
|
|
1791
2249
|
return await handleSubmissionFailure(
|
|
1792
|
-
{
|
|
2250
|
+
{ _data: config._data },
|
|
1793
2251
|
created.id,
|
|
1794
2252
|
mapCreateError2(fromConvexError(prepErr))
|
|
1795
2253
|
);
|
|
@@ -1797,7 +2255,7 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1797
2255
|
const destinationAddress = submission?.destinationAddress;
|
|
1798
2256
|
if (!submission || !destinationAddress) {
|
|
1799
2257
|
return await handleSubmissionFailure(
|
|
1800
|
-
{
|
|
2258
|
+
{ _data: config._data },
|
|
1801
2259
|
created.id,
|
|
1802
2260
|
new CapxulError({
|
|
1803
2261
|
code: "NETWORK_ERROR",
|
|
@@ -1806,6 +2264,7 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1806
2264
|
})
|
|
1807
2265
|
);
|
|
1808
2266
|
}
|
|
2267
|
+
const token = resolvePaymentToken(submission.amount.currency);
|
|
1809
2268
|
const [transferErr, transferOk] = await tryCatch(
|
|
1810
2269
|
transferAsOwner(
|
|
1811
2270
|
{
|
|
@@ -1813,22 +2272,22 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1813
2272
|
signing: config.signing
|
|
1814
2273
|
},
|
|
1815
2274
|
{
|
|
1816
|
-
tokenAddress:
|
|
2275
|
+
tokenAddress: token.address,
|
|
1817
2276
|
recipientAddress: destinationAddress,
|
|
1818
|
-
amount: toTokenUnits(submission.amount.value,
|
|
2277
|
+
amount: toTokenUnits(submission.amount.value, token.decimals)
|
|
1819
2278
|
}
|
|
1820
2279
|
)
|
|
1821
2280
|
);
|
|
1822
2281
|
if (transferErr) {
|
|
1823
2282
|
return await handleSubmissionFailure(
|
|
1824
|
-
{
|
|
2283
|
+
{ _data: config._data },
|
|
1825
2284
|
created.id,
|
|
1826
2285
|
mapCreateError2(fromConvexError(transferErr))
|
|
1827
2286
|
);
|
|
1828
2287
|
}
|
|
1829
2288
|
if (!transferOk.success) {
|
|
1830
2289
|
return await handleSubmissionFailure(
|
|
1831
|
-
{
|
|
2290
|
+
{ _data: config._data },
|
|
1832
2291
|
created.id,
|
|
1833
2292
|
new CapxulError({
|
|
1834
2293
|
code: "NETWORK_ERROR",
|
|
@@ -1842,7 +2301,7 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1842
2301
|
);
|
|
1843
2302
|
}
|
|
1844
2303
|
const [recordErr] = await tryCatch(
|
|
1845
|
-
config.
|
|
2304
|
+
config._data.mutation(api.withdrawals.mutations.recordSubmitted, {
|
|
1846
2305
|
withdrawalId: created.id,
|
|
1847
2306
|
txHash: transferOk.txHash,
|
|
1848
2307
|
userOpHash: transferOk.userOpHash
|
|
@@ -1866,11 +2325,11 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1866
2325
|
return [null, created];
|
|
1867
2326
|
},
|
|
1868
2327
|
retrieve: async (withdrawalId) => {
|
|
1869
|
-
if (!config.
|
|
2328
|
+
if (!config._data) {
|
|
1870
2329
|
return stub("withdrawals.retrieve");
|
|
1871
2330
|
}
|
|
1872
2331
|
const [err, raw] = await tryCatch(
|
|
1873
|
-
config.
|
|
2332
|
+
config._data.query(api.withdrawals.queries.retrieve, { withdrawalId })
|
|
1874
2333
|
);
|
|
1875
2334
|
if (err) {
|
|
1876
2335
|
return [fromConvexError(err), null];
|
|
@@ -1888,11 +2347,11 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1888
2347
|
return [null, withdrawal];
|
|
1889
2348
|
},
|
|
1890
2349
|
list: async (input) => {
|
|
1891
|
-
if (!config.
|
|
2350
|
+
if (!config._data) {
|
|
1892
2351
|
return stub("withdrawals.list");
|
|
1893
2352
|
}
|
|
1894
2353
|
const [err, raw] = await tryCatch(
|
|
1895
|
-
config.
|
|
2354
|
+
config._data.query(api.withdrawals.queries.list, {
|
|
1896
2355
|
limit: input?.limit,
|
|
1897
2356
|
cursor: input?.cursor
|
|
1898
2357
|
})
|
|
@@ -1903,13 +2362,13 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1903
2362
|
return [null, raw];
|
|
1904
2363
|
},
|
|
1905
2364
|
recordCompleted: async (input) => {
|
|
1906
|
-
if (!config.
|
|
2365
|
+
if (!config._data) {
|
|
1907
2366
|
return stub(
|
|
1908
2367
|
"withdrawals.recordCompleted"
|
|
1909
2368
|
);
|
|
1910
2369
|
}
|
|
1911
2370
|
const [err] = await tryCatch(
|
|
1912
|
-
config.
|
|
2371
|
+
config._data.mutation(api.withdrawals.mutations.recordCompleted, {
|
|
1913
2372
|
withdrawalId: input.withdrawalId,
|
|
1914
2373
|
txHash: input.txHash
|
|
1915
2374
|
})
|
|
@@ -1934,13 +2393,13 @@ function createOrgWithdrawalsClient(config = {}) {
|
|
|
1934
2393
|
* orchestration ships in W3+.
|
|
1935
2394
|
*/
|
|
1936
2395
|
create: async (input) => {
|
|
1937
|
-
if (!config.
|
|
2396
|
+
if (!config._data) {
|
|
1938
2397
|
return stub(
|
|
1939
2398
|
"organizations.withdrawals.create"
|
|
1940
2399
|
);
|
|
1941
2400
|
}
|
|
1942
2401
|
const [err, raw] = await tryCatch(
|
|
1943
|
-
config.
|
|
2402
|
+
config._data.mutation(api.withdrawals.mutations.createOrg, {
|
|
1944
2403
|
organizationId: input.organizationId,
|
|
1945
2404
|
amount: input.amount,
|
|
1946
2405
|
destination: {
|
|
@@ -1967,13 +2426,13 @@ function createOrgWithdrawalsClient(config = {}) {
|
|
|
1967
2426
|
return [null, created];
|
|
1968
2427
|
},
|
|
1969
2428
|
retrieve: async (input) => {
|
|
1970
|
-
if (!config.
|
|
2429
|
+
if (!config._data) {
|
|
1971
2430
|
return stub(
|
|
1972
2431
|
"organizations.withdrawals.retrieve"
|
|
1973
2432
|
);
|
|
1974
2433
|
}
|
|
1975
2434
|
const [err, raw] = await tryCatch(
|
|
1976
|
-
config.
|
|
2435
|
+
config._data.query(api.withdrawals.queries.retrieve, {
|
|
1977
2436
|
withdrawalId: input.withdrawalId
|
|
1978
2437
|
})
|
|
1979
2438
|
);
|
|
@@ -2003,13 +2462,13 @@ function createOrgWithdrawalsClient(config = {}) {
|
|
|
2003
2462
|
return [null, withdrawal];
|
|
2004
2463
|
},
|
|
2005
2464
|
list: async (input) => {
|
|
2006
|
-
if (!config.
|
|
2465
|
+
if (!config._data) {
|
|
2007
2466
|
return stub(
|
|
2008
2467
|
"organizations.withdrawals.list"
|
|
2009
2468
|
);
|
|
2010
2469
|
}
|
|
2011
2470
|
const [err, raw] = await tryCatch(
|
|
2012
|
-
config.
|
|
2471
|
+
config._data.query(api.withdrawals.queries.listOrg, {
|
|
2013
2472
|
organizationId: input.organizationId,
|
|
2014
2473
|
limit: input.limit,
|
|
2015
2474
|
cursor: input.cursor
|
|
@@ -2028,7 +2487,7 @@ async function handleSubmissionFailure(config, withdrawalId, error) {
|
|
|
2028
2487
|
}
|
|
2029
2488
|
async function bestEffortMarkFailed2(config, withdrawalId, error) {
|
|
2030
2489
|
await tryCatch(
|
|
2031
|
-
config.
|
|
2490
|
+
config._data.mutation(api.withdrawals.mutations.markFailed, {
|
|
2032
2491
|
withdrawalId,
|
|
2033
2492
|
errorCode: error.code,
|
|
2034
2493
|
errorMessage: error.message
|
|
@@ -2102,28 +2561,131 @@ function createWebhookEventsClient() {
|
|
|
2102
2561
|
list: async () => stub("webhookEvents.list")
|
|
2103
2562
|
};
|
|
2104
2563
|
}
|
|
2105
|
-
|
|
2106
|
-
// src/core/organizations.ts
|
|
2107
|
-
function createOrgExternalAccountsClient(config) {
|
|
2564
|
+
|
|
2565
|
+
// src/core/organizations.ts
|
|
2566
|
+
function createOrgExternalAccountsClient(config) {
|
|
2567
|
+
return {
|
|
2568
|
+
create: async (input) => {
|
|
2569
|
+
if (!config._data) {
|
|
2570
|
+
return stub(
|
|
2571
|
+
"organizations.externalAccounts.create"
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
const [err, raw] = await tryCatch(
|
|
2575
|
+
config._data.mutation(api.externalAccounts.mutations.createOrg, {
|
|
2576
|
+
organizationId: input.organizationId,
|
|
2577
|
+
kind: input.kind,
|
|
2578
|
+
label: input.label,
|
|
2579
|
+
address: input.address,
|
|
2580
|
+
iban: input.iban,
|
|
2581
|
+
bic: input.bic,
|
|
2582
|
+
accountHolder: input.accountHolder,
|
|
2583
|
+
network: input.network,
|
|
2584
|
+
panToken: input.panToken,
|
|
2585
|
+
last4: input.last4
|
|
2586
|
+
})
|
|
2587
|
+
);
|
|
2588
|
+
if (err) {
|
|
2589
|
+
return [fromConvexError(err), null];
|
|
2590
|
+
}
|
|
2591
|
+
if (!raw) {
|
|
2592
|
+
return [
|
|
2593
|
+
new CapxulError({
|
|
2594
|
+
code: "NOT_FOUND",
|
|
2595
|
+
message: "external_account creation returned no resource"
|
|
2596
|
+
}),
|
|
2597
|
+
null
|
|
2598
|
+
];
|
|
2599
|
+
}
|
|
2600
|
+
return [null, brandExternalAccount(raw)];
|
|
2601
|
+
},
|
|
2602
|
+
list: async (input) => {
|
|
2603
|
+
if (!config._data) {
|
|
2604
|
+
return stub(
|
|
2605
|
+
"organizations.externalAccounts.list"
|
|
2606
|
+
);
|
|
2607
|
+
}
|
|
2608
|
+
const [err, result] = await tryCatch(
|
|
2609
|
+
config._data.query(api.externalAccounts.queries.listOrg, {
|
|
2610
|
+
organizationId: input.organizationId,
|
|
2611
|
+
limit: input.limit,
|
|
2612
|
+
cursor: input.cursor
|
|
2613
|
+
})
|
|
2614
|
+
);
|
|
2615
|
+
if (err) {
|
|
2616
|
+
return [fromConvexError(err), null];
|
|
2617
|
+
}
|
|
2618
|
+
const branded = result.data.map(
|
|
2619
|
+
(row) => brandExternalAccount(row)
|
|
2620
|
+
);
|
|
2621
|
+
return [
|
|
2622
|
+
null,
|
|
2623
|
+
{
|
|
2624
|
+
object: "list",
|
|
2625
|
+
data: branded,
|
|
2626
|
+
page: result.page
|
|
2627
|
+
}
|
|
2628
|
+
];
|
|
2629
|
+
},
|
|
2630
|
+
retrieve: async (input) => {
|
|
2631
|
+
if (!config._data) {
|
|
2632
|
+
return stub(
|
|
2633
|
+
"organizations.externalAccounts.retrieve"
|
|
2634
|
+
);
|
|
2635
|
+
}
|
|
2636
|
+
const [err, raw] = await tryCatch(
|
|
2637
|
+
config._data.query(api.externalAccounts.queries.retrieveOrg, {
|
|
2638
|
+
organizationId: input.organizationId,
|
|
2639
|
+
externalAccountId: input.externalAccountId
|
|
2640
|
+
})
|
|
2641
|
+
);
|
|
2642
|
+
if (err) {
|
|
2643
|
+
return [fromConvexError(err), null];
|
|
2644
|
+
}
|
|
2645
|
+
if (!raw) {
|
|
2646
|
+
return [
|
|
2647
|
+
new CapxulError({
|
|
2648
|
+
code: "NOT_FOUND",
|
|
2649
|
+
message: `external_account ${input.externalAccountId} not found`
|
|
2650
|
+
}),
|
|
2651
|
+
null
|
|
2652
|
+
];
|
|
2653
|
+
}
|
|
2654
|
+
return [null, brandExternalAccount(raw)];
|
|
2655
|
+
},
|
|
2656
|
+
remove: async (input) => {
|
|
2657
|
+
if (!config._data) {
|
|
2658
|
+
return stub("organizations.externalAccounts.remove");
|
|
2659
|
+
}
|
|
2660
|
+
const [err] = await tryCatch(
|
|
2661
|
+
config._data.mutation(api.externalAccounts.mutations.removeOrg, {
|
|
2662
|
+
organizationId: input.organizationId,
|
|
2663
|
+
externalAccountId: input.externalAccountId
|
|
2664
|
+
})
|
|
2665
|
+
);
|
|
2666
|
+
if (err) {
|
|
2667
|
+
return [fromConvexError(err), null];
|
|
2668
|
+
}
|
|
2669
|
+
return [null, void 0];
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
function createOrgSubAccountsClient(config) {
|
|
2108
2674
|
return {
|
|
2109
2675
|
create: async (input) => {
|
|
2110
|
-
if (!config.
|
|
2676
|
+
if (!config._data) {
|
|
2111
2677
|
return stub(
|
|
2112
|
-
"organizations.
|
|
2678
|
+
"organizations.subAccounts.create"
|
|
2113
2679
|
);
|
|
2114
2680
|
}
|
|
2115
2681
|
const [err, raw] = await tryCatch(
|
|
2116
|
-
config.
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
accountHolder: input.accountHolder,
|
|
2124
|
-
network: input.network,
|
|
2125
|
-
panToken: input.panToken,
|
|
2126
|
-
last4: input.last4
|
|
2682
|
+
config._data.mutation(api.subAccounts.mutations.create, {
|
|
2683
|
+
parent: {
|
|
2684
|
+
kind: "organization",
|
|
2685
|
+
id: input.organizationId
|
|
2686
|
+
},
|
|
2687
|
+
name: input.name,
|
|
2688
|
+
purpose: input.purpose
|
|
2127
2689
|
})
|
|
2128
2690
|
);
|
|
2129
2691
|
if (err) {
|
|
@@ -2136,58 +2698,60 @@ function createOrgExternalAccountsClient(config) {
|
|
|
2136
2698
|
return [
|
|
2137
2699
|
new CapxulError({
|
|
2138
2700
|
code: "NOT_FOUND",
|
|
2139
|
-
message: "
|
|
2701
|
+
message: "sub_account creation returned no resource"
|
|
2140
2702
|
}),
|
|
2141
2703
|
null
|
|
2142
2704
|
];
|
|
2143
2705
|
}
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
];
|
|
2706
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
2707
|
+
if (brandErr) {
|
|
2708
|
+
return [brandErr, null];
|
|
2709
|
+
}
|
|
2710
|
+
return [null, branded];
|
|
2150
2711
|
},
|
|
2151
2712
|
list: async (input) => {
|
|
2152
|
-
if (!config.
|
|
2713
|
+
if (!config._data) {
|
|
2153
2714
|
return stub(
|
|
2154
|
-
"organizations.
|
|
2715
|
+
"organizations.subAccounts.list"
|
|
2155
2716
|
);
|
|
2156
2717
|
}
|
|
2157
|
-
const [err,
|
|
2158
|
-
config.
|
|
2159
|
-
organizationId: input.organizationId
|
|
2160
|
-
limit: input.limit,
|
|
2161
|
-
cursor: input.cursor
|
|
2718
|
+
const [err, rows] = await tryCatch(
|
|
2719
|
+
config._data.query(api.subAccounts.queries.listByOrganization, {
|
|
2720
|
+
organizationId: input.organizationId
|
|
2162
2721
|
})
|
|
2163
2722
|
);
|
|
2164
2723
|
if (err) {
|
|
2165
|
-
return [
|
|
2724
|
+
return [
|
|
2725
|
+
fromConvexError(err),
|
|
2726
|
+
null
|
|
2727
|
+
];
|
|
2728
|
+
}
|
|
2729
|
+
const branded = [];
|
|
2730
|
+
for (const row of rows) {
|
|
2731
|
+
const [brandErr, value] = tryBrandSubAccount(row);
|
|
2732
|
+
if (brandErr) {
|
|
2733
|
+
return [brandErr, null];
|
|
2734
|
+
}
|
|
2735
|
+
branded.push(value);
|
|
2166
2736
|
}
|
|
2167
|
-
const branded = result.data.map(
|
|
2168
|
-
(row) => brandExternalAccount(
|
|
2169
|
-
row
|
|
2170
|
-
)
|
|
2171
|
-
);
|
|
2172
2737
|
return [
|
|
2173
2738
|
null,
|
|
2174
2739
|
{
|
|
2175
2740
|
object: "list",
|
|
2176
2741
|
data: branded,
|
|
2177
|
-
page:
|
|
2742
|
+
page: { hasMore: false }
|
|
2178
2743
|
}
|
|
2179
2744
|
];
|
|
2180
2745
|
},
|
|
2181
2746
|
retrieve: async (input) => {
|
|
2182
|
-
if (!config.
|
|
2747
|
+
if (!config._data) {
|
|
2183
2748
|
return stub(
|
|
2184
|
-
"organizations.
|
|
2749
|
+
"organizations.subAccounts.retrieve"
|
|
2185
2750
|
);
|
|
2186
2751
|
}
|
|
2187
2752
|
const [err, raw] = await tryCatch(
|
|
2188
|
-
config.
|
|
2189
|
-
|
|
2190
|
-
externalAccountId: input.externalAccountId
|
|
2753
|
+
config._data.query(api.subAccounts.queries.retrieve, {
|
|
2754
|
+
subAccountId: input.subAccountId
|
|
2191
2755
|
})
|
|
2192
2756
|
);
|
|
2193
2757
|
if (err) {
|
|
@@ -2200,28 +2764,29 @@ function createOrgExternalAccountsClient(config) {
|
|
|
2200
2764
|
return [
|
|
2201
2765
|
new CapxulError({
|
|
2202
2766
|
code: "NOT_FOUND",
|
|
2203
|
-
message: `
|
|
2767
|
+
message: `sub_account ${input.subAccountId} not found`
|
|
2204
2768
|
}),
|
|
2205
2769
|
null
|
|
2206
2770
|
];
|
|
2207
2771
|
}
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2772
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
2773
|
+
if (brandErr) {
|
|
2774
|
+
return [
|
|
2775
|
+
brandErr,
|
|
2776
|
+
null
|
|
2777
|
+
];
|
|
2778
|
+
}
|
|
2779
|
+
return [null, branded];
|
|
2214
2780
|
},
|
|
2215
2781
|
remove: async (input) => {
|
|
2216
|
-
if (!config.
|
|
2782
|
+
if (!config._data) {
|
|
2217
2783
|
return stub(
|
|
2218
|
-
"organizations.
|
|
2784
|
+
"organizations.subAccounts.remove"
|
|
2219
2785
|
);
|
|
2220
2786
|
}
|
|
2221
|
-
const [err] = await tryCatch(
|
|
2222
|
-
config.
|
|
2223
|
-
|
|
2224
|
-
externalAccountId: input.externalAccountId
|
|
2787
|
+
const [err, raw] = await tryCatch(
|
|
2788
|
+
config._data.mutation(api.subAccounts.mutations.archive, {
|
|
2789
|
+
subAccountId: input.subAccountId
|
|
2225
2790
|
})
|
|
2226
2791
|
);
|
|
2227
2792
|
if (err) {
|
|
@@ -2230,23 +2795,139 @@ function createOrgExternalAccountsClient(config) {
|
|
|
2230
2795
|
null
|
|
2231
2796
|
];
|
|
2232
2797
|
}
|
|
2233
|
-
|
|
2798
|
+
if (!raw) {
|
|
2799
|
+
return [
|
|
2800
|
+
new CapxulError({
|
|
2801
|
+
code: "NOT_FOUND",
|
|
2802
|
+
message: `sub_account ${input.subAccountId} not found`
|
|
2803
|
+
}),
|
|
2804
|
+
null
|
|
2805
|
+
];
|
|
2806
|
+
}
|
|
2807
|
+
const [brandErr, branded] = tryBrandSubAccount(raw);
|
|
2808
|
+
if (brandErr) {
|
|
2809
|
+
return [
|
|
2810
|
+
brandErr,
|
|
2811
|
+
null
|
|
2812
|
+
];
|
|
2813
|
+
}
|
|
2814
|
+
return [null, branded];
|
|
2234
2815
|
}
|
|
2235
2816
|
};
|
|
2236
2817
|
}
|
|
2237
2818
|
function createOrganizationsClient(config = {}) {
|
|
2238
2819
|
return {
|
|
2239
|
-
create: async () =>
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2820
|
+
create: async (input) => {
|
|
2821
|
+
if (!config._data) {
|
|
2822
|
+
return stub("organizations.create");
|
|
2823
|
+
}
|
|
2824
|
+
if (input.country !== void 0) {
|
|
2825
|
+
return [
|
|
2826
|
+
new CapxulError({
|
|
2827
|
+
code: "INVALID_INPUT",
|
|
2828
|
+
message: "organizations.create does not support country yet \u2014 backend mutation only accepts name.",
|
|
2829
|
+
details: { field: "country" }
|
|
2830
|
+
}),
|
|
2831
|
+
null
|
|
2832
|
+
];
|
|
2833
|
+
}
|
|
2834
|
+
try {
|
|
2835
|
+
const orgId = await config._data.mutation(api.org.mutations.create, {
|
|
2836
|
+
name: input.name
|
|
2837
|
+
});
|
|
2838
|
+
const org = await config._data.query(api.org.queries.retrieve, {
|
|
2839
|
+
orgId
|
|
2840
|
+
});
|
|
2841
|
+
if (!org) {
|
|
2842
|
+
return [
|
|
2843
|
+
new CapxulError({
|
|
2844
|
+
code: "NETWORK_ERROR",
|
|
2845
|
+
message: "organization created but could not be retrieved"
|
|
2846
|
+
}),
|
|
2847
|
+
null
|
|
2848
|
+
];
|
|
2849
|
+
}
|
|
2850
|
+
return [null, org];
|
|
2851
|
+
} catch (cause) {
|
|
2852
|
+
return [fromConvexError(cause), null];
|
|
2853
|
+
}
|
|
2854
|
+
},
|
|
2855
|
+
retrieve: async (organizationId) => {
|
|
2856
|
+
if (!config._data) {
|
|
2857
|
+
return stub("organizations.retrieve");
|
|
2858
|
+
}
|
|
2859
|
+
try {
|
|
2860
|
+
const orgId = organizationId.replace(/^org_/, "");
|
|
2861
|
+
const org = await config._data.query(api.org.queries.retrieve, {
|
|
2862
|
+
orgId
|
|
2863
|
+
});
|
|
2864
|
+
if (!org) {
|
|
2865
|
+
return [
|
|
2866
|
+
new CapxulError({
|
|
2867
|
+
code: "NOT_FOUND",
|
|
2868
|
+
message: `organization ${organizationId} not found`
|
|
2869
|
+
}),
|
|
2870
|
+
null
|
|
2871
|
+
];
|
|
2872
|
+
}
|
|
2873
|
+
return [null, org];
|
|
2874
|
+
} catch (cause) {
|
|
2875
|
+
return [fromConvexError(cause), null];
|
|
2876
|
+
}
|
|
2877
|
+
},
|
|
2878
|
+
list: async (input) => {
|
|
2879
|
+
if (!config._data) {
|
|
2880
|
+
return stub("organizations.list");
|
|
2881
|
+
}
|
|
2882
|
+
try {
|
|
2883
|
+
const page = await config._data.query(api.org.queries.list, {
|
|
2884
|
+
limit: input?.limit,
|
|
2885
|
+
cursor: input?.cursor
|
|
2886
|
+
});
|
|
2887
|
+
const result = {
|
|
2888
|
+
object: "list",
|
|
2889
|
+
data: page.data,
|
|
2890
|
+
page: {
|
|
2891
|
+
hasMore: page.hasMore,
|
|
2892
|
+
cursor: page.nextCursor
|
|
2893
|
+
}
|
|
2894
|
+
};
|
|
2895
|
+
return [null, result];
|
|
2896
|
+
} catch (cause) {
|
|
2897
|
+
return [fromConvexError(cause), null];
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2900
|
+
update: async (input) => {
|
|
2901
|
+
if (!config._data) {
|
|
2902
|
+
return stub("organizations.update");
|
|
2903
|
+
}
|
|
2904
|
+
try {
|
|
2905
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
2906
|
+
const org = await config._data.mutation(api.org.mutations.update, {
|
|
2907
|
+
orgId,
|
|
2908
|
+
name: input.name
|
|
2909
|
+
});
|
|
2910
|
+
if (!org) {
|
|
2911
|
+
return [
|
|
2912
|
+
new CapxulError({
|
|
2913
|
+
code: "NOT_FOUND",
|
|
2914
|
+
message: `organization ${input.organizationId} not found`
|
|
2915
|
+
}),
|
|
2916
|
+
null
|
|
2917
|
+
];
|
|
2918
|
+
}
|
|
2919
|
+
return [null, org];
|
|
2920
|
+
} catch (cause) {
|
|
2921
|
+
return [fromConvexError(cause), null];
|
|
2922
|
+
}
|
|
2923
|
+
},
|
|
2243
2924
|
safes: {
|
|
2244
2925
|
retrieve: async (input) => {
|
|
2245
|
-
if (!config.
|
|
2926
|
+
if (!config._data) {
|
|
2246
2927
|
return stub("organizations.safes.retrieve");
|
|
2247
2928
|
}
|
|
2248
2929
|
try {
|
|
2249
|
-
const safe = await config.
|
|
2930
|
+
const safe = await config._data.query(
|
|
2250
2931
|
api.safe.queries.retrieveOrganizationSafe,
|
|
2251
2932
|
input
|
|
2252
2933
|
);
|
|
@@ -2269,34 +2950,243 @@ function createOrganizationsClient(config = {}) {
|
|
|
2269
2950
|
}
|
|
2270
2951
|
},
|
|
2271
2952
|
treasury: {
|
|
2272
|
-
retrieve: async () =>
|
|
2953
|
+
retrieve: async (organizationId) => {
|
|
2954
|
+
if (!config._data) {
|
|
2955
|
+
return stub(
|
|
2956
|
+
"organizations.treasury.retrieve"
|
|
2957
|
+
);
|
|
2958
|
+
}
|
|
2959
|
+
try {
|
|
2960
|
+
const orgId = organizationId.replace(/^org_/, "");
|
|
2961
|
+
const raw = await config._data.query(
|
|
2962
|
+
api.safe.queries.getOrgTreasuryBalance,
|
|
2963
|
+
{ orgId }
|
|
2964
|
+
);
|
|
2965
|
+
if (!raw) {
|
|
2966
|
+
return [
|
|
2967
|
+
new CapxulError({
|
|
2968
|
+
code: "NOT_FOUND",
|
|
2969
|
+
message: `treasury for organization ${organizationId} not found`
|
|
2970
|
+
}),
|
|
2971
|
+
null
|
|
2972
|
+
];
|
|
2973
|
+
}
|
|
2974
|
+
const treasury = {
|
|
2975
|
+
object: "treasury",
|
|
2976
|
+
id: toTreasuryId(`try_${orgId}`),
|
|
2977
|
+
organizationId,
|
|
2978
|
+
status: "active",
|
|
2979
|
+
safeId: toSafeId(
|
|
2980
|
+
`safe_${raw.safeAddress.replace(/^0x/, "").toLowerCase()}`
|
|
2981
|
+
),
|
|
2982
|
+
totalBalance: { value: "0", currency: "USD" },
|
|
2983
|
+
positions: raw.tokens.map((t) => ({
|
|
2984
|
+
symbol: t.symbol,
|
|
2985
|
+
contractAddress: t.tokenAddress,
|
|
2986
|
+
amount: t.balance
|
|
2987
|
+
})),
|
|
2988
|
+
asOf: raw.lastUpdatedAt ? new Date(raw.lastUpdatedAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
2989
|
+
};
|
|
2990
|
+
return [null, treasury];
|
|
2991
|
+
} catch (cause) {
|
|
2992
|
+
return [
|
|
2993
|
+
fromConvexError(cause),
|
|
2994
|
+
null
|
|
2995
|
+
];
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2273
2998
|
},
|
|
2274
2999
|
members: {
|
|
2275
|
-
list: async () =>
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
3000
|
+
list: async (input) => {
|
|
3001
|
+
if (!config._data?.action) {
|
|
3002
|
+
return stub("organizations.members.list");
|
|
3003
|
+
}
|
|
3004
|
+
try {
|
|
3005
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3006
|
+
const page = await config._data.action(api.org.actions.membersList, {
|
|
3007
|
+
organizationId: orgId,
|
|
3008
|
+
status: input.status,
|
|
3009
|
+
limit: input.limit,
|
|
3010
|
+
cursor: input.cursor
|
|
3011
|
+
});
|
|
3012
|
+
return [null, page];
|
|
3013
|
+
} catch (cause) {
|
|
3014
|
+
return [fromConvexError(cause), null];
|
|
3015
|
+
}
|
|
3016
|
+
},
|
|
3017
|
+
retrieve: async (input) => {
|
|
3018
|
+
if (!config._data?.action) {
|
|
3019
|
+
return stub("organizations.members.retrieve");
|
|
3020
|
+
}
|
|
3021
|
+
try {
|
|
3022
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3023
|
+
const memberId = input.memberId.replace(/^mb_/, "");
|
|
3024
|
+
const member = await config._data.action(
|
|
3025
|
+
api.org.actions.retrieveMember,
|
|
3026
|
+
{
|
|
3027
|
+
organizationId: orgId,
|
|
3028
|
+
memberId
|
|
3029
|
+
}
|
|
3030
|
+
);
|
|
3031
|
+
return [null, member];
|
|
3032
|
+
} catch (cause) {
|
|
3033
|
+
return [fromConvexError(cause), null];
|
|
3034
|
+
}
|
|
3035
|
+
},
|
|
3036
|
+
invite: async (input) => {
|
|
3037
|
+
if (!config._data?.action) {
|
|
3038
|
+
return stub("organizations.members.invite");
|
|
3039
|
+
}
|
|
3040
|
+
try {
|
|
3041
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3042
|
+
const result = await config._data.action(
|
|
3043
|
+
api.org.actions.inviteMember,
|
|
3044
|
+
{
|
|
3045
|
+
organizationId: orgId,
|
|
3046
|
+
email: input.email,
|
|
3047
|
+
role: input.role
|
|
3048
|
+
}
|
|
3049
|
+
);
|
|
3050
|
+
return [null, result];
|
|
3051
|
+
} catch (cause) {
|
|
3052
|
+
return [fromConvexError(cause), null];
|
|
3053
|
+
}
|
|
3054
|
+
},
|
|
3055
|
+
accept: async (input) => {
|
|
3056
|
+
if (!config._data?.action) {
|
|
3057
|
+
return stub("organizations.members.accept");
|
|
3058
|
+
}
|
|
3059
|
+
try {
|
|
3060
|
+
const member = await config._data.action(
|
|
3061
|
+
api.org.actions.acceptInvitation,
|
|
3062
|
+
{ token: input.token }
|
|
3063
|
+
);
|
|
3064
|
+
return [null, member];
|
|
3065
|
+
} catch (cause) {
|
|
3066
|
+
return [fromConvexError(cause), null];
|
|
3067
|
+
}
|
|
3068
|
+
},
|
|
3069
|
+
updateRole: async (input) => {
|
|
3070
|
+
if (!config._data?.action) {
|
|
3071
|
+
return stub("organizations.members.updateRole");
|
|
3072
|
+
}
|
|
3073
|
+
try {
|
|
3074
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3075
|
+
const memberId = input.memberId.replace(/^mb_/, "");
|
|
3076
|
+
const member = await config._data.action(
|
|
3077
|
+
api.org.actions.updateMemberRole,
|
|
3078
|
+
{
|
|
3079
|
+
organizationId: orgId,
|
|
3080
|
+
memberId,
|
|
3081
|
+
role: input.role
|
|
3082
|
+
}
|
|
3083
|
+
);
|
|
3084
|
+
return [null, member];
|
|
3085
|
+
} catch (cause) {
|
|
3086
|
+
return [fromConvexError(cause), null];
|
|
3087
|
+
}
|
|
3088
|
+
},
|
|
3089
|
+
revoke: async (input) => {
|
|
3090
|
+
if (!config._data?.action) {
|
|
3091
|
+
return stub("organizations.members.revoke");
|
|
3092
|
+
}
|
|
3093
|
+
try {
|
|
3094
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3095
|
+
const memberId = input.memberId.replace(/^mb_/, "");
|
|
3096
|
+
const member = await config._data.action(
|
|
3097
|
+
api.org.actions.revokeMember,
|
|
3098
|
+
{
|
|
3099
|
+
organizationId: orgId,
|
|
3100
|
+
memberId
|
|
3101
|
+
}
|
|
3102
|
+
);
|
|
3103
|
+
return [null, member];
|
|
3104
|
+
} catch (cause) {
|
|
3105
|
+
return [fromConvexError(cause), null];
|
|
3106
|
+
}
|
|
3107
|
+
},
|
|
3108
|
+
remove: async (input) => {
|
|
3109
|
+
if (!config._data?.action) {
|
|
3110
|
+
return stub("organizations.members.remove");
|
|
3111
|
+
}
|
|
3112
|
+
try {
|
|
3113
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3114
|
+
const memberId = input.memberId.replace(/^mb_/, "");
|
|
3115
|
+
await config._data.action(api.org.actions.removeMember, {
|
|
3116
|
+
organizationId: orgId,
|
|
3117
|
+
memberId
|
|
3118
|
+
});
|
|
3119
|
+
return [null, void 0];
|
|
3120
|
+
} catch (cause) {
|
|
3121
|
+
return [fromConvexError(cause), null];
|
|
3122
|
+
}
|
|
3123
|
+
},
|
|
3124
|
+
resend: async (input) => {
|
|
3125
|
+
if (!config._data?.action) {
|
|
3126
|
+
return stub("organizations.members.resend");
|
|
3127
|
+
}
|
|
3128
|
+
try {
|
|
3129
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3130
|
+
const memberId = input.memberId.replace(/^mb_/, "");
|
|
3131
|
+
const result = await config._data.action(
|
|
3132
|
+
api.org.actions.resendInvitation,
|
|
3133
|
+
{
|
|
3134
|
+
organizationId: orgId,
|
|
3135
|
+
memberId
|
|
3136
|
+
}
|
|
3137
|
+
);
|
|
3138
|
+
return [null, result];
|
|
3139
|
+
} catch (cause) {
|
|
3140
|
+
return [fromConvexError(cause), null];
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
2280
3143
|
},
|
|
2281
3144
|
apiKeys: createApiKeysClient(),
|
|
2282
|
-
|
|
2283
|
-
start: async () => stub("organizations.kybProfile.start"),
|
|
2284
|
-
retrieve: async () => stub("organizations.kybProfile.retrieve")
|
|
2285
|
-
},
|
|
2286
|
-
subAccounts: {
|
|
2287
|
-
create: async () => stub("organizations.subAccounts.create"),
|
|
2288
|
-
list: async () => stub("organizations.subAccounts.list"),
|
|
2289
|
-
retrieve: async () => stub("organizations.subAccounts.retrieve"),
|
|
2290
|
-
remove: async () => stub("organizations.subAccounts.remove")
|
|
2291
|
-
},
|
|
3145
|
+
subAccounts: createOrgSubAccountsClient(config),
|
|
2292
3146
|
externalAccounts: createOrgExternalAccountsClient(config),
|
|
2293
3147
|
balanceLedger: {
|
|
2294
|
-
list: async () =>
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
3148
|
+
list: async (input) => {
|
|
3149
|
+
if (!config._data) {
|
|
3150
|
+
return stub(
|
|
3151
|
+
"organizations.balanceLedger.list"
|
|
3152
|
+
);
|
|
3153
|
+
}
|
|
3154
|
+
try {
|
|
3155
|
+
const orgId = input.organizationId.replace(/^org_/, "");
|
|
3156
|
+
const page = await config._data.query(
|
|
3157
|
+
api.balanceLedger.queries.listForOrg,
|
|
3158
|
+
{ orgId, limit: input.limit, cursor: input.cursor }
|
|
3159
|
+
);
|
|
3160
|
+
return [null, page];
|
|
3161
|
+
} catch (cause) {
|
|
3162
|
+
return [fromConvexError(cause), null];
|
|
3163
|
+
}
|
|
3164
|
+
},
|
|
3165
|
+
retrieve: async (input) => {
|
|
3166
|
+
if (!config._data) {
|
|
3167
|
+
return stub(
|
|
3168
|
+
"organizations.balanceLedger.retrieve"
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
try {
|
|
3172
|
+
const entry = await config._data.query(
|
|
3173
|
+
api.balanceLedger.queries.retrieve,
|
|
3174
|
+
{ entryId: input.entryId }
|
|
3175
|
+
);
|
|
3176
|
+
if (!entry) {
|
|
3177
|
+
return [
|
|
3178
|
+
new CapxulError({
|
|
3179
|
+
code: "NOT_FOUND",
|
|
3180
|
+
message: `balance_ledger_entry ${input.entryId} not found`
|
|
3181
|
+
}),
|
|
3182
|
+
null
|
|
3183
|
+
];
|
|
3184
|
+
}
|
|
3185
|
+
return [null, entry];
|
|
3186
|
+
} catch (cause) {
|
|
3187
|
+
return [fromConvexError(cause), null];
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
2300
3190
|
},
|
|
2301
3191
|
payments: createOrgPaymentsClient(),
|
|
2302
3192
|
transfers: createOrgTransfersClient(),
|
|
@@ -2307,14 +3197,6 @@ function createOrganizationsClient(config = {}) {
|
|
|
2307
3197
|
};
|
|
2308
3198
|
}
|
|
2309
3199
|
|
|
2310
|
-
// src/core/sub-accounts.ts
|
|
2311
|
-
function createSubAccountsClient() {
|
|
2312
|
-
return {
|
|
2313
|
-
retrieve: async () => stub("subAccounts.retrieve"),
|
|
2314
|
-
remove: async () => stub("subAccounts.remove")
|
|
2315
|
-
};
|
|
2316
|
-
}
|
|
2317
|
-
|
|
2318
3200
|
// src/core/token-transfers.ts
|
|
2319
3201
|
var toTokenTransferId = (raw) => {
|
|
2320
3202
|
if (typeof raw !== "string" || raw.length === 0) {
|
|
@@ -2333,11 +3215,11 @@ function brandRow(row) {
|
|
|
2333
3215
|
function createTokenTransfersClient(config = {}) {
|
|
2334
3216
|
return {
|
|
2335
3217
|
list: async (input) => {
|
|
2336
|
-
if (!config.
|
|
3218
|
+
if (!config._data) {
|
|
2337
3219
|
return stub("tokenTransfers.list");
|
|
2338
3220
|
}
|
|
2339
3221
|
try {
|
|
2340
|
-
const raw = await config.
|
|
3222
|
+
const raw = await config._data.query(
|
|
2341
3223
|
api.tokenTransfers.queries.list,
|
|
2342
3224
|
{
|
|
2343
3225
|
limit: input?.limit,
|
|
@@ -2371,11 +3253,11 @@ function createTokenTransfersClient(config = {}) {
|
|
|
2371
3253
|
}
|
|
2372
3254
|
},
|
|
2373
3255
|
retrieve: async (input) => {
|
|
2374
|
-
if (!config.
|
|
3256
|
+
if (!config._data) {
|
|
2375
3257
|
return stub("tokenTransfers.retrieve");
|
|
2376
3258
|
}
|
|
2377
3259
|
try {
|
|
2378
|
-
const raw = await config.
|
|
3260
|
+
const raw = await config._data.query(
|
|
2379
3261
|
api.tokenTransfers.queries.getByTxLogIndex,
|
|
2380
3262
|
{
|
|
2381
3263
|
txHash: input.txHash,
|
|
@@ -2712,7 +3594,6 @@ var initialContext = {
|
|
|
2712
3594
|
email: null,
|
|
2713
3595
|
code: null,
|
|
2714
3596
|
username: null,
|
|
2715
|
-
signerProvider: null,
|
|
2716
3597
|
bootstrapToken: null,
|
|
2717
3598
|
bootstrapReason: null,
|
|
2718
3599
|
session: null,
|
|
@@ -2910,12 +3791,6 @@ function createAuthBootstrapFlowMachine(client) {
|
|
|
2910
3791
|
error: () => null
|
|
2911
3792
|
})
|
|
2912
3793
|
},
|
|
2913
|
-
ENTER_SIGNER_PROVIDER: {
|
|
2914
|
-
actions: assign({
|
|
2915
|
-
signerProvider: ({ event }) => event.signerProvider,
|
|
2916
|
-
error: () => null
|
|
2917
|
-
})
|
|
2918
|
-
},
|
|
2919
3794
|
COMPLETE_BOOTSTRAP: { target: "completing_bootstrap" },
|
|
2920
3795
|
BACK: { target: "otp_requested" },
|
|
2921
3796
|
RESET: { target: "email", actions: assign(() => initialContext) }
|
|
@@ -2926,8 +3801,7 @@ function createAuthBootstrapFlowMachine(client) {
|
|
|
2926
3801
|
src: "completeBootstrap",
|
|
2927
3802
|
input: ({ context }) => ({
|
|
2928
3803
|
bootstrapToken: requireBootstrapToken(context),
|
|
2929
|
-
username: requireUsername(context)
|
|
2930
|
-
signerProvider: requireSignerProvider(context)
|
|
3804
|
+
username: requireUsername(context)
|
|
2931
3805
|
}),
|
|
2932
3806
|
onDone: {
|
|
2933
3807
|
target: "authenticated",
|
|
@@ -2939,7 +3813,6 @@ function createAuthBootstrapFlowMachine(client) {
|
|
|
2939
3813
|
safe: ({ event }) => event.output.safe,
|
|
2940
3814
|
bootstrapToken: () => null,
|
|
2941
3815
|
bootstrapReason: () => null,
|
|
2942
|
-
signerProvider: () => null,
|
|
2943
3816
|
email: () => null,
|
|
2944
3817
|
error: () => null
|
|
2945
3818
|
}),
|
|
@@ -3020,15 +3893,6 @@ function requireUsername(context) {
|
|
|
3020
3893
|
}
|
|
3021
3894
|
return context.username;
|
|
3022
3895
|
}
|
|
3023
|
-
function requireSignerProvider(context) {
|
|
3024
|
-
if (!context.signerProvider) {
|
|
3025
|
-
throw Errors.invalidInput(
|
|
3026
|
-
"signerProvider",
|
|
3027
|
-
"Auth bootstrap requires a signer provider."
|
|
3028
|
-
);
|
|
3029
|
-
}
|
|
3030
|
-
return context.signerProvider;
|
|
3031
|
-
}
|
|
3032
3896
|
function errorFromEvent2(event) {
|
|
3033
3897
|
const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
|
|
3034
3898
|
if (cause instanceof CapxulError || cause instanceof CapxulError2) {
|
|
@@ -3074,7 +3938,7 @@ function createProvisioningMachine(client) {
|
|
|
3074
3938
|
const provider = context.input?.signerProvider;
|
|
3075
3939
|
if (!provider) return;
|
|
3076
3940
|
track("provisioning_safe_created", {
|
|
3077
|
-
safe_address: provider.
|
|
3941
|
+
safe_address: deriveSafeAddress(provider.signerAddress)
|
|
3078
3942
|
});
|
|
3079
3943
|
}
|
|
3080
3944
|
}
|
|
@@ -3436,7 +4300,7 @@ function createCapxulClient(config = {}) {
|
|
|
3436
4300
|
tokenTransfers: createTokenTransfersClient(config),
|
|
3437
4301
|
withdrawals: createWithdrawalsClient(config),
|
|
3438
4302
|
documents: createDocumentsClient(),
|
|
3439
|
-
subAccounts: createSubAccountsClient(),
|
|
4303
|
+
subAccounts: createSubAccountsClient(config),
|
|
3440
4304
|
virtualAccounts: createVirtualAccountsClient(),
|
|
3441
4305
|
virtualCards: createVirtualCardsClient(),
|
|
3442
4306
|
externalAccounts: createExternalAccountsClient(config),
|