Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: solana walletconnect rpc interface #2677

Merged
merged 11 commits into from
Aug 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import {
Transaction,
TransactionMessage,
VersionedTransaction,
SystemProgram,
Connection
SystemProgram
} from '@solana/web3.js'

import { solana } from '../../utils/ChainsUtil'
import { useChakraToast } from '../Toast'

const PHANTOM_TESTNET_ADDRESS = '8vCyX7oB6Pc3pbWMGYYZF5pbSnAdQ7Gyr32JqxqCy8ZR'
const recipientAddress = new PublicKey(PHANTOM_TESTNET_ADDRESS)
const amountInLamports = 100000000
const amountInLamports = 10_000_000

export function SolanaSendTransactionTest() {
const toast = useChakraToast()
Expand Down Expand Up @@ -53,7 +52,8 @@ export function SolanaSendTransactionTest() {

transaction.recentBlockhash = blockhash

const signature = await walletProvider.sendTransaction(transaction, connection as Connection)
const signature = await walletProvider.sendTransaction(transaction, connection)

toast({
title: 'Success',
description: signature,
Expand Down Expand Up @@ -106,10 +106,7 @@ export function SolanaSendTransactionTest() {
// Make a versioned transaction
const transactionV0 = new VersionedTransaction(messageV0)

const signature = await walletProvider.sendTransaction(
transactionV0,
connection as Connection
)
const signature = await walletProvider.sendTransaction(transactionV0, connection)

toast({
title: 'Success',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { useState } from 'react'
import { Button, Stack, Text, Spacer, Link } from '@chakra-ui/react'
import { useWeb3ModalAccount, useWeb3ModalProvider } from '@web3modal/solana/react'
import { PublicKey, Transaction, SystemProgram } from '@solana/web3.js'
import {
PublicKey,
Transaction,
SystemProgram,
TransactionMessage,
VersionedTransaction
} from '@solana/web3.js'

import { solana } from '../../utils/ChainsUtil'
import { useChakraToast } from '../Toast'

const PHANTOM_TESTNET_ADDRESS = '8vCyX7oB6Pc3pbWMGYYZF5pbSnAdQ7Gyr32JqxqCy8ZR'
const recipientAddress = new PublicKey(PHANTOM_TESTNET_ADDRESS)
const amountInLamports = 50000000
const amountInLamports = 10_000_000

export function SolanaSignAndSendTransaction() {
const toast = useChakraToast()
const { address, chainId } = useWeb3ModalAccount()
const { walletProvider, connection } = useWeb3ModalProvider()
const [loading, setLoading] = useState(false)

async function onSendTransaction() {
async function onSendTransaction(mode: 'legacy' | 'versioned') {
try {
setLoading(true)
if (!walletProvider || !address) {
Expand All @@ -32,16 +38,34 @@ export function SolanaSignAndSendTransaction() {
throw Error('Not enough SOL in wallet')
}

// Create a new transaction
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: walletProvider.publicKey,
toPubkey: recipientAddress,
lamports: amountInLamports
})
)
transaction.feePayer = walletProvider.publicKey
const signature = await walletProvider.signAndSendTransaction(transaction)
const instruction = SystemProgram.transfer({
fromPubkey: walletProvider.publicKey,
toPubkey: recipientAddress,
lamports: amountInLamports
})
const { blockhash } = await connection.getLatestBlockhash()

let signature = ''

if (mode === 'versioned') {
// Create v0 compatible message
const messageV0 = new TransactionMessage({
payerKey: walletProvider.publicKey,
recentBlockhash: blockhash,
instructions: [instruction]
}).compileToV0Message()

// Make a versioned transaction
const versionedTranasction = new VersionedTransaction(messageV0)

signature = await walletProvider.signAndSendTransaction(versionedTranasction)
} else {
// Create a new transaction
const transaction = new Transaction().add(instruction)
transaction.feePayer = walletProvider.publicKey
transaction.recentBlockhash = blockhash
signature = await walletProvider.signAndSendTransaction(transaction)
}

toast({
title: 'Success',
Expand Down Expand Up @@ -75,11 +99,18 @@ export function SolanaSignAndSendTransaction() {
<Stack direction={['column', 'column', 'row']}>
<Button
data-test-id="sign-transaction-button"
onClick={onSendTransaction}
onClick={() => onSendTransaction('legacy')}
isDisabled={loading}
>
Sign and Send Transaction
</Button>
<Button
data-test-id="sign-transaction-button"
onClick={() => onSendTransaction('versioned')}
isDisabled={loading}
>
Sign and Send Versioned Transaction
</Button>
<Spacer />

<Link isExternal href="https://solfaucet.com/">
Expand Down
14 changes: 2 additions & 12 deletions apps/laboratory/src/components/Solana/SolanaSignMessageTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,15 @@ export function SolanaSignMessageTest() {
const encodedMessage = new TextEncoder().encode('Hello from Web3Modal')
const signature = await walletProvider.signMessage(encodedMessage)

// Backpack has specific signature format now
if ((signature as { signature: Uint8Array }).signature) {
toast({
title: ConstantsUtil.SigningSucceededToastTitle,
description: (signature as { signature: Uint8Array }).signature,
type: 'success'
})

return
}
toast({
title: ConstantsUtil.SigningSucceededToastTitle,
description: signature as Uint8Array,
description: signature,
type: 'success'
})
} catch (err) {
toast({
title: ConstantsUtil.SigningFailedToastTitle,
description: 'Failed to sign message',
description: (err as Error).message,
type: 'error'
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useChakraToast } from '../Toast'

const PHANTOM_DEVNET_ADDRESS = '8vCyX7oB6Pc3pbWMGYYZF5pbSnAdQ7Gyr32JqxqCy8ZR'
const recipientAddress = new PublicKey(PHANTOM_DEVNET_ADDRESS)
const amountInLamports = 100000000
const amountInLamports = 10_000_000

export function SolanaSignTransactionTest() {
const toast = useChakraToast()
Expand Down Expand Up @@ -46,18 +46,23 @@ export function SolanaSignTransactionTest() {
const { blockhash } = await connection.getLatestBlockhash()

transaction.recentBlockhash = blockhash
const tx = await walletProvider.signTransaction(transaction)
const signature = tx.signatures[0]?.signature

const signedTransaction = await walletProvider.signTransaction(transaction)
const signature = signedTransaction.signatures[0]?.signature

if (!signature) {
throw Error('Failed to sign transaction')
}

toast({
title: 'Success',
description: signature,
description: Uint8Array.from(signature),
type: 'success'
})
} catch (err) {
toast({
title: 'Error',
description: 'Failed to sign transaction',
description: (err as Error).message,
type: 'error'
})
} finally {
Expand Down Expand Up @@ -94,8 +99,12 @@ export function SolanaSignTransactionTest() {
// Make a versioned transaction
const transactionV0 = new VersionedTransaction(messageV0)

const tx = await walletProvider.signTransaction(transactionV0)
const signature = tx.signatures[0]?.signature
const signedTransaction = await walletProvider.signTransaction(transactionV0)
const signature = signedTransaction.signatures[0]

if (!signature) {
throw Error('Failed to sign transaction')
}

toast({
title: 'Success',
Expand Down
15 changes: 13 additions & 2 deletions apps/laboratory/src/components/Solana/SolanaTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
CardBody,
Box,
Stack,
Text
Text,
Tooltip
} from '@chakra-ui/react'

import { SolanaSignTransactionTest } from './SolanaSignTransactionTest'
Expand Down Expand Up @@ -49,13 +50,23 @@ export function SolanaTests() {
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Sign and Send Transaction (dApp)
Sign and Send Transaction (Dapp)
<Tooltip label="The transaction will be signed by the Wallet, returned to the Dapp and the Dapp will send the transaction into the network">
<Text as="span" fontSize="sm" ml="2">
zoruka marked this conversation as resolved.
Show resolved Hide resolved
ℹ️
</Text>
</Tooltip>
</Heading>
<SolanaSendTransactionTest />
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Sign and Send Transaction (Wallet)
<Tooltip label="The transaction will be sent for the Wallet to be signed and sent into the network">
<Text as="span" fontSize="sm" ml="2">
ℹ️
</Text>
</Tooltip>
</Heading>
<SolanaSignAndSendTransaction />
</Box>
Expand Down
4 changes: 2 additions & 2 deletions packages/solana/exports/react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Web3Modal } from '../src/client.js'
import { SolStoreUtil } from '../src/utils/scaffold/index.js'

import type { Web3ModalOptions } from '../src/client.js'
import type { Provider } from '../src/utils/scaffold/index.js'
import type { Connection, Provider } from '../src/utils/scaffold/index.js'

// -- Setup -------------------------------------------------------------------
let modal: Web3Modal | undefined = undefined
Expand All @@ -36,7 +36,7 @@ export function useWeb3ModalProvider() {
return {
walletProvider: provider as Provider,
walletProviderType: providerType,
connection
connection: connection as Connection
}
}

Expand Down
18 changes: 6 additions & 12 deletions packages/solana/src/connectors/baseConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { SolConstantsUtil, SolStoreUtil } from '../utils/scaffold/index.js'
import { getHashedName, getNameAccountKey } from '../utils/hash.js'
import { NameRegistry } from '../utils/nameService.js'

import type { SendOptions, TransactionSignature } from '@solana/web3.js'

import type {
BlockResult,
AccountInfo,
Expand All @@ -26,7 +24,8 @@ import type {
FilterObject,
RequestMethods,
TransactionArgs,
TransactionType
TransactionType,
Provider
} from '../utils/scaffold/index.js'

export interface Connector {
Expand All @@ -36,15 +35,10 @@ export interface Connector {
getConnectorName: () => string
disconnect: () => Promise<void>
connect: () => Promise<string>
signMessage: (message: Uint8Array) => Promise<string>
signTransaction: (
transaction: Transaction | VersionedTransaction
) => Promise<{ signatures: { signature: string }[] }>
sendTransaction: (transaction: Transaction | VersionedTransaction) => Promise<string>
signAndSendTransaction: (
transaction: Transaction | VersionedTransaction,
options?: SendOptions
) => Promise<TransactionSignature>
signMessage: Provider['signMessage']
signTransaction: Provider['signTransaction']
signAndSendTransaction: Provider['signAndSendTransaction']
sendTransaction: Provider['sendTransaction']
zoruka marked this conversation as resolved.
Show resolved Hide resolved
getAccount: (
requestedAddress?: string,
encoding?: 'base58' | 'base64' | 'jsonParsed'
Expand Down
Loading
Loading