Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ Agent / CLI / App
| `ows key create` | Create an API key for agent access |
| `ows key list` | List all API keys |
| `ows key revoke` | Revoke an API key |
| `ows rpc add` | Add RPC endpoint(s) to a profile |
| `ows rpc list` | List all RPC profiles |
| `ows rpc show` | Show active or named profile |
| `ows rpc use` | Set the active RPC profile |
| `ows rpc remove` | Delete an RPC profile |
| `ows rpc clear` | Clear the active profile |
| `ows update` | Update ows and bindings |
| `ows uninstall` | Remove ows from the system |

Expand Down
48 changes: 48 additions & 0 deletions docs/01-storage-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,54 @@ Each wallet is stored as a single JSON file extending the Ethereum Keystore v3 s
| `key_type` | string | yes | `mnemonic` (BIP-39) or `private_key` (raw) |
| `metadata` | object | no | Extensible metadata |

## Config File Format

The `~/.ows/config.json` file stores global configuration including RPC endpoint profiles.

```json
{
"vault_path": "~/.ows",
"rpc": {
"eip155:1": "https://eth.llamarpc.com",
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": "https://api.mainnet-beta.solana.com"
},
"rpc_config": {
"activeProfile": "team-dev",
"profiles": {
"team-dev": {
"chains": {
"eip155:1": { "url": "https://dev-eth.example.com" },
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": { "url": "https://dev-sol.example.com" }
}
},
"mainnet-evm": {
"chains": {
"eip155:1": { "url": "https://mainnet-eth.example.com" }
}
}
}
}
}
```

### Field Definitions

| Field | Type | Required | Description |
|---|---|---|---|
| `vault_path` | string | yes | Path to the vault directory |
| `rpc` | object | yes | Global RPC endpoints (chain_id → URL). These are the fallback endpoints used when no profile is active. |
| `rpc_config` | object | no | Structured RPC profile configuration |
| `rpc_config.activeProfile` | string | no | Name of the currently active RPC profile |
| `rpc_config.profiles` | object | no | Named profiles, each containing chain-specific endpoint overrides |

The `rpc` field uses chain identifiers like `eip155:1` (Ethereum mainnet), `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` (Solana mainnet), or friendly aliases like `evm` or `solana`.

When resolving RPC endpoints, the following precedence applies:
1. Explicit `--rpc-url` argument (if supported by the command)
2. Active profile endpoint for the requested chain
3. Global `rpc` endpoints
4. Built-in defaults

## API Key File Format

Each API key is stored as a JSON file in `~/.ows/keys/`. The key file contains metadata, policy attachments, and **encrypted copies of wallet secrets** re-encrypted under the API token (see [Policy Engine](03-policy-engine) for the full cryptographic design).
Expand Down
28 changes: 28 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,34 @@ ows sign message --wallet agent-treasury --chain evm --message "hello"
ows sign tx --wallet agent-treasury --chain solana --tx "deadbeef..."
```

## Configure RPC endpoints

By default, OWS uses built-in public RPC endpoints. For production or team workflows, you can configure custom endpoints via RPC profiles.

```bash
# Add a custom endpoint to a named profile
ows rpc add --name team-dev --chain evm --url https://dev-eth.example.com

# Add multiple chains to the same profile
ows rpc add --name team-dev \
--chain evm --url https://dev-eth.example.com \
--chain solana --url https://dev-sol.example.com

# List configured profiles
ows rpc list

# Activate a profile (signing will use endpoints from this profile)
ows rpc use --name team-dev

# Show the active profile
ows rpc show

