Skip to content

Commit 678190c

Browse files
authored
fix decoding (#112)
1 parent a40aeb8 commit 678190c

File tree

2 files changed

+123
-28
lines changed

2 files changed

+123
-28
lines changed

ccip/cct/hardhat/tasks/getPoolConfig.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { task } from "hardhat/config";
22
import {
33
Chains,
4-
networks,
54
logger,
65
getEVMNetworkConfig,
7-
configData,
86
} from "../config";
7+
import {
8+
getChainInfoBySelector,
9+
decodeChainAddress,
10+
} from "../utils/chainHandlers";
911

1012
// Define the interface for the task arguments
1113
interface GetPoolConfigArgs {
@@ -81,43 +83,40 @@ task("getPoolConfig", "Get pool configuration")
8183
poolContract.getCurrentInboundRateLimiterState(chainSelector), // Get inbound rate limits
8284
]);
8385

84-
// Try to get a human-readable chain name from the network configuration
85-
const chainName = Object.keys(networks).find(
86-
(key) =>
87-
configData[
88-
key as keyof typeof configData
89-
]?.chainSelector?.toString() === chainSelector.toString()
90-
);
86+
// Get chain information using the utility function
87+
const chainInfo = getChainInfoBySelector(chainSelector);
88+
const chainDisplayName = chainInfo?.name || chainSelector.toString();
9189

92-
// Decode the remote pool addresses from their encoded form
90+
// Decode the remote pool addresses using the utility function
9391
const remotePoolAddresses = remotePools.map((encodedPool) => {
92+
if (!chainInfo) {
93+
return "UNKNOWN_CHAIN";
94+
}
9495
try {
95-
return new hre.ethers.AbiCoder().decode(
96-
["address"],
97-
encodedPool
98-
)[0];
96+
return decodeChainAddress(encodedPool, chainInfo.chainType, hre);
9997
} catch (error) {
100-
return "DECODE_ERROR"; // Return error string if decoding fails
98+
return "DECODE_ERROR";
10199
}
102100
});
103101

104-
// Decode the remote token address from its encoded form
102+
// Decode the remote token address using the utility function
105103
let remoteTokenAddress;
106-
try {
107-
remoteTokenAddress = new hre.ethers.AbiCoder().decode(
108-
["address"],
109-
remoteTokenAddressEncoded
110-
)[0];
111-
} catch (error) {
112-
remoteTokenAddress = "DECODE_ERROR"; // Return error string if decoding fails
104+
if (!chainInfo) {
105+
remoteTokenAddress = "UNKNOWN_CHAIN";
106+
} else {
107+
try {
108+
remoteTokenAddress = decodeChainAddress(
109+
remoteTokenAddressEncoded,
110+
chainInfo.chainType,
111+
hre
112+
);
113+
} catch (error) {
114+
remoteTokenAddress = "DECODE_ERROR";
115+
}
113116
}
114117

115118
// Display the chain-specific configuration
116-
logger.info(
117-
`\nConfiguration for Remote Chain: ${
118-
chainName || chainSelector.toString()
119-
}`
120-
);
119+
logger.info(`\nConfiguration for Remote Chain: ${chainDisplayName}`);
121120

122121
// Display all remote pool addresses for this chain
123122
logger.info(` Remote Pool Addresses:`);

ccip/cct/hardhat/utils/chainHandlers.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { CHAIN_TYPE } from "../config/types";
22
import bs58 from "bs58";
33
import type { HardhatRuntimeEnvironment } from "hardhat/types";
4+
import { configData } from "../config";
45

56
/**
67
* Error thrown when an invalid address is provided for a specific chain type
@@ -228,3 +229,98 @@ export function convertChainAddressToHex(
228229
export function isValidChainType(chainType: string): chainType is CHAIN_TYPE {
229230
return chainType === "evm" || chainType === "svm";
230231
}
232+
233+
/**
234+
* Interface for chain configuration lookup result
235+
*/
236+
export interface ChainInfo {
237+
name: string;
238+
chainType: CHAIN_TYPE;
239+
chainSelector: string;
240+
config: any;
241+
}
242+
243+
/**
244+
* Looks up chain information by chain selector
245+
* @param chainSelector - The chain selector to look up
246+
* @returns Chain information or undefined if not found
247+
*/
248+
export function getChainInfoBySelector(
249+
chainSelector: string | bigint
250+
): ChainInfo | undefined {
251+
const selectorString = chainSelector.toString();
252+
253+
const chainName = Object.keys(configData).find(
254+
(key) =>
255+
configData[key as keyof typeof configData]?.chainSelector?.toString() ===
256+
selectorString
257+
);
258+
259+
if (!chainName) {
260+
return undefined;
261+
}
262+
263+
const config = configData[chainName as keyof typeof configData];
264+
const chainType = config.chainType as CHAIN_TYPE;
265+
266+
return {
267+
name: chainName,
268+
chainType,
269+
chainSelector: selectorString,
270+
config,
271+
};
272+
}
273+
274+
/**
275+
* Decodes an encoded address based on the chain type
276+
* @param encodedAddress - The encoded address data
277+
* @param chainType - The chain type (evm or svm)
278+
* @param hre - Hardhat runtime environment (optional, required for EVM)
279+
* @returns The decoded address string
280+
* @throws Error if decoding fails
281+
*/
282+
export function decodeChainAddress(
283+
encodedAddress: string,
284+
chainType: CHAIN_TYPE,
285+
hre?: HardhatRuntimeEnvironment
286+
): string {
287+
if (chainType === "svm") {
288+
// For Solana, the encoded address is a hex string (32 bytes)
289+
const hexString = encodedAddress.startsWith("0x")
290+
? encodedAddress.slice(2)
291+
: encodedAddress;
292+
const bytes = Buffer.from(hexString, "hex");
293+
return bs58.encode(bytes);
294+
} else if (chainType === "evm") {
295+
if (!hre) {
296+
throw new Error("HardhatRuntimeEnvironment is required for EVM address decoding");
297+
}
298+
// For EVM chains, use AbiCoder
299+
return new hre.ethers.AbiCoder().decode(["address"], encodedAddress)[0];
300+
} else {
301+
throw new UnsupportedChainTypeError(chainType);
302+
}
303+
}
304+
305+
/**
306+
* Decodes an address by first looking up the chain type from the selector
307+
* @param encodedAddress - The encoded address data
308+
* @param chainSelector - The chain selector
309+
* @param hre - Hardhat runtime environment
310+
* @returns The decoded address string or "UNKNOWN_CHAIN" if chain not found
311+
*/
312+
export function decodeAddressByChainSelector(
313+
encodedAddress: string,
314+
chainSelector: string | bigint,
315+
hre: HardhatRuntimeEnvironment
316+
): string {
317+
try {
318+
const chainInfo = getChainInfoBySelector(chainSelector);
319+
if (!chainInfo) {
320+
return "UNKNOWN_CHAIN";
321+
}
322+
return decodeChainAddress(encodedAddress, chainInfo.chainType, hre);
323+
} catch (error) {
324+
return "DECODE_ERROR";
325+
}
326+
}

0 commit comments

Comments
 (0)