the Solana address from the wallet state or provider. In React framework:
// get address from wallet stateconst { walletState } =useTomo()constsolanaAddress=walletState.solanaAddress// or get address from providerconst { providers } =useTomo()constsolanaAddress=awaitproviders.solanaProvider.getAddress()
Or Pure JS:
/** pure js */import { getWalletState } from'@tomo-inc/tomo-web-sdk';// get from wallet stateconstwalletState=getWalletState()constsolanaAddress=walletState.solanaAddress// or get from providerconstsolanaAddress=awaitwindow.tomo_sol.getAddress()
Provider Functions
providers.solanaProvider exposes three functions for sending requests to the user's wallet:
Signing a Message
It uses the Solana provider to sign a plain text offchain message, which returns the signature of the given message with the message header.
Sign Transaction
Given a transaction in the format of Transaction from @solana/web3.js you can use signTransactionmethod to get the signed transaction in hex value if the user approves the request.
Send Transaction
You can also send the transaction directly through this sendTransaction method. The return value is the transaction signature if signed and sent correctly.
import bs58 from 'bs58'
// interface
signMessage(message: Uint8Array): Promise<Uint8Array>;
// example
const res = await solanaProvider.signMessage(new TextEncoder().encode('hello world'))
console.log('res:', bs58.encode(res))
// res:6EpGiRj6UMPWKZSNQoPsrpDxN9Mw25PmAtrWkD2V6wLZ5HLePPcwJV9DB3aCCeD2eEfW56NzuEkfXJHu2rgwhL7wweJeKJwrU7CoTvndykUPGkaM1mJb7N25NeyeUq7NBEFCNVt3LWPvDvVBmUMU88Vo6jTTjC4jPYnVsfZDrodsEx9
// interface
signTransaction<T extends Transaction>(transaction: T): Promise<Transaction>;
// example, see next session for definition of createSolTx
const transaction = await createSolTx(from, to, amount);
const res = await solanaProvider.signTransaction(transaction)
// interface
type TransactionSignature = string;
sendTransaction<T extends Transaction>(transaction: T, connection?: Connection): Promise<TransactionSignature>;
// example, see next session for definition of createSolTx
const connection = getConnection()
const transaction = await createSolTx(from, to, amount, mintAddress)
const signature = await solanaProvider.sendTransaction(transaction, connection)
import {
Connection,
PublicKey,
SystemProgram,
Transaction
} from '@solana/web3.js'
import {
createAssociatedTokenAccountInstruction,
createTransferInstruction,
getAccount,
getAssociatedTokenAddress,
TOKEN_PROGRAM_ID,
TokenAccountNotFoundError,
TokenInvalidAccountOwnerError
} from '@solana/spl-token'
import BigNumber from 'bignumber.js'
import { TomoContextProvider, useTomo } from '@tomo-inc/tomo-web-sdk'
import '@tomo-inc/tomo-web-sdk/style.css'
const solEndpoint = 'Your rpc endpoint'
const CLIENT_ID = 'Your client id'
// Get Sol Connection
function getConnection() {
const connection = new Connection(solEndpoint, 'recent')
return connection
}
// Get Sol Connection
let connection: Connection
function getConnection() {
if (!connection) {
connection = new Connection(solEndpoint, 'recent')
}
return connection
}
// create transaction
async function createSolTx(
fromAddress: string,
toAddress: string,
amount: number,
mintAddress?: string
) {
try {
const connection = getConnection()
const tx = new Transaction()
const fromPublicKey = new PublicKey(fromAddress)
const toPublicKey = new PublicKey(toAddress)
if (!tx.feePayer) {
tx.feePayer = fromPublicKey
}
if (mintAddress) {
const tokenPublicKey = new PublicKey(mintAddress)
const fromTokenPubKey = await getAssociatedTokenAddress(
tokenPublicKey,
new PublicKey(fromAddress)
)
const toTokenPubKey = await getAssociatedTokenAddress(
tokenPublicKey,
new PublicKey(toAddress)
)
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash
let account: any
try {
account = await getAccount(connection, toTokenPubKey)
} catch (error: unknown) {
if (
error instanceof TokenAccountNotFoundError ||
error instanceof TokenInvalidAccountOwnerError
) {
try {
tx.add(
createAssociatedTokenAccountInstruction(
fromPublicKey,
toTokenPubKey,
toPublicKey,
tokenPublicKey
)
)
} catch (error: unknown) {}
} else {
throw error
}
}
console.log('account', account)
tx.add(
createTransferInstruction(
fromTokenPubKey,
toTokenPubKey,
fromPublicKey,
amount,
[],
TOKEN_PROGRAM_ID
)
)
} else {
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash
tx.add(
SystemProgram.transfer({
fromPubkey: fromPublicKey,
toPubkey: toPublicKey,
lamports: amount
})
)
}
return tx
} catch (e) {
return null
}
}
enum Theme {
Light = 'light',
Dark = 'dark'
}
export default function SOLDemo() {
return (
<TomoContextProvider
theme={Theme.Light}
chainTypes={['solana']}
clientId={CLIENT_ID}
>
<App />
</TomoContextProvider>
)
}
function App() {
const { providers, walletState, openConnectModal } = useTomo()
const { solanaProvider } = providers
return (
<div style={{ display: 'flex', gap: '10px' }}>
<button onClick={openConnectModal}>openConnectModal</button>
<br />
<button
onClick={async () => {
const from = walletState.solanaAddress || ''
const to = 'xxx'
const decimals = 9
const amount = Number(new BigNumber(0.00001).shiftedBy(decimals))
const transaction = await createSolTx(from, to, amount)
if (!transaction) throw new Error('Failed to create transaction')
const res = await solanaProvider.signTransaction(transaction)
console.log('sign transaction res:', res)
// continue to send transaction
// const tx = await solanaProvider.sendTransaction(res)
// console.log('send transaction res:', tx)
}}
>
sign sol transaction
</button>
<br />
<button
onClick={async () => {
const from = walletState.solanaAddress || ''
const to = 'xxxx'
const usdtMintAddress = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
const decimals = 6
const amount = Number(new BigNumber(0.00001).shiftedBy(decimals))
const transaction = await createSolTx(from, to, amount, usdtMintAddress)
if (!transaction) throw new Error('Failed to create transaction')
const connection = getConnection()
const res = await solanaProvider.sendTransaction(transaction, connection)
console.log('send token transaction res:', res)
}}
>
send spl token transaction
</button>
</div>
)
}
import {
Connection,
PublicKey,
SystemProgram,
Transaction
} from '@solana/web3.js'
import {
createAssociatedTokenAccountInstruction,
createTransferInstruction,
getAccount,
getAssociatedTokenAddress,
TOKEN_PROGRAM_ID,
TokenAccountNotFoundError,
TokenInvalidAccountOwnerError
} from '@solana/spl-token'
import BigNumber from 'bignumber.js'
import { CLIENT_ID } from 'constant'
import { initTomoModal } from '@tomo-inc/tomo-web-sdk'
import '@tomo-inc/tomo-web-sdk/style.css'
const solEndpoint = 'Your rpc endpoint'
const CLIENT_ID = 'Your client id'
// Get Sol Connection
function getConnection() {
const connection = new Connection(solEndpoint, 'recent')
return connection
}
// Get Sol Connection
let connection: Connection
function getConnection() {
if (!connection) {
connection = new Connection(solEndpoint, 'recent')
}
return connection
}
// create transaction
async function createSolTx(
fromAddress: string,
toAddress: string,
amount: number,
mintAddress?: string
) {
// ...
}
enum Theme {
Light = 'light',
Dark = 'dark'
}
initTomoModal({
onConnect: (param) => {
console.log('onConnect', param)
},
theme: Theme.Light,
clientId: CLIENT_ID,
chainTypes: ['solana']
})
export default function SOLPureDemo() {
return (
<div style={{ display: 'flex', gap: '10px' }}>
<button
onClick={() => {
window.openTomoConnectModal?.()
}}
>
openTomoConnectModal
</button>
<button
onClick={async () => {
const solanaProvider = window.tomo_sol
if (!solanaProvider) return
const solanaAddress = await solanaProvider?.getAddress()
const from = solanaAddress || ''
const to = 'xxxx'
const decimals = 9
const amount = Number(new BigNumber(0.000001).shiftedBy(decimals))
const transaction = await createSolTx(from, to, amount)
if (!transaction) throw new Error('Failed to create transaction')
const res = await solanaProvider.signTransaction(transaction)
console.log('sign transaction res:', res)
}}
>
sign sol transaction
</button>
<button
onClick={async () => {
const solanaProvider = window.tomo_sol
if (!solanaProvider) return
const solanaAddress = await solanaProvider?.getAddress()
const from = solanaAddress || ''
const to = 'xxxx'
const usdtMintAddress = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
const decimals = 6
const amount = Number(new BigNumber(0.000001).shiftedBy(decimals))
const transaction = await createSolTx(from, to, amount, usdtMintAddress)
if (!transaction) throw new Error('Failed to create transaction')
const connection = getConnection()
const res = await solanaProvider.sendTransaction(transaction, connection)
console.log('send token transaction res:', res)
}}
>
send spl token transaction
</button>
</div>
)
}