viem 0.0.1-alpha.16 → 0.0.1-alpha.18
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/chains.d.ts +1 -1
- package/dist/chains.js +5 -5
- package/dist/chains.mjs +1 -1
- package/dist/{chunk-U7QDLGQL.mjs → chunk-3E5WSIQU.mjs} +2 -2
- package/dist/{chunk-U7QDLGQL.mjs.map → chunk-3E5WSIQU.mjs.map} +0 -0
- package/dist/{chunk-XJKOJIX3.js → chunk-3EXLRM3B.js} +12 -12
- package/dist/{chunk-XJKOJIX3.js.map → chunk-3EXLRM3B.js.map} +0 -0
- package/dist/{chunk-EWTLCB3N.js → chunk-6CXRXH25.js} +2 -2
- package/dist/{chunk-EWTLCB3N.js.map → chunk-6CXRXH25.js.map} +0 -0
- package/dist/{chunk-WTXKCAG7.js → chunk-A4HJ47I6.js} +144 -53
- package/dist/chunk-A4HJ47I6.js.map +1 -0
- package/dist/{chunk-4XREGFHD.js → chunk-BW2LPGYJ.js} +36 -13
- package/dist/chunk-BW2LPGYJ.js.map +1 -0
- package/dist/{chunk-KM6AFT2K.mjs → chunk-NSPSPOUF.mjs} +2 -2
- package/dist/{chunk-KM6AFT2K.mjs.map → chunk-NSPSPOUF.mjs.map} +0 -0
- package/dist/{chunk-B7A2CAHU.mjs → chunk-OGQGNULX.mjs} +98 -7
- package/dist/chunk-OGQGNULX.mjs.map +1 -0
- package/dist/{chunk-TSJ3OOJW.mjs → chunk-TO7QJO5X.mjs} +2 -2
- package/dist/{chunk-TSJ3OOJW.mjs.map → chunk-TO7QJO5X.mjs.map} +0 -0
- package/dist/{chunk-LQXQPPTU.js → chunk-XQZRYOPA.js} +14 -14
- package/dist/{chunk-LQXQPPTU.js.map → chunk-XQZRYOPA.js.map} +0 -0
- package/dist/{chunk-KCMYVU3Z.mjs → chunk-Y3PSHZGB.mjs} +26 -3
- package/dist/chunk-Y3PSHZGB.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/{createClient-cd948138.d.ts → createClient-aadeff37.d.ts} +1 -1
- package/dist/{createPublicClient-989a0556.d.ts → createPublicClient-88f35518.d.ts} +2 -2
- package/dist/{createTestClient-81507f58.d.ts → createTestClient-fbf66ec2.d.ts} +2 -2
- package/dist/{createWalletClient-43f801b9.d.ts → createWalletClient-b13dabd6.d.ts} +2 -2
- package/dist/{eip1193-4330b722.d.ts → eip1193-3a40c941.d.ts} +9 -6
- package/dist/index.d.ts +57 -17
- package/dist/index.js +12 -6
- package/dist/index.mjs +15 -9
- package/dist/{parseGwei-f2d23de6.d.ts → parseGwei-dbd12305.d.ts} +2 -2
- package/dist/public.d.ts +9 -9
- package/dist/public.js +4 -4
- package/dist/public.mjs +5 -5
- package/dist/{rpc-b77c5aee.d.ts → rpc-858670f1.d.ts} +12 -1
- package/dist/{sendTransaction-7a9d241a.d.ts → sendTransaction-bd109cd4.d.ts} +3 -3
- package/dist/{stopImpersonatingAccount-8113150e.d.ts → stopImpersonatingAccount-6603ebdd.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/{transactionReceipt-5d332aab.d.ts → transactionReceipt-aed524b4.d.ts} +30 -4
- package/dist/{transactionRequest-327eb7c2.d.ts → transactionRequest-8e970b0e.d.ts} +1 -1
- package/dist/utils/index.d.ts +5 -5
- package/dist/utils/index.js +2 -2
- package/dist/utils/index.mjs +1 -1
- package/dist/wallet.d.ts +7 -7
- package/dist/wallet.js +3 -3
- package/dist/wallet.mjs +2 -2
- package/dist/{watchAsset-0088384c.d.ts → watchAsset-7ef25553.d.ts} +3 -3
- package/dist/{watchPendingTransactions-670a7ca3.d.ts → watchPendingTransactions-7cbbef80.d.ts} +26 -11
- package/dist/{webSocket-9a3b0b26.d.ts → webSocket-2a77cdb3.d.ts} +2 -2
- package/dist/window.d.ts +2 -2
- package/package.json +1 -1
- package/src/actions/index.test.ts +4 -1
- package/src/actions/index.ts +12 -3
- package/src/actions/public/createEventFilter.ts +2 -4
- package/src/actions/public/deployContract.test.ts +8 -8
- package/src/actions/public/getLogs.test.ts +105 -0
- package/src/actions/public/getLogs.ts +83 -0
- package/src/actions/public/index.test.ts +3 -1
- package/src/actions/public/index.ts +13 -5
- package/src/actions/public/readContract.test.ts +128 -0
- package/src/actions/public/{callContract.ts → readContract.ts} +23 -16
- package/src/actions/public/simulateContract.bench.ts +31 -0
- package/src/actions/public/simulateContract.test.ts +238 -0
- package/src/actions/public/simulateContract.ts +98 -0
- package/src/actions/wallet/index.test.ts +1 -0
- package/src/actions/wallet/index.ts +3 -0
- package/src/actions/wallet/writeContract.test.ts +54 -0
- package/src/actions/wallet/writeContract.ts +56 -0
- package/src/index.test.ts +4 -1
- package/src/index.ts +12 -3
- package/src/public.ts +3 -3
- package/src/types/eip1193.ts +9 -6
- package/src/types/index.ts +1 -1
- package/src/types/misc.ts +1 -0
- package/dist/chunk-4XREGFHD.js.map +0 -1
- package/dist/chunk-B7A2CAHU.mjs.map +0 -1
- package/dist/chunk-KCMYVU3Z.mjs.map +0 -1
- package/dist/chunk-WTXKCAG7.js.map +0 -1
- package/src/actions/public/callContract.bench.ts +0 -24
- package/src/actions/public/callContract.test.ts +0 -285
@@ -0,0 +1,128 @@
|
|
1
|
+
/**
|
2
|
+
* TODO: Heaps more test cases :D
|
3
|
+
* - Complex calldata types
|
4
|
+
* - Complex return types (tuple/structs)
|
5
|
+
* - Calls against blocks
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { describe, expect, test } from 'vitest'
|
9
|
+
import {
|
10
|
+
accounts,
|
11
|
+
publicClient,
|
12
|
+
testClient,
|
13
|
+
wagmiContractConfig,
|
14
|
+
walletClient,
|
15
|
+
} from '../../_test'
|
16
|
+
import { baycContractConfig } from '../../_test/abis'
|
17
|
+
import { encodeFunctionData } from '../../utils'
|
18
|
+
import { mine } from '../test'
|
19
|
+
import { sendTransaction } from '../wallet'
|
20
|
+
|
21
|
+
import { deployContract } from './deployContract'
|
22
|
+
import { getTransactionReceipt } from './getTransactionReceipt'
|
23
|
+
import { readContract } from './readContract'
|
24
|
+
|
25
|
+
describe('wagmi', () => {
|
26
|
+
test('default', async () => {
|
27
|
+
expect(
|
28
|
+
await readContract(publicClient, {
|
29
|
+
...wagmiContractConfig,
|
30
|
+
functionName: 'balanceOf',
|
31
|
+
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'],
|
32
|
+
}),
|
33
|
+
).toEqual(3n)
|
34
|
+
expect(
|
35
|
+
await readContract(publicClient, {
|
36
|
+
...wagmiContractConfig,
|
37
|
+
functionName: 'getApproved',
|
38
|
+
args: [420n],
|
39
|
+
}),
|
40
|
+
).toEqual('0x0000000000000000000000000000000000000000')
|
41
|
+
expect(
|
42
|
+
await readContract(publicClient, {
|
43
|
+
...wagmiContractConfig,
|
44
|
+
functionName: 'isApprovedForAll',
|
45
|
+
args: [
|
46
|
+
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
47
|
+
'0x0000000000000000000000000000000000000000',
|
48
|
+
],
|
49
|
+
}),
|
50
|
+
).toEqual(false)
|
51
|
+
expect(
|
52
|
+
await readContract(publicClient, {
|
53
|
+
...wagmiContractConfig,
|
54
|
+
functionName: 'name',
|
55
|
+
}),
|
56
|
+
).toEqual('wagmi')
|
57
|
+
expect(
|
58
|
+
await readContract(publicClient, {
|
59
|
+
...wagmiContractConfig,
|
60
|
+
functionName: 'ownerOf',
|
61
|
+
args: [420n],
|
62
|
+
}),
|
63
|
+
).toEqual('0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC')
|
64
|
+
expect(
|
65
|
+
await readContract(publicClient, {
|
66
|
+
...wagmiContractConfig,
|
67
|
+
functionName: 'supportsInterface',
|
68
|
+
args: ['0x1a452251'],
|
69
|
+
}),
|
70
|
+
).toEqual(false)
|
71
|
+
expect(
|
72
|
+
await readContract(publicClient, {
|
73
|
+
...wagmiContractConfig,
|
74
|
+
functionName: 'symbol',
|
75
|
+
}),
|
76
|
+
).toEqual('WAGMI')
|
77
|
+
expect(
|
78
|
+
await readContract(publicClient, {
|
79
|
+
...wagmiContractConfig,
|
80
|
+
functionName: 'tokenURI',
|
81
|
+
args: [420n],
|
82
|
+
}),
|
83
|
+
).toMatchInlineSnapshot(
|
84
|
+
'"data:application/json;base64,eyJuYW1lIjogIndhZ21pICM0MjAiLCAiaW1hZ2UiOiAiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhkcFpIUm9QU0l4TURJMElpQm9aV2xuYUhROUlqRXdNalFpSUdacGJHdzlJbTV2Ym1VaVBqeHdZWFJvSUdacGJHdzlJbWh6YkNneE1UY3NJREV3TUNVc0lERXdKU2tpSUdROUlrMHdJREJvTVRBeU5IWXhNREkwU0RCNklpQXZQanhuSUdacGJHdzlJbWh6YkNneU9EZ3NJREV3TUNVc0lEa3dKU2tpUGp4d1lYUm9JR1E5SWswNU1ETWdORE0zTGpWak1DQTVMakV4TXkwM0xqTTRPQ0F4Tmk0MUxURTJMalVnTVRZdU5YTXRNVFl1TlMwM0xqTTROeTB4Tmk0MUxURTJMalVnTnk0ek9EZ3RNVFl1TlNBeE5pNDFMVEUyTGpVZ01UWXVOU0EzTGpNNE55QXhOaTQxSURFMkxqVjZUVFk1T0M0MU1qa2dOVFkyWXpZdU9USXhJREFnTVRJdU5UTXROUzQxT1RZZ01USXVOVE10TVRJdU5YWXROVEJqTUMwMkxqa3dOQ0ExTGpZd09TMHhNaTQxSURFeUxqVXlPUzB4TWk0MWFESTFMakExT1dNMkxqa3lJREFnTVRJdU5USTVJRFV1TlRrMklERXlMalV5T1NBeE1pNDFkalV3WXpBZ05pNDVNRFFnTlM0Mk1Ea2dNVEl1TlNBeE1pNDFNeUF4TWk0MWN6RXlMalV5T1MwMUxqVTVOaUF4TWk0MU1qa3RNVEl1TlhZdE5UQmpNQzAyTGprd05DQTFMall3T1MweE1pNDFJREV5TGpVekxURXlMalZvTWpVdU1EVTVZell1T1RJZ01DQXhNaTQxTWprZ05TNDFPVFlnTVRJdU5USTVJREV5TGpWMk5UQmpNQ0EyTGprd05DQTFMall3T1NBeE1pNDFJREV5TGpVeU9TQXhNaTQxYURNM0xqVTRPV00yTGpreUlEQWdNVEl1TlRJNUxUVXVOVGsySURFeUxqVXlPUzB4TWk0MWRpMDNOV013TFRZdU9UQTBMVFV1TmpBNUxURXlMalV0TVRJdU5USTVMVEV5TGpWekxURXlMalV6SURVdU5UazJMVEV5TGpVeklERXlMalYyTlRZdU1qVmhOaTR5TmpRZ05pNHlOalFnTUNBeElERXRNVEl1TlRJNUlEQldORGM0TGpWak1DMDJMamt3TkMwMUxqWXdPUzB4TWk0MUxURXlMalV6TFRFeUxqVklOams0TGpVeU9XTXROaTQ1TWlBd0xURXlMalV5T1NBMUxqVTVOaTB4TWk0MU1qa2dNVEl1TlhZM05XTXdJRFl1T1RBMElEVXVOakE1SURFeUxqVWdNVEl1TlRJNUlERXlMalY2SWlBdlBqeHdZWFJvSUdROUlrMHhOVGN1TmpVMUlEVTBNV010Tmk0NU16SWdNQzB4TWk0MU5USXROUzQxT1RZdE1USXVOVFV5TFRFeUxqVjJMVFV3WXpBdE5pNDVNRFF0TlM0Mk1Ua3RNVEl1TlMweE1pNDFOVEV0TVRJdU5WTXhNakFnTkRjeExqVTVOaUF4TWpBZ05EYzRMalYyTnpWak1DQTJMamt3TkNBMUxqWXlJREV5TGpVZ01USXVOVFV5SURFeUxqVm9NVFV3TGpZeVl6WXVPVE16SURBZ01USXVOVFV5TFRVdU5UazJJREV5TGpVMU1pMHhNaTQxZGkwMU1HTXdMVFl1T1RBMElEVXVOakU1TFRFeUxqVWdNVEl1TlRVeUxURXlMalZvTVRRMExqTTBOV016TGpRMk5TQXdJRFl1TWpjMklESXVOems0SURZdU1qYzJJRFl1TWpWekxUSXVPREV4SURZdU1qVXROaTR5TnpZZ05pNHlOVWd6TWpBdU9ESTRZeTAyTGprek15QXdMVEV5TGpVMU1pQTFMalU1TmkweE1pNDFOVElnTVRJdU5YWXpOeTQxWXpBZ05pNDVNRFFnTlM0Mk1Ua2dNVEl1TlNBeE1pNDFOVElnTVRJdU5XZ3hOVEF1TmpKak5pNDVNek1nTUNBeE1pNDFOVEl0TlM0MU9UWWdNVEl1TlRVeUxURXlMalYyTFRjMVl6QXROaTQ1TURRdE5TNDJNVGt0TVRJdU5TMHhNaTQxTlRJdE1USXVOVWd5T0RNdU1UY3lZeTAyTGprek1pQXdMVEV5TGpVMU1TQTFMalU1TmkweE1pNDFOVEVnTVRJdU5YWTFNR013SURZdU9UQTBMVFV1TmpFNUlERXlMalV0TVRJdU5UVXlJREV5TGpWb0xUSTFMakV3TTJNdE5pNDVNek1nTUMweE1pNDFOVEl0TlM0MU9UWXRNVEl1TlRVeUxURXlMalYyTFRVd1l6QXROaTQ1TURRdE5TNDJNaTB4TWk0MUxURXlMalUxTWkweE1pNDFjeTB4TWk0MU5USWdOUzQxT1RZdE1USXVOVFV5SURFeUxqVjJOVEJqTUNBMkxqa3dOQzAxTGpZeE9TQXhNaTQxTFRFeUxqVTFNU0F4TWk0MWFDMHlOUzR4TURSNmJUTXdNUzR5TkRJdE5pNHlOV013SURNdU5EVXlMVEl1T0RFeElEWXVNalV0Tmk0eU56WWdOaTR5TlVnek16a3VOalUxWXkwekxqUTJOU0F3TFRZdU1qYzJMVEl1TnprNExUWXVNamMyTFRZdU1qVnpNaTQ0TVRFdE5pNHlOU0EyTGpJM05pMDJMakkxYURFeE1pNDVOalpqTXk0ME5qVWdNQ0EyTGpJM05pQXlMamM1T0NBMkxqSTNOaUEyTGpJMWVrMDBPVGNnTlRVekxqZ3hPR013SURZdU9USTVJRFV1TmpJNElERXlMalUwTmlBeE1pNDFOekVnTVRJdU5UUTJhREV6TW1FMkxqSTRJRFl1TWpnZ01DQXdJREVnTmk0eU9EWWdOaTR5TnpJZ05pNHlPQ0EyTGpJNElEQWdNQ0F4TFRZdU1qZzJJRFl1TWpjemFDMHhNekpqTFRZdU9UUXpJREF0TVRJdU5UY3hJRFV1TmpFMkxURXlMalUzTVNBeE1pNDFORFpCTVRJdU5UWWdNVEl1TlRZZ01DQXdJREFnTlRBNUxqVTNNU0EyTURSb01UVXdMamcxT0dNMkxqazBNeUF3SURFeUxqVTNNUzAxTGpZeE5pQXhNaTQxTnpFdE1USXVOVFExZGkweE1USXVPVEZqTUMwMkxqa3lPQzAxTGpZeU9DMHhNaTQxTkRVdE1USXVOVGN4TFRFeUxqVTBOVWcxTURrdU5UY3hZeTAyTGprME15QXdMVEV5TGpVM01TQTFMall4TnkweE1pNDFOekVnTVRJdU5UUTFkamMxTGpJM00zcHRNemN1TnpFMExUWXlMamN5TjJNdE5pNDVORE1nTUMweE1pNDFOekVnTlM0Mk1UY3RNVEl1TlRjeElERXlMalUwTlhZeU5TNHdPVEZqTUNBMkxqa3lPU0ExTGpZeU9DQXhNaTQxTkRZZ01USXVOVGN4SURFeUxqVTBObWd4TURBdU5UY3lZell1T1RReklEQWdNVEl1TlRjeExUVXVOakUzSURFeUxqVTNNUzB4TWk0MU5EWjJMVEkxTGpBNU1XTXdMVFl1T1RJNExUVXVOakk0TFRFeUxqVTBOUzB4TWk0MU56RXRNVEl1TlRRMVNEVXpOQzQzTVRSNklpQm1hV3hzTFhKMWJHVTlJbVYyWlc1dlpHUWlJQzgrUEM5blBqd3ZjM1puUGc9PSJ9"',
|
85
|
+
)
|
86
|
+
expect(
|
87
|
+
await readContract(publicClient, {
|
88
|
+
...wagmiContractConfig,
|
89
|
+
functionName: 'totalSupply',
|
90
|
+
}),
|
91
|
+
).toEqual(558n)
|
92
|
+
})
|
93
|
+
})
|
94
|
+
|
95
|
+
test('fake contract address', async () => {
|
96
|
+
await expect(() =>
|
97
|
+
readContract(publicClient, {
|
98
|
+
abi: wagmiContractConfig.abi,
|
99
|
+
address: '0x0000000000000000000000000000000000000069',
|
100
|
+
functionName: 'totalSupply',
|
101
|
+
}),
|
102
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
103
|
+
"The contract method \\"totalSupply\\" returned no data (\\"0x\\"). This could be due to any of the following:
|
104
|
+
- The contract does not have the function \\"totalSupply\\",
|
105
|
+
- The parameters passed to the contract function may be invalid, or
|
106
|
+
- The address is not a contract.
|
107
|
+
|
108
|
+
Contract: 0x0000000000000000000000000000000000000000
|
109
|
+
Function: totalSupply()
|
110
|
+
> \\"0x\\"
|
111
|
+
|
112
|
+
Version: viem@1.0.2"
|
113
|
+
`)
|
114
|
+
})
|
115
|
+
|
116
|
+
// Deploy BAYC Contract
|
117
|
+
async function deployBAYC() {
|
118
|
+
const hash = await deployContract(walletClient, {
|
119
|
+
...baycContractConfig,
|
120
|
+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
|
121
|
+
from: accounts[0].address,
|
122
|
+
})
|
123
|
+
await mine(testClient, { blocks: 1 })
|
124
|
+
const { contractAddress } = await getTransactionReceipt(publicClient, {
|
125
|
+
hash,
|
126
|
+
})
|
127
|
+
return { contractAddress }
|
128
|
+
}
|
@@ -7,7 +7,6 @@ import type {
|
|
7
7
|
ExtractArgsFromAbi,
|
8
8
|
ExtractResultFromAbi,
|
9
9
|
ExtractFunctionNameFromAbi,
|
10
|
-
GetValue,
|
11
10
|
} from '../../types'
|
12
11
|
import {
|
13
12
|
EncodeFunctionDataArgs,
|
@@ -17,29 +16,38 @@ import {
|
|
17
16
|
} from '../../utils'
|
18
17
|
import { call, CallArgs, FormattedCall } from './call'
|
19
18
|
|
20
|
-
export type
|
19
|
+
export type FormattedReadContract<
|
21
20
|
TFormatter extends Formatter | undefined = Formatter,
|
22
21
|
> = FormattedCall<TFormatter>
|
23
22
|
|
24
|
-
export type
|
25
|
-
TChain extends Chain = Chain,
|
23
|
+
export type ReadContractArgs<
|
26
24
|
TAbi extends Abi | readonly unknown[] = Abi,
|
27
25
|
TFunctionName extends string = any,
|
28
|
-
> = Omit<
|
26
|
+
> = Omit<
|
27
|
+
CallArgs,
|
28
|
+
| 'accessList'
|
29
|
+
| 'chain'
|
30
|
+
| 'from'
|
31
|
+
| 'gas'
|
32
|
+
| 'gasPrice'
|
33
|
+
| 'maxFeePerGas'
|
34
|
+
| 'maxPriorityFeePerGas'
|
35
|
+
| 'nonce'
|
36
|
+
| 'to'
|
37
|
+
| 'data'
|
38
|
+
| 'value'
|
39
|
+
> & {
|
29
40
|
address: Address
|
30
41
|
abi: TAbi
|
31
|
-
|
32
|
-
functionName: ExtractFunctionNameFromAbi<TAbi, TFunctionName>
|
33
|
-
value?: GetValue<TAbi, TFunctionName, CallArgs<TChain>['value']>
|
42
|
+
functionName: ExtractFunctionNameFromAbi<TAbi, TFunctionName, 'pure' | 'view'>
|
34
43
|
} & ExtractArgsFromAbi<TAbi, TFunctionName>
|
35
44
|
|
36
|
-
export type
|
45
|
+
export type ReadContractResponse<
|
37
46
|
TAbi extends Abi | readonly unknown[] = Abi,
|
38
47
|
TFunctionName extends string = string,
|
39
48
|
> = ExtractResultFromAbi<TAbi, TFunctionName>
|
40
49
|
|
41
|
-
export async function
|
42
|
-
TChain extends Chain,
|
50
|
+
export async function readContract<
|
43
51
|
TAbi extends Abi = Abi,
|
44
52
|
TFunctionName extends string = any,
|
45
53
|
>(
|
@@ -50,8 +58,8 @@ export async function callContract<
|
|
50
58
|
args,
|
51
59
|
functionName,
|
52
60
|
...callRequest
|
53
|
-
}:
|
54
|
-
): Promise<
|
61
|
+
}: ReadContractArgs<TAbi, TFunctionName>,
|
62
|
+
): Promise<ReadContractResponse<TAbi, TFunctionName>> {
|
55
63
|
const calldata = encodeFunctionData({
|
56
64
|
abi,
|
57
65
|
args,
|
@@ -62,19 +70,18 @@ export async function callContract<
|
|
62
70
|
data: calldata,
|
63
71
|
to: address,
|
64
72
|
...callRequest,
|
65
|
-
} as unknown as CallArgs
|
73
|
+
} as unknown as CallArgs)
|
66
74
|
return decodeFunctionResult({
|
67
75
|
abi,
|
68
76
|
functionName,
|
69
77
|
data: data || '0x',
|
70
|
-
})
|
78
|
+
})
|
71
79
|
} catch (err) {
|
72
80
|
throw getContractError(err, {
|
73
81
|
abi,
|
74
82
|
address,
|
75
83
|
args,
|
76
84
|
functionName,
|
77
|
-
sender: callRequest.from,
|
78
85
|
})
|
79
86
|
}
|
80
87
|
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { Contract } from 'ethers'
|
2
|
+
import { bench, describe } from 'vitest'
|
3
|
+
|
4
|
+
import {
|
5
|
+
accounts,
|
6
|
+
ethersProvider,
|
7
|
+
publicClient,
|
8
|
+
wagmiContractConfig,
|
9
|
+
} from '../../_test'
|
10
|
+
|
11
|
+
import { simulateContract } from './simulateContract'
|
12
|
+
|
13
|
+
describe('Simulate Contract', () => {
|
14
|
+
bench('viem: `simulateContract`', async () => {
|
15
|
+
await simulateContract(publicClient, {
|
16
|
+
...wagmiContractConfig,
|
17
|
+
functionName: 'mint',
|
18
|
+
args: [1n],
|
19
|
+
from: accounts[0].address,
|
20
|
+
})
|
21
|
+
})
|
22
|
+
|
23
|
+
bench('ethers: `callStatic`', async () => {
|
24
|
+
const wagmi = new Contract(
|
25
|
+
wagmiContractConfig.address,
|
26
|
+
wagmiContractConfig.abi,
|
27
|
+
ethersProvider,
|
28
|
+
)
|
29
|
+
await wagmi.callStatic.mint(1)
|
30
|
+
})
|
31
|
+
})
|
@@ -0,0 +1,238 @@
|
|
1
|
+
/**
|
2
|
+
* TODO: Heaps more test cases :D
|
3
|
+
* - Complex calldata types
|
4
|
+
* - Complex return types (tuple/structs)
|
5
|
+
* - EIP-1559
|
6
|
+
* - Calls against blocks
|
7
|
+
* - Custom chain types
|
8
|
+
* - Custom nonce
|
9
|
+
*/
|
10
|
+
|
11
|
+
import { describe, expect, test } from 'vitest'
|
12
|
+
import {
|
13
|
+
accounts,
|
14
|
+
publicClient,
|
15
|
+
testClient,
|
16
|
+
wagmiContractConfig,
|
17
|
+
walletClient,
|
18
|
+
} from '../../_test'
|
19
|
+
import { baycContractConfig } from '../../_test/abis'
|
20
|
+
import { encodeFunctionData } from '../../utils'
|
21
|
+
import { mine } from '../test'
|
22
|
+
import { sendTransaction } from '../wallet'
|
23
|
+
|
24
|
+
import { deployContract } from './deployContract'
|
25
|
+
import { getTransactionReceipt } from './getTransactionReceipt'
|
26
|
+
import { simulateContract } from './simulateContract'
|
27
|
+
|
28
|
+
describe('wagmi', () => {
|
29
|
+
test('default', async () => {
|
30
|
+
expect(
|
31
|
+
(
|
32
|
+
await simulateContract(publicClient, {
|
33
|
+
...wagmiContractConfig,
|
34
|
+
from: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
35
|
+
functionName: 'mint',
|
36
|
+
args: [69420n],
|
37
|
+
})
|
38
|
+
).result,
|
39
|
+
).toEqual(undefined)
|
40
|
+
expect(
|
41
|
+
(
|
42
|
+
await simulateContract(publicClient, {
|
43
|
+
...wagmiContractConfig,
|
44
|
+
functionName: 'safeTransferFrom',
|
45
|
+
from: '0x1a1E021A302C237453D3D45c7B82B19cEEB7E2e6',
|
46
|
+
args: [
|
47
|
+
'0x1a1E021A302C237453D3D45c7B82B19cEEB7E2e6',
|
48
|
+
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
49
|
+
1n,
|
50
|
+
],
|
51
|
+
})
|
52
|
+
).result,
|
53
|
+
).toEqual(undefined)
|
54
|
+
})
|
55
|
+
|
56
|
+
test('revert', async () => {
|
57
|
+
await expect(() =>
|
58
|
+
simulateContract(publicClient, {
|
59
|
+
...wagmiContractConfig,
|
60
|
+
functionName: 'approve',
|
61
|
+
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', 420n],
|
62
|
+
from: accounts[0].address,
|
63
|
+
}),
|
64
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
65
|
+
"ERC721: approval to current owner
|
66
|
+
|
67
|
+
Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
|
68
|
+
Contract: 0x0000000000000000000000000000000000000000
|
69
|
+
Function: approve(address to, uint256 tokenId)
|
70
|
+
Arguments: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC, 420)
|
71
|
+
|
72
|
+
Details: execution reverted: ERC721: approval to current owner
|
73
|
+
Version: viem@1.0.2"
|
74
|
+
`)
|
75
|
+
await expect(() =>
|
76
|
+
simulateContract(publicClient, {
|
77
|
+
...wagmiContractConfig,
|
78
|
+
functionName: 'mint',
|
79
|
+
args: [1n],
|
80
|
+
from: accounts[0].address,
|
81
|
+
}),
|
82
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
83
|
+
"Token ID is taken
|
84
|
+
|
85
|
+
Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
|
86
|
+
Contract: 0x0000000000000000000000000000000000000000
|
87
|
+
Function: mint(uint256 tokenId)
|
88
|
+
Arguments: (1)
|
89
|
+
|
90
|
+
Details: execution reverted: Token ID is taken
|
91
|
+
Version: viem@1.0.2"
|
92
|
+
`)
|
93
|
+
await expect(() =>
|
94
|
+
simulateContract(publicClient, {
|
95
|
+
...wagmiContractConfig,
|
96
|
+
functionName: 'safeTransferFrom',
|
97
|
+
from: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
98
|
+
args: [
|
99
|
+
'0x1a1E021A302C237453D3D45c7B82B19cEEB7E2e6',
|
100
|
+
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
|
101
|
+
1n,
|
102
|
+
],
|
103
|
+
}),
|
104
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
105
|
+
"ERC721: transfer caller is not owner nor approved
|
106
|
+
|
107
|
+
Sender: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC
|
108
|
+
Contract: 0x0000000000000000000000000000000000000000
|
109
|
+
Function: safeTransferFrom(address from, address to, uint256 tokenId)
|
110
|
+
Arguments: (0x1a1E021A302C237453D3D45c7B82B19cEEB7E2e6, 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC, 1)
|
111
|
+
|
112
|
+
Details: execution reverted: ERC721: transfer caller is not owner nor approved
|
113
|
+
Version: viem@1.0.2"
|
114
|
+
`)
|
115
|
+
})
|
116
|
+
})
|
117
|
+
|
118
|
+
describe('BAYC', () => {
|
119
|
+
describe('default', () => {
|
120
|
+
test('mintApe', async () => {
|
121
|
+
const { contractAddress } = await deployBAYC()
|
122
|
+
|
123
|
+
// Set sale state to active
|
124
|
+
// TODO: replace w/ writeContract
|
125
|
+
await sendTransaction(walletClient, {
|
126
|
+
data: encodeFunctionData({
|
127
|
+
abi: baycContractConfig.abi,
|
128
|
+
functionName: 'flipSaleState',
|
129
|
+
}),
|
130
|
+
from: accounts[0].address,
|
131
|
+
to: contractAddress!,
|
132
|
+
})
|
133
|
+
await mine(testClient, { blocks: 1 })
|
134
|
+
|
135
|
+
// Mint an Ape!
|
136
|
+
expect(
|
137
|
+
(
|
138
|
+
await simulateContract(publicClient, {
|
139
|
+
abi: baycContractConfig.abi,
|
140
|
+
address: contractAddress!,
|
141
|
+
functionName: 'mintApe',
|
142
|
+
from: accounts[0].address,
|
143
|
+
args: [1n],
|
144
|
+
value: 1000000000000000000n,
|
145
|
+
})
|
146
|
+
).result,
|
147
|
+
).toBe(undefined)
|
148
|
+
})
|
149
|
+
|
150
|
+
test('get a free $100k', async () => {
|
151
|
+
const { contractAddress } = await deployBAYC()
|
152
|
+
|
153
|
+
// Reserve apes
|
154
|
+
expect(
|
155
|
+
(
|
156
|
+
await simulateContract(publicClient, {
|
157
|
+
abi: baycContractConfig.abi,
|
158
|
+
address: contractAddress!,
|
159
|
+
functionName: 'reserveApes',
|
160
|
+
from: accounts[0].address,
|
161
|
+
})
|
162
|
+
).result,
|
163
|
+
).toBe(undefined)
|
164
|
+
})
|
165
|
+
})
|
166
|
+
|
167
|
+
describe('revert', () => {
|
168
|
+
test('sale inactive', async () => {
|
169
|
+
const { contractAddress } = await deployBAYC()
|
170
|
+
|
171
|
+
// Expect mint to fail.
|
172
|
+
await expect(() =>
|
173
|
+
simulateContract(publicClient, {
|
174
|
+
abi: baycContractConfig.abi,
|
175
|
+
address: contractAddress!,
|
176
|
+
functionName: 'mintApe',
|
177
|
+
from: accounts[0].address,
|
178
|
+
args: [1n],
|
179
|
+
}),
|
180
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
181
|
+
"Sale must be active to mint Ape
|
182
|
+
|
183
|
+
Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
|
184
|
+
Contract: 0x0000000000000000000000000000000000000000
|
185
|
+
Function: mintApe(uint256 numberOfTokens)
|
186
|
+
Arguments: (1)
|
187
|
+
|
188
|
+
Details: execution reverted: Sale must be active to mint Ape
|
189
|
+
Version: viem@1.0.2"
|
190
|
+
`)
|
191
|
+
})
|
192
|
+
})
|
193
|
+
})
|
194
|
+
|
195
|
+
test('fake contract address', async () => {
|
196
|
+
await expect(() =>
|
197
|
+
simulateContract(publicClient, {
|
198
|
+
abi: [
|
199
|
+
{
|
200
|
+
name: 'mint',
|
201
|
+
type: 'function',
|
202
|
+
stateMutability: 'nonpayable',
|
203
|
+
inputs: [],
|
204
|
+
outputs: [{ type: 'uint256' }],
|
205
|
+
},
|
206
|
+
],
|
207
|
+
address: '0x0000000000000000000000000000000000000069',
|
208
|
+
functionName: 'mint',
|
209
|
+
from: accounts[0].address,
|
210
|
+
args: [],
|
211
|
+
}),
|
212
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
213
|
+
"The contract method \\"mint\\" returned no data (\\"0x\\"). This could be due to any of the following:
|
214
|
+
- The contract does not have the function \\"mint\\",
|
215
|
+
- The parameters passed to the contract function may be invalid, or
|
216
|
+
- The address is not a contract.
|
217
|
+
|
218
|
+
Contract: 0x0000000000000000000000000000000000000000
|
219
|
+
Function: mint()
|
220
|
+
> \\"0x\\"
|
221
|
+
|
222
|
+
Version: viem@1.0.2"
|
223
|
+
`)
|
224
|
+
})
|
225
|
+
|
226
|
+
// Deploy BAYC Contract
|
227
|
+
async function deployBAYC() {
|
228
|
+
const hash = await deployContract(walletClient, {
|
229
|
+
...baycContractConfig,
|
230
|
+
args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n],
|
231
|
+
from: accounts[0].address,
|
232
|
+
})
|
233
|
+
await mine(testClient, { blocks: 1 })
|
234
|
+
const { contractAddress } = await getTransactionReceipt(publicClient, {
|
235
|
+
hash,
|
236
|
+
})
|
237
|
+
return { contractAddress }
|
238
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import { Abi } from 'abitype'
|
2
|
+
|
3
|
+
import type { Chain, Formatter } from '../../chains'
|
4
|
+
import type { PublicClient } from '../../clients'
|
5
|
+
import type {
|
6
|
+
Address,
|
7
|
+
ExtractArgsFromAbi,
|
8
|
+
ExtractResultFromAbi,
|
9
|
+
ExtractFunctionNameFromAbi,
|
10
|
+
GetValue,
|
11
|
+
} from '../../types'
|
12
|
+
import {
|
13
|
+
EncodeFunctionDataArgs,
|
14
|
+
decodeFunctionResult,
|
15
|
+
encodeFunctionData,
|
16
|
+
getContractError,
|
17
|
+
} from '../../utils'
|
18
|
+
import { WriteContractArgs } from '../wallet'
|
19
|
+
import { call, CallArgs } from './call'
|
20
|
+
|
21
|
+
export type SimulateContractArgs<
|
22
|
+
TChain extends Chain = Chain,
|
23
|
+
TAbi extends Abi | readonly unknown[] = Abi,
|
24
|
+
TFunctionName extends string = any,
|
25
|
+
> = Omit<CallArgs<TChain>, 'to' | 'data' | 'value'> & {
|
26
|
+
address: Address
|
27
|
+
abi: TAbi
|
28
|
+
functionName: ExtractFunctionNameFromAbi<
|
29
|
+
TAbi,
|
30
|
+
TFunctionName,
|
31
|
+
'payable' | 'nonpayable'
|
32
|
+
>
|
33
|
+
value?: GetValue<TAbi, TFunctionName, CallArgs<TChain>['value']>
|
34
|
+
} & ExtractArgsFromAbi<TAbi, TFunctionName>
|
35
|
+
|
36
|
+
export type SimulateContractResponse<
|
37
|
+
TChain extends Chain = Chain,
|
38
|
+
TAbi extends Abi | readonly unknown[] = Abi,
|
39
|
+
TFunctionName extends string = string,
|
40
|
+
> = {
|
41
|
+
result: ExtractResultFromAbi<TAbi, TFunctionName>
|
42
|
+
request: WriteContractArgs<TChain, TAbi, TFunctionName> & {
|
43
|
+
address: Address
|
44
|
+
abi: TAbi
|
45
|
+
functionName: ExtractFunctionNameFromAbi<TAbi, TFunctionName>
|
46
|
+
} & ExtractArgsFromAbi<TAbi, TFunctionName>
|
47
|
+
}
|
48
|
+
|
49
|
+
export async function simulateContract<
|
50
|
+
TChain extends Chain,
|
51
|
+
TAbi extends Abi = Abi,
|
52
|
+
TFunctionName extends string = any,
|
53
|
+
>(
|
54
|
+
client: PublicClient,
|
55
|
+
{
|
56
|
+
abi,
|
57
|
+
address,
|
58
|
+
args,
|
59
|
+
functionName,
|
60
|
+
...callRequest
|
61
|
+
}: SimulateContractArgs<TChain, TAbi, TFunctionName>,
|
62
|
+
): Promise<SimulateContractResponse<TChain, TAbi, TFunctionName>> {
|
63
|
+
const calldata = encodeFunctionData({
|
64
|
+
abi,
|
65
|
+
args,
|
66
|
+
functionName,
|
67
|
+
} as unknown as EncodeFunctionDataArgs<TAbi, TFunctionName>)
|
68
|
+
try {
|
69
|
+
const { data } = await call(client, {
|
70
|
+
data: calldata,
|
71
|
+
to: address,
|
72
|
+
...callRequest,
|
73
|
+
} as unknown as CallArgs<TChain>)
|
74
|
+
const result = decodeFunctionResult({
|
75
|
+
abi,
|
76
|
+
functionName,
|
77
|
+
data: data || '0x',
|
78
|
+
})
|
79
|
+
return {
|
80
|
+
result,
|
81
|
+
request: {
|
82
|
+
abi,
|
83
|
+
address,
|
84
|
+
args,
|
85
|
+
functionName,
|
86
|
+
...callRequest,
|
87
|
+
},
|
88
|
+
} as unknown as SimulateContractResponse<TChain, TAbi, TFunctionName>
|
89
|
+
} catch (err) {
|
90
|
+
throw getContractError(err, {
|
91
|
+
abi,
|
92
|
+
address,
|
93
|
+
args,
|
94
|
+
functionName,
|
95
|
+
sender: callRequest.from,
|
96
|
+
})
|
97
|
+
}
|
98
|
+
}
|
@@ -25,3 +25,6 @@ export type { SwitchChainArgs } from './switchChain'
|
|
25
25
|
|
26
26
|
export { watchAsset } from './watchAsset'
|
27
27
|
export type { WatchAssetArgs, WatchAssetResponse } from './watchAsset'
|
28
|
+
|
29
|
+
export { writeContract } from './writeContract'
|
30
|
+
export type { WriteContractArgs, WriteContractResponse } from './writeContract'
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { expect, test } from 'vitest'
|
2
|
+
import {
|
3
|
+
accounts,
|
4
|
+
publicClient,
|
5
|
+
testClient,
|
6
|
+
wagmiContractConfig,
|
7
|
+
walletClient,
|
8
|
+
} from '../../_test'
|
9
|
+
import { simulateContract } from '../public'
|
10
|
+
import { mine } from '../test'
|
11
|
+
|
12
|
+
import { writeContract } from './writeContract'
|
13
|
+
|
14
|
+
test('default', async () => {
|
15
|
+
expect(
|
16
|
+
await writeContract(walletClient, {
|
17
|
+
...wagmiContractConfig,
|
18
|
+
from: accounts[0].address,
|
19
|
+
functionName: 'mint',
|
20
|
+
args: [69420n],
|
21
|
+
}),
|
22
|
+
).toBeDefined()
|
23
|
+
})
|
24
|
+
|
25
|
+
test('w/ simulateContract', async () => {
|
26
|
+
const { request } = await simulateContract(publicClient, {
|
27
|
+
...wagmiContractConfig,
|
28
|
+
from: accounts[0].address,
|
29
|
+
functionName: 'mint',
|
30
|
+
args: [69420n],
|
31
|
+
})
|
32
|
+
expect(await writeContract(walletClient, request)).toBeDefined()
|
33
|
+
|
34
|
+
await mine(testClient, { blocks: 1 })
|
35
|
+
|
36
|
+
await expect(() =>
|
37
|
+
simulateContract(publicClient, {
|
38
|
+
...wagmiContractConfig,
|
39
|
+
from: accounts[0].address,
|
40
|
+
functionName: 'mint',
|
41
|
+
args: [69420n],
|
42
|
+
}),
|
43
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
44
|
+
"Token ID is taken
|
45
|
+
|
46
|
+
Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
|
47
|
+
Contract: 0x0000000000000000000000000000000000000000
|
48
|
+
Function: mint(uint256 tokenId)
|
49
|
+
Arguments: (69420)
|
50
|
+
|
51
|
+
Details: execution reverted: Token ID is taken
|
52
|
+
Version: viem@1.0.2"
|
53
|
+
`)
|
54
|
+
})
|