@polkadot/api/types#SubmittableExtrinsic TypeScript Examples

The following examples show how to use @polkadot/api/types#SubmittableExtrinsic. 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: Address.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
async function queryForMultisig (api: ApiPromise, requestAddress: string, proxyAddress: string | null, tx: SubmittableExtrinsic<'promise'>): Promise<MultiState | null> {
  const multiModule = api.tx.multisig ? 'multisig' : 'utility';

  if (isFunction(api.query[multiModule]?.multisigs)) {
    const address = proxyAddress || requestAddress;
    const { threshold, who } = extractExternal(address);
    const hash = (proxyAddress ? api.tx.proxy.proxy(requestAddress, null, tx) : tx).method.hash;
    const optMulti = await api.query[multiModule].multisigs<Option<Multisig>>(address, hash);
    const multi = optMulti.unwrapOr(null);

    return multi
      ? {
        address,
        isMultiCall: ((multi.approvals.length + 1) >= threshold),
        who,
        whoFilter: who.filter((w) => !multi.approvals.some((a) => a.eq(w)))
      }
      : {
        address,
        isMultiCall: false,
        who,
        whoFilter: who
      };
  }

  return null;
}
Example #2
Source File: Code.ts    From gear-js with GNU General Public License v3.0 6 votes vote down vote up
/**
   * Submit code without initialization
   * @param code
   * @returns Code hash
   */
  submit(code: Buffer | Uint8Array): { codeHash: Hex; submitted: SubmittableExtrinsic<'promise', ISubmittableResult> } {
    const codeBytes = this.createType.create('bytes', Array.from(code)) as Bytes;
    this.submitted = this.api.tx.gear.submitCode(codeBytes);
    const codeHash = generateCodeHash(code);
    return { codeHash, submitted: this.submitted };
  }
Example #3
Source File: execute.ts    From crust-apps with Apache License 2.0 6 votes vote down vote up
export async function execute (extrinsic: SubmittableExtrinsic<'promise'>, singer: KeyringPair, logger = { info: console.log }): Promise<void> {
  let currentTxDone = false;

  function sendStatusCb ({ events = [], status }: { events?: EventRecord[], status: ExtrinsicStatus; }) {
    if (status.isInvalid) {
      logger.info('Transaction invalid');
      currentTxDone = true;
    } else if (status.isReady) {
      logger.info('Transaction is ready');
    } else if (status.isBroadcast) {
      logger.info('Transaction has been broadcasted');
    } else if (status.isInBlock) {
      logger.info('Transaction is in block');
    } else if (status.isFinalized) {
      logger.info(`Transaction has been included in blockHash ${status.asFinalized.toHex()}`);
      events.forEach(
        ({ event }) => {
          if (event.method === 'ExtrinsicSuccess') {
            logger.info('Transaction succeeded');
          } else if (event.method === 'ExtrinsicFailed') {
            logger.info('Transaction failed');
          }
        }
      );
      currentTxDone = true;
    }
  }

  await extrinsic.signAndSend(singer, sendStatusCb);
  await waitFor(() => currentTxDone, { timeout: 20000 });
}
Example #4
Source File: Message.ts    From gear-js with GNU General Public License v3.0 6 votes vote down vote up
/**
   * Send message
   * @param message Message parameters
   * @param meta Metadata
   * @param messageType MessageType
   * @returns Submitted result
   * ```javascript
   * const api = await GearApi.create()
   * const programId = '0xd7540ae9da85e33b47276e2cb4efc2f0b58fef1227834f21ddc8c7cb551cced6'
   * api.message.submit({
   *  destination: messageId,
   *  payload: 'Hello, World!',
   *  gasLimit: 20_000_000
   * }, undefiend, 'String')
   * api.message.signAndSend(account, (events) => {
   *  events.forEach(({event}) => console.log(event.toHuman()))
   * })
   * ```
   */
  submit(
    message: { destination: string | H256; payload: PayloadType; gasLimit: AnyNumber; value?: AnyNumber },
    meta?: Metadata,
    messageType?: string,
  ): SubmittableExtrinsic<'promise', ISubmittableResult> {
    let payload = createPayload(this.createType, messageType || meta?.handle_input, message.payload, meta);
    try {
      this.submitted = this.api.tx.gear.sendMessage(message.destination, payload, message.gasLimit, message.value || 0);
      return this.submitted;
    } catch (error) {
      throw new SendMessageError();
    }
  }
