@circle-fin/app-kit 1.14.0 → 1.15.1
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 +72 -0
- package/README.md +3 -3
- package/bridge.cjs +7464 -454
- package/bridge.d.cts +585 -61
- package/bridge.d.mts +585 -61
- package/bridge.d.ts +585 -61
- package/bridge.mjs +7464 -454
- package/chains.cjs +146 -5
- package/chains.d.cts +108 -2
- package/chains.d.mts +108 -2
- package/chains.d.ts +108 -2
- package/chains.mjs +146 -6
- package/context.d.cts +522 -57
- package/context.d.mts +522 -57
- package/context.d.ts +522 -57
- package/earn.cjs +478 -181
- package/earn.d.cts +522 -57
- package/earn.d.mts +522 -57
- package/earn.d.ts +522 -57
- package/earn.mjs +478 -181
- package/estimateBridge.cjs +7464 -457
- package/estimateBridge.d.cts +643 -82
- package/estimateBridge.d.mts +643 -82
- package/estimateBridge.d.ts +643 -82
- package/estimateBridge.mjs +7464 -457
- package/estimateSwap.cjs +528 -185
- package/estimateSwap.d.cts +522 -57
- package/estimateSwap.d.mts +522 -57
- package/estimateSwap.d.ts +522 -57
- package/estimateSwap.mjs +528 -185
- package/index.cjs +11548 -2936
- package/index.d.cts +5073 -1738
- package/index.d.mts +5073 -1738
- package/index.d.ts +5073 -1738
- package/index.mjs +11547 -2937
- package/package.json +17 -6
- package/server.cjs +10040 -0
- package/server.cjs.map +1 -0
- package/server.d.cts +2467 -0
- package/server.d.mts +2467 -0
- package/server.d.ts +2467 -0
- package/server.mjs +10028 -0
- package/server.mjs.map +1 -0
- package/swap.cjs +528 -185
- package/swap.d.cts +522 -57
- package/swap.d.mts +522 -57
- package/swap.d.ts +522 -57
- package/swap.mjs +528 -185
- package/unifiedBalance.cjs +742 -44
- package/unifiedBalance.d.cts +223 -1
- package/unifiedBalance.d.mts +223 -1
- package/unifiedBalance.d.ts +223 -1
- package/unifiedBalance.mjs +742 -44
package/unifiedBalance.cjs
CHANGED
|
@@ -708,6 +708,38 @@ class KitError extends Error {
|
|
|
708
708
|
name: 'INPUT_AMOUNT_OUT_OF_RANGE',
|
|
709
709
|
type: 'INPUT'
|
|
710
710
|
},
|
|
711
|
+
/**
|
|
712
|
+
* Protocol fee is denominated in a token that is not supported for the
|
|
713
|
+
* route (only the native gas token and the route's supported fee tokens,
|
|
714
|
+
* such as USDC, are accepted).
|
|
715
|
+
*/ UNSUPPORTED_FEE_TOKEN: {
|
|
716
|
+
code: 1014,
|
|
717
|
+
name: 'INPUT_UNSUPPORTED_FEE_TOKEN',
|
|
718
|
+
type: 'INPUT'
|
|
719
|
+
},
|
|
720
|
+
/** Retry / resume is not supported by this provider for the given result */ RETRY_NOT_SUPPORTED: {
|
|
721
|
+
code: 1015,
|
|
722
|
+
name: 'INPUT_RETRY_NOT_SUPPORTED',
|
|
723
|
+
type: 'INPUT'
|
|
724
|
+
},
|
|
725
|
+
/** Bridge-step analysis for retry is not supported by this provider */ STEP_ANALYSIS_NOT_SUPPORTED: {
|
|
726
|
+
code: 1016,
|
|
727
|
+
name: 'INPUT_STEP_ANALYSIS_NOT_SUPPORTED',
|
|
728
|
+
type: 'INPUT'
|
|
729
|
+
},
|
|
730
|
+
/**
|
|
731
|
+
* A kit operation name collides with a reserved event-subscription
|
|
732
|
+
* method (`on` / `off`) at kit construction.
|
|
733
|
+
*/ RESERVED_OPERATION_NAME: {
|
|
734
|
+
code: 1000,
|
|
735
|
+
name: 'INPUT_RESERVED_OPERATION_NAME',
|
|
736
|
+
type: 'INPUT'
|
|
737
|
+
},
|
|
738
|
+
/** A kit was constructed with a missing / undefined operation factory */ MISSING_OPERATION: {
|
|
739
|
+
code: 1017,
|
|
740
|
+
name: 'INPUT_MISSING_OPERATION',
|
|
741
|
+
type: 'INPUT'
|
|
742
|
+
},
|
|
711
743
|
/** General validation failure for complex validation rules */ VALIDATION_FAILED: {
|
|
712
744
|
code: 1098,
|
|
713
745
|
name: 'INPUT_VALIDATION_FAILED',
|
|
@@ -938,8 +970,376 @@ class KitError extends Error {
|
|
|
938
970
|
code: 8002,
|
|
939
971
|
name: 'SERVICE_UNKNOWN_ERROR',
|
|
940
972
|
type: 'SERVICE'
|
|
973
|
+
}};
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Log-safe error redaction for `KitError.cause.trace` fields.
|
|
977
|
+
*
|
|
978
|
+
* @packageDocumentation
|
|
979
|
+
*/ // ============================================================================
|
|
980
|
+
// Message redactor (operator-configurable secret scrubbing)
|
|
981
|
+
// ============================================================================
|
|
982
|
+
/**
|
|
983
|
+
* A pluggable redactor for the `message` strings that flow onto
|
|
984
|
+
* `KitError.cause.trace`.
|
|
985
|
+
*
|
|
986
|
+
* @remarks
|
|
987
|
+
* Two equivalent shapes are accepted:
|
|
988
|
+
*
|
|
989
|
+
* 1. **`readonly RegExp[]`** — the common case. Each pattern is run
|
|
990
|
+
* against the message; matches are replaced with `[REDACTED]`.
|
|
991
|
+
* The operator owns the `g` flag — pass a global regex to scrub
|
|
992
|
+
* every occurrence, a non-global regex to scrub the first one.
|
|
993
|
+
*
|
|
994
|
+
* 2. **`(message: string) => string`** — escape hatch for callers
|
|
995
|
+
* who want full control over the substitution (different
|
|
996
|
+
* placeholders per pattern, length-preserving redaction for
|
|
997
|
+
* log-volume parity, format-preserving encryption, etc.).
|
|
998
|
+
*
|
|
999
|
+
* @public
|
|
1000
|
+
*/ /**
|
|
1001
|
+
* Known RPC provider host suffixes scrubbed by the default redactor.
|
|
1002
|
+
*
|
|
1003
|
+
* @remarks
|
|
1004
|
+
* The default redactor (see {@link composeRedactor} and
|
|
1005
|
+
* {@link defaultMessageRedactor}) finds every `https?:` / `wss?:` URL
|
|
1006
|
+
* in an error message, parses each one with the platform `URL`
|
|
1007
|
+
* constructor, and replaces it with `[REDACTED]` if the parsed
|
|
1008
|
+
* hostname ends with one of these suffixes. Adding a new provider is
|
|
1009
|
+
* a one-line change and cannot be wrong: there is no regex shape to
|
|
1010
|
+
* audit, no anchor-vs-quantifier trade-off, no
|
|
1011
|
+
* {@link https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS | ReDoS}
|
|
1012
|
+
* surface — the worst case is over-redaction (an unrelated URL on
|
|
1013
|
+
* the same host suffix gets scrubbed) which is the safe failure
|
|
1014
|
+
* mode.
|
|
1015
|
+
*
|
|
1016
|
+
* Suffixes covered:
|
|
1017
|
+
*
|
|
1018
|
+
* | Provider | Suffix |
|
|
1019
|
+
* | --- | --- |
|
|
1020
|
+
* | Alchemy | `.g.alchemy.com` |
|
|
1021
|
+
* | Infura | `.infura.io` |
|
|
1022
|
+
* | QuickNode | `.quiknode.pro` |
|
|
1023
|
+
* | Ankr | `.ankr.com` |
|
|
1024
|
+
* | Chainstack | `.p2pify.com` |
|
|
1025
|
+
* | Tenderly | `.gateway.tenderly.co` |
|
|
1026
|
+
* | BlockPI | `.blockpi.network` |
|
|
1027
|
+
* | GetBlock | `.getblock.io` |
|
|
1028
|
+
* | Moralis | `.moralis-nodes.com` |
|
|
1029
|
+
* | Helius | `.helius-rpc.com`, `.helius.xyz` |
|
|
1030
|
+
* | Triton | `.rpcpool.com` |
|
|
1031
|
+
*
|
|
1032
|
+
* Compose this list with your own self-hosted RPC suffixes via
|
|
1033
|
+
* {@link composeRedactor}.
|
|
1034
|
+
*
|
|
1035
|
+
* @public
|
|
1036
|
+
*/ const DEFAULT_RPC_HOST_SUFFIXES = Object.freeze([
|
|
1037
|
+
'.g.alchemy.com',
|
|
1038
|
+
'.infura.io',
|
|
1039
|
+
'.quiknode.pro',
|
|
1040
|
+
'.ankr.com',
|
|
1041
|
+
'.p2pify.com',
|
|
1042
|
+
'.gateway.tenderly.co',
|
|
1043
|
+
'.blockpi.network',
|
|
1044
|
+
'.getblock.io',
|
|
1045
|
+
'.moralis-nodes.com',
|
|
1046
|
+
'.helius-rpc.com',
|
|
1047
|
+
'.helius.xyz',
|
|
1048
|
+
'.rpcpool.com'
|
|
1049
|
+
]);
|
|
1050
|
+
/**
|
|
1051
|
+
* Built-in non-URL redaction patterns applied alongside the
|
|
1052
|
+
* URL-host scrubber.
|
|
1053
|
+
*
|
|
1054
|
+
* @remarks
|
|
1055
|
+
* Two simple patterns:
|
|
1056
|
+
*
|
|
1057
|
+
* - **Generic credential-bearing query strings** — `?api-key=…`,
|
|
1058
|
+
* `?apikey=…`, `?api-token=…`, `?access-token=…`, `?auth-token=…`,
|
|
1059
|
+
* `?app-key=…`, plus bare `?key=…` / `?token=…` / `?secret=…`.
|
|
1060
|
+
* Catches the case where a self-hosted RPC bakes the credential
|
|
1061
|
+
* into a query string instead of the path. Single canonical-name
|
|
1062
|
+
* alternation; complexity is well under SonarQube S5856's
|
|
1063
|
+
* 20-complexity bound.
|
|
1064
|
+
* - **Bearer header tokens** — `Bearer <token>` with bounded body
|
|
1065
|
+
* length and a `(?<![A-Za-z])` anchor so it can't be matched as a
|
|
1066
|
+
* tail-fragment of a longer word.
|
|
1067
|
+
*
|
|
1068
|
+
* Provider-specific URL-host scrubbing lives in
|
|
1069
|
+
* {@link DEFAULT_RPC_HOST_SUFFIXES} (parsed via `URL`) rather than as
|
|
1070
|
+
* regexes here — the host-list approach is CodeQL-clean (no
|
|
1071
|
+
* `js/regex/missing-anchor` heuristic match), false-positive-free
|
|
1072
|
+
* (provider URLs cannot accidentally collide with calldata or tx
|
|
1073
|
+
* hashes), and trivial to extend (one string per provider).
|
|
1074
|
+
*
|
|
1075
|
+
* @public
|
|
1076
|
+
*/ const DEFAULT_RPC_REDACTION_PATTERNS = Object.freeze([
|
|
1077
|
+
/[?&](?:(?:api|access|auth|app)[-_]?)?(?:key|token|secret)=[^&\s"'<>`]{1,256}/gi,
|
|
1078
|
+
/(?<![A-Za-z])Bearer\s+[A-Za-z0-9._~+/=-]{16,512}/g
|
|
1079
|
+
]);
|
|
1080
|
+
/**
|
|
1081
|
+
* Generic URL extractor used by {@link composeRedactor}.
|
|
1082
|
+
*
|
|
1083
|
+
* @remarks
|
|
1084
|
+
* Matches any `http://`, `https://`, `ws://`, or `wss://` URL,
|
|
1085
|
+
* bounded to 2 048 characters (longest URL Chrome / Firefox / IE
|
|
1086
|
+
* accept in practice; well below any reasonable error-message
|
|
1087
|
+
* payload). The regex is intentionally generic — it does **not**
|
|
1088
|
+
* encode any provider host shape — so CodeQL's
|
|
1089
|
+
* `js/regex/missing-anchor` heuristic (which targets URL-validation
|
|
1090
|
+
* regexes that look for a specific host) does not fire. All
|
|
1091
|
+
* provider classification happens in JS via `URL` parsing + string
|
|
1092
|
+
* suffix matching, never in regex.
|
|
1093
|
+
*/ const URL_EXTRACTOR = /(?<![A-Za-z0-9])(?:https?|wss?):\/\/[^\s"'<>`]{1,2048}/g;
|
|
1094
|
+
/**
|
|
1095
|
+
* Construct a redactor function from a host-suffix list and a
|
|
1096
|
+
* non-URL pattern list.
|
|
1097
|
+
*
|
|
1098
|
+
* @remarks
|
|
1099
|
+
* Each invocation:
|
|
1100
|
+
*
|
|
1101
|
+
* 1. Finds every URL in the message via {@link URL_EXTRACTOR}.
|
|
1102
|
+
* 2. Parses each candidate with the platform `URL` constructor (the
|
|
1103
|
+
* same one browsers and Node use for `fetch()` / `new Request()`),
|
|
1104
|
+
* discarding common trailing punctuation.
|
|
1105
|
+
* 3. Replaces the URL with `[REDACTED]` if its parsed hostname ends
|
|
1106
|
+
* with one of the configured suffixes.
|
|
1107
|
+
* 4. Applies every regex in `patterns` (Bearer headers, query-string
|
|
1108
|
+
* credentials, plus any operator-supplied additions).
|
|
1109
|
+
*
|
|
1110
|
+
* Both arrays default to the SDK's built-ins
|
|
1111
|
+
* ({@link DEFAULT_RPC_HOST_SUFFIXES} and
|
|
1112
|
+
* {@link DEFAULT_RPC_REDACTION_PATTERNS}); pass either to override.
|
|
1113
|
+
*
|
|
1114
|
+
* @param opts - Optional override for the default suffix list and/or
|
|
1115
|
+
* pattern list.
|
|
1116
|
+
* @returns A pure `(message: string) => string` function suitable for
|
|
1117
|
+
* passing to {@link setMessageRedactor}.
|
|
1118
|
+
*
|
|
1119
|
+
* @example
|
|
1120
|
+
* Add your self-hosted RPC URL to the host-suffix list (most common
|
|
1121
|
+
* extension shape):
|
|
1122
|
+
*
|
|
1123
|
+
* ```typescript
|
|
1124
|
+
* import {
|
|
1125
|
+
* composeRedactor,
|
|
1126
|
+
* setMessageRedactor,
|
|
1127
|
+
* DEFAULT_RPC_HOST_SUFFIXES,
|
|
1128
|
+
* } from '@core/errors'
|
|
1129
|
+
*
|
|
1130
|
+
* setMessageRedactor(
|
|
1131
|
+
* composeRedactor({
|
|
1132
|
+
* hostSuffixes: [...DEFAULT_RPC_HOST_SUFFIXES, '.rpc.my-corp.example'],
|
|
1133
|
+
* }),
|
|
1134
|
+
* )
|
|
1135
|
+
* ```
|
|
1136
|
+
*
|
|
1137
|
+
* @example
|
|
1138
|
+
* Add a custom non-URL pattern (e.g. a corporate header token):
|
|
1139
|
+
*
|
|
1140
|
+
* ```typescript
|
|
1141
|
+
* setMessageRedactor(
|
|
1142
|
+
* composeRedactor({
|
|
1143
|
+
* patterns: [
|
|
1144
|
+
* ...DEFAULT_RPC_REDACTION_PATTERNS,
|
|
1145
|
+
* /X-Corp-Token:\s+[A-Za-z0-9_-]{16,128}/g,
|
|
1146
|
+
* ],
|
|
1147
|
+
* }),
|
|
1148
|
+
* )
|
|
1149
|
+
* ```
|
|
1150
|
+
*
|
|
1151
|
+
* @public
|
|
1152
|
+
*/ function composeRedactor(opts) {
|
|
1153
|
+
const hostSuffixes = opts?.hostSuffixes ?? DEFAULT_RPC_HOST_SUFFIXES;
|
|
1154
|
+
const patterns = opts?.patterns ?? DEFAULT_RPC_REDACTION_PATTERNS;
|
|
1155
|
+
return (message)=>{
|
|
1156
|
+
let result = message.replaceAll(URL_EXTRACTOR, (url)=>{
|
|
1157
|
+
// Common trailing punctuation that error-message templates put
|
|
1158
|
+
// immediately after a URL (`Status: 401.`, `(see ...)`, `[1]`).
|
|
1159
|
+
// Strip before parsing so the `URL` parser doesn't reject
|
|
1160
|
+
// `eth-mainnet.g.alchemy.com.` (or accept it with a trailing
|
|
1161
|
+
// dot in `hostname` and miss the suffix match). Implemented as
|
|
1162
|
+
// a length-bounded string loop instead of a `/[.,;)\]>]+$/`
|
|
1163
|
+
// regex so CodeQL `js/redos-on-uncontrolled-input` cannot
|
|
1164
|
+
// flag a polynomial-time backtracking shape on operator-
|
|
1165
|
+
// controlled error text.
|
|
1166
|
+
const TRIM_CHARS = '.,;)]>';
|
|
1167
|
+
let end = url.length;
|
|
1168
|
+
const cap = Math.max(end - 16, 0) // bound the loop, length-cap 16
|
|
1169
|
+
;
|
|
1170
|
+
while(end > cap && TRIM_CHARS.includes(url.charAt(end - 1))){
|
|
1171
|
+
end--;
|
|
1172
|
+
}
|
|
1173
|
+
const trimmed = end === url.length ? url : url.slice(0, end);
|
|
1174
|
+
let parsed;
|
|
1175
|
+
try {
|
|
1176
|
+
parsed = new URL(trimmed);
|
|
1177
|
+
} catch {
|
|
1178
|
+
return url;
|
|
1179
|
+
}
|
|
1180
|
+
// HTTP-Basic userinfo (`user:pass@host`) is a credential by
|
|
1181
|
+
// definition — scrub it regardless of host, so enterprise /
|
|
1182
|
+
// self-hosted RPC URLs that don't match a known provider suffix
|
|
1183
|
+
// still get redacted.
|
|
1184
|
+
if (parsed.username !== '' || parsed.password !== '') {
|
|
1185
|
+
return '[REDACTED]';
|
|
1186
|
+
}
|
|
1187
|
+
const host = parsed.hostname.toLowerCase();
|
|
1188
|
+
return hostSuffixes.some((suffix)=>host.endsWith(suffix)) ? '[REDACTED]' : url;
|
|
1189
|
+
});
|
|
1190
|
+
for (const pattern of patterns){
|
|
1191
|
+
result = result.replaceAll(pattern, '[REDACTED]');
|
|
1192
|
+
}
|
|
1193
|
+
return result;
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
/**
|
|
1197
|
+
* The SDK's default message redactor: scrubs URLs whose hostname
|
|
1198
|
+
* matches a {@link DEFAULT_RPC_HOST_SUFFIXES} entry, plus the
|
|
1199
|
+
* patterns in {@link DEFAULT_RPC_REDACTION_PATTERNS}.
|
|
1200
|
+
*
|
|
1201
|
+
* @remarks
|
|
1202
|
+
* Active at module load and re-installed by
|
|
1203
|
+
* {@link resetMessageRedactor}. Operators who want to layer
|
|
1204
|
+
* additional redaction on top of (rather than replace) the defaults
|
|
1205
|
+
* can call this directly inside a custom function form:
|
|
1206
|
+
*
|
|
1207
|
+
* ```typescript
|
|
1208
|
+
* setMessageRedactor((msg) =>
|
|
1209
|
+
* defaultMessageRedactor(msg).replace(/myExtraPattern/g, '[REDACTED]'),
|
|
1210
|
+
* )
|
|
1211
|
+
* ```
|
|
1212
|
+
*
|
|
1213
|
+
* For most extension cases prefer {@link composeRedactor}, which
|
|
1214
|
+
* gives the same result with structured options instead of a
|
|
1215
|
+
* post-hoc pipe.
|
|
1216
|
+
*
|
|
1217
|
+
* @public
|
|
1218
|
+
*/ const defaultMessageRedactor = composeRedactor();
|
|
1219
|
+
let activeRedactor = defaultMessageRedactor;
|
|
1220
|
+
/**
|
|
1221
|
+
* Apply the active redactor to an arbitrary message string.
|
|
1222
|
+
*
|
|
1223
|
+
* @remarks
|
|
1224
|
+
* Adapters call this on every string they place on `cause.trace`
|
|
1225
|
+
* other than the redacted `rawError` itself — viem `shortMessage`,
|
|
1226
|
+
* ethers `error.info.requestUrl`, the provider's `reason` field,
|
|
1227
|
+
* etc. When no redactor is configured this is the identity function,
|
|
1228
|
+
* so the cost on the no-redactor path is one `if`.
|
|
1229
|
+
*
|
|
1230
|
+
* @param message - The string to scrub.
|
|
1231
|
+
* @returns The redacted string. The original is returned untouched
|
|
1232
|
+
* when no redactor is configured.
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* ```typescript
|
|
1236
|
+
* import { redactErrorMessage, setMessageRedactor } from '@core/errors'
|
|
1237
|
+
*
|
|
1238
|
+
* setMessageRedactor([/[A-Fa-f0-9]{32,64}/g])
|
|
1239
|
+
* redactErrorMessage('failed: 0xabc...64chars...')
|
|
1240
|
+
* // => 'failed: [REDACTED]'
|
|
1241
|
+
* ```
|
|
1242
|
+
*
|
|
1243
|
+
* @public
|
|
1244
|
+
*/ function redactErrorMessage(message) {
|
|
1245
|
+
if (activeRedactor === undefined) return message;
|
|
1246
|
+
// `setMessageRedactor` eagerly compiles the array form into a
|
|
1247
|
+
// `composeRedactor`-wrapped function, so by the time we reach
|
|
1248
|
+
// here `activeRedactor` is always a function. The runtime
|
|
1249
|
+
// `typeof` guard exists for completeness — if a future
|
|
1250
|
+
// contributor introduces a setter path that bypasses the
|
|
1251
|
+
// compilation step, the guard keeps the dispatch correct.
|
|
1252
|
+
if (typeof activeRedactor === 'function') return activeRedactor(message);
|
|
1253
|
+
// Fallback (unreachable in normal use). See note above.
|
|
1254
|
+
return composeRedactor({
|
|
1255
|
+
patterns: activeRedactor,
|
|
1256
|
+
hostSuffixes: []
|
|
1257
|
+
})(message);
|
|
1258
|
+
}
|
|
1259
|
+
// ============================================================================
|
|
1260
|
+
// Object-graph redaction
|
|
1261
|
+
// ============================================================================
|
|
1262
|
+
/**
|
|
1263
|
+
* Redact an `unknown` error to a small, log-safe shape.
|
|
1264
|
+
*
|
|
1265
|
+
* @remarks
|
|
1266
|
+
* Wallet libraries (viem, ethers, web3-provider-engine, …) routinely
|
|
1267
|
+
* attach provider-injected fields to thrown errors: configured RPC URLs,
|
|
1268
|
+
* API keys, opaque internal state, the originating `XMLHttpRequest`,
|
|
1269
|
+
* and so on. Embedding the raw object directly inside `KitError.cause.trace`
|
|
1270
|
+
* means anyone who later JSON-serialises a `KitError` for telemetry leaks
|
|
1271
|
+
* those fields into logs.
|
|
1272
|
+
*
|
|
1273
|
+
* This helper extracts only the two fields that are useful for
|
|
1274
|
+
* post-mortem debugging — `name` and `message` — while never exposing the
|
|
1275
|
+
* underlying object graph. The `message` is run through the operator's
|
|
1276
|
+
* configured {@link setMessageRedactor | message redactor} (if any) so
|
|
1277
|
+
* that secrets the provider has interpolated into the message string
|
|
1278
|
+
* itself can be scrubbed. Non-`Error` throws (raw strings, plain
|
|
1279
|
+
* objects, primitives) are stringified with `String(error)` and then
|
|
1280
|
+
* run through the same redactor, so a secret-bearing string throw
|
|
1281
|
+
* (e.g. WalletConnect / older mobile wallets) is scrubbed too.
|
|
1282
|
+
*
|
|
1283
|
+
* **Two redaction layers, two responsibilities.**
|
|
1284
|
+
*
|
|
1285
|
+
* - **Object-graph stripping (this function, always on)** — drops
|
|
1286
|
+
* extra properties such as `request`, `requestUrl`, `info`, the
|
|
1287
|
+
* originating `XMLHttpRequest`, the configured `transport.url`,
|
|
1288
|
+
* etc. Without this, viem/ethers errors round-trip with the full
|
|
1289
|
+
* provider state graph attached.
|
|
1290
|
+
* - **Message-content scrubbing (configured via
|
|
1291
|
+
* {@link setMessageRedactor}, opt-in)** — handles the case where
|
|
1292
|
+
* the provider has already formatted secrets into `error.message`
|
|
1293
|
+
* itself. Notably, ethers v6's `makeError()` formats info keys
|
|
1294
|
+
* directly into the message:
|
|
1295
|
+
*
|
|
1296
|
+
* ```
|
|
1297
|
+
* missing response (requestUrl="https://mainnet.infura.io/v3/MY_KEY", code=SERVER_ERROR, ...)
|
|
1298
|
+
* ```
|
|
1299
|
+
*
|
|
1300
|
+
* Viem's `HttpRequestError` exhibits the same pattern via
|
|
1301
|
+
* `shortMessage`, which carries the configured URL with API path.
|
|
1302
|
+
* Without a redactor, the API key rides on `cause.trace.rawError.message`
|
|
1303
|
+
* verbatim. With one configured, every match is replaced with
|
|
1304
|
+
* `[REDACTED]` (or the operator's custom substitution).
|
|
1305
|
+
*
|
|
1306
|
+
* The split is intentional: there is no universal URL/secret
|
|
1307
|
+
* heuristic that won't false-positive on legitimate payloads
|
|
1308
|
+
* (mainnet addresses, contract revert reasons, raw call data), so
|
|
1309
|
+
* the SDK refuses to guess. Operators who know which patterns
|
|
1310
|
+
* appear in *their* RPC URLs configure the policy with one call
|
|
1311
|
+
* to {@link setMessageRedactor}.
|
|
1312
|
+
*
|
|
1313
|
+
* @param error - Anything thrown by a third-party wallet/provider library.
|
|
1314
|
+
* @returns A `{ name, message }` pair for `Error` instances (with
|
|
1315
|
+
* `message` run through the active redactor); the stringified value —
|
|
1316
|
+
* also run through the active redactor — otherwise. Always JSON-safe.
|
|
1317
|
+
*
|
|
1318
|
+
* @example
|
|
1319
|
+
* ```typescript
|
|
1320
|
+
* import { redactRawError, setMessageRedactor } from '@core/errors'
|
|
1321
|
+
*
|
|
1322
|
+
* setMessageRedactor([/infura\.io\/v3\/[a-z0-9]+/gi])
|
|
1323
|
+
* const err = new Error('failed: https://mainnet.infura.io/v3/abc123')
|
|
1324
|
+
* redactRawError(err)
|
|
1325
|
+
* // => { name: 'Error', message: 'failed: https://[REDACTED]' }
|
|
1326
|
+
* ```
|
|
1327
|
+
*
|
|
1328
|
+
* @public
|
|
1329
|
+
*/ function redactRawError(error) {
|
|
1330
|
+
if (error instanceof Error) {
|
|
1331
|
+
return {
|
|
1332
|
+
name: error.name,
|
|
1333
|
+
message: redactErrorMessage(error.message)
|
|
1334
|
+
};
|
|
941
1335
|
}
|
|
942
|
-
|
|
1336
|
+
// Non-Error throws (raw strings from WalletConnect / older mobile
|
|
1337
|
+
// wallets, plain objects, primitives) are stringified and then run
|
|
1338
|
+
// through the active redactor. A raw string throw can carry a secret
|
|
1339
|
+
// RPC URL just like an `Error.message` does, so it must be scrubbed
|
|
1340
|
+
// rather than returned verbatim.
|
|
1341
|
+
return redactErrorMessage(String(error));
|
|
1342
|
+
}
|
|
943
1343
|
|
|
944
1344
|
/**
|
|
945
1345
|
* Creates error for network type mismatch between source and destination.
|
|
@@ -985,6 +1385,15 @@ class KitError extends Error {
|
|
|
985
1385
|
*
|
|
986
1386
|
* @param source - Source chain name
|
|
987
1387
|
* @param destination - Destination chain name
|
|
1388
|
+
* @param providerErrors - Optional list of providers whose `supportsRoute`
|
|
1389
|
+
* call threw during the search. When non-empty, the message includes a
|
|
1390
|
+
* summary so consumers can distinguish "no provider supports this route"
|
|
1391
|
+
* from "a provider errored mid-search." Pass the errors raw: each one is
|
|
1392
|
+
* run through `redactRawError` here, so neither the message nor
|
|
1393
|
+
* `cause.trace.providerErrors` carries the provider's raw object graph.
|
|
1394
|
+
* @param token - Optional token the caller asked to bridge. When supplied it
|
|
1395
|
+
* is named in the message and the trace, so a symbol the routing layer does
|
|
1396
|
+
* not recognise reads as a token problem rather than a chain-pair one.
|
|
988
1397
|
* @returns KitError with specific route details
|
|
989
1398
|
*
|
|
990
1399
|
* @example
|
|
@@ -992,22 +1401,51 @@ class KitError extends Error {
|
|
|
992
1401
|
* import { createUnsupportedRouteError } from '@core/errors'
|
|
993
1402
|
*
|
|
994
1403
|
* throw createUnsupportedRouteError('Ethereum', 'Solana')
|
|
995
|
-
* // Message: "Route from Ethereum to Solana is not supported"
|
|
996
|
-
*
|
|
997
|
-
|
|
1404
|
+
* // Message: "Route from Ethereum to Solana is not supported."
|
|
1405
|
+
*
|
|
1406
|
+
* throw createUnsupportedRouteError('Ethereum', 'Arc', [
|
|
1407
|
+
* { provider: 'cctpx', error: new Error('ECONNRESET') },
|
|
1408
|
+
* ])
|
|
1409
|
+
* // Message: "Route from Ethereum to Arc is not supported.
|
|
1410
|
+
* // Providers errored during route check: cctpx (ECONNRESET)."
|
|
1411
|
+
*
|
|
1412
|
+
* throw createUnsupportedRouteError('Ethereum', 'Arc', undefined, 'USCD')
|
|
1413
|
+
* // Message: "Route from Ethereum to Arc is not supported for token 'USCD'."
|
|
1414
|
+
* ```
|
|
1415
|
+
*/ function createUnsupportedRouteError(source, destination, providerErrors, token) {
|
|
1416
|
+
const failures = [];
|
|
1417
|
+
// Redact once, here. `supportsRoute` may be async so a provider can do a
|
|
1418
|
+
// registry-backed network check, and a fetch rejection embeds the request
|
|
1419
|
+
// URL — with a credential in the worst case — in both its object graph and
|
|
1420
|
+
// its message. Both consumers below read from this redacted copy, so the
|
|
1421
|
+
// raw value never leaves this function. Redacting once is load-bearing:
|
|
1422
|
+
// `redactRawError` is not idempotent (it stringifies a non-`Error` input,
|
|
1423
|
+
// so a second pass collapses `{ name, message }` to `"[object Object]"`),
|
|
1424
|
+
// which is why callers pass raw errors in and let the factory do it.
|
|
1425
|
+
const redactedFailures = failures.map((failure)=>({
|
|
1426
|
+
provider: failure.provider,
|
|
1427
|
+
error: redactRawError(failure.error)
|
|
1428
|
+
}));
|
|
1429
|
+
const summary = redactedFailures.length === 0 ? '' : ` Providers errored during route check: ${redactedFailures.map((f)=>`${f.provider} (${describeProviderError(f.error)})`).join(', ')}.`;
|
|
1430
|
+
const tokenClause = '' ;
|
|
998
1431
|
const errorDetails = {
|
|
999
1432
|
...InputError.UNSUPPORTED_ROUTE,
|
|
1000
1433
|
recoverability: 'FATAL',
|
|
1001
|
-
message: `Route from ${source} to ${destination} is not supported
|
|
1434
|
+
message: `Route from ${source} to ${destination} is not supported` + `${tokenClause}.${summary}`,
|
|
1002
1435
|
cause: {
|
|
1003
1436
|
trace: {
|
|
1004
1437
|
source,
|
|
1005
|
-
destination
|
|
1438
|
+
destination,
|
|
1439
|
+
providerErrors: redactedFailures,
|
|
1440
|
+
...{}
|
|
1006
1441
|
}
|
|
1007
1442
|
}
|
|
1008
1443
|
};
|
|
1009
1444
|
return new KitError(errorDetails);
|
|
1010
1445
|
}
|
|
1446
|
+
/** Extract a human-readable summary from a redacted provider error. */ function describeProviderError(error) {
|
|
1447
|
+
return typeof error === 'string' ? error : error.message;
|
|
1448
|
+
}
|
|
1011
1449
|
/**
|
|
1012
1450
|
* Creates error for invalid amount format or precision.
|
|
1013
1451
|
*
|
|
@@ -1196,7 +1634,7 @@ class KitError extends Error {
|
|
|
1196
1634
|
* import { createValidationErrorFromZod } from '@core/errors'
|
|
1197
1635
|
*
|
|
1198
1636
|
* function validateBridgeParams(params: unknown): asserts params is BridgeParams {
|
|
1199
|
-
* const result =
|
|
1637
|
+
* const result = usdcBridgeParamsSchema.safeParse(params)
|
|
1200
1638
|
* if (!result.success) {
|
|
1201
1639
|
* throw createValidationErrorFromZod(result.error, 'bridge parameters')
|
|
1202
1640
|
* }
|
|
@@ -3042,9 +3480,10 @@ class KitError extends Error {
|
|
|
3042
3480
|
Blockchain["Algorand_Testnet"] = "Algorand_Testnet";
|
|
3043
3481
|
Blockchain["Aptos"] = "Aptos";
|
|
3044
3482
|
Blockchain["Aptos_Testnet"] = "Aptos_Testnet";
|
|
3045
|
-
Blockchain["Arc_Testnet"] = "Arc_Testnet";
|
|
3046
3483
|
Blockchain["Arbitrum"] = "Arbitrum";
|
|
3047
3484
|
Blockchain["Arbitrum_Sepolia"] = "Arbitrum_Sepolia";
|
|
3485
|
+
Blockchain["Arc"] = "Arc";
|
|
3486
|
+
Blockchain["Arc_Testnet"] = "Arc_Testnet";
|
|
3048
3487
|
Blockchain["Avalanche"] = "Avalanche";
|
|
3049
3488
|
Blockchain["Avalanche_Fuji"] = "Avalanche_Fuji";
|
|
3050
3489
|
Blockchain["Base"] = "Base";
|
|
@@ -3131,6 +3570,7 @@ var SwapChain;
|
|
|
3131
3570
|
SwapChain["XDC"] = "XDC";
|
|
3132
3571
|
SwapChain["HyperEVM"] = "HyperEVM";
|
|
3133
3572
|
SwapChain["Monad"] = "Monad";
|
|
3573
|
+
SwapChain["Arc"] = "Arc";
|
|
3134
3574
|
// Testnet chains with swap support
|
|
3135
3575
|
SwapChain["Arc_Testnet"] = "Arc_Testnet";
|
|
3136
3576
|
})(SwapChain || (SwapChain = {}));
|
|
@@ -3138,6 +3578,7 @@ var BridgeChain;
|
|
|
3138
3578
|
(function(BridgeChain) {
|
|
3139
3579
|
// Mainnet chains with CCTPv2 support
|
|
3140
3580
|
BridgeChain["Arbitrum"] = "Arbitrum";
|
|
3581
|
+
BridgeChain["Arc"] = "Arc";
|
|
3141
3582
|
BridgeChain["Avalanche"] = "Avalanche";
|
|
3142
3583
|
BridgeChain["Base"] = "Base";
|
|
3143
3584
|
BridgeChain["Codex"] = "Codex";
|
|
@@ -3193,6 +3634,7 @@ var BridgeChain;
|
|
|
3193
3634
|
var UnifiedBalanceChain;
|
|
3194
3635
|
(function(UnifiedBalanceChain) {
|
|
3195
3636
|
// Mainnet chains with Gateway V1 support
|
|
3637
|
+
UnifiedBalanceChain["Arc"] = "Arc";
|
|
3196
3638
|
UnifiedBalanceChain["Arbitrum"] = "Arbitrum";
|
|
3197
3639
|
UnifiedBalanceChain["Avalanche"] = "Avalanche";
|
|
3198
3640
|
UnifiedBalanceChain["Base"] = "Base";
|
|
@@ -3222,6 +3664,7 @@ var UnifiedBalanceChain;
|
|
|
3222
3664
|
})(UnifiedBalanceChain || (UnifiedBalanceChain = {}));
|
|
3223
3665
|
var EarnChain;
|
|
3224
3666
|
(function(EarnChain) {
|
|
3667
|
+
EarnChain["Arc"] = "Arc";
|
|
3225
3668
|
EarnChain["Arc_Testnet"] = "Arc_Testnet";
|
|
3226
3669
|
})(EarnChain || (EarnChain = {}));
|
|
3227
3670
|
/**
|
|
@@ -3238,8 +3681,11 @@ var EarnChain;
|
|
|
3238
3681
|
* console.log(EARN_BRIDGE_SOURCE_BLOCKCHAINS.join(', '))
|
|
3239
3682
|
* ```
|
|
3240
3683
|
*/ const EARN_BRIDGE_SOURCE_BLOCKCHAINS = [
|
|
3684
|
+
"Arbitrum",
|
|
3241
3685
|
"Arbitrum_Sepolia",
|
|
3686
|
+
"Base",
|
|
3242
3687
|
"Base_Sepolia",
|
|
3688
|
+
"Ethereum",
|
|
3243
3689
|
"Ethereum_Sepolia"
|
|
3244
3690
|
];
|
|
3245
3691
|
/**
|
|
@@ -3253,6 +3699,7 @@ var EarnChain;
|
|
|
3253
3699
|
* console.log(EARN_BRIDGE_DESTINATION_BLOCKCHAINS.join(', '))
|
|
3254
3700
|
* ```
|
|
3255
3701
|
*/ const EARN_BRIDGE_DESTINATION_BLOCKCHAINS = [
|
|
3702
|
+
"Arc",
|
|
3256
3703
|
"Arc_Testnet"
|
|
3257
3704
|
];
|
|
3258
3705
|
|
|
@@ -3558,6 +4005,25 @@ var EarnChain;
|
|
|
3558
4005
|
* EVM-compatible chains. Use this address when deploying or testing
|
|
3559
4006
|
* cross-chain USDC transfers on test networks.
|
|
3560
4007
|
*/ const BRIDGE_CONTRACT_EVM_TESTNET = '0xC5567a5E3370d4DBfB0540025078e283e36A363d';
|
|
4008
|
+
/**
|
|
4009
|
+
* The CrossChainTokenService (CCTPx) service address for EVM testnet networks.
|
|
4010
|
+
*
|
|
4011
|
+
* This service coordinates CCTPx cross-chain token operations on testnet
|
|
4012
|
+
* environments and is shared by every EVM test network CCTPx supports. Read the
|
|
4013
|
+
* chain definitions via `isCCTPXSupported` rather than trusting a list here,
|
|
4014
|
+
* which goes stale as deployments land.
|
|
4015
|
+
*/ const CCTPX_SERVICE_ADDRESS_EVM_TESTNET = '0x63753E722bd2C2A5DF6EE19C5106662208B81077';
|
|
4016
|
+
/**
|
|
4017
|
+
* CrossChainTokenService (CCTS) proxy address for CCTPx on EVM **mainnet**.
|
|
4018
|
+
*
|
|
4019
|
+
* @remarks
|
|
4020
|
+
* A distinct deployment from {@link CCTPX_SERVICE_ADDRESS_EVM_TESTNET}, shared
|
|
4021
|
+
* by every EVM mainnet chain that CCTPx supports. A chain becomes
|
|
4022
|
+
* CCTPx-eligible only once its definition carries this as
|
|
4023
|
+
* `cctpx.serviceAddress`, and a route additionally needs both of its endpoints
|
|
4024
|
+
* eligible — so adding a chain here is the deliberate, reviewable step that
|
|
4025
|
+
* opens mainnet CCTPx for it.
|
|
4026
|
+
*/ const CCTPX_SERVICE_ADDRESS_EVM_MAINNET = '0x431871229103b780868f8C6BB820cd16ECf942BC';
|
|
3561
4027
|
/**
|
|
3562
4028
|
* The bridge contract address for EVM mainnet networks.
|
|
3563
4029
|
*
|
|
@@ -3676,6 +4142,76 @@ var EarnChain;
|
|
|
3676
4142
|
* Used by the spend fee-split logic to route Circle's share of custom fees.
|
|
3677
4143
|
*/ const CIRCLE_FEE_RECIPIENT_SOLANA = 'HGMjULXsaMcbXgRhRECkSG3LyiKJgqiNAnLv1zZd8Kpn';
|
|
3678
4144
|
|
|
4145
|
+
/**
|
|
4146
|
+
* Arc Mainnet chain definition
|
|
4147
|
+
* @remarks
|
|
4148
|
+
* This represents the official production network for the Arc blockchain,
|
|
4149
|
+
* Circle's EVM-compatible Layer-1 designed for stablecoin finance
|
|
4150
|
+
* and asset tokenization. Arc uses USDC as the native gas token and
|
|
4151
|
+
* features the Malachite Byzantine Fault Tolerant (BFT) consensus
|
|
4152
|
+
* engine for sub-second finality.
|
|
4153
|
+
*/ const Arc = defineChain({
|
|
4154
|
+
type: 'evm',
|
|
4155
|
+
chain: Blockchain.Arc,
|
|
4156
|
+
name: 'Arc',
|
|
4157
|
+
title: 'Arc Mainnet',
|
|
4158
|
+
nativeCurrency: {
|
|
4159
|
+
name: 'USDC',
|
|
4160
|
+
symbol: 'USDC',
|
|
4161
|
+
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
4162
|
+
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
4163
|
+
// See: https://docs.arc.network/arc/references/contract-addresses
|
|
4164
|
+
decimals: 18
|
|
4165
|
+
},
|
|
4166
|
+
chainId: 5042,
|
|
4167
|
+
isTestnet: false,
|
|
4168
|
+
explorerUrl: 'https://explorer.arc.io/tx/{hash}',
|
|
4169
|
+
rpcEndpoints: [
|
|
4170
|
+
'https://rpc.mainnet.arc.io/'
|
|
4171
|
+
],
|
|
4172
|
+
eurcAddress: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
|
|
4173
|
+
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
4174
|
+
usdtAddress: null,
|
|
4175
|
+
cctp: {
|
|
4176
|
+
domain: 26,
|
|
4177
|
+
contracts: {
|
|
4178
|
+
v2: {
|
|
4179
|
+
type: 'split',
|
|
4180
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4181
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4182
|
+
confirmations: 1,
|
|
4183
|
+
fastConfirmations: 1
|
|
4184
|
+
}
|
|
4185
|
+
},
|
|
4186
|
+
forwarderSupported: {
|
|
4187
|
+
source: false,
|
|
4188
|
+
destination: true
|
|
4189
|
+
}
|
|
4190
|
+
},
|
|
4191
|
+
cctpx: {
|
|
4192
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4193
|
+
},
|
|
4194
|
+
kitContracts: {
|
|
4195
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4196
|
+
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
4197
|
+
},
|
|
4198
|
+
gateway: {
|
|
4199
|
+
domain: 26,
|
|
4200
|
+
contracts: {
|
|
4201
|
+
v1: {
|
|
4202
|
+
wallet: GATEWAY_WALLET_EVM_MAINNET,
|
|
4203
|
+
minter: GATEWAY_MINTER_EVM_MAINNET,
|
|
4204
|
+
depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
|
|
4205
|
+
genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
|
|
4206
|
+
}
|
|
4207
|
+
},
|
|
4208
|
+
forwarderSupported: {
|
|
4209
|
+
source: true,
|
|
4210
|
+
destination: true
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
});
|
|
4214
|
+
|
|
3679
4215
|
/**
|
|
3680
4216
|
* Arc Testnet chain definition
|
|
3681
4217
|
* @remarks
|
|
@@ -3723,6 +4259,9 @@ var EarnChain;
|
|
|
3723
4259
|
destination: true
|
|
3724
4260
|
}
|
|
3725
4261
|
},
|
|
4262
|
+
cctpx: {
|
|
4263
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4264
|
+
},
|
|
3726
4265
|
kitContracts: {
|
|
3727
4266
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
3728
4267
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -3790,6 +4329,9 @@ var EarnChain;
|
|
|
3790
4329
|
destination: true
|
|
3791
4330
|
}
|
|
3792
4331
|
},
|
|
4332
|
+
cctpx: {
|
|
4333
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4334
|
+
},
|
|
3793
4335
|
kitContracts: {
|
|
3794
4336
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
3795
4337
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -3855,6 +4397,9 @@ var EarnChain;
|
|
|
3855
4397
|
destination: true
|
|
3856
4398
|
}
|
|
3857
4399
|
},
|
|
4400
|
+
cctpx: {
|
|
4401
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4402
|
+
},
|
|
3858
4403
|
kitContracts: {
|
|
3859
4404
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
3860
4405
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -3920,6 +4465,9 @@ var EarnChain;
|
|
|
3920
4465
|
destination: true
|
|
3921
4466
|
}
|
|
3922
4467
|
},
|
|
4468
|
+
cctpx: {
|
|
4469
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4470
|
+
},
|
|
3923
4471
|
kitContracts: {
|
|
3924
4472
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
3925
4473
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -3987,6 +4535,9 @@ var EarnChain;
|
|
|
3987
4535
|
rpcEndpoints: [
|
|
3988
4536
|
'https://api.avax-test.network/ext/bc/C/rpc'
|
|
3989
4537
|
],
|
|
4538
|
+
cctpx: {
|
|
4539
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4540
|
+
},
|
|
3990
4541
|
kitContracts: {
|
|
3991
4542
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
3992
4543
|
},
|
|
@@ -4054,6 +4605,9 @@ var EarnChain;
|
|
|
4054
4605
|
destination: true
|
|
4055
4606
|
}
|
|
4056
4607
|
},
|
|
4608
|
+
cctpx: {
|
|
4609
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4610
|
+
},
|
|
4057
4611
|
kitContracts: {
|
|
4058
4612
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4059
4613
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -4119,6 +4673,9 @@ var EarnChain;
|
|
|
4119
4673
|
destination: true
|
|
4120
4674
|
}
|
|
4121
4675
|
},
|
|
4676
|
+
cctpx: {
|
|
4677
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4678
|
+
},
|
|
4122
4679
|
kitContracts: {
|
|
4123
4680
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
4124
4681
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -4511,6 +5068,9 @@ var EarnChain;
|
|
|
4511
5068
|
destination: true
|
|
4512
5069
|
}
|
|
4513
5070
|
},
|
|
5071
|
+
cctpx: {
|
|
5072
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
5073
|
+
},
|
|
4514
5074
|
kitContracts: {
|
|
4515
5075
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4516
5076
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -4576,6 +5136,9 @@ var EarnChain;
|
|
|
4576
5136
|
destination: true
|
|
4577
5137
|
}
|
|
4578
5138
|
},
|
|
5139
|
+
cctpx: {
|
|
5140
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
5141
|
+
},
|
|
4579
5142
|
kitContracts: {
|
|
4580
5143
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
4581
5144
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -5407,6 +5970,9 @@ var EarnChain;
|
|
|
5407
5970
|
destination: true
|
|
5408
5971
|
}
|
|
5409
5972
|
},
|
|
5973
|
+
cctpx: {
|
|
5974
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
5975
|
+
},
|
|
5410
5976
|
kitContracts: {
|
|
5411
5977
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5412
5978
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -5472,6 +6038,9 @@ var EarnChain;
|
|
|
5472
6038
|
destination: true
|
|
5473
6039
|
}
|
|
5474
6040
|
},
|
|
6041
|
+
cctpx: {
|
|
6042
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
6043
|
+
},
|
|
5475
6044
|
kitContracts: {
|
|
5476
6045
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
5477
6046
|
},
|
|
@@ -5867,6 +6436,9 @@ var EarnChain;
|
|
|
5867
6436
|
destination: true
|
|
5868
6437
|
}
|
|
5869
6438
|
},
|
|
6439
|
+
cctpx: {
|
|
6440
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
6441
|
+
},
|
|
5870
6442
|
kitContracts: {
|
|
5871
6443
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5872
6444
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -5935,6 +6507,9 @@ var EarnChain;
|
|
|
5935
6507
|
destination: true
|
|
5936
6508
|
}
|
|
5937
6509
|
},
|
|
6510
|
+
cctpx: {
|
|
6511
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
6512
|
+
},
|
|
5938
6513
|
kitContracts: {
|
|
5939
6514
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
5940
6515
|
},
|
|
@@ -6943,6 +7518,7 @@ var Chains = {
|
|
|
6943
7518
|
AptosTestnet: AptosTestnet,
|
|
6944
7519
|
Arbitrum: Arbitrum,
|
|
6945
7520
|
ArbitrumSepolia: ArbitrumSepolia,
|
|
7521
|
+
Arc: Arc,
|
|
6946
7522
|
ArcTestnet: ArcTestnet,
|
|
6947
7523
|
Avalanche: Avalanche,
|
|
6948
7524
|
AvalancheFuji: AvalancheFuji,
|
|
@@ -7360,6 +7936,7 @@ var Chains = {
|
|
|
7360
7936
|
usdcAddress: zod.z.string().nullable(),
|
|
7361
7937
|
usdtAddress: zod.z.string().nullable(),
|
|
7362
7938
|
cctp: zod.z.any().nullable(),
|
|
7939
|
+
cctpx: zod.z.any().optional(),
|
|
7363
7940
|
kitContracts: zod.z.object({
|
|
7364
7941
|
bridge: zod.z.string().optional(),
|
|
7365
7942
|
adapter: zod.z.string().optional()
|
|
@@ -7565,14 +8142,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
|
|
|
7565
8142
|
* Zod schema for validating the source chain of a cross-chain Earn deposit.
|
|
7566
8143
|
*
|
|
7567
8144
|
* Accept a supported source Blockchain value, a matching string literal, or a
|
|
7568
|
-
* ChainDefinition for a supported source chain. Source chains are Ethereum
|
|
7569
|
-
*
|
|
8145
|
+
* ChainDefinition for a supported source chain. Source chains are Ethereum,
|
|
8146
|
+
* Arbitrum, and Base (mainnet and testnet).
|
|
7570
8147
|
*
|
|
7571
8148
|
* @example
|
|
7572
8149
|
* ```typescript
|
|
7573
8150
|
* import { earnBridgeSourceChainIdentifierSchema } from '@core/chains'
|
|
7574
8151
|
*
|
|
7575
8152
|
* // Valid
|
|
8153
|
+
* earnBridgeSourceChainIdentifierSchema.parse('Ethereum')
|
|
7576
8154
|
* earnBridgeSourceChainIdentifierSchema.parse('Ethereum_Sepolia')
|
|
7577
8155
|
*
|
|
7578
8156
|
* // Invalid (throws ZodError)
|
|
@@ -7591,14 +8169,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
|
|
|
7591
8169
|
* deposit.
|
|
7592
8170
|
*
|
|
7593
8171
|
* Accept a supported destination Blockchain value, a matching string literal,
|
|
7594
|
-
* or a ChainDefinition for a supported destination chain.
|
|
7595
|
-
* Testnet
|
|
8172
|
+
* or a ChainDefinition for a supported destination chain. Arc (mainnet) and
|
|
8173
|
+
* Arc Testnet are supported.
|
|
7596
8174
|
*
|
|
7597
8175
|
* @example
|
|
7598
8176
|
* ```typescript
|
|
7599
8177
|
* import { earnBridgeDestinationChainIdentifierSchema } from '@core/chains'
|
|
7600
8178
|
*
|
|
7601
8179
|
* // Valid
|
|
8180
|
+
* earnBridgeDestinationChainIdentifierSchema.parse('Arc')
|
|
7602
8181
|
* earnBridgeDestinationChainIdentifierSchema.parse('Arc_Testnet')
|
|
7603
8182
|
*
|
|
7604
8183
|
* // Invalid (throws ZodError)
|
|
@@ -9224,6 +9803,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9224
9803
|
// Mainnets (alphabetically sorted)
|
|
9225
9804
|
// =========================================================================
|
|
9226
9805
|
[Blockchain.Arbitrum]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
|
9806
|
+
[Blockchain.Arc]: '0x3600000000000000000000000000000000000000',
|
|
9227
9807
|
[Blockchain.Avalanche]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
|
|
9228
9808
|
[Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
9229
9809
|
[Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
|
|
@@ -9338,6 +9918,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9338
9918
|
// =========================================================================
|
|
9339
9919
|
// Mainnets
|
|
9340
9920
|
// =========================================================================
|
|
9921
|
+
[Blockchain.Arc]: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
|
|
9341
9922
|
[Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
|
|
9342
9923
|
[Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
|
|
9343
9924
|
[Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
|
|
@@ -9581,6 +10162,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9581
10162
|
// =========================================================================
|
|
9582
10163
|
// Mainnets
|
|
9583
10164
|
// =========================================================================
|
|
10165
|
+
[Blockchain.Arc]: '0x171A4217b86A807A64eB94757Db6849fb4bDbAA0',
|
|
9584
10166
|
[Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
|
|
9585
10167
|
// =========================================================================
|
|
9586
10168
|
// Testnets
|
|
@@ -9673,13 +10255,28 @@ function parseOrThrow(value, schema, context) {
|
|
|
9673
10255
|
}
|
|
9674
10256
|
|
|
9675
10257
|
/**
|
|
9676
|
-
*
|
|
10258
|
+
* Type guard: narrows a {@link TokenSelector} to a {@link RawTokenSelector}.
|
|
9677
10259
|
*
|
|
9678
10260
|
* @param selector - The token selector to check.
|
|
9679
|
-
* @returns
|
|
10261
|
+
* @returns `true` if `selector` is a raw token selector (object with `locator`).
|
|
10262
|
+
*
|
|
10263
|
+
* @example
|
|
10264
|
+
* ```typescript
|
|
10265
|
+
* if (isRawSelector(selector)) {
|
|
10266
|
+
* console.log(selector.locator)
|
|
10267
|
+
* }
|
|
10268
|
+
* ```
|
|
9680
10269
|
*/ function isRawSelector(selector) {
|
|
9681
|
-
|
|
10270
|
+
// `typeof null === 'object'` (a JS quirk) and `'locator' in null`
|
|
10271
|
+
// throws, so the explicit `null` check is required at this exported
|
|
10272
|
+
// guard for JS consumers passing nullish values. The lint rule sees
|
|
10273
|
+
// the parameter typed as `TokenSelector` (no null) and flags the
|
|
10274
|
+
// check as unnecessary — disabled because the check IS necessary at
|
|
10275
|
+
// runtime even though TypeScript can prove it dead statically.
|
|
10276
|
+
return typeof selector === 'object' && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
10277
|
+
selector !== null && 'locator' in selector;
|
|
9682
10278
|
}
|
|
10279
|
+
|
|
9683
10280
|
/**
|
|
9684
10281
|
* Normalize a symbol to uppercase for case-insensitive lookup.
|
|
9685
10282
|
*
|
|
@@ -9867,7 +10464,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9867
10464
|
if (typeof selector === 'string') {
|
|
9868
10465
|
return resolveSymbol(selector, chainId);
|
|
9869
10466
|
}
|
|
9870
|
-
throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected
|
|
10467
|
+
throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected a token symbol or a raw selector (with locator).`, selector, chainId);
|
|
9871
10468
|
},
|
|
9872
10469
|
resolveByAddress (address, chainId) {
|
|
9873
10470
|
if (!address || typeof address !== 'string') {
|
|
@@ -11127,7 +11724,7 @@ function resolveOptions(options) {
|
|
|
11127
11724
|
}
|
|
11128
11725
|
|
|
11129
11726
|
var name = "@circle-fin/unified-balance-kit";
|
|
11130
|
-
var version$1 = "1.
|
|
11727
|
+
var version$1 = "1.7.0";
|
|
11131
11728
|
var pkg$1 = {
|
|
11132
11729
|
name: name,
|
|
11133
11730
|
version: version$1};
|
|
@@ -21142,10 +21739,26 @@ function toString(amount) {
|
|
|
21142
21739
|
* - Executing the actual bridge operations
|
|
21143
21740
|
* - Handling protocol-specific logic and error conditions
|
|
21144
21741
|
*
|
|
21742
|
+
* @remarks
|
|
21743
|
+
* Token-type default rationale: `TToken` defaults to the literal
|
|
21744
|
+
* `'USDC'` so a USDC-only subclass needs no generic ceremony at every
|
|
21745
|
+
* call site. This matches the literal `'USDC'` default on
|
|
21746
|
+
* {@link BridgeParams} (consumed at the provider boundary, where the
|
|
21747
|
+
* provider knows exactly which token symbol it accepts). The default
|
|
21748
|
+
* matches the default on {@link BridgeResult} and {@link EstimateResult} for
|
|
21749
|
+
* source compatibility. Provider-agnostic kit internals widen those result
|
|
21750
|
+
* types explicitly.
|
|
21751
|
+
*
|
|
21752
|
+
* Quotes are not typed here. A provider that issues one narrows its own
|
|
21753
|
+
* `estimate` return to the shape it produces — see the CCTPx provider's
|
|
21754
|
+
* `QuoteEnvelope` — which keeps that shape in the provider package rather
|
|
21755
|
+
* than in this shared one. `bridge` takes a caller-supplied quote, which is
|
|
21756
|
+
* public input the provider validates before reading a field.
|
|
21757
|
+
*
|
|
21145
21758
|
* @example
|
|
21146
21759
|
* ```typescript
|
|
21147
21760
|
* class CustomBridgingProvider extends BridgingProvider {
|
|
21148
|
-
*
|
|
21761
|
+
* supportsRoute(source: Chain, destination: Chain, token: TokenType): boolean {
|
|
21149
21762
|
* // Implementation specific logic
|
|
21150
21763
|
* return true
|
|
21151
21764
|
* }
|
|
@@ -21194,6 +21807,36 @@ function toString(amount) {
|
|
|
21194
21807
|
return this.supportedChains.filter((chain)=>chain.isTestnet === source.isTestnet && chain.chain !== source.chain);
|
|
21195
21808
|
}
|
|
21196
21809
|
/**
|
|
21810
|
+
* Return the decimal precision for the given token, or `undefined` when
|
|
21811
|
+
* the provider does not track it.
|
|
21812
|
+
*
|
|
21813
|
+
* Consumers that format a result amount resolve decimals through this
|
|
21814
|
+
* hook first, falling back to their own built-in token registry when it
|
|
21815
|
+
* returns `undefined`. The default implementation returns `undefined`,
|
|
21816
|
+
* so a provider whose tokens are already in the consumer's registry needs
|
|
21817
|
+
* no override; a provider that identifies tokens outside that registry
|
|
21818
|
+
* overrides this to supply their decimals.
|
|
21819
|
+
*
|
|
21820
|
+
* @param _token - The token to resolve decimals for (provider-defined);
|
|
21821
|
+
* unused by the default implementation, consumed by overrides.
|
|
21822
|
+
* @param _sourceChain - Source chain of the bridge. Providers whose tokens
|
|
21823
|
+
* live in per-network registries use it to scope the lookup to the relevant
|
|
21824
|
+
* network; unused by the default implementation. Required, so a lookup is
|
|
21825
|
+
* never asked to guess which network a token belongs to.
|
|
21826
|
+
* @returns A promise resolving to the token's decimals, or `undefined`
|
|
21827
|
+
* when the provider cannot resolve it.
|
|
21828
|
+
*
|
|
21829
|
+
* @example
|
|
21830
|
+
* ```typescript
|
|
21831
|
+
* const decimals = await provider.getTokenDecimals(token, source.chain)
|
|
21832
|
+
* if (decimals === undefined) {
|
|
21833
|
+
* // fall back to the consumer's own decimals lookup
|
|
21834
|
+
* }
|
|
21835
|
+
* ```
|
|
21836
|
+
*/ /* eslint-disable @typescript-eslint/require-await, @typescript-eslint/no-unused-vars -- Async so overrides can resolve decimals via I/O; the default is a constant that ignores its arguments. */ async getTokenDecimals(_token, _sourceChain) {
|
|
21837
|
+
return undefined;
|
|
21838
|
+
}
|
|
21839
|
+
/* eslint-enable @typescript-eslint/require-await, @typescript-eslint/no-unused-vars */ /**
|
|
21197
21840
|
* Register an event dispatcher for handling provider-specific actions and events.
|
|
21198
21841
|
*
|
|
21199
21842
|
*
|
|
@@ -21435,7 +22078,72 @@ var TransferSpeed;
|
|
|
21435
22078
|
*/ recipientAddress: zod.z.string().trim().min(1, 'Fee recipient must be a non-empty string').optional()
|
|
21436
22079
|
}).strict();
|
|
21437
22080
|
/**
|
|
21438
|
-
*
|
|
22081
|
+
* Factory for the bridge-params Zod schema, parameterized by the token
|
|
22082
|
+
* validator. The base schema enforces all non-token fields (amount,
|
|
22083
|
+
* source, destination, config); callers supply the Zod schema for the
|
|
22084
|
+
* `token` field, allowing each provider to validate the token type it
|
|
22085
|
+
* accepts.
|
|
22086
|
+
*
|
|
22087
|
+
* @param tokenSchema - Zod schema applied to the `token` field. Pass
|
|
22088
|
+
* `z.literal('USDC')` for USDC-only validation, or any
|
|
22089
|
+
* provider-specific schema (e.g. a `0x`-prefixed hex regex) for
|
|
22090
|
+
* providers that accept a different token type.
|
|
22091
|
+
* @param config - Required. `maxDecimals` caps the decimal precision
|
|
22092
|
+
* permitted in `amount` and `config.maxFee`. Pass the widest value
|
|
22093
|
+
* any of the provider's tokens require — `6` for USDC-only, `18`
|
|
22094
|
+
* for an ERC-20 family that includes wETH, etc. The schema is a
|
|
22095
|
+
* coarse syntactic gate; narrower per-token precision is enforced
|
|
22096
|
+
* by the provider downstream.
|
|
22097
|
+
* @returns A Zod object schema whose `token` field is validated by
|
|
22098
|
+
* `tokenSchema` and whose other fields (`amount`, `source`,
|
|
22099
|
+
* `destination`, `config`) are validated against the shared bridge
|
|
22100
|
+
* contract. Use `.safeParse` / `.parse` directly, or feed the schema
|
|
22101
|
+
* to {@link parseOrThrow} from `@core/utils` to surface validation
|
|
22102
|
+
* failures as `KitError` with the canonical
|
|
22103
|
+
* `INPUT_VALIDATION_FAILED` code.
|
|
22104
|
+
*
|
|
22105
|
+
* @example
|
|
22106
|
+
* ```typescript
|
|
22107
|
+
* import { createBridgeParamsSchema, z } from '@core/provider'
|
|
22108
|
+
*
|
|
22109
|
+
* const usdcSchema = createBridgeParamsSchema(z.literal('USDC'), { maxDecimals: 6 })
|
|
22110
|
+
* const hexSchema = createBridgeParamsSchema(
|
|
22111
|
+
* z.string().regex(/^0x[0-9a-fA-F]{64}$/),
|
|
22112
|
+
* { maxDecimals: 18 },
|
|
22113
|
+
* )
|
|
22114
|
+
* ```
|
|
22115
|
+
*/ // The full inferred return type of `z.object({...})` here is
|
|
22116
|
+
// effectively impossible to spell out by hand without re-stating every
|
|
22117
|
+
// field's schema. TypeScript infers it from the body — callers receive
|
|
22118
|
+
// a precise Zod schema type via inference, and the explicit-return
|
|
22119
|
+
// rules are disabled for that reason.
|
|
22120
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
|
|
22121
|
+
function createBridgeParamsSchema(tokenSchema, config) {
|
|
22122
|
+
const { maxDecimals } = config;
|
|
22123
|
+
return zod.z.object({
|
|
22124
|
+
amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
|
|
22125
|
+
allowZero: false,
|
|
22126
|
+
regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
|
|
22127
|
+
attributeName: 'amount',
|
|
22128
|
+
maxDecimals
|
|
22129
|
+
})(zod.z.string())),
|
|
22130
|
+
source: walletContextSchema,
|
|
22131
|
+
destination: bridgeDestinationSchema,
|
|
22132
|
+
token: tokenSchema,
|
|
22133
|
+
config: zod.z.object({
|
|
22134
|
+
transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
|
|
22135
|
+
maxFee: zod.z.string().pipe(createDecimalStringValidator({
|
|
22136
|
+
allowZero: true,
|
|
22137
|
+
regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
|
|
22138
|
+
attributeName: 'maxFee',
|
|
22139
|
+
maxDecimals
|
|
22140
|
+
})(zod.z.string())).optional(),
|
|
22141
|
+
customFee: customFeeSchema.optional()
|
|
22142
|
+
})
|
|
22143
|
+
});
|
|
22144
|
+
}
|
|
22145
|
+
/**
|
|
22146
|
+
* Schema for validating bridge parameters with USDC as the token.
|
|
21439
22147
|
* This ensures all required fields are present and properly typed.
|
|
21440
22148
|
* A bridge must include:
|
|
21441
22149
|
* - A valid amount (non-empty numeric string \> 0)
|
|
@@ -21443,11 +22151,15 @@ var TransferSpeed;
|
|
|
21443
22151
|
* - USDC as the token
|
|
21444
22152
|
* - Optional config with transfer speed and max fee settings
|
|
21445
22153
|
*
|
|
22154
|
+
* Providers that accept a non-USDC token type should call
|
|
22155
|
+
* {@link createBridgeParamsSchema} with their own token schema rather
|
|
22156
|
+
* than reusing this constant.
|
|
22157
|
+
*
|
|
21446
22158
|
* @throws KitError if validation fails
|
|
21447
22159
|
*
|
|
21448
22160
|
* @example
|
|
21449
22161
|
* ```typescript
|
|
21450
|
-
* import {
|
|
22162
|
+
* import { usdcBridgeParamsSchema } from '@core/provider'
|
|
21451
22163
|
*
|
|
21452
22164
|
* const validBridge = {
|
|
21453
22165
|
* amount: '100.50',
|
|
@@ -21472,29 +22184,11 @@ var TransferSpeed;
|
|
|
21472
22184
|
* }
|
|
21473
22185
|
* }
|
|
21474
22186
|
*
|
|
21475
|
-
* const result =
|
|
22187
|
+
* const result = usdcBridgeParamsSchema.safeParse(validBridge)
|
|
21476
22188
|
* console.log(result.success) // true
|
|
21477
22189
|
* ```
|
|
21478
|
-
*/ const
|
|
21479
|
-
|
|
21480
|
-
allowZero: false,
|
|
21481
|
-
regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
|
|
21482
|
-
attributeName: 'amount',
|
|
21483
|
-
maxDecimals: 6
|
|
21484
|
-
})(zod.z.string())),
|
|
21485
|
-
source: walletContextSchema,
|
|
21486
|
-
destination: bridgeDestinationSchema,
|
|
21487
|
-
token: zod.z.literal('USDC'),
|
|
21488
|
-
config: zod.z.object({
|
|
21489
|
-
transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
|
|
21490
|
-
maxFee: zod.z.string().pipe(createDecimalStringValidator({
|
|
21491
|
-
allowZero: true,
|
|
21492
|
-
regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
|
|
21493
|
-
attributeName: 'maxFee',
|
|
21494
|
-
maxDecimals: 6
|
|
21495
|
-
})(zod.z.string())).optional(),
|
|
21496
|
-
customFee: customFeeSchema.optional()
|
|
21497
|
-
})
|
|
22190
|
+
*/ const usdcBridgeParamsSchema = createBridgeParamsSchema(zod.z.literal('USDC'), {
|
|
22191
|
+
maxDecimals: 6
|
|
21498
22192
|
});
|
|
21499
22193
|
|
|
21500
22194
|
// ---------------------------------------------------------------------------
|
|
@@ -22088,6 +22782,10 @@ const USDC_DECIMALS$1 = 6;
|
|
|
22088
22782
|
*
|
|
22089
22783
|
* @see {@link https://developers.circle.com/gateway/references/fees}
|
|
22090
22784
|
*/ const GAS_FEE_BY_CHAIN = new Map([
|
|
22785
|
+
[
|
|
22786
|
+
Blockchain.Arc,
|
|
22787
|
+
parseUnits('0.001', USDC_DECIMALS$1)
|
|
22788
|
+
],
|
|
22091
22789
|
[
|
|
22092
22790
|
Blockchain.Arc_Testnet,
|
|
22093
22791
|
parseUnits('0.001', USDC_DECIMALS$1)
|
|
@@ -27453,7 +28151,7 @@ const assertCCTPv2BridgeParamsSymbol = Symbol('assertCCTPv2BridgeParams');
|
|
|
27453
28151
|
* ```
|
|
27454
28152
|
*/ function assertCCTPv2BridgeParams(params) {
|
|
27455
28153
|
// First validate basic bridge params
|
|
27456
|
-
validateWithStateTracking(params,
|
|
28154
|
+
validateWithStateTracking(params, usdcBridgeParamsSchema, 'CCTPv2 bridge parameters', assertCCTPv2BridgeParamsSymbol);
|
|
27457
28155
|
// After validation, we know params is CCTPV2BridgeParams
|
|
27458
28156
|
const bridgeParams = params;
|
|
27459
28157
|
// Enforce that source and destination chains are either testnet or mainnet
|
|
@@ -28320,7 +29018,7 @@ const mockAttestationMessage = {
|
|
|
28320
29018
|
return step;
|
|
28321
29019
|
}
|
|
28322
29020
|
|
|
28323
|
-
var version = "1.
|
|
29021
|
+
var version = "1.14.0";
|
|
28324
29022
|
var pkg = {
|
|
28325
29023
|
version: version};
|
|
28326
29024
|
|
|
@@ -29912,7 +30610,7 @@ function assertCCTPV2Config(config) {
|
|
|
29912
30610
|
* @example
|
|
29913
30611
|
* ```typescript
|
|
29914
30612
|
* const provider = new CCTPV2BridgingProvider()
|
|
29915
|
-
* const canTransfer = provider.supportsRoute(Ethereum, Base)
|
|
30613
|
+
* const canTransfer = provider.supportsRoute(Ethereum, Base, 'USDC')
|
|
29916
30614
|
*
|
|
29917
30615
|
* if (canTransfer) {
|
|
29918
30616
|
* console.log('CCTP v2 transfer is supported between these chains')
|