# Accumulate Python SDK — Full API Digest

Package `accumulate-sdk-opendlt` v2.3.0 (source commit 8fd15ac). Generated from the Accumulate SDK manifest (single source of truth).

## Install & import
```
pip install accumulate-sdk-opendlt
```
`from accumulate_client import Accumulate, TxBody, SmartSigner, QuickStart`

## Conventions (read first)
- Networks: Kermit testnet (used by the examples; fund via faucet), plus mainnet and local devnet.
- Amounts: ACME is denominated in base units where 1 ACME = 1e8 base units. Passing whole ACME as-is is the single most common integration bug.
- Credits: buying credits uses the network oracle price; an ADI/key page must hold credits before it can sign transactions.
- Custom tokens: each declares its own precision at creation (not 1e8). Amounts on the wire are always base units, so issuing 1000 against a precision-8 token mints 0.00001 tokens. Use the SDK amount helper to convert whole tokens to base units.
- Golden path: connect -> build a body with TxBody.<op>(...) -> sign+submit+wait with SmartSigner -> query to confirm.

## Entry points
- **Accumulate** (class, `accumulate_client`) — Main client facade with factory methods for network connection
- **TxBody** (class, `accumulate_client.convenience`) — Static methods that build transaction body objects
- **SmartSigner** (class, `accumulate_client.convenience`) — Signs, submits, and waits for transaction results
- **Ed25519KeyPair** (class, `accumulate_client.crypto.ed25519`) — Ed25519 key pair generation and derivation

## Error catalog (v1.0)

Branch on `code`. **`retryable` decides whether a retry is productive** — retrying a
validation or auth error only burns turns; the condition will not change on its own.

```
from accumulate_client.runtime.errors import AccumulateError, ErrorCode
except AccumulateError as e:
    e.code            # ErrorCode IntEnum
```

### `ACC_ACCOUNT_NOT_FOUND`
The account URL does not exist on this network.

- category: `not_found` · wire -33404
- retryable: **no**
- Python type: `AccountNotFoundError`
- fix: Verify the URL and the network. If you just created the account, wait for its creating transaction to reach 'delivered' first — use wait_for_balance / wait_for_credits rather than querying straight away.

### `ACC_UNAUTHORIZED_SIGNER`
The signing key is not on the key page that authorizes this principal.

- category: `auth` · wire 403
- retryable: **no**
- Python type: `AccumulateError`
- fix: Sign with a key that is on the principal's authorizing key page. After create_identity, ADI-owned principals are signed by `<adi>/book/1`. A key page owned by a second book (e.g. `multisig-book/1`) must be signed by that page's OWN book — Accumulate requires every authority to approve.

### `ACC_INSUFFICIENT_CREDITS`
The signing key page does not hold enough credits to pay for this transaction.

- category: `insufficient_credits`
- retryable: **no**
- Python type: `InsufficientCreditsError`
- fix: Call add_credits for the SIGNING key page, then wait_for_credits on that same page before retrying. Credits are separate from token balance — an account can hold ACME and still be unable to sign. Note add_credits itself must be signed by an account that already has credits (typically the funded lite identity).

### `ACC_NOT_SIGNED`
The envelope reached the network without a valid signature over the transaction body.

- category: `auth`
- retryable: **no**
- Python type: `MissingSignatureError`
- fix: Build and sign through the canonical path — TxBody to construct, SmartSigner to sign and submit. Do not hand-roll envelopes. If you are working ON an SDK and see this for one specific transaction type, its marshaler is missing or its type code is wrong.

### `ACC_ALREADY_EXISTS`
The account or identity being created already exists on chain.

- category: `conflict`
- retryable: **no**
- Python type: `AccumulateError`
- fix: Query the URL first — if it exists and you own it, skip creation and continue. For repeatable scripts, derive a unique URL (e.g. a timestamp suffix) rather than a fixed name.

### `ACC_INVALID_PRINCIPAL`
The principal URL is not a valid target for this transaction type.

- category: `validation`
- retryable: **no**
- Python type: `ValidationError`
- fix: Match the principal to the transaction type. Token transfers use the token account URL (`<lite>/ACME`), credit purchases and key operations use the identity or key page URL.

