@polkadot/types#GenericExtrinsic TypeScript Examples

The following examples show how to use @polkadot/types#GenericExtrinsic. 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: base-provider.ts    From bodhi.js with Apache License 2.0 6 votes vote down vote up
_getExtrinsicsAndEventsAtBlock = async (
    blockHash: string,
    txHash?: string
  ): Promise<{
    extrinsics: GenericExtrinsic | GenericExtrinsic[] | undefined;
    extrinsicsEvents: EventRecord[] | undefined;
  }> => {
    const [block, blockEvents] = await Promise.all([
      this.api.rpc.chain.getBlock(blockHash.toLowerCase()),
      this.queryStorage<Vec<FrameSystemEventRecord>>('system.events', [], blockHash)
    ]);

    if (!txHash) return { extrinsics: block.block.extrinsics, extrinsicsEvents: undefined };

    const { transactionHash, transactionIndex, extrinsicIndex, isExtrinsicFailed } = getTransactionIndexAndHash(
      txHash.toLowerCase(),
      block.block.extrinsics,
      blockEvents
    );

    const extrinsicEvents = blockEvents.filter(
      (event) => event.phase.isApplyExtrinsic && event.phase.asApplyExtrinsic.toNumber() === extrinsicIndex
    );

    return {
      extrinsics: block.block.extrinsics[extrinsicIndex],
      extrinsicsEvents: extrinsicEvents
    };
  };
Example #2
Source File: base-provider.ts    From bodhi.js with Apache License 2.0 6 votes vote down vote up
getTransactionByHash = async (txHash: string): Promise<TX | null> => {
    if (!this.localMode) {
      // local mode is for local instant-sealing node
      // so ignore pending tx to avoid some timing issue
      const pendingTX = await this._getPendingTX(txHash);
      if (pendingTX) return pendingTX;
    }

    const tx = await this._getMinedTXReceipt(txHash);
    if (!tx) return null;

    const res = await this._getExtrinsicsAndEventsAtBlock(tx.blockHash, txHash);

    if (!res) {
      return logger.throwError(`extrinsic not found from hash`, Logger.errors.UNKNOWN_ERROR, { txHash });
    }

    const data = await this._parseExtrinsic(
      tx.blockHash,
      res.extrinsics as GenericExtrinsic,
      res.extrinsicsEvents as EventRecord[]
    );

    return {
      blockHash: tx.blockHash,
      blockNumber: tx.blockNumber,
      transactionIndex: tx.transactionIndex,
      ...data
    };
  };
Example #3
Source File: substrate-rpc.ts    From polkadot-launch with MIT License 6 votes vote down vote up
async function tryLookingForEvents(
	api: ApiPromise,
	extrinsicHash: Uint8Array
): Promise<{ extrinsic: GenericExtrinsic<AnyTuple>; events: Event[] }> {
	await waitOneBlock(api);
	let { extrinsic, events } = await lookForExtrinsicAndEvents(
		api,
		extrinsicHash
	);
	if (events.length > 0) {
		return {
			extrinsic,
			events,
		};
	} else {
		return await tryLookingForEvents(api, extrinsicHash);
	}
}
Example #4
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 #5
Source File: base-provider.ts    From bodhi.js with Apache License 2.0 5 votes vote down vote up
_getTxHashesAtBlock = async (blockHash: string): Promise<string[]> => {
    const extrinsics = (await this._getExtrinsicsAndEventsAtBlock(blockHash)).extrinsics as GenericExtrinsic[];
    return extrinsics.map((e) => e.hash.toHex());
  };
Example #6
Source File: transactionReceiptHelper.ts    From bodhi.js with Apache License 2.0 5 votes vote down vote up
getTransactionIndexAndHash = (
  hashOrNumber: string | number,
  extrinsics: GenericExtrinsic[],
  events: EventRecord[]
): {
  transactionIndex: number;
  transactionHash: string;
  isExtrinsicFailed: boolean;
  extrinsicIndex: number;
} => {
  const evmExtrinsicIndexes = getEvmExtrinsicIndexes(events);
  const extrinsicsHashes = extrinsics.map((extrinsic) => extrinsic.hash.toHex());

  let extrinsicIndex: number | undefined = undefined;

  if (isHexString(hashOrNumber, 32)) {
    extrinsicIndex = extrinsicsHashes.findIndex((hash) => hashOrNumber === hash);
  } else {
    const index = BigNumber.from(hashOrNumber).toNumber();
    extrinsicIndex = evmExtrinsicIndexes[index];
  }

  const transactionHash = extrinsicIndex ? extrinsics[extrinsicIndex]?.hash.toHex() : undefined;

  if (extrinsicIndex === undefined || transactionHash === undefined || extrinsicIndex < 0) {
    return logger.throwError(`transaction hash not found`, Logger.errors.UNKNOWN_ERROR, {
      hashOrNumber
    });
  }

  const transactionIndex = evmExtrinsicIndexes.findIndex((index) => index === extrinsicIndex);

  if (transactionIndex < 0) {
    return logger.throwError(`expected extrinsic include evm events`, Logger.errors.UNKNOWN_ERROR, {
      hashOrNumber
    });
  }

  const isExtrinsicFailed = events[events.length - 1].event.method === 'ExtrinsicFailed';

  return {
    transactionIndex,
    transactionHash,
    extrinsicIndex,
    isExtrinsicFailed
  };
}
Example #7
Source File: Blocks.ts    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
/**
   * Get all extrinsic of particular block
   * @param blockHash hash of particular block
   * @returns Vec of extrinsics
   */
  async getExtrinsics(blockHash: `0x${string}` | Uint8Array): Promise<Vec<GenericExtrinsic<AnyTuple>>> {
    return (await this.get(blockHash)).block.extrinsics;
  }
