---
title: 'Trust Wallet Documentation'
---
# Trust Wallet Documentation - MPC Module and MPC Slice
</br>
## Table of Contents
[TOC]
</br>
## Introduction
</br>
Switching from Existing SeedPhrase Wallet Setup to MPC + SeedPhrase Wallet Setup requires changes in
- UIKit library
- Handler Changes
- Redux Store Changes
- Popup Changes to accomodate new components
Data flow example of MPC Wallet
```sequence
Onboarding->Home: 1st Share - OAuth Social Login
Onboarding->Home: Save 2nd Share in Device
Onboarding->Home: Optional 3rd Share
Home->Security Settings: Additional Share Setup
Home->Security Settings: Password Setup for ease of use
Home -> Onboarding: Remove Wallet
Unlock -> Home: Unlock to reconstruct factors
```
</br>
## Manifest and Package changes
:::info
**Manifest Changes**
:::
> **Permissions**
app/build/manifest/chromeV3.js
Changed permissions to include identity
ref: https://developer.chrome.com/docs/extensions/reference/identity/
Identity API will help us in all OAuth Logins (Google, Discord, Telegram)
> **Key**
Key will help us having a consistent Chrome extension URL.
This value can be used to control the unique ID of an extension, app, or theme when it is loaded during development
This will help us decide constant redirect URL once OAuth login is done.
> Changes
```json=
{
"key": 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyOOw2NA/nBW/71mdOkrKdxV+NM+VE4hHNwX5UHruT6j/I2+D2tPRP58Qq1mE+RjbWUzcqOZHA9uGWIP3jeXYhwEmu7Fos3C3DiZjtEWis1xm74izPRYBnPO6y5/WKniq117hvY+G91RfYx8IdUVmfkNJqtNaNvQDK2k2Qv1FZMIDktQwcn5GImTcrnzpXmHrCu3YvQ3+XO5tQ4NC0yODWNKdBL6cVDNyFpnBLv+l5Td9YNZW/gSjMzQPZihkc9Qu9aF0Qzq0YZw7EigQb3TqD9sREFBCgXlakTGh3hkrfvb3n2m04lLhf5BAiKB34lO5K5rI72SRTINBPoSOnMLvNQIDAQAB',
"permissions": [
'alarms',
'tabs',
'storage',
'clipboardWrite',
'notifications',
'identity',
'scripting',
],
}
```
:::info
**Package.json Changes**
:::
```json=
{
"@tkey/common-types": "8.0.0-alpha.0",
"@tkey/core": "8.0.4-alpha.0",
"@tkey/default": "8.0.4-alpha.0",
"@tkey/security-questions": "8.0.0-alpha.0",
"@tkey/service-provider-base": "8.0.0-alpha.0",
"@tkey/service-provider-torus": "8.0.0-alpha.0",
"@tkey/share-serialization": "8.0.0-alpha.0",
"@tkey/share-transfer": "8.0.0-alpha.0",
"@tkey/storage-layer-torus": "8.0.0-alpha.0",
"@toruslabs/customauth": "11.4.2-alpha.3",
"@toruslabs/eccrypto": "~1.1.8",
"@toruslabs/eth-sig-util": "~5.0.2",
"@toruslabs/rss-client": "~1.3.0",
"@toruslabs/torus.js": "6.2.0-alpha.1",
"@toruslabs/tss-client": "1.2.7-alpha.0",
"@toruslabs/tss-lib": "1.2.1",
"bn.js": "~5.2.1",
"bowser": "~2.11.0",
"copy-to-clipboard": "~3.3.3",
"eccrypto": "~1.1.6",
"elliptic": "~6.5.4",
"jwt-decode": "~3.1.2",
"keccak256": "~1.0.6",
"react-phone-number-input": "^3.2.19",
}
```
All **@tkey** packages are used for **share and factor key management** durning onboarding, settings and recovery flow
@toruslabs/tss-client, @toruslabs/tss-lib, @toruslabs/eth-sig-util, @toruslabs/rss-client packages are used for **signing transactions**
</br>
## Handler Changes
> Main handler changes
app/src/background/v2/main.ts
Added two new modules to existing list of modules
- `MPCModule` - All MPC related stuff to create, update, read MPC wallet
- `MPCVaultModule` - Vault Management for MPC Wallet: to encrypt the MPC states for better security
## MPC & MPC Vault Modules
| Handler name | Functioanlity | Flow |
| -------- | -------- | -------- |
| MPCOAuthShare| Social Login(First Share) | Onboarding/ Relogin |
| DeviceShare | Device Local Storage Share(Second Share) | Onboarding |
| MpcRecoveryShare | Manual Paper/Pen & Email Seed Phrase Share(Additional Share) | Onboarding/ Verification of New Device |
| MPCSendOTP | Mobile OTP Share(Additional Share) | Onboarding/ Verification of New Device |
| CreateMpcWallet | Creation of MPC Wallet | Onboarding/ Verification of New Device |
| MPCPassword | Password Setup for MPC Wallet | Security and Relogin Flow |
| MPCSigning | Transaction and Message Signing | Transaction |
| MPCLogout | Reset MPC wallet state | Logout |
<br>
### `MPCOAuthShare`

