@atomiqlabs/chain-starknet
Version:
Starknet specific base implementation
148 lines (128 loc) • 5.56 kB
text/typescript
import {toBigInt} from "../../../utils/Utils";
import { IntermediaryReputationType } from "@atomiqlabs/base";
import {StarknetSwapModule} from "../StarknetSwapModule";
import {StarknetAction} from "../../base/StarknetAction";
import {cairo} from "starknet";
import {StarknetTx} from "../../base/modules/StarknetTransactions";
export class StarknetLpVault extends StarknetSwapModule {
private static readonly GasCosts = {
WITHDRAW: {l1: 750, l2: 0},
DEPOSIT: {l1: 750, l2: 0}
};
/**
* Action for withdrawing funds from the LP vault
*
* @param signer
* @param token
* @param amount
* @constructor
* @private
*/
private Withdraw(signer: string, token: string, amount: bigint): StarknetAction {
return new StarknetAction(signer, this.root,
this.contract.populateTransaction.withdraw(token, cairo.uint256(amount), signer),
StarknetLpVault.GasCosts.WITHDRAW
);
}
/**
* Action for depositing funds to the LP vault
*
* @param signer
* @param token
* @param amount
* @constructor
* @private
*/
private Deposit(signer: string, token: string, amount: bigint): StarknetAction {
return new StarknetAction(signer, this.root,
this.contract.populateTransaction.deposit(token, cairo.uint256(amount)),
StarknetLpVault.GasCosts.WITHDRAW
);
}
/**
* Returns intermediary's reputation & vault balance for a specific token
*
* @param address
* @param token
*/
public async getIntermediaryData(address: string, token: string): Promise<{
balance: bigint,
reputation: IntermediaryReputationType
}> {
const [balance, reputation] = await Promise.all([
this.getIntermediaryBalance(address, token),
this.getIntermediaryReputation(address, token)
]);
return {balance, reputation};
}
/**
* Returns intermediary's reputation for a specific token
*
* @param address
* @param token
*/
public async getIntermediaryReputation(address: string, token: string): Promise<IntermediaryReputationType> {
const filter = Object.keys(this.root.claimHandlersByAddress).map(claimHandler => cairo.tuple(address, token, claimHandler));
const rawReputation = await this.provider.callContract(this.contract.populateTransaction.get_reputation(filter));
const length = toBigInt(rawReputation.shift());
if(Number(length)!==filter.length) throw new Error("getIntermediaryReputation(): Invalid response length");
const result: any = {};
Object.keys(this.root.claimHandlersByAddress).forEach((address) => {
const handler = this.root.claimHandlersByAddress[address];
result[handler.getType()] = {
successVolume: toBigInt({low: rawReputation.shift(), high: rawReputation.shift()}),
successCount: toBigInt(rawReputation.shift()),
coopCloseVolume: toBigInt({low: rawReputation.shift(), high: rawReputation.shift()}),
coopCloseCount: toBigInt(rawReputation.shift()),
failVolume: toBigInt({low: rawReputation.shift(), high: rawReputation.shift()}),
failCount: toBigInt(rawReputation.shift()),
};
});
return result as any;
}
/**
* Returns the balance of the token an intermediary has in his LP vault
*
* @param address
* @param token
*/
public async getIntermediaryBalance(address: string, token: string): Promise<bigint> {
const balance = toBigInt((await this.contract.get_balance([cairo.tuple(address, token)]))[0]);
this.logger.debug("getIntermediaryBalance(): token LP balance fetched, token: "+token.toString()+
" address: "+address+" amount: "+(balance==null ? "null" : balance.toString()));
return balance;
}
/**
* Creates transactions for withdrawing funds from the LP vault, creates ATA if it doesn't exist and unwraps
* WSOL to SOL if required
*
* @param signer
* @param token
* @param amount
* @param feeRate
*/
public async txsWithdraw(signer: string, token: string, amount: bigint, feeRate?: string): Promise<StarknetTx[]> {
const action = await this.Withdraw(signer, token, amount);
feeRate ??= await this.root.Fees.getFeeRate();
this.logger.debug("txsWithdraw(): withdraw TX created, token: "+token.toString()+
" amount: "+amount.toString(10));
return [await action.tx(feeRate)];
}
/**
* Creates transaction for depositing funds into the LP vault, wraps SOL to WSOL if required
*
* @param signer
* @param token
* @param amount
* @param feeRate
*/
public async txsDeposit(signer: string, token: string, amount: bigint, feeRate?: string): Promise<StarknetTx[]> {
//Approve first
const action = await this.root.Tokens.Approve(signer, this.contract.address, token, amount);
action.add(this.Deposit(signer, token, amount));
feeRate ??= await this.root.Fees.getFeeRate();
this.logger.debug("txsDeposit(): deposit TX created, token: "+token.toString()+
" amount: "+amount.toString(10));
return [await action.tx(feeRate)];
}
}