@capxul/sdk 0.1.0-alpha.4 → 0.1.0-alpha.6
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 +28 -0
- package/README.md +1 -1
- package/dist/{client-CcCtq5XO.d.ts → client-ChfXWMzO.d.ts} +66 -26
- package/dist/{client-CXRKtbfn.d.cts → client-DW_fW9DC.d.cts} +66 -26
- package/dist/client.cjs +678 -276
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +678 -276
- package/dist/index.cjs +781 -389
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +781 -389
- package/dist/{types-75UokagF.d.ts → types-CYvLP5pP.d.ts} +13 -2
- package/dist/{types-DVWojoy4.d.cts → types-X02RbQ2u.d.cts} +13 -2
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/package.json +2 -2
package/dist/client.cjs
CHANGED
|
@@ -69,7 +69,268 @@ function fromConvexError(error) {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// ../observability/src/try-catch.ts
|
|
73
|
+
async function tryCatch(promise) {
|
|
74
|
+
try {
|
|
75
|
+
return [null, await promise];
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return [e instanceof Error ? e : new Error(String(e)), null];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ../observability/src/debug-log.ts
|
|
82
|
+
function isDevelopmentBuild() {
|
|
83
|
+
if (typeof process === "undefined") {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return process.env?.NODE_ENV === "development" || process.env?.NODE_ENV === "test";
|
|
87
|
+
}
|
|
88
|
+
function debugLog(line) {
|
|
89
|
+
if (!isDevelopmentBuild()) return;
|
|
90
|
+
if (typeof globalThis !== "undefined" && "window" in globalThis && typeof console?.info === "function") {
|
|
91
|
+
console.info(line);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof process !== "undefined" && typeof process.stderr?.write === "function") {
|
|
95
|
+
process.stderr.write(`${line}
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function formatDebugValue(value) {
|
|
100
|
+
if (value === void 0 || value === "") return "";
|
|
101
|
+
if (typeof value === "string") return value;
|
|
102
|
+
try {
|
|
103
|
+
return JSON.stringify(value);
|
|
104
|
+
} catch {
|
|
105
|
+
return String(value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function track(...args) {
|
|
109
|
+
const [name, props] = args;
|
|
110
|
+
debugLog(`[TRACK] ${name} ${formatDebugValue(props ?? "")}`);
|
|
111
|
+
}
|
|
112
|
+
function formatDebugValue2(value) {
|
|
113
|
+
if (value === void 0 || value === "") return "";
|
|
114
|
+
if (typeof value === "string") return value;
|
|
115
|
+
try {
|
|
116
|
+
return JSON.stringify(value);
|
|
117
|
+
} catch {
|
|
118
|
+
return String(value);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function identify(userId, traits) {
|
|
122
|
+
debugLog(`[IDENTIFY] ${userId} ${formatDebugValue2(traits ?? "")}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ../platform-kernel/src/ids.ts
|
|
126
|
+
function makePrefixedIdConstructor(prefix, fieldName) {
|
|
127
|
+
const re = new RegExp(`^${prefix}_[A-Za-z0-9_\\-]+$`);
|
|
128
|
+
return (raw) => {
|
|
129
|
+
if (typeof raw !== "string" || !re.test(raw)) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Invalid ${fieldName}: expected string matching ^${prefix}_[A-Za-z0-9_\\-]+$, got ${String(raw)}`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return raw;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
var toOperationId = makePrefixedIdConstructor(
|
|
138
|
+
"op",
|
|
139
|
+
"operationId"
|
|
140
|
+
);
|
|
141
|
+
var toCorrelationId = makePrefixedIdConstructor("ctx", "correlationId");
|
|
142
|
+
var toExternalAccountId = makePrefixedIdConstructor("ext", "externalAccountId");
|
|
143
|
+
|
|
144
|
+
// src/core/external-accounts.ts
|
|
145
|
+
function brandExternalAccount(raw) {
|
|
146
|
+
return {
|
|
147
|
+
...raw,
|
|
148
|
+
id: toExternalAccountId(raw.id),
|
|
149
|
+
operation: {
|
|
150
|
+
id: toOperationId(raw.operation.id),
|
|
151
|
+
status: raw.operation.status,
|
|
152
|
+
correlationId: toCorrelationId(raw.operation.correlationId)
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function createExternalAccountsClient(config = {}) {
|
|
157
|
+
return {
|
|
158
|
+
retrieve: async (externalAccountId) => {
|
|
159
|
+
if (!config.data) {
|
|
160
|
+
return stub(
|
|
161
|
+
"externalAccounts.retrieve"
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const [err, raw] = await tryCatch(
|
|
165
|
+
config.data.query(api.externalAccounts.queries.retrievePersonal, {
|
|
166
|
+
externalAccountId
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
if (err) {
|
|
170
|
+
return [
|
|
171
|
+
fromConvexError(err),
|
|
172
|
+
null
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
if (!raw) {
|
|
176
|
+
return [
|
|
177
|
+
new CapxulError({
|
|
178
|
+
code: "NOT_FOUND",
|
|
179
|
+
message: `external_account ${externalAccountId} not found`
|
|
180
|
+
}),
|
|
181
|
+
null
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
return [null, brandExternalAccount(raw)];
|
|
185
|
+
},
|
|
186
|
+
remove: async (externalAccountId) => {
|
|
187
|
+
if (!config.data) {
|
|
188
|
+
return stub("externalAccounts.remove");
|
|
189
|
+
}
|
|
190
|
+
const [err] = await tryCatch(
|
|
191
|
+
config.data.mutation(api.externalAccounts.mutations.removePersonal, {
|
|
192
|
+
externalAccountId
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
if (err) {
|
|
196
|
+
return [
|
|
197
|
+
fromConvexError(err),
|
|
198
|
+
null
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
return [null, void 0];
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
72
206
|
// src/core/accounts.ts
|
|
207
|
+
function createAccountExternalAccountsClient(config) {
|
|
208
|
+
return {
|
|
209
|
+
create: async (input) => {
|
|
210
|
+
if (!config.data) {
|
|
211
|
+
return stub(
|
|
212
|
+
"accounts.externalAccounts.create"
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
const [err, raw] = await tryCatch(
|
|
216
|
+
config.data.mutation(
|
|
217
|
+
api.externalAccounts.mutations.createPersonal,
|
|
218
|
+
{
|
|
219
|
+
kind: input.kind,
|
|
220
|
+
label: input.label,
|
|
221
|
+
address: input.address,
|
|
222
|
+
iban: input.iban,
|
|
223
|
+
bic: input.bic,
|
|
224
|
+
accountHolder: input.accountHolder,
|
|
225
|
+
network: input.network,
|
|
226
|
+
panToken: input.panToken,
|
|
227
|
+
last4: input.last4
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
if (err) {
|
|
232
|
+
return [
|
|
233
|
+
fromConvexError(err),
|
|
234
|
+
null
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
if (!raw) {
|
|
238
|
+
return [
|
|
239
|
+
new CapxulError({
|
|
240
|
+
code: "NOT_FOUND",
|
|
241
|
+
message: "external_account creation returned no resource"
|
|
242
|
+
}),
|
|
243
|
+
null
|
|
244
|
+
];
|
|
245
|
+
}
|
|
246
|
+
return [
|
|
247
|
+
null,
|
|
248
|
+
brandExternalAccount(
|
|
249
|
+
raw
|
|
250
|
+
)
|
|
251
|
+
];
|
|
252
|
+
},
|
|
253
|
+
list: async (input) => {
|
|
254
|
+
if (!config.data) {
|
|
255
|
+
return stub(
|
|
256
|
+
"accounts.externalAccounts.list"
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
const [err, result] = await tryCatch(
|
|
260
|
+
config.data.query(api.externalAccounts.queries.listPersonal, {
|
|
261
|
+
limit: input.limit,
|
|
262
|
+
cursor: input.cursor
|
|
263
|
+
})
|
|
264
|
+
);
|
|
265
|
+
if (err) {
|
|
266
|
+
return [fromConvexError(err), null];
|
|
267
|
+
}
|
|
268
|
+
const branded = result.data.map(
|
|
269
|
+
(row) => brandExternalAccount(
|
|
270
|
+
row
|
|
271
|
+
)
|
|
272
|
+
);
|
|
273
|
+
return [
|
|
274
|
+
null,
|
|
275
|
+
{
|
|
276
|
+
object: "list",
|
|
277
|
+
data: branded,
|
|
278
|
+
page: result.page
|
|
279
|
+
}
|
|
280
|
+
];
|
|
281
|
+
},
|
|
282
|
+
retrieve: async (externalAccountId) => {
|
|
283
|
+
if (!config.data) {
|
|
284
|
+
return stub(
|
|
285
|
+
"accounts.externalAccounts.retrieve"
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
const [err, raw] = await tryCatch(
|
|
289
|
+
config.data.query(api.externalAccounts.queries.retrievePersonal, {
|
|
290
|
+
externalAccountId
|
|
291
|
+
})
|
|
292
|
+
);
|
|
293
|
+
if (err) {
|
|
294
|
+
return [
|
|
295
|
+
fromConvexError(err),
|
|
296
|
+
null
|
|
297
|
+
];
|
|
298
|
+
}
|
|
299
|
+
if (!raw) {
|
|
300
|
+
return [
|
|
301
|
+
new CapxulError({
|
|
302
|
+
code: "NOT_FOUND",
|
|
303
|
+
message: `external_account ${externalAccountId} not found`
|
|
304
|
+
}),
|
|
305
|
+
null
|
|
306
|
+
];
|
|
307
|
+
}
|
|
308
|
+
return [
|
|
309
|
+
null,
|
|
310
|
+
brandExternalAccount(
|
|
311
|
+
raw
|
|
312
|
+
)
|
|
313
|
+
];
|
|
314
|
+
},
|
|
315
|
+
remove: async (externalAccountId) => {
|
|
316
|
+
if (!config.data) {
|
|
317
|
+
return stub("accounts.externalAccounts.remove");
|
|
318
|
+
}
|
|
319
|
+
const [err] = await tryCatch(
|
|
320
|
+
config.data.mutation(api.externalAccounts.mutations.removePersonal, {
|
|
321
|
+
externalAccountId
|
|
322
|
+
})
|
|
323
|
+
);
|
|
324
|
+
if (err) {
|
|
325
|
+
return [
|
|
326
|
+
fromConvexError(err),
|
|
327
|
+
null
|
|
328
|
+
];
|
|
329
|
+
}
|
|
330
|
+
return [null, void 0];
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
73
334
|
function createAccountsClient(config = {}) {
|
|
74
335
|
return {
|
|
75
336
|
retrieve: async (accountId) => {
|
|
@@ -224,18 +485,7 @@ function createAccountsClient(config = {}) {
|
|
|
224
485
|
create: async () => stub("accounts.kycProfiles.create"),
|
|
225
486
|
retrieve: async () => stub("accounts.kycProfiles.retrieve")
|
|
226
487
|
},
|
|
227
|
-
externalAccounts:
|
|
228
|
-
create: async () => stub(
|
|
229
|
-
"accounts.externalAccounts.create"
|
|
230
|
-
),
|
|
231
|
-
list: async () => stub(
|
|
232
|
-
"accounts.externalAccounts.list"
|
|
233
|
-
),
|
|
234
|
-
retrieve: async () => stub(
|
|
235
|
-
"accounts.externalAccounts.retrieve"
|
|
236
|
-
),
|
|
237
|
-
remove: async () => stub("accounts.externalAccounts.remove")
|
|
238
|
-
},
|
|
488
|
+
externalAccounts: createAccountExternalAccountsClient(config),
|
|
239
489
|
subAccounts: {
|
|
240
490
|
create: async () => stub("accounts.subAccounts.create"),
|
|
241
491
|
list: async () => stub("accounts.subAccounts.list"),
|
|
@@ -330,7 +580,29 @@ var Errors = {
|
|
|
330
580
|
{ details }
|
|
331
581
|
),
|
|
332
582
|
emailDeliveryFailed: (detail) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`),
|
|
333
|
-
internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`)
|
|
583
|
+
internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
584
|
+
/**
|
|
585
|
+
* Verification gate. Surfaced when a request hits a verification
|
|
586
|
+
* boundary the actor cannot cross under their current state. Two
|
|
587
|
+
* variants share this code:
|
|
588
|
+
*
|
|
589
|
+
* - Rail gate (Withdrawals v1 W2, #465): the resolved
|
|
590
|
+
* `external_account.kind` routes to a withdrawal rail (e.g.
|
|
591
|
+
* `fiat_offramp`, `card_payout`) that is not yet supported. Carries
|
|
592
|
+
* `details.rail` + `details.currentKind`.
|
|
593
|
+
* - KYC tier gate (legacy / future): the actor's KYC tier is below
|
|
594
|
+
* the required tier. Carries `details.requiredTier`.
|
|
595
|
+
*
|
|
596
|
+
* Code is shared because both expose the same UX shape ("you cannot
|
|
597
|
+
* proceed until verification advances"); the `details.*` keys
|
|
598
|
+
* differentiate the route.
|
|
599
|
+
*/
|
|
600
|
+
verificationRequired: (details) => {
|
|
601
|
+
const message = "rail" in details ? `Withdrawal rail "${details.rail}" (kind=${details.currentKind}) is not yet supported.` : `Verification tier ${details.requiredTier} is required.`;
|
|
602
|
+
return new CapxulError2("VERIFICATION_REQUIRED", message, {
|
|
603
|
+
details: { ...details }
|
|
604
|
+
});
|
|
605
|
+
}
|
|
334
606
|
};
|
|
335
607
|
|
|
336
608
|
// ../config/src/safe.ts
|
|
@@ -742,14 +1014,6 @@ function createOrgDocumentsClient() {
|
|
|
742
1014
|
};
|
|
743
1015
|
}
|
|
744
1016
|
|
|
745
|
-
// src/core/external-accounts.ts
|
|
746
|
-
function createExternalAccountsClient() {
|
|
747
|
-
return {
|
|
748
|
-
retrieve: async () => stub("externalAccounts.retrieve"),
|
|
749
|
-
remove: async () => stub("externalAccounts.remove")
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
|
|
753
1017
|
// src/core/me.ts
|
|
754
1018
|
function createMeClient(config = {}) {
|
|
755
1019
|
return {
|
|
@@ -1197,67 +1461,68 @@ function createOrgTransfersClient() {
|
|
|
1197
1461
|
cancel: async () => stub("organizations.transfers.cancel")
|
|
1198
1462
|
};
|
|
1199
1463
|
}
|
|
1200
|
-
var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
1201
1464
|
function createWithdrawalsClient(config = {}) {
|
|
1202
1465
|
return {
|
|
1203
1466
|
create: async (input) => {
|
|
1204
1467
|
if (!config.data) {
|
|
1205
1468
|
return stub("withdrawals.create");
|
|
1206
1469
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
details: { field: "destination.externalAccountId" }
|
|
1246
|
-
});
|
|
1247
|
-
}
|
|
1248
|
-
const currentSigner = await config.data.query(
|
|
1249
|
-
api.safe.queries.getMySignerAddress,
|
|
1250
|
-
{}
|
|
1470
|
+
const [createErr, createdRaw] = await tryCatch(
|
|
1471
|
+
config.data.mutation(api.withdrawals.mutations.create, {
|
|
1472
|
+
amount: input.amount,
|
|
1473
|
+
destination: {
|
|
1474
|
+
externalAccountId: input.destination.externalAccountId
|
|
1475
|
+
},
|
|
1476
|
+
source: input.source,
|
|
1477
|
+
reference: input.reference,
|
|
1478
|
+
idempotencyKey: input.idempotencyKey
|
|
1479
|
+
})
|
|
1480
|
+
);
|
|
1481
|
+
if (createErr) {
|
|
1482
|
+
return [mapCreateError2(fromConvexError(createErr)), null];
|
|
1483
|
+
}
|
|
1484
|
+
const created = createdRaw;
|
|
1485
|
+
if (!created) {
|
|
1486
|
+
return [
|
|
1487
|
+
new CapxulError({
|
|
1488
|
+
code: "NETWORK_ERROR",
|
|
1489
|
+
message: "withdrawals.create returned no withdrawal resource"
|
|
1490
|
+
}),
|
|
1491
|
+
null
|
|
1492
|
+
];
|
|
1493
|
+
}
|
|
1494
|
+
if (created.status !== "processing" || created.operation.status !== "processing") {
|
|
1495
|
+
return [null, created];
|
|
1496
|
+
}
|
|
1497
|
+
if (!config.signer || !config.signing) {
|
|
1498
|
+
return [null, created];
|
|
1499
|
+
}
|
|
1500
|
+
const [signerErr, currentSigner] = await tryCatch(
|
|
1501
|
+
config.data.query(api.safe.queries.getMySignerAddress, {})
|
|
1502
|
+
);
|
|
1503
|
+
if (signerErr) {
|
|
1504
|
+
return await handleSubmissionFailure(
|
|
1505
|
+
{ data: config.data },
|
|
1506
|
+
created.id,
|
|
1507
|
+
mapCreateError2(fromConvexError(signerErr))
|
|
1251
1508
|
);
|
|
1252
|
-
|
|
1253
|
-
|
|
1509
|
+
}
|
|
1510
|
+
if (!currentSigner?.address) {
|
|
1511
|
+
return await handleSubmissionFailure(
|
|
1512
|
+
{ data: config.data },
|
|
1513
|
+
created.id,
|
|
1514
|
+
new CapxulError({
|
|
1254
1515
|
code: "PERMISSION_DENIED",
|
|
1255
1516
|
message: "No signer is registered for the authenticated account.",
|
|
1256
1517
|
details: { withdrawalId: created.id }
|
|
1257
|
-
})
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1518
|
+
})
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
if (viem.getAddress(currentSigner.address) !== viem.getAddress(config.signer.address)) {
|
|
1522
|
+
return await handleSubmissionFailure(
|
|
1523
|
+
{ data: config.data },
|
|
1524
|
+
created.id,
|
|
1525
|
+
new CapxulError({
|
|
1261
1526
|
code: "PERMISSION_DENIED",
|
|
1262
1527
|
message: "Configured signer does not match the authenticated account signer.",
|
|
1263
1528
|
details: {
|
|
@@ -1265,170 +1530,228 @@ function createWithdrawalsClient(config = {}) {
|
|
|
1265
1530
|
expectedSignerAddress: currentSigner.address,
|
|
1266
1531
|
actualSignerAddress: config.signer.address
|
|
1267
1532
|
}
|
|
1268
|
-
})
|
|
1269
|
-
}
|
|
1270
|
-
const submission = await config.data.query(
|
|
1271
|
-
api.withdrawals.queries.prepareSubmission,
|
|
1272
|
-
{ withdrawalId: created.id }
|
|
1533
|
+
})
|
|
1273
1534
|
);
|
|
1274
|
-
|
|
1275
|
-
|
|
1535
|
+
}
|
|
1536
|
+
const [prepErr, submission] = await tryCatch(
|
|
1537
|
+
config.data.query(api.withdrawals.queries.prepareSubmission, {
|
|
1538
|
+
withdrawalId: created.id
|
|
1539
|
+
})
|
|
1540
|
+
);
|
|
1541
|
+
if (prepErr) {
|
|
1542
|
+
return await handleSubmissionFailure(
|
|
1543
|
+
{ data: config.data },
|
|
1544
|
+
created.id,
|
|
1545
|
+
mapCreateError2(fromConvexError(prepErr))
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1548
|
+
const destinationAddress = submission?.destinationAddress;
|
|
1549
|
+
if (!submission || !destinationAddress) {
|
|
1550
|
+
return await handleSubmissionFailure(
|
|
1551
|
+
{ data: config.data },
|
|
1552
|
+
created.id,
|
|
1553
|
+
new CapxulError({
|
|
1276
1554
|
code: "NETWORK_ERROR",
|
|
1277
1555
|
message: "withdrawals.prepareSubmission returned no destination.",
|
|
1278
1556
|
details: { withdrawalId: created.id }
|
|
1279
|
-
})
|
|
1280
|
-
|
|
1281
|
-
|
|
1557
|
+
})
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
const [transferErr, transferOk] = await tryCatch(
|
|
1561
|
+
transferAsOwner(
|
|
1282
1562
|
{
|
|
1283
1563
|
signer: config.signer,
|
|
1284
1564
|
signing: config.signing
|
|
1285
1565
|
},
|
|
1286
1566
|
{
|
|
1287
1567
|
tokenAddress: resolvePaymentTokenAddress(submission.amount.currency),
|
|
1288
|
-
recipientAddress:
|
|
1568
|
+
recipientAddress: destinationAddress,
|
|
1289
1569
|
amount: toTokenUnits(submission.amount.value, 6)
|
|
1290
1570
|
}
|
|
1571
|
+
)
|
|
1572
|
+
);
|
|
1573
|
+
if (transferErr) {
|
|
1574
|
+
return await handleSubmissionFailure(
|
|
1575
|
+
{ data: config.data },
|
|
1576
|
+
created.id,
|
|
1577
|
+
mapCreateError2(fromConvexError(transferErr))
|
|
1291
1578
|
);
|
|
1292
|
-
|
|
1293
|
-
|
|
1579
|
+
}
|
|
1580
|
+
if (!transferOk.success) {
|
|
1581
|
+
return await handleSubmissionFailure(
|
|
1582
|
+
{ data: config.data },
|
|
1583
|
+
created.id,
|
|
1584
|
+
new CapxulError({
|
|
1294
1585
|
code: "NETWORK_ERROR",
|
|
1295
1586
|
message: "Bundler submission did not succeed.",
|
|
1296
1587
|
details: {
|
|
1297
1588
|
withdrawalId: created.id,
|
|
1298
|
-
txHash:
|
|
1299
|
-
userOpHash:
|
|
1589
|
+
txHash: transferOk.txHash,
|
|
1590
|
+
userOpHash: transferOk.userOpHash
|
|
1300
1591
|
}
|
|
1301
|
-
})
|
|
1302
|
-
}
|
|
1303
|
-
submitted = {
|
|
1304
|
-
txHash: transfer.txHash,
|
|
1305
|
-
userOpHash: transfer.userOpHash
|
|
1306
|
-
};
|
|
1307
|
-
await config.data.mutation(
|
|
1308
|
-
api.withdrawals.mutations.recordSubmitted,
|
|
1309
|
-
{
|
|
1310
|
-
withdrawalId: created.id,
|
|
1311
|
-
txHash: transfer.txHash,
|
|
1312
|
-
userOpHash: transfer.userOpHash
|
|
1313
|
-
}
|
|
1592
|
+
})
|
|
1314
1593
|
);
|
|
1315
|
-
return [null, created];
|
|
1316
|
-
} catch (cause) {
|
|
1317
|
-
const error = mapCreateError2(fromConvexError(cause));
|
|
1318
|
-
if (created?.id && created.status === "processing" && !submitted) {
|
|
1319
|
-
await bestEffortMarkFailed2({ data: config.data }, created.id, error);
|
|
1320
|
-
}
|
|
1321
|
-
if (submitted && created?.id) {
|
|
1322
|
-
return [
|
|
1323
|
-
new CapxulError({
|
|
1324
|
-
code: "NETWORK_ERROR",
|
|
1325
|
-
message: "Withdrawal was submitted on-chain, but backend submission tracking failed.",
|
|
1326
|
-
cause,
|
|
1327
|
-
details: {
|
|
1328
|
-
withdrawalId: created.id,
|
|
1329
|
-
txHash: submitted.txHash,
|
|
1330
|
-
userOpHash: submitted.userOpHash
|
|
1331
|
-
}
|
|
1332
|
-
}),
|
|
1333
|
-
null
|
|
1334
|
-
];
|
|
1335
|
-
}
|
|
1336
|
-
return [error, null];
|
|
1337
1594
|
}
|
|
1595
|
+
const [recordErr] = await tryCatch(
|
|
1596
|
+
config.data.mutation(api.withdrawals.mutations.recordSubmitted, {
|
|
1597
|
+
withdrawalId: created.id,
|
|
1598
|
+
txHash: transferOk.txHash,
|
|
1599
|
+
userOpHash: transferOk.userOpHash
|
|
1600
|
+
})
|
|
1601
|
+
);
|
|
1602
|
+
if (recordErr) {
|
|
1603
|
+
return [
|
|
1604
|
+
new CapxulError({
|
|
1605
|
+
code: "NETWORK_ERROR",
|
|
1606
|
+
message: "Withdrawal was submitted on-chain, but backend submission tracking failed.",
|
|
1607
|
+
cause: recordErr,
|
|
1608
|
+
details: {
|
|
1609
|
+
withdrawalId: created.id,
|
|
1610
|
+
txHash: transferOk.txHash,
|
|
1611
|
+
userOpHash: transferOk.userOpHash
|
|
1612
|
+
}
|
|
1613
|
+
}),
|
|
1614
|
+
null
|
|
1615
|
+
];
|
|
1616
|
+
}
|
|
1617
|
+
return [null, created];
|
|
1338
1618
|
},
|
|
1339
1619
|
retrieve: async (withdrawalId) => {
|
|
1340
1620
|
if (!config.data) {
|
|
1341
1621
|
return stub("withdrawals.retrieve");
|
|
1342
1622
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
);
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
code: "NOT_FOUND",
|
|
1352
|
-
message: `withdrawal ${withdrawalId} not found`
|
|
1353
|
-
}),
|
|
1354
|
-
null
|
|
1355
|
-
];
|
|
1356
|
-
}
|
|
1357
|
-
return [null, withdrawal];
|
|
1358
|
-
} catch (cause) {
|
|
1623
|
+
const [err, raw] = await tryCatch(
|
|
1624
|
+
config.data.query(api.withdrawals.queries.retrieve, { withdrawalId })
|
|
1625
|
+
);
|
|
1626
|
+
if (err) {
|
|
1627
|
+
return [fromConvexError(err), null];
|
|
1628
|
+
}
|
|
1629
|
+
const withdrawal = raw;
|
|
1630
|
+
if (!withdrawal) {
|
|
1359
1631
|
return [
|
|
1360
|
-
|
|
1632
|
+
new CapxulError({
|
|
1633
|
+
code: "NOT_FOUND",
|
|
1634
|
+
message: `withdrawal ${withdrawalId} not found`
|
|
1635
|
+
}),
|
|
1361
1636
|
null
|
|
1362
1637
|
];
|
|
1363
1638
|
}
|
|
1639
|
+
return [null, withdrawal];
|
|
1364
1640
|
},
|
|
1365
1641
|
list: async (input) => {
|
|
1366
1642
|
if (!config.data) {
|
|
1367
1643
|
return stub("withdrawals.list");
|
|
1368
1644
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1645
|
+
const [err, raw] = await tryCatch(
|
|
1646
|
+
config.data.query(api.withdrawals.queries.list, {
|
|
1647
|
+
limit: input?.limit,
|
|
1648
|
+
cursor: input?.cursor
|
|
1649
|
+
})
|
|
1650
|
+
);
|
|
1651
|
+
if (err) {
|
|
1652
|
+
return [fromConvexError(err), null];
|
|
1653
|
+
}
|
|
1654
|
+
return [null, raw];
|
|
1655
|
+
},
|
|
1656
|
+
recordCompleted: async (input) => {
|
|
1657
|
+
if (!config.data) {
|
|
1658
|
+
return stub(
|
|
1659
|
+
"withdrawals.recordCompleted"
|
|
1376
1660
|
);
|
|
1377
|
-
|
|
1378
|
-
|
|
1661
|
+
}
|
|
1662
|
+
const [err] = await tryCatch(
|
|
1663
|
+
config.data.mutation(api.withdrawals.mutations.recordCompleted, {
|
|
1664
|
+
withdrawalId: input.withdrawalId,
|
|
1665
|
+
txHash: input.txHash
|
|
1666
|
+
})
|
|
1667
|
+
);
|
|
1668
|
+
if (err) {
|
|
1379
1669
|
return [
|
|
1380
|
-
fromConvexError(
|
|
1670
|
+
mapRecordCompletedError(fromConvexError(err)),
|
|
1381
1671
|
null
|
|
1382
1672
|
];
|
|
1383
1673
|
}
|
|
1674
|
+
return [null, null];
|
|
1384
1675
|
}
|
|
1385
1676
|
};
|
|
1386
1677
|
}
|
|
1387
1678
|
function createOrgWithdrawalsClient(config = {}) {
|
|
1388
1679
|
return {
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1680
|
+
/**
|
|
1681
|
+
* Org-scope create (Withdrawals v1 W2, #465).
|
|
1682
|
+
*
|
|
1683
|
+
* D6 — returns the `processing` row only. No `transferAsOwner`
|
|
1684
|
+
* tail, no `recordSubmitted` call. Org Safe + Zodiac submission
|
|
1685
|
+
* orchestration ships in W3+.
|
|
1686
|
+
*/
|
|
1687
|
+
create: async (input) => {
|
|
1688
|
+
if (!config.data) {
|
|
1689
|
+
return stub(
|
|
1690
|
+
"organizations.withdrawals.create"
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
const [err, raw] = await tryCatch(
|
|
1694
|
+
config.data.mutation(api.withdrawals.mutations.createOrg, {
|
|
1695
|
+
organizationId: input.organizationId,
|
|
1696
|
+
amount: input.amount,
|
|
1697
|
+
destination: {
|
|
1698
|
+
externalAccountId: input.destination.externalAccountId
|
|
1699
|
+
},
|
|
1700
|
+
source: input.source,
|
|
1701
|
+
reference: input.reference,
|
|
1702
|
+
idempotencyKey: input.idempotencyKey
|
|
1703
|
+
})
|
|
1704
|
+
);
|
|
1705
|
+
if (err) {
|
|
1706
|
+
return [mapCreateError2(fromConvexError(err)), null];
|
|
1707
|
+
}
|
|
1708
|
+
const created = raw;
|
|
1709
|
+
if (!created) {
|
|
1710
|
+
return [
|
|
1711
|
+
new CapxulError({
|
|
1712
|
+
code: "NETWORK_ERROR",
|
|
1713
|
+
message: "organizations.withdrawals.create returned no withdrawal resource"
|
|
1714
|
+
}),
|
|
1715
|
+
null
|
|
1716
|
+
];
|
|
1717
|
+
}
|
|
1718
|
+
return [null, created];
|
|
1719
|
+
},
|
|
1395
1720
|
retrieve: async (input) => {
|
|
1396
1721
|
if (!config.data) {
|
|
1397
1722
|
return stub(
|
|
1398
1723
|
"organizations.withdrawals.retrieve"
|
|
1399
1724
|
);
|
|
1400
1725
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
}),
|
|
1412
|
-
null
|
|
1413
|
-
];
|
|
1414
|
-
}
|
|
1415
|
-
const ownerCheck = withdrawal.owner;
|
|
1416
|
-
if (ownerCheck?.type !== "organization" || ownerCheck.id !== input.organizationId) {
|
|
1417
|
-
return [
|
|
1418
|
-
new CapxulError({
|
|
1419
|
-
code: "NOT_FOUND",
|
|
1420
|
-
message: `withdrawal ${input.withdrawalId} does not belong to organization ${input.organizationId}`
|
|
1421
|
-
}),
|
|
1422
|
-
null
|
|
1423
|
-
];
|
|
1424
|
-
}
|
|
1425
|
-
return [null, withdrawal];
|
|
1426
|
-
} catch (cause) {
|
|
1726
|
+
const [err, raw] = await tryCatch(
|
|
1727
|
+
config.data.query(api.withdrawals.queries.retrieve, {
|
|
1728
|
+
withdrawalId: input.withdrawalId
|
|
1729
|
+
})
|
|
1730
|
+
);
|
|
1731
|
+
if (err) {
|
|
1732
|
+
return [fromConvexError(err), null];
|
|
1733
|
+
}
|
|
1734
|
+
const withdrawal = raw;
|
|
1735
|
+
if (!withdrawal) {
|
|
1427
1736
|
return [
|
|
1428
|
-
|
|
1737
|
+
new CapxulError({
|
|
1738
|
+
code: "NOT_FOUND",
|
|
1739
|
+
message: `withdrawal ${input.withdrawalId} not found`
|
|
1740
|
+
}),
|
|
1429
1741
|
null
|
|
1430
1742
|
];
|
|
1431
1743
|
}
|
|
1744
|
+
const ownerCheck = withdrawal.owner;
|
|
1745
|
+
if (ownerCheck?.type !== "organization" || ownerCheck.id !== input.organizationId) {
|
|
1746
|
+
return [
|
|
1747
|
+
new CapxulError({
|
|
1748
|
+
code: "NOT_FOUND",
|
|
1749
|
+
message: `withdrawal ${input.withdrawalId} does not belong to organization ${input.organizationId}`
|
|
1750
|
+
}),
|
|
1751
|
+
null
|
|
1752
|
+
];
|
|
1753
|
+
}
|
|
1754
|
+
return [null, withdrawal];
|
|
1432
1755
|
},
|
|
1433
1756
|
list: async (input) => {
|
|
1434
1757
|
if (!config.data) {
|
|
@@ -1436,34 +1759,32 @@ function createOrgWithdrawalsClient(config = {}) {
|
|
|
1436
1759
|
"organizations.withdrawals.list"
|
|
1437
1760
|
);
|
|
1438
1761
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
);
|
|
1448
|
-
return [null, result];
|
|
1449
|
-
} catch (cause) {
|
|
1450
|
-
return [
|
|
1451
|
-
fromConvexError(cause),
|
|
1452
|
-
null
|
|
1453
|
-
];
|
|
1762
|
+
const [err, raw] = await tryCatch(
|
|
1763
|
+
config.data.query(api.withdrawals.queries.listOrg, {
|
|
1764
|
+
organizationId: input.organizationId,
|
|
1765
|
+
limit: input.limit,
|
|
1766
|
+
cursor: input.cursor
|
|
1767
|
+
})
|
|
1768
|
+
);
|
|
1769
|
+
if (err) {
|
|
1770
|
+
return [fromConvexError(err), null];
|
|
1454
1771
|
}
|
|
1772
|
+
return [null, raw];
|
|
1455
1773
|
}
|
|
1456
1774
|
};
|
|
1457
1775
|
}
|
|
1776
|
+
async function handleSubmissionFailure(config, withdrawalId, error) {
|
|
1777
|
+
await bestEffortMarkFailed2(config, withdrawalId, error);
|
|
1778
|
+
return [error, null];
|
|
1779
|
+
}
|
|
1458
1780
|
async function bestEffortMarkFailed2(config, withdrawalId, error) {
|
|
1459
|
-
|
|
1460
|
-
|
|
1781
|
+
await tryCatch(
|
|
1782
|
+
config.data.mutation(api.withdrawals.mutations.markFailed, {
|
|
1461
1783
|
withdrawalId,
|
|
1462
1784
|
errorCode: error.code,
|
|
1463
1785
|
errorMessage: error.message
|
|
1464
|
-
})
|
|
1465
|
-
|
|
1466
|
-
}
|
|
1786
|
+
})
|
|
1787
|
+
);
|
|
1467
1788
|
}
|
|
1468
1789
|
function mapCreateError2(error) {
|
|
1469
1790
|
switch (error.code) {
|
|
@@ -1476,6 +1797,29 @@ function mapCreateError2(error) {
|
|
|
1476
1797
|
case "POLICY_DENIED":
|
|
1477
1798
|
case "RATE_LIMITED":
|
|
1478
1799
|
case "NETWORK_ERROR":
|
|
1800
|
+
case "NOT_FOUND":
|
|
1801
|
+
case "VERIFICATION_REQUIRED":
|
|
1802
|
+
return error;
|
|
1803
|
+
default:
|
|
1804
|
+
return new CapxulError({
|
|
1805
|
+
code: "NETWORK_ERROR",
|
|
1806
|
+
message: error.message,
|
|
1807
|
+
cause: error,
|
|
1808
|
+
details: error.details,
|
|
1809
|
+
operationId: error.operationId,
|
|
1810
|
+
correlationId: error.correlationId,
|
|
1811
|
+
retryable: error.retryable
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
function mapRecordCompletedError(error) {
|
|
1816
|
+
switch (error.code) {
|
|
1817
|
+
case "NOT_AUTHENTICATED":
|
|
1818
|
+
case "PERMISSION_DENIED":
|
|
1819
|
+
case "INVALID_INPUT":
|
|
1820
|
+
case "NOT_FOUND":
|
|
1821
|
+
case "NETWORK_ERROR":
|
|
1822
|
+
case "INTERNAL_ERROR":
|
|
1479
1823
|
return error;
|
|
1480
1824
|
default:
|
|
1481
1825
|
return new CapxulError({
|
|
@@ -1511,6 +1855,136 @@ function createWebhookEventsClient() {
|
|
|
1511
1855
|
}
|
|
1512
1856
|
|
|
1513
1857
|
// src/core/organizations.ts
|
|
1858
|
+
function createOrgExternalAccountsClient(config) {
|
|
1859
|
+
return {
|
|
1860
|
+
create: async (input) => {
|
|
1861
|
+
if (!config.data) {
|
|
1862
|
+
return stub(
|
|
1863
|
+
"organizations.externalAccounts.create"
|
|
1864
|
+
);
|
|
1865
|
+
}
|
|
1866
|
+
const [err, raw] = await tryCatch(
|
|
1867
|
+
config.data.mutation(api.externalAccounts.mutations.createOrg, {
|
|
1868
|
+
organizationId: input.organizationId,
|
|
1869
|
+
kind: input.kind,
|
|
1870
|
+
label: input.label,
|
|
1871
|
+
address: input.address,
|
|
1872
|
+
iban: input.iban,
|
|
1873
|
+
bic: input.bic,
|
|
1874
|
+
accountHolder: input.accountHolder,
|
|
1875
|
+
network: input.network,
|
|
1876
|
+
panToken: input.panToken,
|
|
1877
|
+
last4: input.last4
|
|
1878
|
+
})
|
|
1879
|
+
);
|
|
1880
|
+
if (err) {
|
|
1881
|
+
return [
|
|
1882
|
+
fromConvexError(err),
|
|
1883
|
+
null
|
|
1884
|
+
];
|
|
1885
|
+
}
|
|
1886
|
+
if (!raw) {
|
|
1887
|
+
return [
|
|
1888
|
+
new CapxulError({
|
|
1889
|
+
code: "NOT_FOUND",
|
|
1890
|
+
message: "external_account creation returned no resource"
|
|
1891
|
+
}),
|
|
1892
|
+
null
|
|
1893
|
+
];
|
|
1894
|
+
}
|
|
1895
|
+
return [
|
|
1896
|
+
null,
|
|
1897
|
+
brandExternalAccount(
|
|
1898
|
+
raw
|
|
1899
|
+
)
|
|
1900
|
+
];
|
|
1901
|
+
},
|
|
1902
|
+
list: async (input) => {
|
|
1903
|
+
if (!config.data) {
|
|
1904
|
+
return stub(
|
|
1905
|
+
"organizations.externalAccounts.list"
|
|
1906
|
+
);
|
|
1907
|
+
}
|
|
1908
|
+
const [err, result] = await tryCatch(
|
|
1909
|
+
config.data.query(api.externalAccounts.queries.listOrg, {
|
|
1910
|
+
organizationId: input.organizationId,
|
|
1911
|
+
limit: input.limit,
|
|
1912
|
+
cursor: input.cursor
|
|
1913
|
+
})
|
|
1914
|
+
);
|
|
1915
|
+
if (err) {
|
|
1916
|
+
return [fromConvexError(err), null];
|
|
1917
|
+
}
|
|
1918
|
+
const branded = result.data.map(
|
|
1919
|
+
(row) => brandExternalAccount(
|
|
1920
|
+
row
|
|
1921
|
+
)
|
|
1922
|
+
);
|
|
1923
|
+
return [
|
|
1924
|
+
null,
|
|
1925
|
+
{
|
|
1926
|
+
object: "list",
|
|
1927
|
+
data: branded,
|
|
1928
|
+
page: result.page
|
|
1929
|
+
}
|
|
1930
|
+
];
|
|
1931
|
+
},
|
|
1932
|
+
retrieve: async (input) => {
|
|
1933
|
+
if (!config.data) {
|
|
1934
|
+
return stub(
|
|
1935
|
+
"organizations.externalAccounts.retrieve"
|
|
1936
|
+
);
|
|
1937
|
+
}
|
|
1938
|
+
const [err, raw] = await tryCatch(
|
|
1939
|
+
config.data.query(api.externalAccounts.queries.retrieveOrg, {
|
|
1940
|
+
organizationId: input.organizationId,
|
|
1941
|
+
externalAccountId: input.externalAccountId
|
|
1942
|
+
})
|
|
1943
|
+
);
|
|
1944
|
+
if (err) {
|
|
1945
|
+
return [
|
|
1946
|
+
fromConvexError(err),
|
|
1947
|
+
null
|
|
1948
|
+
];
|
|
1949
|
+
}
|
|
1950
|
+
if (!raw) {
|
|
1951
|
+
return [
|
|
1952
|
+
new CapxulError({
|
|
1953
|
+
code: "NOT_FOUND",
|
|
1954
|
+
message: `external_account ${input.externalAccountId} not found`
|
|
1955
|
+
}),
|
|
1956
|
+
null
|
|
1957
|
+
];
|
|
1958
|
+
}
|
|
1959
|
+
return [
|
|
1960
|
+
null,
|
|
1961
|
+
brandExternalAccount(
|
|
1962
|
+
raw
|
|
1963
|
+
)
|
|
1964
|
+
];
|
|
1965
|
+
},
|
|
1966
|
+
remove: async (input) => {
|
|
1967
|
+
if (!config.data) {
|
|
1968
|
+
return stub(
|
|
1969
|
+
"organizations.externalAccounts.remove"
|
|
1970
|
+
);
|
|
1971
|
+
}
|
|
1972
|
+
const [err] = await tryCatch(
|
|
1973
|
+
config.data.mutation(api.externalAccounts.mutations.removeOrg, {
|
|
1974
|
+
organizationId: input.organizationId,
|
|
1975
|
+
externalAccountId: input.externalAccountId
|
|
1976
|
+
})
|
|
1977
|
+
);
|
|
1978
|
+
if (err) {
|
|
1979
|
+
return [
|
|
1980
|
+
fromConvexError(err),
|
|
1981
|
+
null
|
|
1982
|
+
];
|
|
1983
|
+
}
|
|
1984
|
+
return [null, void 0];
|
|
1985
|
+
}
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1514
1988
|
function createOrganizationsClient(config = {}) {
|
|
1515
1989
|
return {
|
|
1516
1990
|
create: async () => stub("organizations.create"),
|
|
@@ -1566,18 +2040,7 @@ function createOrganizationsClient(config = {}) {
|
|
|
1566
2040
|
retrieve: async () => stub("organizations.subAccounts.retrieve"),
|
|
1567
2041
|
remove: async () => stub("organizations.subAccounts.remove")
|
|
1568
2042
|
},
|
|
1569
|
-
externalAccounts:
|
|
1570
|
-
create: async () => stub(
|
|
1571
|
-
"organizations.externalAccounts.create"
|
|
1572
|
-
),
|
|
1573
|
-
list: async () => stub(
|
|
1574
|
-
"organizations.externalAccounts.list"
|
|
1575
|
-
),
|
|
1576
|
-
retrieve: async () => stub(
|
|
1577
|
-
"organizations.externalAccounts.retrieve"
|
|
1578
|
-
),
|
|
1579
|
-
remove: async () => stub("organizations.externalAccounts.remove")
|
|
1580
|
-
},
|
|
2043
|
+
externalAccounts: createOrgExternalAccountsClient(config),
|
|
1581
2044
|
balanceLedger: {
|
|
1582
2045
|
list: async () => stub(
|
|
1583
2046
|
"organizations.balanceLedger.list"
|
|
@@ -1714,50 +2177,6 @@ function createVirtualCardsClient() {
|
|
|
1714
2177
|
cancel: async () => stub("virtualCards.cancel")
|
|
1715
2178
|
};
|
|
1716
2179
|
}
|
|
1717
|
-
|
|
1718
|
-
// ../observability/src/debug-log.ts
|
|
1719
|
-
function isDevelopmentBuild() {
|
|
1720
|
-
if (typeof process === "undefined") {
|
|
1721
|
-
return false;
|
|
1722
|
-
}
|
|
1723
|
-
return process.env?.NODE_ENV === "development" || process.env?.NODE_ENV === "test";
|
|
1724
|
-
}
|
|
1725
|
-
function debugLog(line) {
|
|
1726
|
-
if (!isDevelopmentBuild()) return;
|
|
1727
|
-
if (typeof globalThis !== "undefined" && "window" in globalThis && typeof console?.info === "function") {
|
|
1728
|
-
console.info(line);
|
|
1729
|
-
return;
|
|
1730
|
-
}
|
|
1731
|
-
if (typeof process !== "undefined" && typeof process.stderr?.write === "function") {
|
|
1732
|
-
process.stderr.write(`${line}
|
|
1733
|
-
`);
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
function formatDebugValue(value) {
|
|
1737
|
-
if (value === void 0 || value === "") return "";
|
|
1738
|
-
if (typeof value === "string") return value;
|
|
1739
|
-
try {
|
|
1740
|
-
return JSON.stringify(value);
|
|
1741
|
-
} catch {
|
|
1742
|
-
return String(value);
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
function track(...args) {
|
|
1746
|
-
const [name, props] = args;
|
|
1747
|
-
debugLog(`[TRACK] ${name} ${formatDebugValue(props ?? "")}`);
|
|
1748
|
-
}
|
|
1749
|
-
function formatDebugValue2(value) {
|
|
1750
|
-
if (value === void 0 || value === "") return "";
|
|
1751
|
-
if (typeof value === "string") return value;
|
|
1752
|
-
try {
|
|
1753
|
-
return JSON.stringify(value);
|
|
1754
|
-
} catch {
|
|
1755
|
-
return String(value);
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
function identify(userId, traits) {
|
|
1759
|
-
debugLog(`[IDENTIFY] ${userId} ${formatDebugValue2(traits ?? "")}`);
|
|
1760
|
-
}
|
|
1761
2180
|
function createAuthFlowMachine(client) {
|
|
1762
2181
|
return xstate.setup({
|
|
1763
2182
|
types: {},
|
|
@@ -2033,23 +2452,6 @@ function emailDomain(email) {
|
|
|
2033
2452
|
const domain = email.split("@")[1]?.trim().toLowerCase();
|
|
2034
2453
|
return domain || "unknown";
|
|
2035
2454
|
}
|
|
2036
|
-
|
|
2037
|
-
// ../platform-kernel/src/ids.ts
|
|
2038
|
-
function makePrefixedIdConstructor(prefix, fieldName) {
|
|
2039
|
-
const re = new RegExp(`^${prefix}_[A-Za-z0-9_\\-]+$`);
|
|
2040
|
-
return (raw) => {
|
|
2041
|
-
if (typeof raw !== "string" || !re.test(raw)) {
|
|
2042
|
-
throw new Error(
|
|
2043
|
-
`Invalid ${fieldName}: expected string matching ^${prefix}_[A-Za-z0-9_\\-]+$, got ${String(raw)}`
|
|
2044
|
-
);
|
|
2045
|
-
}
|
|
2046
|
-
return raw;
|
|
2047
|
-
};
|
|
2048
|
-
}
|
|
2049
|
-
var toOperationId = makePrefixedIdConstructor(
|
|
2050
|
-
"op",
|
|
2051
|
-
"operationId"
|
|
2052
|
-
);
|
|
2053
2455
|
function createProvisioningMachine(client) {
|
|
2054
2456
|
return xstate.setup({
|
|
2055
2457
|
types: {},
|
|
@@ -2442,7 +2844,7 @@ function createCapxulClient(config = {}) {
|
|
|
2442
2844
|
subAccounts: createSubAccountsClient(),
|
|
2443
2845
|
virtualAccounts: createVirtualAccountsClient(),
|
|
2444
2846
|
virtualCards: createVirtualCardsClient(),
|
|
2445
|
-
externalAccounts: createExternalAccountsClient(),
|
|
2847
|
+
externalAccounts: createExternalAccountsClient(config),
|
|
2446
2848
|
operations: createOperationsClient(config),
|
|
2447
2849
|
webhookEndpoints: createWebhookEndpointsClient(),
|
|
2448
2850
|
webhookEvents: createWebhookEventsClient(),
|