Example #5
Source File: Address.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
function filterProxies (allAccounts: string[], tx: Call | SubmittableExtrinsic<'promise'>, proxies: [string, ProxyType][]): string[] {
  // check an array of calls to all have proxies as the address
  const checkCalls = (address: string, txs: Call[]): boolean =>
    !txs.some((tx) => !filterProxies(allAccounts, tx, proxies).includes(address));

  // get the call info
  const { method, section } = findCall(tx);

  return proxies
    .filter(([address, proxy]): boolean => {
      if (!allAccounts.includes(address)) {
        return false;
      }

      switch (proxy.toString()) {
        case 'Any':
          return true;
        case 'Governance':
          return ['council', 'democracy', 'elections', 'electionsPhragmen', 'poll', 'society', 'technicalCommittee', 'tips', 'treasury'].includes(section);
        case 'IdentityJudgement':
          return section === 'identity' && method === 'provideJudgement';
        case 'NonTransfer':
          return !(section === 'balances' || (section === 'indices' && method === 'transfer') || (section === 'vesting' && method === 'vestedTransfer'));
        case 'Staking':
          return section === 'staking' ||
            (section === 'utility' && (
              (method === 'batch' && checkCalls(address, tx.args[0] as Vec<Call>)) ||
              (method === 'asLimitedSub' && checkCalls(address, [tx.args[0] as Call]))
            ));
        case 'SudoBalances':
          return (section === 'sudo' && (method === 'sudo' && findCall(tx.args[0] as Call).section === 'balances')) ||
            (section === 'utility' && (method === 'batch' && checkCalls(address, tx.args[0] as Vec<Call>)));
        default:
          return false;
      }
    })
    .map(([address]) => address);
}
Example #6
Source File: shared.ts    From commonwealth with GNU General Public License v3.0 6 votes vote down vote up
// TODO: refactor fee computation into a more standard form that can be used throughout
  //   and shown at TX creation time
  public async canPayFee(
    sender: SubstrateAccount,
    txFunc: (api: ApiPromise) => SubmittableExtrinsic<'promise'>,
    additionalDeposit?: SubstrateCoin,
  ): Promise<boolean> {
    const senderBalance = await sender.freeBalance;
    const netBalance = additionalDeposit ? senderBalance.sub(additionalDeposit) : senderBalance;
    let fees: SubstrateCoin;
    if (sender.chain.network === ChainNetwork.Edgeware) {
      // XXX: we cannot compute tx fees on edgeware yet, so we are forced to assume no fees
      //   besides explicit additional fees
      fees = additionalDeposit || this.coins(0);
    } else {
      fees = await this.computeFees(sender.address, txFunc);
    }
    console.log(`sender free balance: ${senderBalance.format(true)}, tx fees: ${fees.format(true)}, `
      + `additional deposit: ${additionalDeposit ? additionalDeposit.format(true) : 'N/A'}`);
    return netBalance.gte(fees);
  }
Example #7
Source File: transaction.ts    From interbtc-api with Apache License 2.0 6 votes vote down vote up
async sendLogged<T extends AnyTuple>(
        transaction: SubmittableExtrinsic<"promise">,
        successEventType?: AugmentedEvent<ApiTypes, T>,
        onlyInBlock?: boolean
    ): Promise<ISubmittableResult> {
        if (this.account === undefined) {
            return Promise.reject(new Error(ACCOUNT_NOT_SET_ERROR_MESSAGE));
        }
        return DefaultTransactionAPI.sendLogged(this.api, this.account, transaction, successEventType, onlyInBlock);
    }
