An open API service indexing awesome lists of open source software.

https://github.com/bluntbrain/solana-cross-program-invocation

This project shows how one Solana program calls another program. The main focus is on Cross-Program Invocation (CPI).
https://github.com/bluntbrain/solana-cross-program-invocation

Last synced: 17 days ago
JSON representation

This project shows how one Solana program calls another program. The main focus is on Cross-Program Invocation (CPI).

Awesome Lists containing this project

README

          

# Solana Cross-Program Invocation (CPI) Project

[![Rust](https://img.shields.io/badge/rust-%23000000.svg?style=for-the-badge&logo=rust&logoColor=white)](https://www.rust-lang.org/)
[![Solana](https://img.shields.io/badge/Solana-000?style=for-the-badge&logo=Solana&logoColor=9945FF)](https://solana.com/)
[![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)

This project shows how one Solana program calls another program. The main focus is on Cross-Program Invocation (CPI).

## How It Works

We have three programs:

1. **Double Contract** - A simple counter that doubles numbers
2. **CPI Contract** - Calls the double contract using CPI
3. **PDA Contract** - Demonstrates Program Derived Addresses (PDAs)

The CPI contract doesn't do the math itself. Instead, it calls the double contract to handle the counting logic.

## Project Structure

```
cpi-in-solana/
├── cpi-contract/
│ ├── src/lib.rs # Main CPI program
│ └── Cargo.toml
├── double-contract/
│ ├── src/lib.rs # Counter program that gets called
│ └── Cargo.toml
├── pda-contract/
│ ├── src/lib.rs # PDA demonstration program
│ └── Cargo.toml
└── client/
├── index.test.ts # Tests both programs
└── package.json
```

## The CPI Program

The important part is in `cpi-contract/src/lib.rs`. Here's what it does:

1. Takes two accounts: data account and double contract address
2. Creates an instruction to call the double contract
3. Uses `invoke()` to make the CPI call
4. Passes the data account to the other program

```rust
let instruction = Instruction {
program_id: *double_contract_address.key,
accounts: vec![AccountMeta {
is_signer: true,
is_writable: true,
pubkey: *data_account.key,
}],
data: vec![],
};

invoke(&instruction, &[data_account.clone()])?;
```

This is the core of CPI - one program creating an instruction for another program and calling it.

## Setup

```bash
git clone
cd cpi-in-solana

# Install dependencies
npm run setup

# Build both programs
npm run build

# Run tests
npm run test
```

## Testing

The tests show the CPI in action. They:

1. Deploy both programs to a local blockchain
2. Create accounts and fund them
3. Call the CPI program
4. Verify the double contract was executed

You can see this working in `client/cpi.test.ts`.

## Key Concepts

**Cross-Program Invocation (CPI)**: When one Solana program calls another program during execution.

**invoke()**: The function that makes CPI calls happen. It takes an instruction and the accounts needed.

**invoke_signed()**: Special CPI function that allows programs to sign on behalf of Program Derived Addresses (PDAs). Used when the calling program needs to act as a signer for accounts it owns.

**Program Derived Addresses (PDAs)**: Special accounts owned by programs but without private keys. They're derived deterministically from seeds and the program ID, enabling programs to control accounts programmatically.

**Account Passing**: Accounts get passed from the calling program to the called program. Both programs can read and modify them.

**Program Composition**: Instead of writing one big program, you can split logic into smaller programs that call each other.

## Build Commands

```bash
npm run build:cpi # Build the CPI program
npm run build:double # Build the double counter
npm run build:pda # Build the PDA program
npm run build # Build all programs
npm run test # Run the tests
npm run clean # Clean build files
```