Skip to content

Commit

Permalink
feat(sdk): add sdk.utils; with addMemoToTx method
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonKozAllB committed Nov 23, 2023
1 parent c63336a commit 5244b21
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 74 deletions.
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
TransferStatusResponse,
} from "./models";
import { AllbridgeCoreSdkService, NodeRpcUrlsConfig } from "./services";
import { DefaultUtils, Utils } from "./utils";

export * from "./configs";
export * from "./models";
Expand Down Expand Up @@ -69,6 +70,7 @@ export class AllbridgeCoreSdk {

bridge: BridgeService;
pool: LiquidityPoolService;
utils: Utils;

private service: AllbridgeCoreSdkService;

Expand All @@ -89,6 +91,7 @@ export class AllbridgeCoreSdk {
this.service = new AllbridgeCoreSdkService(nodeRpcUrlsConfig, params);
this.bridge = this.service.bridge;
this.pool = this.service.pool;
this.utils = new DefaultUtils(nodeRpcUrlsConfig.getNodeRpcUrl(ChainSymbol.SOL));
this.params = params;
}

Expand Down
6 changes: 1 addition & 5 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ export {
TxCostAmount,
MessengerTransferTime,
} from "../tokens-info/tokens-info.model";
export {
CheckAllowanceParams as TokensCheckAllowanceParams,
GetAllowanceParams as TokensGetAllowanceParams,
GetTokenBalanceParams as TokensGetTokenBalanceParams,
} from "../services/token/models/token.model";
export {
UserBalanceInfo,
UserBalanceInfoDTO,
Expand All @@ -44,6 +39,7 @@ export {
} from "../utils/calculation/swap-and-bridge-fee-calc";
export { SendAmountDetails, AmountImpact } from "../utils/calculation/swap-and-bridge-details";
export { ChainDetailsMap, ChainDetailsWithTokens } from "../tokens-info";
export { Utils } from "../utils";
export * from "../exceptions";

export enum FeePaymentMethod {
Expand Down
2 changes: 1 addition & 1 deletion src/services/bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AllbridgeCoreClient } from "../../client/core-api";
import { Messenger } from "../../client/core-api/core-api.model";
import { CCTPDoesNotSupportedError, MethodNotSupportedError } from "../../exceptions";
import { TokenWithChainDetails } from "../../tokens-info";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils/utils";
import { Provider, TransactionResponse } from "../models";
import { TokenService } from "../token";
import { EvmBridgeService } from "./evm";
Expand Down
2 changes: 1 addition & 1 deletion src/services/bridge/raw-bridge-transaction-builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NodeRpcUrlsConfig } from "..";
import { AllbridgeCoreClient } from "../../client/core-api";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils/utils";
import { Provider, RawTransaction } from "../models";
import { TokenService } from "../token";
import { ApproveParams, SendParams, SwapParams } from "./models";
Expand Down
37 changes: 5 additions & 32 deletions src/services/bridge/sol/jupiter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { NATIVE_MINT } from "@solana/spl-token";
import { AddressLookupTableAccount, Connection, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import { Connection, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import axios, { AxiosError } from "axios";
import { JupiterError, SdkError } from "../../../exceptions";
import { JupiterError } from "../../../exceptions";
import { fetchAddressLookupTableAccountsFromTx } from "../../../utils/sol";

export class JupiterService {
connection: Connection;
Expand Down Expand Up @@ -70,36 +71,8 @@ export class JupiterService {
sdkTx: VersionedTransaction
): Promise<VersionedTransaction> {
try {
const addressLookupTableAccounts = await Promise.all(
transaction.message.addressTableLookups.map(async (lookup) => {
return new AddressLookupTableAccount({
key: lookup.accountKey,
state: AddressLookupTableAccount.deserialize(
await this.connection.getAccountInfo(lookup.accountKey).then((res) => {
if (!res) {
throw new SdkError("Cannot get AccountInfo");
}
return res.data;
})
),
});
})
);
const sdkAddressLookupTableAccounts = await Promise.all(
sdkTx.message.addressTableLookups.map(async (lookup) => {
return new AddressLookupTableAccount({
key: lookup.accountKey,
state: AddressLookupTableAccount.deserialize(
await this.connection.getAccountInfo(lookup.accountKey).then((res) => {
if (!res) {
throw new SdkError("Cannot get AccountInfo");
}
return res.data;
})
),
});
})
);
const addressLookupTableAccounts = await fetchAddressLookupTableAccountsFromTx(transaction, this.connection);
const sdkAddressLookupTableAccounts = await fetchAddressLookupTableAccountsFromTx(sdkTx, this.connection);

const message = TransactionMessage.decompile(transaction.message, {
addressLookupTableAccounts: addressLookupTableAccounts,
Expand Down
2 changes: 1 addition & 1 deletion src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
SwapAndBridgeCalculationData,
} from "../models";
import { ChainDetailsMap, PoolInfo, PoolKeyObject, TokenWithChainDetails } from "../tokens-info";
import { getPoolInfoByToken, validateAmountDecimals, validateAmountGtZero } from "../utils";
import {
aprInPercents,
convertAmountPrecision,
Expand All @@ -43,6 +42,7 @@ import {
swapAndBridgeFeeCalculation,
swapAndBridgeFeeCalculationReverse,
} from "../utils/calculation/swap-and-bridge-fee-calc";
import { getPoolInfoByToken, validateAmountDecimals, validateAmountGtZero } from "../utils/utils";
import { BridgeService, DefaultBridgeService } from "./bridge";
import { GetNativeTokenBalanceParams } from "./bridge/models";
import { SolanaBridgeParams } from "./bridge/sol";
Expand Down
2 changes: 1 addition & 1 deletion src/services/liquidity-pool/evm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { AbiItem } from "web3-utils";
import { ChainType } from "../../../chains";
import { AllbridgeCoreClient } from "../../../client/core-api";
import { PoolInfo, TokenWithChainDetails } from "../../../tokens-info";
import { promiseWithTimeout } from "../../../utils";
import { calculatePoolInfoImbalance } from "../../../utils/calculation";
import { promiseWithTimeout } from "../../../utils/utils";
import { RawTransaction } from "../../models";
import PoolAbi from "../../models/abi/Pool.json";
import { Pool as PoolContract } from "../../models/abi/types/Pool";
Expand Down
2 changes: 1 addition & 1 deletion src/services/liquidity-pool/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { chainProperties, ChainSymbol, ChainType } from "../../chains";
import { AllbridgeCoreClient } from "../../client/core-api";
import { MethodNotSupportedError } from "../../exceptions";
import { PoolInfo, TokenWithChainDetails } from "../../tokens-info";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils";
import { convertIntAmountToFloat, fromSystemPrecision } from "../../utils/calculation";
import { SYSTEM_PRECISION } from "../../utils/calculation/constants";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils/utils";
import { Provider, TransactionResponse } from "../models";
import { TokenService } from "../token";
import { depositAmountToVUsd, vUsdToWithdrawalAmount } from "../utils/calculation";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NodeRpcUrlsConfig } from "..";
import { AllbridgeCoreClient } from "../../client/core-api";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils";
import { convertFloatAmountToInt } from "../../utils/calculation";
import { SYSTEM_PRECISION } from "../../utils/calculation/constants";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils/utils";
import { Provider, RawTransaction } from "../models";
import { TokenService } from "../token";
import { ApproveParams, LiquidityPoolsParams, LiquidityPoolsParamsWithAmount } from "./models";
Expand Down
2 changes: 1 addition & 1 deletion src/services/token/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import Web3 from "web3";
import { ChainDecimalsByType, chainProperties, ChainSymbol, ChainType } from "../../chains";
import { AllbridgeCoreClient } from "../../client/core-api";
import { AmountFormat, AmountFormatted, MethodNotSupportedError } from "../../models";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils";
import { convertFloatAmountToInt, convertIntAmountToFloat } from "../../utils/calculation";
import { validateAmountDecimals, validateAmountGtZero } from "../../utils/utils";
import { GetNativeTokenBalanceParams } from "../bridge/models";
import { NodeRpcUrlsConfig } from "../index";
import { Provider, RawTransaction, TransactionResponse } from "../models";
Expand Down
60 changes: 30 additions & 30 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import { Big, BigSource } from "big.js";
import { AllbridgeCoreClientPoolInfoCaching } from "../client/core-api/core-client-pool-info-caching";
import { ArgumentInvalidDecimalsError, InvalidAmountError, TimeoutError } from "../exceptions";
import { PoolInfo, TokenWithChainDetails } from "../tokens-info";
import { Connection, PublicKey, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import { SdkError } from "../exceptions";
import { fetchAddressLookupTableAccountsFromTx } from "./sol";

export async function getPoolInfoByToken(
api: AllbridgeCoreClientPoolInfoCaching,
sourceChainToken: TokenWithChainDetails
): Promise<PoolInfo> {
return await api.getPoolInfoByKey({
chainSymbol: sourceChainToken.chainSymbol,
poolAddress: sourceChainToken.poolAddress,
});
/**
* Contains usefully methods
*/
export interface Utils {
/**
* Add memo to solana's transaction
* @param transaction transaction to add memo
* @param memo memo to add (32 char max)
*/
addMemoToTx(transaction: VersionedTransaction, memo: string): Promise<void>;
}

export function validateAmountGtZero(amount: BigSource) {
if (Big(amount).lte(0)) {
throw new InvalidAmountError("Amount must be greater than zero");
}
}
export class DefaultUtils implements Utils {
constructor(readonly solanaRpcUrl: string) {}

export function validateAmountDecimals(argName: string, amountFloat: number | string | Big, decimalRequired: number) {
const amount = Big(amountFloat).toFixed();
if (amount.split(".").length == 2 && amount.split(".")[1].length > decimalRequired) {
throw new ArgumentInvalidDecimalsError(argName, amount.split(".")[1].length, decimalRequired);
async addMemoToTx(transaction: VersionedTransaction, memo: string): Promise<void> {
if (memo.length > 32) {
throw new SdkError("InvalidArgumentException memo cannot be more than 32 characters");
}
const connection = new Connection(this.solanaRpcUrl, "confirmed");
const addressLookupTableAccounts = await fetchAddressLookupTableAccountsFromTx(transaction, connection);
const message = TransactionMessage.decompile(transaction.message, {
addressLookupTableAccounts: addressLookupTableAccounts,
});
message.instructions[message.instructions.length - 1].keys.push({
pubkey: new PublicKey(Buffer.from(memo)),
isSigner: false,
isWritable: false,
});
transaction.message = message.compileToV0Message(addressLookupTableAccounts);
}
}

export async function promiseWithTimeout<T>(promise: Promise<T>, msg: string, timeoutMs: number): Promise<T> {
return (await Promise.race([
promise,
new Promise((resolve, reject) => {
setTimeout(() => reject(new TimeoutError(msg)), timeoutMs);
}),
])) as any as T;
}
22 changes: 22 additions & 0 deletions src/utils/sol/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { AddressLookupTableAccount, Connection, VersionedTransaction } from "@solana/web3.js";

export async function fetchAddressLookupTableAccountsFromTx(
transaction: VersionedTransaction,
connection: Connection
): Promise<AddressLookupTableAccount[]> {
return await Promise.all(
transaction.message.addressTableLookups.map(async (lookup) => {
return new AddressLookupTableAccount({
key: lookup.accountKey,
state: AddressLookupTableAccount.deserialize(
await connection.getAccountInfo(lookup.accountKey).then((res) => {
if (!res) {
throw new Error("Cannot get AccountInfo");
}
return res.data;
})
),
});
})
);
}
36 changes: 36 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Big, BigSource } from "big.js";
import { AllbridgeCoreClientPoolInfoCaching } from "../client/core-api/core-client-pool-info-caching";
import { ArgumentInvalidDecimalsError, InvalidAmountError, TimeoutError } from "../exceptions";
import { PoolInfo, TokenWithChainDetails } from "../tokens-info";

export async function getPoolInfoByToken(
api: AllbridgeCoreClientPoolInfoCaching,
sourceChainToken: TokenWithChainDetails
): Promise<PoolInfo> {
return await api.getPoolInfoByKey({
chainSymbol: sourceChainToken.chainSymbol,
poolAddress: sourceChainToken.poolAddress,
});
}

export function validateAmountGtZero(amount: BigSource) {
if (Big(amount).lte(0)) {
throw new InvalidAmountError("Amount must be greater than zero");
}
}

export function validateAmountDecimals(argName: string, amountFloat: number | string | Big, decimalRequired: number) {
const amount = Big(amountFloat).toFixed();
if (amount.split(".").length == 2 && amount.split(".")[1].length > decimalRequired) {
throw new ArgumentInvalidDecimalsError(argName, amount.split(".")[1].length, decimalRequired);
}
}

export async function promiseWithTimeout<T>(promise: Promise<T>, msg: string, timeoutMs: number): Promise<T> {
return (await Promise.race([
promise,
new Promise((resolve, reject) => {
setTimeout(() => reject(new TimeoutError(msg)), timeoutMs);
}),
])) as any as T;
}

0 comments on commit 5244b21

Please sign in to comment.