Skip to content

Commit

Permalink
Adding support for aligned-unlocks to Stream package (#214)
Browse files Browse the repository at this point in the history
* Adding support for aligned-unlocks create and cancel

* update get and error handling to supprot aligned unlocks

* small refactor + PR comments

* address PR comments and get function

* strongly typed refactor

* minor adjustments

* bump version and computLimit fix

* fix cancel instruction and end time decoding

* remove console.log
  • Loading branch information
tatomir-streamflow authored Oct 16, 2024
1 parent a3aa2b2 commit 1fe1f2d
Show file tree
Hide file tree
Showing 21 changed files with 3,369 additions and 223 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"packages": ["packages/*"],
"version": "7.0.0-alpha.12",
"version": "7.0.0-alpha.13",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
2 changes: 1 addition & 1 deletion 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.12",
"version": "7.0.0-alpha.13",
"description": "Common utilities and types used by streamflow packages.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "./dist/esm/index.js",
Expand Down
2 changes: 1 addition & 1 deletion 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.12",
"version": "7.0.0-alpha.13",
"description": "JavaScript SDK to interact with Streamflow Airdrop protocol.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "dist/esm/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/eslint-config",
"version": "7.0.0-alpha.12",
"version": "7.0.0-alpha.13",
"license": "ISC",
"main": "index.js",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/staking/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/staking",
"version": "7.0.0-alpha.11",
"version": "7.0.0-alpha.13",
"description": "JavaScript SDK to interact with Streamflow Staking protocol.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "dist/esm/index.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/stream/aptos/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import BN from "bn.js";
import { Buffer } from "buffer";

import { buildStreamType, calculateUnlockedAmount } from "../common/contractUtils.js";
import { Stream, StreamType } from "../common/types.js";
import { LinearStream, StreamType } from "../common/types.js";
import { normalizeAptosAddress } from "./utils.js";
import { getNumberFromBN } from "../common/utils.js";

Expand Down Expand Up @@ -70,7 +70,7 @@ export interface ConfigResource {
withdrawor: string;
}

export class Contract implements Stream {
export class Contract implements LinearStream {
magic: number;

version: number;
Expand Down
2 changes: 2 additions & 0 deletions packages/stream/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import BN from "bn.js";

export const MAX_SAFE_UNIX_TIME_VALUE = 8640000000000;

export const BASE_FEE = 1009900; // Buffer to include usual fees when calculating stream amount
export const WITHDRAW_AVAILABLE_AMOUNT = new BN("18446744073709551615"); // Magical number to withdraw all available amount from a Contract
18 changes: 17 additions & 1 deletion packages/stream/common/contractUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BN from "bn.js";

import { StreamType } from "./types.js";
import { AlignedStream, ICreateAlignedStreamData, ICreateStreamData, Stream, StreamType } from "./types.js";
import { MAX_SAFE_UNIX_TIME_VALUE } from "./constants.js";

interface ICalculateUnlockedAmount {
depositedAmount: BN;
Expand Down Expand Up @@ -52,6 +53,14 @@ export const isVesting = (streamData: { canTopup: boolean; depositedAmount: BN;
return !streamData.canTopup && !isCliffCloseToDepositedAmount(streamData);
};

export const isAligned = (stream: Stream): stream is AlignedStream => {
return "minPrice" in stream && "maxPrice" in stream && "minPercentage" in stream && "maxPercentage" in stream;
};

export const isCreateAlignedStreamData = (obj: ICreateStreamData): obj is ICreateAlignedStreamData => {
return "minPrice" in obj && "maxPrice" in obj && "minPercentage" in obj && "maxPercentage" in obj;
};

export const isTokenLock = (streamData: {
canTopup: boolean;
automaticWithdrawal: boolean;
Expand Down Expand Up @@ -91,3 +100,10 @@ export const buildStreamType = (streamData: {
}
return StreamType.Payment;
};

export const decodeEndTime = (endTime: BN): number => {
if (endTime.gt(new BN(MAX_SAFE_UNIX_TIME_VALUE))) {
return MAX_SAFE_UNIX_TIME_VALUE;
}
return endTime.toNumber();
};
178 changes: 127 additions & 51 deletions packages/stream/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Address } from "@coral-xyz/anchor";
import { TransactionInstruction } from "@solana/web3.js";
import { Types } from "aptos";
import BN from "bn.js";

export { IChain, ICluster, ContractError } from "@streamflow/common";

// Stream Client Types
export interface IRecipient {
recipient: string;
amount: BN;
Expand All @@ -13,7 +13,7 @@ export interface IRecipient {
amountPerPeriod: BN;
}

export interface IStreamConfig {
export interface IBaseStreamConfig {
period: number;
start: number;
cliff: number;
Expand All @@ -30,12 +30,31 @@ export interface IStreamConfig {
partner?: string;
}

export type ICreateStreamData = IStreamConfig & IRecipient;
export type IAlignedStreamConfig = {
minPrice: number;
maxPrice: number;
minPercentage: number;
maxPercentage: number;
oracleType?: OracleTypeName;
priceOracle?: Address;
skipInitial?: boolean;
tickSize?: number;
};

export type ICreateLinearStreamData = IBaseStreamConfig & IRecipient;

export type ICreateAlignedStreamData = ICreateLinearStreamData & IAlignedStreamConfig;

export type ICreateStreamData = ICreateLinearStreamData | ICreateAlignedStreamData;

export type ICreateMultipleStreamData = IStreamConfig & {
export type ICreateMultipleLinearStreamData = IBaseStreamConfig & {
recipients: IRecipient[];
};

export type ICreateMultipleAlignedStreamData = ICreateMultipleLinearStreamData & IAlignedStreamConfig;

export type ICreateMultipleStreamData = ICreateMultipleLinearStreamData | ICreateMultipleAlignedStreamData;

export interface IInteractData {
id: string;
}
Expand Down Expand Up @@ -101,6 +120,8 @@ export interface IMultiTransactionResult {
errors: ICreateMultiError[];
}

export type OracleTypeName = "none" | "pyth" | "switchboard" | "test";

export enum StreamDirection {
Outgoing = "outgoing",
Incoming = "incoming",
Expand Down Expand Up @@ -154,6 +175,72 @@ export enum ContractErrorCode {
ENO_RECIPIENT_COIN_ADDRESS = "ENO_RECIPIENT_COIN_ADDRESS",
}

// Base types, implemented by each chain package
export interface LinearStream {
magic: number;
version: number;
createdAt: number;
withdrawnAmount: BN;
canceledAt: number;
end: number;
lastWithdrawnAt: number;
sender: string;
senderTokens: string;
recipient: string;
recipientTokens: string;
mint: string;
escrowTokens: string;
streamflowTreasury: string;
streamflowTreasuryTokens: string;
streamflowFeeTotal: BN;
streamflowFeeWithdrawn: BN;
streamflowFeePercent: number;
partnerFeeTotal: BN;
partnerFeeWithdrawn: BN;
partnerFeePercent: number;
partner: string;
partnerTokens: string;
start: number;
depositedAmount: BN;
period: number;
amountPerPeriod: BN;
cliff: number;
cliffAmount: BN;
cancelableBySender: boolean;
cancelableByRecipient: boolean;
automaticWithdrawal: boolean;
transferableBySender: boolean;
transferableByRecipient: boolean;
canTopup: boolean;
name: string;
withdrawalFrequency: number;
closed: boolean;
currentPauseStart: number;
pauseCumulative: BN;
lastRateChangeTime: number;
fundsUnlockedAtLastRateChange: BN;

type: StreamType;

unlocked(currentTimestamp: number): BN;

remaining(decimals: number): number;
}

export type AlignedStreamData = {
minPrice: number;
maxPrice: number;
minPercentage: number;
maxPercentage: number;
oracleType: OracleTypeName;
priceOracle: string | undefined;
tickSize: number;
};

export type AlignedStream = LinearStream & AlignedStreamData;

export type Stream = LinearStream | AlignedStream;

/**
* Error codes raised by Solana protocol specifically
*/
Expand Down Expand Up @@ -206,54 +293,43 @@ export enum SolanaContractErrorCode {
MetadataNotRentExempt = "MetadataNotRentExempt",
}

// Base types, implemented by each chain package
export interface Stream {
magic: number;
version: number;
createdAt: number;
withdrawnAmount: BN;
canceledAt: number;
end: number;
lastWithdrawnAt: number;
sender: string;
senderTokens: string;
recipient: string;
recipientTokens: string;
mint: string;
escrowTokens: string;
streamflowTreasury: string;
streamflowTreasuryTokens: string;
streamflowFeeTotal: BN;
streamflowFeeWithdrawn: BN;
streamflowFeePercent: number;
partnerFeeTotal: BN;
partnerFeeWithdrawn: BN;
partnerFeePercent: number;
partner: string;
partnerTokens: string;
start: number;
depositedAmount: BN;
period: number;
amountPerPeriod: BN;
cliff: number;
cliffAmount: BN;
cancelableBySender: boolean;
cancelableByRecipient: boolean;
automaticWithdrawal: boolean;
transferableBySender: boolean;
transferableByRecipient: boolean;
canTopup: boolean;
name: string;
withdrawalFrequency: number;
closed: boolean;
currentPauseStart: number;
pauseCumulative: BN;
lastRateChangeTime: number;
fundsUnlockedAtLastRateChange: BN;
export enum SolanaAlignedProxyErrorCode {
/** Authority does not have permission for this action */
Unauthorized = "Unauthorized",

type: StreamType;
/** Arithmetic error */
ArithmeticError = "ArithmeticError",

unlocked(currentTimestamp: number): BN;
/** Mint has unsupported Token Extensions */
UnsupportedTokenExtensions = "UnsupportedTokenExtensions",

remaining(decimals: number): number;
/** Provided period is too short, should be equal or more than 30 seconds */
PeriodTooShort = "PeriodTooShort",

/** Provided percentage tick size is invalid */
InvalidTickSize = "InvalidTickSize",

/** Provided percentage bounds are invalid */
InvalidPercentageBoundaries = "InvalidPercentageBoundaries",

/** Provided price bounds are invalid */
InvalidPriceBoundaries = "InvalidPriceBoundaries",

/** Unsupported price oracle */
UnsupportedOracle = "UnsupportedOracle",

/** Invalid oracle account */
InvalidOracleAccount = "InvalidOracleAccount",

/** Invalid oracle price */
InvalidOraclePrice = "InvalidOraclePrice",

/** Invalid Stream Metadata */
InvalidStreamMetadata = "InvalidStreamMetadata",

/** Release amount has already been updated in this period */
AmountAlreadyUpdated = "AmountAlreadyUpdated",

/** All funds are already unlocked */
AllFundsUnlocked = "AllFundsUnlocked",
}
4 changes: 2 additions & 2 deletions packages/stream/evm/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import BN from "bn.js";
import { BigNumber as BigNumberEvm } from "ethers";

import { buildStreamType, calculateUnlockedAmount } from "../common/contractUtils.js";
import { Stream, StreamType } from "../common/types.js";
import { LinearStream, StreamType } from "../common/types.js";
import { getNumberFromBN } from "../common/utils.js";

export interface StreamAbiResult {
Expand Down Expand Up @@ -54,7 +54,7 @@ export interface FeesAbiResult {
partner_fee: BigNumberEvm;
}

export class EvmContract implements Stream {
export class EvmContract implements LinearStream {
magic: number;

version: number;
Expand Down
3 changes: 2 additions & 1 deletion packages/stream/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/stream",
"version": "7.0.0-alpha.12",
"version": "7.0.0-alpha.13",
"description": "JavaScript SDK to interact with Streamflow protocol.",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
"main": "./dist/esm/index.js",
Expand Down Expand Up @@ -51,6 +51,7 @@
"@types/bn.js": "5.1.1"
},
"dependencies": {
"@coral-xyz/anchor": "^0.30.0",
"@coral-xyz/borsh": "0.30.1",
"@manahippo/aptos-wallet-adapter": "1.0.10",
"@mysten/sui.js": "0.54.1",
Expand Down
Loading

0 comments on commit 1fe1f2d

Please sign in to comment.