Overview
SubWallet provides multiple functions for retrieving and managing user accounts. These functions allow you to get all accounts, subscribe to account changes, and find specific extension instances for signing operations.
All account management functions require web3Enable() to be called first. See web3Enable for details.
web3Accounts
Retrieve all accounts from all enabled extensions.
Function Signature
function web3Accounts (
options ?: Web3AccountsOptions
) : Promise < InjectedAccountWithMeta []>
Source Code Reference
packages/extension-dapp/src/bundle.ts:114
Parameters
Optional configuration object for filtering and formatting accounts. Show Web3AccountsOptions properties
The SS58 format to use for encoding Substrate addresses. If specified, all Substrate addresses will be re-encoded using this format. Common values:
0 - Polkadot
2 - Kusama
42 - Generic Substrate
Filter accounts by type. Only accounts matching the specified types will be returned. Possible values:
'sr25519' - Substrate Schnorrkel accounts
'ed25519' - Substrate Ed25519 accounts
'ecdsa' - ECDSA accounts
'ethereum' - Ethereum accounts
Return Value
accounts
InjectedAccountWithMeta[]
Array of accounts with metadata. Each account contains: Show InjectedAccountWithMeta properties
The account address (encoded according to ss58Format if specified)
Metadata about the account The name of the extension providing this account (e.g., “subwallet-js”)
The user-defined name for this account
The genesis hash of the chain this account is associated with, or null for generic accounts
The cryptographic key type of the account (sr25519, ed25519, ecdsa, ethereum, etc.)
Usage Examples
Basic Usage
import { web3Enable , web3Accounts } from '@subwallet/extension-dapp' ;
// First, enable the extension
await web3Enable ( 'My DApp' );
// Get all accounts
const accounts = await web3Accounts ();
console . log ( `Found ${ accounts . length } accounts` );
accounts . forEach ( account => {
console . log ( ` ${ account . meta . name } : ${ account . address } ` );
});
Filter by Account Type
import { web3Accounts } from '@subwallet/extension-dapp' ;
// Get only Ethereum accounts
const ethereumAccounts = await web3Accounts ({
accountType: [ 'ethereum' ]
});
// Get Substrate accounts (sr25519 and ed25519)
const substrateAccounts = await web3Accounts ({
accountType: [ 'sr25519' , 'ed25519' ]
});
import { web3Accounts } from '@subwallet/extension-dapp' ;
// Get accounts with Polkadot address format
const polkadotAccounts = await web3Accounts ({
ss58Format: 0
});
// Get accounts with Kusama address format
const kusamaAccounts = await web3Accounts ({
ss58Format: 2
});
React Hook Example
import { useState , useEffect } from 'react' ;
import { web3Enable , web3Accounts } from '@subwallet/extension-dapp' ;
function useAccounts () {
const [ accounts , setAccounts ] = useState ([]);
const [ loading , setLoading ] = useState ( true );
useEffect (() => {
async function loadAccounts () {
await web3Enable ( 'My DApp' );
const allAccounts = await web3Accounts ();
setAccounts ( allAccounts );
setLoading ( false );
}
loadAccounts ();
}, []);
return { accounts , loading };
}
// Usage in component
function AccountSelector () {
const { accounts , loading } = useAccounts ();
if ( loading ) return < div > Loading accounts... </ div > ;
return (
< select >
{ accounts . map ( account => (
< option key = { account . address } value = { account . address } >
{ account . meta . name || account . address }
</ option >
)) }
</ select >
);
}
web3AccountsSubscribe
Subscribe to account changes across all extensions. This is useful for keeping your UI in sync when users add, remove, or modify accounts in SubWallet.
Function Signature
function web3AccountsSubscribe (
callback : ( accounts : InjectedAccountWithMeta []) => void | Promise < void >,
options ?: Web3AccountsOptions
) : Promise < Unsubcall >
Source Code Reference
packages/extension-dapp/src/bundle.ts:146
Parameters
callback
(accounts: InjectedAccountWithMeta[]) => void | Promise<void>
required
Function called whenever accounts change. Receives the updated list of accounts as a parameter. Can be synchronous or asynchronous (return a Promise).
Same options as web3Accounts() for filtering and formatting.
Return Value
A function to call when you want to stop receiving updates. Call this function to unsubscribe from account changes. type Unsubcall = () => void ;
Usage Examples
Basic Subscription
import { web3Enable , web3AccountsSubscribe } from '@subwallet/extension-dapp' ;
await web3Enable ( 'My DApp' );
const unsubscribe = await web3AccountsSubscribe (( accounts ) => {
console . log ( `Accounts updated: ${ accounts . length } accounts` );
accounts . forEach ( account => {
console . log ( ` - ${ account . meta . name } : ${ account . address } ` );
});
});
// Later, when you want to stop listening
unsubscribe ();
React Hook with Subscription
import { useState , useEffect } from 'react' ;
import { web3Enable , web3AccountsSubscribe } from '@subwallet/extension-dapp' ;
function useAccountSubscription () {
const [ accounts , setAccounts ] = useState ([]);
useEffect (() => {
let unsubscribe ;
async function subscribe () {
await web3Enable ( 'My DApp' );
unsubscribe = await web3AccountsSubscribe ( setAccounts );
}
subscribe ();
// Cleanup: unsubscribe when component unmounts
return () => {
if ( unsubscribe ) {
unsubscribe ();
}
};
}, []);
return accounts ;
}
// Usage
function App () {
const accounts = useAccountSubscription ();
return (
< div >
< h2 > Active Accounts ( { accounts . length } ) </ h2 >
< ul >
{ accounts . map ( account => (
< li key = { account . address } >
{ account . meta . name || 'Unnamed' } - { account . address }
</ li >
)) }
</ ul >
</ div >
);
}
import { web3AccountsSubscribe } from '@subwallet/extension-dapp' ;
const unsubscribe = await web3AccountsSubscribe (
( accounts ) => {
// Update your UI with Polkadot-formatted addresses
updateAccountList ( accounts );
},
{ ss58Format: 0 } // Polkadot format
);
web3FromSource
Get the injected extension instance for a specific source (extension name). This is useful when you need to access the signer or other features of a specific extension.
Function Signature
function web3FromSource (
source : string
) : Promise < InjectedExtension >
Source Code Reference
packages/extension-dapp/src/bundle.ts:183
Parameters
The name of the extension source (e.g., “subwallet-js”). This value comes from the meta.source property of accounts.
Return Value
The extension instance containing accounts, signer, and other interfaces. See web3Enable return value for the complete structure.
Usage Examples
Get Extension by Source
import { web3Enable , web3FromSource } from '@subwallet/extension-dapp' ;
await web3Enable ( 'My DApp' );
try {
const extension = await web3FromSource ( 'subwallet-js' );
console . log ( `Found extension: ${ extension . name } v ${ extension . version } ` );
// Access the signer
const signer = extension . signer ;
// Use signer for transactions...
} catch ( error ) {
console . error ( 'Extension not found:' , error );
}
web3FromAddress
Get the injected extension instance that manages a specific address. This is the most common way to get a signer for transaction signing.
Function Signature
function web3FromAddress (
address : string
) : Promise < InjectedExtension >
Source Code Reference
packages/extension-dapp/src/bundle.ts:199
Parameters
The account address to look up. Can be in any valid SS58 format - the function will decode and compare addresses correctly.
Return Value
The extension instance that manages this address. Contains the signer needed for transaction signing.
Usage Examples
Basic Usage
import { web3Enable , web3Accounts , web3FromAddress } from '@subwallet/extension-dapp' ;
import { ApiPromise , WsProvider } from '@polkadot/api' ;
// Initialize
await web3Enable ( 'My DApp' );
const accounts = await web3Accounts ();
const selectedAddress = accounts [ 0 ]. address ;
// Get the injected extension for this address
const injected = await web3FromAddress ( selectedAddress );
// Connect to blockchain
const api = await ApiPromise . create ({
provider: new WsProvider ( 'wss://rpc.polkadot.io' )
});
// Create and sign a transaction
const transfer = api . tx . balances . transfer (
'DESTINATION_ADDRESS' ,
12345
);
await transfer . signAndSend (
selectedAddress ,
{ signer: injected . signer },
({ status }) => {
if ( status . isInBlock ) {
console . log ( `Transaction included in block` );
}
}
);
Complete Transaction Example
import { web3Enable , web3FromAddress } from '@subwallet/extension-dapp' ;
import { ApiPromise , WsProvider } from '@polkadot/api' ;
async function sendTransaction ( fromAddress , toAddress , amount ) {
try {
// Enable extension
await web3Enable ( 'My DApp' );
// Get the signer for this address
const injected = await web3FromAddress ( fromAddress );
// Connect to chain
const api = await ApiPromise . create ({
provider: new WsProvider ( 'wss://rpc.polkadot.io' )
});
// Create transaction
const transfer = api . tx . balances . transfer ( toAddress , amount );
// Sign and send
const hash = await transfer . signAndSend (
fromAddress ,
{ signer: injected . signer }
);
console . log ( 'Transaction hash:' , hash . toHex ());
return hash ;
} catch ( error ) {
console . error ( 'Transaction failed:' , error );
throw error ;
}
}
// Usage
await sendTransaction (
'SENDER_ADDRESS' ,
'RECIPIENT_ADDRESS' ,
1000000000000 // 1 DOT (10 decimals)
);
With Error Handling
import { web3FromAddress } from '@subwallet/extension-dapp' ;
async function getSignerForAddress ( address ) {
try {
const injected = await web3FromAddress ( address );
return injected . signer ;
} catch ( error ) {
if ( error . message . includes ( 'Unable to find injected' )) {
console . error ( 'This address is not managed by any extension' );
// Show error to user
} else {
console . error ( 'Unexpected error:' , error );
}
return null ;
}
}
Type Definitions
interface InjectedAccountWithMeta {
address : string ;
meta : {
genesisHash ?: string | null ;
name ?: string ;
source : string ;
};
type ?: KeypairType ;
}
Source: packages/extension-inject/src/types.ts:21
Web3AccountsOptions
interface Web3AccountsOptions {
ss58Format ?: number ;
accountType ?: KeypairType [];
}
Source: packages/extension-inject/src/types.ts:131
KeypairType
type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum' ;
Best Practices
Cache Account Lists : Use web3AccountsSubscribe() instead of repeatedly calling web3Accounts() to keep your account list up to date efficiently.
Address Format Consistency : If your dApp uses a specific chain, always request accounts with the appropriate ss58Format to ensure address display consistency.
Always Check for Accounts : After calling web3Accounts(), always check if the array is empty. Users might not have any accounts created yet.
Source Names : The meta.source property identifies which extension manages an account. For SubWallet, this is typically “subwallet-js”.
See Also