Example #8
Source File: substrate-rpc.ts    From polkadot-launch with MIT License 6 votes vote down vote up
createBlockWithExtrinsicParachain = async <
	Call extends SubmittableExtrinsic<ApiType>,
	ApiType extends ApiTypes
>(
	api: ApiPromise,
	sender: AddressOrPair,
	polkadotCall: Call
): Promise<{ extrinsic: GenericExtrinsic<AnyTuple>; events: Event[] }> => {
	console.log("-------------- EXTRINSIC CALL -------------------------------");
	// This should return a Uint8Array
	const extrinsicHash = (await polkadotCall.signAndSend(
		sender
	)) as unknown as Uint8Array;

	// We create the block which is containing the extrinsic
	//const blockResult = await context.createBlock();
	return await tryLookingForEvents(api, extrinsicHash);
}
Example #9
Source File: gov.ts    From sdk with Apache License 2.0 6 votes vote down vote up
/**
 * make an extrinsic of treasury proposal submission for council member.
 */
async function makeTreasuryProposalSubmission(api: ApiPromise, id: any, isReject: boolean): Promise<SubmittableExtrinsic<"promise">> {
  const members = await (api.query.electionsPhragmen || api.query.elections || api.query.phragmenElection).members<any[]>();
  const councilThreshold = Math.ceil(members.length * 0.6);
  const proposal = isReject ? api.tx.treasury.rejectProposal(id) : api.tx.treasury.approveProposal(id);
  return api.tx.council.propose(councilThreshold, proposal, proposal.length);
}
Example #10
Source File: Extrinsic.tsx    From subscan-multisig-react with Apache License 2.0 6 votes vote down vote up
function ExtrinsicDisplay({
  className = '',
  defaultValue,
  isDisabled,
  isError,
  isPrivate,
  label,
  onChange,
  onEnter,
  onEscape,
  withLabel,
}: Props): React.ReactElement<Props> {
  const _onChange = useCallback(
    (method?: SubmittableExtrinsic<'promise'>): void =>
      onChange &&
      onChange({
        isValid: !!method,
        value: method,
      }),
    [onChange]
  );

  return (
    <BaseExtrinsic
      className={className}
      defaultValue={defaultValue}
      isDisabled={isDisabled}
      isError={isError}
      isPrivate={isPrivate}
      label={label}
      onChange={_onChange}
      onEnter={onEnter}
      onEscape={onEscape}
      withLabel={withLabel}
    />
  );
}
Example #11
Source File: test-precompile-democracy.ts    From moonbeam with GNU General Public License v3.0 6 votes vote down vote up
notePreimagePrecompile = async <
  Call extends SubmittableExtrinsic<ApiType>,
  ApiType extends ApiTypes
