@charterlabs/permissionless
Version:
A utility library for working with ERC-4337
267 lines • 12.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toNexusSmartAccount = toNexusSmartAccount;
const viem_1 = require("viem");
const account_abstraction_1 = require("viem/account-abstraction");
const actions_1 = require("viem/actions");
const getAccountNonce_1 = require("../../actions/public/getAccountNonce.js");
const decode7579Calls_1 = require("../../utils/decode7579Calls.js");
const encode7579Calls_1 = require("../../utils/encode7579Calls.js");
const BICONOMY_ADDRESSES = {
CHARTER_FACTORY_ADDRESS: "0xF6044Df1977DebF1069dE44a3Bf002d8738E25D6",
K1_VALIDATOR_ADDRESS: "0x9Bf4eF98187990262579B0C98764683A824dDc5b"
};
async function toNexusSmartAccount(parameters) {
const { client, index = 0n, address, factoryAddress = BICONOMY_ADDRESSES.CHARTER_FACTORY_ADDRESS, validatorAddress = BICONOMY_ADDRESSES.K1_VALIDATOR_ADDRESS, attesters = [], threshold = 0 } = parameters;
const entryPoint = {
address: parameters.entryPoint?.address ?? account_abstraction_1.entryPoint07Address,
abi: account_abstraction_1.entryPoint07Abi,
version: parameters.entryPoint?.version ?? "0.7"
};
let _accountAddress = address;
const getFactoryArgs = async () => {
const validatorData = parameters.validatorData === undefined
? { pubKeyX: 0n, pubKeyY: 0n }
: parameters.validatorData;
const authenticatorIdHash = parameters.authenticatorIdHash === undefined
? "0x0000000000000000000000000000000000000000000000000000000000000000"
: parameters.authenticatorIdHash;
const executors = parameters.executors === undefined ? [] : parameters.executors;
const hook = parameters.hook === undefined
? { module: "0x0000000000000000000000000000000000000000", data: "0x" }
: parameters.hook;
const fallbacks = parameters.fallbacks === undefined ? [] : parameters.fallbacks;
const preValidationHooks = parameters.preValidationHooks === undefined ? [] : parameters.preValidationHooks;
const registryConfig = {
registry: parameters.registryAddress === undefined
? "0x0000000000000000000000000000000000000000"
: parameters.registryAddress,
attesters: attesters.sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase())),
threshold
};
return {
factory: factoryAddress,
factoryData: (0, viem_1.encodeFunctionData)({
abi: [
{
name: "createAccount",
type: "function",
stateMutability: "payable",
inputs: [
{ type: "uint256", name: "index" },
{
type: "tuple",
name: "validatorData",
components: [
{ type: "uint256", name: "pubKeyX" },
{ type: "uint256", name: "pubKeyY" }
]
},
{ type: "bytes32", name: "authenticatorIdHash" },
{
type: "tuple[]",
name: "executors",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple",
name: "hook",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple[]",
name: "fallbacks",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple[]",
name: "preValidationHooks",
components: [
{ type: "uint256", name: "hookType" },
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple",
name: "registryConfig",
components: [
{ type: "address", name: "registry" },
{ type: "address[]", name: "attesters" },
{ type: "uint8", name: "threshold" }
]
}
],
outputs: [{ type: "address", name: "" }]
}
],
functionName: "createAccount",
args: [
index,
validatorData,
authenticatorIdHash,
executors,
hook,
fallbacks,
preValidationHooks,
registryConfig
]
})
};
};
return (0, account_abstraction_1.toSmartAccount)({
client,
entryPoint,
getFactoryArgs,
async getAddress() {
if (_accountAddress)
return _accountAddress;
const computedAddress = await (0, actions_1.readContract)(client, {
address: factoryAddress,
abi: [
{
name: "computeAccountAddress",
type: "function",
stateMutability: "view",
inputs: [
{ type: "uint256", name: "index" },
{
type: "tuple",
name: "validatorData",
components: [
{ type: "uint256", name: "pubKeyX" },
{ type: "uint256", name: "pubKeyY" }
]
},
{ type: "bytes32", name: "authenticatorIdHash" },
{
type: "tuple[]",
name: "executors",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple",
name: "hook",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple[]",
name: "fallbacks",
components: [
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple[]",
name: "preValidationHooks",
components: [
{ type: "uint256", name: "hookType" },
{ type: "address", name: "module" },
{ type: "bytes", name: "data" }
]
},
{
type: "tuple",
name: "registryConfig",
components: [
{ type: "address", name: "registry" },
{ type: "address[]", name: "attesters" },
{ type: "uint8", name: "threshold" }
]
}
],
outputs: [{ type: "address", name: "expectedAddress" }]
}
],
functionName: "computeAccountAddress",
args: [
index,
parameters.validatorData === undefined
? { pubKeyX: 0n, pubKeyY: 0n }
: parameters.validatorData,
parameters.authenticatorIdHash === undefined
? "0x0000000000000000000000000000000000000000000000000000000000000000"
: parameters.authenticatorIdHash,
parameters.executors === undefined ? [] : parameters.executors,
parameters.hook === undefined
? { module: "0x0000000000000000000000000000000000000000", data: "0x" }
: parameters.hook,
parameters.fallbacks === undefined ? [] : parameters.fallbacks,
parameters.preValidationHooks === undefined ? [] : parameters.preValidationHooks,
{
registry: parameters.registryAddress === undefined
? "0x0000000000000000000000000000000000000000"
: parameters.registryAddress,
attesters: attesters.sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase())),
threshold
}
]
});
_accountAddress = computedAddress;
return computedAddress;
},
async getNonce(args) {
const TIMESTAMP_ADJUSTMENT = 16777215n;
const defaultedKey = (args?.key ?? 0n) % TIMESTAMP_ADJUSTMENT;
const defaultedValidationMode = "0x00";
const key = (0, viem_1.concat)([
(0, viem_1.toHex)(defaultedKey, { size: 3 }),
defaultedValidationMode,
validatorAddress
]);
const address = await this.getAddress();
return (0, getAccountNonce_1.getAccountNonce)(client, {
address,
entryPointAddress: entryPoint.address,
key: BigInt(key)
});
},
encodeCalls: async (calls) => {
return (0, encode7579Calls_1.encode7579Calls)({
mode: {
type: calls.length > 1 ? "batchcall" : "call",
revertOnError: false,
selector: "0x",
context: "0x"
},
callData: calls
});
},
async decodeCalls(callData) {
return (0, decode7579Calls_1.decode7579Calls)(callData).callData;
},
async getStubSignature() {
const dynamicPart = validatorAddress.substring(2).padEnd(40, "0");
return `0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000${dynamicPart}000000000000000000000000000000000000000000000000000000000000004181d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b00000000000000000000000000000000000000000000000000000000000000`;
},
async sign({ hash }) {
return this.signMessage({ message: hash });
},
async signMessage() {
throw new Error('Not implemented');
},
async signTypedData() {
throw new Error('Not implemented');
},
async signUserOperation() {
throw new Error('Not implemented');
}
});
}
//# sourceMappingURL=toNexusSmartAccount.js.map