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

Reference

These pages are generated from the program’s Codama IDL: one per instruction, with its accounts and arguments. Nothing here was written by hand.

This analysis is experimental, and our propulsion deserves some of the credit. The Infinite Improbability Drive from the Heart of Gold was unavailable, so we are running on a drive salvaged from the ship of fools, a vessel crewed largely by telephone sanitizers and marketing executives; this may account for a certain amount of the improbability below. Everything here was reconstructed by machine from the IDL rather than declared by a human, so it arrives with the cheerful confidence of a depressed robot who has worked out the odds and would rather not go on about it. Anything surprising is worth checking against the executed examples nested under each instruction, which have at least had the decency to actually run.

Don’t Panic.

initialize

Accounts

AccountSignerWritableSupplied
recordAccount·caller
authority··caller

Initialize stamps the version and authority

Source: record/tests/record.rs L46

  • Given: a fresh, uninitialized record account with 16 bytes of payload space
  • When: payer initializes the record, nominating alice as authority
  • Then: version = 1 ✓
  • Then: authority = 2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT ✓
  • Then: payload = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ✓

Result: ✓ success — 707 CU · claims 3/3 ✓

sequenceDiagram
    participant p0 as payer
    participant p1 as Record
    p0->>p1: initialize
    activate p1
    p1-->>p0: ✓ 707cu
    deactivate p1

Authority

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

Ownership

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

Accounts

AccountSignerWritableOwner
1117…·Record
alice··system
Call tree and logs
Initialize stamps the version and authority
payer (707cu)
└─ Record::initialize ✓ 707cu
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 invoke [1]
Program log: RecordInstruction::Initialize
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 consumed 707 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};

// --- initialize ---
let program_id: Pubkey = pubkey!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
let record_account: Pubkey = pubkey!("1117mWrzzrZr312ebPDHu8tbfMwFNvCvMbr6WepCNG"); // supply your own
let authority: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(record_account, false), // recordAccount
        AccountMeta::new_readonly(authority, false), // authority
    ],
    // discriminator ++ borsh()
    data: vec![0x00],
};
}

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 { getInitializeInstructionAsync } from "your-generated-client";

const ix = await getInitializeInstructionAsync({
  recordAccount: address("1117mWrzzrZr312ebPDHu8tbfMwFNvCvMbr6WepCNG"),
  authority: address("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"), // alice
});
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 initialize_stamps_version_and_authority() {
    let mut story = Story::load(SO, IDL);

    story.given("a fresh, uninitialized record account with 16 bytes of payload space");
    let payer = story.cast("payer");
    let alice = story.cast("alice");
    let record = story.stage_record(WRITABLE_START + 16);

    let version = story.track("version", move |s| s.read_record(&record).0);
    let authority = story.track("authority", move |s| s.read_record(&record).1);
    let payload = story.track("payload", move |s| s.read_record(&record).2);

    let out = story
        .when(
            "payer initializes the record, nominating alice as authority",
            initialize()
                .record_account(record)
                .authority(alice.pubkey()),
            &[&payer],
        )
        .expect_success();

    story.then_eq(&version, 1);
    story.then_eq(&authority, alice.pubkey());
    story.then_eq(&payload, vec![0u8; 16]);
    emit_scenario(&story, &out, "Initialize stamps the version and authority");
}
}

write

Accounts

AccountSignerWritableSupplied
recordAccount·caller
authority·caller

Arguments

ArgumentType
offsetu64
databytes

A write from a non-authority is refused

Source: record/tests/record.rs L117

  • Given: a record initialized with alice as authority
  • When: setup: payer initializes the record
  • When: mallory tries to forge a write
  • Then: a write from someone who is not the authority is rejected ✓

Result: ✗ failed — 833 CU · claims 1/1 ✓

sequenceDiagram
    participant p0 as mallory
    participant p1 as Record
    p0->>p1: write
    activate p1
    note over p1: 🚩 custom program error  0x0
    p1-->>p0: ✗ 833cu
    deactivate p1

