solana/web3.js/src/layout.js

92 lines
2.0 KiB
JavaScript

// @flow
import * as BufferLayout from 'buffer-layout';
/**
* Layout for a public key
*/
export const publicKey = (property: string = 'publicKey'): Object => {
return BufferLayout.blob(32, property);
};
/**
* Layout for a 64bit unsigned value
*/
export const uint64 = (property: string = 'uint64'): Object => {
return BufferLayout.blob(8, property);
};
/**
* Layout for a Rust String type
*/
export const rustString = (property: string = 'string') => {
const rsl = BufferLayout.struct(
[
BufferLayout.u32('length'),
BufferLayout.u32('lengthPadding'),
BufferLayout.blob(BufferLayout.offset(BufferLayout.u32(), -8), 'chars'),
],
property,
);
const _decode = rsl.decode.bind(rsl);
const _encode = rsl.encode.bind(rsl);
rsl.decode = (buffer, offset) => {
const data = _decode(buffer, offset);
return data.chars.toString('utf8');
};
rsl.encode = (str, buffer, offset) => {
const data = {
chars: Buffer.from(str, 'utf8'),
};
return _encode(data, buffer, offset);
};
rsl.alloc = str => {
return (
BufferLayout.u32().span +
BufferLayout.u32().span +
Buffer.from(str, 'utf8').length
);
};
return rsl;
};
/**
* Layout for an Authorized object
*/
export const authorized = (property: string = 'authorized') => {
return BufferLayout.struct(
[publicKey('staker'), publicKey('withdrawer')],
property,
);
};
/**
* Layout for a Lockup object
*/
export const lockup = (property: string = 'lockup') => {
return BufferLayout.struct(
[
BufferLayout.ns64('unixTimestamp'),
BufferLayout.ns64('epoch'),
publicKey('custodian'),
],
property,
);
};
export function getAlloc(type: Object, fields: Object): number {
let alloc = 0;
type.layout.fields.forEach(item => {
if (item.span >= 0) {
alloc += item.span;
} else if (typeof item.alloc === 'function') {
alloc += item.alloc(fields[item.property]);
}
});
return alloc;
}