accounts.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import * as BufferLayout from "buffer-layout";
  2. import { publicKey, uint64, coption, bool } from "./buffer-layout.js";
  3. import { AccountsCoder } from "../index.js";
  4. import { Idl, IdlTypeDef } from "../../idl.js";
  5. import { accountSize } from "../common";
  6. export class SplTokenAccountsCoder<A extends string = string>
  7. implements AccountsCoder
  8. {
  9. constructor(private idl: Idl) {}
  10. public async encode<T = any>(accountName: A, account: T): Promise<Buffer> {
  11. switch (accountName) {
  12. case "token": {
  13. const buffer = Buffer.alloc(165);
  14. const len = TOKEN_ACCOUNT_LAYOUT.encode(account, buffer);
  15. return buffer.slice(0, len);
  16. }
  17. case "mint": {
  18. const buffer = Buffer.alloc(82);
  19. const len = MINT_ACCOUNT_LAYOUT.encode(account, buffer);
  20. return buffer.slice(0, len);
  21. }
  22. default: {
  23. throw new Error(`Invalid account name: ${accountName}`);
  24. }
  25. }
  26. }
  27. public decode<T = any>(accountName: A, ix: Buffer): T {
  28. return this.decodeUnchecked(accountName, ix);
  29. }
  30. public decodeUnchecked<T = any>(accountName: A, ix: Buffer): T {
  31. switch (accountName) {
  32. case "token": {
  33. return decodeTokenAccount(ix);
  34. }
  35. case "mint": {
  36. return decodeMintAccount(ix);
  37. }
  38. default: {
  39. throw new Error(`Invalid account name: ${accountName}`);
  40. }
  41. }
  42. }
  43. // TODO: this won't use the appendData.
  44. public memcmp(accountName: A, _appendData?: Buffer): any {
  45. switch (accountName) {
  46. case "token": {
  47. return {
  48. dataSize: 165,
  49. };
  50. }
  51. case "mint": {
  52. return {
  53. dataSize: 82,
  54. };
  55. }
  56. default: {
  57. throw new Error(`Invalid account name: ${accountName}`);
  58. }
  59. }
  60. }
  61. public size(idlAccount: IdlTypeDef): number {
  62. return accountSize(this.idl, idlAccount) ?? 0;
  63. }
  64. }
  65. function decodeMintAccount<T = any>(ix: Buffer): T {
  66. return MINT_ACCOUNT_LAYOUT.decode(ix) as T;
  67. }
  68. function decodeTokenAccount<T = any>(ix: Buffer): T {
  69. return TOKEN_ACCOUNT_LAYOUT.decode(ix) as T;
  70. }
  71. const MINT_ACCOUNT_LAYOUT = BufferLayout.struct([
  72. coption(publicKey(), "mintAuthority"),
  73. uint64("supply"),
  74. BufferLayout.u8("decimals"),
  75. bool("isInitialized"),
  76. coption(publicKey(), "freezeAuthority"),
  77. ]);
  78. const TOKEN_ACCOUNT_LAYOUT = BufferLayout.struct([
  79. publicKey("mint"),
  80. publicKey("authority"),
  81. uint64("amount"),
  82. coption(publicKey(), "delegate"),
  83. BufferLayout.u8("state"),
  84. coption(uint64(), "isNative"),
  85. uint64("delegatedAmount"),
  86. coption(publicKey(), "closeAuthority"),
  87. ]);