Skip to content

Commit

Permalink
refactor transformers list to persist
Browse files Browse the repository at this point in the history
  • Loading branch information
nbayindirli committed May 1, 2024
1 parent a66d923 commit 87f8be6
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 56 deletions.
7 changes: 0 additions & 7 deletions typescript/sdk/src/providers/transactions/TransactionTypes.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { Logger } from 'pino';
import { rootLogger } from '@hyperlane-xyz/utils';
import { ProtocolType } from '@hyperlane-xyz/utils';

import { ChainName } from '../../../../types.js';
import {
ProtocolTypedReceipt,
ProtocolTypedTransaction,
} from '../../../ProviderType.js';
import { TxTransformerInterface } from '../../transformer/TxTransformerInterface.js';
import { TxSubmitterInterface } from '../TxSubmitterInterface.js';
import { TxSubmitterType } from '../TxSubmitterTypes.js';

/**
* Builds a TxSubmitterBuilder for batch transaction submission.
Expand All @@ -29,15 +31,23 @@ import { TxSubmitterInterface } from '../TxSubmitterInterface.js';
* new EV5JsonRpcTxSubmitter(chainC)
* ).submit(txs);
*/
export class TxSubmitterBuilder<TProtocol extends ProtocolType> {
export class TxSubmitterBuilder<TProtocol extends ProtocolType>
implements TxSubmitterInterface<TProtocol>
{
public readonly txSubmitterType: TxSubmitterType;
public readonly chain: ChainName;

protected readonly logger: Logger = rootLogger.child({
module: 'submitter-builder',
});

constructor(
private currentSubmitter: TxSubmitterInterface<TProtocol>,
private readonly currentTransformers: TxTransformerInterface<TProtocol>[] = [],
) {}
private currentTransformers: TxTransformerInterface<TProtocol>[] = [],
) {
this.txSubmitterType = this.currentSubmitter.txSubmitterType;
this.chain = this.currentSubmitter.chain;
}

/**
* Sets the current submitter for the builder.
Expand All @@ -55,9 +65,9 @@ export class TxSubmitterBuilder<TProtocol extends ProtocolType> {
* @param txTransformerOrType The transformer to add to the builder
*/
public transform(
txTransformer: TxTransformerInterface<TProtocol>,
...txTransformers: TxTransformerInterface<TProtocol>[]
): TxSubmitterBuilder<TProtocol> {
this.currentTransformers.push(txTransformer);
this.currentTransformers = txTransformers;
return this;
}

Expand All @@ -73,9 +83,7 @@ export class TxSubmitterBuilder<TProtocol extends ProtocolType> {
);

let transformedTxs = txs;
while (this.currentTransformers.length > 0) {
const currentTransformer: TxTransformerInterface<TProtocol> =
this.currentTransformers.pop()!;
for (const currentTransformer of this.currentTransformers) {
transformedTxs = await currentTransformer.transform(...transformedTxs);
this.logger.info(
`🔄 Transformed ${transformedTxs.length} transactions with the ${currentTransformer.txTransformerType} transformer...`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ import { Address, rootLogger } from '@hyperlane-xyz/utils';
import { ChainName } from '../../../../types.js';
import { getSafe, getSafeService } from '../../../../utils/gnosisSafe.js';
import { MultiProvider } from '../../../MultiProvider.js';
import { EV5Tx } from '../../TransactionTypes.js';
import { TxSubmitterType } from '../TxSubmitterTypes.js';

import { EV5TxSubmitterInterface } from './EV5TxSubmitterInterface.js';

interface EV5GnosisSafeTxSubmitterProps {
safeAddress: Address;
signerAddress?: Address;
}

export class EV5GnosisSafeTxSubmitter implements EV5TxSubmitterInterface {
Expand All @@ -37,7 +35,7 @@ export class EV5GnosisSafeTxSubmitter implements EV5TxSubmitterInterface {
public readonly props: EV5GnosisSafeTxSubmitterProps,
) {}

public async submit(...txs: EV5Tx[]): Promise<void> {
public async submit(...txs: PopulatedTransaction[]): Promise<void> {
const safe: Safe.default = await getSafe(
this.chain,
this.multiProvider,
Expand Down Expand Up @@ -65,10 +63,9 @@ export class EV5GnosisSafeTxSubmitter implements EV5TxSubmitterInterface {
});
const safeTransactionData: SafeTransactionData = safeTransaction.data;
const safeTxHash: string = await safe.getTransactionHash(safeTransaction);
let senderAddress: Address | undefined = this.props.signerAddress;
if (!senderAddress) {
senderAddress = await this.multiProvider.getSignerAddress(this.chain);
}
const senderAddress: Address = await this.multiProvider.getSignerAddress(
this.chain,
);
const safeSignature: EthSafeSignature = await safe.signTransactionHash(
safeTxHash,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContractReceipt } from 'ethers';
import { TransactionReceipt } from '@ethersproject/providers';
import { PopulatedTransaction } from 'ethers';
import { Logger } from 'pino';

import { rootLogger } from '@hyperlane-xyz/utils';
Expand All @@ -7,18 +8,15 @@ import { Address } from '@hyperlane-xyz/utils';
import { ChainName } from '../../../../types.js';
import { impersonateAccount } from '../../../../utils/fork.js';
import { MultiProvider } from '../../../MultiProvider.js';
import { EV5Receipt, EV5Tx } from '../../TransactionTypes.js';
import { TxSubmitterType } from '../TxSubmitterTypes.js';

import { EV5TxSubmitterInterface } from './EV5TxSubmitterInterface.js';
import { EV5JsonRpcTxSubmitter } from './EV5JsonRpcTxSubmitter.js';

interface EV5ImpersonatedAccountTxSubmitterProps {
address: Address;
}

export class EV5ImpersonatedAccountTxSubmitter
implements EV5TxSubmitterInterface
{
export class EV5ImpersonatedAccountTxSubmitter extends EV5JsonRpcTxSubmitter {
public readonly txSubmitterType: TxSubmitterType =
TxSubmitterType.IMPERSONATED_ACCOUNT;

Expand All @@ -30,24 +28,16 @@ export class EV5ImpersonatedAccountTxSubmitter
public readonly multiProvider: MultiProvider,
public readonly chain: ChainName,
public readonly props: EV5ImpersonatedAccountTxSubmitterProps,
) {}

public async submit(...txs: EV5Tx[]): Promise<EV5Receipt[]> {
const receipts: EV5Receipt[] = [];
for (const tx of txs) {
const signer = await impersonateAccount(this.props.address);
this.multiProvider.setSigner(this.chain, signer);
const receipt: ContractReceipt = await this.multiProvider.sendTransaction(
this.chain,
tx,
);

this.logger.debug(
`Submitted EthersV5Transaction on ${this.chain}: ${receipt.transactionHash}`,
);

receipts.push(receipt);
}
return receipts;
) {
super(multiProvider, chain);
}

public async submit(
...txs: PopulatedTransaction[]
): Promise<TransactionReceipt[]> {
const impersonatedAccount = await impersonateAccount(this.props.address);
this.multiProvider.setSigner(this.chain, impersonatedAccount);
super.multiProvider.setSigner(this.chain, impersonatedAccount);
return await super.submit(...txs);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ContractReceipt } from 'ethers';
import { TransactionReceipt } from '@ethersproject/providers';
import { ContractReceipt, PopulatedTransaction } from 'ethers';
import { Logger } from 'pino';

import { rootLogger } from '@hyperlane-xyz/utils';

import { ChainName } from '../../../../types.js';
import { MultiProvider } from '../../../MultiProvider.js';
import { EV5Receipt, EV5Tx } from '../../TransactionTypes.js';
import { TxSubmitterType } from '../TxSubmitterTypes.js';

import { EV5TxSubmitterInterface } from './EV5TxSubmitterInterface.js';
Expand All @@ -22,15 +22,17 @@ export class EV5JsonRpcTxSubmitter implements EV5TxSubmitterInterface {
public readonly chain: ChainName,
) {}

public async submit(...txs: EV5Tx[]): Promise<EV5Receipt[]> {
const receipts: EV5Receipt[] = [];
public async submit(
...txs: PopulatedTransaction[]
): Promise<TransactionReceipt[]> {
const receipts: TransactionReceipt[] = [];
for (const tx of txs) {
const receipt: ContractReceipt = await this.multiProvider.sendTransaction(
this.chain,
tx,
);
this.logger.debug(
`Submitted EthersV5Transaction on ${this.chain}: ${receipt.transactionHash}`,
`Submitted PopulatedTransaction on ${this.chain}: ${receipt.transactionHash}`,
);
receipts.push(receipt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { InterchainAccount } from '../../../../middleware/account/InterchainAcco
import { AccountConfig } from '../../../../middleware/account/types.js';
import { ChainName } from '../../../../types.js';
import { MultiProvider } from '../../../MultiProvider.js';
import { EV5Tx } from '../../TransactionTypes.js';
import { TxTransformerType } from '../TxTransformerTypes.js';

import { EV5TxTransformerInterface } from './EV5TxTransformerInterface.js';
Expand All @@ -34,18 +33,20 @@ export class EV5InterchainAccountTxTransformer
public readonly props: EV5InterchainAccountTxTransformerProps,
) {}

public async transform(...txs: EV5Tx[]): Promise<EV5Tx[]> {
public async transform(
...txs: PopulatedTransaction[]
): Promise<PopulatedTransaction[]> {
const destinationChainId = txs[0].chainId;
assert(
destinationChainId,
'Missing destination chainId in EthersV5Transaction.',
'Missing destination chainId in PopulatedTransaction.',
);

const innerCalls: CallData[] = txs.map(
({ to, data, value }: PopulatedTransaction) => {
assert(
to && data,
'Invalid EthersV5Transaction: Missing required field to or data.',
'Invalid PopulatedTransaction: Missing required field to or data.',
);
return { to, data, value };
},
Expand Down

0 comments on commit 87f8be6

Please sign in to comment.