@wagmi/core 0.4.8 → 0.5.0

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.
Files changed (78) hide show
  1. package/README.md +5 -5
  2. package/chains/dist/wagmi-core-chains.cjs.dev.js +2 -2
  3. package/chains/dist/wagmi-core-chains.cjs.prod.js +2 -2
  4. package/chains/dist/wagmi-core-chains.esm.js +2 -2
  5. package/connectors/coinbaseWallet/dist/wagmi-core-connectors-coinbaseWallet.cjs.dev.js +28 -26
  6. package/connectors/coinbaseWallet/dist/wagmi-core-connectors-coinbaseWallet.cjs.prod.js +28 -26
  7. package/connectors/coinbaseWallet/dist/wagmi-core-connectors-coinbaseWallet.esm.js +5 -3
  8. package/connectors/metaMask/dist/wagmi-core-connectors-metaMask.cjs.dev.js +22 -23
  9. package/connectors/metaMask/dist/wagmi-core-connectors-metaMask.cjs.prod.js +22 -23
  10. package/connectors/metaMask/dist/wagmi-core-connectors-metaMask.esm.js +7 -8
  11. package/connectors/mock/dist/wagmi-core-connectors-mock.cjs.dev.js +33 -31
  12. package/connectors/mock/dist/wagmi-core-connectors-mock.cjs.prod.js +33 -31
  13. package/connectors/mock/dist/wagmi-core-connectors-mock.esm.js +6 -4
  14. package/connectors/walletConnect/dist/wagmi-core-connectors-walletConnect.cjs.dev.js +24 -25
  15. package/connectors/walletConnect/dist/wagmi-core-connectors-walletConnect.cjs.prod.js +24 -25
  16. package/connectors/walletConnect/dist/wagmi-core-connectors-walletConnect.esm.js +5 -6
  17. package/dist/{chains-7e6dc59c.cjs.dev.js → chains-13baf029.cjs.prod.js} +4 -4
  18. package/dist/{chains-fd2c546c.esm.js → chains-4b1a6cf8.esm.js} +4 -4
  19. package/dist/{chains-f7bb3211.cjs.prod.js → chains-a1aae67e.cjs.dev.js} +4 -4
  20. package/dist/declarations/src/actions/accounts/fetchBalance.d.ts +0 -1
  21. package/dist/declarations/src/actions/accounts/fetchSigner.d.ts +3 -3
  22. package/dist/declarations/src/actions/contracts/deprecatedWriteContract.d.ts +16 -0
  23. package/dist/declarations/src/actions/{tokens → contracts}/fetchToken.d.ts +1 -0
  24. package/dist/declarations/src/actions/contracts/index.d.ts +4 -1
  25. package/dist/declarations/src/actions/contracts/prepareWriteContract.d.ts +37 -0
  26. package/dist/declarations/src/actions/contracts/writeContract.d.ts +44 -8
  27. package/dist/declarations/src/actions/ens/fetchEnsAddress.d.ts +2 -1
  28. package/dist/declarations/src/actions/index.d.ts +2 -3
  29. package/dist/declarations/src/actions/transactions/deprecatedSendTransaction.d.ts +12 -0
  30. package/dist/declarations/src/actions/transactions/fetchTransaction.d.ts +21 -0
  31. package/dist/declarations/src/actions/transactions/index.d.ts +4 -1
  32. package/dist/declarations/src/actions/transactions/prepareSendTransaction.d.ts +36 -0
  33. package/dist/declarations/src/actions/transactions/sendTransaction.d.ts +43 -8
  34. package/dist/declarations/src/client.d.ts +3 -3
  35. package/dist/declarations/src/connectors/base.d.ts +1 -2
  36. package/dist/declarations/src/connectors/coinbaseWallet.d.ts +2 -2
  37. package/dist/declarations/src/connectors/index.d.ts +1 -1
  38. package/dist/declarations/src/connectors/injected.d.ts +4 -4
  39. package/dist/declarations/src/connectors/metaMask.d.ts +1 -1
  40. package/dist/declarations/src/connectors/mock/provider.d.ts +3 -2
  41. package/dist/declarations/src/connectors/walletConnect.d.ts +3 -2
  42. package/dist/declarations/src/constants/index.d.ts +1 -1
  43. package/dist/declarations/src/constants/rpcs.d.ts +2 -2
  44. package/dist/declarations/src/errors.d.ts +10 -3
  45. package/dist/declarations/src/index.d.ts +5 -5
  46. package/dist/declarations/src/providers/alchemy.d.ts +2 -3
  47. package/dist/declarations/src/providers/infura.d.ts +2 -3
  48. package/dist/declarations/src/providers/jsonRpc.d.ts +1 -2
  49. package/dist/declarations/src/providers/public.d.ts +2 -4
  50. package/dist/declarations/src/types/index.d.ts +133 -129
  51. package/dist/declarations/src/utils/configureChains.d.ts +3 -1
  52. package/dist/declarations/src/utils/getInjectedName.d.ts +2 -1
  53. package/dist/{client-a6e61429.cjs.prod.js → getProvider-5b369460.cjs.prod.js} +449 -56
  54. package/dist/{client-a05fd511.esm.js → getProvider-dda5b21b.esm.js} +383 -14
  55. package/dist/{client-71ece661.cjs.dev.js → getProvider-e4848469.cjs.dev.js} +449 -56
  56. package/dist/{rpcs-1fd0a12f.cjs.prod.js → rpcs-3d4e8104.cjs.dev.js} +9 -9
  57. package/dist/{rpcs-f1d24f0e.cjs.dev.js → rpcs-4b3a7778.cjs.prod.js} +9 -9
  58. package/dist/{rpcs-b73a8f60.esm.js → rpcs-5dc0ea1f.esm.js} +8 -8
  59. package/dist/wagmi-core.cjs.dev.js +591 -298
  60. package/dist/wagmi-core.cjs.prod.js +591 -298
  61. package/dist/wagmi-core.esm.js +499 -213
  62. package/package.json +8 -4
  63. package/providers/alchemy/dist/wagmi-core-providers-alchemy.cjs.dev.js +5 -7
  64. package/providers/alchemy/dist/wagmi-core-providers-alchemy.cjs.prod.js +5 -7
  65. package/providers/alchemy/dist/wagmi-core-providers-alchemy.esm.js +5 -7
  66. package/providers/infura/dist/wagmi-core-providers-infura.cjs.dev.js +5 -7
  67. package/providers/infura/dist/wagmi-core-providers-infura.cjs.prod.js +5 -7
  68. package/providers/infura/dist/wagmi-core-providers-infura.esm.js +5 -7
  69. package/providers/jsonRpc/dist/wagmi-core-providers-jsonRpc.cjs.dev.js +0 -2
  70. package/providers/jsonRpc/dist/wagmi-core-providers-jsonRpc.cjs.prod.js +0 -2
  71. package/providers/jsonRpc/dist/wagmi-core-providers-jsonRpc.esm.js +0 -2
  72. package/providers/public/dist/wagmi-core-providers-public.cjs.dev.js +0 -2
  73. package/providers/public/dist/wagmi-core-providers-public.cjs.prod.js +0 -2
  74. package/providers/public/dist/wagmi-core-providers-public.esm.js +0 -2
  75. package/dist/base-797ad073.cjs.prod.js +0 -343
  76. package/dist/base-90b7f3e4.cjs.dev.js +0 -343
  77. package/dist/base-b565d5d4.esm.js +0 -316
  78. package/dist/declarations/src/actions/tokens/index.d.ts +0 -1
