@circle-fin/app-kit 1.15.2 → 1.16.0
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 +59 -0
- package/README.md +5 -2
- package/borrow.cjs +28028 -0
- package/borrow.cjs.map +1 -0
- package/borrow.d.cts +10723 -0
- package/borrow.d.mts +10723 -0
- package/borrow.d.ts +10723 -0
- package/borrow.mjs +28000 -0
- package/borrow.mjs.map +1 -0
- package/bridge.cjs +1942 -290
- package/bridge.d.cts +157 -12
- package/bridge.d.mts +157 -12
- package/bridge.d.ts +157 -12
- package/bridge.mjs +1942 -290
- package/chains.cjs +70 -3
- package/chains.d.cts +2 -0
- package/chains.d.mts +2 -0
- package/chains.d.ts +2 -0
- package/chains.mjs +70 -3
- package/context.cjs +1 -0
- package/context.d.cts +157 -12
- package/context.d.mts +157 -12
- package/context.d.ts +157 -12
- package/context.mjs +1 -0
- package/earn.cjs +5466 -3459
- package/earn.d.cts +1112 -983
- package/earn.d.mts +1112 -983
- package/earn.d.ts +1112 -983
- package/earn.mjs +5466 -3459
- package/estimateBridge.cjs +1940 -288
- package/estimateBridge.d.cts +157 -12
- package/estimateBridge.d.mts +157 -12
- package/estimateBridge.d.ts +157 -12
- package/estimateBridge.mjs +1940 -288
- package/estimateSwap.cjs +8497 -6831
- package/estimateSwap.d.cts +157 -12
- package/estimateSwap.d.mts +157 -12
- package/estimateSwap.d.ts +157 -12
- package/estimateSwap.mjs +8498 -6832
- package/index.cjs +30741 -18498
- package/index.d.cts +22724 -2322
- package/index.d.mts +22724 -2322
- package/index.d.ts +22724 -2322
- package/index.mjs +30682 -18492
- package/package.json +17 -7
- package/server.cjs +113 -22
- package/server.d.cts +10 -9
- package/server.d.mts +10 -9
- package/server.d.ts +10 -9
- package/server.mjs +113 -22
- package/swap.cjs +8497 -6831
- package/swap.d.cts +157 -12
- package/swap.d.mts +157 -12
- package/swap.d.ts +157 -12
- package/swap.mjs +8498 -6832
- package/unifiedBalance.cjs +457 -128
- package/unifiedBalance.d.cts +108 -11
- package/unifiedBalance.d.mts +108 -11
- package/unifiedBalance.d.ts +108 -11
- package/unifiedBalance.mjs +457 -128
package/estimateBridge.cjs
CHANGED
|
@@ -1367,6 +1367,34 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
1367
1367
|
return redactErrorMessage(String(error));
|
|
1368
1368
|
}
|
|
1369
1369
|
|
|
1370
|
+
/**
|
|
1371
|
+
* Render an object value for an error message without letting the rendering
|
|
1372
|
+
* itself throw.
|
|
1373
|
+
*
|
|
1374
|
+
* `JSON.stringify` rejects `BigInt` and circular structures, and a rejected
|
|
1375
|
+
* value is exactly the kind of thing a validation error is built from: an
|
|
1376
|
+
* on-chain read or a receipt log carries `bigint` fields, so serializing one
|
|
1377
|
+
* naively replaces the intended error with a `TypeError`.
|
|
1378
|
+
*
|
|
1379
|
+
* @param value - The value to render.
|
|
1380
|
+
* @returns A JSON string with `bigint` fields stringified, or
|
|
1381
|
+
* `'[unserializable object]'` if serialization still fails.
|
|
1382
|
+
* @throws Never; serialization failures are caught and rendered as a fallback string.
|
|
1383
|
+
* @example
|
|
1384
|
+
* ```typescript
|
|
1385
|
+
* import { describeObjectValue } from '@core/errors'
|
|
1386
|
+
*
|
|
1387
|
+
* describeObjectValue({ amount: 1n })
|
|
1388
|
+
* // '{"amount":"1"}'
|
|
1389
|
+
* ```
|
|
1390
|
+
*/ function describeObjectValue(value) {
|
|
1391
|
+
try {
|
|
1392
|
+
return JSON.stringify(value, (_key, entry)=>typeof entry === 'bigint' ? entry.toString() : entry);
|
|
1393
|
+
} catch {
|
|
1394
|
+
return '[unserializable object]';
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1370
1398
|
/**
|
|
1371
1399
|
* Creates error for network type mismatch between source and destination.
|
|
1372
1400
|
*
|
|
@@ -1629,7 +1657,7 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
1629
1657
|
* // Message: "Validation failed for 'chainId': 999 - Unsupported chain ID"
|
|
1630
1658
|
*
|
|
1631
1659
|
* throw createValidationFailedError('config', { invalid: true }, 'Missing required properties')
|
|
1632
|
-
* // Message: "Validation failed for 'config':
|
|
1660
|
+
* // Message: "Validation failed for 'config': {"invalid":true} - Missing required properties"
|
|
1633
1661
|
* ```
|
|
1634
1662
|
*/ function createValidationFailedError$1(field, value, reason) {
|
|
1635
1663
|
// Convert value to string for display, handling different types appropriately
|
|
@@ -1637,7 +1665,7 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
1637
1665
|
if (typeof value === 'string') {
|
|
1638
1666
|
valueString = `'${value}'`;
|
|
1639
1667
|
} else if (typeof value === 'object' && value !== null) {
|
|
1640
|
-
valueString =
|
|
1668
|
+
valueString = describeObjectValue(value);
|
|
1641
1669
|
} else {
|
|
1642
1670
|
valueString = String(value);
|
|
1643
1671
|
}
|
|
@@ -3135,6 +3163,105 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
3135
3163
|
return chain;
|
|
3136
3164
|
}
|
|
3137
3165
|
|
|
3166
|
+
/**
|
|
3167
|
+
* Extracts the HTTP status code from an error message.
|
|
3168
|
+
*
|
|
3169
|
+
* Attempts to parse HTTP status codes from common error message formats,
|
|
3170
|
+
* such as "HTTP 404" or "Status: 500".
|
|
3171
|
+
*
|
|
3172
|
+
* Shared by `parseApiError` and the backend-error-code parsers that route on
|
|
3173
|
+
* status when no backend code is available, so all of them recognise the same
|
|
3174
|
+
* message shapes.
|
|
3175
|
+
*
|
|
3176
|
+
* @param msg - The error message to extract from
|
|
3177
|
+
* @returns The extracted HTTP status code, or null if not found
|
|
3178
|
+
*
|
|
3179
|
+
* @example
|
|
3180
|
+
* ```typescript
|
|
3181
|
+
* const code = extractHttpStatusCode('HTTP 404')
|
|
3182
|
+
* // Returns: 404
|
|
3183
|
+
* ```
|
|
3184
|
+
*
|
|
3185
|
+
* @example
|
|
3186
|
+
* ```typescript
|
|
3187
|
+
* const code = extractHttpStatusCode('Status: 500 Internal Server Error')
|
|
3188
|
+
* // Returns: 500
|
|
3189
|
+
* ```
|
|
3190
|
+
*
|
|
3191
|
+
* @internal
|
|
3192
|
+
*/ function extractHttpStatusCode(msg) {
|
|
3193
|
+
// Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
|
|
3194
|
+
const patterns = [
|
|
3195
|
+
/HTTP (\d{3})/i,
|
|
3196
|
+
/Status:\s*(\d{3})/i,
|
|
3197
|
+
/^(\d{3}) -/
|
|
3198
|
+
];
|
|
3199
|
+
for (const pattern of patterns){
|
|
3200
|
+
const match = pattern.exec(msg);
|
|
3201
|
+
const codeStr = match?.at(1);
|
|
3202
|
+
if (codeStr !== undefined) {
|
|
3203
|
+
const code = Number.parseInt(codeStr, 10);
|
|
3204
|
+
// Validate it's a valid HTTP status code
|
|
3205
|
+
if (code >= 100 && code < 600) {
|
|
3206
|
+
return code;
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
return null;
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
/**
|
|
3214
|
+
* Type guard that narrows an unknown error to one carrying a non-null
|
|
3215
|
+
* object `responseBody` property (attached by `makeApiRequest`).
|
|
3216
|
+
*
|
|
3217
|
+
* Shared by backend-error-code parsers (`parseEarnApiError`,
|
|
3218
|
+
* `parseBorrowApiError`) so the narrowing logic lives in one place.
|
|
3219
|
+
*
|
|
3220
|
+
* @param error - The raw error from the HTTP layer
|
|
3221
|
+
* @returns `true` when `error.responseBody` is a non-null object
|
|
3222
|
+
* @internal
|
|
3223
|
+
*/ function hasResponseBody(error) {
|
|
3224
|
+
return typeof error === 'object' && error !== null && 'responseBody' in error && typeof error['responseBody'] === 'object' && error['responseBody'] !== null;
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3227
|
+
* Narrow an unknown value to a non-null object.
|
|
3228
|
+
*
|
|
3229
|
+
* @param value - The value to check
|
|
3230
|
+
* @returns `true` when `value` is a non-null object
|
|
3231
|
+
* @internal
|
|
3232
|
+
*/ function isRecord(value) {
|
|
3233
|
+
return typeof value === 'object' && value !== null;
|
|
3234
|
+
}
|
|
3235
|
+
/**
|
|
3236
|
+
* Read the machine-readable error fields (`code`, `message`,
|
|
3237
|
+
* `externalMessage`) that a Circle service attaches to an HTTP error body.
|
|
3238
|
+
*
|
|
3239
|
+
* `platform-common-go` serializes app-thrown errors under a nested envelope —
|
|
3240
|
+
* `{ response: { status: { code, message, externalMessage } } }` — for every
|
|
3241
|
+
* HTTP status, so this returns that inner `response.status` object when
|
|
3242
|
+
* present. It otherwise falls back to the top-level body so a flattened shape
|
|
3243
|
+
* (e.g. the stablecoin-kits-proxy) is still read. Callers read
|
|
3244
|
+
* `code` / `message` / `externalMessage` off the returned object uniformly.
|
|
3245
|
+
*
|
|
3246
|
+
* @param error - The raw error from the HTTP layer
|
|
3247
|
+
* @returns The error-status fields, or `undefined` when the error carries no
|
|
3248
|
+
* response body
|
|
3249
|
+
* @internal
|
|
3250
|
+
*/ function extractResponseBody$1(error) {
|
|
3251
|
+
if (!hasResponseBody(error)) {
|
|
3252
|
+
return undefined;
|
|
3253
|
+
}
|
|
3254
|
+
const body = error.responseBody;
|
|
3255
|
+
const response = body['response'];
|
|
3256
|
+
if (isRecord(response)) {
|
|
3257
|
+
const status = response['status'];
|
|
3258
|
+
if (isRecord(status)) {
|
|
3259
|
+
return status;
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
return body;
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3138
3265
|
/**
|
|
3139
3266
|
* Proxy-specific structured error codes carried in `responseBody.code`.
|
|
3140
3267
|
*
|
|
@@ -3435,29 +3562,22 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
3435
3562
|
});
|
|
3436
3563
|
}
|
|
3437
3564
|
/**
|
|
3438
|
-
*
|
|
3439
|
-
*
|
|
3565
|
+
* Extract the machine-readable error fields that `makeApiRequest` attaches to
|
|
3566
|
+
* HTTP error instances.
|
|
3440
3567
|
*
|
|
3441
|
-
*
|
|
3442
|
-
*
|
|
3443
|
-
*
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
}
|
|
3447
|
-
/**
|
|
3448
|
-
* Extract the `responseBody` property that `makeApiRequest` attaches to
|
|
3449
|
-
* HTTP error instances when the server returns a JSON body.
|
|
3568
|
+
* Delegates to the shared extractor so this fall-through path reads the same
|
|
3569
|
+
* shape as the backend-code parsers: it unwraps the nested
|
|
3570
|
+
* `{ response: { status } }` envelope when present, otherwise returns the
|
|
3571
|
+
* top-level body. Routing both halves through one extractor keeps an
|
|
3572
|
+
* unmapped-code error from losing the server's `externalMessage`.
|
|
3450
3573
|
*
|
|
3451
3574
|
* @param error - The raw error from the HTTP layer
|
|
3452
|
-
* @returns The parsed body
|
|
3575
|
+
* @returns The parsed body as {@link ApiErrorResponseBody}, or undefined
|
|
3453
3576
|
* @throws Never. Returns `undefined` when the error does not carry a valid
|
|
3454
3577
|
* `responseBody`.
|
|
3455
3578
|
* @internal
|
|
3456
3579
|
*/ function extractResponseBody(error) {
|
|
3457
|
-
|
|
3458
|
-
return undefined;
|
|
3459
|
-
}
|
|
3460
|
-
return error.responseBody;
|
|
3580
|
+
return extractResponseBody$1(error);
|
|
3461
3581
|
}
|
|
3462
3582
|
/**
|
|
3463
3583
|
* Extract a field name from an {@link ApiFieldError}.
|
|
@@ -3566,46 +3686,6 @@ let activeRedactor = defaultMessageRedactor;
|
|
|
3566
3686
|
}
|
|
3567
3687
|
return topMessage ?? fieldDetail;
|
|
3568
3688
|
}
|
|
3569
|
-
/**
|
|
3570
|
-
* Extracts the HTTP status code from an error message.
|
|
3571
|
-
*
|
|
3572
|
-
* Attempts to parse HTTP status codes from common error message formats,
|
|
3573
|
-
* such as "HTTP 404" or "Status: 500".
|
|
3574
|
-
*
|
|
3575
|
-
* @param msg - The error message to extract from
|
|
3576
|
-
* @returns The extracted HTTP status code, or null if not found
|
|
3577
|
-
*
|
|
3578
|
-
* @example
|
|
3579
|
-
* ```typescript
|
|
3580
|
-
* const code = extractHttpStatusCode('HTTP 404')
|
|
3581
|
-
* // Returns: 404
|
|
3582
|
-
* ```
|
|
3583
|
-
*
|
|
3584
|
-
* @example
|
|
3585
|
-
* ```typescript
|
|
3586
|
-
* const code = extractHttpStatusCode('Status: 500 Internal Server Error')
|
|
3587
|
-
* // Returns: 500
|
|
3588
|
-
* ```
|
|
3589
|
-
*/ function extractHttpStatusCode(msg) {
|
|
3590
|
-
// Pattern: "HTTP 404" or "HTTP 404 - some message" or "Status: 404"
|
|
3591
|
-
const patterns = [
|
|
3592
|
-
/HTTP (\d{3})/i,
|
|
3593
|
-
/Status:\s*(\d{3})/i,
|
|
3594
|
-
/^(\d{3}) -/
|
|
3595
|
-
];
|
|
3596
|
-
for (const pattern of patterns){
|
|
3597
|
-
const match = pattern.exec(msg);
|
|
3598
|
-
const codeStr = match?.at(1);
|
|
3599
|
-
if (codeStr !== undefined) {
|
|
3600
|
-
const code = Number.parseInt(codeStr, 10);
|
|
3601
|
-
// Validate it's a valid HTTP status code
|
|
3602
|
-
if (code >= 100 && code < 600) {
|
|
3603
|
-
return code;
|
|
3604
|
-
}
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
return null;
|
|
3608
|
-
}
|
|
3609
3689
|
|
|
3610
3690
|
/**
|
|
3611
3691
|
* @packageDocumentation
|
|
@@ -3861,6 +3941,11 @@ var EarnChain;
|
|
|
3861
3941
|
"Arc",
|
|
3862
3942
|
"Arc_Testnet"
|
|
3863
3943
|
];
|
|
3944
|
+
var BorrowChain;
|
|
3945
|
+
(function(BorrowChain) {
|
|
3946
|
+
BorrowChain["Arc"] = "Arc";
|
|
3947
|
+
BorrowChain["Arc_Testnet"] = "Arc_Testnet";
|
|
3948
|
+
})(BorrowChain || (BorrowChain = {}));
|
|
3864
3949
|
|
|
3865
3950
|
/**
|
|
3866
3951
|
* Helper function to define a chain with proper TypeScript typing.
|
|
@@ -4203,6 +4288,29 @@ var EarnChain;
|
|
|
4203
4288
|
* on EVM-compatible testnet chains. Use this address for testnet adapter
|
|
4204
4289
|
* integrations (e.g., Arc Testnet).
|
|
4205
4290
|
*/ const ADAPTER_CONTRACT_EVM_TESTNET = '0xBBD70b01a1CAbc96d5b7b129Ae1AAabdf50dd40b';
|
|
4291
|
+
/**
|
|
4292
|
+
* The sender-preserving batching contract on Arc (`Multicall3From`).
|
|
4293
|
+
*
|
|
4294
|
+
* This predeploy batches calls like the ubiquitous Multicall3, but routes each
|
|
4295
|
+
* subcall through Arc's `CallFrom` precompile
|
|
4296
|
+
* (`0x1800000000000000000000000000000000000003`), which executes on behalf of
|
|
4297
|
+
* the transaction's original sender. Every target therefore sees the calling
|
|
4298
|
+
* EOA as `msg.sender`, which is what makes a plain, un-upgraded EOA capable of
|
|
4299
|
+
* an atomic batch on Arc.
|
|
4300
|
+
*
|
|
4301
|
+
* Deployed at the same address on Arc Testnet and Arc Mainnet.
|
|
4302
|
+
*
|
|
4303
|
+
* @see https://docs.arc.io/arc/concepts/batched-transactions
|
|
4304
|
+
*/ const BATCHER_CONTRACT_ARC_TESTNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
|
|
4305
|
+
/**
|
|
4306
|
+
* The sender-preserving batching contract on Arc Mainnet (`Multicall3From`).
|
|
4307
|
+
*
|
|
4308
|
+
* See {@link BATCHER_CONTRACT_ARC_TESTNET} for how this contract works.
|
|
4309
|
+
* Requires Arc's Zero7 hardfork, which activates the `CallFrom` precompile
|
|
4310
|
+
* this contract depends on.
|
|
4311
|
+
*
|
|
4312
|
+
* @see https://docs.arc.io/arc/concepts/batched-transactions
|
|
4313
|
+
*/ const BATCHER_CONTRACT_ARC_MAINNET = '0x522fAf9A91c41c443c66765030741e4AaCe147D0';
|
|
4206
4314
|
/**
|
|
4207
4315
|
* The GatewayWallet contract address for EVM mainnet networks.
|
|
4208
4316
|
*
|
|
@@ -4342,7 +4450,10 @@ var EarnChain;
|
|
|
4342
4450
|
},
|
|
4343
4451
|
kitContracts: {
|
|
4344
4452
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4345
|
-
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
4453
|
+
adapter: ADAPTER_CONTRACT_EVM_MAINNET,
|
|
4454
|
+
// Arc is the only chain with a sender-preserving batcher, because it
|
|
4455
|
+
// takes a precompile rather than an ordinary contract to build one.
|
|
4456
|
+
senderPreservingBatcher: BATCHER_CONTRACT_ARC_MAINNET
|
|
4346
4457
|
},
|
|
4347
4458
|
gateway: {
|
|
4348
4459
|
domain: 26,
|
|
@@ -4413,7 +4524,10 @@ var EarnChain;
|
|
|
4413
4524
|
},
|
|
4414
4525
|
kitContracts: {
|
|
4415
4526
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
4416
|
-
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
4527
|
+
adapter: ADAPTER_CONTRACT_EVM_TESTNET,
|
|
4528
|
+
// Arc is the only chain with a sender-preserving batcher, because it
|
|
4529
|
+
// takes a precompile rather than an ordinary contract to build one.
|
|
4530
|
+
senderPreservingBatcher: BATCHER_CONTRACT_ARC_TESTNET
|
|
4417
4531
|
},
|
|
4418
4532
|
gateway: {
|
|
4419
4533
|
domain: 26,
|
|
@@ -8083,7 +8197,8 @@ var Chains = {
|
|
|
8083
8197
|
cctpx: zod.z.any().optional(),
|
|
8084
8198
|
kitContracts: zod.z.object({
|
|
8085
8199
|
bridge: zod.z.string().optional(),
|
|
8086
|
-
adapter: zod.z.string().optional()
|
|
8200
|
+
adapter: zod.z.string().optional(),
|
|
8201
|
+
senderPreservingBatcher: zod.z.string().optional()
|
|
8087
8202
|
}).optional(),
|
|
8088
8203
|
gateway: gatewayConfigSchema.optional()
|
|
8089
8204
|
});
|
|
@@ -8279,6 +8394,38 @@ var Chains = {
|
|
|
8279
8394
|
message: `"${chain.chain}" is not a supported earn chain. ` + `Supported chains: ${Object.values(EarnChain).join(', ')}`
|
|
8280
8395
|
}))
|
|
8281
8396
|
]);
|
|
8397
|
+
/**
|
|
8398
|
+
* Zod schema for validating Borrow-specific chain identifiers.
|
|
8399
|
+
*
|
|
8400
|
+
* Validate that the provided chain is supported for Borrow Kit's loan
|
|
8401
|
+
* operations. Unlike {@link earnChainIdentifierSchema}, this includes Arc
|
|
8402
|
+
* mainnet as well as Arc Testnet.
|
|
8403
|
+
*
|
|
8404
|
+
* Accept a BorrowChain enum value, a matching string literal, or a
|
|
8405
|
+
* ChainDefinition for a supported chain.
|
|
8406
|
+
*
|
|
8407
|
+
* @example
|
|
8408
|
+
* ```typescript
|
|
8409
|
+
* import { borrowChainIdentifierSchema } from '@core/chains'
|
|
8410
|
+
* import { Arc, BorrowChain } from '@core/chains'
|
|
8411
|
+
*
|
|
8412
|
+
* // Valid
|
|
8413
|
+
* borrowChainIdentifierSchema.parse(BorrowChain.Arc)
|
|
8414
|
+
* borrowChainIdentifierSchema.parse('Arc')
|
|
8415
|
+
* borrowChainIdentifierSchema.parse(Arc)
|
|
8416
|
+
*
|
|
8417
|
+
* // Invalid (throws ZodError)
|
|
8418
|
+
* borrowChainIdentifierSchema.parse('Solana')
|
|
8419
|
+
* ```
|
|
8420
|
+
*/ const borrowChainIdentifierSchema = zod.z.union([
|
|
8421
|
+
zod.z.string().refine((val)=>val in BorrowChain, (val)=>({
|
|
8422
|
+
message: `"${val}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
|
|
8423
|
+
})),
|
|
8424
|
+
zod.z.nativeEnum(BorrowChain),
|
|
8425
|
+
chainDefinitionSchema$2.refine((chain)=>chain.chain in BorrowChain, (chain)=>({
|
|
8426
|
+
message: `"${chain.chain}" is not a supported borrow chain. ` + `Supported chains: ${Object.values(BorrowChain).join(', ')}`
|
|
8427
|
+
}))
|
|
8428
|
+
]);
|
|
8282
8429
|
// Widened views so `.includes()` accepts arbitrary strings under strict TS.
|
|
8283
8430
|
const EARN_BRIDGE_SOURCE_CHAIN_VALUES = EARN_BRIDGE_SOURCE_BLOCKCHAINS;
|
|
8284
8431
|
const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS;
|
|
@@ -8489,8 +8636,13 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
8489
8636
|
*/ function resolveChainName(value) {
|
|
8490
8637
|
if (value == null) return undefined;
|
|
8491
8638
|
if (typeof value === 'string') return value;
|
|
8492
|
-
|
|
8493
|
-
|
|
8639
|
+
try {
|
|
8640
|
+
if (typeof value === 'object' && 'chain' in value) {
|
|
8641
|
+
const chain = value.chain;
|
|
8642
|
+
if (typeof chain === 'string') return chain;
|
|
8643
|
+
}
|
|
8644
|
+
} catch {
|
|
8645
|
+
return undefined;
|
|
8494
8646
|
}
|
|
8495
8647
|
return undefined;
|
|
8496
8648
|
}
|
|
@@ -9198,6 +9350,7 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
9198
9350
|
* - Retries on rate limiting (429)
|
|
9199
9351
|
* - Does not retry on client errors (4xx, except 429)
|
|
9200
9352
|
* - Does not retry on validation failures
|
|
9353
|
+
* - Does not retry when `config.isTerminalError` marks the error terminal
|
|
9201
9354
|
*
|
|
9202
9355
|
* Each HTTP request is given a configurable timeout before it is aborted.
|
|
9203
9356
|
* Between retry attempts the wait depends on the `backoff` strategy. The
|
|
@@ -9277,7 +9430,10 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
9277
9430
|
return await makeApiRequest(url, method, isValidType, effectiveConfig, body);
|
|
9278
9431
|
} catch (err) {
|
|
9279
9432
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
9280
|
-
|
|
9433
|
+
// A caller-supplied predicate can mark an error terminal (e.g. a
|
|
9434
|
+
// deterministic 404) so it is surfaced immediately instead of burning
|
|
9435
|
+
// the retry budget on a non-transient answer.
|
|
9436
|
+
if (effectiveConfig.isTerminalError?.(error) === true || !isRetryableError(error)) {
|
|
9281
9437
|
throw error;
|
|
9282
9438
|
}
|
|
9283
9439
|
lastError = error;
|
|
@@ -9361,7 +9517,24 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
9361
9517
|
* // After this call, TypeScript knows params is of type BridgeParams
|
|
9362
9518
|
* ```
|
|
9363
9519
|
*/ function validate(value, schema, context) {
|
|
9364
|
-
|
|
9520
|
+
let result;
|
|
9521
|
+
try {
|
|
9522
|
+
result = schema.safeParse(value);
|
|
9523
|
+
} catch (error) {
|
|
9524
|
+
throw new KitError({
|
|
9525
|
+
...InputError.VALIDATION_FAILED,
|
|
9526
|
+
recoverability: 'FATAL',
|
|
9527
|
+
message: `Invalid ${context}: reading a property threw`,
|
|
9528
|
+
cause: {
|
|
9529
|
+
trace: {
|
|
9530
|
+
validationErrors: [
|
|
9531
|
+
'Reading a property of the value threw'
|
|
9532
|
+
],
|
|
9533
|
+
originalError: error
|
|
9534
|
+
}
|
|
9535
|
+
}
|
|
9536
|
+
});
|
|
9537
|
+
}
|
|
9365
9538
|
if (!result.success) {
|
|
9366
9539
|
throw createValidationErrorFromZod(result.error, context);
|
|
9367
9540
|
}
|
|
@@ -12062,11 +12235,11 @@ function resolveOptions(options) {
|
|
|
12062
12235
|
void emitAnalyticsLog(buildPayload(config, stepEntry?.[1] ?? fallbackEventType, errorDetails, context));
|
|
12063
12236
|
}
|
|
12064
12237
|
|
|
12065
|
-
var name$
|
|
12066
|
-
var version$
|
|
12067
|
-
var pkg$
|
|
12068
|
-
name: name$
|
|
12069
|
-
version: version$
|
|
12238
|
+
var name$3 = "@circle-fin/bridge-kit";
|
|
12239
|
+
var version$4 = "1.15.2";
|
|
12240
|
+
var pkg$4 = {
|
|
12241
|
+
name: name$3,
|
|
12242
|
+
version: version$4};
|
|
12070
12243
|
|
|
12071
12244
|
const assertCustomFeePolicySymbol = Symbol('assertCustomFeePolicy');
|
|
12072
12245
|
/**
|
|
@@ -12635,6 +12808,12 @@ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
|
|
|
12635
12808
|
/** EIP-2612 standard permit */ PermitType[PermitType["EIP2612"] = 1] = "EIP2612";
|
|
12636
12809
|
})(PermitType || (PermitType = {}));
|
|
12637
12810
|
|
|
12811
|
+
var BorrowPermitType;
|
|
12812
|
+
(function(BorrowPermitType) {
|
|
12813
|
+
/** Tokens must be approved separately. */ BorrowPermitType[BorrowPermitType["NONE"] = 0] = "NONE";
|
|
12814
|
+
/** EIP-2612 permit calldata accompanies the token input. */ BorrowPermitType[BorrowPermitType["EIP2612"] = 1] = "EIP2612";
|
|
12815
|
+
})(BorrowPermitType || (BorrowPermitType = {}));
|
|
12816
|
+
|
|
12638
12817
|
/**
|
|
12639
12818
|
* Abstract base class for bridging providers that implement cross-chain bridging protocols.
|
|
12640
12819
|
*
|
|
@@ -19758,7 +19937,7 @@ const defaultSleep = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms))
|
|
|
19758
19937
|
* Must always contain both adapter and chain explicitly.
|
|
19759
19938
|
*
|
|
19760
19939
|
* Optionally includes address for developer-controlled adapters.
|
|
19761
|
-
*/ const adapterContextSchema$
|
|
19940
|
+
*/ const adapterContextSchema$4 = zod.z.object({
|
|
19762
19941
|
adapter: adapterSchema,
|
|
19763
19942
|
chain: bridgeChainIdentifierSchema,
|
|
19764
19943
|
address: zod.z.string().optional()
|
|
@@ -19767,14 +19946,14 @@ const defaultSleep = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms))
|
|
|
19767
19946
|
* Schema for validating BridgeDestinationWithAddress objects.
|
|
19768
19947
|
* Contains an explicit recipientAddress along with adapter and chain.
|
|
19769
19948
|
* The address format is validated based on the chain type (EVM or Solana).
|
|
19770
|
-
*/ const bridgeDestinationWithAddressSchema = adapterContextSchema$
|
|
19949
|
+
*/ const bridgeDestinationWithAddressSchema = adapterContextSchema$4.extend({
|
|
19771
19950
|
recipientAddress: zod.z.string().min(1, 'Recipient address is required'),
|
|
19772
19951
|
useForwarder: zod.z.boolean().optional()
|
|
19773
19952
|
}).superRefine(createRecipientAddressValidator());
|
|
19774
19953
|
/**
|
|
19775
19954
|
* Schema for validating AdapterContext with optional useForwarder.
|
|
19776
19955
|
* Extends adapterContextSchema with the useForwarder flag.
|
|
19777
|
-
*/ const adapterContextWithForwarderSchema = adapterContextSchema$
|
|
19956
|
+
*/ const adapterContextWithForwarderSchema = adapterContextSchema$4.extend({
|
|
19778
19957
|
useForwarder: zod.z.boolean().optional()
|
|
19779
19958
|
});
|
|
19780
19959
|
/**
|
|
@@ -19849,7 +20028,7 @@ const defaultSleep = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms))
|
|
|
19849
20028
|
* }
|
|
19850
20029
|
* ```
|
|
19851
20030
|
*/ const bridgeParamsWithChainIdentifierSchema = zod.z.object({
|
|
19852
|
-
from: adapterContextSchema$
|
|
20031
|
+
from: adapterContextSchema$4.strict(),
|
|
19853
20032
|
to: bridgeDestinationSchema,
|
|
19854
20033
|
amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
|
|
19855
20034
|
allowZero: false,
|
|
@@ -20009,7 +20188,7 @@ const defaultSleep = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms))
|
|
|
20009
20188
|
const bridgeKitCaller = {
|
|
20010
20189
|
type: 'kit',
|
|
20011
20190
|
name: 'BridgeKit',
|
|
20012
|
-
version: pkg$
|
|
20191
|
+
version: pkg$4.version
|
|
20013
20192
|
};
|
|
20014
20193
|
// Create default runtime and tokens for invocation context resolution
|
|
20015
20194
|
const defaults = {
|
|
@@ -23228,16 +23407,16 @@ const mockAttestationMessage = {
|
|
|
23228
23407
|
return step;
|
|
23229
23408
|
}
|
|
23230
23409
|
|
|
23231
|
-
var version$
|
|
23232
|
-
var pkg$
|
|
23233
|
-
version: version$
|
|
23410
|
+
var version$3 = "1.14.1";
|
|
23411
|
+
var pkg$3 = {
|
|
23412
|
+
version: version$3};
|
|
23234
23413
|
|
|
23235
23414
|
/**
|
|
23236
23415
|
* Provider caller component for bridge operations.
|
|
23237
23416
|
*/ const BRIDGE_CALLER = {
|
|
23238
23417
|
type: 'provider',
|
|
23239
23418
|
name: 'CCTPV2BridgingProvider.bridge',
|
|
23240
|
-
version: pkg$
|
|
23419
|
+
version: pkg$3.version
|
|
23241
23420
|
};
|
|
23242
23421
|
/**
|
|
23243
23422
|
* Resolve invocation context for bridge operations.
|
|
@@ -23610,7 +23789,7 @@ var pkg$2 = {
|
|
|
23610
23789
|
*/ const RETRY_CALLER = {
|
|
23611
23790
|
type: 'provider',
|
|
23612
23791
|
name: 'CCTPV2BridgingProvider.retry',
|
|
23613
|
-
version: pkg$
|
|
23792
|
+
version: pkg$3.version
|
|
23614
23793
|
};
|
|
23615
23794
|
/**
|
|
23616
23795
|
* Resolve invocation context for retry operations.
|
|
@@ -25537,7 +25716,7 @@ function assertCCTPV2Config(config) {
|
|
|
25537
25716
|
* Decimal string in token minor units, constrained to be strictly positive.
|
|
25538
25717
|
*
|
|
25539
25718
|
* @internal
|
|
25540
|
-
*/ const positiveAmountSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
|
|
25719
|
+
*/ const positiveAmountSchema$1 = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
|
|
25541
25720
|
// regex check above fails ("dirty"), so guard BigInt() against throwing on a
|
|
25542
25721
|
// non-numeric value before comparing.
|
|
25543
25722
|
.refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
|
|
@@ -25617,7 +25796,7 @@ const preFinalityRequestSchema = zod.z.object({
|
|
|
25617
25796
|
*/ const fetchFeeQuoteInputSchema = zod.z.object({
|
|
25618
25797
|
sourceDomain: zod.z.number().int().nonnegative(),
|
|
25619
25798
|
destinationDomain: zod.z.number().int().nonnegative(),
|
|
25620
|
-
amount: positiveAmountSchema,
|
|
25799
|
+
amount: positiveAmountSchema$1,
|
|
25621
25800
|
feeToken: evmAddressSchema.optional(),
|
|
25622
25801
|
requests: feeQuoteRequestsSchema,
|
|
25623
25802
|
isTestnet: zod.z.boolean(),
|
|
@@ -26494,7 +26673,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26494
26673
|
* The ERC-20 `decimals` field is a `uint8`, so a provider reporting more than
|
|
26495
26674
|
* this is returning something that cannot describe a real token.
|
|
26496
26675
|
*/ const MAX_TOKEN_DECIMALS = 255;
|
|
26497
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME = resolveKitSdkName(pkg$
|
|
26676
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME = resolveKitSdkName(pkg$4.name);
|
|
26498
26677
|
/**
|
|
26499
26678
|
* Pick the most-relevant `txHash` to attach to an error telemetry payload.
|
|
26500
26679
|
*
|
|
@@ -26535,7 +26714,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26535
26714
|
*/ const BRIDGE_KIT_CALLER = {
|
|
26536
26715
|
type: 'kit',
|
|
26537
26716
|
name: 'BridgeKit',
|
|
26538
|
-
version: pkg$
|
|
26717
|
+
version: pkg$4.version
|
|
26539
26718
|
};
|
|
26540
26719
|
/**
|
|
26541
26720
|
* Merge BridgeKit's caller into the invocation metadata for retry operations.
|
|
@@ -26683,7 +26862,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26683
26862
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
26684
26863
|
this.telemetryConfig = {
|
|
26685
26864
|
sdkName: SDK_NAME,
|
|
26686
|
-
sdkVersion: pkg$
|
|
26865
|
+
sdkVersion: pkg$4.version,
|
|
26687
26866
|
disabled: this.disableErrorReporting
|
|
26688
26867
|
};
|
|
26689
26868
|
for (const provider of this.providers){
|
|
@@ -27407,7 +27586,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
27407
27586
|
}
|
|
27408
27587
|
|
|
27409
27588
|
// Auto-register this kit for user agent tracking
|
|
27410
|
-
registerKit(`${pkg$
|
|
27589
|
+
registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
27411
27590
|
|
|
27412
27591
|
/**
|
|
27413
27592
|
* Create a BridgeKit instance with optional developer fee configuration.
|
|
@@ -27478,11 +27657,11 @@ registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
|
27478
27657
|
return kit;
|
|
27479
27658
|
};
|
|
27480
27659
|
|
|
27481
|
-
var name$
|
|
27482
|
-
var version$
|
|
27483
|
-
var pkg$
|
|
27484
|
-
name: name$
|
|
27485
|
-
version: version$
|
|
27660
|
+
var name$2 = "@circle-fin/swap-kit";
|
|
27661
|
+
var version$2 = "1.7.1";
|
|
27662
|
+
var pkg$2 = {
|
|
27663
|
+
name: name$2,
|
|
27664
|
+
version: version$2};
|
|
27486
27665
|
|
|
27487
27666
|
const chainIdentifierField = zod.z.custom((value)=>chainIdentifierSchema.safeParse(value).success, {
|
|
27488
27667
|
message: 'chain must be a valid chain identifier'
|
|
@@ -27563,7 +27742,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
|
|
|
27563
27742
|
*
|
|
27564
27743
|
* @remarks
|
|
27565
27744
|
* Optionally includes address for developer-controlled adapters.
|
|
27566
|
-
*/ const adapterContextSchema$
|
|
27745
|
+
*/ const adapterContextSchema$3 = zod.z.object({
|
|
27567
27746
|
adapter: adapterSchema,
|
|
27568
27747
|
chain: chainIdentifierField,
|
|
27569
27748
|
address: zod.z.string().optional()
|
|
@@ -27584,7 +27763,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
|
|
|
27584
27763
|
* }
|
|
27585
27764
|
* ```
|
|
27586
27765
|
*/ zod.z.object({
|
|
27587
|
-
from: adapterContextSchema$
|
|
27766
|
+
from: adapterContextSchema$3,
|
|
27588
27767
|
tokenIn: zod.z.string({
|
|
27589
27768
|
required_error: 'tokenIn is required',
|
|
27590
27769
|
invalid_type_error: 'tokenIn must be a string'
|
|
@@ -28312,36 +28491,176 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
28312
28491
|
return normalize(source.apiKey) ?? normalize(source.kitKey);
|
|
28313
28492
|
};
|
|
28314
28493
|
|
|
28494
|
+
function isBigIntLike$1(value) {
|
|
28495
|
+
try {
|
|
28496
|
+
BigInt(value);
|
|
28497
|
+
return true;
|
|
28498
|
+
} catch {
|
|
28499
|
+
return false;
|
|
28500
|
+
}
|
|
28501
|
+
}
|
|
28502
|
+
function isNonNegativeBigIntLike$3(value) {
|
|
28503
|
+
try {
|
|
28504
|
+
return BigInt(value) >= 0n;
|
|
28505
|
+
} catch {
|
|
28506
|
+
return false;
|
|
28507
|
+
}
|
|
28508
|
+
}
|
|
28315
28509
|
/**
|
|
28316
|
-
*
|
|
28510
|
+
* A `0x`-prefixed, even-length hex byte string (`'0x'` for empty calldata).
|
|
28317
28511
|
*
|
|
28318
|
-
*
|
|
28319
|
-
|
|
28320
|
-
|
|
28512
|
+
* @internal
|
|
28513
|
+
*/ const hexBytesSchema$3 = zod.z.union([
|
|
28514
|
+
hexStringSchema,
|
|
28515
|
+
zod.z.literal('0x')
|
|
28516
|
+
]).refine((value)=>value.length % 2 === 0, {
|
|
28517
|
+
message: 'value must be a 0x-prefixed even-length hex string'
|
|
28518
|
+
});
|
|
28519
|
+
/**
|
|
28520
|
+
* A non-negative uint256, accepted as a decimal string or a `bigint`.
|
|
28321
28521
|
*
|
|
28322
|
-
* @
|
|
28323
|
-
|
|
28324
|
-
|
|
28325
|
-
|
|
28522
|
+
* @internal
|
|
28523
|
+
*/ const uint256LikeSchema$3 = zod.z.union([
|
|
28524
|
+
zod.z.string(),
|
|
28525
|
+
zod.z.bigint()
|
|
28526
|
+
]).refine(isNonNegativeBigIntLike$3, {
|
|
28527
|
+
message: 'value must be a non-negative bigint-compatible string or bigint'
|
|
28528
|
+
});
|
|
28529
|
+
/**
|
|
28530
|
+
* A typed base-unit amount object as emitted by the API.
|
|
28326
28531
|
*
|
|
28327
|
-
*
|
|
28328
|
-
|
|
28329
|
-
|
|
28532
|
+
* @internal
|
|
28533
|
+
*/ const amountJsonSchema$2 = zod.z.object({
|
|
28534
|
+
raw: zod.z.string().refine(isBigIntLike$1, {
|
|
28535
|
+
message: 'raw must be a bigint-compatible string'
|
|
28536
|
+
}),
|
|
28537
|
+
decimals: zod.z.number().int().nonnegative()
|
|
28538
|
+
});
|
|
28539
|
+
/**
|
|
28540
|
+
* One instruction in a signed claim-rewards execution payload.
|
|
28330
28541
|
*
|
|
28331
|
-
*
|
|
28332
|
-
* ```typescript
|
|
28333
|
-
* import { AdapterCapabilitiesSchema } from '@core/adapter-evm/validation'
|
|
28334
|
-
* import { Ethereum, Base } from '@core/chains'
|
|
28542
|
+
* `.passthrough()` so a backend that adds a field does not fail validation.
|
|
28335
28543
|
*
|
|
28336
|
-
*
|
|
28337
|
-
|
|
28338
|
-
|
|
28339
|
-
|
|
28340
|
-
|
|
28544
|
+
* @internal
|
|
28545
|
+
*/ const claimRewardsInstructionSchema = zod.z.object({
|
|
28546
|
+
target: evmAddressSchema$1,
|
|
28547
|
+
data: hexBytesSchema$3,
|
|
28548
|
+
value: uint256LikeSchema$3,
|
|
28549
|
+
tokenIn: evmAddressSchema$1,
|
|
28550
|
+
amountToApprove: uint256LikeSchema$3,
|
|
28551
|
+
tokenOut: evmAddressSchema$1,
|
|
28552
|
+
minTokenOut: uint256LikeSchema$3
|
|
28553
|
+
}).passthrough();
|
|
28554
|
+
const claimRewardsTokenSchema = zod.z.object({
|
|
28555
|
+
token: evmAddressSchema$1,
|
|
28556
|
+
beneficiary: evmAddressSchema$1
|
|
28557
|
+
}).passthrough();
|
|
28558
|
+
/**
|
|
28559
|
+
* The signed execution payload the `earn.claimRewards` Adapter action takes.
|
|
28341
28560
|
*
|
|
28342
|
-
*
|
|
28343
|
-
|
|
28344
|
-
|
|
28561
|
+
* @internal
|
|
28562
|
+
*/ const claimRewardsExecutionParamsSchema = zod.z.object({
|
|
28563
|
+
instructions: zod.z.tuple([
|
|
28564
|
+
claimRewardsInstructionSchema
|
|
28565
|
+
]).rest(claimRewardsInstructionSchema),
|
|
28566
|
+
tokens: zod.z.tuple([
|
|
28567
|
+
claimRewardsTokenSchema
|
|
28568
|
+
]).rest(claimRewardsTokenSchema),
|
|
28569
|
+
execId: uint256LikeSchema$3,
|
|
28570
|
+
deadline: uint256LikeSchema$3,
|
|
28571
|
+
metadata: hexBytesSchema$3
|
|
28572
|
+
}).passthrough();
|
|
28573
|
+
/**
|
|
28574
|
+
* A single claimable reward entry in a claim-rewards response.
|
|
28575
|
+
*
|
|
28576
|
+
* @internal
|
|
28577
|
+
*/ const claimedAmountSchema = zod.z.object({
|
|
28578
|
+
token: evmAddressSchema$1,
|
|
28579
|
+
symbol: zod.z.string(),
|
|
28580
|
+
amount: amountJsonSchema$2
|
|
28581
|
+
});
|
|
28582
|
+
/**
|
|
28583
|
+
* The `data` envelope of a claim-rewards response.
|
|
28584
|
+
*
|
|
28585
|
+
* `executionParams` and `signature` are present exactly when rewards are
|
|
28586
|
+
* claimable — never one without the other, and never either when `rewards`
|
|
28587
|
+
* is empty.
|
|
28588
|
+
*
|
|
28589
|
+
* @internal
|
|
28590
|
+
*/ const claimRewardsPayloadSchema = zod.z.object({
|
|
28591
|
+
rewards: zod.z.array(claimedAmountSchema),
|
|
28592
|
+
executionParams: claimRewardsExecutionParamsSchema.optional(),
|
|
28593
|
+
signature: evmSignatureSchema.optional()
|
|
28594
|
+
}).refine((data)=>{
|
|
28595
|
+
const signedFieldCount = (data.executionParams === undefined ? 0 : 1) + (data.signature === undefined ? 0 : 1);
|
|
28596
|
+
if (data.rewards.length > 0) {
|
|
28597
|
+
return signedFieldCount === 2;
|
|
28598
|
+
}
|
|
28599
|
+
return signedFieldCount === 0;
|
|
28600
|
+
}, {
|
|
28601
|
+
message: 'claim rewards response must include executionParams and signature only when rewards are claimable'
|
|
28602
|
+
});
|
|
28603
|
+
/**
|
|
28604
|
+
* Zod schema for a claim-rewards API response.
|
|
28605
|
+
*
|
|
28606
|
+
* @internal
|
|
28607
|
+
*/ zod.z.object({
|
|
28608
|
+
data: claimRewardsPayloadSchema
|
|
28609
|
+
});
|
|
28610
|
+
/**
|
|
28611
|
+
* A single claimable reward entry in a claim-rewards quote response.
|
|
28612
|
+
*
|
|
28613
|
+
* @internal
|
|
28614
|
+
*/ const claimRewardsQuoteRewardSchema = zod.z.object({
|
|
28615
|
+
token: zod.z.string(),
|
|
28616
|
+
symbol: zod.z.string(),
|
|
28617
|
+
amount: amountJsonSchema$2
|
|
28618
|
+
});
|
|
28619
|
+
/**
|
|
28620
|
+
* The `data` envelope of a claim-rewards quote response.
|
|
28621
|
+
*
|
|
28622
|
+
* @internal
|
|
28623
|
+
*/ const claimRewardsQuotePayloadSchema = zod.z.object({
|
|
28624
|
+
rewards: zod.z.array(claimRewardsQuoteRewardSchema)
|
|
28625
|
+
});
|
|
28626
|
+
/**
|
|
28627
|
+
* Zod schema for a claim-rewards quote API response.
|
|
28628
|
+
*
|
|
28629
|
+
* @internal
|
|
28630
|
+
*/ zod.z.object({
|
|
28631
|
+
data: claimRewardsQuotePayloadSchema
|
|
28632
|
+
});
|
|
28633
|
+
|
|
28634
|
+
/**
|
|
28635
|
+
* Zod schema for validating EVM adapter capabilities.
|
|
28636
|
+
*
|
|
28637
|
+
* This schema ensures that EVM adapter capabilities meet the requirements for the
|
|
28638
|
+
* OperationContext pattern by validating the addressContext property and ensuring
|
|
28639
|
+
* the supportedChains property contains only EVM-compatible chains.
|
|
28640
|
+
*
|
|
28641
|
+
* @remarks
|
|
28642
|
+
* This schema enforces that all supported chains are EVM type, making it specific
|
|
28643
|
+
* to EVM adapters (Ethers, Viem, etc.). For non-EVM adapters, a different validation
|
|
28644
|
+
* schema should be used.
|
|
28645
|
+
*
|
|
28646
|
+
* When used with the validate() function from @core/utils, this throws KitError
|
|
28647
|
+
* with INPUT_VALIDATION_FAILED code if validation fails, with details about which
|
|
28648
|
+
* properties failed.
|
|
28649
|
+
*
|
|
28650
|
+
* @example
|
|
28651
|
+
* ```typescript
|
|
28652
|
+
* import { AdapterCapabilitiesSchema } from '@core/adapter-evm/validation'
|
|
28653
|
+
* import { Ethereum, Base } from '@core/chains'
|
|
28654
|
+
*
|
|
28655
|
+
* // Valid user-controlled capabilities
|
|
28656
|
+
* const userCapabilities = {
|
|
28657
|
+
* addressContext: 'user-controlled',
|
|
28658
|
+
* supportedChains: [Ethereum, Base]
|
|
28659
|
+
* }
|
|
28660
|
+
*
|
|
28661
|
+
* // Valid developer-controlled capabilities
|
|
28662
|
+
* const devCapabilities = {
|
|
28663
|
+
* addressContext: 'developer-controlled',
|
|
28345
28664
|
* supportedChains: [Ethereum]
|
|
28346
28665
|
* }
|
|
28347
28666
|
*
|
|
@@ -28739,7 +29058,7 @@ const abiParameterSchema = zod.z.object({
|
|
|
28739
29058
|
* const result = evmPreparedChainRequestParamsSchema.safeParse(params)
|
|
28740
29059
|
* ```
|
|
28741
29060
|
*/ zod.z.object({
|
|
28742
|
-
type: zod.z.literal('evm'),
|
|
29061
|
+
type: zod.z.literal('evm').optional(),
|
|
28743
29062
|
abi: abiSchema,
|
|
28744
29063
|
address: evmAddressSchema$1,
|
|
28745
29064
|
functionName: zod.z.string({
|
|
@@ -28856,7 +29175,7 @@ const abiParameterSchema = zod.z.object({
|
|
|
28856
29175
|
message: 'Private key must be a valid 64-character hex string. Please provide a valid private key with or without "0x" prefix.'
|
|
28857
29176
|
}));
|
|
28858
29177
|
|
|
28859
|
-
const hexBytesSchema$
|
|
29178
|
+
const hexBytesSchema$2 = zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
|
|
28860
29179
|
message: 'value must be a 0x-prefixed even-length hex string'
|
|
28861
29180
|
}).transform((value)=>value);
|
|
28862
29181
|
zod.z.object({
|
|
@@ -28868,6 +29187,53 @@ zod.z.object({
|
|
|
28868
29187
|
amount: zod.z.bigint().refine((value)=>value >= 0n, {
|
|
28869
29188
|
message: 'amount must be a non-negative bigint'
|
|
28870
29189
|
}),
|
|
29190
|
+
permitCalldata: hexBytesSchema$2
|
|
29191
|
+
}))
|
|
29192
|
+
}).passthrough();
|
|
29193
|
+
|
|
29194
|
+
const hexBytesSchema$1 = zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, {
|
|
29195
|
+
message: 'value must be a 0x-prefixed even-length hex string'
|
|
29196
|
+
}).transform((value)=>value);
|
|
29197
|
+
function isNonNegativeBigIntLike$2(value) {
|
|
29198
|
+
try {
|
|
29199
|
+
return BigInt(value) >= 0n;
|
|
29200
|
+
} catch {
|
|
29201
|
+
return false;
|
|
29202
|
+
}
|
|
29203
|
+
}
|
|
29204
|
+
const uint256LikeSchema$2 = zod.z.union([
|
|
29205
|
+
zod.z.string(),
|
|
29206
|
+
zod.z.bigint()
|
|
29207
|
+
]).refine(isNonNegativeBigIntLike$2, {
|
|
29208
|
+
message: 'value must be a non-negative bigint-compatible string or bigint'
|
|
29209
|
+
});
|
|
29210
|
+
const borrowExecutionParamsSchema$1 = zod.z.object({
|
|
29211
|
+
instructions: zod.z.array(zod.z.object({
|
|
29212
|
+
target: evmAddressSchema$1,
|
|
29213
|
+
data: hexBytesSchema$1,
|
|
29214
|
+
value: uint256LikeSchema$2,
|
|
29215
|
+
tokenIn: evmAddressSchema$1,
|
|
29216
|
+
amountToApprove: uint256LikeSchema$2,
|
|
29217
|
+
tokenOut: evmAddressSchema$1,
|
|
29218
|
+
minTokenOut: uint256LikeSchema$2
|
|
29219
|
+
}).passthrough()).min(1),
|
|
29220
|
+
tokens: zod.z.array(zod.z.object({
|
|
29221
|
+
token: evmAddressSchema$1,
|
|
29222
|
+
beneficiary: evmAddressSchema$1
|
|
29223
|
+
}).passthrough()),
|
|
29224
|
+
execId: uint256LikeSchema$2,
|
|
29225
|
+
deadline: uint256LikeSchema$2,
|
|
29226
|
+
metadata: hexBytesSchema$1
|
|
29227
|
+
}).passthrough();
|
|
29228
|
+
zod.z.object({
|
|
29229
|
+
executeParams: borrowExecutionParamsSchema$1,
|
|
29230
|
+
signature: evmSignatureSchema,
|
|
29231
|
+
tokenInputs: zod.z.array(zod.z.object({
|
|
29232
|
+
permitType: zod.z.nativeEnum(BorrowPermitType),
|
|
29233
|
+
token: evmAddressSchema$1,
|
|
29234
|
+
amount: zod.z.bigint().refine((value)=>value >= 0n, {
|
|
29235
|
+
message: 'amount must be a non-negative bigint'
|
|
29236
|
+
}),
|
|
28871
29237
|
permitCalldata: hexBytesSchema$1
|
|
28872
29238
|
}))
|
|
28873
29239
|
}).passthrough();
|
|
@@ -29260,7 +29626,7 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
|
|
|
29260
29626
|
* Schema for validating AdapterContext.
|
|
29261
29627
|
* Must always contain both adapter and chain explicitly.
|
|
29262
29628
|
* Optionally includes address for developer-controlled adapters.
|
|
29263
|
-
*/ const adapterContextSchema$
|
|
29629
|
+
*/ const adapterContextSchema$2 = zod.z.object({
|
|
29264
29630
|
adapter: adapterSchema,
|
|
29265
29631
|
chain: swapChainIdentifierField,
|
|
29266
29632
|
address: zod.z.string().optional()
|
|
@@ -29321,7 +29687,7 @@ const swapDestinationSchema = zod.z.object({
|
|
|
29321
29687
|
message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
|
|
29322
29688
|
}).optional()
|
|
29323
29689
|
}).strict();
|
|
29324
|
-
const EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
29690
|
+
const EVM_ADDRESS_REGEX$1 = /^0x[a-fA-F0-9]{40}$/;
|
|
29325
29691
|
const SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
29326
29692
|
const BASE58_CHARS_REGEX = /^[1-9A-HJ-NP-Za-km-z]+$/;
|
|
29327
29693
|
/**
|
|
@@ -29364,7 +29730,7 @@ const MAX_DISPLAY_LENGTH = 30;
|
|
|
29364
29730
|
*/ let _symbolResult;
|
|
29365
29731
|
const swapTokenSchema = zod.z.string().superRefine((value, ctx)=>{
|
|
29366
29732
|
if (value.startsWith('0x')) {
|
|
29367
|
-
if (!EVM_ADDRESS_REGEX.test(value)) {
|
|
29733
|
+
if (!EVM_ADDRESS_REGEX$1.test(value)) {
|
|
29368
29734
|
ctx.addIssue({
|
|
29369
29735
|
code: zod.z.ZodIssueCode.custom,
|
|
29370
29736
|
message: `Invalid EVM token address format. Expected '0x' followed by 40 hexadecimal characters, but received: '${truncate(value)}'`
|
|
@@ -29459,7 +29825,7 @@ const amountInSchema = zod.z.string().min(1, 'Required').pipe(createDecimalStrin
|
|
|
29459
29825
|
* }
|
|
29460
29826
|
* ```
|
|
29461
29827
|
*/ zod.z.object({
|
|
29462
|
-
from: adapterContextSchema$
|
|
29828
|
+
from: adapterContextSchema$2,
|
|
29463
29829
|
tokenIn: swapTokenSchema,
|
|
29464
29830
|
tokenOut: swapTokenSchema,
|
|
29465
29831
|
amountIn: amountInSchema,
|
|
@@ -29500,16 +29866,16 @@ new Set(Object.values(Blockchain));
|
|
|
29500
29866
|
|
|
29501
29867
|
new Set(Object.values(Blockchain));
|
|
29502
29868
|
|
|
29503
|
-
/** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$
|
|
29869
|
+
/** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$2.name);
|
|
29504
29870
|
|
|
29505
29871
|
// Auto-register this kit for user agent tracking
|
|
29506
|
-
registerKit(`${pkg$
|
|
29872
|
+
registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
29507
29873
|
|
|
29508
|
-
var name = "@circle-fin/earn-kit";
|
|
29509
|
-
var version = "1.
|
|
29510
|
-
var pkg = {
|
|
29511
|
-
name: name,
|
|
29512
|
-
version: version};
|
|
29874
|
+
var name$1 = "@circle-fin/earn-kit";
|
|
29875
|
+
var version$1 = "1.8.1";
|
|
29876
|
+
var pkg$1 = {
|
|
29877
|
+
name: name$1,
|
|
29878
|
+
version: version$1};
|
|
29513
29879
|
|
|
29514
29880
|
/**
|
|
29515
29881
|
* Map SDK chain identifiers to bridge API chain strings.
|
|
@@ -29581,7 +29947,7 @@ function isBigIntLike(value) {
|
|
|
29581
29947
|
return false;
|
|
29582
29948
|
}
|
|
29583
29949
|
}
|
|
29584
|
-
function isNonNegativeBigIntLike(value) {
|
|
29950
|
+
function isNonNegativeBigIntLike$1(value) {
|
|
29585
29951
|
try {
|
|
29586
29952
|
return BigInt(value) >= 0n;
|
|
29587
29953
|
} catch {
|
|
@@ -29601,28 +29967,22 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29601
29967
|
* unchanged so signed execution params can be forwarded verbatim.
|
|
29602
29968
|
*
|
|
29603
29969
|
* @internal
|
|
29604
|
-
*/ const uint256LikeSchema = zod.z.union([
|
|
29970
|
+
*/ const uint256LikeSchema$1 = zod.z.union([
|
|
29605
29971
|
zod.z.string(),
|
|
29606
29972
|
zod.z.bigint()
|
|
29607
|
-
]).refine(isNonNegativeBigIntLike, {
|
|
29973
|
+
]).refine(isNonNegativeBigIntLike$1, {
|
|
29608
29974
|
message: 'value must be a non-negative bigint-compatible string or bigint'
|
|
29609
29975
|
});
|
|
29610
29976
|
/**
|
|
29611
29977
|
* Zod schema for typed amount objects emitted by the API.
|
|
29612
29978
|
*
|
|
29613
29979
|
* @internal
|
|
29614
|
-
*/ const amountJsonSchema = zod.z.object({
|
|
29980
|
+
*/ const amountJsonSchema$1 = zod.z.object({
|
|
29615
29981
|
raw: zod.z.string().refine(isBigIntLike, {
|
|
29616
29982
|
message: 'raw must be a bigint-compatible string'
|
|
29617
29983
|
}),
|
|
29618
29984
|
decimals: zod.z.number().int().nonnegative()
|
|
29619
29985
|
});
|
|
29620
|
-
/** @internal */ const hexBytesSchema = zod.z.union([
|
|
29621
|
-
hexStringSchema,
|
|
29622
|
-
zod.z.literal('0x')
|
|
29623
|
-
]).refine((value)=>value.length % 2 === 0, {
|
|
29624
|
-
message: 'value must be a 0x-prefixed even-length hex string'
|
|
29625
|
-
});
|
|
29626
29986
|
/** @internal */ const bytes32HexSchema = hexStringSchema.refine((value)=>value.length === BYTES32_HEX_LENGTH, {
|
|
29627
29987
|
message: 'value must be a 0x-prefixed 32-byte hex string'
|
|
29628
29988
|
});
|
|
@@ -29648,10 +30008,8 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29648
30008
|
assetAddress: zod.z.string(),
|
|
29649
30009
|
lltv: zod.z.number(),
|
|
29650
30010
|
supplyUsd: zod.z.number(),
|
|
29651
|
-
//
|
|
29652
|
-
|
|
29653
|
-
// schema; `null` when the product exposes no per-market allocation (V2).
|
|
29654
|
-
allocationPct: zod.z.number().nullable().optional()
|
|
30011
|
+
// `null` when the product exposes no per-market allocation (V2).
|
|
30012
|
+
allocationPct: zod.z.number().nullable()
|
|
29655
30013
|
});
|
|
29656
30014
|
/**
|
|
29657
30015
|
* Zod schema for a Morpho vault warning in the API response.
|
|
@@ -29708,9 +30066,9 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29708
30066
|
*
|
|
29709
30067
|
* @internal
|
|
29710
30068
|
*/ const liquidityProfileSchema = zod.z.object({
|
|
29711
|
-
totalDeposits: amountJsonSchema,
|
|
29712
|
-
available: amountJsonSchema,
|
|
29713
|
-
totalSupply: amountJsonSchema,
|
|
30069
|
+
totalDeposits: amountJsonSchema$1,
|
|
30070
|
+
available: amountJsonSchema$1,
|
|
30071
|
+
totalSupply: amountJsonSchema$1,
|
|
29714
30072
|
status: zod.z.enum([
|
|
29715
30073
|
'active',
|
|
29716
30074
|
'low_liquidity'
|
|
@@ -29747,8 +30105,8 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29747
30105
|
vaultFee: zod.z.number(),
|
|
29748
30106
|
rewards: zod.z.array(vaultRewardSchema),
|
|
29749
30107
|
collateral: zod.z.array(collateralSchema),
|
|
29750
|
-
totalDeposits: amountJsonSchema,
|
|
29751
|
-
liquidity: amountJsonSchema,
|
|
30108
|
+
totalDeposits: amountJsonSchema$1,
|
|
30109
|
+
liquidity: amountJsonSchema$1,
|
|
29752
30110
|
status: zod.z.enum([
|
|
29753
30111
|
'active',
|
|
29754
30112
|
'low_liquidity'
|
|
@@ -29758,19 +30116,20 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29758
30116
|
earnKitWarnings: zod.z.array(zod.z.string()).optional()
|
|
29759
30117
|
});
|
|
29760
30118
|
/**
|
|
29761
|
-
* Shared base schema: existing flat fields (kept
|
|
29762
|
-
* facets
|
|
29763
|
-
*
|
|
30119
|
+
* Shared base schema: existing flat fields (kept as deprecated aliases) plus
|
|
30120
|
+
* the nested facets. Zenith emits all facets on every response; required here
|
|
30121
|
+
* so a partial emission is caught at parse time rather than surfacing as a
|
|
30122
|
+
* runtime `undefined` access.
|
|
29764
30123
|
*
|
|
29765
30124
|
* @internal
|
|
29766
30125
|
*/ const earnBaseSchema = vaultInfoResponseSchema.extend({
|
|
29767
|
-
address: zod.z.string()
|
|
29768
|
-
asOf: zod.z.string()
|
|
29769
|
-
manager: managerSchema.nullable()
|
|
29770
|
-
apyProfile: apyProfileSchema
|
|
29771
|
-
fee: feeInfoSchema
|
|
29772
|
-
liquidityProfile: liquidityProfileSchema
|
|
29773
|
-
riskSignals: riskSignalsSchema
|
|
30126
|
+
address: zod.z.string(),
|
|
30127
|
+
asOf: zod.z.string(),
|
|
30128
|
+
manager: managerSchema.nullable(),
|
|
30129
|
+
apyProfile: apyProfileSchema,
|
|
30130
|
+
fee: feeInfoSchema,
|
|
30131
|
+
liquidityProfile: liquidityProfileSchema,
|
|
30132
|
+
riskSignals: riskSignalsSchema
|
|
29774
30133
|
});
|
|
29775
30134
|
/**
|
|
29776
30135
|
* Zod schema for the `vault` opportunity variant.
|
|
@@ -29857,13 +30216,13 @@ const bridgeFeeTokenSchema = hexAddressSchema;
|
|
|
29857
30216
|
*/ const accruedRewardSchema = zod.z.object({
|
|
29858
30217
|
token: zod.z.string(),
|
|
29859
30218
|
symbol: zod.z.string(),
|
|
29860
|
-
amount: amountJsonSchema
|
|
30219
|
+
amount: amountJsonSchema$1
|
|
29861
30220
|
});
|
|
29862
30221
|
const positionPnlSchema = zod.z.discriminatedUnion('status', [
|
|
29863
30222
|
zod.z.object({
|
|
29864
30223
|
status: zod.z.literal('available'),
|
|
29865
|
-
principalDeposited: amountJsonSchema,
|
|
29866
|
-
totalYieldEarned: amountJsonSchema
|
|
30224
|
+
principalDeposited: amountJsonSchema$1,
|
|
30225
|
+
totalYieldEarned: amountJsonSchema$1
|
|
29867
30226
|
}),
|
|
29868
30227
|
zod.z.object({
|
|
29869
30228
|
status: zod.z.literal('pending')
|
|
@@ -29883,9 +30242,9 @@ const positionPnlSchema = zod.z.discriminatedUnion('status', [
|
|
|
29883
30242
|
vaultAddress: zod.z.string(),
|
|
29884
30243
|
vaultName: zod.z.string(),
|
|
29885
30244
|
asset: zod.z.string(),
|
|
29886
|
-
currentBalance: amountJsonSchema,
|
|
30245
|
+
currentBalance: amountJsonSchema$1,
|
|
29887
30246
|
currentApy: zod.z.number(),
|
|
29888
|
-
shares: amountJsonSchema,
|
|
30247
|
+
shares: amountJsonSchema$1,
|
|
29889
30248
|
pnl: positionPnlSchema,
|
|
29890
30249
|
accruedRewards: zod.z.array(accruedRewardSchema).optional(),
|
|
29891
30250
|
rewardsUnavailableReason: zod.z.string().optional()
|
|
@@ -29913,7 +30272,7 @@ const positionPnlSchema = zod.z.discriminatedUnion('status', [
|
|
|
29913
30272
|
* @internal
|
|
29914
30273
|
*/ const earnInstructionSchema = zod.z.object({
|
|
29915
30274
|
tokenIn: hexAddressSchema,
|
|
29916
|
-
amountToApprove: uint256LikeSchema
|
|
30275
|
+
amountToApprove: uint256LikeSchema$1
|
|
29917
30276
|
}).passthrough();
|
|
29918
30277
|
/**
|
|
29919
30278
|
* Zod schema for earn execution params returned by the earn service.
|
|
@@ -29927,50 +30286,10 @@ const positionPnlSchema = zod.z.discriminatedUnion('status', [
|
|
|
29927
30286
|
instructions: zod.z.tuple([
|
|
29928
30287
|
earnInstructionSchema
|
|
29929
30288
|
]).rest(earnInstructionSchema),
|
|
29930
|
-
deadline: uint256LikeSchema
|
|
30289
|
+
deadline: uint256LikeSchema$1
|
|
29931
30290
|
}).passthrough();
|
|
29932
30291
|
/** @internal */ const depositExecutionParamsSchema = earnExecutionParamsSchema;
|
|
29933
30292
|
/** @internal */ const withdrawExecutionParamsSchema = earnExecutionParamsSchema;
|
|
29934
|
-
/**
|
|
29935
|
-
* Zod schema for the claim rewards instruction fields that must be safe to
|
|
29936
|
-
* ABI-encode.
|
|
29937
|
-
*
|
|
29938
|
-
* Claim rewards has no approval preflight, so this validates the forwarded
|
|
29939
|
-
* signed payload at the provider boundary. Additional instruction fields are
|
|
29940
|
-
* accepted and preserved.
|
|
29941
|
-
*
|
|
29942
|
-
* @internal
|
|
29943
|
-
*/ const claimRewardsInstructionSchema = zod.z.object({
|
|
29944
|
-
target: hexAddressSchema,
|
|
29945
|
-
data: hexBytesSchema,
|
|
29946
|
-
value: uint256LikeSchema,
|
|
29947
|
-
tokenIn: hexAddressSchema,
|
|
29948
|
-
amountToApprove: uint256LikeSchema,
|
|
29949
|
-
tokenOut: hexAddressSchema,
|
|
29950
|
-
minTokenOut: uint256LikeSchema
|
|
29951
|
-
}).passthrough();
|
|
29952
|
-
/** @internal */ const claimRewardsTokenSchema = zod.z.object({
|
|
29953
|
-
token: hexAddressSchema,
|
|
29954
|
-
beneficiary: hexAddressSchema
|
|
29955
|
-
}).passthrough();
|
|
29956
|
-
/**
|
|
29957
|
-
* Zod schema for signed claim rewards execution params.
|
|
29958
|
-
*
|
|
29959
|
-
* This enforces the required envelope and preserves additive fields so the
|
|
29960
|
-
* adapter receives the signed params verbatim.
|
|
29961
|
-
*
|
|
29962
|
-
* @internal
|
|
29963
|
-
*/ const claimRewardsExecutionParamsSchema = zod.z.object({
|
|
29964
|
-
instructions: zod.z.tuple([
|
|
29965
|
-
claimRewardsInstructionSchema
|
|
29966
|
-
]).rest(claimRewardsInstructionSchema),
|
|
29967
|
-
tokens: zod.z.tuple([
|
|
29968
|
-
claimRewardsTokenSchema
|
|
29969
|
-
]).rest(claimRewardsTokenSchema),
|
|
29970
|
-
execId: uint256LikeSchema,
|
|
29971
|
-
deadline: uint256LikeSchema,
|
|
29972
|
-
metadata: hexBytesSchema
|
|
29973
|
-
}).passthrough();
|
|
29974
30293
|
/**
|
|
29975
30294
|
* Zod schema for the deposit payload inside the API `data` envelope.
|
|
29976
30295
|
*
|
|
@@ -30029,9 +30348,9 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
|
|
|
30029
30348
|
message: zod.z.object({
|
|
30030
30349
|
from: hexAddressSchema,
|
|
30031
30350
|
to: hexAddressSchema,
|
|
30032
|
-
value: uint256LikeSchema,
|
|
30033
|
-
validAfter: uint256LikeSchema,
|
|
30034
|
-
validBefore: uint256LikeSchema,
|
|
30351
|
+
value: uint256LikeSchema$1,
|
|
30352
|
+
validAfter: uint256LikeSchema$1,
|
|
30353
|
+
validBefore: uint256LikeSchema$1,
|
|
30035
30354
|
nonce: bytes32HexSchema
|
|
30036
30355
|
}).passthrough()
|
|
30037
30356
|
}).passthrough();
|
|
@@ -30049,7 +30368,7 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
|
|
|
30049
30368
|
feeToken: bridgeFeeTokenSchema,
|
|
30050
30369
|
items: zod.z.array(zod.z.object({
|
|
30051
30370
|
type: zod.z.string(),
|
|
30052
|
-
amount: uint256LikeSchema
|
|
30371
|
+
amount: uint256LikeSchema$1
|
|
30053
30372
|
}).passthrough())
|
|
30054
30373
|
}).passthrough();
|
|
30055
30374
|
/**
|
|
@@ -30065,7 +30384,7 @@ const eip712DomainSchema = eip712DomainSchema$1.extend({
|
|
|
30065
30384
|
const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
30066
30385
|
sourceChain: zod.z.string(),
|
|
30067
30386
|
destinationChain: zod.z.string(),
|
|
30068
|
-
amount: amountJsonSchema,
|
|
30387
|
+
amount: amountJsonSchema$1,
|
|
30069
30388
|
vaultAddress: hexAddressSchema
|
|
30070
30389
|
}).passthrough();
|
|
30071
30390
|
/** @internal */ const bridgeQuoteExpirySchema = zod.z.discriminatedUnion('mode', [
|
|
@@ -30200,44 +30519,6 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
30200
30519
|
// ---------------------------------------------------------------------------
|
|
30201
30520
|
// Claim rewards response schema
|
|
30202
30521
|
// ---------------------------------------------------------------------------
|
|
30203
|
-
/**
|
|
30204
|
-
* Zod schema for a claimed reward amount in the API response.
|
|
30205
|
-
*
|
|
30206
|
-
* @internal
|
|
30207
|
-
*/ const claimedAmountSchema = zod.z.object({
|
|
30208
|
-
token: hexAddressSchema,
|
|
30209
|
-
symbol: zod.z.string(),
|
|
30210
|
-
amount: amountJsonSchema
|
|
30211
|
-
});
|
|
30212
|
-
/**
|
|
30213
|
-
* Zod schema for the claim rewards payload inside the API `data` envelope.
|
|
30214
|
-
*
|
|
30215
|
-
* Enforce that `executionParams` and `signature` are either both
|
|
30216
|
-
* present (claimable rewards) or both absent (nothing to claim).
|
|
30217
|
-
*
|
|
30218
|
-
* @internal
|
|
30219
|
-
*/ const claimRewardsPayloadSchema = zod.z.object({
|
|
30220
|
-
rewards: zod.z.array(claimedAmountSchema),
|
|
30221
|
-
executionParams: claimRewardsExecutionParamsSchema.optional(),
|
|
30222
|
-
signature: hexSignatureSchema.optional()
|
|
30223
|
-
}).refine((data)=>{
|
|
30224
|
-
const signedFieldCount = (data.executionParams === undefined ? 0 : 1) + (data.signature === undefined ? 0 : 1);
|
|
30225
|
-
if (data.rewards.length > 0) {
|
|
30226
|
-
return signedFieldCount === 2;
|
|
30227
|
-
}
|
|
30228
|
-
return signedFieldCount === 0;
|
|
30229
|
-
}, {
|
|
30230
|
-
message: 'claim rewards response must include executionParams and signature only when rewards are claimable'
|
|
30231
|
-
});
|
|
30232
|
-
/**
|
|
30233
|
-
* Zod schema for the `POST /v1/earnKit/claimRewards` API response.
|
|
30234
|
-
*
|
|
30235
|
-
* The Earn Service API wraps the claim rewards payload in a `data` envelope.
|
|
30236
|
-
*
|
|
30237
|
-
* @internal
|
|
30238
|
-
*/ zod.z.object({
|
|
30239
|
-
data: claimRewardsPayloadSchema
|
|
30240
|
-
});
|
|
30241
30522
|
// ---------------------------------------------------------------------------
|
|
30242
30523
|
// Deposit quote response schema
|
|
30243
30524
|
// ---------------------------------------------------------------------------
|
|
@@ -30256,7 +30537,7 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
30256
30537
|
type: zod.z.string().optional(),
|
|
30257
30538
|
status: zod.z.string().optional(),
|
|
30258
30539
|
token: zod.z.string(),
|
|
30259
|
-
amount: amountJsonSchema
|
|
30540
|
+
amount: amountJsonSchema$1
|
|
30260
30541
|
});
|
|
30261
30542
|
/**
|
|
30262
30543
|
* Zod schema for a native gas-fee entry in an EarnKit quote response.
|
|
@@ -30293,8 +30574,8 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
30293
30574
|
vaultAddress: zod.z.string(),
|
|
30294
30575
|
vaultName: zod.z.string(),
|
|
30295
30576
|
asset: zod.z.string(),
|
|
30296
|
-
depositAmount: amountJsonSchema,
|
|
30297
|
-
expectedShares: amountJsonSchema,
|
|
30577
|
+
depositAmount: amountJsonSchema$1,
|
|
30578
|
+
expectedShares: amountJsonSchema$1,
|
|
30298
30579
|
sharePrice: zod.z.string(),
|
|
30299
30580
|
currentApy: zod.z.number(),
|
|
30300
30581
|
fees: zod.z.array(feeSchema).optional(),
|
|
@@ -30320,10 +30601,10 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
30320
30601
|
vaultAddress: zod.z.string(),
|
|
30321
30602
|
vaultName: zod.z.string(),
|
|
30322
30603
|
asset: zod.z.string(),
|
|
30323
|
-
withdrawAmount: amountJsonSchema,
|
|
30324
|
-
sharesToRedeem: amountJsonSchema,
|
|
30604
|
+
withdrawAmount: amountJsonSchema$1,
|
|
30605
|
+
sharesToRedeem: amountJsonSchema$1,
|
|
30325
30606
|
sharePrice: zod.z.string(),
|
|
30326
|
-
maxWithdrawable: amountJsonSchema,
|
|
30607
|
+
maxWithdrawable: amountJsonSchema$1,
|
|
30327
30608
|
fees: zod.z.array(feeSchema),
|
|
30328
30609
|
gasFees: zod.z.array(quoteGasFeeSchema).optional(),
|
|
30329
30610
|
warnings: zod.z.array(zod.z.string()).optional()
|
|
@@ -30340,31 +30621,6 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
30340
30621
|
// ---------------------------------------------------------------------------
|
|
30341
30622
|
// Claim rewards quote response schema
|
|
30342
30623
|
// ---------------------------------------------------------------------------
|
|
30343
|
-
/**
|
|
30344
|
-
* Zod schema for a reward in the claim rewards quote response.
|
|
30345
|
-
*
|
|
30346
|
-
* @internal
|
|
30347
|
-
*/ const claimRewardsQuoteRewardSchema = zod.z.object({
|
|
30348
|
-
token: zod.z.string(),
|
|
30349
|
-
symbol: zod.z.string(),
|
|
30350
|
-
amount: amountJsonSchema
|
|
30351
|
-
});
|
|
30352
|
-
/**
|
|
30353
|
-
* Zod schema for the inner claim rewards quote payload.
|
|
30354
|
-
*
|
|
30355
|
-
* @internal
|
|
30356
|
-
*/ const claimRewardsQuotePayloadSchema = zod.z.object({
|
|
30357
|
-
rewards: zod.z.array(claimRewardsQuoteRewardSchema)
|
|
30358
|
-
});
|
|
30359
|
-
/**
|
|
30360
|
-
* Zod schema for the `POST /v1/earnKit/claimRewards/quote` API response.
|
|
30361
|
-
*
|
|
30362
|
-
* The API wraps the payload in a `data` envelope.
|
|
30363
|
-
*
|
|
30364
|
-
* @internal
|
|
30365
|
-
*/ zod.z.object({
|
|
30366
|
-
data: claimRewardsQuotePayloadSchema
|
|
30367
|
-
});
|
|
30368
30624
|
// ---------------------------------------------------------------------------
|
|
30369
30625
|
// Batch vault response schema
|
|
30370
30626
|
// ---------------------------------------------------------------------------
|
|
@@ -30504,7 +30760,7 @@ createTokenRegistry();
|
|
|
30504
30760
|
* fast instead of being silently stripped.
|
|
30505
30761
|
*
|
|
30506
30762
|
* @internal
|
|
30507
|
-
*/ const adapterContextSchema = zod.z.object({
|
|
30763
|
+
*/ const adapterContextSchema$1 = zod.z.object({
|
|
30508
30764
|
adapter: adapterSchema,
|
|
30509
30765
|
// AdapterContext accepts a wider chain field, but runtime validation must
|
|
30510
30766
|
// stay constrained to EarnChain identifiers.
|
|
@@ -30736,10 +30992,53 @@ const sourceAdapterContextSchema = zod.z.object({
|
|
|
30736
30992
|
* })
|
|
30737
30993
|
* ```
|
|
30738
30994
|
*/ zod.z.object({
|
|
30739
|
-
from: adapterContextSchema,
|
|
30995
|
+
from: adapterContextSchema$1,
|
|
30740
30996
|
vaultAddress: vaultAddressSchema,
|
|
30741
30997
|
config: earnConfigSchema.optional()
|
|
30742
30998
|
});
|
|
30999
|
+
/**
|
|
31000
|
+
* Schema for a successful gas fee entry (fees is non-null).
|
|
31001
|
+
*
|
|
31002
|
+
* Validates the kit shape — {@link EarnEstimatedGas} uses decimal strings for
|
|
31003
|
+
* `gas`, `gasPrice`, and `fee`. Only digits are accepted so that the deposit
|
|
31004
|
+
* operation can safely convert them to `bigint` before passing them to the
|
|
31005
|
+
* provider's `computeGasReserve`.
|
|
31006
|
+
*
|
|
31007
|
+
* @internal
|
|
31008
|
+
*/ const earnGasFeeEstimateSuccessSchema = zod.z.object({
|
|
31009
|
+
name: zod.z.string(),
|
|
31010
|
+
token: zod.z.string(),
|
|
31011
|
+
blockchain: zod.z.string(),
|
|
31012
|
+
fees: zod.z.object({
|
|
31013
|
+
gas: zod.z.string().regex(/^\d+$/, 'gas must be a non-negative integer string'),
|
|
31014
|
+
gasPrice: zod.z.string().regex(/^\d+$/, 'gasPrice must be a non-negative integer string'),
|
|
31015
|
+
fee: zod.z.string().regex(/^\d+$/, 'fee must be a non-negative integer string')
|
|
31016
|
+
}),
|
|
31017
|
+
error: zod.z.undefined().optional()
|
|
31018
|
+
}).strict();
|
|
31019
|
+
/**
|
|
31020
|
+
* Schema for a failed gas fee entry (fees is null, error is a string).
|
|
31021
|
+
*
|
|
31022
|
+
* @internal
|
|
31023
|
+
*/ const earnGasFeeEstimateFailureSchema = zod.z.object({
|
|
31024
|
+
name: zod.z.string(),
|
|
31025
|
+
token: zod.z.string(),
|
|
31026
|
+
blockchain: zod.z.string(),
|
|
31027
|
+
fees: zod.z.null(),
|
|
31028
|
+
error: zod.z.string()
|
|
31029
|
+
}).strict();
|
|
31030
|
+
/**
|
|
31031
|
+
* Schema for a single kit-level gas fee estimate entry.
|
|
31032
|
+
*
|
|
31033
|
+
* Rejects arbitrary inputs (null, numbers, empty objects, non-numeric fee
|
|
31034
|
+
* strings) so callers receive a descriptive validation error instead of a
|
|
31035
|
+
* raw `BigInt` conversion error inside `computeGasReserve`.
|
|
31036
|
+
*
|
|
31037
|
+
* @internal
|
|
31038
|
+
*/ const earnGasFeeEstimateSchema = zod.z.union([
|
|
31039
|
+
earnGasFeeEstimateSuccessSchema,
|
|
31040
|
+
earnGasFeeEstimateFailureSchema
|
|
31041
|
+
]);
|
|
30743
31042
|
/**
|
|
30744
31043
|
* Validation schema for the same-chain variant of DepositParams.
|
|
30745
31044
|
*
|
|
@@ -30748,10 +31047,11 @@ const sourceAdapterContextSchema = zod.z.object({
|
|
|
30748
31047
|
*
|
|
30749
31048
|
* @internal Exported for branch-targeted validation in the deposit operation.
|
|
30750
31049
|
*/ const sameChainDepositParamsSchema = zod.z.object({
|
|
30751
|
-
from: adapterContextSchema,
|
|
31050
|
+
from: adapterContextSchema$1,
|
|
30752
31051
|
to: zod.z.undefined().optional(),
|
|
30753
31052
|
vaultAddress: vaultAddressSchema,
|
|
30754
31053
|
amount: amountSchema,
|
|
31054
|
+
gasFees: zod.z.array(earnGasFeeEstimateSchema).optional(),
|
|
30755
31055
|
config: earnConfigSchema.optional()
|
|
30756
31056
|
}).strict();
|
|
30757
31057
|
const crossChainDepositDestinationSchema = zod.z.object({
|
|
@@ -30818,7 +31118,7 @@ const crossChainDepositDestinationSchema = zod.z.object({
|
|
|
30818
31118
|
* })
|
|
30819
31119
|
* ```
|
|
30820
31120
|
*/ zod.z.object({
|
|
30821
|
-
from: adapterContextSchema,
|
|
31121
|
+
from: adapterContextSchema$1,
|
|
30822
31122
|
vaultAddress: vaultAddressSchema,
|
|
30823
31123
|
amount: amountSchema,
|
|
30824
31124
|
config: earnConfigSchema.optional()
|
|
@@ -30872,7 +31172,7 @@ const crossChainDepositDestinationSchema = zod.z.object({
|
|
|
30872
31172
|
* })
|
|
30873
31173
|
* ```
|
|
30874
31174
|
*/ zod.z.object({
|
|
30875
|
-
from: adapterContextSchema,
|
|
31175
|
+
from: adapterContextSchema$1,
|
|
30876
31176
|
vaultAddress: vaultAddressSchema,
|
|
30877
31177
|
amount: amountSchema,
|
|
30878
31178
|
config: earnConfigSchema.optional()
|
|
@@ -30892,12 +31192,12 @@ const crossChainDepositDestinationSchema = zod.z.object({
|
|
|
30892
31192
|
*
|
|
30893
31193
|
* @internal
|
|
30894
31194
|
*/ zod.z.object({
|
|
30895
|
-
from: adapterContextSchema,
|
|
31195
|
+
from: adapterContextSchema$1,
|
|
30896
31196
|
vaultAddress: vaultAddressSchema,
|
|
30897
31197
|
config: earnConfigSchema.optional()
|
|
30898
31198
|
});
|
|
30899
31199
|
const sameChainGetDepositQuoteParamsSchema = zod.z.object({
|
|
30900
|
-
from: adapterContextSchema,
|
|
31200
|
+
from: adapterContextSchema$1,
|
|
30901
31201
|
vaultAddress: vaultAddressSchema,
|
|
30902
31202
|
amount: amountSchema,
|
|
30903
31203
|
config: earnConfigSchema.optional()
|
|
@@ -30981,7 +31281,7 @@ function hasCrossChainDepositQuoteShape(params) {
|
|
|
30981
31281
|
* })
|
|
30982
31282
|
* ```
|
|
30983
31283
|
*/ zod.z.object({
|
|
30984
|
-
from: adapterContextSchema,
|
|
31284
|
+
from: adapterContextSchema$1,
|
|
30985
31285
|
vaultAddress: vaultAddressSchema,
|
|
30986
31286
|
amount: amountSchema,
|
|
30987
31287
|
config: earnConfigSchema.optional()
|
|
@@ -31001,11 +31301,1363 @@ function hasCrossChainDepositQuoteShape(params) {
|
|
|
31001
31301
|
*
|
|
31002
31302
|
* @internal
|
|
31003
31303
|
*/ zod.z.object({
|
|
31004
|
-
from: adapterContextSchema,
|
|
31304
|
+
from: adapterContextSchema$1,
|
|
31005
31305
|
vaultAddress: vaultAddressSchema,
|
|
31006
31306
|
config: earnConfigSchema.optional()
|
|
31007
31307
|
});
|
|
31008
31308
|
|
|
31309
|
+
/** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$1.name);
|
|
31310
|
+
|
|
31311
|
+
// Auto-register this kit for user agent tracking
|
|
31312
|
+
registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
31313
|
+
|
|
31314
|
+
var name = "@circle-fin/borrow-kit";
|
|
31315
|
+
var version = "1.0.0";
|
|
31316
|
+
var pkg = {
|
|
31317
|
+
name: name,
|
|
31318
|
+
version: version};
|
|
31319
|
+
|
|
31320
|
+
const HUMAN_READABLE_AMOUNT_REGEX$1 = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
31321
|
+
const EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
|
|
31322
|
+
const POSITIVE_USDC_AMOUNT_REGEX = /^(?:0|[1-9]\d*)(?:\.\d{1,6})?$/;
|
|
31323
|
+
/**
|
|
31324
|
+
* True when `value` parses as a URL whose scheme is exactly `https:`.
|
|
31325
|
+
*
|
|
31326
|
+
* Uses the WHATWG `URL` parser rather than `startsWith('https://')` so the
|
|
31327
|
+
* check is scheme-normalized (case-insensitive, e.g. `HTTPS://...` still
|
|
31328
|
+
* passes) instead of a literal prefix match. `value` has already passed
|
|
31329
|
+
* `z.string().url()` by the time this runs, but a caller could still supply
|
|
31330
|
+
* a string that `URL` itself rejects, so the parse is guarded.
|
|
31331
|
+
*/ function isHttpsUrl$1(value) {
|
|
31332
|
+
try {
|
|
31333
|
+
return new URL(value).protocol === 'https:';
|
|
31334
|
+
} catch {
|
|
31335
|
+
return false;
|
|
31336
|
+
}
|
|
31337
|
+
}
|
|
31338
|
+
const borrowServiceConfigSchema$1 = zod.z.object({
|
|
31339
|
+
apiKey: zod.z.string().optional(),
|
|
31340
|
+
baseUrl: zod.z.string().url().optional()
|
|
31341
|
+
}).strict();
|
|
31342
|
+
/** Loan asset amounts are USDC, so they carry at most 6 decimal places. */ function positiveLoanAssetAmountSchema(field) {
|
|
31343
|
+
return zod.z.string().regex(POSITIVE_USDC_AMOUNT_REGEX, `${field} must be a canonical decimal with at most 6 decimal places`).refine((value)=>/[1-9]/.test(value), {
|
|
31344
|
+
message: `${field} must be greater than zero`
|
|
31345
|
+
});
|
|
31346
|
+
}
|
|
31347
|
+
/**
|
|
31348
|
+
* Collateral amounts denominate an arbitrary token, so the decimal count is the
|
|
31349
|
+
* token's rather than USDC's — a satoshi-precision collateral is valid.
|
|
31350
|
+
*/ function positiveCollateralAmountSchema(field) {
|
|
31351
|
+
return zod.z.string().regex(HUMAN_READABLE_AMOUNT_REGEX$1, `${field} must be a canonical decimal`).refine((value)=>/[1-9]/.test(value), {
|
|
31352
|
+
message: `${field} must be greater than zero`
|
|
31353
|
+
});
|
|
31354
|
+
}
|
|
31355
|
+
/** @internal */ zod.z.object({
|
|
31356
|
+
chain: chainIdentifierSchema,
|
|
31357
|
+
marketId: zod.z.string().min(1),
|
|
31358
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31359
|
+
}).strict();
|
|
31360
|
+
/** @internal */ zod.z.object({
|
|
31361
|
+
walletAddress: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
31362
|
+
chain: chainIdentifierSchema,
|
|
31363
|
+
pageSize: zod.z.number().int().positive().optional(),
|
|
31364
|
+
pageAfter: zod.z.string().min(1).optional(),
|
|
31365
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31366
|
+
}).strict();
|
|
31367
|
+
/** @internal */ const marketSortBySchema$1 = zod.z.enum([
|
|
31368
|
+
'lltv',
|
|
31369
|
+
'borrowApy'
|
|
31370
|
+
]);
|
|
31371
|
+
/** @internal */ const decimalFilterSchema$1 = zod.z.string().regex(/^\d+(\.\d+)?$/, 'filter thresholds must be non-negative decimal strings');
|
|
31372
|
+
/**
|
|
31373
|
+
* Provider-level runtime schema for {@link ExploreMarketsServiceParams}.
|
|
31374
|
+
*
|
|
31375
|
+
* Mirrors the kit's `exploreMarketsParamsSchema` at the provider boundary so a
|
|
31376
|
+
* plain-JS caller invoking `BorrowServiceProvider.exploreMarkets` directly is
|
|
31377
|
+
* still validated before any filter reaches `url.searchParams` — including the
|
|
31378
|
+
* kit's `minLltv <= maxLltv` / `minBorrow <= maxBorrow` range check, which
|
|
31379
|
+
* otherwise lets an inverted range serialize into the request and return a
|
|
31380
|
+
* silently empty page.
|
|
31381
|
+
*
|
|
31382
|
+
* @internal
|
|
31383
|
+
*/ zod.z.object({
|
|
31384
|
+
chain: chainIdentifierSchema,
|
|
31385
|
+
minLltv: decimalFilterSchema$1.optional(),
|
|
31386
|
+
maxLltv: decimalFilterSchema$1.optional(),
|
|
31387
|
+
minBorrow: decimalFilterSchema$1.optional(),
|
|
31388
|
+
maxBorrow: decimalFilterSchema$1.optional(),
|
|
31389
|
+
sortBy: marketSortBySchema$1.optional(),
|
|
31390
|
+
pageSize: zod.z.number().int().min(1).max(1000).optional(),
|
|
31391
|
+
pageAfter: zod.z.string().min(1).optional(),
|
|
31392
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31393
|
+
}).strict().superRefine((value, ctx)=>{
|
|
31394
|
+
if (value.minLltv !== undefined && value.maxLltv !== undefined && Number(value.minLltv) > Number(value.maxLltv)) {
|
|
31395
|
+
ctx.addIssue({
|
|
31396
|
+
code: zod.z.ZodIssueCode.custom,
|
|
31397
|
+
path: [
|
|
31398
|
+
'maxLltv'
|
|
31399
|
+
],
|
|
31400
|
+
message: 'maxLltv must be greater than or equal to minLltv'
|
|
31401
|
+
});
|
|
31402
|
+
}
|
|
31403
|
+
if (value.minBorrow !== undefined && value.maxBorrow !== undefined && Number(value.minBorrow) > Number(value.maxBorrow)) {
|
|
31404
|
+
ctx.addIssue({
|
|
31405
|
+
code: zod.z.ZodIssueCode.custom,
|
|
31406
|
+
path: [
|
|
31407
|
+
'maxBorrow'
|
|
31408
|
+
],
|
|
31409
|
+
message: 'maxBorrow must be greater than or equal to minBorrow'
|
|
31410
|
+
});
|
|
31411
|
+
}
|
|
31412
|
+
});
|
|
31413
|
+
/** @internal */ const repayQuoteServiceParamsSchema = zod.z.object({
|
|
31414
|
+
loanId: zod.z.string().uuid(),
|
|
31415
|
+
chain: chainIdentifierSchema,
|
|
31416
|
+
repayAmount: positiveLoanAssetAmountSchema('repayAmount'),
|
|
31417
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31418
|
+
}).strict();
|
|
31419
|
+
/** @internal */ repayQuoteServiceParamsSchema.omit({
|
|
31420
|
+
chain: true
|
|
31421
|
+
}).extend({
|
|
31422
|
+
idempotencyKey: zod.z.string().uuid().optional()
|
|
31423
|
+
});
|
|
31424
|
+
/** @internal */ const closeLoanQuoteServiceParamsSchema = zod.z.object({
|
|
31425
|
+
loanId: zod.z.string().uuid(),
|
|
31426
|
+
chain: chainIdentifierSchema,
|
|
31427
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
31428
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31429
|
+
}).strict();
|
|
31430
|
+
/** Fields a borrow carries whichever way it names its position. @internal */ const borrowServiceParamsBaseShape = {
|
|
31431
|
+
loanAssetAmount: positiveLoanAssetAmountSchema('loanAssetAmount'),
|
|
31432
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
31433
|
+
idempotencyKey: zod.z.string().uuid().optional(),
|
|
31434
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31435
|
+
};
|
|
31436
|
+
/** A first-open: owner, chain and market are required together. @internal */ const openLoanServiceParamsSchema = zod.z.object({
|
|
31437
|
+
...borrowServiceParamsBaseShape,
|
|
31438
|
+
walletAddress: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
31439
|
+
chain: chainIdentifierSchema,
|
|
31440
|
+
marketId: zod.z.string().min(1)
|
|
31441
|
+
}).strict();
|
|
31442
|
+
/** A borrow-more: the loan is the only addressing field. @internal */ const borrowMoreServiceParamsSchema = zod.z.object({
|
|
31443
|
+
...borrowServiceParamsBaseShape,
|
|
31444
|
+
loanId: zod.z.string().uuid()
|
|
31445
|
+
}).strict();
|
|
31446
|
+
/**
|
|
31447
|
+
* The two ways a borrow names its position.
|
|
31448
|
+
*
|
|
31449
|
+
* A union of strict objects rather than one object with a refinement:
|
|
31450
|
+
* `.strict()` is what rejects a mixed body, and the service refuses `loanId`
|
|
31451
|
+
* next to any open-tuple field as well as an incomplete open tuple.
|
|
31452
|
+
*
|
|
31453
|
+
* @internal
|
|
31454
|
+
*/ zod.z.union([
|
|
31455
|
+
openLoanServiceParamsSchema,
|
|
31456
|
+
borrowMoreServiceParamsSchema
|
|
31457
|
+
]);
|
|
31458
|
+
/** A first-open quote carries the complete owner/chain/market tuple. @internal */ const openLoanQuoteServiceParamsSchema = zod.z.object({
|
|
31459
|
+
walletAddress: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
31460
|
+
chain: chainIdentifierSchema,
|
|
31461
|
+
marketId: zod.z.string().min(1),
|
|
31462
|
+
loanAssetAmount: positiveLoanAssetAmountSchema('loanAssetAmount'),
|
|
31463
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
31464
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31465
|
+
}).strict();
|
|
31466
|
+
/** A borrow-more quote needs only the existing loan ID. @internal */ const borrowMoreQuoteServiceParamsSchema = zod.z.object({
|
|
31467
|
+
loanId: zod.z.string().uuid(),
|
|
31468
|
+
loanAssetAmount: positiveLoanAssetAmountSchema('loanAssetAmount'),
|
|
31469
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
31470
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31471
|
+
}).strict();
|
|
31472
|
+
/** @internal */ zod.z.union([
|
|
31473
|
+
openLoanQuoteServiceParamsSchema,
|
|
31474
|
+
borrowMoreQuoteServiceParamsSchema
|
|
31475
|
+
]);
|
|
31476
|
+
/** @internal */ zod.z.object({
|
|
31477
|
+
chain: chainIdentifierSchema,
|
|
31478
|
+
marketId: zod.z.string().min(1),
|
|
31479
|
+
loanAssetAmount: positiveLoanAssetAmountSchema('loanAssetAmount'),
|
|
31480
|
+
// `.finite()` is load-bearing, not decoration: the value is encoded as a
|
|
31481
|
+
// decimal string on the wire, and there is no decimal string for Infinity.
|
|
31482
|
+
targetHealthFactor: zod.z.number().positive().finite(),
|
|
31483
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31484
|
+
}).strict();
|
|
31485
|
+
/** @internal */ zod.z.object({
|
|
31486
|
+
chain: chainIdentifierSchema,
|
|
31487
|
+
marketId: zod.z.string().min(1),
|
|
31488
|
+
collateralAmount: positiveCollateralAmountSchema('collateralAmount'),
|
|
31489
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31490
|
+
}).strict();
|
|
31491
|
+
/** @internal */ closeLoanQuoteServiceParamsSchema.omit({
|
|
31492
|
+
chain: true
|
|
31493
|
+
}).extend({
|
|
31494
|
+
idempotencyKey: zod.z.string().uuid().optional()
|
|
31495
|
+
});
|
|
31496
|
+
/**
|
|
31497
|
+
* Provider-level runtime schema for the non-adapter portion of
|
|
31498
|
+
* {@link ClaimRewardsServiceParams} / {@link GetRewardsServiceParams}.
|
|
31499
|
+
*
|
|
31500
|
+
* `from` (the adapter context) is intentionally excluded — like
|
|
31501
|
+
* `repay`/`closeLoan`, it is validated structurally by TypeScript and resolved
|
|
31502
|
+
* via `resolveAdapterContext` rather than by a Zod schema, since it carries a
|
|
31503
|
+
* live adapter instance rather than plain data. `config` is the only field
|
|
31504
|
+
* that reaches the wire, so it is what gets validated here, matching every
|
|
31505
|
+
* other provider method's independent `parseOrThrow` call.
|
|
31506
|
+
*
|
|
31507
|
+
* @internal
|
|
31508
|
+
*/ zod.z.object({
|
|
31509
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31510
|
+
}).strict();
|
|
31511
|
+
/**
|
|
31512
|
+
* Provider-level runtime schema for {@link GetPositionServiceParams}.
|
|
31513
|
+
*
|
|
31514
|
+
* @internal
|
|
31515
|
+
*/ zod.z.object({
|
|
31516
|
+
loanId: zod.z.string().uuid(),
|
|
31517
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31518
|
+
}).strict();
|
|
31519
|
+
/** @internal */ const withdrawCollateralQuoteServiceParamsSchema = zod.z.object({
|
|
31520
|
+
loanId: zod.z.string().uuid(),
|
|
31521
|
+
chain: chainIdentifierSchema,
|
|
31522
|
+
// Carries no decimal-place cap: the repayment is USDC, but the collateral
|
|
31523
|
+
// is the market's own token and may hold more precision than USDC's six.
|
|
31524
|
+
collateralAmount: positiveCollateralAmountSchema('collateralAmount'),
|
|
31525
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
31526
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31527
|
+
}).strict();
|
|
31528
|
+
/** @internal */ withdrawCollateralQuoteServiceParamsSchema.omit({
|
|
31529
|
+
chain: true
|
|
31530
|
+
}).extend({
|
|
31531
|
+
idempotencyKey: zod.z.string().uuid().optional()
|
|
31532
|
+
});
|
|
31533
|
+
/**
|
|
31534
|
+
* Adding collateral sizes no second leg, so there is no slippage bound.
|
|
31535
|
+
*
|
|
31536
|
+
* @internal
|
|
31537
|
+
*/ const addCollateralQuoteServiceParamsSchema = zod.z.object({
|
|
31538
|
+
loanId: zod.z.string().uuid(),
|
|
31539
|
+
chain: chainIdentifierSchema,
|
|
31540
|
+
collateralAmount: positiveCollateralAmountSchema('collateralAmount'),
|
|
31541
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31542
|
+
}).strict();
|
|
31543
|
+
/** @internal */ addCollateralQuoteServiceParamsSchema.omit({
|
|
31544
|
+
chain: true
|
|
31545
|
+
}).extend({
|
|
31546
|
+
idempotencyKey: zod.z.string().uuid().optional()
|
|
31547
|
+
});
|
|
31548
|
+
/** @internal */ const borrowAssetAmountSchema = zod.z.object({
|
|
31549
|
+
token: zod.z.string().min(1),
|
|
31550
|
+
tokenAddress: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
31551
|
+
decimals: zod.z.number().int().min(0).max(255),
|
|
31552
|
+
amount: zod.z.string().regex(HUMAN_READABLE_AMOUNT_REGEX$1)
|
|
31553
|
+
});
|
|
31554
|
+
/** @internal */ const healthFactorBandSchema = zod.z.enum([
|
|
31555
|
+
'SAFE',
|
|
31556
|
+
'WARN',
|
|
31557
|
+
'URGENT',
|
|
31558
|
+
'IMMINENT',
|
|
31559
|
+
'LIQUIDATABLE'
|
|
31560
|
+
]);
|
|
31561
|
+
/**
|
|
31562
|
+
* Whether a loan's economic projection has converged.
|
|
31563
|
+
*
|
|
31564
|
+
* `PENDING` means the loan's identity and lifecycle are known but its
|
|
31565
|
+
* economics are not yet materialized — every economic field is `null` until
|
|
31566
|
+
* the service's repair queue fills them in. See {@link loanSchema}.
|
|
31567
|
+
*
|
|
31568
|
+
* @internal
|
|
31569
|
+
*/ const loanDataStatusSchema = zod.z.enum([
|
|
31570
|
+
'READY',
|
|
31571
|
+
'PENDING'
|
|
31572
|
+
]);
|
|
31573
|
+
/**
|
|
31574
|
+
* Lifecycle status of a loan: still open (`active`) or fully wound down
|
|
31575
|
+
* (`closed`). Unlike {@link loanDataStatusSchema} this is not about whether
|
|
31576
|
+
* economics have converged — a `closed` loan is `READY` with every economic
|
|
31577
|
+
* field legitimately zeroed, not `null`. Shared by {@link loanSchema} and
|
|
31578
|
+
* {@link loanPayloadSchema}, which return the same field for the same entity.
|
|
31579
|
+
*
|
|
31580
|
+
* @internal
|
|
31581
|
+
*/ const loanStatusSchema = zod.z.enum([
|
|
31582
|
+
'active',
|
|
31583
|
+
'closed'
|
|
31584
|
+
]);
|
|
31585
|
+
/**
|
|
31586
|
+
* Zod schema for one loan in the `GET /v1/borrowKit/loans` page.
|
|
31587
|
+
*
|
|
31588
|
+
* @remarks Every economic field is nullable because the service returns a
|
|
31589
|
+
* `PENDING` loan — identity and lifecycle fields set, all economics `null` —
|
|
31590
|
+
* while materialization, principal, debt, or market APY is still converging.
|
|
31591
|
+
* That is the documented representation of a freshly-created loan, so
|
|
31592
|
+
* declaring these non-nullable made the first read after a `borrow()` fail
|
|
31593
|
+
* validation. `dataStatus` tells callers which of the two shapes they hold.
|
|
31594
|
+
*
|
|
31595
|
+
* `status` distinguishes a fully wound-down loan — `READY` with legitimately
|
|
31596
|
+
* zeroed economics — from a live one. Without it a caller cannot tell the two
|
|
31597
|
+
* apart, which is what left a closed loan sitting in `getLoans` output looking
|
|
31598
|
+
* open. It is declared **required here and on {@link loanPayloadSchema}**: a
|
|
31599
|
+
* live `GET /v1/borrowKit/loans` page reports it on every loan, including a
|
|
31600
|
+
* closed one.
|
|
31601
|
+
*
|
|
31602
|
+
* @internal
|
|
31603
|
+
*/ const loanSchema = zod.z.object({
|
|
31604
|
+
loanId: zod.z.string().uuid(),
|
|
31605
|
+
chain: zod.z.string().min(1),
|
|
31606
|
+
marketId: zod.z.string().min(1),
|
|
31607
|
+
walletAddress: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
31608
|
+
dataStatus: loanDataStatusSchema,
|
|
31609
|
+
collateral: borrowAssetAmountSchema.nullable(),
|
|
31610
|
+
borrowed: borrowAssetAmountSchema.nullable(),
|
|
31611
|
+
principalBorrowed: borrowAssetAmountSchema.nullable(),
|
|
31612
|
+
accruedInterest: borrowAssetAmountSchema.nullable(),
|
|
31613
|
+
borrowApy: zod.z.number().nullable(),
|
|
31614
|
+
ltv: zod.z.number().nullable(),
|
|
31615
|
+
healthFactor: zod.z.number().nullable(),
|
|
31616
|
+
healthFactorBand: healthFactorBandSchema.nullable(),
|
|
31617
|
+
liquidationPrice: borrowAssetAmountSchema.nullable(),
|
|
31618
|
+
status: loanStatusSchema
|
|
31619
|
+
});
|
|
31620
|
+
/**
|
|
31621
|
+
* Zod schema for the `GET /v1/borrowKit/loans` API response. The Borrow
|
|
31622
|
+
* Service wraps every response in a `data` envelope.
|
|
31623
|
+
*
|
|
31624
|
+
* @internal
|
|
31625
|
+
*/ zod.z.object({
|
|
31626
|
+
data: zod.z.object({
|
|
31627
|
+
loans: zod.z.array(loanSchema),
|
|
31628
|
+
pagination: zod.z.object({
|
|
31629
|
+
pageAfter: zod.z.string().optional()
|
|
31630
|
+
})
|
|
31631
|
+
})
|
|
31632
|
+
});
|
|
31633
|
+
/** @internal */ const borrowFeeSchema = zod.z.object({
|
|
31634
|
+
type: zod.z.string(),
|
|
31635
|
+
token: zod.z.string(),
|
|
31636
|
+
amount: borrowAssetAmountSchema
|
|
31637
|
+
});
|
|
31638
|
+
/** @internal */ const borrowQuoteGasFeeSchema = zod.z.object({
|
|
31639
|
+
name: zod.z.string(),
|
|
31640
|
+
fees: zod.z.object({
|
|
31641
|
+
gas: zod.z.string(),
|
|
31642
|
+
gasPrice: borrowAssetAmountSchema,
|
|
31643
|
+
fee: borrowAssetAmountSchema
|
|
31644
|
+
})
|
|
31645
|
+
});
|
|
31646
|
+
/** @internal */ const hexBytesSchema = zod.z.string().regex(/^0x(?:[0-9a-fA-F]{2})*$/).transform((value)=>value);
|
|
31647
|
+
function isNonNegativeBigIntLike(value) {
|
|
31648
|
+
try {
|
|
31649
|
+
return BigInt(value) >= 0n;
|
|
31650
|
+
} catch {
|
|
31651
|
+
return false;
|
|
31652
|
+
}
|
|
31653
|
+
}
|
|
31654
|
+
/** @internal */ const uint256LikeSchema = zod.z.union([
|
|
31655
|
+
zod.z.string(),
|
|
31656
|
+
zod.z.bigint()
|
|
31657
|
+
]).refine(isNonNegativeBigIntLike, {
|
|
31658
|
+
message: 'value must be a non-negative bigint-compatible string or bigint'
|
|
31659
|
+
});
|
|
31660
|
+
/**
|
|
31661
|
+
* A quoted decimal that has to parse finite, for the response fields the
|
|
31662
|
+
* service marshals from a Go `decimal.Decimal`.
|
|
31663
|
+
*
|
|
31664
|
+
* Deliberately not `z.coerce.number()`: coercion maps `''` and whitespace to
|
|
31665
|
+
* `0`, so a service that stopped sending a value would read as a real `0.0` —
|
|
31666
|
+
* a health factor of zero is a liquidated position, so that failure mode
|
|
31667
|
+
* silently reports the opposite of the truth. Refusing anything unparseable
|
|
31668
|
+
* here also makes the `decimalToNumber` mapper total, with no fallback value to
|
|
31669
|
+
* invent downstream.
|
|
31670
|
+
*/ const decimalNumericString = zod.z.string().min(1).refine((value)=>value.trim() !== '' && Number.isFinite(Number(value)), {
|
|
31671
|
+
message: 'value must be a decimal string that parses to a finite number'
|
|
31672
|
+
});
|
|
31673
|
+
/** @internal */ const borrowExecutionParamsSchema = zod.z.object({
|
|
31674
|
+
instructions: zod.z.array(zod.z.object({
|
|
31675
|
+
target: evmAddressSchema$1,
|
|
31676
|
+
data: hexBytesSchema,
|
|
31677
|
+
value: uint256LikeSchema,
|
|
31678
|
+
tokenIn: evmAddressSchema$1,
|
|
31679
|
+
amountToApprove: uint256LikeSchema,
|
|
31680
|
+
tokenOut: evmAddressSchema$1,
|
|
31681
|
+
minTokenOut: uint256LikeSchema
|
|
31682
|
+
}).passthrough()).min(1),
|
|
31683
|
+
tokens: zod.z.array(zod.z.object({
|
|
31684
|
+
token: evmAddressSchema$1,
|
|
31685
|
+
beneficiary: evmAddressSchema$1
|
|
31686
|
+
}).passthrough()),
|
|
31687
|
+
execId: uint256LikeSchema,
|
|
31688
|
+
deadline: uint256LikeSchema,
|
|
31689
|
+
metadata: hexBytesSchema
|
|
31690
|
+
}).passthrough();
|
|
31691
|
+
/**
|
|
31692
|
+
* Inner payload for a Borrow Service execution response, shared by every
|
|
31693
|
+
* write endpoint (`borrow`, `repay`, `addCollateral`, `closeLoan`,
|
|
31694
|
+
* `withdrawCollateral`). Kept separate from {@link loanExecutionSchema} so
|
|
31695
|
+
* {@link withdrawCollateralExecutionSchema} — the one execution response that
|
|
31696
|
+
* omits `chain` — can build on it without re-declaring every field.
|
|
31697
|
+
*
|
|
31698
|
+
* @internal
|
|
31699
|
+
*/ const loanExecutionPayloadSchema = zod.z.object({
|
|
31700
|
+
loanId: zod.z.string().uuid(),
|
|
31701
|
+
chain: zod.z.string().min(1),
|
|
31702
|
+
execId: zod.z.string().min(1),
|
|
31703
|
+
signature: evmSignatureSchema,
|
|
31704
|
+
executionParams: borrowExecutionParamsSchema
|
|
31705
|
+
});
|
|
31706
|
+
/**
|
|
31707
|
+
* Zod schema for a Borrow Service execution API response. The Borrow Service
|
|
31708
|
+
* wraps every response in a `data` envelope.
|
|
31709
|
+
*
|
|
31710
|
+
* @internal
|
|
31711
|
+
*/ zod.z.object({
|
|
31712
|
+
data: loanExecutionPayloadSchema
|
|
31713
|
+
});
|
|
31714
|
+
/**
|
|
31715
|
+
* Zod schema for the `POST /v1/borrowKit/loans/borrow` execution API
|
|
31716
|
+
* response. Extends {@link loanExecutionPayloadSchema} with `fees`, the fee
|
|
31717
|
+
* legs the signed bundle charges at origination (empty when nothing is
|
|
31718
|
+
* charged) — a field only this endpoint's response carries.
|
|
31719
|
+
*
|
|
31720
|
+
* `fees` is optional here, and only here. The API spec documents it as always
|
|
31721
|
+
* present and `[]` when nothing is charged, but the deployed service omits the
|
|
31722
|
+
* key entirely; requiring it fails validation on a healthy `200` and turns
|
|
31723
|
+
* every borrow into a FATAL error. It is optional rather than defaulted
|
|
31724
|
+
* because the guard consuming this schema reports `safeParse().success` and
|
|
31725
|
+
* discards the parsed value, so a default would never reach a reader.
|
|
31726
|
+
*
|
|
31727
|
+
* The absence is preserved to the caller rather than normalised to `[]`:
|
|
31728
|
+
* `fetchBorrow` returns `response.data` unchanged and `BorrowResponse.fees` is
|
|
31729
|
+
* optional, so "the service named no legs" stays distinguishable from "nothing
|
|
31730
|
+
* was charged". `executeBorrow` is what resolves it, by reporting the fee
|
|
31731
|
+
* transfers the receipt paid out under `type: 'unknown'`.
|
|
31732
|
+
*
|
|
31733
|
+
* @internal
|
|
31734
|
+
*/ zod.z.object({
|
|
31735
|
+
data: loanExecutionPayloadSchema.extend({
|
|
31736
|
+
fees: zod.z.array(borrowFeeSchema).optional()
|
|
31737
|
+
})
|
|
31738
|
+
});
|
|
31739
|
+
/** @internal */ const resultingHealthSchema = {
|
|
31740
|
+
resultingHealthFactor: zod.z.number().nullable(),
|
|
31741
|
+
resultingLtv: zod.z.number().nullable(),
|
|
31742
|
+
resultingBand: healthFactorBandSchema,
|
|
31743
|
+
liquidationPrice: borrowAssetAmountSchema.nullable()
|
|
31744
|
+
};
|
|
31745
|
+
/**
|
|
31746
|
+
* Zod schema for the `POST /v1/borrowKit/loans/:loan_id/repay/quote` API
|
|
31747
|
+
* response. The Borrow Service wraps every response in a `data` envelope.
|
|
31748
|
+
*
|
|
31749
|
+
* @internal
|
|
31750
|
+
*/ zod.z.object({
|
|
31751
|
+
data: zod.z.object({
|
|
31752
|
+
chain: zod.z.string().min(1),
|
|
31753
|
+
repayAmount: borrowAssetAmountSchema,
|
|
31754
|
+
fees: zod.z.array(borrowFeeSchema),
|
|
31755
|
+
gasFees: zod.z.array(borrowQuoteGasFeeSchema),
|
|
31756
|
+
...resultingHealthSchema
|
|
31757
|
+
})
|
|
31758
|
+
});
|
|
31759
|
+
// ---------------------------------------------------------------------------
|
|
31760
|
+
// Loan position response schema (SE-6383: getPosition)
|
|
31761
|
+
// ---------------------------------------------------------------------------
|
|
31762
|
+
/**
|
|
31763
|
+
* Zod schema for the inner loan position payload.
|
|
31764
|
+
*
|
|
31765
|
+
* @remarks Matches the real `GET /v1/borrowKit/loans/:loan_id` wire shape
|
|
31766
|
+
* (Zenith's `borrowkit.LoanResponse`). Two fields in the original placeholder
|
|
31767
|
+
* did not exist on that contract and made every lookup of a real loan fail
|
|
31768
|
+
* validation: the owner address is sent as `walletAddress`, not `wallet`, and
|
|
31769
|
+
* the service sends no liquidation threshold at all — liquidation LTV is a
|
|
31770
|
+
* market property, served by `GET /v1/borrowKit/markets/:chain/:market_id` as
|
|
31771
|
+
* `lltv`, not a per-loan one.
|
|
31772
|
+
*
|
|
31773
|
+
* `collateral` and `borrowed` are nullable for the same reason they are on
|
|
31774
|
+
* {@link loanSchema}: this route returns the same `PENDING` representation —
|
|
31775
|
+
* null economics — for a loan whose on-chain create has not been observed
|
|
31776
|
+
* yet, which is exactly the state a `borrow()` leaves behind. `dataStatus`
|
|
31777
|
+
* distinguishes that from a `READY` loan whose economics happen to be zero.
|
|
31778
|
+
*
|
|
31779
|
+
* Declares the same economic field set as {@link loanSchema}, because Zenith
|
|
31780
|
+
* serves both routes from one struct (`borrowkit.LoanResponse`): a loan read
|
|
31781
|
+
* one at a time reports exactly what the same loan reports inside a page, so a
|
|
31782
|
+
* caller never has to list a wallet to recover a field. Both declare `status`
|
|
31783
|
+
* as required: a live `GET /v1/borrowKit/loans` page reports it on every loan,
|
|
31784
|
+
* including a closed one.
|
|
31785
|
+
*
|
|
31786
|
+
* `registeredAt` is the sole field on the wire that neither schema declares.
|
|
31787
|
+
*
|
|
31788
|
+
* @internal
|
|
31789
|
+
*/ const loanPayloadSchema = zod.z.object({
|
|
31790
|
+
loanId: zod.z.string(),
|
|
31791
|
+
walletAddress: zod.z.string(),
|
|
31792
|
+
chain: zod.z.string(),
|
|
31793
|
+
marketId: zod.z.string().min(1),
|
|
31794
|
+
dataStatus: loanDataStatusSchema,
|
|
31795
|
+
collateral: borrowAssetAmountSchema.nullable(),
|
|
31796
|
+
borrowed: borrowAssetAmountSchema.nullable(),
|
|
31797
|
+
principalBorrowed: borrowAssetAmountSchema.nullable(),
|
|
31798
|
+
accruedInterest: borrowAssetAmountSchema.nullable(),
|
|
31799
|
+
borrowApy: zod.z.number().nullable(),
|
|
31800
|
+
ltv: zod.z.number().nullable(),
|
|
31801
|
+
healthFactor: zod.z.number().nullable(),
|
|
31802
|
+
healthFactorBand: healthFactorBandSchema.nullable(),
|
|
31803
|
+
liquidationPrice: borrowAssetAmountSchema.nullable(),
|
|
31804
|
+
status: loanStatusSchema
|
|
31805
|
+
});
|
|
31806
|
+
/**
|
|
31807
|
+
* Zod schema for the `GET /v1/borrowKit/loans/:loan_id` API response.
|
|
31808
|
+
*
|
|
31809
|
+
* @internal
|
|
31810
|
+
*/ zod.z.object({
|
|
31811
|
+
data: loanPayloadSchema
|
|
31812
|
+
});
|
|
31813
|
+
// ---------------------------------------------------------------------------
|
|
31814
|
+
// Inferred types
|
|
31815
|
+
// ---------------------------------------------------------------------------
|
|
31816
|
+
/**
|
|
31817
|
+
* Zod schema for the `POST /v1/borrowKit/loans/borrow/quote` API response.
|
|
31818
|
+
* The Borrow Service wraps every response in a `data` envelope.
|
|
31819
|
+
*
|
|
31820
|
+
* @internal
|
|
31821
|
+
*/ zod.z.object({
|
|
31822
|
+
data: zod.z.object({
|
|
31823
|
+
chain: zod.z.string().min(1),
|
|
31824
|
+
collateralAmount: borrowAssetAmountSchema,
|
|
31825
|
+
loanAssetAmount: borrowAssetAmountSchema,
|
|
31826
|
+
// Nullable: the service reports null when the curated market row has no
|
|
31827
|
+
// cached rate yet, rather than a misleading 0%. The loans and markets
|
|
31828
|
+
// schemas already allow it; this one did not, so an unpriced market failed
|
|
31829
|
+
// validation and surfaced the whole quote as SERVICE_UNKNOWN_ERROR.
|
|
31830
|
+
borrowApy: zod.z.number().nullable(),
|
|
31831
|
+
fees: zod.z.array(borrowFeeSchema),
|
|
31832
|
+
gasFees: zod.z.array(borrowQuoteGasFeeSchema),
|
|
31833
|
+
...resultingHealthSchema
|
|
31834
|
+
})
|
|
31835
|
+
});
|
|
31836
|
+
/**
|
|
31837
|
+
* Zod schema for the `POST /v1/borrowKit/loans/:loan_id/addCollateral/quote`
|
|
31838
|
+
* API response. The Borrow Service wraps every response in a `data` envelope.
|
|
31839
|
+
*
|
|
31840
|
+
* @internal
|
|
31841
|
+
*/ zod.z.object({
|
|
31842
|
+
data: zod.z.object({
|
|
31843
|
+
chain: zod.z.string().min(1),
|
|
31844
|
+
collateralAmount: borrowAssetAmountSchema,
|
|
31845
|
+
fees: zod.z.array(borrowFeeSchema),
|
|
31846
|
+
gasFees: zod.z.array(borrowQuoteGasFeeSchema),
|
|
31847
|
+
...resultingHealthSchema
|
|
31848
|
+
})
|
|
31849
|
+
});
|
|
31850
|
+
/**
|
|
31851
|
+
* Zod schema for the `POST /v1/borrowKit/loans/:loan_id/closeLoan/quote` API
|
|
31852
|
+
* response. The Borrow Service wraps every response in a `data` envelope.
|
|
31853
|
+
*
|
|
31854
|
+
* @internal
|
|
31855
|
+
*/ zod.z.object({
|
|
31856
|
+
data: zod.z.object({
|
|
31857
|
+
chain: zod.z.string().min(1),
|
|
31858
|
+
repayAmount: borrowAssetAmountSchema,
|
|
31859
|
+
collateralAmount: borrowAssetAmountSchema,
|
|
31860
|
+
fees: zod.z.array(borrowFeeSchema),
|
|
31861
|
+
gasFees: zod.z.array(borrowQuoteGasFeeSchema),
|
|
31862
|
+
...resultingHealthSchema
|
|
31863
|
+
})
|
|
31864
|
+
});
|
|
31865
|
+
/**
|
|
31866
|
+
* The collateral-withdrawal execution response is the one Borrow Service
|
|
31867
|
+
* execution body that omits `chain`, so it cannot reuse
|
|
31868
|
+
* {@link loanExecutionSchema} unchanged. Built on
|
|
31869
|
+
* {@link loanExecutionPayloadSchema} so the `data` envelope only needs to be
|
|
31870
|
+
* applied once.
|
|
31871
|
+
*
|
|
31872
|
+
* @internal
|
|
31873
|
+
*/ zod.z.object({
|
|
31874
|
+
data: loanExecutionPayloadSchema.omit({
|
|
31875
|
+
chain: true
|
|
31876
|
+
})
|
|
31877
|
+
});
|
|
31878
|
+
/**
|
|
31879
|
+
* Zod schema for the
|
|
31880
|
+
* `POST /v1/borrowKit/loans/:loan_id/withdrawCollateral/quote` API response.
|
|
31881
|
+
* The Borrow Service wraps every response in a `data` envelope.
|
|
31882
|
+
*
|
|
31883
|
+
* @internal
|
|
31884
|
+
*/ zod.z.object({
|
|
31885
|
+
data: zod.z.object({
|
|
31886
|
+
chain: zod.z.string().min(1),
|
|
31887
|
+
repayAmount: borrowAssetAmountSchema,
|
|
31888
|
+
collateralAmount: borrowAssetAmountSchema,
|
|
31889
|
+
fees: zod.z.array(borrowFeeSchema),
|
|
31890
|
+
gasFees: zod.z.array(borrowQuoteGasFeeSchema),
|
|
31891
|
+
...resultingHealthSchema
|
|
31892
|
+
})
|
|
31893
|
+
});
|
|
31894
|
+
/**
|
|
31895
|
+
* Zod schema for the `POST /v1/borrowKit/loans/requiredCollateral/quote` API
|
|
31896
|
+
* response. The Borrow Service wraps every response in a `data` envelope.
|
|
31897
|
+
*
|
|
31898
|
+
* @remarks Deliberately not {@link resultingHealthSchema}. The two
|
|
31899
|
+
* market-scoped sizing quotes send four fields, not seven — no `resultingLtv`
|
|
31900
|
+
* and no `resultingBand` — so requiring the loan-scoped health block rejected
|
|
31901
|
+
* every well-formed response with `MALFORMED_RESPONSE`.
|
|
31902
|
+
*
|
|
31903
|
+
* `resultingHealthFactor` arrives as a decimal *string* on this route alone
|
|
31904
|
+
* (Zenith types it `decimal.Decimal`, which marshals quoted, where every other
|
|
31905
|
+
* route types it `*float64`). It is accepted as either encoding here and
|
|
31906
|
+
* narrowed to a `number` by the mapper — deliberately not via a Zod
|
|
31907
|
+
* `.transform`, because these schemas are consumed through boolean type guards
|
|
31908
|
+
* (`isRequiredCollateralQuote`), which discard a transform's output and would
|
|
31909
|
+
* leave the raw string flowing on while typed as a number.
|
|
31910
|
+
*
|
|
31911
|
+
* @internal
|
|
31912
|
+
*/ zod.z.object({
|
|
31913
|
+
data: zod.z.object({
|
|
31914
|
+
chain: zod.z.string().min(1),
|
|
31915
|
+
requiredCollateral: borrowAssetAmountSchema,
|
|
31916
|
+
resultingHealthFactor: zod.z.union([
|
|
31917
|
+
zod.z.number(),
|
|
31918
|
+
decimalNumericString
|
|
31919
|
+
]).nullable(),
|
|
31920
|
+
liquidationPrice: borrowAssetAmountSchema.nullable()
|
|
31921
|
+
})
|
|
31922
|
+
});
|
|
31923
|
+
/**
|
|
31924
|
+
* Zod schema for the `POST /v1/borrowKit/loans/maxBorrow/quote` API response.
|
|
31925
|
+
* The Borrow Service wraps every response in a `data` envelope.
|
|
31926
|
+
*
|
|
31927
|
+
* @remarks Four fields, not seven — see
|
|
31928
|
+
* {@link requiredCollateralQuoteSchema}. `resultingHealthFactor` is a plain
|
|
31929
|
+
* JSON number here (Zenith types it `*float64` on this route), so unlike its
|
|
31930
|
+
* inverse it needs no string coercion.
|
|
31931
|
+
*
|
|
31932
|
+
* @internal
|
|
31933
|
+
*/ zod.z.object({
|
|
31934
|
+
data: zod.z.object({
|
|
31935
|
+
chain: zod.z.string().min(1),
|
|
31936
|
+
maxBorrowAmount: borrowAssetAmountSchema,
|
|
31937
|
+
resultingHealthFactor: zod.z.number().nullable(),
|
|
31938
|
+
liquidationPrice: borrowAssetAmountSchema.nullable()
|
|
31939
|
+
})
|
|
31940
|
+
});
|
|
31941
|
+
/**
|
|
31942
|
+
* Zod schema for the `GET`/`POST /v1/borrowKit/integrators/config` API
|
|
31943
|
+
* response. The Borrow Service wraps every response in a `data` envelope.
|
|
31944
|
+
*
|
|
31945
|
+
* @internal
|
|
31946
|
+
*/ zod.z.object({
|
|
31947
|
+
data: zod.z.object({
|
|
31948
|
+
integratorId: zod.z.string().min(1),
|
|
31949
|
+
integratorFeeBps: zod.z.number().int().min(0),
|
|
31950
|
+
integratorFeeAddress: zod.z.string().regex(EVM_ADDRESS_REGEX).nullable(),
|
|
31951
|
+
createdAt: zod.z.string().datetime({
|
|
31952
|
+
offset: true
|
|
31953
|
+
}),
|
|
31954
|
+
updatedAt: zod.z.string().datetime({
|
|
31955
|
+
offset: true
|
|
31956
|
+
})
|
|
31957
|
+
})
|
|
31958
|
+
});
|
|
31959
|
+
/** @internal */ zod.z.object({
|
|
31960
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31961
|
+
}).strict();
|
|
31962
|
+
/**
|
|
31963
|
+
* Both fee fields are always required, so neither half is accepted alone.
|
|
31964
|
+
*
|
|
31965
|
+
* `integratorFeeAddress` may be `null` only when `integratorFeeBps` is 0, which
|
|
31966
|
+
* is how an integrator turns a fee off and clears the recipient. The reverse is
|
|
31967
|
+
* still allowed: a 0 rate can keep an address, which pauses the fee without
|
|
31968
|
+
* forgetting where it used to go. A rate above 0 with no recipient is unusable.
|
|
31969
|
+
*
|
|
31970
|
+
* The rule spans two fields, so it cannot live on either one and cannot be
|
|
31971
|
+
* expressed in the type. `{ integratorFeeBps: 25, integratorFeeAddress: null }`
|
|
31972
|
+
* type-checks and fails here.
|
|
31973
|
+
*
|
|
31974
|
+
* @internal
|
|
31975
|
+
*/ zod.z.object({
|
|
31976
|
+
integratorFeeBps: zod.z.number().int().min(0).max(10_000),
|
|
31977
|
+
integratorFeeAddress: zod.z.string().regex(EVM_ADDRESS_REGEX).nullable(),
|
|
31978
|
+
config: borrowServiceConfigSchema$1.optional()
|
|
31979
|
+
}).strict().refine((params)=>params.integratorFeeAddress !== null || params.integratorFeeBps === 0, {
|
|
31980
|
+
message: 'integratorFeeAddress can only be null when integratorFeeBps is 0',
|
|
31981
|
+
path: [
|
|
31982
|
+
'integratorFeeAddress'
|
|
31983
|
+
]
|
|
31984
|
+
});
|
|
31985
|
+
/**
|
|
31986
|
+
* Zod schema for the webhook registration payload inside the API `data`
|
|
31987
|
+
* envelope, returned by
|
|
31988
|
+
* `POST /v1/borrowKit/loans/:loan_id/webhookRegistration`.
|
|
31989
|
+
*
|
|
31990
|
+
* @internal
|
|
31991
|
+
*/ const webhookRegistrationPayloadSchema = zod.z.object({
|
|
31992
|
+
loanId: zod.z.string().uuid(),
|
|
31993
|
+
webhookUrl: zod.z.string().nullish()
|
|
31994
|
+
});
|
|
31995
|
+
/**
|
|
31996
|
+
* Zod schema validating the caller-supplied `loanId` and `webhookUrl` inputs
|
|
31997
|
+
* to `BorrowServiceProvider.registerWebhook` before they're signed and
|
|
31998
|
+
* submitted.
|
|
31999
|
+
*
|
|
32000
|
+
* `loanId` must be a UUID, consistent with every other loan-scoped schema in
|
|
32001
|
+
* this package (`repayQuoteServiceParamsSchema`, `loanSchema`,
|
|
32002
|
+
* `loanExecutionSchema`). `webhookUrl` must be `null` (an explicit "unset"
|
|
32003
|
+
* intent) or a syntactically valid **https** URL string — an empty string is
|
|
32004
|
+
* neither, so it's rejected here rather than silently reaching the `?? ''`
|
|
32005
|
+
* coercion that `buildWebhookRegistrationTypedData` applies to a genuine
|
|
32006
|
+
* `null`. The scheme is restricted to `https:` because this URL is where
|
|
32007
|
+
* loan-lifecycle callbacks get delivered and is cryptographically signed by
|
|
32008
|
+
* the loan owner: allowing `http:` would let a signed registration point at
|
|
32009
|
+
* a plaintext endpoint (or a link-local/loopback address reachable only from
|
|
32010
|
+
* the callback sender's own network), and the SDK is the natural place to
|
|
32011
|
+
* refuse that before it's ever signed or transmitted.
|
|
32012
|
+
*
|
|
32013
|
+
* @internal
|
|
32014
|
+
*/ zod.z.object({
|
|
32015
|
+
loanId: zod.z.string().uuid(),
|
|
32016
|
+
webhookUrl: zod.z.string().url().refine((value)=>isHttpsUrl$1(value), 'webhookUrl must use the https scheme').nullable()
|
|
32017
|
+
}).strict();
|
|
32018
|
+
/**
|
|
32019
|
+
* Zod schema for the `POST /v1/borrowKit/loans/:loan_id/webhookRegistration`
|
|
32020
|
+
* API response.
|
|
32021
|
+
*
|
|
32022
|
+
* The Borrow Service API wraps the webhook registration payload in a `data`
|
|
32023
|
+
* envelope.
|
|
32024
|
+
*
|
|
32025
|
+
* @internal
|
|
32026
|
+
*/ zod.z.object({
|
|
32027
|
+
data: webhookRegistrationPayloadSchema
|
|
32028
|
+
});
|
|
32029
|
+
/** @internal */ const marketAssetSchema = zod.z.object({
|
|
32030
|
+
symbol: zod.z.string().min(1),
|
|
32031
|
+
address: zod.z.string().regex(EVM_ADDRESS_REGEX),
|
|
32032
|
+
decimals: zod.z.number().int().nonnegative()
|
|
32033
|
+
});
|
|
32034
|
+
/**
|
|
32035
|
+
* Wire shape for a typed token amount: raw atoms as an integer string plus the
|
|
32036
|
+
* token's decimals, matching `@core/amounts` {@link AmountJSON}.
|
|
32037
|
+
*
|
|
32038
|
+
* @internal
|
|
32039
|
+
*/ const amountJsonSchema = zod.z.object({
|
|
32040
|
+
raw: zod.z.string().refine(isNonNegativeBigIntLike, {
|
|
32041
|
+
message: 'raw must be a non-negative bigint-compatible string'
|
|
32042
|
+
}),
|
|
32043
|
+
decimals: zod.z.number().int().nonnegative()
|
|
32044
|
+
});
|
|
32045
|
+
/**
|
|
32046
|
+
* Wire shape for a single borrow market returned by
|
|
32047
|
+
* `GET /v1/borrowKit/markets/:chain/:market_id`. `chain` is the Borrow Service
|
|
32048
|
+
* API chain code (mapped back to the SDK chain by `toMarketInfo`); display
|
|
32049
|
+
* ratios arrive as numbers, token amounts as `{ raw, decimals }` objects.
|
|
32050
|
+
*
|
|
32051
|
+
* @remarks `lltv`, `borrowAssets`, `liquidity`, `borrowApy`, `utilization`,
|
|
32052
|
+
* and `refreshedAt` are all nullable because the service's economics are
|
|
32053
|
+
* cached projections, not live reads: a market that has been discovered but
|
|
32054
|
+
* not yet backfilled by the cache reports every economic field as `null`
|
|
32055
|
+
* rather than a placeholder value. An idle market keeps its last-known values
|
|
32056
|
+
* and old `refreshedAt` rather than reporting zeros, so `null` unambiguously
|
|
32057
|
+
* means "never backfilled." `borrowCap` is always `null` (Morpho Blue has no
|
|
32058
|
+
* per-market cap) but carried anyway so the field does not have to be added
|
|
32059
|
+
* later as a breaking change; it is also optional since the service may omit
|
|
32060
|
+
* it entirely.
|
|
32061
|
+
*
|
|
32062
|
+
* @internal
|
|
32063
|
+
*/ const marketResponseSchema = zod.z.object({
|
|
32064
|
+
marketId: zod.z.string().min(1),
|
|
32065
|
+
protocol: zod.z.enum([
|
|
32066
|
+
'morpho'
|
|
32067
|
+
]),
|
|
32068
|
+
chain: zod.z.string().min(1),
|
|
32069
|
+
loanAsset: marketAssetSchema,
|
|
32070
|
+
collateralAsset: marketAssetSchema,
|
|
32071
|
+
lltv: zod.z.number().nonnegative().nullable(),
|
|
32072
|
+
borrowCap: amountJsonSchema.nullable().optional(),
|
|
32073
|
+
borrowAssets: amountJsonSchema.nullable(),
|
|
32074
|
+
liquidity: amountJsonSchema.nullable(),
|
|
32075
|
+
borrowApy: zod.z.number().nonnegative().nullable(),
|
|
32076
|
+
utilization: zod.z.number().nonnegative().nullable(),
|
|
32077
|
+
refreshedAt: zod.z.string().datetime({
|
|
32078
|
+
offset: true
|
|
32079
|
+
}).nullable()
|
|
32080
|
+
});
|
|
32081
|
+
/**
|
|
32082
|
+
* Zod schema for the `GET /v1/borrowKit/markets/:chain/:market_id` API
|
|
32083
|
+
* response. The Borrow Service wraps every response in a `data` envelope;
|
|
32084
|
+
* {@link marketResponseSchema} itself stays unwrapped since it is also reused
|
|
32085
|
+
* per-entry inside {@link listMarketsResponseSchema}.
|
|
32086
|
+
*
|
|
32087
|
+
* @internal
|
|
32088
|
+
*/ zod.z.object({
|
|
32089
|
+
data: marketResponseSchema
|
|
32090
|
+
});
|
|
32091
|
+
/**
|
|
32092
|
+
* Wire shape for a page of borrow markets returned by
|
|
32093
|
+
* `GET /v1/borrowKit/markets`. Reuses {@link marketResponseSchema} per entry so
|
|
32094
|
+
* the per-market wire format stays defined in one place, and adds the
|
|
32095
|
+
* pagination envelope: an opaque `pageAfter` cursor absent on the last page.
|
|
32096
|
+
* The Borrow Service wraps every response in a `data` envelope.
|
|
32097
|
+
*
|
|
32098
|
+
* @internal
|
|
32099
|
+
*/ zod.z.object({
|
|
32100
|
+
data: zod.z.object({
|
|
32101
|
+
markets: zod.z.array(marketResponseSchema),
|
|
32102
|
+
pagination: zod.z.object({
|
|
32103
|
+
pageAfter: zod.z.string().optional()
|
|
32104
|
+
})
|
|
32105
|
+
})
|
|
32106
|
+
});
|
|
32107
|
+
|
|
32108
|
+
/** @internal */ const BORROW_CHAIN_TO_API = {
|
|
32109
|
+
[Blockchain.Arc]: 'ARC',
|
|
32110
|
+
[Blockchain.Arc_Testnet]: 'ARC-TESTNET'
|
|
32111
|
+
};
|
|
32112
|
+
|
|
32113
|
+
Object.fromEntries(Object.entries(BORROW_CHAIN_TO_API).map(([sdkChain, apiChain])=>[
|
|
32114
|
+
apiChain,
|
|
32115
|
+
sdkChain
|
|
32116
|
+
]));
|
|
32117
|
+
|
|
32118
|
+
/**
|
|
32119
|
+
* Schema for the Borrow Service configuration options.
|
|
32120
|
+
*
|
|
32121
|
+
* `apiKey` carries a Circle API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) or a
|
|
32122
|
+
* legacy `KIT_KEY:<keyId>:<keySecret>` value. It is shape-checked only — as
|
|
32123
|
+
* with every other field here, the credential's format is the provider's call,
|
|
32124
|
+
* and `buildConfig` rejects a malformed one via `isValidApiKey`. The empty
|
|
32125
|
+
* string is allowed on purpose: `process.env.CIRCLE_API_KEY ?? ''` yields one
|
|
32126
|
+
* when the variable is unset, and the provider reads that as "no credential"
|
|
32127
|
+
* rather than as a malformed one.
|
|
32128
|
+
*
|
|
32129
|
+
* This schema is `.strict()`, so a field missing here is not merely unvalidated
|
|
32130
|
+
* — it is rejected outright, which is what made an `apiKey` config unusable
|
|
32131
|
+
* before it was listed.
|
|
32132
|
+
*
|
|
32133
|
+
* @internal
|
|
32134
|
+
*/ const borrowServiceConfigSchema = zod.z.object({
|
|
32135
|
+
apiKey: zod.z.string().optional(),
|
|
32136
|
+
baseUrl: zod.z.string().url('baseUrl must be a valid URL').optional()
|
|
32137
|
+
}).strict();
|
|
32138
|
+
/**
|
|
32139
|
+
* Runtime schema for {@link GetLoansParams}.
|
|
32140
|
+
*
|
|
32141
|
+
* @example
|
|
32142
|
+
* ```typescript
|
|
32143
|
+
* import { getLoansParamsSchema } from '@circle-fin/borrow-kit'
|
|
32144
|
+
*
|
|
32145
|
+
* const result = getLoansParamsSchema.safeParse({
|
|
32146
|
+
* walletAddress: '0x1111111111111111111111111111111111111111',
|
|
32147
|
+
* chain: 'Arc_Testnet',
|
|
32148
|
+
* })
|
|
32149
|
+
* ```
|
|
32150
|
+
*/ zod.z.object({
|
|
32151
|
+
walletAddress: evmAddressSchema$1,
|
|
32152
|
+
chain: chainIdentifierSchema,
|
|
32153
|
+
pageSize: zod.z.number().int().positive().optional(),
|
|
32154
|
+
pageAfter: zod.z.string().min(1).optional(),
|
|
32155
|
+
config: borrowServiceConfigSchema.optional()
|
|
32156
|
+
}).strict();
|
|
32157
|
+
/**
|
|
32158
|
+
* Runtime schema for {@link GetIntegratorConfigParams}.
|
|
32159
|
+
*
|
|
32160
|
+
* @example
|
|
32161
|
+
* ```typescript
|
|
32162
|
+
* import { getIntegratorConfigParamsSchema } from '@circle-fin/borrow-kit'
|
|
32163
|
+
*
|
|
32164
|
+
* const result = getIntegratorConfigParamsSchema.safeParse({
|
|
32165
|
+
* config: { apiKey: 'TEST_API_KEY:key-id:key-secret' },
|
|
32166
|
+
* })
|
|
32167
|
+
* ```
|
|
32168
|
+
*/ zod.z.object({
|
|
32169
|
+
config: borrowServiceConfigSchema.optional()
|
|
32170
|
+
}).strict();
|
|
32171
|
+
/**
|
|
32172
|
+
* Runtime schema for {@link GetMarketParams}.
|
|
32173
|
+
*
|
|
32174
|
+
* @example
|
|
32175
|
+
* ```typescript
|
|
32176
|
+
* import { getMarketParamsSchema } from '@circle-fin/borrow-kit'
|
|
32177
|
+
*
|
|
32178
|
+
* const result = getMarketParamsSchema.safeParse({
|
|
32179
|
+
* chain: 'Arc_Testnet',
|
|
32180
|
+
* marketId: '0xabc...',
|
|
32181
|
+
* })
|
|
32182
|
+
* ```
|
|
32183
|
+
*/ zod.z.object({
|
|
32184
|
+
chain: chainIdentifierSchema,
|
|
32185
|
+
marketId: zod.z.string().min(1),
|
|
32186
|
+
config: borrowServiceConfigSchema.optional()
|
|
32187
|
+
}).strict();
|
|
32188
|
+
/**
|
|
32189
|
+
* Runtime schema for {@link SetIntegratorConfigParams}.
|
|
32190
|
+
*
|
|
32191
|
+
* Both fee fields are required, so neither half is accepted alone.
|
|
32192
|
+
* `integratorFeeAddress` may be `null` only when `integratorFeeBps` is 0, which
|
|
32193
|
+
* turns the fee off and clears the recipient. A rate above 0 with no recipient
|
|
32194
|
+
* is unusable and is rejected.
|
|
32195
|
+
*
|
|
32196
|
+
* @example
|
|
32197
|
+
* ```typescript
|
|
32198
|
+
* import { setIntegratorConfigParamsSchema } from '@circle-fin/borrow-kit'
|
|
32199
|
+
*
|
|
32200
|
+
* const result = setIntegratorConfigParamsSchema.safeParse({
|
|
32201
|
+
* integratorFeeBps: 25,
|
|
32202
|
+
* integratorFeeAddress: '0x1111111111111111111111111111111111111111',
|
|
32203
|
+
* })
|
|
32204
|
+
*
|
|
32205
|
+
* // Turning the fee off and clearing the recipient.
|
|
32206
|
+
* const cleared = setIntegratorConfigParamsSchema.safeParse({
|
|
32207
|
+
* integratorFeeBps: 0,
|
|
32208
|
+
* integratorFeeAddress: null,
|
|
32209
|
+
* })
|
|
32210
|
+
* ```
|
|
32211
|
+
*/ zod.z.object({
|
|
32212
|
+
integratorFeeBps: zod.z.number().int().min(0).max(10_000),
|
|
32213
|
+
integratorFeeAddress: evmAddressSchema$1.nullable(),
|
|
32214
|
+
config: borrowServiceConfigSchema.optional()
|
|
32215
|
+
}).strict().refine((params)=>params.integratorFeeAddress !== null || params.integratorFeeBps === 0, {
|
|
32216
|
+
message: 'integratorFeeAddress can only be null when integratorFeeBps is 0',
|
|
32217
|
+
path: [
|
|
32218
|
+
'integratorFeeAddress'
|
|
32219
|
+
]
|
|
32220
|
+
});
|
|
32221
|
+
/** @internal */ const HUMAN_READABLE_AMOUNT_REGEX = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
32222
|
+
/**
|
|
32223
|
+
* @param maxDecimals - Decimal places the amount may carry, or `null` for no
|
|
32224
|
+
* cap. USDC amounts take the default six; an amount denominated in a market's
|
|
32225
|
+
* own collateral token may be finer, so those pass `null`.
|
|
32226
|
+
* @internal
|
|
32227
|
+
*/ function createPositiveAmountSchema(field, maxDecimals = 6) {
|
|
32228
|
+
const positive = zod.z.string().regex(HUMAN_READABLE_AMOUNT_REGEX, `${field} must be a human-readable decimal string`).refine((value)=>/[1-9]/.test(value), `${field} must be greater than zero`);
|
|
32229
|
+
if (maxDecimals === null) {
|
|
32230
|
+
return positive;
|
|
32231
|
+
}
|
|
32232
|
+
return positive.refine((value)=>(value.split('.')[1]?.length ?? 0) <= maxDecimals, `${field} must have at most ${maxDecimals.toString()} decimal places`);
|
|
32233
|
+
}
|
|
32234
|
+
/** @internal */ const positiveAmountSchema = createPositiveAmountSchema('repayAmount');
|
|
32235
|
+
const NIL_UUID = '00000000-0000-0000-0000-000000000000';
|
|
32236
|
+
const idempotencyKeySchema = zod.z.string().uuid().refine((value)=>value !== NIL_UUID, {
|
|
32237
|
+
message: 'idempotencyKey must not be the nil UUID; generate a fresh one per write'
|
|
32238
|
+
});
|
|
32239
|
+
/** @internal */ const adapterContextSchema = zod.z.object({
|
|
32240
|
+
// prepareAction is declared in the shape (rather than checked only via
|
|
32241
|
+
// .passthrough()) so its value is read off the input by property access:
|
|
32242
|
+
// .passthrough() only copies an input's own enumerable keys into its
|
|
32243
|
+
// output, which drops prototype methods like a class's prepareAction.
|
|
32244
|
+
adapter: adapterSchema.extend({
|
|
32245
|
+
prepareAction: zod.z.unknown()
|
|
32246
|
+
}).passthrough().refine((adapter)=>typeof adapter.prepareAction === 'function', 'adapter must expose prepareAction'),
|
|
32247
|
+
chain: chainIdentifierSchema,
|
|
32248
|
+
address: evmAddressSchema$1.optional()
|
|
32249
|
+
}).strict();
|
|
32250
|
+
/**
|
|
32251
|
+
* Shared `superRefine` enforcing the address/adapter-capability contract: a
|
|
32252
|
+
* developer-controlled adapter must supply `address` (the kit cannot resolve
|
|
32253
|
+
* it), and a user-controlled adapter must not (the adapter itself resolves
|
|
32254
|
+
* it — a caller-supplied value would silently take precedence, letting the
|
|
32255
|
+
* two disagree). Applied to every schema whose `from` shape carries an
|
|
32256
|
+
* adapter with a declared `addressContext` capability, so every Borrow Kit
|
|
32257
|
+
* write rejects a mismatched `from` the same way.
|
|
32258
|
+
*
|
|
32259
|
+
* @internal
|
|
32260
|
+
*/ function refineAddressContext(from, context) {
|
|
32261
|
+
const addressContext = from.adapter.capabilities?.addressContext;
|
|
32262
|
+
if (addressContext === 'developer-controlled' && from.address === undefined) {
|
|
32263
|
+
context.addIssue({
|
|
32264
|
+
code: zod.z.ZodIssueCode.custom,
|
|
32265
|
+
message: 'address is required for developer-controlled adapters',
|
|
32266
|
+
path: [
|
|
32267
|
+
'address'
|
|
32268
|
+
]
|
|
32269
|
+
});
|
|
32270
|
+
}
|
|
32271
|
+
if (addressContext === 'user-controlled' && from.address !== undefined) {
|
|
32272
|
+
context.addIssue({
|
|
32273
|
+
code: zod.z.ZodIssueCode.custom,
|
|
32274
|
+
message: 'address must be resolved by user-controlled adapters',
|
|
32275
|
+
path: [
|
|
32276
|
+
'address'
|
|
32277
|
+
]
|
|
32278
|
+
});
|
|
32279
|
+
}
|
|
32280
|
+
}
|
|
32281
|
+
/** @internal */ const borrowExecutionFromSchema = zod.z.object({
|
|
32282
|
+
// prepareAction/validateChainSupport/capabilities are declared in the
|
|
32283
|
+
// shape (rather than checked only via .passthrough()) so their values are
|
|
32284
|
+
// read off the input by property access: .passthrough() only copies an
|
|
32285
|
+
// input's own enumerable keys into its output, which drops a prototype
|
|
32286
|
+
// method or getter like a class's prepareAction/validateChainSupport/
|
|
32287
|
+
// capabilities. capabilities is read below and by refineAddressContext.
|
|
32288
|
+
adapter: adapterSchema.extend({
|
|
32289
|
+
prepareAction: zod.z.unknown(),
|
|
32290
|
+
validateChainSupport: zod.z.unknown(),
|
|
32291
|
+
capabilities: zod.z.unknown()
|
|
32292
|
+
}).passthrough().refine((adapter)=>typeof adapter.prepareAction === 'function', 'adapter must expose prepareAction').refine((adapter)=>typeof adapter.validateChainSupport === 'function', 'adapter must expose validateChainSupport').refine((adapter)=>adapter.capabilities?.addressContext === 'user-controlled' || adapter.capabilities?.addressContext === 'developer-controlled', 'adapter must declare its addressContext capability'),
|
|
32293
|
+
chain: chainIdentifierSchema,
|
|
32294
|
+
address: evmAddressSchema$1.optional()
|
|
32295
|
+
}).strict().superRefine(refineAddressContext);
|
|
32296
|
+
/**
|
|
32297
|
+
* Runtime schema for {@link RepayQuoteParams}.
|
|
32298
|
+
*/ const repayQuoteParamsSchema = zod.z.object({
|
|
32299
|
+
loanId: zod.z.string().uuid(),
|
|
32300
|
+
chain: chainIdentifierSchema,
|
|
32301
|
+
repayAmount: positiveAmountSchema,
|
|
32302
|
+
config: borrowServiceConfigSchema.optional()
|
|
32303
|
+
}).strict();
|
|
32304
|
+
/** Runtime schema for {@link RepayParams}. */ repayQuoteParamsSchema.omit({
|
|
32305
|
+
chain: true
|
|
32306
|
+
}).extend({
|
|
32307
|
+
idempotencyKey: idempotencyKeySchema.optional(),
|
|
32308
|
+
from: borrowExecutionFromSchema
|
|
32309
|
+
});
|
|
32310
|
+
/** Runtime schema for requesting a full-close quote. */ const closeLoanQuoteParamsSchema = zod.z.object({
|
|
32311
|
+
loanId: zod.z.string().uuid(),
|
|
32312
|
+
chain: chainIdentifierSchema,
|
|
32313
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
32314
|
+
config: borrowServiceConfigSchema.optional()
|
|
32315
|
+
}).strict();
|
|
32316
|
+
/** Runtime schema for atomically closing a loan. */ closeLoanQuoteParamsSchema.omit({
|
|
32317
|
+
chain: true
|
|
32318
|
+
}).extend({
|
|
32319
|
+
idempotencyKey: idempotencyKeySchema.optional(),
|
|
32320
|
+
from: borrowExecutionFromSchema
|
|
32321
|
+
});
|
|
32322
|
+
/**
|
|
32323
|
+
* Runtime schema for {@link GetPositionParams}.
|
|
32324
|
+
*
|
|
32325
|
+
* @example
|
|
32326
|
+
* ```typescript
|
|
32327
|
+
* import { getPositionParamsSchema } from '@circle-fin/borrow-kit'
|
|
32328
|
+
*
|
|
32329
|
+
* const result = getPositionParamsSchema.safeParse({
|
|
32330
|
+
* loanId: '11111111-1111-4111-8111-111111111111',
|
|
32331
|
+
* })
|
|
32332
|
+
* ```
|
|
32333
|
+
*/ zod.z.object({
|
|
32334
|
+
loanId: zod.z.string().uuid(),
|
|
32335
|
+
config: borrowServiceConfigSchema.optional()
|
|
32336
|
+
}).strict();
|
|
32337
|
+
/**
|
|
32338
|
+
* Schema for the adapter context within Borrow operations.
|
|
32339
|
+
*
|
|
32340
|
+
* `.strict()` so a typo nested inside `from` fails fast instead of being
|
|
32341
|
+
* silently stripped. The address field is optional (resolved from the
|
|
32342
|
+
* adapter at runtime).
|
|
32343
|
+
*
|
|
32344
|
+
* @internal
|
|
32345
|
+
*/ const borrowAdapterContextSchema = zod.z.object({
|
|
32346
|
+
// signTypedData/capabilities are declared in the shape (rather than
|
|
32347
|
+
// checked only via .passthrough()) so their values are read off the input
|
|
32348
|
+
// by property access: .passthrough() only copies an input's own
|
|
32349
|
+
// enumerable keys into its output, which drops a prototype method or
|
|
32350
|
+
// getter like a class's signTypedData/capabilities. capabilities is read
|
|
32351
|
+
// by refineAddressContext below.
|
|
32352
|
+
adapter: adapterSchema.extend({
|
|
32353
|
+
signTypedData: zod.z.unknown(),
|
|
32354
|
+
capabilities: zod.z.unknown()
|
|
32355
|
+
}).passthrough().refine(// supportsSignTypedData is optional on SignTypedDataAdapter (see
|
|
32356
|
+
// @core/adapter-evm's hasSignTypedData/canSignTypedData): only
|
|
32357
|
+
// signTypedData itself is required here.
|
|
32358
|
+
(adapter)=>typeof adapter.signTypedData === 'function', 'adapter must support signTypedData'),
|
|
32359
|
+
// BorrowAdapterContext accepts a wider chain field, but runtime
|
|
32360
|
+
// validation must stay constrained to chains where loans exist. No cast
|
|
32361
|
+
// needed here: inferring straight from borrowChainIdentifierSchema keeps
|
|
32362
|
+
// this schema's exported type accurate (only the Borrow chain set),
|
|
32363
|
+
// unlike the previous `as unknown as typeof chainIdentifierSchema` cast,
|
|
32364
|
+
// which over-widened it to the full ChainIdentifier union.
|
|
32365
|
+
chain: borrowChainIdentifierSchema,
|
|
32366
|
+
address: zod.z.string().min(1, 'address must not be empty').optional()
|
|
32367
|
+
}).strict()// Same address/adapter-capability contract every other Borrow Kit write
|
|
32368
|
+
// enforces via borrowExecutionFromSchema: a developer-controlled adapter
|
|
32369
|
+
// without `address` fails fast with a named message instead of falling
|
|
32370
|
+
// through to adapter.getAddress(); a user-controlled adapter with `address`
|
|
32371
|
+
// set is rejected instead of silently taking precedence.
|
|
32372
|
+
.superRefine(refineAddressContext);
|
|
32373
|
+
/** @internal */ const borrowParamsBaseSchema = zod.z.object({
|
|
32374
|
+
from: adapterContextSchema,
|
|
32375
|
+
borrowAmount: createPositiveAmountSchema('borrowAmount'),
|
|
32376
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
32377
|
+
idempotencyKey: idempotencyKeySchema.optional(),
|
|
32378
|
+
config: borrowServiceConfigSchema.optional()
|
|
32379
|
+
});
|
|
32380
|
+
/**
|
|
32381
|
+
* Runtime schema for {@link BorrowParams}.
|
|
32382
|
+
*
|
|
32383
|
+
* One strict object with a refinement, rather than a union of a market branch
|
|
32384
|
+
* and a loan branch: a union that fails every branch reports one `invalid_union`
|
|
32385
|
+
* issue, which costs the caller the field that actually failed. The refinement
|
|
32386
|
+
* states the rule it enforces, and every other field keeps naming itself.
|
|
32387
|
+
*/ borrowParamsBaseSchema.extend({
|
|
32388
|
+
marketId: zod.z.string().min(1).optional(),
|
|
32389
|
+
loanId: zod.z.string().uuid().optional()
|
|
32390
|
+
}).strict().refine((params)=>params.marketId === undefined !== (params.loanId === undefined), {
|
|
32391
|
+
message: 'Provide exactly one of marketId or loanId'
|
|
32392
|
+
});
|
|
32393
|
+
/**
|
|
32394
|
+
* Schema for the adapter context within reward-claiming operations.
|
|
32395
|
+
*
|
|
32396
|
+
* Validate that a properly-shaped adapter instance and a valid chain
|
|
32397
|
+
* identifier are provided. The address field is optional at the schema
|
|
32398
|
+
* level (resolved from the adapter at runtime for user-controlled
|
|
32399
|
+
* adapters, required for developer-controlled ones — that distinction is
|
|
32400
|
+
* enforced by {@link BorrowAdapterContext}'s conditional `AddressField`,
|
|
32401
|
+
* not by this runtime schema). `.strict()` so a typo nested inside `from`
|
|
32402
|
+
* fails fast instead of being silently stripped.
|
|
32403
|
+
*
|
|
32404
|
+
* Reward claiming is restricted to the Borrow chain identifiers (Arc and
|
|
32405
|
+
* Arc Testnet), which is narrower than the general
|
|
32406
|
+
* {@link chainIdentifierSchema} `repay`/`borrow` accept.
|
|
32407
|
+
*
|
|
32408
|
+
* @internal
|
|
32409
|
+
*/ const claimRewardsAdapterContextSchema = zod.z.object({
|
|
32410
|
+
adapter: adapterSchema,
|
|
32411
|
+
chain: borrowChainIdentifierSchema,
|
|
32412
|
+
address: evmAddressSchema$1.optional()
|
|
32413
|
+
}).strict()// Same address/adapter-capability contract every other Borrow Kit write
|
|
32414
|
+
// enforces via borrowExecutionFromSchema: a developer-controlled adapter
|
|
32415
|
+
// without `address` fails fast with a named message instead of falling
|
|
32416
|
+
// through to adapter.getAddress(); a user-controlled adapter with `address`
|
|
32417
|
+
// set is rejected instead of silently taking precedence.
|
|
32418
|
+
.superRefine(refineAddressContext);
|
|
32419
|
+
/** @internal */ const borrowPreviewParamsBaseSchema = zod.z.object({
|
|
32420
|
+
chain: chainIdentifierSchema,
|
|
32421
|
+
marketId: zod.z.string().min(1),
|
|
32422
|
+
config: borrowServiceConfigSchema.optional()
|
|
32423
|
+
});
|
|
32424
|
+
/** Runtime schema for a first-open borrow quote. @internal */ const openLoanQuoteParamsSchema = borrowPreviewParamsBaseSchema.extend({
|
|
32425
|
+
walletAddress: evmAddressSchema$1,
|
|
32426
|
+
borrowAmount: createPositiveAmountSchema('borrowAmount'),
|
|
32427
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional()
|
|
32428
|
+
}).strict();
|
|
32429
|
+
/** Runtime schema for an existing-loan borrow quote. @internal */ const borrowMoreQuoteParamsSchema = zod.z.object({
|
|
32430
|
+
loanId: zod.z.string().uuid(),
|
|
32431
|
+
borrowAmount: createPositiveAmountSchema('borrowAmount'),
|
|
32432
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
32433
|
+
config: borrowServiceConfigSchema.optional()
|
|
32434
|
+
}).strict();
|
|
32435
|
+
/** Runtime schema for {@link BorrowQuoteParams}. */ zod.z.union([
|
|
32436
|
+
openLoanQuoteParamsSchema,
|
|
32437
|
+
borrowMoreQuoteParamsSchema
|
|
32438
|
+
]);
|
|
32439
|
+
/** Runtime schema for {@link RequiredCollateralParams}. */ borrowPreviewParamsBaseSchema.extend({
|
|
32440
|
+
borrowAmount: createPositiveAmountSchema('borrowAmount'),
|
|
32441
|
+
targetHealthFactor: zod.z.number().positive().finite()
|
|
32442
|
+
}).strict();
|
|
32443
|
+
// Uncapped: repayments are USDC, but collateral is the market's own token and
|
|
32444
|
+
// may hold more precision than USDC's six places.
|
|
32445
|
+
/** @internal */ const collateralAmountSchema = createPositiveAmountSchema('collateralAmount', null);
|
|
32446
|
+
/**
|
|
32447
|
+
* Validation schema for ClaimRewardsParams.
|
|
32448
|
+
*
|
|
32449
|
+
* @example
|
|
32450
|
+
* ```typescript
|
|
32451
|
+
* import { claimRewardsParamsSchema } from '@circle-fin/borrow-kit'
|
|
32452
|
+
*
|
|
32453
|
+
* const result = claimRewardsParamsSchema.safeParse({
|
|
32454
|
+
* from: { adapter, chain: 'Arc_Testnet' },
|
|
32455
|
+
* })
|
|
32456
|
+
* ```
|
|
32457
|
+
*/ zod.z.object({
|
|
32458
|
+
from: claimRewardsAdapterContextSchema,
|
|
32459
|
+
config: borrowServiceConfigSchema.optional()
|
|
32460
|
+
}).strict();
|
|
32461
|
+
/**
|
|
32462
|
+
* Validation schema for GetClaimRewardsQuoteParams.
|
|
32463
|
+
*
|
|
32464
|
+
* @example
|
|
32465
|
+
* ```typescript
|
|
32466
|
+
* import { getClaimRewardsQuoteParamsSchema } from '@circle-fin/borrow-kit'
|
|
32467
|
+
*
|
|
32468
|
+
* const result = getClaimRewardsQuoteParamsSchema.safeParse({
|
|
32469
|
+
* from: { adapter, chain: 'Arc_Testnet' },
|
|
32470
|
+
* })
|
|
32471
|
+
* ```
|
|
32472
|
+
*/ zod.z.object({
|
|
32473
|
+
from: claimRewardsAdapterContextSchema,
|
|
32474
|
+
config: borrowServiceConfigSchema.optional()
|
|
32475
|
+
}).strict();
|
|
32476
|
+
/** @internal */ const marketSortBySchema = zod.z.enum([
|
|
32477
|
+
'lltv',
|
|
32478
|
+
'borrowApy'
|
|
32479
|
+
]);
|
|
32480
|
+
/**
|
|
32481
|
+
* Build a schema for an optional non-negative decimal filter string.
|
|
32482
|
+
*
|
|
32483
|
+
* Accepts values like `'0'`, `'100'`, `'0.86'`; rejects negatives, leading
|
|
32484
|
+
* dots, and non-numeric input so a malformed filter fails fast.
|
|
32485
|
+
*
|
|
32486
|
+
* @param field - The filter field name, used in the rejection message.
|
|
32487
|
+
* @returns A Zod string schema constrained to a non-negative decimal form.
|
|
32488
|
+
* @internal
|
|
32489
|
+
*/ function decimalFilterSchema(field) {
|
|
32490
|
+
return zod.z.string().regex(/^\d+(\.\d+)?$/, `${field} must be a non-negative decimal string`);
|
|
32491
|
+
}
|
|
32492
|
+
const exploreMarketsParamsBase = zod.z.object({
|
|
32493
|
+
chain: chainIdentifierSchema,
|
|
32494
|
+
minLltv: decimalFilterSchema('minLltv').optional(),
|
|
32495
|
+
maxLltv: decimalFilterSchema('maxLltv').optional(),
|
|
32496
|
+
minBorrow: decimalFilterSchema('minBorrow').optional(),
|
|
32497
|
+
maxBorrow: decimalFilterSchema('maxBorrow').optional(),
|
|
32498
|
+
sortBy: marketSortBySchema.optional(),
|
|
32499
|
+
// Provisional bounds: the backend has not published a pageSize range, so
|
|
32500
|
+
// reject only implausible values rather than plausible ones.
|
|
32501
|
+
pageSize: zod.z.number().int('pageSize must be an integer').min(1, 'pageSize must be at least 1').max(1000, 'pageSize must be at most 1000').optional(),
|
|
32502
|
+
pageAfter: zod.z.string().min(1, 'pageAfter must not be empty').optional(),
|
|
32503
|
+
config: borrowServiceConfigSchema.optional()
|
|
32504
|
+
}).strict();
|
|
32505
|
+
/**
|
|
32506
|
+
* Runtime schema for {@link MaxBorrowParams}.
|
|
32507
|
+
*
|
|
32508
|
+
* The collateral amount is not held to the loan asset's six decimal places: it
|
|
32509
|
+
* denominates the market's collateral token, whose precision may be finer.
|
|
32510
|
+
*/ borrowPreviewParamsBaseSchema.extend({
|
|
32511
|
+
collateralAmount: collateralAmountSchema
|
|
32512
|
+
}).strict();
|
|
32513
|
+
/** Runtime schema for {@link WithdrawCollateralQuoteParams}. */ const withdrawCollateralQuoteParamsSchema = zod.z.object({
|
|
32514
|
+
loanId: zod.z.string().uuid(),
|
|
32515
|
+
chain: chainIdentifierSchema,
|
|
32516
|
+
collateralAmount: collateralAmountSchema,
|
|
32517
|
+
slippageBps: zod.z.number().int().min(0).max(10_000).optional(),
|
|
32518
|
+
config: borrowServiceConfigSchema.optional()
|
|
32519
|
+
}).strict();
|
|
32520
|
+
/**
|
|
32521
|
+
* Maximum accepted signature deadline: 300 seconds from now, matching the
|
|
32522
|
+
* Borrow Service's own hard limit on `WebhookRegistration` deadlines. A wider
|
|
32523
|
+
* SDK-side window would let a caller sign a deadline the service always
|
|
32524
|
+
* rejects.
|
|
32525
|
+
*
|
|
32526
|
+
* @internal
|
|
32527
|
+
*/ const MAX_DEADLINE_SKEW_SECONDS = 300;
|
|
32528
|
+
/**
|
|
32529
|
+
* True when `value` parses as a URL whose scheme is exactly `https:`.
|
|
32530
|
+
*
|
|
32531
|
+
* Uses the WHATWG `URL` parser rather than `startsWith('https://')` so the
|
|
32532
|
+
* check is scheme-normalized (case-insensitive, e.g. `HTTPS://...` still
|
|
32533
|
+
* passes) instead of a literal prefix match. `value` has already passed
|
|
32534
|
+
* `z.string().url()` by the time this runs, but a caller could still supply
|
|
32535
|
+
* a string that `URL` itself rejects, so the parse is guarded.
|
|
32536
|
+
*
|
|
32537
|
+
* @internal
|
|
32538
|
+
*/ function isHttpsUrl(value) {
|
|
32539
|
+
try {
|
|
32540
|
+
return new URL(value).protocol === 'https:';
|
|
32541
|
+
} catch {
|
|
32542
|
+
return false;
|
|
32543
|
+
}
|
|
32544
|
+
}
|
|
32545
|
+
/**
|
|
32546
|
+
* Validation schema for RegisterWebhookParams.
|
|
32547
|
+
*
|
|
32548
|
+
* @example
|
|
32549
|
+
* ```typescript
|
|
32550
|
+
* import { registerWebhookParamsSchema } from '@circle-fin/borrow-kit'
|
|
32551
|
+
*
|
|
32552
|
+
* const result = registerWebhookParamsSchema.safeParse({
|
|
32553
|
+
* from: { adapter, chain: 'Arc_Testnet' },
|
|
32554
|
+
* loanId: '11111111-1111-4111-8111-111111111111',
|
|
32555
|
+
* webhookUrl: 'https://example.com/webhook',
|
|
32556
|
+
* })
|
|
32557
|
+
* ```
|
|
32558
|
+
*/ zod.z.object({
|
|
32559
|
+
from: borrowAdapterContextSchema,
|
|
32560
|
+
// loanId must be a UUID, consistent with every other loan-scoped schema
|
|
32561
|
+
// in this package (repayQuoteParamsSchema, closeLoanQuoteParamsSchema,
|
|
32562
|
+
// borrowParamsSchema) and with the provider-level
|
|
32563
|
+
// registerWebhookInputSchema, which already enforces this.
|
|
32564
|
+
loanId: zod.z.string().uuid(),
|
|
32565
|
+
// Restricted to https: for the same reason as the provider-level
|
|
32566
|
+
// registerWebhookInputSchema — this URL receives a cryptographically
|
|
32567
|
+
// signed, owner-authorized registration, and http:// would let that
|
|
32568
|
+
// signed intent point at a plaintext or link-local/loopback endpoint.
|
|
32569
|
+
webhookUrl: zod.z.string().url('webhookUrl must be a valid URL').refine((value)=>isHttpsUrl(value), 'webhookUrl must use the https scheme').nullable().optional(),
|
|
32570
|
+
deadline: zod.z.number().int('deadline must be an integer unix-seconds timestamp').refine((deadline)=>deadline > Math.floor(Date.now() / 1000), 'deadline must be in the future — a past deadline would sign a message the Borrow Service always rejects').refine((deadline)=>deadline <= Math.floor(Date.now() / 1000) + MAX_DEADLINE_SKEW_SECONDS, `deadline must be at most ${String(MAX_DEADLINE_SKEW_SECONDS)} seconds from now`).optional(),
|
|
32571
|
+
config: borrowServiceConfigSchema.optional()
|
|
32572
|
+
}).strict();
|
|
32573
|
+
/**
|
|
32574
|
+
* Reject a filter range whose lower bound exceeds its upper bound.
|
|
32575
|
+
*
|
|
32576
|
+
* Each bound is validated independently, so `{ minLltv: '0.9', maxLltv: '0.1' }`
|
|
32577
|
+
* would otherwise pass and return a silently empty page; comparing the bounds
|
|
32578
|
+
* numerically turns that contradiction into a clear validation error. Shared by
|
|
32579
|
+
* the single-page and iterator schemas so the two cannot drift.
|
|
32580
|
+
*
|
|
32581
|
+
* @param value - The parsed explore filters.
|
|
32582
|
+
* @param ctx - The Zod refinement context that collects any range issues.
|
|
32583
|
+
* @internal
|
|
32584
|
+
*/ function refineFilterRanges(value, ctx) {
|
|
32585
|
+
if (value.minLltv !== undefined && value.maxLltv !== undefined && Number(value.minLltv) > Number(value.maxLltv)) {
|
|
32586
|
+
ctx.addIssue({
|
|
32587
|
+
code: zod.z.ZodIssueCode.custom,
|
|
32588
|
+
path: [
|
|
32589
|
+
'maxLltv'
|
|
32590
|
+
],
|
|
32591
|
+
message: 'maxLltv must be greater than or equal to minLltv'
|
|
32592
|
+
});
|
|
32593
|
+
}
|
|
32594
|
+
if (value.minBorrow !== undefined && value.maxBorrow !== undefined && Number(value.minBorrow) > Number(value.maxBorrow)) {
|
|
32595
|
+
ctx.addIssue({
|
|
32596
|
+
code: zod.z.ZodIssueCode.custom,
|
|
32597
|
+
path: [
|
|
32598
|
+
'maxBorrow'
|
|
32599
|
+
],
|
|
32600
|
+
message: 'maxBorrow must be greater than or equal to minBorrow'
|
|
32601
|
+
});
|
|
32602
|
+
}
|
|
32603
|
+
}
|
|
32604
|
+
/**
|
|
32605
|
+
* Runtime schema for {@link ExploreMarketsParams}.
|
|
32606
|
+
*
|
|
32607
|
+
* `chain` is required; every filter is optional. `pageAfter` is an opaque
|
|
32608
|
+
* non-empty cursor and `pageSize` a positive integer (provisional upper bound
|
|
32609
|
+
* 1000, pending backend confirmation). Unknown keys are rejected, and a range
|
|
32610
|
+
* whose minimum exceeds its maximum is rejected rather than returning a
|
|
32611
|
+
* silently empty page.
|
|
32612
|
+
*
|
|
32613
|
+
* @example
|
|
32614
|
+
* ```typescript
|
|
32615
|
+
* import { exploreMarketsParamsSchema } from '@circle-fin/borrow-kit'
|
|
32616
|
+
*
|
|
32617
|
+
* const result = exploreMarketsParamsSchema.safeParse({
|
|
32618
|
+
* chain: 'Arc_Testnet',
|
|
32619
|
+
* minLltv: '0.8',
|
|
32620
|
+
* sortBy: 'borrowApy',
|
|
32621
|
+
* })
|
|
32622
|
+
* ```
|
|
32623
|
+
*/ exploreMarketsParamsBase.superRefine(refineFilterRanges);
|
|
32624
|
+
/**
|
|
32625
|
+
* Runtime schema for {@link ExploreMarketsIteratorParams}.
|
|
32626
|
+
*
|
|
32627
|
+
* Identical to {@link exploreMarketsParamsSchema} minus `pageAfter`: the
|
|
32628
|
+
* iterator owns the cursor and advances through pages itself.
|
|
32629
|
+
*
|
|
32630
|
+
* @example
|
|
32631
|
+
* ```typescript
|
|
32632
|
+
* import { exploreMarketsIteratorParamsSchema } from '@circle-fin/borrow-kit'
|
|
32633
|
+
*
|
|
32634
|
+
* const result = exploreMarketsIteratorParamsSchema.safeParse({
|
|
32635
|
+
* chain: 'Arc_Testnet',
|
|
32636
|
+
* sortBy: 'borrowApy',
|
|
32637
|
+
* })
|
|
32638
|
+
* ```
|
|
32639
|
+
*/ exploreMarketsParamsBase.omit({
|
|
32640
|
+
pageAfter: true
|
|
32641
|
+
}).superRefine(refineFilterRanges);
|
|
32642
|
+
/** Runtime schema for {@link WithdrawCollateralParams}. */ withdrawCollateralQuoteParamsSchema.omit({
|
|
32643
|
+
chain: true
|
|
32644
|
+
}).extend({
|
|
32645
|
+
idempotencyKey: idempotencyKeySchema.optional(),
|
|
32646
|
+
from: borrowExecutionFromSchema
|
|
32647
|
+
});
|
|
32648
|
+
/** Runtime schema for {@link AddCollateralQuoteParams}. */ const addCollateralQuoteParamsSchema = zod.z.object({
|
|
32649
|
+
loanId: zod.z.string().uuid(),
|
|
32650
|
+
chain: chainIdentifierSchema,
|
|
32651
|
+
collateralAmount: collateralAmountSchema,
|
|
32652
|
+
config: borrowServiceConfigSchema.optional()
|
|
32653
|
+
}).strict();
|
|
32654
|
+
/** Runtime schema for {@link AddCollateralParams}. */ addCollateralQuoteParamsSchema.omit({
|
|
32655
|
+
chain: true
|
|
32656
|
+
}).extend({
|
|
32657
|
+
idempotencyKey: idempotencyKeySchema.optional(),
|
|
32658
|
+
from: borrowExecutionFromSchema
|
|
32659
|
+
});
|
|
32660
|
+
|
|
31009
32661
|
/** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg.name);
|
|
31010
32662
|
|
|
31011
32663
|
// Auto-register this kit for user agent tracking
|