Solace Docs

Smart Contract Wallet for Solana

In this document, we discuss about how the Solace Smart Contract Wallet works.

The Basics

  1. Every wallet has two main properties:

    1. name

    2. Signing KeyPair (owner KeyPair)

  2. All transactions to the smart-contract need to be signed by the owner keypair.

  3. All funds are stored in a PDA, whose address is derived using the name parameter. Hence, name has to be unique.

  4. All SOL funds are stored in the PDA and SPL Tokens are stored in Associated Token Accounts derived for this PDA.

  5. guardians are other public keys which help safeguard the wallet. They are responsible for two things:

    1. Replacing the owner field to assign a new owner.

    2. Approving SPL and SOL transfers.

Incubation Mode

What is Incubation Mode?

Incubation mode is a state of the wallet where all transactions are instant & doesn't require any guardian approvals. This includes:

  1. Adding new guardians to the wallet.

  2. Adding new "trusted addresses" to the wallet

  3. Any SPL Transfers

  4. Any SOL Transfers

This mode exists to ensure that all transactions are instant and smooth when the user first creates the wallet. The security aspects of the Solace Wallet will kick in when the incubation mode ends, which is after 12 hours of wallet creation.

  1. When the wallet is first created, a created_at marks the time of creation and incubation_mode set to true.

  2. incubation_mode can be set to false by the user using the end_incubation call.

  3. Wallet has a method check_incubation which will return true or false based on the following rules:

    1. If the wallet was created less than 12 hours ago, then return incubation_mode

    2. If the wallet is older than 12 hours, then return false.

Guardians

adding guardians to your solace wallet

there are two stages during which guardians can be added to your solace wallet

  • within the 12 hour incubation window

  • after the 12 hour incubation window

adding guardians within the 12 hour incubation window

  1. the 12 hour incubation window begins when the wallet is first created.

  2. in this window, there is NO wait-time for adding guardians to your wallet.

  3. it’s crucial to not lose access to your device in this 12 hour window, as it’s the most vulnerable at this time.

adding guardians after the 12 hour incubation

  1. guardians to be added after the initial incubation window, requires a 36 hour wait-time to elapse.

  2. only after this 36 hour period, guardians can approve their request for guardianship, and be added as new guardians

  3. this wait-time prevents malicious actors from adding guardians to a wallet and compromising funds

Transfers

There are two types of Transfers:

  1. Instant SPL / SOL transfer

  2. Guarded SPL / SOL transfer

Instant SPL / SOL Transfer

This is when the recipient is already in the trusted_pubkeys. This transaction will execute. It will fail if the recipient is not in the trusted_pubkeys vector.

There are separate transaction calls for SOL and SPL as SPL transfers require more accounts to be passed in

Guarded SPL / SOL Transfer

When a recipient addres is not in the trusted_pubkeys, then the trasnsactions will require approval from Guardians of the wallet.

For this purpose, a new PDA is created and the account contains all the details about the transfer as well as the approval state

// PDA Account to handle Transfers
#[account]
pub struct GuardedTransfer {
    // Flag to check if SPL Transfer
    pub is_spl_transfer: bool,
    // Usually the pubkey of the account itself
    pub from: Pubkey,
    // The associated token account to which the transfer needs to be made
    pub to: Pubkey,
    // ATA of the wallet
    pub from_token_account: Option<Pubkey>,
    // In the case that the to_key was derived
    pub to_base: Option<Pubkey>,
    // Mint of the token to be transferred
    pub token_mint: Option<Pubkey>,
    // None if SOL transfer and Some(Pubkey) for SPL transfers
    pub program_id: Option<Pubkey>,
    // The amount to be transacted
    pub amount: u64,
    // The approvers of the transactions
    pub approvers: Vec<Pubkey>,
    // The approvals by guardians
    pub approvals: Vec<bool>,
    // The threshold of approvals required for the transaction
    pub threshold: u8,
    // Flag if the transfer is executable or not
    pub is_executable: bool,
    // Payer who is funding the PDA
    pub rent_payer: Pubkey,
    // The random pubkey used to derive this account
    pub random: Pubkey,
}

A guardian can approve a transfer using approve_transfer and can approve & execute a transfer (if all the other guardians have approved as well, using approve_and_execute_transfer.

Note that all these transaction should be signed by the guardian and should include the PDA involved in the transfer

trusted addresses

  1. all transactions on the solace-vault require guardian approvals. this is to prevent malicious actors form draining funds from your vault.

  2. however, trusted addresses are addresses to which your solace vault can transfer sol/spl tokens to, without the requirement of guardian approvals

how to add a trusted address?

currently, there are only two ways a trusted address can be added to the wallet

  1. incubation window - if the vault is in the incubation window adding trusted addresses is instant.

  2. transaction history - if the wallet is not in the incubation window, and if the vault has a transaction history with the address being requested


technical specifications

  1. call the add_trusted_pubkey with the key to be trusted.

  2. if the serialization fails with a custom program error, then one of the above mentioned criteria isn’t met.

  3. else, the pubkey is added to the trusted list.

Wallet Recovery

Wallet recovery is when the original owner has lost access to the owner privatekey or has lost access to the device / account. In this case a WalletRecovery can be initiated on a new device with a new owner KeyPair, where the wallet will be put into recovery_mode and no transfers will be allowed.

The guardians will have to approve_recovery_by_keypair to assign the new owner as the owner of the PDA Wallet.

Last updated