Skip to content

Commit

Permalink
feat: solana sign and send transaction (#664)
Browse files Browse the repository at this point in the history
* feat: add solana signAndSendTransaction function

* refactor: remove blockhash param

* feat: add signAndSendTransaction options and confirmation

* fix: remove unnecessary extra condition
  • Loading branch information
zoruka committed Aug 6, 2024
1 parent 2bfb822 commit 5fc7b7b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 6 deletions.
9 changes: 5 additions & 4 deletions advanced/wallets/react-wallet-v2/src/data/SolanaData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const SOLANA_MAINNET_CHAINS = {
name: 'Solana',
logo: '/chain-logos/solana-5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp.png',
rgb: '30, 240, 166',
rpc: '',
rpc: 'https://api.mainnet-beta.solana.com',
namespace: 'solana'
}
}
Expand All @@ -41,15 +41,15 @@ export const SOLANA_TEST_CHAINS = {
name: 'Solana Devnet',
logo: '/chain-logos/solana-5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp.png',
rgb: '30, 240, 166',
rpc: '',
rpc: 'https://api.devnet.solana.com',
namespace: 'solana'
},
'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': {
chainId: '4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',
name: 'Solana Testnet',
logo: '/chain-logos/solana-5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp.png',
rgb: '30, 240, 166',
rpc: '',
rpc: 'https://api.testnet.solana.com',
namespace: 'solana'
}
}
Expand All @@ -61,5 +61,6 @@ export const SOLANA_CHAINS = { ...SOLANA_MAINNET_CHAINS, ...SOLANA_TEST_CHAINS }
*/
export const SOLANA_SIGNING_METHODS = {
SOLANA_SIGN_TRANSACTION: 'solana_signTransaction',
SOLANA_SIGN_MESSAGE: 'solana_signMessage'
SOLANA_SIGN_MESSAGE: 'solana_signMessage',
SOLANA_SIGN_AND_SEND_TRANSACTION: 'solana_signAndSendTransaction'
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export default function useWalletConnectEventsManager(initialized: boolean) {

case SOLANA_SIGNING_METHODS.SOLANA_SIGN_MESSAGE:
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_TRANSACTION:
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_AND_SEND_TRANSACTION:
return ModalStore.open('SessionSignSolanaModal', { requestEvent, requestSession })

case POLKADOT_SIGNING_METHODS.POLKADOT_SIGN_MESSAGE:
Expand Down
58 changes: 57 additions & 1 deletion advanced/wallets/react-wallet-v2/src/lib/SolanaLib.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { Keypair } from '@solana/web3.js'
import {
Keypair,
Connection,
Transaction,
TransactionInstruction,
PublicKey,
SendOptions
} from '@solana/web3.js'
import bs58 from 'bs58'
import nacl from 'tweetnacl'
import SolanaWallet, { SolanaSignTransaction } from 'solana-wallet'
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'

/**
* Types
Expand Down Expand Up @@ -58,4 +66,52 @@ export default class SolanaLib {

return { signature }
}

public async signAndSendTransaction(
feePayer: SolanaSignTransaction['feePayer'],
instructions: SolanaSignTransaction['instructions'],
chainId: string,
options: SendOptions = {}
) {
const rpc = { ...SOLANA_TEST_CHAINS, ...SOLANA_MAINNET_CHAINS }[chainId]?.rpc

if (!rpc) {
throw new Error('There is no RPC URL for the provided chain')
}

const connection = new Connection(rpc)

const parsedInstructions = instructions.map(instruction => {
const keys = instruction.keys.map(key => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable
}))
const programId = new PublicKey(instruction.programId)
const data =
typeof instruction.data === 'string'
? Buffer.from(bs58.decode(instruction.data).buffer)
: instruction.data

return new TransactionInstruction({
keys,
programId,
data
})
})

const transaction = new Transaction().add(...parsedInstructions)
transaction.feePayer = new PublicKey(feePayer)
transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash
transaction.sign(this.keypair)

const signature = await connection.sendRawTransaction(transaction.serialize())
const confirmation = await connection.confirmTransaction(signature, options.preflightCommitment)

if (confirmation.value.err) {
throw new Error(confirmation.value.err.toString())
}

return { signature }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export async function approveSolanaRequest(
requestEvent: SignClientTypes.EventArguments['session_request']
) {
const { params, id } = requestEvent
const { request } = params
const { request, chainId } = params
const wallet = solanaWallets[getWalletAddressFromParams(solanaAddresses, params)]

switch (request.method) {
Expand All @@ -26,6 +26,16 @@ export async function approveSolanaRequest(

return formatJsonRpcResult(id, signedTransaction)

case SOLANA_SIGNING_METHODS.SOLANA_SIGN_AND_SEND_TRANSACTION:
const signedAndSentTransaction = await wallet.signAndSendTransaction(
request.params.feePayer,
request.params.instructions,
chainId,
request.params.options
)

return formatJsonRpcResult(id, signedAndSentTransaction)

default:
throw new Error(getSdkError('INVALID_METHOD').message)
}
Expand Down

0 comments on commit 5fc7b7b

Please sign in to comment.