@abstract-foundation/agw-client
Version:
Abstract Global Wallet Client SDK
120 lines (112 loc) • 3.38 kB
text/typescript
import {
type Account,
type Address,
BaseError,
type Chain,
type Client,
type Hex,
type PublicClient,
type SendTransactionRequest,
type Transport,
type WalletClient,
} from 'viem';
import { getChainId, sendRawTransaction } from 'viem/actions';
import {
assertCurrentChain,
getAction,
getTransactionError,
type GetTransactionErrorParameters,
parseAccount,
} from 'viem/utils';
import {
type ChainEIP712,
type SendEip712TransactionParameters,
type SendEip712TransactionReturnType,
} from 'viem/zksync';
import { INSUFFICIENT_BALANCE_SELECTOR } from '../constants.js';
import { AccountNotFoundError } from '../errors/account.js';
import { InsufficientBalanceError } from '../errors/insufficientBalance.js';
import type { CustomPaymasterHandler } from '../types/customPaymaster.js';
import { prepareTransactionRequest } from './prepareTransaction.js';
import { signTransaction } from './signTransaction.js';
export async function sendTransactionInternal<
const request extends SendTransactionRequest<chain, chainOverride>,
chain extends ChainEIP712 | undefined = ChainEIP712 | undefined,
account extends Account | undefined = Account | undefined,
chainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined,
>(
client: Client<Transport, ChainEIP712, Account>,
signerClient: WalletClient<Transport, ChainEIP712, Account>,
publicClient: PublicClient<Transport, ChainEIP712>,
parameters: SendEip712TransactionParameters<
chain,
account,
chainOverride,
request
>,
validator: Address,
validationHookData: Record<string, Hex> = {},
customPaymasterHandler: CustomPaymasterHandler | undefined = undefined,
): Promise<SendEip712TransactionReturnType> {
const { chain = client.chain } = parameters;
if (!signerClient.account)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/sendTransaction',
});
const account = parseAccount(signerClient.account);
try {
// assertEip712Request(parameters)
// Prepare the request for signing (assign appropriate fees, etc.)
const request = await prepareTransactionRequest(
client,
signerClient,
publicClient,
{
...parameters,
parameters: ['gas', 'nonce', 'fees'],
isSponsored:
customPaymasterHandler !== undefined ||
(parameters as any).paymaster !== undefined,
} as any,
);
let chainId: number | undefined;
if (chain !== null) {
chainId = await getAction(signerClient, getChainId, 'getChainId')({});
assertCurrentChain({
currentChainId: chainId,
chain,
});
}
const serializedTransaction = await signTransaction(
client,
signerClient,
publicClient,
{
...request,
chainId,
} as any,
validator,
validationHookData,
customPaymasterHandler,
);
return await getAction(
client,
sendRawTransaction,
'sendRawTransaction',
)({
serializedTransaction,
});
} catch (err) {
if (
err instanceof Error &&
err.message.includes(INSUFFICIENT_BALANCE_SELECTOR)
) {
throw new InsufficientBalanceError();
}
throw getTransactionError(err as BaseError, {
...(parameters as GetTransactionErrorParameters),
account,
chain: chain as Chain,
});
}
}