-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sdk): add sdk.utils; with addMemoToTx method
- Loading branch information
1 parent
c63336a
commit 5244b21
Showing
13 changed files
with
104 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}) | ||
), | ||
}); | ||
}) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |