Transfer
After connecting a wallet, build a PTB that transfers SUI to the to address and execute it with useSignAndExecuteTransaction.
This example uses
devnet.
Live Editor
function Transfer() { const account = useCurrentAccount(); const { mutate: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction(); const { data: balance } = useSuiClientQuery('getBalance', { owner: account?.address ?? '' }, { enabled: !!account }); const [to, setTo] = useState(''); const [mist, setMist] = useState('1000000'); const [digest, setDigest] = useState(''); const [error, setError] = useState(''); if (!account) { return ( <div className="alert alert--info"> Connect your wallet first (top-right wallet icon). </div> ); } const hasValidTo = /^0x[0-9a-fA-F]+$/.test(to) && to.length >= 4; const hasValidAmount = /^[0-9]+$/.test(mist) && mist !== '0'; const canSubmit = hasValidTo && hasValidAmount && !isPending; return ( <div style={{ maxWidth: 980 }}> <div style={{ marginBottom: 10, fontSize: 12, fontWeight: 700, color: 'var(--ifm-color-emphasis-700)' }}> General </div> <div style={{ border: '1px solid var(--ifm-color-emphasis-300)', borderRadius: 12, padding: 16, background: 'var(--ifm-background-surface-color)', }} > <div className="row" style={{ rowGap: 12 }}> <div className="col col--3"> <div className="text--muted" style={{ fontSize: 12 }}> Network </div> <div style={{ fontWeight: 700 }}> <code>sui:devnet</code> </div> </div> <div className="col col--3"> <div className="text--muted" style={{ fontSize: 12 }}> Balance </div> <div style={{ fontWeight: 700 }}> {balance ? ( <> <code>{balance.totalBalance}</code> <span className="text--muted">mist</span> </> ) : ( <span className="text--muted">Loading…</span> )} </div> </div> <div className="col col--6"> <div className="text--muted" style={{ fontSize: 12 }}> From </div> <div style={{ wordBreak: 'break-all' }}> <code>{account.address}</code> </div> </div> </div> </div> <div className="margin-top--lg" style={{ marginBottom: 10, fontSize: 12, fontWeight: 700, color: 'var(--ifm-color-emphasis-700)' }}> Transaction Inputs </div> <div style={{ border: '1px solid var(--ifm-color-emphasis-300)', borderRadius: 12, padding: 16, background: 'var(--ifm-background-surface-color)', }} > <div className="row" style={{ rowGap: 16 }}> <div className="col col--8"> <label className="form-label" style={{ display: 'block' }}> <b>To address</b> </label> <input className="input input--lg" value={to} onChange={(e) => setTo(e.target.value.trim())} placeholder="0x..." /> {!to ? null : hasValidTo ? null : ( <div className="margin-top--xs text--danger" style={{ fontSize: 13 }}> Enter a valid 0x address. </div> )} </div> <div className="col col--4"> <label className="form-label" style={{ display: 'block' }}> <b>Amount (mist)</b> </label> <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}> <input className="input input--lg" value={mist} onChange={(e) => setMist(e.target.value.trim())} inputMode="numeric" /> <button type="button" className="button button--secondary button--sm" onClick={() => { if (!balance) return; setMist(String(balance.totalBalance)); }} disabled={!balance} > Max </button> </div> {!mist ? null : hasValidAmount ? null : ( <div className="margin-top--xs text--danger" style={{ fontSize: 13 }}> Amount must be a positive integer. </div> )} </div> </div> <div className="margin-top--lg" style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}> <button className="button button--warning button--lg" disabled={!canSubmit} onClick={() => { setError(''); setDigest(''); if (!hasValidTo) return; if (!hasValidAmount) return; const tx = new Transaction(); const [coin] = tx.splitCoins(tx.gas, [mist]); tx.transferObjects([coin], to); signAndExecuteTransaction( { transaction: tx, chain: 'sui:devnet' }, { onSuccess: (result) => setDigest(result.digest), onError: (e) => { const message = e?.message ?? String(e); if (message.includes('No valid gas coins found')) { setError( 'No gas coins found on Devnet for this address. Switch your wallet network to Devnet and request faucet SUI, then try again.', ); return; } setError(message); }, }, ); }} > {isPending ? 'Executing…' : 'Execute'} </button> <div style={{ flex: 1, minWidth: 260 }}> <div className="text--muted" style={{ fontSize: 12 }}> Result </div> {digest ? ( <div style={{ marginTop: 4, display: 'flex', gap: 10, alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap' }}> <code style={{ wordBreak: 'break-all' }}>{digest}</code> <a href={`https://suiexplorer.com/txblock/${digest}?network=devnet`} target="_blank" rel="noreferrer" style={{ fontWeight: 600, whiteSpace: 'nowrap' }} > Open </a> </div> ) : ( <div className="text--muted" style={{ fontSize: 13, marginTop: 4 }}> Result will appear here after execution. </div> )} </div> </div> </div> {error ? <div className="alert alert--danger margin-top--md">{error}</div> : null} </div> ); } render(<Transfer />);
Result
Loading...