types#TransactionsState TypeScript Examples

The following examples show how to use types#TransactionsState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Transactions.tsx    From contracts-ui with GNU General Public License v3.0 5 votes vote down vote up
export function Transactions({
  dismiss,
  txs,
}: React.HTMLAttributes<HTMLDivElement> & TransactionsState) {
  return (
    <div className={classes('z-10 fixed right-3 top-3 w-80')}>
      {Object.entries(txs).map(([id, tx]: [string, QueuedTxOptions | undefined]) => {
        const { status, events, extrinsic } = tx || {};
        const isComplete = status === 'error' || status === 'success';

        return (
          <>
            <div
              data-cy="transaction-queued"
              key={id}
              className="max-w-full dark:bg-elevation-3 dark:text-white bg-gray-200 text-gray-600 p-3 flex items-center"
            >
              <NotificationIcon status={status} />
              <div className="pl-2 flex-grow text-sm">
                <div>{extrinsic?.registry.findMetaCall(extrinsic.callIndex).method}</div>
                <div className="text-gray-400">{status}</div>
              </div>
              {isComplete && (
                <XIcon
                  className="text-gray-400 w-4 h-4"
                  onClick={() => dismiss(parseInt(id))}
                  data-cy="dismiss-notification"
                />
              )}
            </div>
            {isComplete && events && !isEmptyObj(events) && (
              <div
                className="max-w-full dark:bg-elevation-3 dark:text-white bg-gray-200 text-gray-600 p-3 mt-2 flex items-center"
                data-cy="transaction-complete"
              >
                <BellIcon className="text-yellow-400 w-12 h-12" />
                <div className="pl-2 flex-grow text-sm">
                  {Object.keys(events).map(eventName => {
                    const times = events[eventName] > 1 ? ` (x${events[eventName]})` : '';
                    return (
                      <div key={eventName} className="dark:text-gray-400">
                        {`${eventName}${times}`}
                      </div>
                    );
                  })}
                </div>
                <XIcon className="text-gray-400 w-4 h-4" onClick={() => dismiss(parseInt(id))} />
              </div>
            )}
          </>
        );
      })}
    </div>
  );
}
Example #2
Source File: TransactionsContext.tsx    From contracts-ui with GNU General Public License v3.0 5 votes vote down vote up
TransactionsContext = createContext({} as unknown as TransactionsState)
Example #3
Source File: TransactionsContext.tsx    From contracts-ui with GNU General Public License v3.0 4 votes vote down vote up
export function TransactionsContextProvider({
  children,
}: React.PropsWithChildren<Partial<TransactionsState>>) {
  const { api, keyring, systemChainType } = useApi();
  const [txs, setTxs] = useState<TransactionsQueue>({});

  function queue(options: TxOptions): number {
    setTxs({
      ...txs,
      [nextId]: {
        ...options,
        status: Status.Queued,
        events: {},
      },
    });

    return nextId;
  }
  async function process(id: number) {
    const tx = txs[id];

    if (tx) {
      const { extrinsic, accountId, isValid, onSuccess, onError } = tx;

      setTxs({ ...txs, [id]: { ...tx, status: Status.Processing } });

      let injector, accountOrPair;
      try {
        injector = await web3FromAddress(accountId);
        accountOrPair = accountId;
      } catch (e) {
        accountOrPair = keyring.getPair(accountId);
      }

      try {
        const unsub = await extrinsic.signAndSend(
          accountOrPair,
          { signer: injector?.signer || undefined },
          async result => {
            if (isResultReady(result, systemChainType)) {
              const events: Record<string, number> = {};

              result.events.forEach(record => {
                const { event } = record;
                const key = `${event.section}:${event.method}`;
                if (!events[key]) {
                  events[key] = 1;
                } else {
                  events[key]++;
                }
              });

              if (!isValid(result)) {
                setTxs({ ...txs, [id]: { ...tx, status: Status.Error, events } });

                let message = 'Transaction failed';

                if (result.dispatchError?.isModule) {
                  const decoded = api.registry.findMetaError(result.dispatchError.asModule);
                  message = `${decoded.section.toUpperCase()}.${decoded.method}: ${decoded.docs}`;
                }

                onError && onError(result);

                throw new Error(message);
              }

              onSuccess && (await onSuccess(result));

              setTxs({ ...txs, [id]: { ...tx, status: Status.Success, events } });

              unsub();

              nextId++;
            }
          }
        );
      } catch (error) {
        setTxs({ ...txs, [id]: { ...tx, status: Status.Error } });
        console.error(error);
      }
    }
  }

  function dismiss(id: number) {
    const newTxs = { ...txs };
    delete newTxs[id];
    setTxs(newTxs);
  }

  useEffect((): (() => void) => {
    let autoDismiss: NodeJS.Timeout;

    if (!isEmptyObj(txs)) {
      const completed: number[] = [];
      for (const id in txs) {
        if (txs[id]?.status === 'error' || txs[id]?.status === 'success') {
          completed.push(parseInt(id));
        }
      }
      if (completed.length > 0) {
        autoDismiss = setTimeout((): void => {
          const newTxs = { ...txs };
          completed.forEach(id => delete newTxs[id]);
          setTxs(newTxs);
        }, 5000);
      }
    }

    return () => clearTimeout(autoDismiss);
  }, [txs]);

  const state = {
    txs,
    dismiss,
    process,
    queue,
  };

  return (
    <TransactionsContext.Provider value={state}>
      <Transactions {...state} />
      {children}
    </TransactionsContext.Provider>
  );
}