diff --git a/docs/precompiles/precompiles/distribution.mdx b/docs/precompiles/precompiles/distribution.mdx
index a52b5156..532558f6 100644
--- a/docs/precompiles/precompiles/distribution.mdx
+++ b/docs/precompiles/precompiles/distribution.mdx
@@ -1,6 +1,6 @@
---
-title: 'Distribution Precompile'
-description: 'Claim staking rewards and manage reward distribution through the Distribution precompile contract'
+title: "Distribution Precompile"
+description: "Claim staking rewards and manage reward distribution through the Distribution precompile contract"
icon: "gift"
---
@@ -37,26 +37,13 @@ The Distribution precompile provides access to Sei's staking reward distribution
```
-
- Withdraw staking rewards from multiple validators in a single transaction.
-
- **Parameters:**
- - `validators` (string[]): Array of validator operator addresses
-
- **Returns:** Success boolean
-
- ```typescript
- const validators = [
- "seivaloper1...",
- "seivaloper2...",
- "seivaloper3..."
- ];
-
- const success = await distributionContract.withdrawMultipleDelegationRewards(
- validators
- );
- ```
-
+
+ Withdraw staking rewards from multiple validators in a single transaction.
+ **Parameters:** - `validators` (string[]): Array of validator operator
+ addresses **Returns:** Success boolean ```typescript const validators = [
+ "seivaloper1...", "seivaloper2...", "seivaloper3..." ]; const success = await
+ distributionContract.withdrawMultipleDelegationRewards( validators ); ```
+
Set a custom address to receive withdrawn rewards.
@@ -134,7 +121,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
seiTestnet,
DISTRIBUTION_PRECOMPILE_ABI,
DISTRIBUTION_PRECOMPILE_ADDRESS
- } from '@sei-js/precompiles/viem';
+ } from '@sei-js/precompiles';
const publicClient = createPublicClient({
chain: seiTestnet,
@@ -156,7 +143,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
functionName: 'rewards',
args: [delegatorAddress]
});
-
+
return {
totalRewards: rewards.total.map(coin => ({
denom: coin.denom,
@@ -182,7 +169,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
functionName: 'withdrawDelegationRewards',
args: [validatorAddress]
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
@@ -194,7 +181,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
functionName: 'withdrawMultipleDelegationRewards',
args: [validatorAddresses]
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
@@ -206,7 +193,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
functionName: 'setWithdrawAddress',
args: [withdrawAddress]
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
@@ -214,22 +201,22 @@ The Distribution precompile provides access to Sei's staking reward distribution
async function manageRewards(delegatorAddress: string) {
// 1. Check pending rewards
const pendingRewards = await getPendingRewards(delegatorAddress);
-
+
console.log('Pending rewards:');
pendingRewards.totalRewards.forEach(reward => {
console.log(` ${reward.denom}: ${reward.amount}`);
});
-
+
// 2. Get validators with rewards
const validatorsWithRewards = pendingRewards.validatorRewards
.filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
.map(reward => reward.validator);
-
+
if (validatorsWithRewards.length === 0) {
console.log('No rewards to claim');
return;
}
-
+
// 3. Claim all rewards efficiently
if (validatorsWithRewards.length === 1) {
console.log('Claiming rewards from single validator');
@@ -248,37 +235,38 @@ The Distribution precompile provides access to Sei's staking reward distribution
// This would require integration with staking precompile
const rewards = await getPendingRewards(delegatorAddress);
const totalSeiRewards = rewards.totalRewards.find(r => r.denom === 'usei');
-
+
if (totalSeiRewards && parseFloat(totalSeiRewards.amount) > 0) {
console.log(`Auto-compounding ${totalSeiRewards.amount} SEI`);
-
+
// 1. Claim rewards
const validatorsWithRewards = rewards.validatorRewards
.filter(r => r.coins.some(c => c.denom === 'usei' && parseFloat(c.amount) > 0))
.map(r => r.validator);
-
+
await claimAllRewards(validatorsWithRewards);
-
+
// 2. Re-delegate (would need staking precompile integration)
console.log(`Would re-delegate to ${preferredValidator}`);
}
}
```
+
```typescript
import { ethers } from 'ethers';
- import { getDistributionPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+ import { getDistributionPrecompileEthersV6Contract } from '@sei-js/precompiles';
const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
const signer = new ethers.Wallet('0x...', provider);
- const distributionContract = getDistributionPrecompileEthersContract(provider);
+ const distributionContract = getDistributionPrecompileEthersV6Contract(provider);
// Query pending rewards
async function getPendingRewards(delegatorAddress: string) {
const rewards = await distributionContract.rewards(delegatorAddress);
-
+
return {
totalRewards: rewards.total.map(coin => ({
denom: coin.denom,
@@ -299,7 +287,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
// Claim rewards from single validator
async function claimRewardsFromValidator(validatorAddress: string) {
const distributionWithSigner = distributionContract.connect(signer);
-
+
const tx = await distributionWithSigner.withdrawDelegationRewards(validatorAddress);
return await tx.wait();
}
@@ -307,7 +295,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
// Claim rewards from multiple validators
async function claimAllRewards(validatorAddresses: string[]) {
const distributionWithSigner = distributionContract.connect(signer);
-
+
const tx = await distributionWithSigner.withdrawMultipleDelegationRewards(validatorAddresses);
return await tx.wait();
}
@@ -316,15 +304,15 @@ The Distribution precompile provides access to Sei's staking reward distribution
class RewardManager {
private contract: ethers.Contract;
private signer: ethers.Signer;
-
+
constructor(provider: ethers.Provider, signer: ethers.Signer) {
- this.contract = getDistributionPrecompileEthersContract(provider);
+ this.contract = getDistributionPrecompileEthersV6Contract(provider);
this.signer = signer;
}
-
+
async getPendingRewards(delegatorAddress: string) {
const rewards = await this.contract.rewards(delegatorAddress);
-
+
return {
totalRewards: rewards.total.map(coin => ({
denom: coin.denom,
@@ -341,20 +329,20 @@ The Distribution precompile provides access to Sei's staking reward distribution
}))
};
}
-
+
async claimAllAvailableRewards(delegatorAddress: string) {
const rewards = await this.getPendingRewards(delegatorAddress);
-
+
const validatorsWithRewards = rewards.validatorRewards
.filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
.map(reward => reward.validator);
-
+
if (validatorsWithRewards.length === 0) {
throw new Error('No rewards available to claim');
}
-
+
const contractWithSigner = this.contract.connect(this.signer);
-
+
if (validatorsWithRewards.length === 1) {
const tx = await contractWithSigner.withdrawDelegationRewards(validatorsWithRewards[0]);
return await tx.wait();
@@ -363,7 +351,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
return await tx.wait();
}
}
-
+
async setWithdrawAddress(withdrawAddress: string) {
const contractWithSigner = this.contract.connect(this.signer);
const tx = await contractWithSigner.setWithdrawAddress(withdrawAddress);
@@ -373,11 +361,12 @@ The Distribution precompile provides access to Sei's staking reward distribution
// Usage
const rewardManager = new RewardManager(provider, signer);
-
+
// Check and claim all rewards
const delegatorAddress = await signer.getAddress();
await rewardManager.claimAllAvailableRewards(delegatorAddress);
```
+
@@ -389,7 +378,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
// Using with web3.js
import Web3 from 'web3';
-
+
const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
const distributionContract = new web3.eth.Contract(
DISTRIBUTION_PRECOMPILE_ABI,
@@ -398,7 +387,7 @@ The Distribution precompile provides access to Sei's staking reward distribution
// Query pending rewards
const rewards = await distributionContract.methods
- .rewards('0x742d35Cc6634C0532925a3b8D6Ac0c2fb15d8d2A')
+ .rewards('0xAddress')
.call();
// Setup account for transactions
@@ -422,22 +411,26 @@ The Distribution precompile provides access to Sei's staking reward distribution
gas: 300000
});
```
+
## Common Use Cases
### Automated Reward Claiming
+
- **DeFi Protocols**: Automatically claim and reinvest staking rewards
- **Yield Optimization**: Compound rewards to maximize returns
- **Portfolio Management**: Regular reward harvesting across multiple validators
### Liquid Staking Protocols
+
- **Reward Distribution**: Distribute claimed rewards to token holders
- **Fee Collection**: Set withdrawal addresses to protocol treasury
- **Automated Compounding**: Reinvest rewards to increase staking positions
### Staking-as-a-Service
+
- **Client Management**: Claim rewards on behalf of clients
- **Fee Deduction**: Set withdrawal addresses for fee collection
- **Performance Tracking**: Monitor reward generation across validators
@@ -445,68 +438,73 @@ The Distribution precompile provides access to Sei's staking reward distribution
## Reward Optimization Strategies
### Timing Optimization
+
```typescript
// Check if rewards are worth claiming (considering gas costs)
async function shouldClaimRewards(
delegatorAddress: string,
- minRewardThreshold: string = "1" // 1 SEI minimum
+ minRewardThreshold: string = "1", // 1 SEI minimum
) {
const rewards = await getPendingRewards(delegatorAddress);
- const totalSeiRewards = rewards.totalRewards.find(r => r.denom === 'usei');
-
+ const totalSeiRewards = rewards.totalRewards.find((r) => r.denom === "usei");
+
if (!totalSeiRewards) return false;
-
+
const rewardAmount = parseFloat(totalSeiRewards.amount);
const threshold = parseFloat(minRewardThreshold);
-
+
return rewardAmount >= threshold;
}
```
### Validator Selection for Claiming
+
```typescript
// Prioritize validators with highest rewards
async function getOptimalClaimingOrder(delegatorAddress: string) {
const rewards = await getPendingRewards(delegatorAddress);
-
+
return rewards.validatorRewards
- .filter(reward => reward.coins.some(coin => parseFloat(coin.amount) > 0))
+ .filter((reward) =>
+ reward.coins.some((coin) => parseFloat(coin.amount) > 0),
+ )
.sort((a, b) => {
- const aSeiReward = a.coins.find(c => c.denom === 'usei');
- const bSeiReward = b.coins.find(c => c.denom === 'usei');
-
+ const aSeiReward = a.coins.find((c) => c.denom === "usei");
+ const bSeiReward = b.coins.find((c) => c.denom === "usei");
+
const aAmount = aSeiReward ? parseFloat(aSeiReward.amount) : 0;
const bAmount = bSeiReward ? parseFloat(bSeiReward.amount) : 0;
-
+
return bAmount - aAmount; // Descending order
})
- .map(reward => reward.validator);
+ .map((reward) => reward.validator);
}
```
### Batch Claiming Strategy
+
```typescript
// Determine optimal batching strategy
async function getOptimalClaimingStrategy(
delegatorAddress: string,
- maxValidatorsPerTx: number = 10
+ maxValidatorsPerTx: number = 10,
) {
const validatorsWithRewards = await getOptimalClaimingOrder(delegatorAddress);
-
+
if (validatorsWithRewards.length <= maxValidatorsPerTx) {
return {
- strategy: 'single_batch',
- batches: [validatorsWithRewards]
+ strategy: "single_batch",
+ batches: [validatorsWithRewards],
};
} else {
const batches = [];
for (let i = 0; i < validatorsWithRewards.length; i += maxValidatorsPerTx) {
batches.push(validatorsWithRewards.slice(i, i + maxValidatorsPerTx));
}
-
+
return {
- strategy: 'multiple_batches',
- batches
+ strategy: "multiple_batches",
+ batches,
};
}
}
@@ -523,47 +521,49 @@ class RewardTracker {
amount: string;
txHash: string;
}> = [];
-
+
recordClaim(validators: string[], amount: string, txHash: string) {
this.claimedRewards.push({
timestamp: Date.now(),
validators,
amount,
- txHash
+ txHash,
});
}
-
+
getTotalClaimed(): string {
return this.claimedRewards
.reduce((total, claim) => total + parseFloat(claim.amount), 0)
.toString();
}
-
+
getClaimFrequency(): number {
if (this.claimedRewards.length < 2) return 0;
-
- const timeSpan = this.claimedRewards[this.claimedRewards.length - 1].timestamp -
- this.claimedRewards[0].timestamp;
-
+
+ const timeSpan =
+ this.claimedRewards[this.claimedRewards.length - 1].timestamp -
+ this.claimedRewards[0].timestamp;
+
return timeSpan / (this.claimedRewards.length - 1); // Average time between claims
}
-
+
getMostRewardingValidators(): string[] {
const validatorRewards = new Map();
-
- this.claimedRewards.forEach(claim => {
- const rewardPerValidator = parseFloat(claim.amount) / claim.validators.length;
- claim.validators.forEach(validator => {
+
+ this.claimedRewards.forEach((claim) => {
+ const rewardPerValidator =
+ parseFloat(claim.amount) / claim.validators.length;
+ claim.validators.forEach((validator) => {
validatorRewards.set(
- validator,
- (validatorRewards.get(validator) || 0) + rewardPerValidator
+ validator,
+ (validatorRewards.get(validator) || 0) + rewardPerValidator,
);
});
});
-
+
return Array.from(validatorRewards.entries())
.sort((a, b) => b[1] - a[1])
- .map(entry => entry[0]);
+ .map((entry) => entry[0]);
}
}
```
@@ -582,22 +582,23 @@ async function safeClaimRewards(validatorAddresses: string[]) {
try {
// Validate inputs
if (validatorAddresses.length === 0) {
- throw new Error('No validators specified');
+ throw new Error("No validators specified");
}
-
+
// Check for pending rewards first
const delegatorAddress = await signer.getAddress();
const rewards = await getPendingRewards(delegatorAddress);
-
- const hasRewards = rewards.validatorRewards.some(reward =>
- validatorAddresses.includes(reward.validator) &&
- reward.coins.some(coin => parseFloat(coin.amount) > 0)
+
+ const hasRewards = rewards.validatorRewards.some(
+ (reward) =>
+ validatorAddresses.includes(reward.validator) &&
+ reward.coins.some((coin) => parseFloat(coin.amount) > 0),
);
-
+
if (!hasRewards) {
- throw new Error('No rewards available for specified validators');
+ throw new Error("No rewards available for specified validators");
}
-
+
// Claim rewards
if (validatorAddresses.length === 1) {
return await claimRewardsFromValidator(validatorAddresses[0]);
@@ -605,12 +606,14 @@ async function safeClaimRewards(validatorAddresses: string[]) {
return await claimAllRewards(validatorAddresses);
}
} catch (error) {
- if (error.message.includes('no rewards')) {
- throw new Error('No rewards available to claim');
- } else if (error.message.includes('validator not found')) {
- throw new Error('One or more validators not found');
- } else if (error.message.includes('out of gas')) {
- throw new Error('Insufficient gas - try claiming fewer validators at once');
+ if (error.message.includes("no rewards")) {
+ throw new Error("No rewards available to claim");
+ } else if (error.message.includes("validator not found")) {
+ throw new Error("One or more validators not found");
+ } else if (error.message.includes("out of gas")) {
+ throw new Error(
+ "Insufficient gas - try claiming fewer validators at once",
+ );
} else {
throw error;
}
diff --git a/docs/precompiles/precompiles/staking.mdx b/docs/precompiles/precompiles/staking.mdx
index dd2df436..d63c4f87 100644
--- a/docs/precompiles/precompiles/staking.mdx
+++ b/docs/precompiles/precompiles/staking.mdx
@@ -1,6 +1,6 @@
---
-title: 'Staking Precompile'
-description: 'Manage validator delegations and staking operations through the Staking precompile contract'
+title: "Staking Precompile"
+description: "Manage validator delegations and staking operations through the Staking precompile contract"
icon: "coins"
---
@@ -30,35 +30,42 @@ The Staking precompile provides access to Sei's native staking functionality, al
**Returns:** Success boolean
- **Note:** This function is payable - send SEI with the transaction to delegate
-
+ **Note:**
+ - This function is payable - send SEI with the transaction to delegate
+ - This function accepts argument parsed to 18 decimals
+
```typescript
const success = await stakingContract.delegate(
- "seivaloper1...",
+ "seivaloper1...",
{ value: parseEther("100") } // Delegate 100 SEI
);
```
-
-
- Redelegate tokens from one validator to another without unbonding.
-
- **Parameters:**
- - `srcAddress` (string): Source validator address
- - `dstAddress` (string): Destination validator address
- - `amount` (uint256): Amount to redelegate (in wei)
-
- **Returns:** Success boolean
-
- ```typescript
- const success = await stakingContract.redelegate(
- "seivaloper1source...",
- "seivaloper1destination...",
- parseEther("50") // Redelegate 50 SEI
- );
- ```
+
+ Redelegate tokens from one validator to another without unbonding.
+
+**Parameters:**
+
+- `srcAddress` (string): Source validator address
+- `dstAddress` (string): Destination validator address
+- `amount` (uint256): Amount to redelegate (in wei)
+
+**Returns:** Success boolean
+
+**Note:** This function accepts argument parsed to 6 decimals
+
+```typescript
+const success = await stakingContract.redelegate(
+ "seivaloper1source...",
+ "seivaloper1destination...",
+ parseUnits("50", 6), // Redelegate 50 SEI
+);
+```
+
+
+
Undelegate tokens from a validator (starts unbonding period).
@@ -68,12 +75,14 @@ The Staking precompile provides access to Sei's native staking functionality, al
**Returns:** Success boolean
- **Note:** Undelegated tokens are subject to a 21-day unbonding period
+ **Note:**
+ - Undelegated tokens are subject to a 21-day unbonding period
+ - This function takes arguments parsed to 6 decimals
```typescript
const success = await stakingContract.undelegate(
"seivaloper1...",
- parseEther("25") // Undelegate 25 SEI
+ parseUnits("25", 6) // Undelegate 25 SEI
);
```
@@ -130,7 +139,7 @@ The Staking precompile provides access to Sei's native staking functionality, al
seiTestnet,
STAKING_PRECOMPILE_ABI,
STAKING_PRECOMPILE_ADDRESS
- } from '@sei-js/precompiles/viem';
+ } from '@sei-js/precompiles';
const publicClient = createPublicClient({
chain: seiTestnet,
@@ -153,7 +162,7 @@ The Staking precompile provides access to Sei's native staking functionality, al
args: [validatorAddress],
value: parseEther(amount)
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
@@ -165,7 +174,7 @@ The Staking precompile provides access to Sei's native staking functionality, al
functionName: 'delegation',
args: [delegatorAddress, validatorAddress]
});
-
+
return {
amount: formatEther(delegation.balance.amount),
denom: delegation.balance.denom,
@@ -177,16 +186,16 @@ The Staking precompile provides access to Sei's native staking functionality, al
// Redelegate between validators
async function redelegateTokens(
fromValidator: string,
- toValidator: string,
+ toValidator: string,
amount: string
) {
const hash = await walletClient.writeContract({
address: STAKING_PRECOMPILE_ADDRESS,
abi: STAKING_PRECOMPILE_ABI,
functionName: 'redelegate',
- args: [fromValidator, toValidator, parseEther(amount)]
+ args: [fromValidator, toValidator, parseUnits(amount, 6)]
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
@@ -196,52 +205,53 @@ The Staking precompile provides access to Sei's native staking functionality, al
address: STAKING_PRECOMPILE_ADDRESS,
abi: STAKING_PRECOMPILE_ABI,
functionName: 'undelegate',
- args: [validatorAddress, parseEther(amount)]
+ args: [validatorAddress, parseUnits(amount, 6)]
});
-
+
return await publicClient.waitForTransactionReceipt({ hash });
}
// Get all delegations for an address (requires multiple calls)
async function getAllDelegations(
- delegatorAddress: string,
+ delegatorAddress: string,
validatorAddresses: string[]
) {
const delegationPromises = validatorAddresses.map(validator =>
getDelegation(delegatorAddress, validator)
);
-
+
const delegations = await Promise.all(delegationPromises);
-
+
return delegations.filter(d => parseFloat(d.amount) > 0);
}
```
+
```typescript
import { ethers } from 'ethers';
- import { getStakingPrecompileEthersContract } from '@sei-js/precompiles/ethers';
+ import { getStakingPrecompileEthersV6Contract } from '@sei-js/precompiles';
const provider = new ethers.JsonRpcProvider('https://evm-rpc-testnet.sei-apis.com');
const signer = new ethers.Wallet('0x...', provider);
- const stakingContract = getStakingPrecompileEthersContract(provider);
+ const stakingContract = getStakingPrecompileEthersV6Contract(provider);
// Delegate tokens to a validator
async function delegateToValidator(validatorAddress: string, amount: string) {
const stakingWithSigner = stakingContract.connect(signer);
-
+
const tx = await stakingWithSigner.delegate(validatorAddress, {
value: ethers.parseEther(amount)
});
-
+
return await tx.wait();
}
// Check delegation
async function getDelegation(delegatorAddress: string, validatorAddress: string) {
const delegation = await stakingContract.delegation(delegatorAddress, validatorAddress);
-
+
return {
amount: ethers.formatEther(delegation.balance.amount),
denom: delegation.balance.denom,
@@ -257,25 +267,25 @@ The Staking precompile provides access to Sei's native staking functionality, al
amount: string
) {
const stakingWithSigner = stakingContract.connect(signer);
-
+
const tx = await stakingWithSigner.redelegate(
fromValidator,
toValidator,
- ethers.parseEther(amount)
+ ethers.parseUnits(amount, 6)
);
-
+
return await tx.wait();
}
// Undelegate tokens
async function undelegateTokens(validatorAddress: string, amount: string) {
const stakingWithSigner = stakingContract.connect(signer);
-
+
const tx = await stakingWithSigner.undelegate(
validatorAddress,
- ethers.parseEther(amount)
+ ethers.parseUnits(amount, 6)
);
-
+
return await tx.wait();
}
@@ -288,9 +298,9 @@ The Staking precompile provides access to Sei's native staking functionality, al
'seivaloper2...',
// ... more validators
];
-
+
const delegations = [];
-
+
for (const validator of validatorAddresses) {
try {
const delegation = await getDelegation(delegatorAddress, validator);
@@ -301,10 +311,11 @@ The Staking precompile provides access to Sei's native staking functionality, al
// No delegation to this validator
}
}
-
+
return delegations;
}
```
+
@@ -316,7 +327,7 @@ The Staking precompile provides access to Sei's native staking functionality, al
// Using with web3.js
import Web3 from 'web3';
-
+
const web3 = new Web3('https://evm-rpc-testnet.sei-apis.com');
const stakingContract = new web3.eth.Contract(
STAKING_PRECOMPILE_ABI,
@@ -340,22 +351,26 @@ The Staking precompile provides access to Sei's native staking functionality, al
gas: 200000
});
```
+
## Common Use Cases
### Liquid Staking Protocols
+
- **Auto-Delegation**: Automatically delegate user deposits to optimal validators
- **Rebalancing**: Redelegate between validators based on performance metrics
- **Yield Optimization**: Monitor and adjust delegations for maximum rewards
### Staking-as-a-Service
+
- **Portfolio Management**: Manage delegations across multiple validators
- **Risk Distribution**: Spread delegations to reduce validator risk
- **Performance Tracking**: Monitor delegation performance and rewards
### DeFi Integration
+
- **Collateral Management**: Use staked tokens as collateral in lending protocols
- **Governance Participation**: Delegate to validators aligned with protocol governance
- **Yield Strategies**: Combine staking with other DeFi yield opportunities
@@ -363,6 +378,7 @@ The Staking precompile provides access to Sei's native staking functionality, al
## Validator Selection Strategies
### Performance-Based Selection
+
```typescript
// Example: Select validators based on commission and uptime
interface ValidatorMetrics {
@@ -374,30 +390,32 @@ interface ValidatorMetrics {
function selectOptimalValidators(
validators: ValidatorMetrics[],
- maxValidators: number = 5
+ maxValidators: number = 5,
): string[] {
return validators
- .filter(v => v.uptime > 0.95) // 95% uptime minimum
- .filter(v => v.commission < 0.1) // Max 10% commission
+ .filter((v) => v.uptime > 0.95) // 95% uptime minimum
+ .filter((v) => v.commission < 0.1) // Max 10% commission
.sort((a, b) => a.commission - b.commission) // Prefer lower commission
.slice(0, maxValidators)
- .map(v => v.address);
+ .map((v) => v.address);
}
```
### Diversification Strategy
+
```typescript
// Spread delegations across multiple validators
async function diversifyDelegations(
totalAmount: string,
- validatorAddresses: string[]
+ validatorAddresses: string[],
) {
- const amountPerValidator = parseEther(totalAmount) / BigInt(validatorAddresses.length);
-
- const delegationPromises = validatorAddresses.map(validator =>
- delegateToValidator(validator, formatEther(amountPerValidator))
+ const amountPerValidator =
+ parseEther(totalAmount) / BigInt(validatorAddresses.length);
+
+ const delegationPromises = validatorAddresses.map((validator) =>
+ delegateToValidator(validator, formatEther(amountPerValidator)),
);
-
+
return await Promise.all(delegationPromises);
}
```
@@ -413,16 +431,16 @@ Common errors when using the Staking precompile:
```typescript
try {
- await delegateToValidator('seivaloper1...', '100');
+ await delegateToValidator("seivaloper1...", "100");
} catch (error) {
- if (error.message.includes('insufficient funds')) {
- console.error('Not enough SEI to delegate');
- } else if (error.message.includes('validator not found')) {
- console.error('Invalid validator address');
- } else if (error.message.includes('delegation not found')) {
- console.error('No existing delegation found');
+ if (error.message.includes("insufficient funds")) {
+ console.error("Not enough SEI to delegate");
+ } else if (error.message.includes("validator not found")) {
+ console.error("Invalid validator address");
+ } else if (error.message.includes("delegation not found")) {
+ console.error("No existing delegation found");
} else {
- console.error('Unexpected error:', error);
+ console.error("Unexpected error:", error);
}
}
```
@@ -441,7 +459,7 @@ When undelegating tokens, they enter a 21-day unbonding period:
async function getUnbondingDelegations(delegatorAddress: string) {
// Implementation would depend on additional precompiles or API calls
// This is a placeholder for the concept
- console.log('Unbonding delegations require additional API calls');
+ console.log("Unbonding delegations require additional API calls");
}
```