diff --git a/apps/laboratory/src/components/Solana/SolanaSignAllTransactionsTest.tsx b/apps/laboratory/src/components/Solana/SolanaSignAllTransactionsTest.tsx
new file mode 100644
index 0000000000..e271cd0a32
--- /dev/null
+++ b/apps/laboratory/src/components/Solana/SolanaSignAllTransactionsTest.tsx
@@ -0,0 +1,136 @@
+import { useState } from 'react'
+import { Button, Stack, Text, Spacer } from '@chakra-ui/react'
+import {
+ PublicKey,
+ Transaction,
+ TransactionMessage,
+ VersionedTransaction,
+ SystemProgram
+} from '@solana/web3.js'
+
+import { useWeb3ModalAccount, useWeb3ModalProvider, type Provider } from '@web3modal/solana/react'
+
+import { solana } from '../../utils/ChainsUtil'
+import { useChakraToast } from '../Toast'
+import type { Connection } from '@web3modal/base/adapters/solana/web3js'
+import bs58 from 'bs58'
+
+const PHANTOM_DEVNET_ADDRESS = '8vCyX7oB6Pc3pbWMGYYZF5pbSnAdQ7Gyr32JqxqCy8ZR'
+const recipientAddress = new PublicKey(PHANTOM_DEVNET_ADDRESS)
+const amountInLamports = 1_000_000
+
+export function SolanaSignAllTransactionsTest() {
+ const toast = useChakraToast()
+ const { chainId } = useWeb3ModalAccount()
+ const { walletProvider, connection } = useWeb3ModalProvider()
+ const [loading, setLoading] = useState(false)
+
+ async function onSignTransaction(type: 'legacy' | 'versioned') {
+ try {
+ setLoading(true)
+ if (!walletProvider?.publicKey) {
+ throw Error('user is disconnected')
+ }
+
+ if (!connection) {
+ throw Error('no connection set')
+ }
+
+ const transactions = await Promise.all(
+ Array.from({ length: 5 }, () => createTransaction(walletProvider, connection, type))
+ )
+ const response = await walletProvider.signAllTransactions(transactions)
+
+ const description = response
+ .map(transaction => {
+ const signature =
+ transaction.signatures[0] instanceof Uint8Array
+ ? transaction.signatures[0]
+ : transaction.signatures[0]?.signature
+
+ if (!signature) {
+ throw Error('Empty signature')
+ }
+
+ return bs58.encode(signature)
+ })
+ .join('\n\n')
+
+ toast({
+ title: 'Success',
+ description,
+ type: 'success'
+ })
+ } catch (err) {
+ toast({
+ title: 'Error',
+ description: (err as Error).message,
+ type: 'error'
+ })
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ if (chainId === solana.chainId) {
+ return (
+
+ Switch to Solana Devnet or Testnet to test this feature
+
+ )
+ }
+
+ return (
+
+
+
+
+
+ )
+}
+
+async function createTransaction(
+ provider: Provider,
+ connection: Connection,
+ type: 'legacy' | 'versioned'
+) {
+ if (!provider.publicKey) {
+ throw Error('No public key found')
+ }
+
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash()
+
+ const instructions = [
+ SystemProgram.transfer({
+ fromPubkey: provider.publicKey,
+ toPubkey: recipientAddress,
+ lamports: amountInLamports
+ })
+ ]
+
+ if (type === 'legacy') {
+ return new Transaction({ feePayer: provider.publicKey, blockhash, lastValidBlockHeight }).add(
+ ...instructions
+ )
+ }
+
+ return new VersionedTransaction(
+ new TransactionMessage({
+ payerKey: provider.publicKey,
+ recentBlockhash: blockhash,
+ instructions
+ }).compileToV0Message()
+ )
+}
diff --git a/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx b/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx
index a189d5e985..f7b8ec5d60 100644
--- a/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx
+++ b/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx
@@ -1,5 +1,5 @@
import { useState } from 'react'
-import { Button, Stack, Text, Spacer, Link } from '@chakra-ui/react'
+import { Button, Stack, Text, Spacer } from '@chakra-ui/react'
import {
PublicKey,
Transaction,
@@ -12,6 +12,7 @@ import { useWeb3ModalAccount, useWeb3ModalProvider } from '@web3modal/solana/rea
import { solana } from '../../utils/ChainsUtil'
import { useChakraToast } from '../Toast'
+import bs58 from 'bs58'
const PHANTOM_DEVNET_ADDRESS = '8vCyX7oB6Pc3pbWMGYYZF5pbSnAdQ7Gyr32JqxqCy8ZR'
const recipientAddress = new PublicKey(PHANTOM_DEVNET_ADDRESS)
@@ -56,7 +57,7 @@ export function SolanaSignTransactionTest() {
toast({
title: 'Success',
- description: Uint8Array.from(signature),
+ description: bs58.encode(signature),
type: 'success'
})
} catch (err) {
@@ -108,7 +109,7 @@ export function SolanaSignTransactionTest() {
toast({
title: 'Success',
- description: signature,
+ description: bs58.encode(signature),
type: 'success'
})
} catch (err) {
@@ -147,12 +148,6 @@ export function SolanaSignTransactionTest() {
Sign Versioned Transaction
-
-
-
-
)
}
diff --git a/apps/laboratory/src/components/Solana/SolanaTests.tsx b/apps/laboratory/src/components/Solana/SolanaTests.tsx
index b940c1d24b..0414d51e28 100644
--- a/apps/laboratory/src/components/Solana/SolanaTests.tsx
+++ b/apps/laboratory/src/components/Solana/SolanaTests.tsx
@@ -17,6 +17,7 @@ import { SolanaSignMessageTest } from './SolanaSignMessageTest'
import { SolanaWriteContractTest } from './SolanaWriteContractTest'
import { solana, solanaDevnet, solanaTestnet } from '../../utils/ChainsUtil'
import { SolanaSignAndSendTransaction } from './SolanaSignAndSendTransactionTest'
+import { SolanaSignAllTransactionsTest } from './SolanaSignAllTransactionsTest'
export function SolanaTests() {
const { isConnected, currentChain } = useWeb3ModalAccount()
@@ -48,6 +49,18 @@ export function SolanaTests() {
+
+
+ Sign All Transactions
+
+
+ ℹ️
+
+
+
+
+
+
Sign and Send Transaction (Dapp)
diff --git a/packages/base/adapters/solana/web3js/providers/AuthProvider.ts b/packages/base/adapters/solana/web3js/providers/AuthProvider.ts
index 7c33a23dc7..682859159d 100644
--- a/packages/base/adapters/solana/web3js/providers/AuthProvider.ts
+++ b/packages/base/adapters/solana/web3js/providers/AuthProvider.ts
@@ -131,6 +131,31 @@ export class AuthProvider extends ProviderEventEmitter implements Provider, Prov
return signature
}
+ public async signAllTransactions(transactions: T): Promise {
+ const result = await this.provider.request({
+ method: 'solana_signAllTransactions',
+ params: {
+ transactions: transactions.map(transaction => this.serializeTransaction(transaction))
+ }
+ })
+
+ return (result.transactions as string[]).map((encodedTransaction, index) => {
+ const transaction = transactions[index]
+
+ if (!transaction) {
+ throw new Error('Invalid solana_signAllTransactions response')
+ }
+
+ const decodedTransaction = base58.decode(encodedTransaction)
+
+ if (isVersionedTransaction(transaction)) {
+ return VersionedTransaction.deserialize(decodedTransaction)
+ }
+
+ return Transaction.from(decodedTransaction)
+ }) as T
+ }
+
// -- W3mFrameProvider methods ------------------------------------------- //
connectEmail: ProviderAuthMethods['connectEmail'] = args => this.provider.connectEmail(args)
connectOtp: ProviderAuthMethods['connectOtp'] = args => this.provider.connectOtp(args)
diff --git a/packages/base/adapters/solana/web3js/providers/WalletConnectProvider.ts b/packages/base/adapters/solana/web3js/providers/WalletConnectProvider.ts
index 5acbc03418..cc12dc8b78 100644
--- a/packages/base/adapters/solana/web3js/providers/WalletConnectProvider.ts
+++ b/packages/base/adapters/solana/web3js/providers/WalletConnectProvider.ts
@@ -177,6 +177,12 @@ export class WalletConnectProvider extends ProviderEventEmitter implements Provi
return signature
}
+ public async signAllTransactions(transactions: T): Promise {
+ return (await Promise.all(
+ transactions.map(transaction => this.signTransaction(transaction))
+ )) as T
+ }
+
// -- Private ------------------------------------------ //
private request(
method: Method,
diff --git a/packages/base/adapters/solana/web3js/providers/WalletStandardProvider.ts b/packages/base/adapters/solana/web3js/providers/WalletStandardProvider.ts
index d91963fbdd..bba28eef2f 100644
--- a/packages/base/adapters/solana/web3js/providers/WalletStandardProvider.ts
+++ b/packages/base/adapters/solana/web3js/providers/WalletStandardProvider.ts
@@ -183,6 +183,35 @@ export class WalletStandardProvider extends ProviderEventEmitter implements Prov
return signature
}
+ public async signAllTransactions(transactions: T): Promise {
+ const feature = this.getWalletFeature(SolanaSignTransaction)
+
+ const account = this.getAccount(true)
+ const chain = this.getActiveChainName()
+
+ const result = await feature.signTransaction(
+ ...transactions.map(transaction => ({
+ transaction: this.serializeTransaction(transaction),
+ account,
+ chain
+ }))
+ )
+
+ return result.map(({ signedTransaction }, index) => {
+ const transaction = transactions[index]
+
+ if (!transaction) {
+ throw new WalletSignTransactionError('Invalid transaction signature response')
+ }
+
+ if (isVersionedTransaction(transaction)) {
+ return VersionedTransaction.deserialize(signedTransaction)
+ }
+
+ return Transaction.from(signedTransaction)
+ }) as T
+ }
+
// -- Private ------------------------------------------- //
private serializeTransaction(transaction: AnyTransaction) {
return transaction.serialize({ verifySignatures: false })
diff --git a/packages/base/adapters/solana/web3js/tests/AuthProvider.test.ts b/packages/base/adapters/solana/web3js/tests/AuthProvider.test.ts
index 4e9d3e397a..9da09a661f 100644
--- a/packages/base/adapters/solana/web3js/tests/AuthProvider.test.ts
+++ b/packages/base/adapters/solana/web3js/tests/AuthProvider.test.ts
@@ -134,4 +134,20 @@ describe('AuthProvider specific tests', () => {
expect(provider.switchNetwork).toHaveBeenCalledWith(newChain.chainId)
expect(listener).toHaveBeenCalledWith(newChain.chainId)
})
+
+ it('should call signAllTransactions with correct params', async () => {
+ await authProvider.connect()
+ const transactions = [mockLegacyTransaction(), mockVersionedTransaction()]
+ await authProvider.signAllTransactions(transactions)
+
+ expect(provider.request).toHaveBeenCalledWith({
+ method: 'solana_signAllTransactions',
+ params: {
+ transactions: [
+ 'AKhoybLLJS1deDJDyjELDNhfkBBX3k4dt4bBfmppjfPVVimhQdFEfDo8AiFcCBCC9VkYWV2r3jkh9n1DAXEhnJPwMmnsrx6huAVrhHAbmRUqfUuWZ9aWMGmdEWaeroCnPR6jkEnjJcn14a59TZhkiTXMygMqu4KaqD1TqzE8vNHSw3YgbW24cfqWfQczGysuy4ugxj4TGSpqRtNmf5D7zRRa76eJTeZEaBcBQGkqxb31vBRXDMdQzGEbq',
+ '48ckoQL1HhH5aqU1ifKqpQkwq3WPDgMnsHHQkVfddisxYcapwAVXr8hejTi2jeJpMPkZMsF72SwmJFDByyfRtaknz4ytCYNAcdHrxtrHa9hTjMKckVQrFFqS8zG63Wj5mJ6wPfj8dv1wKu2XkU6GSXSGdQmuvfRv3K6LUSMbK5XSP3yBGb1SDZKCuoFX4qDKcKhCG7Awn3ssAWB1yRaXMd6mS6HQHKSF11FTp3jTH2HKUNbKyyuGh4tYtq8b'
+ ]
+ }
+ })
+ })
})
diff --git a/packages/base/adapters/solana/web3js/tests/GenericProvider.test.ts b/packages/base/adapters/solana/web3js/tests/GenericProvider.test.ts
index 5811f21e2b..bdb619fa6f 100644
--- a/packages/base/adapters/solana/web3js/tests/GenericProvider.test.ts
+++ b/packages/base/adapters/solana/web3js/tests/GenericProvider.test.ts
@@ -9,6 +9,7 @@ import { Transaction, VersionedTransaction } from '@solana/web3.js'
import { mockLegacyTransaction, mockVersionedTransaction } from './mocks/Transaction.js'
import { AuthProvider } from '../providers/AuthProvider.js'
import { mockW3mFrameProvider } from './mocks/W3mFrameProvider.js'
+import { isVersionedTransaction } from '@solana/wallet-adapter-base'
const getActiveChain = vi.fn(() => TestConstants.chains[0])
@@ -99,4 +100,24 @@ describe.each(providers)('Generic provider tests for $name', ({ provider }) => {
expect(result).toBeTypeOf('string')
})
+
+ it('should signAllTransactions with AnyTransaction', async () => {
+ const transactions = [
+ mockLegacyTransaction(),
+ mockVersionedTransaction(),
+ mockLegacyTransaction(),
+ mockVersionedTransaction()
+ ]
+ const result = await provider.signAllTransactions(transactions)
+
+ expect(result).toHaveLength(transactions.length)
+
+ transactions.forEach((transaction, index) => {
+ if (isVersionedTransaction(transaction)) {
+ expect(result[index]).toBeInstanceOf(VersionedTransaction)
+ } else {
+ expect(result[index]).toBeInstanceOf(Transaction)
+ }
+ })
+ })
})
diff --git a/packages/base/adapters/solana/web3js/tests/WalletConnectProvider.test.ts b/packages/base/adapters/solana/web3js/tests/WalletConnectProvider.test.ts
index c0baa6b04c..1400a9460b 100644
--- a/packages/base/adapters/solana/web3js/tests/WalletConnectProvider.test.ts
+++ b/packages/base/adapters/solana/web3js/tests/WalletConnectProvider.test.ts
@@ -258,4 +258,75 @@ describe('WalletConnectProvider specific tests', () => {
'solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K'
)
})
+
+ it('should call signTransaction correctly for signAllTransactions', async () => {
+ await walletConnectProvider.connect()
+ const transactions = [mockLegacyTransaction(), mockVersionedTransaction()]
+ await walletConnectProvider.signAllTransactions(transactions)
+
+ expect(provider.request).toHaveBeenNthCalledWith(
+ 1,
+ {
+ method: 'solana_signTransaction',
+ params: {
+ feePayer: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP',
+ instructions: [
+ {
+ data: '3Bxs4NN8M2Yn4TLb',
+ keys: [
+ {
+ isSigner: true,
+ isWritable: true,
+ pubkey: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP'
+ },
+ {
+ isSigner: false,
+ isWritable: true,
+ pubkey: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP'
+ }
+ ],
+ programId: '11111111111111111111111111111111'
+ }
+ ],
+ recentBlockhash: 'EZySCpmzXRuUtM95P2JGv9SitqYph6Nv6HaYBK7a8PKJ',
+ transaction:
+ 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAECFj6WhBP/eepC4T4bDgYuJMiSVXNh9IvPWv1ZDUV52gYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMmaU6FiJxS/swxct+H8Iree7FERP/8vrGuAdF90ANelAQECAAAMAgAAAICWmAAAAAAA',
+ pubkey: TestConstants.accounts[0].address
+ }
+ },
+ 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
+ )
+ expect(provider.request).toHaveBeenNthCalledWith(
+ 2,
+ {
+ method: 'solana_signTransaction',
+ params: {
+ feePayer: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP',
+ instructions: [
+ {
+ data: '3Bxs4NN8M2Yn4TLb',
+ keys: [
+ {
+ isSigner: true,
+ isWritable: true,
+ pubkey: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP'
+ },
+ {
+ isSigner: true,
+ isWritable: true,
+ pubkey: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP'
+ }
+ ],
+ programId: '11111111111111111111111111111111'
+ }
+ ],
+ recentBlockhash: 'EZySCpmzXRuUtM95P2JGv9SitqYph6Nv6HaYBK7a8PKJ',
+ transaction:
+ 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABAhY+loQT/3nqQuE+Gw4GLiTIklVzYfSLz1r9WQ1FedoGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJmlOhYicUv7MMXLfh/CK3nuxRET//L6xrgHRfdADXpQEBAgAADAIAAACAlpgAAAAAAAA=',
+ pubkey: TestConstants.accounts[0].address
+ }
+ },
+ 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
+ )
+ })
})
diff --git a/packages/base/adapters/solana/web3js/tests/WalletStandardProvider.test.ts b/packages/base/adapters/solana/web3js/tests/WalletStandardProvider.test.ts
index 6209ca47ea..3fce944bb5 100644
--- a/packages/base/adapters/solana/web3js/tests/WalletStandardProvider.test.ts
+++ b/packages/base/adapters/solana/web3js/tests/WalletStandardProvider.test.ts
@@ -125,4 +125,17 @@ describe('WalletStandardProvider specific tests', () => {
walletStandardProvider.signAndSendTransaction(mockLegacyTransaction())
).rejects.toThrowError(WalletStandardFeatureNotSupportedError)
})
+
+ it('should call signTransaction with correct params for multiple transactions over singAllTransactions method', async () => {
+ const transactions = [mockLegacyTransaction(), mockVersionedTransaction()]
+ await walletStandardProvider.signAllTransactions(transactions)
+
+ expect(wallet.features[SolanaSignTransaction].signTransaction).toHaveBeenCalledWith(
+ ...transactions.map(transaction => ({
+ transaction: transaction.serialize({ verifySignatures: false }),
+ account: wallet.accounts[0],
+ chain: 'solana:mainnet'
+ }))
+ )
+ })
})
diff --git a/packages/base/adapters/solana/web3js/tests/mocks/W3mFrameProvider.ts b/packages/base/adapters/solana/web3js/tests/mocks/W3mFrameProvider.ts
index 586d0e38df..08b0e55626 100644
--- a/packages/base/adapters/solana/web3js/tests/mocks/W3mFrameProvider.ts
+++ b/packages/base/adapters/solana/web3js/tests/mocks/W3mFrameProvider.ts
@@ -8,8 +8,8 @@ export function mockW3mFrameProvider() {
w3mFrame.connect = vi.fn(() => Promise.resolve(mockSession()))
w3mFrame.disconnect = vi.fn(() => Promise.resolve(undefined))
- w3mFrame.request = vi.fn(({ method }: W3mFrameTypes.RPCRequest) => {
- switch (method) {
+ w3mFrame.request = vi.fn((request: W3mFrameTypes.RPCRequest) => {
+ switch (request.method) {
case 'solana_signMessage':
return Promise.resolve({
signature:
@@ -25,6 +25,14 @@ export function mockW3mFrameProvider() {
signature:
'2Lb1KQHWfbV3pWMqXZveFWqneSyhH95YsgCENRWnArSkLydjN1M42oB82zSd6BBdGkM9pE6sQLQf1gyBh8KWM2c4'
})
+ case 'solana_signAllTransactions':
+ return Promise.resolve({
+ transactions: Array.from({ length: request.params.transactions.length }).map(
+ () =>
+ '4zZMC2ddAFY1YHcA2uFCqbuTHmD1xvB5QLzgNnT3dMb4aQT98md8jVm1YRGUsKJkYkLPYarnkobvESUpjqEUnDmoG76e9cgNJzLuFXBW1i6njs2Sy1Lnr9TZmLnhif5CYjh1agVJEvjfYpTq1QbTnLS3rBt4yKVjQ6FcV3x22Vm3XBPqodTXz17o1YcHMcvYQbHZfVUyikQ3Nmv6ktZzWe36D6ceKCVBV88VvYkkFhwWUWkA5ErPvsHWQU64VvbtENaJXFUUnuqTFSX4q3ccHuHdmtnhWQ7Mv8Xkb'
+ )
+ })
+
default:
return Promise.reject(new Error('not implemented'))
}
diff --git a/packages/base/adapters/solana/web3js/tests/mocks/WalletStandard.ts b/packages/base/adapters/solana/web3js/tests/mocks/WalletStandard.ts
index 13fa9a91fa..89da7f495e 100644
--- a/packages/base/adapters/solana/web3js/tests/mocks/WalletStandard.ts
+++ b/packages/base/adapters/solana/web3js/tests/mocks/WalletStandard.ts
@@ -43,9 +43,9 @@ export function mockWalletStandard() {
'solana:signTransaction': {
version: '1.0.0',
supportedTransactionVersions: [0, 'legacy'],
- signTransaction: vi.fn(() =>
- Promise.resolve([
- {
+ signTransaction: vi.fn((...transactions: unknown[]) =>
+ Promise.resolve(
+ Array.from({ length: transactions.length }, () => ({
signedTransaction: new Uint8Array([
1, 195, 86, 227, 117, 63, 116, 76, 21, 3, 236, 37, 188, 235, 178, 151, 68, 192, 248,
193, 10, 232, 44, 63, 138, 193, 225, 213, 179, 76, 95, 250, 42, 74, 225, 195, 254,
@@ -62,8 +62,8 @@ export function mockWalletStandard() {
0, 0, 0, 0, 3, 0, 5, 2, 64, 13, 3, 0, 2, 2, 0, 1, 12, 2, 0, 0, 0, 128, 150, 152, 0,
0, 0, 0, 0
])
- }
- ])
+ }))
+ )
)
} satisfies SolanaSignTransactionFeature['solana:signTransaction'],
diff --git a/packages/scaffold-utils/src/solana/SolanaTypesUtil.ts b/packages/scaffold-utils/src/solana/SolanaTypesUtil.ts
index c65f6b376e..91df22a5de 100644
--- a/packages/scaffold-utils/src/solana/SolanaTypesUtil.ts
+++ b/packages/scaffold-utils/src/solana/SolanaTypesUtil.ts
@@ -56,6 +56,7 @@ export interface Provider extends ProviderEventEmitterMethods {
connection: Connection,
options?: SendTransactionOptions
) => Promise
+ signAllTransactions: (transactions: T) => Promise
}
export interface ProviderEventEmitterMethods {
diff --git a/packages/wallet/src/W3mFrameConstants.ts b/packages/wallet/src/W3mFrameConstants.ts
index 7185425f72..1a5323c9de 100644
--- a/packages/wallet/src/W3mFrameConstants.ts
+++ b/packages/wallet/src/W3mFrameConstants.ts
@@ -142,6 +142,7 @@ export const W3mFrameRpcConstants = {
'eth_sendTransaction',
'solana_signMessage',
'solana_signTransaction',
+ 'solana_signAllTransactions',
'solana_signAndSendTransaction',
'wallet_sendCalls',
'wallet_grantPermissions'
diff --git a/packages/wallet/src/W3mFrameSchema.ts b/packages/wallet/src/W3mFrameSchema.ts
index 776cbd4773..dd119b7cf0 100644
--- a/packages/wallet/src/W3mFrameSchema.ts
+++ b/packages/wallet/src/W3mFrameSchema.ts
@@ -326,6 +326,13 @@ export const RpcSolanaSignTransactionRequest = z.object({
})
})
+export const RpcSolanaSignAllTransactionsRequest = z.object({
+ method: z.literal('solana_signAllTransactions'),
+ params: z.object({
+ transactions: z.array(z.string())
+ })
+})
+
export const RpcSolanaSignAndSendTransactionRequest = z.object({
method: z.literal('solana_signAndSendTransaction'),
params: z.object({
@@ -503,6 +510,7 @@ export const W3mFrameSchema = {
.or(RpcEthSendTransactionRequest)
.or(RpcSolanaSignMessageRequest)
.or(RpcSolanaSignTransactionRequest)
+ .or(RpcSolanaSignAllTransactionsRequest)
.or(RpcSolanaSignAndSendTransactionRequest)
.or(WalletGetCallsReceiptRequest)
.or(WalletSendCallsRequest)
diff --git a/packages/wallet/src/W3mFrameTypes.ts b/packages/wallet/src/W3mFrameTypes.ts
index 2fef971b06..fa43cee93e 100644
--- a/packages/wallet/src/W3mFrameTypes.ts
+++ b/packages/wallet/src/W3mFrameTypes.ts
@@ -71,7 +71,8 @@ import {
WalletGrantPermissionsRequest,
RpcSolanaSignMessageRequest,
RpcSolanaSignTransactionRequest,
- RpcSolanaSignAndSendTransactionRequest
+ RpcSolanaSignAndSendTransactionRequest,
+ RpcSolanaSignAllTransactionsRequest
} from './W3mFrameSchema.js'
import type { W3mFrameRpcConstants } from './W3mFrameConstants.js'
import type { CaipNetworkId } from '@web3modal/common'
@@ -174,6 +175,7 @@ export namespace W3mFrameTypes {
| z.infer
| z.infer
| z.infer
+ | z.infer
| z.infer
| z.infer
| z.infer
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1f19e3ae94..d7d5d927bd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -66,7 +66,7 @@ importers:
version: 0.22.0(rollup@4.21.1)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.6))
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
apps/demo:
dependencies:
@@ -108,7 +108,7 @@ importers:
version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
wagmi:
specifier: 2.12.5
- version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
+ version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
zustand:
specifier: 4.5.2
version: 4.5.2(@types/react@18.2.62)(react@18.2.0)
@@ -374,7 +374,7 @@ importers:
version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
wagmi:
specifier: 2.12.5
- version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
+ version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
devDependencies:
'@types/node':
specifier: 20.11.5
@@ -510,7 +510,7 @@ importers:
version: 5.2.11(@types/node@20.11.5)(terser@5.31.6)
wagmi:
specifier: 2.12.5
- version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
+ version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
devDependencies:
'@types/react':
specifier: 18.2.62
@@ -651,7 +651,7 @@ importers:
version: 18.2.0
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
'@vue/runtime-core':
specifier: 3.4.3
version: 3.4.3
@@ -699,7 +699,7 @@ importers:
version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
vue:
specifier: 3.4.3
version: 3.4.3(typescript@5.3.3)
@@ -752,10 +752,10 @@ importers:
devDependencies:
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
packages/core:
dependencies:
@@ -771,13 +771,13 @@ importers:
devDependencies:
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
viem:
specifier: 2.19.6
version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
packages/ethers:
dependencies:
@@ -1037,13 +1037,13 @@ importers:
version: 5.1.5
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
'@walletconnect/types':
specifier: 2.14.0
version: 2.14.0
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
packages/ui:
dependencies:
@@ -1059,7 +1059,7 @@ importers:
version: 1.5.5
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
'@web3modal/common':
specifier: workspace:*
version: link:../common
@@ -1077,7 +1077,7 @@ importers:
version: 2.0.4(eslint@8.57.0)
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
packages/wagmi:
dependencies:
@@ -1123,7 +1123,7 @@ importers:
version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
vue:
specifier: 3.4.3
version: 3.4.3(typescript@5.3.3)
@@ -1148,13 +1148,13 @@ importers:
devDependencies:
'@vitest/coverage-v8':
specifier: 2.0.5
- version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))
+ version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))
jsdom:
specifier: 24.1.0
version: 24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
vitest:
specifier: 2.0.3
- version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
services/id-allocation-service:
dependencies:
@@ -19877,11 +19877,11 @@ snapshots:
std-env: 3.7.0
test-exclude: 6.0.0
v8-to-istanbul: 9.3.0
- vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
transitivePeerDependencies:
- supports-color
- '@vitest/coverage-v8@2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6))':
+ '@vitest/coverage-v8@2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6))':
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 0.2.3
@@ -19895,7 +19895,7 @@ snapshots:
std-env: 3.7.0
test-exclude: 7.0.1
tinyrainbow: 1.2.0
- vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6)
+ vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6)
transitivePeerDependencies:
- supports-color
@@ -20067,6 +20067,45 @@ snapshots:
- utf-8-validate
- zod
+ '@wagmi/connectors@5.1.5(@types/react@18.2.62)(@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)':
+ dependencies:
+ '@coinbase/wallet-sdk': 4.0.4
+ '@metamask/sdk': 0.27.0(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.0)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(utf-8-validate@5.0.10)
+ '@safe-global/safe-apps-provider': 0.18.3(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
+ '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
+ '@wagmi/core': 2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))
+ '@walletconnect/ethereum-provider': 2.14.0(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10)
+ '@walletconnect/modal': 2.6.2(@types/react@18.2.62)(react@18.2.0)
+ cbw-sdk: '@coinbase/wallet-sdk@3.9.3'
+ viem: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
+ optionalDependencies:
+ typescript: 5.3.3
+ transitivePeerDependencies:
+ - '@azure/app-configuration'
+ - '@azure/cosmos'
+ - '@azure/data-tables'
+ - '@azure/identity'
+ - '@azure/keyvault-secrets'
+ - '@azure/storage-blob'
+ - '@capacitor/preferences'
+ - '@netlify/blobs'
+ - '@planetscale/database'
+ - '@react-native-async-storage/async-storage'
+ - '@types/react'
+ - '@upstash/redis'
+ - '@vercel/kv'
+ - bufferutil
+ - encoding
+ - ioredis
+ - react
+ - react-dom
+ - react-native
+ - rollup
+ - supports-color
+ - uWebSockets.js
+ - utf-8-validate
+ - zod
+
'@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.0)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))':
dependencies:
eventemitter3: 5.0.1
@@ -27784,7 +27823,7 @@ snapshots:
fsevents: 2.3.3
terser: 5.31.6
- vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.6):
+ vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.6):
dependencies:
'@ampproject/remapping': 2.3.0
'@vitest/expect': 2.0.3
@@ -27909,6 +27948,43 @@ snapshots:
- utf-8-validate
- zod
+ wagmi@2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4):
+ dependencies:
+ '@tanstack/react-query': 5.24.8(react@18.2.0)
+ '@wagmi/connectors': 5.1.5(@types/react@18.2.62)(@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)
+ '@wagmi/core': 2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))
+ react: 18.2.0
+ use-sync-external-store: 1.2.0(react@18.2.0)
+ viem: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)
+ optionalDependencies:
+ typescript: 5.3.3
+ transitivePeerDependencies:
+ - '@azure/app-configuration'
+ - '@azure/cosmos'
+ - '@azure/data-tables'
+ - '@azure/identity'
+ - '@azure/keyvault-secrets'
+ - '@azure/storage-blob'
+ - '@capacitor/preferences'
+ - '@netlify/blobs'
+ - '@planetscale/database'
+ - '@react-native-async-storage/async-storage'
+ - '@tanstack/query-core'
+ - '@types/react'
+ - '@upstash/redis'
+ - '@vercel/kv'
+ - bufferutil
+ - encoding
+ - immer
+ - ioredis
+ - react-dom
+ - react-native
+ - rollup
+ - supports-color
+ - uWebSockets.js
+ - utf-8-validate
+ - zod
+
walker@1.0.8:
dependencies:
makeerror: 1.0.12