Claude-skill-registry crane-deployment
This skill should be used when the user asks about "create3", "deploy", "diamond factory", "package", "deterministic deployment", "cross-chain", "DiamondPackageCallBackFactory", "FactoryService", or needs guidance on deploying Diamond proxies and facets using Crane's factory system.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/crane-deployment" ~/.claude/skills/majiayu000-claude-skill-registry-crane-deployment && rm -rf "$T"
manifest:
skills/data/crane-deployment/SKILL.mdsource content
Crane Deployment Patterns
Crane uses a two-factory system for deterministic cross-chain deployments of Diamond proxies.
Factory Hierarchy
Create3Factory # Deploys facets, packages, and any contract └── DiamondPackageCallBackFactory # Deploys Diamond proxy instances from packages
Deployment Flow
Step 1: Initialize Factories
In test
setUp() or deployment scripts:
(ICreate3Factory factory, IDiamondPackageCallBackFactory diamondFactory) = InitDevService.initEnv(address(this));
Step 2: Deploy Facets
Use Create3Factory to deploy facets with deterministic addresses:
IFacet erc20Facet = factory.deployFacet( type(ERC20Facet).creationCode, abi.encode(type(ERC20Facet).name)._hash() // Salt from name hash );
Step 3: Deploy Package
Deploy package with facet references in constructor:
IERC20DFPkg erc20Pkg = IERC20DFPkg(address( factory.deployPackageWithArgs( type(ERC20DFPkg).creationCode, abi.encode(IERC20DFPkg.PkgInit({ erc20Facet: erc20Facet })), // Constructor args abi.encode(type(ERC20DFPkg).name)._hash() // Salt ) ));
Step 4: Deploy Diamond Proxy Instances
// Option A: Via package's deploy() helper IERC20 token = erc20Pkg.deploy(diamondFactory, "Token", "TKN", 18, 1000e18, recipient, bytes32(0)); // Option B: Via factory directly address proxy = diamondFactory.deploy(pkg, abi.encode(pkgArgs));
Key Components
| Component | Purpose |
|---|---|
| Deploys any contract with deterministic addresses via CREATE3 |
| Deploys Diamond proxies, calls via delegatecall |
| Interface for packages - bundles facets + initialization logic |
| Library to bootstrap the factory system in tests |
Create3Factory Methods
deployFacet()
deployFacet()Deploy a facet (no constructor args):
IFacet facet = factory.deployFacet( type(MyFacet).creationCode, salt );
deployPackageWithArgs()
deployPackageWithArgs()Deploy a package with constructor arguments:
IDiamondFactoryPackage pkg = IDiamondFactoryPackage(address( factory.deployPackageWithArgs( type(MyPkg).creationCode, abi.encode(IMyPkg.PkgInit({ ... })), // Constructor args salt ) ));
deploy()
deploy()Deploy any contract:
address deployed = factory.deploy( creationCode, salt );
Salt Calculation
Always derive salt from type name for deterministic addresses:
using BetterEfficientHashLib for bytes; bytes32 salt = abi.encode(type(MyContract).name)._hash();
This ensures:
- Same address across all EVM chains
- Predictable deployment addresses
- No salt collision between different contracts
DiamondPackageCallBackFactory Flow
- User calls
factory.deploy(pkg, pkgArgs) - Factory calculates deterministic address via
pkg.calcSalt(pkgArgs) - Factory deploys
via CREATE2MinimalDiamondCallBackProxy - Proxy calls back to factory's
initAccount() - Factory delegatecalls
to initialize storagepkg.initAccount() - Factory calls
for any post-deployment hookspkg.postDeploy()
FactoryService Pattern
Group related deployments in FactoryService libraries:
library MyFeatureFactoryService { using BetterEfficientHashLib for bytes; Vm constant vm = Vm(VM_ADDRESS); function deployMyFacet(ICreate3Factory factory) internal returns (IFacet) { IFacet facet = factory.deployFacet( type(MyFacet).creationCode, abi.encode(type(MyFacet).name)._hash() ); vm.label(address(facet), type(MyFacet).name); // Always label! return facet; } }
See
references/factory-service-examples.md for complete examples.
Test Setup Pattern
contract MyTest is CraneTest { IFacet myFacet; IMyDFPkg myPkg; function setUp() public override { super.setUp(); // Initializes factories // Deploy facet myFacet = create3Factory.deployFacet( type(MyFacet).creationCode, abi.encode(type(MyFacet).name)._hash() ); vm.label(address(myFacet), "MyFacet"); // Deploy package myPkg = IMyDFPkg(address( create3Factory.deployPackageWithArgs( type(MyDFPkg).creationCode, abi.encode(IMyDFPkg.PkgInit({ myFacet: myFacet })), abi.encode(type(MyDFPkg).name)._hash() ) )); vm.label(address(myPkg), "MyDFPkg"); } }
Additional Resources
Reference Files
- Complete FactoryService examplesreferences/factory-service-examples.md
- Production deployment script patternsreferences/deployment-scripts.md
Key Files
- CREATE3 factory/contracts/factories/create3/Create3Factory.sol
- Diamond factory/contracts/factories/diamondPkg/DiamondPackageCallBackFactory.sol
- Factory initialization/contracts/InitDevService.sol
- Package interface with flow diagram/contracts/interfaces/IDiamondFactoryPackage.sol