@circle-fin/bridge-kit 1.1.1 → 1.1.2
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 +15 -0
- package/index.cjs +145 -46
- package/index.d.ts +55 -25
- package/index.mjs +145 -46
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @circle-fin/bridge-kit
|
|
2
2
|
|
|
3
|
+
## 1.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed bug where tokens could be burned when bridging to unsupported chains, and improved error messages to clearly show which chains are supported.
|
|
8
|
+
|
|
9
|
+
**What's Fixed:**
|
|
10
|
+
- **Prevents fund loss**: Bridge operations now fail immediately if your adapter doesn't support the source or destination chain, **before** any tokens are approved or burned. Previously, tokens could be burned on the source chain before discovering the destination chain was unsupported, requiring manual recovery.
|
|
11
|
+
- **Better error messages**: When you attempt to use an unsupported chain, the error now clearly lists all chains your adapter supports, making it easy to pick an alternative:
|
|
12
|
+
```
|
|
13
|
+
Invalid chain 'Linea Sepolia': Not supported by this adapter.
|
|
14
|
+
It supports 17 chains: Arbitrum, Base, Ethereum, Polygon, Solana, ...
|
|
15
|
+
```
|
|
16
|
+
- **Correct error codes**: Chain validation errors now use the correct `INVALID_CHAIN` error code instead of `UNSUPPORTED_ROUTE`, making it easier to handle errors programmatically.
|
|
17
|
+
|
|
3
18
|
## 1.1.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/index.cjs
CHANGED
|
@@ -2741,7 +2741,7 @@ class Actionable {
|
|
|
2741
2741
|
}
|
|
2742
2742
|
|
|
2743
2743
|
var name = "@circle-fin/bridge-kit";
|
|
2744
|
-
var version = "1.1.
|
|
2744
|
+
var version = "1.1.2";
|
|
2745
2745
|
var pkg = {
|
|
2746
2746
|
name: name,
|
|
2747
2747
|
version: version};
|
|
@@ -2758,9 +2758,71 @@ const RECOVERABILITY_VALUES = [
|
|
|
2758
2758
|
'RESUMABLE',
|
|
2759
2759
|
'FATAL',
|
|
2760
2760
|
];
|
|
2761
|
+
/**
|
|
2762
|
+
* Error type constants for categorizing errors by origin.
|
|
2763
|
+
*
|
|
2764
|
+
* This const object provides a reference for error types, enabling
|
|
2765
|
+
* IDE autocomplete and preventing typos when creating custom errors.
|
|
2766
|
+
*
|
|
2767
|
+
* @remarks
|
|
2768
|
+
* While internal error definitions use string literals with type annotations
|
|
2769
|
+
* for strict type safety, this constant is useful for developers creating
|
|
2770
|
+
* custom error instances or checking error types programmatically.
|
|
2771
|
+
*
|
|
2772
|
+
* @example
|
|
2773
|
+
* ```typescript
|
|
2774
|
+
* import { ERROR_TYPES, KitError } from '@core/errors'
|
|
2775
|
+
*
|
|
2776
|
+
* // Use for type checking
|
|
2777
|
+
* if (error.type === ERROR_TYPES.BALANCE) {
|
|
2778
|
+
* console.log('This is a balance error')
|
|
2779
|
+
* }
|
|
2780
|
+
* ```
|
|
2781
|
+
*
|
|
2782
|
+
* @example
|
|
2783
|
+
* ```typescript
|
|
2784
|
+
* // Use as reference when creating custom errors
|
|
2785
|
+
* const error = new KitError({
|
|
2786
|
+
* code: 9999,
|
|
2787
|
+
* name: 'CUSTOM_ERROR',
|
|
2788
|
+
* type: ERROR_TYPES.BALANCE, // IDE autocomplete works here
|
|
2789
|
+
* recoverability: 'FATAL',
|
|
2790
|
+
* message: 'Custom balance error'
|
|
2791
|
+
* })
|
|
2792
|
+
* ```
|
|
2793
|
+
*/
|
|
2794
|
+
const ERROR_TYPES = {
|
|
2795
|
+
/** User input validation and parameter checking */
|
|
2796
|
+
INPUT: 'INPUT',
|
|
2797
|
+
/** Insufficient token balances and amount validation */
|
|
2798
|
+
BALANCE: 'BALANCE',
|
|
2799
|
+
/** On-chain execution: reverts, gas issues, transaction failures */
|
|
2800
|
+
ONCHAIN: 'ONCHAIN',
|
|
2801
|
+
/** Blockchain RPC provider issues and endpoint problems */
|
|
2802
|
+
RPC: 'RPC',
|
|
2803
|
+
/** Internet connectivity, DNS resolution, connection issues */
|
|
2804
|
+
NETWORK: 'NETWORK',
|
|
2805
|
+
};
|
|
2806
|
+
/**
|
|
2807
|
+
* Array of valid error type values for validation.
|
|
2808
|
+
* Derived from ERROR_TYPES const object.
|
|
2809
|
+
*/
|
|
2810
|
+
const ERROR_TYPE_VALUES = Object.values(ERROR_TYPES);
|
|
2761
2811
|
|
|
2762
|
-
// Create
|
|
2812
|
+
// Create mutable arrays for Zod enum validation
|
|
2763
2813
|
const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
2814
|
+
const ERROR_TYPE_ARRAY = [...ERROR_TYPE_VALUES];
|
|
2815
|
+
/**
|
|
2816
|
+
* Error code ranges for validation.
|
|
2817
|
+
* Single source of truth for valid error code ranges.
|
|
2818
|
+
*/
|
|
2819
|
+
const ERROR_CODE_RANGES = [
|
|
2820
|
+
{ min: 1000, max: 1999, type: 'INPUT' },
|
|
2821
|
+
{ min: 3000, max: 3999, type: 'NETWORK' },
|
|
2822
|
+
{ min: 4000, max: 4999, type: 'RPC' },
|
|
2823
|
+
{ min: 5000, max: 5999, type: 'ONCHAIN' },
|
|
2824
|
+
{ min: 9000, max: 9999, type: 'BALANCE' },
|
|
2825
|
+
];
|
|
2764
2826
|
/**
|
|
2765
2827
|
* Zod schema for validating ErrorDetails objects.
|
|
2766
2828
|
*
|
|
@@ -2773,7 +2835,8 @@ const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
|
2773
2835
|
*
|
|
2774
2836
|
* const result = errorDetailsSchema.safeParse({
|
|
2775
2837
|
* code: 1001,
|
|
2776
|
-
* name: '
|
|
2838
|
+
* name: 'INPUT_NETWORK_MISMATCH',
|
|
2839
|
+
* type: 'INPUT',
|
|
2777
2840
|
* recoverability: 'FATAL',
|
|
2778
2841
|
* message: 'Source and destination networks must be different'
|
|
2779
2842
|
* })
|
|
@@ -2782,30 +2845,56 @@ const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
|
2782
2845
|
* console.error('Validation failed:', result.error.issues)
|
|
2783
2846
|
* }
|
|
2784
2847
|
* ```
|
|
2848
|
+
*
|
|
2849
|
+
* @example
|
|
2850
|
+
* ```typescript
|
|
2851
|
+
* // Runtime error
|
|
2852
|
+
* const result = errorDetailsSchema.safeParse({
|
|
2853
|
+
* code: 9001,
|
|
2854
|
+
* name: 'BALANCE_INSUFFICIENT_TOKEN',
|
|
2855
|
+
* type: 'BALANCE',
|
|
2856
|
+
* recoverability: 'FATAL',
|
|
2857
|
+
* message: 'Insufficient USDC balance'
|
|
2858
|
+
* })
|
|
2859
|
+
* ```
|
|
2785
2860
|
*/
|
|
2786
2861
|
const errorDetailsSchema = zod.z.object({
|
|
2787
|
-
/**
|
|
2862
|
+
/**
|
|
2863
|
+
* Numeric identifier following standardized ranges:
|
|
2864
|
+
* - 1000-1999: INPUT errors - Parameter validation
|
|
2865
|
+
* - 3000-3999: NETWORK errors - Connectivity issues
|
|
2866
|
+
* - 4000-4999: RPC errors - Provider issues, gas estimation
|
|
2867
|
+
* - 5000-5999: ONCHAIN errors - Transaction/simulation failures
|
|
2868
|
+
* - 9000-9999: BALANCE errors - Insufficient funds
|
|
2869
|
+
*/
|
|
2788
2870
|
code: zod.z
|
|
2789
2871
|
.number()
|
|
2790
2872
|
.int('Error code must be an integer')
|
|
2791
|
-
.
|
|
2792
|
-
|
|
2793
|
-
|
|
2873
|
+
.refine((code) => ERROR_CODE_RANGES.some((range) => code >= range.min && code <= range.max), {
|
|
2874
|
+
message: 'Error code must be in valid ranges: 1000-1999 (INPUT), 3000-3999 (NETWORK), 4000-4999 (RPC), 5000-5999 (ONCHAIN), 9000-9999 (BALANCE)',
|
|
2875
|
+
}),
|
|
2876
|
+
/** Human-readable ID (e.g., "INPUT_NETWORK_MISMATCH", "BALANCE_INSUFFICIENT_TOKEN") */
|
|
2794
2877
|
name: zod.z
|
|
2795
2878
|
.string()
|
|
2796
2879
|
.min(1, 'Error name must be a non-empty string')
|
|
2797
2880
|
.regex(/^[A-Z_][A-Z0-9_]*$/, 'Error name must match pattern: ^[A-Z_][A-Z0-9_]*$'),
|
|
2881
|
+
/** Error category indicating where the error originated */
|
|
2882
|
+
type: zod.z.enum(ERROR_TYPE_ARRAY, {
|
|
2883
|
+
errorMap: () => ({
|
|
2884
|
+
message: 'Error type must be one of: INPUT, BALANCE, ONCHAIN, RPC, NETWORK',
|
|
2885
|
+
}),
|
|
2886
|
+
}),
|
|
2798
2887
|
/** Error handling strategy */
|
|
2799
2888
|
recoverability: zod.z.enum(RECOVERABILITY_ARRAY, {
|
|
2800
2889
|
errorMap: () => ({
|
|
2801
2890
|
message: 'Recoverability must be one of: RETRYABLE, RESUMABLE, FATAL',
|
|
2802
2891
|
}),
|
|
2803
2892
|
}),
|
|
2804
|
-
/** User-friendly explanation with
|
|
2893
|
+
/** User-friendly explanation with context */
|
|
2805
2894
|
message: zod.z
|
|
2806
2895
|
.string()
|
|
2807
2896
|
.min(1, 'Error message must be a non-empty string')
|
|
2808
|
-
.max(
|
|
2897
|
+
.max(1000, 'Error message must be 1000 characters or less'),
|
|
2809
2898
|
/** Raw error details, context, or the original error that caused this one. */
|
|
2810
2899
|
cause: zod.z
|
|
2811
2900
|
.object({
|
|
@@ -2820,7 +2909,7 @@ const errorDetailsSchema = zod.z.object({
|
|
|
2820
2909
|
*
|
|
2821
2910
|
* @param details - The object to validate
|
|
2822
2911
|
* @returns The validated ErrorDetails object
|
|
2823
|
-
* @throws
|
|
2912
|
+
* @throws TypeError When validation fails
|
|
2824
2913
|
*
|
|
2825
2914
|
* @example
|
|
2826
2915
|
* ```typescript
|
|
@@ -2897,6 +2986,8 @@ class KitError extends Error {
|
|
|
2897
2986
|
code;
|
|
2898
2987
|
/** Human-readable ID (e.g., "NETWORK_MISMATCH") */
|
|
2899
2988
|
name;
|
|
2989
|
+
/** Error category indicating where the error originated */
|
|
2990
|
+
type;
|
|
2900
2991
|
/** Error handling strategy */
|
|
2901
2992
|
recoverability;
|
|
2902
2993
|
/** Raw error details, context, or the original error that caused this one. */
|
|
@@ -2925,6 +3016,12 @@ class KitError extends Error {
|
|
|
2925
3016
|
enumerable: true,
|
|
2926
3017
|
configurable: false,
|
|
2927
3018
|
},
|
|
3019
|
+
type: {
|
|
3020
|
+
value: validatedDetails.type,
|
|
3021
|
+
writable: false,
|
|
3022
|
+
enumerable: true,
|
|
3023
|
+
configurable: false,
|
|
3024
|
+
},
|
|
2928
3025
|
recoverability: {
|
|
2929
3026
|
value: validatedDetails.recoverability,
|
|
2930
3027
|
writable: false,
|
|
@@ -2944,20 +3041,19 @@ class KitError extends Error {
|
|
|
2944
3041
|
}
|
|
2945
3042
|
|
|
2946
3043
|
/**
|
|
2947
|
-
*
|
|
2948
|
-
*
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
*
|
|
2953
|
-
*
|
|
3044
|
+
* Standardized error code ranges for consistent categorization:
|
|
3045
|
+
*
|
|
3046
|
+
* - 1000-1999: INPUT errors - Parameter validation, input format errors
|
|
3047
|
+
* - 3000-3999: NETWORK errors - Internet connectivity, DNS, connection issues
|
|
3048
|
+
* - 4000-4999: RPC errors - Blockchain provider issues, gas estimation, nonce errors
|
|
3049
|
+
* - 5000-5999: ONCHAIN errors - Transaction/simulation failures, gas exhaustion, reverts
|
|
3050
|
+
* - 9000-9999: BALANCE errors - Insufficient funds, token balance, allowance
|
|
2954
3051
|
*/
|
|
2955
|
-
const INPUT_ERROR_CODE_MAX = 1100;
|
|
2956
3052
|
/**
|
|
2957
3053
|
* Standardized error definitions for INPUT type errors.
|
|
2958
3054
|
*
|
|
2959
|
-
* Each entry combines the numeric error code
|
|
2960
|
-
*
|
|
3055
|
+
* Each entry combines the numeric error code, string name, and type
|
|
3056
|
+
* to ensure consistency when creating error instances.
|
|
2961
3057
|
*
|
|
2962
3058
|
* Error codes follow a hierarchical numbering scheme where the first digit
|
|
2963
3059
|
* indicates the error category (1 = INPUT) and subsequent digits provide
|
|
@@ -2974,9 +3070,10 @@ const INPUT_ERROR_CODE_MAX = 1100;
|
|
|
2974
3070
|
* message: 'Source and destination networks must be different'
|
|
2975
3071
|
* })
|
|
2976
3072
|
*
|
|
2977
|
-
* // Access code and
|
|
3073
|
+
* // Access code, name, and type individually if needed
|
|
2978
3074
|
* console.log(InputError.NETWORK_MISMATCH.code) // 1001
|
|
2979
3075
|
* console.log(InputError.NETWORK_MISMATCH.name) // 'INPUT_NETWORK_MISMATCH'
|
|
3076
|
+
* console.log(InputError.NETWORK_MISMATCH.type) // 'INPUT'
|
|
2980
3077
|
* ```
|
|
2981
3078
|
*/
|
|
2982
3079
|
const InputError = {
|
|
@@ -2984,31 +3081,37 @@ const InputError = {
|
|
|
2984
3081
|
NETWORK_MISMATCH: {
|
|
2985
3082
|
code: 1001,
|
|
2986
3083
|
name: 'INPUT_NETWORK_MISMATCH',
|
|
3084
|
+
type: 'INPUT',
|
|
2987
3085
|
},
|
|
2988
3086
|
/** Invalid amount format or value (negative, zero, or malformed) */
|
|
2989
3087
|
INVALID_AMOUNT: {
|
|
2990
3088
|
code: 1002,
|
|
2991
3089
|
name: 'INPUT_INVALID_AMOUNT',
|
|
3090
|
+
type: 'INPUT',
|
|
2992
3091
|
},
|
|
2993
3092
|
/** Unsupported or invalid bridge route configuration */
|
|
2994
3093
|
UNSUPPORTED_ROUTE: {
|
|
2995
3094
|
code: 1003,
|
|
2996
3095
|
name: 'INPUT_UNSUPPORTED_ROUTE',
|
|
3096
|
+
type: 'INPUT',
|
|
2997
3097
|
},
|
|
2998
3098
|
/** Invalid wallet or contract address format */
|
|
2999
3099
|
INVALID_ADDRESS: {
|
|
3000
3100
|
code: 1004,
|
|
3001
3101
|
name: 'INPUT_INVALID_ADDRESS',
|
|
3102
|
+
type: 'INPUT',
|
|
3002
3103
|
},
|
|
3003
3104
|
/** Invalid or unsupported chain identifier */
|
|
3004
3105
|
INVALID_CHAIN: {
|
|
3005
3106
|
code: 1005,
|
|
3006
3107
|
name: 'INPUT_INVALID_CHAIN',
|
|
3108
|
+
type: 'INPUT',
|
|
3007
3109
|
},
|
|
3008
3110
|
/** General validation failure for complex validation rules */
|
|
3009
3111
|
VALIDATION_FAILED: {
|
|
3010
3112
|
code: 1098,
|
|
3011
3113
|
name: 'INPUT_VALIDATION_FAILED',
|
|
3114
|
+
type: 'INPUT',
|
|
3012
3115
|
},
|
|
3013
3116
|
};
|
|
3014
3117
|
|
|
@@ -3254,39 +3357,31 @@ function isRetryableError(error) {
|
|
|
3254
3357
|
return isKitError(error) && error.recoverability === 'RETRYABLE';
|
|
3255
3358
|
}
|
|
3256
3359
|
/**
|
|
3257
|
-
*
|
|
3360
|
+
* Type guard to check if error is KitError with INPUT type.
|
|
3258
3361
|
*
|
|
3259
|
-
* INPUT errors
|
|
3260
|
-
*
|
|
3261
|
-
*
|
|
3262
|
-
* input before retrying.
|
|
3362
|
+
* INPUT errors represent validation failures, invalid parameters,
|
|
3363
|
+
* or user input problems. These errors are always FATAL and require
|
|
3364
|
+
* the user to correct their input before retrying.
|
|
3263
3365
|
*
|
|
3264
3366
|
* @param error - Unknown error to check
|
|
3265
|
-
* @returns True if error is KitError with INPUT
|
|
3367
|
+
* @returns True if error is KitError with INPUT type
|
|
3266
3368
|
*
|
|
3267
3369
|
* @example
|
|
3268
3370
|
* ```typescript
|
|
3269
3371
|
* import { isInputError } from '@core/errors'
|
|
3270
|
-
* import { createBridgeKit } from '@core/bridge'
|
|
3271
|
-
*
|
|
3272
|
-
* async function handleBridge() {
|
|
3273
|
-
* const kit = createBridgeKit(config)
|
|
3274
|
-
* const params = { amount: '100', from: 'ethereum', to: 'polygon' }
|
|
3275
3372
|
*
|
|
3276
|
-
*
|
|
3277
|
-
*
|
|
3278
|
-
*
|
|
3279
|
-
*
|
|
3280
|
-
*
|
|
3281
|
-
*
|
|
3373
|
+
* try {
|
|
3374
|
+
* await kit.bridge(params)
|
|
3375
|
+
* } catch (error) {
|
|
3376
|
+
* if (isInputError(error)) {
|
|
3377
|
+
* console.log('Validation error:', error.message)
|
|
3378
|
+
* showValidationUI()
|
|
3282
3379
|
* }
|
|
3283
3380
|
* }
|
|
3284
3381
|
* ```
|
|
3285
3382
|
*/
|
|
3286
3383
|
function isInputError(error) {
|
|
3287
|
-
return
|
|
3288
|
-
error.code >= INPUT_ERROR_CODE_MIN &&
|
|
3289
|
-
error.code < INPUT_ERROR_CODE_MAX);
|
|
3384
|
+
return isKitError(error) && error.type === ERROR_TYPES.INPUT;
|
|
3290
3385
|
}
|
|
3291
3386
|
/**
|
|
3292
3387
|
* Safely extracts error message from any error type.
|
|
@@ -3572,8 +3667,8 @@ function getChainFromParams(params) {
|
|
|
3572
3667
|
/**
|
|
3573
3668
|
* Maximum length for error messages in fallback validation errors.
|
|
3574
3669
|
*
|
|
3575
|
-
* KitError enforces a
|
|
3576
|
-
* fallback validation errors that combine multiple Zod issues, we use
|
|
3670
|
+
* KitError enforces a 1000-character limit on error messages. When creating
|
|
3671
|
+
* fallback validation errors that combine multiple Zod issues, we use 950
|
|
3577
3672
|
* characters to leave a 50-character buffer for:
|
|
3578
3673
|
* - The error message prefix ("Invalid bridge parameters: ")
|
|
3579
3674
|
* - Potential encoding differences or formatting overhead
|
|
@@ -3582,7 +3677,7 @@ function getChainFromParams(params) {
|
|
|
3582
3677
|
* This ensures that even with concatenated issue summaries, the final message
|
|
3583
3678
|
* stays within KitError's constraints.
|
|
3584
3679
|
*/
|
|
3585
|
-
const MAX_MESSAGE_LENGTH =
|
|
3680
|
+
const MAX_MESSAGE_LENGTH = 950;
|
|
3586
3681
|
|
|
3587
3682
|
/**
|
|
3588
3683
|
* Converts a Zod validation error into a specific KitError instance using structured pattern matching.
|
|
@@ -4716,6 +4811,10 @@ function resolveConfig(params) {
|
|
|
4716
4811
|
async function resolveBridgeParams(params) {
|
|
4717
4812
|
const fromChain = resolveChainDefinition(params.from);
|
|
4718
4813
|
const toChain = resolveChainDefinition(params.to);
|
|
4814
|
+
// Validate adapter chain support after resolution
|
|
4815
|
+
// This ensures adapters support the resolved chains before proceeding
|
|
4816
|
+
params.from.adapter.validateChainSupport(fromChain);
|
|
4817
|
+
params.to.adapter.validateChainSupport(toChain);
|
|
4719
4818
|
const [fromAddress, toAddress] = await Promise.all([
|
|
4720
4819
|
resolveAddress(params.from),
|
|
4721
4820
|
resolveAddress(params.to),
|
|
@@ -4893,7 +4992,7 @@ class BridgeKit {
|
|
|
4893
4992
|
async bridge(params) {
|
|
4894
4993
|
// First validate the parameters
|
|
4895
4994
|
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
4896
|
-
// Then resolve chain definitions
|
|
4995
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
4897
4996
|
const resolvedParams = await resolveBridgeParams(params);
|
|
4898
4997
|
// Validate network compatibility
|
|
4899
4998
|
this.validateNetworkCompatibility(resolvedParams);
|
|
@@ -4997,7 +5096,7 @@ class BridgeKit {
|
|
|
4997
5096
|
async estimate(params) {
|
|
4998
5097
|
// First validate the parameters
|
|
4999
5098
|
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
5000
|
-
// Then resolve chain definitions
|
|
5099
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
5001
5100
|
const resolvedParams = await resolveBridgeParams(params);
|
|
5002
5101
|
// Validate network compatibility
|
|
5003
5102
|
this.validateNetworkCompatibility(resolvedParams);
|
package/index.d.ts
CHANGED
|
@@ -1179,6 +1179,14 @@ interface CCTPv2ActionMap {
|
|
|
1179
1179
|
* the adapter's default address.
|
|
1180
1180
|
*/
|
|
1181
1181
|
readonly destinationAddress?: string;
|
|
1182
|
+
/**
|
|
1183
|
+
* The mint recipient address from the decoded CCTP message.
|
|
1184
|
+
*
|
|
1185
|
+
* This is the actual address encoded in the burn message where tokens will be minted.
|
|
1186
|
+
* For Solana, this is already the Associated Token Account (ATA) address, not the owner.
|
|
1187
|
+
* For EVM chains, this is the recipient's wallet address.
|
|
1188
|
+
*/
|
|
1189
|
+
readonly mintRecipient?: string;
|
|
1182
1190
|
};
|
|
1183
1191
|
/**
|
|
1184
1192
|
* Initiate a cross-chain USDC transfer using a custom bridge contract with preapproval funnel.
|
|
@@ -2120,10 +2128,10 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2120
2128
|
* This address is used as the default sender for transactions
|
|
2121
2129
|
* and interactions initiated by this adapter.
|
|
2122
2130
|
*
|
|
2123
|
-
* @param chain -
|
|
2131
|
+
* @param chain - The chain to use for address resolution.
|
|
2124
2132
|
* @returns A promise that resolves to the blockchain address as a string.
|
|
2125
2133
|
*/
|
|
2126
|
-
abstract getAddress(chain
|
|
2134
|
+
abstract getAddress(chain: ChainDefinition): Promise<string>;
|
|
2127
2135
|
/**
|
|
2128
2136
|
* Switches the adapter to operate on the specified chain.
|
|
2129
2137
|
*
|
|
@@ -2194,7 +2202,7 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2194
2202
|
* Validate that the target chain is supported by this adapter.
|
|
2195
2203
|
*
|
|
2196
2204
|
* @param targetChain - The chain to validate.
|
|
2197
|
-
* @throws
|
|
2205
|
+
* @throws KitError with INVALID_CHAIN code if the chain is not supported by this adapter.
|
|
2198
2206
|
*/
|
|
2199
2207
|
validateChainSupport(targetChain: ChainDefinition): void;
|
|
2200
2208
|
/**
|
|
@@ -4061,6 +4069,15 @@ declare const RECOVERABILITY_VALUES: readonly ["RETRYABLE", "RESUMABLE", "FATAL"
|
|
|
4061
4069
|
* - RESUMABLE errors are returned when a flow fails mid-execution but can be continued
|
|
4062
4070
|
*/
|
|
4063
4071
|
type Recoverability = (typeof RECOVERABILITY_VALUES)[number];
|
|
4072
|
+
/**
|
|
4073
|
+
* Array of valid error type values for validation.
|
|
4074
|
+
* Derived from ERROR_TYPES const object.
|
|
4075
|
+
*/
|
|
4076
|
+
declare const ERROR_TYPE_VALUES: ("INPUT" | "BALANCE" | "ONCHAIN" | "RPC" | "NETWORK")[];
|
|
4077
|
+
/**
|
|
4078
|
+
* Error type indicating the category of the error.
|
|
4079
|
+
*/
|
|
4080
|
+
type ErrorType = (typeof ERROR_TYPE_VALUES)[number];
|
|
4064
4081
|
/**
|
|
4065
4082
|
* Structured error details with consistent properties for programmatic handling.
|
|
4066
4083
|
*
|
|
@@ -4072,7 +4089,8 @@ type Recoverability = (typeof RECOVERABILITY_VALUES)[number];
|
|
|
4072
4089
|
* ```typescript
|
|
4073
4090
|
* const error: ErrorDetails = {
|
|
4074
4091
|
* code: 1001,
|
|
4075
|
-
* name: "
|
|
4092
|
+
* name: "INPUT_NETWORK_MISMATCH",
|
|
4093
|
+
* type: "INPUT",
|
|
4076
4094
|
* recoverability: "FATAL",
|
|
4077
4095
|
* message: "Source and destination networks must be different",
|
|
4078
4096
|
* cause: {
|
|
@@ -4080,15 +4098,31 @@ type Recoverability = (typeof RECOVERABILITY_VALUES)[number];
|
|
|
4080
4098
|
* }
|
|
4081
4099
|
* }
|
|
4082
4100
|
* ```
|
|
4101
|
+
*
|
|
4102
|
+
* @example
|
|
4103
|
+
* ```typescript
|
|
4104
|
+
* const error: ErrorDetails = {
|
|
4105
|
+
* code: 9001,
|
|
4106
|
+
* name: "BALANCE_INSUFFICIENT_TOKEN",
|
|
4107
|
+
* type: "BALANCE",
|
|
4108
|
+
* recoverability: "FATAL",
|
|
4109
|
+
* message: "Insufficient USDC balance on Ethereum",
|
|
4110
|
+
* cause: {
|
|
4111
|
+
* trace: { token: "USDC", chain: "Ethereum" }
|
|
4112
|
+
* }
|
|
4113
|
+
* }
|
|
4114
|
+
* ```
|
|
4083
4115
|
*/
|
|
4084
4116
|
interface ErrorDetails {
|
|
4085
|
-
/** Numeric identifier following standardized ranges (
|
|
4117
|
+
/** Numeric identifier following standardized ranges (see error code registry) */
|
|
4086
4118
|
code: number;
|
|
4087
|
-
/** Human-readable ID (e.g., "
|
|
4119
|
+
/** Human-readable ID (e.g., "INPUT_NETWORK_MISMATCH", "BALANCE_INSUFFICIENT_TOKEN") */
|
|
4088
4120
|
name: string;
|
|
4121
|
+
/** Error category indicating where the error originated */
|
|
4122
|
+
type: ErrorType;
|
|
4089
4123
|
/** Error handling strategy */
|
|
4090
4124
|
recoverability: Recoverability;
|
|
4091
|
-
/** User-friendly explanation with
|
|
4125
|
+
/** User-friendly explanation with context */
|
|
4092
4126
|
message: string;
|
|
4093
4127
|
/** Raw error details, context, or the original error that caused this one. */
|
|
4094
4128
|
cause?: {
|
|
@@ -4145,6 +4179,8 @@ declare class KitError extends Error implements ErrorDetails {
|
|
|
4145
4179
|
readonly code: number;
|
|
4146
4180
|
/** Human-readable ID (e.g., "NETWORK_MISMATCH") */
|
|
4147
4181
|
readonly name: string;
|
|
4182
|
+
/** Error category indicating where the error originated */
|
|
4183
|
+
readonly type: ErrorType;
|
|
4148
4184
|
/** Error handling strategy */
|
|
4149
4185
|
readonly recoverability: Recoverability;
|
|
4150
4186
|
/** Raw error details, context, or the original error that caused this one. */
|
|
@@ -4239,31 +4275,25 @@ declare function isFatalError(error: unknown): boolean;
|
|
|
4239
4275
|
*/
|
|
4240
4276
|
declare function isRetryableError(error: unknown): boolean;
|
|
4241
4277
|
/**
|
|
4242
|
-
*
|
|
4278
|
+
* Type guard to check if error is KitError with INPUT type.
|
|
4243
4279
|
*
|
|
4244
|
-
* INPUT errors
|
|
4245
|
-
*
|
|
4246
|
-
*
|
|
4247
|
-
* input before retrying.
|
|
4280
|
+
* INPUT errors represent validation failures, invalid parameters,
|
|
4281
|
+
* or user input problems. These errors are always FATAL and require
|
|
4282
|
+
* the user to correct their input before retrying.
|
|
4248
4283
|
*
|
|
4249
4284
|
* @param error - Unknown error to check
|
|
4250
|
-
* @returns True if error is KitError with INPUT
|
|
4285
|
+
* @returns True if error is KitError with INPUT type
|
|
4251
4286
|
*
|
|
4252
4287
|
* @example
|
|
4253
4288
|
* ```typescript
|
|
4254
4289
|
* import { isInputError } from '@core/errors'
|
|
4255
|
-
* import { createBridgeKit } from '@core/bridge'
|
|
4256
4290
|
*
|
|
4257
|
-
*
|
|
4258
|
-
*
|
|
4259
|
-
*
|
|
4260
|
-
*
|
|
4261
|
-
*
|
|
4262
|
-
*
|
|
4263
|
-
* } catch (error) {
|
|
4264
|
-
* if (isInputError(error)) {
|
|
4265
|
-
* console.log(`Input error: ${error.message} (code: ${error.code})`)
|
|
4266
|
-
* }
|
|
4291
|
+
* try {
|
|
4292
|
+
* await kit.bridge(params)
|
|
4293
|
+
* } catch (error) {
|
|
4294
|
+
* if (isInputError(error)) {
|
|
4295
|
+
* console.log('Validation error:', error.message)
|
|
4296
|
+
* showValidationUI()
|
|
4267
4297
|
* }
|
|
4268
4298
|
* }
|
|
4269
4299
|
* ```
|
|
@@ -4321,4 +4351,4 @@ declare function getErrorMessage(error: unknown): string;
|
|
|
4321
4351
|
declare function getErrorCode(error: unknown): number | null;
|
|
4322
4352
|
|
|
4323
4353
|
export { Blockchain, BridgeKit, KitError, TransferSpeed, bridgeParamsWithChainIdentifierSchema, getErrorCode, getErrorMessage, isFatalError, isInputError, isKitError, isRetryableError, setExternalPrefix };
|
|
4324
|
-
export type { ActionHandler, AdapterContext, BridgeConfig, BridgeKitConfig, BridgeParams, BridgeResult, ChainDefinition, ChainIdentifier, CustomFeePolicy, ErrorDetails, Recoverability };
|
|
4354
|
+
export type { ActionHandler, AdapterContext, BridgeConfig, BridgeKitConfig, BridgeParams, BridgeResult, ChainDefinition, ChainIdentifier, CustomFeePolicy, ErrorDetails, EstimateResult, Recoverability };
|
package/index.mjs
CHANGED
|
@@ -2739,7 +2739,7 @@ class Actionable {
|
|
|
2739
2739
|
}
|
|
2740
2740
|
|
|
2741
2741
|
var name = "@circle-fin/bridge-kit";
|
|
2742
|
-
var version = "1.1.
|
|
2742
|
+
var version = "1.1.2";
|
|
2743
2743
|
var pkg = {
|
|
2744
2744
|
name: name,
|
|
2745
2745
|
version: version};
|
|
@@ -2756,9 +2756,71 @@ const RECOVERABILITY_VALUES = [
|
|
|
2756
2756
|
'RESUMABLE',
|
|
2757
2757
|
'FATAL',
|
|
2758
2758
|
];
|
|
2759
|
+
/**
|
|
2760
|
+
* Error type constants for categorizing errors by origin.
|
|
2761
|
+
*
|
|
2762
|
+
* This const object provides a reference for error types, enabling
|
|
2763
|
+
* IDE autocomplete and preventing typos when creating custom errors.
|
|
2764
|
+
*
|
|
2765
|
+
* @remarks
|
|
2766
|
+
* While internal error definitions use string literals with type annotations
|
|
2767
|
+
* for strict type safety, this constant is useful for developers creating
|
|
2768
|
+
* custom error instances or checking error types programmatically.
|
|
2769
|
+
*
|
|
2770
|
+
* @example
|
|
2771
|
+
* ```typescript
|
|
2772
|
+
* import { ERROR_TYPES, KitError } from '@core/errors'
|
|
2773
|
+
*
|
|
2774
|
+
* // Use for type checking
|
|
2775
|
+
* if (error.type === ERROR_TYPES.BALANCE) {
|
|
2776
|
+
* console.log('This is a balance error')
|
|
2777
|
+
* }
|
|
2778
|
+
* ```
|
|
2779
|
+
*
|
|
2780
|
+
* @example
|
|
2781
|
+
* ```typescript
|
|
2782
|
+
* // Use as reference when creating custom errors
|
|
2783
|
+
* const error = new KitError({
|
|
2784
|
+
* code: 9999,
|
|
2785
|
+
* name: 'CUSTOM_ERROR',
|
|
2786
|
+
* type: ERROR_TYPES.BALANCE, // IDE autocomplete works here
|
|
2787
|
+
* recoverability: 'FATAL',
|
|
2788
|
+
* message: 'Custom balance error'
|
|
2789
|
+
* })
|
|
2790
|
+
* ```
|
|
2791
|
+
*/
|
|
2792
|
+
const ERROR_TYPES = {
|
|
2793
|
+
/** User input validation and parameter checking */
|
|
2794
|
+
INPUT: 'INPUT',
|
|
2795
|
+
/** Insufficient token balances and amount validation */
|
|
2796
|
+
BALANCE: 'BALANCE',
|
|
2797
|
+
/** On-chain execution: reverts, gas issues, transaction failures */
|
|
2798
|
+
ONCHAIN: 'ONCHAIN',
|
|
2799
|
+
/** Blockchain RPC provider issues and endpoint problems */
|
|
2800
|
+
RPC: 'RPC',
|
|
2801
|
+
/** Internet connectivity, DNS resolution, connection issues */
|
|
2802
|
+
NETWORK: 'NETWORK',
|
|
2803
|
+
};
|
|
2804
|
+
/**
|
|
2805
|
+
* Array of valid error type values for validation.
|
|
2806
|
+
* Derived from ERROR_TYPES const object.
|
|
2807
|
+
*/
|
|
2808
|
+
const ERROR_TYPE_VALUES = Object.values(ERROR_TYPES);
|
|
2759
2809
|
|
|
2760
|
-
// Create
|
|
2810
|
+
// Create mutable arrays for Zod enum validation
|
|
2761
2811
|
const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
2812
|
+
const ERROR_TYPE_ARRAY = [...ERROR_TYPE_VALUES];
|
|
2813
|
+
/**
|
|
2814
|
+
* Error code ranges for validation.
|
|
2815
|
+
* Single source of truth for valid error code ranges.
|
|
2816
|
+
*/
|
|
2817
|
+
const ERROR_CODE_RANGES = [
|
|
2818
|
+
{ min: 1000, max: 1999, type: 'INPUT' },
|
|
2819
|
+
{ min: 3000, max: 3999, type: 'NETWORK' },
|
|
2820
|
+
{ min: 4000, max: 4999, type: 'RPC' },
|
|
2821
|
+
{ min: 5000, max: 5999, type: 'ONCHAIN' },
|
|
2822
|
+
{ min: 9000, max: 9999, type: 'BALANCE' },
|
|
2823
|
+
];
|
|
2762
2824
|
/**
|
|
2763
2825
|
* Zod schema for validating ErrorDetails objects.
|
|
2764
2826
|
*
|
|
@@ -2771,7 +2833,8 @@ const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
|
2771
2833
|
*
|
|
2772
2834
|
* const result = errorDetailsSchema.safeParse({
|
|
2773
2835
|
* code: 1001,
|
|
2774
|
-
* name: '
|
|
2836
|
+
* name: 'INPUT_NETWORK_MISMATCH',
|
|
2837
|
+
* type: 'INPUT',
|
|
2775
2838
|
* recoverability: 'FATAL',
|
|
2776
2839
|
* message: 'Source and destination networks must be different'
|
|
2777
2840
|
* })
|
|
@@ -2780,30 +2843,56 @@ const RECOVERABILITY_ARRAY = [...RECOVERABILITY_VALUES];
|
|
|
2780
2843
|
* console.error('Validation failed:', result.error.issues)
|
|
2781
2844
|
* }
|
|
2782
2845
|
* ```
|
|
2846
|
+
*
|
|
2847
|
+
* @example
|
|
2848
|
+
* ```typescript
|
|
2849
|
+
* // Runtime error
|
|
2850
|
+
* const result = errorDetailsSchema.safeParse({
|
|
2851
|
+
* code: 9001,
|
|
2852
|
+
* name: 'BALANCE_INSUFFICIENT_TOKEN',
|
|
2853
|
+
* type: 'BALANCE',
|
|
2854
|
+
* recoverability: 'FATAL',
|
|
2855
|
+
* message: 'Insufficient USDC balance'
|
|
2856
|
+
* })
|
|
2857
|
+
* ```
|
|
2783
2858
|
*/
|
|
2784
2859
|
const errorDetailsSchema = z.object({
|
|
2785
|
-
/**
|
|
2860
|
+
/**
|
|
2861
|
+
* Numeric identifier following standardized ranges:
|
|
2862
|
+
* - 1000-1999: INPUT errors - Parameter validation
|
|
2863
|
+
* - 3000-3999: NETWORK errors - Connectivity issues
|
|
2864
|
+
* - 4000-4999: RPC errors - Provider issues, gas estimation
|
|
2865
|
+
* - 5000-5999: ONCHAIN errors - Transaction/simulation failures
|
|
2866
|
+
* - 9000-9999: BALANCE errors - Insufficient funds
|
|
2867
|
+
*/
|
|
2786
2868
|
code: z
|
|
2787
2869
|
.number()
|
|
2788
2870
|
.int('Error code must be an integer')
|
|
2789
|
-
.
|
|
2790
|
-
|
|
2791
|
-
|
|
2871
|
+
.refine((code) => ERROR_CODE_RANGES.some((range) => code >= range.min && code <= range.max), {
|
|
2872
|
+
message: 'Error code must be in valid ranges: 1000-1999 (INPUT), 3000-3999 (NETWORK), 4000-4999 (RPC), 5000-5999 (ONCHAIN), 9000-9999 (BALANCE)',
|
|
2873
|
+
}),
|
|
2874
|
+
/** Human-readable ID (e.g., "INPUT_NETWORK_MISMATCH", "BALANCE_INSUFFICIENT_TOKEN") */
|
|
2792
2875
|
name: z
|
|
2793
2876
|
.string()
|
|
2794
2877
|
.min(1, 'Error name must be a non-empty string')
|
|
2795
2878
|
.regex(/^[A-Z_][A-Z0-9_]*$/, 'Error name must match pattern: ^[A-Z_][A-Z0-9_]*$'),
|
|
2879
|
+
/** Error category indicating where the error originated */
|
|
2880
|
+
type: z.enum(ERROR_TYPE_ARRAY, {
|
|
2881
|
+
errorMap: () => ({
|
|
2882
|
+
message: 'Error type must be one of: INPUT, BALANCE, ONCHAIN, RPC, NETWORK',
|
|
2883
|
+
}),
|
|
2884
|
+
}),
|
|
2796
2885
|
/** Error handling strategy */
|
|
2797
2886
|
recoverability: z.enum(RECOVERABILITY_ARRAY, {
|
|
2798
2887
|
errorMap: () => ({
|
|
2799
2888
|
message: 'Recoverability must be one of: RETRYABLE, RESUMABLE, FATAL',
|
|
2800
2889
|
}),
|
|
2801
2890
|
}),
|
|
2802
|
-
/** User-friendly explanation with
|
|
2891
|
+
/** User-friendly explanation with context */
|
|
2803
2892
|
message: z
|
|
2804
2893
|
.string()
|
|
2805
2894
|
.min(1, 'Error message must be a non-empty string')
|
|
2806
|
-
.max(
|
|
2895
|
+
.max(1000, 'Error message must be 1000 characters or less'),
|
|
2807
2896
|
/** Raw error details, context, or the original error that caused this one. */
|
|
2808
2897
|
cause: z
|
|
2809
2898
|
.object({
|
|
@@ -2818,7 +2907,7 @@ const errorDetailsSchema = z.object({
|
|
|
2818
2907
|
*
|
|
2819
2908
|
* @param details - The object to validate
|
|
2820
2909
|
* @returns The validated ErrorDetails object
|
|
2821
|
-
* @throws
|
|
2910
|
+
* @throws TypeError When validation fails
|
|
2822
2911
|
*
|
|
2823
2912
|
* @example
|
|
2824
2913
|
* ```typescript
|
|
@@ -2895,6 +2984,8 @@ class KitError extends Error {
|
|
|
2895
2984
|
code;
|
|
2896
2985
|
/** Human-readable ID (e.g., "NETWORK_MISMATCH") */
|
|
2897
2986
|
name;
|
|
2987
|
+
/** Error category indicating where the error originated */
|
|
2988
|
+
type;
|
|
2898
2989
|
/** Error handling strategy */
|
|
2899
2990
|
recoverability;
|
|
2900
2991
|
/** Raw error details, context, or the original error that caused this one. */
|
|
@@ -2923,6 +3014,12 @@ class KitError extends Error {
|
|
|
2923
3014
|
enumerable: true,
|
|
2924
3015
|
configurable: false,
|
|
2925
3016
|
},
|
|
3017
|
+
type: {
|
|
3018
|
+
value: validatedDetails.type,
|
|
3019
|
+
writable: false,
|
|
3020
|
+
enumerable: true,
|
|
3021
|
+
configurable: false,
|
|
3022
|
+
},
|
|
2926
3023
|
recoverability: {
|
|
2927
3024
|
value: validatedDetails.recoverability,
|
|
2928
3025
|
writable: false,
|
|
@@ -2942,20 +3039,19 @@ class KitError extends Error {
|
|
|
2942
3039
|
}
|
|
2943
3040
|
|
|
2944
3041
|
/**
|
|
2945
|
-
*
|
|
2946
|
-
*
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
*
|
|
2951
|
-
*
|
|
3042
|
+
* Standardized error code ranges for consistent categorization:
|
|
3043
|
+
*
|
|
3044
|
+
* - 1000-1999: INPUT errors - Parameter validation, input format errors
|
|
3045
|
+
* - 3000-3999: NETWORK errors - Internet connectivity, DNS, connection issues
|
|
3046
|
+
* - 4000-4999: RPC errors - Blockchain provider issues, gas estimation, nonce errors
|
|
3047
|
+
* - 5000-5999: ONCHAIN errors - Transaction/simulation failures, gas exhaustion, reverts
|
|
3048
|
+
* - 9000-9999: BALANCE errors - Insufficient funds, token balance, allowance
|
|
2952
3049
|
*/
|
|
2953
|
-
const INPUT_ERROR_CODE_MAX = 1100;
|
|
2954
3050
|
/**
|
|
2955
3051
|
* Standardized error definitions for INPUT type errors.
|
|
2956
3052
|
*
|
|
2957
|
-
* Each entry combines the numeric error code
|
|
2958
|
-
*
|
|
3053
|
+
* Each entry combines the numeric error code, string name, and type
|
|
3054
|
+
* to ensure consistency when creating error instances.
|
|
2959
3055
|
*
|
|
2960
3056
|
* Error codes follow a hierarchical numbering scheme where the first digit
|
|
2961
3057
|
* indicates the error category (1 = INPUT) and subsequent digits provide
|
|
@@ -2972,9 +3068,10 @@ const INPUT_ERROR_CODE_MAX = 1100;
|
|
|
2972
3068
|
* message: 'Source and destination networks must be different'
|
|
2973
3069
|
* })
|
|
2974
3070
|
*
|
|
2975
|
-
* // Access code and
|
|
3071
|
+
* // Access code, name, and type individually if needed
|
|
2976
3072
|
* console.log(InputError.NETWORK_MISMATCH.code) // 1001
|
|
2977
3073
|
* console.log(InputError.NETWORK_MISMATCH.name) // 'INPUT_NETWORK_MISMATCH'
|
|
3074
|
+
* console.log(InputError.NETWORK_MISMATCH.type) // 'INPUT'
|
|
2978
3075
|
* ```
|
|
2979
3076
|
*/
|
|
2980
3077
|
const InputError = {
|
|
@@ -2982,31 +3079,37 @@ const InputError = {
|
|
|
2982
3079
|
NETWORK_MISMATCH: {
|
|
2983
3080
|
code: 1001,
|
|
2984
3081
|
name: 'INPUT_NETWORK_MISMATCH',
|
|
3082
|
+
type: 'INPUT',
|
|
2985
3083
|
},
|
|
2986
3084
|
/** Invalid amount format or value (negative, zero, or malformed) */
|
|
2987
3085
|
INVALID_AMOUNT: {
|
|
2988
3086
|
code: 1002,
|
|
2989
3087
|
name: 'INPUT_INVALID_AMOUNT',
|
|
3088
|
+
type: 'INPUT',
|
|
2990
3089
|
},
|
|
2991
3090
|
/** Unsupported or invalid bridge route configuration */
|
|
2992
3091
|
UNSUPPORTED_ROUTE: {
|
|
2993
3092
|
code: 1003,
|
|
2994
3093
|
name: 'INPUT_UNSUPPORTED_ROUTE',
|
|
3094
|
+
type: 'INPUT',
|
|
2995
3095
|
},
|
|
2996
3096
|
/** Invalid wallet or contract address format */
|
|
2997
3097
|
INVALID_ADDRESS: {
|
|
2998
3098
|
code: 1004,
|
|
2999
3099
|
name: 'INPUT_INVALID_ADDRESS',
|
|
3100
|
+
type: 'INPUT',
|
|
3000
3101
|
},
|
|
3001
3102
|
/** Invalid or unsupported chain identifier */
|
|
3002
3103
|
INVALID_CHAIN: {
|
|
3003
3104
|
code: 1005,
|
|
3004
3105
|
name: 'INPUT_INVALID_CHAIN',
|
|
3106
|
+
type: 'INPUT',
|
|
3005
3107
|
},
|
|
3006
3108
|
/** General validation failure for complex validation rules */
|
|
3007
3109
|
VALIDATION_FAILED: {
|
|
3008
3110
|
code: 1098,
|
|
3009
3111
|
name: 'INPUT_VALIDATION_FAILED',
|
|
3112
|
+
type: 'INPUT',
|
|
3010
3113
|
},
|
|
3011
3114
|
};
|
|
3012
3115
|
|
|
@@ -3252,39 +3355,31 @@ function isRetryableError(error) {
|
|
|
3252
3355
|
return isKitError(error) && error.recoverability === 'RETRYABLE';
|
|
3253
3356
|
}
|
|
3254
3357
|
/**
|
|
3255
|
-
*
|
|
3358
|
+
* Type guard to check if error is KitError with INPUT type.
|
|
3256
3359
|
*
|
|
3257
|
-
* INPUT errors
|
|
3258
|
-
*
|
|
3259
|
-
*
|
|
3260
|
-
* input before retrying.
|
|
3360
|
+
* INPUT errors represent validation failures, invalid parameters,
|
|
3361
|
+
* or user input problems. These errors are always FATAL and require
|
|
3362
|
+
* the user to correct their input before retrying.
|
|
3261
3363
|
*
|
|
3262
3364
|
* @param error - Unknown error to check
|
|
3263
|
-
* @returns True if error is KitError with INPUT
|
|
3365
|
+
* @returns True if error is KitError with INPUT type
|
|
3264
3366
|
*
|
|
3265
3367
|
* @example
|
|
3266
3368
|
* ```typescript
|
|
3267
3369
|
* import { isInputError } from '@core/errors'
|
|
3268
|
-
* import { createBridgeKit } from '@core/bridge'
|
|
3269
|
-
*
|
|
3270
|
-
* async function handleBridge() {
|
|
3271
|
-
* const kit = createBridgeKit(config)
|
|
3272
|
-
* const params = { amount: '100', from: 'ethereum', to: 'polygon' }
|
|
3273
3370
|
*
|
|
3274
|
-
*
|
|
3275
|
-
*
|
|
3276
|
-
*
|
|
3277
|
-
*
|
|
3278
|
-
*
|
|
3279
|
-
*
|
|
3371
|
+
* try {
|
|
3372
|
+
* await kit.bridge(params)
|
|
3373
|
+
* } catch (error) {
|
|
3374
|
+
* if (isInputError(error)) {
|
|
3375
|
+
* console.log('Validation error:', error.message)
|
|
3376
|
+
* showValidationUI()
|
|
3280
3377
|
* }
|
|
3281
3378
|
* }
|
|
3282
3379
|
* ```
|
|
3283
3380
|
*/
|
|
3284
3381
|
function isInputError(error) {
|
|
3285
|
-
return
|
|
3286
|
-
error.code >= INPUT_ERROR_CODE_MIN &&
|
|
3287
|
-
error.code < INPUT_ERROR_CODE_MAX);
|
|
3382
|
+
return isKitError(error) && error.type === ERROR_TYPES.INPUT;
|
|
3288
3383
|
}
|
|
3289
3384
|
/**
|
|
3290
3385
|
* Safely extracts error message from any error type.
|
|
@@ -3570,8 +3665,8 @@ function getChainFromParams(params) {
|
|
|
3570
3665
|
/**
|
|
3571
3666
|
* Maximum length for error messages in fallback validation errors.
|
|
3572
3667
|
*
|
|
3573
|
-
* KitError enforces a
|
|
3574
|
-
* fallback validation errors that combine multiple Zod issues, we use
|
|
3668
|
+
* KitError enforces a 1000-character limit on error messages. When creating
|
|
3669
|
+
* fallback validation errors that combine multiple Zod issues, we use 950
|
|
3575
3670
|
* characters to leave a 50-character buffer for:
|
|
3576
3671
|
* - The error message prefix ("Invalid bridge parameters: ")
|
|
3577
3672
|
* - Potential encoding differences or formatting overhead
|
|
@@ -3580,7 +3675,7 @@ function getChainFromParams(params) {
|
|
|
3580
3675
|
* This ensures that even with concatenated issue summaries, the final message
|
|
3581
3676
|
* stays within KitError's constraints.
|
|
3582
3677
|
*/
|
|
3583
|
-
const MAX_MESSAGE_LENGTH =
|
|
3678
|
+
const MAX_MESSAGE_LENGTH = 950;
|
|
3584
3679
|
|
|
3585
3680
|
/**
|
|
3586
3681
|
* Converts a Zod validation error into a specific KitError instance using structured pattern matching.
|
|
@@ -4714,6 +4809,10 @@ function resolveConfig(params) {
|
|
|
4714
4809
|
async function resolveBridgeParams(params) {
|
|
4715
4810
|
const fromChain = resolveChainDefinition(params.from);
|
|
4716
4811
|
const toChain = resolveChainDefinition(params.to);
|
|
4812
|
+
// Validate adapter chain support after resolution
|
|
4813
|
+
// This ensures adapters support the resolved chains before proceeding
|
|
4814
|
+
params.from.adapter.validateChainSupport(fromChain);
|
|
4815
|
+
params.to.adapter.validateChainSupport(toChain);
|
|
4717
4816
|
const [fromAddress, toAddress] = await Promise.all([
|
|
4718
4817
|
resolveAddress(params.from),
|
|
4719
4818
|
resolveAddress(params.to),
|
|
@@ -4891,7 +4990,7 @@ class BridgeKit {
|
|
|
4891
4990
|
async bridge(params) {
|
|
4892
4991
|
// First validate the parameters
|
|
4893
4992
|
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
4894
|
-
// Then resolve chain definitions
|
|
4993
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
4895
4994
|
const resolvedParams = await resolveBridgeParams(params);
|
|
4896
4995
|
// Validate network compatibility
|
|
4897
4996
|
this.validateNetworkCompatibility(resolvedParams);
|
|
@@ -4995,7 +5094,7 @@ class BridgeKit {
|
|
|
4995
5094
|
async estimate(params) {
|
|
4996
5095
|
// First validate the parameters
|
|
4997
5096
|
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
4998
|
-
// Then resolve chain definitions
|
|
5097
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
4999
5098
|
const resolvedParams = await resolveBridgeParams(params);
|
|
5000
5099
|
// Validate network compatibility
|
|
5001
5100
|
this.validateNetworkCompatibility(resolvedParams);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@circle-fin/bridge-kit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "SDK for seamless cross-chain stablecoin bridging",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=16.0.0"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"types": "./index.d.ts",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"zod": "3.25.67",
|
|
13
|
-
"@circle-fin/provider-cctp-v2": "^1.0.
|
|
13
|
+
"@circle-fin/provider-cctp-v2": "^1.0.4",
|
|
14
14
|
"abitype": "^1.1.0",
|
|
15
15
|
"@solana/web3.js": "^1.98.4",
|
|
16
16
|
"@ethersproject/address": "^5.8.0",
|