@polkadot/util#stringToHex TypeScript Examples

The following examples show how to use @polkadot/util#stringToHex. 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: polkadot_web_wallet.ts    From commonwealth with GNU General Public License v3.0 6 votes vote down vote up
// ACTIONS
  public async validateWithAccount(account: Account<any>): Promise<void> {
    const signer = await this.getSigner(account.address);
    const token = account.validationToken;
    const payload: SignerPayloadRaw = {
      address: account.address,
      data: stringToHex(token),
      type: 'bytes',
    };
    const signature = (await signer.signRaw(payload)).signature;
    return account.validate(signature);
  }
Example #2
Source File: parachain.ts    From polkadot-launch with MIT License 5 votes vote down vote up
export function parachainAccount(id: string) {
	let prefix = stringToHex("para");
	let encoded_id = bnToHex(parseInt(id), { isLe: true });
	let address_bytes = (prefix + hexStripPrefix(encoded_id)).padEnd(64 + 2, "0");
	let address = encodeAddress(address_bytes);

	return address;
}
Example #3
Source File: test-precompile-assets-erc20.ts    From moonbeam with GNU General Public License v3.0 4 votes vote down vote up
describeDevMoonbeamAllEthTxTypes(
  "Precompiles - Assets-ERC20 Wasm",
  (context) => {
    let sudoAccount, assetId, iFace;
    before("Setup contract and mock balance", async () => {
      const keyring = new Keyring({ type: "ethereum" });
      sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum");
      // We need to mint units with sudo.setStorage, as we dont have xcm mocker yet
      // And we need relay tokens for issuing a transaction to be executed in the relay
      const balance = new BN("100000000000000");
      const assetBalance = context.polkadotApi.createType("PalletAssetsAssetAccount", {
        balance: balance,
      });
      assetId = context.polkadotApi.createType(
        "u128",
        new BN("42259045809535163221576417993425387648")
      );

      const assetDetails = context.polkadotApi.createType("PalletAssetsAssetDetails", {
        supply: balance,
      });

      await mockAssetBalance(context, assetBalance, assetDetails, sudoAccount, assetId, ALITH);

      let beforeAssetBalance = (
        (await context.polkadotApi.query.assets.account(assetId, ALITH)) as any
      ).balance as BN;

      const contractData = await getCompiled("ERC20Instance");
      iFace = new ethers.utils.Interface(contractData.contract.abi);
      const { contract, rawTx } = await createContract(context, "ERC20Instance");
      const address = contract.options.address;
      await context.createBlock({ transactions: [rawTx] });
    });

    it("allows to call name", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "name",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: ADDRESS_ERC20,
          data: data,
        },
      ]);

      let expected = stringToHex("DOT");
      let offset = numberToHex(32).slice(2).padStart(64, "0");
      let length = numberToHex(3).slice(2).padStart(64, "0");
      // Bytes are padded at the end
      let expected_hex = expected.slice(2).padEnd(64, "0");
      expect(tx_call.result).equals("0x" + offset + length + expected_hex);
    });

    it("allows to call symbol", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "symbol",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: ADDRESS_ERC20,
          data: data,
        },
      ]);

      let expected = stringToHex("DOT");
      let offset = numberToHex(32).slice(2).padStart(64, "0");
      let length = numberToHex(3).slice(2).padStart(64, "0");
      // Bytes are padded at the end
      let expected_hex = expected.slice(2).padEnd(64, "0");
      expect(tx_call.result).equals("0x" + offset + length + expected_hex);
    });

    it("allows to call decimals", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "decimals",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: ADDRESS_ERC20,
          data: data,
        },
      ]);

      let expected = "0x" + numberToHex(12).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(expected);
    });

    it("allows to call getBalance", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "balanceOf",
        [ALITH]
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: ADDRESS_ERC20,
          data: data,
        },
      ]);
      let amount = new BN(100000000000000);

      let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(amount_hex);
    });

    it("allows to call totalSupply", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "totalSupply",
        []
      );
      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: ADDRESS_ERC20,
          data: data,
        },
      ]);

      let amount = new BN(100000000000000);

      let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(amount_hex);
    });
  },
  true
);
Example #4
Source File: test-precompile-local-assets-erc20.ts    From moonbeam with GNU General Public License v3.0 4 votes vote down vote up
describeDevMoonbeamAllEthTxTypes(
  "Precompiles - Assets-ERC20 Wasm",
  (context) => {
    let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress;
    before("Setup contract and mock balance", async () => {
      const keyring = new Keyring({ type: "ethereum" });
      sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum");
      baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum");

      // registerAsset
      const { events: eventsRegister } = await createBlockWithExtrinsic(
        context,
        sudoAccount,
        context.polkadotApi.tx.sudo.sudo(
          context.polkadotApi.tx.assetManager.registerLocalAsset(
            baltatharAccount.address,
            baltatharAccount.address,
            true,
            new BN(1)
          )
        )
      );

      // Look for assetId in events
      eventsRegister.forEach((e) => {
        if (e.section.toString() === "assetManager") {
          assetId = e.data[0].toHex();
        }
      });
      assetId = assetId.replace(/,/g, "");

      // Set metadata
      await createBlockWithExtrinsic(
        context,
        baltatharAccount,
        context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12))
      );

      // mint asset
      await createBlockWithExtrinsic(
        context,
        baltatharAccount,
        context.polkadotApi.tx.localAssets.mint(assetId, baltatharAccount.address, 100000000000000)
      );

      assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)]));

      const contractData = await getCompiled("LocalAssetExtendedErc20Instance");
      iFace = new ethers.utils.Interface(contractData.contract.abi);
      const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance");
      contractInstanceAddress = contract.options.address;
      await context.createBlock({ transactions: [rawTx] });
    });

    it("allows to call name", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "name",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: ALITH,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: assetAddress,
          data: data,
        },
      ]);

      let expected = stringToHex("Local");
      let offset = numberToHex(32).slice(2).padStart(64, "0");
      let length = numberToHex(5).slice(2).padStart(64, "0");
      // Bytes are padded at the end
      let expected_hex = expected.slice(2).padEnd(64, "0");
      expect(tx_call.result).equals("0x" + offset + length + expected_hex);
    });

    it("allows to call symbol", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "symbol",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: assetAddress,
          data: data,
        },
      ]);

      let expected = stringToHex("Local");
      let offset = numberToHex(32).slice(2).padStart(64, "0");
      let length = numberToHex(5).slice(2).padStart(64, "0");
      // Bytes are padded at the end
      let expected_hex = expected.slice(2).padEnd(64, "0");
      expect(tx_call.result).equals("0x" + offset + length + expected_hex);
    });

    it("allows to call decimals", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "decimals",
        []
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: assetAddress,
          data: data,
        },
      ]);

      let expected = "0x" + numberToHex(12).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(expected);
    });

    it("allows to call getBalance", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "balanceOf",
        [BALTATHAR]
      );

      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: assetAddress,
          data: data,
        },
      ]);
      let amount = new BN(100000000000000);

      let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(amount_hex);
    });

    it("allows to call totalSupply", async function () {
      let data = iFace.encodeFunctionData(
        // action
        "totalSupply",
        []
      );
      const tx_call = await customWeb3Request(context.web3, "eth_call", [
        {
          from: GENESIS_ACCOUNT,
          value: "0x0",
          gas: "0x10000",
          gasPrice: GAS_PRICE,
          to: assetAddress,
          data: data,
        },
      ]);

      let amount = new BN(100000000000000);

      let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0");
      expect(tx_call.result).equals(amount_hex);
    });
  },
  true
);
Example #5
Source File: hooks.ts    From crust-apps with Apache License 2.0 4 votes vote down vote up
export function useSign (account: LoginUser, metamask: Metamask, near: NearM, flow: FlowM, solana: SolanaM, elrond: ElrondM): UseSign {
  const [state, setState] = useState<UseSign>({ isLocked: true });

  useEffect(() => {
    if (!account.account) return;

    // eslint-disable-next-line
    const nearKeyPair = near?.keyPair;

    if (account.wallet === 'near' && near.wallet && nearKeyPair) {
      setState((o) => ({ ...o, isLocked: false }));

      const sign = function (data: string): Promise<string> {
        const msg = Buffer.from(data);
        // eslint-disable-next-line
        const { signature } = nearKeyPair.sign(msg);
        const hexSignature = Buffer.from(signature).toString('hex');

        return Promise.resolve<string>(hexSignature);
      };

      setState((o) => ({ ...o, sign }));

      return;
    }

    if (account.wallet === 'flow') {
      setState((o) => ({ ...o, isLocked: false }));

      const sign = function (data: string): Promise<string> {
        const msg = Buffer.from(data);

        // eslint-disable-next-line
        return fcl.currentUser().signUserMessage(msg.toString('hex'))
          .then((res: any) => {
            if (!res) {
              throw new Error('Signature failed');
            }

            if (_.includes(res, 'Declined: User rejected signature')) {
              throw new Error('User rejected signature');
            }

            return window.btoa(JSON.stringify(res));
          });
      };

      setState((o) => ({ ...o, sign }));

      return;
    }

    if (account.wallet === 'solana') {
      setState((o) => ({ ...o, isLocked: false }));

      const sign = function (data: string): Promise<string> {
        const encodedMessage = new TextEncoder().encode(data);
        // eslint-disable-next-line
        return window.solana.signMessage(encodedMessage, 'utf8')
          // eslint-disable-next-line
          .then((sig: any) => Buffer.from(sig.signature).toString('hex'));
      };

      setState((o) => ({ ...o, sign }));

      return;
    }

    if (account.wallet === 'elrond') {
      // waiting for sign
      const provider = elrond.provider;

      if (elrond.isInstalled && provider) {
        const sign = function (data: string): Promise<string> {
          const address = provider.account.address;
          const signableMessage = new SignableMessage({
            address: new Address(address),
            message: Buffer.from('0x' + Buffer.from(address).toString('hex'), 'ascii')
          });

          return provider.signMessage(signableMessage).then((message) => {
            return `elrond-${address}-${signableMessage.serializeForSigning().toString('hex')}:${message.signature.hex()}`;
          })
            .catch((err) => {
              console.error('Elrond wallet signMessage error', err);

              return '';
            });
        };

        setState((o) => ({ ...o, sign, isLocked: false }));
      }

      return;
    }

    if (account.wallet === 'metamask') {
      setState((o) => ({ ...o, isLocked: false }));
      const ethReq = metamask?.ethereum?.request;

      if (metamask.isInstalled && metamask.isAllowed && ethReq) {
        const sign = function (data: string): Promise<string> {
          const msg = Buffer.from(data, 'utf8').toString('hex');
          // const msg = data;

          console.info('msg::', msg);

          return ethReq<string>({
            from: account.account,
            params: [msg, account.account],
            method: 'personal_sign'
          }).then((signature) => {
            console.info('signData:', signature);

            // return ethReq<string>({
            //   from: account.account,
            //   params: [msg, signature],
            //   method: 'personal_ecRecover'
            // }).then((res) => {
            //   console.info('recover:', res);
            //
            //   return signature;
            // });
            return signature;
          });
        };

        setState((o) => ({ ...o, sign }));
      }
    } else {
      const currentPair = keyring.getPair(account.account);

      if (!currentPair) return;
      const meta = currentPair.meta || {};
      const isInjected = (meta.isInjected as boolean) || false;
      const accountIsLocked = isInjected ? false : currentPair.isLocked || false;

      setState((o) => ({ ...o, isLocked: accountIsLocked }));

      // for injected, retrieve the signer
      if (meta.source && isInjected) {
        web3FromSource(meta.source as string)
          .catch(() => null)
          .then((injected) => {
            const signRaw = injected?.signer?.signRaw;

            if (signRaw && isFunction(signRaw)) {
              const sign = function (data: string): Promise<string> {
                return signRaw({
                  address: currentPair.address,
                  data: stringToHex(data),
                  type: 'bytes'
                }).then((res) => res.signature);
              };

              setState((o) => ({ ...o, sign }));
            }

            return null;
          })
          .catch(console.error);
      } else {
        const sign = function (data: string, password?: string): Promise<string> {
          return new Promise<string>((resolve, reject) => {
            setTimeout(() => {
              try {
                if (accountIsLocked) {
                  currentPair.unlock(password);
                }

                resolve(u8aToHex(currentPair.sign(stringToU8a(data))));
              } catch (e) {
                reject(e);
              }
            }, 100);
          });
        };

        setState((o) => ({ ...o, sign }));
      }
    }
  }, [account, metamask, near, flow, solana, elrond]);

  return state;
}
Example #6
Source File: Sign.tsx    From crust-apps with Apache License 2.0 4 votes vote down vote up
function Sign ({ className = '' }: Props): React.ReactElement<Props> {
  const { t } = useTranslation();
  const [currentPair, setCurrentPair] = useState<KeyringPair | null>(() => keyring.getPairs()[0] || null);
  const [{ data, isHexData }, setData] = useState<DataState>({ data: '', isHexData: false });
  const [{ isInjected }, setAccountState] = useState<AccountState>({ isExternal: false, isHardware: false, isInjected: false });
  const [isLocked, setIsLocked] = useState(false);
  const [{ isUsable, signer }, setSigner] = useState<SignerState>({ isUsable: true, signer: null });
  const [signature, setSignature] = useState('');
  const [isUnlockVisible, toggleUnlock] = useToggle();

  useEffect((): void => {
    const meta = (currentPair && currentPair.meta) || {};
    const isExternal = (meta.isExternal as boolean) || false;
    const isHardware = (meta.isHardware as boolean) || false;
    const isInjected = (meta.isInjected as boolean) || false;
    const isUsable = !(isExternal || isHardware || isInjected);

    setAccountState({ isExternal, isHardware, isInjected });
    setIsLocked(
      isInjected
        ? false
        : (currentPair && currentPair.isLocked) || false
    );
    setSignature('');
    setSigner({ isUsable, signer: null });

    // for injected, retrieve the signer
    if (meta.source && isInjected) {
      web3FromSource(meta.source as string)
        .catch((): null => null)
        .then((injected) => setSigner({
          isUsable: isFunction(injected?.signer?.signRaw),
          signer: injected?.signer || null
        }))
        .catch(console.error);
    }
  }, [currentPair]);

  const _onChangeAccount = useCallback(
    (accountId: string | null) => accountId && setCurrentPair(keyring.getPair(accountId)),
    []
  );

  const _onChangeData = useCallback(
    (data: string) => setData({ data, isHexData: isHex(data) }),
    []
  );

  const _onSign = useCallback(
    (): void => {
      if (isLocked || !isUsable || !currentPair) {
        return;
      }

      if (signer && isFunction(signer.signRaw)) {
        setSignature('');

        signer
          .signRaw({
            address: currentPair.address,
            data: isHexData
              ? data
              : stringToHex(data),
            type: 'bytes'
          })
          .then(({ signature }) => setSignature(signature))
          .catch(console.error);
      } else {
        setSignature(u8aToHex(
          currentPair.sign(
            isHexData
              ? hexToU8a(data)
              : stringToU8a(data)
          )
        ));
      }
    },
    [currentPair, data, isHexData, isLocked, isUsable, signer]
  );

  const _onUnlock = useCallback(
    (): void => {
      setIsLocked(false);
      toggleUnlock();
    },
    [toggleUnlock]
  );

  return (
    <div className={`toolbox--Sign ${className}`}>
      <div className='ui--row'>
        <InputAddress
          className='full'
          help={t<string>('select the account you wish to sign data with')}
          isInput={false}
          label={t<string>('account')}
          onChange={_onChangeAccount}
          type='account'
        />
      </div>
      <div className='toolbox--Sign-input'>
        <div className='ui--row'>
          <Input
            autoFocus
            className='full'
            help={t<string>('The input data to sign. This can be either specified as a hex value (0x-prefix) or as a string.')}
            label={t<string>('sign the following data')}
            onChange={_onChangeData}
            value={data}
          />
        </div>
        <div className='ui--row'>
          <Static
            className='medium'
            help={t<string>('Detection on the input string to determine if it is hex or non-hex.')}
            label={t<string>('hex input data')}
            value={
              isHexData
                ? t<string>('Yes')
                : t<string>('No')
            }
          />
        </div>
        <div className='ui--row'>
          <Output
            className='full'
            help={t<string>('The resulting signature of the input data, as done with the crypto algorithm from the account. (This could be non-deterministic for some types such as sr25519).')}
            isHidden={signature.length === 0}
            isMonospace
            label={t<string>('signature of supplied data')}
            value={signature}
            withCopy
          />
        </div>
        <div
          className='unlock-overlay'
          hidden={!isUsable || !isLocked || isInjected}
        >
          {isLocked && (
            <div className='unlock-overlay-warning'>
              <div className='unlock-overlay-content'>
                {t<string>('You need to unlock this account to be able to sign data.')}<br/>
                <Button.Group>
                  <Button
                    icon='unlock'
                    label={t<string>('Unlock account')}
                    onClick={toggleUnlock}
                  />
                </Button.Group>
              </div>
            </div>
          )}
        </div>
        <div
          className='unlock-overlay'
          hidden={isUsable}
        >
          <div className='unlock-overlay-warning'>
            <div className='unlock-overlay-content'>
              {isInjected
                ? t<string>('This injected account cannot be used to sign data since the extension does not support raw signing.')
                : t<string>('This external account cannot be used to sign data. Only Limited support is currently available for signing from any non-internal accounts.')}
            </div>
          </div>
        </div>
        {isUnlockVisible && (
          <Unlock
            onClose={toggleUnlock}
            onUnlock={_onUnlock}
            pair={currentPair}
          />
        )}
      </div>
      <Button.Group>
        <Button
          icon='key'
          isDisabled={!(isUsable && !isLocked)}
          label={t<string>('Sign message')}
          onClick={_onSign}
        />
      </Button.Group>
    </div>
  );
}