@moesi/deployer-strategies
v0.3.1
Published
Pure deterministic deployer math (CREATE2/3, CreateX 4 guards, Nick's method). No chain RPC.
Maintainers
Readme
@moesi/deployer-strategies
Pure deterministic deployer math for Moesi. No chain RPC, no settlement.
Covers the Arachnid deterministic deployment proxy, CreateX (all 4 guards), and Nick's-method legacy-tx replay.
Install
npm install @moesi/deployer-strategies viemCreateX
import {
predictCreateXAddress,
encodeDeployCreate2Calldata,
CREATEX_FACTORY,
} from "@moesi/deployer-strategies";
const address = predictCreateXAddress({
salt: "counter-v1",
guard: "sender-protected", // or "none" | "crosschain-protected" | "sender-and-crosschain-protected"
initCode: "0x6080…",
sender: kernelAddress,
chainId: 11155111, // sepolia
});
const calldata = encodeDeployCreate2Calldata({
salt: "counter-v1",
guard: "sender-protected",
initCode: "0x6080…",
sender: kernelAddress,
});For a deployer-independent manifest or imperative input that follows the common Forge head-entropy convention, pass the exact 11-byte suffix. Moesi injects the sender and guard flag:
const address = predictCreateXCreate3Address({
entropy: "0x04a9469db98e61f23775c1",
guard: "sender-protected",
sender: deployer,
chainId: 1,
});Existing deployments can also pass their full 32-byte CreateX salt directly:
import { predictCreateXCreate3Address } from "@moesi/deployer-strategies";
const address = predictCreateXCreate3Address({
rawSalt: legacyRawSalt,
guard: "sender-protected",
sender: deployer,
chainId: 1,
});Use exactly one of salt, entropy, or rawSalt. entropy must be exactly 11
bytes. Moesi validates that an explicit raw salt's sender prefix and flag encode
the declared guard, preventing prediction from diverging from CreateX's on-chain
guard selection.
Arachnid deterministic deployment proxy
Moesi treats deployer: create2 as a call to the Arachnid deterministic deployment proxy at 0x4e59b44847b379578588920cA78FbF26c0B4956C. This is not Nick's method; the calldata is salt || initCode.
import {
DETERMINISTIC_DEPLOYMENT_PROXY,
encodeDeterministicDeploymentProxyCalldata,
predictDeterministicDeploymentProxyAddress,
} from "@moesi/deployer-strategies";
const address = predictDeterministicDeploymentProxyAddress({
salt: "counter-v1",
initCode: "0x6080…",
});
const calldata = encodeDeterministicDeploymentProxyCalldata({
salt: "counter-v1",
initCode: "0x6080…",
});Nick's method
Build a legacy transaction signed by Nick's deterministic signer so the same contract address lands on every EVM chain that supports legacy txs. This is a keyless transaction flow, not a callable proxy contract.
import { buildNicksTx, predictNicksAddress } from "@moesi/deployer-strategies";
const tx = buildNicksTx({ initCode: "0x…" });
const predicted = predictNicksAddress("0x4c8d290a1b368ac4728d83a9e8321fc3af2b39b1");EOA write batching and hex helpers
encodeMulticall3Aggregate(calls) packs ordered, zero-native-value calls into
one transaction to the canonical Multicall3 address. It uses aggregate, so a
failed subcall reverts the batch and per-call native value is unsupported.
Check deployment first with hasMulticall3(client).
hexPrefix, ensure32ByteHex, and formatInitCode are small normalization
helpers. hexPrefix only normalizes the prefix; ensure32ByteHex additionally
validates and left-pads to bytes32; formatInitCode requires valid whole-byte
hex and never silently truncates.
License
Apache-2.0
