Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Staking Examples #271

Open
wants to merge 13 commits into
base: release-v0.7.0
Choose a base branch
from
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions src/examples/ethereum/get_staking_rewards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Coinbase, StakingReward } from "../..";

const apiKeyFilePath = "~/.apikeys/prod.json";

/**
* Fetches and logs staking rewards for an Ethereum validator.
*/
async function stake() {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

const end = new Date();
const start = new Date();
start.setDate(end.getDate() - 60);

const rewards = await StakingReward.list(
Coinbase.networks.EthereumMainnet,
Coinbase.assets.Eth,
[
"0xad927b51bf02d120dd5e25526ee734ba78468cc5c7588fde2a2d9b02ba4502296b97b0fa0ff22900ff7425652ac76d51",
],
start.toISOString(),
end.toISOString(),
);

// Loop through the rewards and print each staking reward
rewards.forEach(reward => console.log(reward.toString()));
}

(async () => {
try {
await stake();
} catch (error) {
console.error("Error during stake operation", error);
}
})();
23 changes: 23 additions & 0 deletions src/examples/ethereum/get_validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Coinbase, Validator } from "../..";

const apiKeyFilePath = "<YOUR_API_KEY_FILE_HERE>";

/**
* List the validators you've provisioned on the `ethereum-holesky` testnet network.
*/
async function listValidators() {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

// Get the validators that you've provisioned for staking.
const validator = await Validator.fetch(
Coinbase.networks.EthereumHolesky,
"eth",
"0xa1d1ad0714035353258038e964ae9675dc0252ee22cea896825c01458e1807bfad2f9969338798548d9858a571f7425c",
);

console.log(JSON.stringify(validator, null, 2));
}

(async () => {
await listValidators();
})();
26 changes: 26 additions & 0 deletions src/examples/ethereum/get_validators_by_status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Coinbase, Validator, ValidatorStatus } from "../..";

const apiKeyFilePath = "<YOUR_API_KEY_FILE_HERE>";

/**
* List the validators you've provisioned on the `ethereum-holesky` testnet network.
*/
async function listValidators() {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

// Get the validators that you've provisioned for staking.
const validators = await Validator.list(
Coinbase.networks.EthereumHolesky,
"eth",
ValidatorStatus.PROVISIONED,
);

// Loop through the validators and print each validator
validators.forEach(validator => {
console.log(validator.toString());
});
}

(async () => {
await listValidators();
})();
55 changes: 55 additions & 0 deletions src/examples/ethereum/stake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Coinbase, ExternalAddress, StakeOptionsMode } from "../..";
import { ethers } from "ethers";

const apiKeyFilePath = "<YOUR_API_KEY_FILE_HERE>";

/**
* List the validators you've provisioned on the `ethereum-holesky` testnet network.
*/
async function stakeETH() {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

// Create a new external address on the `ethereum-holesky` network.
const address = new ExternalAddress(
"ethereum-holesky",
"0x04DF51085DB07BBA5eAAAf3b5c09469D7374a98c",
);

console.log("created address", address);

// Build a stake operation for an amount <= stakeableBalance, and in multiples of 32. In this case, 32 ETH.
const stakingOperation = await address.buildStakeOperation(32, "eth", StakeOptionsMode.NATIVE);

console.log("created staking operation", stakingOperation);

/*
* Native ETH staking involves setting up infrastructure, which can take time.
* Example of polling the stake operation status until it reaches a terminal state using the SDK.
*/
console.log("waiting until underlying infra is provisioned", stakingOperation);
await stakingOperation.wait();
console.log("done!", stakingOperation);

// Load your wallet's private key from which you initiated the above stake operation.
const wallet = new ethers.Wallet(
"a93461695bc246aff6f517c5c02b925c4f157e6eeec22d31ef8d37f79ad9e9fa",
);

// Sign the transactions within staking operation resource with your wallet.
await stakingOperation.sign(wallet);

// For Holesky, publicly available RPC URL's can be found here https://chainlist.org/chain/17000
const provider = new ethers.JsonRpcProvider(
"https://boldest-weathered-aura.ethereum-holesky.quiknode.pro/0ff8cbb4e5c14043ab259fd21d8bade2d6815a4b",
);

// Broadcast each of the signed transactions to the network.
stakingOperation.getTransactions().forEach(async tx => {
const resp = await provider.broadcastTransaction(tx.getSignedPayload()!);
console.log(resp);
});
}

(async () => {
await stakeETH();
})();
31 changes: 31 additions & 0 deletions src/examples/ethereum/unstake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Coinbase, ExternalAddress, StakeOptionsMode } from "../..";

const apiKeyFilePath = "<YOUR_API_KEY_FILE_HERE>";

/**
* List the validators you've provisioned on the `ethereum-holesky` testnet network.
*/
async function stakeETH() {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

// Create a new external address on the `ethereum-holesky` network.
const address = new ExternalAddress(
"ethereum-holesky",
"0x04DF51085DB07BBA5eAAAf3b5c09469D7374a98c",
);

console.log("created address", address);

const unstakeableBalance = await address.unstakeableBalance("eth", StakeOptionsMode.NATIVE);
console.log("unstakeable balance", unstakeableBalance);

// Build an unstake operation for an amount <= unstakeableBalance, in this case 0.005 ETH.
const unstakeOperation = await address.buildUnstakeOperation(32, "eth", StakeOptionsMode.NATIVE, {
immediate: "false",
});
console.log("created unstake operation", unstakeOperation);
}

(async () => {
await stakeETH();
})();
39 changes: 39 additions & 0 deletions src/examples/solana/get_staking_rewards_and_balances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { StakingBalance } from "../../coinbase/staking_balance";
import { StakingReward } from "../../coinbase/staking_reward";
import { Coinbase } from "../../coinbase/coinbase";
import { NetworkIdentifier } from "../../client";

const apiKeyFilePath = "<YOUR_API_KEY_FILE_HERE>";

/**
* List Solana historical staking balances for a given wallet.
*
* @param wallet - The wallet address to list historical staking rewards and balances for.
*/
async function listSolanaStakingBalances(wallet: string): Promise<void> {
Coinbase.configureFromJson({ filePath: apiKeyFilePath });

const startTime = new Date(2024, 5).toISOString();

const rewards = await StakingReward.list(
NetworkIdentifier.SolanaMainnet,
Coinbase.assets.Sol,
[wallet],
startTime,
new Date().toISOString(),
);
console.log(rewards);

const balances = await StakingBalance.list(
NetworkIdentifier.SolanaMainnet,
Coinbase.assets.Sol,
wallet,
startTime,
new Date().toISOString(),
);
console.log(balances);
}

(async () => {
await listSolanaStakingBalances("51KR6Q6TRisKJ3NyFB7vmGUji675ufsC8ycmeNY7dDiP");
})();
19 changes: 0 additions & 19 deletions src/examples/solana_list_rewards.ts

This file was deleted.