Methods
WaaP for Sui exposes standard features via the Sui Wallet Standard, plus WaaP-specific methods. You can use either dapp-kit hooks (recommended) or the WaaP's features directly.
Accessing the wallet
You need a reference to the WaaP Sui wallet to call methods. Two common patterns:
From the Wallet Standard registry
Use this when you need the standard Wallet object (e.g. for connect({ wallet }) or wallet.features['sui:switchChain']):
import { getWallets } from '@mysten/wallet-standard'
const wallets = getWallets().get()
const waapWallet = wallets.find((w) => w.name === 'WaaP')
if (waapWallet) {
// Pass to useConnectWallet for programmatic connect
connect({ wallet: waapWallet })
// Use Wallet Standard features directly
await waapWallet.features['sui:switchChain']?.switchChain({ chain: 'sui:testnet' })
// Connect first, then use accounts (e.g. for signing)
const { accounts } = await waapWallet.features['standard:connect']?.connect()
const [account] = accounts ?? []
}
From your app's provider setup
If you followed Quick Start: Sui, you exposed a method via getWaaPSuiWallet() in Providers:
import { getWaaPSuiWallet } from './Providers'
const wallet = getWaaPSuiWallet()
if (wallet) {
// WaaP-specific: request user's verified email (opens consent UI)
const email = await wallet.requestEmail()
// Wallet Standard: switch network
await wallet.features['sui:switchChain']?.switchChain({ chain: 'sui:testnet' })
// Wallet Standard: sign a message (need an account from wallet.accounts)
const [account] = wallet.accounts
if (account && wallet.features['sui:signPersonalMessage']) {
const result = await wallet.features['sui:signPersonalMessage'].signPersonalMessage({
message: new TextEncoder().encode('Hello, WaaP!'),
account,
})
console.log('Signature:', result.signature)
}
}
Wallet Standard methods
WaaP supports these Wallet Standard features:
| Feature | Description |
|---|---|
standard:connect | Connect the wallet and get accounts |
standard:disconnect | Disconnect the wallet |
standard:events | Subscribe to account/chain changes |
sui:signPersonalMessage | Sign a personal message |
sui:signTransaction | Sign a transaction (no execution) |
sui:signAndExecuteTransaction | Sign and execute a transaction |
sui:switchChain | Switch active network |
sui:signTransactionBlock | Legacy: sign transaction block |
sui:signAndExecuteTransactionBlock | Legacy: sign and execute transaction block |
In most apps you use dapp-kit hooks (useConnectWallet, useSignPersonalMessage, etc.); for more control you can call wallet.features['sui:...'] directly.
connect & disconnect
Connecting and disconnecting are usually handled by the ConnectButton from @mysten/dapp-kit. To connect or disconnect programmatically:
import { useConnectWallet, useDisconnectWallet } from '@mysten/dapp-kit'
import { getWallets } from '@mysten/wallet-standard'
function ConnectActions() {
const { mutate: connect } = useConnectWallet()
const { mutate: disconnect } = useDisconnectWallet()
const waapWallet = getWallets().get().find((w) => w.name === 'WaaP')
const handleConnect = () => {
if (waapWallet) {
connect({ wallet: waapWallet })
}
}
return (
<div>
<button onClick={handleConnect}>Connect WaaP</button>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
)
}
switchChain
Switch the wallet's active network. Supported chains: sui:mainnet, sui:testnet, sui:devnet, sui:localnet.
Using the wallet features API:
import { getWallets } from '@mysten/wallet-standard'
const wallets = getWallets().get()
const wallet = wallets.find((w) => w.name === 'WaaP')
if (wallet?.features['sui:switchChain']) {
await wallet.features['sui:switchChain'].switchChain({ chain: 'sui:testnet' })
}
With @mysten/dapp-kit (recommended when using dapp-kit so the app's network context stays in sync):
import { useCurrentWallet, useSuiClientContext } from '@mysten/dapp-kit'
export function NetworkSwitcher() {
const { currentWallet } = useCurrentWallet()
const ctx = useSuiClientContext()
const switchToTestnet = async () => {
if (!currentWallet?.features['sui:switchChain']) return
await currentWallet.features['sui:switchChain'].switchChain({ chain: 'sui:testnet' })
ctx.selectNetwork('testnet')
}
return <button onClick={switchToTestnet}>Switch to Testnet</button>
}
See Networks for full configuration and examples.
sui:signPersonalMessage
Sign a personal message. The user approves in the WaaP modal.
With @mysten/dapp-kit:
import { useSignPersonalMessage } from '@mysten/dapp-kit'
export function SignMessage() {
const { mutate: signPersonalMessage } = useSignPersonalMessage()
const handleSign = () => {
signPersonalMessage(
{ message: new TextEncoder().encode('Hello, WaaP!') },
{
onSuccess: (result) => console.log('Signature:', result.signature),
onError: (err) => console.error('Sign failed', err),
},
)
}
return <button onClick={handleSign}>Sign Message</button>
}
For the standard API and more options, see Sign Messages.
sui:signTransaction
Sign a transaction without submitting it for execution. Returns the signed transaction and signature to your app so you can submit or broadcast it yourself (e.g. for batching or custom RPC). The user approves in the WaaP modal.
With @mysten/dapp-kit:
import { useSignTransaction } from '@mysten/dapp-kit'
import { Transaction } from '@mysten/sui/transactions'
export function SignOnly() {
const { mutate: signTransaction } = useSignTransaction()
const sign = () => {
const tx = new Transaction()
const [coin] = tx.splitCoins(tx.gas, [1000])
tx.transferObjects([coin], '0xRecipientAddress...')
signTransaction(
{ transaction: tx },
{
onSuccess: (result) => {
console.log('Signed transaction:', result.signature)
// Submit result via your own client if needed
},
onError: (err) => console.error('Sign failed', err),
},
)
}
return <button onClick={sign}>Sign transaction</button>
}
sui:signAndExecuteTransaction
Sign a transaction and submit it for execution. The user approves in the WaaP modal.
With @mysten/dapp-kit:
import { useSignAndExecuteTransaction } from '@mysten/dapp-kit'
import { Transaction } from '@mysten/sui/transactions'
export function SendSui() {
const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction()
const send = () => {
const tx = new Transaction()
const [coin] = tx.splitCoins(tx.gas, [1000])
tx.transferObjects([coin], '0xRecipientAddress...')
signAndExecuteTransaction(
{ transaction: tx },
{
onSuccess: (result) => console.log('Digest:', result.digest),
onError: (err) => console.error('Tx failed', err),
},
)
}
return <button onClick={send}>Send 1000 MIST</button>
}
sui:signTransactionBlock (legacy)
Legacy version of sui:signTransaction. Signs a transaction block without executing it. Use this when integrating with older Sui SDKs or APIs that expect the "transaction block" naming.
With @mysten/dapp-kit:
import { useSignTransactionBlock } from '@mysten/dapp-kit'
import { Transaction } from '@mysten/sui/transactions'
export function SignTransactionBlock() {
const { mutate: signTransactionBlock } = useSignTransactionBlock()
const sign = () => {
const tx = new Transaction()
const [coin] = tx.splitCoins(tx.gas, [1000])
tx.transferObjects([coin], '0xRecipientAddress...')
signTransactionBlock(
{ transactionBlock: tx },
{
onSuccess: (result) => console.log('Signed:', result.signature),
onError: (err) => console.error('Sign failed', err),
},
)
}
return <button onClick={sign}>Sign transaction block</button>
}
sui:signAndExecuteTransactionBlock (legacy)
Legacy version of sui:signAndExecuteTransaction. Signs and executes a transaction block. Use when your code or dependencies still use the "transaction block" API.
With @mysten/dapp-kit:
import { useSignAndExecuteTransactionBlock } from '@mysten/dapp-kit'
import { Transaction } from '@mysten/sui/transactions'
export function ExecuteTransactionBlock() {
const { mutate: signAndExecuteTransactionBlock } = useSignAndExecuteTransactionBlock()
const send = () => {
const tx = new Transaction()
const [coin] = tx.splitCoins(tx.gas, [1000])
tx.transferObjects([coin], '0xRecipientAddress...')
signAndExecuteTransactionBlock(
{ transactionBlock: tx },
{
onSuccess: (result) => console.log('Digest:', result.digest),
onError: (err) => console.error('Tx failed', err),
},
)
}
return <button onClick={send}>Send 1000 MIST</button>
}
For the standard (features) API and full details, see Transactions.
standard:events
Subscribe to account and chain changes via the wallet's on method. The 'change' event fires when the wallet's accounts or connection state change (e.g. user connects, disconnects, or switches account).
Basic subscription and cleanup:
import { getWallets } from '@mysten/wallet-standard'
const wallets = getWallets().get()
const wallet = wallets.find((w) => w.name === 'WaaP')
if (wallet?.features['standard:events']) {
const { on } = wallet.features['standard:events']
// Subscribe: callback receives { accounts } (and possibly other fields)
const unsubscribe = on('change', ({ accounts }) => {
console.log('Accounts changed:', accounts)
const primary = accounts[0]
if (primary) {
console.log('Primary account:', primary.address)
} else {
console.log('Wallet disconnected')
}
})
// Later: remove the listener (e.g. on component unmount)
unsubscribe()
}
In a React component (with cleanup):
import { useEffect } from 'react'
import { getWallets } from '@mysten/wallet-standard'
function useWaapAccountChange(callback: (accounts: readonly { address: string }[]) => void) {
useEffect(() => {
const wallets = getWallets().get()
const wallet = wallets.find((w) => w.name === 'WaaP')
if (!wallet?.features['standard:events']) return
const { on } = wallet.features['standard:events']
const unsubscribe = on('change', ({ accounts }) => callback(accounts))
return () => unsubscribe()
}, [callback])
}
When using dapp-kit, you can also rely on useCurrentAccount() and useSuiClientContext() to react to account and network changes.
WaaP-specific methods
requestEmail
Requests the user's verified email address. This is a WaaP-only feature: the wallet shows a consent UI and returns the email only if the user approves.
- Returns:
Promise<string>— the user's email, or throws if the user declines or an error occurs. - Use case: Onboarding, notifications, account recovery, or personalized UX without a separate auth flow.
import { getWaaPSuiWallet } from './Providers'
const wallet = getWaaPSuiWallet()
if (wallet) {
try {
const email = await wallet.requestEmail()
console.log('User email:', email)
} catch (error) {
console.log('Email not shared or error:', error)
}
}
This triggers a prompt in the WaaP wallet interface; the user can approve or decline. Only call requestEmail after the user has connected with WaaP (not with another wallet from the list).
Summary
| Need | Approach |
|---|---|
| Connect / disconnect | ConnectButton or useConnectWallet / useDisconnectWallet |
| Current account | useCurrentAccount() from dapp-kit |
| Switch network | wallet.features['sui:switchChain'].switchChain({ chain }) or dapp-kit + useSuiClientContext() |
| Sign message | useSignPersonalMessage() or Sign Messages |
| Sign & execute tx | useSignAndExecuteTransaction() or Transactions |
| User email (WaaP only) | getWaaPSuiWallet()?.requestEmail() |
For full setup and provider wiring, see Setup & Initialization.