fix: offload bn.js dependency

This commit is contained in:
AhsanJavaid
2021-12-16 11:23:09 +05:00
committed by ahsan-javaid
parent 534f1b8acf
commit c4ee99b21e
22 changed files with 282 additions and 152 deletions

View File

@@ -40,9 +40,7 @@
"dependencies": {
"@stacks/common": "^3.0.0",
"@stacks/network": "^3.2.0",
"@stacks/transactions": "^3.2.0",
"@types/bn.js": "^4.11.6",
"bn.js": "^4.12.0"
"@stacks/transactions": "^3.2.0"
},
"devDependencies": {
"@types/jest": "^26.0.22",

View File

@@ -1,8 +1,6 @@
import { Buffer } from '@stacks/common';
import { bufferCV, uintCV, hash160 } from '@stacks/transactions';
import BN from 'bn.js';
export function decodeFQN(fqdn: string): {
name: string;
namespace: string;
@@ -30,6 +28,6 @@ export function decodeFQN(fqdn: string): {
export const bufferCVFromString = (string: string) => bufferCV(Buffer.from(string));
export const uintCVFromBN = (int: BN) => uintCV(int.toString(10));
export const uintCVFromBN = (int: bigint) => uintCV(int.toString(10));
export const getZonefileHash = (zonefile: string) => hash160(Buffer.from(zonefile));

View File

@@ -30,8 +30,7 @@ import {
import {bufferCVFromString, decodeFQN, getZonefileHash, uintCVFromBN} from "../src/utils";
import BN from "bn.js";
import { ChainID } from "@stacks/common";
import { ChainID } from '@stacks/common';
beforeEach(() => {
fetchMock.resetMocks();
@@ -356,7 +355,7 @@ test('getNamePrice error', async () => {
test('preorderNamespace', async () => {
const namespace = 'id';
const salt = 'salt';
const stxToBurn = new BN(10);
const stxToBurn = BigInt(10);
const publicKey = '03ef788b3830c00abe8f64f62dc32fc863bc0b2cafeb073b6c8e1c7657d9c2c3ab';
const network = new StacksTestnet();
@@ -416,29 +415,29 @@ test('revealNamespace', async () => {
const publicKey = '03ef788b3830c00abe8f64f62dc32fc863bc0b2cafeb073b6c8e1c7657d9c2c3ab';
const priceFunction: PriceFunction = {
base: new BN(10),
coefficient: new BN(1),
b1: new BN(1),
b2: new BN(2),
b3: new BN(3),
b4: new BN(4),
b5: new BN(5),
b6: new BN(6),
b7: new BN(7),
b8: new BN(8),
b9: new BN(9),
b10: new BN(10),
b11: new BN(11),
b12: new BN(12),
b13: new BN(13),
b14: new BN(14),
b15: new BN(15),
b16: new BN(16),
nonAlphaDiscount: new BN(0),
noVowelDiscount: new BN(0),
base: BigInt(10),
coefficient: BigInt(1),
b1: BigInt(1),
b2: BigInt(2),
b3: BigInt(3),
b4: BigInt(4),
b5: BigInt(5),
b6: BigInt(6),
b7: BigInt(7),
b8: BigInt(8),
b9: BigInt(9),
b10: BigInt(10),
b11: BigInt(11),
b12: BigInt(12),
b13: BigInt(13),
b14: BigInt(14),
b15: BigInt(15),
b16: BigInt(16),
nonAlphaDiscount: BigInt(0),
noVowelDiscount: BigInt(0),
}
const lifetime = new BN(10000);
const lifetime = BigInt(10000);
const namespaceImportAddress = 'SPF0324DSC4K505TP6A8C7GAK4R95E38TGNZP7RE';
const makeUnsignedContractCall = jest.fn().mockResolvedValue({});
@@ -602,7 +601,7 @@ test('readyNamespace', async () => {
test('preorderName', async () => {
const fullyQualifiedName = 'test.id';
const salt = 'salt';
const stxToBurn = new BN(10);
const stxToBurn = BigInt(10);
const publicKey = '03ef788b3830c00abe8f64f62dc32fc863bc0b2cafeb073b6c8e1c7657d9c2c3ab';
const makeUnsignedContractCall = jest.fn().mockResolvedValue({});
@@ -957,7 +956,7 @@ test('revokeName', async () => {
test('renewName', async () => {
const fullyQualifiedName = 'test.id';
const stxToBurn = new BN(10);
const stxToBurn = BigInt(10);
const newOwnerAddress = 'SPF0324DSC4K505TP6A8C7GAK4R95E38TGNZP7RE';
const zonefile = 'zonefile';
const publicKey = '03ef788b3830c00abe8f64f62dc32fc863bc0b2cafeb073b6c8e1c7657d9c2c3ab';
@@ -1023,7 +1022,7 @@ test('renewName', async () => {
test('renewName optionalArguments', async () => {
const fullyQualifiedName = 'test.id';
const stxToBurn = new BN(10);
const stxToBurn = BigInt(10);
const newOwnerAddress = undefined;
const zonefile = undefined;
const publicKey = '03ef788b3830c00abe8f64f62dc32fc863bc0b2cafeb073b6c8e1c7657d9c2c3ab';

View File

@@ -102,7 +102,6 @@
"bip39": "^3.0.2",
"bitcoinjs-lib": "^5.2.0",
"blockstack": "^19.2.2",
"bn.js": "^4.12.0",
"c32check": "^1.1.3",
"cors": "^2.8.4",
"cross-fetch": "^3.1.4",

View File

@@ -6,7 +6,6 @@ import * as fs from 'fs';
import * as winston from 'winston';
import cors from 'cors';
import BN from 'bn.js';
import * as crypto from 'crypto';
import * as bip39 from 'bip39';
import express from 'express';
@@ -372,21 +371,10 @@ function balance(network: CLINetworkAdapter, args: string[]): Promise<string> {
return response.json();
})
.then(response => {
let balanceHex = response.balance;
if (response.balance.startsWith('0x')) {
balanceHex = response.balance.substr(2);
}
let lockedHex = response.locked;
if (response.locked.startsWith('0x')) {
lockedHex = response.locked.substr(2);
}
const unlockHeight = response.unlock_height;
const balance = new BN(balanceHex, 16);
const locked = new BN(lockedHex, 16);
const res = {
balance: balance.toString(10),
locked: locked.toString(10),
unlock_height: unlockHeight,
balance: BigInt(response.balance).toString(10),
locked: BigInt(response.locked).toString(10),
unlock_height: response.unlock_height,
nonce: response.nonce,
};
return Promise.resolve(JSONStringify(res));
@@ -539,9 +527,9 @@ function getAccountHistory(network: CLINetworkAdapter, args: string[]): Promise<
*/
async function sendTokens(network: CLINetworkAdapter, args: string[]): Promise<string> {
const recipientAddress = args[0];
const tokenAmount = new BN(args[1]);
const fee = new BN(args[2]);
const nonce = new BN(args[3]);
const tokenAmount = BigInt(args[1]);
const fee = BigInt(args[2]);
const nonce = BigInt(args[3]);
const privateKey = args[4];
let memo = '';
@@ -605,8 +593,8 @@ async function sendTokens(network: CLINetworkAdapter, args: string[]): Promise<s
async function contractDeploy(network: CLINetworkAdapter, args: string[]): Promise<string> {
const sourceFile = args[0];
const contractName = args[1];
const fee = new BN(args[2]);
const nonce = new BN(args[3]);
const fee = BigInt(args[2]);
const nonce = BigInt(args[3]);
const privateKey = args[4];
const source = fs.readFileSync(sourceFile).toString();
@@ -668,8 +656,8 @@ async function contractFunctionCall(network: CLINetworkAdapter, args: string[]):
const contractAddress = args[0];
const contractName = args[1];
const functionName = args[2];
const fee = new BN(args[3]);
const nonce = new BN(args[4]);
const fee = BigInt(args[3]);
const nonce = BigInt(args[4]);
const privateKey = args[5];
// temporary hack to use network config from stacks-transactions lib
@@ -1517,7 +1505,7 @@ async function stackingStatus(network: CLINetworkAdapter, args: string[]): Promi
}
async function canStack(network: CLINetworkAdapter, args: string[]): Promise<string> {
const amount = new BN(args[0]);
const amount = BigInt(args[0]);
const cycles = Number(args[1]);
const poxAddress = args[2];
const stxAddress = args[3];
@@ -1542,16 +1530,16 @@ async function canStack(network: CLINetworkAdapter, args: string[]): Promise<str
return Promise.all([balancePromise, poxInfoPromise, stackingEligiblePromise])
.then(([balance, poxInfo, stackingEligible]) => {
const minAmount = new BN(poxInfo.min_amount_ustx);
const balanceBN = new BN(balance.stx.balance);
const minAmount = BigInt(poxInfo.min_amount_ustx);
const balanceBN = BigInt(balance.stx.balance);
if (minAmount.gt(amount)) {
if (minAmount > amount) {
throw new Error(
`Stacking amount less than required minimum of ${minAmount.toString()} microstacks`
);
}
if (amount.gt(balanceBN)) {
if (amount > balanceBN) {
throw new Error(
`Stacking amount greater than account balance of ${balanceBN.toString()} microstacks`
);
@@ -1569,7 +1557,7 @@ async function canStack(network: CLINetworkAdapter, args: string[]): Promise<str
}
async function stack(network: CLINetworkAdapter, args: string[]): Promise<string> {
const amount = new BN(args[0]);
const amount = BigInt(args[0]);
const cycles = Number(args[1]);
const poxAddress = args[2];
const privateKey = args[3];
@@ -1610,18 +1598,18 @@ async function stack(network: CLINetworkAdapter, args: string[]): Promise<string
return Promise.all([balancePromise, poxInfoPromise, coreInfoPromise, stackingEligiblePromise])
.then(([balance, poxInfo, coreInfo, stackingEligible]) => {
const minAmount = new BN(poxInfo.min_amount_ustx);
const balanceBN = new BN(balance.stx.balance);
const minAmount = BigInt(poxInfo.min_amount_ustx);
const balanceBN = BigInt(balance.stx.balance);
const burnChainBlockHeight = coreInfo.burn_block_height;
const startBurnBlock = burnChainBlockHeight + 3;
if (minAmount.gt(amount)) {
if (minAmount > amount) {
throw new Error(
`Stacking amount less than required minimum of ${minAmount.toString()} microstacks`
);
}
if (amount.gt(balanceBN)) {
if (amount > balanceBN) {
throw new Error(
`Stacking amount greater than account balance of ${balanceBN.toString()} microstacks`
);

View File

@@ -1,6 +1,5 @@
import blockstack from 'blockstack';
import * as bitcoin from 'bitcoinjs-lib';
import BN from 'bn.js';
import fetch from 'node-fetch';
import { CLI_CONFIG_TYPE } from './argparse';
@@ -22,7 +21,7 @@ export interface CLI_NETWORK_OPTS {
export interface PriceType {
units: 'BTC' | 'STACKS';
amount: import('bn.js');
amount: bigint;
}
export type NameInfoType = {
@@ -144,7 +143,7 @@ export class CLINetworkAdapter {
return new Promise((resolve: any) =>
resolve({
units: String(this.priceUnits),
amount: new BN(this.priceToPay as string),
amount: BigInt(this.priceToPay),
} as PriceType)
);
}
@@ -154,7 +153,7 @@ export class CLINetworkAdapter {
if (!priceInfo.units) {
priceInfo = {
units: 'BTC',
amount: new BN(String(priceInfo)),
amount: BigInt(priceInfo),
};
}
return priceInfo;
@@ -167,7 +166,7 @@ export class CLINetworkAdapter {
return new Promise((resolve: any) =>
resolve({
units: String(this.priceUnits),
amount: new BN(String(this.priceToPay)),
amount: BigInt(this.priceToPay),
} as PriceType)
);
}
@@ -177,7 +176,7 @@ export class CLINetworkAdapter {
if (!priceInfo.units) {
priceInfo = {
units: 'BTC',
amount: new BN(String(priceInfo)),
amount: BigInt(priceInfo),
} as PriceType;
}
return priceInfo;

View File

@@ -34,7 +34,6 @@
},
"dependencies": {
"@types/node": "^14.14.43",
"bn.js": "^4.12.0",
"buffer": "^6.0.3",
"cross-fetch": "^3.1.4"
},

View File

@@ -9,8 +9,6 @@ import { Buffer as BufferPolyfill } from 'buffer/';
// so export using the type definition from NodeJS (@types/node).
import type { Buffer as NodeJSBuffer } from 'buffer';
import BN from 'bn.js';
const AvailableBufferModule: typeof NodeJSBuffer =
// eslint-disable-next-line node/prefer-global/buffer
typeof Buffer !== 'undefined' ? Buffer : (BufferPolyfill as any);
@@ -331,16 +329,11 @@ export function getGlobalObjects<K extends Extract<keyof Window, string>>(
return result;
}
export type IntegerType = number | string | bigint | Uint8Array | BN;
export type IntegerType = number | string | bigint | Uint8Array;
// eslint-disable-next-line node/prefer-global/buffer
export function intToBytes(value: IntegerType, signed: boolean, byteLength: number): Buffer {
return intToBN(value, signed).toArrayLike(AvailableBufferModule, 'be', byteLength);
}
export function intToBN(value: IntegerType, signed: boolean): BN {
const bigInt = intToBigInt(value, signed);
return new BN(bigInt.toString());
return toBuffer(intToBigInt(value, signed), byteLength);
}
export function intToBigInt(value: IntegerType, signed: boolean): bigint {
@@ -380,17 +373,14 @@ export function intToBigInt(value: IntegerType, signed: boolean): bigint {
// Allow byte arrays smaller than 128-bits to be passed.
// This allows positive signed ints like `0x08` (8) or negative signed
// ints like `0xf8` (-8) to be passed without having to pad to 16 bytes.
const bn = new BN(parsedValue, 'be').fromTwos(parsedValue.byteLength * 8);
const bn = fromTwos(BigInt(`0x${bytesToHex(parsedValue)}`), parsedValue.byteLength * 8);
return BigInt(bn.toString());
} else {
return BigInt(new BN(parsedValue, 'be').toString());
return BigInt(`0x${bytesToHex(parsedValue)}`);
}
}
if (parsedValue instanceof BN || BN.isBN(parsedValue)) {
return BigInt(parsedValue.toString());
}
throw new TypeError(
`Invalid value type. Must be a number, bigint, integer-string, hex-string, BN.js instance, or Buffer.`
`Invalid value type. Must be a number, bigint, integer-string, hex-string, BigInt instance, or Buffer.`
);
}
@@ -413,3 +403,93 @@ export function hexToBigInt(hex: string): bigint {
export function utf8ToBytes(content: string) {
return new TextEncoder().encode(content);
}
/**
* Converts IntegerType to hex string
*/
export const intToHexString = (integer: IntegerType, lengthBytes = 8): string => {
const value = typeof integer === 'bigint' ? integer : intToBigInt(integer, false);
return value.toString(16).padStart(lengthBytes * 2, '0');
};
/**
* Converts hex string to Uint8Array
* @param {hex} hex string without 0x prefix
* @output {Uint8Array} instance of bytes
*/
export function hexToBytes(hex: string): Uint8Array {
if (typeof hex !== 'string') {
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
}
if (hex.slice(0, 2) === '0x') {
throw new Error('input hex should be without 0x prefix');
}
if (hex.length % 2)
throw new Error(`hexToBytes: received invalid unpadded hex, got: ${hex.length}`);
const array = new Uint8Array(hex.length / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
const hexByte = hex.slice(j, j + 2);
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');
array[i] = byte;
}
return array;
}
const byteToHexCache: string[] = new Array(0xff);
for (let n = 0; n <= 0xff; ++n) {
byteToHexCache[n] = n.toString(16).padStart(2, '0');
}
/**
* Converts Uint8Array to hex string
*/
export function bytesToHex(uint8a: Uint8Array): string {
const hexOctets = new Array(uint8a.length);
for (let i = 0; i < uint8a.length; ++i) hexOctets[i] = byteToHexCache[uint8a[i]];
return hexOctets.join('');
}
/**
* Converts bigint to buffer type
* @param {value} bigint value to be converted into buffer
* @param {length} buffer optional length
* @return {Buffer} buffer instance in big endian format
*/
export function toBuffer(value: bigint, length: number = 16) {
const hex = intToHexString(value, length);
// buffer instance in big endian format
return AvailableBufferModule.from(hexToBytes(hex));
}
/**
* Converts from negative number to two's complement
*/
export function toTwos(value: bigint, size: number): bigint {
// make sure its in range given the number of bits
if (
value < -(BigInt(1) << (BigInt(size) - BigInt(1))) ||
value > (BigInt(1) << (BigInt(size) - BigInt(1))) - BigInt(1)
)
throw `Integer out of range given ${size} bits to represent.`;
// if positive, return the positive value
if (value >= BigInt(0)) return BigInt(value);
// if negative, convert to twos complement representation
const result = ~((-value - BigInt(1)) | ~((BigInt(1) << BigInt(size)) - BigInt(1)));
return BigInt(result);
}
/**
* Converts from two's complement to negative number
*/
export function fromTwos(value: bigint, size: number) {
if ((value & (BigInt(1) << (BigInt(size) - BigInt(1)))) > BigInt(0))
value = value - (BigInt(1) << BigInt(size));
return value;
}

View File

@@ -1,4 +1,13 @@
import { isSameOriginAbsoluteUrl, isLaterVersion } from '../src'
import {
isSameOriginAbsoluteUrl,
isLaterVersion,
intToHexString,
hexToBytes,
bytesToHex,
fromTwos,
toTwos,
toBuffer
} from '../src'
test('isLaterVersion', () => {
expect(isLaterVersion('', '1.1.0')).toEqual(false)
@@ -21,3 +30,80 @@ test('isSameOriginAbsoluteUrl', () => {
expect(isSameOriginAbsoluteUrl('http://example.com', 'http://example.com:1234')).toEqual(false)
expect(isSameOriginAbsoluteUrl('http://app.example.com', 'https://example.com/manifest.json')).toEqual(false)
})
test('intToHexString', () => {
const expected = '0000000000000010';
expect(intToHexString(BigInt(16))).toEqual(expected);
expect(intToHexString(16)).toEqual(expected);
});
test('hexToBytes & bytesToHex', () => {
const hex = 'ff';
const bytes = Uint8Array.of(255);
expect(hexToBytes(hex)).toEqual(bytes);
expect(bytesToHex(bytes)).toEqual(hex);
});
test('should return proper buffer', () => {
const n = BigInt('0x123456');
expect(toBuffer(n, 5).toString('hex')).toBe('0000123456');
const s = '211e1566be78319bb949470577c2d4';
for (let i = 1; i <= s.length; i++) {
const slice = (i % 2 === 0 ? '' : '0') + s.slice(0, i);
const bn = BigInt(`0x${slice}`);
expect(toBuffer(bn).toString('hex')).toBe(slice.padStart(32, '0'))
}
});
test('should convert from two\'s complement to negative number', () => {
expect(Number(fromTwos(BigInt('0x00000000'),32))).toBe(0);
expect(Number(fromTwos(BigInt('0x00000001'),32))).toBe(1);
expect(Number(fromTwos(BigInt('0x7fffffff'),32))).toBe(2147483647);
expect(Number(fromTwos(BigInt('0x80000000'),32))).toBe(-2147483648);
expect(Number(fromTwos(BigInt('0xf0000000'),32))).toBe(-268435456);
expect(Number(fromTwos(BigInt('0xf1234567'),32))).toBe(-249346713);
expect(Number(fromTwos(BigInt('0xffffffff'),32))).toBe(-1);
expect(Number(fromTwos(BigInt('0xfffffffe'),32))).toBe(-2);
expect(Number(fromTwos(BigInt('0xfffffffffffffffffffffffffffffffe'),128))).toBe(-2);
expect(Number(fromTwos(BigInt('0xffffffffffffffffffffffffffffffff' +
'fffffffffffffffffffffffffffffffe'),256))).toBe(-2);
expect(Number(fromTwos(BigInt('0xffffffffffffffffffffffffffffffff' +
'ffffffffffffffffffffffffffffffff'),256))).toBe(-1);
expect(
fromTwos(BigInt('0x7fffffffffffffffffffffffffffffff' +
'ffffffffffffffffffffffffffffffff'),256).toString(10))
.toEqual(BigInt('5789604461865809771178549250434395392663499' +
'2332820282019728792003956564819967').toString(10));
expect(
fromTwos(BigInt('0x80000000000000000000000000000000' +
'00000000000000000000000000000000'),256).toString(10))
.toEqual(BigInt('-578960446186580977117854925043439539266349' +
'92332820282019728792003956564819968').toString(10));
});
test('should convert from negative number to two\'s complement', () => {
expect(toTwos(BigInt(0), 32).toString(16)).toEqual('0');
expect(toTwos(BigInt(1), 32).toString(16)).toEqual('1');
expect(toTwos(BigInt(2147483647), 32).toString(16)).toEqual('7fffffff');
expect(toTwos(BigInt(-2147483648), 32).toString(16)).toEqual('80000000');
expect(toTwos(BigInt(-268435456), 32).toString(16)).toEqual('f0000000');
expect(toTwos(BigInt(-249346713), 32).toString(16)).toEqual('f1234567');
expect(toTwos(BigInt(-1), 32).toString(16)).toEqual('ffffffff');
expect(toTwos(BigInt(-2), 32).toString(16)).toEqual('fffffffe');
expect(toTwos(BigInt(-2), 128).toString(16)).toEqual('fffffffffffffffffffffffffffffffe');
expect(toTwos(BigInt(-2), 256).toString(16))
.toEqual('fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe');
expect(toTwos(BigInt(-1), 256).toString(16))
.toEqual('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
expect(toTwos(BigInt('5789604461865809771178549250434395392663' +
'4992332820282019728792003956564819967'), 256).toString(16))
.toEqual('7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
expect(toTwos(BigInt('-578960446186580977117854925043439539266' +
'34992332820282019728792003956564819968'), 256).toString(16))
.toEqual('8000000000000000000000000000000000000000000000000000000000000000');
});

View File

@@ -31,11 +31,9 @@
},
"dependencies": {
"@stacks/common": "^3.0.0",
"@types/bn.js": "^4.11.6",
"@types/node": "^14.14.43",
"bip39": "^3.0.2",
"bitcoinjs-lib": "^5.2.0",
"bn.js": "^4.12.0",
"elliptic": "^6.5.4",
"randombytes": "^2.1.0",
"ripemd160-min": "^0.0.6",

View File

@@ -1,8 +1,7 @@
import { Buffer } from '@stacks/common';
import { ec as EllipticCurve } from 'elliptic';
import * as BN from 'bn.js';
import { randomBytes } from './cryptoRandom';
import { FailedDecryptionError } from '@stacks/common';
import { FailedDecryptionError, toBuffer } from '@stacks/common';
import { getPublicKeyFromPrivate } from './keys';
import { hashSha256Sync, hashSha512Sync } from './sha2Hash';
import { createHmacSha256 } from './hmacSha256';
@@ -162,12 +161,12 @@ function isValidPublicKey(pub: string): {
}
/**
* Hex encodes a 32-byte BN.js instance.
* Hex encodes a 32-byte bigint instance.
* The result string is zero padded and always 64 characters in length.
* @ignore
*/
export function getHexFromBN(bnInput: BN): string {
const hexOut = bnInput.toString('hex', 64);
export function getHexFromBN(bnInput: bigint): string {
const hexOut = bnInput.toString(16);
if (hexOut.length === 64) {
return hexOut;
} else if (hexOut.length < 64) {
@@ -181,14 +180,14 @@ export function getHexFromBN(bnInput: BN): string {
}
/**
* Returns a big-endian encoded 32-byte BN.js instance.
* Returns a big-endian encoded 32-byte buffer instance.
* The result Buffer is zero padded and always 32 bytes in length.
* @ignore
*/
export function getBufferFromBN(bnInput: BN): Buffer {
const result = bnInput.toArrayLike(Buffer, 'be', 32);
export function getBufferFromBN(bnInput: bigint): Buffer {
const result = toBuffer(bnInput, 32);
if (result.byteLength !== 32) {
throw new Error('Failed to generate a 32-byte BN');
throw new Error('Failed to generate a 32-byte buffer instance');
}
return result;
}
@@ -328,8 +327,8 @@ export async function encryptECIES(
const ecPK = ecurve.keyFromPublic(publicKey, 'hex').getPublic();
const ephemeralSK = ecurve.genKeyPair();
const ephemeralPK = Buffer.from(ephemeralSK.getPublic().encodeCompressed());
const sharedSecret = ephemeralSK.derive(ecPK) as BN;
const sharedSecretBuffer = getBufferFromBN(sharedSecret);
const sharedSecret = ephemeralSK.derive(ecPK).toString();
const sharedSecretBuffer = getBufferFromBN(BigInt(sharedSecret));
const sharedKeys = sharedSecretToKeys(sharedSecretBuffer);
const initializationVector = randomBytes(16);
@@ -392,8 +391,8 @@ export async function decryptECIES(
);
}
const sharedSecret = ecSK.derive(ephemeralPK) as BN;
const sharedSecretBuffer = getBufferFromBN(sharedSecret);
const sharedSecret = ecSK.derive(ephemeralPK).toString();
const sharedSecretBuffer = getBufferFromBN(BigInt(sharedSecret));
const sharedKeys = sharedSecretToKeys(sharedSecretBuffer);

View File

@@ -11,7 +11,6 @@ import * as aesCipher from '../src/aesCipher'
import * as sha2Hash from '../src/sha2Hash'
import * as hmacSha256 from '../src/hmacSha256'
import * as ripemd160 from '../src/hashRipemd160'
import BN from 'bn.js'
import { getBufferFromBN } from '../src/ec'
const privateKey = 'a5c61c6ca7b3e7e55edee68566aeab22e4da26baa285c7bd10e8d2218aa3b229'
@@ -461,15 +460,15 @@ test('bn-padded-to-64-bytes', () => {
const ephemeralSK = ecurve.keyFromPrivate(hex)
const ephemeralPK = ephemeralSK.getPublic()
const sharedSecret = ephemeralSK.derive(ephemeralPK)
return getHexFromBN(sharedSecret).length === 64
return getHexFromBN(BigInt(sharedSecret.toString())).length === 64
})
expect(results.every(x => x)).toEqual(true)
const bnBuffer = getBufferFromBN(new BN(123))
const bnBuffer = getBufferFromBN(BigInt(123))
expect(bnBuffer.byteLength).toEqual(32)
expect(bnBuffer.toString('hex')).toEqual(getHexFromBN(new BN(123)))
expect(bnBuffer.toString('hex')).toEqual(getHexFromBN(BigInt(123)))
})
test('encryptMnemonic & decryptMnemonic', async () => {

View File

@@ -70,13 +70,11 @@
"@stacks/profile": "^3.2.0",
"@stacks/storage": "^3.2.0",
"@stacks/transactions": "^3.2.0",
"@types/bn.js": "^4.11.6",
"@types/node": "^14.14.43",
"@types/triplesec": "^3.0.0",
"bip32": "^2.0.4",
"bip39": "^3.0.2",
"bitcoinjs-lib": "^5.2.0",
"bn.js": "^4.12.0",
"c32check": "^1.1.3",
"jsontokens": "^3.0.0",
"randombytes": "^2.1.0",

View File

@@ -14,7 +14,6 @@ import {
import { StacksTestnet, StacksNetwork, StacksNetworkName } from '@stacks/network';
import RPCClient from '@blockstack/rpc-client';
import BN from 'bn.js';
interface ContractCallOptions {
contractName: string;
@@ -120,7 +119,7 @@ export class WalletSigner {
codeBody: codeBody,
senderKey: this.getSTXPrivateKey().toString('hex'),
network: this.getNetwork(),
nonce: new BN(nonce),
nonce: BigInt(nonce),
postConditionMode,
postConditions,
anchorMode,
@@ -139,11 +138,11 @@ export class WalletSigner {
}: STXTransferOptions) {
const tx = await makeSTXTokenTransfer({
recipient,
amount: new BN(amount),
amount: BigInt(amount),
memo,
senderKey: this.getSTXPrivateKey().toString('hex'),
network: this.getNetwork(),
nonce: new BN(nonce),
nonce: BigInt(nonce),
postConditionMode,
postConditions,
anchorMode,

View File

@@ -38,9 +38,7 @@
"@stacks/network": "^3.2.0",
"@stacks/stacks-blockchain-api-types": "^0.61.0",
"@stacks/transactions": "^3.2.0",
"@types/bn.js": "^4.11.6",
"bitcoinjs-lib": "^5.2.0",
"bn.js": "^4.12.0"
"bitcoinjs-lib": "^5.2.0"
},
"devDependencies": {
"@types/jest": "^26.0.22",

View File

@@ -1,4 +1,5 @@
import { Buffer, IntegerType, intToBigInt } from '@stacks/common';
// @ts-ignore
import { Buffer, IntegerType, intToBigInt, toBuffer } from '@stacks/common';
import {
makeContractCall,
bufferCV,
@@ -30,7 +31,6 @@ import {
BurnchainRewardSlotHolderListResponse,
} from '@stacks/stacks-blockchain-api-types';
import { StacksNetwork } from '@stacks/network';
import BN from 'bn.js';
import { StackingErrors } from './constants';
import { fetchPrivate } from '@stacks/common';
import { decodeBtcAddress } from './utils';
@@ -326,7 +326,7 @@ export class StackingClient {
return Promise.all([balancePromise, poxInfoPromise])
.then(([balance, poxInfo]) => {
const { hashMode, data } = decodeBtcAddress(poxAddress);
const hashModeBuffer = bufferCV(new BN(hashMode, 10).toArrayLike(Buffer));
const hashModeBuffer = bufferCV(toBuffer(BigInt(hashMode)));
const hashbytes = bufferCV(data);
const poxAddressCV = tupleCV({
hashbytes,
@@ -528,7 +528,7 @@ export class StackingClient {
burnBlockHeight: number;
}) {
const { hashMode, data } = decodeBtcAddress(poxAddress);
const hashModeBuffer = bufferCV(new BN(hashMode, 10).toArrayLike(Buffer));
const hashModeBuffer = bufferCV(toBuffer(BigInt(hashMode)));
const hashbytes = bufferCV(data);
const address = tupleCV({
hashbytes,
@@ -566,7 +566,7 @@ export class StackingClient {
if (poxAddress) {
const { hashMode, data } = decodeBtcAddress(poxAddress);
const hashModeBuffer = bufferCV(new BN(hashMode, 10).toArrayLike(Buffer));
const hashModeBuffer = bufferCV(toBuffer(BigInt(hashMode)));
const hashbytes = bufferCV(data);
address = someCV(
tupleCV({
@@ -613,7 +613,7 @@ export class StackingClient {
nonce?: IntegerType;
}) {
const { hashMode, data } = decodeBtcAddress(poxAddress);
const hashModeBuffer = bufferCV(new BN(hashMode, 10).toArrayLike(Buffer));
const hashModeBuffer = bufferCV(toBuffer(BigInt(hashMode)));
const hashbytes = bufferCV(data);
const address = tupleCV({
hashbytes,
@@ -655,7 +655,7 @@ export class StackingClient {
rewardCycle: number;
}) {
const { hashMode, data } = decodeBtcAddress(poxAddress);
const hashModeBuffer = bufferCV(new BN(hashMode, 10).toArrayLike(Buffer));
const hashModeBuffer = bufferCV(toBuffer(BigInt(hashMode)));
const hashbytes = bufferCV(data);
const address = tupleCV({
hashbytes,

View File

@@ -8,7 +8,6 @@ import {
TupleCV,
} from '@stacks/transactions';
import { address } from 'bitcoinjs-lib';
import BN from 'bn.js';
import { StackingErrors } from './constants';
export class InvalidAddressError extends Error {
@@ -140,7 +139,7 @@ export function poxAddressToBtcAddress(...args: PoxAddressArgs): string {
}
export function getBTCAddress(version: Buffer, checksum: Buffer) {
const btcAddress = address.toBase58Check(checksum, new BN(version).toNumber());
const btcAddress = address.toBase58Check(checksum, Number(version.toString()));
return btcAddress;
}

View File

@@ -1,6 +1,6 @@
import { StacksTestnet } from '@stacks/network';
import { Buffer, toBuffer } from '@stacks/common';
import fetchMock from 'jest-fetch-mock';
import BN from 'bn.js';
import { StackingErrors } from '../src/constants';
import {
uintCV,
@@ -223,7 +223,7 @@ test('stack stx', async () => {
const address = 'ST3XKKN4RPV69NN1PHFDNX3TYKXT7XPC4N8KC1ARH';
const poxAddress = '1Xik14zRm29UsyS6DjhYg4iZeZqsDa8D3';
const network = new StacksTestnet();
const amountMicroStx = new BN(100000000000);
const amountMicroStx = BigInt(100000000000);
const cycles = 10;
const privateKey = 'd48f215481c16cbe6426f8e557df9b78895661971d71735126545abddcd5377001';
const burnBlockHeight = 2000;
@@ -263,7 +263,7 @@ test('stack stx', async () => {
});
const { version, hash } = btcAddress.fromBase58Check(poxAddress);
const versionBuffer = bufferCV(new BN(version, 10).toBuffer());
const versionBuffer = bufferCV(toBuffer(BigInt(version)));
const hashbytes = bufferCV(hash);
const poxAddressCV = tupleCV({
hashbytes,
@@ -299,7 +299,7 @@ test('delegate stx', async () => {
const delegateTo = 'ST2MCYPWTFMD2MGR5YY695EJG0G1R4J2BTJPRGM7H';
const poxAddress = '1Xik14zRm29UsyS6DjhYg4iZeZqsDa8D3';
const network = new StacksTestnet();
const amountMicroStx = new BN(100000000000);
const amountMicroStx = BigInt(100000000000);
const untilBurnBlockHeight = 2000;
const privateKey = 'd48f215481c16cbe6426f8e557df9b78895661971d71735126545abddcd5377001';
@@ -340,7 +340,7 @@ test('delegate stx', async () => {
});
const { version, hash } = btcAddress.fromBase58Check(poxAddress);
const versionBuffer = bufferCV(new BN(version, 10).toBuffer());
const versionBuffer = bufferCV(toBuffer(BigInt(version)));
const hashbytes = bufferCV(hash);
const poxAddressCV = tupleCV({
hashbytes,
@@ -375,7 +375,7 @@ test('delegate stx with empty optional parameters', async () => {
const address = 'ST3XKKN4RPV69NN1PHFDNX3TYKXT7XPC4N8KC1ARH';
const delegateTo = 'ST2MCYPWTFMD2MGR5YY695EJG0G1R4J2BTJPRGM7H';
const network = new StacksTestnet();
const amountMicroStx = new BN(100000000000);
const amountMicroStx = BigInt(100000000000);
const privateKey = 'd48f215481c16cbe6426f8e557df9b78895661971d71735126545abddcd5377001';
const transaction = { serialize: () => 'mocktxhex' }
@@ -445,7 +445,7 @@ test('delegate stack stx with one delegator', async () => {
const address = 'ST2MCYPWTFMD2MGR5YY695EJG0G1R4J2BTJPRGM7H';
const poxAddress = '1Xik14zRm29UsyS6DjhYg4iZeZqsDa8D3';
const network = new StacksTestnet();
const amountMicroStx = new BN(100000000000);
const amountMicroStx = BigInt(100000000000);
const burnBlockHeight = 2000;
const cycles = 10;
const privateKey = 'd48f215481c16cbe6426f8e557df9b78895661971d71735126545abddcd5377001';
@@ -497,7 +497,7 @@ test('delegate stack stx with one delegator', async () => {
});
const { version, hash } = btcAddress.fromBase58Check(poxAddress);
const versionBuffer = bufferCV(new BN(version, 10).toBuffer());
const versionBuffer = bufferCV(toBuffer(BigInt(version)));
const hashbytes = bufferCV(hash);
const poxAddressCV = tupleCV({
hashbytes,
@@ -534,11 +534,11 @@ test('delegate stack stx with set nonce', async () => {
const address = 'ST2MCYPWTFMD2MGR5YY695EJG0G1R4J2BTJPRGM7H';
const poxAddress = '1Xik14zRm29UsyS6DjhYg4iZeZqsDa8D3';
const network = new StacksTestnet();
const amountMicroStx = new BN(100000000000);
const amountMicroStx = BigInt(100000000000);
const burnBlockHeight = 2000;
const cycles = 10;
const privateKey = 'd48f215481c16cbe6426f8e557df9b78895661971d71735126545abddcd5377001';
const nonce = new BN(1);
const nonce = BigInt(1);
const transaction = { serialize: () => 'mocktxhex' }
const makeContractCall = jest.fn().mockResolvedValue(transaction);
@@ -588,7 +588,7 @@ test('delegate stack stx with set nonce', async () => {
});
const { version, hash } = btcAddress.fromBase58Check(poxAddress);
const versionBuffer = bufferCV(new BN(version, 10).toBuffer());
const versionBuffer = bufferCV(toBuffer(BigInt(version)));
const hashbytes = bufferCV(hash);
const poxAddressCV = tupleCV({
hashbytes,
@@ -662,7 +662,7 @@ test('delegator commit', async () => {
});
const { version, hash } = btcAddress.fromBase58Check(poxAddress);
const versionBuffer = bufferCV(new BN(version, 10).toBuffer());
const versionBuffer = bufferCV(toBuffer(BigInt(version)));
const hashbytes = bufferCV(hash);
const poxAddressCV = tupleCV({
hashbytes,
@@ -953,8 +953,9 @@ test('get account balance', async () => {
const responseBalanceInfo = await client.getAccountBalance();
expect(fetchMock.mock.calls[0][0]).toEqual(network.getAccountApiUrl(address));
expect(responseBalanceInfo.toString()).toEqual(new BN(balanceInfo.balance.substr(2), 'hex').toString());
expect(responseBalanceInfo.toString()).toEqual(BigInt(balanceInfo.balance).toString());
})
test('get seconds until next cycle', async () => {
const address = 'ST3XKKN4RPV69NN1PHFDNX3TYKXT7XPC4N8KC1ARH';
const network = new StacksTestnet();

View File

@@ -46,11 +46,9 @@
"@noble/secp256k1": "^1.5.2",
"@stacks/common": "^3.0.0",
"@stacks/network": "^3.2.0",
"@types/bn.js": "^4.11.6",
"@types/node": "^14.14.43",
"@types/randombytes": "^2.0.0",
"@types/sha.js": "^2.4.0",
"bn.js": "^4.12.0",
"c32check": "^1.1.3",
"cross-fetch": "^3.1.4",
"lodash.clonedeep": "^4.5.0",

View File

@@ -1,4 +1,4 @@
import { Buffer } from '@stacks/common';
import { Buffer, toTwos, toBuffer } from '@stacks/common';
import { serializeAddress, serializeLPString } from '../types';
import { createLPString } from '../postcondition-types';
import {
@@ -19,7 +19,6 @@ import { BufferArray } from '../utils';
import { SerializationError } from '../errors';
import { StringAsciiCV, StringUtf8CV } from './types/stringCV';
import { CLARITY_INT_BYTE_SIZE, CLARITY_INT_SIZE } from '../constants';
import BN from 'bn.js';
function bufferWithTypeID(typeId: ClarityType, buffer: Buffer): Buffer {
const id = Buffer.from([typeId]);
@@ -45,14 +44,12 @@ function serializeBufferCV(cv: BufferCV): Buffer {
}
function serializeIntCV(cv: IntCV): Buffer {
const buffer = new BN(cv.value.toString())
.toTwos(CLARITY_INT_SIZE)
.toArrayLike(Buffer, 'be', CLARITY_INT_BYTE_SIZE);
const buffer = toBuffer(toTwos(cv.value, CLARITY_INT_SIZE), CLARITY_INT_BYTE_SIZE);
return bufferWithTypeID(cv.type, buffer);
}
function serializeUIntCV(cv: UIntCV): Buffer {
const buffer = new BN(cv.value.toString()).toArrayLike(Buffer, 'be', CLARITY_INT_BYTE_SIZE);
const buffer = toBuffer(cv.value, CLARITY_INT_BYTE_SIZE);
return bufferWithTypeID(cv.type, buffer);
}

View File

@@ -34,7 +34,6 @@ import {
} from '../src/clarity';
import { BufferReader } from '../src/bufferReader';
import { cvToString, cvToJSON, cvToValue, getCVTypeString } from '../src/clarity/clarityValue';
import BN from 'bn.js';
const ADDRESS = 'SP2JXKMSH007NPYAQHKJPQMAQYAD90NQGTVJVQ02B';
@@ -227,7 +226,7 @@ describe('Clarity Types', () => {
['-10', '-10', '0xfffffffffffffffffffffffffffffff6'],
['0xfff6', '-10', '0xfffffffffffffffffffffffffffffff6'],
['0xf6', '-10', '0xfffffffffffffffffffffffffffffff6'],
[new BN(-10), '-10', '0xfffffffffffffffffffffffffffffff6'],
[BigInt(-10), '-10', '0xfffffffffffffffffffffffffffffff6'],
[Buffer.from([0xff, 0xf6]), '-10', '0xfffffffffffffffffffffffffffffff6'],
[Buffer.from([0xf6]), '-10', '0xfffffffffffffffffffffffffffffff6'],
[Buffer.from([0xff, 0xfe]), '-2', '0xfffffffffffffffffffffffffffffffe'],
@@ -246,7 +245,7 @@ describe('Clarity Types', () => {
['0x000a', '10', '0x0000000000000000000000000000000a'],
['0xa', '10', '0x0000000000000000000000000000000a'], // hex string with odd padding
['0x00a', '10', '0x0000000000000000000000000000000a'], // hex string with odd padding
[new BN(10), '10', '0x0000000000000000000000000000000a'],
[BigInt(10), '10', '0x0000000000000000000000000000000a'],
[Buffer.from([0x0a]), '10', '0x0000000000000000000000000000000a'],
[Buffer.from([0x00, 0x0a]), '10', '0x0000000000000000000000000000000a'],
[Uint8Array.of(0x0a), '10', '0x0000000000000000000000000000000a'],
@@ -329,7 +328,7 @@ describe('Clarity Types', () => {
[10n, '10', '0x0000000000000000000000000000000a'],
['10', '10', '0x0000000000000000000000000000000a'],
['0x0a', '10', '0x0000000000000000000000000000000a'],
[new BN(10), '10', '0x0000000000000000000000000000000a'],
[BigInt(10), '10', '0x0000000000000000000000000000000a'],
[Buffer.from([0x0a]), '10', '0x0000000000000000000000000000000a'],
[Buffer.from([0x00, 0x0a]), '10', '0x0000000000000000000000000000000a']
]

View File

@@ -52,7 +52,6 @@
"bip32": "2.0.6",
"bip39": "^3.0.2",
"bitcoinjs-lib": "^5.1.6",
"bn.js": "^4.12.0",
"c32check": "^1.1.3",
"jsontokens": "^3.0.0",
"randombytes": "^2.1.0",