Skip to content

HongThaiPham/timelock-base-wallet-program

Repository files navigation

Timelock Base Wallet Program

A Solana blockchain program that provides timelock functionality for both SOL (native tokens) and SPL tokens. Users can lock their tokens for a specified period and withdraw them only after the unlock timestamp has passed.

πŸš€ Features

  • SOL Timelock: Lock native SOL tokens with customizable unlock timestamps
  • SPL Token Timelock: Lock any SPL tokens with timelock functionality
  • Secure Withdrawal: Tokens can only be withdrawn by the original owner after the unlock time
  • Flexible Timing: Set any future timestamp for unlock
  • Built with Anchor: Uses the modern Anchor framework for Solana development

πŸ“ Project Structure

timelock-base-wallet-program/
β”œβ”€β”€ programs/timelock-base-wallet-program/   # Main Rust program code
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs                          # Main program entry point
β”‚   β”‚   β”œβ”€β”€ state/
β”‚   β”‚   β”‚   └── vault.rs                    # Vault state definition
β”‚   β”‚   β”œβ”€β”€ instructions/
β”‚   β”‚   β”‚   β”œβ”€β”€ sol/                        # SOL token instructions
β”‚   β”‚   β”‚   └── spl/                        # SPL token instructions
β”‚   β”‚   β”œβ”€β”€ error.rs                        # Custom error definitions
β”‚   β”‚   β”œβ”€β”€ events.rs                       # Program events
β”‚   β”‚   └── constants.rs                    # Program constants
β”‚   └── Cargo.toml                          # Rust dependencies
β”œβ”€β”€ tests/                                   # TypeScript tests
β”‚   └── timelock-base-wallet-program.ts     # Main test file
β”œβ”€β”€ migrations/                              # Anchor migrations
β”œβ”€β”€ Anchor.toml                             # Anchor configuration
β”œβ”€β”€ package.json                            # Node.js dependencies
└── tsconfig.json                           # TypeScript configuration

πŸ› οΈ Prerequisites

Before building and running this project, ensure you have the following installed:

  • Rust (latest stable version)
  • Solana CLI (v1.18.0 or later)
  • Anchor CLI (v0.31.1 or later)
  • Node.js (v18 or later)
  • Yarn package manager

Installation Commands

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"

# Install Anchor CLI
cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked

# Install Node.js and Yarn (if not already installed)
# Visit https://nodejs.org/ for Node.js installation
npm install -g yarn

πŸ”§ Build Instructions

  1. Clone the repository:

    git clone <repository-url>
    cd timelock-base-wallet-program
  2. Install dependencies:

    yarn install
  3. Build the Anchor program:

    anchor build
  4. Generate TypeScript types (optional):

    anchor idl parse -f programs/timelock-base-wallet-program/src/lib.rs > target/idl/timelock_base_wallet_program.json

πŸ§ͺ Testing Instructions

The project uses TypeScript tests with Mocha and Anchor's bankrun for testing:

  1. Make sure the program is built:

    anchor build
  2. Run the tests:

    anchor test

    Or run tests directly:

    yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts
  3. Run specific test files:

    yarn run ts-mocha -p ./tsconfig.json tests/timelock-base-wallet-program.ts
  4. Run tests with Surfpool from txtx:

    surfpool start --watch
    surfpool run sol-vault
    surfpool run spl-vault

πŸ” Code Quality

  • Lint TypeScript code:

    yarn lint
  • Fix linting issues:

    yarn lint:fix

πŸ“– Program API

Core Functions

1. Initialize SOL Lock

pub fn initialize_sol_lock(
    ctx: Context<InitializeSolLock>,
    amount: u64,
    unlock_timestamp: i64,
) -> Result<()>

Creates a new timelock vault for SOL tokens.

Parameters:

  • amount: Amount of SOL to lock (in lamports)
  • unlock_timestamp: Unix timestamp when tokens can be withdrawn

2. Withdraw SOL Lock

pub fn withdraw_sol_lock(ctx: Context<WithdrawSolLock>) -> Result<()>

Withdraws SOL tokens from a vault after the unlock timestamp has passed.

3. Initialize SPL Lock

pub fn initialize_spl_lock(
    ctx: Context<InitializeSplLock>,
    amount: u64,
    unlock_timestamp: i64,
) -> Result<()>

Creates a new timelock vault for SPL tokens.

Parameters:

  • amount: Amount of SPL tokens to lock
  • unlock_timestamp: Unix timestamp when tokens can be withdrawn

4. Withdraw SPL Lock

pub fn withdraw_spl_lock(ctx: Context<WithdrawSplLock>) -> Result<()>

Withdraws SPL tokens from a vault after the unlock timestamp has passed.

State Structure

Vault

pub struct Vault {
    pub owner: Pubkey,           // Owner of the locked tokens
    pub amount: u64,             // Amount of tokens locked
    pub bump: u8,                // PDA bump seed
    pub unlock_timestamp: i64,   // When tokens can be withdrawn
    pub mint: Option<Pubkey>,    // None for SOL, Some(mint) for SPL
}

Error Codes

  • UnlockTimestampMustBeInFuture: Unlock timestamp must be in the future
  • AmountMustBeGreaterThanZero: Amount must be greater than zero
  • VaultLocked: Vault is still locked (current time < unlock_timestamp)
  • VaultLocking: Vault is in locking state
  • InvalidVaultMint: Invalid vault mint provided

🎯 Usage Examples

Using with Anchor TypeScript Client

import * as anchor from '@coral-xyz/anchor';
import { TimelockBaseWalletProgram } from './target/types/timelock_base_wallet_program';

// Initialize program
const program = anchor.workspace
  .TimelockBaseWalletProgram as Program<TimelockBaseWalletProgram>;

// Lock SOL for 24 hours
const unlockTimestamp = Date.now() / 1000 + 24 * 60 * 60; // 24 hours from now
const amount = new anchor.BN(anchor.web3.LAMPORTS_PER_SOL); // 1 SOL

await program.methods
  .initializeSolLock(amount, new anchor.BN(unlockTimestamp))
  .accounts({
    // ... account setup
  })
  .rpc();

// Withdraw after unlock time
await program.methods
  .withdrawSolLock()
  .accounts({
    // ... account setup
  })
  .rpc();

πŸ”’ Security Considerations

  • Always verify the unlock timestamp is in the future when creating locks
  • Ensure proper account validation in all instructions
  • The program uses Program Derived Addresses (PDAs) for secure vault management
  • All withdrawals are validated against the vault owner and unlock timestamp

πŸ“„ License

This project is licensed under the ISC License.

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run tests and linting
  6. Submit a pull request

πŸ“ž Support

For questions or issues, please open an issue in the GitHub repository.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •