near-safe
Version:
An SDK for controlling Ethereum Smart Accounts via ERC4337 from a Near Account.
64 lines (63 loc) • 2.24 kB
JavaScript
import { decodeFunctionData, formatEther, parseTransaction, serializeTransaction, } from "viem";
import { SAFE_DEPLOYMENTS } from "../_gen/deployments";
import { decodeMulti, isMultisendTx } from "../lib/multisend";
export function decodeTransactionSerializable(chainId, tx) {
const { gas, maxFeePerGas, maxPriorityFeePerGas, to } = tx;
if (chainId !== tx.chainId) {
throw Error(`Transaction chainId mismatch ${chainId} != ${tx.chainId}`);
}
if (!gas || !maxFeePerGas || !maxPriorityFeePerGas) {
throw Error(`Insufficient feeData for ${serializeTransaction(tx)}. Check https://rawtxdecode.in/`);
}
if (!to) {
throw Error(`Transaction is missing the 'to' in ${serializeTransaction(tx)}. Check https://rawtxdecode.in/`);
}
return {
chainId,
// This is an upper bound on the gas fees (could be lower)
costEstimate: formatEther(gas * (maxFeePerGas + maxPriorityFeePerGas)),
transactions: [
{
to,
value: (tx.value || 0n).toString(),
data: tx.data || "0x",
},
],
};
}
export function decodeRlpHex(chainId, tx) {
return decodeTransactionSerializable(chainId, parseTransaction(tx));
}
export function decodeTypedData(chainId, data) {
return {
chainId,
costEstimate: "0",
transactions: [],
message: data,
};
}
export function decodeUserOperation(chainId, userOp) {
const { callGasLimit, maxFeePerGas, maxPriorityFeePerGas } = userOp;
const maxGasPrice = BigInt(maxFeePerGas) + BigInt(maxPriorityFeePerGas);
const { args } = decodeFunctionData({
abi: SAFE_DEPLOYMENTS.m4337.abi,
data: userOp.callData,
});
// Determine if singular or double!
const transactions = isMultisendTx(args)
? decodeMulti(args[2])
: [
{
to: args[0],
value: args[1],
data: args[2],
operation: args[3],
},
];
return {
chainId,
// This is an upper bound on the gas fees (could be lower)
costEstimate: formatEther(BigInt(callGasLimit) * maxGasPrice),
transactions,
};
}