From 01a7acc56fccf0affc1b2404abdfd6f8662da224 Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Tue, 10 Sep 2024 13:21:33 -0300 Subject: [PATCH] feat: add max button feature for solana send flow --- .../base/adapters/solana/web3js/client.ts | 35 ++++++++++++++++--- .../web3js/utils/createSendTransaction.ts | 5 ++- .../core/src/controllers/SendController.ts | 9 +++++ .../core/src/controllers/SwapController.ts | 2 +- .../src/partials/w3m-input-token/index.ts | 14 ++++---- .../src/views/w3m-wallet-send-view/index.ts | 3 ++ 6 files changed, 56 insertions(+), 12 deletions(-) diff --git a/packages/base/adapters/solana/web3js/client.ts b/packages/base/adapters/solana/web3js/client.ts index a1804fac3f..6295307d30 100644 --- a/packages/base/adapters/solana/web3js/client.ts +++ b/packages/base/adapters/solana/web3js/client.ts @@ -184,16 +184,29 @@ export class SolanaWeb3JsClient implements ChainAdapter { + estimateGas: async params => { + if (params.chainNamespace !== 'solana') { + throw new Error('Chain namespace is not supported') + } + const connection = SolStoreUtil.state.connection if (!connection) { throw new Error('Connection is not set') } - const recentBlockhash = await connection.getRecentBlockhash() + const provider = this.getProvider() + + const transaction = await createSendTransaction({ + provider, + connection, + to: '11111111111111111111111111111111', + value: 1 + }) + + const fee = await transaction.getEstimatedFee(connection) - return BigInt(recentBlockhash.feeCalculator.lamportsPerSignature) + return BigInt(fee || 0) }, // -- Transaction methods --------------------------------------------------- /** @@ -213,8 +226,9 @@ export class SolanaWeb3JsClient implements ChainAdapter(resolve => { + const interval = setInterval(async () => { + const status = await connection.getSignatureStatus(result) + + if (status?.value) { + clearInterval(interval) + resolve() + } + }, 1000) + }) + + await this.syncBalance(address) + return result }, diff --git a/packages/base/adapters/solana/web3js/utils/createSendTransaction.ts b/packages/base/adapters/solana/web3js/utils/createSendTransaction.ts index 2264c57b0e..df8664d76a 100644 --- a/packages/base/adapters/solana/web3js/utils/createSendTransaction.ts +++ b/packages/base/adapters/solana/web3js/utils/createSendTransaction.ts @@ -3,7 +3,8 @@ import { SystemProgram, type Connection, Transaction, - LAMPORTS_PER_SOL + LAMPORTS_PER_SOL, + ComputeBudgetProgram } from '@solana/web3.js' import type { Provider } from '@web3modal/scaffold-utils/solana' @@ -30,6 +31,8 @@ export async function createSendTransaction({ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash() const instructions = [ + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 20000000 }), + ComputeBudgetProgram.setComputeUnitLimit({ units: 500 }), SystemProgram.transfer({ fromPubkey: provider.publicKey, toPubkey, diff --git a/packages/core/src/controllers/SendController.ts b/packages/core/src/controllers/SendController.ts index a7a3814513..cc1754fe44 100644 --- a/packages/core/src/controllers/SendController.ts +++ b/packages/core/src/controllers/SendController.ts @@ -160,6 +160,15 @@ export const SendController = { to: this.state.receiverAddress, value: this.state.sendTokenAmount }) + .then(() => { + this.resetSend() + AccountController.fetchTokenBalance() + }) + .catch(error => { + SnackController.showError('Failed to send transaction. Please try again.') + // eslint-disable-next-line no-console + console.error('SendController:sendToken - failed to send solana transaction', error) + }) return default: diff --git a/packages/core/src/controllers/SwapController.ts b/packages/core/src/controllers/SwapController.ts index d22aaca2a1..7c3e6960ab 100644 --- a/packages/core/src/controllers/SwapController.ts +++ b/packages/core/src/controllers/SwapController.ts @@ -456,7 +456,7 @@ export const SwapController = { case 'solana': state.gasFee = res.standard state.gasPriceInUSD = NumberUtil.multiply(res.standard, state.networkPrice) - .dividedBy(10 ** 9) + .dividedBy(1e9) .toNumber() return { diff --git a/packages/scaffold-ui/src/partials/w3m-input-token/index.ts b/packages/scaffold-ui/src/partials/w3m-input-token/index.ts index b8026898d5..32ee2e13d8 100644 --- a/packages/scaffold-ui/src/partials/w3m-input-token/index.ts +++ b/packages/scaffold-ui/src/partials/w3m-input-token/index.ts @@ -17,6 +17,8 @@ export class W3mInputToken extends LitElement { @property({ type: Number }) public gasPriceInUSD?: number + @property({ type: Number }) public gasPrice?: number + // -- Render -------------------------------------------- // public override render() { return html` this.token?.address === nativeAddress ) + const numericGas = NumberUtil.bigNumber(this.gasPrice).shiftedBy( + -this.token.quantity.decimals + ) + const maxValue = isNetworkToken - ? NumberUtil.bigNumber(this.token.quantity.numeric).minus(amountOfTokenGasRequires) + ? NumberUtil.bigNumber(this.token.quantity.numeric).minus(numericGas) : NumberUtil.bigNumber(this.token.quantity.numeric) SendController.setTokenAmount(Number(maxValue.toFixed(20))) diff --git a/packages/scaffold-ui/src/views/w3m-wallet-send-view/index.ts b/packages/scaffold-ui/src/views/w3m-wallet-send-view/index.ts index eb25367857..b0d7f4b6b5 100644 --- a/packages/scaffold-ui/src/views/w3m-wallet-send-view/index.ts +++ b/packages/scaffold-ui/src/views/w3m-wallet-send-view/index.ts @@ -30,6 +30,8 @@ export class W3mWalletSendView extends LitElement { @state() private gasPriceInUSD = SendController.state.gasPriceInUSD + @state() private gasPrice = SendController.state.gasPrice + @state() private message: | 'Preview Send' | 'Select Token' @@ -70,6 +72,7 @@ export class W3mWalletSendView extends LitElement { .token=${this.token} .sendTokenAmount=${this.sendTokenAmount} .gasPriceInUSD=${this.gasPriceInUSD} + .gasPrice=${this.gasPrice} >