Skip to content

Commit

Permalink
Use legacy transactions with Ledger until supported upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Nov 30, 2022
1 parent b9e022f commit 783c334
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
Expand Up @@ -97,13 +97,13 @@ export const wrapCommand = (command) => {
if (!lastValidBlockHeight) {
throw new Error('Block not found. Could not generate message data')
}
const tx = utils.makeTx({
const tx = utils.makeLegacyTx({
instructions: rawTxs,
recentBlockhash: blockhash,
payerKey: signer,
})

const msgData = Buffer.from(tx.serialize()).toString('base64')
const msgData = Buffer.from(tx.serializeMessage()).toString('base64')
logger.line()
logger.success(`Message generated with blockhash ID: ${blockhash.toString()}). MESSAGE DATA:`)
logger.log()
Expand Down
55 changes: 39 additions & 16 deletions gauntlet/packages/gauntlet-solana/src/commands/internal/solana.ts
Expand Up @@ -10,13 +10,15 @@ import {
TransactionConfirmationStatus,
SimulatedTransactionResponse,
TransactionExpiredBlockheightExceededError,
Transaction,
VersionedTransaction,
} from '@solana/web3.js'
import { withProvider, withWallet, withNetwork } from '../middlewares'
import { TransactionResponse } from '../types'
import { ProgramError, parseIdlErrors, Idl, Program, AnchorProvider } from '@project-serum/anchor'
import { SolanaWallet } from '../wallet'
import { LedgerWallet, SolanaWallet } from '../wallet'
import { logger } from '@chainlink/gauntlet-core/dist/utils'
import { makeTx } from '../../lib/utils'
import { makeLegacyTx, makeTx } from '../../lib/utils'

/**
* If transaction is not confirmed by validators in 152 blocks
Expand Down Expand Up @@ -119,22 +121,43 @@ export default abstract class SolanaCommand extends WriteCommand<TransactionResp

const currentBlockhash = await this.provider.connection.getLatestBlockhash()

const tx = makeTx(
{
instructions: rawTxs,
recentBlockhash: currentBlockhash.blockhash,
payerKey: this.wallet.publicKey,
},
overrides,
)
if (extraSigners) {
tx.sign(extraSigners)
}
const signedTx = await this.wallet.signVersionedTransaction(tx)
logger.loading('Sending tx...')
let tx: Transaction | VersionedTransaction
let rawTransaction: Uint8Array

const rawTransaction = signedTx.serialize()
// Workaround until Ledger supports v0 transactions
if (this.wallet instanceof LedgerWallet) {
tx = makeLegacyTx(
{
instructions: rawTxs,
recentBlockhash: currentBlockhash.blockhash,
payerKey: this.wallet.publicKey,
},
overrides,
)
if (extraSigners) {
tx.sign(...extraSigners)
}
const signedTx = await this.wallet.signTransaction(tx)

rawTransaction = signedTx.serialize()
} else {
tx = makeTx(
{
instructions: rawTxs,
recentBlockhash: currentBlockhash.blockhash,
payerKey: this.wallet.publicKey,
},
overrides,
)
if (extraSigners) {
tx.sign(extraSigners)
}
const signedTx = await this.wallet.signVersionedTransaction(tx)

rawTransaction = signedTx.serialize()
}

logger.loading('Sending tx...')
const txid = await this.provider.connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
Expand Down
20 changes: 20 additions & 0 deletions gauntlet/packages/gauntlet-solana/src/lib/utils.ts
Expand Up @@ -4,6 +4,7 @@ import {
ComputeBudgetProgram,
TransactionMessageArgs,
TransactionInstruction,
Transaction,
} from '@solana/web3.js'

export const makeTx = (
Expand All @@ -23,3 +24,22 @@ export const makeTx = (
const messageV0 = new TransactionMessage(args).compileToV0Message()
return new VersionedTransaction(messageV0)
}

// TODO: Remove once Ledger supports VersionedTransaction (https://github.com/LedgerHQ/app-solana/pull/48)
export const makeLegacyTx = (
args: TransactionMessageArgs,
overrides: { price?: number; units?: number } = {},
): Transaction => {
if (overrides.price && overrides.units)
throw new Error('Cannot set limit for units and price in the same transaction')

let computeIx: TransactionInstruction
if (overrides.price) computeIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: overrides.price })
if (overrides.units) computeIx = ComputeBudgetProgram.setComputeUnitLimit({ units: overrides.units })
if (computeIx) {
args.instructions.unshift(computeIx)
}

let tx = args.instructions.reduce((tx, ix) => tx.add(ix), new Transaction())
return tx
}

0 comments on commit 783c334

Please sign in to comment.