> For the complete documentation index, see [llms.txt](https://shinkalabs.gitbook.io/hub/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shinkalabs.gitbook.io/hub/andromeda/getting-started/create-dwallet.md).

# Create a dWallet

Two ways to create a dWallet:

* **The high-level call** (recommended, also an MCP tool): `POST /v1/dwallet/create` with a passphrase. Andromeda runs the whole 2PC-MPC DKG for you and never holds your key. Use this from an app or an AI agent.
* **The low-level pair** (`/v1/dwallet/dkg/prepare` → `/v1/dwallet/dkg/submit`): you do the client side of the MPC protocol yourself. Only needed if you have your own MPC client.

{% hint style="warning" %}
Pre-alpha / Solana devnet only. The signer is a single mock node — no MPC guarantee yet. dWallets created here are wiped at Alpha 1. Do not custody real value.
{% endhint %}

## High-level: `POST /v1/dwallet/create`

```bash
curl -X POST https://api.andromedainfra.pro/v1/dwallet/create \
  -H "X-Api-Key: $ANDROMEDA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "passphrase": "a passphrase of at least 12 characters", "curve": "Curve25519", "attachRecoveryPolicy": true }'
# returns:
# { "success": true, "data": {
#     "dwalletAddress": "AdFku…RCpBge",
#     "curve": "Curve25519", "curveId": 2,
#     "ownerPubkeyBase58": "3WJVi…ZMYou",
#     "committed": true,
#     "signable": true,           # ← usable for signing right away (via /v1/dwallet/approve → /v1/dwallet/sign)
#     "recoverable": true,        # ← a rules-policy holds it; recoverable by primary owner / quorum
#     "policyAddress": "9hyc…Thr",
#     "disclaimer": "pre-alpha / Solana devnet only — …"
# }}
```

* `curve` — optional, default `Curve25519` (Solana/Ed25519); also `Secp256k1`, `Secp256r1`.
* `attachRecoveryPolicy` — optional, default `false`. When `true`, Andromeda also deploys a [`rules-policy`](/hub/andromeda/guides/deploy-policy/rules-policy.md) for the new dWallet (you, via the passphrase-wrapped keystore key, are the policy's primary owner) and delegates the dWallet's authority to it. The result is a wallet that is **signable** (see [Sign a message](/hub/andromeda/getting-started/sign.md)) and **recoverable** (see [Configure recovery](/hub/andromeda/guides/configure-recovery.md)) from the first call. Requires the recovery policy layer to be enabled on the deployment; otherwise the call returns `400`.
* `committed: true` — the on-chain dWallet account has materialised. `signable` / `recoverable` reflect whether the policy attach (when requested) completed; a non-fatal `policyAttachWarning` is included if it didn't (the dWallet itself still exists — finish the delegation with `POST /v1/dwallet/transfer-ownership`).

If you create a dWallet without `attachRecoveryPolicy`, it is **bare** (`signable: false`, `recoverable: false`) — usable only via the low-level DKG/sign path, or after you deploy a policy and `transfer-ownership` it (below).

### How the key is handled (the passphrase model)

Andromeda generates the dWallet's signer key, derives a wrapping key from your `passphrase` (Argon2id), encrypts the signer key with it (AES-256-GCM), and stores **only the ciphertext**. The passphrase and the plaintext key are never written to disk; the plaintext key lives only in memory during the DKG and is then discarded. To sign later, you supply the same passphrase again; Andromeda unwraps in memory, signs, discards.

* **Not permanent custody.** Andromeda cannot decrypt the key without your passphrase.
* **Brief exposure window.** During the create (and each sign) the plaintext key is in server memory momentarily — that's the residual trade-off of doing this server-side with zero client install. Acceptable for pre-alpha/devnet.
* **Lost passphrase ≠ lost wallet** — *if* a recovery policy is attached. With `attachRecoveryPolicy: true` it is, but the primary owner defaults to the same keystore key (so recovery still needs the passphrase). For passphrase-independent recovery, after creation add a quorum of external members (or set an external wallet as primary) via the [recovery policy admin actions](/hub/andromeda/guides/configure-recovery.md).
* **From an agent (MCP).** The same operation is the `create_dwallet` tool — see [Connect via MCP](/hub/andromeda/getting-started/mcp.md). The agent prompts you for the passphrase.

### Allocate a presign

```bash
curl -X POST https://api.andromedainfra.pro/v1/dwallet/presign \
  -H "X-Api-Key: $ANDROMEDA_KEY" -H "Content-Type: application/json" \
  -d '{ "dwalletAddress": "<DWALLET>" }'
# returns: { "success": true, "data": { "presignSessionIdHex": "3d7ac6…" } }
```

No passphrase needed (a presign doesn't touch the signer key). Single-use; allocate a few ahead of time if you sign in bursts. (MCP tool: `presign`.)

## Delegating a bare dWallet later: `POST /v1/dwallet/transfer-ownership`

A bare dWallet is owned by its signer key, so it can't yet produce an on-chain `MessageApproval` (the protocol only lets a *program* — a policy — authorise signing). To make a bare dWallet signable + recoverable after the fact: deploy a [`rules-policy`](/hub/andromeda/guides/deploy-policy/rules-policy.md) for it (see [Configure recovery](/hub/andromeda/guides/configure-recovery.md)), then delegate its authority to that policy's CPI authority PDA:

```bash
curl -X POST https://api.andromedainfra.pro/v1/dwallet/transfer-ownership \
  -H "X-Api-Key: $ANDROMEDA_KEY" -H "Content-Type: application/json" \
  -d '{ "dwalletAddress": "<DWALLET>", "passphrase": "…", "newAuthorityBase58": "<rules-policy CPI authority PDA>" }'
# returns: { "success": true, "data": { "txSignature": "…", "newAuthority": "<PDA>" } }
```

The passphrase unwraps the keystore key in memory to sign the transaction; Andromeda pays the gas. (MCP tool: `transfer_ownership`.) Using `attachRecoveryPolicy: true` at create time does the deploy + this delegation for you.

## Low-level: DKG `prepare` → `submit`

For clients that run the MPC protocol's client side themselves (a Rust/WASM Ika client). `POST /v1/dwallet/dkg/prepare` returns the session/envelope hints; you assemble and sign the `SignedRequestData` and submit it via `POST /v1/dwallet/dkg/submit`. The response carries the dWallet's public key. Use an [`Idempotency-Key`](/hub/andromeda/guides/idempotency.md) so a retry does not start a second DKG. Exact bodies in the [OpenAPI spec](https://api.andromedainfra.pro/openapi.json).

## Notes

* A dWallet's authoritative state is on Solana (the Ika program). Andromeda caches it for speed; a cold cache during a later flow is read from on-chain, not regenerated.
* Pick the curve that matches the chains you will sign for. See [Chains & curves](/hub/andromeda/reference/chains-curves.md).
* Identity layer (where enabled): the dWallet address is derived deterministically from the OAuth subject, so the same account reaches the same wallet across clients. See [Identity](/hub/andromeda/concepts/identity.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shinkalabs.gitbook.io/hub/andromeda/getting-started/create-dwallet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
