createWalletPreGen() require the stored userShare and an MPC ceremony every time you sign. After migration, signing only needs a wallet ID and your API key.
SDK pregen vs REST API wallets
Both wallet types use the same database and MPC infrastructure. The difference is where the user’s key share lives.| SDK pregen wallet | REST API wallet | |
|---|---|---|
| Created with | createWalletPreGen() (SDK) | POST /v1/wallets (REST) |
| User share stored by | Your application | Para’s enclave |
| Signing requires | userShare + MPC ceremony | Wallet ID + API key |
In GET /v1/wallets?status=ready | No (until migrated) | Yes |
What happens during migration
- The SDK encrypts your
userSharewith the enclave’s P-256 public key (ECIES). The plaintext never leaves your server. - The encrypted payload is sent to Para’s backend, which forwards it to the hardware-isolated enclave for decryption and storage.
- The wallet becomes eligible for REST API signing and appears in
GET /v1/wallets?status=readyqueries.
Migration is additive — you’re adding REST API access, not replacing SDK signing. After verifying migration, you can optionally delete the stored
userShare values from your database if you no longer need SDK-based signing.Migrate with the SDK (recommended)
The server SDK handles encryption for you.POST /v1/wallets/{walletId}/migrate-share.
EVM and Cosmos wallets use the DKLS scheme (the default). Pass 'ED25519' for Solana or Stellar wallets.
Migrate with the REST API directly
If you’re not using the SDK, you’ll need to encrypt the share yourself before calling the endpoint.Fetch the enclave public key
Encrypt the share
Implement ECIES encryption with the P-256 curve:- Generate an ephemeral P-256 key pair
- Run ECDH with the enclave’s public key to derive a shared secret
- SHA-256 hash the shared secret to produce the AES key
- Encrypt the share data with AES-256-GCM using a random 12-byte IV
- Prepend the IV to the ciphertext (which includes the GCM auth tag), then base64-encode the result into
encryptedData
signer field is the raw signer secret extracted from the userShare string. The userShare is a series of base64-encoded JSON segments joined by -. Parse each segment, find the one whose id matches your wallet ID, and use its signer field.
Set userId to the wallet ID. Pregen wallets don’t have a user ID, but the enclave schema requires a non-empty value — the wallet ID is used as a placeholder and is ignored during signing.
Send the encrypted payload
TheencryptedPayload value is a JSON string, not a nested object. Stringify your ECIES envelope before embedding it in the request body.
| Status | Meaning |
|---|---|
200 | Wallet migrated |
400 | Missing or invalid encryptedPayload, key generation incomplete, or payload targets wrong wallet |
404 | Wallet not found or doesn’t belong to your project |
409 | Wallet already migrated |
Step-by-step migration
Stop creating SDK pregen wallets
For new wallets, switch to the REST API. Replace
createWalletPreGen() calls with POST /v1/wallets. Wallets created via the REST API are already ready for signing — no migration needed.Export existing user shares
Gather the
userShare values you stored when you created each SDK pregen wallet. You need the walletId and its corresponding userShare for every wallet you want to migrate.SDK method to REST endpoint mapping
| SDK method | REST API endpoint | Notes |
|---|---|---|
createWalletPreGen() | POST /v1/wallets | REST API persists shares server-side |
getUserShare() + partner signing | POST /v1/wallets/{id}/sign-raw | No userShare needed after migration |
| — | POST /v1/wallets/{id}/sign-transaction | EVM, Solana, and Stellar |
| — | POST /v1/wallets/{id}/sign-message | EVM, Solana, Cosmos, and Stellar |
| — | POST /v1/wallets/{id}/sign-typed-data | EVM only (EIP-712) |
| — | POST /v1/wallets/{id}/transfer | EVM and Solana only |
getWallets() | GET /v1/wallets | Use ?status=ready to filter to migrated wallets |
FAQ
Can I still use the SDK after migration?
Can I still use the SDK after migration?
Yes. The wallet works with both the SDK and the REST API after migration.
Can I undo a migration?
Can I undo a migration?
No. Once the share is persisted to the enclave, it can’t be removed. The wallet remains usable through both the SDK and REST API.
Can I migrate a wallet that was already migrated?
Can I migrate a wallet that was already migrated?
No. The endpoint returns
409 Conflict. The migration loop above handles this by catching 409s and skipping.Does migration affect wallet claiming?
Does migration affect wallet claiming?
Migration and claiming are separate operations. A migrated wallet can still be claimed by a user. Note that REST API signing only works on unclaimed wallets — once a user claims the wallet, use the SDK signing flow instead.
Is there a rate limit?
Is there a rate limit?
Standard rate limits apply. See Setup - Rate limits for details.
Do I need to handle encryption myself?
Do I need to handle encryption myself?
Only if you’re not using the SDK.
para.migrateWalletShare() handles ECIES encryption for you.