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