ckSOL: A SOL Twin Token on the IC
Hello everybody
!
We’d like to start a forum thread on ckSOL, where we can discuss the design and post updates on our progress.
What is ckSOL?
Chain-key SOL, or ckSOL, is an IC-native token that represents SOL, the native token of the Solana blockchain. Anybody that has SOL can convert it into ckSOL, and vice-versa. All SOL backing ckSOL is held by a canister smart contract using threshold Schnorr over Ed25519 — the corresponding private key is never derived.
Since ckSOL is an IC-native token, it can be transacted very fast and with low fees, and is easy to use from other IC dapps. ckSOL follows the ICRC-1, ICRC-2, and ICRC-3 standards.
If you’re familiar with ckBTC or ckETH, you can think of ckSOL as the equivalent for Solana.
How is it built?
The ckSOL system consists of a ckSOL Ledger — a standard ICRC ledger canister — and a ckSOL Minter, which is responsible for converting between SOL and ckSOL and holds custody of all backing SOL.
The design closely follows ckETH: the minter communicates with Solana through the SOL RPC canister, which queries multiple independent JSON-RPC providers simultaneously and requires consensus on responses, removing any single point of failure.
The full design — both conversion flows, the fee model, the parameter choices and the reasoning behind them — is written up in the design document in the repository.
Converting SOL to ckSOL
Similar to ckBTC, each ICP account gets its own dedicated Solana deposit address, derived from the user’s principal and subaccount. This makes it possible to deposit directly from centralized exchanges, which typically don’t support memo fields — and often don’t even show you the transaction signature.
After sending SOL to that address, the user calls deposit_sol. The minter credits the deposit from the balance of the address rather than from individual transfers, so no Solana transaction ever has to be identified: it sweeps the address into its main account, and mints ckSOL once that sweep is finalized, for the amount the sweep actually moved. deposit_sol_status follows a deposit from queued through to minted.
Reading a balance rather than individual transfers also means that several transfers, each too small on its own, are credited together once their sum is large enough.
An automatic flow, in which the minter discovers deposits without the user calling anything, is deferred to a post-launch upgrade.
Converting ckSOL to SOL
A user holding ckSOL that wants to receive native SOL grants the minter an ICRC-2 approval and calls withdraw_sol, specifying the destination Solana address and amount. The minter burns the ckSOL and sends the equivalent SOL to the destination address, minus a small withdrawal fee. withdraw_sol_status tracks the request.
Withdrawals are submitted as durable-nonce transactions, so they never expire. That matters because a transaction carrying a recent block hash does expire, and replacing one safely requires certainty that the original can never land — which a missing status from an RPC provider can never give you. A durable nonce turns that judgement into a positive on-chain fact instead.
Current status
The code is available at github.com/dfinity/cksol. A staging deployment targeting Solana Devnet (ckDevnetSOL) is live on ICP mainnet and we are now about to launch the production version (see this post).
Discussion & people involved
We hope this thread can serve as a good place to discuss all things around ckSOL and keep everyone up to date on our progress.
Special thanks to @lpahlavi, @THLO, @maciejdfinity1 who started the project and @mathiasb to help bring it to the finish line.