@@ -1,20 +1,19 @@
1
- import { g as getClient } from './client-a05fd511.esm.js';
2
- export { C as Client, I as InjectedConnector, c as createClient, a as createStorage, n as noopStorage } from './client-a05fd511.esm.js';
3
- import { C as ConnectorAlreadyConnectedError, P as ProviderChainsNotFound, a as ChainDoesNotSupportMulticallError, b as ContractMethodNoResultError, c as ConnectorNotFoundError, d as ChainMismatchError, U as UserRejectedRequestError, n as normalizeChainId, S as SwitchChainNotSupportedError } from './base-b565d5d4.esm.js';
4
- export { A as AddChainError, a as ChainDoesNotSupportMulticallError, d as ChainMismatchError, f as ChainNotConfiguredError, e as Connector, C as ConnectorAlreadyConnectedError, c as ConnectorNotFoundError, b as ContractMethodNoResultError, P as ProviderChainsNotFound, g as ProviderRpcError, R as ResourceUnavailableError, h as RpcError, i as SwitchChainError, S as SwitchChainNotSupportedError, U as UserRejectedRequestError, n as normalizeChainId } from './base-b565d5d4.esm.js';
5
- import { Contract, logger } from 'ethers/lib/ethers';
6
- import { isAddress, Logger, formatUnits, getAddress } from 'ethers/lib/utils';
1
+ import { g as getClient, C as ConnectorAlreadyConnectedError, a as ConnectorNotFoundError, b as ChainMismatchError, U as UserRejectedRequestError, c as ContractMethodDoesNotExistError, d as getProvider, P as ProviderChainsNotFound, e as ChainDoesNotSupportMulticallError, f as ContractMethodNoResultError, n as normalizeChainId, S as SwitchChainNotSupportedError } from './getProvider-dda5b21b.esm.js';
2
+ export { A as AddChainError, e as ChainDoesNotSupportMulticallError, b as ChainMismatchError, k as ChainNotConfiguredError, i as Client, j as Connector, C as ConnectorAlreadyConnectedError, a as ConnectorNotFoundError, c as ContractMethodDoesNotExistError, f as ContractMethodNoResultError, I as InjectedConnector, P as ProviderChainsNotFound, l as ProviderRpcError, R as ResourceUnavailableError, m as RpcError, o as SwitchChainError, S as SwitchChainNotSupportedError, U as UserRejectedRequestError, h as createClient, p as createStorage, d as getProvider, q as noopStorage, n as normalizeChainId } from './getProvider-dda5b21b.esm.js';
7
3
  import { providers, Contract as Contract$1 } from 'ethers';
4
+ import { Contract, logger } from 'ethers/lib/ethers';
5
+ import { formatUnits, getAddress, isAddress, Logger } from 'ethers/lib/utils';
8
6
  import shallow from 'zustand/shallow';
9
- export { a as alchemyRpcUrls, i as infuraRpcUrls, p as publicRpcUrls } from './rpcs-b73a8f60.esm.js';
10
- export { a as allChains, c as chain, b as chainId, d as defaultChains, e as defaultL2Chains, f as etherscanBlockExplorers } from './chains-fd2c546c.esm.js';
11
- import 'zustand/vanilla';
7
+ export { a as alchemyRpcUrls, i as infuraRpcUrls, p as publicRpcUrls } from './rpcs-5dc0ea1f.esm.js';
8
+ export { a as allChains, c as chain, b as chainId, d as defaultChains, e as defaultL2Chains, f as etherscanBlockExplorers } from './chains-4b1a6cf8.esm.js';
12
9
  import 'zustand/middleware';
10
+ import 'zustand/vanilla';
13
11
  import 'eventemitter3';
14
12
 
