diff --git a/.changeset/sour-mugs-add.md b/.changeset/sour-mugs-add.md new file mode 100644 index 0000000000..18da0908cc --- /dev/null +++ b/.changeset/sour-mugs-add.md @@ -0,0 +1,5 @@ +--- +"viem": patch +--- + +Fixed `getAbiItem` for different overloaded bytes lengths diff --git a/src/utils/abi/getAbiItem.test.ts b/src/utils/abi/getAbiItem.test.ts index d8b637df2b..f64e9df6e9 100644 --- a/src/utils/abi/getAbiItem.test.ts +++ b/src/utils/abi/getAbiItem.test.ts @@ -329,7 +329,14 @@ test('overload: different types', () => { type: 'function', }, { - inputs: [{ name: 'tokenId', type: 'string' }], + inputs: [{ name: 'tokenId', type: 'address' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'bytes32' }], name: 'mint', outputs: [], stateMutability: 'nonpayable', @@ -377,14 +384,37 @@ test('overload: different types', () => { getAbiItem({ abi, name: 'mint', - args: ['foo'], + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], }), ).toMatchInlineSnapshot(` { "inputs": [ { "name": "tokenId", - "type": "string", + "type": "address", + }, + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + } + `) + + expect( + getAbiItem({ + abi, + name: 'mint', + args: [ + '0x000000000000000000000000A0Cf798816D4b9b9866b5330EEa46a18382f251e', + ], + }), + ).toMatchInlineSnapshot(` + { + "inputs": [ + { + "name": "tokenId", + "type": "bytes32", }, ], "name": "mint", diff --git a/src/utils/abi/getAbiItem.ts b/src/utils/abi/getAbiItem.ts index d2a409f1d3..643300087d 100644 --- a/src/utils/abi/getAbiItem.ts +++ b/src/utils/abi/getAbiItem.ts @@ -189,8 +189,19 @@ export function isArgOfType(arg: unknown, abiParameter: AbiParameter): boolean { // `bytes`: binary type of `M` bytes, `0 < M <= 32` // https://regexr.com/6va55 - if (/^bytes([1-9]|1[0-9]|2[0-9]|3[0-2])?$/.test(abiParameterType)) - return argType === 'string' || arg instanceof Uint8Array + const bytesMatch = /^bytes([1-9]|1[0-9]|2[0-9]|3[0-2])?$/.exec( + abiParameterType, + ) + if (bytesMatch) { + const length = bytesMatch[1] ? Number(bytesMatch[1]) : undefined + return ( + (argType === 'string' && + (length === undefined || + (arg as string).length === length * 2 + 2)) || + (arg instanceof Uint8Array && + (length === undefined || arg.length === length)) + ) + } // fixed-length (`[M]`) and dynamic (`[]`) arrays // https://regexr.com/6va6i