@circle-fin/app-kit 1.5.0 → 1.5.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 +6 -0
- package/index.cjs +156 -13
- package/index.mjs +156 -13
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @circle-fin/app-kit
|
|
2
2
|
|
|
3
|
+
## 1.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Improves the error you get when attempting a Gateway spend with a smart-contract account (SCA) as the signer. The failure previously surfaced as a confusing `invalid integer value <nil>/<nil> for type uint256` response from the Circle Wallets backend; you now get a clear `INPUT_UNSUPPORTED_ACTION` error up front that points at the delegate workflow (`kit.unifiedBalance.addDelegate` + `kit.unifiedBalance.spend` with the delegate EOA as `from.address` and the SCA as `from.sourceAccount`).
|
|
8
|
+
|
|
3
9
|
## 1.5.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/index.cjs
CHANGED
|
@@ -15750,7 +15750,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCo
|
|
|
15750
15750
|
return step;
|
|
15751
15751
|
}
|
|
15752
15752
|
|
|
15753
|
-
var version$2 = "1.8.
|
|
15753
|
+
var version$2 = "1.8.1";
|
|
15754
15754
|
var pkg$2 = {
|
|
15755
15755
|
version: version$2};
|
|
15756
15756
|
|
|
@@ -18149,7 +18149,7 @@ const createBridgeKit = (context) => {
|
|
|
18149
18149
|
};
|
|
18150
18150
|
|
|
18151
18151
|
var name$1 = "@circle-fin/swap-kit";
|
|
18152
|
-
var version$1 = "1.2.
|
|
18152
|
+
var version$1 = "1.2.1";
|
|
18153
18153
|
var pkg$1 = {
|
|
18154
18154
|
name: name$1,
|
|
18155
18155
|
version: version$1};
|
|
@@ -22029,6 +22029,119 @@ function evmSigningData(burnIntent) {
|
|
|
22029
22029
|
};
|
|
22030
22030
|
}
|
|
22031
22031
|
|
|
22032
|
+
/**
|
|
22033
|
+
* EIP-7702 delegation indicator. A 7702-delegated EOA's bytecode is
|
|
22034
|
+
* `0xef0100` followed by the 20-byte delegate address (23 bytes total).
|
|
22035
|
+
* The underlying secp256k1 key still produces `ecrecover`-verifiable
|
|
22036
|
+
* signatures, so for Gateway's purposes a 7702-delegated address is
|
|
22037
|
+
* an EOA, not an SCA.
|
|
22038
|
+
*
|
|
22039
|
+
* Spec: https://eips.ethereum.org/EIPS/eip-7702
|
|
22040
|
+
*/
|
|
22041
|
+
const EIP_7702_DELEGATION_PREFIX = '0xef0100';
|
|
22042
|
+
/**
|
|
22043
|
+
* Assert that `address` on `chain` can sign Gateway burn intents.
|
|
22044
|
+
*
|
|
22045
|
+
* Gateway verifies burn-intent signatures with plain `ecrecover` (see
|
|
22046
|
+
* `evm-gateway-contracts/src/lib/EIP712Domain.sol`). Smart-contract
|
|
22047
|
+
* accounts (SCAs) produce signatures over wrapped hashes (ERC-1271 /
|
|
22048
|
+
* ERC-6492 / ERC-6900 replay-safe hashes) that Gateway cannot verify.
|
|
22049
|
+
* Additionally, the Circle Wallets backend rejects SCA typed-data signing
|
|
22050
|
+
* against Gateway's chainId-less domain with an opaque
|
|
22051
|
+
* `invalid integer value <nil>/<nil> for type uint256` error.
|
|
22052
|
+
*
|
|
22053
|
+
* EIP-7702-delegated EOAs are exempt: they expose non-empty bytecode
|
|
22054
|
+
* (`0xef0100<delegate>`) but the underlying secp256k1 key still produces
|
|
22055
|
+
* `ecrecover`-verifiable signatures, so Gateway accepts them.
|
|
22056
|
+
*
|
|
22057
|
+
* When the signer is a true SCA, raises an `INPUT_UNSUPPORTED_ACTION`
|
|
22058
|
+
* error directing the caller to register an EOA delegate against the
|
|
22059
|
+
* SCA and then submit the spend with the delegate EOA as the signer
|
|
22060
|
+
* and the SCA as the source account. See the unified-balance / Gateway
|
|
22061
|
+
* docs for the exact API.
|
|
22062
|
+
*
|
|
22063
|
+
* If bytecode cannot be read (RPC failure, etc.) the pre-check is
|
|
22064
|
+
* skipped and downstream signing surfaces its own error — a warning is
|
|
22065
|
+
* logged so the skip is diagnosable.
|
|
22066
|
+
*
|
|
22067
|
+
* @param adapter - Anything exposing {@link EvmAdapterLike.readBytecode}.
|
|
22068
|
+
* @param address - Signer address to validate.
|
|
22069
|
+
* @param chain - EVM chain where the signer lives.
|
|
22070
|
+
* @throws {KitError} INPUT_UNSUPPORTED_ACTION when `address` is an SCA.
|
|
22071
|
+
*
|
|
22072
|
+
* @example
|
|
22073
|
+
* ```typescript
|
|
22074
|
+
* import { assertSignerIsEoa } from '@core/adapter-evm'
|
|
22075
|
+
* import { Ethereum } from '@core/chains'
|
|
22076
|
+
*
|
|
22077
|
+
* await assertSignerIsEoa(adapter, '0xabc...', Ethereum)
|
|
22078
|
+
* ```
|
|
22079
|
+
*/
|
|
22080
|
+
async function assertSignerIsEoa(adapter, address, chain) {
|
|
22081
|
+
let code;
|
|
22082
|
+
try {
|
|
22083
|
+
code = await adapter.readBytecode(address, chain);
|
|
22084
|
+
}
|
|
22085
|
+
catch (err) {
|
|
22086
|
+
console.warn(`[gateway] assertSignerIsEoa skipped (readBytecode failed for ` +
|
|
22087
|
+
`${address} on ${chain.name}): ` +
|
|
22088
|
+
(err instanceof Error ? err.message : String(err)));
|
|
22089
|
+
return;
|
|
22090
|
+
}
|
|
22091
|
+
if (code === undefined ||
|
|
22092
|
+
code === '0x' ||
|
|
22093
|
+
code.toLowerCase().startsWith(EIP_7702_DELEGATION_PREFIX)) {
|
|
22094
|
+
return;
|
|
22095
|
+
}
|
|
22096
|
+
throw new KitError({
|
|
22097
|
+
...InputError.UNSUPPORTED_ACTION,
|
|
22098
|
+
recoverability: 'FATAL',
|
|
22099
|
+
message: `Gateway burn-intent signing requires an EOA signer (Gateway ` +
|
|
22100
|
+
`verifies signatures with ecrecover and does not support ERC-1271). ` +
|
|
22101
|
+
`The signer ${address} on ${chain.name} has on-chain bytecode, ` +
|
|
22102
|
+
`indicating it is a smart-contract account (SCA). Register an EOA ` +
|
|
22103
|
+
`delegate against the SCA, then submit the spend with the delegate ` +
|
|
22104
|
+
`EOA as the signer and the SCA as the source account. See DEVX-2774.`,
|
|
22105
|
+
cause: {
|
|
22106
|
+
trace: {
|
|
22107
|
+
operation: 'signEvmIntentGroup.assertSignerIsEoa',
|
|
22108
|
+
address,
|
|
22109
|
+
chain: chain.name,
|
|
22110
|
+
bytecodeBytes: (code.length - 2) / 2,
|
|
22111
|
+
bytecodePrefix: code.slice(0, 12),
|
|
22112
|
+
},
|
|
22113
|
+
},
|
|
22114
|
+
});
|
|
22115
|
+
}
|
|
22116
|
+
|
|
22117
|
+
/**
|
|
22118
|
+
* Duck-type test for an EVM adapter that exposes `readBytecode`.
|
|
22119
|
+
*
|
|
22120
|
+
* Used as a structural guard at package boundaries (e.g. the Circle Wallets
|
|
22121
|
+
* hybrid adapter calling into a chain adapter, or the Gateway sign path
|
|
22122
|
+
* receiving an arbitrary adapter implementation) where `instanceof EvmAdapter`
|
|
22123
|
+
* is unreliable because each consumer bundles its own copy of the base class.
|
|
22124
|
+
*
|
|
22125
|
+
* @param value - The value to test.
|
|
22126
|
+
* @returns `true` when `value` is an object exposing a callable
|
|
22127
|
+
* `readBytecode` method, narrowed to {@link EvmAdapterLike}.
|
|
22128
|
+
*
|
|
22129
|
+
* @example
|
|
22130
|
+
* ```typescript
|
|
22131
|
+
* import { isEvmAdapterLike } from '@core/adapter-evm'
|
|
22132
|
+
*
|
|
22133
|
+
* if (isEvmAdapterLike(adapter)) {
|
|
22134
|
+
* const code = await adapter.readBytecode('0xabc...', chain)
|
|
22135
|
+
* }
|
|
22136
|
+
* ```
|
|
22137
|
+
*/
|
|
22138
|
+
function isEvmAdapterLike(value) {
|
|
22139
|
+
return (typeof value === 'object' &&
|
|
22140
|
+
value !== null &&
|
|
22141
|
+
'readBytecode' in value &&
|
|
22142
|
+
typeof value.readBytecode === 'function');
|
|
22143
|
+
}
|
|
22144
|
+
|
|
22032
22145
|
/**
|
|
22033
22146
|
* Sign an EVM adapter group: batches all intents and produces a single
|
|
22034
22147
|
* EIP-712 ECDSA signature.
|
|
@@ -22036,6 +22149,12 @@ function evmSigningData(burnIntent) {
|
|
|
22036
22149
|
* For a single-intent group, `primaryType` is `'BurnIntent'`.
|
|
22037
22150
|
* For multi-intent groups, `primaryType` is `'BurnIntentSet'`.
|
|
22038
22151
|
*
|
|
22152
|
+
* Before signing, asserts that the signer address is an EOA. Gateway
|
|
22153
|
+
* verifies burn-intent signatures with plain `ecrecover` (no ERC-1271
|
|
22154
|
+
* fallback), so signatures produced by smart-contract accounts (SCAs)
|
|
22155
|
+
* cannot be verified. When an SCA is detected, a clear error is raised
|
|
22156
|
+
* directing the caller to the delegate workflow (DEVX-2774).
|
|
22157
|
+
*
|
|
22039
22158
|
* @param group - The adapter group containing the adapter, chain, and
|
|
22040
22159
|
* burn intents to sign.
|
|
22041
22160
|
* @returns A signed set with the intents and the ECDSA signature.
|
|
@@ -22056,6 +22175,22 @@ function evmSigningData(burnIntent) {
|
|
|
22056
22175
|
async function signEvmIntentGroup(group) {
|
|
22057
22176
|
const { adapter, intents: groupIntents, chain, address } = group;
|
|
22058
22177
|
const operationContext = address === undefined ? { chain } : { chain, address };
|
|
22178
|
+
// Gateway verifies burn-intent signatures with plain ecrecover. An SCA
|
|
22179
|
+
// signer silently produces a signature over a wrapped hash that Gateway
|
|
22180
|
+
// cannot verify, and Circle Wallets' KMS rejects the typed data up front
|
|
22181
|
+
// with an opaque `<nil>/<nil>` error. Short-circuit with a clear message
|
|
22182
|
+
// when we can detect bytecode at the signer address. See DEVX-2774.
|
|
22183
|
+
//
|
|
22184
|
+
// Duck-typed on readBytecode rather than `instanceof EvmAdapter` because
|
|
22185
|
+
// each consumer package bundles its own copy of the base class and the
|
|
22186
|
+
// `instanceof` identity check fails across package boundaries.
|
|
22187
|
+
//
|
|
22188
|
+
// Empty string is defended against because assertSignerIsEoa would
|
|
22189
|
+
// otherwise call eth_getCode('') on the RPC.
|
|
22190
|
+
const hasResolvedSigner = typeof address === 'string' && address.length > 0;
|
|
22191
|
+
if (hasResolvedSigner && chain.type === 'evm' && isEvmAdapterLike(adapter)) {
|
|
22192
|
+
await assertSignerIsEoa(adapter, address, chain);
|
|
22193
|
+
}
|
|
22059
22194
|
const firstIntent = groupIntents[0];
|
|
22060
22195
|
const typedData = groupIntents.length === 1 && firstIntent
|
|
22061
22196
|
? evmSigningData(firstIntent)
|
|
@@ -22325,9 +22460,10 @@ function getSolanaFeeRecipient() {
|
|
|
22325
22460
|
return CIRCLE_FEE_RECIPIENT_SOLANA;
|
|
22326
22461
|
}
|
|
22327
22462
|
|
|
22328
|
-
|
|
22329
|
-
|
|
22330
|
-
|
|
22463
|
+
const enc = new TextEncoder();
|
|
22464
|
+
enc.encode('gateway_minter');
|
|
22465
|
+
enc.encode('gateway_minter_custody');
|
|
22466
|
+
enc.encode('used_transfer_spec_hash');
|
|
22331
22467
|
|
|
22332
22468
|
async function executeAndWait$1(adapter, request, chain) {
|
|
22333
22469
|
if (request.type === 'noop') {
|
|
@@ -30002,7 +30138,7 @@ const getSupportedChains$2 = (context, operationType, unifiedBalance) => {
|
|
|
30002
30138
|
};
|
|
30003
30139
|
|
|
30004
30140
|
var name = "@circle-fin/unified-balance-kit";
|
|
30005
|
-
var version = "1.1.
|
|
30141
|
+
var version = "1.1.1";
|
|
30006
30142
|
var pkg = {
|
|
30007
30143
|
name: name,
|
|
30008
30144
|
version: version};
|
|
@@ -33307,13 +33443,20 @@ async function resolveAllocationsAndIntents(params, destChain, recipientAddress,
|
|
|
33307
33443
|
const sourcesArray = rawSources.filter((s) => s != null);
|
|
33308
33444
|
const networkType = destChain.isTestnet ? 'testnet' : 'mainnet';
|
|
33309
33445
|
const balanceResults = await Promise.all(sourcesArray.map(async (source) => {
|
|
33310
|
-
|
|
33311
|
-
|
|
33312
|
-
|
|
33313
|
-
|
|
33314
|
-
|
|
33315
|
-
|
|
33316
|
-
|
|
33446
|
+
// When sourceAccount is set (delegate flow), scope the balance
|
|
33447
|
+
// query to the Gateway depositor — not the signer. Using the
|
|
33448
|
+
// address-only path bypasses adapter address resolution, which
|
|
33449
|
+
// would otherwise return the signer's balance (developer-
|
|
33450
|
+
// controlled) or reject an explicit address (user-controlled).
|
|
33451
|
+
let querySource;
|
|
33452
|
+
if (source.sourceAccount) {
|
|
33453
|
+
querySource = { address: source.sourceAccount };
|
|
33454
|
+
}
|
|
33455
|
+
else {
|
|
33456
|
+
querySource = { adapter: source.adapter };
|
|
33457
|
+
if ('address' in source && source.address) {
|
|
33458
|
+
querySource['address'] = source.address;
|
|
33459
|
+
}
|
|
33317
33460
|
}
|
|
33318
33461
|
return getBalances$1({
|
|
33319
33462
|
token: params.token,
|
package/index.mjs
CHANGED
|
@@ -15743,7 +15743,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCo
|
|
|
15743
15743
|
return step;
|
|
15744
15744
|
}
|
|
15745
15745
|
|
|
15746
|
-
var version$2 = "1.8.
|
|
15746
|
+
var version$2 = "1.8.1";
|
|
15747
15747
|
var pkg$2 = {
|
|
15748
15748
|
version: version$2};
|
|
15749
15749
|
|
|
@@ -18142,7 +18142,7 @@ const createBridgeKit = (context) => {
|
|
|
18142
18142
|
};
|
|
18143
18143
|
|
|
18144
18144
|
var name$1 = "@circle-fin/swap-kit";
|
|
18145
|
-
var version$1 = "1.2.
|
|
18145
|
+
var version$1 = "1.2.1";
|
|
18146
18146
|
var pkg$1 = {
|
|
18147
18147
|
name: name$1,
|
|
18148
18148
|
version: version$1};
|
|
@@ -22022,6 +22022,119 @@ function evmSigningData(burnIntent) {
|
|
|
22022
22022
|
};
|
|
22023
22023
|
}
|
|
22024
22024
|
|
|
22025
|
+
/**
|
|
22026
|
+
* EIP-7702 delegation indicator. A 7702-delegated EOA's bytecode is
|
|
22027
|
+
* `0xef0100` followed by the 20-byte delegate address (23 bytes total).
|
|
22028
|
+
* The underlying secp256k1 key still produces `ecrecover`-verifiable
|
|
22029
|
+
* signatures, so for Gateway's purposes a 7702-delegated address is
|
|
22030
|
+
* an EOA, not an SCA.
|
|
22031
|
+
*
|
|
22032
|
+
* Spec: https://eips.ethereum.org/EIPS/eip-7702
|
|
22033
|
+
*/
|
|
22034
|
+
const EIP_7702_DELEGATION_PREFIX = '0xef0100';
|
|
22035
|
+
/**
|
|
22036
|
+
* Assert that `address` on `chain` can sign Gateway burn intents.
|
|
22037
|
+
*
|
|
22038
|
+
* Gateway verifies burn-intent signatures with plain `ecrecover` (see
|
|
22039
|
+
* `evm-gateway-contracts/src/lib/EIP712Domain.sol`). Smart-contract
|
|
22040
|
+
* accounts (SCAs) produce signatures over wrapped hashes (ERC-1271 /
|
|
22041
|
+
* ERC-6492 / ERC-6900 replay-safe hashes) that Gateway cannot verify.
|
|
22042
|
+
* Additionally, the Circle Wallets backend rejects SCA typed-data signing
|
|
22043
|
+
* against Gateway's chainId-less domain with an opaque
|
|
22044
|
+
* `invalid integer value <nil>/<nil> for type uint256` error.
|
|
22045
|
+
*
|
|
22046
|
+
* EIP-7702-delegated EOAs are exempt: they expose non-empty bytecode
|
|
22047
|
+
* (`0xef0100<delegate>`) but the underlying secp256k1 key still produces
|
|
22048
|
+
* `ecrecover`-verifiable signatures, so Gateway accepts them.
|
|
22049
|
+
*
|
|
22050
|
+
* When the signer is a true SCA, raises an `INPUT_UNSUPPORTED_ACTION`
|
|
22051
|
+
* error directing the caller to register an EOA delegate against the
|
|
22052
|
+
* SCA and then submit the spend with the delegate EOA as the signer
|
|
22053
|
+
* and the SCA as the source account. See the unified-balance / Gateway
|
|
22054
|
+
* docs for the exact API.
|
|
22055
|
+
*
|
|
22056
|
+
* If bytecode cannot be read (RPC failure, etc.) the pre-check is
|
|
22057
|
+
* skipped and downstream signing surfaces its own error — a warning is
|
|
22058
|
+
* logged so the skip is diagnosable.
|
|
22059
|
+
*
|
|
22060
|
+
* @param adapter - Anything exposing {@link EvmAdapterLike.readBytecode}.
|
|
22061
|
+
* @param address - Signer address to validate.
|
|
22062
|
+
* @param chain - EVM chain where the signer lives.
|
|
22063
|
+
* @throws {KitError} INPUT_UNSUPPORTED_ACTION when `address` is an SCA.
|
|
22064
|
+
*
|
|
22065
|
+
* @example
|
|
22066
|
+
* ```typescript
|
|
22067
|
+
* import { assertSignerIsEoa } from '@core/adapter-evm'
|
|
22068
|
+
* import { Ethereum } from '@core/chains'
|
|
22069
|
+
*
|
|
22070
|
+
* await assertSignerIsEoa(adapter, '0xabc...', Ethereum)
|
|
22071
|
+
* ```
|
|
22072
|
+
*/
|
|
22073
|
+
async function assertSignerIsEoa(adapter, address, chain) {
|
|
22074
|
+
let code;
|
|
22075
|
+
try {
|
|
22076
|
+
code = await adapter.readBytecode(address, chain);
|
|
22077
|
+
}
|
|
22078
|
+
catch (err) {
|
|
22079
|
+
console.warn(`[gateway] assertSignerIsEoa skipped (readBytecode failed for ` +
|
|
22080
|
+
`${address} on ${chain.name}): ` +
|
|
22081
|
+
(err instanceof Error ? err.message : String(err)));
|
|
22082
|
+
return;
|
|
22083
|
+
}
|
|
22084
|
+
if (code === undefined ||
|
|
22085
|
+
code === '0x' ||
|
|
22086
|
+
code.toLowerCase().startsWith(EIP_7702_DELEGATION_PREFIX)) {
|
|
22087
|
+
return;
|
|
22088
|
+
}
|
|
22089
|
+
throw new KitError({
|
|
22090
|
+
...InputError.UNSUPPORTED_ACTION,
|
|
22091
|
+
recoverability: 'FATAL',
|
|
22092
|
+
message: `Gateway burn-intent signing requires an EOA signer (Gateway ` +
|
|
22093
|
+
`verifies signatures with ecrecover and does not support ERC-1271). ` +
|
|
22094
|
+
`The signer ${address} on ${chain.name} has on-chain bytecode, ` +
|
|
22095
|
+
`indicating it is a smart-contract account (SCA). Register an EOA ` +
|
|
22096
|
+
`delegate against the SCA, then submit the spend with the delegate ` +
|
|
22097
|
+
`EOA as the signer and the SCA as the source account. See DEVX-2774.`,
|
|
22098
|
+
cause: {
|
|
22099
|
+
trace: {
|
|
22100
|
+
operation: 'signEvmIntentGroup.assertSignerIsEoa',
|
|
22101
|
+
address,
|
|
22102
|
+
chain: chain.name,
|
|
22103
|
+
bytecodeBytes: (code.length - 2) / 2,
|
|
22104
|
+
bytecodePrefix: code.slice(0, 12),
|
|
22105
|
+
},
|
|
22106
|
+
},
|
|
22107
|
+
});
|
|
22108
|
+
}
|
|
22109
|
+
|
|
22110
|
+
/**
|
|
22111
|
+
* Duck-type test for an EVM adapter that exposes `readBytecode`.
|
|
22112
|
+
*
|
|
22113
|
+
* Used as a structural guard at package boundaries (e.g. the Circle Wallets
|
|
22114
|
+
* hybrid adapter calling into a chain adapter, or the Gateway sign path
|
|
22115
|
+
* receiving an arbitrary adapter implementation) where `instanceof EvmAdapter`
|
|
22116
|
+
* is unreliable because each consumer bundles its own copy of the base class.
|
|
22117
|
+
*
|
|
22118
|
+
* @param value - The value to test.
|
|
22119
|
+
* @returns `true` when `value` is an object exposing a callable
|
|
22120
|
+
* `readBytecode` method, narrowed to {@link EvmAdapterLike}.
|
|
22121
|
+
*
|
|
22122
|
+
* @example
|
|
22123
|
+
* ```typescript
|
|
22124
|
+
* import { isEvmAdapterLike } from '@core/adapter-evm'
|
|
22125
|
+
*
|
|
22126
|
+
* if (isEvmAdapterLike(adapter)) {
|
|
22127
|
+
* const code = await adapter.readBytecode('0xabc...', chain)
|
|
22128
|
+
* }
|
|
22129
|
+
* ```
|
|
22130
|
+
*/
|
|
22131
|
+
function isEvmAdapterLike(value) {
|
|
22132
|
+
return (typeof value === 'object' &&
|
|
22133
|
+
value !== null &&
|
|
22134
|
+
'readBytecode' in value &&
|
|
22135
|
+
typeof value.readBytecode === 'function');
|
|
22136
|
+
}
|
|
22137
|
+
|
|
22025
22138
|
/**
|
|
22026
22139
|
* Sign an EVM adapter group: batches all intents and produces a single
|
|
22027
22140
|
* EIP-712 ECDSA signature.
|
|
@@ -22029,6 +22142,12 @@ function evmSigningData(burnIntent) {
|
|
|
22029
22142
|
* For a single-intent group, `primaryType` is `'BurnIntent'`.
|
|
22030
22143
|
* For multi-intent groups, `primaryType` is `'BurnIntentSet'`.
|
|
22031
22144
|
*
|
|
22145
|
+
* Before signing, asserts that the signer address is an EOA. Gateway
|
|
22146
|
+
* verifies burn-intent signatures with plain `ecrecover` (no ERC-1271
|
|
22147
|
+
* fallback), so signatures produced by smart-contract accounts (SCAs)
|
|
22148
|
+
* cannot be verified. When an SCA is detected, a clear error is raised
|
|
22149
|
+
* directing the caller to the delegate workflow (DEVX-2774).
|
|
22150
|
+
*
|
|
22032
22151
|
* @param group - The adapter group containing the adapter, chain, and
|
|
22033
22152
|
* burn intents to sign.
|
|
22034
22153
|
* @returns A signed set with the intents and the ECDSA signature.
|
|
@@ -22049,6 +22168,22 @@ function evmSigningData(burnIntent) {
|
|
|
22049
22168
|
async function signEvmIntentGroup(group) {
|
|
22050
22169
|
const { adapter, intents: groupIntents, chain, address } = group;
|
|
22051
22170
|
const operationContext = address === undefined ? { chain } : { chain, address };
|
|
22171
|
+
// Gateway verifies burn-intent signatures with plain ecrecover. An SCA
|
|
22172
|
+
// signer silently produces a signature over a wrapped hash that Gateway
|
|
22173
|
+
// cannot verify, and Circle Wallets' KMS rejects the typed data up front
|
|
22174
|
+
// with an opaque `<nil>/<nil>` error. Short-circuit with a clear message
|
|
22175
|
+
// when we can detect bytecode at the signer address. See DEVX-2774.
|
|
22176
|
+
//
|
|
22177
|
+
// Duck-typed on readBytecode rather than `instanceof EvmAdapter` because
|
|
22178
|
+
// each consumer package bundles its own copy of the base class and the
|
|
22179
|
+
// `instanceof` identity check fails across package boundaries.
|
|
22180
|
+
//
|
|
22181
|
+
// Empty string is defended against because assertSignerIsEoa would
|
|
22182
|
+
// otherwise call eth_getCode('') on the RPC.
|
|
22183
|
+
const hasResolvedSigner = typeof address === 'string' && address.length > 0;
|
|
22184
|
+
if (hasResolvedSigner && chain.type === 'evm' && isEvmAdapterLike(adapter)) {
|
|
22185
|
+
await assertSignerIsEoa(adapter, address, chain);
|
|
22186
|
+
}
|
|
22052
22187
|
const firstIntent = groupIntents[0];
|
|
22053
22188
|
const typedData = groupIntents.length === 1 && firstIntent
|
|
22054
22189
|
? evmSigningData(firstIntent)
|
|
@@ -22318,9 +22453,10 @@ function getSolanaFeeRecipient() {
|
|
|
22318
22453
|
return CIRCLE_FEE_RECIPIENT_SOLANA;
|
|
22319
22454
|
}
|
|
22320
22455
|
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
|
|
22456
|
+
const enc = new TextEncoder();
|
|
22457
|
+
enc.encode('gateway_minter');
|
|
22458
|
+
enc.encode('gateway_minter_custody');
|
|
22459
|
+
enc.encode('used_transfer_spec_hash');
|
|
22324
22460
|
|
|
22325
22461
|
async function executeAndWait$1(adapter, request, chain) {
|
|
22326
22462
|
if (request.type === 'noop') {
|
|
@@ -29995,7 +30131,7 @@ const getSupportedChains$2 = (context, operationType, unifiedBalance) => {
|
|
|
29995
30131
|
};
|
|
29996
30132
|
|
|
29997
30133
|
var name = "@circle-fin/unified-balance-kit";
|
|
29998
|
-
var version = "1.1.
|
|
30134
|
+
var version = "1.1.1";
|
|
29999
30135
|
var pkg = {
|
|
30000
30136
|
name: name,
|
|
30001
30137
|
version: version};
|
|
@@ -33300,13 +33436,20 @@ async function resolveAllocationsAndIntents(params, destChain, recipientAddress,
|
|
|
33300
33436
|
const sourcesArray = rawSources.filter((s) => s != null);
|
|
33301
33437
|
const networkType = destChain.isTestnet ? 'testnet' : 'mainnet';
|
|
33302
33438
|
const balanceResults = await Promise.all(sourcesArray.map(async (source) => {
|
|
33303
|
-
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
|
|
33308
|
-
|
|
33309
|
-
|
|
33439
|
+
// When sourceAccount is set (delegate flow), scope the balance
|
|
33440
|
+
// query to the Gateway depositor — not the signer. Using the
|
|
33441
|
+
// address-only path bypasses adapter address resolution, which
|
|
33442
|
+
// would otherwise return the signer's balance (developer-
|
|
33443
|
+
// controlled) or reject an explicit address (user-controlled).
|
|
33444
|
+
let querySource;
|
|
33445
|
+
if (source.sourceAccount) {
|
|
33446
|
+
querySource = { address: source.sourceAccount };
|
|
33447
|
+
}
|
|
33448
|
+
else {
|
|
33449
|
+
querySource = { adapter: source.adapter };
|
|
33450
|
+
if ('address' in source && source.address) {
|
|
33451
|
+
querySource['address'] = source.address;
|
|
33452
|
+
}
|
|
33310
33453
|
}
|
|
33311
33454
|
return getBalances$1({
|
|
33312
33455
|
token: params.token,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@circle-fin/app-kit",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "A one-stop Circle SDK solution for building stablecoin (e.g. USDC) applications, with bridging, swapping, and more on-chain operations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"circle",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"module": "./index.mjs",
|
|
37
37
|
"types": "./index.d.ts",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@circle-fin/unified-balance-kit": "1.1.
|
|
40
|
-
"@circle-fin/provider-gateway-v1": "1.0.
|
|
39
|
+
"@circle-fin/unified-balance-kit": "1.1.1",
|
|
40
|
+
"@circle-fin/provider-gateway-v1": "1.0.4",
|
|
41
41
|
"@circle-fin/bridge-kit": "1.10.0",
|
|
42
|
-
"@circle-fin/swap-kit": "1.2.
|
|
42
|
+
"@circle-fin/swap-kit": "1.2.1",
|
|
43
43
|
"zod": "3.25.67",
|
|
44
44
|
"@ethersproject/address": "^5.8.0",
|
|
45
45
|
"@ethersproject/bytes": "^5.8.0",
|