# Clear the active profile (revert to global/default endpoints)
ows rpc clear
```

When a profile is active, its endpoints take precedence over built-in defaults when signing or broadcasting transactions. The `--rpc-url` argument (supported by some commands) overrides everything.

## Use in code

### Node.js
Expand Down
76 changes: 76 additions & 0 deletions docs/sdk-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,82 @@ ows fund balance --wallet "my-wallet" --chain base
| `--wallet <NAME>` | Wallet name (required) |
| `--chain <CHAIN>` | Chain to query (required) |

## RPC Profile Commands

### `ows rpc add`

Add or update RPC endpoint(s) in a named profile. Profiles allow you to manage chain-specific endpoint sets (e.g., dev/staging/prod environments or chain-specific endpoint collections).

```bash
# Add EVM mainnet endpoint to a profile
ows rpc add --name mainnet-evm --chain eip155:1 --url https://eth.example.com

# Add multiple chains to the same profile (repeat --chain and --url pairs)
ows rpc add --name team-dev \
--chain eip155:1 --url https://dev-eth.example.com \
--chain solana --url https://dev-solana.example.com
```

| Flag | Description |
|------|-------------|
| `--name <NAME>` | Profile name (required) |
| `--chain <CHAIN>` | Chain identifier (repeat for multiple pairs) |
| `--url <URL>` | RPC endpoint URL (must match --chain order) |

### `ows rpc list`

List all configured RPC profiles and their endpoints.

```bash
ows rpc list
```

### `ows rpc show`

Show the active profile and its endpoints, or a specific named profile.

```bash
ows rpc show # show active profile
ows rpc show --name team-dev # show specific profile
```

| Flag | Description |
|------|-------------|
| `--name <NAME>` | Profile name (optional, defaults to active) |

### `ows rpc use`

Set the active RPC profile. When a profile is active, its endpoints take precedence over global RPC settings when resolving endpoints for signing operations.

```bash
ows rpc use --name team-dev
```

### `ows rpc remove`

Remove (delete) an entire RPC profile. If the removed profile was active, the active profile is cleared.

```bash
ows rpc remove --name team-dev
```

### `ows rpc clear`

Clear the active profile (use global/default endpoints only).

```bash
ows rpc clear
```

### RPC Resolution Precedence

When resolving RPC endpoints for signing and broadcasting transactions, the following precedence applies:

1. **Explicit `--rpc-url` argument** (highest priority, if supported by the command)
2. **Active profile endpoint** (if a profile is active and contains the chain)
3. **Global RPC config** (`~/.ows/config.json` `rpc` field)
4. **Built-in defaults** (lowest priority)

## System Commands

### `ows update`
Expand Down
36 changes: 35 additions & 1 deletion ows/crates/ows-cli/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,25 @@ pub fn show() -> Result<(), CliError> {
);
}

// Show active profile
println!();
println!("RPC endpoints:");
println!(
"Active profile: {}",
config.active_profile().unwrap_or("(none)")
);

// Show active profile endpoints if one is set
if let Some(profile_name) = config.active_profile() {
if let Some(profile) = config.profile(profile_name) {
println!("Profile endpoints ({}):", profile_name);
for (chain, url) in profile.endpoints() {
println!(" {:<40} {}", chain, url);
}
}
}

println!();
println!("Global RPC endpoints (fallback / when no profile is active):");
Comment thread
cursor[bot] marked this conversation as resolved.

let mut keys: Vec<&String> = config.rpc.keys().collect();
keys.sort();
Expand All @@ -37,5 +54,22 @@ pub fn show() -> Result<(), CliError> {
println!(" {:<40} {} {}", key, url, annotation);
}

// Show available profiles
let profile_count = config.profile_names().count();
if profile_count > 0 {
println!();
println!("Available profiles ({}):", profile_count);
for name in config.profile_names() {
let marker = if config.active_profile() == Some(name) {
" (active)"
} else {
""
};
if let Some(profile) = config.profile(name) {
println!(" {}{} ({} chains)", name, marker, profile.chains.len());
}
}
}

Ok(())
}
1 change: 1 addition & 0 deletions ows/crates/ows-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod info;
pub mod key;
pub mod pay;
pub mod policy;
pub mod rpc;
pub mod send_transaction;
pub mod sign_message;
pub mod sign_transaction;
Expand Down
Loading