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

An authority revokes a delegation

Source: subscriptions/tests/test_revoke_delegation.rs L140

  • When: the user initializes a subscription authority
  • Then: initSubscriptionAuthority executes source-free ✓
  • When: a fixed delegation is created
  • Then: createFixedDelegation succeeds ✓
  • Then: fixedDelegation.header.discriminator = 2 ✓
  • When: the authority revokes the delegation
  • Then: revokeDelegation succeeds ✓
  • Then: the delegation account is closed ✓
  • Then: the rent flows back to Alice ✓
  • Then: alice’s rent increased by approximately the delegation rent ✓

Result: ✓ success — 289 CU · claims 7/7 ✓

sequenceDiagram
    participant p0 as alice
    participant p1 as Subscriptions
    p0->>p1: revokeDelegation
    activate p1
    p1-->>p0: ✓ 289cu
    deactivate p1

Authority

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

Ownership

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

Accounts

AccountSignerWritableOwner
alicesystem
94BV…·system
Call tree and logs
An authority revokes a delegation
alice (289cu)
└─ Subscriptions::revokeDelegation ✓ 289cu
Program De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 invoke [1]
Program De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 consumed 289 of 200000 compute units
Program De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 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};

// --- revokeDelegation ---
let program_id: Pubkey = pubkey!("De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44");
let authority: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let delegation_account: Pubkey = pubkey!("94BV622mohWYRCczHM2JuxzLx2dLLzFvqcN6DNfJqdek"); // supply your own
let ix = Instruction {
    program_id,
    accounts: vec![
        AccountMeta::new(authority, true), // authority
        AccountMeta::new(delegation_account, false), // delegationAccount
    ],
    // 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 { getRevokeDelegationInstructionAsync } from "your-generated-client";

const ix = await getRevokeDelegationInstructionAsync({
  authority: authoritySigner, // alice (a TransactionSigner)
  delegationAccount: address("94BV622mohWYRCczHM2JuxzLx2dLLzFvqcN6DNfJqdek"),
});
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 revoke_fixed_delegation() {
    let mut story = Story::load(SO, IDL);
    let alice = story.cast("alice");
    let mint = story.mint(&alice, MINT_DECIMALS);
    story.fund(&alice, &[(mint, 1_000_000)]);
    init(&mut story, &alice, mint);

    let delegatee = Pubkey::new_unique();
    let expiry = story.now() + 1000;
    let delegation_pda = fixed(&mut story, &alice, mint, delegatee, 0, 100, expiry, None);

    let delegation_rent = lamports(&story, &delegation_pda);
    let discriminator =
        story.track_field::<u8>("fixedDelegation", delegation_pda, "header.discriminator");
    story.then_eq(&discriminator, TAG_FIXED_DELEGATION);

    let alice_before = lamports(&story, &alice.pubkey());
    let out = story.revoke_delegation(RevokeArgs {
        signer: &alice,
        delegation_pda,
        receiver: None,
    });
    story.then_holds("revokeDelegation succeeds", out.success);

    story.then_holds(
        "the delegation account is closed",
        is_gone(&story, &delegation_pda),
    );
    let alice_after = lamports(&story, &alice.pubkey());
    story.then_holds("the rent flows back to Alice", alice_after > alice_before);
    story.then_holds(
        "alice's rent increased by approximately the delegation rent",
        alice_after >= alice_before + delegation_rent - 10_000,
    );
    emit_scenario(&story, &out, "An authority revokes a delegation");
}
}