Every instruction of the curta program: its tag, who signs it, its arguments byte by byte, its accounts in order, the checks it makes, what it changes and the event it emits.
Reading this page
Each instruction below gives its data layout, its accounts in the order the program reads them, the checks it makes with the error each one raises, what it changes, and its event. Offsets count from the first byte of the instruction data, where the tag sits. Program reference gives the encodings.
The account tables list the instruction’s own accounts. Every instruction takes two more after them, both read-only: the event authority and the curta program. The builders in @curta/sdk append them, and each builder’s signature is given with its instruction.
The account’s data is shorter than its type: 128 bytes for Config, 4,096 for Model, 256 for Run, 8 for a vault. A weight account is not exactly 2,048 bytes plus its section’s length.
config or feeVault already holds data or is owned by a program other than System.
What it changes
Creates config at 128 bytes and feeVault at 8 bytes, both owned by the program and rent-exempt. Lamports already sitting at either address count toward its rent.
Writes the Config: tag, authority, FeeVault address, turn reward, protocol share rate and both bumps.
Writes the tag CURTAFEE into the FeeVault.
Event
Emits a init_config event, action 0: primary is the Config, actor the authority, related the FeeVault. Values: turn reward, protocol share basis points. Events gives the byte layout.
set_config
Sets the turn reward and the protocol share rate. A run records both when it opens, so the new values apply to runs opened afterwards.
The signer is not the authority the Config records.
What it changes
Writes the turn reward at offset 72 and the protocol share rate at offset 80 of the Config.
Event
Emits a set_config event, action 1: primary is the Config, actor the authority, related the FeeVault. Values: turn reward, protocol share basis points. Events gives the byte layout.
create_model
Writes a Model account in an account created earlier in the transaction, with its configuration, name, royalty, weights hash and one descriptor per weight account, and creates the model’s vault.
Tag
2
Signer
The publisher and the model keypair
Data length
74 bytes, plus the name, plus 40 bytes per section
Lamports per generated token, paid to the model’s vault.
9
config
7 × u32
dimension, hidden dimension, layers, heads, KV heads, vocabulary size, context length, in that order. Dimension 1 to 512, hidden dimension 1 to 2,048, layers 1 to 16, heads 1 to 16, vocabulary 259 to 65,536, context 1 to 512. KV heads divides heads, heads divides dimension, and dimension over heads is even and at most 64.
37
nameLength
u8
Length of the name in bytes, 1 to 64. Called n below.
38
name
bytes
The model’s name, UTF-8, n bytes.
38 + n
weightsHash
32 bytes
The hash the written weights must reach at sealing.
70 + n
sectionCount
u32
Number of weight accounts, 2 to 64.
74 + n
sections
40 bytes each
Per section, in order: the weight account’s address (32 bytes) and the section’s length in bytes as u64. Each length is from 1 to 10,483,712, and each address appears once.
Accounts
#
Account
Signer
Writable
What it is
0
publisher
yes
yes
The model’s publisher. Pays the vault’s rent.
1
model
yes
yes
A zero-filled 4,096-byte account owned by the program, holding its rent.
2
modelVault
yes
The ModelVault address, seeds "model-vault" and the model’s address.
modelVault is not the address derived for this model, or systemProgram is not the System program.
What it changes
Creates modelVault at 8 bytes with the tag CURTAVLT.
Writes the Model: tag, publisher, vault address, configuration, section count, vault bump, royalty, weights hash, total weight bytes, the slot, the name and the section descriptors, each with zero bytes written.
Event
Emits a create_model event, action 2: primary is the model, actor the publisher, related the ModelVault. Values: royalty, total weight bytes, section count. Events gives the byte layout.
write_weights
Writes one chunk of a section into its weight account and sets the chunk’s bit in the upload bitmap. A chunk is 800 bytes; the last chunk of a section is the remainder. Chunks arrive in any order, and sending a chunk again with the same bytes succeeds without counting twice.
The chunk’s bit is set and the bytes differ from the ones stored, or the bit is clear and the target bytes are not all zero.
What it changes
On the first write to a section, writes the weight account’s header: the tag CURTAWGT, the model’s address and the section index.
Copies the chunk to offset 2,048 + offset of the weight account and sets bit (offset / 800) of the bitmap that starts at byte 64.
Adds the chunk’s length to the section’s bytes-written counter in the Model. A chunk whose bit is already set leaves the counter as it is.
Event
Emits a write_weights event, action 3: primary is the model, actor the publisher, related the weight account. Values: section, offset, chunk length, bytes written in the section so far. Events gives the byte layout.
seal_model
Takes one step of sealing. A step hashes the next 65,536 bytes of the section being sealed into the model’s running hash, stopping at the section’s end, and on section zero also validates 512 tokenizer entries. The step that finishes the last section compares the running hash with the weights hash and seals the model.
On section zero: the metadata does not parse, its structure is invalid, its configuration, section count or section lengths differ from the Model’s, or a tokenizer entry in this step’s 512 is invalid.
Sets the running hash to SHA-256 of the previous running hash followed by the step’s bytes. The running hash starts as 32 zero bytes.
Sets the sealing flag, which closes the model to write_weights, and adds one to the seal step.
On section zero, advances the tokenizer validation cursor by 512 entries, up to the vocabulary size. Section zero is finished when its bytes are hashed and the cursor has reached the vocabulary size.
Advances the seal byte offset, or moves to the next section with the offset at zero when the section is finished.
When the last section is finished and the hashes match, sets the sealed flag and clears the sealing flag.
Event
Emits a seal_model event, action 4: primary is the model, actor the publisher, related the weight account. Values: section, byte offset reached in it, bytes hashed in this step, sealed (1 when this step sealed the model). Events gives the byte layout.
set_royalty
Sets the model’s royalty per generated token. A run records the royalty when it opens, so the new value applies to runs opened afterwards.
Emits a set_royalty event, action 5: primary is the model, actor the publisher, related the all-zero address. Values: royalty. Events gives the byte layout.
claim_royalties
Moves lamports from the model’s vault to the publisher. An amount of zero claims everything above the vault’s rent.
Moves the amount from modelVault to publisher. The vault keeps its rent.
Event
Emits a claim_royalties event, action 6: primary is the model, actor the publisher, related the ModelVault. Values: amount claimed. Events gives the byte layout.
open_run
Opens a run on a sealed model, in a run account created earlier in the transaction. The run account arrives zero-filled at its exact size and holds its rent plus the budget. The run records the turn reward, the royalty and the protocol share rate in force, and the cost of its first turn.
Tokens to generate at most, 1 to the model’s context length.
5
temperatureQ16
u32
The temperature times 65,536, from 0 to 1,048,576 (temperature 0 to 16).
9
seed
u64
The sampling seed.
17
budget
u64
Lamports the run may spend. The run account holds them above its rent.
25
promptLength
u32
Length of the prompt in bytes, 0 to 1,024.
29
prompt
bytes
The prompt, UTF-8, with no zero byte.
Accounts
#
Account
Signer
Writable
What it is
0
opener
yes
yes
The run’s opener. Cancels and closes the run later.
1
model
yes
The Model account, sealed.
2
run
yes
A zero-filled account owned by the program, of exactly 256 bytes plus the working state.
3
config
The Config account.
4
metadata
The model’s section zero weight account.
5
systemProgram
The System program.
6
eventAuthority
The event authority address.
7
program
The curta program.
The run account’s size comes from the model’s configuration, the prompt’s byte length and maxTokens; Accounts gives the formula, and client.quote returns it as runAccountSize with the rent and the budget for the whole run. A program opens a run by CPI with its own PDA as the opener, as Call from a program shows.
Rent plus budget, or the model’s run counter, passes 64 bits.
What it changes
Writes the working state: its header, the parameters and the prompt.
Writes the run header: tag, opener, model, Config address, protocol share rate, max tokens, temperature, prompt length, seed, turn reward, royalty, budget deposited and remaining (both the budget), the working state’s length, and the slot as both opened slot and last activity slot.
Computes the cost of the first turn and stores it. The state is running when the budget covers it, starved otherwise.
Adds one to the model’s count of runs opened.
Event
Emits a open_run event, action 7: primary is the run, actor the opener, related the model. Values: budget, max tokens, temperature Q16, seed, 0, state. Events gives the byte layout.
turn
Advances the run’s forward pass as far as one transaction allows, pays the signer the turn reward from the run’s budget, and accrues the royalty and the protocol share in the run.
The run’s turn count, read from offset 184 of the run. The turn lands only while the run is still at this count.
9
nonce
u64
Any value. It makes two turn transactions with the same accounts, turn index and blockhash distinct. The builder picks a fresh one when nonce is left out.
17
weightAccountCount
u8
Matrix weight accounts that follow metadata: 1 or 2. Data that ends after expectedTurn or after nonce reads as 1.
Accounts
#
Account
Signer
Writable
What it is
0
cranker
yes
yes
Whoever lands the turn. Receives the turn reward.
1
run
yes
The Run account.
2
model
The run’s Model account.
3
config
The Config account the run records.
4
metadata
The model’s section zero weight account.
5
weights
The first matrix section the turn reads. Section zero again when the turn reads no matrix section.
6
additionalWeights
The second matrix section, present when weightAccountCount is 2.
7
eventAuthority
The event authority address.
8
program
The curta program.
With one matrix account the event authority is account 6 and the program account 7; with two they are 7 and 8. The matrix sections a turn reads follow from the run’s working state alone. The SDK computes them with the core’s planTurn, as SDK reference describes, and client.turn(run) builds the whole instruction. The turn write-locks two accounts, the run and the cranker, so turns on different runs of one model execute in parallel.
weightAccountCount differs from the number of matrix sections this turn reads, or a weight account is not the one the model names for the section the turn reads at that position.
A reward, royalty or protocol share sum passes 64 bits.
What it changes
Plans the turn from the working state: which matrix sections it reads and how many tokens it can complete at most. The reserve is the turn reward, plus the royalty for that many tokens, plus the protocol share those add.
When the budget remaining is below the reserve: sets the state to starved, stores the reserve as the cost of the next turn, and ends. The transaction succeeds, no computation runs and no reward is paid.
Otherwise runs the core on the working state, which advances the forward pass and appends the id and the text bytes of every token it completes.
Charges the budget: the turn reward, the royalty times the tokens this turn completed, and the growth of the protocol share, which is floor((rewards paid + royalties accrued) × rate / 10,000) less the share already accrued.
Writes the budget remaining, rewards paid, royalties accrued, protocol share accrued, the turn count plus one, the generated token count, the slot as last activity slot, and the cost of the next turn.
Sets the state: complete when the run reached the end token or its max tokens, starved when the budget is below the next turn’s cost, running otherwise.
Moves the turn reward from the run account to the cranker.
Event
Emits a turn event, action 8: primary is the run, actor the cranker, related the model. Values: turn count after the turn, reward paid, royalty accrued by this turn, protocol share accrued by this turn, budget remaining, state. The token list carries the id of every token the turn completed. A turn that starved the run carries the unchanged turn count, zeros for the three amounts, and no tokens. Events gives the byte layout.
fund
Moves SOL from the signer into the budget of a running or starved run. A starved run whose budget now covers its next turn returns to running.
Adds the amount to the budget deposited and the budget remaining.
Sets the state: running when the budget remaining covers the cost of the next turn, starved otherwise.
Transfers the amount from funder to the run account through the System program.
Event
Emits a fund event, action 9: primary is the run, actor the funder, related the model. Values: amount, budget remaining, state. Events gives the byte layout.
cancel
Marks a running or starved run cancelled. Turns stop, and the royalty and protocol share accrued so far stay owed until settlement.
The run account holds fewer lamports than the amounts owed.
What it changes
Adds the run’s generated tokens to the model’s tokens settled and its accrued royalty to the model’s royalties settled.
Sets the run’s settled flag.
Moves the accrued royalty from the run account to modelVault and the accrued protocol share to feeVault.
Event
Emits a settle event, action 11: primary is the run, actor the caller, related the model. Values: royalty paid, protocol share paid, turn rewards the run paid in total, tokens generated. Events gives the byte layout.
close_run
Closes a settled run and returns every lamport in the account to the opener: the unspent budget and the rent.
Tag
12
Signer
The opener
Data length
1 byte
Builder
closeRunInstruction({ opener, run, programId? })
Data
Offset
Field
Type
Meaning
0
tag
u8
12
Accounts
#
Account
Signer
Writable
What it is
0
opener
yes
yes
The opener the run records. Receives the lamports.
Moves the run account’s whole balance to the opener.
Resizes the run account to zero bytes and assigns it to the System program.
Event
Emits a close_run event, action 12: primary is the run, actor the opener, related the model. Values: lamports returned. Events gives the byte layout.
Sending an instruction
The builders return a TransactionInstruction. client.send puts a compute unit limit of 1,400,000 in front, signs with the client’s wallet and any extra signers, and resolves with the signature once the transaction is confirmed.