123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import { AccountsCoder } from "../index.js";
- import { Idl, IdlTypeDef } from "../../idl.js";
- import * as BufferLayout from "buffer-layout";
- import { NONCE_ACCOUNT_LENGTH, PublicKey } from "@solana/web3.js";
- import { accountSize } from "../common.js";
- export class SystemAccountsCoder<A extends string = string>
- implements AccountsCoder
- {
- constructor(private idl: Idl) {}
- public async encode<T = any>(accountName: A, account: T): Promise<Buffer> {
- switch (accountName) {
- case "nonce": {
- const buffer = Buffer.alloc(NONCE_ACCOUNT_LENGTH);
- const len = NONCE_ACCOUNT_LAYOUT.encode(account, buffer);
- return buffer.slice(0, len);
- }
- default: {
- throw new Error(`Invalid account name: ${accountName}`);
- }
- }
- }
- public decode<T = any>(accountName: A, ix: Buffer): T {
- return this.decodeUnchecked(accountName, ix);
- }
- public decodeUnchecked<T = any>(accountName: A, ix: Buffer): T {
- switch (accountName) {
- case "nonce": {
- return decodeNonceAccount(ix);
- }
- default: {
- throw new Error(`Invalid account name: ${accountName}`);
- }
- }
- }
- // TODO: this won't use the appendData.
- public memcmp(accountName: A, _appendData?: Buffer): any {
- switch (accountName) {
- case "nonce": {
- return {
- dataSize: NONCE_ACCOUNT_LENGTH,
- };
- }
- default: {
- throw new Error(`Invalid account name: ${accountName}`);
- }
- }
- }
- public size(idlAccount: IdlTypeDef): number {
- return accountSize(this.idl, idlAccount) ?? 0;
- }
- }
- function decodeNonceAccount<T = any>(ix: Buffer): T {
- return NONCE_ACCOUNT_LAYOUT.decode(ix) as T;
- }
- class WrappedLayout<T, U> extends BufferLayout.Layout<U> {
- layout: BufferLayout.Layout<T>;
- decoder: (data: T) => U;
- encoder: (src: U) => T;
- constructor(
- layout: BufferLayout.Layout<T>,
- decoder: (data: T) => U,
- encoder: (src: U) => T,
- property?: string
- ) {
- super(layout.span, property);
- this.layout = layout;
- this.decoder = decoder;
- this.encoder = encoder;
- }
- decode(b: Buffer, offset?: number): U {
- return this.decoder(this.layout.decode(b, offset));
- }
- encode(src: U, b: Buffer, offset?: number): number {
- return this.layout.encode(this.encoder(src), b, offset);
- }
- getSpan(b: Buffer, offset?: number): number {
- return this.layout.getSpan(b, offset);
- }
- }
- function publicKey(property?: string): BufferLayout.Layout<PublicKey> {
- return new WrappedLayout(
- BufferLayout.blob(32),
- (b: Buffer) => new PublicKey(b),
- (key: PublicKey) => key.toBuffer(),
- property
- );
- }
- const NONCE_ACCOUNT_LAYOUT = BufferLayout.struct([
- BufferLayout.u32("version"),
- BufferLayout.u32("state"),
- publicKey("authorizedPubkey"),
- publicKey("nonce"),
- BufferLayout.struct(
- [BufferLayout.nu64("lamportsPerSignature")],
- "feeCalculator"
- ),
- ]);
|