Skip to content

Commit

Permalink
Merge pull request #13 from router-protocol/feat/aleph-hooks
Browse files Browse the repository at this point in the history
aleph hooks added
  • Loading branch information
jayeshbhole-rp authored Sep 13, 2024
2 parents 6525c70 + c2ef646 commit 31aa3bc
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 41 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function App({ Component, pageProps }) {
| EVM | :white_check_mark: | :white_check_mark: | :small_orange_diamond: | :small_orange_diamond: | :small_orange_diamond: |
| Solana | :white_check_mark: | :white_check_mark: | :small_orange_diamond: | :small_orange_diamond: | :small_orange_diamond: |
| Tron | :white_check_mark: | :white_check_mark: | :small_orange_diamond: | :small_orange_diamond: | :small_orange_diamond: |
| AlephZero | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: |
| AlephZero | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Sui | :small_orange_diamond: | :x: | :x: | :x: | :x: |
| Cosmos | :x: | :x: | :x: | :x: | :x: |
| Near | :x: | :x: | :x: | :x: | :x: |
Expand Down
7 changes: 7 additions & 0 deletions example-next/src/components/Tokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ const tokens: TokenMetadata[] = [
symbol: 'USDC',
chainId: 'alephZero',
},
{
address: '5CMdxZDuprVZKnw6tEWjhEtK17Z52PUJo2dj1JLdyKeuUcfH',
decimals: 6,
name: 'USDT',
symbol: 'USDT',
chainId: 'alephZero',
},
];

export default Tokens;
48 changes: 45 additions & 3 deletions packages/react/src/actions/getTransactionReceipt.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getTransactionReceipt as getEVMTransactionReceipt } from '@wagmi/core';
import { ChainData, ChainType, ConnectionOrConfig, TransactionReceipt } from '../types/index.js';
import { TransactionParams } from './waitForTransaction.js';