### `ACC_INSUFFICIENT_BALANCE`
The source account does not hold enough tokens for this transfer.

- category: `insufficient_balance`
- retryable: **no**
- Python type: `InsufficientBalanceError`
- fix: Confirm the balance with wait_for_balance before transferring. Build amounts with the Amount helper — 1 ACME = 1e8 base units, and custom tokens carry their OWN precision set at creation.

### `ACC_TX_PENDING`
The transaction was accepted but is not final — it is awaiting additional signatures.

- category: `pending`
- retryable: **yes**
- Python type: `AccumulateError`
- fix: This is not a failure. Collect the remaining signatures up to the page threshold, then poll status until 'delivered'. Treating 'pending' as success is the common multisig bug; so is treating it as a hard error.

### `ACC_TX_NOT_SETTLED`
The transaction was submitted and accepted, but did not reach a final state before the wait timed out.

- category: `pending`
- retryable: **yes**
- Python type: `AccumulateError`
- fix: Do NOT resubmit — a resubmit risks a duplicate or an ACC_ALREADY_EXISTS. Keep polling the transaction status until 'delivered', with a longer timeout. Synthetic deposits (faucet, cross-account transfers) routinely need more time than a single block.

### `ACC_INVALID_URL`
The string is not a well-formed Accumulate URL.

- category: `validation` · wire 1002
- retryable: **no**
- Python type: `ValidationError`
- fix: Accumulate URLs are `acc://<authority>[/<path>]`. Lite token accounts end in the token symbol, e.g. `acc://<keyhash>/ACME`.

### `ACC_INVALID_PARAMS`
The JSON-RPC parameters were rejected by the node.

- category: `validation` · wire -32602
- retryable: **no**
- Python type: `ValidationError`
- fix: Check the operation's declared inputs in llms-full.txt. Hashes are 32-byte hex; amounts are base-unit integers, not decimals.

### `ACC_METHOD_NOT_FOUND`
The node does not expose the RPC method that was called.

- category: `validation` · wire -32601
- retryable: **no**
- Python type: `AccumulateError`
- fix: Use the SDK's canonical client rather than raw RPC — it targets the correct API version for the endpoint.

### `ACC_NETWORK_UNAVAILABLE`
The endpoint could not be reached, or the request timed out.

- category: `network`
- retryable: **yes**
- Python type: `NetworkError`
- fix: Retry with exponential backoff. This is the ONLY class of error where a bare retry is productive — retrying a validation or auth error just burns turns.

### `ACC_INTERNAL`
The node reported an internal error.

- category: `internal` · wire -32603
- retryable: **yes**
- Python type: `AccumulateError`
- fix: Retry once with backoff. If it persists, the request is likely malformed in a way the node did not classify — re-check the transaction body against llms-full.txt.

## Operations (24)

### generate_keys  —  Generate Keys  [utility]
Symbols:
  - `Ed25519KeyPair.generate` — `() -> Ed25519KeyPair`
  - `Ed25519KeyPair.derive_lite_identity_url` — `(self) -> str`
  - `Ed25519KeyPair.derive_lite_token_account_url` — `(self, token: str) -> str`
  - `Ed25519KeyPair.public_key_bytes` — `(self) -> bytes`
Outputs:
  - `keypair` (Ed25519KeyPair)
  - `liteIdentity` (str)
  - `liteTokenAccount` (str)
  - `publicKeyHash` (str)
Errors: ACC_NETWORK_UNAVAILABLE
Examples: examples/generate_keys.py

### faucet  —  Faucet  [utility]
Symbols:
  - `Accumulate.faucet` — `(self, account: str) -> dict`
Inputs:
  - `account` (str, required) — Lite token account URL to fund
  - `times` (int, optional) — Number of faucet calls [e.g. 1]
Requires: keypair
Errors: ACC_INSUFFICIENT_BALANCE, ACC_NETWORK_UNAVAILABLE, ACC_TX_NOT_SETTLED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/faucet.py

### wait_for_balance  —  Wait For Balance  [utility]
Symbols:
  - `Accumulate.v3.query` — `(self, url: str) -> dict`
