@account-kit/infra
Version:
adapters for @aa-sdk/core for interacting with alchemy services
130 lines (122 loc) • 4.33 kB
text/typescript
import {
isSmartAccountWithSigner,
sendTransaction,
sendTransactions,
sendUserOperation,
type GetEntryPointFromAccount,
type SendTransactionsParameters,
type SendUserOperationParameters,
type SendUserOperationResult,
type SmartContractAccount,
type UserOperationContext,
type UserOperationOverrides,
clientHeaderTrack,
} from "@aa-sdk/core";
import type {
Chain,
Client,
Hex,
SendTransactionParameters,
Transport,
} from "viem";
import { simulateUserOperationChanges } from "../../actions/simulateUserOperationChanges.js";
import type { SimulateUserOperationAssetChangesResponse } from "../../actions/types.js";
import { InfraLogger } from "../../metrics.js";
export type AlchemySmartAccountClientActions<
TAccount extends SmartContractAccount | undefined =
| SmartContractAccount
| undefined,
TContext extends UserOperationContext | undefined =
| UserOperationContext
| undefined,
TChain extends Chain | undefined = Chain | undefined,
TEntryPointVersion extends
GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>,
> = {
simulateUserOperation: (
args: SendUserOperationParameters<TAccount, TContext>,
) => Promise<SimulateUserOperationAssetChangesResponse>;
sendUserOperation: (
args: SendUserOperationParameters<
TAccount,
TContext,
GetEntryPointFromAccount<TAccount>
>,
) => Promise<SendUserOperationResult<TEntryPointVersion>>;
sendTransaction: <TChainOverride extends Chain | undefined = undefined>(
args: SendTransactionParameters<TChain, TAccount, TChainOverride>,
overrides?: UserOperationOverrides<TEntryPointVersion>,
context?: TContext,
) => Promise<Hex>;
sendTransactions: (
args: SendTransactionsParameters<TAccount, TContext>,
) => Promise<Hex>;
};
/**
* Provides a set of actions for interacting with the Alchemy Smart Account client, including the ability to simulate user operations.
*
* @example
* ```ts
* import { alchemyActions } from "@account-kit/infra";
* import { createPublicClient } from "viem";
*
* const client = createPublicClient(...);
* const clientWithAlchemyActions = client.extend(alchemyActions);
* ```
*
* @param {Client<TTransport, TChain, TAccount>} client_ The client instance used to perform actions
* @returns {AlchemySmartAccountClientActions<TAccount, TContext>} An object containing Alchemy Smart Account client actions
*/
export const alchemyActions: <
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends SmartContractAccount | undefined =
| SmartContractAccount
| undefined,
TContext extends UserOperationContext | undefined =
| UserOperationContext
| undefined,
>(
client: Client<TTransport, TChain, TAccount>,
) => AlchemySmartAccountClientActions<TAccount, TContext, TChain> = (
client_,
) => ({
simulateUserOperation: async (args) => {
const client = clientHeaderTrack(client_, "simulateUserOperation");
return simulateUserOperationChanges(client, args);
},
async sendUserOperation(args) {
const client = clientHeaderTrack(client_, "infraSendUserOperation");
const { account = client.account } = args;
const result = sendUserOperation(client, args);
logSendUoEvent(client.chain!.id, account!);
return result;
},
sendTransaction: async (args, overrides, context) => {
const client = clientHeaderTrack(client_, "sendTransaction");
const { account = client.account } = args;
const result = await sendTransaction(client, args, overrides, context);
logSendUoEvent(client.chain!.id, account as SmartContractAccount);
return result;
},
async sendTransactions(args) {
const client = clientHeaderTrack(client_, "sendTransactions");
const { account = client.account } = args;
const result = sendTransactions(client, args);
logSendUoEvent(client.chain!.id, account!);
return result;
},
});
function logSendUoEvent(chainId: number, account: SmartContractAccount) {
const signerType = isSmartAccountWithSigner(account)
? account.getSigner().signerType
: "unknown";
InfraLogger.trackEvent({
name: "client_send_uo",
data: {
chainId,
signerType: signerType,
entryPoint: account.getEntryPoint().address,
},
});
}