Skip to content

Commit

Permalink
[ts-sdk] Remove usage of buffer in SDK (MystenLabs#5706)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan-Mysten authored Nov 2, 2022
1 parent 82a6440 commit 01989d3
Show file tree
Hide file tree
Showing 19 changed files with 132 additions and 173 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-bananas-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@mysten/sui.js": minor
---

Remove usage of Buffer within SDK
6 changes: 0 additions & 6 deletions pnpm-lock.yaml

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

2 changes: 0 additions & 2 deletions sdk/bcs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ export class BcsReader {
}
/**
* Read U128 value from the buffer and shift cursor by 16.
* @returns
*/
read128(): bigint {
let value1 = this.read64();
Expand All @@ -142,7 +141,6 @@ export class BcsReader {
/**
* Read `num` number of bytes from the buffer and shift cursor by `num`.
* @param num Number of bytes to read.
* @returns Selected Buffer.
*/
readBytes(num: number): Uint8Array {
let start = this.bytePosition + this.dataView.byteOffset;
Expand Down
19 changes: 19 additions & 0 deletions sdk/typescript/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@
module.exports = {
root: true,
extends: ['react-app', 'prettier', 'plugin:prettier/recommended'],
rules: {
'@typescript-eslint/ban-types': [
'error',
{
types: {
Buffer:
'Buffer usage increases bundle size and is not consistently implemented on web.',
},
},
],
'no-restricted-globals': [
'error',
{
name: 'Buffer',
message:
'Buffer usage increases bundle size and is not consistently implemented on web.',
},
],
},
settings: {
react: {
version: '18',
Expand Down
11 changes: 4 additions & 7 deletions sdk/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,16 @@
},
"size-limit": [
{
"path": "dist/sui.js.cjs.production.min.js",
"limit": "10 KB"
"path": "dist/index.js",
"limit": "100 KB"
},
{
"path": "dist/sui.js.esm.js",
"limit": "10 KB"
"path": "dist/index.mjs",
"limit": "100 KB"
}
],
"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.8",
"@types/bn.js": "^5.1.0",
"@types/lossless-json": "^1.0.1",
"axios": "^0.27.2",
"eslint": "^8.23.0",
Expand All @@ -91,8 +90,6 @@
"@noble/secp256k1": "^1.6.3",
"@scure/bip32": "^1.1.0",
"@scure/bip39": "^1.1.0",
"bn.js": "^5.2.0",
"buffer": "^6.0.3",
"cross-fetch": "^3.1.5",
"jayson": "^3.6.6",
"js-sha3": "^0.8.0",
Expand Down
58 changes: 17 additions & 41 deletions sdk/typescript/src/cryptography/ed25519-publickey.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import BN from 'bn.js';
import { Buffer } from 'buffer';
import sha3 from 'js-sha3';
import { fromB64, toB64 } from '@mysten/bcs';
import {
checkPublicKeyData,
bytesEqual,
PublicKeyInitData,
SIGNATURE_SCHEME_TO_FLAG,
} from './publickey';
Expand All @@ -16,70 +15,47 @@ const PUBLIC_KEY_SIZE = 32;
* An Ed25519 public key
*/
export class Ed25519PublicKey {
/** @internal */
_bn: BN;
private data: Uint8Array;

/**
* Create a new Ed25519PublicKey object
* @param value ed25519 public key as buffer or base-64 encoded string
*/
constructor(value: PublicKeyInitData) {
if (checkPublicKeyData(value)) {
this._bn = value._bn;
if (typeof value === 'string') {
this.data = fromB64(value);
} else if (value instanceof Uint8Array) {
this.data = value;
} else {
if (typeof value === 'string') {
const buffer = Buffer.from(value, 'base64');
if (buffer.length !== PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${PUBLIC_KEY_SIZE} bytes, got ${buffer.length}`
);
}
this._bn = new BN(buffer);
} else {
this._bn = new BN(value);
}
let length = this._bn.byteLength();
if (length != PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${PUBLIC_KEY_SIZE} bytes, got ${length}`
);
}
this.data = Uint8Array.from(value);
}

if (this.data.length !== PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${PUBLIC_KEY_SIZE} bytes, got ${this.data.length}`
);
}
}

/**
* Checks if two Ed25519 public keys are equal
*/
equals(publicKey: Ed25519PublicKey): boolean {
return this._bn.eq(publicKey._bn);
return bytesEqual(this.toBytes(), publicKey.toBytes());
}

/**
* Return the base-64 representation of the Ed25519 public key
*/
toBase64(): string {
return this.toBuffer().toString('base64');
return toB64(this.toBytes());
}

/**
* Return the byte array representation of the Ed25519 public key
*/
toBytes(): Uint8Array {
return this.toBuffer();
}

/**
* Return the Buffer representation of the Ed25519 public key
*/
toBuffer(): Buffer {
const b = this._bn.toArrayLike(Buffer);
if (b.length === PUBLIC_KEY_SIZE) {
return b;
}

const zeroPad = Buffer.alloc(PUBLIC_KEY_SIZE);
b.copy(zeroPad, PUBLIC_KEY_SIZE - b.length);
return zeroPad;
return this.data;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion sdk/typescript/src/cryptography/mnemonics.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
import { toHEX } from '@mysten/bcs';
import { mnemonicToSeedSync as bip39MnemonicToSeedSync } from '@scure/bip39';

/**
Expand Down Expand Up @@ -42,5 +43,5 @@ export function mnemonicToSeed(mnemonics: string): Uint8Array {
* @param mnemonics 12 words string split by spaces.
*/
export function mnemonicToSeedHex(mnemonics: string): string {
return Buffer.from(mnemonicToSeed(mnemonics)).toString('hex');
return toHEX(mnemonicToSeed(mnemonics));
}
41 changes: 15 additions & 26 deletions sdk/typescript/src/cryptography/publickey.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
import BN from 'bn.js';

/**
* Value to be converted into public key.
*/
export type PublicKeyInitData =
| number
| string
| Buffer
| Uint8Array
| Array<number>
| PublicKeyData;
export type PublicKeyInitData = string | Uint8Array | Iterable<number>;

/**
* JSON object representation of PublicKey class.
*/
export type PublicKeyData = {
/** @internal */
_bn: BN;
};
export function bytesEqual(a: Uint8Array, b: Uint8Array) {
if (a === b) return true;

if (a.length !== b.length) {
return false;
}

for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}

/**
* A keypair used for signing transactions.
Expand All @@ -31,12 +31,6 @@ export const SIGNATURE_SCHEME_TO_FLAG = {
Secp256k1: 0x01,
};

export function checkPublicKeyData(
value: PublicKeyInitData
): value is PublicKeyData {
return (value as PublicKeyData)._bn !== undefined;
}

/**
* A public key
*/
Expand All @@ -56,11 +50,6 @@ export interface PublicKey {
*/
toBytes(): Uint8Array;

/**
* Return the Buffer representation of the public key
*/
toBuffer(): Buffer;

/**
* Return the base-64 representation of the public key
*/
Expand Down
58 changes: 17 additions & 41 deletions sdk/typescript/src/cryptography/secp256k1-publickey.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import BN from 'bn.js';
import { Buffer } from 'buffer';
import { fromB64, toB64 } from '@mysten/bcs';
import sha3 from 'js-sha3';
import {
checkPublicKeyData,
bytesEqual,
PublicKey,
PublicKeyInitData,
SIGNATURE_SCHEME_TO_FLAG,
Expand All @@ -17,70 +16,47 @@ const SECP256K1_PUBLIC_KEY_SIZE = 33;
* A Secp256k1 public key
*/
export class Secp256k1PublicKey implements PublicKey {
/** @internal */
_bn: BN;
private data: Uint8Array;

/**
* Create a new Secp256k1PublicKey object
* @param value secp256k1 public key as buffer or base-64 encoded string
*/
constructor(value: PublicKeyInitData) {
if (checkPublicKeyData(value)) {
this._bn = value._bn;
if (typeof value === 'string') {
this.data = fromB64(value);
} else if (value instanceof Uint8Array) {
this.data = value;
} else {
if (typeof value === 'string') {
const buffer = Buffer.from(value, 'base64');
if (buffer.length !== SECP256K1_PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${SECP256K1_PUBLIC_KEY_SIZE} bytes, got ${buffer.length}`
);
}
this._bn = new BN(buffer);
} else {
this._bn = new BN(value);
}
let length = this._bn.byteLength();
if (length != SECP256K1_PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${SECP256K1_PUBLIC_KEY_SIZE} bytes, got ${length}`
);
}
this.data = Uint8Array.from(value);
}

if (this.data.length !== SECP256K1_PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${SECP256K1_PUBLIC_KEY_SIZE} bytes, got ${this.data.length}`
);
}
}

/**
* Checks if two Secp256k1 public keys are equal
*/
equals(publicKey: Secp256k1PublicKey): boolean {
return this._bn.eq(publicKey._bn);
return bytesEqual(this.toBytes(), publicKey.toBytes());
}

/**
* Return the base-64 representation of the Secp256k1 public key
*/
toBase64(): string {
return this.toBuffer().toString('base64');
return toB64(this.toBytes());
}

/**
* Return the byte array representation of the Secp256k1 public key
*/
toBytes(): Uint8Array {
return this.toBuffer();
}

/**
* Return the Buffer representation of the Secp256k1 public key
*/
toBuffer(): Buffer {
const b = this._bn.toArrayLike(Buffer);
if (b.length === SECP256K1_PUBLIC_KEY_SIZE) {
return b;
}

const zeroPad = Buffer.alloc(SECP256K1_PUBLIC_KEY_SIZE);
b.copy(zeroPad, SECP256K1_PUBLIC_KEY_SIZE - b.length);
return zeroPad;
return this.data;
}

/**
Expand Down
Loading

0 comments on commit 01989d3

Please sign in to comment.