>(
  context: DevTestContext,
  iFace: Interface,
  proposal: Call
): Promise<`0x${string}`> => {
  const encodedProposal = proposal.method.toHex();

  const data = iFace.encodeFunctionData(
    // action
    "note_preimage",
    [encodedProposal]
  );

  const tx = await createTransaction(context, {
    from: GENESIS_ACCOUNT,
    privateKey: GENESIS_ACCOUNT_PRIVATE_KEY,
    value: "0x0",
    gas: "0x200000",
    gasPrice: GAS_PRICE,
    to: ADDRESS_DEMO_PRECOMPILE,
    data,
  });

  await context.createBlock({
    transactions: [tx],
  });
  // return encodedHash
  return blake2AsHex(encodedProposal);
}
Example #12
Source File: sendTx.ts    From bodhi.js with Apache License 2.0 6 votes vote down vote up
sendTx = (api: ApiPromise, extrinsic: SubmittableExtrinsic<'promise'>): Promise<SubmittableResult> => {
  return new Promise((resolve, reject) => {
    extrinsic
      .send((result) => {
        handleTxResponse(result, api)
          .then(({ result }) => {
            resolve(result);
          })
          .catch((err) => {
            reject(err);
          });
      })
      .catch((error) => {
        reject(error);
      });
  });
}
Example #13
Source File: generateTransactionPayload.ts    From metamask-snap-polkadot with Apache License 2.0 6 votes vote down vote up
export async function generateTransactionPayload(
  wallet: Wallet, api: ApiPromise, to: string, amount: string | number
): Promise<TxPayload> {
  // fetch last signed block and account address
  const [signedBlock, address] = await Promise.all([api.rpc.chain.getBlock(), getAddress(wallet)]);
  // create signer options
  const nonce = (await api.derive.balances.account(address)).accountNonce;
  const signerOptions = {
    blockHash: signedBlock.block.header.hash,
    era: api.createType('ExtrinsicEra', {
      current: signedBlock.block.header.number,
      period: 50
    }),
    nonce
  };
    // define transaction method
  const transaction: SubmittableExtrinsic<'promise'> = api.tx.balances.transfer(to, amount);

  // create SignerPayload
  const signerPayload = api.createType('SignerPayload', {
    genesisHash: api.genesisHash,
    runtimeVersion: api.runtimeVersion,
    version: api.extrinsicVersion,
    ...signerOptions,
    address: to,
    blockNumber: signedBlock.block.header.number,
    method: transaction.method,
    signedExtensions: [],
    transactionVersion: transaction.version,
  });


  return {
    payload: signerPayload.toPayload(),
    tx: transaction.toHex()
  };
}
Example #14
Source File: governance.ts    From moonbeam with GNU General Public License v3.0 6 votes vote down vote up
execFromTwoThirdsOfCouncil = async <
  Call extends SubmittableExtrinsic<ApiType>,
  ApiType extends ApiTypes
>(
  context: DevTestContext,
  polkadotCall: Call
) => {
  // Council members
  const charleth = await keyring.addFromUri(CHARLETH_PRIV_KEY, null, "ethereum");
  const dorothy = await keyring.addFromUri(DOROTHY_PRIV_KEY, null, "ethereum");

  // Charleth submit the proposal to the council (and therefore implicitly votes for)
  let lengthBound = polkadotCall.encodedLength;
  const { events: proposalEvents } = await createBlockWithExtrinsic(
    context,
    charleth,
    context.polkadotApi.tx.councilCollective.propose(2, polkadotCall, lengthBound)
  );
  const proposalHash = proposalEvents
    .find((e) => e.method.toString() == "Proposed")
    .data[2].toHex() as string;

  // Dorothy vote for this proposal and close it
  await Promise.all([
    context.polkadotApi.tx.councilCollective.vote(proposalHash, 0, true).signAndSend(charleth),
    context.polkadotApi.tx.councilCollective.vote(proposalHash, 0, true).signAndSend(dorothy),
  ]);
  await context.createBlock();

  return await createBlockWithExtrinsic(
    context,
    dorothy,
    context.polkadotApi.tx.councilCollective.close(proposalHash, 0, 1_000_000_000, lengthBound)
  );
}
Example #15
Source File: Account.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
function createClearDemocracyTx (api: ApiPromise, address: string, unlockableIds: BN[]): SubmittableExtrinsic<'promise'> | null {
  return api.tx.utility
    ? api.tx.utility.batch(
      unlockableIds
        .map((id) => api.tx.democracy.removeVote(id))
        .concat(api.tx.democracy.unlock(address))
    )
    : null;
}
Example #16
Source File: test-xcm-para.ts    From moonbeam with GNU General Public License v3.0 6 votes vote down vote up
execFromAllMembersOfTechCommittee = async <Call extends SubmittableExtrinsic<ApiTypes>>(
  parachainApi: ApiPromise,
  polkadotCall: Call,
  key_1: KeyringPair,
  key_2: KeyringPair,
  index: Number
) => {
  let lengthBound = polkadotCall.encodedLength;
  const { events: proposalEvents } = await createBlockWithExtrinsicParachain(
    parachainApi,
    key_1,
    parachainApi.tx.techCommitteeCollective.propose(2, polkadotCall, lengthBound)
  );

  const proposalHash = proposalEvents
    .find((e) => e.method.toString() == "Proposed")
    .data[2].toHex() as string;

  await createBlockWithExtrinsicParachain(
    parachainApi,
    key_1,
    parachainApi.tx.techCommitteeCollective.vote(proposalHash, index, true)
  );

  await createBlockWithExtrinsicParachain(
    parachainApi,
    key_2,
    parachainApi.tx.techCommitteeCollective.vote(proposalHash, index, true)
  );

  await createBlockWithExtrinsicParachain(
    parachainApi,
    key_2,
    parachainApi.tx.techCommitteeCollective.close(proposalHash, index, 1_000_000_000, lengthBound)
  );
}
Example #17
Source File: extrinsics.ts    From atlas with GNU General Public License v3.0 6 votes vote down vote up
private async sendExtrinsic(
    tx: SubmittableExtrinsic<'promise'>,
    cb?: ExtrinsicStatusCallbackFn
  ): Promise<SendExtrinsicResult> {
    const account = this.getAccount()
    if (!account) {
      throw new JoystreamLibError({ name: 'AccountNotSelectedError' })
    }

    try {
      cb?.(ExtrinsicStatus.Unsigned)

      const { events, blockHash } = await sendExtrinsicAndParseEvents(tx, account, this.api.registry, this.endpoint, cb)

      const blockHeader = await this.api.rpc.chain.getHeader(blockHash)

      const getEventData: GetEventDataFn = (section, method) => {
        const event = events.find((event) => event.section === section && event.method === method)

        if (!event) {
          throw new JoystreamLibError({
            name: 'MissingRequiredEventError',
            message: `Required event ${section}.${method} not found in extrinsic`,
          })
        }

        return event.data as ReturnType<GetEventDataFn>
      }

      return { events, block: blockHeader.number.toNumber(), getEventData }
    } catch (error) {
      if (error?.message === 'Cancelled') {
        throw new JoystreamLibError({ name: 'SignCancelledError' })
      }
      throw error
    }
  }
