A delegator creates a fixed delegation
Source: subscriptions/tests/test_create_fixed_delegation.rs L206
- When: the user initializes a subscription authority
- When: a fixed delegation is created
- Then: the fixed delegation is created ✓
- Then: fixedDelegation.header.delegator = 2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT ✓
- Then: fixedDelegation.header.delegatee = 111FJo4zLAGU9nzTWa6EnbV4VAmtG4FR8kcokrtZYr ✓
- Then: fixedDelegation.header.discriminator = 2 ✓
- Then: fixedDelegation.amount = 100000000 ✓
- Then: fixedDelegation.expiryTs = 86400 ✓
Result: ✓ success — 6538 CU · claims 6/6 ✓
sequenceDiagram
participant p0 as alice
participant p1 as Subscriptions
participant p2 as system
p0->>p1: createFixedDelegation
activate p1
p1->>p2: createAccount
activate p2
p2-->>p1: ✓
deactivate p2
p1-->>p0: ✓ 6538cu
deactivate p1
Authority
flowchart LR
Subscriptions["Subscriptions"]:::program
alice(["alice"]):::signer
7JW9(["7JW9…"]):::signer
system["system"]:::program
alice -->|signs| Subscriptions
Subscriptions -->|writes| 7JW9
alice -->|signs| system
7JW9 -->|signs| system
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
Subscriptions["Subscriptions"]:::program
7JW9[("7JW9…")]:::state
system -->|owns| alice
Subscriptions -->|owns| 7JW9
classDef program fill:#dae8fc,stroke:#6c8ebf;
classDef signer fill:#d5e8d4,stroke:#82b366;
classDef state fill:#ffe6cc,stroke:#d79b00;
Accounts
| Account | Signer | Writable | Owner |
|---|---|---|---|
| alice | ✓ | ✓ | system |
| SA(alice, Mint) | · | · | Subscriptions |
| 7JW9… | · | ✓ | Subscriptions |
| 111F… | · | · | system |
| system | · | · | Nati… |
Call tree and logs
A delegator creates a fixed delegation
alice (6538cu)
└─ Subscriptions::createFixedDelegation ✓ 6538cu
└─ system::createAccount ✓
Program De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 invoke [1]
Program 11111111111111111111111111111111 invoke [2]
Program 11111111111111111111111111111111 success
Program De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44 consumed 6538 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};
// --- createFixedDelegation ---
let program_id: Pubkey = pubkey!("De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44");
let delegator: Pubkey = pubkey!("2rj1EEgg32bupe12mMYnPFaKQCPPyYBhKYmDFZ8cXxpT"); // alice: this scenario's value; supply your own
let subscription_authority: Pubkey = pubkey!("4RDKDQRnKtZC5ti4wunSAayArwxdZida5St595CiKJ7i"); // SA(alice, Mint): this scenario's value; supply your own
let delegation_account: Pubkey = pubkey!("7JW9nfbPZbx3UQUbDA69x9D9Tytmmh23p7wYJ6Eq9RWM"); // supply your own
let delegatee: Pubkey = pubkey!("111FJo4zLAGU9nzTWa6EnbV4VAmtG4FR8kcokrtZYr"); // supply your own
let system_program: Pubkey = pubkey!("11111111111111111111111111111111"); // the system program
let ix = Instruction {
program_id,
accounts: vec![
AccountMeta::new(delegator, true), // delegator
AccountMeta::new_readonly(subscription_authority, false), // subscriptionAuthority
AccountMeta::new(delegation_account, false), // delegationAccount
AccountMeta::new_readonly(delegatee, false), // delegatee
AccountMeta::new_readonly(system_program, false), // systemProgram
],
// discriminator ++ borsh(fixedDelegation: {nonce: 0, amount: 100000000, expiryTs: 86400, expectedSubscriptionAuthorityInitId: 0})
data: vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00, 0x80, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 { getCreateFixedDelegationInstructionAsync } from "your-generated-client";
const ix = await getCreateFixedDelegationInstructionAsync({
delegator: delegatorSigner, // alice (a TransactionSigner)
subscriptionAuthority: address("4RDKDQRnKtZC5ti4wunSAayArwxdZida5St595CiKJ7i"), // SA(alice, Mint)
delegationAccount: address("7JW9nfbPZbx3UQUbDA69x9D9Tytmmh23p7wYJ6Eq9RWM"),
delegatee: address("111FJo4zLAGU9nzTWa6EnbV4VAmtG4FR8kcokrtZYr"),
// systemProgram defaults to the system program
fixedDelegation: {
nonce: 0n,
amount: 100000000n,
expiryTs: 86400n,
expectedSubscriptionAuthorityInitId: 0n
},
});
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 create_fixed_delegation() {
let mut story = Story::load(SO, IDL);
let payer = story.cast("alice");
let amount: u64 = 100_000_000;
let expiry_ts = story.now() + days(1) as i64;
let nonce: u64 = 0;
let mint = story.mint(&payer, MINT_DECIMALS);
story.fund(&payer, &[(mint, 1_000_000)]);
init(&mut story, &payer, mint);
let delegatee = Pubkey::new_unique();
let delegation_pda = story.delegation_pda(&payer.pubkey(), &mint, &delegatee, nonce);
let out = story.create_fixed_delegation(CreateFixedArgs {
delegator: &payer,
mint,
delegatee,
nonce,
amount,
expiry_ts,
sponsor: None,
expected_init_id: None,
delegation_override: None,
});
story.then_holds("the fixed delegation is created", out.success);
let delegator =
story.track_field::<Pubkey>("fixedDelegation", delegation_pda, "header.delegator");
let delegatee_field =
story.track_field::<Pubkey>("fixedDelegation", delegation_pda, "header.delegatee");
let discriminator =
story.track_field::<u8>("fixedDelegation", delegation_pda, "header.discriminator");
let amount_field = story.track_field::<u64>("fixedDelegation", delegation_pda, "amount");
let expiry = story.track_field::<i64>("fixedDelegation", delegation_pda, "expiryTs");
story.then_eq(&delegator, payer.pubkey());
story.then_eq(&delegatee_field, delegatee);
story.then_eq(&discriminator, TAG_FIXED_DELEGATION);
story.then_eq(&amount_field, amount);
story.then_eq(&expiry, expiry_ts);
emit_scenario(&story, &out, "A delegator creates a fixed delegation");
}
}