For the complete documentation index, see llms.txt. This page is also available as Markdown.

Core patterns

Read state, drive the three execution paths, interpret statuses and handle errors with @bloxchain/sdk.

You need: SDK setup complete, an account address on Sepolia

Read state

Use a PublicClient and the read methods of each wrapper. All wrappers point at the same account address.

Question
Call

Who owns the account, who can recover it, who may broadcast

SecureOwnable.owner(), getRecovery(), getBroadcasters()

How long is the time lock

SecureOwnable.getTimeLockPeriodSec()

Which roles exist and who holds them

RuntimeRBAC.getSupportedRoles(), getRole(hash), getWalletRoles(address), hasRole(hash, address)

What an action's schema looks like

RuntimeRBAC.getFunctionSchema(selector)

Which requests are open

BaseStateMachine.getPendingTransactions(), getTransaction(txId)

Details and signatures: API reference.

The three execution paths

The Platform names three execution paths. Each maps to Protocol calls and permission steps.

Platform name
Tab label
Protocol shape
Time lock enforced?
Calls

Delayed release

Delayed

Time-locked request, then on-chain approve

Yes

Request: GuardController.executeWithTimeLock(...). After releaseTime: approveTimeLockExecution(txId). Cancel during the wait is also on chain.

Signed approval

Signed

Request on chain, approval signed off chain, submitted by a broadcaster

No (the signature is the authorisation)

Approver: MetaTransactionSigner.createSignedMetaTransactionForExisting(...). Broadcaster submits the signed approval.

One signature

One sign

Request and approval in one signature, submitted by a broadcaster

No

Requester: MetaTransactionSigner.createUnsignedMetaTransactionForNew(...), sign. Broadcaster: GuardController.requestAndApproveExecution(metaTx).

The nine action steps

Permissions are granted per step, not per path. There are nine steps, and each is a TxAction value in the SDK. Each step belongs to one of three phases: Request, Approval, Execute.

Step

TxAction

Phase

Pending Request

EXECUTE_TIME_DELAY_REQUEST

Request

Approve

EXECUTE_TIME_DELAY_APPROVE

Approval

Cancel

EXECUTE_TIME_DELAY_CANCEL

Approval

Sign and approve request

SIGN_META_REQUEST_AND_APPROVE

Request

Sign approval

SIGN_META_APPROVE

Approval

Sign cancellation

SIGN_META_CANCEL

Approval

Finalize approved request

EXECUTE_META_REQUEST_AND_APPROVE

Execute

Finalize approval

EXECUTE_META_APPROVE

Execute

Finalize cancellation

EXECUTE_META_CANCEL

Execute

A role needs the step for the phase it performs, and the matching gate on the handler selector that carries the step. Granting a step without its gate is the most common reason a correctly assigned wallet still cannot act. To grant either from code, see Configure an account programmatically. See also How governed operations work.

Delayed release

  1. Request. A wallet with request permission calls executeWithTimeLock(target, value, selector, params, gasLimit, operationType, { from }). A record is created with status PENDING and releaseTime = now + timeLockPeriodSec.

  2. Wait. Approving before releaseTime reverts.

  3. Approve. A wallet with approve permission calls approveTimeLockExecution(txId, { from }). The record moves to EXECUTING and the guarded call runs in the same transaction.

  4. Record. The record ends COMPLETED or FAILED. Cancelling a pending record ends it CANCELLED.

Always wait for the receipt before reading state.

Signed approval and One signature

  1. Build the unsigned meta-transaction with MetaTransactionSigner. The contract itself generates the EIP-712 digest, so the signed payload always matches what the chain verifies.

  2. Sign the raw digest, with no EIP-191 wrapper. The contract recovers the signer with a plain ecrecover over the digest itself, so any prefix breaks recovery. Use the signer's signMetaTransactionWithWallet(unsigned) for a browser or hardware wallet, which signs the digest as EIP-712 typed data, or account.sign({ hash: unsigned.message }) when you hold the key in process. Do not reach for viem's signMessage, including its { raw } form: it always prepends \x19Ethereum Signed Message:\n before hashing, which is exactly the prefix the contract cannot accept.

  3. Set a short deadline and use the signer's current nonce (getSignerNonce). Nonces are per signer and sequential, so one signer's meta-transactions must be submitted in order.

  4. A Broadcaster submits the signed payload and pays gas. The handler selector in the payload must match the function actually used to submit.