`verifier details - developer dashboard`
https://dashboard.web3auth.io/
```json =
{
google: {
name: 'google',
typeOfLogin: 'google',
verifier: 'w3a-trust-google',
clientId: '774338308167-q463s7kpvja16l4l0kko3nb925ikds2p.apps.googleusercontent.com',
},
apple: {
name: 'apple',
typeOfLogin: 'jwt',
clientId: '4rTyicWotSjIEHcXi9GaovEmJpqlQRUK',
redirect_uri: chromeRedirectUrl,
verifier: 'w3a-trust-apple',
jwtParams: {
domain: 'https://web3auth.au.auth0.com/',
connection: 'apple',
verifierIdField: 'email',
},
},
discord: {
name: 'discord',
typeOfLogin: 'discord',
clientId: '993506120276648017',
verifier: 'w3a-trust-discord',
// verifierIdentifier: 'email',
},
telegram: {
name: 'telegram',
typeOfLogin: 'telegram',
clientId: '6008080200',
verifier: 'w3a-trust-telegram',
jwtParams: {
domain: 'https://oauth.telegram.org/auth',
verifierIdField: 'sub',
},
}
}
```
`Trigger Points`
- will be called during onboarding process and unlock using social provider flows
Torus node details
metadata
- where metadata about social logins and other shares are stored
- metadata url - https://sapphire-1.auth.network/metadata
Every social handlers will have
`setFinalUrl()` - to get the authentication url according to a social provider
`getUserInfo()` - used to get user info with auth or id token after successfull login
`social handlers`:
- `Discord` - /mpc/handlers/OAuthhandler/DiscordHandler.ts
- `Google` - /mpc/handlers/OAuthhandler/GoogleHandler.ts
- `Telegram ` - /mpc/handlers/OAuthhandler/TelegramHandler.ts
- `Apple` - /mpc/handlers/OAuthhandler/AppleIDHandler.ts
<!-- todo: add a flow diagram -->
`Flow`
- user selects a social login handler
- we will fetch the `verifier` info from above and create handler based on provider choose
- we will use `setFinalUrl()` to get the url to be redirected to get oauth verification done
- we will get `access_token` back from oauth, which we will use to get user info
- `getTorusKey()` from torus.js packages https://github.com/torusresearch/torus.js
- we `set oauthKey and signatures` from response of above method which will be used in `signing` transactions
- check if metadata or if user is already logged in to torus metadata
- if not proceed with new account flow and redirect to save device share screen
- if existing user and device share exists in device, unlock the wallet with both shares available
- if existing user and no device share, proceed to recovery flow to ask user to input one of already added share like seedphrase, mobile otp, etc...
### `DeviceShare`
- used to store second share store after initializing tkey to devices local storage
- this will be used in later part during unlock or fresh onboarding to check for second share to reconstruct tkey and login to MPC wallet
### ` MpcRecoveryShare`
- when `params.type === `**manual**` `

``` json =
portStream.emit(events.MPC_RECOVERY_SHARE, {
action: 'Create',
type: 'manual',
path: 'Settings',
})
```
#### `parameters passed`:
- action
- path
- backupPhrase
#### `action`: mandatory parameter
- `create `
used in onboarding and settings flow to create a manual/ pen paper seedphrase
- `read `
used to display the seedphrase to user once created for writing down or copy and save
- `verify`
verification of seedphrase during onboarding/ recovery flow to reconstruct tkey
#### `path`: optional parameter
``used when action === "Create" ``
VALUES: Onboarding || Settings
* used to find out whether creation of factor is from settings/ onboarding flow
#### `backupPhrase`: optional parameter
* the seedphrase send from recovery flow to reconstruct tkey and factor
when `params.type === `**email**` `

