@polkadot/util#isNumber TypeScript Examples

The following examples show how to use @polkadot/util#isNumber. 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: useChainInfo.ts    From crust-apps with Apache License 2.0 6 votes vote down vote up
function createInfo (api: ApiPromise, systemChain: string, systemName: string): ChainInfo {
  return {
    chain: systemChain,
    color: getSystemChainColor(systemChain, systemName),
    genesisHash: api.genesisHash.toHex(),
    icon: getSystemIcon(systemName),
    metaCalls: Buffer.from(api.runtimeMetadata.asCallsOnly.toU8a()).toString('base64'),
    specVersion: api.runtimeVersion.specVersion.toNumber(),
    ss58Format: isNumber(api.registry.chainSS58) ? api.registry.chainSS58 : DEFAULT_SS58.toNumber(),
    tokenDecimals: (api.registry.chainDecimals || [DEFAULT_DECIMALS.toNumber()])[0],
    tokenSymbol: (api.registry.chainTokens || formatBalance.getDefaults().unit)[0],
    types: getSpecTypes(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion) as unknown as Record<string, string>
  };
}
Example #2
Source File: createInstantiateTx.ts    From contracts-ui with GNU General Public License v3.0 6 votes vote down vote up
export function createInstantiateTx(
  api: ApiPromise,
  {
    argValues,
    codeHash,
    constructorIndex,
    weight: gasLimit,
    value,
    metadata,
    salt,
    storageDepositLimit,
  }: InstantiateData
): SubmittableExtrinsic<'promise'> | null {
  const wasm = metadata?.info.source.wasm;
  const isValid = codeHash || !!wasm;

  if (isValid && metadata && isNumber(constructorIndex) && metadata && argValues) {
    const constructor = metadata.findConstructor(constructorIndex);

    const options = {
      gasLimit,
      salt: salt ? encodeSalt(salt) : null,
      storageDepositLimit: storageDepositLimit || undefined,
      value: value && constructor.isPayable ? api.registry.createType('Balance', value) : undefined,
    };

    const codeOrBlueprint = codeHash
      ? new BlueprintPromise(api, metadata, codeHash)
      : new CodePromise(api, metadata, wasm && wasm.toU8a());

    const transformed = transformUserInput(api.registry, constructor.args, argValues);

    return constructor.args.length > 0
      ? codeOrBlueprint.tx[constructor.method](options, ...transformed)
      : codeOrBlueprint.tx[constructor.method](options);
  } else {
    throw new Error('Unknown error');
  }
}
Example #3
Source File: index.ts    From contracts-ui with GNU General Public License v3.0 6 votes vote down vote up
export function toBalance(api: ApiPromise, value: string | number): BN {
  const asString = isNumber(value) ? value.toString() : value;
  const siPower = new BN(api.registry.chainDecimals[0]);

  const isDecimalValue = /^(\d+)\.(\d+)$/.exec(asString);

  if (isDecimalValue) {
    const div = new BN(asString.replace(/\.\d*$/, ''));
    const modString = asString.replace(/^\d+\./, '').substr(0, api.registry.chainDecimals[0]);
    const mod = new BN(modString);

    return div
      .mul(BN_TEN.pow(siPower))
      .add(mod.mul(BN_TEN.pow(new BN(siPower.subn(modString.length)))));
  } else {
    return new BN(asString.replace(/[^\d]/g, '')).mul(BN_TEN.pow(siPower));
  }
}
Example #4
Source File: index.ts    From contracts-ui with GNU General Public License v3.0 6 votes vote down vote up
export function toSats(api: ApiPromise, balance: BN | number): BN {
  let bn: BN;

  if (isNumber(balance)) {
    bn = new BN(balance);
  } else {
    bn = balance;
  }

  return bn.mul(BN_TEN.pow(new BN(api.registry.chainDecimals[0])));
}
Example #5
Source File: Provider.ts    From evm-provider.js with Apache License 2.0 6 votes vote down vote up
async _resolveBlockNumber(
    blockTag?: BlockTag | Promise<BlockTag>
  ): Promise<number> {
    await this.resolveApi;

    if (!blockTag) {
      return logger.throwError(`Blocktag cannot be undefined`);
    }

    const resolvedBlockNumber = await blockTag;

    if (resolvedBlockNumber === 'pending') {
      throw new Error('Unsupport Block Pending');
    }

    if (resolvedBlockNumber === 'latest') {
      const header = await this.api.rpc.chain.getHeader();
      return header.number.toNumber();
    }

    if (resolvedBlockNumber === 'earliest') {
      return 0;
    }

    if (isNumber(resolvedBlockNumber)) {
      return resolvedBlockNumber;
    } else {
      throw new Error('Expect blockHash to be a number or tag');
    }
  }
