Quickstart
Run the worker and API, create a key, and sync your first wallet.
This guide syncs a real wallet against mainnet, and takes about 15 minutes.
Requirements
- Node 24 and pnpm 10
- Docker, for Postgres
- A Solana RPC endpoint with archival history. Public mainnet works but is slow; a provider key is recommended.
Steps
Install and start Postgres
git clone <your corpact checkout> && cd corpact
pnpm install
cp .env.example .env # set SOLANA_RPC_URL
docker compose up -d # Postgres on 127.0.0.1:54329
Prepare the ledger
cd apps/worker
pnpm cli migrate
pnpm cli sync-registry # verify mints on chain
pnpm cli import-issuer-actions # actions from fixtures
pnpm start # job queue + mint polling
Create a tenant and an API key
cd apps/api
pnpm tenants create demo "My integration"
pnpm keys create backend --tenant demo \
--scopes assets:read,ledger:read,wallets:sync
PORT=4600 pnpm start
The key is printed once. Only its SHA-256 is stored.
Sync a wallet
Registering a wallet adds it to your tenant and queues a historical sync.
export CORPACT_API_KEY=cpk_…
curl -s -X POST http://127.0.0.1:4600/v1/wallets/sync \
-H "authorization: Bearer $CORPACT_API_KEY" \
-H 'content-type: application/json' \
-d '{"owner":"6kn8Vj9YkvNLo8peW2fzebQdSLtX33A3TkRJwXqMCy1U"}'
import { createCorpactClient } from '@corpact/client';
const corpact = createCorpactClient({ baseUrl: 'http://127.0.0.1:4600', apiKey: process.env.CORPACT_API_KEY });
await corpact.requestSync('6kn8Vj9YkvNLo8peW2fzebQdSLtX33A3TkRJwXqMCy1U');
{ "owner": "6kn8Vj9YkvNLo8peW2fzebQdSLtX33A3TkRJwXqMCy1U", "registration": "registered", "status": "queued", "job": "enqueued" }
A first sync replays the wallet's whole archival history, so it can take several minutes. Poll its status until it reads complete or partial:
curl -s http://127.0.0.1:4600/v1/wallets/6kn8Vj9YkvNLo8peW2fzebQdSLtX33A3TkRJwXqMCy1U/status \
-H "authorization: Bearer $CORPACT_API_KEY"
Read the ledger
const { actions } = await corpact.v2.actions(wallet);
for (const a of actions) {
console.log(a.type, a.treatment, a.quantityDisplay, a.usd ?? 'USD unknown', a.lifecycle.state);
}
const portfolio = await corpact.portfolio(wallet);
const { entries } = await corpact.income(wallet);
for (const p of portfolio.positions) {
console.log(p.symbol, p.status, p.quantity, 'floor', p.protectedQuantity, 'income', p.dividendIncomeUsd);
}
curl -s "http://127.0.0.1:4600/v2/actions?owner=$WALLET" \
-H "authorization: Bearer $CORPACT_API_KEY"