use multi rpc everywhere (#378)

* use multi rpc everywhere

* fix
This commit is contained in:
Adrian Brzeziński 2024-01-26 14:39:18 +01:00 committed by GitHub
parent c2ca998174
commit bd27f72809
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 133 additions and 51 deletions

View File

@ -1,7 +1,7 @@
import { ChangeEvent, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'next-i18next'
import mangoStore from '@store/mangoStore'
import { createSolanaMessage, notify } from '../../utils/notifications'
import { createLedgerMessage, notify } from '../../utils/notifications'
import Button, { IconButton, LinkButton } from '../shared/Button'
import BounceLoader from '../shared/BounceLoader'
import Input from '../forms/Input'
@ -88,7 +88,7 @@ const CreateAccountForm = ({
)
if (tx) {
if (signToNotifications) {
createSolanaMessage(walletContext, setCookie)
createLedgerMessage(walletContext, setCookie, connection)
}
const pk = walletContext.wallet.adapter.publicKey

View File

@ -64,7 +64,6 @@ const ListMarket = ({ goBack }: { goBack: () => void }) => {
const connection = mangoStore((s) => s.connection)
const client = mangoStore((s) => s.client)
const voter = GovernanceStore((s) => s.voter)
const vsrClient = GovernanceStore((s) => s.vsrClient)
const proposals = GovernanceStore((s) => s.proposals)
const proposalsLoading = GovernanceStore((s) => s.loadingProposals)
@ -192,6 +191,7 @@ const ListMarket = ({ goBack }: { goBack: () => void }) => {
try {
const proposalAddress = await createProposal(
connection,
client,
walletSigner,
MANGO_DAO_WALLET_GOVERNANCE,
voter.tokenOwnerRecord!,
@ -213,18 +213,19 @@ const ListMarket = ({ goBack }: { goBack: () => void }) => {
}
setProposing(false)
}, [
isFormValid,
advForm,
proposals,
baseBank,
client,
connection,
group,
isFormValid,
proposals,
quoteBank,
t,
wallet,
connection,
voter.tokenOwnerRecord,
vsrClient,
wallet,
fee,
t,
])
const goToPropsPage = async () => {

View File

@ -583,6 +583,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
if (!simulation.value.err) {
const proposalAddress = await createProposal(
connection,
client,
walletSigner,
MANGO_DAO_WALLET_GOVERNANCE,
voter.tokenOwnerRecord!,

View File

@ -17,6 +17,7 @@ import { MARKET_STATE_LAYOUT_V2 } from '@project-serum/serum'
import { notify } from 'utils/notifications'
import InlineNotification from '@components/shared/InlineNotification'
import Switch from '@components/forms/Switch'
import { sendTxAndConfirm } from 'utils/governance/tools'
type CreateObMarketForm = {
programId: string
@ -70,7 +71,7 @@ const CreateOpenbookMarketModal = ({
const connection = mangoStore((s) => s.connection)
const fee = mangoStore((s) => s.priorityFee)
const { connect, signAllTransactions, connected, publicKey } = useWallet()
const client = mangoStore((s) => s.client)
const [form, setForm] = useState({ ...defaultFormValues })
const [formErrors, setFormErrors] = useState<FormErrors>({})
const [creating, setCreating] = useState(false)
@ -84,7 +85,6 @@ const CreateOpenbookMarketModal = ({
if (!publicKey || !signAllTransactions) {
return
}
let sig = ''
setCreating(true)
try {
const ixObj = await makeCreateOpenBookMarketInstructionSimple({
@ -120,15 +120,12 @@ const CreateOpenbookMarketModal = ({
const signedTransactions = await signAllTransactions(transactions)
for (const tx of signedTransactions) {
const rawTransaction = tx.serialize()
sig = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: sig,
})
await sendTxAndConfirm(
client.opts.multipleConnections,
connection,
tx,
latestBlockhash,
)
}
onClose()
notify({
@ -140,7 +137,6 @@ const CreateOpenbookMarketModal = ({
notify({
title: t('error-creating-market'),
description: `${e}`,
txid: sig,
type: 'error',
})
}

View File

@ -21,6 +21,7 @@ import Loading from '@components/shared/Loading'
import { WhirlpoolContext, buildWhirlpoolClient } from '@orca-so/whirlpools-sdk'
import { LIQUIDITY_STATE_LAYOUT_V4 } from '@raydium-io/raydium-sdk'
import { LISTING_PRESETS_KEY } from '@blockworks-foundation/mango-v4-settings/lib/helpers/listingTools'
import { sendTxAndConfirm } from 'utils/governance/tools'
const poolAddressError = 'no-pool-address-found'
const wrongTierPassedForCreation = 'Wrong tier passed for creation of oracle'
@ -58,6 +59,7 @@ const CreateSwitchboardOracleModal = ({
}: RaydiumProps | OrcaProps) => {
const { t } = useTranslation(['governance'])
const connection = mangoStore((s) => s.connection)
const client = mangoStore((s) => s.client)
const wallet = useWallet()
const quoteTokenName = 'USD'
const pythUsdOracle = 'Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD'
@ -355,15 +357,12 @@ const CreateSwitchboardOracleModal = ({
}
const signedTransactions = await wallet.signAllTransactions!(transactions)
for (const tx of signedTransactions) {
const rawTransaction = tx.serialize()
const address = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: address,
})
await sendTxAndConfirm(
client.opts.multipleConnections,
connection,
tx,
latestBlockhash,
)
}
setCreatingOracle(false)
onClose()

View File

@ -268,6 +268,7 @@ const DashboardSuggestedValues = ({
const index = proposals ? Object.values(proposals).length : 0
const proposalAddress = await createProposal(
connection,
client,
walletSigner,
MANGO_DAO_WALLET_GOVERNANCE,
voter.tokenOwnerRecord!,

View File

@ -64,6 +64,7 @@ import {
} from '@tanstack/react-query'
import { isTokenInsured } from '@components/DepositForm'
import UninsuredNotification from '@components/shared/UninsuredNotification'
import { sendTxAndConfirm } from 'utils/governance/tools'
type JupiterRouteInfoProps = {
amountIn: Decimal
@ -227,7 +228,6 @@ export const fetchJupiterWalletSwapTransaction = async (
).json()
const { swapTransaction } = transactions
const parsedSwapTransaction = VersionedTransaction.deserialize(
Buffer.from(swapTransaction, 'base64'),
)
@ -413,6 +413,7 @@ const SwapReviewRouteInfo = ({
const onWalletSwap = useCallback(async () => {
if (!selectedRoute || !inputBank || !outputBank || !wallet.publicKey) return
const actions = mangoStore.getState().actions
const client = mangoStore.getState().client
const set = mangoStore.getState().set
const connection = mangoStore.getState().connection
setSubmitting(true)
@ -424,17 +425,15 @@ const SwapReviewRouteInfo = ({
inputBank.mint,
outputBank.mint,
)
const latestBlockhash = await connection.getLatestBlockhash()
const sign = wallet.signTransaction!
const signed = await sign(vtx)
const rawTransaction = signed.serialize()
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
maxRetries: 2,
})
await connection.confirmTransaction(txid)
const txid = await sendTxAndConfirm(
client.opts.multipleConnections,
connection,
signed,
latestBlockhash,
)
set((s) => {
s.swap.amountIn = ''
s.swap.amountOut = ''

View File

@ -23,10 +23,15 @@ import { MANGO_MINT } from 'utils/constants'
import { MANGO_GOVERNANCE_PROGRAM, MANGO_REALM_PK } from '../constants'
import { VsrClient } from '../voteStakeRegistryClient'
import { updateVoterWeightRecord } from './updateVoteWeightRecord'
import { createComputeBudgetIx } from '@blockworks-foundation/mango-v4'
import {
createComputeBudgetIx,
MangoClient,
} from '@blockworks-foundation/mango-v4'
import { sendTxAndConfirm } from '../tools'
export const createProposal = async (
connection: Connection,
mangoClient: MangoClient,
wallet: WalletSigner,
governance: PublicKey,
tokenOwnerRecord: ProgramAccount<TokenOwnerRecord>,
@ -144,16 +149,12 @@ export const createProposal = async (
const signedTransactions = await wallet.signAllTransactions(transactions)
for (const tx of signedTransactions) {
const rawTransaction = tx.serialize()
const address = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: address,
})
await sendTxAndConfirm(
mangoClient.opts.multipleConnections,
connection,
tx,
latestBlockhash,
)
}
return proposalAddress
}

View File

@ -5,10 +5,19 @@ import {
ProgramAccount,
pubkeyFilter,
} from '@solana/spl-governance'
import { Connection, PublicKey } from '@solana/web3.js'
import {
Connection,
PublicKey,
RpcResponseAndContext,
SignatureResult,
Transaction,
VersionedTransaction,
} from '@solana/web3.js'
import { TokenProgramAccount } from './accounts/vsrAccounts'
import { MintLayout, RawMint } from '@solana/spl-token'
import { BN } from '@coral-xyz/anchor'
import { awaitTransactionSignatureConfirmation } from '@blockworks-foundation/mangolana/lib/transactions'
import { MangoError, tryStringify } from '@blockworks-foundation/mango-v4'
export async function fetchRealm({
connection,
@ -157,3 +166,78 @@ export const compareObjectsAndGetDifferentKeys = <T extends object>(
return diffKeys as (keyof T)[]
}
export const sendTxAndConfirm = async (
multipleConnections: Connection[] = [],
connection: Connection,
tx: Transaction | VersionedTransaction,
latestBlockhash: {
lastValidBlockHeight: number
blockhash: string
},
) => {
let signature = ''
const abortController = new AbortController()
try {
const allConnections = [connection, ...multipleConnections]
const rawTransaction = tx.serialize()
signature = await Promise.any(
allConnections.map((c) => {
return c.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
}),
)
await Promise.any(
allConnections.map((c) =>
awaitTransactionSignatureConfirmation({
txid: signature,
confirmLevel: 'processed',
connection: c,
timeoutStrategy: {
block: latestBlockhash,
},
abortSignal: abortController.signal,
}),
),
)
abortController.abort()
return signature
} catch (e) {
abortController.abort()
if (e instanceof AggregateError) {
for (const individualError of e.errors) {
const stringifiedError = tryStringify(individualError)
throw new MangoError({
txid: signature,
message: `${
stringifiedError
? stringifiedError
: individualError
? individualError
: 'Unknown error'
}`,
})
}
}
if (isErrorWithSignatureResult(e)) {
const stringifiedError = tryStringify(e?.value?.err)
throw new MangoError({
txid: signature,
message: `${stringifiedError ? stringifiedError : e?.value?.err}`,
})
}
const stringifiedError = tryStringify(e)
throw new MangoError({
txid: signature,
message: `${stringifiedError ? stringifiedError : e}`,
})
}
}
function isErrorWithSignatureResult(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
err: any,
): err is RpcResponseAndContext<SignatureResult> {
return err && typeof err.value !== 'undefined'
}