Skip to content

Commit 246fc00

Browse files
authored
Merge pull request #161 from ensdomains/fix/delete-abi-with-setRecords
fix setting abi and add tests
2 parents 11749bb + c09cedd commit 246fc00

File tree

9 files changed

+161
-50
lines changed

9 files changed

+161
-50
lines changed

packages/ensjs/src/functions/wallet/setAbiRecord.test.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,21 +136,34 @@ it('should allow an abi record to be set with uri content type', async () => {
136136
expect(response!.decoded).toBe(true)
137137
})
138138

139-
it('should allow an abi record to be set to blank', async () => {
140-
const tx = await setAbiRecord(walletClient, {
141-
name: 'with-type-1-abi.eth',
142-
encodedAbi: null,
143-
resolverAddress: (await getResolver(publicClient, {
144-
name: 'test123.eth',
145-
}))!,
146-
account: accounts[1],
147-
})
148-
expect(tx).toBeTruthy()
149-
const receipt = await waitForTransaction(tx)
150-
expect(receipt.status).toBe('success')
139+
type EncodeAs = Parameters<typeof encodeAbi>[0]['encodeAs']
140+
it.each([
141+
['json', 'with-type-1-abi.eth'],
142+
['zlib', 'with-type-2-abi.eth'],
143+
['cbor', 'with-type-4-abi.eth'],
144+
['uri', 'with-type-8-abi.eth'],
145+
] as [EncodeAs, string][])(
146+
`should allow an abi record to be set to null with %s content type`,
147+
async (encodeAs, name) => {
148+
const encodedAbi = await encodeAbi({
149+
encodeAs,
150+
data: null,
151+
})
152+
const tx = await setAbiRecord(walletClient, {
153+
name,
154+
encodedAbi,
155+
resolverAddress: (await getResolver(publicClient, {
156+
name,
157+
}))!,
158+
account: accounts[1],
159+
})
160+
expect(tx).toBeTruthy()
161+
const receipt = await waitForTransaction(tx)
162+
expect(receipt.status).toBe('success')
151163

152-
const response = await getAbiRecord(publicClient, {
153-
name: 'test123.eth',
154-
})
155-
expect(response).toBeNull()
156-
})
164+
const response = await getAbiRecord(publicClient, {
165+
name,
166+
})
167+
expect(response).toBeNull()
168+
},
169+
)

packages/ensjs/src/functions/wallet/setAbiRecord.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export type SetAbiRecordDataParameters = {
2222
/** Name to set ABI for */
2323
name: string
2424
/** Encoded ABI data to set */
25-
encodedAbi: EncodedAbi | null
25+
encodedAbi: EncodedAbi
2626
/** Resolver address to set ABI on */
2727
resolverAddress: Address
2828
}
@@ -47,12 +47,11 @@ export const makeFunctionData = <
4747
_wallet: WalletWithEns<Transport, TChain, TAccount>,
4848
{ name, encodedAbi, resolverAddress }: SetAbiRecordDataParameters,
4949
): SetAbiRecordDataReturnType => {
50-
const encodedAbi_ = encodedAbi || { contentType: 0, encodedData: null }
5150
return {
5251
to: resolverAddress,
5352
data: encodeSetAbi({
5453
namehash: namehash(name),
55-
...encodedAbi_,
54+
...encodedAbi,
5655
} as EncodeSetAbiParameters),
5756
}
5857
}

packages/ensjs/src/functions/wallet/setRecords.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,59 @@ it('should return a transaction to the resolver and set successfully', async ()
9191
]
9292
`)
9393
})
94+
it('should return a transaction to the resolver and delete successfully', async () => {
95+
const setupTx = await setRecords(walletClient, {
96+
name: 'test123.eth',
97+
resolverAddress: (await getResolver(publicClient, {
98+
name: 'test123.eth',
99+
}))!,
100+
coins: [
101+
{
102+
coin: 'etcLegacy',
103+
value: '0x42D63ae25990889E35F215bC95884039Ba354115',
104+
},
105+
],
106+
texts: [{ key: 'foo', value: 'bar' }],
107+
abi: await encodeAbi({ encodeAs: 'json', data: dummyABI }),
108+
account: accounts[1],
109+
})
110+
await waitForTransaction(setupTx)
111+
const checkRecords = await getRecords(publicClient, {
112+
name: 'test123.eth',
113+
coins: ['etcLegacy'],
114+
texts: ['foo'],
115+
abi: true,
116+
})
117+
expect(checkRecords.abi!.abi).not.toBeNull()
118+
expect(checkRecords.coins).toHaveLength(1)
119+
expect(checkRecords.texts).toHaveLength(1)
120+
const tx = await setRecords(walletClient, {
121+
name: 'test123.eth',
122+
resolverAddress: (await getResolver(publicClient, {
123+
name: 'test123.eth',
124+
}))!,
125+
coins: [
126+
{
127+
coin: 'etcLegacy',
128+
value: '',
129+
},
130+
],
131+
texts: [{ key: 'foo', value: '' }],
132+
abi: await encodeAbi({ encodeAs: 'json', data: null }),
133+
account: accounts[1],
134+
})
135+
await waitForTransaction(tx)
136+
137+
const records = await getRecords(publicClient, {
138+
name: 'test123.eth',
139+
coins: ['etcLegacy'],
140+
texts: ['foo'],
141+
abi: true,
142+
})
143+
expect(records.abi).toBeNull()
144+
expect(records.coins).toHaveLength(0)
145+
expect(records.texts).toHaveLength(0)
146+
})
94147
it('should error if there are no records to set', async () => {
95148
await expect(
96149
setRecords(walletClient, {

packages/ensjs/src/utils/encoders/encodeAbi.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ describe('encodeAbi', () => {
1212
expect(result.encodedData).toEqual('0x7b22666f6f223a22626172227d')
1313
})
1414

15+
// Null JSON data
16+
it('encodes null JSON data', async () => {
17+
const result = await encodeAbi({ encodeAs: 'json', data: null })
18+
expect(result.contentType).toEqual(1)
19+
expect(result.encodedData).toEqual('0x')
20+
})
21+
1522
it('encodes data as zlib', async () => {
1623
const data = { foo: 'bar' }
1724
const result = await encodeAbi({ encodeAs: 'zlib', data })
@@ -21,19 +28,40 @@ describe('encodeAbi', () => {
2128
)
2229
})
2330

31+
// Null zlib data
32+
it('encodes null zlib data', async () => {
33+
const result = await encodeAbi({ encodeAs: 'zlib', data: null })
34+
expect(result.contentType).toEqual(2)
35+
expect(result.encodedData).toEqual('0x')
36+
})
37+
2438
it('encodes data as cbor', async () => {
2539
const data = { foo: 'bar' }
2640
const result = await encodeAbi({ encodeAs: 'cbor', data })
2741
expect(result.contentType).toEqual(4)
2842
expect(result.encodedData).toEqual('0xa163666f6f63626172')
2943
})
3044

45+
// Null CBOR data
46+
it('encodes null CBOR data', async () => {
47+
const result = await encodeAbi({ encodeAs: 'cbor', data: null })
48+
expect(result.contentType).toEqual(4)
49+
expect(result.encodedData).toEqual('0x')
50+
})
51+
3152
it('encodes data as uri', async () => {
3253
const data = 'foo=bar'
3354
const result = await encodeAbi({ encodeAs: 'uri', data })
3455
expect(result.contentType).toEqual(8)
3556
expect(result.encodedData).toEqual('0x666f6f3d626172')
3657
})
58+
59+
// Null URI data
60+
it('encodes null URI data', async () => {
61+
const result = await encodeAbi({ encodeAs: 'uri', data: null })
62+
expect(result.contentType).toEqual(8)
63+
expect(result.encodedData).toEqual('0x')
64+
})
3765
})
3866

3967
describe('encodeAsToContentType', () => {

packages/ensjs/src/utils/encoders/encodeAbi.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ export type EncodeAbiParameters<TEncodeAs extends AbiEncodeAs = AbiEncodeAs> =
2020
TEncodeAs extends 'uri'
2121
? {
2222
encodeAs: TEncodeAs
23-
data: string
23+
data: string | null
2424
}
2525
: {
2626
encodeAs: TEncodeAs
27-
data: Record<any, any>
27+
data: Record<any, any> | null
2828
}
2929

3030
export type EncodedAbi<TContentType extends AbiContentType = AbiContentType> = {
@@ -72,27 +72,31 @@ export const encodeAbi = async <
7272
Prettify<EncodeAbiReturnType<TContentType>>
7373
> => {
7474
let contentType: AbiContentType
75-
let encodedData: Hex
75+
let encodedData: Hex = '0x'
7676
switch (encodeAs) {
7777
case 'json':
7878
contentType = 1
79-
encodedData = stringToHex(JSON.stringify(data))
79+
if (data) encodedData = stringToHex(JSON.stringify(data))
8080
break
8181
case 'zlib': {
8282
contentType = 2
83-
const { deflate } = await import('pako/dist/pako_deflate.min.js')
84-
encodedData = bytesToHex(deflate(JSON.stringify(data)))
83+
if (data) {
84+
const { deflate } = await import('pako/dist/pako_deflate.min.js')
85+
encodedData = bytesToHex(deflate(JSON.stringify(data)))
86+
}
8587
break
8688
}
8789
case 'cbor': {
8890
contentType = 4
89-
const { cborEncode } = await import('@ensdomains/address-encoder/utils')
90-
encodedData = bytesToHex(new Uint8Array(cborEncode(data)))
91+
if (data) {
92+
const { cborEncode } = await import('@ensdomains/address-encoder/utils')
93+
encodedData = bytesToHex(new Uint8Array(cborEncode(data)))
94+
}
9195
break
9296
}
9397
default: {
9498
contentType = 8
95-
encodedData = stringToHex(data as string)
99+
if (data) encodedData = stringToHex(data as string)
96100
break
97101
}
98102
}

packages/ensjs/src/utils/encoders/encodeSetAbi.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ import { encodeSetAbi, type EncodeSetAbiParameters } from './encodeSetAbi.js'
44
describe('encodeSetAbi', () => {
55
const namehash =
66
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
7-
const contentType = 0
8-
const encodedData = null
7+
const contentType = 1
8+
const encodedData = '0x'
99

1010
const parameters: EncodeSetAbiParameters = {
1111
namehash,
1212
contentType,
1313
encodedData,
1414
}
1515

16-
it('encodes the setAbi function data correctly', () => {
16+
it('encodes the setAbi function data correctly with null encodedData', async () => {
1717
const expected =
18-
'0x623195b01234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000'
18+
'0x623195b01234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000'
1919
const result = encodeSetAbi(parameters)
2020
expect(result).toEqual(expected)
2121
})

packages/ensjs/src/utils/encoders/encodeSetAbi.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { EncodedAbi } from './encodeAbi.js'
44

55
export type EncodeSetAbiParameters = {
66
namehash: Hex
7-
} & (EncodedAbi | { contentType: 0; encodedData: null })
7+
} & EncodedAbi
88

99
export type EncodeSetAbiReturnType = Hex
1010

@@ -16,6 +16,6 @@ export const encodeSetAbi = ({
1616
return encodeFunctionData({
1717
abi: publicResolverSetAbiSnippet,
1818
functionName: 'setABI',
19-
args: [namehash, BigInt(contentType), encodedData ?? '0x'],
19+
args: [namehash, BigInt(contentType), encodedData],
2020
})
2121
}

packages/ensjs/src/utils/generateRecordCallArray.test.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { generateRecordCallArray } from './generateRecordCallArray.js'
2+
import { encodeAbi } from './index.js'
23
import { namehash } from './normalise.js'
34

45
it('generates a record call array', () => {
@@ -44,18 +45,6 @@ it('adds contentHash call when contentHash is defined', () => {
4445
]
4546
`)
4647
})
47-
it('adds abi call when abi is null', () => {
48-
expect(
49-
generateRecordCallArray({
50-
namehash: namehash('test.eth'),
51-
abi: null,
52-
}),
53-
).toMatchInlineSnapshot(`
54-
[
55-
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
56-
]
57-
`)
58-
})
5948
it('does not add abi call when abi is undefined', () => {
6049
expect(
6150
generateRecordCallArray({
@@ -90,3 +79,29 @@ it('adds coin calls when coins array is defined and not empty', () => {
9079
]
9180
`)
9281
})
82+
it('adds abi call when data is null', async () => {
83+
const result = await encodeAbi({ encodeAs: 'uri', data: null })
84+
expect(
85+
generateRecordCallArray({
86+
namehash: namehash('test.eth'),
87+
abi: result,
88+
}),
89+
).toMatchInlineSnapshot(`
90+
[
91+
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f1000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
92+
]
93+
`)
94+
})
95+
it('adds abi call when data is not empty', async () => {
96+
const result = await encodeAbi({ encodeAs: 'json', data: { foo: 'bar' } })
97+
expect(
98+
generateRecordCallArray({
99+
namehash: namehash('test.eth'),
100+
abi: result,
101+
}),
102+
).toMatchInlineSnapshot(`
103+
[
104+
"0x623195b0eb4f647bea6caa36333c816d7b46fdcb05f9466ecacc140ea8c66faf15b3d9f100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000d7b22666f6f223a22626172227d00000000000000000000000000000000000000",
105+
]
106+
`)
107+
})

packages/ensjs/src/utils/generateRecordCallArray.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type RecordOptions = Prettify<{
2626
/** Array of coin records */
2727
coins?: Omit<EncodeSetAddrParameters, 'namehash'>[]
2828
/** ABI value */
29-
abi?: EncodedAbi | null
29+
abi?: EncodedAbi
3030
}>
3131

3232
export const generateRecordCallArray = ({
@@ -49,8 +49,7 @@ export const generateRecordCallArray = ({
4949
}
5050

5151
if (abi !== undefined) {
52-
const abi_ = abi ?? { contentType: 0, encodedData: null }
53-
const data = encodeSetAbi({ namehash, ...abi_ } as EncodeSetAbiParameters)
52+
const data = encodeSetAbi({ namehash, ...abi } as EncodeSetAbiParameters)
5453
if (data) calls.push(data)
5554
}
5655

0 commit comments

Comments
 (0)