`trigger points `
* Onboarding and security settings
`params`
- recoveryEmail - email to send the seedphrase used for recovery flow in new device
- loginProvider - social login google/apple/discord/telegram
- verifierId - logged in address
- path - Settings/Onboarding
`flow`
will be called as below
await portStream.emit(events.MPC_RECOVERY_SHARE_EMAIL, {
recoveryEmail: email,
loginProvider: 'google',
verifierId: email,
});
<br >
### `MPCSendOTP`

#### `trigger points`
* onboarding
* security settings
* recovery
#### `params`
`action:`
* `Send, Add - new Device`
* `Request, reconstruct - recovery flow`
* ` Bypass - skip the mobile otp setup for later `
`mobileNumber`
* Mobile Number
`code`
* OTP Code
`path`
* Settings
* Onboarding
#### `flows`
* Onboarding
* Security Settings
* Recovery
#### `Onboarding `
1. Send otp
```json =
await portStream.emit(events.MPC_SEND_OTP, {
action: 'Send',
mobileNumber,
})
```
2. Add New Share
```json =
await portStream.emit(events.MPC_SEND_OTP, {
action: 'Add',
mobileNumber,
code: "OTP_CODE"
})
```
#### `Recovery `
1. Request otp
note: we don't need mobile number since we will pass oauth pub key to sms otp server which will pick the number from existing metadata
```json =
await portStream.emit(events.MPC_SEND_OTP, {
action: 'Request',
})
```
2. Reconstruct New Share
```json =
await portStream.emit(events.MPC_SEND_OTP, {
action: 'Reconstruct',
mobileNumber,
code: "OTP_CODE"
})
```
#### `Bypass` (2/2 flow)
Skip the additional share creation in onboarding flow
```json =
await portStream.emit(events.MPC_SEND_OTP, {
action: 'ByPass',
})
```
### `MPCPassword`
#### `trigger points:`
* from security settings
* when we setup MPC vault password
* during MPC unlock flow with password
#### `params:`
* `action: Set, Verify`
* `password: raw password sent from popup file`
#### `flow`
1. set password
``` json ===
await portStream.emit(events.MPC_PASSWORD, {
action: 'Set',
password: password,
});
```
2. Verify password
``` json ===
await portStream.emit(events.MPC_PASSWORD, {
action: 'Verify',
password: password,
});
```
### `MPCSigning`
#### `trigger points: `
when we sign a transaction
#### `params: `
msgHashHex: string
` snippet`
``` json =
// transaction - transaction object
const unsignedTx = utils.serializeTransaction(transaction).substring(2);
const msgHashHex = keccak256(Buffer.from(unsignedTx, 'hex')).toString('hex');
```
#### `flow:`
MPCSigning - has **3** main steps
- precompute
- sign
- cleanup
<br/>
### `MPCLogout`
#### `trigger point:`
- remove wallet from settings page
- reset wallet during unlock flow
- reset account for fresh start during account verification flow(only developer mode)
#### `params:`
`action`
* deleteKey
* logout
#### `flows:`
`logout`
* will reset MPC vault state to clear all mpc related storages
* will remove MPC wallet from list of wallets
* if any other wallet exists
* switch to that wallet and redirect to home page
* if not
* clear all vault storages
* restart event manager
* redirect to onboarding flow
### `MPCVault`

