Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix setting abi and add tests #161

Merged
merged 8 commits into from
Jan 21, 2024
47 changes: 30 additions & 17 deletions packages/ensjs/src/functions/wallet/setAbiRecord.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,34 @@ it('should allow an abi record to be set with uri content type', async () => {
expect(response!.decoded).toBe(true)
})

it('should allow an abi record to be set to blank', async () => {
const tx = await setAbiRecord(walletClient, {
name: 'with-type-1-abi.eth',
encodedAbi: null,
resolverAddress: (await getResolver(publicClient, {
name: 'test123.eth',
}))!,
account: accounts[1],
})
expect(tx).toBeTruthy()
const receipt = await waitForTransaction(tx)
expect(receipt.status).toBe('success')
type EncodeAs = Parameters<typeof encodeAbi>[0]['encodeAs']
it.each([
['json', 'with-type-1-abi.eth'],
['zlib', 'with-type-2-abi.eth'],
['cbor', 'with-type-4-abi.eth'],
['uri', 'with-type-8-abi.eth'],
] as [EncodeAs, string][])(
`should allow an abi record to be set to null with %s content type`,
async (encodeAs, name) => {
const encodedAbi = await encodeAbi({
encodeAs,
data: null,
})
const tx = await setAbiRecord(walletClient, {
name,
encodedAbi,
resolverAddress: (await getResolver(publicClient, {
name,
}))!,
account: accounts[1],
})
expect(tx).toBeTruthy()
const receipt = await waitForTransaction(tx)
expect(receipt.status).toBe('success')

const response = await getAbiRecord(publicClient, {
name: 'test123.eth',
})
expect(response).toBeNull()
})
const response = await getAbiRecord(publicClient, {
name,
})
expect(response).toBeNull()
},
)
5 changes: 2 additions & 3 deletions packages/ensjs/src/functions/wallet/setAbiRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type SetAbiRecordDataParameters = {
/** Name to set ABI for */
name: string
/** Encoded ABI data to set */
encodedAbi: EncodedAbi | null
encodedAbi: EncodedAbi
/** Resolver address to set ABI on */
resolverAddress: Address
}
Expand All @@ -47,12 +47,11 @@ export const makeFunctionData = <
_wallet: WalletWithEns<Transport, TChain, TAccount>,
{ name, encodedAbi, resolverAddress }: SetAbiRecordDataParameters,
): SetAbiRecordDataReturnType => {
const encodedAbi_ = encodedAbi || { contentType: 0, encodedData: null }
return {
to: resolverAddress,
data: encodeSetAbi({
namehash: namehash(name),
...encodedAbi_,
...encodedAbi,
} as EncodeSetAbiParameters),
}
}
Expand Down
53 changes: 53 additions & 0 deletions packages/ensjs/src/functions/wallet/setRecords.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,59 @@ it('should return a transaction to the resolver and set successfully', async ()
]
`)
})
it('should return a transaction to the resolver and delete successfully', async () => {
const setupTx = await setRecords(walletClient, {
name: 'test123.eth',
resolverAddress: (await getResolver(publicClient, {
name: 'test123.eth',
}))!,
coins: [
{
coin: 'etcLegacy',
value: '0x42D63ae25990889E35F215bC95884039Ba354115',
},
],
texts: [{ key: 'foo', value: 'bar' }],
abi: await encodeAbi({ encodeAs: 'json', data: dummyABI }),
account: accounts[1],
})
await waitForTransaction(setupTx)
const checkRecords = await getRecords(publicClient, {
name: 'test123.eth',
coins: ['etcLegacy'],
texts: ['foo'],
abi: true,
})
expect(checkRecords.abi!.abi).not.toBeNull()
expect(checkRecords.coins).toHaveLength(1)
expect(checkRecords.texts).toHaveLength(1)
const tx = await setRecords(walletClient, {
name: 'test123.eth',
resolverAddress: (await getResolver(publicClient, {
name: 'test123.eth',
}))!,
coins: [
{
coin: 'etcLegacy',
value: '',
},
],
texts: [{ key: 'foo', value: '' }],
abi: await encodeAbi({ encodeAs: 'json', data: null }),
account: accounts[1],
})
await waitForTransaction(tx)

const records = await getRecords(publicClient, {
name: 'test123.eth',
coins: ['etcLegacy'],
texts: ['foo'],
abi: true,
})
expect(records.abi).toBeNull()
expect(records.coins).toHaveLength(0)
expect(records.texts).toHaveLength(0)
})
it('should error if there are no records to set', async () => {
await expect(
setRecords(walletClient, {
Expand Down
28 changes: 28 additions & 0 deletions packages/ensjs/src/utils/encoders/encodeAbi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ describe('encodeAbi', () => {
expect(result.encodedData).toEqual('0x7b22666f6f223a22626172227d')
})

// Null JSON data
it('encodes null JSON data', async () => {
const result = await encodeAbi({ encodeAs: 'json', data: null })
expect(result.contentType).toEqual(1)
expect(result.encodedData).toEqual('0x')
})

it('encodes data as zlib', async () => {
const data = { foo: 'bar' }
const result = await encodeAbi({ encodeAs: 'zlib', data })
Expand All @@ -21,19 +28,40 @@ describe('encodeAbi', () => {
)
})

// Null zlib data
it('encodes null zlib data', async () => {
const result = await encodeAbi({ encodeAs: 'zlib', data: null })
expect(result.contentType).toEqual(2)
expect(result.encodedData).toEqual('0x')
})

it('encodes data as cbor', async () => {
const data = { foo: 'bar' }
const result = await encodeAbi({ encodeAs: 'cbor', data })
expect(result.contentType).toEqual(4)
expect(result.encodedData).toEqual('0xa163666f6f63626172')
})

// Null CBOR data
it('encodes null CBOR data', async () => {
const result = await encodeAbi({ encodeAs: 'cbor', data: null })
expect(result.contentType).toEqual(4)
expect(result.encodedData).toEqual('0x')
})

it('encodes data as uri', async () => {
const data = 'foo=bar'
const result = await encodeAbi({ encodeAs: 'uri', data })
expect(result.contentType).toEqual(8)
expect(result.encodedData).toEqual('0x666f6f3d626172')
})

// Null URI data
it('encodes null URI data', async () => {
const result = await encodeAbi({ encodeAs: 'uri', data: null })
expect(result.contentType).toEqual(8)
expect(result.encodedData).toEqual('0x')
})
})

describe('encodeAsToContentType', () => {
Expand Down
22 changes: 13 additions & 9 deletions packages/ensjs/src/utils/encoders/encodeAbi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export type EncodeAbiParameters<TEncodeAs extends AbiEncodeAs = AbiEncodeAs> =
TEncodeAs extends 'uri'
? {
encodeAs: TEncodeAs
data: string
data: string | null
}
: {
encodeAs: TEncodeAs
data: Record<any, any>
data: Record<any, any> | null
}

export type EncodedAbi<TContentType extends AbiContentType = AbiContentType> = {
Expand Down Expand Up @@ -72,27 +72,31 @@ export const encodeAbi = async <
Prettify<EncodeAbiReturnType<TContentType>>
> => {
let contentType: AbiContentType
let encodedData: Hex
let encodedData: Hex = '0x'
switch (encodeAs) {
case 'json':
contentType = 1
encodedData = stringToHex(JSON.stringify(data))
if (data) encodedData = stringToHex(JSON.stringify(data))
break
case 'zlib': {
contentType = 2
const { deflate } = await import('pako/dist/pako_deflate.min.js')
encodedData = bytesToHex(deflate(JSON.stringify(data)))
if (data) {
const { deflate } = await import('pako/dist/pako_deflate.min.js')
encodedData = bytesToHex(deflate(JSON.stringify(data)))
}
break
}
case 'cbor': {
contentType = 4
const { cborEncode } = await import('@ensdomains/address-encoder/utils')
encodedData = bytesToHex(new Uint8Array(cborEncode(data)))
if (data) {
const { cborEncode } = await import('@ensdomains/address-encoder/utils')
encodedData = bytesToHex(new Uint8Array(cborEncode(data)))
}
break
}
default: {
contentType = 8
encodedData = stringToHex(data as string)
if (data) encodedData = stringToHex(data as string)
break
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/ensjs/src/utils/encoders/encodeSetAbi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { encodeSetAbi, type EncodeSetAbiParameters } from './encodeSetAbi.js'
describe('encodeSetAbi', () => {
const namehash =
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
const contentType = 0
const encodedData = null
const contentType = 1
const encodedData = '0x'

const parameters: EncodeSetAbiParameters = {
namehash,
contentType,
encodedData,
}

it('encodes the setAbi function data correctly', () => {
it('encodes the setAbi function data correctly with null encodedData', async () => {
const expected =
'0x623195b01234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000'
'0x623195b01234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000'
const result = encodeSetAbi(parameters)
expect(result).toEqual(expected)
})
Expand Down
4 changes: 2 additions & 2 deletions packages/ensjs/src/utils/encoders/encodeSetAbi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { EncodedAbi } from './encodeAbi.js'

export type EncodeSetAbiParameters = {
namehash: Hex
} & (EncodedAbi | { contentType: 0; encodedData: null })
} & EncodedAbi

export type EncodeSetAbiReturnType = Hex

Expand All @@ -16,6 +16,6 @@ export const encodeSetAbi = ({
return encodeFunctionData({
abi: publicResolverSetAbiSnippet,
functionName: 'setABI',
args: [namehash, BigInt(contentType), encodedData ?? '0x'],
args: [namehash, BigInt(contentType), encodedData],
})
}
39 changes: 27 additions & 12 deletions packages/ensjs/src/utils/generateRecordCallArray.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { generateRecordCallArray } from './generateRecordCallArray.js'
import { encodeAbi } from './index.js'
import { namehash } from './normalise.js'

it('generates a record call array', () => {
Expand Down Expand Up @@ -44,18 +45,6 @@ it('adds contentHash call when contentHash is defined', () => {
]
`)
})
it('adds abi call when abi is null', () => {
expect(
generateRecordCallArray({
namehash: namehash('test.eth'),
abi: null,
}),
).toMatchInlineSnapshot(`
[
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
]
`)
})
it('does not add abi call when abi is undefined', () => {
expect(
generateRecordCallArray({
Expand Down Expand Up @@ -90,3 +79,29 @@ it('adds coin calls when coins array is defined and not empty', () => {
]
`)
})
it('adds abi call when data is null', async () => {
const result = await encodeAbi({ encodeAs: 'uri', data: null })
expect(
generateRecordCallArray({
namehash: namehash('test.eth'),
abi: result,
}),
).toMatchInlineSnapshot(`
[
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
]
`)
})
it('adds abi call when data is not empty', async () => {
const result = await encodeAbi({ encodeAs: 'json', data: { foo: 'bar' } })
expect(
generateRecordCallArray({
namehash: namehash('test.eth'),
abi: result,
}),
).toMatchInlineSnapshot(`
[
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000d7b22666f6f223a22626172227d00000000000000000000000000000000000000",
]
`)
})
5 changes: 2 additions & 3 deletions packages/ensjs/src/utils/generateRecordCallArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type RecordOptions = Prettify<{
/** Array of coin records */
coins?: Omit<EncodeSetAddrParameters, 'namehash'>[]
/** ABI value */
abi?: EncodedAbi | null
abi?: EncodedAbi
}>

export const generateRecordCallArray = ({
Expand All @@ -49,8 +49,7 @@ export const generateRecordCallArray = ({
}

if (abi !== undefined) {
const abi_ = abi ?? { contentType: 0, encodedData: null }
const data = encodeSetAbi({ namehash, ...abi_ } as EncodeSetAbiParameters)
const data = encodeSetAbi({ namehash, ...abi } as EncodeSetAbiParameters)
if (data) calls.push(data)
}

Expand Down
Loading