ox
Version:
Ethereum Standard Library
331 lines (310 loc) • 9.65 kB
text/typescript
import { attest } from '@ark/attest'
import { Abi, AbiEvent } from 'ox'
import { describe, test } from 'vp/test'
import {
seaportContractConfig,
wagmiContractConfig,
} from '../../../test/constants/abis.js'
describe('decode', () => {
test('behavior: named', () => {
const transfer = AbiEvent.from(
'event Transfer(address indexed from, address indexed to, uint256 value)',
)
const decoded = AbiEvent.decode(transfer, {
data: '0x0000000000000000000000000000000000000000000000000000000000000001',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
],
})
attest(decoded).type.toString.snap(`{
from: \`0x\${string}\`
to: \`0x\${string}\`
value: bigint
}`)
})
test('behavior: unnamed', () => {
const transfer = AbiEvent.from(
'event Transfer(address indexed, address indexed, uint256)',
)
const decoded = AbiEvent.decode(transfer, {
data: '0x0000000000000000000000000000000000000000000000000000000000000001',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
],
})
attest(decoded).type.toString.snap(
'readonly [`0x${string}`, `0x${string}`, bigint]',
)
})
test('behavior: named + unnamed', () => {
const transfer = AbiEvent.from(
'event Transfer(address indexed from, address indexed to, uint256)',
)
const decoded = AbiEvent.decode(transfer, {
data: '0x0000000000000000000000000000000000000000000000000000000000000001',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
],
})
attest(decoded).type.toString.snap(`{
from: \`0x\${string}\`
to: \`0x\${string}\`
2: bigint
}`)
})
test('behavior: named + unnamed', () => {
const transfer = AbiEvent.from(
'event Transfer(address indexed from, address indexed, uint256 value)',
)
const decoded = AbiEvent.decode(transfer, {
data: '0x0000000000000000000000000000000000000000000000000000000000000001',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
],
})
attest(decoded).type.toString.snap(`{
from: \`0x\${string}\`
1: \`0x\${string}\`
value: bigint
}`)
})
test('behavior: named + unnamed', () => {
const transfer = AbiEvent.from(
'event Transfer(address indexed from, address indexed, uint256 value, uint256)',
)
const decoded = AbiEvent.decode(transfer, {
data: '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001',
topics: [
'0x9ed053bb818ff08b8353cd46f78db1f0799f31c9e4458fdb425c10eccd2efc44',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
'0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
],
})
attest(decoded).type.toString.snap(`{
from: \`0x\${string}\`
1: \`0x\${string}\`
value: bigint
3: bigint
}`)
})
test('behavior: string inputs', () => {
const transfer = AbiEvent.from('event Transfer(string indexed a)')
const decoded = AbiEvent.decode(transfer, {
topics: [
'0x7cebee4ee226a36ff8751d9d69bb8265f5138c825f8c25d7ebdd60d972ffe5be',
'0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8',
],
})
attest(decoded).type.toString.snap('{ a: string }')
})
test('behavior: widened event', () => {
const transfer = AbiEvent.from('event Transfer(string indexed a)')
const decoded = AbiEvent.decode(transfer as AbiEvent.AbiEvent, {
topics: [
'0x7cebee4ee226a36ff8751d9d69bb8265f5138c825f8c25d7ebdd60d972ffe5be',
'0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8',
],
})
attest(decoded).type.toString.snap('unknown')
})
test('behavior: union event', () => {
const transfer = AbiEvent.fromAbi(
seaportContractConfig.abi,
'CounterIncremented' as AbiEvent.Name<typeof seaportContractConfig.abi>,
)
const decoded = AbiEvent.decode(transfer, {
data: '0x0000000000000000000000000000000000000000000000000000000000000000',
topics: [
'0x721c20121297512b72821b97f5326877ea8ecf4bb9948fea5bfcb6453074d37f',
'0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8',
],
})
attest(decoded).type.toString
.snap(` | { newCounter: bigint; offerer: \`0x\${string}\` }
| {
orderHash: \`0x\${string}\`
offerer: \`0x\${string}\`
zone: \`0x\${string}\`
}
| {
orderHash: \`0x\${string}\`
offerer: \`0x\${string}\`
zone: \`0x\${string}\`
recipient: \`0x\${string}\`
offer: readonly {
itemType: number
token: \`0x\${string}\`
identifier: bigint
amount: bigint
}[]
consideration: readonly {
itemType: number
token: \`0x\${string}\`
identifier: bigint
amount: bigint
recipient: \`0x\${string}\`
}[]
}
| {
orderHash: \`0x\${string}\`
offerer: \`0x\${string}\`
zone: \`0x\${string}\`
}`)
})
})
describe('fromAbi', () => {
test('default', () => {
const item = AbiEvent.fromAbi(wagmiContractConfig.abi, 'Approval')
attest(item).type.toString.snap(`{
readonly anonymous: false
readonly inputs: readonly [
{
readonly indexed: true
readonly name: "owner"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "approved"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "tokenId"
readonly type: "uint256"
}
]
readonly name: "Approval"
readonly type: "event"
}`)
})
test('behavior: unknown abi', () => {
const item = AbiEvent.fromAbi(
wagmiContractConfig.abi as readonly unknown[],
'Approval',
)
attest(item).type.toString.snap('AbiEvent')
})
test('behavior: name', () => {
const item = AbiEvent.fromAbi(wagmiContractConfig.abi, 'Approval')
const item_2 = AbiEvent.fromAbi(
wagmiContractConfig.abi,
AbiEvent.getSelector(item),
)
attest(item_2).type.toString.snap(` | {
readonly anonymous: false
readonly inputs: readonly [
{
readonly indexed: true
readonly name: "owner"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "approved"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "tokenId"
readonly type: "uint256"
}
]
readonly name: "Approval"
readonly type: "event"
}
| {
readonly anonymous: false
readonly inputs: readonly [
{
readonly indexed: true
readonly name: "owner"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "operator"
readonly type: "address"
},
{
readonly indexed: false
readonly name: "approved"
readonly type: "bool"
}
]
readonly name: "ApprovalForAll"
readonly type: "event"
}
| {
readonly anonymous: false
readonly inputs: readonly [
{
readonly indexed: true
readonly name: "from"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "to"
readonly type: "address"
},
{
readonly indexed: true
readonly name: "tokenId"
readonly type: "uint256"
}
]
readonly name: "Transfer"
readonly type: "event"
}`)
})
test('behavior: overloads', () => {
const abi = Abi.from(['event Bar()', 'event Foo()', 'event Foo(uint256)'])
const item = AbiEvent.fromAbi(abi, 'Foo')
attest(item).type.toString.snap(`{
readonly name: "Foo"
readonly type: "event"
readonly inputs: readonly []
}`)
})
test('behavior: overloads: no inputs or args', () => {
const abi = Abi.from([
'event Bar()',
'event Foo(bytes)',
'event Foo(uint256)',
])
const item = AbiEvent.fromAbi(abi, 'Foo')
attest(item).type.toString.snap(`{
readonly name: "Foo"
readonly type: "event"
readonly inputs: readonly [{ readonly type: "bytes" }]
readonly overloads: [
{
readonly name: "Foo"
readonly type: "event"
readonly inputs: readonly [
{ readonly type: "uint256" }
]
}
]
}`)
})
test('behavior: widened name', () => {
const abi = Abi.from(wagmiContractConfig.abi)
const abiItem = AbiEvent.fromAbi(
abi,
'Approval' as AbiEvent.Name<typeof abi>,
)
attest(abiItem.name).type.toString.snap(
'"Transfer" | "Approval" | "ApprovalForAll"',
)
})
})