CreateReservedV1.
Verify support on your target cluster before funding a reserved address.
Set up the SDK
The examples use the reservation APIs inswig-protocol-sdk.
The TypeScript reservation APIs in this guide require a source build containing
ReservationV1 and getCreateReservedSwigInstruction. Follow the
Solana source setup.
- TypeScript:
ReservationV1is exported by@swig-wallet/lib,@swig-wallet/classic, and@swig-wallet/kit. - Rust: use
swig_sdk::reservation::ReservationV1. The underlyingswig-interfacecrate owns the package format and instruction builder.
Choose the owner and address
Provide a direct Ed25519, secp256k1, or secp256r1 (P-256) public key. For secp256k1, provide the public key, not a 20-byte Ethereum address. Choose either an account index or your own 32-byte salt:- Omitting the option uses index
0. - A different index gives the same owner another wallet. Indices range from
0to4,294,967,295. - A custom salt must be exactly 32 bytes. The SDK does not generate one.
Reserve and activate
TypeScript
This Classic example reserves an Ed25519 wallet and prepares its activation instructions using the same reservation object.walletAddress as the SOL deposit address and as the owner when deriving
token accounts. Use configAddress to fetch roles and build wallet operations.
Classic returns Web3.js PublicKey values, so configAddress can be passed
directly to fetchSwig.
Add the returned instructions to a transaction, sign with the payer, submit
through your Solana client, and confirm the transaction. The builder performs no RPC
or submission. The 600,000-unit compute budget accommodates P-256 validation;
the activation builder itself does not add a compute-budget instruction.
For Solana Kit, import ReservationV1 and getCreateReservedSwigInstruction
from @swig-wallet/kit. Pass the payer as a Kit Address; the builder returns
a Kit instruction. await reservation.addresses() returns Kit Address values
for both swigAddress and walletAddress, ready to use with Kit helpers.
Include a 600,000-unit compute limit for P-256 owners.
Only the external payer signs activation. It pays the required account top-ups
and transaction fee. The program fixes role 0 to the committed owner with
All permissions; the payer cannot substitute an owner or permission set.
Activation preserves SOL deposited before account creation.
Rust
The Rust flow uses the same package bytes and addresses. Pass the reservation returned byreserve_wallet to prepare_activation to build instructions for
the payer. This example uses solana-sdk 4.x and
solana-compute-budget-interface 3.x alongside the source swig-sdk crate.
swig-interface at the same version/revision used by swig-sdk for
program_id(). Call reservation.addresses()? to get swig_address for the
config and wallet_address for deposits.
For a wallet API that handles RPC and activation, use
SwigWallet::from_reservation.
It activates a missing or prefunded uninitialized config, then opens it. For an
active config, it opens the wallet with the current authority without sending
an activation transaction. RPC failures and invalid existing accounts remain
errors.
Continue using the wallet
- After confirmation, fetch the wallet by its config address and use the current on-chain roles for signing and authority management.
- Retrying activation for the same valid active reservation preserves its authorities, counters, and permissions, including owner rotations.
- If you saved the package, keep it after a rotation: it identifies the wallet’s creation address, while current on-chain roles determine who can act.
- A closed config retains a tombstone. Activation cannot recreate it.
- Reserved wallets use address-bound V2 subaccounts. The TypeScript legacy V1 subaccount helpers are incompatible; use the Rust V2 subaccount APIs when you need that flow.
Optional: load a saved reservation
Use the existing reservation object while it is available. If you save a reservation for a later session, store its exact package bytes and keep the wallet address in a trusted record. The package contains public data, but changing it can change the destination. Encode the bytes as base64 or hex if your storage requires text. When loading, check the expected program ID and compare the derived wallet address with your trusted record. The loaded reservation can be passed to the same activation builder used above.TypeScript
Savereservation.toBytes() and walletAddress.toBase58() from the Classic
example. Kit addresses are already base58 strings.
Rust
Savereservation.package_bytes and
reservation.addresses()?.wallet_address.
Package compatibility
Imports accept exactly one canonical V1 package: 99 bytes for Ed25519 or 100 bytes for secp256k1/P-256. They reject unsupported owner types, malformed keys, wrong program IDs, unsupported versions, and trailing bytes. Ed25519 owners must be canonical, non-small-order curve points. Constructors accept compressed (33-byte) or uncompressed (65-byte) SEC1 keys for both secp curves, and raw 64-byte keys for secp256k1. Serialized packages always contain the compressed form. The config uses["rsv", SHA256("rsv" || package)] as PDA seeds. The wallet
uses ["swig-wallet-address", config_address]. An account index is encoded
little-endian in the last four bytes of an otherwise zero 32-byte salt.
Use the returned config address directly: passing its commitment to legacy
findSwigPda derives a different wallet.