Example #8
Source File: base-provider.ts    From bodhi.js with Apache License 2.0 4 votes vote down vote up
_parseExtrinsic = async (
    blockHash: string,
    extrinsic: GenericExtrinsic,
    extrinsicEvents: EventRecord[]
  ): Promise<any> => {
    // logger.info(extrinsic.method.toHuman());
    // logger.info(extrinsic.method);

    const evmEvent = findEvmEvent(extrinsicEvents);
    if (!evmEvent) {
      return logger.throwError(
        'findEvmEvent failed. extrinsic: ' + extrinsic.method.toJSON(),
        Logger.errors.UNSUPPORTED_OPERATION
      );
    }

    let gas;
    let value;
    let input;
    const from = evmEvent.event.data[0].toString();
    const to = ['Created', 'CreatedFailed'].includes(evmEvent.event.method) ? null : evmEvent.event.data[1].toString();

    // @TODO remove
    // only work on mandala and karura-testnet
    // https://github.com/AcalaNetwork/Acala/pull/1985
    let gasPrice = BIGNUMBER_ONE;

    if (
      evmEvent.event.data.length > 5 ||
      (evmEvent.event.data.length === 5 &&
        (evmEvent.event.method === 'Created' || evmEvent.event.method === 'Executed'))
    ) {
      const used_gas = BigNumber.from(evmEvent.event.data[evmEvent.event.data.length - 2].toString());
      const used_storage = BigNumber.from(evmEvent.event.data[evmEvent.event.data.length - 1].toString());

      const block = await this.api.rpc.chain.getBlock(blockHash);
      // use parentHash to get tx fee
      const payment = await this.api.rpc.payment.queryInfo(extrinsic.toHex(), block.block.header.parentHash);
      // ACA/KAR decimal is 12. Mul 10^6 to make it 18.
      let tx_fee = ethers.utils.parseUnits(payment.partialFee.toString(), 'mwei');

      // get storage fee
      // if used_storage > 0, tx_fee include the storage fee.
      if (used_storage.gt(0)) {
        const { storageDepositPerByte } = this._getGasConsts();
        tx_fee = tx_fee.add(used_storage.mul(storageDepositPerByte));
      }

      gasPrice = tx_fee.div(used_gas);
    }

    switch (extrinsic.method.section.toUpperCase()) {
      case 'EVM': {
        const evmExtrinsic: any = extrinsic.method.toJSON();
        value = evmExtrinsic?.args?.value;
        gas = evmExtrinsic?.args?.gas_limit;
        // @TODO remove
        // only work on mandala and karura-testnet
        // https://github.com/AcalaNetwork/Acala/pull/1965
        input = evmExtrinsic?.args?.input || evmExtrinsic?.args?.init;
        break;
      }
      // Not a raw evm transaction, input = 0x
      // case 'CURRENCIES':
      // case 'DEX':
      // case 'HONZONBRIDGE':
      // case 'PROXY':
      // case 'SUDO':
      // case 'TECHNICALCOMMITTEE':
      // case 'STABLEASSET':
      // @TODO support utility
      // case 'UTILITY': {
      //   return logger.throwError('Unspport utility, blockHash: ' + blockHash, Logger.errors.UNSUPPORTED_OPERATION);
      // }
      // default: {
      //   return logger.throwError(
      //     'Unspport ' + extrinsic.method.section.toUpperCase() + ' blockHash: ' + blockHash,
      //     Logger.errors.UNSUPPORTED_OPERATION
      //   );
      // }

      // Not a raw evm transaction, input = 0x
      default: {
        value = 0;
        gas = 2_100_000;
        input = '0x';
      }
    }

    // @TODO eip2930, eip1559

    // @TODO Missing data
    return {
      gasPrice,
      gas,
      input,
      v: DUMMY_V,
      r: DUMMY_R,
      s: DUMMY_S,
      hash: extrinsic.hash.toHex(),
      nonce: extrinsic.nonce.toNumber(),
      from: from,
      to: to,
      value: hexValue(value)
    };
  };