feat: Add comprehensive staking interface to PaperclipWallet

- Add staking RPC methods for validators, delegation, and rewards
- Implement complete staking UI with validator selection and delegation
- Add reward claiming functionality and validator creation interface
- Include professional staking dashboard with real-time data
- Integrate staking navigation into existing wallet interface
This commit is contained in:
2025-06-17 14:38:53 -07:00
parent 8414593d47
commit 2c3ad62bc4
6 changed files with 1242 additions and 0 deletions

View File

@@ -199,6 +199,93 @@ class PaperclipRPC {
}
}
// Staking Methods
async getValidators() {
try {
const result = await this._makeRPCCall("abci_query", {
path: `"validators"`
});
if (result.result && result.result.response && result.result.response.value) {
const validators = Buffer.from(result.result.response.value, 'base64').toString();
return JSON.parse(validators);
}
return [];
} catch (error) {
this._writeLog(`Failed to get validators: ${error.message}`);
return [];
}
}
async getStakingInfo(address) {
try {
const result = await this._makeRPCCall("abci_query", {
path: `"staker:${address}"`
});
if (result.result && result.result.response && result.result.response.value) {
const stakingInfo = Buffer.from(result.result.response.value, 'base64').toString();
return JSON.parse(stakingInfo);
}
return null;
} catch (error) {
this._writeLog(`Failed to get staking info for ${address}: ${error.message}`);
return null;
}
}
async getValidatorInfo(validatorAddress) {
try {
const result = await this._makeRPCCall("abci_query", {
path: `"validator:${validatorAddress}"`
});
if (result.result && result.result.response && result.result.response.value) {
const validatorInfo = Buffer.from(result.result.response.value, 'base64').toString();
return JSON.parse(validatorInfo);
}
return null;
} catch (error) {
this._writeLog(`Failed to get validator info for ${validatorAddress}: ${error.message}`);
return null;
}
}
async getStakingRewards(address) {
try {
const result = await this._makeRPCCall("abci_query", {
path: `"rewards:${address}"`
});
if (result.result && result.result.response && result.result.response.value) {
const rewards = Buffer.from(result.result.response.value, 'base64').toString();
return parseInt(rewards) || 0;
}
return 0;
} catch (error) {
this._writeLog(`Failed to get staking rewards for ${address}: ${error.message}`);
return 0;
}
}
async getTotalStaked() {
try {
const result = await this._makeRPCCall("abci_query", {
path: `"total_staked"`
});
if (result.result && result.result.response && result.result.response.value) {
const totalStaked = Buffer.from(result.result.response.value, 'base64').toString();
return parseInt(totalStaked) || 0;
}
return 0;
} catch (error) {
this._writeLog(`Failed to get total staked: ${error.message}`);
return 0;
}
}
setRPCUrl(url) {
this.rpcUrl = url;
this._writeLog(`RPC URL updated to: ${url}`);
@@ -254,4 +341,25 @@ ipcMain.handle("paperclip-get-block", async (event, height) => {
return await PaperclipNode.getBlock(height);
});
// Staking IPC handlers
ipcMain.handle("paperclip-get-validators", async () => {
return await PaperclipNode.getValidators();
});
ipcMain.handle("paperclip-get-staking-info", async (event, address) => {
return await PaperclipNode.getStakingInfo(address);
});
ipcMain.handle("paperclip-get-validator-info", async (event, validatorAddress) => {
return await PaperclipNode.getValidatorInfo(validatorAddress);
});
ipcMain.handle("paperclip-get-staking-rewards", async (event, address) => {
return await PaperclipNode.getStakingRewards(address);
});
ipcMain.handle("paperclip-get-total-staked", async () => {
return await PaperclipNode.getTotalStaked();
});
module.exports = PaperclipNode;