Inputs:
  - `account` (str, required) — Account URL to poll
  - `minBalance` (str, required) — Minimum balance to wait for
Outputs:
  - `balance` (str)
Requires: keypair
Errors: ACC_ACCOUNT_NOT_FOUND, ACC_INSUFFICIENT_BALANCE, ACC_NETWORK_UNAVAILABLE, ACC_TX_NOT_SETTLED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/wait_for_balance.py

### wait_for_credits  —  Wait For Credits  [utility]
Symbols:
  - `Accumulate.v3.query` — `(self, url: str) -> dict`
Inputs:
  - `account` (str, required) — Key page URL to poll
  - `minCredits` (int, required) — Minimum credit balance to wait for
Outputs:
  - `credits` (int)
Requires: keypair
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_TX_NOT_SETTLED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/wait_for_credits.py

### add_credits  —  Add Credits  [credits]
Symbols:
  - `TxBody.add_credits` — `(recipient: str, amount: str, oracle: int) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `recipient` (str, required) — Key page URL to credit
  - `amount` (str, required) — ACME amount to spend
  - `oracle` (int, required) — Oracle price (fetched at runtime)
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_ACCOUNT_NOT_FOUND, ACC_INSUFFICIENT_CREDITS, ACC_INVALID_PRINCIPAL, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/add_credits.py

### transfer_credits  —  Transfer Credits  [credits]
Symbols:
  - `TxBody.transfer_credits` — `(recipient: str, amount: int) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `recipient` (str, required) — Destination key page
  - `amount` (int, required) — Credits to transfer
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_NOT_SIGNED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/transfer_credits.py

