Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

stake-pool-js: Fix build for downstream users #6793

Merged
merged 2 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions stake-pool/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solana/spl-stake-pool",
"version": "1.1.4",
"version": "1.1.5",
"description": "SPL Stake Pool Program JS API",
"scripts": {
"build": "tsc && cross-env NODE_ENV=production rollup -c",
Expand Down Expand Up @@ -43,7 +43,6 @@
],
"license": "ISC",
"dependencies": {
"@coral-xyz/borsh": "^0.30.0",
"@solana/buffer-layout": "^4.0.1",
"@solana/spl-token": "0.4.6",
"@solana/web3.js": "^1.91.8",
Expand Down
4 changes: 2 additions & 2 deletions stake-pool/js/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ function generateConfig(configType, format) {

// Prevent dependencies from being bundled
config.external = [
'@coral-xyz/borsh',
'@solana/buffer-layout',
'@solana/spl-token',
'@solana/web3.js',
'bn.js',
'buffer',
'buffer-layout',
];
}

Expand All @@ -94,12 +94,12 @@ function generateConfig(configType, format) {

// Prevent dependencies from being bundled
config.external = [
'@coral-xyz/borsh',
'@solana/buffer-layout',
'@solana/spl-token',
'@solana/web3.js',
'bn.js',
'buffer',
'buffer-layout',
];
}

Expand Down
159 changes: 159 additions & 0 deletions stake-pool/js/src/codecs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { blob, Layout as LayoutCls, offset, seq, struct, u32, u8 } from 'buffer-layout';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';

export interface Layout<T> {
span: number;
property?: string;

decode(b: Buffer, offset?: number): T;

encode(src: T, b: Buffer, offset?: number): number;

getSpan(b: Buffer, offset?: number): number;

replicate(name: string): this;
}

class BNLayout extends LayoutCls<BN> {
blob: Layout<Buffer>;
signed: boolean;

constructor(span: number, signed: boolean, property?: string) {
super(span, property);
this.blob = blob(span);
this.signed = signed;
}

decode(b: Buffer, offset = 0) {
const num = new BN(this.blob.decode(b, offset), 10, 'le');
if (this.signed) {
return num.fromTwos(this.span * 8).clone();
}
return num;
}

encode(src: BN, b: Buffer, offset = 0) {
if (this.signed) {
src = src.toTwos(this.span * 8);
}
return this.blob.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset);
}
}

export function u64(property?: string): Layout<BN> {
return new BNLayout(8, false, property);
}

class WrappedLayout<T, U> extends LayoutCls<U> {
layout: Layout<T>;
decoder: (data: T) => U;
encoder: (src: U) => T;

constructor(
layout: 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);
}
}

export function publicKey(property?: string): Layout<PublicKey> {
return new WrappedLayout(
blob(32),
(b: Buffer) => new PublicKey(b),
(key: PublicKey) => key.toBuffer(),
property,
);
}

class OptionLayout<T> extends LayoutCls<T | null> {
layout: Layout<T>;
discriminator: Layout<number>;

constructor(layout: Layout<T>, property?: string) {
super(-1, property);
this.layout = layout;
this.discriminator = u8();
}

encode(src: T | null, b: Buffer, offset = 0): number {
if (src === null || src === undefined) {
return this.discriminator.encode(0, b, offset);
}
this.discriminator.encode(1, b, offset);
return this.layout.encode(src, b, offset + 1) + 1;
}

decode(b: Buffer, offset = 0): T | null {
const discriminator = this.discriminator.decode(b, offset);
if (discriminator === 0) {
return null;
} else if (discriminator === 1) {
return this.layout.decode(b, offset + 1);
}
throw new Error('Invalid option ' + this.property);
}

getSpan(b: Buffer, offset = 0): number {
const discriminator = this.discriminator.decode(b, offset);
if (discriminator === 0) {
return 1;
} else if (discriminator === 1) {
return this.layout.getSpan(b, offset + 1) + 1;
}
throw new Error('Invalid option ' + this.property);
}
}

export function option<T>(layout: Layout<T>, property?: string): Layout<T | null> {
return new OptionLayout<T>(layout, property);
}

export function bool(property?: string): Layout<boolean> {
return new WrappedLayout(u8(), decodeBool, encodeBool, property);
}

function decodeBool(value: number): boolean {
if (value === 0) {
return false;
} else if (value === 1) {
return true;
}
throw new Error('Invalid bool: ' + value);
}

function encodeBool(value: boolean): number {
return value ? 1 : 0;
}

export function vec<T>(elementLayout: Layout<T>, property?: string): Layout<T[]> {
const length = u32('length');
const layout: Layout<{ values: T[] }> = struct([
length,
seq(elementLayout, offset(length, -length.span), 'values'),
]);
return new WrappedLayout(
layout,
({ values }) => values,
(values) => ({ values }),
property,
);
}
8 changes: 4 additions & 4 deletions stake-pool/js/src/layouts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Layout, publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh';
import { Layout as LayoutCls, u8 as u8Cls } from 'buffer-layout';
import { Layout, publicKey, u64, option, vec } from './codecs';
import { struct, Layout as LayoutCls, u8, u32 } from 'buffer-layout';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
import {
Expand Down Expand Up @@ -45,7 +45,7 @@ export class FutureEpochLayout<T> extends LayoutCls<T | null> {
constructor(layout: Layout<T>, property?: string) {
super(-1, property);
this.layout = layout;
this.discriminator = u8Cls();
this.discriminator = u8();
}

encode(src: T | null, b: Buffer, offset = 0): number {
Expand Down Expand Up @@ -78,7 +78,7 @@ export class FutureEpochLayout<T> extends LayoutCls<T | null> {
}
}

export function futureEpoch<T>(layout: Layout<T>, property?: string): Layout<T | null> {
export function futureEpoch<T>(layout: Layout<T>, property?: string): LayoutCls<T | null> {
return new FutureEpochLayout<T>(layout, property);
}

Expand Down
7 changes: 7 additions & 0 deletions stake-pool/js/src/types/buffer-layout.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ declare module 'buffer-layout' {
property?: string,
decodePrefixes?: boolean,
): Layout<T>;
export function seq<T>(
elementLayout: Layout<T>,
count: number | Layout<number>,
property?: string,
): Layout<T[]>;
export function offset<T>(layout: Layout<T>, offset?: number, property?: string): Layout<T>;
export function blob(length: number | Layout<number>, property?: string): Layout<Buffer>;
export function s32(property?: string): Layout<number>;
export function u32(property?: string): Layout<number>;
export function s16(property?: string): Layout<number>;
Expand Down