UNPKG

sui-svelte-wallet-kit

Version:

Svelte 5 wallet kit for Sui: connect wallets, manage accounts, SuiNS, balance, sign transactions/messages

139 lines (138 loc) 6.03 kB
import { fromBase64 } from '@mysten/sui/utils'; const normalizeSignedTx = (res) => { if (!res) throw new Error('Empty signTransaction result'); const sig = res?.signature; const b = res?.bytes; if (typeof sig !== 'string' || !sig) throw new Error('Missing signature'); if (b instanceof Uint8Array) return { signature: sig, bytes: b }; if (typeof b === 'string' && b) return { signature: sig, bytes: fromBase64(b) }; const legacy = res?.transactionBlockBytes; if (typeof legacy === 'string' && legacy) return { signature: sig, bytes: fromBase64(legacy) }; throw new Error('Missing bytes'); }; export const signAndExecuteTransaction = async (transaction, session, zkLoginGoogle) => { session.ensureCallable(); const acct = session.getAccount(); if (!acct) throw new Error('No account connected'); const chain = Array.isArray(acct?.chains) && acct.chains[0] ? acct.chains[0] : session.getChain(zkLoginGoogle); try { if (transaction && typeof transaction.setSender === 'function') { transaction.setSender(acct.address); } } catch { } const walletAdapter = session.getAdapter(); if (typeof walletAdapter?.signAndExecuteTransaction === 'function') { return await walletAdapter.signAndExecuteTransaction({ account: acct, chain, transaction }); } const featTx = walletAdapter?.features?.['sui:signAndExecuteTransaction']; if (featTx && typeof featTx.signAndExecuteTransaction === 'function') { return await featTx.signAndExecuteTransaction({ account: acct, chain, transaction }); } const featTxB = walletAdapter?.features?.['sui:signAndExecuteTransactionBlock']; if (featTxB && typeof featTxB.signAndExecuteTransactionBlock === 'function') { return await featTxB.signAndExecuteTransactionBlock({ account: acct, chain, transactionBlock: transaction }); } throw new Error('This wallet does not support signAndExecuteTransaction.'); }; export const signTransaction = async (transaction, options = {}, session, zkLoginGoogle) => { session.ensureCallable(); const acct = session.getAccount(); if (!acct) throw new Error('No account connected'); const chain = Array.isArray(acct?.chains) && acct.chains[0] ? acct.chains[0] : session.getChain(zkLoginGoogle); try { const sender = typeof options?.sender === 'string' && options.sender ? options.sender : acct.address; if (transaction && typeof transaction.setSender === 'function') { transaction.setSender(sender); } } catch { } const walletAdapter = session.getAdapter(); if (typeof walletAdapter?.signTransaction === 'function') { return normalizeSignedTx(await walletAdapter.signTransaction({ account: acct, chain, transaction })); } const feat = walletAdapter?.features?.['sui:signTransaction']; if (feat && typeof feat.signTransaction === 'function') { return normalizeSignedTx(await feat.signTransaction({ account: acct, chain, transaction })); } throw new Error('This wallet does not support signTransaction.'); }; export const signMessage = async (message, session, zkLoginGoogle) => { session.ensureCallable(); const messageBytes = typeof message === 'string' ? new TextEncoder().encode(message) : message; const acct = session.getAccount(); if (!acct) throw new Error('No account connected'); const chain = Array.isArray(acct?.chains) && acct.chains[0] ? acct.chains[0] : session.getChain(zkLoginGoogle); const walletAdapter = session.getAdapter(); const featMsg = walletAdapter?.features?.['sui:signMessage']; if (featMsg && typeof featMsg.signMessage === 'function') { const result = await featMsg.signMessage({ account: acct, chain, message: messageBytes }); return { signature: result.signature, messageBytes: Array.from(messageBytes) .map((b) => b.toString(16).padStart(2, '0')) .join('') }; } const featPersonal = walletAdapter?.features?.['sui:signPersonalMessage']; if (featPersonal && typeof featPersonal.signPersonalMessage === 'function') { const result = await featPersonal.signPersonalMessage({ account: acct, chain, message: messageBytes }); return { signature: result.signature, messageBytes: Array.from(messageBytes) .map((b) => b.toString(16).padStart(2, '0')) .join('') }; } if (walletAdapter && typeof walletAdapter.signPersonalMessage === 'function') { const result = await walletAdapter.signPersonalMessage({ account: acct, message: messageBytes }); return { signature: result.signature, messageBytes: Array.from(messageBytes) .map((b) => b.toString(16).padStart(2, '0')) .join('') }; } throw new Error('This wallet does not support message signing. Please try a different wallet or use signAndExecuteTransaction instead.'); }; export const canSignMessage = (session) => { const status = session.getStatus(); const walletAdapter = session.getAdapter(); if (status !== 'connected' || !walletAdapter) { return false; } return ((walletAdapter.features && walletAdapter.features['sui:signMessage'] && typeof walletAdapter.features['sui:signMessage'].signMessage === 'function') || (walletAdapter.features && walletAdapter.features['sui:signPersonalMessage'] && typeof walletAdapter.features['sui:signPersonalMessage'].signPersonalMessage === 'function') || typeof walletAdapter.signMessage === 'function' || typeof walletAdapter.signPersonalMessage === 'function'); };