Example #6
Source File: Provider.ts    From evm-provider.js with Apache License 2.0 6 votes vote down vote up
async _resolveTransaction(
    tx: Deferrable<TransactionRequest>
  ): Promise<Deferrable<TransactionRequest>> {
    for (const key of ['gasLimit', 'value']) {
      const typeKey = key as 'gasLimit' | 'value';

      if (tx[typeKey]) {
        if (BigNumber.isBigNumber(tx[typeKey])) {
          tx[typeKey] = (tx[typeKey] as BigNumber).toHexString();
        } else if (isNumber(tx[typeKey])) {
          tx[typeKey] = numberToHex(tx[typeKey] as number);
        }
      }
    }

    delete tx.nonce;
    delete tx.gasPrice;
    delete tx.chainId;

    return tx;
  }
Example #7
Source File: Provider.ts    From evm-provider.js with Apache License 2.0 6 votes vote down vote up
async _resolveStorageLimit(
    tx: Deferrable<TransactionRequest>
  ): Promise<BigNumber> {
    if (tx.customData) {
      if ('storageLimit' in tx.customData) {
        const storageLimit = tx.customData.storageLimit;
        if (BigNumber.isBigNumber(storageLimit)) {
          return storageLimit;
        } else if (isNumber(storageLimit)) {
          return BigNumber.from(storageLimit);
        }
      }
    }

    // At least 60 REEF are needed to deploy
    return BigNumber.from(60_000);
  }
