diff --git a/modules/sdk-coin-evm/src/lib/utils.ts b/modules/sdk-coin-evm/src/lib/utils.ts index 7c29280e42..ff934e9861 100644 --- a/modules/sdk-coin-evm/src/lib/utils.ts +++ b/modules/sdk-coin-evm/src/lib/utils.ts @@ -223,3 +223,52 @@ async function getGasLimitFromRPC(query: Record, rpcUrl: string) return response.body; } + +export function validateHederaAccountId(address: string): { valid: boolean; error: string | null } { + const parts = address.split('.'); + if (parts.length !== 3) { + return { + valid: false, + error: 'Invalid Hedera Account ID format. Use format: 0.0.12345', + }; + } + const [shardStr, realmStr, accountStr] = parts; + if (!shardStr || !realmStr || !accountStr) { + return { + valid: false, + error: 'Invalid Hedera Account ID. All parts are required.', + }; + } + + const shard = Number(shardStr); + const realm = Number(realmStr); + const account = Number(accountStr); + + // Validate all parts are valid non-negative integers within safe range + if ( + !Number.isInteger(shard) || + !Number.isInteger(realm) || + !Number.isInteger(account) || + shard < 0 || + realm < 0 || + account < 0 + ) { + return { + valid: false, + error: 'Invalid Hedera Account ID. All parts must be non-negative integers.', + }; + } + + // Check for JavaScript safe integer limits (prevents precision loss) + if (!Number.isSafeInteger(shard) || !Number.isSafeInteger(realm) || !Number.isSafeInteger(account)) { + return { + valid: false, + error: 'Invalid Hedera Account ID. Values are too large.', + }; + } + + return { + valid: true, + error: null, + }; +}