Example #18
Source File: AccountMainnet.tsx    From crust-apps with Apache License 2.0 6 votes vote down vote up
function createClearDemocracyTx (api: ApiPromise, address: string, unlockableIds: BN[]): SubmittableExtrinsic<'promise'> | null {
  return api.tx.utility
    ? api.tx.utility.batch(
      unlockableIds
        .map((id) => api.tx.democracy.removeVote(id))
        .concat(api.tx.democracy.unlock(address))
    )
    : null;
}
Example #19
Source File: governance.ts    From moonbeam with GNU General Public License v3.0 6 votes vote down vote up
notePreimage = async <
  Call extends SubmittableExtrinsic<ApiType>,
  ApiType extends ApiTypes
>(
  context: DevTestContext,
  proposal: Call,
  account: KeyringPair
): Promise<string> => {
  const encodedProposal = proposal.method.toHex() || "";
  await context.polkadotApi.tx.democracy.notePreimage(encodedProposal).signAndSend(account);
  await context.createBlock();

  return blake2AsHex(encodedProposal);
}
Example #20
Source File: helpers.ts    From crust-apps with Apache License 2.0 5 votes vote down vote up
export async function proposeMotion (api: ApiPromise, submittableExtrinsic: SubmittableExtrinsic<'promise'>, signer: KeyringPair): Promise<void> {
  await execute(api.tx.council.propose(4, submittableExtrinsic, LENGTH_BOUND), signer);
}
Example #21
Source File: Program.ts    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
/**
   * @param program Upload program data
   * @param meta Metadata
   * @returns ProgramId
   * @example
   * ```javascript
   * const code = fs.readFileSync('path/to/program.opt.wasm');
   * const meta = await getWasmMetadata(fs.readFileSync('path/to/program.meta.wasm'));
   * const api = await GearApi.create();
   * const { programId, salt, submitted } = api.program.submit({
   *   code,
   *   initPayload: {field: 'someValue'},
   *   gasLimit: 20_000_000,
   * }, meta)
   * api.program.signAndSend(account, (events) => {
   *   events.forEach(({event}) => console.log(event.toHuman()))
   * })
   * ```
   */
  submit(
    program: {
      code: Buffer | Uint8Array;
      salt?: `0x${string}`;
      initPayload?: string | any;
      gasLimit: u64 | AnyNumber;
      value?: BalanceOf | AnyNumber;
    },
    meta?: Metadata,
    messageType?: string,
  ): { programId: Hex; salt: Hex; submitted: SubmittableExtrinsic<'promise', ISubmittableResult> } {
    const salt = program.salt || randomAsHex(20);
    const code = this.createType.create('bytes', Array.from(program.code)) as Bytes;
    let payload = createPayload(this.createType, messageType || meta?.init_input, program.initPayload, meta);
    try {
      this.submitted = this.api.tx.gear.submitProgram(code, salt, payload, program.gasLimit, program.value || 0);
      const programId = generateProgramId(code, salt);
      return { programId, salt, submitted: this.submitted };
    } catch (error) {
      throw new SubmitProgramError();
    }
  }
