Skip to content

Commit

Permalink
fix: allow non-prefixed string and bytearray inputs (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechsimetka committed Nov 13, 2022
1 parent a92fec1 commit 11964e1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
9 changes: 4 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
import { keccak256 } from '@ethersproject/keccak256'
import { toUtf8Bytes } from '@ethersproject/strings'
import { type BytesLike, hexlify } from '@ethersproject/bytes'
import { addHexPrefix } from './utils'

export function splitCallData(calldata: BytesLike): [string, string] {
const cd = hexlify(calldata)
const cd = typeof calldata === 'string' ? addHexPrefix(calldata) : hexlify(calldata)

return [cd.substring(0, 10), `0x${cd.substring(10)}`]
}
Expand All @@ -36,10 +37,8 @@ export function getSighash(abiFragment: string | Fragment | JsonFragment): strin
}

export function findMethodById(methodId: BytesLike, abi: JsonFragment[]): JsonFragment | undefined {
const mId = typeof methodId === 'string' ? methodId : hexlify(methodId)
return abi
.filter((a) => a.type === 'function')
.find((a) => getMethodId(getSighash(a)) === mId)
const mId = typeof methodId === 'string' ? addHexPrefix(methodId) : hexlify(methodId)
return abi.filter((a) => a.type === 'function').find((a) => getMethodId(getSighash(a)) === mId)
}

export function decodeCallData(calldata: BytesLike, abi: JsonFragment[], loose?: boolean) {
Expand Down
10 changes: 10 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Strips prefix from a string
*
* @param s string input
*/
export function addHexPrefix(s: string): string {
if (typeof s === 'string' && /^[0-9a-f]+$/i.test(s)) return `0x${s}`

return s
}
42 changes: 38 additions & 4 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import decodeCallData, { decodeInputs, findMethodById, getMethodId, getSighash } from '../src/index'
import { BigNumber } from '@ethersproject/bignumber'
import abi2 from './abi2.json'
import { arrayify } from '@ethersproject/bytes'
import abi2 from './data/abi2.json'

describe('getMethodId', () => {
const testValues = [{ input: 'mint(uint256,uint256)', output: '0x1b2ef1ca' }]
Expand Down Expand Up @@ -88,12 +89,24 @@ describe('decodeInputs', () => {
})

describe('findMethodById', () => {
test('should find method in abi', () => {
test('should find method in abi as string with prefix', () => {
const res = findMethodById('0x1b2ef1ca', abi2)

expect(res).toBeDefined()
expect(res?.name).toEqual('mint')
})
test('should find method in abi as string without prefix', () => {
const res = findMethodById('1b2ef1ca', abi2)

expect(res).toBeDefined()
expect(res?.name).toEqual('mint')
})
test('should find method in abi as bytearray', () => {
const res = findMethodById(arrayify('0x1b2ef1ca'), abi2)

expect(res).toBeDefined()
expect(res?.name).toEqual('mint')
})
test('should not find method in abi', () => {
const res = findMethodById('0x00000000', abi2)

Expand All @@ -102,8 +115,29 @@ describe('findMethodById', () => {
})

describe('decodeCalldata', () => {
test('should decode call data', () => {
const res = decodeCallData('0x1b2ef1ca0000000000000000000000000000000000000000000000070c1cc73b00c800000000000000000000000000000000000000000000000001567fdd05cd25f80000', abi2)
test('should decode call data as prefixed string', () => {
const res = decodeCallData(
'0x1b2ef1ca0000000000000000000000000000000000000000000000070c1cc73b00c800000000000000000000000000000000000000000000000001567fdd05cd25f80000',
abi2
)

expect(res.method.name).toEqual('mint')
})
test('should decode call data as bytes array', () => {
const res = decodeCallData(
'1b2ef1ca0000000000000000000000000000000000000000000000070c1cc73b00c800000000000000000000000000000000000000000000000001567fdd05cd25f80000',
abi2
)

expect(res.method.name).toEqual('mint')
})
test('should decode call data as string without prefix', () => {
const res = decodeCallData(
arrayify(
'0x1b2ef1ca0000000000000000000000000000000000000000000000070c1cc73b00c800000000000000000000000000000000000000000000000001567fdd05cd25f80000'
),
abi2
)

expect(res.method.name).toEqual('mint')
})
Expand Down

0 comments on commit 11964e1

Please sign in to comment.