> For the complete documentation index, see [llms.txt](https://docs.bloxchain.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bloxchain.app/get-started/developer-quickstart.md).

# Developer quickstart

Read a smart account and submit a governed request from TypeScript with `@bloxchain/sdk`.

**Where:** your own project · **You need:** Node.js 18+, a Sepolia RPC endpoint, a funded key that holds a role on an existing smart account

Deploy the account first from the [Platform quickstart](/get-started/quickstart.md), or with your own script as described in [Deployment](/developers/deployment.md). The SDK talks to the same contract; the rules you configured there apply unchanged here.

## 1. Install

Install `@bloxchain/sdk`, `@bloxchain/contracts` and `viem` as shown in [SDK setup and authentication](/developers/sdk-setup.md#install). `viem` is a peer dependency. Pin the two Bloxchain packages to the same Protocol release as the contracts you talk to. See [Releases](/resources/releases.md).

## 2. Environment

Never hardcode a private key. Put these in `.env` (and in `.gitignore`):

```bash
RPC_URL=https://sepolia.example-rpc.org      # your Sepolia RPC endpoint
PRIVATE_KEY=0x...                            # a key that holds a role on the account
ACCOUNT_ADDRESS=0x...                        # the smart account (from Account details)
```

## 3. Create clients

Build a viem `publicClient` and `walletClient` from `RPC_URL` and `PRIVATE_KEY` exactly as shown in [SDK setup and authentication](/developers/sdk-setup.md#public-client-versus-wallet-client). The public client reads; the wallet client signs and sends. For a read-only integration you can omit the wallet client and pass `undefined` to the SDK constructors.

The snippets below call the signing account `signer` and expect `publicClient` and `walletClient` in scope.

## 4. Read the account

A smart account combines three components behind one address. Each has an SDK wrapper, and all three point at the same `ACCOUNT_ADDRESS`.

```typescript
import { SecureOwnable, RuntimeRBAC, GuardController } from '@bloxchain/sdk';

const accountAddress = process.env.ACCOUNT_ADDRESS as `0x${string}`;

const secureOwnable   = new SecureOwnable(publicClient, walletClient, accountAddress, sepolia);
const runtimeRBAC     = new RuntimeRBAC(publicClient, walletClient, accountAddress, sepolia);
const guardController = new GuardController(publicClient, walletClient, accountAddress, sepolia);

const owner       = await secureOwnable.owner();
const recovery    = await secureOwnable.getRecovery();
const broadcasters = await secureOwnable.getBroadcasters();
const timeLockSec = await secureOwnable.getTimeLockPeriodSec();

console.log({ owner, recovery, broadcasters, timeLockSec });

const myRoles = await runtimeRBAC.getWalletRoles(signer.address);
console.log('Roles held by this key:', myRoles);
```

`getTimeLockPeriodSec()` returns the wait in seconds as a `bigint`. `getWalletRoles()` is the SDK equivalent of the **My access** page.

## 5. Submit a governed request

Requests go through the same lifecycle the Platform shows: request, wait, approve, execute, record. On the delayed path that is two calls, separated by the time lock.

```typescript
// 1) Request: post a time-locked call to an allowlisted target.
const request = await guardController.executeWithTimeLock(
  targetAddress,        // must be on the account's allowlist
  0n,                   // native value to send
  functionSelector,     // e.g. '0xa9059cbb' for transfer(address,uint256)
  encodedParams,        // ABI-encoded arguments
  300_000n,             // gas limit for the inner call
  operationType,        // operation type registered for this action
  { from: signer.address },
);
await publicClient.waitForTransactionReceipt({ hash: request.hash });

// 2) After the time lock: an approver approves, which executes.
const approval = await guardController.approveTimeLockExecution(txId, {
  from: signer.address,
});
await publicClient.waitForTransactionReceipt({ hash: approval.hash });
```

The contract enforces every rule on both calls: the requester's role must be permitted at the **Request** step, the target must be allowlisted, the time lock must have elapsed, and the approver's role must be permitted at the **Approval** step. If any check fails the transaction reverts, exactly as it would from the Platform.

The signed paths (**Signed approval** and **One signature**) use EIP-712 meta-transactions that a broadcaster submits; they follow the same pattern with `requestAndApproveExecution`. See [Meta-transactions](/protocol-reference/api-reference/meta-transactions.md).

## Where to look next

| Need                                                                         | Page                                                                                                                                            |
| ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Client configuration, keys and environment patterns                          | [SDK setup and authentication](/developers/sdk-setup.md)                                                                                        |
| Request, approve, cancel and meta-transaction patterns, with worked examples | [SDK core patterns](/developers/sdk-setup/sdk-core-patterns.md)                                                                                 |
| Exact constructor and method signatures                                      | [API reference](/protocol-reference/api-reference.md)                                                                                           |
| Full setup, including definition library addresses                           | [Protocol getting started](/protocol-reference/getting-started.md)                                                                              |
| Registering actions, allowlists and gates from code                          | [Guard controller](/protocol-reference/api-reference/guard-controller.md) and [Runtime RBAC](/protocol-reference/api-reference/runtime-rbac.md) |
| Choosing between the Platform, the SDK and the Protocol                      | [Integration surfaces](/developers/integration-surfaces.md)                                                                                     |
| A checklist before real value moves                                          | [Production readiness](/developers/deployment/production-readiness.md)                                                                          |
| Giving an AI agent the context to draft a request you approve                | [For AI agents](/developers/for-ai-agents.md)                                                                                                   |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.bloxchain.app/get-started/developer-quickstart.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
