DocsReference

Instructions

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.

TagInstructionFamilyWho signs
0init_configConfigThe program’s upgrade authority
1set_configConfigThe Config authority
2create_modelModelThe publisher and the model keypair
3write_weightsModelThe publisher
4seal_modelModelThe publisher
5set_royaltyModelThe publisher
6claim_royaltiesModelThe publisher
7open_runRunThe opener, a wallet or a program’s PDA
8turnRunAnyone
9fundRunAnyone
10cancelRunThe opener
11settleRunAnyone
12close_runRunThe opener

Checks every instruction makes

These run on every instruction, and the tables further down list what each instruction checks beyond them.

ErrorRaised when
InvalidAccountThe program id of the instruction is not the curta program.
InvalidInstructionThe data is empty, or its first byte is not a tag from 0 to 12.
InvalidAccountThe account list is not exactly the instruction’s own accounts plus the two trailing ones, or the last account is not the executable curta program.
InvalidInstructionThe arguments are shorter than the instruction’s layout, or bytes remain after the last argument.
MissingSignatureAn account the instruction requires as signer did not sign.
InvalidAccountAn account the instruction writes is not marked writable.
InvalidEventThe account before the last is not the event authority address.

Each Config, Model, Run, weight or vault account an instruction takes is checked by type:

ErrorRaised when
InvalidOwnerA Config, Model, Run, weight or vault account is not owned by the curta program.
InvalidSizeThe 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.
InvalidAccountThe account’s first eight bytes are not its type’s tag, or a Config account is not at the address derived from "config".

init_config

Creates the Config account and the FeeVault, and sets the turn reward and the protocol share rate. It runs once per program.

Tag0
SignerThe program’s upgrade authority
Data length13 bytes
BuilderinitConfigInstruction({ authority, turnRewardLamports, protocolShareBps, programId? })

Data

OffsetFieldTypeMeaning
0tagu80
1turnRewardu64Lamports paid to the cranker for each turn. Greater than zero.
9protocolShareBpsu16The protocol share rate in basis points, 0 to 10,000.
11configBumpu8The bump of the Config address.
12feeBumpu8The bump of the FeeVault address.

Accounts

#AccountSignerWritableWhat it is
0authorityyesyesThe program’s upgrade authority. Pays the rent of both accounts and becomes the Config authority.
1configyesThe Config address, seeds "config".
2feeVaultyesThe FeeVault address, seeds "fee".
3systemProgramThe System program.
4programDataThe program’s ProgramData account under the upgradeable loader.
5eventAuthorityThe event authority address.
6programThe curta program.

Checks

ErrorRaised when
InvalidConfigThe turn reward is zero, or the protocol share is above 10,000 basis points.
InvalidAuthorityprogramData is not owned by the upgradeable loader, is not a ProgramData account, or names an upgrade authority other than the signer.
InvalidAuthorityThe curta program account does not point at the programData account passed.
InvalidAccountconfig or feeVault is not the address its seeds and the bump passed derive.
InvalidAccountsystemProgram is not the System program.
AlreadyInitializedconfig 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.

Tag1
SignerThe Config authority
Data length11 bytes
BuildersetConfigInstruction({ authority, turnRewardLamports, protocolShareBps, programId? })

Data

OffsetFieldTypeMeaning
0tagu81
1turnRewardu64Lamports per turn. Greater than zero.
9protocolShareBpsu16Basis points, 0 to 10,000.

Accounts

#AccountSignerWritableWhat it is
0authorityyesThe authority the Config records.
1configyesThe Config account.
2eventAuthorityThe event authority address.
3programThe curta program.

Checks

ErrorRaised when
InvalidConfigThe turn reward is zero, or the protocol share is above 10,000 basis points.
InvalidAuthorityThe 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.

Tag2
SignerThe publisher and the model keypair
Data length74 bytes, plus the name, plus 40 bytes per section
BuildercreateModelInstruction({ publisher, model, config, name, royaltyLamports, expectedHash, sections, programId? })

Data

