-
Notifications
You must be signed in to change notification settings - Fork 236
/
rainbow-wallet.ts
156 lines (133 loc) · 4.94 KB
/
rainbow-wallet.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import type { WalletConnectConnector as WalletConnectConnectorType } from "../connectors/wallet-connect";
import type { QRModalOptions } from "../connectors/wallet-connect/qrModalOptions";
import { Connector, WagmiAdapter } from "../interfaces/connector";
import { AbstractClientWallet, WalletOptions } from "./base";
import type { RainbowConnector as RainbowConnectorType } from "../connectors/rainbow";
import { walletIds } from "../constants/walletIds";
import { TW_WC_PROJECT_ID } from "../constants/wc";
import { getInjectedRainbowProvider } from "../connectors/rainbow/getInjectedRainbowProvider";
type RainbowAdditionalOptions = {
/**
* Whether to open the default Wallet Connect QR code Modal for connecting to Rainbow Wallet on mobile if Rainbow is not injected when calling connect().
*/
qrcode?: boolean;
/**
* When connecting Rainbow using the QR Code - Wallet Connect connector is used which requires a project id.
* This project id is Your project’s unique identifier for wallet connect that can be obtained at cloud.walletconnect.com.
*
* https://docs.walletconnect.com/2.0/web3modal/options#projectid-required
*/
projectId?: string;
/**
* options to customize the Wallet Connect QR Code Modal ( only relevant when qrcode is true )
*
* https://docs.walletconnect.com/2.0/web3modal/options
*/
qrModalOptions?: QRModalOptions;
};
export type RainbowWalletOptions = WalletOptions<RainbowAdditionalOptions>;
type ConnectWithQrCodeArgs = {
chainId?: number;
onQrCodeUri: (uri: string) => void;
onConnected: (accountAddress: string) => void;
};
/**
* @wallet
*/
export class RainbowWallet extends AbstractClientWallet<RainbowAdditionalOptions> {
connector?: Connector;
walletConnectConnector?: WalletConnectConnectorType;
rainbowConnector?: RainbowConnectorType;
isInjected: boolean;
static meta = {
name: "Rainbow Wallet",
iconURL:
"ipfs://QmSZn47p4DVVBfzvg9BAX2EqwnPxkT1YAE7rUnrtd9CybQ/rainbow-logo.png",
urls: {
chrome:
"https://chrome.google.com/webstore/detail/rainbow/opfgelmcmbiajamepnmloijbpoleiama",
android: "https://rnbwapp.com/e/Va41HWS6Oxb",
ios: "https://rnbwapp.com/e/OeMdmkJ6Oxb",
},
};
static id = walletIds.rainbow as string;
public get walletName() {
return "Rainbow Wallet" as const;
}
constructor(options: RainbowWalletOptions) {
super(RainbowWallet.id, options);
this.isInjected = !!getInjectedRainbowProvider();
}
protected async getConnector(): Promise<Connector> {
if (!this.connector) {
// if rainbow is injected, use the injected connector
// otherwise, use the wallet connect connector for using the rainbow app on mobile via QR code scan
if (this.isInjected) {
// import the connector dynamically
const { RainbowConnector } = await import("../connectors/rainbow");
const rainbowConnector = new RainbowConnector({
chains: this.chains,
connectorStorage: this.walletStorage,
options: {
shimDisconnect: true,
},
});
this.rainbowConnector = rainbowConnector;
this.connector = new WagmiAdapter(rainbowConnector);
} else {
const { WalletConnectConnector } = await import(
"../connectors/wallet-connect"
);
const walletConnectConnector = new WalletConnectConnector({
chains: this.chains,
options: {
projectId: this.options?.projectId || TW_WC_PROJECT_ID, // TODO,
storage: this.walletStorage,
qrcode: this.options?.qrcode,
dappMetadata: this.dappMetadata,
qrModalOptions: this.options?.qrModalOptions,
},
});
walletConnectConnector.getProvider().then((provider) => {
provider.signer.client.on("session_request_sent", () => {
this.emit("wc_session_request_sent");
});
});
// need to save this for getting the QR code URI
this.walletConnectConnector = walletConnectConnector;
this.connector = new WagmiAdapter(walletConnectConnector);
}
}
return this.connector;
}
/**
* connect to wallet with QR code
*
* @example
* ```typescript
* rainbow.connectWithQrCode({
* chainId: 1,
* onQrCodeUri(qrCodeUri) {
* // render the QR code with `qrCodeUri`
* },
* onConnected(accountAddress) {
* // update UI to show connected state
* },
* })
* ```
*/
async connectWithQrCode(options: ConnectWithQrCodeArgs) {
await this.getConnector();
const wcConnector = this.walletConnectConnector;
if (!wcConnector) {
throw new Error("WalletConnect connector not found");
}
const wcProvider = await wcConnector.getProvider();
// set a listener for display_uri event
wcProvider.on("display_uri", (uri) => {
options.onQrCodeUri(uri);
});
// trigger connect flow
this.connect({ chainId: options.chainId }).then(options.onConnected);
}
}