Skip to content

Commit

Permalink
Merge pull request #161 from ensdomains/fix/delete-abi-with-setRecords
Browse files Browse the repository at this point in the history
fix setting abi and add tests
  • Loading branch information
TateB authored Jan 21, 2024
2 parents 11749bb + c09cedd commit 246fc00
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 50 deletions.
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

0 comments on commit 246fc00

Please sign in to comment.