@capxul/sdk 0.1.0-alpha.2 → 0.1.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/dist/client.js CHANGED
@@ -1098,298 +1098,24 @@ function createOrgTransfersClient() {
1098
1098
  cancel: async () => stub("organizations.transfers.cancel")
1099
1099
  };
1100
1100
  }
1101
- var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
1102
- function createWithdrawalsClient(config = {}) {
1101
+
1102
+ // src/core/withdrawals.ts
1103
+ function createWithdrawalsClient() {
1103
1104
  return {
1104
- create: async (input) => {
1105
- if (!config.data) {
1106
- return stub("withdrawals.create");
1107
- }
1108
- let created = null;
1109
- let submitted = null;
1110
- try {
1111
- created = await config.data.mutation(
1112
- api.withdrawals.mutations.create,
1113
- {
1114
- amount: input.amount,
1115
- destination: {
1116
- externalAccountId: input.destination.externalAccountId,
1117
- kind: input.destination.kind
1118
- },
1119
- source: input.source,
1120
- reference: input.reference,
1121
- idempotencyKey: input.idempotencyKey
1122
- }
1123
- );
1124
- if (!created) {
1125
- return [
1126
- new CapxulError({
1127
- code: "NETWORK_ERROR",
1128
- message: "withdrawals.create returned no withdrawal resource"
1129
- }),
1130
- null
1131
- ];
1132
- }
1133
- if (created.status !== "processing" || created.operation.status !== "processing") {
1134
- return [null, created];
1135
- }
1136
- if (input.destination.kind !== "evm") {
1137
- return [null, created];
1138
- }
1139
- if (!config.signer || !config.signing) {
1140
- return [null, created];
1141
- }
1142
- if (!EVM_ADDRESS_RE.test(input.destination.externalAccountId)) {
1143
- throw new CapxulError({
1144
- code: "INVALID_INPUT",
1145
- message: "destination.externalAccountId must be a 0x-prefixed EVM address while external_accounts resolution is pending (slice 1).",
1146
- details: { field: "destination.externalAccountId" }
1147
- });
1148
- }
1149
- const currentSigner = await config.data.query(
1150
- api.safe.queries.getMySignerAddress,
1151
- {}
1152
- );
1153
- if (!currentSigner?.address) {
1154
- throw new CapxulError({
1155
- code: "PERMISSION_DENIED",
1156
- message: "No signer is registered for the authenticated account.",
1157
- details: { withdrawalId: created.id }
1158
- });
1159
- }
1160
- if (getAddress(currentSigner.address) !== getAddress(config.signer.address)) {
1161
- throw new CapxulError({
1162
- code: "PERMISSION_DENIED",
1163
- message: "Configured signer does not match the authenticated account signer.",
1164
- details: {
1165
- withdrawalId: created.id,
1166
- expectedSignerAddress: currentSigner.address,
1167
- actualSignerAddress: config.signer.address
1168
- }
1169
- });
1170
- }
1171
- const submission = await config.data.query(
1172
- api.withdrawals.queries.prepareSubmission,
1173
- { withdrawalId: created.id }
1174
- );
1175
- if (!submission?.externalAccountId) {
1176
- throw new CapxulError({
1177
- code: "NETWORK_ERROR",
1178
- message: "withdrawals.prepareSubmission returned no destination.",
1179
- details: { withdrawalId: created.id }
1180
- });
1181
- }
1182
- const transfer = await transferAsOwner(
1183
- {
1184
- signer: config.signer,
1185
- signing: config.signing
1186
- },
1187
- {
1188
- tokenAddress: resolvePaymentTokenAddress(submission.amount.currency),
1189
- recipientAddress: submission.externalAccountId,
1190
- amount: toTokenUnits(submission.amount.value, 6)
1191
- }
1192
- );
1193
- if (!transfer.success) {
1194
- throw new CapxulError({
1195
- code: "NETWORK_ERROR",
1196
- message: "Bundler submission did not succeed.",
1197
- details: {
1198
- withdrawalId: created.id,
1199
- txHash: transfer.txHash,
1200
- userOpHash: transfer.userOpHash
1201
- }
1202
- });
1203
- }
1204
- submitted = {
1205
- txHash: transfer.txHash,
1206
- userOpHash: transfer.userOpHash
1207
- };
1208
- await config.data.mutation(
1209
- api.withdrawals.mutations.recordSubmitted,
1210
- {
1211
- withdrawalId: created.id,
1212
- txHash: transfer.txHash,
1213
- userOpHash: transfer.userOpHash
1214
- }
1215
- );
1216
- return [null, created];
1217
- } catch (cause) {
1218
- const error = mapCreateError2(fromConvexError(cause));
1219
- if (created?.id && created.status === "processing" && !submitted) {
1220
- await bestEffortMarkFailed2({ data: config.data }, created.id, error);
1221
- }
1222
- if (submitted && created?.id) {
1223
- return [
1224
- new CapxulError({
1225
- code: "NETWORK_ERROR",
1226
- message: "Withdrawal was submitted on-chain, but backend submission tracking failed.",
1227
- cause,
1228
- details: {
1229
- withdrawalId: created.id,
1230
- txHash: submitted.txHash,
1231
- userOpHash: submitted.userOpHash
1232
- }
1233
- }),
1234
- null
1235
- ];
1236
- }
1237
- return [error, null];
1238
- }
1239
- },
1240
- retrieve: async (withdrawalId) => {
1241
- if (!config.data) {
1242
- return stub("withdrawals.retrieve");
1243
- }
1244
- try {
1245
- const withdrawal = await config.data.query(
1246
- api.withdrawals.queries.retrieve,
1247
- { withdrawalId }
1248
- );
1249
- if (!withdrawal) {
1250
- return [
1251
- new CapxulError({
1252
- code: "NOT_FOUND",
1253
- message: `withdrawal ${withdrawalId} not found`
1254
- }),
1255
- null
1256
- ];
1257
- }
1258
- return [null, withdrawal];
1259
- } catch (cause) {
1260
- return [
1261
- fromConvexError(cause),
1262
- null
1263
- ];
1264
- }
1265
- },
1266
- list: async (input) => {
1267
- if (!config.data) {
1268
- return stub("withdrawals.list");
1269
- }
1270
- try {
1271
- const result = await config.data.query(
1272
- api.withdrawals.queries.list,
1273
- {
1274
- limit: input?.limit,
1275
- cursor: input?.cursor
1276
- }
1277
- );
1278
- return [null, result];
1279
- } catch (cause) {
1280
- return [
1281
- fromConvexError(cause),
1282
- null
1283
- ];
1284
- }
1285
- }
1105
+ create: async () => stub("withdrawals.create"),
1106
+ retrieve: async () => stub("withdrawals.retrieve"),
1107
+ list: async () => stub("withdrawals.list")
1286
1108
  };
1287
1109
  }
1288
- function createOrgWithdrawalsClient(config = {}) {
1110
+ function createOrgWithdrawalsClient() {
1289
1111
  return {
1290
- // Slice 1 ships personal-scope only end-to-end; org-scope create
1291
- // remains stubbed pending org-scoped backend mutation. List + retrieve
1292
- // are wired through the org-aware query.
1293
1112
  create: async () => stub(
1294
1113
  "organizations.withdrawals.create"
1295
1114
  ),
1296
- retrieve: async (input) => {
1297
- if (!config.data) {
1298
- return stub(
1299
- "organizations.withdrawals.retrieve"
1300
- );
1301
- }
1302
- try {
1303
- const withdrawal = await config.data.query(
1304
- api.withdrawals.queries.retrieve,
1305
- { withdrawalId: input.withdrawalId }
1306
- );
1307
- if (!withdrawal) {
1308
- return [
1309
- new CapxulError({
1310
- code: "NOT_FOUND",
1311
- message: `withdrawal ${input.withdrawalId} not found`
1312
- }),
1313
- null
1314
- ];
1315
- }
1316
- const ownerCheck = withdrawal.owner;
1317
- if (ownerCheck?.type !== "organization" || ownerCheck.id !== input.organizationId) {
1318
- return [
1319
- new CapxulError({
1320
- code: "NOT_FOUND",
1321
- message: `withdrawal ${input.withdrawalId} does not belong to organization ${input.organizationId}`
1322
- }),
1323
- null
1324
- ];
1325
- }
1326
- return [null, withdrawal];
1327
- } catch (cause) {
1328
- return [
1329
- fromConvexError(cause),
1330
- null
1331
- ];
1332
- }
1333
- },
1334
- list: async (input) => {
1335
- if (!config.data) {
1336
- return stub(
1337
- "organizations.withdrawals.list"
1338
- );
1339
- }
1340
- try {
1341
- const result = await config.data.query(
1342
- api.withdrawals.queries.listOrg,
1343
- {
1344
- organizationId: input.organizationId,
1345
- limit: input.limit,
1346
- cursor: input.cursor
1347
- }
1348
- );
1349
- return [null, result];
1350
- } catch (cause) {
1351
- return [
1352
- fromConvexError(cause),
1353
- null
1354
- ];
1355
- }
1356
- }
1115
+ retrieve: async () => stub("organizations.withdrawals.retrieve"),
1116
+ list: async () => stub("organizations.withdrawals.list")
1357
1117
  };
1358
1118
  }
1359
- async function bestEffortMarkFailed2(config, withdrawalId, error) {
1360
- try {
1361
- await config.data.mutation(api.withdrawals.mutations.markFailed, {
1362
- withdrawalId,
1363
- errorCode: error.code,
1364
- errorMessage: error.message
1365
- });
1366
- } catch {
1367
- }
1368
- }
1369
- function mapCreateError2(error) {
1370
- switch (error.code) {
1371
- case "NOT_AUTHENTICATED":
1372
- case "PERMISSION_DENIED":
1373
- case "INVALID_INPUT":
1374
- case "INSUFFICIENT_BALANCE":
1375
- case "IDEMPOTENCY_CONFLICT":
1376
- case "KYC_REQUIRED":
1377
- case "POLICY_DENIED":
1378
- case "RATE_LIMITED":
1379
- case "NETWORK_ERROR":
1380
- return error;
1381
- default:
1382
- return new CapxulError({
1383
- code: "NETWORK_ERROR",
1384
- message: error.message,
1385
- cause: error,
1386
- details: error.details,
1387
- operationId: error.operationId,
1388
- correlationId: error.correlationId,
1389
- retryable: error.retryable
1390
- });
1391
- }
1392
- }
1393
1119
 
1394
1120
  // src/core/webhook-endpoints.ts
1395
1121
  function createWebhookEndpointsClient() {
@@ -1489,7 +1215,7 @@ function createOrganizationsClient(config = {}) {
1489
1215
  },
1490
1216
  payments: createOrgPaymentsClient(),
1491
1217
  transfers: createOrgTransfersClient(),
1492
- withdrawals: createOrgWithdrawalsClient(config),
1218
+ withdrawals: createOrgWithdrawalsClient(),
1493
1219
  documents: createOrgDocumentsClient(),
1494
1220
  webhookEndpoints: createWebhookEndpointsClient(),
1495
1221
  webhookEvents: createWebhookEventsClient()
@@ -2247,7 +1973,7 @@ function createCapxulClient(config = {}) {
2247
1973
  organizations: createOrganizationsClient(config),
2248
1974
  payments: createPaymentsClient(config),
2249
1975
  transfers: createTransfersClient(),
2250
- withdrawals: createWithdrawalsClient(config),
1976
+ withdrawals: createWithdrawalsClient(),
2251
1977
  documents: createDocumentsClient(),
2252
1978
  subAccounts: createSubAccountsClient(),
2253
1979
  virtualAccounts: createVirtualAccountsClient(),
package/dist/index.cjs CHANGED
@@ -1102,298 +1102,24 @@ function createOrgTransfersClient() {
1102
1102
  cancel: async () => stub("organizations.transfers.cancel")
1103
1103
  };
1104
1104
  }
1105
- var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
1106
- function createWithdrawalsClient(config = {}) {
1105
+
1106
+ // src/core/withdrawals.ts
1107
+ function createWithdrawalsClient() {
1107
1108
  return {
1108
- create: async (input) => {
1109
- if (!config.data) {
1110
- return stub("withdrawals.create");
1111
- }
1112
- let created = null;
1113
- let submitted = null;
1114
- try {
1115
- created = await config.data.mutation(
1116
- api.withdrawals.mutations.create,
1117
- {
1118
- amount: input.amount,
1119
- destination: {
1120
- externalAccountId: input.destination.externalAccountId,
1121
- kind: input.destination.kind
1122
- },
1123
- source: input.source,
1124
- reference: input.reference,
1125
- idempotencyKey: input.idempotencyKey
1126
- }
1127
- );
1128
- if (!created) {
1129
- return [
1130
- new CapxulError({
1131
- code: "NETWORK_ERROR",
1132
- message: "withdrawals.create returned no withdrawal resource"
1133
- }),
1134
- null
1135
- ];
1136
- }
1137
- if (created.status !== "processing" || created.operation.status !== "processing") {
1138
- return [null, created];
1139
- }
1140
- if (input.destination.kind !== "evm") {
1141
- return [null, created];
1142
- }
1143
- if (!config.signer || !config.signing) {
1144
- return [null, created];
1145
- }
1146
- if (!EVM_ADDRESS_RE.test(input.destination.externalAccountId)) {
1147
- throw new CapxulError({
1148
- code: "INVALID_INPUT",
1149
- message: "destination.externalAccountId must be a 0x-prefixed EVM address while external_accounts resolution is pending (slice 1).",
1150
- details: { field: "destination.externalAccountId" }
1151
- });
1152
- }
1153
- const currentSigner = await config.data.query(
1154
- api.safe.queries.getMySignerAddress,
1155
- {}
1156
- );
1157
- if (!currentSigner?.address) {
1158
- throw new CapxulError({
1159
- code: "PERMISSION_DENIED",
1160
- message: "No signer is registered for the authenticated account.",
1161
- details: { withdrawalId: created.id }
1162
- });
1163
- }
1164
- if (viem.getAddress(currentSigner.address) !== viem.getAddress(config.signer.address)) {
1165
- throw new CapxulError({
1166
- code: "PERMISSION_DENIED",
1167
- message: "Configured signer does not match the authenticated account signer.",
1168
- details: {
1169
- withdrawalId: created.id,
1170
- expectedSignerAddress: currentSigner.address,
1171
- actualSignerAddress: config.signer.address
1172
- }
1173
- });
1174
- }
1175
- const submission = await config.data.query(
1176
- api.withdrawals.queries.prepareSubmission,
1177
- { withdrawalId: created.id }
1178
- );
1179
- if (!submission?.externalAccountId) {
1180
- throw new CapxulError({
1181
- code: "NETWORK_ERROR",
1182
- message: "withdrawals.prepareSubmission returned no destination.",
1183
- details: { withdrawalId: created.id }
1184
- });
1185
- }
1186
- const transfer = await transferAsOwner(
1187
- {
1188
- signer: config.signer,
1189
- signing: config.signing
1190
- },
1191
- {
1192
- tokenAddress: resolvePaymentTokenAddress(submission.amount.currency),
1193
- recipientAddress: submission.externalAccountId,
1194
- amount: toTokenUnits(submission.amount.value, 6)
1195
- }
1196
- );
1197
- if (!transfer.success) {
1198
- throw new CapxulError({
1199
- code: "NETWORK_ERROR",
1200
- message: "Bundler submission did not succeed.",
1201
- details: {
1202
- withdrawalId: created.id,
1203
- txHash: transfer.txHash,
1204
- userOpHash: transfer.userOpHash
1205
- }
1206
- });
1207
- }
1208
- submitted = {
1209
- txHash: transfer.txHash,
1210
- userOpHash: transfer.userOpHash
1211
- };
1212
- await config.data.mutation(
1213
- api.withdrawals.mutations.recordSubmitted,
1214
- {
1215
- withdrawalId: created.id,
1216
- txHash: transfer.txHash,
1217
- userOpHash: transfer.userOpHash
1218
- }
1219
- );
1220
- return [null, created];
1221
- } catch (cause) {
1222
- const error = mapCreateError2(fromConvexError(cause));
1223
- if (created?.id && created.status === "processing" && !submitted) {
1224
- await bestEffortMarkFailed2({ data: config.data }, created.id, error);
1225
- }
1226
- if (submitted && created?.id) {
1227
- return [
1228
- new CapxulError({
1229
- code: "NETWORK_ERROR",
1230
- message: "Withdrawal was submitted on-chain, but backend submission tracking failed.",
1231
- cause,
1232
- details: {
1233
- withdrawalId: created.id,
1234
- txHash: submitted.txHash,
1235
- userOpHash: submitted.userOpHash
1236
- }
1237
- }),
1238
- null
1239
- ];
1240
- }
1241
- return [error, null];
1242
- }
1243
- },
1244
- retrieve: async (withdrawalId) => {
1245
- if (!config.data) {
1246
- return stub("withdrawals.retrieve");
1247
- }
1248
- try {
1249
- const withdrawal = await config.data.query(
1250
- api.withdrawals.queries.retrieve,
1251
- { withdrawalId }
1252
- );
1253
- if (!withdrawal) {
1254
- return [
1255
- new CapxulError({
1256
- code: "NOT_FOUND",
1257
- message: `withdrawal ${withdrawalId} not found`
1258
- }),
1259
- null
1260
- ];
1261
- }
1262
- return [null, withdrawal];
1263
- } catch (cause) {
1264
- return [
1265
- fromConvexError(cause),
1266
- null
1267
- ];
1268
- }
1269
- },
1270
- list: async (input) => {
1271
- if (!config.data) {
1272
- return stub("withdrawals.list");
1273
- }
1274
- try {
1275
- const result = await config.data.query(
1276
- api.withdrawals.queries.list,
1277
- {
1278
- limit: input?.limit,
1279
- cursor: input?.cursor
1280
- }
1281
- );
1282
- return [null, result];
1283
- } catch (cause) {
1284
- return [
1285
- fromConvexError(cause),
1286
- null
1287
- ];
1288
- }
1289
- }
1109
+ create: async () => stub("withdrawals.create"),
1110
+ retrieve: async () => stub("withdrawals.retrieve"),
1111
+ list: async () => stub("withdrawals.list")
1290
1112
  };
1291
1113
  }
1292
- function createOrgWithdrawalsClient(config = {}) {
1114
+ function createOrgWithdrawalsClient() {
1293
1115
  return {
1294
- // Slice 1 ships personal-scope only end-to-end; org-scope create
1295
- // remains stubbed pending org-scoped backend mutation. List + retrieve
1296
- // are wired through the org-aware query.
1297
1116
  create: async () => stub(
1298
1117
  "organizations.withdrawals.create"
1299
1118
  ),
1300
- retrieve: async (input) => {
1301
- if (!config.data) {
1302
- return stub(
1303
- "organizations.withdrawals.retrieve"
1304
- );
1305
- }
1306
- try {
1307
- const withdrawal = await config.data.query(
1308
- api.withdrawals.queries.retrieve,
1309
- { withdrawalId: input.withdrawalId }
1310
- );
1311
- if (!withdrawal) {
1312
- return [
1313
- new CapxulError({
1314
- code: "NOT_FOUND",
1315
- message: `withdrawal ${input.withdrawalId} not found`
1316
- }),
1317
- null
1318
- ];
1319
- }
1320
- const ownerCheck = withdrawal.owner;
1321
- if (ownerCheck?.type !== "organization" || ownerCheck.id !== input.organizationId) {
1322
- return [
1323
- new CapxulError({
1324
- code: "NOT_FOUND",
1325
- message: `withdrawal ${input.withdrawalId} does not belong to organization ${input.organizationId}`
1326
- }),
1327
- null
1328
- ];
1329
- }
1330
- return [null, withdrawal];
1331
- } catch (cause) {
1332
- return [
1333
- fromConvexError(cause),
1334
- null
1335
- ];
1336
- }
1337
- },
1338
- list: async (input) => {
1339
- if (!config.data) {
1340
- return stub(
1341
- "organizations.withdrawals.list"
1342
- );
1343
- }
1344
- try {
1345
- const result = await config.data.query(
1346
- api.withdrawals.queries.listOrg,
1347
- {
1348
- organizationId: input.organizationId,
1349
- limit: input.limit,
1350
- cursor: input.cursor
1351
- }
1352
- );
1353
- return [null, result];
1354
- } catch (cause) {
1355
- return [
1356
- fromConvexError(cause),
1357
- null
1358
- ];
1359
- }
1360
- }
1119
+ retrieve: async () => stub("organizations.withdrawals.retrieve"),
1120
+ list: async () => stub("organizations.withdrawals.list")
1361
1121
  };
1362
1122
  }
1363
- async function bestEffortMarkFailed2(config, withdrawalId, error) {
1364
- try {
1365
- await config.data.mutation(api.withdrawals.mutations.markFailed, {
1366
- withdrawalId,
1367
- errorCode: error.code,
1368
- errorMessage: error.message
1369
- });
1370
- } catch {
1371
- }
1372
- }
1373
- function mapCreateError2(error) {
1374
- switch (error.code) {
1375
- case "NOT_AUTHENTICATED":
1376
- case "PERMISSION_DENIED":
1377
- case "INVALID_INPUT":
1378
- case "INSUFFICIENT_BALANCE":
1379
- case "IDEMPOTENCY_CONFLICT":
1380
- case "KYC_REQUIRED":
1381
- case "POLICY_DENIED":
1382
- case "RATE_LIMITED":
1383
- case "NETWORK_ERROR":
1384
- return error;
1385
- default:
1386
- return new CapxulError({
1387
- code: "NETWORK_ERROR",
1388
- message: error.message,
1389
- cause: error,
1390
- details: error.details,
1391
- operationId: error.operationId,
1392
- correlationId: error.correlationId,
1393
- retryable: error.retryable
1394
- });
1395
- }
1396
- }
1397
1123
 
1398
1124
  // src/core/webhook-endpoints.ts
1399
1125
  function createWebhookEndpointsClient() {
@@ -1493,7 +1219,7 @@ function createOrganizationsClient(config = {}) {
1493
1219
  },
1494
1220
  payments: createOrgPaymentsClient(),
1495
1221
  transfers: createOrgTransfersClient(),
1496
- withdrawals: createOrgWithdrawalsClient(config),
1222
+ withdrawals: createOrgWithdrawalsClient(),
1497
1223
  documents: createOrgDocumentsClient(),
1498
1224
  webhookEndpoints: createWebhookEndpointsClient(),
1499
1225
  webhookEvents: createWebhookEventsClient()
@@ -1530,6 +1256,15 @@ function createVirtualCardsClient() {
1530
1256
  };
1531
1257
  }
1532
1258
 
1259
+ // ../observability/src/try-catch.ts
1260
+ async function tryCatch(promise) {
1261
+ try {
1262
+ return [null, await promise];
1263
+ } catch (e) {
1264
+ return [e instanceof Error ? e : new Error(String(e)), null];
1265
+ }
1266
+ }
1267
+
1533
1268
  // ../observability/src/debug-log.ts
1534
1269
  function isDevelopmentBuild() {
1535
1270
  if (typeof process === "undefined") {
@@ -2350,7 +2085,7 @@ function createCapxulClient(config = {}) {
2350
2085
  organizations: createOrganizationsClient(config),
2351
2086
  payments: createPaymentsClient(config),
2352
2087
  transfers: createTransfersClient(),
2353
- withdrawals: createWithdrawalsClient(config),
2088
+ withdrawals: createWithdrawalsClient(),
2354
2089
  documents: createDocumentsClient(),
2355
2090
  subAccounts: createSubAccountsClient(),
2356
2091
  virtualAccounts: createVirtualAccountsClient(),
@@ -2501,4 +2236,5 @@ exports.toVirtualCardId = toVirtualCardId;
2501
2236
  exports.toWebhookEndpointId = toWebhookEndpointId;
2502
2237
  exports.toWebhookEventId = toWebhookEventId;
2503
2238
  exports.toWithdrawalId = toWithdrawalId;
2239
+ exports.tryCatch = tryCatch;
2504
2240
  exports.verifyWebhook = verifyWebhook;