- We want multiple accounts
on trust wallet (mnemonics + MPC wallet) => Use social login key as encryption key
- There are 2 ways to unlock the wallet now. One is social login, another is password. (dependent on step 3).
- Its possible to have 3 states now. Mnemonic only account, MPC only account, MPC + multiple mnemonics account.
- mnemonics => start with password, incase MPC is added later, no changes to the encryption key. Add another encryption (social login key will encrypt the password)
- mpc only account => start with 2 shares, encrypt the vault using social login key. If the mnemonic account is added later, we swap the enc key from social login to password key.
- heterogeneous account => User can't start with both accounts simultaneously. Step1/2 takes care of this flow.
- Introduced new keys value pairs in mpc vault service.
- If user quits during onboarding, no state should be affected. TempSession takes care of this flow.
- Logout => Delete the MPC account from trust wallet.
- Signing => A new `remoteSign` function was introduced to cater to signing via MPC nodes. "@toruslabs/eth-sig-util"
<br/>
<!-- todo add comments on each handler and correspoding tkey service functionalities -->
## Redux State Changes
| Handler name | Type | Functioanlity | Action |
| ------------------------------- | ---------- | ------------------------------------------------------- | ----------------------- |
| mpcEnabled | boolean | did user used mpc during his previous login | `setUsingMPC()` |
| mpcPassword | boolean | did user setup mpc password for login | `setUsingMPCPassword()` |
| mpcUserInfo | Object< typeOfLogin: string; verifierId: string > | tkey user info | `setMPCUserInfo()` |
| mpcDeviceShare | string | tkey device share | `setMPCDeviceShare()` |
| shouldShowFactorSetupReminder | boolean | if mpc wallet type is used, reminder to setup 3 factors | `setShouldShowFactorSetupReminder()` |
| mpcWalletId | string | used to track MPC wallet id | `setMPCWalletId() ` |
| shouldShowPasswordSetupReminder | boolean | if mpc wallet type is used, reminder to setup password | `setShouldShowPasswordSetupReminder()` |
| shareDetails | Array<ShareDetails> | Share details of factors added | `setShareDetails()` |
#### `Action dispatch and usage of redux states`
`mpcEnabled: boolean`
- `setUsingMPC()`
- action will be dispatched while creating or importing a MPC wallet as indicator
- used to check if mpc wallet is being used in trust wallet context
- to navigate MPC unlock screen in case of lock or session timeout
`mpcPassword: boolean`
- `setUsingMPCPassword()`
- will be called from MPC vault service when user sets password which can be used for easier unlock
- will be used during add a new account and unlock existing wallet flows
- will be used during set reminder as check whether already available
`mpcDeviceShare: String`
- `setMPCDeviceShare()`
- action will be dispatched when creating a new tkey device share also after retreiving an existing device share to store it in device storage for easier
- will be used to reconstruct tkey after logging back using social login (reconstruct - social + device share)
`mpcWalletId:string`
- `setMPCWalletId()`
- action will be dispatched post wallet creation or import to track MPC wallet id
- it will be used to remove wallet and check with selected id against MPC wallet Id
`shouldShowFactorSetupReminder: boolean`
- `setShouldShowFactorSetupReminder()`
- will be called post MPC wallet creation if only 2 shares are setup and refreshed every 24 hrs to show the reminder every day till user sets up the additional factor
- will be used in home page to show warning to setup more factors which will be redirected to security settings page to setup additional factor
`shouldShowPasswordSetupReminder`
- `setShouldShowPasswordSetupReminder()`
- will be called post MPC wallet creation if only password setup is not done and refreshed every 24 hrs to show the reminder every day till user sets up the password screen
- will be used in home page to show warning to setup password which will be redirected to MPC Password page to setup additional factor
`mpcUserInfo`
- `setMPCUserInfo()`
- will be called post Social Login
- will be used in multiple places to fetch type of login used and user information display and retreival during settings and account unlock flow
`shareDetails`
- `setShareDetails()`
- will be called during MPC wallet creation or recovery flow
- will be used in multiple places like settings, account recovery to feetch existing factor details and to add more
## Existing Service Service Changes
> Asset Service
Currently disable solana symbols for MPC Wallet type, will be added post beta release
> Ethereum transaction service
Modified
https://www.npmjs.com/package/@toruslabs/eth-sig-util with https://github.com/torusresearch/eth-sig-util to accept MPC Signing
we will have remote sign method which will be called to sign a message or transaction in case of MPC Wallet which will not use private key
> sample remote sign code for MPC wallets
```json=
remoteSign = async (msgHash: Buffer) => {
const { signature } = await this.tKeyService.MPCSigning(msgHash.toString('hex'));
const recoveryParam = parseInt(signature.v, 16) % 2;
return {
v: BigInt(recoveryParam + vOffset),
r: Buffer.from(signature.r, 'hex'),
s: Buffer.from(signature.s, 'hex'),
};
};
```
> sample remote sign code for PrivateKey wallets
```json=
// key -> privatekey
remoteSign = async (msgHash: Buffer) => {
const { v, r, s } = await ecsign(msgHash, Buffer.from(key.data().buffer));
return { v: BigInt(v), r, s };
};
```
```json
import { personalSign } from '@toruslabs/eth-sig-util';
// personal sign has modified code to accept remotesign method where signature is handled by application which code snippet is above
_signMessage(
data: string,
remoteSign: (msgHash: Buffer) => Promise<{
v: bigint;
r: Buffer;
s: Buffer;
}>,
) {
return personalSign({ remoteSign, data });
}
```
</br>