Keys module
The keys module of Joystream SDK facilitates the management of keys and integrations with external signers.
Key features
- simplifies WalletConnect integration,
- uses
@polkadot/keyring
internally to manage the set of available keys, - provides a unified interface to access all available keys, regardless of their source (whether they are directly added to the Keyring, provided by WalletConnect or via other extensions)
- environment agnositc, works both in the browser and Node.js environments.
KeyManager class
KeyManager
is main class provided by the keys module.
Creating a new instance of KeyManager
is extemely simple:
import { KeyManager } from '@joystream/sdk-core/keys'
const keyManager = new KeyManager()
// Optionally, if you didn't call cryptoWaitReady() before:
await keyManager.ready()
You can also override the default Keyring configuration if you need:
const keyManager = new KeyManager({
keyringOptions: {
isDev: true, // Will import all dev accounts like //Alice, //Bob etc.
type: 'sr25519', // The default key type will be 'sr25519'
// ...
},
})
Adding keys directly
You can add new keys directly to KeyManager, similarly to how you would add them to a Keyring
instance:
// Add from mnemonic
keyManager.addKey({
mnemonic:
'bottom drive obey lake curtain smoke basket hold race lonely fit walk',
type: 'sr25519', // Would use the default type if not provided
meta: { name: 'Dev' }, // You can optionally add some metadata
})
// Add from SURI
keyManager.addKey({
suri: '//Alice',
// ...optionally other options can be provided as above
})
// Add from seed:
keyManager.addKey({
seed: '0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a',
// ...optionally other options can be provided as above
})
Using external providers
KeyManager allow you to add external key provides as long as they match the following interface:
interface KeyProvider {
signer?: Signer
getAccounts(): Promise<{ address: string }[]>
subscribeAccounts(cb: (keys: KeyInfo[] | undefined) => void): unknown
}
interface KeyInfo {
address: string
type?: KeyType
name?: string
}
This interface is compatible with some of the most popular packages for connecting wallets, such as:
It's also combatible with the WalletConnect
class that you can import from @joystream/sdk-core/keys/integrations/wallet-connect
(see WalletConnect integration).
To add a key provider which matches this interface to a KeyManager
you can simply call:
keyManager.addKeysProvider(PROVIDER_NAME, PROVIDER)
See WalletConnect integration for a more concrete example.
Retrieving keys
To retrieve all available keys from the KeyManager
you can use one of the following methods:
// Retrieve keys once:
const keys = keyManager.keys
// Subscribe keys:
const unsubscribe = keyManager.subscribeKeys((keys) => {
/* Do something with the keys */
})
The returned keys will match the following interface:
interface Key {
// Name of the provider specified during `.addKeysProvider`
// or 'internal' if the key was added directly to the Keyring
provider: string
// SS58 address of the key (uses the Joystream network prefix by default)
address: string
// Type of the key (if specified)
type?: 'ed25519' | 'sr25519'
// meta.name if specified
name?: string
}
WalletConnect integration
@joystream/sdk-core/keys
provides a WalletConnect
class to allow very easy integration with Wallet Connect.
See the minimal example below:
import { KeyManager } from '@joystream/sdk-core/keys'
import { UxHandler } from '@joystream/sdk-core/keys/integrations/wallet-connect/ux'
import { WalletConnect } from '@joystream/sdk-core/keys/integrations/wallet-connect'
const keyManager = new KeyManager()
await keyManager.ready()
// Specify the actions to take on connection request
// and (optionally) when the connection process is finalized.
const wxUxHandler: UxHandler = {
requestConnect: async (uri: string) => {
/* Show a QR code or allow the user to copy the WalletConnect uri manually */
},
onFinalized: async (uri: string) => {
/* For example: close the WalletConnect modal */
},
}
const walletConnect = new WalletConnect(
{
projectId: process.env.PROJECT_ID, // You must provide a valid PROJECT_ID here!
relayUrl: 'wss://relay.walletconnect.com',
},
wxUxHandler
)
await walletConnect.connect()
await keyManager.addKeysProvider('WalletConnect', walletConnect)
console.log(keyManager.keys)
For more concrete examples, see Example apps below.
Example apps
React
The example React app which uses @joystream/sdk-core/keys
module can be found in /examples/keys-react
.
To run the example locally you can execute the following steps:
git clone https://github.com/Joystream/sdk.git joystream-sdk
cd joystream-sdk
git checkout dev
yarn
cd examples/keys-react
yarn start
You should see a simple UI like this:
The example React app allows you to add keys using 3 different ways:
- using Talisman Connect, which supports most popular browser extensions / injected wallets, such as:
- Talisman
- SubWallet
- Nova Wallet
- Polkadot.js
- etc. (see full list here)
- using WalletConnect, which supports:
- Mobile / Desktop wallets such as:
- Subwallet
- Nova Wallet
- Tangem hardware wallet
- etc. (see full list here)
- Mobile / Desktop wallets such as:
- direcly to Keyring from:
- mnemonic
- seed
- SURI
You can verify the signing process by signing an example message using the Sign
button:
CLI
The example CLI app which uses @joystream/sdk-core/keys
module can be found in /examples/keys-cli
.
To run the example locally you can execute the following steps:
git clone https://github.com/Joystream/sdk.git joystream-sdk
cd joystream-sdk
git checkout dev
yarn
yarn run-example keys-cli