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
package/src/errors/base.test.ts
CHANGED
@@ -17,6 +17,13 @@ test('BaseError', () => {
|
|
17
17
|
Details: details
|
18
18
|
Version: viem@1.0.2]
|
19
19
|
`)
|
20
|
+
|
21
|
+
expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(`
|
22
|
+
[ViemError: An error occurred.
|
23
|
+
|
24
|
+
Details: details
|
25
|
+
Version: viem@1.0.2]
|
26
|
+
`)
|
20
27
|
})
|
21
28
|
|
22
29
|
test('BaseError (w/ docsPath)', () => {
|
@@ -29,6 +36,43 @@ test('BaseError (w/ docsPath)', () => {
|
|
29
36
|
[ViemError: An error occurred.
|
30
37
|
|
31
38
|
Docs: https://viem.sh/lol
|
39
|
+
Details: details
|
40
|
+
Version: viem@1.0.2]
|
41
|
+
`)
|
42
|
+
expect(
|
43
|
+
new BaseError('An error occurred.', {
|
44
|
+
cause: new BaseError('error', { docsPath: '/docs' }),
|
45
|
+
}),
|
46
|
+
).toMatchInlineSnapshot(`
|
47
|
+
[ViemError: An error occurred.
|
48
|
+
|
49
|
+
Docs: https://viem.sh/docs
|
50
|
+
Version: viem@1.0.2]
|
51
|
+
`)
|
52
|
+
expect(
|
53
|
+
new BaseError('An error occurred.', {
|
54
|
+
cause: new BaseError('error'),
|
55
|
+
docsPath: '/lol',
|
56
|
+
}),
|
57
|
+
).toMatchInlineSnapshot(`
|
58
|
+
[ViemError: An error occurred.
|
59
|
+
|
60
|
+
Docs: https://viem.sh/lol
|
61
|
+
Version: viem@1.0.2]
|
62
|
+
`)
|
63
|
+
})
|
64
|
+
|
65
|
+
test('BaseError (w/ metaMessages)', () => {
|
66
|
+
expect(
|
67
|
+
new BaseError('An error occurred.', {
|
68
|
+
details: 'details',
|
69
|
+
metaMessages: ['Reason: idk', 'Cause: lol'],
|
70
|
+
}),
|
71
|
+
).toMatchInlineSnapshot(`
|
72
|
+
[ViemError: An error occurred.
|
73
|
+
|
74
|
+
Reason: idk
|
75
|
+
Cause: lol
|
32
76
|
|
33
77
|
Details: details
|
34
78
|
Version: viem@1.0.2]
|
@@ -48,7 +92,6 @@ test('inherited BaseError', () => {
|
|
48
92
|
[ViemError: An internal error occurred.
|
49
93
|
|
50
94
|
Docs: https://viem.sh/lol
|
51
|
-
|
52
95
|
Details: details
|
53
96
|
Version: viem@1.0.2]
|
54
97
|
`)
|
@@ -65,7 +108,6 @@ test('inherited Error', () => {
|
|
65
108
|
[ViemError: An internal error occurred.
|
66
109
|
|
67
110
|
Docs: https://viem.sh/lol
|
68
|
-
|
69
111
|
Details: details
|
70
112
|
Version: viem@1.0.2]
|
71
113
|
`)
|
package/src/errors/base.ts
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
// @ts-ignore
|
2
2
|
import pkg from '../../package.json'
|
3
|
-
import { stringify } from '../utils/stringify'
|
4
3
|
|
5
4
|
/* c8 ignore next */
|
6
5
|
const version = process.env.TEST ? '1.0.2' : pkg.version
|
7
6
|
|
8
|
-
type BaseErrorArgs = {
|
7
|
+
type BaseErrorArgs = {
|
8
|
+
docsPath?: string
|
9
|
+
metaMessages?: string[]
|
10
|
+
} & (
|
9
11
|
| {
|
10
12
|
cause?: never
|
11
13
|
details?: string
|
@@ -17,13 +19,14 @@ type BaseErrorArgs = { docsPath?: string } & (
|
|
17
19
|
)
|
18
20
|
|
19
21
|
export class BaseError extends Error {
|
20
|
-
humanMessage: string
|
21
22
|
details: string
|
22
23
|
docsPath?: string
|
24
|
+
metaMessages?: string[]
|
25
|
+
shortMessage: string
|
23
26
|
|
24
27
|
name = 'ViemError'
|
25
28
|
|
26
|
-
constructor(
|
29
|
+
constructor(shortMessage: string, args: BaseErrorArgs = {}) {
|
27
30
|
const details =
|
28
31
|
args.cause instanceof BaseError
|
29
32
|
? args.cause.details
|
@@ -35,16 +38,12 @@ export class BaseError extends Error {
|
|
35
38
|
? args.cause.docsPath || args.docsPath
|
36
39
|
: args.docsPath
|
37
40
|
const message = [
|
38
|
-
|
39
|
-
...(docsPath ? ['', `Docs: https://viem.sh${docsPath}`] : []),
|
41
|
+
shortMessage || 'An error occurred.',
|
40
42
|
'',
|
43
|
+
...(args.metaMessages ? [...args.metaMessages, ''] : []),
|
44
|
+
...(docsPath ? [`Docs: https://viem.sh${docsPath}`] : []),
|
41
45
|
...(details ? [`Details: ${details}`] : []),
|
42
46
|
`Version: viem@${version}`,
|
43
|
-
...(args.cause &&
|
44
|
-
!(args.cause instanceof BaseError) &&
|
45
|
-
Object.keys(args.cause).length > 0
|
46
|
-
? [`Internal Error: ${stringify(args.cause)}`]
|
47
|
-
: []),
|
48
47
|
].join('\n')
|
49
48
|
|
50
49
|
super(message)
|
@@ -52,6 +51,7 @@ export class BaseError extends Error {
|
|
52
51
|
if (args.cause) this.cause = args.cause
|
53
52
|
this.details = details
|
54
53
|
this.docsPath = docsPath
|
55
|
-
this.
|
54
|
+
this.metaMessages = args.metaMessages
|
55
|
+
this.shortMessage = shortMessage
|
56
56
|
}
|
57
57
|
}
|
package/src/errors/block.test.ts
CHANGED
@@ -5,17 +5,17 @@ test('BlockNotFoundError', () => {
|
|
5
5
|
expect(
|
6
6
|
new BlockNotFoundError({ blockNumber: 69420n }),
|
7
7
|
).toMatchInlineSnapshot(`
|
8
|
-
|
8
|
+
[BlockNotFoundError: Block at number "69420" could not be found.
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
Version: viem@1.0.2]
|
11
|
+
`)
|
12
12
|
expect(
|
13
13
|
new BlockNotFoundError({ blockHash: '0x69420' }),
|
14
14
|
).toMatchInlineSnapshot(`
|
15
|
-
|
15
|
+
[BlockNotFoundError: Block at hash "0x69420" could not be found.
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
Version: viem@1.0.2]
|
18
|
+
`)
|
19
19
|
expect(new BlockNotFoundError({})).toMatchInlineSnapshot(`
|
20
20
|
[BlockNotFoundError: Block could not be found.
|
21
21
|
|
@@ -0,0 +1,233 @@
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
2
|
+
import { baycContractConfig } from '../_test/abis'
|
3
|
+
import { errorsExampleABI } from '../_test/generated'
|
4
|
+
import { BaseError } from './base'
|
5
|
+
import {
|
6
|
+
ContractFunctionExecutionError,
|
7
|
+
ContractFunctionRevertedError,
|
8
|
+
RawContractError,
|
9
|
+
} from './contract'
|
10
|
+
|
11
|
+
describe('ContractFunctionExecutionError', () => {
|
12
|
+
test('default', () => {
|
13
|
+
expect(
|
14
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
15
|
+
abi: baycContractConfig.abi,
|
16
|
+
functionName: 'totalSupply',
|
17
|
+
}),
|
18
|
+
).toMatchInlineSnapshot(`
|
19
|
+
[ContractFunctionExecutionError: Internal error.
|
20
|
+
|
21
|
+
Function: totalSupply()
|
22
|
+
|
23
|
+
Version: viem@1.0.2]
|
24
|
+
`)
|
25
|
+
})
|
26
|
+
|
27
|
+
test('args: contractAddress', () => {
|
28
|
+
expect(
|
29
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
30
|
+
abi: baycContractConfig.abi,
|
31
|
+
functionName: 'totalSupply',
|
32
|
+
contractAddress: '0x0000000000000000000000000000000000000000',
|
33
|
+
}),
|
34
|
+
).toMatchInlineSnapshot(`
|
35
|
+
[ContractFunctionExecutionError: Internal error.
|
36
|
+
|
37
|
+
Contract: 0x0000000000000000000000000000000000000000
|
38
|
+
Function: totalSupply()
|
39
|
+
|
40
|
+
Version: viem@1.0.2]
|
41
|
+
`)
|
42
|
+
})
|
43
|
+
|
44
|
+
test('args: args', () => {
|
45
|
+
expect(
|
46
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
47
|
+
abi: baycContractConfig.abi,
|
48
|
+
functionName: 'mintApe',
|
49
|
+
args: [1n],
|
50
|
+
contractAddress: '0x0000000000000000000000000000000000000000',
|
51
|
+
}),
|
52
|
+
).toMatchInlineSnapshot(`
|
53
|
+
[ContractFunctionExecutionError: Internal error.
|
54
|
+
|
55
|
+
Contract: 0x0000000000000000000000000000000000000000
|
56
|
+
Function: mintApe(uint256 numberOfTokens)
|
57
|
+
Arguments: (1)
|
58
|
+
|
59
|
+
Version: viem@1.0.2]
|
60
|
+
`)
|
61
|
+
})
|
62
|
+
|
63
|
+
test('args: docsPath', () => {
|
64
|
+
expect(
|
65
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
66
|
+
abi: baycContractConfig.abi,
|
67
|
+
functionName: 'mintApe',
|
68
|
+
args: [1n],
|
69
|
+
contractAddress: '0x0000000000000000000000000000000000000000',
|
70
|
+
docsPath: '/docs',
|
71
|
+
}),
|
72
|
+
).toMatchInlineSnapshot(`
|
73
|
+
[ContractFunctionExecutionError: Internal error.
|
74
|
+
|
75
|
+
Contract: 0x0000000000000000000000000000000000000000
|
76
|
+
Function: mintApe(uint256 numberOfTokens)
|
77
|
+
Arguments: (1)
|
78
|
+
|
79
|
+
Docs: https://viem.sh/docs
|
80
|
+
Version: viem@1.0.2]
|
81
|
+
`)
|
82
|
+
})
|
83
|
+
|
84
|
+
test('args: sender', () => {
|
85
|
+
expect(
|
86
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
87
|
+
abi: baycContractConfig.abi,
|
88
|
+
functionName: 'mintApe',
|
89
|
+
args: [1n],
|
90
|
+
contractAddress: '0x0000000000000000000000000000000000000000',
|
91
|
+
sender: '0x0000000000000000000000000000000000000000',
|
92
|
+
}),
|
93
|
+
).toMatchInlineSnapshot(`
|
94
|
+
[ContractFunctionExecutionError: Internal error.
|
95
|
+
|
96
|
+
Contract: 0x0000000000000000000000000000000000000000
|
97
|
+
Function: mintApe(uint256 numberOfTokens)
|
98
|
+
Arguments: (1)
|
99
|
+
Sender: 0x0000000000000000000000000000000000000000
|
100
|
+
|
101
|
+
Version: viem@1.0.2]
|
102
|
+
`)
|
103
|
+
})
|
104
|
+
|
105
|
+
test('cause: metaMessages', () => {
|
106
|
+
expect(
|
107
|
+
new ContractFunctionExecutionError(
|
108
|
+
new BaseError('Internal error.', { metaMessages: ['foo', 'bar'] }),
|
109
|
+
{
|
110
|
+
abi: baycContractConfig.abi,
|
111
|
+
functionName: 'totalSupply',
|
112
|
+
contractAddress: '0x0000000000000000000000000000000000000000',
|
113
|
+
},
|
114
|
+
),
|
115
|
+
).toMatchInlineSnapshot(`
|
116
|
+
[ContractFunctionExecutionError: Internal error.
|
117
|
+
|
118
|
+
foo
|
119
|
+
bar
|
120
|
+
|
121
|
+
Contract: 0x0000000000000000000000000000000000000000
|
122
|
+
Function: totalSupply()
|
123
|
+
|
124
|
+
Version: viem@1.0.2]
|
125
|
+
`)
|
126
|
+
})
|
127
|
+
|
128
|
+
test('no message', () => {
|
129
|
+
expect(
|
130
|
+
new ContractFunctionExecutionError(new BaseError(''), {
|
131
|
+
abi: baycContractConfig.abi,
|
132
|
+
functionName: 'foo',
|
133
|
+
}),
|
134
|
+
).toMatchInlineSnapshot(`
|
135
|
+
[ContractFunctionExecutionError: An unknown error occurred while executing the contract function "foo".
|
136
|
+
|
137
|
+
|
138
|
+
Version: viem@1.0.2]
|
139
|
+
`)
|
140
|
+
})
|
141
|
+
|
142
|
+
test('function does not exist', () => {
|
143
|
+
expect(
|
144
|
+
new ContractFunctionExecutionError(new BaseError('Internal error.'), {
|
145
|
+
abi: baycContractConfig.abi,
|
146
|
+
functionName: 'foo',
|
147
|
+
}),
|
148
|
+
).toMatchInlineSnapshot(`
|
149
|
+
[ContractFunctionExecutionError: Internal error.
|
150
|
+
|
151
|
+
|
152
|
+
Version: viem@1.0.2]
|
153
|
+
`)
|
154
|
+
})
|
155
|
+
})
|
156
|
+
|
157
|
+
describe('ContractFunctionRevertedError', () => {
|
158
|
+
test('default', () => {
|
159
|
+
expect(
|
160
|
+
new ContractFunctionRevertedError({
|
161
|
+
abi: errorsExampleABI,
|
162
|
+
message: 'oh no',
|
163
|
+
functionName: 'totalSupply',
|
164
|
+
}),
|
165
|
+
).toMatchInlineSnapshot(`
|
166
|
+
[ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason:
|
167
|
+
oh no
|
168
|
+
|
169
|
+
Version: viem@1.0.2]
|
170
|
+
`)
|
171
|
+
})
|
172
|
+
|
173
|
+
test('data: Error(string)', () => {
|
174
|
+
expect(
|
175
|
+
new ContractFunctionRevertedError({
|
176
|
+
abi: errorsExampleABI,
|
177
|
+
data: '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000022456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473000000000000000000000000000000000000000000000000000000000000',
|
178
|
+
functionName: 'totalSupply',
|
179
|
+
}),
|
180
|
+
).toMatchInlineSnapshot(`
|
181
|
+
[ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason:
|
182
|
+
EnumerableSet: index out of bounds
|
183
|
+
|
184
|
+
Version: viem@1.0.2]
|
185
|
+
`)
|
186
|
+
})
|
187
|
+
|
188
|
+
test('data: Panic(uint256)', () => {
|
189
|
+
expect(
|
190
|
+
new ContractFunctionRevertedError({
|
191
|
+
abi: errorsExampleABI,
|
192
|
+
data: '0x4e487b710000000000000000000000000000000000000000000000000000000000000001',
|
193
|
+
functionName: 'totalSupply',
|
194
|
+
}),
|
195
|
+
).toMatchInlineSnapshot(`
|
196
|
+
[ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason:
|
197
|
+
An \`assert\` condition failed.
|
198
|
+
|
199
|
+
Version: viem@1.0.2]
|
200
|
+
`)
|
201
|
+
})
|
202
|
+
|
203
|
+
test('data: custom error', () => {
|
204
|
+
expect(
|
205
|
+
new ContractFunctionRevertedError({
|
206
|
+
abi: errorsExampleABI,
|
207
|
+
data: '0xdb731cf4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000066275676765720000000000000000000000000000000000000000000000000000',
|
208
|
+
functionName: 'customComplexError',
|
209
|
+
}),
|
210
|
+
).toMatchInlineSnapshot(`
|
211
|
+
[ContractFunctionRevertedError: The contract function "customComplexError" reverted.
|
212
|
+
|
213
|
+
Error: ComplexError((address sender, uint256 bar), string message, uint256 number)
|
214
|
+
Arguments: ({"sender":"0x0000000000000000000000000000000000000000","bar":"69"}, bugger, 69)
|
215
|
+
|
216
|
+
Version: viem@1.0.2]
|
217
|
+
`)
|
218
|
+
})
|
219
|
+
|
220
|
+
test('data: zero data', () => {
|
221
|
+
expect(
|
222
|
+
new ContractFunctionRevertedError({
|
223
|
+
abi: errorsExampleABI,
|
224
|
+
data: '0x',
|
225
|
+
functionName: 'customComplexError',
|
226
|
+
}),
|
227
|
+
).toMatchInlineSnapshot(`
|
228
|
+
[ContractFunctionRevertedError: The contract function "customComplexError" reverted.
|
229
|
+
|
230
|
+
Version: viem@1.0.2]
|
231
|
+
`)
|
232
|
+
})
|
233
|
+
})
|
package/src/errors/contract.ts
CHANGED
@@ -1,125 +1,178 @@
|
|
1
1
|
import { Abi } from 'abitype'
|
2
|
-
import {
|
2
|
+
import { panicReasons } from '../constants'
|
3
|
+
import { Address, Hex } from '../types'
|
4
|
+
import {
|
5
|
+
DecodeErrorResultResponse,
|
6
|
+
decodeErrorResult,
|
7
|
+
getAbiItem,
|
8
|
+
formatAbiItemWithArgs,
|
9
|
+
formatAbiItem,
|
10
|
+
} from '../utils'
|
3
11
|
import { BaseError } from './base'
|
4
12
|
|
5
|
-
export class
|
6
|
-
abi
|
13
|
+
export class ContractFunctionExecutionError extends BaseError {
|
14
|
+
abi: Abi
|
7
15
|
args?: unknown[]
|
16
|
+
cause: BaseError
|
8
17
|
contractAddress?: Address
|
9
18
|
formattedArgs?: string
|
10
|
-
functionName
|
11
|
-
reason?: string
|
19
|
+
functionName: string
|
12
20
|
sender?: Address
|
13
21
|
|
14
|
-
name = '
|
22
|
+
name = 'ContractFunctionExecutionError'
|
15
23
|
|
16
24
|
constructor(
|
17
|
-
|
25
|
+
cause: BaseError,
|
18
26
|
{
|
19
27
|
abi,
|
20
28
|
args,
|
21
|
-
cause,
|
22
29
|
contractAddress,
|
23
|
-
|
30
|
+
docsPath,
|
24
31
|
functionName,
|
25
|
-
functionWithParams,
|
26
32
|
sender,
|
27
33
|
}: {
|
28
|
-
abi
|
34
|
+
abi: Abi
|
29
35
|
args?: any
|
30
|
-
cause?: Error
|
31
36
|
contractAddress?: Address
|
32
|
-
|
33
|
-
functionName
|
34
|
-
functionWithParams?: string
|
37
|
+
docsPath?: string
|
38
|
+
functionName: string
|
35
39
|
sender?: Address
|
36
|
-
}
|
40
|
+
},
|
37
41
|
) {
|
42
|
+
const abiItem = getAbiItem({ abi, args, name: functionName })
|
43
|
+
const formattedArgs = abiItem
|
44
|
+
? formatAbiItemWithArgs({
|
45
|
+
abiItem,
|
46
|
+
args,
|
47
|
+
includeFunctionName: false,
|
48
|
+
includeName: false,
|
49
|
+
})
|
50
|
+
: undefined
|
51
|
+
const functionWithParams = abiItem
|
52
|
+
? formatAbiItem(abiItem, { includeName: true })
|
53
|
+
: undefined
|
54
|
+
|
38
55
|
super(
|
39
|
-
|
40
|
-
|
41
|
-
' ',
|
42
|
-
sender && `Sender: ${sender}`,
|
43
|
-
contractAddress &&
|
44
|
-
`Contract: ${
|
45
|
-
/* c8 ignore start */
|
46
|
-
process.env.TEST
|
47
|
-
? '0x0000000000000000000000000000000000000000'
|
48
|
-
: contractAddress
|
49
|
-
/* c8 ignore end */
|
50
|
-
}`,
|
51
|
-
functionWithParams && `Function: ${functionWithParams}`,
|
52
|
-
formattedArgs &&
|
53
|
-
`Arguments: ${[...Array(functionName?.length ?? 0).keys()]
|
54
|
-
.map(() => ' ')
|
55
|
-
.join('')}${formattedArgs}`,
|
56
|
-
]
|
57
|
-
.filter(Boolean)
|
58
|
-
.join('\n'),
|
56
|
+
cause.shortMessage ||
|
57
|
+
`An unknown error occurred while executing the contract function "${functionName}".`,
|
59
58
|
{
|
60
59
|
cause,
|
60
|
+
docsPath,
|
61
|
+
metaMessages: [
|
62
|
+
...(cause.metaMessages ? [...cause.metaMessages, ' '] : []),
|
63
|
+
contractAddress &&
|
64
|
+
`Contract: ${
|
65
|
+
/* c8 ignore start */
|
66
|
+
process.env.TEST
|
67
|
+
? '0x0000000000000000000000000000000000000000'
|
68
|
+
: contractAddress
|
69
|
+
/* c8 ignore end */
|
70
|
+
}`,
|
71
|
+
functionWithParams && `Function: ${functionWithParams}`,
|
72
|
+
formattedArgs &&
|
73
|
+
formattedArgs !== '()' &&
|
74
|
+
`Arguments: ${[...Array(functionName?.length ?? 0).keys()]
|
75
|
+
.map(() => ' ')
|
76
|
+
.join('')}${formattedArgs}`,
|
77
|
+
sender && `Sender: ${sender}`,
|
78
|
+
].filter(Boolean) as string[],
|
61
79
|
},
|
62
80
|
)
|
63
|
-
if (message) this.reason = message
|
64
81
|
this.abi = abi
|
65
82
|
this.args = args
|
83
|
+
this.cause = cause
|
66
84
|
this.contractAddress = contractAddress
|
67
85
|
this.functionName = functionName
|
68
86
|
this.sender = sender
|
69
87
|
}
|
70
88
|
}
|
71
89
|
|
72
|
-
export class
|
73
|
-
|
74
|
-
args?: unknown[]
|
75
|
-
contractAddress?: Address
|
76
|
-
functionName?: string
|
77
|
-
functionWithParams?: string
|
90
|
+
export class ContractFunctionRevertedError extends BaseError {
|
91
|
+
name = 'ContractFunctionRevertedError'
|
78
92
|
|
79
|
-
|
93
|
+
data?: DecodeErrorResultResponse
|
94
|
+
reason?: string
|
80
95
|
|
81
96
|
constructor({
|
82
97
|
abi,
|
83
|
-
|
84
|
-
cause,
|
85
|
-
contractAddress,
|
98
|
+
data,
|
86
99
|
functionName,
|
87
|
-
|
88
|
-
}: {
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
100
|
+
message,
|
101
|
+
}: { abi: Abi; data?: Hex; functionName: string; message?: string }) {
|
102
|
+
let decodedData: DecodeErrorResultResponse | undefined = undefined
|
103
|
+
let metaMessages
|
104
|
+
let reason
|
105
|
+
if (data && data !== '0x') {
|
106
|
+
decodedData = decodeErrorResult({ abi, data })
|
107
|
+
const { abiItem, errorName, args: errorArgs } = decodedData
|
108
|
+
if (errorName === 'Error') {
|
109
|
+
reason = (errorArgs as [string])[0]
|
110
|
+
} else if (errorName === 'Panic') {
|
111
|
+
const [firstArg] = errorArgs as [number]
|
112
|
+
reason = panicReasons[firstArg as keyof typeof panicReasons]
|
113
|
+
} else if (errorArgs) {
|
114
|
+
const errorWithParams = abiItem
|
115
|
+
? formatAbiItem(abiItem, { includeName: true })
|
116
|
+
: undefined
|
117
|
+
const formattedArgs = abiItem
|
118
|
+
? formatAbiItemWithArgs({
|
119
|
+
abiItem,
|
120
|
+
args: errorArgs,
|
121
|
+
includeFunctionName: false,
|
122
|
+
includeName: false,
|
123
|
+
})
|
124
|
+
: undefined
|
125
|
+
|
126
|
+
metaMessages = [
|
127
|
+
errorWithParams ? `Error: ${errorWithParams}` : '',
|
128
|
+
formattedArgs && formattedArgs !== '()'
|
129
|
+
? `Arguments: ${[...Array(errorName?.length ?? 0).keys()]
|
130
|
+
.map(() => ' ')
|
131
|
+
.join('')}${formattedArgs}`
|
132
|
+
: '',
|
133
|
+
]
|
134
|
+
}
|
135
|
+
} else if (message) reason = message
|
136
|
+
|
96
137
|
super(
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
contractAddress &&
|
104
|
-
`Contract: ${
|
105
|
-
/* c8 ignore start */
|
106
|
-
process.env.TEST
|
107
|
-
? '0x0000000000000000000000000000000000000000'
|
108
|
-
: contractAddress
|
109
|
-
/* c8 ignore end */
|
110
|
-
}`,
|
111
|
-
functionWithParams && `Function: ${functionWithParams}`,
|
112
|
-
functionWithParams && ` > "0x"`,
|
113
|
-
]
|
114
|
-
.filter(Boolean)
|
115
|
-
.join('\n'),
|
138
|
+
reason
|
139
|
+
? [
|
140
|
+
`The contract function "${functionName}" reverted with the following reason:`,
|
141
|
+
reason,
|
142
|
+
].join('\n')
|
143
|
+
: `The contract function "${functionName}" reverted.`,
|
116
144
|
{
|
117
|
-
|
145
|
+
metaMessages,
|
118
146
|
},
|
119
147
|
)
|
120
|
-
|
121
|
-
this.
|
122
|
-
this.
|
123
|
-
|
148
|
+
|
149
|
+
this.reason = reason
|
150
|
+
this.data = decodedData
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
export class ContractFunctionZeroDataError extends BaseError {
|
155
|
+
name = 'ContractFunctionZeroDataError'
|
156
|
+
constructor({ functionName }: { functionName: string }) {
|
157
|
+
super(`The contract function "${functionName}" returned no data ("0x").`, {
|
158
|
+
metaMessages: [
|
159
|
+
'This could be due to any of the following:',
|
160
|
+
`- The contract does not have the function "${functionName}",`,
|
161
|
+
'- The parameters passed to the contract function may be invalid, or',
|
162
|
+
'- The address is not a contract.',
|
163
|
+
],
|
164
|
+
})
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
export class RawContractError extends BaseError {
|
169
|
+
code = 3
|
170
|
+
name = 'RawContractError'
|
171
|
+
|
172
|
+
data?: Hex
|
173
|
+
|
174
|
+
constructor({ data, message }: { data?: Hex; message?: string }) {
|
175
|
+
super(message || '')
|
176
|
+
this.data = data
|
124
177
|
}
|
125
178
|
}
|
package/src/errors/index.ts
CHANGED
@@ -25,8 +25,10 @@ export { BaseError } from './base'
|
|
25
25
|
export { BlockNotFoundError } from './block'
|
26
26
|
|
27
27
|
export {
|
28
|
-
|
29
|
-
|
28
|
+
ContractFunctionExecutionError,
|
29
|
+
ContractFunctionRevertedError,
|
30
|
+
ContractFunctionZeroDataError,
|
31
|
+
RawContractError,
|
30
32
|
} from './contract'
|
31
33
|
|
32
34
|
export { SizeExceedsPaddingSizeError } from './data'
|
@@ -27,7 +27,7 @@ test('RequestError', () => {
|
|
27
27
|
error: { code: 1337, message: 'error details' },
|
28
28
|
}),
|
29
29
|
{
|
30
|
-
|
30
|
+
shortMessage: 'An internal error was received.',
|
31
31
|
},
|
32
32
|
),
|
33
33
|
).toMatchInlineSnapshot(`
|
@@ -46,7 +46,7 @@ test('RpcRequestError', () => {
|
|
46
46
|
url: 'https://viem.sh',
|
47
47
|
error: { code: 1337, message: 'error details' },
|
48
48
|
}),
|
49
|
-
{
|
49
|
+
{ shortMessage: 'An internal error was received.' },
|
50
50
|
),
|
51
51
|
).toMatchInlineSnapshot(`
|
52
52
|
[RpcError: An internal error was received.
|
@@ -65,7 +65,7 @@ test('RpcRequestError', () => {
|
|
65
65
|
error: { code: 1337, message: 'error details' },
|
66
66
|
}),
|
67
67
|
{
|
68
|
-
|
68
|
+
shortMessage: 'An internal error was received.',
|
69
69
|
docsPath: '/lol',
|
70
70
|
},
|
71
71
|
),
|
@@ -73,7 +73,6 @@ test('RpcRequestError', () => {
|
|
73
73
|
[RpcError: An internal error was received.
|
74
74
|
|
75
75
|
Docs: https://viem.sh/lol
|
76
|
-
|
77
76
|
Details: error details
|
78
77
|
Version: viem@1.0.2]
|
79
78
|
`)
|