Liquid Staking
Stake SUI and receive afSUI to earn a reliable yield, and hold the most decentralized staking derivative on Sui.
The Staking class provides functionality for staking and unstaking SUI tokens in the Aftermath Finance protocol.
Initialization
const afSdk = new Aftermath("MAINNET");
await afSdk.init(); // initialize provider
const staking = afSdk.Staking();
Constants
Staking.constants = {
fees: {
protocolUnstake: 0.05, // 5%
defaultValidator: 0, // 0%
maxValidator: 0.05, // 5%
},
bounds: {
minStake: BigInt("1000000000"), // 1 SUI
minUnstake: BigInt("1000000000"), // 1 afSUI
maxExternalFeePercentage: 0.5, // 50%
},
defaultValidatorFee: 0, // 0%
};
Methods
Validator Information
// Get active validators
const validators = await staking.getActiveValidators();
// Get validator APYs
const apys = await staking.getValidatorApys();
// Get validator configurations
const configs = await staking.getValidatorConfigs();
// Get delegated stakes for an address
const stakes = await staking.getDelegatedStakes({
walletAddress: "0x...",
});
// Get validator operation caps
const operationCaps = await staking.getValidatorOperationCaps({
walletAddress: "0x...",
});
Staking Operations
// Stake SUI
const stakeTx = await staking.getStakeTransaction({
walletAddress: "0x...",
suiStakeAmount: BigInt("1000000000"),
validatorAddress: "0x...",
referrer: "0x...",
externalFee: {
recipient: "0x...",
feePercentage: 0.01,
},
isSponsoredTx: boolean,
});
// Unstake SUI
const unstakeTx = await staking.getUnstakeTransaction({
walletAddress: "0x...",
afSuiUnstakeAmount: BigInt("1000000000"),
isAtomic: true,
referrer: "0x...",
externalFee: {
recipient: "0x...",
feePercentage: 0.01,
},
isSponsoredTx: boolean,
});
// Stake stakedSUI tokens
const stakeStakedTx = await staking.getStakeStakedSuiTransaction({
walletAddress: "0x...",
stakedSuiIds: ["0x..."],
validatorAddress: "0x...",
referrer: "0x...",
isSponsoredTx: boolean,
});
Queries and Statistics
// Get staking positions
const positions = await staking.getStakingPositions({
walletAddress: "0x...",
cursor: number,
limit: number,
});
// Get total SUI TVL
const tvl = await staking.getSuiTvl();
// Get afSUI/SUI exchange rate
const rate = await staking.getAfSuiToSuiExchangeRate();
// Get staked SUI vault state
const vaultState = await staking.getStakedSuiVaultState();
// Get staking APY
const apy = await staking.getApy();
Validator Management
// Update validator fee
const updateFeeTx = await staking.getUpdateValidatorFeeTransaction({
walletAddress: "0x...",
validatorOperationCapId: "0x...",
newFeePercentage: 0.01,
isSponsoredTx: boolean,
});
// Crank afSUI (update epoch)
const crankTx = await staking.getCrankAfSuiTransaction({
walletAddress: "0x...",
});
Types
Position Types
type StakingPosition = StakePosition | UnstakePosition;
interface StakePosition {
stakedSuiId: string;
suiId: string;
staker: string;
validatorAddress: string;
epoch: bigint;
suiStakeAmount: bigint;
validatorFee: number;
isRestaked: boolean;
afSuiId: string;
afSuiAmount: bigint;
timestamp?: number;
txnDigest: string;
}
interface UnstakePosition {
state: "REQUEST" | "SUI_MINTED";
afSuiId: string;
providedAfSuiAmount: bigint;
requester: string;
epoch: bigint;
suiId?: string;
returnedSuiAmount?: bigint;
timestamp?: number;
txnDigest: string;
}
Validator Types
interface ValidatorConfigObject {
suiAddress: string;
operationCapId: string;
fee: number;
}
interface StakedSuiVaultStateObject {
atomicUnstakeSuiReservesTargetValue: bigint;
atomicUnstakeSuiReserves: bigint;
minAtomicUnstakeFee: bigint;
maxAtomicUnstakeFee: bigint;
totalRewardsAmount: bigint;
totalSuiAmount: bigint;
activeEpoch: bigint;
}
Example Usage
const afSdk = new Aftermath("MAINNET");
await afSdk.init();
const staking = afSdk.Staking();
// Get active validators and APYs
const validators = await staking.getActiveValidators();
const apys = await staking.getValidatorApys();
// Stake SUI
const stakeTx = await staking.getStakeTransaction({
walletAddress: "0x...",
suiStakeAmount: BigInt("1000000000"), // 1 SUI
validatorAddress: validators[0].suiAddress,
});
// Check staking positions
const positions = await staking.getStakingPositions({
walletAddress: "0x...",
});
// Unstake atomic
const unstakeTx = await staking.getUnstakeTransaction({
walletAddress: "0x...",
afSuiUnstakeAmount: BigInt("1000000000"), // 1 afSUI
isAtomic: true,
Last updated