> ## Documentation Index
> Fetch the complete documentation index at: https://molelcule.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Molecule API: Generating and Managing Trading Keys

> Ed25519 trading keys authenticate every signed request. Generate a keypair, register the public key with Molecule, and store the private seed securely.

A trading key is an Ed25519 keypair you generate locally. You register the public key with Molecule, and Molecule uses it to verify that each signed request originated from a process holding the corresponding private key. Ed25519 is used because it produces compact, deterministic 64-byte signatures with strong security properties and fast verification — suitable for the low-latency, high-throughput requirements of trading infrastructure. The private key is never transmitted to Molecule and never stored anywhere outside your own systems.

***

## Key format

The canonical private key format is a **base64-encoded 32-byte Ed25519 seed**. This is the format you should use when storing keys in environment variables, secrets managers, or configuration files.

The SDK also accepts the following alternative representations, all of which resolve to the same 32-byte seed:

| Format | Details |
| - | - |
| **Base64 (canonical)** | Base64 encoding of the 32-byte seed. This is the recommended storage format. |
| **Hex string** | 64-character lowercase hex string of the 32-byte seed. |
| **Raw bytes** | A `bytes` object of exactly 32 bytes. |
| **64-byte blob** | Base64 or `bytes` of the 64-byte `seed \|\| public_key` concatenation — the SDK truncates to the first 32 bytes. |

### Generate a keypair

Use the `nacl` library (installed as a dependency of the `molecule` package) to generate a new keypair and export the seed in canonical format. Register the printed public key hex with Molecule, and store the private seed securely.

```python theme={"dark"}
from nacl.signing import SigningKey
import base64

key = SigningKey.generate()
private_seed_b64 = base64.b64encode(bytes(key)).decode()
public_key_hex = key.verify_key.encode().hex()

print("Private (seed, base64):", private_seed_b64)
print("Public (hex):", public_key_hex)
```

<Warning>
  The private seed printed above grants full signing authority over any subaccount it is associated with. Never log, transmit, or commit it to version control. Treat it with the same care as a private TLS key or database password.
</Warning>

***

## Loading the key in the SDK

Pass the private seed directly to the `Molecule` constructor using the `private_key` parameter, alongside your registered `key_id`.

```python theme={"dark"}
import os
from molecule import Molecule

client = Molecule(
    base_url=os.environ["MOLECULE_BASE_URL"],
    key_id=os.environ["MOLECULE_KEY_ID"],
    private_key=os.environ["MOLECULE_PRIVATE_KEY"],  # base64 seed string
)
```

### Using environment variables

The SDK reads the following environment variables if the corresponding constructor parameters are omitted:

| Variable | Constructor parameter | Description |
| - | - | - |
| `MOLECULE_BASE_URL` | `base_url` | API base URL (required) |
| `MOLECULE_KEY_ID` | `key_id` | Registered key identifier |
| `MOLECULE_PRIVATE_KEY` | `private_key` | Ed25519 seed in any accepted format |

With all three variables set, you can instantiate the client with no arguments:

```python theme={"dark"}
from molecule import Molecule

# Reads MOLECULE_BASE_URL, MOLECULE_KEY_ID, MOLECULE_PRIVATE_KEY from environment
client = Molecule()
```

<Tip>
  In containerised or serverless environments, inject secrets at runtime through your orchestration platform's secrets mechanism (e.g., Kubernetes Secrets, AWS Secrets Manager, HashiCorp Vault) rather than baking them into the container image or source code.
</Tip>

### Loading the key from raw bytes at runtime

If your secrets manager returns the key as raw bytes rather than a string, pass them directly:

```python theme={"dark"}
import os
from molecule import Molecule

# e.g., bytes retrieved from a hardware security module or secrets API
raw_seed: bytes = fetch_key_from_hsm()

client = Molecule(
    base_url=os.environ["MOLECULE_BASE_URL"],
    key_id=os.environ["MOLECULE_KEY_ID"],
    private_key=raw_seed,  # 32-byte bytes object
)
```

***

## Security best practices

<AccordionGroup>
  <Accordion title="Store keys in environment variables or secrets managers">
    Never hardcode a private key in source code or configuration files that are committed to version control. Use environment variables for local development and a dedicated secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, or equivalent) for production workloads. Rotate access to the secrets manager itself through IAM roles rather than long-lived credentials.
  </Accordion>

  <Accordion title="Never commit keys to version control">
    A private key committed to a repository — even a private one, even for a single commit — must be considered compromised. The commit history persists indefinitely. If a key is accidentally committed, rotate it immediately: register a new public key, update your running systems, and revoke the exposed key through the Molecule dashboard.
  </Accordion>

  <Accordion title="Use separate keys per trading system">
    Trading keys are bound to subaccounts. If you operate multiple independent trading systems, register a distinct keypair for each. This limits the blast radius of a compromised key to a single system and gives you a clear audit trail of which system generated each signed request.
  </Accordion>

  <Accordion title="Rotate keys on a regular schedule">
    To rotate a trading key:

    1. Generate a new Ed25519 keypair using the snippet in [Key format](#key-format).
    2. Register the new public key with Molecule through the dashboard.
    3. Update your running systems to use the new `key_id` and `private_key`.
    4. Verify that traffic is signing correctly with the new key.
    5. Deregister the old public key.

    Avoid gaps in service by completing steps 2–4 before deregistering the old key.
  </Accordion>
</AccordionGroup>

<Warning>
  Molecule stores only the public key. Your private seed is never transmitted during registration or at any other point. If you lose the private seed, there is no recovery path — you must generate a new keypair and register the new public key.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.