OffsetFieldTypeMeaning
0tagu82
1royaltyu64Lamports per generated token, paid to the model’s vault.
9config7 × u32dimension, 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.
37nameLengthu8Length of the name in bytes, 1 to 64. Called n below.
38namebytesThe model’s name, UTF-8, n bytes.
38 + nweightsHash32 bytesThe hash the written weights must reach at sealing.
70 + nsectionCountu32Number of weight accounts, 2 to 64.
74 + nsections40 bytes eachPer 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

#AccountSignerWritableWhat it is
0publisheryesyesThe model’s publisher. Pays the vault’s rent.
1modelyesyesA zero-filled 4,096-byte account owned by the program, holding its rent.
2modelVaultyesThe ModelVault address, seeds "model-vault" and the model’s address.
3systemProgramThe System program.
4eventAuthorityThe event authority address.
5programThe curta program.

Checks

ErrorRaised when
InvalidOwnermodel is not owned by the curta program.
InvalidSizemodel is not exactly 4,096 bytes.
AlreadyInitializedmodel’s first 256 bytes are not all zero, or modelVault already holds data.
InvalidConfigThe configuration is outside the supported ranges.
InvalidModelThe name is empty, longer than 64 bytes, or not UTF-8.
InvalidWeightsThe section count is below 2 or above 64, a section length is zero or above 10,483,712 bytes, or two sections name the same address.
ArithmeticOverflowThe section lengths sum past 64 bits.
InsufficientFundsmodel holds fewer lamports than the rent of 4,096 bytes.
InvalidAccountmodelVault 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.

Tag3
SignerThe publisher
Data length13 bytes plus the chunk
BuilderwriteWeightsInstruction({ publisher, model, weights, section, offset, bytes, programId? })

Data

OffsetFieldTypeMeaning
0tagu83
1sectionu32Index of the section, from zero.
5offsetu64Byte offset of the chunk inside the section. A multiple of 800.
13chunkbytesThe rest of the data: 800 bytes, or the bytes left in the section from the offset when fewer than 800 remain.

Accounts

#AccountSignerWritableWhat it is
0publisheryesThe publisher the model records.
1modelyesThe Model account.
2weightsyesThe weight account the model names for this section: 2,048 bytes plus the section’s length, owned by the program.
3eventAuthorityThe event authority address.
4programThe curta program.

Checks

ErrorRaised when
InvalidInstructionThe chunk is empty.
InvalidAuthorityThe signer is not the model’s publisher.
InvalidStateThe model is sealed, or sealing has begun.
InvalidWeightsThe section index is not below the model’s section count, or weights is not the address the model names for that section.
InvalidOffsetThe offset is not a multiple of 800.
InvalidSizeThe chunk runs past the section’s end, or its length is not the smaller of 800 and the bytes left from the offset.
InvalidOwnerweights is not owned by the curta program.
InvalidSizeweights is not exactly 2,048 bytes plus the section’s length.
AlreadyInitializedThe section has no bytes written and the weight account’s 2,048-byte header is not all zero.
InvalidWeightsThe section has bytes written and the weight account’s header does not carry this model and section.
InvalidWeightsThe 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.

Tag4
SignerThe publisher
Data length9 bytes
BuildersealModelInstruction({ publisher, model, weights, expectedStep, programId? })

Data

OffsetFieldTypeMeaning
0tagu84
1expectedStepu64The model’s seal step, read from offset 312 of the Model. Zero for the first step.

Accounts

#AccountSignerWritableWhat it is
0publisheryesThe publisher the model records.
1modelyesThe Model account.
2weightsThe weight account of the section being sealed, the one at the index in the Model’s offset 108.
3eventAuthorityThe event authority address.
4programThe curta program.

Checks

ErrorRaised when
InvalidAuthorityThe signer is not the model’s publisher.
InvalidStateThe model is already sealed.
InvalidOffsetexpectedStep is not the model’s seal step.
InvalidWeightsA section’s bytes written differ from its length.
InvalidWeightsweights is not the address the model names for the section being sealed, or its header does not carry this model and section.
InvalidOwnerweights is not owned by the curta program.
InvalidSizeweights is not exactly 2,048 bytes plus the section’s length.
InvalidWeightsOn 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.
HashMismatchThe step finishes the last section and the running hash differs from the weights hash.
ArithmeticOverflowThe seal step passes 64 bits.

What it changes

  • 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.

