useAbi.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2017-2020 @polkadot/react-hooks authors & contributors
  2. // This software may be modified and distributed under the terms
  3. // of the Apache-2.0 license. See the LICENSE file for details.
  4. import { StringOrNull } from '@polkadot/react-components/types';
  5. import { useCallback, useEffect, useState } from 'react';
  6. import { Abi } from '@polkadot/api-contract';
  7. import { registry } from '@polkadot/react-api';
  8. import { u8aToString } from '@polkadot/util';
  9. import store from './store';
  10. import { useTranslation } from './translate';
  11. interface UseAbi {
  12. abi: string | null;
  13. contractAbi: Abi | null;
  14. errorText: string | null;
  15. isAbiError: boolean;
  16. isAbiValid: boolean;
  17. isAbiSupplied: boolean;
  18. onChangeAbi: (u8a: Uint8Array) => void;
  19. onRemoveAbi: () => void;
  20. }
  21. interface ContractABIOutdated {
  22. deploy?: any;
  23. messages?: any;
  24. }
  25. export default function useAbi (initialValue: [string | null, Abi | null] = [null, null], codeHash: StringOrNull = null, isRequired = false): UseAbi {
  26. const { t } = useTranslation();
  27. const [[abi, contractAbi, isAbiSupplied, isAbiValid], setAbi] = useState<[StringOrNull, Abi | null, boolean, boolean]>([initialValue[0], initialValue[1], !!initialValue[1], !isRequired || !!initialValue[1]]);
  28. const [[isAbiError, errorText], setError] = useState<[boolean, string | null]>([false, null]);
  29. useEffect(
  30. (): void => {
  31. if (!!initialValue[0] && abi !== initialValue[0]) {
  32. setAbi([initialValue[0], initialValue[1], !!initialValue[1], !isRequired || !!initialValue[1]]);
  33. }
  34. },
  35. [abi, initialValue, isRequired]
  36. );
  37. const onChangeAbi = useCallback(
  38. (u8a: Uint8Array): void => {
  39. const json = u8aToString(u8a);
  40. try {
  41. const abiOutdated = JSON.parse(json) as ContractABIOutdated;
  42. if (abiOutdated.deploy || abiOutdated.messages) {
  43. throw new Error(t('You are using an ABI with an outdated format. Please generate a new one.'));
  44. }
  45. setAbi([json, new Abi(registry, JSON.parse(json)), true, true]);
  46. codeHash && store.saveCode(
  47. codeHash,
  48. { abi: json }
  49. );
  50. } catch (error) {
  51. console.error(error);
  52. setAbi([null, null, false, false]);
  53. setError([true, error]);
  54. }
  55. },
  56. [codeHash, t]
  57. );
  58. const onRemoveAbi = useCallback(
  59. (): void => {
  60. setAbi([null, null, false, false]);
  61. setError([false, null]);
  62. codeHash && store.saveCode(
  63. codeHash,
  64. { abi: null }
  65. );
  66. },
  67. [codeHash]
  68. );
  69. return {
  70. abi, contractAbi, errorText, isAbiError, isAbiSupplied, isAbiValid, onChangeAbi, onRemoveAbi
  71. };
  72. }