Authority

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

Ownership

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

Accounts

AccountSignerWritableOwner
111J…·Record
mallorysystem
Call tree and logs
A write from a non-authority is refused
mallory (833cu)
└─ Record::write ✗ 833cu
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 invoke [1]
Program log: RecordInstruction::Write
Program log: Incorrect record authority provided
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 consumed 833 of 200000 compute units
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 failed: custom program error: 0x0

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};

// --- write ---
let program_id: Pubkey = pubkey!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
let record_account: Pubkey = pubkey!("111JV6iBiRLoJUtNieRJ9QmcpE2KPE3gLpDzAUkbNW"); // supply your own
let authority: Pubkey = pubkey!("CccbLj76vNwYe3sSTuPVUc1nRqRFG6fhAQThsiochKMg"); // mallory: this scenario's value; supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(record_account, false), // recordAccount
        AccountMeta::new_readonly(authority, true), // authority
    ],
    // discriminator ++ borsh(offset: 0, data: …)
    data: vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x64],
};
}

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 { getWriteInstructionAsync } from "your-generated-client";

const ix = await getWriteInstructionAsync({
  recordAccount: address("111JV6iBiRLoJUtNieRJ9QmcpE2KPE3gLpDzAUkbNW"),
  authority: authoritySigner, // mallory (a TransactionSigner)
  offset: 0n,
  data: /* … */,
});
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 write_requires_the_authority() {
    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 mallory = story.cast("mallory");
    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 out = story.when(
        "mallory tries to forge a write",
        write()
            .record_account(record)
            .authority(&mallory)
            .offset(0)
            .data(b"forged".to_vec()),
        &[&mallory],
    );
    story.then_holds(
        "a write from someone who is not the authority is rejected",
        !out.success,
    );
    emit_scenario(&story, &out, "A write from a non-authority is refused");
}
}

Write lands bytes behind the authority

Source: record/tests/record.rs L82

  • Given: a record initialized with alice as authority
  • When: setup: payer initializes the record
  • When: alice writes “hello” at payload offset 0
  • Then: the bytes land at payload offset 0 ✓

Result: ✓ success — 805 CU · claims 1/1 ✓

sequenceDiagram
    participant p0 as alice
    participant p1 as Record
    p0->>p1: write
    activate p1
    p1-->>p0: ✓ 805cu
    deactivate p1

Authority

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

Ownership

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

Accounts

AccountSignerWritableOwner
1119…·Record
alicesystem
Call tree and logs
Write lands bytes behind the authority
alice (805cu)
└─ Record::write ✓ 805cu
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 invoke [1]
Program log: RecordInstruction::Write
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 consumed 805 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};

// --- write ---
let program_id: Pubkey = pubkey!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
let record_account: Pubkey = pubkey!("1119DWteoLSdjvrT6g6L8C2PfDD2faiTQUpsjY2RiF"); // supply your own
let authority: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(record_account, false), // recordAccount
        AccountMeta::new_readonly(authority, true), // authority
    ],
    // discriminator ++ borsh(offset: 0, data: …)
    data: vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f],
};
}

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 { getWriteInstructionAsync } from "your-generated-client";

const ix = await getWriteInstructionAsync({
  recordAccount: address("1119DWteoLSdjvrT6g6L8C2PfDD2faiTQUpsjY2RiF"),
  authority: authoritySigner, // alice (a TransactionSigner)
  offset: 0n,
  data: /* … */,
});
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 write_then_read_back() {
    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 out = story
        .when(
            "alice writes \"hello\" at payload offset 0",
            write()
                .record_account(record)
                .authority(&alice)
                .offset(0)
                .data(b"hello".to_vec()),
            &[&alice],
        )
        .expect_success();

    story.then("the bytes land at payload offset 0", move |s| {
        &s.read_record(&record).2[..5] == b"hello"
    });
    emit_scenario(&story, &out, "Write lands bytes behind the authority");
}
}

