Skip to content

Commit

Permalink
Switch to bignumber.js in v7 (#191)
Browse files Browse the repository at this point in the history
* switch to bignubmer.js initial + rebase

* fixes

* fixes

* public API and README update

* bump to 7.0.0-alpa.2

* fix pre-commit

* lerna version bump and import fixes

* remove comments

* remove more leftover comments
  • Loading branch information
tatomir-streamflow authored and RolginRoman committed Sep 24, 2024
1 parent fa0a0d8 commit 30299b6
Show file tree
Hide file tree
Showing 36 changed files with 455 additions and 458 deletions.
20 changes: 18 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
#!/usr/bin/env sh
#!/bin/sh

. "$(dirname -- "$0")/_/husky.sh"

npm run lint
TARGET_FOLDER="packages/distributor/solana/generated"

OS=$(uname)

echo "Replacing 'BN' with 'BigNumber' in $TARGET_FOLDER and its subfolders"
if [ "$OS" = "Darwin" ]; then
SED_NO_BACKUP=( -i '' )
else
SED_NO_BACKUP=( -i )
fi

find "$TARGET_FOLDER" -type f -name "*.ts" -exec sed "${SED_NO_BACKUP[@]}" -e 's/BN/BigNumber/g' -e 's/bn/bignumber/g' {} +

git add $TARGET_FOLDER

npm run lint
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"packages": [
"packages/*"
],
"version": "7.0.0-alpha.1",
"version": "7.0.0-alpha.2",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
5 changes: 2 additions & 3 deletions packages/common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/common",
"version": "7.0.0-alpha.1",
"version": "7.0.0-alpha.2",
"description": "Common utilities and types used by streamflow packages.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "./dist/esm/index.js",
Expand Down Expand Up @@ -30,7 +30,6 @@
"gitHead": "a37306eba0e762af096db642fa22f07194014cfd",
"devDependencies": {
"@streamflow/eslint-config": "workspace:*",
"@types/bn.js": "5.1.1",
"date-fns": "2.28.0",
"typescript": "^4.9.5"
},
Expand All @@ -41,7 +40,7 @@
"@solana/wallet-adapter-base": "0.9.19",
"@solana/web3.js": "1.90.2",
"aptos": "1.21.0",
"bn.js": "5.2.1",
"bignumber.js": "^9.1.2",
"borsh": "^2.0.0",
"bs58": "5.0.0",
"p-queue": "^8.0.1"
Expand Down
4 changes: 2 additions & 2 deletions packages/common/solana/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import {
createSyncNativeInstruction,
} from "@solana/spl-token";
import { Connection, PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js";
import BN from "bn.js";
import BigNumber from "bignumber.js";

export const prepareWrappedAccount = async (
connection: Connection,
senderAddress: PublicKey,
amount: BN,
amount: BigNumber,
): Promise<TransactionInstruction[]> => {
const tokenAccount = await getAssociatedTokenAddress(NATIVE_MINT, senderAddress, true);

Expand Down
30 changes: 12 additions & 18 deletions packages/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
import BN from "bn.js";
import BigNumber from "bignumber.js";

import { ContractError } from "./types.js";

/**
* Used for conversion of token amounts to their Big Number representation.
* Get Big Number representation in the smallest units from the same value in the highest units.
* @param {number} value - Number of tokens you want to convert to its BN representation.
* Used for token amounts conversion from their Big Number representation to number.
* Get value in the highest units from BigNumber representation of the same value in the smallest units.
* @param {BigNumber} value - Big Number representation of value in the smallest units.
* @param {number} decimals - Number of decimals the token has.
*/
export const getBN = (value: number, decimals: number): BN => {
const decimalPart = value - Math.trunc(value);
const integerPart = new BN(Math.trunc(value));

const decimalE = new BN(decimalPart * 1e9);

const sum = integerPart.mul(new BN(1e9)).add(decimalE);
const resultE = sum.mul(new BN(10).pow(new BN(decimals)));
return resultE.div(new BN(1e9));
export const getNumberFromBigNumber = (bigNum: BigNumber, decimals: number): number => {
return bigNum.div(BigNumber(10).pow(decimals)).toNumber();
};

/**
* Used for token amounts conversion from their Big Number representation to number.
* Get value in the highest units from BN representation of the same value in the smallest units.
* @param {BN} value - Big Number representation of value in the smallest units.
* Used for conversion of token amounts to their Big Number representation.
* Get Big Number representation in the smallest units from the same value in the highest units.
* @param {number} value - Number of tokens you want to convert to its BigNumber representation.
* @param {number} decimals - Number of decimals the token has.
*/
export const getNumberFromBN = (value: BN, decimals: number): number =>
value.gt(new BN(2 ** 53 - 1)) ? value.div(new BN(10 ** decimals)).toNumber() : value.toNumber() / 10 ** decimals;
export const getScaledBigNumber = (value: number | string | BigNumber, decimals: number): BigNumber => {
return new BigNumber(value).times(new BigNumber(10).pow(decimals));
};

/**
* Used to make on chain calls to the contract and wrap raised errors if any
Expand Down
9 changes: 4 additions & 5 deletions packages/distributor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ Automated Airdrop Creation: [notion doc →](https://streamflow.notion.site/Auto
Most common imports:

```javascript
import { BN } from "bn.js";
import { ICluster } from "@streamflow/common";
import { SolanaDistributorClient } from "@streamflow/distributor/solana";
```
Expand Down Expand Up @@ -62,8 +61,8 @@ const res = await client.create(
54, 218, 49, 68, 131, 214, 250, 113, 37, 143, 167, 73, 17, 54, 233, 26, 141, 93, 28, 186, 137, 211, 251, 205,
240, 192, 134, 208, 108, 246, 0, 191,
], // Merkle root
maxNumNodes: new BN("4"), // Number of recipients
maxTotalClaim: new BN("4000000000"), // Total amount to distribute
maxNumNodes: 4, // Number of recipients
maxTotalClaim: "4000000000", // Total amount to distribute
unlockPeriod: 1, // Unlock period in seconds
startVestingTs: 0, // Timestamp when Airdrop starts
endVestingTs: now + 3600 * 24 * 7, // Timestamp when Airdrop ends
Expand Down Expand Up @@ -94,8 +93,8 @@ const claimRes = await client.claim(
43, 104, 75, 183, 12, 38, 37, 153,
],
], // Merkle Proof used to verify claim
amountUnlocked: new BN("0"), // Total amount unlocked for a Recipient
amountLocked: new BN("1000000000"), // Total amount locked for a Recipient
amountUnlocked: "0", // Total amount unlocked for a Recipient
amountLocked: "1000000000", // Total amount locked for a Recipient
},
solanaParams,
);
Expand Down
5 changes: 2 additions & 3 deletions packages/distributor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/distributor",
"version": "7.0.0-alpha.1",
"version": "7.0.0-alpha.2",
"description": "JavaScript SDK to interact with Streamflow Airdrop protocol.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "dist/esm/index.js",
Expand Down Expand Up @@ -29,7 +29,6 @@
"gitHead": "a37306eba0e762af096db642fa22f07194014cfd",
"devDependencies": {
"@streamflow/eslint-config": "workspace:*",
"@types/bn.js": "5.1.1",
"date-fns": "2.28.0",
"typescript": "^4.9.5"
},
Expand All @@ -40,7 +39,7 @@
"@solana/wallet-adapter-base": "0.9.19",
"@solana/web3.js": "1.90.2",
"@streamflow/common": "workspace:*",
"bn.js": "5.2.1",
"bignumber.js": "^9.1.2",
"borsh": "^2.0.0",
"bs58": "5.0.0",
"p-queue": "^8.0.1"
Expand Down
39 changes: 22 additions & 17 deletions packages/distributor/solana/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import bs58 from "bs58";
import BN from "bn.js";
import BigNumber from "bignumber.js";
import PQueue from "p-queue";
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
Expand Down Expand Up @@ -140,14 +140,14 @@ export default class SolanaDistributorClient {
const senderTokens = await ata(mint, extParams.invoker.publicKey, tokenProgramId);

const args: NewDistributorArgs = {
version: new BN(data.version, 10),
version: BigNumber(data.version),
root: data.root,
maxTotalClaim: data.maxTotalClaim,
maxNumNodes: data.maxNumNodes,
unlockPeriod: new BN(data.unlockPeriod, 10),
startVestingTs: new BN(data.startVestingTs, 10),
endVestingTs: new BN(data.endVestingTs, 10),
clawbackStartTs: new BN(data.clawbackStartTs, 10),
maxTotalClaim: BigNumber(data.maxTotalClaim),
maxNumNodes: BigNumber(data.maxNumNodes),
unlockPeriod: BigNumber(data.unlockPeriod),
startVestingTs: BigNumber(data.startVestingTs),
endVestingTs: BigNumber(data.endVestingTs),
clawbackStartTs: BigNumber(data.clawbackStartTs),
claimsClosable: data.claimsClosable,
};
const accounts: NewDistributorAccounts = {
Expand All @@ -162,13 +162,15 @@ export default class SolanaDistributorClient {
};

if (extParams.isNative) {
ixs.push(...(await prepareWrappedAccount(this.connection, extParams.invoker.publicKey, data.maxTotalClaim)));
ixs.push(
...(await prepareWrappedAccount(this.connection, extParams.invoker.publicKey, BigNumber(data.maxTotalClaim))),
);
}

const nowTs = new BN(Math.floor(Date.now() / 1000));
const endVestingTs = args.endVestingTs.eqn(0) ? nowTs : args.endVestingTs;
const startVestingTs = args.startVestingTs.eqn(0) ? nowTs : args.startVestingTs;
if (endVestingTs.gt(startVestingTs) && endVestingTs.sub(startVestingTs).lt(args.unlockPeriod)) {
const nowTs = BigNumber(Math.floor(Date.now() / 1000));
const endVestingTs = args.endVestingTs.isZero() ? nowTs : args.endVestingTs;
const startVestingTs = args.startVestingTs.isZero() ? nowTs : args.startVestingTs;
if (endVestingTs.gt(startVestingTs) && endVestingTs.minus(startVestingTs).lt(args.unlockPeriod)) {
throw new Error("The unlock period cannot be longer than the total vesting duration!");
}

Expand Down Expand Up @@ -280,15 +282,18 @@ export default class SolanaDistributorClient {

if (!claimStatus) {
const args: NewClaimArgs = {
amountLocked: data.amountLocked,
amountUnlocked: data.amountUnlocked,
amountLocked: BigNumber(data.amountLocked),
amountUnlocked: BigNumber(data.amountUnlocked),
proof: data.proof,
};
ixs.push(newClaim(args, accounts, this.programId));
}

const nowTs = new BN(Math.floor(Date.now() / 1000));
if (claimStatus || (data.amountLocked.gtn(0) && nowTs.sub(distributor.startTs).gte(distributor.unlockPeriod))) {
const nowTs = BigNumber(Math.floor(Date.now() / 1000));
if (
claimStatus ||
(BigNumber(data.amountLocked).gt(0) && nowTs.minus(distributor.startTs).gte(distributor.unlockPeriod))
) {
ixs.push(claimLocked(accounts, this.programId));
}

Expand Down
32 changes: 16 additions & 16 deletions packages/distributor/solana/generated/accounts/ClaimStatus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PublicKey, Connection } from "@solana/web3.js";
import BN from "bn.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
import BigNumber from "bignumber.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars

import { PROGRAM_ID } from "../programId";
Expand All @@ -8,15 +8,15 @@ export interface ClaimStatusFields {
/** Authority that claimed the tokens. */
claimant: PublicKey;
/** Locked amount */
lockedAmount: BN;
lockedAmount: BigNumber;
/** Locked amount withdrawn */
lockedAmountWithdrawn: BN;
lockedAmountWithdrawn: BigNumber;
/** Unlocked amount */
unlockedAmount: BN;
unlockedAmount: BigNumber;
/** Last claim time */
lastClaimTs: BN;
lastClaimTs: BigNumber;
/** Track amount per unlock, can be useful for non-linear vesting */
lastAmountPerUnlock: BN;
lastAmountPerUnlock: BigNumber;
/** Whether claim is closed */
closed: boolean;
/** Buffer for additional fields */
Expand Down Expand Up @@ -52,19 +52,19 @@ export class ClaimStatus {
readonly claimant: PublicKey;

/** Locked amount */
readonly lockedAmount: BN;
readonly lockedAmount: BigNumber;

/** Locked amount withdrawn */
readonly lockedAmountWithdrawn: BN;
readonly lockedAmountWithdrawn: BigNumber;

/** Unlocked amount */
readonly unlockedAmount: BN;
readonly unlockedAmount: BigNumber;

/** Last claim time */
readonly lastClaimTs: BN;
readonly lastClaimTs: BigNumber;

/** Track amount per unlock, can be useful for non-linear vesting */
readonly lastAmountPerUnlock: BN;
readonly lastAmountPerUnlock: BigNumber;

/** Whether claim is closed */
readonly closed: boolean;
Expand Down Expand Up @@ -174,11 +174,11 @@ export class ClaimStatus {
static fromJSON(obj: ClaimStatusJSON): ClaimStatus {
return new ClaimStatus({
claimant: new PublicKey(obj.claimant),
lockedAmount: new BN(obj.lockedAmount),
lockedAmountWithdrawn: new BN(obj.lockedAmountWithdrawn),
unlockedAmount: new BN(obj.unlockedAmount),
lastClaimTs: new BN(obj.lastClaimTs),
lastAmountPerUnlock: new BN(obj.lastAmountPerUnlock),
lockedAmount: BigNumber(obj.lockedAmount),
lockedAmountWithdrawn: BigNumber(obj.lockedAmountWithdrawn),
unlockedAmount: BigNumber(obj.unlockedAmount),
lastClaimTs: BigNumber(obj.lastClaimTs),
lastAmountPerUnlock: BigNumber(obj.lastAmountPerUnlock),
closed: obj.closed,
buffer1: obj.buffer1,
buffer2: obj.buffer2,
Expand Down
Loading

0 comments on commit 30299b6

Please sign in to comment.