prelude.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. # seahorse.prelude: the basis for writing Seahorse programs.
  2. #
  3. # NOTE: this file just contains types and documentation for your editor. This
  4. # is NOT executable code, and you won't be able to change the behavior of your
  5. # Seahorse programs by editing this file.
  6. from typing import *
  7. from math import floor, ceil
  8. T = TypeVar('T')
  9. N = TypeVar('N')
  10. # ===========================================================
  11. # Internal types - here for completeness, but not really used
  12. # ===========================================================
  13. class ProgramResult:
  14. """Result from executing an instruction - either a success, or a failure with an error message."""
  15. # ==========
  16. # Rust types
  17. # ==========
  18. class u8:
  19. """Single-byte unsigned integer."""
  20. def __init__(self, _: Any):
  21. return self
  22. def __add__(self, _: Any):
  23. return self
  24. def __radd__(self, _: Any):
  25. return self
  26. def __iadd__(self, _: Any):
  27. return self
  28. def __sub__(self, _: Any):
  29. return self
  30. def __rsub__(self, _: Any):
  31. return self
  32. def __isub__(self, _: Any):
  33. return self
  34. def __mul__(self, _: Any):
  35. return self
  36. def __rmul__(self, _: Any):
  37. return self
  38. def __imul__(self, _: Any):
  39. return self
  40. def __div__(self, _: Any):
  41. return self
  42. def __rdiv__(self, _: Any):
  43. return self
  44. def __idiv__(self, _: Any):
  45. return self
  46. class u64:
  47. """64-bit unsigned integer."""
  48. def __init__(self, _: Any):
  49. return self
  50. def __add__(self, _: Any):
  51. return self
  52. def __radd__(self, _: Any):
  53. return self
  54. def __iadd__(self, _: Any):
  55. return self
  56. def __sub__(self, _: Any):
  57. return self
  58. def __rsub__(self, _: Any):
  59. return self
  60. def __isub__(self, _: Any):
  61. return self
  62. def __mul__(self, _: Any):
  63. return self
  64. def __rmul__(self, _: Any):
  65. return self
  66. def __imul__(self, _: Any):
  67. return self
  68. def __div__(self, _: Any):
  69. return self
  70. def __rdiv__(self, _: Any):
  71. return self
  72. def __idiv__(self, _: Any):
  73. return self
  74. class i64:
  75. """64-bit signed integer."""
  76. def __init__(self, _: Any):
  77. return self
  78. def __add__(self, _: Any):
  79. return self
  80. def __radd__(self, _: Any):
  81. return self
  82. def __iadd__(self, _: Any):
  83. return self
  84. def __sub__(self, _: Any):
  85. return self
  86. def __rsub__(self, _: Any):
  87. return self
  88. def __isub__(self, _: Any):
  89. return self
  90. def __mul__(self, _: Any):
  91. return self
  92. def __rmul__(self, _: Any):
  93. return self
  94. def __imul__(self, _: Any):
  95. return self
  96. def __div__(self, _: Any):
  97. return self
  98. def __rdiv__(self, _: Any):
  99. return self
  100. def __idiv__(self, _: Any):
  101. return self
  102. class f64:
  103. """64-bit floating point number."""
  104. def __add__(self, _: Any):
  105. return self
  106. def __radd__(self, _: Any):
  107. return self
  108. def __iadd__(self, _: Any):
  109. return self
  110. def __sub__(self, _: Any):
  111. return self
  112. def __rsub__(self, _: Any):
  113. return self
  114. def __isub__(self, _: Any):
  115. return self
  116. def __mul__(self, _: Any):
  117. return self
  118. def __rmul__(self, _: Any):
  119. return self
  120. def __imul__(self, _: Any):
  121. return self
  122. def __div__(self, _: Any):
  123. return self
  124. def __rdiv__(self, _: Any):
  125. return self
  126. def __idiv__(self, _: Any):
  127. return self
  128. class Array(Generic[T, N]):
  129. """A fixed-length array: contains type T and has size N.
  130. Lists (Python builtin type) can coerce to this type. Example:
  131. ```
  132. class MyData(Account):
  133. data: Array[u64, 4]
  134. @instruction
  135. def set_data(my_data: MyData):
  136. # Will successfully set `data` to [0, 1, 2, 3]
  137. my_data.data = [i for i in range(0, 4)]
  138. # Will attempt (and fail, crashing the instruction at runtime!) to set `data` to [0, 1, 2, 3, 4]
  139. my_data.data = [i for i in range(0, 5)]
  140. ```
  141. """
  142. class Enum:
  143. """A type that can have one of multiple named values.
  144. Note that unlike Rust enums, these cannot contain any data (other than the variant itself). Example:
  145. ```
  146. class MyEnum(Enum):
  147. ONE = 1
  148. TWO = 2
  149. THREE = 3
  150. @instruction
  151. def use_enum(code: MyEnum):
  152. if code == MyEnum.ONE:
  153. print(1)
  154. # ...
  155. ```
  156. """
  157. # ============
  158. # Solana types
  159. # ============
  160. class Pubkey:
  161. """32-byte account identifier."""
  162. class SolanaAccount:
  163. """Generic Solana account."""
  164. def key(self) -> Pubkey:
  165. """Get this account's key."""
  166. def transfer_lamports(self, to: SolanaAccount, amount: u64):
  167. """Transfer some SOL (as an amount of lamports) to another account.
  168. Note: this will successfully transfer from a program-owned account without needing to
  169. provide the seeds for a PDA, so no signer field is required (unlike the SPL methods).
  170. """
  171. class Account(SolanaAccount):
  172. """User-defined Solana account."""
  173. class Signer(SolanaAccount):
  174. """Instruction signer."""
  175. class Empty(Generic[T]):
  176. """An account that needs to be initialized."""
  177. def bump(self) -> u8:
  178. """Get this account's bump, needed if you want to use this account to sign CPI calls."""
  179. def init(self, payer: Signer, seeds: List[Union[str, Account, u8]], mint: TokenMint, authority: Account) -> T:
  180. """
  181. Initialize the account.
  182. @param payer: The account that will pay for the rent cost of the initialized account. Must be an instruction signer.
  183. @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.
  184. @param mint: If initializing a TokenAccount, this is the mint that the account belongs to.
  185. @param decimals: If initializing a TokenMint, this is the number of decimals the new token has.
  186. @param authority: If initializing a TokenAccount/TokenMint, this is the account that has authority over the account.
  187. @returns: The new, initialized account. All of the data in this account will be set to 0.
  188. """
  189. class TokenAccount(SolanaAccount):
  190. """SPL token account."""
  191. def authority(self) -> Pubkey:
  192. """Get the owner of this token account."""
  193. def amount(self) -> u64:
  194. """Get the amount of token stored in this account."""
  195. def transfer(self, authority: SolanaAccount, to: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None):
  196. """
  197. Transfer funds from this SPL token account to another.
  198. @param authority: The account that owns this TokenAccount. Must be an instruction signer or the account given by the `signer` param.
  199. @param to: The recipient TokenAccount.
  200. @param amount: How much (in *native* token units) to transfer.
  201. @param signer: (Optional) seeds for the signature of a PDA.
  202. """
  203. class TokenMint(SolanaAccount):
  204. """SPL token mint."""
  205. def authority(self) -> Pubkey:
  206. """Get the owner of this token account."""
  207. def mint(self, authority: SolanaAccount, to: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None):
  208. """
  209. Mint new tokens to a token account.
  210. @param authority: The account that owns this TokenMint. Must be an instruction signer or the account given by the `signer` param.
  211. @param to: The recipient TokenAccount.
  212. @param amount: How much (in *native* token units) to mint.
  213. @param signer: (Optional) seeds for the signature of a PDA.
  214. """
  215. def burn(self, authority: SolanaAccount, holder: TokenAccount, amount: u64, signer: List[Union[str, Account, u8]] = None):
  216. """
  217. Burn tokens from a token account.
  218. @param authority: The account that owns the `holder` TokenAccount. Must be an instruction signer or the account given by the `signer` param.
  219. @param holder: The TokenAccount to burn from.
  220. @param amount: How much (in *native* token units) to burn.
  221. @param signer: (Optional) seeds for the signature of a PDA.
  222. """
  223. # ================
  224. # Helper functions
  225. # ================
  226. def declare_id(id: str):
  227. """Inform Anchor what this program's ID is.
  228. @param id: The program's ID, generated by Anchor in /target/idl/<program>.json. This must be copied-pasted straight from there as a string literal.
  229. """
  230. def instruction(function: Callable[..., None]) -> Callable[..., ProgramResult]:
  231. """Decorator to turn a function into a program instruction."""