Running
Prerequisites
- node.js >= 22.0.0
- yarn >= 1.22.0 (can be installed using
sudo npm i -g yarn
) - docker >= 20.0.0
Installing CLI utility
npm i --global @cambrianone/camb-client@latest
Cambrian CLI utility
AVS management
camb avs run [-d, --detach] [-v, --verbose] [-u, --update]
- run AVScamb avs stop
- stop AVScamb avs list
- list AVS instances
Operator node management
camb operator list -a <AVS public key>
- list operator nodescamb operator run [-d, --detach] [-v, --verbose] [-u, --update] <operator public key>
- run operator nodecamb operator stop <operator public key>
- stop operator nodecamb operator info [<operator public key>]
- get operator node(s) info
Running payload
camb payload run-container -a <AVS public key | AVS URL> [-p period in seconds] <payload container image>
- Run payload from container for the given AVS
Project scaffolding
camb init -t AVS <output directory>
- scaffold AVS projectcamb init -t operator <output directory>
- scaffold operator project
Management
camb manage poa get-state -a <AVS public key>
- get PoA statecamb manage poa init -a <AVS public key>
- initialize PoAcamb manage poa set-threshold -a <AVS public key> threshold
- update threshold in PoAcamb manage add-external -n <service name> -p <path to AVS/operator directory> -i <external service container image> [-e <NAME1=VALUE1...>]
- add external service to run with existing AVS/operator
Flow
- Scaffold AVS:
camb proposal init -t AVS <output directory>
- Run AVS:
camb avs run -u -v <AVS public key>
- List registered operators:
camb operator list -a <AVS public key>
- Build oracle update image:
git clone https://github.com/cambrianone/oracle-update-examples && docker build -t oracle-update-current-date ./oracle-update-examples/current-date/container-stream
- Build payload image:
git clone https://github.com/cambrianone/payload-images && docker build -t payload-check-oracle ./payload-images/check-oracle
- Scaffold operator(s) and choose
container-stream
as oracle update method and setoracle-update-current-date
as oracle update container image:camb proposal init -t operator <output directory>
, you can find an admin private key in~/.cambrian/config.toml
- Run operator(s):
camb operator run -a <AVS public key> -v <voter public key>
- Run payload:
camb payload run-container -a <AVS public key | AVS URL> payload-check-oracle
Updating oracle
There are 4 ways of updating oracle data:
- Streaming container (
container-stream
option while scaffolding operator) - container periodically writes string data to stdout, operator stores this chunks of data on-chain - Running container (
container-run
option while scaffolding operator) - operator starts container with periods specified by a cron spec. Container should write some string data into stdout and then it exits with code 0. Operator stores this data on-chain. - [DEPRECATED] Running typescript/javascript code (
file-run
option while scaffolding operator) - operator should execute a code from the given file with periods specified by a cron spec. This code should write some string data into stdout and then child process exits with code 0. Operator stores this data on-chain. - [DEPRECATED] Streaming typescript/javascript code (Not implemented yet).
Running payload
There are two ways of executing payload:
- From a container (recommended way, using
camb payload run-container
command) - From a typescript/javascript code (deprecated way, using
camb payload run-file
)
Container receives a parameter serialized as JSON-object. It's type is:
type TPayloadInput = {
executorPDA: string;
apiUrl: string;
extraSigners: Array<string>;
}
extraSigners
represents an optional array of serialized private keys used for signing transaction.
Container should write a JSON-stringified object. It's type is:
type TPayloadOutput = {
proposalInstructions: Array<{
accounts: Array<{
address: string;
role: 0 | 1 | 2 | 3
}>,
data: string;
programmAddress: string;
}>;
}
where data
is base58-serialized data buffer and role
is the following enum:
enum AccountRole {
// Bitflag guide: is signer ⌄⌄ is writable
WRITABLE_SIGNER = /* 3 */ 0b11,
READONLY_SIGNER = /* 2 */ 0b10,
WRITABLE = /* 1 */ 0b01,
READONLY = /* 0 */ 0b00,
}
Running in development mode
Start
yarn set version berry
yarn config set nodeLinker node-modules
yarn config set enableGlobalCache false
yarn workspaces foreach -A install
yarn build:packages
LOG_LEVEL=debug docker compose -f docker/docker-compose.yml up
Usage
curl -v -kisL http://localhost:3000/upload -F "file=@./services/camb-operator/src/test/payload-demo.ts"
Configuration
Environment variables
camb-operator
Name | Description | Default value | ||
---|---|---|---|---|
WS_URL |
AVS WebSocket URL | ws://localhost:3001/ |
||
WALLET_KEY |
Wallet private key as an array of integers | |||
OPERATOR_KEY |
Operator private key as an array of integers | |||
API_URL |
Solana RPC URL | https://devnet.helius-rpc.com/?api-key=e3278038-4bfb-4b21-bb4c-c6203303cc70 |