Tag5
SignerThe publisher
Data length9 bytes
BuildersetRoyaltyInstruction({ publisher, model, royaltyLamports, programId? })

Data

OffsetFieldTypeMeaning
0tagu85
1royaltyu64Lamports per generated token.

Accounts

#AccountSignerWritableWhat it is
0publisheryesThe publisher the model records.
1modelyesThe Model account.
2eventAuthorityThe event authority address.
3programThe curta program.

Checks

ErrorRaised when
InvalidAuthorityThe signer is not the model’s publisher.

What it changes

  • Writes the royalty at offset 120 of the Model.

Event

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.

Tag6
SignerThe publisher
Data length9 bytes
BuilderclaimRoyaltiesInstruction({ publisher, model, amountLamports?, programId? })

Data

OffsetFieldTypeMeaning
0tagu86
1amountu64Lamports to claim. Zero means the whole balance above the vault’s rent. The builder sends zero when amountLamports is left out.

Accounts

#AccountSignerWritableWhat it is
0publisheryesyesThe publisher the model records. Receives the lamports.
1modelThe Model account.
2modelVaultyesThe vault the model records.
3eventAuthorityThe event authority address.
4programThe curta program.

Checks

ErrorRaised when
InvalidAuthorityThe signer is not the model’s publisher, or modelVault is not the vault the model records.
InsufficientFundsThe amount is above the vault’s balance less the rent of 8 bytes.
InvalidAccountpublisher and modelVault are the same account.

What it changes

  • 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.

Tag7
SignerThe opener, a wallet or a program’s PDA
Data length29 bytes plus the prompt
BuilderopenRunInstruction({ opener, model, run, metadata, prompt, maxTokens, temperatureQ16, seed, budgetLamports, programId? })

Data

OffsetFieldTypeMeaning
0tagu87
1maxTokensu32Tokens to generate at most, 1 to the model’s context length.
5temperatureQ16u32The temperature times 65,536, from 0 to 1,048,576 (temperature 0 to 16).
9seedu64The sampling seed.
17budgetu64Lamports the run may spend. The run account holds them above its rent.
25promptLengthu32Length of the prompt in bytes, 0 to 1,024.
29promptbytesThe prompt, UTF-8, with no zero byte.

Accounts

#AccountSignerWritableWhat it is
0openeryesyesThe run’s opener. Cancels and closes the run later.
1modelyesThe Model account, sealed.
2runyesA zero-filled account owned by the program, of exactly 256 bytes plus the working state.
3configThe Config account.
4metadataThe model’s section zero weight account.
5systemProgramThe System program.
6eventAuthorityThe event authority address.
7programThe 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.

Checks

ErrorRaised when
InvalidAccountsystemProgram is not the System program, or run and opener are the same account.
InvalidStateThe model is not sealed.
InvalidConfigThe prompt is longer than 1,024 bytes, or maxTokens is zero or above the model’s context length.
InvalidOwnerrun is not owned by the curta program.
InvalidSizerun is not exactly 256 bytes plus the working state for this prompt length and maxTokens.
AlreadyInitializedrun’s first 256 bytes are not all zero.
InvalidWeightsmetadata is not the model’s section zero account, its header does not carry this model, or its configuration differs from the Model’s.
InsufficientFundsrun holds fewer lamports than its rent plus the budget.
CoreErrorThe prompt contains a zero byte or is not UTF-8, or the temperature is above 1,048,576.
ArithmeticOverflowRent 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.

Tag8
SignerAnyone
Data length18 bytes
BuilderturnInstruction({ cranker, run, model, metadata, weights, additionalWeights?, expectedTurn, nonce?, programId? })

Data

OffsetFieldTypeMeaning
0tagu88
1expectedTurnu64The run’s turn count, read from offset 184 of the run. The turn lands only while the run is still at this count.
9nonceu64Any 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.
17weightAccountCountu8Matrix weight accounts that follow metadata: 1 or 2. Data that ends after expectedTurn or after nonce reads as 1.

Accounts