### burn_credits  —  Burn Credits  [credits]
Symbols:
  - `TxBody.burn_credits` — `(amount: int) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `amount` (int, required) — Credits to burn
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/burn_credits.py

### create_identity  —  Create Identity  [identity]
Symbols:
  - `TxBody.create_identity` — `(url: str, key_book_url: str, public_key_hash: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — ADI URL
  - `keyBookUrl` (str, required) — Key book URL
  - `publicKeyHash` (str, required) — SHA256 hash of public key
Outputs:
  - `adiUrl` (str)
  - `keyBookUrl` (str)
  - `keyPageUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_INVALID_URL, ACC_NETWORK_UNAVAILABLE, ACC_TX_NOT_SETTLED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_identity.py

### create_key_book  —  Create Key Book  [identity]
Symbols:
  - `TxBody.create_key_book` — `(url: str, public_key_hash: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — Key book URL
  - `publicKeyHash` (str, optional) — Initial key hash
Outputs:
  - `keyBookUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_NOT_SIGNED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_key_book.py

### create_key_page  —  Create Key Page  [identity]
Symbols:
  - `TxBody.create_key_page` — `(url: str, keys: list[str]) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — Key page URL
  - `keys` (list[str], required) — Initial key hashes
Outputs:
  - `keyPageUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_key_page.py

### create_token_account  —  Create Token Account  [account]
Symbols:
  - `TxBody.create_token_account` — `(url: str, token_url: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — Token account URL
  - `tokenUrl` (str, required) — Token type URL
Outputs:
  - `tokenAccountUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_token_account.py

### create_data_account  —  Create Data Account  [account]
Symbols:
  - `TxBody.create_data_account` — `(url: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — Data account URL
Outputs:
  - `dataAccountUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_data_account.py

### create_token  —  Create Token  [account]
Symbols:
  - `TxBody.create_token` — `(url: str, symbol: str, precision: int, supply_limit: str | None) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `url` (str, required) — Token URL
  - `symbol` (str, required) — Token symbol
  - `precision` (int, required) — Decimal precision
  - `supplyLimit` (str, optional) — Maximum supply
Outputs:
  - `tokenUrl` (str)
Requires: keypair, credits
Errors: ACC_ALREADY_EXISTS, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_token.py

### create_lite_token_account  —  Create Lite Token Account  [account]
Symbols:
  - `Ed25519KeyPair.derive_lite_token_account_url` — `(self, token: str) -> str`
Outputs:
  - `liteTokenAccountUrl` (str)
Requires: keypair
Errors: ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/create_lite_token_account.py

### send_tokens  —  Send Tokens  [transaction]
Symbols:
  - `TxBody.send_tokens_single` — `(to_url: str, amount: str) -> dict`
  - `TxBody.send_tokens` — `(recipients: list[tuple[str, str]]) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `recipients` (list[tuple[str, str]], required) — List of (url, amount) tuples
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_ACCOUNT_NOT_FOUND, ACC_INSUFFICIENT_BALANCE, ACC_INSUFFICIENT_CREDITS, ACC_INVALID_PRINCIPAL, ACC_INVALID_URL, ACC_NETWORK_UNAVAILABLE, ACC_NOT_SIGNED, ACC_TX_NOT_SETTLED, ACC_TX_PENDING, ACC_UNAUTHORIZED_SIGNER
Examples: examples/send_tokens.py

### issue_tokens  —  Issue Tokens  [transaction]
Symbols:
  - `TxBody.issue_tokens` — `(recipient: str, amount: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `recipient` (str, required) — Recipient token account
  - `amount` (str, required) — Amount to issue
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_BALANCE, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/issue_tokens.py

### burn_tokens  —  Burn Tokens  [transaction]
Symbols:
  - `TxBody.burn_tokens` — `(amount: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `amount` (str, required) — Amount to burn
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_BALANCE, ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/burn_tokens.py

### write_data  —  Write Data  [transaction]
Symbols:
  - `TxBody.write_data` — `(data: list[str]) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `entries` (list[str], required) — Hex-encoded data entries
Outputs:
  - `txHash` (str)
  - `entryHash` (str)
Requires: keypair, credits
Errors: ACC_ACCOUNT_NOT_FOUND, ACC_INSUFFICIENT_CREDITS, ACC_INVALID_PARAMS, ACC_INVALID_PRINCIPAL, ACC_NETWORK_UNAVAILABLE, ACC_TX_NOT_SETTLED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/write_data.py

### write_data_to  —  Write Data To  [transaction]
Symbols:
  - `TxBody.write_data_to` — `(recipient: str, data: list[str]) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `recipient` (str, required) — Target data account
  - `entries` (list[str], required) — Hex-encoded data entries
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/write_data_to.py

### query_account  —  Query Account  [query]
Symbols:
  - `Accumulate.v3.query` — `(self, url: str) -> dict`
Inputs:
  - `url` (str, required) — Account URL to query
Outputs:
  - `account` (dict)
Errors: ACC_ACCOUNT_NOT_FOUND, ACC_INVALID_PARAMS, ACC_INVALID_URL, ACC_METHOD_NOT_FOUND, ACC_NETWORK_UNAVAILABLE
Examples: examples/query_account.py

### update_key_page  —  Update Key Page  [authority]
Symbols:
  - `TxBody.update_key_page` — `(operations: list) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `operations` (list, required) — Key page operations (add, remove, setThreshold)
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_INVALID_PRINCIPAL, ACC_NETWORK_UNAVAILABLE, ACC_TX_PENDING, ACC_UNAUTHORIZED_SIGNER
Examples: examples/update_key_page.py

### update_key  —  Update Key  [authority]
Symbols:
  - `TxBody.update_key` — `(new_key: str) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `newKey` (str, required) — New public key hash
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_NOT_SIGNED, ACC_UNAUTHORIZED_SIGNER
Examples: examples/update_key.py

### lock_account  —  Lock Account  [authority]
Symbols:
  - `TxBody.lock_account` — `(height: int) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `height` (int, required) — Block height to lock until
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_UNAUTHORIZED_SIGNER
Examples: examples/lock_account.py

### update_account_auth  —  Update Account Auth  [authority]
Symbols:
  - `TxBody.update_account_auth` — `(operations: list) -> dict`
  - `SmartSigner.sign_submit_and_wait` — `(self, principal: str, body: dict) -> dict`
Inputs:
  - `operations` (list, required) — Auth operations (enable, disable, add, remove)
Outputs:
  - `txHash` (str)
Requires: keypair, credits
Errors: ACC_INSUFFICIENT_CREDITS, ACC_NETWORK_UNAVAILABLE, ACC_TX_PENDING, ACC_UNAUTHORIZED_SIGNER
Examples: examples/update_account_auth.py
