Polygon
@stakefish/sdk-polygon
The @stakefish/sdk-polygon is a JavaScript/TypeScript library that provides a unified interface for staking operations on the Polygon PoS blockchain with stake.fish validators. It allows developers to easily delegate stakes, undelegate, claim rewards, sign transactions, and broadcast them to the network.
Table of Contents
Installation
To use this SDK in your project, install it via npm or yarn:
npm install @stakefish/sdk-polygonyarn add @stakefish/sdk-polygonType Imports
import { Polygon } from '@stakefish/sdk-polygon';
import type {
PolygonConfig,
PolygonPrepareDelegate,
PolygonPrepareUndelegate,
PolygonPrepareClaimRewards,
PolygonPrepareClaimUnstaked,
PolygonPrepareRestakeRewards,
PolygonPrepareApprove,
PolygonGetBalance,
PolygonGetAllowance,
PolygonSign,
PolygonBroadcast,
PolygonUnsignedTransaction,
PolygonSignedTransaction,
PolygonTransactionBroadcastResult,
} from '@stakefish/sdk-polygon';API Reference
Constructor
import type { PolygonConfig } from '@stakefish/sdk-polygon';
new Polygon({ ethereumRpcUrl: 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID' }: PolygonConfig)Creates a new Polygon SDK instance.
Parameters:
ethereumRpcUrl: Ethereum RPC endpoint URL for transaction broadcasting
delegate
import type { PolygonPrepareDelegate, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
delegate({ delegatorAddress: '0x...', amount: '1000000000000000000', token: 'POL' }: PolygonPrepareDelegate): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction for delegating a specified amount of POL or MATIC tokens (in wei, the smallest unit) from the delegator's address to the stake.fish validator.
Parameters:
delegatorAddress: The Ethereum address of the delegator (e.g.,0x...)amount: The amount to delegate in wei (1 POL = 10^18 wei, 1 MATIC = 10^18 wei)token(optional): Token to delegate ('POL'or'MATIC'), defaults to'POL'
undelegate
import type { PolygonPrepareUndelegate, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
undelegate({ delegatorAddress: '0x...', amount: '1000000000000000000' }: PolygonPrepareUndelegate): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction for undelegating a specified amount from the stake.fish validator. This starts a 3-4 day unbonding period.
Parameters:
delegatorAddress: The Ethereum address of the delegatoramount: The amount to undelegate in wei (1 POL = 10^18 wei)
claimRewards
import type { PolygonPrepareClaimRewards, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
claimRewards({ delegatorAddress: '0x...' }: PolygonPrepareClaimRewards): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction for claiming POL staking rewards from the stake.fish validator.
Parameters:
delegatorAddress: The Ethereum address of the delegator
claimUnstaked
import type { PolygonPrepareClaimUnstaked, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
claimUnstaked({ delegatorAddress: '0x...', unbondNonce: '12345' }: PolygonPrepareClaimUnstaked): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction for claiming unstaked tokens after the unbonding period has completed.
Parameters:
delegatorAddress: The Ethereum address of the delegatorunbondNonce: The nonce from the undelegation transaction
restakeRewards
import type { PolygonPrepareRestakeRewards, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
restakeRewards({ delegatorAddress: '0x...' }: PolygonPrepareRestakeRewards): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction for compounding POL staking rewards into delegation.
Parameters:
delegatorAddress: The Ethereum address of the delegator
approve
import type { PolygonPrepareApprove, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
approve({ delegatorAddress: '0x...', amount: '1000000000000000000', token: 'POL' }: PolygonPrepareApprove): Promise<PolygonUnsignedTransaction>Creates an unsigned transaction to approve the StakeManager contract to spend tokens on behalf of the delegator. Important: Approval must be given to the StakeManager contract, NOT the ValidatorShare contract.
Parameters:
delegatorAddress: The Ethereum address of the delegatoramount: The amount to approve in weitoken(optional): Token to approve ('POL'or'MATIC'), defaults to'POL'
getBalance
import type { PolygonGetBalance } from '@stakefish/sdk-polygon';
getBalance({ delegatorAddress: '0x...', token: 'POL' }: PolygonGetBalance): Promise<string>Gets the token balance for a given address.
Parameters:
delegatorAddress: The Ethereum address to check balance fortoken(optional): Token to check balance for ('POL'or'MATIC'), defaults to'POL'
getAllowance
import type { PolygonGetAllowance } from '@stakefish/sdk-polygon';
getAllowance({ delegatorAddress: '0x...', token: 'POL' }: PolygonGetAllowance): Promise<string>Gets the amount of tokens that the StakeManager contract is approved to spend on behalf of the delegator.
Parameters:
delegatorAddress: The Ethereum address of the delegatortoken(optional): Token to check allowance for ('POL'or'MATIC'), defaults to'POL'
sign
import type { PolygonSign, PolygonSignedTransaction, PolygonUnsignedTransaction } from '@stakefish/sdk-polygon';
sign({ privateKeyHex: '0x...', unsignedTx }: PolygonSign): Promise<PolygonSignedTransaction>Signs the unsigned transaction using the provided private key. This operation works completely offline and does not require network connectivity.
Parameters:
privateKeyHex: The private key in hexadecimal format (with or without'0x'prefix)unsignedTx: The unsigned transaction object fromdelegate(),undelegate(),claimRewards(),claimUnstaked(), orrestakeRewards()
broadcast
import type { PolygonBroadcast, PolygonTransactionBroadcastResult, PolygonSignedTransaction } from '@stakefish/sdk-polygon';
broadcast({ signedTx, checkInclusion: false, timeoutMs: 60000, pollIntervalMs: 2000 }: PolygonBroadcast): Promise<PolygonTransactionBroadcastResult>Broadcasts the signed transaction to the Ethereum network and optionally waits for inclusion confirmation.
Parameters:
signedTx: The signed transaction object fromsign()checkInclusion(optional): Whether to wait for transaction inclusion (default:false)timeoutMs(optional): Maximum time to wait for inclusion in milliseconds (default:60000)pollIntervalMs(optional): Interval between inclusion checks in milliseconds (default:2000)
Returns: PolygonTransactionBroadcastResult object containing:
txId: The transaction hashsuccess: Boolean indicating if the transaction was successfulerror: Error message if the transaction failed (optional)
Examples
Full delegation example
import { Polygon } from '@stakefish/sdk-polygon';
import type {
PolygonConfig,
PolygonUnsignedTransaction,
PolygonSignedTransaction,
PolygonTransactionBroadcastResult,
} from '@stakefish/sdk-polygon';
// or: const { Polygon } = require('@stakefish/sdk-polygon');
const delegator = process.env.ETHEREUM_ADDRESS;
const rpcUrl = process.env.ETHEREUM_RPC_URL;
const privateKeyHex = process.env.ETHEREUM_PRIVATE_KEY;
async function main() {
const polygon = new Polygon({
ethereumRpcUrl: rpcUrl,
});
// Delegation (1 POL = 10^18 wei)
const unsignedTx: PolygonUnsignedTransaction = await polygon.delegate({
delegatorAddress: delegator,
amount: '1000000000000000000',
});
// Sign
const signedTx: PolygonSignedTransaction = await polygon.sign({ privateKeyHex, unsignedTx });
// Broadcast
const result: PolygonTransactionBroadcastResult = await polygon.broadcast({ signedTx });
console.log('Broadcast result:', JSON.stringify(result));
}
void main().catch(console.error);MATIC Delegation
// Delegation with MATIC tokens (1 MATIC = 10^18 wei)
const unsignedTx: PolygonUnsignedTransaction = await polygon.delegate({
delegatorAddress: delegator,
amount: '1000000000000000000',
token: 'MATIC',
});Undelegation
const unsignedTx: PolygonUnsignedTransaction = await polygon.undelegate({
delegatorAddress: delegator,
amount: '1000000000000000000',
});Claim Rewards
const unsignedTx: PolygonUnsignedTransaction = await polygon.claimRewards({
delegatorAddress: delegator,
});Claim Unstaked
const unsignedTx: PolygonUnsignedTransaction = await polygon.claimUnstaked({
delegatorAddress: delegator,
unbondNonce: '12345',
});Restake Rewards
const unsignedTx: PolygonUnsignedTransaction = await polygon.restakeRewards({
delegatorAddress: delegator,
});Approve POL Tokens
// Approve StakeManager contract to spend 1 POL
const unsignedTx: PolygonUnsignedTransaction = await polygon.approve({
delegatorAddress: delegator,
amount: '1000000000000000000',
token: 'POL',
});Approve MATIC Tokens
// Approve StakeManager contract to spend 1 MATIC
const unsignedTx: PolygonUnsignedTransaction = await polygon.approve({
delegatorAddress: delegator,
amount: '1000000000000000000',
token: 'MATIC',
});Check POL Balance
const balance: string = await polygon.getBalance({
delegatorAddress: delegator,
token: 'POL',
});
console.log(`POL Balance: ${balance} wei`);Check MATIC Balance
const balance: string = await polygon.getBalance({
delegatorAddress: delegator,
token: 'MATIC',
});
console.log(`MATIC Balance: ${balance} wei`);Check POL Allowance
const allowance: string = await polygon.getAllowance({
delegatorAddress: delegator,
token: 'POL',
});
console.log(`POL Allowance: ${allowance} wei`);Check MATIC Allowance
const allowance: string = await polygon.getAllowance({
delegatorAddress: delegator,
token: 'MATIC',
});
console.log(`MATIC Allowance: ${allowance} wei`);Configuration
The SDK requires configuration during instantiation with Ethereum RPC endpoint:
import type { PolygonConfig } from '@stakefish/sdk-polygon';
const polygon = new Polygon({
ethereumRpcUrl: 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID',
} as PolygonConfig);Notes
- Staking happens on Ethereum mainnet, not on Polygon chain
- You need ETH to pay gas fees for staking transactions
- POL tokens must be on Ethereum mainnet to stake
- Use Polygon Portal to bridge POL from Polygon to Ethereum if needed
- All amounts in the SDK are specified in wei, the smallest unit of POL (1 POL = 10^18 wei)
- The SDK automatically handles gas estimation and fee calculation for transactions
- Private keys can be provided in hexadecimal format with or without the '0x' prefix
- Private keys should be kept secure and never committed to version control
Updated 9 days ago