Example #22
Source File: ProxyOverview.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
function createAddProxy (api: ApiPromise, account: AccountId, type: ProxyType, delay = 0): SubmittableExtrinsic<'promise'> {
  return api.tx.proxy.addProxy.meta.args.length === 2
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore old version
    ? api.tx.proxy.addProxy(account, type)
    : api.tx.proxy.addProxy(account, type, delay);
}
Example #23
Source File: MessageReply.ts    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
/**
   * Sends reply message
   * @param message Message parameters
   * @param meta Metadata
   * @param messageType MessageType
   * @returns Submitted result
   * @example
   * ```javascript
   * const api = await GearApi.create()
   * const messageId = '0xd7540ae9da85e33b47276e2cb4efc2f0b58fef1227834f21ddc8c7cb551cced6'
   * api.reply.submit({
   *  replyToId: messageId,
   *  payload: 'Reply message',
   *  gasLimit: 20_000_000
   * }, undefiend, 'String')
   * api.reply.signAndSend(account, (events) => {
   *  events.forEach(({event}) => console.log(event.toHuman()))
   * })
   * ```
   */
  submit(
    message: {
      replyToId: H256 | string;
      payload: string | any;
      gasLimit: u64 | AnyNumber;
      value?: BalanceOf | AnyNumber;
    },
    meta?: Metadata,
    messageType?: string,
  ): SubmittableExtrinsic<'promise', ISubmittableResult> {
    let payload = createPayload(
      this.createType,
      messageType || meta?.async_handle_input || meta?.async_init_input,
      message.payload,
      meta,
    );

    try {
      this.submitted = this.api.tx.gear.sendReply(message.replyToId, payload, message.gasLimit, message.value);
      return this.submitted;
    } catch (error) {
      throw new SendReplyError();
    }
  }
Example #24
Source File: keyring.ts    From sdk with Apache License 2.0 5 votes vote down vote up
/**
 * sign and send extrinsic to network and wait for result.
 */