Signed payloads can also leave your system as a .bloxmeta.json file and be imported into the Platform. See Signed files and Meta-transactions.

Statuses

Protocol statuses on the record: UNDEFINED, PENDING, EXECUTING, COMPLETED, FAILED, CANCELLED, plus PROCESSING_PAYMENT when an attached payment runs. There is no APPROVED status; approval moves a record straight from PENDING to EXECUTING.

The Platform layers user-facing labels on top of these. In Approvals, a PENDING record shows as Awaiting Approval or Awaiting Your Approval, with a State of Blocked while the time lock runs and Ready once it has passed. A signed but unsubmitted payload sits in the Approved tab as Ready to Execute, or Ready to Submit Cancellation for a signed cancellation, and becomes Expired once its deadline passes. While a submission confirms, rows read Submitting, Pending Confirmation, Executing and then Confirmed. Settled records show in History as Executed, Cancelled or Failed. See Approvals and the Glossary.

Errors

  • SDK errors extend BloxchainError (code, details); contract calls raise ContractError (contractAddress, method); bad inputs raise ValidationError.

  • A FAILED record means the guarded call reverted after approval. Read the revert data from the execution transaction.

  • Most reverts before execution are policy denials: missing role, missing gate, target or recipient not on an allowlist, or an approval attempted before releaseTime. Fix the policy, do not retry blindly.

Retries

  • Reads and simulations are safe to retry.

  • For writes, re-simulate after a failure. Re-sending a request creates a second PENDING record, which is rarely what you want.

  • Respect the time lock: poll getTransaction(txId).releaseTime and approve only after it passes.

  • For meta-transactions, a resubmitted payload with a consumed nonce or an expired deadline will revert. Sign a fresh one.

Worked examples

Short snippets verified against the Protocol reference, for a smart account on Sepolia. Install and client setup are covered once in SDK setup and authentication; these snippets assume publicClient, walletClient, account and accountAddress from that page, and RPC_URL, ACCOUNT_ADDRESS and (for writes) PRIVATE_KEY in your environment. Fuller samples: Basic examples and Protocol getting started.

Delayed release: request, wait, approve

A time-locked ownership transfer is the simplest end-to-end delayed request. The requester must be the owner or recovery address; approval is possible only after the time lock.

Delayed release: a guarded call to an allowlisted contract

For registered actions, the request goes through the guard. The target must be on the account's Allowed contracts list for that function.

Signed approval: sign off chain, submit with a broadcaster

The approver signs; a Broadcaster submits and pays gas. Sign the raw digest that the contract produced.

When the key is in process rather than in a wallet, sign the digest directly and attach the signature yourself:

txId is the pending record you are approving; metaTxParams (including the signer's current nonce and a deadline) is described in Meta-transactions. The same signed payload, saved as a .bloxmeta.json file, can be imported into the Platform under Approvals → Import signed file. See Signed files.

Configuration batches

Registering an action, creating a role, granting a gate or adding a destination to an allowlist all travel as signed configuration batches that a Broadcaster submits. The batch shape, a worked allowlist example and the idempotency rules are on Configure an account programmatically.

Wait for and check a transaction

A successful receipt on an approval does not by itself mean the guarded call succeeded. Read the record: COMPLETED means it ran, FAILED means it reverted inside the guard.

Runnable references

The Protocol repository ships SDK sanity suites under scripts/sanity-sdk/ (run with npm run test:sanity-sdk) that exercise SecureOwnable, RuntimeRBAC and GuardController end to end. Browse them at the pinned commit: scripts/sanity-sdk.

Version alignment

@bloxchain/sdk, @bloxchain/contracts and the deployed bytecode must come from the same release. See Releases and compatibility.

Last updated

Was this helpful?