viem 0.0.1-alpha.21 → 0.0.1-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chain-32f56cfa.d.ts → chain-4b39613a.d.ts} +2 -2
- package/dist/{chain-f12cdc7f.d.ts → chain-aa4898d0.d.ts} +1 -1
- package/dist/chains.d.ts +3 -3
- package/dist/chains.js +46 -46
- package/dist/chains.mjs +1 -1
- package/dist/{chunk-46BO7YAQ.mjs → chunk-JMFNAGCD.mjs} +4 -3
- package/dist/chunk-JMFNAGCD.mjs.map +1 -0
- package/dist/{chunk-KZMJR27B.js → chunk-MVD4Y3AE.js} +67 -63
- package/dist/chunk-MVD4Y3AE.js.map +1 -0
- package/dist/{chunk-57ZOFERP.mjs → chunk-OZIBQJYR.mjs} +2 -2
- package/dist/{chunk-57ZOFERP.mjs.map → chunk-OZIBQJYR.mjs.map} +0 -0
- package/dist/{chunk-KEHGSYDO.js → chunk-PMPJGAHY.js} +14 -13
- package/dist/chunk-PMPJGAHY.js.map +1 -0
- package/dist/{chunk-W7BWWAC4.js → chunk-QA3IE5DU.js} +14 -14
- package/dist/{chunk-W7BWWAC4.js.map → chunk-QA3IE5DU.js.map} +0 -0
- package/dist/{chunk-DSPMAIDO.mjs → chunk-QN2NCTEN.mjs} +2 -2
- package/dist/{chunk-DSPMAIDO.mjs.map → chunk-QN2NCTEN.mjs.map} +1 -1
- package/dist/{chunk-EC3NUIJE.js → chunk-S77NLWHO.js} +13 -13
- package/dist/{chunk-EC3NUIJE.js.map → chunk-S77NLWHO.js.map} +1 -1
- package/dist/{chunk-O2GYLJVD.js → chunk-V5U5S7PQ.js} +403 -165
- package/dist/chunk-V5U5S7PQ.js.map +1 -0
- package/dist/{chunk-62VTYU2V.mjs → chunk-WWJ5YPTJ.mjs} +404 -166
- package/dist/chunk-WWJ5YPTJ.mjs.map +1 -0
- package/dist/{chunk-DGO77E2H.mjs → chunk-ZXXEENRD.mjs} +7 -3
- package/dist/chunk-ZXXEENRD.mjs.map +1 -0
- package/dist/clients/index.d.ts +7 -7
- package/dist/clients/index.js +3 -3
- package/dist/clients/index.mjs +2 -2
- package/dist/{contract-9af4608b.d.ts → contract-74f34ac9.d.ts} +14 -3
- package/dist/{createClient-5d316c7e.d.ts → createClient-55a04188.d.ts} +2 -2
- package/dist/{createPublicClient-9d2b42e1.d.ts → createPublicClient-3b27b282.d.ts} +3 -3
- package/dist/{createTestClient-79498dab.d.ts → createTestClient-93f9eac6.d.ts} +3 -3
- package/dist/{createWalletClient-f69a5230.d.ts → createWalletClient-c10df94d.d.ts} +3 -3
- package/dist/{eip1193-6c485d63.d.ts → eip1193-4c24765a.d.ts} +1 -1
- package/dist/ens.d.ts +1 -0
- package/dist/ens.js +11 -0
- package/dist/ens.js.map +1 -0
- package/dist/ens.mjs +11 -0
- package/dist/ens.mjs.map +1 -0
- package/dist/index.d.ts +125 -113
- package/dist/index.js +14 -6
- package/dist/index.mjs +13 -5
- package/dist/normalize-ef9240c0.d.ts +33 -0
- package/dist/{parseGwei-4308ad80.d.ts → parseGwei-b323fb0a.d.ts} +101 -37
- package/dist/public.d.ts +9 -9
- package/dist/public.js +4 -4
- package/dist/public.mjs +3 -3
- package/dist/{sendTransaction-1c8290a9.d.ts → sendTransaction-f17a2389.d.ts} +3 -3
- package/dist/{stopImpersonatingAccount-7781842a.d.ts → stopImpersonatingAccount-afb26486.d.ts} +2 -2
- package/dist/test.d.ts +5 -5
- package/dist/test.js +3 -3
- package/dist/test.mjs +2 -2
- package/dist/{transactionRequest-341b6ed2.d.ts → transactionRequest-93e9f001.d.ts} +2 -2
- package/dist/utils/index.d.ts +14 -16
- package/dist/utils/index.js +8 -2
- package/dist/utils/index.mjs +7 -1
- package/dist/wallet.d.ts +7 -7
- package/dist/wallet.js +3 -3
- package/dist/wallet.mjs +2 -2
- package/dist/{watchAsset-afaad3c7.d.ts → watchAsset-efd3dd05.d.ts} +3 -3
- package/dist/{watchPendingTransactions-3b722547.d.ts → watchPendingTransactions-a8688b26.d.ts} +17 -27
- package/dist/{webSocket-b180e679.d.ts → webSocket-d2e7bd0e.d.ts} +2 -2
- package/dist/window.d.ts +2 -2
- package/package.json +8 -2
- package/src/_test/abis.ts +7 -0
- package/src/_test/bench.ts +4 -4
- package/src/_test/index.ts +3 -1
- package/src/_test/utils.ts +39 -1
- package/src/actions/public/call.bench.ts +5 -5
- package/src/actions/public/deployContract.ts +4 -4
- package/src/actions/public/estimateGas.bench.ts +6 -6
- package/src/actions/public/getBlock.bench.ts +5 -5
- package/src/actions/public/getBlockNumber.bench.ts +5 -5
- package/src/actions/public/getGasPrice.bench.ts +1 -10
- package/src/actions/public/getTransaction.bench.ts +5 -5
- package/src/actions/public/getTransactionReceipt.bench.ts +5 -5
- package/src/actions/public/multicall.test.ts +452 -0
- package/src/actions/public/multicall.ts +103 -0
- package/src/actions/public/readContract.test.ts +226 -26
- package/src/actions/public/readContract.ts +13 -27
- package/src/actions/public/simulateContract.bench.ts +10 -0
- package/src/actions/public/simulateContract.test.ts +209 -37
- package/src/actions/public/simulateContract.ts +17 -21
- package/src/actions/public/watchContractEvent.test.ts +36 -32
- package/src/actions/public/watchEvent.test.ts +34 -29
- package/src/actions/wallet/signMessage.test.ts +0 -1
- package/src/actions/wallet/switchChain.test.ts +1 -2
- package/src/actions/wallet/watchAsset.test.ts +1 -2
- package/src/actions/wallet/writeContract.test.ts +37 -7
- package/src/actions/wallet/writeContract.ts +5 -14
- package/src/clients/transports/fallback.test.ts +34 -0
- package/src/clients/transports/fallback.ts +3 -1
- package/src/clients/transports/http.test.ts +0 -1
- package/src/clients/transports/webSocket.test.ts +0 -1
- package/src/constants/abis.test.ts +53 -0
- package/src/constants/abis.ts +44 -0
- package/src/constants/index.test.ts +14 -0
- package/src/constants/index.ts +3 -0
- package/src/constants/solidity.test.ts +41 -0
- package/src/constants/solidity.ts +35 -0
- package/src/ens.ts +5 -0
- package/src/errors/abi.test.ts +0 -2
- package/src/errors/base.test.ts +44 -2
- package/src/errors/base.ts +12 -12
- package/src/errors/block.test.ts +6 -6
- package/src/errors/contract.test.ts +233 -0
- package/src/errors/contract.ts +133 -80
- package/src/errors/index.ts +4 -2
- package/src/errors/request.test.ts +3 -4
- package/src/errors/request.ts +17 -17
- package/src/errors/rpc.test.ts +1 -2
- package/src/errors/transaction.test.ts +12 -12
- package/src/errors/transport.test.ts +0 -1
- package/src/index.test.ts +46 -0
- package/src/index.ts +8 -0
- package/src/types/contract.ts +55 -4
- package/src/types/index.ts +5 -0
- package/src/types/multicall.ts +82 -0
- package/src/utils/abi/decodeAbi.test.ts +1 -2
- package/src/utils/abi/decodeAbi.ts +11 -7
- package/src/utils/abi/decodeDeployData.test.ts +7 -15
- package/src/utils/abi/decodeDeployData.ts +10 -7
- package/src/utils/abi/decodeErrorResult.test.ts +103 -3
- package/src/utils/abi/decodeErrorResult.ts +30 -13
- package/src/utils/abi/decodeFunctionData.test.ts +0 -1
- package/src/utils/abi/decodeFunctionResult.test.ts +80 -9
- package/src/utils/abi/decodeFunctionResult.ts +15 -11
- package/src/utils/abi/encodeAbi.test.ts +3 -4
- package/src/utils/abi/encodeAbi.ts +19 -10
- package/src/utils/abi/encodeDeployData.test.ts +6 -13
- package/src/utils/abi/encodeDeployData.ts +10 -7
- package/src/utils/abi/encodeErrorResult.test.ts +2 -7
- package/src/utils/abi/encodeErrorResult.ts +18 -11
- package/src/utils/abi/encodeEventTopics.test.ts +11 -14
- package/src/utils/abi/encodeEventTopics.ts +15 -9
- package/src/utils/abi/encodeFunctionData.test.ts +5 -7
- package/src/utils/abi/encodeFunctionData.ts +16 -9
- package/src/utils/abi/encodeFunctionResult.test.ts +10 -15
- package/src/utils/abi/encodeFunctionResult.ts +9 -7
- package/src/utils/abi/getAbiItem.test.ts +547 -0
- package/src/utils/abi/getAbiItem.ts +93 -3
- package/src/utils/abi/index.ts +5 -1
- package/src/utils/address/getAddress.test.ts +6 -6
- package/src/utils/contract/getContractError.test.ts +247 -62
- package/src/utils/contract/getContractError.ts +30 -38
- package/src/utils/data/pad.bench.ts +0 -9
- package/src/utils/data/trim.bench.ts +0 -16
- package/src/utils/encoding/encodeBytes.bench.ts +0 -12
- package/src/utils/encoding/encodeHex.bench.ts +0 -11
- package/src/utils/ens/index.test.ts +13 -0
- package/src/utils/ens/index.ts +5 -0
- package/src/utils/ens/labelhash.test.ts +55 -0
- package/src/utils/ens/labelhash.ts +16 -0
- package/src/utils/ens/namehash.test.ts +65 -0
- package/src/utils/ens/namehash.ts +28 -0
- package/src/utils/ens/normalize.bench.ts +14 -0
- package/src/utils/ens/normalize.test.ts +35 -0
- package/src/utils/ens/normalize.ts +14 -0
- package/src/utils/hash/keccak256.ts +3 -5
- package/src/utils/index.test.ts +3 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/rpc.test.ts +3 -6
- package/src/utils/unit/formatUnit.bench.ts +0 -5
- package/src/utils/unit/parseUnit.bench.ts +0 -5
- package/dist/chunk-46BO7YAQ.mjs.map +0 -1
- package/dist/chunk-62VTYU2V.mjs.map +0 -1
- package/dist/chunk-DGO77E2H.mjs.map +0 -1
- package/dist/chunk-KEHGSYDO.js.map +0 -1
- package/dist/chunk-KZMJR27B.js.map +0 -1
- package/dist/chunk-O2GYLJVD.js.map +0 -1
@@ -14,7 +14,15 @@ test('revert SoldOutError()', () => {
|
|
14
14
|
],
|
15
15
|
data: '0x7f6df6bb',
|
16
16
|
}),
|
17
|
-
).toEqual({
|
17
|
+
).toEqual({
|
18
|
+
abiItem: {
|
19
|
+
inputs: [],
|
20
|
+
name: 'SoldOutError',
|
21
|
+
type: 'error',
|
22
|
+
},
|
23
|
+
errorName: 'SoldOutError',
|
24
|
+
args: undefined,
|
25
|
+
})
|
18
26
|
expect(
|
19
27
|
decodeErrorResult({
|
20
28
|
abi: [
|
@@ -26,7 +34,14 @@ test('revert SoldOutError()', () => {
|
|
26
34
|
],
|
27
35
|
data: '0x7f6df6bb',
|
28
36
|
}),
|
29
|
-
).toEqual({
|
37
|
+
).toEqual({
|
38
|
+
abiItem: {
|
39
|
+
name: 'SoldOutError',
|
40
|
+
type: 'error',
|
41
|
+
},
|
42
|
+
errorName: 'SoldOutError',
|
43
|
+
args: undefined,
|
44
|
+
})
|
30
45
|
})
|
31
46
|
|
32
47
|
test('revert AccessDeniedError(string)', () => {
|
@@ -48,6 +63,17 @@ test('revert AccessDeniedError(string)', () => {
|
|
48
63
|
data: '0x83aa206e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a796f7520646f206e6f7420686176652061636365737320736572000000000000',
|
49
64
|
}),
|
50
65
|
).toEqual({
|
66
|
+
abiItem: {
|
67
|
+
inputs: [
|
68
|
+
{
|
69
|
+
internalType: 'string',
|
70
|
+
name: 'a',
|
71
|
+
type: 'string',
|
72
|
+
},
|
73
|
+
],
|
74
|
+
name: 'AccessDeniedError',
|
75
|
+
type: 'error',
|
76
|
+
},
|
51
77
|
errorName: 'AccessDeniedError',
|
52
78
|
args: ['you do not have access ser'],
|
53
79
|
})
|
@@ -94,6 +120,39 @@ test('revert AccessDeniedError((uint256,bool,address,uint256))', () => {
|
|
94
120
|
data: '0x0a1895610000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000000029',
|
95
121
|
}),
|
96
122
|
).toEqual({
|
123
|
+
abiItem: {
|
124
|
+
inputs: [
|
125
|
+
{
|
126
|
+
components: [
|
127
|
+
{
|
128
|
+
internalType: 'uint256',
|
129
|
+
name: 'weight',
|
130
|
+
type: 'uint256',
|
131
|
+
},
|
132
|
+
{
|
133
|
+
internalType: 'bool',
|
134
|
+
name: 'voted',
|
135
|
+
type: 'bool',
|
136
|
+
},
|
137
|
+
{
|
138
|
+
internalType: 'address',
|
139
|
+
name: 'delegate',
|
140
|
+
type: 'address',
|
141
|
+
},
|
142
|
+
{
|
143
|
+
internalType: 'uint256',
|
144
|
+
name: 'vote',
|
145
|
+
type: 'uint256',
|
146
|
+
},
|
147
|
+
],
|
148
|
+
internalType: 'struct Ballot.Voter',
|
149
|
+
name: 'voter',
|
150
|
+
type: 'tuple',
|
151
|
+
},
|
152
|
+
],
|
153
|
+
name: 'AccessDeniedError',
|
154
|
+
type: 'error',
|
155
|
+
},
|
97
156
|
errorName: 'AccessDeniedError',
|
98
157
|
args: [
|
99
158
|
{
|
@@ -106,6 +165,48 @@ test('revert AccessDeniedError((uint256,bool,address,uint256))', () => {
|
|
106
165
|
})
|
107
166
|
})
|
108
167
|
|
168
|
+
test('Error(string)', () => {
|
169
|
+
expect(
|
170
|
+
decodeErrorResult({
|
171
|
+
data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000047465737400000000000000000000000000000000000000000000000000000000',
|
172
|
+
}),
|
173
|
+
).toEqual({
|
174
|
+
abiItem: {
|
175
|
+
inputs: [
|
176
|
+
{
|
177
|
+
name: 'message',
|
178
|
+
type: 'string',
|
179
|
+
},
|
180
|
+
],
|
181
|
+
name: 'Error',
|
182
|
+
type: 'error',
|
183
|
+
},
|
184
|
+
errorName: 'Error',
|
185
|
+
args: ['test'],
|
186
|
+
})
|
187
|
+
})
|
188
|
+
|
189
|
+
test.todo('Panic(uint256)')
|
190
|
+
|
191
|
+
test('zero data', () => {
|
192
|
+
expect(() =>
|
193
|
+
decodeErrorResult({
|
194
|
+
abi: [
|
195
|
+
{
|
196
|
+
inputs: [],
|
197
|
+
name: 'SoldOutError',
|
198
|
+
type: 'error',
|
199
|
+
},
|
200
|
+
],
|
201
|
+
data: '0x',
|
202
|
+
}),
|
203
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
204
|
+
"Cannot decode zero data (\\"0x\\") with ABI parameters.
|
205
|
+
|
206
|
+
Version: viem@1.0.2"
|
207
|
+
`)
|
208
|
+
})
|
209
|
+
|
109
210
|
test("errors: error doesn't exist", () => {
|
110
211
|
expect(() =>
|
111
212
|
decodeErrorResult({
|
@@ -124,7 +225,6 @@ test("errors: error doesn't exist", () => {
|
|
124
225
|
You can look up the signature \\"0xa3741467\\" here: https://sig.eth.samczsun.com/.
|
125
226
|
|
126
227
|
Docs: https://viem.sh/docs/contract/decodeErrorResult
|
127
|
-
|
128
228
|
Version: viem@1.0.2"
|
129
229
|
`)
|
130
230
|
})
|
@@ -1,28 +1,45 @@
|
|
1
|
-
import { Abi } from 'abitype'
|
2
|
-
import {
|
3
|
-
import {
|
1
|
+
import { Abi, AbiError } from 'abitype'
|
2
|
+
import { solidityError, solidityPanic } from '../../constants'
|
3
|
+
import {
|
4
|
+
AbiDecodingZeroDataError,
|
5
|
+
AbiErrorSignatureNotFoundError,
|
6
|
+
} from '../../errors'
|
7
|
+
import { AbiItem, Hex } from '../../types'
|
4
8
|
import { slice } from '../data'
|
5
9
|
import { getFunctionSignature } from '../hash'
|
6
10
|
import { decodeAbi } from './decodeAbi'
|
7
11
|
import { formatAbiItem } from './formatAbiItem'
|
8
12
|
|
9
|
-
export type DecodeErrorResultArgs = { abi
|
13
|
+
export type DecodeErrorResultArgs = { abi?: Abi; data: Hex }
|
10
14
|
|
11
|
-
export
|
15
|
+
export type DecodeErrorResultResponse = {
|
16
|
+
abiItem: AbiItem
|
17
|
+
errorName: string
|
18
|
+
args?: readonly unknown[]
|
19
|
+
}
|
20
|
+
|
21
|
+
export function decodeErrorResult({
|
22
|
+
abi,
|
23
|
+
data,
|
24
|
+
}: DecodeErrorResultArgs): DecodeErrorResultResponse {
|
12
25
|
const signature = slice(data, 0, 4)
|
13
|
-
|
14
|
-
|
26
|
+
if (signature === '0x') throw new AbiDecodingZeroDataError()
|
27
|
+
|
28
|
+
const abi_ = [...(abi || []), solidityError, solidityPanic]
|
29
|
+
const abiItem = abi_.find(
|
30
|
+
(x) =>
|
31
|
+
x.type === 'error' &&
|
32
|
+
signature === getFunctionSignature(formatAbiItem(x)),
|
15
33
|
)
|
16
|
-
if (!
|
34
|
+
if (!abiItem)
|
17
35
|
throw new AbiErrorSignatureNotFoundError(signature, {
|
18
36
|
docsPath: '/docs/contract/decodeErrorResult',
|
19
37
|
})
|
20
38
|
return {
|
21
|
-
|
22
|
-
args: ('inputs' in
|
23
|
-
|
24
|
-
description.inputs.length > 0
|
25
|
-
? decodeAbi({ data: slice(data, 4), params: description.inputs })
|
39
|
+
abiItem,
|
40
|
+
args: ('inputs' in abiItem && abiItem.inputs && abiItem.inputs.length > 0
|
41
|
+
? decodeAbi({ data: slice(data, 4), params: abiItem.inputs })
|
26
42
|
: undefined) as readonly unknown[] | undefined,
|
43
|
+
errorName: (abiItem as { name: string }).name,
|
27
44
|
}
|
28
45
|
}
|
@@ -13,7 +13,7 @@ test('returns ()', () => {
|
|
13
13
|
stateMutability: 'pure',
|
14
14
|
type: 'function',
|
15
15
|
},
|
16
|
-
]
|
16
|
+
],
|
17
17
|
functionName: 'foo',
|
18
18
|
data: '0x',
|
19
19
|
}),
|
@@ -28,7 +28,7 @@ test('returns ()', () => {
|
|
28
28
|
stateMutability: 'pure',
|
29
29
|
type: 'function',
|
30
30
|
},
|
31
|
-
]
|
31
|
+
],
|
32
32
|
functionName: 'foo',
|
33
33
|
// @ts-expect-error
|
34
34
|
data: '',
|
@@ -53,7 +53,7 @@ test('returns (address)', () => {
|
|
53
53
|
stateMutability: 'pure',
|
54
54
|
type: 'function',
|
55
55
|
},
|
56
|
-
]
|
56
|
+
],
|
57
57
|
functionName: 'foo',
|
58
58
|
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
|
59
59
|
}),
|
@@ -111,7 +111,7 @@ test('returns (Bar)', () => {
|
|
111
111
|
stateMutability: 'pure',
|
112
112
|
type: 'function',
|
113
113
|
},
|
114
|
-
]
|
114
|
+
],
|
115
115
|
functionName: 'bar',
|
116
116
|
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000000045',
|
117
117
|
}),
|
@@ -182,7 +182,7 @@ test('returns (Bar, string)', () => {
|
|
182
182
|
stateMutability: 'pure',
|
183
183
|
type: 'function',
|
184
184
|
},
|
185
|
-
]
|
185
|
+
],
|
186
186
|
functionName: 'baz',
|
187
187
|
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000',
|
188
188
|
}),
|
@@ -200,6 +200,79 @@ test('returns (Bar, string)', () => {
|
|
200
200
|
])
|
201
201
|
})
|
202
202
|
|
203
|
+
test('overloads', () => {
|
204
|
+
expect(
|
205
|
+
decodeFunctionResult({
|
206
|
+
abi: [
|
207
|
+
{
|
208
|
+
inputs: [{ internalType: 'uint256', name: 'x', type: 'uint256' }],
|
209
|
+
name: 'foo',
|
210
|
+
outputs: [
|
211
|
+
{
|
212
|
+
internalType: 'uint256',
|
213
|
+
name: 'x',
|
214
|
+
type: 'uint256',
|
215
|
+
},
|
216
|
+
],
|
217
|
+
stateMutability: 'pure',
|
218
|
+
type: 'function',
|
219
|
+
},
|
220
|
+
{
|
221
|
+
inputs: [],
|
222
|
+
name: 'foo',
|
223
|
+
outputs: [
|
224
|
+
{
|
225
|
+
internalType: 'address',
|
226
|
+
name: 'sender',
|
227
|
+
type: 'address',
|
228
|
+
},
|
229
|
+
],
|
230
|
+
stateMutability: 'pure',
|
231
|
+
type: 'function',
|
232
|
+
},
|
233
|
+
],
|
234
|
+
functionName: 'foo',
|
235
|
+
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
|
236
|
+
}),
|
237
|
+
).toEqual('0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC')
|
238
|
+
|
239
|
+
expect(
|
240
|
+
decodeFunctionResult({
|
241
|
+
abi: [
|
242
|
+
{
|
243
|
+
inputs: [{ internalType: 'uint256', name: 'x', type: 'uint256' }],
|
244
|
+
name: 'foo',
|
245
|
+
outputs: [
|
246
|
+
{
|
247
|
+
internalType: 'uint256',
|
248
|
+
name: 'x',
|
249
|
+
type: 'uint256',
|
250
|
+
},
|
251
|
+
],
|
252
|
+
stateMutability: 'pure',
|
253
|
+
type: 'function',
|
254
|
+
},
|
255
|
+
{
|
256
|
+
inputs: [],
|
257
|
+
name: 'foo',
|
258
|
+
outputs: [
|
259
|
+
{
|
260
|
+
internalType: 'address',
|
261
|
+
name: 'sender',
|
262
|
+
type: 'address',
|
263
|
+
},
|
264
|
+
],
|
265
|
+
stateMutability: 'pure',
|
266
|
+
type: 'function',
|
267
|
+
},
|
268
|
+
],
|
269
|
+
functionName: 'foo',
|
270
|
+
data: '0x0000000000000000000000000000000000000000000000000000000000000069',
|
271
|
+
args: [10n],
|
272
|
+
}),
|
273
|
+
).toEqual(105n)
|
274
|
+
})
|
275
|
+
|
203
276
|
test("error: function doesn't exist", () => {
|
204
277
|
expect(() =>
|
205
278
|
decodeFunctionResult({
|
@@ -217,7 +290,7 @@ test("error: function doesn't exist", () => {
|
|
217
290
|
stateMutability: 'pure',
|
218
291
|
type: 'function',
|
219
292
|
},
|
220
|
-
]
|
293
|
+
],
|
221
294
|
// @ts-expect-error
|
222
295
|
functionName: 'baz',
|
223
296
|
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
|
@@ -228,7 +301,6 @@ test("error: function doesn't exist", () => {
|
|
228
301
|
Make sure you are using the correct ABI and that the function exists on it.
|
229
302
|
|
230
303
|
Docs: https://viem.sh/docs/contract/decodeFunctionResult
|
231
|
-
|
232
304
|
Version: viem@1.0.2"
|
233
305
|
`,
|
234
306
|
)
|
@@ -244,7 +316,7 @@ test("error: function doesn't exist", () => {
|
|
244
316
|
stateMutability: 'pure',
|
245
317
|
type: 'function',
|
246
318
|
},
|
247
|
-
]
|
319
|
+
],
|
248
320
|
functionName: 'foo',
|
249
321
|
data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
|
250
322
|
}),
|
@@ -255,7 +327,6 @@ test("error: function doesn't exist", () => {
|
|
255
327
|
Make sure you are using the correct ABI and that the function exists on it.
|
256
328
|
|
257
329
|
Docs: https://viem.sh/docs/contract/decodeFunctionResult
|
258
|
-
|
259
330
|
Version: viem@1.0.2"
|
260
331
|
`,
|
261
332
|
)
|
@@ -1,46 +1,50 @@
|
|
1
|
-
import { Abi,
|
1
|
+
import { Abi, Narrow } from 'abitype'
|
2
2
|
import {
|
3
3
|
AbiFunctionNotFoundError,
|
4
4
|
AbiFunctionOutputsNotFoundError,
|
5
5
|
} from '../../errors'
|
6
|
-
|
7
6
|
import {
|
7
|
+
ExtractArgsFromAbi,
|
8
8
|
ExtractFunctionNameFromAbi,
|
9
9
|
ExtractResultFromAbi,
|
10
10
|
Hex,
|
11
11
|
} from '../../types'
|
12
12
|
import { decodeAbi } from './decodeAbi'
|
13
|
+
import { getAbiItem, GetAbiItemArgs } from './getAbiItem'
|
13
14
|
|
14
15
|
const docsPath = '/docs/contract/decodeFunctionResult'
|
15
16
|
|
16
17
|
export type DecodeFunctionResultArgs<
|
17
18
|
TAbi extends Abi | readonly unknown[] = Abi,
|
18
|
-
TFunctionName extends string =
|
19
|
+
TFunctionName extends string = string,
|
19
20
|
> = {
|
20
|
-
abi: TAbi
|
21
|
+
abi: Narrow<TAbi>
|
21
22
|
functionName: ExtractFunctionNameFromAbi<TAbi, TFunctionName>
|
22
23
|
data: Hex
|
23
|
-
}
|
24
|
+
} & Partial<ExtractArgsFromAbi<TAbi, TFunctionName>>
|
24
25
|
|
25
26
|
export type DecodeFunctionResultResponse<
|
26
27
|
TAbi extends Abi | readonly unknown[] = Abi,
|
27
|
-
TFunctionName extends string =
|
28
|
+
TFunctionName extends string = string,
|
28
29
|
> = ExtractResultFromAbi<TAbi, TFunctionName>
|
29
30
|
|
30
31
|
export function decodeFunctionResult<
|
31
|
-
TAbi extends Abi | readonly unknown[]
|
32
|
-
TFunctionName extends string
|
32
|
+
TAbi extends Abi | readonly unknown[],
|
33
|
+
TFunctionName extends string,
|
33
34
|
>({
|
34
35
|
abi,
|
36
|
+
args,
|
35
37
|
functionName,
|
36
38
|
data,
|
37
39
|
}: DecodeFunctionResultArgs<TAbi, TFunctionName>): DecodeFunctionResultResponse<
|
38
40
|
TAbi,
|
39
41
|
TFunctionName
|
40
42
|
> {
|
41
|
-
const description = (
|
42
|
-
|
43
|
-
|
43
|
+
const description = getAbiItem({
|
44
|
+
abi,
|
45
|
+
args,
|
46
|
+
name: functionName,
|
47
|
+
} as GetAbiItemArgs)
|
44
48
|
if (!description)
|
45
49
|
throw new AbiFunctionNotFoundError(functionName, { docsPath })
|
46
50
|
if (!('outputs' in description))
|
@@ -745,7 +745,7 @@ describe('static', () => {
|
|
745
745
|
{ internalType: 'uint256[2]', name: 'xOut', type: 'uint256[2]' },
|
746
746
|
{ internalType: 'bool', name: 'yOut', type: 'bool' },
|
747
747
|
{ internalType: 'string[3]', name: 'zOut', type: 'string[3]' },
|
748
|
-
]
|
748
|
+
],
|
749
749
|
values: [[420n, 69n], true, ['wagmi', 'viem', 'lol']],
|
750
750
|
}),
|
751
751
|
).toMatchInlineSnapshot(
|
@@ -885,7 +885,7 @@ describe('dynamic', () => {
|
|
885
885
|
name: 'zIn',
|
886
886
|
type: 'string',
|
887
887
|
},
|
888
|
-
]
|
888
|
+
],
|
889
889
|
values: [[420n, 69n], true, 'wagmi'],
|
890
890
|
}),
|
891
891
|
).toMatchInlineSnapshot(
|
@@ -1202,7 +1202,7 @@ describe('dynamic', () => {
|
|
1202
1202
|
name: 'wagmiIn',
|
1203
1203
|
type: 'tuple',
|
1204
1204
|
},
|
1205
|
-
]
|
1205
|
+
],
|
1206
1206
|
values: [
|
1207
1207
|
{
|
1208
1208
|
foo: {
|
@@ -1390,7 +1390,6 @@ test('invalid type', () => {
|
|
1390
1390
|
Please provide a valid ABI type.
|
1391
1391
|
|
1392
1392
|
Docs: https://viem.sh/docs/contract/encodeAbi
|
1393
|
-
|
1394
1393
|
Version: viem@1.0.2"
|
1395
1394
|
`)
|
1396
1395
|
})
|
@@ -2,6 +2,7 @@ import {
|
|
2
2
|
AbiParameter,
|
3
3
|
AbiParametersToPrimitiveTypes,
|
4
4
|
AbiParameterToPrimitiveType,
|
5
|
+
Narrow,
|
5
6
|
} from 'abitype'
|
6
7
|
|
7
8
|
import {
|
@@ -14,25 +15,33 @@ import { Hex } from '../../types'
|
|
14
15
|
import { concat, padHex, size, slice } from '../data'
|
15
16
|
import { boolToHex, numberToHex, stringToHex } from '../encoding'
|
16
17
|
|
17
|
-
export type EncodeAbiArgs<
|
18
|
-
|
19
|
-
|
18
|
+
export type EncodeAbiArgs<
|
19
|
+
TParams extends
|
20
|
+
| readonly AbiParameter[]
|
21
|
+
| readonly unknown[] = readonly AbiParameter[],
|
22
|
+
> = {
|
23
|
+
params: Narrow<TParams>
|
24
|
+
values: TParams extends readonly AbiParameter[]
|
25
|
+
? AbiParametersToPrimitiveTypes<TParams>
|
26
|
+
: never
|
20
27
|
}
|
21
28
|
|
22
29
|
/**
|
23
30
|
* @description Encodes a list of primitive values into an ABI-encoded hex value.
|
24
31
|
*/
|
25
|
-
export function encodeAbi<
|
26
|
-
|
27
|
-
|
28
|
-
}: EncodeAbiArgs<TParams>) {
|
32
|
+
export function encodeAbi<
|
33
|
+
TParams extends readonly AbiParameter[] | readonly unknown[],
|
34
|
+
>({ params, values }: EncodeAbiArgs<TParams>) {
|
29
35
|
if (params.length !== values.length)
|
30
36
|
throw new AbiEncodingLengthMismatchError({
|
31
|
-
expectedLength: params.length,
|
37
|
+
expectedLength: params.length as number,
|
32
38
|
givenLength: values.length,
|
33
39
|
})
|
34
40
|
// Prepare the parameters to determine dynamic types to encode.
|
35
|
-
const preparedParams = prepareParams({
|
41
|
+
const preparedParams = prepareParams({
|
42
|
+
params: params as readonly AbiParameter[],
|
43
|
+
values,
|
44
|
+
})
|
36
45
|
const data = encodeParams(preparedParams)
|
37
46
|
if (data.length === 0) return '0x'
|
38
47
|
return data
|
@@ -49,7 +58,7 @@ function prepareParams<TParams extends readonly AbiParameter[]>({
|
|
49
58
|
params,
|
50
59
|
values,
|
51
60
|
}: {
|
52
|
-
params: TParams
|
61
|
+
params: Narrow<TParams>
|
53
62
|
values: AbiParametersToPrimitiveTypes<TParams>
|
54
63
|
}) {
|
55
64
|
let preparedParams: PreparedParam[] = []
|
@@ -11,7 +11,7 @@ test('constructor()', () => {
|
|
11
11
|
stateMutability: 'nonpayable',
|
12
12
|
type: 'constructor',
|
13
13
|
},
|
14
|
-
]
|
14
|
+
],
|
15
15
|
bytecode:
|
16
16
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
17
17
|
}),
|
@@ -20,13 +20,12 @@ test('constructor()', () => {
|
|
20
20
|
)
|
21
21
|
expect(
|
22
22
|
encodeDeployData({
|
23
|
-
// @ts-expect-error
|
24
23
|
abi: [
|
25
24
|
{
|
26
25
|
stateMutability: 'nonpayable',
|
27
26
|
type: 'constructor',
|
28
27
|
},
|
29
|
-
]
|
28
|
+
],
|
30
29
|
bytecode:
|
31
30
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
32
31
|
}),
|
@@ -50,7 +49,7 @@ test('constructor(uint256)', () => {
|
|
50
49
|
stateMutability: 'nonpayable',
|
51
50
|
type: 'constructor',
|
52
51
|
},
|
53
|
-
]
|
52
|
+
],
|
54
53
|
bytecode:
|
55
54
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
56
55
|
args: [69420n],
|
@@ -63,8 +62,7 @@ test('constructor(uint256)', () => {
|
|
63
62
|
test('error: constructor not found', () => {
|
64
63
|
expect(() =>
|
65
64
|
encodeDeployData({
|
66
|
-
|
67
|
-
abi: [{}] as const,
|
65
|
+
abi: [{}],
|
68
66
|
bytecode:
|
69
67
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
70
68
|
args: [69420n],
|
@@ -74,7 +72,6 @@ test('error: constructor not found', () => {
|
|
74
72
|
Make sure you are using the correct ABI and that the constructor exists on it.
|
75
73
|
|
76
74
|
Docs: https://viem.sh/docs/contract/encodeDeployData
|
77
|
-
|
78
75
|
Version: viem@1.0.2"
|
79
76
|
`)
|
80
77
|
})
|
@@ -82,13 +79,12 @@ test('error: constructor not found', () => {
|
|
82
79
|
test('error: no inputs', () => {
|
83
80
|
expect(() =>
|
84
81
|
encodeDeployData({
|
85
|
-
// @ts-expect-error
|
86
82
|
abi: [
|
87
83
|
{
|
88
84
|
stateMutability: 'nonpayable',
|
89
85
|
type: 'constructor',
|
90
86
|
},
|
91
|
-
]
|
87
|
+
],
|
92
88
|
bytecode:
|
93
89
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
94
90
|
args: [69420n],
|
@@ -99,21 +95,19 @@ test('error: no inputs', () => {
|
|
99
95
|
Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
|
100
96
|
|
101
97
|
Docs: https://viem.sh/docs/contract/encodeDeployData
|
102
|
-
|
103
98
|
Version: viem@1.0.2"
|
104
99
|
`,
|
105
100
|
)
|
106
101
|
|
107
102
|
expect(() =>
|
108
103
|
encodeDeployData({
|
109
|
-
// @ts-expect-error
|
110
104
|
abi: [
|
111
105
|
{
|
112
106
|
inputs: undefined,
|
113
107
|
stateMutability: 'nonpayable',
|
114
108
|
type: 'constructor',
|
115
109
|
},
|
116
|
-
]
|
110
|
+
],
|
117
111
|
bytecode:
|
118
112
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
119
113
|
args: [69420n],
|
@@ -124,7 +118,6 @@ test('error: no inputs', () => {
|
|
124
118
|
Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
|
125
119
|
|
126
120
|
Docs: https://viem.sh/docs/contract/encodeDeployData
|
127
|
-
|
128
121
|
Version: viem@1.0.2"
|
129
122
|
`,
|
130
123
|
)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Abi } from 'abitype'
|
1
|
+
import { Abi, Narrow } from 'abitype'
|
2
2
|
|
3
3
|
import {
|
4
4
|
AbiConstructorNotFoundError,
|
@@ -10,19 +10,22 @@ import { encodeAbi } from './encodeAbi'
|
|
10
10
|
|
11
11
|
const docsPath = '/docs/contract/encodeDeployData'
|
12
12
|
|
13
|
-
export type EncodeDeployDataArgs<TAbi extends Abi = Abi> =
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
export type EncodeDeployDataArgs<TAbi extends Abi | readonly unknown[] = Abi> =
|
14
|
+
{
|
15
|
+
abi: Narrow<TAbi>
|
16
|
+
bytecode: Hex
|
17
|
+
} & ExtractConstructorArgsFromAbi<TAbi>
|
17
18
|
|
18
|
-
export function encodeDeployData<TAbi extends Abi
|
19
|
+
export function encodeDeployData<TAbi extends Abi | readonly unknown[]>({
|
19
20
|
abi,
|
20
21
|
args,
|
21
22
|
bytecode,
|
22
23
|
}: EncodeDeployDataArgs<TAbi>) {
|
23
24
|
if (!args || args.length === 0) return bytecode
|
24
25
|
|
25
|
-
const description = abi.find(
|
26
|
+
const description = (abi as Abi).find(
|
27
|
+
(x) => 'type' in x && x.type === 'constructor',
|
28
|
+
)
|
26
29
|
if (!description) throw new AbiConstructorNotFoundError({ docsPath })
|
27
30
|
if (!('inputs' in description))
|
28
31
|
throw new AbiConstructorParamsNotFoundError({ docsPath })
|