@polkadot/types/types#ITuple TypeScript Examples

The following examples show how to use @polkadot/types/types#ITuple. 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: useProxies.ts    From crust-apps with Apache License 2.0 6 votes vote down vote up
export default function useProxies (address?: string | null): State {
  const { api } = useApi();
  const { allAccounts } = useAccounts();
  const mountedRef = useIsMountedRef();
  const [known, setState] = useState<State>(EMPTY_STATE);

  useEffect((): void => {
    setState(EMPTY_STATE);

    address && api.query.proxy &&
      api.query.proxy
        .proxies<ITuple<[Vec<ITuple<[AccountId, ProxyType]> | ProxyDefinition>, BalanceOf]>>(address)
        .then(([_proxies]): void => {
          const proxies = api.tx.proxy.addProxy.meta.args.length === 3
            ? (_proxies as ProxyDefinition[]).map(({ delay, delegate, proxyType }) =>
              createProxy(allAccounts, delegate, proxyType, delay)
            )
            : (_proxies as [AccountId, ProxyType][]).map(([delegate, proxyType]) =>
              createProxy(allAccounts, delegate, proxyType)
            );
          const owned = proxies.filter(({ isOwned }) => isOwned);

          mountedRef.current && setState({
            hasOwned: owned.length !== 0,
            owned,
            proxies
          });
        })
        .catch(console.error);
  }, [allAccounts, api, address, mountedRef]);

  return known;
}
Example #2
Source File: IdentitySub.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
function extractInfo ([[ids], opts]: [[string[]], Option<ITuple<[AccountId, Data]>>[]]): [string, string][] {
  return ids.reduce((result: [string, string][], id, index): [string, string][] => {
    const opt = opts[index];

    if (opt.isSome) {
      const [, data] = opt.unwrap();

      if (data.isRaw) {
        result.push([id, u8aToString(data.asRaw)]);
      }
    }

    return result;
  }, []);
}
Example #3
Source File: index.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
optionsMulti = {
  defaultValue: {
    auctionInfo: null,
    numAuctions: null
  },
  transform: ([numAuctions, optInfo]: [AuctionIndex, Option<ITuple<[LeasePeriodOf, BlockNumber]>>]) => ({
    auctionInfo: optInfo.unwrapOr(null),
    numAuctions
  })
}
Example #4
Source File: Upcoming.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
optMulti = {
  defaultValue: {
    headHex: null,
    leases: null,
    lifecycle: null,
    manager: null
  },
  transform: ([optHead, optGenesis, optLifecycle, optInfo, leases]: [Option<HeadData>, Option<ParaGenesisArgs>, Option<ParaLifecycle>, Option<ParaInfo>, Vec<Option<ITuple<[AccountId, BalanceOf]>>>]): MultiState => ({
    headHex: optHead.isSome
      ? sliceHex(optHead.unwrap())
      : optGenesis.isSome
        ? sliceHex(optGenesis.unwrap().genesisHead)
        : null,
    leases: leases
      ? leases
        .map((optLease, period): LeaseInfo | null => {
          if (optLease.isNone) {
            return null;
          }

          const [accountId, balance] = optLease.unwrap();

          return {
            accountId,
            balance,
            period
          };
        })
        .filter((item): item is LeaseInfo => !!item)
      : [],
    lifecycle: optLifecycle.unwrapOr(null),
    manager: optInfo.isSome
      ? optInfo.unwrap().manager
      : null
  })
}
Example #5
Source File: index.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
optExtractCandidates = {
  transform: (entries: [StorageKey<[AccountId]>, Option<ITuple<[BalanceOf, BidKind]>>][]): CandidateSuspend[] =>
    entries
      .filter(([{ args: [accountId] }, opt]) => opt.isSome && accountId)
      .map(([{ args: [accountId] }, opt]) => {
        const [balance, bid] = opt.unwrap();

        return { accountId, balance, bid };
      })
      .sort((a, b) => a.balance.cmp(b.balance))
}
Example #6
Source File: Address.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
async function queryForProxy (api: ApiPromise, allAccounts: string[], address: string, tx: SubmittableExtrinsic<'promise'>): Promise<ProxyState | null> {
  if (isFunction(api.query.proxy?.proxies)) {
    const { isProxied } = extractExternal(address);
    const [_proxies] = await api.query.proxy.proxies<ITuple<[Vec<ITuple<[AccountId, ProxyType]> | ProxyDefinition>, BalanceOf]>>(address);
    const proxies = api.tx.proxy.addProxy.meta.args.length === 3
      ? (_proxies as ProxyDefinition[]).map(({ delegate, proxyType }): [string, ProxyType] => [delegate.toString(), proxyType])
      : (_proxies as [AccountId, ProxyType][]).map(([delegate, proxyType]): [string, ProxyType] => [delegate.toString(), proxyType]);
    const proxiesFilter = filterProxies(allAccounts, tx, proxies);

    if (proxiesFilter.length) {
      return { address, isProxied, proxies, proxiesFilter };
    }
  }

  return null;
}
Example #7
Source File: democracy_proposal.ts    From commonwealth with GNU General Public License v3.0 6 votes vote down vote up
public updateVoters = async () => {
    const depositOpt = await this._Chain.api.query.democracy.depositOf(this.data.index);
    if (!depositOpt.isSome) return;
    const depositorsTuple: ITuple<[ BalanceOf | Vec<AccountId>, BalanceOf | Vec<AccountId> ]> = depositOpt.unwrap();
    let depositors: Vec<AccountId>;
    if (isFunction((depositorsTuple[1] as BalanceOf).mul)) {
      depositors = depositorsTuple[0] as Vec<AccountId>;
    } else {
      depositors = depositorsTuple[1] as Vec<AccountId>;
    }
    for (const depositor of depositors) {
      const acct = this._Accounts.fromAddress(depositor.toString());
      const votes = this.getVotes(acct);
      if (!votes.length) {
        this.addOrUpdateVote(new DepositVote(acct, this._Chain.coins(this.data.deposit)));
      } else {
        // if they second a proposal multiple times, sum up the vote weight
        const vote = new DepositVote(acct, this._Chain.coins(votes[0].deposit.add(this.data.deposit)));
        this.addOrUpdateVote(vote);
      }
    }
  }