export type GetTransactionReceiptOverrides<C extends ChainType = ChainType> = C extends 'solana'
? {
Expand All @@ -8,27 +9,28 @@ export type GetTransactionReceiptOverrides<C extends ChainType = ChainType> = C
: any;

Check warning on line 9 in packages/react/src/actions/getTransactionReceipt.ts

View workflow job for this annotation

GitHub Actions / build (20)

Unexpected any. Specify a different type

export type GetTransactionReceiptParams<C extends ChainType = ChainType> = {
txHash: string;
transactionParams: TransactionParams<C>;
chain: ChainData<C>;
config: ConnectionOrConfig;
overrides: GetTransactionReceiptOverrides<C> | undefined;
};

/**
* Get transaction receipt
* @param txHash - Transaction hash
* @param transactionParams - Transaction Parameters {@link TransactionParams}
* @param chain - {@link ChainData}
* @param config {@link ConnectionOrConfig}
* @returns Transaction Receipt {@link TransactionReceipt}
*/
export const getTransactionReceipt = async <C extends ChainType>({
txHash,
transactionParams,
chain,
config,
overrides = {} as GetTransactionReceiptOverrides,
}: GetTransactionReceiptParams<C>): Promise<TransactionReceipt<C>> => {
// evm chain
if (chain.type === 'evm') {
const { txHash } = transactionParams as TransactionParams<'evm'>;
const receipt = await getEVMTransactionReceipt(config.wagmiConfig, {
hash: txHash as `0x${string}`,
chainId: chain.id,
Expand All @@ -37,10 +39,12 @@ export const getTransactionReceipt = async <C extends ChainType>({
}

if (chain.type === 'tron') {
const { txHash } = transactionParams as TransactionParams<'tron'>;
return (await config.tronWeb.trx.getTransactionInfo(txHash)) as TransactionReceipt<C>;
}

if (chain.type === 'solana') {
const { txHash } = transactionParams as TransactionParams<'solana'>;
const result = config.solanaConnection.getTransaction(txHash, {
maxSupportedTransactionVersion: 0,
...overrides,
Expand All @@ -51,5 +55,43 @@ export const getTransactionReceipt = async <C extends ChainType>({
return result as TransactionReceipt<C>;
}

if (chain.type === 'alephZero') {
const { blockHash, extrinsicIndex } = transactionParams as TransactionParams<'alephZero'>;
const alephZero = config.alephZeroApi;

const signedBlock = await alephZero.rpc.chain.getBlock(blockHash);

// Get the specific extrinsic
const extrinsic = signedBlock.block.extrinsics[extrinsicIndex];

if (!extrinsic) {
throw new Error('Extrinsic not found');
}

// Get the events for this block
const apiAt = await alephZero.at(blockHash);
const allRecords = (await apiAt.query.system.events()).toPrimitive() as any[];

Check warning on line 73 in packages/react/src/actions/getTransactionReceipt.ts

View workflow job for this annotation

GitHub Actions / build (20)

Unexpected any. Specify a different type

const extrinsicEvents = allRecords.filter(
(event) => event.phase.applyExtrinsic && event.phase.applyExtrinsic === extrinsicIndex,
);

const transactionData = {
blockHash,
extrinsicIndex,
extrinsic: extrinsic,
extrinsicHash: extrinsic.hash.toHuman(),
method: extrinsic.method.toHuman(),
args: extrinsic.args.map((arg) => arg.toHuman()),
events: extrinsicEvents,
};

if (!transactionData) {
throw new Error('Transaction not found');
}

return transactionData as TransactionReceipt<C>;
}

throw new Error('Chain type not supported');
};
37 changes: 36 additions & 1 deletion packages/react/src/actions/sendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { VersionedTransaction as SolanaVersionedTransaction } from '@solana/web3
import { sendTransaction as sendEVMTransaction } from '@wagmi/core';
import { Address as EVMAddress } from 'viem';

import { Signer, SubmittableExtrinsic } from '@polkadot/api/types';
import { ChainData, ChainType, ConnectionOrConfig } from '../types/index.js';
import { WalletInstance } from '../types/wallet.js';

Expand Down Expand Up @@ -31,7 +32,7 @@ type TransactionArgs<C extends ChainType> = C extends 'evm'
}
: C extends 'alephZero'
? {
z: string;
submittableExtrinsic: SubmittableExtrinsic<'promise' | 'rxjs'>;
}
: never;

Expand Down Expand Up @@ -93,7 +94,41 @@ export const sendTransactionToChain = async <C extends ChainType>({
}

if (chain.type === 'alephZero') {
let txnHash: string | undefined = undefined;
let block: string | undefined = undefined;
let extrinsicId: number | undefined = undefined;

const walletConnector = config.connector as WalletInstance<'alephZero'>;

// send transaction to Aleph chain
const { submittableExtrinsic } = args as TransactionArgs<'alephZero'>;
await submittableExtrinsic.signAndSend(
from,
{ signer: walletConnector.signer as Signer },
({ events, status, txHash, txIndex }) => {
events.forEach(({ event }) => {
const { method } = event;

if (method === 'ExtrinsicSuccess' && status.type === 'InBlock') {
txnHash = txHash.toString();
block = status.asFinalized.toHex();
extrinsicId = txIndex;
} else if (method === 'ExtrinsicFailed') {
throw new Error(`Transaction failed: ${method}`);
}
});
},
);

if (txnHash === undefined || block === undefined) {
throw 'Trasaction failed';
}

return {
txHash: txnHash,
block: block,
txIndex: extrinsicId,
};
}

throw new Error('Chain not supported');
Expand Down
68 changes: 65 additions & 3 deletions packages/react/src/actions/waitForTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@ export type WatchTransactionOverrides<C extends ChainType = ChainType> = Default
}
: any);

export type WatchTransactionParams<C extends ChainType = ChainType> = {
export type DefaultTransactionParams = {
txHash: string;
};

export type TransactionParams<C extends ChainType = ChainType> = C extends 'alephZero'
? {
blockHash: string;
extrinsicIndex: number;
}
: DefaultTransactionParams;

export type WatchTransactionParams<C extends ChainType = ChainType> = {
transactionParams: TransactionParams<C>;
chain: ChainData<C>;
config: ConnectionOrConfig;
overrides: WatchTransactionOverrides<C> | undefined;
Expand All @@ -32,7 +43,7 @@ const DEFAULT_POLLING_INTERVAL = 2500; // 2.5 seconds

/**
* Watch transaction
* @param txHash - Transaction hash
* @param transactionParams - Transaction Parameters
* @param chain - {@link ChainData}
* @param config {@link ConnectionOrConfig}
* @returns Transaction Receipt {@link TransactionReceipt}
Expand All @@ -41,9 +52,10 @@ export const waitForTransaction = async <C extends ChainType>({
chain,
config,
overrides,
txHash,
transactionParams,
}: WatchTransactionParams<C>): Promise<TransactionReceipt<C>> => {
if (chain.type === 'evm') {
const { txHash } = transactionParams as TransactionParams<'evm'>;
const evmOverrides = (overrides || {}) as WatchTransactionOverrides<'evm'>;
const receipt = await waitForTransactionReceipt(config.wagmiConfig, {
hash: txHash as `0x${string}`,
Expand All @@ -57,6 +69,7 @@ export const waitForTransaction = async <C extends ChainType>({
if (chain.type === 'tron') {
const txInfo = await pollCallback(
async () => {
const { txHash } = transactionParams as TransactionParams<'tron'>;
const tx = await config.tronWeb.trx.getConfirmedTransaction(txHash);

// If transaction is not found, return undefined. This will trigger the next poll
Expand All @@ -74,6 +87,7 @@ export const waitForTransaction = async <C extends ChainType>({
}

if (chain.type === 'solana') {
const { txHash } = transactionParams as TransactionParams<'solana'>;
const _overrides = (overrides || {}) as WatchTransactionOverrides<'solana'>;

const receipt = await pollCallback(
Expand All @@ -95,5 +109,53 @@ export const waitForTransaction = async <C extends ChainType>({
return receipt as TransactionReceipt<C>;
}

if (chain.type === 'alephZero') {
const { blockHash, extrinsicIndex } = transactionParams as TransactionParams<'alephZero'>;
const alephZero = config.alephZeroApi;

const receipt = await pollCallback(
async () => {
const signedBlock = await alephZero.rpc.chain.getBlock(blockHash);

// Get the specific extrinsic
const extrinsic = signedBlock.block.extrinsics[extrinsicIndex];

if (!extrinsic) {
throw new Error('Extrinsic not found');
}

// Get the events for this block
const apiAt = await alephZero.at(blockHash);
const allRecords = (await apiAt.query.system.events()).toPrimitive() as any[];

const extrinsicEvents = allRecords.filter(
(event) => event.phase.applyExtrinsic && event.phase.applyExtrinsic === extrinsicIndex,
);

const transactionData = {
blockHash,
extrinsicIndex,
extrinsic: extrinsic,
extrinsicHash: extrinsic.hash.toHuman(),
method: extrinsic.method.toHuman(),
args: extrinsic.args.map((arg) => arg.toHuman()),
events: extrinsicEvents,
};

return transactionData;
},
{
interval: overrides?.interval || DEFAULT_POLLING_INTERVAL,
timeout: overrides?.timeout,
},
);

if (!receipt) {
throw new Error('Transaction not found');
}

return receipt as TransactionReceipt<C>;
}

throw new Error('Chain not supported');
};
19 changes: 10 additions & 9 deletions packages/react/src/hooks/useTransactionReceipt.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import { GetTransactionReceiptOverrides, getTransactionReceipt } from '../actions/getTransactionReceipt.js';
import { TransactionParams } from '../actions/waitForTransaction.js';
import { ChainId } from '../types/index.js';
import { useChain } from './useChain.js';
import { useConnectionOrConfig } from './useConnectionOrConfig.js';

export type UseTransactionReceiptParams = {
/** Transaction hash */
txHash: string | undefined;
/** Transaction Params {@link TransactionParams} */
transactionParams: TransactionParams | undefined;
/** Chain ID of transaction */
chainId: ChainId;
/** Transaction overrides {@link GetTransactionReceiptOverrides} */
Expand All @@ -15,36 +16,36 @@ export type UseTransactionReceiptParams = {

/**
* Transaction Receipt Hook
* @param txHash - Transaction hash
* @param transactionParams - Transaction Parameters
* @param chainId - Chain ID of transaction
* @param overrides - Transaction overrides {@link GetTransactionReceiptOverrides}
* @returns Query object
*/
export const useTransactionReceipt = ({ txHash, chainId, overrides }: UseTransactionReceiptParams) => {
export const useTransactionReceipt = ({ transactionParams, chainId, overrides }: UseTransactionReceiptParams) => {
const connectionOrConfig = useConnectionOrConfig();
const chain = useChain(chainId);

return useQuery({
queryKey: ['transaction receipt', txHash, chainId],
queryKey: ['transaction receipt', transactionParams, chainId],
queryFn: async () => {
if (!connectionOrConfig) {
throw new Error('Connections or config not found');
}
if (!chain) {
throw new Error('Chain is not supported');
}
if (!txHash) {
throw new Error('Transaction hash is required');
if (!transactionParams) {
throw new Error('Transaction Params are required');
}

return await getTransactionReceipt({
txHash,
transactionParams,
chain,
config: connectionOrConfig,
overrides,
});
},
enabled: Boolean(connectionOrConfig && chain && txHash),
enabled: Boolean(connectionOrConfig && chain && transactionParams),
retry: false,
refetchOnWindowFocus: false,
});
Expand Down
Loading

0 comments on commit 31aa3bc

Please sign in to comment.