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