Example #8
Source File: storage.ts    From interbtc-api with Apache License 2.0 6 votes vote down vote up
async function setStorage(
    api: ApiPromise,
    moduleName: string,
    storageItemName: string,
    data: string,
    account: AddressOrPair
): Promise<void> {
    const key = getStorageKey(moduleName, storageItemName);
    const storageKey = api.createType("StorageKey", key);
    const storageData = api.createType("StorageData", data);
    const tx = api.tx.sudo.sudo(api.tx.system.setStorage([[storageKey, storageData] as ITuple<[StorageKey, Bytes]>]));
    await DefaultTransactionAPI.sendLogged(api, account, tx, undefined, true);
}
Example #9
Source File: PricesTask.ts    From guardian with Apache License 2.0 6 votes vote down vote up
async start<T extends BaseSubstrateGuardian>(guardian: T) {
    const { apiRx } = await guardian.isReady();

    const { key, period } = this.arguments;
    if (key === 'all') {
      return observeRPC<Vec<ITuple<[Codec, Option<TimestampedValue>]>>>(
        apiRx.rpc.oracle.getAllValues,
        ['Aggregated'],
        period
      ).pipe(
        mergeMap((result): Observable<Price> => {
          return from(result).pipe(
            filter(([, item]) => item.isSome),
            map(([key, item]) => ({
              key: key.toString(),
              value: getValueFromTimestampValue(item.unwrap()).toString()
            }))
          );
        })
      );
    }

    const keys = castArray(key).map((x) => apiRx.createType('CurrencyId', x));
    return from(keys).pipe(
      mergeMap((key) =>
        from(getOraclePrice(apiRx, period)(key)).pipe(
          map((price) => ({ key: key.toString(), value: price.toFixed(0) }))
        )
      ),
      filter((price) => price.value.length > 0)
    );
  }
Example #10
Source File: Address.tsx    From subscan-multisig-react with Apache License 2.0 6 votes vote down vote up
async function queryForProxy(
  api: ApiPromise,
  allAccounts: string[],
  address: string,
  tx: SubmittableExtrinsic<'promise'>
): Promise<ProxyState | null> {
  if (isFunction(api.query.proxy?.proxies)) {
    const { isProxied } = extractExternal(address);
    const [_proxies] = await api.query.proxy.proxies<
      ITuple<[Vec<ITuple<[AccountId, ProxyType]> | ProxyDefinition>, BalanceOf]>
    >(address);
    const proxies =
      api.tx.proxy.addProxy.meta.args.length === 3
        ? (_proxies as ProxyDefinition[]).map(({ delegate, proxyType }): [string, ProxyType] => [
            delegate.toString(),
            proxyType,
          ])
        : (_proxies as [AccountId, ProxyType][]).map(([delegate, proxyType]): [string, ProxyType] => [
            delegate.toString(),
            proxyType,
          ]);
    const proxiesFilter = filterProxies(allAccounts, tx, proxies);

    if (proxiesFilter.length) {
      return { address, isProxied, proxies, proxiesFilter };
    }
  }

  return null;
}
Example #11
Source File: IdentitySub.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
transformIds = {
  transform: ([, ids]: ITuple<[Balance, Vec<AccountId>]>) => ids.map((a) => a.toString())
}
Example #12
Source File: Queue.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
function extractEvents (result?: SubmittableResult): ActionStatus[] {
  return mergeStatus(
    ((result && result.events) || [])
      // filter events handled globally, or those we are not interested in, these are
      // handled by the global overview, so don't add them here
      .filter((record): boolean => !!record.event && record.event.section !== 'democracy')
      .map(({ event: { data, method, section } }): ActionStatusPartial => {
        if (section === 'system' && method === 'ExtrinsicFailed') {
          const [dispatchError] = data as unknown as ITuple<[DispatchError]>;
          let message = dispatchError.type;

          if (dispatchError.isModule) {
            try {
              const mod = dispatchError.asModule;
              const error = dispatchError.registry.findMetaError(mod);

              message = `${error.section}.${error.name}`;
            } catch (error) {
              // swallow
            }
          }

          return {
            action: `${section}.${method}`,
            message,
            status: 'error'
          };
        } else if (section === 'contracts') {
          if (method === 'ContractExecution' && data.length === 2) {
            // see if we have info for this contract
            const [accountId, encoded] = data;

            try {
              const abi = getContractAbi(accountId.toString());

              if (abi) {
                const decoded = abi.decodeEvent(encoded as Bytes);

                return {
                  action: decoded.event.identifier,
                  message: 'contract event',
                  status: 'event'
                };
              }
            } catch (error) {
              // ABI mismatch?
              console.error(error);
            }
          } else if (method === 'Evicted') {
            return {
              action: `${section}.${method}`,
              message: 'contract evicted',
              status: 'error'
            };
          }
        }

        return {
          action: `${section}.${method}`,
          message: EVENT_MESSAGE,
          status: 'event'
        };
      })
  );
}
Example #13
Source File: keyring.ts    From sdk with Apache License 2.0 5 votes vote down vote up
function _extractEvents(api: ApiPromise, result: SubmittableResult) {
  if (!result || !result.events) {
    return {};
  }

  let success = false;
  let error: DispatchError["type"] = "";
  result.events
    .filter((event) => !!event.event)
    .map(({ event: { data, method, section } }) => {
      if (section === "system" && method === "ExtrinsicFailed") {
        const [dispatchError] = (data as unknown) as ITuple<[DispatchError]>;
        let message = dispatchError.type;

        if (dispatchError.isModule) {
          try {
            const mod = dispatchError.asModule;
            const err = api.registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()]));

            message = `${err.section}.${err.name}`;
          } catch (error) {
            // swallow error
          }
        }
        (<any>window).send("txUpdateEvent", {
          title: `${section}.${method}`,
          message,
        });
        error = message;
      } else {
        (<any>window).send("txUpdateEvent", {
          title: `${section}.${method}`,
          message: "ok",
        });
        if (section == "system" && method == "ExtrinsicSuccess") {
          success = true;
        }
      }
    });
  return { success, error };
}
Example #14
Source File: Queue.tsx    From subscan-multisig-react with Apache License 2.0 5 votes vote down vote up
function extractEvents(result?: SubmittableResult): ActionStatus[] {
  return mergeStatus(
    ((result && result.events) || [])
      // filter events handled globally, or those we are not interested in, these are
      // handled by the global overview, so don't add them here
      .filter((record): boolean => !!record.event && record.event.section !== 'democracy')
      // eslint-disable-next-line complexity
      .map(({ event: { data, method, section } }): ActionStatusPartial => {
        if (section === 'system' && method === 'ExtrinsicFailed') {
          const [dispatchError] = data as unknown as ITuple<[DispatchError]>;
          let message: string = dispatchError.type;

          if (dispatchError.isModule) {
            try {
              const mod = dispatchError.asModule;
              const error = dispatchError.registry.findMetaError(mod);

              message = `${error.section}.${error.name}`;
            } catch (error) {
              // swallow
            }
          } else if (dispatchError.isToken) {
            message = `${dispatchError.type}.${dispatchError.asToken.type}`;
          }

          return {
            action: `${section}.${method}`,
            message,
            status: 'error',
          };
        } else if (section === 'contracts') {
          // eslint-disable-next-line no-magic-numbers
          if (method === 'ContractExecution' && data.length === 2) {
            // see if we have info for this contract
            const [accountId, encoded] = data;

            try {
              const abi = getContractAbi(accountId.toString());

              if (abi) {
                const decoded = abi.decodeEvent(encoded as Bytes);

                return {
                  action: decoded.event.identifier,
                  message: 'contract event',
                  status: 'event',
                };
              }
            } catch (error) {
              // ABI mismatch?
              console.error(error);
            }
          } else if (method === 'Evicted') {
            return {
              action: `${section}.${method}`,
              message: 'contract evicted',
              status: 'error',
            };
          }
        }

        return {
          action: `${section}.${method}`,
          message: EVENT_MESSAGE,
          status: 'event',
        };
      })
  );
}
Example #15
Source File: IdentitySub.tsx    From crust-apps with Apache License 2.0 4 votes vote down vote up
function IdentitySubModal ({ address, className, onClose }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const { api } = useApi();
  const { allAccounts } = useAccounts();
  const queryIds = useCall<string[]>(api.query.identity.subsOf, [address], transformIds);
  const queryInfos = useCall<[[string[]], Option<ITuple<[AccountId, Data]>>[]]>(queryIds && queryIds.length !== 0 && api.query.identity.superOf.multi, [queryIds], transformInfo);
  const [infos, setInfos] = useState<[string, string][] | undefined>();

  useEffect((): void => {
    if (queryInfos) {
      setInfos(extractInfo(queryInfos));
    } else if (queryIds && !queryIds.length) {
      setInfos([]);
    }
  }, [allAccounts, queryIds, queryInfos]);

  const _rowAdd = useCallback(
    () => setInfos((infos) => infos && infos.concat([[allAccounts[0], '']])),
    [allAccounts]
  );

  const _rowRemove = useCallback(
    () => setInfos((infos) => infos && infos.slice(0, infos.length - 1)),
    []
  );

  const _setAddress = useCallback(
    (index: number, address: string) => setInfos((infos) => (infos || []).map(([a, n], i) => [index === i ? address : a, n])),
    []
  );

  const _setName = useCallback(
    (index: number, name: string) => setInfos((infos) => (infos || []).map(([a, n], i) => [a, index === i ? name : n])),
    []
  );

  return (
    <Modal
      className={className}
      header={t<string>('Register sub-identities')}
      size='large'
    >
      <Modal.Content>
        {!infos
          ? <Spinner label={t<string>('Retrieving sub-identities')} />
          : (
            <div>
              {!infos.length
                ? <article>{t('No sub identities set.')}</article>
                : infos.map(([address, name], index) =>
                  <IdentitySubMemo
                    address={address}
                    index={index}
                    key={index}
                    name={name}
                    setAddress={_setAddress}
                    setName={_setName}
                    t={t}
                  />
                )
              }
              <Button.Group>
                <Button
                  icon='plus'
                  label={t<string>('Add sub')}
                  onClick={_rowAdd}
                />
                <Button
                  icon='minus'
                  isDisabled={infos.length === 0}
                  label={t<string>('Remove sub')}
                  onClick={_rowRemove}
                />
              </Button.Group>
            </div>
          )
        }
      </Modal.Content>
      <Modal.Actions onCancel={onClose}>
        {infos && (
          <TxButton
            accountId={address}
            isDisabled={infos.some(([address, raw]) => !address || !raw)}
            label={t<string>('Set Subs')}
            onStart={onClose}
            params={[
              infos.map(([address, raw]) => [address, { raw }])
            ]}
            tx={api.tx.identity.setSubs}
          />
        )}
      </Modal.Actions>
    </Modal>
  );
}
Example #16
Source File: index.tsx    From crust-apps with Apache License 2.0 4 votes vote down vote up
function PollApp ({ basePath, className }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const { api } = useApi();
  const bestNumber = useBestNumber();
  const [totalIssuance, totals] = useCallMulti<MultiResult>([
    api.query.balances.totalIssuance,
    api.query.poll.totals
  ], optMulti);
  const [accountId, setAccountId] = useState<string | null>(null);
  const [turnout, setTurnout] = useState<Turnout | null>(null);
  const [opt10m, setOpt10m] = useState(false);
  const [opt100m, setOpt100m] = useState(false);
  const [opt1b, setOpt1b] = useState(false);
  const [opt10b, setOpt10b] = useState(false);
  const [progress, setProgress] = useState<BN[] | undefined>();

  const itemsRef = useRef([{
    isRoot: true,
    name: 'poll',
    text: t<string>('Denomination poll')
  }]);

  useEffect((): void => {
    if (totalIssuance && totals) {
      const max = bnMax(BN_ONE, ...totals);

      setProgress(totals.map((total) => total.mul(BN_MILLION).div(max)));

      api.query.poll.voteOf
        .entries<ITuple<[Approvals, Balance]>>()
        .then((entries): void => {
          const voted = entries.reduce((voted: BN, [, [, balance]]) => voted.iadd(balance), new BN(0));
          const percentage = voted.muln(10_000).div(totalIssuance).toNumber() / 100;

          setTurnout({ percentage, voted });
        })
        .catch(console.log);
    }
  }, [api, totalIssuance, totals]);

  if (!totals || !progress || !bestNumber) {
    return (
      <main className={className}>
        <div className='pollContainer'>
          <Spinner label={t<string>('Retrieving totals...')} />
        </div>
      </main>
    );
  }

  const blocksLeft = (api.consts.poll.end as BlockNumber).sub(bestNumber);
  const canVote = blocksLeft.gt(BN_ZERO);
  const options: [string, string, boolean, (value: boolean) => void][] = [
    [t('No change'), t('No change from the original 2017 sale definitions; will mean a total of 10 million DOT from genesis.'), opt10m, setOpt10m],
    [t('Split of 10x'), t('Split of 10x from the original sale; will mean a total of 100 million DOT from genesis. Apparent DOT price would be 10x lower and apparent account balances 10x higher.'), opt100m, setOpt100m],
    [t('Split of 100x'), t('Split of 100x from the original sale; will mean a total of 1 billion DOT from genesis. Apparent DOT price would be 100x lower and apparent account balances 100x higher.'), opt1b, setOpt1b],
    [t('Split of 1000x'), t('Split of 1000x from the original sale; will mean a total of 10 billion DOT from genesis. Apparent DOT price would be 1000x lower and apparent account balances 1000x higher.'), opt10b, setOpt10b]
  ];
  const hasValue = opt10m || opt100m || opt1b || opt10b;

  /* eslint-disable react/jsx-max-props-per-line */

  return (
    <main className={className}>
      <Tabs
        basePath={basePath}
        items={itemsRef.current}
      />
      <div className='pollContainer'>
        <div className='pollHeader'>
          <h1>{t('denomination vote')}</h1>
          <div className='pollBlocksRight'>
            {turnout && (
              <div>
                <div>{t('{{balance}} voted', { replace: { balance: formatBalance(turnout.voted) } })}</div>
                <div>{t('{{percentage}}% turnout', { replace: { percentage: turnout.percentage.toFixed(2) } })}</div>
              </div>
            )}
            <div>
              {canVote
                ? <BlockToTime value={blocksLeft} />
                : t<string>('Completed')
              }
              <div>#{formatNumber(api.consts.poll.end as BlockNumber)}</div>
            </div>
          </div>
        </div>
        <article className='keepAlive'>
          <p><Trans key='poll1'>The Polkadot DOT denomination vote: Seventy-two hours after the DOT token becomes transferable, the most popular option from this poll will decide the denomination used for the DOT token.</Trans></p>
          <p><Trans key='poll2'>This is an <a href='https://en.wikipedia.org/wiki/Approval_voting' rel='noreferrer' target='_blank'>approval vote</a>. There are four options and you may select any combination of them. The most popular of the four will be selected as the final DOT denomination three days after DOT token transfers are enabled.</Trans></p>
          <p><Trans key='poll3'>Please see the <a href='https://medium.com/polkadot-network/the-first-polkadot-vote-1fc1b8bd357b' rel='noreferrer' target='_blank'>Medium article </a> for more information</Trans></p>
          {canVote && (
            <p className='pollAll'><Trans key='poll4'><b>Please vote for any combination of options</b></Trans></p>
          )}
          <div className={`options ${canVote ? 'canVote' : ''}`}>
            {options.map(([label, desc, value, onChange], index) =>
              <Columar
                is60
                key={index}
              >
                <Columar.Column className='option'>
                  <div className='optionName'>{label}</div>
                  <div className='optionDesc'>{desc}</div>
                  {canVote && (
                    <Toggle
                      className='pollToggle'
                      isDisabled={!canVote}
                      label={
                        canVote
                          ? value
                            ? t<string>('Aye, I support this')
                            : t<string>('Nay, I do not support this')
                          : t<string>('Voting closed')
                      }
                      onChange={onChange}
                      value={canVote && value}
                    />
                  )}
                </Columar.Column>
                <Columar.Column>
                  {totals[index].isZero()
                    ? <div className='result' />
                    : (
                      <div className='result'>
                        <FormatBalance value={totals[index]} />
                        <Progress
                          isDisabled={!turnout}
                          total={turnout?.voted}
                          value={totals[index]}
                        />
                      </div>
                    )
                  }
                </Columar.Column>
              </Columar>
            )}
          </div>
          {canVote && (
            <>
              <InputAddress
                label={t('vote using my account')}
                onChange={setAccountId}
                type='account'
              />
              <Button.Group>
                <TxButton
                  accountId={accountId}
                  icon='paper-plane'
                  isDisabled={!hasValue}
                  label={t('Vote')}
                  params={[[opt10m, opt100m, opt1b, opt10b]]}
                  tx={api.tx.poll.vote}
                />
              </Button.Group>
            </>
          )}
        </article>
        <div className='pollActions'>
          <ul>
            <li>{t('Any combination of the four options may be approved of by the voter. There is no need to select only one option!')}</li>
            <li>{t('Approving of all or none of the options is equivalent and will not affect the outcome of the poll.')}</li>
            <li>{t('All voters may alter their votes any number of times prior to the close of the poll.')}</li>
            <li>{t('Voting costs nothing other than the transaction fee and can be done from all accounts with a non-zero spendable balance.')}</li>
            <li>{t('Locked funds (e.g. for staking) are counted.')}</li>
            <li>{t('No discretionary lock-voting is in place; all DOT used to vote counts the same.')}</li>
            <li>{t('Voting is made on a per-account basis; a single account must all vote the same way and cannot split its vote.')}</li>
            <li>{t('This vote does not affect any economics of the Polkadot platform. Staking rewards, inflation, effective market capitalisation and the underlying balances of every account remain completely unchanged. It is "merely" about what units we use to denominate the balances into "DOT" for the purpose of display.')}</li>
          </ul>
        </div>
      </div>
    </main>
  );
}