Skip to content

Commit 0233feb

Browse files
authored
[core: 2.4.0-alpha.1] - [enhancement] - Set Primary Account (#1119)
* Expose setPrimaryWalletAction * Increment version * Update docs
1 parent 2e74efb commit 0233feb

File tree

7 files changed

+158
-82
lines changed

7 files changed

+158
-82
lines changed

packages/core/README.md

Lines changed: 105 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ unsubscribe()
148148
```
149149

150150
```typescript
151-
152151
export type NotifyOptions = {
153152
desktop: Notify
154153
mobile: Notify
@@ -168,10 +167,10 @@ export type Notify = {
168167
}
169168

170169
export type CommonPositions =
171-
| 'topRight'
172-
| 'bottomRight'
173-
| 'bottomLeft'
174-
| 'topLeft'
170+
| 'topRight'
171+
| 'bottomRight'
172+
| 'bottomLeft'
173+
| 'topLeft'
175174

176175
export type TransactionHandlerReturn = CustomNotification | boolean | void
177176

@@ -214,28 +213,6 @@ export interface UpdateNotification {
214213
}
215214
```
216215

217-
Notify can be used to deliver custom DApp notifications by passing a `CustomNotification` object to the `customNotification` action. This will return an `UpdateNotification` type.
218-
This `UpdateNotification` will return an `update` function that can be passed a new `CustomNotification` to update the existing notification.
219-
The `customNotification` method also returns a `dismiss` method that is called without any parameters to dismiss the notification.
220-
221-
```typescript
222-
const { update, dismiss } = onboard.state.actions.customNotification({
223-
type: 'pending',
224-
message: 'This is a custom DApp pending notification to use however you want',
225-
autoDismiss: 0
226-
})
227-
setTimeout(
228-
() =>
229-
update({
230-
eventCode: 'dbUpdateSuccess',
231-
message: 'Updated status for custom notification',
232-
type: 'success',
233-
autoDismiss: 8000
234-
}),
235-
4000
236-
)
237-
```
238-
239216
### Initialization Example
240217

241218
Putting it all together, here is an example initialization with the injected wallet modules:
@@ -551,7 +528,7 @@ unsubscribe()
551528

552529
A limited subset of internal actions are exposed to update the Onboard state.
553530

554-
**setWalletModules**
531+
**`setWalletModules`**
555532
For updating the wallets that are displayed in the wallet selection modal. This can be used if the wallets you want to support is conditional on another user action within your app. The `setWalletModules` action is called with an updated array of wallets (the same wallets that are passed in on initialization)
556533

557534
```typescript
@@ -584,10 +561,10 @@ const onboard = Onboard({
584561
onboard.state.actions.setWalletModules([ledger, trezor])
585562
```
586563

587-
**updatedBalances**
588-
You may decide to get updated balances for connected wallets after a user action by calling the `updatedBalances` function, which expects a conditional array of addresses.
564+
**`updateBalances`**
565+
You may decide to get updated balances for connected wallets after a user action by calling the `updatedBalances` function, which expects a conditional array of addresses:
589566

590-
```
567+
```javascript
591568
onboard.state.actions.updateBalances() // update all balances for all connected addresses
592569
onboard.state.actions.updateBalances(['0xfdadfadsadsadsadasdsa']) // update balance for one address
593570
onboard.state.actions.updateBalances([
@@ -596,6 +573,103 @@ onboard.state.actions.updateBalances([
596573
]) // update balance for two addresses
597574
```
598575

576+
**`setLocale`**
577+
Onboard will automatically detect the browser locale at runtime, but if you would like to update it manually you can call the `setLocale` function:
578+
579+
```javascript
580+
onboard.state.actions.setLocal('fr_FR')
581+
```
582+
583+
**`updateNotify`**
584+
If you need to update your notify configuration after initialization, you can do that by calling the `updateNotify` function:
585+
586+
```javascript
587+
onboard.state.actions.updateNotify({
588+
desktop: {
589+
enabled: true,
590+
transactionHandler: transaction => {
591+
console.log({ transaction })
592+
if (transaction.eventCode === 'txPool') {
593+
return {
594+
type: 'success',
595+
message: 'Your transaction from #1 DApp is in the mempool'
596+
}
597+
}
598+
},
599+
position: 'bottomLeft'
600+
},
601+
mobile: {
602+
enabled: true,
603+
transactionHandler: transaction => {
604+
console.log({ transaction })
605+
if (transaction.eventCode === 'txPool') {
606+
return {
607+
type: 'success',
608+
message: 'Your transaction from #1 DApp is in the mempool'
609+
}
610+
}
611+
},
612+
position: 'topRight'
613+
}
614+
})
615+
```
616+
617+
**`customNotification`**
618+
Notify can be used to deliver custom DApp notifications by passing a `CustomNotification` object to the `customNotification` action. This will return an `UpdateNotification` type.
619+
This `UpdateNotification` will return an `update` function that can be passed a new `CustomNotification` to update the existing notification.
620+
The `customNotification` method also returns a `dismiss` method that is called without any parameters to dismiss the notification.
621+
622+
```typescript
623+
const { update, dismiss } = onboard.state.actions.customNotification({
624+
type: 'pending',
625+
message: 'This is a custom DApp pending notification to use however you want',
626+
autoDismiss: 0
627+
})
628+
setTimeout(
629+
() =>
630+
update({
631+
eventCode: 'dbUpdateSuccess',
632+
message: 'Updated status for custom notification',
633+
type: 'success',
634+
autoDismiss: 8000
635+
}),
636+
4000
637+
)
638+
```
639+
640+
**`updateAccountCenter`**
641+
If you need to update your Account Center configuration after initialization, you can call the `updateAccountCenter` function with the new configuration
642+
643+
```typescript
644+
onboard.state.actions.updateAccountCenter({
645+
desktop: {
646+
position: 'topRight',
647+
enabled: true,
648+
minimal: true
649+
},
650+
mobile: {
651+
position: 'topRight',
652+
enabled: true,
653+
minimal: true
654+
}
655+
})
656+
```
657+
658+
**`setPrimaryWallet`**
659+
The primary wallet (first in the list of connected wallets) and primary account (first in the list of connected accounts for a wallet) can be set by using the `setPrimaryWallet` function. The wallet that is to be set needs to be passed in for the first parameter and if you would like to set the primary account, the address of that account also needs to be passed in:
660+
661+
```typescript
662+
// set the second wallet in the wallets array as the primary
663+
onboard.state.actions.setPrimaryWallet(wallets[1])
664+
665+
// set the second wallet in the wallets array as the primary wallet
666+
// as well as setting the third account in that wallet as the primary account
667+
onboard.state.actions.setPrimaryWallet(
668+
wallets[1],
669+
wallets[1].accounts[2].address
670+
)
671+
```
672+
599673
## Setting the User's Chain/Network
600674

601675
When initializing Onboard you define a list of chains/networks that your app supports. If you would like to prompt the user to switch to one of those chains, you can use the `setChain` method on an initialized instance of Onboard:

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@web3-onboard/core",
3-
"version": "2.3.2",
3+
"version": "2.4.0-alpha.1",
44
"repository": "blocknative/web3-onboard",
55
"scripts": {
66
"build": "rollup -c",

packages/core/src/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from './validation'
1212
import initI18N from './i18n'
1313
import App from './views/Index.svelte'
14-
import type { InitOptions, OnboardAPI, Notify } from './types'
14+
import type { InitOptions, Notify } from './types'
1515
import { APP_INITIAL_STATE } from './constants'
1616
import { configuration, updateConfiguration } from './configuration'
1717

@@ -21,12 +21,13 @@ import {
2121
updateAccountCenter,
2222
updateNotify,
2323
customNotification,
24-
setLocale
24+
setLocale,
25+
setPrimaryWallet
2526
} from './store/actions'
2627

2728
import updateBalances from './updateBalances'
2829

29-
const API: OnboardAPI = {
30+
const API = {
3031
connectWallet,
3132
disconnectWallet,
3233
setChain,
@@ -39,14 +40,16 @@ const API: OnboardAPI = {
3940
updateNotify,
4041
customNotification,
4142
updateBalances,
42-
updateAccountCenter
43+
updateAccountCenter,
44+
setPrimaryWallet
4345
}
4446
}
4547
}
4648

49+
export type OnboardAPI = typeof API
50+
4751
export type {
4852
InitOptions,
49-
OnboardAPI,
5053
ConnectOptions,
5154
DisconnectOptions,
5255
WalletState,

packages/core/src/store/actions.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export function updateWallet(id: string, update: Partial<WalletState>): void {
106106
}
107107

108108
export function removeWallet(id: string): void {
109-
const error = validateString(id)
109+
const error = validateString(id, 'wallet id')
110110

111111
if (error) {
112112
throw error
@@ -122,6 +122,31 @@ export function removeWallet(id: string): void {
122122
dispatch(action as RemoveWalletAction)
123123
}
124124

125+
export function setPrimaryWallet(wallet: WalletState, address?: string): void {
126+
console.log({ address })
127+
const error =
128+
validateWallet(wallet) || (address && validateString(address, 'address'))
129+
130+
if (error) {
131+
throw error
132+
}
133+
134+
// if also setting the primary account
135+
if (address) {
136+
const account = wallet.accounts.find(ac => ac.address === address)
137+
138+
if (account) {
139+
wallet.accounts = [
140+
account,
141+
...wallet.accounts.filter(({ address }) => address !== account.address)
142+
]
143+
}
144+
}
145+
146+
// add wallet will set it to first wallet since it already exists
147+
addWallet(wallet)
148+
}
149+
125150
export function updateAccount(
126151
id: string,
127152
address: string,

packages/core/src/types.ts

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,6 @@ export interface InitOptions {
4949
notify?: Partial<NotifyOptions> | Partial<Notify>
5050
}
5151

52-
export interface OnboardAPI {
53-
connectWallet: typeof connect
54-
disconnectWallet: typeof disconnect
55-
setChain: typeof setChain
56-
state: {
57-
select: typeof state.select
58-
get: typeof state.get
59-
actions: ExposedActions
60-
}
61-
}
62-
63-
interface ExposedActions {
64-
setWalletModules: (wallets: WalletInit[]) => void
65-
setLocale: (locale: string) => void
66-
updateNotify: (update: Partial<Notify>) => void
67-
customNotification: (
68-
updatedNotification: CustomNotification
69-
) => {
70-
dismiss: () => void
71-
update: UpdateNotification
72-
}
73-
updateBalances: (addresses?: string[]) => Promise<void>
74-
updateAccountCenter: (update: AccountCenter | Partial<AccountCenter>) => void
75-
}
76-
7752
export interface ConnectOptions {
7853
autoSelect?: { label: string; disableModals: boolean }
7954
}
@@ -155,10 +130,10 @@ export type i18nOptions = Record<Locale, i18n>
155130
export type i18n = typeof en
156131

157132
export type CommonPositions =
158-
| 'topRight'
159-
| 'bottomRight'
160-
| 'bottomLeft'
161-
| 'topLeft'
133+
| 'topRight'
134+
| 'bottomRight'
135+
| 'bottomLeft'
136+
| 'topLeft'
162137

163138
export type AccountCenterPosition = CommonPositions
164139

@@ -192,7 +167,7 @@ export type Notify = {
192167
event: EthereumTransactionData
193168
) => TransactionHandlerReturn
194169
/**
195-
* Position of notifications that defaults to the same position as the
170+
* Position of notifications that defaults to the same position as the
196171
* Account Center (if enabled) of the top right if AC is disabled
197172
* and notifications are enabled (enabled by default with API key)
198173
*/

packages/core/src/validation.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ const wallet = Joi.object({
9292
accounts,
9393
chains: Joi.array().items(connectedChain)
9494
})
95+
.required()
96+
.error(new Error('wallet must be defined'))
9597

9698
const wallets = Joi.array().items(wallet)
9799

@@ -268,8 +270,13 @@ export function validateDisconnectOptions(
268270
return validate(disconnectOptions, data)
269271
}
270272

271-
export function validateString(str: string): ValidateReturn {
272-
return validate(Joi.string().required(), str)
273+
export function validateString(str: string, label?: string): ValidateReturn {
274+
return validate(
275+
Joi.string()
276+
.required()
277+
.label(label || 'value'),
278+
str
279+
)
273280
}
274281

275282
export function validateSetChainOptions(data: {

0 commit comments

Comments
 (0)