function sendTx(api: ApiPromise, txInfo: any, paramList: any[], password: string, msgId: string) {
  return new Promise(async (resolve) => {
    let tx: SubmittableExtrinsic<"promise">;
    // wrap tx with council.propose for treasury propose
    if (txInfo.txName == "treasury.approveProposal") {
      tx = await gov.makeTreasuryProposalSubmission(api, paramList[0], false);
    } else if (txInfo.txName == "treasury.rejectProposal") {
      tx = await gov.makeTreasuryProposalSubmission(api, paramList[0], true);
    } else {
      tx = api.tx[txInfo.module][txInfo.call](...paramList);
    }
    let unsub = () => {};
    const onStatusChange = (result: SubmittableResult) => {
      if (result.status.isInBlock || result.status.isFinalized) {
        const { success, error } = _extractEvents(api, result);
        if (success) {
          resolve({ hash: tx.hash.toString(), blockHash: (result.status.asInBlock || result.status.asFinalized).toHex() });
        }
        if (error) {
          resolve({ error });
        }
        unsub();
      } else {
        (<any>window).send(msgId, result.status.type);
      }
    };
    if (txInfo.isUnsigned) {
      tx.send(onStatusChange)
        .then((res) => {
          unsub = res;
        })
        .catch((err) => {
          resolve({ error: err.message });
        });
      return;
    }

    let keyPair: KeyringPair;
    if (!txInfo.proxy) {
      keyPair = keyring.getPair(hexToU8a(txInfo.sender.pubKey));
    } else {
      // wrap tx with recovery.asRecovered for proxy tx
      tx = api.tx.recovery.asRecovered(txInfo.sender.address, tx);
      keyPair = keyring.getPair(hexToU8a(txInfo.proxy.pubKey));
    }

    try {
      keyPair.decodePkcs8(password);
    } catch (err) {
      resolve({ error: "password check failed" });
    }
    tx.signAndSend(keyPair, { tip: new BN(txInfo.tip, 10) }, onStatusChange)
      .then((res) => {
        unsub = res;
      })
      .catch((err) => {
        resolve({ error: err.message });
      });
  });
}
Example #25
Source File: Transaction.ts    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
submitted: SubmittableExtrinsic<'promise', ISubmittableResult>;
Example #26
Source File: shared.ts    From commonwealth with GNU General Public License v3.0 5 votes vote down vote up
public async computeFees(
    senderAddress: string,
    txFunc: (api: ApiPromise) => SubmittableExtrinsic<'promise'>,
  ): Promise<SubstrateCoin> {
    return txFunc(this.api).paymentInfo(senderAddress)
      .then((fees) => this.coins(fees.partialFee.toBn()));
  }
Example #27
Source File: QrSigner.ts    From sdk with Apache License 2.0 5 votes vote down vote up
export function makeTx(api: ApiPromise, txInfo: any, paramList: any[], ss58: number) {
  return new Promise((resolve) => {
    const signer = txInfo.proxy ? encodeAddress(hexToU8a(txInfo.proxy.pubKey), ss58) : txInfo.sender.address;
    api.derive.tx
      .signingInfo(signer)
      .then(async ({ header, mortalLength, nonce }) => {
        let tx: SubmittableExtrinsic<"promise">;
        // wrap tx with council.propose for treasury propose
        if (txInfo.txName == "treasury.approveProposal") {
          tx = await gov.makeTreasuryProposalSubmission(api, paramList[0], false);
        } else if (txInfo.txName == "treasury.rejectProposal") {
          tx = await gov.makeTreasuryProposalSubmission(api, paramList[0], true);
        } else {
          tx = api.tx[txInfo.module][txInfo.call](...paramList);
        }
        // wrap tx with recovery.asRecovered for proxy tx
        if (txInfo.proxy) {
          tx = api.tx.recovery.asRecovered(txInfo.sender.address, tx);
        }
        const signerPayload = api.registry.createType("SignerPayload", {
          address: signer,
          blockHash: header.hash,
          blockNumber: header ? header.number : 0,
          era: api.registry.createType("ExtrinsicEra", {
            current: header.number,
            period: mortalLength,
          }),
          genesisHash: api.genesisHash,
          method: tx.method,
          nonce,
          signedExtensions: ["CheckNonce"],
          tip: txInfo.tip,
          runtimeVersion: {
            specVersion: api.runtimeVersion.specVersion,
            transactionVersion: api.runtimeVersion.transactionVersion,
          },
          version: api.extrinsicVersion,
        });
        const payload = signerPayload.toPayload();

        // limit size of the transaction
        const qrIsHashed = payload.method.length > 5000;
        const wrapper = api.registry.createType("ExtrinsicPayload", payload, {
          version: payload.version,
        });
        const qrPayload = qrIsHashed ? blake2AsU8a(wrapper.toU8a(true)) : wrapper.toU8a();
        // cache this submittableExtrinsic
        submittable = {
          tx,
          payload: signerPayload.toPayload(),
        };
        // submittable.tx = tx;
        // submittable.payload = signerPayload.toPayload();
        resolve({
          qrAddress: payload.address,
          qrIsHashed,
          qrPayload: _createFrames(_createSignPayload(payload.address, qrIsHashed ? CMD_HASH : CMD_MORTAL, qrPayload, api.genesisHash))[0],
        });
      })
      .catch((err) => resolve({ error: err.message }));
  });
}
Example #28
Source File: transaction.ts    From interbtc-api with Apache License 2.0 5 votes vote down vote up
static async sendLogged<T extends AnyTuple>(
        api: ApiPromise,
        account: AddressOrPair,
        transaction: SubmittableExtrinsic<"promise">,
        successEventType?: AugmentedEvent<ApiTypes, T>,
        onlyInBlock?: boolean
    ): Promise<ISubmittableResult> {
        const { unsubscribe, result } = await new Promise((resolve, reject) => {
            let unsubscribe: () => void;
            // When passing { nonce: -1 } to signAndSend the API will use system.accountNextIndex to determine the nonce
            transaction
                .signAndSend(account, { nonce: -1 }, (result: ISubmittableResult) => callback({ unsubscribe, result }))
                .then((u: () => void) => (unsubscribe = u))
                .catch((error) => reject(error));

            function callback(callbackObject: { unsubscribe: () => void; result: ISubmittableResult }): void {
                const status = callbackObject.result.status;
                if (onlyInBlock) {
                    if (status.isInBlock) {
                        resolve(callbackObject);
                    }
                } else {
                    if (status.isFinalized) {
                        resolve(callbackObject);
                    }
                }
            }
        });

        if (onlyInBlock) {
            console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
        } else {
            console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
        }
        unsubscribe(result);

        // Print all events for debugging
        DefaultTransactionAPI.printEvents(api, result.events);

        const dispatchError = result.dispatchError;
        if (dispatchError) {
            // Construct error message
            let message = "The transaction failed.";
            // Runtime error in one of the parachain modules
            if (dispatchError.isModule) {
                // for module errors, we have the section indexed, lookup
                const decoded = api.registry.findMetaError(dispatchError.asModule);
                const { docs, name, section } = decoded;
                message = message.concat(` The error code is ${section}.${name}. ${docs.join(" ")}`);
                // Bad origin
            } else if (dispatchError.isBadOrigin) {
                message = message.concat(` The error is caused by using an incorrect account.
                The error code is BadOrigin ${dispatchError}.`);
            }
            // Other, CannotLookup, no extra info
            else {
                message = message.concat(` The error is ${dispatchError}.`);
            }
            console.log(message);
            return Promise.reject(new Error(message));
        }
        return result;
    }
