Getting started
This guide shows the simplest way to start using the Bloxchain protocol: by connecting to an Accountβbased contract that already combines all core components (SecureOwnable, RuntimeRBAC, GuardController) behind a single address.
For a deeper explanation of the pattern itself, see the Account Pattern doc.
π Prerequisites
Node.js 18+
TypeScript 4.5+
npm or yarn
Basic knowledge of Ethereum and smart contracts
Pin @bloxchain/sdk and optionally @bloxchain/contracts to exact versions in production. See Versioning & releases for how npm semver relates to on-chain EngineBlox.VERSION.
π Installation
npm install @bloxchain/sdk
# Or with yarn
yarn add @bloxchain/sdkπ§ Basic Setup (Account-Based Contract)
1. Import Required Dependencies
2. Initialize Clients
3. Connect to an Account-Based Contract
Use a deployed Account implementation (for example AccountBlox) from deployed-addresses.json:
Definition library addresses (public testnets)
Integrators need deployed definition libraries for execution-param helpers (updateRecoveryExecutionParams, batch encoders, schema refresh). Keys in deployed-addresses.json map to env vars:
deployed-addresses.json key
Env variable
SecureOwnableDefinitions
SECURE_OWNABLE_DEFINITIONS_ADDRESS
RuntimeRBACDefinitions
RUNTIME_RBAC_DEFINITIONS_ADDRESS
GuardControllerDefinitions
GUARD_CONTROLLER_DEFINITIONS_ADDRESS
GuardControllerDefinitions
DEFINITION_CONTRACT_ADDRESS (alias for single schema-refresh address)
Example for Sepolia:
Pass these addresses to SDK helpers such as updateRecoveryExecutionParams(client, sod, newRecovery).
π Common Tasks with an Account
1. Inspect Ownership & Security State
2. Perform a Secure Ownership Transfer
3. Guarded Call via GuardController
Use the GuardController wrapper to execute a timeβlocked call to a whitelisted target:
(Approvals, cancellations, and metaβtx flows use the same patterns as described in the componentβspecific docs.)
Deployment and initialization
Accountβstyle contracts use OpenZeppelin Initializable semantics: there is no constructor state on the implementation; a single correct initialize(...) (or your productβs chained initializer) must run on the proxy (or minimal proxy). Treat initialization as part of deployment: the address end users call should not appear as a public, uninitialized proxy across block boundariesβwire initialize in the same transaction that creates the proxy (factory, proxy constructor _data, or equivalent), then rely on ownership, RBAC, and guards.
1. Recommended: factory / cloner pattern
To avoid βforgot to call initializeβ or wrong ordering when spinning up many instances, prefer a factory that creates the proxy and calls initialize in the same transaction. The repo includes CopyBlox as a reference pattern (contracts/examples/applications/CopyBlox/CopyBlox.sol):
Validates the implementation implements
IBaseStateMachine.Clones.clone(EIPβ1167) thencallsinitialize(address,address,address,uint256,address)on the new clone.If initialization reverts, the whole transaction revertsβyou do not end up with a live, uninitialized clone from that path.
Use the same initializer arity and argument order your concrete contract exposes (often the same five parameters as CopyBlox / BaseStateMachine).
2. Proxy deploy runbook (atomic initialize)
If you deploy transparent / UUPS / ERCβ1967βstyle proxies yourself, you still must avoid a live, public proxy that is uninitialized between transactions. Prefer one atomic transaction that both creates the proxy and runs initializeβfor example:
OpenZeppelin proxy constructors that accept
_data: supply ABIβencodedinitialize(...)calldata so the proxyβs constructor performs the initializer delegatecall before the deployment transaction ends.A proxy factory (or deployer helper) whose single entrypoint
deploys the proxy andcallsinitializeon the new address in the same transaction (any revert aborts the whole deploy; no orphan uninitialized proxy from that path).
Explicit runbook:
Deploy implementation (never call userβfacing
initializeon the implementation in production unless you mean to brick or document a patternβfollow OZ guidance).Create the proxy using a pattern where
initializeruns in the same transaction as proxy creation, with owner, broadcaster, recovery, timelock, andeventForwarder(match your concrete contractβs arity and order). Do not rely on a followβup transaction to initialize a proxy that is already callable at its deployed address.Only after that atomic creation+initialization transaction succeeds, run smokeβreads on the proxy:
owner(),getRecovery(),getTimeLockPeriodSec(), and verifyeventForwardermatches your intentβbefore funding, granting roles, or sending production traffic.
More detail: Best Practices β Deployment (initializer subsection under Deployment) and Account Pattern.
π Security Basics
Keep these minimum practices in your integration:
For a full set of recommendations, see Best Practices.
π§ͺ Protocol development (internal test chain)
The repo includes internal scripts for running sanity tests against a local JSON-RPC node (often called remote_evm in deployed-addresses.json). This is not part of the published protocol surface integrators should rely on.
For protocol maintainers only:
Copy
env.exampleto.env(or runnpm run generate:sanity-env -- --out .envafter an internal deploy).Deploy the internal test stack:
npm run deploy:remote-evm:testRun Foundry:
npm run test:foundry; optional SDK sanity:npm run test:sanity-sdk:core
Integrators should use public testnets (e.g. sepolia) and addresses from deployed-addresses.json with the SDK β not hard-coded role or wallet profiles from sanity tooling.
π Next Steps
Learn more about the Account Pattern and how it composes the core components.
Explore componentβlevel docs:
Dive into architecture:
Look at endβtoβend flows in Basic Examples.
For detailed API signatures, see the API Reference.
Last updated
Was this helpful?