From 6a7115b8bd06e8d500be4e71255ab5d1a773f69e Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 13 Feb 2020 08:25:22 +0800 Subject: [PATCH] fix: allow Uint8Array and Array where Buffer is accepted --- web3.js/module.d.ts | 18 ++++++++++-------- web3.js/module.flow.js | 20 ++++++++++++-------- web3.js/src/account.js | 5 +++-- web3.js/src/bpf-loader.js | 2 +- web3.js/src/connection.js | 5 +++-- web3.js/src/loader.js | 2 +- web3.js/src/publickey.js | 2 +- web3.js/src/transaction.js | 2 +- web3.js/src/util/to-buffer.js | 11 +++++++++++ web3.js/src/validator-info.js | 2 +- web3.js/src/vote-account.js | 5 +++-- web3.js/test/transaction.test.js | 13 ++++++++----- 12 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 web3.js/src/util/to-buffer.js diff --git a/web3.js/module.d.ts b/web3.js/module.d.ts index 73b69387e8..05f3dfd4d6 100644 --- a/web3.js/module.d.ts +++ b/web3.js/module.d.ts @@ -3,7 +3,7 @@ declare module '@solana/web3.js' { // === src/publickey.js === export class PublicKey { - constructor(value: number | string | Buffer | Array); + constructor(value: number | string | Buffer | Uint8Array | Array); static isPublicKey(o: object): boolean; equals(publickey: PublicKey): boolean; toBase58(): string; @@ -16,7 +16,7 @@ declare module '@solana/web3.js' { // === src/account.js === export class Account { - constructor(secretKey?: Buffer); + constructor(secretKey?: Buffer | Uint8Array | Array); publicKey: PublicKey; secretKey: Buffer; } @@ -206,7 +206,9 @@ declare module '@solana/web3.js' { sendEncodedTransaction( encodedTransaction: string, ): Promise; - sendRawTransaction(wireTransaction: Buffer): Promise; + sendRawTransaction( + wireTransaction: Buffer | Uint8Array | Array, + ): Promise; onAccountChange( publickey: PublicKey, callback: AccountChangeCallback, @@ -312,7 +314,7 @@ declare module '@solana/web3.js' { info: Info; constructor(key: PublicKey, info: Info); - static fromConfigData(buffer: Buffer): ValidatorInfo | null | undefined; + static fromConfigData(buffer: Buffer | Uint8Array | Array): ValidatorInfo | null; } // === src/sysvar.js === @@ -344,7 +346,7 @@ declare module '@solana/web3.js' { credits: number; lastEpochCredits: number; epochCredits: Array; - static fromAccountData(buffer: Buffer): VoteAccount; + static fromAccountData(buffer: Buffer | Uint8Array | Array): VoteAccount; } // === src/instruction.js === @@ -396,7 +398,7 @@ declare module '@solana/web3.js' { recentBlockhash?: Blockhash; constructor(opts?: TransactionCtorFields); - static from(buffer: Buffer): Transaction; + static from(buffer: Buffer | Uint8Array | Array): Transaction; add( ...items: Array< Transaction | TransactionInstruction | TransactionInstructionCtorFields @@ -457,7 +459,7 @@ declare module '@solana/web3.js' { payer: Account, program: Account, programId: PublicKey, - data: Buffer | Array, + data: Buffer | Uint8Array | Array, ): Promise; } @@ -468,7 +470,7 @@ declare module '@solana/web3.js' { static load( connection: Connection, payer: Account, - elfBytes: Buffer | Array, + elfBytes: Buffer | Uint8Array | Array, ): Promise; } diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 32c5cb4769..f93caa586d 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -15,7 +15,9 @@ import * as BufferLayout from 'buffer-layout'; declare module '@solana/web3.js' { // === src/publickey.js === declare export class PublicKey { - constructor(value: number | string | Buffer | Array): PublicKey; + constructor( + value: number | string | Buffer | Uint8Array | Array, + ): PublicKey; static isPublicKey(o: Object): boolean; equals(publickey: PublicKey): boolean; toBase58(): string; @@ -28,7 +30,7 @@ declare module '@solana/web3.js' { // === src/account.js === declare export class Account { - constructor(secretKey: ?Buffer): Account; + constructor(secretKey?: Buffer | Uint8Array | Array): Account; publicKey: PublicKey; secretKey: Buffer; } @@ -219,7 +221,9 @@ declare module '@solana/web3.js' { sendEncodedTransaction( encodedTransaction: string, ): Promise; - sendRawTransaction(wireTransaction: Buffer): Promise; + sendRawTransaction( + wireTransaction: Buffer | Uint8Array | Array, + ): Promise; onAccountChange( publickey: PublicKey, callback: AccountChangeCallback, @@ -369,7 +373,7 @@ declare module '@solana/web3.js' { info: Info; constructor(key: PublicKey, info: Info): ValidatorInfo; - static fromConfigData(buffer: Buffer): ?ValidatorInfo; + static fromConfigData(buffer: Buffer | Uint8Array | Array): ValidatorInfo | null; } // === src/sysvar.js === @@ -401,7 +405,7 @@ declare module '@solana/web3.js' { credits: number; lastEpochCredits: number; epochCredits: Array; - static fromAccountData(buffer: Buffer): VoteAccount; + static fromAccountData(buffer: Buffer | Uint8Array | Array): VoteAccount; } // === src/instruction.js === @@ -451,7 +455,7 @@ declare module '@solana/web3.js' { recentBlockhash: ?Blockhash; constructor(opts?: TransactionCtorFields): Transaction; - static from(buffer: Buffer): Transaction; + static from(buffer: Buffer | Uint8Array | Array): Transaction; add( ...items: Array< Transaction | TransactionInstruction | TransactionInstructionCtorFields, @@ -471,7 +475,7 @@ declare module '@solana/web3.js' { payer: Account, program: Account, programId: PublicKey, - data: Buffer | Array, + data: Buffer | Uint8Array | Array, ): Promise; } @@ -482,7 +486,7 @@ declare module '@solana/web3.js' { static load( connection: Connection, payer: Account, - elfBytes: Buffer | Array, + elfBytes: Buffer | Uint8Array | Array, ): Promise; } diff --git a/web3.js/src/account.js b/web3.js/src/account.js index 534ed2567d..05e53a89c8 100644 --- a/web3.js/src/account.js +++ b/web3.js/src/account.js @@ -2,6 +2,7 @@ import nacl from 'tweetnacl'; import type {KeyPair} from 'tweetnacl'; +import {toBuffer} from './util/to-buffer'; import {PublicKey} from './publickey'; /** @@ -18,9 +19,9 @@ export class Account { * * @param secretKey Secret key for the account */ - constructor(secretKey: ?Buffer = null) { + constructor(secretKey?: Buffer | Uint8Array | Array) { if (secretKey) { - this._keypair = nacl.sign.keyPair.fromSecretKey(secretKey); + this._keypair = nacl.sign.keyPair.fromSecretKey(toBuffer(secretKey)); } else { this._keypair = nacl.sign.keyPair(); } diff --git a/web3.js/src/bpf-loader.js b/web3.js/src/bpf-loader.js index 3d140a67cc..aeea178abb 100644 --- a/web3.js/src/bpf-loader.js +++ b/web3.js/src/bpf-loader.js @@ -36,7 +36,7 @@ export class BpfLoader { static load( connection: Connection, payer: Account, - elf: Buffer | Array, + elf: Buffer | Uint8Array | Array, ): Promise { const program = new Account(); return Loader.load(connection, payer, program, BpfLoader.programId, elf); diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 1f99a1d4a9..a3bdcacf04 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -13,6 +13,7 @@ import {PublicKey} from './publickey'; import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from './timing'; import {Transaction} from './transaction'; import {sleep} from './util/sleep'; +import {toBuffer} from './util/to-buffer'; import type {Blockhash} from './blockhash'; import type {FeeCalculator} from './fee-calculator'; import type {Account} from './account'; @@ -1281,9 +1282,9 @@ export class Connection { * wire format */ async sendRawTransaction( - rawTransaction: Buffer, + rawTransaction: Buffer | Uint8Array | Array, ): Promise { - const encodedTransaction = bs58.encode(rawTransaction); + const encodedTransaction = bs58.encode(toBuffer(rawTransaction)); const result = await this.sendEncodedTransaction(encodedTransaction); return result; } diff --git a/web3.js/src/loader.js b/web3.js/src/loader.js index cff3a87f5c..1217ab7d96 100644 --- a/web3.js/src/loader.js +++ b/web3.js/src/loader.js @@ -52,7 +52,7 @@ export class Loader { payer: Account, program: Account, programId: PublicKey, - data: Buffer | Array, + data: Buffer | Uint8Array | Array, ): Promise { { const balanceNeeded = await connection.getMinimumBalanceForRentExemption( diff --git a/web3.js/src/publickey.js b/web3.js/src/publickey.js index 5dd073e0aa..58930a4bdc 100644 --- a/web3.js/src/publickey.js +++ b/web3.js/src/publickey.js @@ -13,7 +13,7 @@ export class PublicKey { /** * Create a new PublicKey object */ - constructor(value: number | string | Buffer | Array) { + constructor(value: number | string | Buffer | Uint8Array | Array) { if (typeof value === 'string') { // hexadecimal number if (value.startsWith('0x')) { diff --git a/web3.js/src/transaction.js b/web3.js/src/transaction.js index fae08553dd..7821ec2372 100644 --- a/web3.js/src/transaction.js +++ b/web3.js/src/transaction.js @@ -480,7 +480,7 @@ export class Transaction { /** * Parse a wire transaction into a Transaction object. */ - static from(buffer: Buffer): Transaction { + static from(buffer: Buffer | Uint8Array | Array): Transaction { // Slice up wire data let byteArray = [...buffer]; diff --git a/web3.js/src/util/to-buffer.js b/web3.js/src/util/to-buffer.js new file mode 100644 index 0000000000..82bc5c3c50 --- /dev/null +++ b/web3.js/src/util/to-buffer.js @@ -0,0 +1,11 @@ +// @flow + +export const toBuffer = (arr: Buffer | Uint8Array | Array): Buffer => { + if (arr instanceof Buffer) { + return arr; + } else if (arr instanceof Uint8Array) { + return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength); + } else { + return Buffer.from(arr); + } +}; diff --git a/web3.js/src/validator-info.js b/web3.js/src/validator-info.js index 5d6276f5f5..3c8ea97db0 100644 --- a/web3.js/src/validator-info.js +++ b/web3.js/src/validator-info.js @@ -72,7 +72,7 @@ export class ValidatorInfo { * @param buffer config account data * @return null if info was not found */ - static fromConfigData(buffer: Buffer): ?ValidatorInfo { + static fromConfigData(buffer: Buffer | Uint8Array | Array): ValidatorInfo | null { const PUBKEY_LENGTH = 32; let byteArray = [...buffer]; diff --git a/web3.js/src/vote-account.js b/web3.js/src/vote-account.js index b75415bf92..fdb30d1d96 100644 --- a/web3.js/src/vote-account.js +++ b/web3.js/src/vote-account.js @@ -3,6 +3,7 @@ import * as BufferLayout from 'buffer-layout'; import * as Layout from './layout'; import {PublicKey} from './publickey'; +import {toBuffer} from './util/to-buffer'; export const VOTE_PROGRAM_ID = new PublicKey( 'Vote111111111111111111111111111111111111111', @@ -79,8 +80,8 @@ export class VoteAccount { * @param buffer account data * @return VoteAccount */ - static fromAccountData(buffer: Buffer): VoteAccount { - const va = VoteAccountLayout.decode(buffer, 0); + static fromAccountData(buffer: Buffer | Uint8Array | Array): VoteAccount { + const va = VoteAccountLayout.decode(toBuffer(buffer), 0); va.nodePubkey = new PublicKey(va.nodePubkey); va.authorizedVoterPubkey = new PublicKey(va.authorizedVoterPubkey); va.authorizedWithdrawerPubkey = new PublicKey( diff --git a/web3.js/test/transaction.test.js b/web3.js/test/transaction.test.js index dd87106469..58e3163642 100644 --- a/web3.js/test/transaction.test.js +++ b/web3.js/test/transaction.test.js @@ -200,7 +200,8 @@ test('serialize unsigned transaction', () => { ); // Arbitrary known public key const transfer = SystemProgram.transfer(sender.publicKey, recipient, 49); const expectedTransaction = new Transaction({recentBlockhash}).add(transfer); - const wireTransaction = Buffer.from([ + + const wireTransactionArray = [ 1, 0, 0, @@ -416,9 +417,11 @@ test('serialize unsigned transaction', () => { 0, 0, 0, - ]); - expect(wireTransaction).toEqual(expectedTransaction.serialize()); + ]; - const tx = Transaction.from(wireTransaction); - expect(tx).toEqual(expectedTransaction); + const wireTransaction = Buffer.from(wireTransactionArray); + expect(wireTransaction).toEqual(expectedTransaction.serialize()); + expect(Transaction.from(wireTransaction)).toEqual(expectedTransaction); + expect(Transaction.from(wireTransactionArray)).toEqual(expectedTransaction); + expect(Transaction.from(Uint8Array.from(wireTransactionArray))).toEqual(expectedTransaction); });