# seahorse.prelude: the basis for writing Seahorse programs. # # NOTE: this file just contains types and documentation for your editor. This # is NOT executable code, and you won't be able to change the behavior of your # Seahorse programs by editing this file. from typing import * from math import floor, ceil T = TypeVar('T') N = TypeVar('N') # =========================================================== # Internal types - here for completeness, but not really used # =========================================================== class ProgramResult: """Result from executing an instruction - either a success, or a failure with an error message.""" # ========== # Rust types # ========== class u8: """Single-byte unsigned integer.""" def __init__(self, _: Any): return self def __add__(self, _: Any): return self def __radd__(self, _: Any): return self def __iadd__(self, _: Any): return self def __sub__(self, _: Any): return self def __rsub__(self, _: Any): return self def __isub__(self, _: Any): return self def __mul__(self, _: Any): return self def __rmul__(self, _: Any): return self def __imul__(self, _: Any): return self def __div__(self, _: Any): return self def __rdiv__(self, _: Any): return self def __idiv__(self, _: Any): return self class u64: """64-bit unsigned integer.""" def __init__(self, _: Any): return self def __add__(self, _: Any): return self def __radd__(self, _: Any): return self def __iadd__(self, _: Any): return self def __sub__(self, _: Any): return self def __rsub__(self, _: Any): return self def __isub__(self, _: Any): return self def __mul__(self, _: Any): return self def __rmul__(self, _: Any): return self def __imul__(self, _: Any): return self def __div__(self, _: Any): return self def __rdiv__(self, _: Any): return self def __idiv__(self, _: Any): return self class i64: """64-bit signed integer.""" def __init__(self, _: Any): return self def __add__(self, _: Any): return self def __radd__(self, _: Any): return self def __iadd__(self, _: Any): return self def __sub__(self, _: Any): return self def __rsub__(self, _: Any): return self def __isub__(self, _: Any): return self def __mul__(self, _: Any): return self def __rmul__(self, _: Any): return self def __imul__(self, _: Any): return self def __div__(self, _: Any): return self def __rdiv__(self, _: Any): return self def __idiv__(self, _: Any): return self class f64: """64-bit floating point number.""" def __add__(self, _: Any): return self def __radd__(self, _: Any): return self def __iadd__(self, _: Any): return self def __sub__(self, _: Any): return self def __rsub__(self, _: Any): return self def __isub__(self, _: Any): return self def __mul__(self, _: Any): return self def __rmul__(self, _: Any): return self def __imul__(self, _: Any): return self def __div__(self, _: Any): return self def __rdiv__(self, _: Any): return self def __idiv__(self, _: Any): return self class Array(Generic[T, N]): """A fixed-length array: contains type T and has size N. Lists (Python builtin type) can coerce to this type. Example: ``` class MyData(Account): data: Array[u64, 4] @instruction def set_data(my_data: MyData): # Will successfully set `data` to [0, 1, 2, 3] my_data.data = [i for i in range(0, 4)] # Will attempt (and fail, crashing the instruction at runtime!) to set `data` to [0, 1, 2, 3, 4] my_data.data = [i for i in range(0, 5)] ``` """ class Enum: """A type that can have one of multiple named values. Note that unlike Rust enums, these cannot contain any data (other than the variant itself). Example: ``` class MyEnum(Enum): ONE = 1 TWO = 2 THREE = 3 @instruction def use_enum(code: MyEnum): if code == MyEnum.ONE: print(1) # ... ``` """ # ============ # Solana types # ============ class Pubkey: """32-byte account identifier.""" class SolanaAccount: """Generic Solana account.""" def key(self) -> Pubkey: """Get this account's key.""" def transfer_lamports(self, to: SolanaAccount, amount: u64): """Transfer some SOL (as an amount of lamports) to another account. Note: this will successfully transfer from a program-owned account without needing to provide the seeds for a PDA, so no signer field is required (unlike the SPL methods). """ class Account(SolanaAccount): """User-defined Solana account.""" class Signer(SolanaAccount): """Instruction signer.""" class Empty(Generic[T]): """An account that needs to be initialized.""" def bump(self) -> u8: """Get this account's bump, needed if you want to use this account to sign CPI calls.""" def init(self, payer: Signer, seeds: List[Union[str, Account, u8]], mint: TokenMint, authority: Account) -> T: """ Initialize the account. @param payer: The account that will pay for the rent cost of the initialized account. Must be an instruction signer. @param seeds: A list of parameters to uniquely identify this account among all accounts created by your program. These may be string literals or other accounts. @param mint: If initializing a TokenAccount, this is the mint that the account belongs to. @param decimals: If initializing a TokenMint, this is the number of decimals the new token has. @param authority: If initializing a TokenAccount/TokenMint, this is the account that has authority over the account. @returns: The new, initialized account. All of the data in this account will be set to 0. """ class TokenAccount(SolanaAccount): """SPL token account.""" def authority(self) -> Pubkey: """Get the owner of this token account.""" def amount(self) -> u64: """Get the amount of token stored in this account.""" def transfer(self, authority: SolanaAccount, to: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None): """ Transfer funds from this SPL token account to another. @param authority: The account that owns this TokenAccount. Must be an instruction signer or the account given by the `signer` param. @param to: The recipient TokenAccount. @param amount: How much (in *native* token units) to transfer. @param signer: (Optional) seeds for the signature of a PDA. """ class TokenMint(SolanaAccount): """SPL token mint.""" def authority(self) -> Pubkey: """Get the owner of this token account.""" def mint(self, authority: SolanaAccount, to: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None): """ Mint new tokens to a token account. @param authority: The account that owns this TokenMint. Must be an instruction signer or the account given by the `signer` param. @param to: The recipient TokenAccount. @param amount: How much (in *native* token units) to mint. @param signer: (Optional) seeds for the signature of a PDA. """ def burn(self, authority: SolanaAccount, holder: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None): """ Burn tokens from a token account. @param authority: The account that owns the `holder` TokenAccount. Must be an instruction signer or the account given by the `signer` param. @param holder: The TokenAccount to burn from. @param amount: How much (in *native* token units) to burn. @param signer: (Optional) seeds for the signature of a PDA. """ # ================ # Helper functions # ================ def declare_id(id: str): """Inform Anchor what this program's ID is. @param id: The program's ID, generated by Anchor in /target/idl/.json. This must be copied-pasted straight from there as a string literal. """ def instruction(function: Callable[..., None]) -> Callable[..., ProgramResult]: """Decorator to turn a function into a program instruction."""