Generate a Diamond Factory Package (DFPkg) with PkgInit and PkgArgs structs
Generates a complete Diamond Factory Package (DFPkg) with PkgInit and PkgArgs structs for deploying Diamond proxy instances based on a provided feature name.
When to use
Use this when you need to create a new reusable deployment package for a Diamond proxy feature, bundling related facets and configuration.
How to invoke
manual via /new-dfpkg
npx claudepluginhub cyotee/cyotee-claude-plugin-crane<FeatureName>Generate a complete Diamond Factory Package for deploying Diamond proxy instances.
The user provides a feature name (e.g., MyFeature).
Locate related facets:
{FeatureName}Facet.sol and related facetsDetermine output directory:
packages/ subdirectoryGenerate the following files:
I{FeatureName}DFPkg.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
interface I{FeatureName}DFPkg {
/// @notice Constructor arguments for the package
/// @dev Contains immutable facet references
struct PkgInit {
IFacet {featureName}Facet;
// Add other facets as needed
}
/// @notice Deployment arguments for each instance
/// @dev Passed to initAccount() during deployment
struct PkgArgs {
// Add per-instance configuration
// e.g., string name;
// e.g., address owner;
}
}
{FeatureName}DFPkg.sol)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {IDiamond} from "@crane/contracts/introspection/ERC2535/interfaces/IDiamond.sol";
import {IDiamondFactoryPackage} from "@crane/contracts/interfaces/IDiamondFactoryPackage.sol";
import {IFacet} from "@crane/contracts/interfaces/IFacet.sol";
import {I{FeatureName}DFPkg} from "./interfaces/I{FeatureName}DFPkg.sol";
import {{FeatureName}Repo} from "./{FeatureName}Repo.sol";
contract {FeatureName}DFPkg is I{FeatureName}DFPkg, IDiamondFactoryPackage {
IFacet immutable {FEATURE_NAME}_FACET;
constructor(PkgInit memory pkgInit_) {
{FEATURE_NAME}_FACET = pkgInit_.{featureName}Facet;
}
function packageName() public pure returns (string memory) {
return type({FeatureName}DFPkg).name;
}
function facetCuts() public view returns (IDiamond.FacetCut[] memory cuts_) {
cuts_ = new IDiamond.FacetCut[](1);
cuts_[0] = IDiamond.FacetCut({
facetAddress: address({FEATURE_NAME}_FACET),
action: IDiamond.FacetCutAction.Add,
functionSelectors: {FEATURE_NAME}_FACET.facetFuncs()
});
}
function diamondConfig() public view returns (DiamondConfig memory) {
// Return diamond configuration
}
function calcSalt(bytes memory pkgArgs_) public pure returns (bytes32) {
PkgArgs memory args = abi.decode(pkgArgs_, (PkgArgs));
// Return deterministic salt based on args
// e.g., return keccak256(abi.encode(args.name));
}
function initAccount(bytes memory initArgs_) public {
PkgArgs memory args = abi.decode(initArgs_, (PkgArgs));
// Initialize storage via Repo
// {FeatureName}Repo._initialize(...);
}
function postDeploy(address) public returns (bool) {
return true;
}
}
File placement:
contracts/{feature-path}/
├── interfaces/
│ └── I{FeatureName}DFPkg.sol
└── {FeatureName}DFPkg.sol
Add deploy helper (optional):
// In {FeatureName}DFPkg.sol
function deploy(
IDiamondPackageCallBackFactory factory_,
// Add PkgArgs fields as parameters
bytes32 salt_
) external returns (I{FeatureName}) {
return I{FeatureName}(
factory_.deploy(
IDiamondFactoryPackage(address(this)),
abi.encode(PkgArgs({
// Map parameters to struct
})),
salt_
)
);
}
Inform the user: