UNPKG

zksync-sso

Version:
150 lines (136 loc) 5.03 kB
import { type Account, assertRequest, type AssertRequestErrorType, type Chain, type Client, type ExactPartial, type Hash, type PublicActions, type RpcSchema, type SendTransactionRequest, type Transport, type WalletActions } from "viem"; import { parseAccount } from "viem/accounts"; import { prepareTransactionRequest, sendRawTransaction } from "viem/actions"; import { type ChainEIP712, type SendEip712TransactionParameters, type SendEip712TransactionReturnType, type SendTransactionParameters, zksync } from "viem/zksync"; import { InvalidEip712TransactionError, type InvalidEip712TransactionErrorType } from "../../utils/assertEip712Transaction.js"; import { isEIP712Transaction } from "../../utils/isEip712Transaction.js"; /** * Creates, signs, and sends a new EIP712 transaction to the network. * * @param client - Client to use * @param parameters - {@link SendEip712TransactionParameters} * @returns The [Transaction](https://viem.sh/docs/glossary/terms#transaction) hash. {@link SendTransactionReturnType} * * @example * import { createWalletClient, custom } from 'viem' * import { zksync } from 'viem/chains' * import { sendEip712Transaction } from 'viem/zksync' * * const client = createWalletClient({ * chain: zksync, * transport: custom(window.ethereum), * }) * const hash = await sendEip712Transaction(client, { * account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', * value: 1000000000000000000n, * }) * * @example * // Account Hoisting * import { createWalletClient, http } from 'viem' * import { privateKeyToAccount } from 'viem/accounts' * import { zksync } from 'viem/chains' * import { sendEip712Transaction } from 'viem/zksync' * * const client = createWalletClient({ * account: privateKeyToAccount('0x…'), * chain: zksync, * transport: http(), * }) * * const hash = await sendEip712Transaction(client, { * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', * value: 1000000000000000000n, * }) */ export async function sendEip712Transaction< chain extends ChainEIP712 | undefined, account extends Account | undefined, const request extends SendTransactionRequest<chain, chainOverride>, chainOverride extends ChainEIP712 | undefined = undefined, >( client: Client<Transport, chain, account>, parameters: SendEip712TransactionParameters< chain, account, chainOverride, request >, ): Promise<SendEip712TransactionReturnType> { const { account: account_ = client.account, chain = client.chain, ...rest } = parameters; if (!account_) throw new Error("Account not found."); const account = parseAccount(account_); assertEip712Request(parameters); const request = await getAction( client, prepareTransactionRequest, "prepareTransactionRequest", )({ account, chain, nonceManager: account.nonceManager, ...rest, } as any); const serializer = chain?.serializers?.transaction; const serializedTransaction = (await account.signTransaction!(request, { serializer, })) as Hash; return await getAction( client, sendRawTransaction, "sendRawTransaction", )({ serializedTransaction, }); } /** * Retrieves and returns an action from the client (if exists), and falls * back to the tree-shakable action. * * Useful for extracting overridden actions from a client (ie. if a consumer * wants to override the `sendTransaction` implementation). */ export function getAction< transport extends Transport, chain extends Chain | undefined, account extends Account | undefined, rpcSchema extends RpcSchema | undefined, extended extends { [key: string]: unknown }, client extends Client<transport, chain, account, rpcSchema, extended>, parameters, returnType, >( client: client, actionFn: (_: any, parameters: parameters) => returnType, // cspell:ignore minifiers // Some minifiers drop `Function.prototype.name`, or replace it with short letters, // meaning that `actionFn.name` will not always work. For that case, the consumer // needs to pass the name explicitly. name: keyof PublicActions | keyof WalletActions | (string & {}), ): (parameters: parameters) => returnType { const action_implicit = client[actionFn.name]; if (typeof action_implicit === "function") return action_implicit as (params: parameters) => returnType; const action_explicit = client[name]; if (typeof action_explicit === "function") return action_explicit as (params: parameters) => returnType; return (params) => actionFn(client, params); } type AssertEip712RequestParameters = ExactPartial< SendTransactionParameters<typeof zksync> >; /** @internal */ export type AssertEip712RequestErrorType = | InvalidEip712TransactionErrorType | AssertRequestErrorType; export function assertEip712Request(args: AssertEip712RequestParameters) { if (!isEIP712Transaction(args as any)) throw new InvalidEip712TransactionError(); assertRequest(args as any); }