#AccountSignerWritableWhat it is
0crankeryesyesWhoever lands the turn. Receives the turn reward.
1runyesThe Run account.
2modelThe run’s Model account.
3configThe Config account the run records.
4metadataThe model’s section zero weight account.
5weightsThe first matrix section the turn reads. Section zero again when the turn reads no matrix section.
6additionalWeightsThe second matrix section, present when weightAccountCount is 2.
7eventAuthorityThe event authority address.
8programThe 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.

Checks

ErrorRaised when
InvalidInstructionweightAccountCount is not 1 or 2.
InvalidAccountcranker and run are the same account, or model, config or a weight account is marked writable.
InvalidModelmodel or config is not the one the run records, or the model is not sealed.
InvalidStateThe run is not running.
StaleTurnexpectedTurn is not the run’s turn count: another turn landed first.
InvalidSizeThe run account’s length is not 256 bytes plus the working state length it records.
InvalidWeightsweightAccountCount 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.
InvalidOwnerA weight account is not owned by the curta program.
CoreErrorThe inference core returns an error while planning or computing the turn.
InsufficientBudgetThe turn’s charge is above the budget remaining.
ArithmeticOverflowA 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.

Tag9
SignerAnyone
Data length9 bytes
BuilderfundInstruction({ funder, run, amountLamports, programId? })

Data

OffsetFieldTypeMeaning
0tagu89
1amountu64Lamports to add. Greater than zero.

Accounts

#AccountSignerWritableWhat it is
0funderyesyesWhoever pays. A System-owned account.
1runyesThe Run account.
2systemProgramThe System program.
3eventAuthorityThe event authority address.
4programThe curta program.

Checks

ErrorRaised when
InvalidAccountsystemProgram is not the System program, or funder and run are the same account.
InvalidInstructionThe amount is zero.
InvalidStateThe run is complete or cancelled.
ArithmeticOverflowThe budget deposited or remaining passes 64 bits.

What it changes

  • 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.

Tag10
SignerThe opener
Data length1 byte
BuildercancelInstruction({ opener, run, programId? })

Data

OffsetFieldTypeMeaning
0tagu810

Accounts

#AccountSignerWritableWhat it is
0openeryesThe opener the run records.
1runyesThe Run account.
2eventAuthorityThe event authority address.
3programThe curta program.

Checks

ErrorRaised when
InvalidAuthorityThe signer is not the run’s opener.
InvalidStateThe run is complete or already cancelled.

What it changes

  • Sets the state to cancelled.

Event

Emits a cancel event, action 10: primary is the run, actor the opener, related the model. Values: budget remaining. Events gives the byte layout.

settle

Pays out what a complete or cancelled run accrued: the royalty to the model’s vault and the protocol share to the FeeVault. It runs once per run.

Tag11
SignerAnyone
Data length1 byte
BuildersettleInstruction({ caller, run, model, programId? })

Data

OffsetFieldTypeMeaning
0tagu811

Accounts

#AccountSignerWritableWhat it is
0calleryesWhoever sends it.
1runyesThe Run account.
2modelyesThe run’s Model account.
3modelVaultyesThe vault the model records.
4feeVaultyesThe FeeVault the Config records.
5configThe Config account the run records.
6eventAuthorityThe event authority address.
7programThe curta program.

Checks

ErrorRaised when
InvalidStateThe run is running or starved, or is already settled.
InvalidModelmodel or config is not the one the run records.
InvalidAccountmodelVault is not the vault the model records, or feeVault is not the one the Config records.
ArithmeticOverflowThe model’s token or royalty counter passes 64 bits.
InsufficientFundsThe 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.

Tag12
SignerThe opener
Data length1 byte
BuildercloseRunInstruction({ opener, run, programId? })

Data

OffsetFieldTypeMeaning
0tagu812

Accounts

#AccountSignerWritableWhat it is
0openeryesyesThe opener the run records. Receives the lamports.
1runyesThe Run account, settled.
2eventAuthorityThe event authority address.
3programThe curta program.

Checks

ErrorRaised when
InvalidAuthorityThe signer is not the run’s opener.
NotSettledThe run’s settled flag is clear.
InvalidAccountopener and run are the same account.

What it changes

  • 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.

fund.ts
import { fundInstruction } from '@curta/sdk'

const signature = await curta.send([
  fundInstruction({ funder: curta.wallet!.publicKey, run, amountLamports: 1_000_000n }),
])