@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.mjs
CHANGED
|
@@ -701,6 +701,38 @@ class KitError extends Error {
|
|
|
701
701
|
name: 'INPUT_AMOUNT_OUT_OF_RANGE',
|
|
702
702
|
type: 'INPUT'
|
|
703
703
|
},
|
|
704
|
+
/**
|
|
705
|
+
* Protocol fee is denominated in a token that is not supported for the
|
|
706
|
+
* route (only the native gas token and the route's supported fee tokens,
|
|
707
|
+
* such as USDC, are accepted).
|
|
708
|
+
*/ UNSUPPORTED_FEE_TOKEN: {
|
|
709
|
+
code: 1014,
|
|
710
|
+
name: 'INPUT_UNSUPPORTED_FEE_TOKEN',
|
|
711
|
+
type: 'INPUT'
|
|
712
|
+
},
|
|
713
|
+
/** Retry / resume is not supported by this provider for the given result */ RETRY_NOT_SUPPORTED: {
|
|
714
|
+
code: 1015,
|
|
715
|
+
name: 'INPUT_RETRY_NOT_SUPPORTED',
|
|
716
|
+
type: 'INPUT'
|
|
717
|
+
},
|
|
718
|
+
/** Bridge-step analysis for retry is not supported by this provider */ STEP_ANALYSIS_NOT_SUPPORTED: {
|
|
719
|
+
code: 1016,
|
|
720
|
+
name: 'INPUT_STEP_ANALYSIS_NOT_SUPPORTED',
|
|
721
|
+
type: 'INPUT'
|
|
722
|
+
},
|
|
723
|
+
/**
|
|
724
|
+
* A kit operation name collides with a reserved event-subscription
|
|
725
|
+
* method (`on` / `off`) at kit construction.
|
|
726
|
+
*/ RESERVED_OPERATION_NAME: {
|
|
727
|
+
code: 1000,
|
|
728
|
+
name: 'INPUT_RESERVED_OPERATION_NAME',
|
|
729
|
+
type: 'INPUT'
|
|
730
|
+
},
|
|
731
|
+
/** A kit was constructed with a missing / undefined operation factory */ MISSING_OPERATION: {
|
|
732
|
+
code: 1017,
|
|
733
|
+
name: 'INPUT_MISSING_OPERATION',
|
|
734
|
+
type: 'INPUT'
|
|
735
|
+
},
|
|
704
736
|
/** General validation failure for complex validation rules */ VALIDATION_FAILED: {
|
|
705
737
|
code: 1098,
|
|
706
738
|
name: 'INPUT_VALIDATION_FAILED',
|
|
@@ -931,8 +963,376 @@ class KitError extends Error {
|
|
|
931
963
|
code: 8002,
|
|
932
964
|
name: 'SERVICE_UNKNOWN_ERROR',
|
|
933
965
|
type: 'SERVICE'
|
|
966
|
+
}};
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Log-safe error redaction for `KitError.cause.trace` fields.
|
|
970
|
+
*
|
|
971
|
+
* @packageDocumentation
|
|
972
|
+
*/ // ============================================================================
|
|
973
|
+
// Message redactor (operator-configurable secret scrubbing)
|
|
974
|
+
// ============================================================================
|
|
975
|
+
/**
|
|
976
|
+
* A pluggable redactor for the `message` strings that flow onto
|
|
977
|
+
* `KitError.cause.trace`.
|
|
978
|
+
*
|
|
979
|
+
* @remarks
|
|
980
|
+
* Two equivalent shapes are accepted:
|
|
981
|
+
*
|
|
982
|
+
* 1. **`readonly RegExp[]`** — the common case. Each pattern is run
|
|
983
|
+
* against the message; matches are replaced with `[REDACTED]`.
|
|
984
|
+
* The operator owns the `g` flag — pass a global regex to scrub
|
|
985
|
+
* every occurrence, a non-global regex to scrub the first one.
|
|
986
|
+
*
|
|
987
|
+
* 2. **`(message: string) => string`** — escape hatch for callers
|
|
988
|
+
* who want full control over the substitution (different
|
|
989
|
+
* placeholders per pattern, length-preserving redaction for
|
|
990
|
+
* log-volume parity, format-preserving encryption, etc.).
|
|
991
|
+
*
|
|
992
|
+
* @public
|
|
993
|
+
*/ /**
|
|
994
|
+
* Known RPC provider host suffixes scrubbed by the default redactor.
|
|
995
|
+
*
|
|
996
|
+
* @remarks
|
|
997
|
+
* The default redactor (see {@link composeRedactor} and
|
|
998
|
+
* {@link defaultMessageRedactor}) finds every `https?:` / `wss?:` URL
|
|
999
|
+
* in an error message, parses each one with the platform `URL`
|
|
1000
|
+
* constructor, and replaces it with `[REDACTED]` if the parsed
|
|
1001
|
+
* hostname ends with one of these suffixes. Adding a new provider is
|
|
1002
|
+
* a one-line change and cannot be wrong: there is no regex shape to
|
|
1003
|
+
* audit, no anchor-vs-quantifier trade-off, no
|
|
1004
|
+
* {@link https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS | ReDoS}
|
|
1005
|
+
* surface — the worst case is over-redaction (an unrelated URL on
|
|
1006
|
+
* the same host suffix gets scrubbed) which is the safe failure
|
|
1007
|
+
* mode.
|
|
1008
|
+
*
|
|
1009
|
+
* Suffixes covered:
|
|
1010
|
+
*
|
|
1011
|
+
* | Provider | Suffix |
|
|
1012
|
+
* | --- | --- |
|
|
1013
|
+
* | Alchemy | `.g.alchemy.com` |
|
|
1014
|
+
* | Infura | `.infura.io` |
|
|
1015
|
+
* | QuickNode | `.quiknode.pro` |
|
|
1016
|
+
* | Ankr | `.ankr.com` |
|
|
1017
|
+
* | Chainstack | `.p2pify.com` |
|
|
1018
|
+
* | Tenderly | `.gateway.tenderly.co` |
|
|
1019
|
+
* | BlockPI | `.blockpi.network` |
|
|
1020
|
+
* | GetBlock | `.getblock.io` |
|
|
1021
|
+
* | Moralis | `.moralis-nodes.com` |
|
|
1022
|
+
* | Helius | `.helius-rpc.com`, `.helius.xyz` |
|
|
1023
|
+
* | Triton | `.rpcpool.com` |
|
|
1024
|
+
*
|
|
1025
|
+
* Compose this list with your own self-hosted RPC suffixes via
|
|
1026
|
+
* {@link composeRedactor}.
|
|
1027
|
+
*
|
|
1028
|
+
* @public
|
|
1029
|
+
*/ const DEFAULT_RPC_HOST_SUFFIXES = Object.freeze([
|
|
1030
|
+
'.g.alchemy.com',
|
|
1031
|
+
'.infura.io',
|
|
1032
|
+
'.quiknode.pro',
|
|
1033
|
+
'.ankr.com',
|
|
1034
|
+
'.p2pify.com',
|
|
1035
|
+
'.gateway.tenderly.co',
|
|
1036
|
+
'.blockpi.network',
|
|
1037
|
+
'.getblock.io',
|
|
1038
|
+
'.moralis-nodes.com',
|
|
1039
|
+
'.helius-rpc.com',
|
|
1040
|
+
'.helius.xyz',
|
|
1041
|
+
'.rpcpool.com'
|
|
1042
|
+
]);
|
|
1043
|
+
/**
|
|
1044
|
+
* Built-in non-URL redaction patterns applied alongside the
|
|
1045
|
+
* URL-host scrubber.
|
|
1046
|
+
*
|
|
1047
|
+
* @remarks
|
|
1048
|
+
* Two simple patterns:
|
|
1049
|
+
*
|
|
1050
|
+
* - **Generic credential-bearing query strings** — `?api-key=…`,
|
|
1051
|
+
* `?apikey=…`, `?api-token=…`, `?access-token=…`, `?auth-token=…`,
|
|
1052
|
+
* `?app-key=…`, plus bare `?key=…` / `?token=…` / `?secret=…`.
|
|
1053
|
+
* Catches the case where a self-hosted RPC bakes the credential
|
|
1054
|
+
* into a query string instead of the path. Single canonical-name
|
|
1055
|
+
* alternation; complexity is well under SonarQube S5856's
|
|
1056
|
+
* 20-complexity bound.
|
|
1057
|
+
* - **Bearer header tokens** — `Bearer <token>` with bounded body
|
|
1058
|
+
* length and a `(?<![A-Za-z])` anchor so it can't be matched as a
|
|
1059
|
+
* tail-fragment of a longer word.
|
|
1060
|
+
*
|
|
1061
|
+
* Provider-specific URL-host scrubbing lives in
|
|
1062
|
+
* {@link DEFAULT_RPC_HOST_SUFFIXES} (parsed via `URL`) rather than as
|
|
1063
|
+
* regexes here — the host-list approach is CodeQL-clean (no
|
|
1064
|
+
* `js/regex/missing-anchor` heuristic match), false-positive-free
|
|
1065
|
+
* (provider URLs cannot accidentally collide with calldata or tx
|
|
1066
|
+
* hashes), and trivial to extend (one string per provider).
|
|
1067
|
+
*
|
|
1068
|
+
* @public
|
|
1069
|
+
*/ const DEFAULT_RPC_REDACTION_PATTERNS = Object.freeze([
|
|
1070
|
+
/[?&](?:(?:api|access|auth|app)[-_]?)?(?:key|token|secret)=[^&\s"'<>`]{1,256}/gi,
|
|
1071
|
+
/(?<![A-Za-z])Bearer\s+[A-Za-z0-9._~+/=-]{16,512}/g
|
|
1072
|
+
]);
|
|
1073
|
+
/**
|
|
1074
|
+
* Generic URL extractor used by {@link composeRedactor}.
|
|
1075
|
+
*
|
|
1076
|
+
* @remarks
|
|
1077
|
+
* Matches any `http://`, `https://`, `ws://`, or `wss://` URL,
|
|
1078
|
+
* bounded to 2 048 characters (longest URL Chrome / Firefox / IE
|
|
1079
|
+
* accept in practice; well below any reasonable error-message
|
|
1080
|
+
* payload). The regex is intentionally generic — it does **not**
|
|
1081
|
+
* encode any provider host shape — so CodeQL's
|
|
1082
|
+
* `js/regex/missing-anchor` heuristic (which targets URL-validation
|
|
1083
|
+
* regexes that look for a specific host) does not fire. All
|
|
1084
|
+
* provider classification happens in JS via `URL` parsing + string
|
|
1085
|
+
* suffix matching, never in regex.
|
|
1086
|
+
*/ const URL_EXTRACTOR = /(?<![A-Za-z0-9])(?:https?|wss?):\/\/[^\s"'<>`]{1,2048}/g;
|
|
1087
|
+
/**
|
|
1088
|
+
* Construct a redactor function from a host-suffix list and a
|
|
1089
|
+
* non-URL pattern list.
|
|
1090
|
+
*
|
|
1091
|
+
* @remarks
|
|
1092
|
+
* Each invocation:
|
|
1093
|
+
*
|
|
1094
|
+
* 1. Finds every URL in the message via {@link URL_EXTRACTOR}.
|
|
1095
|
+
* 2. Parses each candidate with the platform `URL` constructor (the
|
|
1096
|
+
* same one browsers and Node use for `fetch()` / `new Request()`),
|
|
1097
|
+
* discarding common trailing punctuation.
|
|
1098
|
+
* 3. Replaces the URL with `[REDACTED]` if its parsed hostname ends
|
|
1099
|
+
* with one of the configured suffixes.
|
|
1100
|
+
* 4. Applies every regex in `patterns` (Bearer headers, query-string
|
|
1101
|
+
* credentials, plus any operator-supplied additions).
|
|
1102
|
+
*
|
|
1103
|
+
* Both arrays default to the SDK's built-ins
|
|
1104
|
+
* ({@link DEFAULT_RPC_HOST_SUFFIXES} and
|
|
1105
|
+
* {@link DEFAULT_RPC_REDACTION_PATTERNS}); pass either to override.
|
|
1106
|
+
*
|
|
1107
|
+
* @param opts - Optional override for the default suffix list and/or
|
|
1108
|
+
* pattern list.
|
|
1109
|
+
* @returns A pure `(message: string) => string` function suitable for
|
|
1110
|
+
* passing to {@link setMessageRedactor}.
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* Add your self-hosted RPC URL to the host-suffix list (most common
|
|
1114
|
+
* extension shape):
|
|
1115
|
+
*
|
|
1116
|
+
* ```typescript
|
|
1117
|
+
* import {
|
|
1118
|
+
* composeRedactor,
|
|
1119
|
+
* setMessageRedactor,
|
|
1120
|
+
* DEFAULT_RPC_HOST_SUFFIXES,
|
|
1121
|
+
* } from '@core/errors'
|
|
1122
|
+
*
|
|
1123
|
+
* setMessageRedactor(
|
|
1124
|
+
* composeRedactor({
|
|
1125
|
+
* hostSuffixes: [...DEFAULT_RPC_HOST_SUFFIXES, '.rpc.my-corp.example'],
|
|
1126
|
+
* }),
|
|
1127
|
+
* )
|
|
1128
|
+
* ```
|
|
1129
|
+
*
|
|
1130
|
+
* @example
|
|
1131
|
+
* Add a custom non-URL pattern (e.g. a corporate header token):
|
|
1132
|
+
*
|
|
1133
|
+
* ```typescript
|
|
1134
|
+
* setMessageRedactor(
|
|
1135
|
+
* composeRedactor({
|
|
1136
|
+
* patterns: [
|
|
1137
|
+
* ...DEFAULT_RPC_REDACTION_PATTERNS,
|
|
1138
|
+
* /X-Corp-Token:\s+[A-Za-z0-9_-]{16,128}/g,
|
|
1139
|
+
* ],
|
|
1140
|
+
* }),
|
|
1141
|
+
* )
|
|
1142
|
+
* ```
|
|
1143
|
+
*
|
|
1144
|
+
* @public
|
|
1145
|
+
*/ function composeRedactor(opts) {
|
|
1146
|
+
const hostSuffixes = opts?.hostSuffixes ?? DEFAULT_RPC_HOST_SUFFIXES;
|
|
1147
|
+
const patterns = opts?.patterns ?? DEFAULT_RPC_REDACTION_PATTERNS;
|
|
1148
|
+
return (message)=>{
|
|
1149
|
+
let result = message.replaceAll(URL_EXTRACTOR, (url)=>{
|
|
1150
|
+
// Common trailing punctuation that error-message templates put
|
|
1151
|
+
// immediately after a URL (`Status: 401.`, `(see ...)`, `[1]`).
|
|
1152
|
+
// Strip before parsing so the `URL` parser doesn't reject
|
|
1153
|
+
// `eth-mainnet.g.alchemy.com.` (or accept it with a trailing
|
|
1154
|
+
// dot in `hostname` and miss the suffix match). Implemented as
|
|
1155
|
+
// a length-bounded string loop instead of a `/[.,;)\]>]+$/`
|
|
1156
|
+
// regex so CodeQL `js/redos-on-uncontrolled-input` cannot
|
|
1157
|
+
// flag a polynomial-time backtracking shape on operator-
|
|
1158
|
+
// controlled error text.
|
|
1159
|
+
const TRIM_CHARS = '.,;)]>';
|
|
1160
|
+
let end = url.length;
|
|
1161
|
+
const cap = Math.max(end - 16, 0) // bound the loop, length-cap 16
|
|
1162
|
+
;
|
|
1163
|
+
while(end > cap && TRIM_CHARS.includes(url.charAt(end - 1))){
|
|
1164
|
+
end--;
|
|
1165
|
+
}
|
|
1166
|
+
const trimmed = end === url.length ? url : url.slice(0, end);
|
|
1167
|
+
let parsed;
|
|
1168
|
+
try {
|
|
1169
|
+
parsed = new URL(trimmed);
|
|
1170
|
+
} catch {
|
|
1171
|
+
return url;
|
|
1172
|
+
}
|
|
1173
|
+
// HTTP-Basic userinfo (`user:pass@host`) is a credential by
|
|
1174
|
+
// definition — scrub it regardless of host, so enterprise /
|
|
1175
|
+
// self-hosted RPC URLs that don't match a known provider suffix
|
|
1176
|
+
// still get redacted.
|
|
1177
|
+
if (parsed.username !== '' || parsed.password !== '') {
|
|
1178
|
+
return '[REDACTED]';
|
|
1179
|
+
}
|
|
1180
|
+
const host = parsed.hostname.toLowerCase();
|
|
1181
|
+
return hostSuffixes.some((suffix)=>host.endsWith(suffix)) ? '[REDACTED]' : url;
|
|
1182
|
+
});
|
|
1183
|
+
for (const pattern of patterns){
|
|
1184
|
+
result = result.replaceAll(pattern, '[REDACTED]');
|
|
1185
|
+
}
|
|
1186
|
+
return result;
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* The SDK's default message redactor: scrubs URLs whose hostname
|
|
1191
|
+
* matches a {@link DEFAULT_RPC_HOST_SUFFIXES} entry, plus the
|
|
1192
|
+
* patterns in {@link DEFAULT_RPC_REDACTION_PATTERNS}.
|
|
1193
|
+
*
|
|
1194
|
+
* @remarks
|
|
1195
|
+
* Active at module load and re-installed by
|
|
1196
|
+
* {@link resetMessageRedactor}. Operators who want to layer
|
|
1197
|
+
* additional redaction on top of (rather than replace) the defaults
|
|
1198
|
+
* can call this directly inside a custom function form:
|
|
1199
|
+
*
|
|
1200
|
+
* ```typescript
|
|
1201
|
+
* setMessageRedactor((msg) =>
|
|
1202
|
+
* defaultMessageRedactor(msg).replace(/myExtraPattern/g, '[REDACTED]'),
|
|
1203
|
+
* )
|
|
1204
|
+
* ```
|
|
1205
|
+
*
|
|
1206
|
+
* For most extension cases prefer {@link composeRedactor}, which
|
|
1207
|
+
* gives the same result with structured options instead of a
|
|
1208
|
+
* post-hoc pipe.
|
|
1209
|
+
*
|
|
1210
|
+
* @public
|
|
1211
|
+
*/ const defaultMessageRedactor = composeRedactor();
|
|
1212
|
+
let activeRedactor = defaultMessageRedactor;
|
|
1213
|
+
/**
|
|
1214
|
+
* Apply the active redactor to an arbitrary message string.
|
|
1215
|
+
*
|
|
1216
|
+
* @remarks
|
|
1217
|
+
* Adapters call this on every string they place on `cause.trace`
|
|
1218
|
+
* other than the redacted `rawError` itself — viem `shortMessage`,
|
|
1219
|
+
* ethers `error.info.requestUrl`, the provider's `reason` field,
|
|
1220
|
+
* etc. When no redactor is configured this is the identity function,
|
|
1221
|
+
* so the cost on the no-redactor path is one `if`.
|
|
1222
|
+
*
|
|
1223
|
+
* @param message - The string to scrub.
|
|
1224
|
+
* @returns The redacted string. The original is returned untouched
|
|
1225
|
+
* when no redactor is configured.
|
|
1226
|
+
*
|
|
1227
|
+
* @example
|
|
1228
|
+
* ```typescript
|
|
1229
|
+
* import { redactErrorMessage, setMessageRedactor } from '@core/errors'
|
|
1230
|
+
*
|
|
1231
|
+
* setMessageRedactor([/[A-Fa-f0-9]{32,64}/g])
|
|
1232
|
+
* redactErrorMessage('failed: 0xabc...64chars...')
|
|
1233
|
+
* // => 'failed: [REDACTED]'
|
|
1234
|
+
* ```
|
|
1235
|
+
*
|
|
1236
|
+
* @public
|
|
1237
|
+
*/ function redactErrorMessage(message) {
|
|
1238
|
+
if (activeRedactor === undefined) return message;
|
|
1239
|
+
// `setMessageRedactor` eagerly compiles the array form into a
|
|
1240
|
+
// `composeRedactor`-wrapped function, so by the time we reach
|
|
1241
|
+
// here `activeRedactor` is always a function. The runtime
|
|
1242
|
+
// `typeof` guard exists for completeness — if a future
|
|
1243
|
+
// contributor introduces a setter path that bypasses the
|
|
1244
|
+
// compilation step, the guard keeps the dispatch correct.
|
|
1245
|
+
if (typeof activeRedactor === 'function') return activeRedactor(message);
|
|
1246
|
+
// Fallback (unreachable in normal use). See note above.
|
|
1247
|
+
return composeRedactor({
|
|
1248
|
+
patterns: activeRedactor,
|
|
1249
|
+
hostSuffixes: []
|
|
1250
|
+
})(message);
|
|
1251
|
+
}
|
|
1252
|
+
// ============================================================================
|
|
1253
|
+
// Object-graph redaction
|
|
1254
|
+
// ============================================================================
|
|
1255
|
+
/**
|
|
1256
|
+
* Redact an `unknown` error to a small, log-safe shape.
|
|
1257
|
+
*
|
|
1258
|
+
* @remarks
|
|
1259
|
+
* Wallet libraries (viem, ethers, web3-provider-engine, …) routinely
|
|
1260
|
+
* attach provider-injected fields to thrown errors: configured RPC URLs,
|
|
1261
|
+
* API keys, opaque internal state, the originating `XMLHttpRequest`,
|
|
1262
|
+
* and so on. Embedding the raw object directly inside `KitError.cause.trace`
|
|
1263
|
+
* means anyone who later JSON-serialises a `KitError` for telemetry leaks
|
|
1264
|
+
* those fields into logs.
|
|
1265
|
+
*
|
|
1266
|
+
* This helper extracts only the two fields that are useful for
|
|
1267
|
+
* post-mortem debugging — `name` and `message` — while never exposing the
|
|
1268
|
+
* underlying object graph. The `message` is run through the operator's
|
|
1269
|
+
* configured {@link setMessageRedactor | message redactor} (if any) so
|
|
1270
|
+
* that secrets the provider has interpolated into the message string
|
|
1271
|
+
* itself can be scrubbed. Non-`Error` throws (raw strings, plain
|
|
1272
|
+
* objects, primitives) are stringified with `String(error)` and then
|
|
1273
|
+
* run through the same redactor, so a secret-bearing string throw
|
|
1274
|
+
* (e.g. WalletConnect / older mobile wallets) is scrubbed too.
|
|
1275
|
+
*
|
|
1276
|
+
* **Two redaction layers, two responsibilities.**
|
|
1277
|
+
*
|
|
1278
|
+
* - **Object-graph stripping (this function, always on)** — drops
|
|
1279
|
+
* extra properties such as `request`, `requestUrl`, `info`, the
|
|
1280
|
+
* originating `XMLHttpRequest`, the configured `transport.url`,
|
|
1281
|
+
* etc. Without this, viem/ethers errors round-trip with the full
|
|
1282
|
+
* provider state graph attached.
|
|
1283
|
+
* - **Message-content scrubbing (configured via
|
|
1284
|
+
* {@link setMessageRedactor}, opt-in)** — handles the case where
|
|
1285
|
+
* the provider has already formatted secrets into `error.message`
|
|
1286
|
+
* itself. Notably, ethers v6's `makeError()` formats info keys
|
|
1287
|
+
* directly into the message:
|
|
1288
|
+
*
|
|
1289
|
+
* ```
|
|
1290
|
+
* missing response (requestUrl="https://mainnet.infura.io/v3/MY_KEY", code=SERVER_ERROR, ...)
|
|
1291
|
+
* ```
|
|
1292
|
+
*
|
|
1293
|
+
* Viem's `HttpRequestError` exhibits the same pattern via
|
|
1294
|
+
* `shortMessage`, which carries the configured URL with API path.
|
|
1295
|
+
* Without a redactor, the API key rides on `cause.trace.rawError.message`
|
|
1296
|
+
* verbatim. With one configured, every match is replaced with
|
|
1297
|
+
* `[REDACTED]` (or the operator's custom substitution).
|
|
1298
|
+
*
|
|
1299
|
+
* The split is intentional: there is no universal URL/secret
|
|
1300
|
+
* heuristic that won't false-positive on legitimate payloads
|
|
1301
|
+
* (mainnet addresses, contract revert reasons, raw call data), so
|
|
1302
|
+
* the SDK refuses to guess. Operators who know which patterns
|
|
1303
|
+
* appear in *their* RPC URLs configure the policy with one call
|
|
1304
|
+
* to {@link setMessageRedactor}.
|
|
1305
|
+
*
|
|
1306
|
+
* @param error - Anything thrown by a third-party wallet/provider library.
|
|
1307
|
+
* @returns A `{ name, message }` pair for `Error` instances (with
|
|
1308
|
+
* `message` run through the active redactor); the stringified value —
|
|
1309
|
+
* also run through the active redactor — otherwise. Always JSON-safe.
|
|
1310
|
+
*
|
|
1311
|
+
* @example
|
|
1312
|
+
* ```typescript
|
|
1313
|
+
* import { redactRawError, setMessageRedactor } from '@core/errors'
|
|
1314
|
+
*
|
|
1315
|
+
* setMessageRedactor([/infura\.io\/v3\/[a-z0-9]+/gi])
|
|
1316
|
+
* const err = new Error('failed: https://mainnet.infura.io/v3/abc123')
|
|
1317
|
+
* redactRawError(err)
|
|
1318
|
+
* // => { name: 'Error', message: 'failed: https://[REDACTED]' }
|
|
1319
|
+
* ```
|
|
1320
|
+
*
|
|
1321
|
+
* @public
|
|
1322
|
+
*/ function redactRawError(error) {
|
|
1323
|
+
if (error instanceof Error) {
|
|
1324
|
+
return {
|
|
1325
|
+
name: error.name,
|
|
1326
|
+
message: redactErrorMessage(error.message)
|
|
1327
|
+
};
|
|
934
1328
|
}
|
|
935
|
-
|
|
1329
|
+
// Non-Error throws (raw strings from WalletConnect / older mobile
|
|
1330
|
+
// wallets, plain objects, primitives) are stringified and then run
|
|
1331
|
+
// through the active redactor. A raw string throw can carry a secret
|
|
1332
|
+
// RPC URL just like an `Error.message` does, so it must be scrubbed
|
|
1333
|
+
// rather than returned verbatim.
|
|
1334
|
+
return redactErrorMessage(String(error));
|
|
1335
|
+
}
|
|
936
1336
|
|
|
937
1337
|
/**
|
|
938
1338
|
* Creates error for network type mismatch between source and destination.
|
|
@@ -978,6 +1378,15 @@ class KitError extends Error {
|
|
|
978
1378
|
*
|
|
979
1379
|
* @param source - Source chain name
|
|
980
1380
|
* @param destination - Destination chain name
|
|
1381
|
+
* @param providerErrors - Optional list of providers whose `supportsRoute`
|
|
1382
|
+
* call threw during the search. When non-empty, the message includes a
|
|
1383
|
+
* summary so consumers can distinguish "no provider supports this route"
|
|
1384
|
+
* from "a provider errored mid-search." Pass the errors raw: each one is
|
|
1385
|
+
* run through `redactRawError` here, so neither the message nor
|
|
1386
|
+
* `cause.trace.providerErrors` carries the provider's raw object graph.
|
|
1387
|
+
* @param token - Optional token the caller asked to bridge. When supplied it
|
|
1388
|
+
* is named in the message and the trace, so a symbol the routing layer does
|
|
1389
|
+
* not recognise reads as a token problem rather than a chain-pair one.
|
|
981
1390
|
* @returns KitError with specific route details
|
|
982
1391
|
*
|
|
983
1392
|
* @example
|
|
@@ -985,22 +1394,51 @@ class KitError extends Error {
|
|
|
985
1394
|
* import { createUnsupportedRouteError } from '@core/errors'
|
|
986
1395
|
*
|
|
987
1396
|
* throw createUnsupportedRouteError('Ethereum', 'Solana')
|
|
988
|
-
* // Message: "Route from Ethereum to Solana is not supported"
|
|
989
|
-
*
|
|
990
|
-
|
|
1397
|
+
* // Message: "Route from Ethereum to Solana is not supported."
|
|
1398
|
+
*
|
|
1399
|
+
* throw createUnsupportedRouteError('Ethereum', 'Arc', [
|
|
1400
|
+
* { provider: 'cctpx', error: new Error('ECONNRESET') },
|
|
1401
|
+
* ])
|
|
1402
|
+
* // Message: "Route from Ethereum to Arc is not supported.
|
|
1403
|
+
* // Providers errored during route check: cctpx (ECONNRESET)."
|
|
1404
|
+
*
|
|
1405
|
+
* throw createUnsupportedRouteError('Ethereum', 'Arc', undefined, 'USCD')
|
|
1406
|
+
* // Message: "Route from Ethereum to Arc is not supported for token 'USCD'."
|
|
1407
|
+
* ```
|
|
1408
|
+
*/ function createUnsupportedRouteError(source, destination, providerErrors, token) {
|
|
1409
|
+
const failures = [];
|
|
1410
|
+
// Redact once, here. `supportsRoute` may be async so a provider can do a
|
|
1411
|
+
// registry-backed network check, and a fetch rejection embeds the request
|
|
1412
|
+
// URL — with a credential in the worst case — in both its object graph and
|
|
1413
|
+
// its message. Both consumers below read from this redacted copy, so the
|
|
1414
|
+
// raw value never leaves this function. Redacting once is load-bearing:
|
|
1415
|
+
// `redactRawError` is not idempotent (it stringifies a non-`Error` input,
|
|
1416
|
+
// so a second pass collapses `{ name, message }` to `"[object Object]"`),
|
|
1417
|
+
// which is why callers pass raw errors in and let the factory do it.
|
|
1418
|
+
const redactedFailures = failures.map((failure)=>({
|
|
1419
|
+
provider: failure.provider,
|
|
1420
|
+
error: redactRawError(failure.error)
|
|
1421
|
+
}));
|
|
1422
|
+
const summary = redactedFailures.length === 0 ? '' : ` Providers errored during route check: ${redactedFailures.map((f)=>`${f.provider} (${describeProviderError(f.error)})`).join(', ')}.`;
|
|
1423
|
+
const tokenClause = '' ;
|
|
991
1424
|
const errorDetails = {
|
|
992
1425
|
...InputError.UNSUPPORTED_ROUTE,
|
|
993
1426
|
recoverability: 'FATAL',
|
|
994
|
-
message: `Route from ${source} to ${destination} is not supported
|
|
1427
|
+
message: `Route from ${source} to ${destination} is not supported` + `${tokenClause}.${summary}`,
|
|
995
1428
|
cause: {
|
|
996
1429
|
trace: {
|
|
997
1430
|
source,
|
|
998
|
-
destination
|
|
1431
|
+
destination,
|
|
1432
|
+
providerErrors: redactedFailures,
|
|
1433
|
+
...{}
|
|
999
1434
|
}
|
|
1000
1435
|
}
|
|
1001
1436
|
};
|
|
1002
1437
|
return new KitError(errorDetails);
|
|
1003
1438
|
}
|
|
1439
|
+
/** Extract a human-readable summary from a redacted provider error. */ function describeProviderError(error) {
|
|
1440
|
+
return typeof error === 'string' ? error : error.message;
|
|
1441
|
+
}
|
|
1004
1442
|
/**
|
|
1005
1443
|
* Creates error for invalid amount format or precision.
|
|
1006
1444
|
*
|
|
@@ -1189,7 +1627,7 @@ class KitError extends Error {
|
|
|
1189
1627
|
* import { createValidationErrorFromZod } from '@core/errors'
|
|
1190
1628
|
*
|
|
1191
1629
|
* function validateBridgeParams(params: unknown): asserts params is BridgeParams {
|
|
1192
|
-
* const result =
|
|
1630
|
+
* const result = usdcBridgeParamsSchema.safeParse(params)
|
|
1193
1631
|
* if (!result.success) {
|
|
1194
1632
|
* throw createValidationErrorFromZod(result.error, 'bridge parameters')
|
|
1195
1633
|
* }
|
|
@@ -3035,9 +3473,10 @@ class KitError extends Error {
|
|
|
3035
3473
|
Blockchain["Algorand_Testnet"] = "Algorand_Testnet";
|
|
3036
3474
|
Blockchain["Aptos"] = "Aptos";
|
|
3037
3475
|
Blockchain["Aptos_Testnet"] = "Aptos_Testnet";
|
|
3038
|
-
Blockchain["Arc_Testnet"] = "Arc_Testnet";
|
|
3039
3476
|
Blockchain["Arbitrum"] = "Arbitrum";
|
|
3040
3477
|
Blockchain["Arbitrum_Sepolia"] = "Arbitrum_Sepolia";
|
|
3478
|
+
Blockchain["Arc"] = "Arc";
|
|
3479
|
+
Blockchain["Arc_Testnet"] = "Arc_Testnet";
|
|
3041
3480
|
Blockchain["Avalanche"] = "Avalanche";
|
|
3042
3481
|
Blockchain["Avalanche_Fuji"] = "Avalanche_Fuji";
|
|
3043
3482
|
Blockchain["Base"] = "Base";
|
|
@@ -3124,6 +3563,7 @@ var SwapChain;
|
|
|
3124
3563
|
SwapChain["XDC"] = "XDC";
|
|
3125
3564
|
SwapChain["HyperEVM"] = "HyperEVM";
|
|
3126
3565
|
SwapChain["Monad"] = "Monad";
|
|
3566
|
+
SwapChain["Arc"] = "Arc";
|
|
3127
3567
|
// Testnet chains with swap support
|
|
3128
3568
|
SwapChain["Arc_Testnet"] = "Arc_Testnet";
|
|
3129
3569
|
})(SwapChain || (SwapChain = {}));
|
|
@@ -3131,6 +3571,7 @@ var BridgeChain;
|
|
|
3131
3571
|
(function(BridgeChain) {
|
|
3132
3572
|
// Mainnet chains with CCTPv2 support
|
|
3133
3573
|
BridgeChain["Arbitrum"] = "Arbitrum";
|
|
3574
|
+
BridgeChain["Arc"] = "Arc";
|
|
3134
3575
|
BridgeChain["Avalanche"] = "Avalanche";
|
|
3135
3576
|
BridgeChain["Base"] = "Base";
|
|
3136
3577
|
BridgeChain["Codex"] = "Codex";
|
|
@@ -3186,6 +3627,7 @@ var BridgeChain;
|
|
|
3186
3627
|
var UnifiedBalanceChain;
|
|
3187
3628
|
(function(UnifiedBalanceChain) {
|
|
3188
3629
|
// Mainnet chains with Gateway V1 support
|
|
3630
|
+
UnifiedBalanceChain["Arc"] = "Arc";
|
|
3189
3631
|
UnifiedBalanceChain["Arbitrum"] = "Arbitrum";
|
|
3190
3632
|
UnifiedBalanceChain["Avalanche"] = "Avalanche";
|
|
3191
3633
|
UnifiedBalanceChain["Base"] = "Base";
|
|
@@ -3215,6 +3657,7 @@ var UnifiedBalanceChain;
|
|
|
3215
3657
|
})(UnifiedBalanceChain || (UnifiedBalanceChain = {}));
|
|
3216
3658
|
var EarnChain;
|
|
3217
3659
|
(function(EarnChain) {
|
|
3660
|
+
EarnChain["Arc"] = "Arc";
|
|
3218
3661
|
EarnChain["Arc_Testnet"] = "Arc_Testnet";
|
|
3219
3662
|
})(EarnChain || (EarnChain = {}));
|
|
3220
3663
|
/**
|
|
@@ -3231,8 +3674,11 @@ var EarnChain;
|
|
|
3231
3674
|
* console.log(EARN_BRIDGE_SOURCE_BLOCKCHAINS.join(', '))
|
|
3232
3675
|
* ```
|
|
3233
3676
|
*/ const EARN_BRIDGE_SOURCE_BLOCKCHAINS = [
|
|
3677
|
+
"Arbitrum",
|
|
3234
3678
|
"Arbitrum_Sepolia",
|
|
3679
|
+
"Base",
|
|
3235
3680
|
"Base_Sepolia",
|
|
3681
|
+
"Ethereum",
|
|
3236
3682
|
"Ethereum_Sepolia"
|
|
3237
3683
|
];
|
|
3238
3684
|
/**
|
|
@@ -3246,6 +3692,7 @@ var EarnChain;
|
|
|
3246
3692
|
* console.log(EARN_BRIDGE_DESTINATION_BLOCKCHAINS.join(', '))
|
|
3247
3693
|
* ```
|
|
3248
3694
|
*/ const EARN_BRIDGE_DESTINATION_BLOCKCHAINS = [
|
|
3695
|
+
"Arc",
|
|
3249
3696
|
"Arc_Testnet"
|
|
3250
3697
|
];
|
|
3251
3698
|
|
|
@@ -3551,6 +3998,25 @@ var EarnChain;
|
|
|
3551
3998
|
* EVM-compatible chains. Use this address when deploying or testing
|
|
3552
3999
|
* cross-chain USDC transfers on test networks.
|
|
3553
4000
|
*/ const BRIDGE_CONTRACT_EVM_TESTNET = '0xC5567a5E3370d4DBfB0540025078e283e36A363d';
|
|
4001
|
+
/**
|
|
4002
|
+
* The CrossChainTokenService (CCTPx) service address for EVM testnet networks.
|
|
4003
|
+
*
|
|
4004
|
+
* This service coordinates CCTPx cross-chain token operations on testnet
|
|
4005
|
+
* environments and is shared by every EVM test network CCTPx supports. Read the
|
|
4006
|
+
* chain definitions via `isCCTPXSupported` rather than trusting a list here,
|
|
4007
|
+
* which goes stale as deployments land.
|
|
4008
|
+
*/ const CCTPX_SERVICE_ADDRESS_EVM_TESTNET = '0x63753E722bd2C2A5DF6EE19C5106662208B81077';
|
|
4009
|
+
/**
|
|
4010
|
+
* CrossChainTokenService (CCTS) proxy address for CCTPx on EVM **mainnet**.
|
|
4011
|
+
*
|
|
4012
|
+
* @remarks
|
|
4013
|
+
* A distinct deployment from {@link CCTPX_SERVICE_ADDRESS_EVM_TESTNET}, shared
|
|
4014
|
+
* by every EVM mainnet chain that CCTPx supports. A chain becomes
|
|
4015
|
+
* CCTPx-eligible only once its definition carries this as
|
|
4016
|
+
* `cctpx.serviceAddress`, and a route additionally needs both of its endpoints
|
|
4017
|
+
* eligible — so adding a chain here is the deliberate, reviewable step that
|
|
4018
|
+
* opens mainnet CCTPx for it.
|
|
4019
|
+
*/ const CCTPX_SERVICE_ADDRESS_EVM_MAINNET = '0x431871229103b780868f8C6BB820cd16ECf942BC';
|
|
3554
4020
|
/**
|
|
3555
4021
|
* The bridge contract address for EVM mainnet networks.
|
|
3556
4022
|
*
|
|
@@ -3669,6 +4135,76 @@ var EarnChain;
|
|
|
3669
4135
|
* Used by the spend fee-split logic to route Circle's share of custom fees.
|
|
3670
4136
|
*/ const CIRCLE_FEE_RECIPIENT_SOLANA = 'HGMjULXsaMcbXgRhRECkSG3LyiKJgqiNAnLv1zZd8Kpn';
|
|
3671
4137
|
|
|
4138
|
+
/**
|
|
4139
|
+
* Arc Mainnet chain definition
|
|
4140
|
+
* @remarks
|
|
4141
|
+
* This represents the official production network for the Arc blockchain,
|
|
4142
|
+
* Circle's EVM-compatible Layer-1 designed for stablecoin finance
|
|
4143
|
+
* and asset tokenization. Arc uses USDC as the native gas token and
|
|
4144
|
+
* features the Malachite Byzantine Fault Tolerant (BFT) consensus
|
|
4145
|
+
* engine for sub-second finality.
|
|
4146
|
+
*/ const Arc = defineChain({
|
|
4147
|
+
type: 'evm',
|
|
4148
|
+
chain: Blockchain.Arc,
|
|
4149
|
+
name: 'Arc',
|
|
4150
|
+
title: 'Arc Mainnet',
|
|
4151
|
+
nativeCurrency: {
|
|
4152
|
+
name: 'USDC',
|
|
4153
|
+
symbol: 'USDC',
|
|
4154
|
+
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
4155
|
+
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
4156
|
+
// See: https://docs.arc.network/arc/references/contract-addresses
|
|
4157
|
+
decimals: 18
|
|
4158
|
+
},
|
|
4159
|
+
chainId: 5042,
|
|
4160
|
+
isTestnet: false,
|
|
4161
|
+
explorerUrl: 'https://explorer.arc.io/tx/{hash}',
|
|
4162
|
+
rpcEndpoints: [
|
|
4163
|
+
'https://rpc.mainnet.arc.io/'
|
|
4164
|
+
],
|
|
4165
|
+
eurcAddress: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
|
|
4166
|
+
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
4167
|
+
usdtAddress: null,
|
|
4168
|
+
cctp: {
|
|
4169
|
+
domain: 26,
|
|
4170
|
+
contracts: {
|
|
4171
|
+
v2: {
|
|
4172
|
+
type: 'split',
|
|
4173
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4174
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4175
|
+
confirmations: 1,
|
|
4176
|
+
fastConfirmations: 1
|
|
4177
|
+
}
|
|
4178
|
+
},
|
|
4179
|
+
forwarderSupported: {
|
|
4180
|
+
source: false,
|
|
4181
|
+
destination: true
|
|
4182
|
+
}
|
|
4183
|
+
},
|
|
4184
|
+
cctpx: {
|
|
4185
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4186
|
+
},
|
|
4187
|
+
kitContracts: {
|
|
4188
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4189
|
+
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
4190
|
+
},
|
|
4191
|
+
gateway: {
|
|
4192
|
+
domain: 26,
|
|
4193
|
+
contracts: {
|
|
4194
|
+
v1: {
|
|
4195
|
+
wallet: GATEWAY_WALLET_EVM_MAINNET,
|
|
4196
|
+
minter: GATEWAY_MINTER_EVM_MAINNET,
|
|
4197
|
+
depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
|
|
4198
|
+
genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
|
|
4199
|
+
}
|
|
4200
|
+
},
|
|
4201
|
+
forwarderSupported: {
|
|
4202
|
+
source: true,
|
|
4203
|
+
destination: true
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
});
|
|
4207
|
+
|
|
3672
4208
|
/**
|
|
3673
4209
|
* Arc Testnet chain definition
|
|
3674
4210
|
* @remarks
|
|
@@ -3716,6 +4252,9 @@ var EarnChain;
|
|
|
3716
4252
|
destination: true
|
|
3717
4253
|
}
|
|
3718
4254
|
},
|
|
4255
|
+
cctpx: {
|
|
4256
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4257
|
+
},
|
|
3719
4258
|
kitContracts: {
|
|
3720
4259
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
3721
4260
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -3783,6 +4322,9 @@ var EarnChain;
|
|
|
3783
4322
|
destination: true
|
|
3784
4323
|
}
|
|
3785
4324
|
},
|
|
4325
|
+
cctpx: {
|
|
4326
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4327
|
+
},
|
|
3786
4328
|
kitContracts: {
|
|
3787
4329
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
3788
4330
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -3848,6 +4390,9 @@ var EarnChain;
|
|
|
3848
4390
|
destination: true
|
|
3849
4391
|
}
|
|
3850
4392
|
},
|
|
4393
|
+
cctpx: {
|
|
4394
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4395
|
+
},
|
|
3851
4396
|
kitContracts: {
|
|
3852
4397
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
3853
4398
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -3913,6 +4458,9 @@ var EarnChain;
|
|
|
3913
4458
|
destination: true
|
|
3914
4459
|
}
|
|
3915
4460
|
},
|
|
4461
|
+
cctpx: {
|
|
4462
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4463
|
+
},
|
|
3916
4464
|
kitContracts: {
|
|
3917
4465
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
3918
4466
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -3980,6 +4528,9 @@ var EarnChain;
|
|
|
3980
4528
|
rpcEndpoints: [
|
|
3981
4529
|
'https://api.avax-test.network/ext/bc/C/rpc'
|
|
3982
4530
|
],
|
|
4531
|
+
cctpx: {
|
|
4532
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4533
|
+
},
|
|
3983
4534
|
kitContracts: {
|
|
3984
4535
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
3985
4536
|
},
|
|
@@ -4047,6 +4598,9 @@ var EarnChain;
|
|
|
4047
4598
|
destination: true
|
|
4048
4599
|
}
|
|
4049
4600
|
},
|
|
4601
|
+
cctpx: {
|
|
4602
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
4603
|
+
},
|
|
4050
4604
|
kitContracts: {
|
|
4051
4605
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4052
4606
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -4112,6 +4666,9 @@ var EarnChain;
|
|
|
4112
4666
|
destination: true
|
|
4113
4667
|
}
|
|
4114
4668
|
},
|
|
4669
|
+
cctpx: {
|
|
4670
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
4671
|
+
},
|
|
4115
4672
|
kitContracts: {
|
|
4116
4673
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
4117
4674
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -4504,6 +5061,9 @@ var EarnChain;
|
|
|
4504
5061
|
destination: true
|
|
4505
5062
|
}
|
|
4506
5063
|
},
|
|
5064
|
+
cctpx: {
|
|
5065
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
5066
|
+
},
|
|
4507
5067
|
kitContracts: {
|
|
4508
5068
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
4509
5069
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -4569,6 +5129,9 @@ var EarnChain;
|
|
|
4569
5129
|
destination: true
|
|
4570
5130
|
}
|
|
4571
5131
|
},
|
|
5132
|
+
cctpx: {
|
|
5133
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
5134
|
+
},
|
|
4572
5135
|
kitContracts: {
|
|
4573
5136
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
4574
5137
|
adapter: ADAPTER_CONTRACT_EVM_TESTNET
|
|
@@ -5400,6 +5963,9 @@ var EarnChain;
|
|
|
5400
5963
|
destination: true
|
|
5401
5964
|
}
|
|
5402
5965
|
},
|
|
5966
|
+
cctpx: {
|
|
5967
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
5968
|
+
},
|
|
5403
5969
|
kitContracts: {
|
|
5404
5970
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5405
5971
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -5465,6 +6031,9 @@ var EarnChain;
|
|
|
5465
6031
|
destination: true
|
|
5466
6032
|
}
|
|
5467
6033
|
},
|
|
6034
|
+
cctpx: {
|
|
6035
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
6036
|
+
},
|
|
5468
6037
|
kitContracts: {
|
|
5469
6038
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
5470
6039
|
},
|
|
@@ -5860,6 +6429,9 @@ var EarnChain;
|
|
|
5860
6429
|
destination: true
|
|
5861
6430
|
}
|
|
5862
6431
|
},
|
|
6432
|
+
cctpx: {
|
|
6433
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
|
|
6434
|
+
},
|
|
5863
6435
|
kitContracts: {
|
|
5864
6436
|
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5865
6437
|
adapter: ADAPTER_CONTRACT_EVM_MAINNET
|
|
@@ -5928,6 +6500,9 @@ var EarnChain;
|
|
|
5928
6500
|
destination: true
|
|
5929
6501
|
}
|
|
5930
6502
|
},
|
|
6503
|
+
cctpx: {
|
|
6504
|
+
serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
|
|
6505
|
+
},
|
|
5931
6506
|
kitContracts: {
|
|
5932
6507
|
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
5933
6508
|
},
|
|
@@ -6936,6 +7511,7 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
6936
7511
|
AptosTestnet: AptosTestnet,
|
|
6937
7512
|
Arbitrum: Arbitrum,
|
|
6938
7513
|
ArbitrumSepolia: ArbitrumSepolia,
|
|
7514
|
+
Arc: Arc,
|
|
6939
7515
|
ArcTestnet: ArcTestnet,
|
|
6940
7516
|
Avalanche: Avalanche,
|
|
6941
7517
|
AvalancheFuji: AvalancheFuji,
|
|
@@ -7353,6 +7929,7 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
7353
7929
|
usdcAddress: z.string().nullable(),
|
|
7354
7930
|
usdtAddress: z.string().nullable(),
|
|
7355
7931
|
cctp: z.any().nullable(),
|
|
7932
|
+
cctpx: z.any().optional(),
|
|
7356
7933
|
kitContracts: z.object({
|
|
7357
7934
|
bridge: z.string().optional(),
|
|
7358
7935
|
adapter: z.string().optional()
|
|
@@ -7558,14 +8135,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
|
|
|
7558
8135
|
* Zod schema for validating the source chain of a cross-chain Earn deposit.
|
|
7559
8136
|
*
|
|
7560
8137
|
* Accept a supported source Blockchain value, a matching string literal, or a
|
|
7561
|
-
* ChainDefinition for a supported source chain. Source chains are Ethereum
|
|
7562
|
-
*
|
|
8138
|
+
* ChainDefinition for a supported source chain. Source chains are Ethereum,
|
|
8139
|
+
* Arbitrum, and Base (mainnet and testnet).
|
|
7563
8140
|
*
|
|
7564
8141
|
* @example
|
|
7565
8142
|
* ```typescript
|
|
7566
8143
|
* import { earnBridgeSourceChainIdentifierSchema } from '@core/chains'
|
|
7567
8144
|
*
|
|
7568
8145
|
* // Valid
|
|
8146
|
+
* earnBridgeSourceChainIdentifierSchema.parse('Ethereum')
|
|
7569
8147
|
* earnBridgeSourceChainIdentifierSchema.parse('Ethereum_Sepolia')
|
|
7570
8148
|
*
|
|
7571
8149
|
* // Invalid (throws ZodError)
|
|
@@ -7584,14 +8162,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
|
|
|
7584
8162
|
* deposit.
|
|
7585
8163
|
*
|
|
7586
8164
|
* Accept a supported destination Blockchain value, a matching string literal,
|
|
7587
|
-
* or a ChainDefinition for a supported destination chain.
|
|
7588
|
-
* Testnet
|
|
8165
|
+
* or a ChainDefinition for a supported destination chain. Arc (mainnet) and
|
|
8166
|
+
* Arc Testnet are supported.
|
|
7589
8167
|
*
|
|
7590
8168
|
* @example
|
|
7591
8169
|
* ```typescript
|
|
7592
8170
|
* import { earnBridgeDestinationChainIdentifierSchema } from '@core/chains'
|
|
7593
8171
|
*
|
|
7594
8172
|
* // Valid
|
|
8173
|
+
* earnBridgeDestinationChainIdentifierSchema.parse('Arc')
|
|
7595
8174
|
* earnBridgeDestinationChainIdentifierSchema.parse('Arc_Testnet')
|
|
7596
8175
|
*
|
|
7597
8176
|
* // Invalid (throws ZodError)
|
|
@@ -9217,6 +9796,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9217
9796
|
// Mainnets (alphabetically sorted)
|
|
9218
9797
|
// =========================================================================
|
|
9219
9798
|
[Blockchain.Arbitrum]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
|
9799
|
+
[Blockchain.Arc]: '0x3600000000000000000000000000000000000000',
|
|
9220
9800
|
[Blockchain.Avalanche]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
|
|
9221
9801
|
[Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
9222
9802
|
[Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
|
|
@@ -9331,6 +9911,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9331
9911
|
// =========================================================================
|
|
9332
9912
|
// Mainnets
|
|
9333
9913
|
// =========================================================================
|
|
9914
|
+
[Blockchain.Arc]: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
|
|
9334
9915
|
[Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
|
|
9335
9916
|
[Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
|
|
9336
9917
|
[Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
|
|
@@ -9574,6 +10155,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9574
10155
|
// =========================================================================
|
|
9575
10156
|
// Mainnets
|
|
9576
10157
|
// =========================================================================
|
|
10158
|
+
[Blockchain.Arc]: '0x171A4217b86A807A64eB94757Db6849fb4bDbAA0',
|
|
9577
10159
|
[Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
|
|
9578
10160
|
// =========================================================================
|
|
9579
10161
|
// Testnets
|
|
@@ -9666,13 +10248,28 @@ function parseOrThrow(value, schema, context) {
|
|
|
9666
10248
|
}
|
|
9667
10249
|
|
|
9668
10250
|
/**
|
|
9669
|
-
*
|
|
10251
|
+
* Type guard: narrows a {@link TokenSelector} to a {@link RawTokenSelector}.
|
|
9670
10252
|
*
|
|
9671
10253
|
* @param selector - The token selector to check.
|
|
9672
|
-
* @returns
|
|
10254
|
+
* @returns `true` if `selector` is a raw token selector (object with `locator`).
|
|
10255
|
+
*
|
|
10256
|
+
* @example
|
|
10257
|
+
* ```typescript
|
|
10258
|
+
* if (isRawSelector(selector)) {
|
|
10259
|
+
* console.log(selector.locator)
|
|
10260
|
+
* }
|
|
10261
|
+
* ```
|
|
9673
10262
|
*/ function isRawSelector(selector) {
|
|
9674
|
-
|
|
10263
|
+
// `typeof null === 'object'` (a JS quirk) and `'locator' in null`
|
|
10264
|
+
// throws, so the explicit `null` check is required at this exported
|
|
10265
|
+
// guard for JS consumers passing nullish values. The lint rule sees
|
|
10266
|
+
// the parameter typed as `TokenSelector` (no null) and flags the
|
|
10267
|
+
// check as unnecessary — disabled because the check IS necessary at
|
|
10268
|
+
// runtime even though TypeScript can prove it dead statically.
|
|
10269
|
+
return typeof selector === 'object' && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
10270
|
+
selector !== null && 'locator' in selector;
|
|
9675
10271
|
}
|
|
10272
|
+
|
|
9676
10273
|
/**
|
|
9677
10274
|
* Normalize a symbol to uppercase for case-insensitive lookup.
|
|
9678
10275
|
*
|
|
@@ -9860,7 +10457,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9860
10457
|
if (typeof selector === 'string') {
|
|
9861
10458
|
return resolveSymbol(selector, chainId);
|
|
9862
10459
|
}
|
|
9863
|
-
throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected
|
|
10460
|
+
throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected a token symbol or a raw selector (with locator).`, selector, chainId);
|
|
9864
10461
|
},
|
|
9865
10462
|
resolveByAddress (address, chainId) {
|
|
9866
10463
|
if (!address || typeof address !== 'string') {
|
|
@@ -11120,7 +11717,7 @@ function resolveOptions(options) {
|
|
|
11120
11717
|
}
|
|
11121
11718
|
|
|
11122
11719
|
var name = "@circle-fin/unified-balance-kit";
|
|
11123
|
-
var version$1 = "1.
|
|
11720
|
+
var version$1 = "1.7.0";
|
|
11124
11721
|
var pkg$1 = {
|
|
11125
11722
|
name: name,
|
|
11126
11723
|
version: version$1};
|
|
@@ -21135,10 +21732,26 @@ function toString(amount) {
|
|
|
21135
21732
|
* - Executing the actual bridge operations
|
|
21136
21733
|
* - Handling protocol-specific logic and error conditions
|
|
21137
21734
|
*
|
|
21735
|
+
* @remarks
|
|
21736
|
+
* Token-type default rationale: `TToken` defaults to the literal
|
|
21737
|
+
* `'USDC'` so a USDC-only subclass needs no generic ceremony at every
|
|
21738
|
+
* call site. This matches the literal `'USDC'` default on
|
|
21739
|
+
* {@link BridgeParams} (consumed at the provider boundary, where the
|
|
21740
|
+
* provider knows exactly which token symbol it accepts). The default
|
|
21741
|
+
* matches the default on {@link BridgeResult} and {@link EstimateResult} for
|
|
21742
|
+
* source compatibility. Provider-agnostic kit internals widen those result
|
|
21743
|
+
* types explicitly.
|
|
21744
|
+
*
|
|
21745
|
+
* Quotes are not typed here. A provider that issues one narrows its own
|
|
21746
|
+
* `estimate` return to the shape it produces — see the CCTPx provider's
|
|
21747
|
+
* `QuoteEnvelope` — which keeps that shape in the provider package rather
|
|
21748
|
+
* than in this shared one. `bridge` takes a caller-supplied quote, which is
|
|
21749
|
+
* public input the provider validates before reading a field.
|
|
21750
|
+
*
|
|
21138
21751
|
* @example
|
|
21139
21752
|
* ```typescript
|
|
21140
21753
|
* class CustomBridgingProvider extends BridgingProvider {
|
|
21141
|
-
*
|
|
21754
|
+
* supportsRoute(source: Chain, destination: Chain, token: TokenType): boolean {
|
|
21142
21755
|
* // Implementation specific logic
|
|
21143
21756
|
* return true
|
|
21144
21757
|
* }
|
|
@@ -21187,6 +21800,36 @@ function toString(amount) {
|
|
|
21187
21800
|
return this.supportedChains.filter((chain)=>chain.isTestnet === source.isTestnet && chain.chain !== source.chain);
|
|
21188
21801
|
}
|
|
21189
21802
|
/**
|
|
21803
|
+
* Return the decimal precision for the given token, or `undefined` when
|
|
21804
|
+
* the provider does not track it.
|
|
21805
|
+
*
|
|
21806
|
+
* Consumers that format a result amount resolve decimals through this
|
|
21807
|
+
* hook first, falling back to their own built-in token registry when it
|
|
21808
|
+
* returns `undefined`. The default implementation returns `undefined`,
|
|
21809
|
+
* so a provider whose tokens are already in the consumer's registry needs
|
|
21810
|
+
* no override; a provider that identifies tokens outside that registry
|
|
21811
|
+
* overrides this to supply their decimals.
|
|
21812
|
+
*
|
|
21813
|
+
* @param _token - The token to resolve decimals for (provider-defined);
|
|
21814
|
+
* unused by the default implementation, consumed by overrides.
|
|
21815
|
+
* @param _sourceChain - Source chain of the bridge. Providers whose tokens
|
|
21816
|
+
* live in per-network registries use it to scope the lookup to the relevant
|
|
21817
|
+
* network; unused by the default implementation. Required, so a lookup is
|
|
21818
|
+
* never asked to guess which network a token belongs to.
|
|
21819
|
+
* @returns A promise resolving to the token's decimals, or `undefined`
|
|
21820
|
+
* when the provider cannot resolve it.
|
|
21821
|
+
*
|
|
21822
|
+
* @example
|
|
21823
|
+
* ```typescript
|
|
21824
|
+
* const decimals = await provider.getTokenDecimals(token, source.chain)
|
|
21825
|
+
* if (decimals === undefined) {
|
|
21826
|
+
* // fall back to the consumer's own decimals lookup
|
|
21827
|
+
* }
|
|
21828
|
+
* ```
|
|
21829
|
+
*/ /* 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) {
|
|
21830
|
+
return undefined;
|
|
21831
|
+
}
|
|
21832
|
+
/* eslint-enable @typescript-eslint/require-await, @typescript-eslint/no-unused-vars */ /**
|
|
21190
21833
|
* Register an event dispatcher for handling provider-specific actions and events.
|
|
21191
21834
|
*
|
|
21192
21835
|
*
|
|
@@ -21428,7 +22071,72 @@ var TransferSpeed;
|
|
|
21428
22071
|
*/ recipientAddress: z.string().trim().min(1, 'Fee recipient must be a non-empty string').optional()
|
|
21429
22072
|
}).strict();
|
|
21430
22073
|
/**
|
|
21431
|
-
*
|
|
22074
|
+
* Factory for the bridge-params Zod schema, parameterized by the token
|
|
22075
|
+
* validator. The base schema enforces all non-token fields (amount,
|
|
22076
|
+
* source, destination, config); callers supply the Zod schema for the
|
|
22077
|
+
* `token` field, allowing each provider to validate the token type it
|
|
22078
|
+
* accepts.
|
|
22079
|
+
*
|
|
22080
|
+
* @param tokenSchema - Zod schema applied to the `token` field. Pass
|
|
22081
|
+
* `z.literal('USDC')` for USDC-only validation, or any
|
|
22082
|
+
* provider-specific schema (e.g. a `0x`-prefixed hex regex) for
|
|
22083
|
+
* providers that accept a different token type.
|
|
22084
|
+
* @param config - Required. `maxDecimals` caps the decimal precision
|
|
22085
|
+
* permitted in `amount` and `config.maxFee`. Pass the widest value
|
|
22086
|
+
* any of the provider's tokens require — `6` for USDC-only, `18`
|
|
22087
|
+
* for an ERC-20 family that includes wETH, etc. The schema is a
|
|
22088
|
+
* coarse syntactic gate; narrower per-token precision is enforced
|
|
22089
|
+
* by the provider downstream.
|
|
22090
|
+
* @returns A Zod object schema whose `token` field is validated by
|
|
22091
|
+
* `tokenSchema` and whose other fields (`amount`, `source`,
|
|
22092
|
+
* `destination`, `config`) are validated against the shared bridge
|
|
22093
|
+
* contract. Use `.safeParse` / `.parse` directly, or feed the schema
|
|
22094
|
+
* to {@link parseOrThrow} from `@core/utils` to surface validation
|
|
22095
|
+
* failures as `KitError` with the canonical
|
|
22096
|
+
* `INPUT_VALIDATION_FAILED` code.
|
|
22097
|
+
*
|
|
22098
|
+
* @example
|
|
22099
|
+
* ```typescript
|
|
22100
|
+
* import { createBridgeParamsSchema, z } from '@core/provider'
|
|
22101
|
+
*
|
|
22102
|
+
* const usdcSchema = createBridgeParamsSchema(z.literal('USDC'), { maxDecimals: 6 })
|
|
22103
|
+
* const hexSchema = createBridgeParamsSchema(
|
|
22104
|
+
* z.string().regex(/^0x[0-9a-fA-F]{64}$/),
|
|
22105
|
+
* { maxDecimals: 18 },
|
|
22106
|
+
* )
|
|
22107
|
+
* ```
|
|
22108
|
+
*/ // The full inferred return type of `z.object({...})` here is
|
|
22109
|
+
// effectively impossible to spell out by hand without re-stating every
|
|
22110
|
+
// field's schema. TypeScript infers it from the body — callers receive
|
|
22111
|
+
// a precise Zod schema type via inference, and the explicit-return
|
|
22112
|
+
// rules are disabled for that reason.
|
|
22113
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
|
|
22114
|
+
function createBridgeParamsSchema(tokenSchema, config) {
|
|
22115
|
+
const { maxDecimals } = config;
|
|
22116
|
+
return z.object({
|
|
22117
|
+
amount: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
|
|
22118
|
+
allowZero: false,
|
|
22119
|
+
regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
|
|
22120
|
+
attributeName: 'amount',
|
|
22121
|
+
maxDecimals
|
|
22122
|
+
})(z.string())),
|
|
22123
|
+
source: walletContextSchema,
|
|
22124
|
+
destination: bridgeDestinationSchema,
|
|
22125
|
+
token: tokenSchema,
|
|
22126
|
+
config: z.object({
|
|
22127
|
+
transferSpeed: z.nativeEnum(TransferSpeed).optional(),
|
|
22128
|
+
maxFee: z.string().pipe(createDecimalStringValidator({
|
|
22129
|
+
allowZero: true,
|
|
22130
|
+
regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
|
|
22131
|
+
attributeName: 'maxFee',
|
|
22132
|
+
maxDecimals
|
|
22133
|
+
})(z.string())).optional(),
|
|
22134
|
+
customFee: customFeeSchema.optional()
|
|
22135
|
+
})
|
|
22136
|
+
});
|
|
22137
|
+
}
|
|
22138
|
+
/**
|
|
22139
|
+
* Schema for validating bridge parameters with USDC as the token.
|
|
21432
22140
|
* This ensures all required fields are present and properly typed.
|
|
21433
22141
|
* A bridge must include:
|
|
21434
22142
|
* - A valid amount (non-empty numeric string \> 0)
|
|
@@ -21436,11 +22144,15 @@ var TransferSpeed;
|
|
|
21436
22144
|
* - USDC as the token
|
|
21437
22145
|
* - Optional config with transfer speed and max fee settings
|
|
21438
22146
|
*
|
|
22147
|
+
* Providers that accept a non-USDC token type should call
|
|
22148
|
+
* {@link createBridgeParamsSchema} with their own token schema rather
|
|
22149
|
+
* than reusing this constant.
|
|
22150
|
+
*
|
|
21439
22151
|
* @throws KitError if validation fails
|
|
21440
22152
|
*
|
|
21441
22153
|
* @example
|
|
21442
22154
|
* ```typescript
|
|
21443
|
-
* import {
|
|
22155
|
+
* import { usdcBridgeParamsSchema } from '@core/provider'
|
|
21444
22156
|
*
|
|
21445
22157
|
* const validBridge = {
|
|
21446
22158
|
* amount: '100.50',
|
|
@@ -21465,29 +22177,11 @@ var TransferSpeed;
|
|
|
21465
22177
|
* }
|
|
21466
22178
|
* }
|
|
21467
22179
|
*
|
|
21468
|
-
* const result =
|
|
22180
|
+
* const result = usdcBridgeParamsSchema.safeParse(validBridge)
|
|
21469
22181
|
* console.log(result.success) // true
|
|
21470
22182
|
* ```
|
|
21471
|
-
*/ const
|
|
21472
|
-
|
|
21473
|
-
allowZero: false,
|
|
21474
|
-
regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
|
|
21475
|
-
attributeName: 'amount',
|
|
21476
|
-
maxDecimals: 6
|
|
21477
|
-
})(z.string())),
|
|
21478
|
-
source: walletContextSchema,
|
|
21479
|
-
destination: bridgeDestinationSchema,
|
|
21480
|
-
token: z.literal('USDC'),
|
|
21481
|
-
config: z.object({
|
|
21482
|
-
transferSpeed: z.nativeEnum(TransferSpeed).optional(),
|
|
21483
|
-
maxFee: z.string().pipe(createDecimalStringValidator({
|
|
21484
|
-
allowZero: true,
|
|
21485
|
-
regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
|
|
21486
|
-
attributeName: 'maxFee',
|
|
21487
|
-
maxDecimals: 6
|
|
21488
|
-
})(z.string())).optional(),
|
|
21489
|
-
customFee: customFeeSchema.optional()
|
|
21490
|
-
})
|
|
22183
|
+
*/ const usdcBridgeParamsSchema = createBridgeParamsSchema(z.literal('USDC'), {
|
|
22184
|
+
maxDecimals: 6
|
|
21491
22185
|
});
|
|
21492
22186
|
|
|
21493
22187
|
// ---------------------------------------------------------------------------
|
|
@@ -22081,6 +22775,10 @@ const USDC_DECIMALS$1 = 6;
|
|
|
22081
22775
|
*
|
|
22082
22776
|
* @see {@link https://developers.circle.com/gateway/references/fees}
|
|
22083
22777
|
*/ const GAS_FEE_BY_CHAIN = new Map([
|
|
22778
|
+
[
|
|
22779
|
+
Blockchain.Arc,
|
|
22780
|
+
parseUnits('0.001', USDC_DECIMALS$1)
|
|
22781
|
+
],
|
|
22084
22782
|
[
|
|
22085
22783
|
Blockchain.Arc_Testnet,
|
|
22086
22784
|
parseUnits('0.001', USDC_DECIMALS$1)
|
|
@@ -27446,7 +28144,7 @@ const assertCCTPv2BridgeParamsSymbol = Symbol('assertCCTPv2BridgeParams');
|
|
|
27446
28144
|
* ```
|
|
27447
28145
|
*/ function assertCCTPv2BridgeParams(params) {
|
|
27448
28146
|
// First validate basic bridge params
|
|
27449
|
-
validateWithStateTracking(params,
|
|
28147
|
+
validateWithStateTracking(params, usdcBridgeParamsSchema, 'CCTPv2 bridge parameters', assertCCTPv2BridgeParamsSymbol);
|
|
27450
28148
|
// After validation, we know params is CCTPV2BridgeParams
|
|
27451
28149
|
const bridgeParams = params;
|
|
27452
28150
|
// Enforce that source and destination chains are either testnet or mainnet
|
|
@@ -28313,7 +29011,7 @@ const mockAttestationMessage = {
|
|
|
28313
29011
|
return step;
|
|
28314
29012
|
}
|
|
28315
29013
|
|
|
28316
|
-
var version = "1.
|
|
29014
|
+
var version = "1.14.0";
|
|
28317
29015
|
var pkg = {
|
|
28318
29016
|
version: version};
|
|
28319
29017
|
|
|
@@ -29905,7 +30603,7 @@ function assertCCTPV2Config(config) {
|
|
|
29905
30603
|
* @example
|
|
29906
30604
|
* ```typescript
|
|
29907
30605
|
* const provider = new CCTPV2BridgingProvider()
|
|
29908
|
-
* const canTransfer = provider.supportsRoute(Ethereum, Base)
|
|
30606
|
+
* const canTransfer = provider.supportsRoute(Ethereum, Base, 'USDC')
|
|
29909
30607
|
*
|
|
29910
30608
|
* if (canTransfer) {
|
|
29911
30609
|
* console.log('CCTP v2 transfer is supported between these chains')
|