viem 0.0.1-alpha.21 → 0.0.1-alpha.23
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-EC3NUIJE.js → chunk-7Y5QVLX7.js} +13 -13
- package/dist/{chunk-EC3NUIJE.js.map → chunk-7Y5QVLX7.js.map} +1 -1
- package/dist/{chunk-KEHGSYDO.js → chunk-BV5NTHUX.js} +14 -13
- package/dist/chunk-BV5NTHUX.js.map +1 -0
- package/dist/{chunk-46BO7YAQ.mjs → chunk-EGVXCZNJ.mjs} +4 -3
- package/dist/chunk-EGVXCZNJ.mjs.map +1 -0
- package/dist/{chunk-57ZOFERP.mjs → chunk-GX2KDAM3.mjs} +2 -2
- package/dist/{chunk-57ZOFERP.mjs.map → chunk-GX2KDAM3.mjs.map} +0 -0
- package/dist/{chunk-W7BWWAC4.js → chunk-NW6724MI.js} +14 -14
- package/dist/{chunk-W7BWWAC4.js.map → chunk-NW6724MI.js.map} +0 -0
- package/dist/{chunk-DGO77E2H.mjs → chunk-RJLUZTJS.mjs} +86 -3
- package/dist/chunk-RJLUZTJS.mjs.map +1 -0
- package/dist/{chunk-O2GYLJVD.js → chunk-SSPRUPGN.js} +405 -165
- package/dist/chunk-SSPRUPGN.js.map +1 -0
- package/dist/{chunk-DSPMAIDO.mjs → chunk-TXHOG6KU.mjs} +2 -2
- package/dist/{chunk-DSPMAIDO.mjs.map → chunk-TXHOG6KU.mjs.map} +1 -1
- package/dist/{chunk-62VTYU2V.mjs → chunk-XBUH66KN.mjs} +406 -166
- package/dist/chunk-XBUH66KN.mjs.map +1 -0
- package/dist/{chunk-KZMJR27B.js → chunk-ZKYGWITF.js} +147 -64
- package/dist/chunk-ZKYGWITF.js.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-4c3a37b3.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 +174 -113
- package/dist/index.js +16 -6
- package/dist/index.mjs +15 -5
- package/dist/normalize-ef9240c0.d.ts +33 -0
- package/dist/{parseGwei-4308ad80.d.ts → parseGwei-3411cf2d.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-57df1a13.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/constants.ts +4 -3
- package/src/_test/index.ts +4 -2
- package/src/_test/utils.ts +39 -1
- package/src/actions/index.test.ts +1 -0
- package/src/actions/index.ts +2 -0
- 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/getFilterChanges.test.ts +9 -9
- package/src/actions/public/getFilterLogs.test.ts +7 -7
- package/src/actions/public/getGasPrice.bench.ts +1 -10
- package/src/actions/public/getLogs.test.ts +7 -7
- package/src/actions/public/getTransaction.bench.ts +5 -5
- package/src/actions/public/getTransactionReceipt.bench.ts +5 -5
- package/src/actions/public/index.test.ts +1 -0
- package/src/actions/public/index.ts +3 -0
- 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 +61 -57
- package/src/actions/public/watchEvent.test.ts +42 -37
- package/src/actions/test/impersonateAccount.test.ts +4 -6
- package/src/actions/test/sendUnsignedTransaction.test.ts +2 -2
- package/src/actions/test/stopImpersonatingAccount.test.ts +5 -7
- 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 +47 -0
- package/src/index.ts +10 -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
@@ -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
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
@@ -22,13 +22,12 @@ test('constructor()', () => {
|
|
22
22
|
})
|
23
23
|
expect(
|
24
24
|
decodeDeployData({
|
25
|
-
// @ts-expect-error
|
26
25
|
abi: [
|
27
26
|
{
|
28
27
|
stateMutability: 'nonpayable',
|
29
28
|
type: 'constructor',
|
30
29
|
},
|
31
|
-
]
|
30
|
+
],
|
32
31
|
bytecode:
|
33
32
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
34
33
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
@@ -54,7 +53,7 @@ test('constructor(uint256)', () => {
|
|
54
53
|
stateMutability: 'nonpayable',
|
55
54
|
type: 'constructor',
|
56
55
|
},
|
57
|
-
]
|
56
|
+
],
|
58
57
|
bytecode:
|
59
58
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
60
59
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
|
@@ -69,8 +68,7 @@ test('constructor(uint256)', () => {
|
|
69
68
|
test('error: constructor not found', () => {
|
70
69
|
expect(() =>
|
71
70
|
decodeDeployData({
|
72
|
-
|
73
|
-
abi: [{}] as const,
|
71
|
+
abi: [{}],
|
74
72
|
bytecode:
|
75
73
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
76
74
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
|
@@ -80,7 +78,6 @@ test('error: constructor not found', () => {
|
|
80
78
|
Make sure you are using the correct ABI and that the constructor exists on it.
|
81
79
|
|
82
80
|
Docs: https://viem.sh/docs/contract/decodeDeployData
|
83
|
-
|
84
81
|
Version: viem@1.0.2"
|
85
82
|
`)
|
86
83
|
})
|
@@ -88,13 +85,12 @@ test('error: constructor not found', () => {
|
|
88
85
|
test('error: no inputs', () => {
|
89
86
|
expect(() =>
|
90
87
|
decodeDeployData({
|
91
|
-
// @ts-expect-error
|
92
88
|
abi: [
|
93
89
|
{
|
94
90
|
stateMutability: 'nonpayable',
|
95
91
|
type: 'constructor',
|
96
92
|
},
|
97
|
-
]
|
93
|
+
],
|
98
94
|
bytecode:
|
99
95
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
100
96
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
|
@@ -105,7 +101,6 @@ test('error: no inputs', () => {
|
|
105
101
|
Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
|
106
102
|
|
107
103
|
Docs: https://viem.sh/docs/contract/decodeDeployData
|
108
|
-
|
109
104
|
Version: viem@1.0.2"
|
110
105
|
`,
|
111
106
|
)
|
@@ -117,7 +112,7 @@ test('error: no inputs', () => {
|
|
117
112
|
stateMutability: 'nonpayable',
|
118
113
|
type: 'constructor',
|
119
114
|
},
|
120
|
-
]
|
115
|
+
],
|
121
116
|
bytecode:
|
122
117
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
123
118
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
|
@@ -128,20 +123,18 @@ test('error: no inputs', () => {
|
|
128
123
|
Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
|
129
124
|
|
130
125
|
Docs: https://viem.sh/docs/contract/decodeDeployData
|
131
|
-
|
132
126
|
Version: viem@1.0.2"
|
133
127
|
`,
|
134
128
|
)
|
135
129
|
expect(() =>
|
136
130
|
decodeDeployData({
|
137
|
-
// @ts-expect-error
|
138
131
|
abi: [
|
139
132
|
{
|
140
133
|
inputs: undefined,
|
141
134
|
stateMutability: 'nonpayable',
|
142
135
|
type: 'constructor',
|
143
136
|
},
|
144
|
-
]
|
137
|
+
],
|
145
138
|
bytecode:
|
146
139
|
'0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
|
147
140
|
data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
|
@@ -152,7 +145,6 @@ test('error: no inputs', () => {
|
|
152
145
|
Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
|
153
146
|
|
154
147
|
Docs: https://viem.sh/docs/contract/decodeDeployData
|
155
|
-
|
156
148
|
Version: viem@1.0.2"
|
157
149
|
`,
|
158
150
|
)
|
@@ -9,24 +9,27 @@ import { decodeAbi } from './decodeAbi'
|
|
9
9
|
|
10
10
|
const docsPath = '/docs/contract/decodeDeployData'
|
11
11
|
|
12
|
-
export type DecodeDeployDataArgs<TAbi extends Abi = Abi> =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
export type DecodeDeployDataArgs<TAbi extends Abi | readonly unknown[] = Abi> =
|
13
|
+
{
|
14
|
+
abi: TAbi
|
15
|
+
bytecode: Hex
|
16
|
+
data: Hex
|
17
|
+
}
|
17
18
|
export type DecodeDeployDataResponse = {
|
18
19
|
args?: readonly unknown[] | undefined
|
19
20
|
bytecode: Hex
|
20
21
|
}
|
21
22
|
|
22
|
-
export function decodeDeployData<TAbi extends Abi
|
23
|
+
export function decodeDeployData<TAbi extends Abi | readonly unknown[]>({
|
23
24
|
abi,
|
24
25
|
bytecode,
|
25
26
|
data,
|
26
27
|
}: DecodeDeployDataArgs<TAbi>): DecodeDeployDataResponse {
|
27
28
|
if (data === bytecode) return { bytecode }
|
28
29
|
|
29
|
-
const description = abi.find(
|
30
|
+
const description = (abi as Abi).find(
|
31
|
+
(x) => 'type' in x && x.type === 'constructor',
|
32
|
+
)
|
30
33
|
if (!description) throw new AbiConstructorNotFoundError({ docsPath })
|
31
34
|
if (!('inputs' in description))
|
32
35
|
throw new AbiConstructorParamsNotFoundError({ docsPath })
|
@@ -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[] = []
|