feat: add borsh utilities and public key support (#17239)
* feat: add borsh utilities and public key support * fix: make bn internal for flow * fix: add Buffer import in borsh file
This commit is contained in:
@@ -16,6 +16,7 @@ export * from './transaction';
|
||||
export * from './validator-info';
|
||||
export * from './vote-account';
|
||||
export * from './sysvar';
|
||||
export * from './util/borsh-schema';
|
||||
export * from './util/send-and-confirm-transaction';
|
||||
export * from './util/send-and-confirm-raw-transaction';
|
||||
export * from './util/cluster';
|
||||
|
@@ -4,6 +4,7 @@ import nacl from 'tweetnacl';
|
||||
import {sha256} from 'crypto-hash';
|
||||
import {Buffer} from 'buffer';
|
||||
|
||||
import {Struct, SOLANA_SCHEMA} from './util/borsh-schema';
|
||||
import {toBuffer} from './util/to-buffer';
|
||||
|
||||
/**
|
||||
@@ -11,10 +12,27 @@ import {toBuffer} from './util/to-buffer';
|
||||
*/
|
||||
export const MAX_SEED_LENGTH = 32;
|
||||
|
||||
type PublicKeyInitData =
|
||||
| number
|
||||
| string
|
||||
| Buffer
|
||||
| Uint8Array
|
||||
| Array<number>
|
||||
| PublicKeyData;
|
||||
|
||||
type PublicKeyData = {
|
||||
/** @internal */
|
||||
_bn: BN;
|
||||
};
|
||||
|
||||
function isPublicKeyData(value: PublicKeyInitData): value is PublicKeyData {
|
||||
return (value as PublicKeyData)._bn !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* A public key
|
||||
*/
|
||||
export class PublicKey {
|
||||
export class PublicKey extends Struct {
|
||||
/** @internal */
|
||||
_bn: BN;
|
||||
|
||||
@@ -22,20 +40,25 @@ export class PublicKey {
|
||||
* Create a new PublicKey object
|
||||
* @param value ed25519 public key as buffer or base-58 encoded string
|
||||
*/
|
||||
constructor(value: number | string | Buffer | Uint8Array | Array<number>) {
|
||||
if (typeof value === 'string') {
|
||||
// assume base 58 encoding by default
|
||||
const decoded = bs58.decode(value);
|
||||
if (decoded.length != 32) {
|
||||
constructor(value: PublicKeyInitData) {
|
||||
super({});
|
||||
if (isPublicKeyData(value)) {
|
||||
this._bn = value._bn;
|
||||
} else {
|
||||
if (typeof value === 'string') {
|
||||
// assume base 58 encoding by default
|
||||
const decoded = bs58.decode(value);
|
||||
if (decoded.length != 32) {
|
||||
throw new Error(`Invalid public key input`);
|
||||
}
|
||||
this._bn = new BN(decoded);
|
||||
} else {
|
||||
this._bn = new BN(value);
|
||||
}
|
||||
|
||||
if (this._bn.byteLength() > 32) {
|
||||
throw new Error(`Invalid public key input`);
|
||||
}
|
||||
this._bn = new BN(decoded);
|
||||
} else {
|
||||
this._bn = new BN(value);
|
||||
}
|
||||
|
||||
if (this._bn.byteLength() > 32) {
|
||||
throw new Error(`Invalid public key input`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +190,11 @@ export class PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
SOLANA_SCHEMA.set(PublicKey, {
|
||||
kind: 'struct',
|
||||
fields: [['_bn', 'u256']],
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
let naclLowLevel = nacl.lowlevel;
|
||||
|
||||
|
34
web3.js/src/util/borsh-schema.ts
Normal file
34
web3.js/src/util/borsh-schema.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import {Buffer} from 'buffer';
|
||||
import {serialize, deserialize} from 'borsh';
|
||||
|
||||
// Class wrapping a plain object
|
||||
export class Struct {
|
||||
constructor(properties: any) {
|
||||
Object.assign(this, properties);
|
||||
}
|
||||
|
||||
encode(): Buffer {
|
||||
return Buffer.from(serialize(SOLANA_SCHEMA, this));
|
||||
}
|
||||
|
||||
static decode(data: Buffer): any {
|
||||
return deserialize(SOLANA_SCHEMA, this, data);
|
||||
}
|
||||
}
|
||||
|
||||
// Class representing a Rust-compatible enum, since enums are only strings or
|
||||
// numbers in pure JS
|
||||
export class Enum extends Struct {
|
||||
enum: string = '';
|
||||
constructor(properties: any) {
|
||||
super(properties);
|
||||
if (Object.keys(properties).length !== 1) {
|
||||
throw new Error('Enum can only take single value');
|
||||
}
|
||||
Object.keys(properties).map(key => {
|
||||
this.enum = key;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const SOLANA_SCHEMA: Map<Function, any> = new Map();
|
Reference in New Issue
Block a user