From d98d7d5219841b4d2287143ace0980f273490d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crist=C3=B3v=C3=A3o=20Honorato?= Date: Wed, 8 Jan 2025 11:47:08 +0100 Subject: [PATCH] feat: invoke normalizeRoute when planning --- src/addresses.ts | 39 ++++++++--------------------------- src/execute/normalizeRoute.ts | 19 +++++++---------- src/execute/plan.test.ts | 38 +++++++++++++++++----------------- src/execute/plan.ts | 3 +++ 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/src/addresses.ts b/src/addresses.ts index 1001317..10159a2 100644 --- a/src/addresses.ts +++ b/src/addresses.ts @@ -19,13 +19,20 @@ export const formatPrefixedAddress = ( export const splitPrefixedAddress = ( prefixedAddress: PrefixedAddress | Address ): [ChainId | undefined, Address] => { - validatePrefixedAddress(prefixedAddress) - if (prefixedAddress.length == zeroAddress.length) { + if (!isAddress(prefixedAddress)) { + throw new Error(`Not an Address: ${prefixedAddress}`) + } return [undefined, getAddress(prefixedAddress)] } else { + if (prefixedAddress.indexOf(':') == -1) { + throw new Error(`Unsupported PrefixedAddress format: ${prefixedAddress}`) + } const [prefix, address] = prefixedAddress.split(':') const chain = chains.find(({ shortName }) => shortName === prefix) + if (prefix && prefix != 'eoa' && !chain) { + throw new Error(`Unsupported chain shortName: ${prefix}`) + } return [chain?.chainId, getAddress(address)] as const } @@ -37,31 +44,3 @@ export const parsePrefixedAddress = ( const [, address] = splitPrefixedAddress(prefixedAddress) return address } - -export const validatePrefixedAddress = ( - prefixedAddress: PrefixedAddress | Address -) => { - if (prefixedAddress.length == zeroAddress.length) { - if (!isAddress(prefixedAddress)) { - throw new Error(`Not an Address: ${prefixedAddress}`) - } - } else { - if (prefixedAddress.indexOf(':') == -1) { - throw new Error(`Unsupported PrefixedAddress format: ${prefixedAddress}`) - } - - const [prefix, address] = prefixedAddress.split(':') - - if ( - prefix && - prefix != 'eoa' && - chains.every((chain) => chain.shortName != prefix) - ) { - throw new Error(`Unsupported chain shortName: ${prefix}`) - } - - if (!isAddress(address)) { - throw new Error(`Not an Address: ${address}`) - } - } -} diff --git a/src/execute/normalizeRoute.ts b/src/execute/normalizeRoute.ts index 0ab8334..980e4de 100644 --- a/src/execute/normalizeRoute.ts +++ b/src/execute/normalizeRoute.ts @@ -1,6 +1,6 @@ -import { Address, encodeFunctionData, parseAbi } from 'viem' +import { encodeFunctionData, getAddress, parseAbi } from 'viem' -import { splitPrefixedAddress, validatePrefixedAddress } from '../addresses' +import { formatPrefixedAddress, splitPrefixedAddress } from '../addresses' import { Account, @@ -55,7 +55,7 @@ async function normalizeAccount( ): Promise { account = { ...account, - address: normalizeAddress(account.address), + address: getAddress(account.address), prefixedAddress: normalizePrefixedAddress(account.prefixedAddress), } @@ -76,14 +76,11 @@ function normalizeConnection(connection: Connection): Connection { } } -function normalizeAddress(address: Address): Address { - validatePrefixedAddress(address) - return address.toLowerCase() as Address -} - -function normalizePrefixedAddress(address: PrefixedAddress): PrefixedAddress { - validatePrefixedAddress(address) - return address.toLowerCase() as PrefixedAddress +function normalizePrefixedAddress( + prefixedAddress: PrefixedAddress +): PrefixedAddress { + const [chainId, address] = splitPrefixedAddress(prefixedAddress) + return formatPrefixedAddress(chainId, address) } async function fetchThreshold( diff --git a/src/execute/plan.test.ts b/src/execute/plan.test.ts index 340d99b..4b5eb52 100644 --- a/src/execute/plan.test.ts +++ b/src/execute/plan.test.ts @@ -69,7 +69,7 @@ describe('plan', () => { [ { data: '0x', - to: receiver.address as `0x{string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, }, @@ -126,7 +126,7 @@ describe('plan', () => { [ { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, }, @@ -192,7 +192,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, } @@ -231,7 +231,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, } @@ -277,7 +277,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver as `0x${string}`, + to: receiver, value: parseEther('1'), operation: OperationType.Call, } @@ -333,7 +333,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver as `0x${string}`, + to: receiver, value: parseEther('1'), operation: OperationType.Call, } @@ -436,7 +436,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, } @@ -517,7 +517,7 @@ describe('plan', () => { [ { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('1'), operation: OperationType.Call, }, @@ -592,7 +592,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -658,7 +658,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -733,7 +733,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -825,7 +825,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -917,7 +917,7 @@ describe('plan', () => { }) const route = eoaRolesSafeOwnsSafe({ - eoa: member.address as `0x${string}`, + eoa: member.address, roles, roleId, safe1, @@ -926,7 +926,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -999,7 +999,7 @@ describe('plan', () => { }) const route = eoaRolesSafeOwnsSafe({ - eoa: member.address as `0x${string}`, + eoa: member.address, roles, roleId, safe1, @@ -1008,7 +1008,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -1106,7 +1106,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } @@ -1156,7 +1156,7 @@ describe('plan', () => { ).toEqual(parseEther('0.123')) }) - it('plans and executes independently', async () => { + it.only('plans and executes independently', async () => { const owner = privateKeyToAccount(randomHash()) const eoa = privateKeyToAccount(randomHash()) const receiver = privateKeyToAccount(randomHash()) @@ -1204,7 +1204,7 @@ describe('plan', () => { const transaction: MetaTransactionRequest = { data: '0x', - to: receiver.address as `0x${string}`, + to: receiver.address, value: parseEther('0.123'), operation: OperationType.Call, } diff --git a/src/execute/plan.ts b/src/execute/plan.ts index 0042a32..1f293e0 100644 --- a/src/execute/plan.ts +++ b/src/execute/plan.ts @@ -4,6 +4,7 @@ import { Eip1193Provider } from '@safe-global/protocol-kit' import { createPreApprovedSignature } from './signatures' import { encodeMultiSend } from './multisend' +import { normalizeRoute } from './normalizeRoute' import { prepareSafeTransaction } from './safeTransaction' import { splitPrefixedAddress } from '../addresses' @@ -64,6 +65,8 @@ export const planExecution = async ( route: Route, options: Options = {} ): Promise => { + route = await normalizeRoute(route, options) + // encode batch using the appropriate multiSend contract address const lastRolesAccount = route.waypoints.findLast( (wp) => wp.account.type === AccountType.ROLES