Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

closeAccount returns the lamports

Source: record/tests/record.rs L212

  • Given: a record initialized with alice as authority
  • When: setup: payer initializes the record
  • When: alice closes the record and drains lamports to receiver
  • Then: record lamports = 0 ✓
  • Then: receiver lamports = 10000000 ✓

Result: ✓ success — 988 CU · claims 2/2 ✓

sequenceDiagram
    participant p0 as alice
    participant p1 as Record
    p0->>p1: closeAccount
    activate p1
    p1-->>p0: ✓ 988cu
    deactivate p1

Authority

flowchart LR
    Record["Record"]:::program
    1115[("1115…")]:::state
    alice(["alice"]):::signer
    111B[("111B…")]:::state
    Record -->|writes| 1115
    alice -->|signs| Record
    Record -->|writes| 111B
    classDef program fill:#dae8fc,stroke:#6c8ebf;
    classDef signer fill:#d5e8d4,stroke:#82b366;
    classDef state fill:#ffe6cc,stroke:#d79b00;

Ownership

flowchart LR
    Record["Record"]:::program
    1115[("1115…")]:::state
    system["system"]:::program
    alice[("alice")]:::state
    111B[("111B…")]:::state
    Record -->|owns| 1115
    system -->|owns| alice
    system -->|owns| 111B
    classDef program fill:#dae8fc,stroke:#6c8ebf;
    classDef signer fill:#d5e8d4,stroke:#82b366;
    classDef state fill:#ffe6cc,stroke:#d79b00;

Accounts

AccountSignerWritableOwner
1115…·Record
alicesystem
111B…·system
Call tree and logs
closeAccount returns the lamports
alice (988cu)
└─ Record::closeAccount ✓ 988cu
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 invoke [1]
Program log: RecordInstruction::CloseAccount
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 consumed 988 of 200000 compute units
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 success

Integration

What an integrator writes: the derivations and the instruction, byte-identical to the transaction this page witnessed. Addresses are this scenario’s; supply your own.

#![allow(unused)]
fn main() {
use solana_instruction::{AccountMeta, Instruction};
use solana_pubkey::{pubkey, Pubkey};

// --- closeAccount ---
let program_id: Pubkey = pubkey!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
let record_account: Pubkey = pubkey!("11157t3sqMV725NVRLrVQbAu98Jjfk1uCKehJnXXQs"); // supply your own
let authority: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let receiver: Pubkey = pubkey!("111BuZ6b86gm7XhxjvTakhRvxSMjXp2GqgifkNUmDK"); // supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(record_account, false), // recordAccount
        AccountMeta::new_readonly(authority, true), // authority
        AccountMeta::new(receiver, false), // receiver
    ],
    // discriminator ++ borsh()
    data: vec![0x03],
};
}

The same call through the Codama-generated TypeScript client (the async builder derives every PDA the resolver derived here, so only the free inputs appear):

import { address } from "@solana/kit";
import { getCloseAccountInstructionAsync } from "your-generated-client";

const ix = await getCloseAccountInstructionAsync({
  recordAccount: address("11157t3sqMV725NVRLrVQbAu98Jjfk1uCKehJnXXQs"),
  authority: authoritySigner, // alice (a TransactionSigner)
  receiver: address("111BuZ6b86gm7XhxjvTakhRvxSMjXp2GqgifkNUmDK"),
});
How this page verifies itself: the test that ran it

The narrative above is this test; the page and the code cannot drift.

#![allow(unused)]
fn main() {
#[test]
fn close_account_returns_the_lamports() {
    let mut story = Story::load(SO, IDL);

    story.given("a record initialized with alice as authority");
    let payer = story.cast("payer");
    let alice = story.cast("alice");
    let record = story.stage_record(WRITABLE_START + 16);
    story
        .when(
            "setup: payer initializes the record",
            initialize()
                .record_account(record)
                .authority(alice.pubkey()),
            &[&payer],
        )
        .expect_success();
    let record_lamports = lamports(&story, &record);
    let receiver = Pubkey::new_unique();

    let record_lamports_after = story.track("record lamports", move |s| lamports(s, &record));
    let receiver_lamports = story.track("receiver lamports", move |s| lamports(s, &receiver));

    let out = story
        .when(
            "alice closes the record and drains lamports to receiver",
            close_account()
                .record_account(record)
                .authority(&alice)
                .receiver(receiver),
            &[&alice],
        )
        .expect_success();
    story.then_eq(&record_lamports_after, 0);
    story.then_eq(&receiver_lamports, record_lamports);
    emit_scenario(&story, &out, "closeAccount returns the lamports");
}
}