Example #8
Source File: Summary.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
function Summary ({ leasePeriod, parachainCount, proposalCount, upcomingCount }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();

  return (
    <SummaryBox>
      <section>
        {isNumber(parachainCount) && (
          <CardSummary label={t<string>('parachains')}>
            {formatNumber(parachainCount)}
          </CardSummary>
        )}
        {isNumber(upcomingCount) && (
          <CardSummary label={t<string>('upcoming')}>
            {formatNumber(upcomingCount)}
          </CardSummary>
        )}
        {isNumber(proposalCount) && (
          <CardSummary label={t<string>('proposals')}>
            {formatNumber(proposalCount)}
          </CardSummary>
        )}
      </section>
      <section>
        {leasePeriod && (
          <CardSummary label={t<string>('current lease')}>
            {formatNumber(leasePeriod.currentPeriod)}
          </CardSummary>
        )}
      </section>
      <section>
        {leasePeriod && (
          <CardSummary
            label={t<string>('lease period')}
            progress={{
              total: leasePeriod.length,
              value: leasePeriod.remainder,
              withTime: true
            }}
          />
        )}
        <SummarySession
          className='media--800'
          withEra={false}
        />
      </section>
    </SummaryBox>
  );
}
Example #9
Source File: HorizBar.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
function calculateOptions (aspectRatio: number, values: HorizBarValue[], jsonValues: string, max: number, showLabels: boolean): State {
  const chartData = values.reduce((data, { colors: [normalColor = '#00f', hoverColor], label, value }): Config => {
    const dataset = data.datasets[0];

    dataset.backgroundColor.push(alphaColor(normalColor));
    dataset.hoverBackgroundColor.push(alphaColor(hoverColor || normalColor));
    dataset.data.push(isNumber(value) ? value : bnToBn(value).toNumber());
    data.labels.push(label);

    return data;
  }, {
    datasets: [{
      backgroundColor: [] as string[],
      data: [] as number[],
      hoverBackgroundColor: [] as string[]
    }],
    labels: [] as string[]
  });

  return {
    chartData,
    chartOptions: {
      // width/height by default this is "1", i.e. a square box
      aspectRatio,
      // no need for the legend, expect the labels contain everything
      legend: {
        display: false
      },
      scales: {
        xAxes: [{
          ticks: showLabels
            ? { beginAtZero: true, max }
            : { display: false }
        }]
      },
      tooltips: {
        callbacks: {
          label: (item: TooltipItem): string =>
            values[item.index].tooltip || values[item.index].label
        }
      }
    },
    jsonValues
  };
}
Example #10
Source File: Enum.tsx    From contracts-ui with GNU General Public License v3.0 5 votes vote down vote up
export function Enum(props: Props) {
  const { components, typeDef, onChange: _onChange, registry, value = {} } = props;
  const variants = typeDef.sub as TypeDef[];
  const { keyring } = useApi();
  const [variantIndex, _setVariantIndex] = useState<number>(
    Math.max(
      0,
      variants.findIndex(({ name }) => name === Object.keys(value)[0])
    )
  );

  const Component = components[variantIndex];

  const onChange = useCallback(
    (value: unknown): void => {
      _onChange({ [variants[variantIndex].name as string]: value });
    },
    [_onChange, variants, variantIndex]
  );

  const setVariantIndex = useCallback(
    (value: OrFalsy<number>) => {
      if (isNumber(value)) {
        _setVariantIndex(value);

        _onChange({
          [variants[value].name as string]: getInitValue(registry, keyring, variants[value]),
        });
      }
    },
    [registry, keyring, _onChange, variants]
  );

  return (
    <>
      <Dropdown
        options={variants.map(({ name }, index) => ({ label: name, value: index }))}
        value={variantIndex}
        onChange={setVariantIndex}
      />
      {variants[variantIndex].type !== 'Null' && (
        <FormField
          className="ml-8 mt-2"
          label={<ArgSignature arg={{ type: variants[variantIndex] }} />}
          {...getValidation(props)}
        >
          <Component value={Object.values(value)[0]} onChange={onChange} />
        </FormField>
      )}
    </>
  );
}
Example #11
Source File: InputStorageDepositLimit.tsx    From contracts-ui with GNU General Public License v3.0 5 votes vote down vote up
export function InputStorageDepositLimit({
  className,
  isActive = false,
  maximum,
  onChange,
  toggleIsActive,
  value,
  ...props
}: Props) {
  const percentage = useMemo((): number | null => {
    if (!maximum || maximum.eqn(0)) {
      return null;
    }
    return 100 * new Big(value.toString()).div(new Big(maximum.toString())).toNumber();
  }, [maximum, value]);

  return (
    <div className={classes(className)}>
      <div className="flex items-center">
        <InputBalance
          className="flex-1"
          value={isActive ? value : undefined}
          id="storageDepositLimit"
          isDisabled={!isActive}
          onChange={onChange}
          placeholder={isActive ? undefined : 'Do not use'}
          withUnits={isActive}
          {...getValidation(props)}
        />
        <div className="flex justify-center items-center w-18">
          <Switch value={isActive} onChange={toggleIsActive} />
        </div>
      </div>
      {isActive && !isNull(percentage) && (
        <Meter
          label={isNumber(percentage) ? `${percentage.toFixed(2)}% of free balance` : null}
          percentage={isNumber(percentage) ? percentage : 100}
        />
      )}
    </div>
  );
}
Example #12
Source File: HorizBar.tsx    From subscan-multisig-react with Apache License 2.0 5 votes vote down vote up
function calculateOptions(
  aspectRatio: number,
  values: HorizBarValue[],
  jsonValues: string,
  max: number,
  showLabels: boolean
): State {
  const chartData = values.reduce(
    (data, { colors: [normalColor = '#00f', hoverColor], label, value }): Config => {
      const dataset = data.datasets[0];

      dataset.backgroundColor.push(alphaColor(normalColor));
      dataset.hoverBackgroundColor.push(alphaColor(hoverColor || normalColor));
      dataset.data.push(isNumber(value) ? value : bnToBn(value).toNumber());
      data.labels.push(label);

      return data;
    },
    {
      datasets: [
        {
          backgroundColor: [] as string[],
          data: [] as number[],
          hoverBackgroundColor: [] as string[],
        },
      ],
      labels: [] as string[],
    }
  );

  return {
    chartData,
    chartOptions: {
      // width/height by default this is "1", i.e. a square box
      aspectRatio,
      // no need for the legend, expect the labels contain everything
      legend: {
        display: false,
      },
      scales: {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        xAxes: [
          {
            ticks: showLabels ? { beginAtZero: true, max } : { display: false },
          },
        ],
      },
      tooltips: {
        callbacks: {
          label: (item: TooltipItem): string => values[item.index].tooltip || values[item.index].label,
        },
      },
    },
    jsonValues,
  };
}
Example #13
Source File: useTeleport.ts    From subscan-multisig-react with Apache License 2.0 5 votes vote down vote up
export function useTeleport(): Teleport {
  const { api, apiUrl, isApiReady } = useApi();
  const paraId = useCall<ParaId>(isApiReady && api.query.parachainInfo?.parachainId);
  const [state, setState] = useState<Teleport>(() => ({ ...DEFAULT_STATE }));

  useEffect((): void => {
    if (isApiReady) {
      const relayGenesis = api.genesisHash.toHex();
      const endpoint = endpoints.find(({ genesisHash }: any) => genesisHash === relayGenesis);

      if (endpoint) {
        const destinations = extractRelayDestinations(
          relayGenesis,
          ({ paraId }: any) => isNumber(paraId) && endpoint.teleport.includes(paraId)
        );
        const oneWay = extractRelayDestinations(
          relayGenesis,
          ({ paraId, teleport }: any) => isNumber(paraId) && !teleport.includes(-1)
        ).map(({ paraId }: any) => paraId || -1);

        setState({
          allowTeleport: destinations.length !== 0,
          destinations,
          isRelayTeleport: true,
          oneWay,
        });
      }
    }
  }, [api, isApiReady]);

  useEffect((): void => {
    if (paraId) {
      const endpoint = endpoints.find(({ value }: any) => value === apiUrl);

      if (endpoint && endpoint.genesisHashRelay) {
        const destinations = extractRelayDestinations(endpoint.genesisHashRelay, ({ paraId }: any) =>
          endpoint.teleport.includes(isNumber(paraId) ? paraId : -1)
        );
        const oneWay = extractRelayDestinations(
          endpoint.genesisHashRelay,
          ({ paraId, teleport }: any) => !teleport.includes(isNumber(paraId) ? paraId : -1)
        ).map(({ paraId }: any) => paraId || -1);

        setState({
          allowTeleport: destinations.length !== 0,
          destinations,
          isParaTeleport: true,
          oneWay,
        });
      }
    }
  }, [apiUrl, paraId]);

  return state;
}
Example #14
Source File: Step2.tsx    From contracts-ui with GNU General Public License v3.0 4 votes vote down vote up
export function Step2() {
  const {
    data: { accountId, metadata },
    dryRunResult,
    stepBackward,
    currentStep,
    onFinalize,
    onFormChange,
  } = useInstantiate();

  const { value, onChange: onChangeValue, ...valueValidation } = useBalance(10000);
  const dbValue = useDebounce(value);

  const [estimatedWeight, setEstimatedWeight] = useState<OrFalsy<BN>>(null);
  const weight = useWeight(estimatedWeight);
  const dbWeight = useDebounce(weight.weight);

  const storageDepositLimit = useStorageDepositLimit(accountId);
  const dbStorageDepositLimit = useDebounce(storageDepositLimit.value);

  const salt = useFormField<string>(randomAsHex(), value => {
    if (!!value && isHex(value) && value.length === 66) {
      return { isValid: true };
    }

    return { isValid: false, isError: true, message: 'Invalid hex string' };
  });
  const dbSalt = useDebounce(salt.value);

  const [constructorIndex, setConstructorIndex] = useState<number>(0);
  const [deployConstructor, setDeployConstructor] = useState<AbiMessage>();

  const [argValues, setArgValues] = useArgValues(deployConstructor?.args || null);
  const dbArgValues = useDebounce(argValues);

  useEffect(() => {
    setConstructorIndex(0);
    metadata && setDeployConstructor(metadata.constructors[0]);
  }, [metadata, setConstructorIndex]);

  const [isUsingSalt, toggleIsUsingSalt] = useToggle(true);
  const [isUsingStorageDepositLimit, toggleIsUsingStorageDepositLimit] = useToggle();

  const onSubmit = () => {
    onFinalize &&
      onFinalize({
        constructorIndex,
        salt: isUsingSalt ? salt.value : undefined,
        value,
        argValues,
        storageDepositLimit: isUsingStorageDepositLimit ? storageDepositLimit.value : undefined,
        weight: weight.isActive ? weight.weight : estimatedWeight || weight.defaultWeight,
      });
  };

  useEffect((): void => {
    if (
      dryRunResult?.result.isOk &&
      dryRunResult.gasRequired &&
      !estimatedWeight?.eq(dryRunResult.gasRequired)
    ) {
      setEstimatedWeight(dryRunResult.gasRequired);
    }
  }, [
    dryRunResult?.result.isOk,
    dryRunResult?.result.isErr,
    dryRunResult?.gasRequired,
    estimatedWeight,
  ]);

  useEffect((): void => {
    onFormChange &&
      onFormChange({
        constructorIndex,
        salt: isUsingSalt ? dbSalt : null,
        value: dbValue && deployConstructor?.isPayable ? dbValue : null,
        argValues: dbArgValues,
        storageDepositLimit: isUsingStorageDepositLimit ? dbStorageDepositLimit : null,
        weight: weight.isActive ? dbWeight : weight.defaultWeight,
      });
  }, [
    onFormChange,
    constructorIndex,
    deployConstructor,
    dbSalt,
    dbValue,
    dbArgValues,
    dbStorageDepositLimit,
    dbWeight,
    isUsingSalt,
    isUsingStorageDepositLimit,
    weight.defaultWeight,
    weight.isActive,
  ]);

  useEffect(
    (): void => {
      if (!metadata) {
        setEstimatedWeight(null);
        weight.setIsActive(false);
      }
    },
    // eslint-disable-next-line
    [metadata]
  );

  if (currentStep !== 2) return null;

  return metadata ? (
    <>
      <Form>
        <FormField
          help="The constructor to use for this contract deployment."
          id="constructor"
          label="Deployment Constructor"
        >
          <Dropdown
            id="constructor"
            options={createConstructorOptions(metadata.constructors)}
            className="mb-4"
            value={constructorIndex}
            onChange={v => {
              if (isNumber(v)) {
                setConstructorIndex(v);
                setDeployConstructor(metadata.constructors[v]);
              }
            }}
          >
            No constructors found
          </Dropdown>
          {deployConstructor && argValues && (
            <ArgumentForm
              key={`args-${deployConstructor.method}`}
              args={deployConstructor.args}
              registry={metadata.registry}
              setArgValues={setArgValues}
              argValues={argValues}
              className="argument-form"
            />
          )}
        </FormField>
        {deployConstructor?.isPayable && (
          <FormField
            help="The balance to transfer from the `origin` to the newly created contract."
            id="value"
            label="Value"
            {...valueValidation}
          >
            <InputBalance id="value" value={value} onChange={onChangeValue} />
          </FormField>
        )}
        <FormField
          help="A hex or string value that acts as a salt for this deployment."
          id="salt"
          label="Deployment Salt"
          {...getValidation(salt)}
        >
          <InputSalt isActive={isUsingSalt} toggleIsActive={toggleIsUsingSalt} {...salt} />
        </FormField>
        <FormField
          help="The maximum amount of gas (in millions of units) to use for this instantiation. If the transaction requires more, it will fail."
          id="maxGas"
          label="Max Gas Allowed"
          isError={!weight.isValid}
          message={!weight.isValid ? 'Invalid gas limit' : null}
        >
          <InputGas isCall withEstimate {...weight} />
        </FormField>
        <FormField
          help="The maximum balance allowed to be deducted for the new contract's storage deposit."
          id="storageDepositLimit"
          label="Storage Deposit Limit"
          isError={!storageDepositLimit.isValid}
          message={
            !storageDepositLimit.isValid
              ? storageDepositLimit.message || 'Invalid storage deposit limit'
              : null
          }
        >
          <InputStorageDepositLimit
            isActive={isUsingStorageDepositLimit}
            toggleIsActive={toggleIsUsingStorageDepositLimit}
            {...storageDepositLimit}
          />
        </FormField>
      </Form>
      <Buttons>
        <Button
          isDisabled={
            (deployConstructor?.isPayable && !valueValidation.isValid) ||
            (isUsingSalt && !salt.isValid) ||
            !weight.isValid ||
            !storageDepositLimit.isValid ||
            !deployConstructor?.method ||
            !argValues ||
            (dryRunResult && dryRunResult.result.isErr)
          }
          onClick={onSubmit}
          variant="primary"
          data-cy="next-btn"
        >
          Next
        </Button>

        <Button onClick={stepBackward} variant="default">
          Go Back
        </Button>
      </Buttons>
    </>
  ) : null;
}
Example #15
Source File: Signer.ts    From evm-provider.js with Apache License 2.0 4 votes vote down vote up
/**
   *
   * @param transaction
   * @returns A promise that resolves to the transaction's response
   */
  async sendTransaction(
    _transaction: Deferrable<TransactionRequest>
  ): Promise<TransactionResponse> {
    this._checkProvider('sendTransaction');

    const signerAddress = await this.getSubstrateAddress();
    const evmAddress = await this.getAddress();

    // estimateResources requires the from parameter.
    // However, when creating the contract, there is no from parameter in the tx
    const transaction = {
      from: evmAddress,
      ..._transaction
    };

    const resources = await this.provider.estimateResources(transaction);

    // Multiply by 3.1
    const gasLimit: BigNumber = resources.gas.mul(31).div(10);
    let storageLimit: BigNumber;

    // If the storage limit is supplied, override it from the estimateResources
    if (transaction.customData) {
      if ('storageLimit' in transaction.customData) {
        storageLimit = transaction.customData.storageLimit;
        if (isNumber(storageLimit)) {
          storageLimit = BigNumber.from(storageLimit);
        }
      }
    } else {
      storageLimit = resources.storage.mul(31).div(10);
    }

    let totalLimit = await transaction.gasLimit;

    if (totalLimit === null || totalLimit === undefined) {
      totalLimit = gasLimit.add(storageLimit);
    }

    transaction.gasLimit = totalLimit;

    const tx = await this.populateTransaction(transaction);

    const data = tx.data;
    const from = tx.from;

    if (!data) {
      return logger.throwError('Request data not found');
    }

    if (!from) {
      return logger.throwError('Request from not found');
    }

    let extrinsic: SubmittableExtrinsic<'promise'>;

    // @TODO create contract
    if (!tx.to) {
      extrinsic = this.provider.api.tx.evm.create(
        tx.data,
        toBN(tx.value),
        toBN(gasLimit),
        toBN(storageLimit.isNegative() ? 0 : storageLimit)
      );
    } else {
      extrinsic = this.provider.api.tx.evm.call(
        tx.to,
        tx.data,
        toBN(tx.value),
        toBN(gasLimit),
        toBN(storageLimit.isNegative() ? 0 : storageLimit)
      );
    }

    await extrinsic.signAsync(signerAddress);

    return new Promise((resolve, reject) => {
      extrinsic
        .send((result: SubmittableResult) => {
          handleTxResponse(result, this.provider.api)
            .then(() => {
              resolve({
                hash: extrinsic.hash.toHex(),
                from: from || '',
                confirmations: 0,
                nonce: toBN(tx.nonce).toNumber(),
                gasLimit: BigNumber.from(tx.gasLimit || '0'),
                gasPrice: BigNumber.from(0),
                data: dataToString(data),
                value: BigNumber.from(tx.value || '0'),
                chainId: 13939,
                wait: (confirmations?: number): Promise<TransactionReceipt> => {
                  return this.provider._resolveTransactionReceipt(
                    extrinsic.hash.toHex(),
                    result.status.asInBlock.toHex(),
                    from
                  );
                }
              });
            })
            .catch(({ message, result }) => {
              reject(message);
            });
        })
        .catch((error) => {
          reject(error && error.message);
        });
    });
  }