state.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { Buffer } from "buffer";
  2. import { Layout } from "buffer-layout";
  3. import { sha256 } from "js-sha256";
  4. import { Idl } from "../../idl.js";
  5. import { IdlCoder } from "./idl.js";
  6. import * as features from '../../utils/features';
  7. import { BorshAccountHeader } from "./accounts";
  8. export class BorshStateCoder {
  9. private layout: Layout;
  10. private header: BorshAccountHeader;
  11. public constructor(idl: Idl, header: BorshAccountHeader) {
  12. if (idl.state === undefined) {
  13. throw new Error("Idl state not defined.");
  14. }
  15. this.layout = IdlCoder.typeDefLayout(idl.state.struct, idl.types);
  16. this.header = header;
  17. }
  18. public async encode<T = any>(name: string, account: T): Promise<Buffer> {
  19. const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer.
  20. const len = this.layout.encode(account, buffer);
  21. let ns = features.isSet("anchor-deprecated-state") ? "account" : "state";
  22. const header = this.header.encode(name, ns);
  23. const accData = buffer.slice(0, len);
  24. return Buffer.concat([header, accData]);
  25. }
  26. public decode<T = any>(data: Buffer): T {
  27. // Chop off header.
  28. data = data.slice(BorshAccountHeader.size());
  29. return this.layout.decode(data);
  30. }
  31. }
  32. // Calculates unique 8 byte discriminator prepended to all anchor state accounts.
  33. export async function stateDiscriminator(name: string): Promise<Buffer> {
  34. let ns = features.isSet("anchor-deprecated-state") ? "account" : "state";
  35. return Buffer.from(sha256.digest(`${ns}:${name}`)).slice(
  36. 0,
  37. this.header.discriminatorSize()
  38. );
  39. }