15
13
  function configureChains(defaultChains, providers) {
16
14
  let {
17
15
  minQuorum = 1,
16
+ pollingInterval = 4000,
18
17
  targetQuorum = 1,
19
18
  stallTimeout
20
19
  } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
@@ -60,21 +59,27 @@ function configureChains(defaultChains, providers) {
60
59
  return {
61
60
  chains,
62
61
  provider: _ref2 => {
63
- var _defaultChains$, _chainProviders$;
62
+ var _defaultChains$;
64
63
 
65
64
  let {
66
65
  chainId
67
66
  } = _ref2;
68
67
  const activeChainId = chainId && chains.some(x => x.id === chainId) ? chainId : (_defaultChains$ = defaultChains[0]) === null || _defaultChains$ === void 0 ? void 0 : _defaultChains$.id;
69
68
  const chainProviders = providers_[activeChainId];
70
- if (!chainProviders) throw new Error("No providers configured for chain \"".concat(activeChainId, "\""));
71
- if (chainProviders.length === 1) return Object.assign(((_chainProviders$ = chainProviders[0]) === null || _chainProviders$ === void 0 ? void 0 : _chainProviders$.call(chainProviders)) || {}, {
72
- chains
73
- });
69
+ if (!chainProviders || !chainProviders[0]) throw new Error("No providers configured for chain \"".concat(activeChainId, "\""));
70
+
71
+ if (chainProviders.length === 1) {
72
+ return Object.assign(chainProviders[0](), {
73
+ chains,
74
+ pollingInterval
75
+ });
76
+ }
77
+
74
78
  return Object.assign(fallbackProvider(targetQuorum, minQuorum, chainProviders, {
75
79
  stallTimeout
76
80
  }), {
77
- chains
81
+ chains,
82
+ pollingInterval
78
83
  });
79
84
  },
80
85
  webSocketProvider: _ref3 => {
@@ -264,9 +269,12 @@ async function connect(_ref) {
264
269
  connector
265
270
  };
266
271
  } catch (err) {
267
- client.setState(x => ({ ...x,
268
- status: 'disconnected'
269
- }));
272
+ client.setState(x => {
273
+ return { ...x,
274
+ // Keep existing connector connected in case of error
275
+ status: x.connector ? 'connected' : 'disconnected'
276
+ };
277
+ });
270
278
  throw err;
271
279
  }
272
280
  }
@@ -287,15 +295,151 @@ function getContract(_ref) {
287
295
  return new Contract$1(addressOrName, contractInterface, signerOrProvider);
288
296
  }
289
297
 
290
- function getProvider() {
298
+ async function deprecatedWriteContract(_ref) {
291
299
  let {
300
+ addressOrName,
301
+ args,
302
+ chainId,
303
+ contractInterface,
304
+ functionName,
305
+ overrides,
306
+ signerOrProvider
307
+ } = _ref;
308
+ const {
309
+ connector
310
+ } = getClient();
311
+ if (!connector) throw new ConnectorNotFoundError();
312
+ const params = [...(Array.isArray(args) ? args : args ? [args] : []), ...(overrides ? [overrides] : [])];
313
+
314
+ try {
315
+ var _chain;
316
+
317
+ let chain;
318
+
319
+ if (chainId) {
320
+ const activeChainId = await connector.getChainId(); // Try to switch chain to provided `chainId`
321
+
322
+ if (chainId !== activeChainId) {
323
+ var _connector$chains$fin, _connector$chains$fin2, _connector$chains$fin3, _connector$chains$fin4;
324
+
325
+ if (connector.switchChain) chain = await connector.switchChain(chainId);else throw new ChainMismatchError({
326
+ activeChain: (_connector$chains$fin = (_connector$chains$fin2 = connector.chains.find(x => x.id === activeChainId)) === null || _connector$chains$fin2 === void 0 ? void 0 : _connector$chains$fin2.name) !== null && _connector$chains$fin !== void 0 ? _connector$chains$fin : "Chain ".concat(activeChainId),
327
+ targetChain: (_connector$chains$fin3 = (_connector$chains$fin4 = connector.chains.find(x => x.id === chainId)) === null || _connector$chains$fin4 === void 0 ? void 0 : _connector$chains$fin4.name) !== null && _connector$chains$fin3 !== void 0 ? _connector$chains$fin3 : "Chain ".concat(chainId)
328
+ });
329
+ }
330
+ }
331
+
332
+ const signer = await connector.getSigner({
333
+ chainId: (_chain = chain) === null || _chain === void 0 ? void 0 : _chain.id
334
+ });
335
+ const contract = getContract({
336
+ addressOrName,
337
+ contractInterface,
338
+ signerOrProvider
339
+ });
340
+ const contractWithSigner = contract.connect(signer);
341
+ const contractFunction = contractWithSigner[functionName];
342
+ if (!contractFunction) console.warn("\"".concat(functionName, "\" does not exist in interface for contract \"").concat(addressOrName, "\""));
343
+ return await contractFunction(...params);
344
+ } catch (error) {
345
+ if (error.code === 4001) throw new UserRejectedRequestError(error);
346
+ throw error;
347
+ }
348
+ }
349
+
350
+ async function fetchToken(_ref) {
351
+ let {
352
+ address,
353
+ chainId,
354
+ formatUnits: units = 'ether'
355
+ } = _ref;
356
+ const erc20Config = {
357
+ addressOrName: address,
358
+ contractInterface: erc20ABI,
292
359
  chainId
293
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
294
- const client = getClient();
295
- if (chainId && typeof client.config.provider === 'function') return client.config.provider({
296
- chainId
360
+ };
361
+ const [decimals, name, symbol, totalSupply] = await readContracts({
362
+ allowFailure: false,
363
+ contracts: [{ ...erc20Config,
364
+ functionName: 'decimals'
365
+ }, { ...erc20Config,
366
+ functionName: 'name'
367
+ }, { ...erc20Config,
368
+ functionName: 'symbol'
369
+ }, { ...erc20Config,
370
+ functionName: 'totalSupply'
371
+ }]
297
372
  });
298
- return client.provider;
373
+ return {
374
+ address,
375
+ decimals,
376
+ name,
377
+ symbol,
378
+ totalSupply: {
379
+ formatted: formatUnits(totalSupply, units),
380
+ value: totalSupply
381
+ }
382
+ };
383
+ }
384
+
385
+ /**
386
+ * @description Prepares the parameters required for a contract write transaction.
387
+ *
388
+ * Returns config to be passed through to `writeContract`.
389
+ *
390
+ * @example
391
+ * import { prepareWriteContract, writeContract } from '@wagmi/core'
392
+ *
393
+ * const config = await prepareWriteContract({
394
+ * addressOrName: '0x...',
395
+ * contractInterface: wagmiAbi,
396
+ * functionName: 'mint',
397
+ * })
398
+ * const result = await writeContract(config)
399
+ */
400
+ async function prepareWriteContract(_ref) {
401
+ let {
402
+ addressOrName,
403
+ args,
404
+ chainId,
405
+ contractInterface,
406
+ functionName,
407
+ overrides,
408
+ signer: signer_
409
+ } = _ref;
410
+ const signer = signer_ !== null && signer_ !== void 0 ? signer_ : await fetchSigner();
411
+ if (!signer) throw new ConnectorNotFoundError();
412
+ const contract = getContract({
413
+ addressOrName,
414
+ contractInterface,
415
+ signerOrProvider: signer
416
+ });
417
+ const populateTransactionFn = contract.populateTransaction[functionName];
418
+
419
+ if (!populateTransactionFn) {
420
+ throw new ContractMethodDoesNotExistError({
421
+ addressOrName,
422
+ functionName
423
+ });
424
+ }
425
+
426
+ const params = [...(Array.isArray(args) ? args : args ? [args] : []), ...(overrides ? [overrides] : [])];
427
+ const unsignedTransaction = await populateTransactionFn(...params);
428
+ const gasLimit = unsignedTransaction.gasLimit || (await signer.estimateGas(unsignedTransaction));
429
+ return {
430
+ addressOrName,
431
+ args,
432
+ ...(chainId ? {
433
+ chainId
434
+ } : {}),
435
+ contractInterface,
436
+ functionName,
437
+ overrides,
438
+ request: { ...unsignedTransaction,
439
+ gasLimit
440
+ },
441
+ mode: 'prepared'
442
+ };
299
443
  }
300
444
 
301
445
  function getWebSocketProvider() {
@@ -424,11 +568,9 @@ async function multicall(_ref) {
424
568
  } = contracts[i];
425
569
 
426
570
  if (returnData === '0x') {
427
- var _chain$blockExplorers;
428
-
429
571
  const err = new ContractMethodNoResultError({
430
572
  addressOrName,
431
- blockExplorer: (_chain$blockExplorers = chain.blockExplorers) === null || _chain$blockExplorers === void 0 ? void 0 : _chain$blockExplorers.default,
573
+ chainId: chain.id,
432
574
  functionName
433
575
  });
434
576
  if (!allowFailure) throw err;
@@ -657,21 +799,15 @@ function watchReadContracts(config, callback) {
657
799
  };
658
800
  }
659
801
 
660
- async function writeContract(_ref) {
802
+ async function deprecatedSendTransaction(_ref) {
661
803
  let {
662
- addressOrName,
663
- args,
664
804
  chainId,
665
- contractInterface,
666
- functionName,
667
- overrides,
668
- signerOrProvider
805
+ request
669
806
  } = _ref;
670
807
  const {
671
808
  connector
672
809
  } = getClient();
673
810
  if (!connector) throw new ConnectorNotFoundError();
674
- const params = [...(Array.isArray(args) ? args : args ? [args] : []), ...(overrides ? [overrides] : [])];
675
811
 
676
812
  try {
677
813
  var _chain;
@@ -694,28 +830,325 @@ async function writeContract(_ref) {
694
830
  const signer = await connector.getSigner({
695
831
  chainId: (_chain = chain) === null || _chain === void 0 ? void 0 : _chain.id
696
832
  });
697
- const contract = getContract({
698
- addressOrName,
699
- contractInterface,
700
- signerOrProvider
833
+ return await signer.sendTransaction(request);
834
+ } catch (error) {
835
+ if (error.code === 4001) throw new UserRejectedRequestError(error);
836
+ throw error;
837
+ }
838
+ }
839
+
840
+ /**
841
+ * @description Fetches transaction for hash
842
+ *
843
+ * @example
844
+ * import { fetchTransaction } from '@wagmi/core'
845
+ *
846
+ * const transaction = await fetchTransaction({
847
+ * chainId: 1,
848
+ * hash: '0x...',
849
+ * })
850
+ */
851
+ async function fetchTransaction(_ref) {
852
+ let {
853
+ chainId,
854
+ hash
855
+ } = _ref;
856
+ const provider = getProvider({
857
+ chainId
858
+ });
859
+ return await provider.getTransaction(hash);
860
+ }
861
+
862
+ async function fetchEnsAddress(_ref) {
863
+ let {
864
+ chainId,
865
+ name
866
+ } = _ref;
867
+ const provider = getProvider({
868
+ chainId
869
+ });
870
+ const address = await provider.resolveName(name);
871
+
872
+ try {
873
+ return address ? getAddress(address) : null;
874
+ } catch (_error) {
875
+ return null;
876
+ }
877
+ }
878
+
879
+ async function fetchEnsAvatar(_ref) {
880
+ let {
881
+ addressOrName,
882
+ chainId
883
+ } = _ref;
884
+ const provider = getProvider({
885
+ chainId
886
+ }); // TODO: Update with more advanced logic
887
+ // https://github.com/ensdomains/ens-avatar
888
+
889
+ const avatar = await provider.getAvatar(addressOrName);
890
+ return avatar;
891
+ }
892
+
893
+ async function fetchEnsName(_ref) {
894
+ let {
895
+ address,
896
+ chainId
897
+ } = _ref;
898
+ const provider = getProvider({
899
+ chainId
900
+ });
901
+ return await provider.lookupAddress(address);
902
+ }
903
+
904
+ async function fetchEnsResolver(_ref) {
905
+ let {
906
+ chainId,
907
+ name
908
+ } = _ref;
909
+ const provider = getProvider({
910
+ chainId
911
+ });
912
+ const resolver = await provider.getResolver(name);
913
+ return resolver;
914
+ }
915
+
916
+ /**
917
+ * @description Prepares the parameters required for sending a transaction.
918
+ *
919
+ * Returns config to be passed through to `sendTransaction`.
920
+ *
921
+ * @example
922
+ * import { prepareSendTransaction, sendTransaction } from '@wagmi/core'
923
+ *
924
+ * const config = await prepareSendTransaction({
925
+ * request: {
926
+ * to: 'moxey.eth',
927
+ * value: parseEther('1'),
928
+ * }
929
+ * })
930
+ * const result = await sendTransaction(config)
931
+ */
932
+ async function prepareSendTransaction(_ref) {
933
+ let {
934
+ chainId,
935
+ request,
936
+ signerOrProvider = getProvider({
937
+ chainId
938
+ })
939
+ } = _ref;
940
+ const [to, gasLimit] = await Promise.all([isAddress(request.to) ? Promise.resolve(request.to) : fetchEnsAddress({
941
+ name: request.to
942
+ }), request.gasLimit ? Promise.resolve(request.gasLimit) : signerOrProvider.estimateGas(request)]);
943
+ if (!to) throw new Error('Could not resolve ENS name');
944
+ return { ...(chainId ? {
945
+ chainId
946
+ } : {}),
947
+ request: { ...request,
948
+ gasLimit,
949
+ to
950
+ },
951
+ mode: 'prepared'
952
+ };
953
+ }
954
+
955
+ /**
956
+ * @description Function to send a transaction.
957
+ *
958
+ * It is recommended to pair this with the `prepareSendTransaction` function to avoid
959
+ * [UX pitfalls](https://wagmi.sh/docs/prepare-hooks/intro#ux-pitfalls-without-prepare-hooks).
960
+ *
961
+ * @example
962
+ * import { prepareSendTransaction, sendTransaction } from '@wagmi/core'
963
+ *
964
+ * const config = await prepareSendTransaction({
965
+ * to: 'moxey.eth',
966
+ * value: parseEther('1'),
967
+ * })
968
+ * const result = await sendTransaction(config)
969
+ */
970
+ async function sendTransaction(_ref) {
971
+ let {
972
+ chainId,
973
+ mode,
974
+ request
975
+ } = _ref;
976
+
977
+ /********************************************************************/
978
+
979
+ /** START: iOS App Link cautious code. */
980
+
981
+ /** Do not perform any async operations in this block. */
982
+
983
+ /** Ref: wagmi.sh/docs/prepare-hooks/intro#ios-app-link-constraints */
984
+
985
+ /********************************************************************/
986
+ // `fetchSigner` isn't really "asynchronous" as we have already
987
+ // initialized the provider upon user connection, so it will return
988
+ // immediately.
989
+ const signer = await fetchSigner();
990
+ if (!signer) throw new ConnectorNotFoundError();
991
+
992
+ if (mode === 'prepared') {
993
+ if (!request.gasLimit) throw new Error('`gasLimit` is required');
994
+ if (!request.to) throw new Error('`to` is required');
995
+ }
996
+
997
+ const {
998
+ chain: activeChain,
999
+ chains
1000
+ } = getNetwork();
1001
+ const activeChainId = activeChain === null || activeChain === void 0 ? void 0 : activeChain.id;
1002
+
1003
+ if (chainId && chainId !== (activeChain === null || activeChain === void 0 ? void 0 : activeChain.id)) {
1004
+ var _chains$find$name, _chains$find, _chains$find$name2, _chains$find2;
1005
+
1006
+ throw new ChainMismatchError({
1007
+ activeChain: (_chains$find$name = (_chains$find = chains.find(x => x.id === activeChainId)) === null || _chains$find === void 0 ? void 0 : _chains$find.name) !== null && _chains$find$name !== void 0 ? _chains$find$name : "Chain ".concat(activeChainId),
1008
+ targetChain: (_chains$find$name2 = (_chains$find2 = chains.find(x => x.id === chainId)) === null || _chains$find2 === void 0 ? void 0 : _chains$find2.name) !== null && _chains$find$name2 !== void 0 ? _chains$find$name2 : "Chain ".concat(chainId)
701
1009
  });
702
- const contractWithSigner = contract.connect(signer);
703
- const contractFunction = contractWithSigner[functionName];
704
- if (!contractFunction) console.warn("\"".concat(functionName, "\" does not exist in interface for contract \"").concat(addressOrName, "\""));
705
- return await contractFunction(...params);
1010
+ }
1011
+
1012
+ try {
1013
+ var _connectUnchecked, _ref2;
1014
+
1015
+ // Why don't we just use `signer.sendTransaction`?
1016
+ // The `signer.sendTransaction` method performs async
1017
+ // heavy operations (such as fetching block number)
1018
+ // which is not really needed for our case.
1019
+ // Having async heavy operations has side effects
1020
+ // when using it in a click handler (iOS deep linking issues,
1021
+ // delay to open wallet, etc).
1022
+ const uncheckedSigner = (_connectUnchecked = (_ref2 = signer).connectUnchecked) === null || _connectUnchecked === void 0 ? void 0 : _connectUnchecked.call(_ref2);
1023
+ const {
1024
+ hash,
1025
+ wait
1026
+ } = await (uncheckedSigner !== null && uncheckedSigner !== void 0 ? uncheckedSigner : signer).sendTransaction(request);
1027
+ /********************************************************************/
1028
+
1029
+ /** END: iOS App Link cautious code. */
1030
+
1031
+ /** Go nuts! */
1032
+
1033
+ /********************************************************************/
1034
+
1035
+ return {
1036
+ hash,
1037
+ wait
1038
+ };
706
1039
  } catch (error) {
707
1040
  if (error.code === 4001) throw new UserRejectedRequestError(error);
708
1041
  throw error;
709
1042
  }
710
1043
  }
711
1044
 
1045
+ async function waitForTransaction(_ref) {
1046
+ let {
1047
+ chainId,
1048
+ confirmations,
1049
+ hash,
1050
+ timeout,
1051
+ wait: wait_
1052
+ } = _ref;
1053
+ let promise;
1054
+
1055
+ if (hash) {
1056
+ const provider = getProvider({
1057
+ chainId
1058
+ });
1059
+ promise = provider.waitForTransaction(hash, confirmations, timeout);
1060
+ } else if (wait_) promise = wait_(confirmations);else throw new Error('hash or wait is required');
1061
+
1062
+ return await promise;
1063
+ }
1064
+
1065
+ /**
1066
+ * @description Function to call a contract write method.
1067
+ *
1068
+ * It is recommended to pair this with the {@link prepareWriteContract} function
1069
+ * to avoid [UX pitfalls](https://wagmi.sh/docs/prepare-hooks/intro#ux-pitfalls-without-prepare-hooks).
1070
+ *
1071
+ * @example
1072
+ * import { prepareWriteContract, writeContract } from '@wagmi/core'
1073
+ *
1074
+ * const config = await prepareWriteContract({
1075
+ * addressOrName: '0x...',
1076
+ * contractInterface: wagmiAbi,
1077
+ * functionName: 'mint',
1078
+ * })
1079
+ * const result = await writeContract(config)
1080
+ */
1081
+ async function writeContract(_ref) {
1082
+ let {
1083
+ addressOrName,
1084
+ args,
1085
+ chainId,
1086
+ contractInterface,
1087
+ functionName,
1088
+ mode,
1089
+ overrides,
1090
+ request: request_
1091
+ } = _ref;
1092
+
1093
+ /********************************************************************/
1094
+
1095
+ /** START: iOS App Link cautious code. */
1096
+
1097
+ /** Do not perform any async operations in this block. */
1098
+
1099
+ /** Ref: wagmi.sh/docs/prepare-hooks/intro#ios-app-link-constraints */
1100
+
1101
+ /********************************************************************/
1102
+ const signer = await fetchSigner();
1103
+ if (!signer) throw new ConnectorNotFoundError();
1104
+ const {
1105
+ chain: activeChain,
1106
+ chains
1107
+ } = getNetwork();
1108
+ const activeChainId = activeChain === null || activeChain === void 0 ? void 0 : activeChain.id;
1109
+
1110
+ if (chainId && chainId !== activeChainId) {
1111
+ var _chains$find$name, _chains$find, _chains$find$name2, _chains$find2;
1112
+
1113
+ throw new ChainMismatchError({
1114
+ activeChain: (_chains$find$name = (_chains$find = chains.find(x => x.id === activeChainId)) === null || _chains$find === void 0 ? void 0 : _chains$find.name) !== null && _chains$find$name !== void 0 ? _chains$find$name : "Chain ".concat(activeChainId),
1115
+ targetChain: (_chains$find$name2 = (_chains$find2 = chains.find(x => x.id === chainId)) === null || _chains$find2 === void 0 ? void 0 : _chains$find2.name) !== null && _chains$find$name2 !== void 0 ? _chains$find$name2 : "Chain ".concat(chainId)
1116
+ });
1117
+ }
1118
+
1119
+ if (mode === 'prepared') {
1120
+ if (!request_) throw new Error('`request` is required');
1121
+ }
1122
+
1123
+ const request = mode === 'recklesslyUnprepared' ? (await prepareWriteContract({
1124
+ addressOrName,
1125
+ args,
1126
+ contractInterface,
1127
+ functionName,
1128
+ overrides
1129
+ })).request : request_;
1130
+ const transaction = await sendTransaction({
1131
+ request,
1132
+ mode: 'prepared'
1133
+ });
1134
+ /********************************************************************/
1135
+
1136
+ /** END: iOS App Link cautious code. */
1137
+
1138
+ /** Go nuts! */
1139
+
1140
+ /********************************************************************/
1141
+
1142
+ return transaction;
1143
+ }
1144
+
712
1145
  async function fetchBalance(_ref) {
713
1146
  var _client$chains, _chain$nativeCurrency, _chain$nativeCurrency2, _chain$nativeCurrency3, _chain$nativeCurrency4;
714
1147
 
715
1148
  let {
716
1149
  addressOrName,
717
1150
  chainId,
718
- formatUnits: unit = 'ether',
1151
+ formatUnits: unit,
719
1152
  token
720
1153
  } = _ref;
721
1154
  const client = getClient();
@@ -752,9 +1185,8 @@ async function fetchBalance(_ref) {
752
1185
  });
753
1186
  return {
754
1187
  decimals,
755
- formatted: formatUnits(value !== null && value !== void 0 ? value : '0', unit),
1188
+ formatted: formatUnits(value !== null && value !== void 0 ? value : '0', unit !== null && unit !== void 0 ? unit : decimals),
756
1189
  symbol,
757
- unit,
758
1190
  value
759
1191
  };
760
1192
  }
@@ -764,9 +1196,8 @@ async function fetchBalance(_ref) {
764
1196
  const chain = chains.find(x => x.id === provider.network.chainId);
765
1197
  return {
766
1198
  decimals: (_chain$nativeCurrency = chain === null || chain === void 0 ? void 0 : (_chain$nativeCurrency2 = chain.nativeCurrency) === null || _chain$nativeCurrency2 === void 0 ? void 0 : _chain$nativeCurrency2.decimals) !== null && _chain$nativeCurrency !== void 0 ? _chain$nativeCurrency : 18,
767
- formatted: formatUnits(value !== null && value !== void 0 ? value : '0', unit),
1199
+ formatted: formatUnits(value !== null && value !== void 0 ? value : '0', unit !== null && unit !== void 0 ? unit : 'ether'),
768
1200
  symbol: (_chain$nativeCurrency3 = chain === null || chain === void 0 ? void 0 : (_chain$nativeCurrency4 = chain.nativeCurrency) === null || _chain$nativeCurrency4 === void 0 ? void 0 : _chain$nativeCurrency4.symbol) !== null && _chain$nativeCurrency3 !== void 0 ? _chain$nativeCurrency3 : 'ETH',
769
- unit,
770
1201
  value
771
1202
  };
772
1203
  }
@@ -873,42 +1304,32 @@ async function signTypedData(_ref) {
873
1304
  types,
874
1305
  value
875
1306
  } = _ref;
1307
+ const signer = await fetchSigner();
1308
+ if (!signer) throw new ConnectorNotFoundError();
876
1309
  const {
877
- connector
878
- } = getClient();
879
- if (!connector) throw new ConnectorNotFoundError();
880
-
881
- try {
882
- var _chain;
883
-
884
- const {
885
- chainId
886
- } = domain;
887
- let chain;
1310
+ chain: activeChain,
1311
+ chains
1312
+ } = getNetwork();
1313
+ const {
1314
+ chainId: chainId_
1315
+ } = domain;
888
1316
 
889
- if (chainId) {
890
- const chainId_ = normalizeChainId(chainId);
891
- const activeChainId = await connector.getChainId(); // Try to switch chain to provided `chainId`
1317
+ if (chainId_) {
1318
+ const chainId = normalizeChainId(chainId_);
1319
+ const activeChainId = activeChain === null || activeChain === void 0 ? void 0 : activeChain.id;
892
1320
 
893
- if (chainId !== activeChainId) {
894
- var _connector$chains$fin, _connector$chains$fin2, _connector$chains$fin3, _connector$chains$fin4;
1321
+ if (chainId !== (activeChain === null || activeChain === void 0 ? void 0 : activeChain.id)) {
1322
+ var _chains$find$name, _chains$find, _chains$find$name2, _chains$find2;
895
1323
 
896
- if (connector.switchChain) chain = await connector.switchChain(chainId_);else throw new ChainMismatchError({
897
- activeChain: (_connector$chains$fin = (_connector$chains$fin2 = connector.chains.find(x => x.id === activeChainId)) === null || _connector$chains$fin2 === void 0 ? void 0 : _connector$chains$fin2.name) !== null && _connector$chains$fin !== void 0 ? _connector$chains$fin : "Chain ".concat(activeChainId),
898
- targetChain: (_connector$chains$fin3 = (_connector$chains$fin4 = connector.chains.find(x => x.id === chainId_)) === null || _connector$chains$fin4 === void 0 ? void 0 : _connector$chains$fin4.name) !== null && _connector$chains$fin3 !== void 0 ? _connector$chains$fin3 : "Chain ".concat(chainId_)
899
- });
900
- }
1324
+ throw new ChainMismatchError({
1325
+ activeChain: (_chains$find$name = (_chains$find = chains.find(x => x.id === activeChainId)) === null || _chains$find === void 0 ? void 0 : _chains$find.name) !== null && _chains$find$name !== void 0 ? _chains$find$name : "Chain ".concat(activeChainId),
1326
+ targetChain: (_chains$find$name2 = (_chains$find2 = chains.find(x => x.id === chainId)) === null || _chains$find2 === void 0 ? void 0 : _chains$find2.name) !== null && _chains$find$name2 !== void 0 ? _chains$find$name2 : "Chain ".concat(chainId)
1327
+ });
901
1328
  }
1329
+ } // Method name may be changed in the future, see https://docs.ethers.io/v5/api/signer/#Signer-signTypedData
902
1330
 
903
- const signer = await connector.getSigner({
904
- chainId: (_chain = chain) === null || _chain === void 0 ? void 0 : _chain.id
905
- }); // Method name may be changed in the future, see https://docs.ethers.io/v5/api/signer/#Signer-signTypedData
906
1331
 
907
- return await signer._signTypedData(domain, types, value);
908
- } catch (error) {
909
- if (error.code === 4001) throw new UserRejectedRequestError(error);
910
- throw error;
911
- }
1332
+ return await signer._signTypedData(domain, types, value);
912
1333
  }
913
1334
 
914
1335
  async function switchNetwork(_ref) {
@@ -998,60 +1419,6 @@ function watchSigner(callback) {
998
1419
  return unsubscribe;
999
1420
  }
1000
1421
 
1001
- async function fetchEnsAddress(_ref) {
1002
- let {
1003
- chainId,
1004
- name
1005
- } = _ref;
1006
- const provider = getProvider({
1007
- chainId
1008
- });
1009
- const address = await provider.resolveName(name);
1010
-
1011
- try {
1012
- return address ? getAddress(address) : null;
1013
- } catch (_error) {
1014
- return null;
1015
- }
1016
- }
1017
-
1018
- async function fetchEnsAvatar(_ref) {
1019
- let {
1020
- addressOrName,
1021
- chainId
1022
- } = _ref;
1023
- const provider = getProvider({
1024
- chainId
1025
- }); // TODO: Update with more advanced logic
1026
- // https://github.com/ensdomains/ens-avatar
1027
-
1028
- const avatar = await provider.getAvatar(addressOrName);
1029
- return avatar;
1030
- }
1031
-
1032
- async function fetchEnsName(_ref) {
1033
- let {
1034
- address,
1035
- chainId
1036
- } = _ref;
1037
- const provider = getProvider({
1038
- chainId
1039
- });
1040
- return await provider.lookupAddress(address);
1041
- }
1042
-
1043
- async function fetchEnsResolver(_ref) {
1044
- let {
1045
- chainId,
1046
- name
1047
- } = _ref;
1048
- const provider = getProvider({
1049
- chainId
1050
- });
1051
- const resolver = await provider.getResolver(name);
1052
- return resolver;
1053
- }
1054
-
1055
1422
  async function fetchFeeData() {
1056
1423
  let {
1057
1424
  chainId,
@@ -1071,85 +1438,4 @@ async function fetchFeeData() {
1071
1438
  };
1072
1439
  }
1073
1440
 
1074
- async function fetchToken(_ref) {
1075
- let {
1076
- address,
1077
- chainId,
1078
- formatUnits: units = 'ether'
1079
- } = _ref;
1080
- const provider = getProvider({
1081
- chainId
1082
- });
1083
- const contract = new Contract(address, erc20ABI, provider);
1084
- const [symbol, decimals, totalSupply] = await Promise.all([contract.symbol(), contract.decimals(), contract.totalSupply()]);
1085
- const token = {
1086
- address,
1087
- decimals,
1088
- symbol,
1089
- totalSupply: {
1090
- formatted: formatUnits(totalSupply, units),
1091
- value: totalSupply
1092
- }
1093
- };
1094
- return token;
1095
- }
1096
-
1097
- async function sendTransaction(_ref) {
1098
- let {
1099
- chainId,
1100
- request
1101
- } = _ref;
1102
- const {
1103
- connector
1104
- } = getClient();
1105
- if (!connector) throw new ConnectorNotFoundError();
1106
-
1107
- try {
1108
- var _chain;
1109
-
1110
- let chain;
1111
-
1112
- if (chainId) {
1113
- const activeChainId = await connector.getChainId(); // Try to switch chain to provided `chainId`
1114
-
1115
- if (chainId !== activeChainId) {
1116
- var _connector$chains$fin, _connector$chains$fin2, _connector$chains$fin3, _connector$chains$fin4;
1117
-
1118
- if (connector.switchChain) chain = await connector.switchChain(chainId);else throw new ChainMismatchError({
1119
- activeChain: (_connector$chains$fin = (_connector$chains$fin2 = connector.chains.find(x => x.id === activeChainId)) === null || _connector$chains$fin2 === void 0 ? void 0 : _connector$chains$fin2.name) !== null && _connector$chains$fin !== void 0 ? _connector$chains$fin : "Chain ".concat(activeChainId),
1120
- targetChain: (_connector$chains$fin3 = (_connector$chains$fin4 = connector.chains.find(x => x.id === chainId)) === null || _connector$chains$fin4 === void 0 ? void 0 : _connector$chains$fin4.name) !== null && _connector$chains$fin3 !== void 0 ? _connector$chains$fin3 : "Chain ".concat(chainId)
1121
- });
1122
- }
1123
- }
1124
-
1125
- const signer = await connector.getSigner({
1126
- chainId: (_chain = chain) === null || _chain === void 0 ? void 0 : _chain.id
1127
- });
1128
- return await signer.sendTransaction(request);
1129
- } catch (error) {
1130
- if (error.code === 4001) throw new UserRejectedRequestError(error);
1131
- throw error;
1132
- }
1133
- }
1134
-
1135
- async function waitForTransaction(_ref) {
1136
- let {
1137
- chainId,
1138
- confirmations,
1139
- hash,
1140
- timeout,
1141
- wait: wait_
1142
- } = _ref;
1143
- let promise;
1144
-
1145
- if (hash) {
1146
- const provider = getProvider({
1147
- chainId
1148
- });
1149
- promise = provider.waitForTransaction(hash, confirmations, timeout);
1150
- } else if (wait_) promise = wait_(confirmations);else throw new Error('hash or wait is required');
1151
-
1152
- return await promise;
1153
- }
1154
-
1155
- export { configureChains, connect, deepEqual, disconnect, erc20ABI, erc721ABI, fetchBalance, fetchBlockNumber, fetchEnsAddress, fetchEnsAvatar, fetchEnsName, fetchEnsResolver, fetchFeeData, fetchSigner, fetchToken, getAccount, getContract, getNetwork, getProvider, getWebSocketProvider, parseContractResult, readContract, readContracts, sendTransaction, signMessage, signTypedData, switchNetwork, units, waitForTransaction, watchAccount, watchBlockNumber, watchContractEvent, watchNetwork, watchProvider, watchReadContract, watchReadContracts, watchSigner, watchWebSocketProvider, writeContract };
1441
+ export { configureChains, connect, deepEqual, deprecatedSendTransaction, deprecatedWriteContract, disconnect, erc20ABI, erc721ABI, fetchBalance, fetchBlockNumber, fetchEnsAddress, fetchEnsAvatar, fetchEnsName, fetchEnsResolver, fetchFeeData, fetchSigner, fetchToken, fetchTransaction, getAccount, getContract, getNetwork, getWebSocketProvider, parseContractResult, prepareSendTransaction, prepareWriteContract, readContract, readContracts, sendTransaction, signMessage, signTypedData, switchNetwork, units, waitForTransaction, watchAccount, watchBlockNumber, watchContractEvent, watchNetwork, watchProvider, watchReadContract, watchReadContracts, watchSigner, watchWebSocketProvider, writeContract };