setAuthority

Accounts

AccountSignerWritableSupplied
recordAccount·caller
authority·caller
newAuthority··caller

setAuthority transfers control

Source: record/tests/record.rs L174

  • Given: a record initialized with alice as authority
  • When: setup: payer initializes the record
  • When: alice hands off authority to bob
  • Then: authority = 6DAhWE3pSJQrSFRNjkGQznpUi7wWnqWf3FnRyZQqxbvu ✓
  • When: bob writes to the record he now controls
  • When: alice tries to write after handing off
  • Then: alice no longer controls it ✓

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

sequenceDiagram
    participant p0 as alice
    participant p1 as Record
    p0->>p1: setAuthority
    activate p1
    p1-->>p0: ✓ 943cu
    deactivate p1

Authority

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

Ownership

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

Accounts

AccountSignerWritableOwner
111F…·Record
alicesystem
bob··system
Call tree and logs
setAuthority transfers control
alice (943cu)
└─ Record::setAuthority ✓ 943cu
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 invoke [1]
Program log: RecordInstruction::SetAuthority
Program recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5 consumed 943 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};

// --- setAuthority ---
let program_id: Pubkey = pubkey!("recr1L3PCGKLbckBqMNcJhuuyU1zgo8nBhfLVsJNwr5");
let record_account: Pubkey = pubkey!("111FJo4zLAGU9nzTWa6EnbV4VAmtG4FR8kcokrtZYr"); // supply your own
let authority: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let new_authority: Pubkey = pubkey!("6DAhWE3pSJQrSFRNjkGQznpUi7wWnqWf3FnRyZQqxbvu"); // bob: this scenario's value; supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(record_account, false), // recordAccount
        AccountMeta::new_readonly(authority, true), // authority
        AccountMeta::new_readonly(new_authority, false), // newAuthority
    ],
    // discriminator ++ borsh()
    data: vec![0x02],
};
}

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 { getSetAuthorityInstructionAsync } from "your-generated-client";

const ix = await getSetAuthorityInstructionAsync({
  recordAccount: address("111FJo4zLAGU9nzTWa6EnbV4VAmtG4FR8kcokrtZYr"),
  authority: authoritySigner, // alice (a TransactionSigner)
  newAuthority: address("6DAhWE3pSJQrSFRNjkGQznpUi7wWnqWf3FnRyZQqxbvu"), // bob
});
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 set_authority_transfers_control() {
    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 bob = story.cast("bob");
    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 authority = story.track("authority", move |s| s.read_record(&record).1);
    let handoff = story
        .when(
            "alice hands off authority to bob",
            set_authority()
                .record_account(record)
                .authority(&alice)
                .new_authority(bob.pubkey()),
            &[&alice],
        )
        .expect_success();
    story.then_eq(&authority, bob.pubkey());

    story
        .when(
            "bob writes to the record he now controls",
            write()
                .record_account(record)
                .authority(&bob)
                .offset(0)
                .data(b"bob".to_vec()),
            &[&bob],
        )
        .expect_success();

    let out = story.when(
        "alice tries to write after handing off",
        write()
            .record_account(record)
            .authority(&alice)
            .offset(0)
            .data(b"back".to_vec()),
        &[&alice],
    );
    story.then_holds("alice no longer controls it", !out.success);
    emit_scenario(&story, &handoff, "setAuthority transfers control");
}
}

closeAccount

Accounts

AccountSignerWritableSupplied
recordAccount·caller
authority·caller
receiver·caller

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");
}
}

reallocate

Accounts

AccountSignerWritableSupplied
recordAccount·caller
authority·caller

Arguments

ArgumentType
dataLengthu64

Errors

CodeNameMessage
0incorrectAuthorityIncorrect authority provided on update or delete
1overflowCalculation overflow