Example #29
Source File: governance.ts    From moonbeam with GNU General Public License v3.0 5 votes vote down vote up
execFromAllMembersOfTechCommittee = async <
  Call extends SubmittableExtrinsic<ApiType>,
  ApiType extends ApiTypes
>(
  context: DevTestContext,
  polkadotCall: Call
) => {
  // Tech committee members
  const alith = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum");
  const baltathar = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum");

  // Alith submit the proposal to the council (and therefore implicitly votes for)
  let lengthBound = polkadotCall.encodedLength;
  const { events: proposalEvents } = await createBlockWithExtrinsic(
    context,
    alith,
    context.polkadotApi.tx.techCommitteeCollective.propose(2, polkadotCall, lengthBound)
  );
  const proposalHash = proposalEvents
    .find((e) => e.method.toString() == "Proposed")
    .data[2].toHex() as string;

  // Get proposal count
  const proposalCount = await context.polkadotApi.query.techCommitteeCollective.proposalCount();

  // Alith, Baltathar vote for this proposal and close it
  await Promise.all([
    context.polkadotApi.tx.techCommitteeCollective
      .vote(proposalHash, Number(proposalCount) - 1, true)
      .signAndSend(alith),
    context.polkadotApi.tx.techCommitteeCollective
      .vote(proposalHash, Number(proposalCount) - 1, true)
      .signAndSend(baltathar),
  ]);

  await context.createBlock();
  await context.createBlock();
  return await createBlockWithExtrinsic(
    context,
    baltathar,
    context.polkadotApi.tx.techCommitteeCollective.close(
      proposalHash,
      Number(proposalCount) - 1,
      1_000_000_000,
      lengthBound
    )
  );
}