π±Staking
The StakingService class reachable through sodax.staking instance provides functionality for staking SODA tokens, unstaking, claiming rewards, and retrieving staking information. It supports operations across different blockchain chains with automatic hub chain integration.
Methods
isAllowanceValid
Checks if the current allowance is sufficient for the staking operations.
Parameters:
params: Staking parameters including action type and amountspokeProvider: The spoke chain provider instance
Returns: Promise<Result<boolean, StakingError<'ALLOWANCE_CHECK_FAILED'>>>
Note: For Stellar-based operations, the allowance system works differently:
Source Chain (Stellar): The standard
isAllowanceValidmethod works as expected for EVM chains, but for Stellar as the source chain, this method checks and establishes trustlines automatically.Staking Flow: Staking operations always flow from spoke chains (including Stellar) to the hub chain (Sonic), so Stellar is only used as a source chain for staking operations.
Example:
const result = await sodax.staking.isAllowanceValid({
params: {
amount: 1000000000000000000n, // 1 SODA
minReceive: 950000000000000000n, // 0.95 xSODA minimum
account: '0x1234567890abcdef...',
action: 'stake'
},
spokeProvider: baseSpokeProvider
});
if (result.ok && result.value) {
console.log('Allowance is sufficient');
} else {
console.log('Need to approve tokens first');
}approve
Approves token spending for the staking operations. This method is only supported for EVM-based spoke chains.
Parameters:
params: Staking parametersspokeProvider: The spoke provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'APPROVAL_FAILED'>>>
Note: For Stellar-based operations, the approval system works differently:
Source Chain (Stellar): The standard
approvemethod works as expected for EVM chains, but for Stellar as the source chain, this method establishes trustlines automatically.Staking Flow: Staking operations always flow from spoke chains (including Stellar) to the hub chain (Sonic), so Stellar is only used as a source chain for staking operations.
Example:
Stellar Trustline Requirements
For Stellar-based staking operations, you need to handle trustlines when Stellar is used as the source chain. See Stellar Trustline Requirements for detailed information and code examples.
Note: Staking operations always flow from spoke chains (including Stellar) to the hub chain (Sonic), so Stellar is only used as a source chain for staking operations.
stake
Executes a complete stake transaction, including creating the stake intent and relaying it to the hub chain.
Parameters:
params: Stake parameters including amount, minimum receive amount, and accountspokeProvider: The spoke chain provider instancetimeout: Optional timeout in milliseconds (default: 60 seconds)
Returns: Promise<Result<[SpokeTxHash, HubTxHash], StakingError<'STAKE_FAILED'> | RelayError>>
Example:
createStakeIntent
Creates a stake intent on the spoke chain without relaying it to the hub. This is useful for advanced users who want to handle the relaying process manually.
Parameters:
params: Stake parameters including amount, minimum receive amount, and accountspokeProvider: The spoke chain provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'STAKE_FAILED'>> & { data?: { address: string; payload: Hex } }>
Example:
Note: This method only executes the transaction on the spoke chain and creates the stake intent. To successfully stake tokens, you need to:
Check if the allowance is sufficient using
isAllowanceValidApprove the appropriate contract to spend the tokens using
approveCreate the stake intent using this method
Relay the transaction to the hub and await completion using the
stakemethod
unstake
Executes a complete unstake transaction for unstaking xSoda shares.
Parameters:
params: Unstake parameters including amount and accountspokeProvider: The spoke chain provider instancetimeout: Optional timeout in milliseconds (default: 60 seconds)
Returns: Promise<Result<[SpokeTxHash, HubTxHash], StakingError<'UNSTAKE_FAILED'> | RelayError>>
Example:
createUnstakeIntent
Creates an unstake intent on the spoke chain without relaying it to the hub.
Parameters:
params: Unstake parameters including amount and accountspokeProvider: The spoke chain provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'UNSTAKE_FAILED'>> & { data?: { address: string; payload: Hex } }>
Example:
Note: This method only executes the transaction on the spoke chain and creates the unstake intent. To successfully unstake tokens, you need to:
Check if the allowance is sufficient using
isAllowanceValidApprove the appropriate contract to spend the tokens using
approveCreate the unstake intent using this method
Relay the transaction to the hub and await completion using the
unstakemethod
instantUnstake
Executes a complete instant unstake transaction for instantly unstaking xSoda shares.
Parameters:
params: Instant unstake parameters including amount, minimum amount, and accountspokeProvider: The spoke chain provider instancetimeout: Optional timeout in milliseconds (default: 60 seconds)
Returns: Promise<Result<[SpokeTxHash, HubTxHash], StakingError<'INSTANT_UNSTAKE_FAILED'> | RelayError>>
Example:
createInstantUnstakeIntent
Creates an instant unstake intent on the spoke chain without relaying it to the hub.
Parameters:
params: Instant unstake parameters including amount, minimum amount, and accountspokeProvider: The spoke chain provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'INSTANT_UNSTAKE_FAILED'>> & { data?: { address: string; payload: Hex } }>
Example:
Note: This method only executes the transaction on the spoke chain and creates the instant unstake intent. To successfully instant unstake tokens, you need to:
Create the instant unstake intent using this method
Relay the transaction to the hub and await completion using the
instantUnstakemethod
claim
Executes a complete claim transaction for claiming unstaked tokens after the unstaking period.
Parameters:
params: Claim parameters including requestId and claimable amountspokeProvider: The spoke chain provider instancetimeout: Optional timeout in milliseconds (default: 60 seconds)
Returns: Promise<Result<[SpokeTxHash, HubTxHash], StakingError<'CLAIM_FAILED'> | RelayError>>
Example:
createClaimIntent
Creates a claim intent on the spoke chain without relaying it to the hub.
Parameters:
params: Claim parameters including requestId and claimable amountspokeProvider: The spoke chain provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'CLAIM_FAILED'>> & { data?: { address: string; payload: Hex } }>
Example:
Note: This method only executes the transaction on the spoke chain and creates the claim intent. To successfully claim tokens, you need to:
Create the claim intent using this method
Relay the transaction to the hub and await completion using the
claimmethod
cancelUnstake
Executes a complete cancel unstake transaction for cancelling an unstake request.
Parameters:
params: Cancel unstake parameters including requestIdspokeProvider: The spoke chain provider instancetimeout: Optional timeout in milliseconds (default: 60 seconds)
Returns: Promise<Result<[SpokeTxHash, HubTxHash], StakingError<'CANCEL_UNSTAKE_FAILED'> | RelayError>>
Example:
createCancelUnstakeIntent
Creates a cancel unstake intent on the spoke chain without relaying it to the hub.
Parameters:
params: Cancel unstake parameters including requestIdspokeProvider: The spoke chain provider instanceraw: Whether to return raw transaction data (optional, default: false)
Returns: Promise<Result<TxReturnType<S, R>, StakingError<'CANCEL_UNSTAKE_FAILED'>> & { data?: { address: string; payload: Hex } }>
Example:
Note: This method only executes the transaction on the spoke chain and creates the cancel unstake intent. To successfully cancel an unstake request, you need to:
Create the cancel unstake intent using this method
Relay the transaction to the hub and await completion using the
cancelUnstakemethod
getStakingInfoFromSpoke
Retrieves comprehensive staking information for a user using spoke provider.
Parameters:
spokeProvider: The spoke chain provider instance
Returns: Promise<Result<StakingInfo, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getStakingInfo
Retrieves comprehensive staking information for a user by address.
Parameters:
userAddress: The user's address
Returns: Promise<Result<StakingInfo, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getUnstakingInfo
Retrieves unstaking information for a user.
Parameters:
param: The user's address or spoke provider
Returns: Promise<Result<UnstakingInfo, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getUnstakingInfoWithPenalty
Retrieves unstaking information with penalty calculations for a user.
Parameters:
param: The user's address or spoke provider
Returns: Promise<Result<UnstakingInfo & { requestsWithPenalty: UnstakeRequestWithPenalty[] }, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getStakingConfig
Retrieves staking configuration from the stakedSoda contract.
Returns: Promise<Result<StakingConfig, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getInstantUnstakeRatio
Retrieves the instant unstake ratio for a given amount.
Parameters:
amount: The amount of xSoda to estimate instant unstake for
Returns: Promise<Result<bigint, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getConvertedAssets
Retrieves converted assets amount for xSODA shares.
Parameters:
amount: The amount of xSoda shares to convert
Returns: Promise<Result<bigint, StakingError<'INFO_FETCH_FAILED'>>>
Example:
getStakeRatio
Retrieves stake ratio for a given amount (xSoda amount and preview deposit).
Parameters:
amount: The amount of SODA to estimate stake for
Returns: Promise<Result<[bigint, bigint], StakingError<'INFO_FETCH_FAILED'>>>
Example:
Types
StakeParams
UnstakeParams
ClaimParams
CancelUnstakeParams
InstantUnstakeParams
StakingInfo
UnstakingInfo
UnstakeRequestWithPenalty
StakingConfig
StakingAction
Error Handling
All methods return a Result type that indicates success or failure:
Common error codes include:
STAKE_FAILED: Stake transaction failedUNSTAKE_FAILED: Unstake transaction failedINSTANT_UNSTAKE_FAILED: Instant unstake transaction failedCLAIM_FAILED: Claim transaction failedCANCEL_UNSTAKE_FAILED: Cancel unstake transaction failedINFO_FETCH_FAILED: Failed to fetch staking informationALLOWANCE_CHECK_FAILED: Insufficient allowance for the transactionAPPROVAL_FAILED: Token approval transaction failed
Usage Flow
The typical staking operation follows this sequence:
Check allowance using
isAllowanceValid()Approve tokens using
approve()if neededFor Stellar source chains: Check and establish trustlines (see Stellar Trustline Requirements)
Execute staking operation using
stake(),unstake(),instantUnstake(),claim(), orcancelUnstake()Monitor progress using the returned transaction hashes
Supported Chains
The service supports various blockchain networks as source chains for staking operations:
EVM chains (Ethereum, Polygon, Base, etc.)
Sonic (hub chain - can be both source and destination)
Non-EVM chains (Icon, Sui, Stellar, etc.)
Note: All staking operations flow from spoke chains (including Stellar) to the hub chain (Sonic). Stellar and other non-EVM chains can only be used as source chains for staking operations.
Penalty System
The staking system includes a penalty mechanism for early unstaking:
Minimum Unstaking Period: No penalty if unstaking after this period
Maximum Penalty: Applied if unstaking before the minimum period
Reduction Period: Penalty gradually reduces between minimum and full unstaking periods
The penalty is calculated based on the time elapsed since the unstake request was initiated.
Instant Unstaking
Instant unstaking allows users to immediately receive SODA tokens in exchange for xSODA shares, but with a reduced amount due to the instant liquidity mechanism. The actual amount received depends on the current liquidity pool and is calculated using the getInstantUnstakeRatio method.
Last updated