From 66698240249a1f81d364e9e8df604ad041c1c93e Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 13:57:57 +0100 Subject: [PATCH 01/12] Ethereum: Fix withdraw all assets --- packages/ethereum/src/lib/methods/buildWithdrawTx.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/ethereum/src/lib/methods/buildWithdrawTx.ts b/packages/ethereum/src/lib/methods/buildWithdrawTx.ts index 9dc175f..0e92aba 100644 --- a/packages/ethereum/src/lib/methods/buildWithdrawTx.ts +++ b/packages/ethereum/src/lib/methods/buildWithdrawTx.ts @@ -19,7 +19,9 @@ export async function buildWithdrawTx (request: { const multicallArgs = queueItems .filter((item) => { - return !positionTickets || positionTickets.includes(item.positionTicket.toString()) + if (!positionTickets) return item.isWithdrawable + + return positionTickets.includes(item.positionTicket.toString()) }) .map((item) => { const timestamp = Math.floor(item.when.getTime() / 1000) @@ -27,7 +29,7 @@ export async function buildWithdrawTx (request: { throw new Error('Exit queue index is missing') } if (!item.isWithdrawable) { - throw new Error('Item is not withdrawable') + throw new Error(`Position #${item.positionTicket} is not withdrawable`) } return encodeFunctionData({ From 98b456ab9f6c28cfa7fffbe700ebb1ffe380ea17 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 13:58:39 +0100 Subject: [PATCH 02/12] Ethereum: Comment on what amount represents - shares or assets --- packages/ethereum/src/staker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index ebad24f..65c9144 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -86,7 +86,7 @@ export class EthereumStaker { async buildStakeTx (params: { delegatorAddress: Hex validatorAddress: Hex - amount: string + amount: string // ETH assets referrer?: Hex }): Promise<{ tx: Transaction }> { const tx = await buildStakeTx({ @@ -118,7 +118,7 @@ export class EthereumStaker { async buildUnstakeTx (params: { delegatorAddress: Hex validatorAddress: Hex - amount: string + amount: string // ETH assets }): Promise<{ tx: Transaction }> { const tx = await buildUnstakeTx({ connector: this.connector, @@ -177,7 +177,7 @@ export class EthereumStaker { async buildMintTx (params: { delegatorAddress: Hex validatorAddress: Hex - amount: string // shares + amount: string // osETH shares referrer?: Hex }): Promise<{ tx: Transaction }> { const tx = await buildMintTx({ @@ -204,7 +204,7 @@ export class EthereumStaker { async buildBurnTx (params: { delegatorAddress: Hex validatorAddress: Hex - amount: string + amount: string // osETH shares }): Promise<{ tx: Transaction }> { const tx = await buildBurnTx({ connector: this.connector, From 6614ae1f9256f454684a5df45a4f0031d1f567e2 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 14:21:21 +0100 Subject: [PATCH 03/12] Ethereum: Remove account value from transaction --- book/ethereum-tutorial/3-staking.md | 2 -- packages/ethereum/src/lib/methods/buildBurnTx.ts | 3 +-- packages/ethereum/src/lib/methods/buildMintTx.ts | 1 - packages/ethereum/src/lib/methods/buildStakeTx.ts | 3 +-- packages/ethereum/src/lib/methods/buildUnstakeTx.ts | 1 - packages/ethereum/src/lib/methods/buildWithdrawTx.ts | 1 - packages/ethereum/src/lib/types/transaction.ts | 5 ----- 7 files changed, 2 insertions(+), 14 deletions(-) diff --git a/book/ethereum-tutorial/3-staking.md b/book/ethereum-tutorial/3-staking.md index 5f6e694..11f81b3 100644 --- a/book/ethereum-tutorial/3-staking.md +++ b/book/ethereum-tutorial/3-staking.md @@ -86,7 +86,6 @@ const stake = async ({ console.log(stakeTx) // { - // account: "0x...", // to: "0x...", // data: "0x...", // value: 10000000000000000n @@ -111,7 +110,6 @@ The network determines the actual fee based on the current demand for block spac The `Transaction` object returned by `buildStakeTransaction` includes the following parameters: -- **`account` (Hex)**: The user's Ethereum address. - **`to` (Hex)**: The address of the contract to interact with(the vault address). - **`data` (Hex)**: A contract hashed method call with encoded arguments (the transformation of the method call into this encoded and hashed form is handled by the `encodeFunctionData` method from the viem library). - **`value` (bigint)**: The amount of ETH being used in the transaction. In this case, it's the amount being staked. diff --git a/packages/ethereum/src/lib/methods/buildBurnTx.ts b/packages/ethereum/src/lib/methods/buildBurnTx.ts index 902ddfc..2e0b164 100644 --- a/packages/ethereum/src/lib/methods/buildBurnTx.ts +++ b/packages/ethereum/src/lib/methods/buildBurnTx.ts @@ -9,7 +9,7 @@ export async function buildBurnTx (request: { vault: Hex amount: bigint }): Promise { - const { userAccount, vault, amount } = request + const { vault, amount } = request const tx = encodeFunctionData({ abi: VaultABI, @@ -18,7 +18,6 @@ export async function buildBurnTx (request: { }) return { - account: userAccount, to: vault, data: tx } diff --git a/packages/ethereum/src/lib/methods/buildMintTx.ts b/packages/ethereum/src/lib/methods/buildMintTx.ts index 37c1311..1845897 100644 --- a/packages/ethereum/src/lib/methods/buildMintTx.ts +++ b/packages/ethereum/src/lib/methods/buildMintTx.ts @@ -19,7 +19,6 @@ export const buildMintTx = async (request: { }) return { - account: userAccount, to: vault, data: tx } diff --git a/packages/ethereum/src/lib/methods/buildStakeTx.ts b/packages/ethereum/src/lib/methods/buildStakeTx.ts index 86b4031..3ddfabe 100644 --- a/packages/ethereum/src/lib/methods/buildStakeTx.ts +++ b/packages/ethereum/src/lib/methods/buildStakeTx.ts @@ -5,7 +5,7 @@ import { keeperABI } from '../contracts/keeperAbi' import { getHarvestParams } from '../utils/getHarvestParams' import { Transaction } from '../types/transaction' -export async function buildStakeTx (request: { +export async function buildStakeTx(request: { connector: StakewiseConnector userAccount: Hex vault: Hex @@ -48,7 +48,6 @@ export async function buildStakeTx (request: { } return { - account: userAccount, to: vault, data: tx, value: amount diff --git a/packages/ethereum/src/lib/methods/buildUnstakeTx.ts b/packages/ethereum/src/lib/methods/buildUnstakeTx.ts index 544924a..4e6ffa4 100644 --- a/packages/ethereum/src/lib/methods/buildUnstakeTx.ts +++ b/packages/ethereum/src/lib/methods/buildUnstakeTx.ts @@ -47,7 +47,6 @@ export async function buildUnstakeTx (request: { } return { - account: userAccount, to: vault, data: tx } diff --git a/packages/ethereum/src/lib/methods/buildWithdrawTx.ts b/packages/ethereum/src/lib/methods/buildWithdrawTx.ts index 0e92aba..0f931a7 100644 --- a/packages/ethereum/src/lib/methods/buildWithdrawTx.ts +++ b/packages/ethereum/src/lib/methods/buildWithdrawTx.ts @@ -46,7 +46,6 @@ export async function buildWithdrawTx (request: { }) return { - account: userAccount, to: vault, data: tx } diff --git a/packages/ethereum/src/lib/types/transaction.ts b/packages/ethereum/src/lib/types/transaction.ts index 756c6e2..7b1317d 100644 --- a/packages/ethereum/src/lib/types/transaction.ts +++ b/packages/ethereum/src/lib/types/transaction.ts @@ -4,11 +4,6 @@ import { Hex } from 'viem' * Represents an Ethereum transaction. */ export interface Transaction { - /** - * The account (sender) address in hexadecimal format. - */ - account: Hex - /** * The recipient (receiver) address in hexadecimal format. */ From 8795cc7593f471295124f2a83a7b6a6862076053 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 14:22:14 +0100 Subject: [PATCH 04/12] Ethereum: Fix docs tx destructuring --- book/ethereum-tutorial/3-staking.md | 2 +- book/ethereum-tutorial/4-unstaking.md | 4 ++-- book/ethereum-tutorial/5-minting-os-eth.md | 2 +- book/ethereum-tutorial/6-burning-os-eth.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/book/ethereum-tutorial/3-staking.md b/book/ethereum-tutorial/3-staking.md index 11f81b3..bd96295 100644 --- a/book/ethereum-tutorial/3-staking.md +++ b/book/ethereum-tutorial/3-staking.md @@ -78,7 +78,7 @@ const stake = async ({ const validatorAddress = CHORUS_ONE_ETHEREUM_VALIDATORS.ethereum.mevMaxVault - const stakeTx = await staker.buildStakeTx({ + const { tx: stakeTx } = await staker.buildStakeTx({ delegatorAddress: userAddress, validatorAddress, amount: amountToStake diff --git a/book/ethereum-tutorial/4-unstaking.md b/book/ethereum-tutorial/4-unstaking.md index e9cab70..43b9439 100644 --- a/book/ethereum-tutorial/4-unstaking.md +++ b/book/ethereum-tutorial/4-unstaking.md @@ -50,7 +50,7 @@ Once you've determined the maximum unstakeable amount, you can proceed to build **The following example demonstrates how to use the `buildUnstakeTx` method:** ```typescript -const unstakeTx = await staker.buildUnstakeTx({ +const { tx: unstakeTx } = await staker.buildUnstakeTx({ delegatorAddress: userAddress, validatorAddress, amount: amountToUnstake @@ -103,7 +103,7 @@ To withdraw assets, you'll need to identify which queue items are ready to be wi **The following example demonstrates how to prepare the withdrawal transaction:** ```typescript -const withdrawTx = await staker.buildWithdrawTx({ +const { tx: withdrawTx } = await staker.buildWithdrawTx({ delegatorAddress: userAddress, validatorAddress, positionTickets: unstakeQueue.filter((item) => item.isWithdrawable).map((item) => item.positionTicket) diff --git a/book/ethereum-tutorial/5-minting-os-eth.md b/book/ethereum-tutorial/5-minting-os-eth.md index 7d5b234..36b05a1 100644 --- a/book/ethereum-tutorial/5-minting-os-eth.md +++ b/book/ethereum-tutorial/5-minting-os-eth.md @@ -88,7 +88,7 @@ If the minting limits and health factors are within acceptable ranges, you can p **To illustrate this, we use the `buildMintTx` method in the following example:** ```typescript -const mintTx = await staker.buildMintTx({ +const { tx: mintTx } = await staker.buildMintTx({ delegatorAddress: userAddress, validatorAddress, amount: amountToMint diff --git a/book/ethereum-tutorial/6-burning-os-eth.md b/book/ethereum-tutorial/6-burning-os-eth.md index 556120e..c8d5b91 100644 --- a/book/ethereum-tutorial/6-burning-os-eth.md +++ b/book/ethereum-tutorial/6-burning-os-eth.md @@ -34,7 +34,7 @@ After determining the maximum amount of osETH that can be burned, proceed to bui **Here's how you can implement this with the `buildBurnTx` method:** ```typescript -const burnTx = await staker.buildBurnTx({ +const { tx: burnTx } = await staker.buildBurnTx({ delegatorAddress: userAddress, validatorAddress, amount: amountToBurn From 01e58a5284d6d235db7cfc5c7745d73a706f4e67 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 16:08:06 +0100 Subject: [PATCH 05/12] Ethereum: fix getTxHistory fetching for specific delegator --- packages/ethereum/src/lib/methods/getTxHistory.ts | 15 ++++++++++----- packages/ethereum/src/staker.ts | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/ethereum/src/lib/methods/getTxHistory.ts b/packages/ethereum/src/lib/methods/getTxHistory.ts index c9593a6..6198336 100644 --- a/packages/ethereum/src/lib/methods/getTxHistory.ts +++ b/packages/ethereum/src/lib/methods/getTxHistory.ts @@ -2,13 +2,18 @@ import { Hex } from 'viem' import { StakewiseConnector } from '../connector' import { VaultActionType, VaultTransaction } from '../types/transactionHistory' -async function extractTransactionsHistory (connector: StakewiseConnector, vault: Hex): Promise { +async function extractTransactionsHistory ( + connector: StakewiseConnector, + vault: Hex, + userAccount: Hex +): Promise { const vars_getActions = { where: { vault_: { id: vault.toLowerCase() }, - actionType_in: Object.values(VaultActionType) + actionType_in: Object.values(VaultActionType), + address: userAccount.toLowerCase() }, first: 1000, skip: 0 @@ -63,10 +68,10 @@ async function extractTransactionsHistory (connector: StakewiseConnector, vault: export async function getTxHistory (params: { connector: StakewiseConnector vault: Hex - // userAccount: Hex + userAccount: Hex }): Promise> { - const { connector, vault } = params - const interactions = await extractTransactionsHistory(connector, vault) + const { connector, vault, userAccount } = params + const interactions = await extractTransactionsHistory(connector, vault, userAccount) return interactions } diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index 65c9144..e37ee8f 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -301,9 +301,9 @@ export class EthereumStaker { * @returns Returns a promise that resolves to the transaction history for the specified delegator. */ async getTxHistory (params: { delegatorAddress: Hex; validatorAddress: Hex }) { - // TODO: add validatorAddress to the query const txHistory = await getTxHistory({ connector: this.connector, + userAccount: params.delegatorAddress, vault: params.validatorAddress }) From 8ab5f43e4158c7211d5e5ec93d388155bf747aa3 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 18:10:26 +0100 Subject: [PATCH 06/12] Ethereum: revisit fee calculation --- .../ethereum/overview.md | 16 ++++++++++- book/ethereum-tutorial/3-staking.md | 3 ++ packages/ethereum/src/lib/connector.ts | 15 +++------- packages/ethereum/src/staker.ts | 28 ++++++++++++++++--- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index a635e4f..741621b 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -142,6 +142,8 @@ Once the transaction is built, you can sign that transaction using your own sign const signedTx = await yourWalletClient.signTransaction(tx) ``` +When using your own signer, you will need to calculate the transaction fees yourself before signing. + Additionally, you can use the Chorus One SDK to sign transactions using Fireblocks, mnemonic or other methods. - For detailed information on setting up and configuring these options, please refer to the [What is a Signer?](../../signers-explained/what-is-a-signer.md) section. @@ -167,10 +169,22 @@ await signer.init() const { signedTx } = await staker.sign({ signer, signerAddress: '0x70aEe8a9099ebADB186C2D530F72CF5dC7FE6B30', - tx + tx, + fees: { + baseFeeMultiplier: 2, // Optional: Multiplier for the base fee per gas + defaultPriorityFee: '2' // Optional: Override for the maxPriorityFeePerGas + } }) ``` +### Configuring Transaction Fees + +When signing transactions, you can optionally configure the fees to manage cost and priority. The `fees` parameter allows you to specify a `baseFeeMultiplier` and a `defaultPriorityFee`. + +- **`baseFeeMultiplier`**: (Optional) This multiplier helps manage fee fluctuations by adjusting the base fee per gas from the latest block. For example, if the `baseFeeMultiplier` is set to 2, the final `maxFeePerGas` will be 2 times the base fee. The default value is 1.2. + +- **`defaultPriorityFee`**: (Optional) This value allows you to override the `maxPriorityFeePerGas` estimated by the RPC. You can specify a fixed value to ensure that your transaction has a certain priority. By default, the `maxPriorityFeePerGas` is calculated by the RPC. + For more information please refer to the [Signing with Fireblocks](../../signers-explained/fireblocks.md) {% endtab %} {% endtabs %} diff --git a/book/ethereum-tutorial/3-staking.md b/book/ethereum-tutorial/3-staking.md index bd96295..7b396a2 100644 --- a/book/ethereum-tutorial/3-staking.md +++ b/book/ethereum-tutorial/3-staking.md @@ -98,6 +98,7 @@ const stake = async ({ ``` {% hint style="info" %} +**Configuring Fees** We utilize here the Ethereum Improvement Proposal 1559 (EIP-1559) transaction type. With EIP-1559, users specify two types of fees: @@ -106,6 +107,8 @@ We utilize here the Ethereum Improvement Proposal 1559 (EIP-1559) transaction ty The network determines the actual fee based on the current demand for block space and the transaction's priority. To estimate the gas required for the transaction, we use the `prepareTransactionRequest` method from the `viem`'s wallet client. +For detailed information on configuring fees, please refer to the [Viem Documentation](https://viem.sh/docs/chains/fees). + {% endhint %} The `Transaction` object returned by `buildStakeTransaction` includes the following parameters: diff --git a/packages/ethereum/src/lib/connector.ts b/packages/ethereum/src/lib/connector.ts index e580e12..9859e65 100644 --- a/packages/ethereum/src/lib/connector.ts +++ b/packages/ethereum/src/lib/connector.ts @@ -1,4 +1,4 @@ -import { createPublicClient, PublicClient, http, Hex, parseGwei } from 'viem' +import { createPublicClient, PublicClient, http, Hex, Chain } from 'viem' import { holesky, mainnet } from 'viem/chains' import { Networks } from './types/networks' @@ -13,6 +13,7 @@ export interface GraphQLRequest { // Connector abstraction, providing on-chain and GraphQL API primitives export class StakewiseConnector { + chain: Chain /** Base URL for Stakewise main graph API */ baseAPI: string /** Base URL for Stakewise subgraph */ @@ -27,18 +28,13 @@ export class StakewiseConnector { mintTokenConfig: Hex /** Stakewise mint token controller contract address */ mintTokenController: Hex - /** Gas max fee */ - maxFeePerGas: bigint - /** Gas max priority fee */ - maxPriorityFeePerGas: bigint constructor (network: Networks, rpcUrl?: string) { // These parameters might need to be changed for Gnosis and Mainnet - this.maxFeePerGas = parseGwei('1.5') - this.maxPriorityFeePerGas = parseGwei('1.5') const transport = rpcUrl ? http(rpcUrl) : http() switch (network) { case 'holesky': + this.chain = holesky this.eth = createPublicClient({ chain: holesky, transport @@ -53,6 +49,7 @@ export class StakewiseConnector { this.mintTokenController = '0x7BbC1733ee018f103A9a9052a18fA9273255Cf36' break case 'ethereum': + this.chain = mainnet this.eth = createPublicClient({ chain: mainnet, transport @@ -60,10 +57,6 @@ export class StakewiseConnector { this.baseAPI = 'https://mainnet-api.stakewise.io/graphql' this.baseGraph = 'https://mainnet-graph.stakewise.io/subgraphs/name/stakewise/stakewise' - this.eth = createPublicClient({ - chain: mainnet, - transport: transport - }) // Stakewise keeper contract this.keeper = '0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5' this.priceOracle = '0x8023518b2192FB5384DAdc596765B3dD1cdFe471' diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index e37ee8f..c65d267 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -1,6 +1,6 @@ import type { Signer } from '@chorus-one/signer' import { publicKeyConvert } from 'secp256k1' -import { createWalletClient, formatEther, Hex, http, keccak256, parseEther, serializeTransaction } from 'viem' +import { Chain, createWalletClient, formatEther, Hex, http, keccak256, parseEther, serializeTransaction } from 'viem' import { StakewiseConnector } from './lib/connector' import { @@ -418,13 +418,33 @@ export class EthereumStaker { * @param params.signer - A signer instance. * @param params.signerAddress - The address of the signer * @param params.tx - The transaction to sign + * @param params.fees - (Optional) The fees to include in the transaction + * @param params.fees.baseFeeMultiplier - (Optional) The multiplier for fees, which is used to manage fee fluctuations, is applied to the base fee per gas from the latest block to determine the final `maxFeePerGas`. The default value is 1.2. + * @param params.fees.defaultPriorityFee - (Optional) This overrides the the `maxPriorityFeePerGas` estimated by the RPC. * * @returns A promise that resolves to an object containing the signed transaction. */ - async sign (params: { signer: Signer; signerAddress: Hex; tx: Transaction }): Promise<{ signedTx: Hex }> { - const { signer, signerAddress, tx: tx } = params + async sign (params: { + signer: Signer + signerAddress: Hex + tx: Transaction + fees?: { + baseFeeMultiplier?: number + defaultPriorityFee?: string + } + }): Promise<{ signedTx: Hex }> { + const { signer, signerAddress, tx: tx, fees } = params + const chain: Chain = { + ...this.connector.chain, + fees: fees + ? { + baseFeeMultiplier: fees.baseFeeMultiplier, + defaultPriorityFee: fees.defaultPriorityFee === undefined ? undefined : parseEther(fees.defaultPriorityFee) + } + : undefined + } const client = createWalletClient({ - chain: this.connector.eth.chain, + chain, transport: http(), account: signerAddress }) From bbb6ce175c089e1c394aef626a62aa31802cc747 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 19:16:59 +0100 Subject: [PATCH 07/12] Ethereum: highlight amount format and validate it --- .../ethereum/overview.md | 21 +++++++++ book/ethereum-tutorial/3-staking.md | 35 ++++++++++++--- book/ethereum-tutorial/4-unstaking.md | 2 +- book/ethereum-tutorial/5-minting-os-eth.md | 2 +- book/ethereum-tutorial/6-burning-os-eth.md | 2 +- packages/ethereum/src/staker.ts | 44 ++++++++++++++----- 6 files changed, 85 insertions(+), 21 deletions(-) diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index 741621b..62acccf 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -113,6 +113,27 @@ const { tx } = await staker.buildStakeTx({ }) ``` +{% hint style="warning" %} + +**Ensuring Correct Amount Format for Staking** + +The `amount` parameter must be a string representing the amount of ETH to deposit. For example, `'1'` represents 1 ETH. + +If you have the amount as a `bigint`, convert it to a string using the `formatEther` function from `viem`. Example: + +```typescript +import { formatEther } from 'viem' + +const amountBigInt = 10000000000000000n // 0.01 ETH +const amountToStake = formatEther(amountBigInt) + +console.log(amountToStake) // "0.01" +``` + +This ensures the `amountToStake` parameter is in the correct format for the staking transaction function. + +{% endhint %} + --- ## Getting the Validator Address provided by Chorus One diff --git a/book/ethereum-tutorial/3-staking.md b/book/ethereum-tutorial/3-staking.md index 7b396a2..8ae6d3f 100644 --- a/book/ethereum-tutorial/3-staking.md +++ b/book/ethereum-tutorial/3-staking.md @@ -81,7 +81,7 @@ const stake = async ({ const { tx: stakeTx } = await staker.buildStakeTx({ delegatorAddress: userAddress, validatorAddress, - amount: amountToStake + amount: amountToStake // Passed as string, e.g. '1' - 1 ETH }) console.log(stakeTx) @@ -97,6 +97,33 @@ const stake = async ({ } ``` +The `Transaction` object returned by `buildStakeTransaction` includes the following parameters: + +- **`to` (Hex)**: The address of the contract to interact with(the vault address). +- **`data` (Hex)**: A contract hashed method call with encoded arguments (the transformation of the method call into this encoded and hashed form is handled by the `encodeFunctionData` method from the viem library). +- **`value` (bigint)**: The amount of ETH being used in the transaction. In this case, it's the amount being staked. + +{% hint style="warning" %} + +**Ensuring Correct Amount Format for Staking** + +The `amountToStake` parameter must be a string representing the amount of ETH to deposit. For example, `'1'` represents 1 ETH. + +If you have the amount as a `bigint`, convert it to a string using the `formatEther` function from `viem`. Example: + +```typescript +import { formatEther } from 'viem' + +const amountBigInt = 10000000000000000n // 0.01 ETH +const amountToStake = formatEther(amountBigInt) + +console.log(amountToStake) // "0.01" +``` + +This ensures the `amountToStake` parameter is in the correct format for the staking transaction function. + +{% endhint %} + {% hint style="info" %} **Configuring Fees** @@ -111,12 +138,6 @@ For detailed information on configuring fees, please refer to the [Viem Document {% endhint %} -The `Transaction` object returned by `buildStakeTransaction` includes the following parameters: - -- **`to` (Hex)**: The address of the contract to interact with(the vault address). -- **`data` (Hex)**: A contract hashed method call with encoded arguments (the transformation of the method call into this encoded and hashed form is handled by the `encodeFunctionData` method from the viem library). -- **`value` (bigint)**: The amount of ETH being used in the transaction. In this case, it's the amount being staked. - ## Next Steps Having integrated the basic staking functionality into your application, you're now ready to expand its capabilities. diff --git a/book/ethereum-tutorial/4-unstaking.md b/book/ethereum-tutorial/4-unstaking.md index 43b9439..aac5a38 100644 --- a/book/ethereum-tutorial/4-unstaking.md +++ b/book/ethereum-tutorial/4-unstaking.md @@ -53,7 +53,7 @@ Once you've determined the maximum unstakeable amount, you can proceed to build const { tx: unstakeTx } = await staker.buildUnstakeTx({ delegatorAddress: userAddress, validatorAddress, - amount: amountToUnstake + amount: amountToUnstake // Passed as string, e.g. '1' - 1 ETH }) const request = await walletClient.prepareTransactionRequest(unstakeTx) diff --git a/book/ethereum-tutorial/5-minting-os-eth.md b/book/ethereum-tutorial/5-minting-os-eth.md index 36b05a1..331a988 100644 --- a/book/ethereum-tutorial/5-minting-os-eth.md +++ b/book/ethereum-tutorial/5-minting-os-eth.md @@ -91,7 +91,7 @@ If the minting limits and health factors are within acceptable ranges, you can p const { tx: mintTx } = await staker.buildMintTx({ delegatorAddress: userAddress, validatorAddress, - amount: amountToMint + amount: amountToMint // Passed as string, e.g. '1' - 1 ETH }) const request = await walletClient.prepareTransactionRequest(unstakeTx) diff --git a/book/ethereum-tutorial/6-burning-os-eth.md b/book/ethereum-tutorial/6-burning-os-eth.md index c8d5b91..3420ef2 100644 --- a/book/ethereum-tutorial/6-burning-os-eth.md +++ b/book/ethereum-tutorial/6-burning-os-eth.md @@ -37,7 +37,7 @@ After determining the maximum amount of osETH that can be burned, proceed to bui const { tx: burnTx } = await staker.buildBurnTx({ delegatorAddress: userAddress, validatorAddress, - amount: amountToBurn + amount: amountToBurn // Passed as string, e.g. '1' - 1 ETH }) const request = await walletClient.prepareTransactionRequest(unstakeTx) diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index c65d267..4493896 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -76,7 +76,7 @@ export class EthereumStaker { * @param params - Parameters for building the transaction * @param params.delegatorAddress - The delegator (wallet) address to stake from * @param params.validatorAddress - The validator (vault) address to stake with - * @param params.amount - The amount to stake, specified in `ETH` + * @param params.amount - The amount to stake, specified in `ETH`. E.g. "1" - 1 ETH * @param params.referrer - (Optional) The address of the referrer. This is used to track the origin of transactions, * providing insights into which sources or campaigns are driving activity. This can be useful for analytics and * optimizing user acquisition strategies @@ -93,7 +93,7 @@ export class EthereumStaker { connector: this.connector, userAccount: params.delegatorAddress, vault: params.validatorAddress, - amount: parseEther(params.amount), + amount: this.parseEther(params.amount), referrer: params.referrer }) @@ -111,7 +111,7 @@ export class EthereumStaker { * @param params - Parameters for building the transaction * @param params.delegatorAddress - The delegator (wallet) address that is unstaking * @param params.validatorAddress - The validator (vault) address to unstake from - * @param params.amount - The amount to unstake, specified in `ETH` + * @param params.amount - The amount to unstake, specified in `ETH`. E.g. "1" - 1 ETH * * @returns Returns a promise that resolves to an Ethereum unstaking transaction. */ @@ -120,11 +120,12 @@ export class EthereumStaker { validatorAddress: Hex amount: string // ETH assets }): Promise<{ tx: Transaction }> { + this.validateAmount(params.amount) const tx = await buildUnstakeTx({ connector: this.connector, userAccount: params.delegatorAddress, vault: params.validatorAddress, - amount: parseEther(params.amount) + amount: this.parseEther(params.amount) }) return { tx } @@ -167,7 +168,7 @@ export class EthereumStaker { * @param params - Parameters for building the transaction * @param params.delegatorAddress - The delegator (wallet) address * @param params.validatorAddress - The validator (vault) address to mint shares for - * @param params.amount - The amount to mint, specified in `osETH` + * @param params.amount - The amount to mint, specified in `osETH`. E.g. "1" - 1 osETH * @param params.referrer - (Optional) The address of the referrer. This is used to track the origin of * transactions, providing insights into which sources or campaigns are driving activity. This can be useful for * analytics and optimizing user acquisition strategies. @@ -180,11 +181,12 @@ export class EthereumStaker { amount: string // osETH shares referrer?: Hex }): Promise<{ tx: Transaction }> { + this.validateAmount(params.amount) const tx = await buildMintTx({ connector: this.connector, userAccount: params.delegatorAddress, vault: params.validatorAddress, - amount: parseEther(params.amount), + amount: this.parseEther(params.amount), referrer: params.referrer }) @@ -197,7 +199,7 @@ export class EthereumStaker { * @param params - Parameters for building the transaction * @param params.delegatorAddress - The delegator (wallet) address * @param params.validatorAddress - The validator (vault) address to burn shares from - * @param params.amount - The amount to burn, specified in `osETH` + * @param params.amount - The amount to burn, specified in `osETH`. E.g. "1" - 1 osETH * * @returns Returns a promise that resolves to an Ethereum burn transaction. */ @@ -206,11 +208,12 @@ export class EthereumStaker { validatorAddress: Hex amount: string // osETH shares }): Promise<{ tx: Transaction }> { + this.validateAmount(params.amount) const tx = await buildBurnTx({ connector: this.connector, userAccount: params.delegatorAddress, vault: params.validatorAddress, - amount: parseEther(params.amount) + amount: this.parseEther(params.amount) }) return { tx } @@ -404,8 +407,8 @@ export class EthereumStaker { async getMintHealth (params: { stakeAmount: string; mintAmount: string }) { const health = await getMintHealth({ connector: this.connector, - mintedShares: parseEther(params.mintAmount), - stakedAssets: parseEther(params.stakeAmount) + mintedShares: this.parseEther(params.mintAmount), + stakedAssets: this.parseEther(params.stakeAmount) }) return { health } @@ -439,7 +442,8 @@ export class EthereumStaker { fees: fees ? { baseFeeMultiplier: fees.baseFeeMultiplier, - defaultPriorityFee: fees.defaultPriorityFee === undefined ? undefined : parseEther(fees.defaultPriorityFee) + defaultPriorityFee: + fees.defaultPriorityFee === undefined ? undefined : this.parseEther(fees.defaultPriorityFee) } : undefined } @@ -516,4 +520,22 @@ export class EthereumStaker { } } } + + private parseEther (amount: string): bigint { + if (typeof amount === 'bigint') + throw new Error( + 'Amount must be a string, denominated in ETH. e.g. "1.5" - 1.5 ETH. You can use `formatEther` to convert a `bigint` to a string' + ) + if (typeof amount !== 'string') + throw new Error('Amount must be a string, denominated in ETH. e.g. "1.5" - 1.5 ETH.') + if (amount === '') throw new Error('Amount cannot be empty') + let result: bigint + try { + result = parseEther(amount) + } catch (e) { + throw new Error('Amount must be a valid number denominated in ETH. e.g. "1.5" - 1.5 ETH') + } + if (result <= 0n) throw new Error('Amount must be greater than 0') + return result + } } From ed5f81a939c7321e6e3e518b72768027c7ee718e Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 19:50:26 +0100 Subject: [PATCH 08/12] Improve compatibility notice --- book/build-your-staking-dapp/avalanche/overview.md | 12 ++++++++---- book/build-your-staking-dapp/cosmos/overview.md | 12 ++++++++---- book/build-your-staking-dapp/ethereum/overview.md | 12 ++++++++---- book/build-your-staking-dapp/near/overview.md | 12 ++++++++---- .../polkadot-substrate/overview.md | 12 ++++++++---- book/build-your-staking-dapp/solana/overview.md | 12 ++++++++---- book/build-your-staking-dapp/ton/overview.md | 12 ++++++++---- 7 files changed, 56 insertions(+), 28 deletions(-) diff --git a/book/build-your-staking-dapp/avalanche/overview.md b/book/build-your-staking-dapp/avalanche/overview.md index 96ab340..c1d5292 100644 --- a/book/build-your-staking-dapp/avalanche/overview.md +++ b/book/build-your-staking-dapp/avalanche/overview.md @@ -8,6 +8,14 @@ The Avalanche blockchain, renowned for its rapid transaction processing, low fee The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular Avalanche libraries such as `@avalabs/avalanchejs`. This compatibility ensures that you can seamlessly integrate these methods into your existing Avalanche projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on Avalanche using the Chorus One SDK. ## Setting Up the Staker @@ -139,10 +147,6 @@ const { status, receipt } = await staker.getTxStatus({ txId, chain: 'P' }) console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular Avalanche libraries like `@avalabs/avalanchejs`. -{% endhint %} - --- ## Next Steps diff --git a/book/build-your-staking-dapp/cosmos/overview.md b/book/build-your-staking-dapp/cosmos/overview.md index 1caf7e7..e89ec37 100644 --- a/book/build-your-staking-dapp/cosmos/overview.md +++ b/book/build-your-staking-dapp/cosmos/overview.md @@ -8,6 +8,14 @@ The Cosmos network, renowned for its interoperability and modular framework, uti The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular Cosmos libraries such as `@cosmjs/cosmwasm`. This compatibility ensures that you can seamlessly integrate these methods into your existing Cosmos projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on Cosmos using the Chorus One SDK. ## Setting Up the Staker @@ -107,10 +115,6 @@ const signedTx = TxRaw.encode(rawTx).finish() Additionally, you can use the Chorus One SDK to sign transactions using Fireblocks, mnemonic or other methods. -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular Cosmos libraries like `@cosmjs/cosmwasm`. -{% endhint %} - For detailed information on setting up and configuring these options, refer to the [What is a Signer?](../../signers-explained/what-is-a-signer.md) section. {% tabs %} diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index 62acccf..6bc2b70 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -10,6 +10,14 @@ The Ethereum blockchain, renowned for its smart contract functionality and vibra The **Chorus One SDK** simplifies the staking process on the Ethereum network, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular Ethereum libraries such as `Ethers` and `viem`. This compatibility ensures that you can seamlessly integrate these methods into your existing Ethereum projects. + +{% endhint %} + To enhance efficiency, the SDK leverages [Stakewise V3's](https://docs.stakewise.io/) audited and secure smart contracts. By utilizing a pooling solution, it allows multiple users to combine their stakes, making staking more accessible and beneficial for smaller stakeholders. This guide will walk you through the fundamentals of staking on Ethereum using the Chorus One SDK. @@ -228,10 +236,6 @@ const { status, receipt } = await staker.getTxStatus({ txHash }) console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular Ethereum libraries like `viem`. -{% endhint %} - --- ## Next Steps diff --git a/book/build-your-staking-dapp/near/overview.md b/book/build-your-staking-dapp/near/overview.md index e68af78..2ae27ee 100644 --- a/book/build-your-staking-dapp/near/overview.md +++ b/book/build-your-staking-dapp/near/overview.md @@ -8,6 +8,14 @@ The NEAR blockchain, known for its scalability, low transaction fees, and develo The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular NEAR libraries such as `near-api-js`. This compatibility ensures that you can seamlessly integrate these methods into your existing NEAR projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on NEAR using the Chorus One SDK. ## Setting Up the Staker @@ -151,10 +159,6 @@ const { status, receipt } = await staker.getTxStatus({ console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular NEAR libraries like `near-api-js`. -{% endhint %} - --- ## Next Steps diff --git a/book/build-your-staking-dapp/polkadot-substrate/overview.md b/book/build-your-staking-dapp/polkadot-substrate/overview.md index 59d9ad7..dcaefe0 100644 --- a/book/build-your-staking-dapp/polkadot-substrate/overview.md +++ b/book/build-your-staking-dapp/polkadot-substrate/overview.md @@ -8,6 +8,14 @@ The Substrate blockchain framework is known for its flexibility and modularity, The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular Substrate libraries such as `@polkadot/api`. This compatibility ensures that you can seamlessly integrate these methods into your existing Substrate projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on Substrate using the Chorus One SDK. ## Setting Up the Staker @@ -145,10 +153,6 @@ const { status, receipt } = await staker.getTxStatus({ txHash }) console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular Substrate libraries like `@polkadot/api`. -{% endhint %} - ## Closing the Connection After completing the staking operations, close the connection to the Substrate network: diff --git a/book/build-your-staking-dapp/solana/overview.md b/book/build-your-staking-dapp/solana/overview.md index 5834038..b1fa8ee 100644 --- a/book/build-your-staking-dapp/solana/overview.md +++ b/book/build-your-staking-dapp/solana/overview.md @@ -10,6 +10,14 @@ The Solana blockchain, distinguished by its high throughput and low latency, lev The **Chorus One SDK** simplifies the staking process on the Solana network, providing developers with the tools needed to build, sign, and broadcast staking transactions. +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular Solana libraries such as `@solana/web3.js`. This compatibility ensures that you can seamlessly integrate these methods into your existing Solana projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on Solana using the Chorus One SDK. ## Setting Up the Staker @@ -147,10 +155,6 @@ const { status, receipt } = await staker.getTxStatus({ txHash }) console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular Solana libraries like `@solana/web3.js`. -{% endhint %} - --- ## Next Steps diff --git a/book/build-your-staking-dapp/ton/overview.md b/book/build-your-staking-dapp/ton/overview.md index ce8148b..3d033b2 100644 --- a/book/build-your-staking-dapp/ton/overview.md +++ b/book/build-your-staking-dapp/ton/overview.md @@ -13,6 +13,14 @@ It supports: - The official Nominator Pool smart contracts available for review on the official [TON Docs](https://docs.ton.org/participate/network-maintenance/nominators) - The official Single Nominator Pool smart contract available for review on the official [TON Docs](https://docs.ton.org/participate/network-maintenance/single-nominator) +{% hint style="info" %} + +### Compatibility Notice + +The methods provided in this documentation are compatible with popular TON libraries such as `@ton/ton`. This compatibility ensures that you can seamlessly integrate these methods into your existing TON projects. + +{% endhint %} + This guide will walk you through the fundamentals of staking on TON using the Chorus One SDK. ## Setting Up the Staker @@ -175,10 +183,6 @@ const { status, receipt } = await staker.getTxStatus({ console.log(status) // 'success' ``` -{% hint style="info" %} -The signature of these methods is compatible with the methods provided by popular TON libraries like `@ton/ton`. -{% endhint %} - --- ## Next Steps From f297962240ba6a5e6e6cbbbdef1f37329c7907d6 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 20:03:53 +0100 Subject: [PATCH 09/12] Ethereum: Add viem and ethers examples --- .../ethereum/overview.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index 6bc2b70..d1b7d6c 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -178,7 +178,54 @@ Additionally, you can use the Chorus One SDK to sign transactions using Firebloc - For detailed information on setting up and configuring these options, please refer to the [What is a Signer?](../../signers-explained/what-is-a-signer.md) section. {% tabs %} + +{% tab title="Using wagmi/Viem for Signing" %} +By integrating wagmi, you can take advantage of its lightweight developer-friendly wallet client capabilities to sign transactions on the Ethereum network: + +```javascript +import { useWalletClient } from 'wagmi' + +const { data: walletClient } = useWalletClient() + +const request = await walletClient.prepareTransactionRequest(tx) + +// Sign and send the transaction +const hash = await walletClient.sendTransaction(request) +``` + +For more information please refer to the [Viem Documentation](https://viem.sh/) + +{% endtab %} + +{% tab title="Using Ethers for Signing" %} + +By integrating Ethers, you can use its widely adopted and feature-rich library for signing transactions on the Ethereum network: + +```javascript +import { BrowserProvider } from 'ethers' + +const provider = new BrowserProvider(window.ethereum) +const signer = await provider.getSigner() + +const feeData = await provider.getFeeData() +const gasLimit = await provider.estimateGas(stakeTx2) + +// Sign and send the transaction +const { hash } = await signer.sendTransaction({ + ...stakeTx2, + // Optional: Set the gas limit and fees + gasLimit: gasLimit, + maxFeePerGas: feeData.maxFeePerGas, + maxPriorityFeePerGas: feeData.maxPriorityFeePerGas +}) +``` + +For more information please refer to the [Ethers Documentation](https://docs.ethers.org/) + +{% endtab %} + {% tab title="Using Fireblocks for Signing" %} + By integrating Fireblocks, you can leverage its robust security features to sign transactions on the Ethereum network. To set up Fireblocks, you will need to provide the necessary API key, secret key, and vault ID: ```javascript @@ -215,7 +262,9 @@ When signing transactions, you can optionally configure the fees to manage cost - **`defaultPriorityFee`**: (Optional) This value allows you to override the `maxPriorityFeePerGas` estimated by the RPC. You can specify a fixed value to ensure that your transaction has a certain priority. By default, the `maxPriorityFeePerGas` is calculated by the RPC. For more information please refer to the [Signing with Fireblocks](../../signers-explained/fireblocks.md) + {% endtab %} + {% endtabs %} --- From b1ac024597623b89dc0173b62345f6937a557b48 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 20:25:23 +0100 Subject: [PATCH 10/12] Ethereum: generate docs & fix linting issues --- book/docs/classes/ethereum_src.EthereumStaker.md | 11 +++++++---- book/docs/interfaces/ethereum_src.Transaction.md | 9 --------- packages/ethereum/src/lib/methods/buildStakeTx.ts | 2 +- packages/ethereum/src/staker.ts | 3 --- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/book/docs/classes/ethereum_src.EthereumStaker.md b/book/docs/classes/ethereum_src.EthereumStaker.md index b30076b..ea83bc4 100644 --- a/book/docs/classes/ethereum_src.EthereumStaker.md +++ b/book/docs/classes/ethereum_src.EthereumStaker.md @@ -107,7 +107,7 @@ Builds a staking transaction. | `params` | `Object` | Parameters for building the transaction | | `params.delegatorAddress` | \`0x$\{string}\` | The delegator (wallet) address to stake from | | `params.validatorAddress` | \`0x$\{string}\` | The validator (vault) address to stake with | -| `params.amount` | `string` | The amount to stake, specified in `ETH` | +| `params.amount` | `string` | The amount to stake, specified in `ETH`. E.g. "1" - 1 ETH | | `params.referrer?` | \`0x$\{string}\` | (Optional) The address of the referrer. This is used to track the origin of transactions, providing insights into which sources or campaigns are driving activity. This can be useful for analytics and optimizing user acquisition strategies | ### Returns @@ -136,7 +136,7 @@ method. | `params` | `Object` | Parameters for building the transaction | | `params.delegatorAddress` | \`0x$\{string}\` | The delegator (wallet) address that is unstaking | | `params.validatorAddress` | \`0x$\{string}\` | The validator (vault) address to unstake from | -| `params.amount` | `string` | The amount to unstake, specified in `ETH` | +| `params.amount` | `string` | The amount to unstake, specified in `ETH`. E.g. "1" - 1 ETH | ### Returns @@ -186,7 +186,7 @@ Builds a mint transaction. | `params` | `Object` | Parameters for building the transaction | | `params.delegatorAddress` | \`0x$\{string}\` | The delegator (wallet) address | | `params.validatorAddress` | \`0x$\{string}\` | The validator (vault) address to mint shares for | -| `params.amount` | `string` | The amount to mint, specified in `osETH` | +| `params.amount` | `string` | The amount to mint, specified in `osETH`. E.g. "1" - 1 osETH | | `params.referrer?` | \`0x$\{string}\` | (Optional) The address of the referrer. This is used to track the origin of transactions, providing insights into which sources or campaigns are driving activity. This can be useful for analytics and optimizing user acquisition strategies. | ### Returns @@ -210,7 +210,7 @@ Builds a burn transaction. | `params` | `Object` | Parameters for building the transaction | | `params.delegatorAddress` | \`0x$\{string}\` | The delegator (wallet) address | | `params.validatorAddress` | \`0x$\{string}\` | The validator (vault) address to burn shares from | -| `params.amount` | `string` | The amount to burn, specified in `osETH` | +| `params.amount` | `string` | The amount to burn, specified in `osETH`. E.g. "1" - 1 osETH | ### Returns @@ -415,6 +415,9 @@ Signs a transaction using the provided signer. | `params.signer` | `Signer` | A signer instance. | | `params.signerAddress` | \`0x$\{string}\` | The address of the signer | | `params.tx` | [`Transaction`](../interfaces/ethereum_src.Transaction.md) | The transaction to sign | +| `params.fees?` | `Object` | (Optional) The fees to include in the transaction | +| `params.fees.baseFeeMultiplier?` | `number` | - | +| `params.fees.defaultPriorityFee?` | `string` | - | ### Returns diff --git a/book/docs/interfaces/ethereum_src.Transaction.md b/book/docs/interfaces/ethereum_src.Transaction.md index f11afcd..fa72993 100644 --- a/book/docs/interfaces/ethereum_src.Transaction.md +++ b/book/docs/interfaces/ethereum_src.Transaction.md @@ -4,21 +4,12 @@ Represents an Ethereum transaction. ### Properties -- [account](ethereum_src.Transaction.md#account) - [to](ethereum_src.Transaction.md#to) - [value](ethereum_src.Transaction.md#value) - [data](ethereum_src.Transaction.md#data) ## Properties -### account - -• **account**: \`0x$\{string}\` - -The account (sender) address in hexadecimal format. - -___ - ### to • **to**: \`0x$\{string}\` diff --git a/packages/ethereum/src/lib/methods/buildStakeTx.ts b/packages/ethereum/src/lib/methods/buildStakeTx.ts index 3ddfabe..d6093e9 100644 --- a/packages/ethereum/src/lib/methods/buildStakeTx.ts +++ b/packages/ethereum/src/lib/methods/buildStakeTx.ts @@ -5,7 +5,7 @@ import { keeperABI } from '../contracts/keeperAbi' import { getHarvestParams } from '../utils/getHarvestParams' import { Transaction } from '../types/transaction' -export async function buildStakeTx(request: { +export async function buildStakeTx (request: { connector: StakewiseConnector userAccount: Hex vault: Hex diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index 4493896..affc7aa 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -120,7 +120,6 @@ export class EthereumStaker { validatorAddress: Hex amount: string // ETH assets }): Promise<{ tx: Transaction }> { - this.validateAmount(params.amount) const tx = await buildUnstakeTx({ connector: this.connector, userAccount: params.delegatorAddress, @@ -181,7 +180,6 @@ export class EthereumStaker { amount: string // osETH shares referrer?: Hex }): Promise<{ tx: Transaction }> { - this.validateAmount(params.amount) const tx = await buildMintTx({ connector: this.connector, userAccount: params.delegatorAddress, @@ -208,7 +206,6 @@ export class EthereumStaker { validatorAddress: Hex amount: string // osETH shares }): Promise<{ tx: Transaction }> { - this.validateAmount(params.amount) const tx = await buildBurnTx({ connector: this.connector, userAccount: params.delegatorAddress, From 832bc5a28b09abab16128d562e3a1c266012b30a Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 20:28:23 +0100 Subject: [PATCH 11/12] Ethereum: small fixes --- .../ethereum/overview.md | 12 +++---- .../classes/ethereum_src.EthereumStaker.md | 5 ++- packages/ethereum/src/staker.ts | 34 ++++++++++--------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index d1b7d6c..73b4a99 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -187,6 +187,7 @@ import { useWalletClient } from 'wagmi' const { data: walletClient } = useWalletClient() +// Prepare the transaction and estimate the gas fees const request = await walletClient.prepareTransactionRequest(tx) // Sign and send the transaction @@ -207,12 +208,13 @@ import { BrowserProvider } from 'ethers' const provider = new BrowserProvider(window.ethereum) const signer = await provider.getSigner() +// Estimate gas fees const feeData = await provider.getFeeData() -const gasLimit = await provider.estimateGas(stakeTx2) +const gasLimit = await provider.estimateGas(tx) // Sign and send the transaction const { hash } = await signer.sendTransaction({ - ...stakeTx2, + ...tx, // Optional: Set the gas limit and fees gasLimit: gasLimit, maxFeePerGas: feeData.maxFeePerGas, @@ -246,10 +248,8 @@ const { signedTx } = await staker.sign({ signer, signerAddress: '0x70aEe8a9099ebADB186C2D530F72CF5dC7FE6B30', tx, - fees: { - baseFeeMultiplier: 2, // Optional: Multiplier for the base fee per gas - defaultPriorityFee: '2' // Optional: Override for the maxPriorityFeePerGas - } + baseFeeMultiplier: 2, // Optional: Multiplier for the base fee per gas + defaultPriorityFee: '2' // Optional: Override for the maxPriorityFeePerGas }) ``` diff --git a/book/docs/classes/ethereum_src.EthereumStaker.md b/book/docs/classes/ethereum_src.EthereumStaker.md index ea83bc4..b971269 100644 --- a/book/docs/classes/ethereum_src.EthereumStaker.md +++ b/book/docs/classes/ethereum_src.EthereumStaker.md @@ -415,9 +415,8 @@ Signs a transaction using the provided signer. | `params.signer` | `Signer` | A signer instance. | | `params.signerAddress` | \`0x$\{string}\` | The address of the signer | | `params.tx` | [`Transaction`](../interfaces/ethereum_src.Transaction.md) | The transaction to sign | -| `params.fees?` | `Object` | (Optional) The fees to include in the transaction | -| `params.fees.baseFeeMultiplier?` | `number` | - | -| `params.fees.defaultPriorityFee?` | `string` | - | +| `params.baseFeeMultiplier?` | `number` | (Optional) The multiplier for fees, which is used to manage fee fluctuations, is applied to the base fee per gas from the latest block to determine the final `maxFeePerGas`. The default value is 1.2. | +| `params.defaultPriorityFee?` | `string` | (Optional) This overrides the the `maxPriorityFeePerGas` estimated by the RPC. | ### Returns diff --git a/packages/ethereum/src/staker.ts b/packages/ethereum/src/staker.ts index affc7aa..3b04de2 100644 --- a/packages/ethereum/src/staker.ts +++ b/packages/ethereum/src/staker.ts @@ -418,9 +418,8 @@ export class EthereumStaker { * @param params.signer - A signer instance. * @param params.signerAddress - The address of the signer * @param params.tx - The transaction to sign - * @param params.fees - (Optional) The fees to include in the transaction - * @param params.fees.baseFeeMultiplier - (Optional) The multiplier for fees, which is used to manage fee fluctuations, is applied to the base fee per gas from the latest block to determine the final `maxFeePerGas`. The default value is 1.2. - * @param params.fees.defaultPriorityFee - (Optional) This overrides the the `maxPriorityFeePerGas` estimated by the RPC. + * @param params.baseFeeMultiplier - (Optional) The multiplier for fees, which is used to manage fee fluctuations, is applied to the base fee per gas from the latest block to determine the final `maxFeePerGas`. The default value is 1.2. + * @param params.defaultPriorityFee - (Optional) This overrides the the `maxPriorityFeePerGas` estimated by the RPC. * * @returns A promise that resolves to an object containing the signed transaction. */ @@ -428,21 +427,24 @@ export class EthereumStaker { signer: Signer signerAddress: Hex tx: Transaction - fees?: { - baseFeeMultiplier?: number - defaultPriorityFee?: string - } + baseFeeMultiplier?: number + defaultPriorityFee?: string }): Promise<{ signedTx: Hex }> { - const { signer, signerAddress, tx: tx, fees } = params + const { signer, signerAddress, tx: tx, baseFeeMultiplier, defaultPriorityFee } = params + + const baseChain = this.connector.chain + + const baseFees = baseChain.fees ?? {} + const fees = { + ...baseFees, + baseFeeMultiplier: baseFeeMultiplier ?? baseFees.baseFeeMultiplier, + defaultPriorityFee: + defaultPriorityFee === undefined ? baseFees.defaultPriorityFee : this.parseEther(defaultPriorityFee) + } + const chain: Chain = { - ...this.connector.chain, - fees: fees - ? { - baseFeeMultiplier: fees.baseFeeMultiplier, - defaultPriorityFee: - fees.defaultPriorityFee === undefined ? undefined : this.parseEther(fees.defaultPriorityFee) - } - : undefined + ...baseChain, + fees } const client = createWalletClient({ chain, From f36a2b5380fbfa2ebe1506efb479837a16709083 Mon Sep 17 00:00:00 2001 From: Dmitry Yakimov Date: Fri, 26 Jul 2024 21:03:24 +0100 Subject: [PATCH 12/12] Adjust docs styling --- .../avalanche/overview.md | 10 ++++----- .../cosmos/overview.md | 6 +++--- .../ethereum/overview.md | 21 ++++++++----------- book/build-your-staking-dapp/near/overview.md | 6 +++--- .../polkadot-substrate/overview.md | 6 +++--- .../solana/overview.md | 6 +++--- book/build-your-staking-dapp/ton/overview.md | 6 +++--- book/ethereum-tutorial/3-staking.md | 6 +----- 8 files changed, 30 insertions(+), 37 deletions(-) diff --git a/book/build-your-staking-dapp/avalanche/overview.md b/book/build-your-staking-dapp/avalanche/overview.md index c1d5292..bb13c4a 100644 --- a/book/build-your-staking-dapp/avalanche/overview.md +++ b/book/build-your-staking-dapp/avalanche/overview.md @@ -1,23 +1,23 @@ # Overview -Staking on the Avalanche network (AVAX) involves locking up tokens to support the network's security and operations. In return, stakers earn rewards. - {% hint style="info" %} The Avalanche blockchain, renowned for its rapid transaction processing, low fees, and eco-friendly architecture, utilizes a unique consensus protocol known as Avalanche Consensus. This protocol enables a high degree of decentralization and security, allowing validators to participate by staking AVAX, the network's native token. {% endhint %} +Staking on the Avalanche network (AVAX) involves locking up tokens to support the network's security and operations. In return, stakers earn rewards. + The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +This guide will walk you through the fundamentals of staking on Avalanche using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular Avalanche libraries such as `@avalabs/avalanchejs`. This compatibility ensures that you can seamlessly integrate these methods into your existing Avalanche projects. {% endhint %} -This guide will walk you through the fundamentals of staking on Avalanche using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on the Avalanche network using the Chorus One SDK, you will first need to initialize the SDK. diff --git a/book/build-your-staking-dapp/cosmos/overview.md b/book/build-your-staking-dapp/cosmos/overview.md index e89ec37..cd74f25 100644 --- a/book/build-your-staking-dapp/cosmos/overview.md +++ b/book/build-your-staking-dapp/cosmos/overview.md @@ -8,16 +8,16 @@ The Cosmos network, renowned for its interoperability and modular framework, uti The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +This guide will walk you through the fundamentals of staking on Cosmos using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular Cosmos libraries such as `@cosmjs/cosmwasm`. This compatibility ensures that you can seamlessly integrate these methods into your existing Cosmos projects. {% endhint %} -This guide will walk you through the fundamentals of staking on Cosmos using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on the Cosmos network using the Chorus One SDK, you will first need to initialize the SDK for Cosmos. diff --git a/book/build-your-staking-dapp/ethereum/overview.md b/book/build-your-staking-dapp/ethereum/overview.md index 73b4a99..1b24312 100644 --- a/book/build-your-staking-dapp/ethereum/overview.md +++ b/book/build-your-staking-dapp/ethereum/overview.md @@ -10,18 +10,18 @@ The Ethereum blockchain, renowned for its smart contract functionality and vibra The **Chorus One SDK** simplifies the staking process on the Ethereum network, providing developers with the tools needed to build, sign, and broadcast staking transactions. +To enhance efficiency, the SDK leverages [Stakewise V3's](https://docs.stakewise.io/) audited and secure smart contracts. By utilizing a pooling solution, it allows multiple users to combine their stakes, making staking more accessible and beneficial for smaller stakeholders. + +This guide will walk you through the fundamentals of staking on Ethereum using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular Ethereum libraries such as `Ethers` and `viem`. This compatibility ensures that you can seamlessly integrate these methods into your existing Ethereum projects. {% endhint %} -To enhance efficiency, the SDK leverages [Stakewise V3's](https://docs.stakewise.io/) audited and secure smart contracts. By utilizing a pooling solution, it allows multiple users to combine their stakes, making staking more accessible and beneficial for smaller stakeholders. - -This guide will walk you through the fundamentals of staking on Ethereum using the Chorus One SDK. - ## Understanding Key Concepts
@@ -121,9 +121,7 @@ const { tx } = await staker.buildStakeTx({ }) ``` -{% hint style="warning" %} - -**Ensuring Correct Amount Format for Staking** +### Ensuring Correct Amount Format for Staking The `amount` parameter must be a string representing the amount of ETH to deposit. For example, `'1'` represents 1 ETH. @@ -140,8 +138,6 @@ console.log(amountToStake) // "0.01" This ensures the `amountToStake` parameter is in the correct format for the staking transaction function. -{% endhint %} - --- ## Getting the Validator Address provided by Chorus One @@ -190,7 +186,7 @@ const { data: walletClient } = useWalletClient() // Prepare the transaction and estimate the gas fees const request = await walletClient.prepareTransactionRequest(tx) -// Sign and send the transaction +// Sign and broadcast the transaction const hash = await walletClient.sendTransaction(request) ``` @@ -212,7 +208,7 @@ const signer = await provider.getSigner() const feeData = await provider.getFeeData() const gasLimit = await provider.estimateGas(tx) -// Sign and send the transaction +// Sign and broadcast the transaction const { hash } = await signer.sendTransaction({ ...tx, // Optional: Set the gas limit and fees @@ -244,6 +240,7 @@ const signer = new FireblocksSigner({ await signer.init() +// Just sign the transaction const { signedTx } = await staker.sign({ signer, signerAddress: '0x70aEe8a9099ebADB186C2D530F72CF5dC7FE6B30', diff --git a/book/build-your-staking-dapp/near/overview.md b/book/build-your-staking-dapp/near/overview.md index 2ae27ee..9fca63b 100644 --- a/book/build-your-staking-dapp/near/overview.md +++ b/book/build-your-staking-dapp/near/overview.md @@ -8,16 +8,16 @@ The NEAR blockchain, known for its scalability, low transaction fees, and develo The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +This guide will walk you through the fundamentals of staking on NEAR using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular NEAR libraries such as `near-api-js`. This compatibility ensures that you can seamlessly integrate these methods into your existing NEAR projects. {% endhint %} -This guide will walk you through the fundamentals of staking on NEAR using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on the NEAR network using the Chorus One SDK, you will first need to initialize the SDK for NEAR. diff --git a/book/build-your-staking-dapp/polkadot-substrate/overview.md b/book/build-your-staking-dapp/polkadot-substrate/overview.md index dcaefe0..a916ee7 100644 --- a/book/build-your-staking-dapp/polkadot-substrate/overview.md +++ b/book/build-your-staking-dapp/polkadot-substrate/overview.md @@ -8,16 +8,16 @@ The Substrate blockchain framework is known for its flexibility and modularity, The **Chorus One SDK** simplifies this process, providing developers with the tools needed to build, sign, and broadcast staking transactions. +This guide will walk you through the fundamentals of staking on Substrate using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular Substrate libraries such as `@polkadot/api`. This compatibility ensures that you can seamlessly integrate these methods into your existing Substrate projects. {% endhint %} -This guide will walk you through the fundamentals of staking on Substrate using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on the Substrate network using the Chorus One SDK, you will first need to initialize the SDK for Substrate. diff --git a/book/build-your-staking-dapp/solana/overview.md b/book/build-your-staking-dapp/solana/overview.md index b1fa8ee..553d6ad 100644 --- a/book/build-your-staking-dapp/solana/overview.md +++ b/book/build-your-staking-dapp/solana/overview.md @@ -10,16 +10,16 @@ The Solana blockchain, distinguished by its high throughput and low latency, lev The **Chorus One SDK** simplifies the staking process on the Solana network, providing developers with the tools needed to build, sign, and broadcast staking transactions. +This guide will walk you through the fundamentals of staking on Solana using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular Solana libraries such as `@solana/web3.js`. This compatibility ensures that you can seamlessly integrate these methods into your existing Solana projects. {% endhint %} -This guide will walk you through the fundamentals of staking on Solana using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on the Solana network using the Chorus One SDK, you will first need to initialize the SDK. diff --git a/book/build-your-staking-dapp/ton/overview.md b/book/build-your-staking-dapp/ton/overview.md index 3d033b2..17997de 100644 --- a/book/build-your-staking-dapp/ton/overview.md +++ b/book/build-your-staking-dapp/ton/overview.md @@ -13,16 +13,16 @@ It supports: - The official Nominator Pool smart contracts available for review on the official [TON Docs](https://docs.ton.org/participate/network-maintenance/nominators) - The official Single Nominator Pool smart contract available for review on the official [TON Docs](https://docs.ton.org/participate/network-maintenance/single-nominator) +This guide will walk you through the fundamentals of staking on TON using the Chorus One SDK. + {% hint style="info" %} -### Compatibility Notice +**Compatibility Notice** The methods provided in this documentation are compatible with popular TON libraries such as `@ton/ton`. This compatibility ensures that you can seamlessly integrate these methods into your existing TON projects. {% endhint %} -This guide will walk you through the fundamentals of staking on TON using the Chorus One SDK. - ## Setting Up the Staker To get started with staking on TON using the Chorus One SDK, you will first need to initialize the SDK. diff --git a/book/ethereum-tutorial/3-staking.md b/book/ethereum-tutorial/3-staking.md index 8ae6d3f..57ef7fc 100644 --- a/book/ethereum-tutorial/3-staking.md +++ b/book/ethereum-tutorial/3-staking.md @@ -103,9 +103,7 @@ The `Transaction` object returned by `buildStakeTransaction` includes the follow - **`data` (Hex)**: A contract hashed method call with encoded arguments (the transformation of the method call into this encoded and hashed form is handled by the `encodeFunctionData` method from the viem library). - **`value` (bigint)**: The amount of ETH being used in the transaction. In this case, it's the amount being staked. -{% hint style="warning" %} - -**Ensuring Correct Amount Format for Staking** +### Ensuring Correct Amount Format for Staking The `amountToStake` parameter must be a string representing the amount of ETH to deposit. For example, `'1'` represents 1 ETH. @@ -122,8 +120,6 @@ console.log(amountToStake) // "0.01" This ensures the `amountToStake` parameter is in the correct format for the staking transaction function. -{% endhint %} - {% hint style="info" %} **Configuring Fees**