@rango-dev/provider-walletconnect-2 0.0.0-experimental-936229e8-20251208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +240 -0
  2. package/dist/chunk-BPSEZJUF.js +2 -0
  3. package/dist/chunk-BPSEZJUF.js.map +7 -0
  4. package/dist/chunk-DXVBX5XQ.js +2 -0
  5. package/dist/chunk-DXVBX5XQ.js.map +7 -0
  6. package/dist/chunk-RPL2NMJC.js +2 -0
  7. package/dist/chunk-RPL2NMJC.js.map +7 -0
  8. package/dist/constants.d.ts +55 -0
  9. package/dist/cosmos-I3Z34UI3.js +2 -0
  10. package/dist/cosmos-I3Z34UI3.js.map +7 -0
  11. package/dist/dist-6GI3ECE5.js +139 -0
  12. package/dist/dist-6GI3ECE5.js.map +7 -0
  13. package/dist/evm-MYSQOTV5.js +2 -0
  14. package/dist/evm-MYSQOTV5.js.map +7 -0
  15. package/dist/helpers.d.ts +31 -0
  16. package/dist/index.d.ts +21 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +7 -0
  19. package/dist/provider-walletconnect-2.build.json +1 -0
  20. package/dist/session.d.ts +63 -0
  21. package/dist/signer.d.ts +3 -0
  22. package/dist/signers/cosmos.d.ts +14 -0
  23. package/dist/signers/evm.d.ts +15 -0
  24. package/dist/signers/helper.d.ts +2 -0
  25. package/dist/signers/mock.d.ts +2 -0
  26. package/dist/signers/solana.d.ts +14 -0
  27. package/dist/solana-35I33VLX.js +2 -0
  28. package/dist/solana-35I33VLX.js.map +7 -0
  29. package/dist/types.d.ts +24 -0
  30. package/package.json +52 -0
  31. package/readme.md +8 -0
  32. package/src/constants.ts +91 -0
  33. package/src/helpers.ts +242 -0
  34. package/src/index.ts +233 -0
  35. package/src/session.ts +374 -0
  36. package/src/signer.ts +45 -0
  37. package/src/signers/cosmos.ts +248 -0
  38. package/src/signers/evm.ts +163 -0
  39. package/src/signers/helper.ts +77 -0
  40. package/src/signers/mock.ts +3798 -0
  41. package/src/signers/solana.ts +160 -0
  42. package/src/types.ts +30 -0
  43. package/src/wc-types.d.ts +31 -0
package/src/index.ts ADDED
@@ -0,0 +1,233 @@
1
+ import type { Environments, WCInstance } from './types.js';
2
+ import type {
3
+ CanSwitchNetwork,
4
+ Connect,
5
+ Disconnect,
6
+ GetInstance,
7
+ Subscribe,
8
+ SwitchNetwork,
9
+ WalletConfig,
10
+ WalletInfo,
11
+ } from '@rango-dev/wallets-shared';
12
+ import type { ISignClient } from '@walletconnect/types';
13
+ import type { BlockchainMeta, SignerFactory } from 'rango-types';
14
+
15
+ import { debug, error as logError } from '@rango-dev/logging-core';
16
+ import { Networks, WalletTypes } from '@rango-dev/wallets-shared';
17
+ import Client from '@walletconnect/sign-client';
18
+ import { AccountId, ChainId } from 'caip';
19
+ import { evmBlockchains } from 'rango-types';
20
+
21
+ import {
22
+ DEFAULT_APP_METADATA,
23
+ DEFAULT_NETWORK,
24
+ EthereumEvents,
25
+ EthereumRPCMethods,
26
+ NAMESPACES,
27
+ RELAY_URL,
28
+ } from './constants.js';
29
+ import {
30
+ createModalInstance,
31
+ filterEvmAccounts,
32
+ simulateRequest,
33
+ switchOrAddEvmChain,
34
+ } from './helpers.js';
35
+ import {
36
+ cleanupSingleSession,
37
+ disconnectSessions,
38
+ getAccountsFromEvent,
39
+ getAccountsFromSession,
40
+ getPersistedChainId,
41
+ ignoreNamespaceMethods,
42
+ persistCurrentChainId,
43
+ tryConnect,
44
+ updateSessionAccounts,
45
+ } from './session.js';
46
+ import signer from './signer.js';
47
+
48
+ const WALLET = WalletTypes.WALLET_CONNECT_2;
49
+
50
+ let envs: Environments = {
51
+ WC_PROJECT_ID: '',
52
+ DISABLE_MODAL_AND_OPEN_LINK: undefined,
53
+ };
54
+
55
+ export type { Environments };
56
+
57
+ export const init = (environments: Environments) => {
58
+ envs = environments;
59
+
60
+ createModalInstance(envs.WC_PROJECT_ID);
61
+ };
62
+
63
+ export const config: WalletConfig = {
64
+ type: WALLET,
65
+ checkInstallation: false,
66
+ isAsyncInstance: true,
67
+ defaultNetwork: DEFAULT_NETWORK,
68
+ isAsyncSwitchNetwork: true,
69
+ };
70
+
71
+ export const getInstance: GetInstance = async (options) => {
72
+ const { currentProvider, getState, meta } = options;
73
+
74
+ /*
75
+ * Create a new pair, if exists use the pair,
76
+ * Or use the already created one.
77
+ */
78
+ let provider: ISignClient;
79
+ if (!currentProvider) {
80
+ if (!envs.WC_PROJECT_ID) {
81
+ throw new Error(
82
+ 'You need to set `WC_PROJECT_ID` in Wallet Connect provider.'
83
+ );
84
+ }
85
+ provider = await Client.init({
86
+ relayUrl: RELAY_URL,
87
+ projectId: envs.WC_PROJECT_ID,
88
+ metadata: DEFAULT_APP_METADATA,
89
+ });
90
+ } else {
91
+ provider = currentProvider;
92
+ }
93
+
94
+ return {
95
+ client: provider,
96
+ session: null,
97
+ request: async (params: any) =>
98
+ simulateRequest(params, provider, meta, getState),
99
+ };
100
+ };
101
+
102
+ export const connect: Connect = async ({ instance, meta }) => {
103
+ const { client } = instance as WCInstance;
104
+ // Try to restore the session first, if couldn't, create a new session by showing a modal.
105
+ const session = await tryConnect(client, { meta, envs });
106
+ // Override the value (session).
107
+ instance.session = session;
108
+ const currentChainId = await getPersistedChainId(client);
109
+ const accounts = getAccountsFromSession(session);
110
+ return filterEvmAccounts(accounts, currentChainId);
111
+ };
112
+
113
+ export const subscribe: Subscribe = ({
114
+ instance,
115
+ updateChainId,
116
+ updateAccounts,
117
+ disconnect,
118
+ }) => {
119
+ const { client } = instance as WCInstance;
120
+
121
+ /**
122
+ * Session events refrence:
123
+ * https://docs.walletconnect.com/2.0/specs/clients/sign/session-events
124
+ */
125
+
126
+ // Listen to updating the session by adding a new chain, method, or event
127
+ client.on('session_update', (args) => {
128
+ const allAccounts = getAccountsFromEvent(args);
129
+ allAccounts.forEach((accountsWithChain) => {
130
+ updateAccounts(accountsWithChain.accounts, accountsWithChain.chainId);
131
+ });
132
+ });
133
+
134
+ // Listen to events triggred by wallet. (e.g. accountsChanged and chainChanged)
135
+ client.on('session_event', (args) => {
136
+ if (args.params.event.name === EthereumEvents.ACCOUNTS_CHANGED) {
137
+ const accounts = args.params.event.data.map((account: string) => {
138
+ return new AccountId(account).address;
139
+ });
140
+ const chainId = ChainId.parse(args.params.chainId).reference;
141
+ updateAccounts(accounts);
142
+ updateChainId(chainId);
143
+ } else if (args.params.event.name === EthereumEvents.CHAIN_CHANGED) {
144
+ const chainId = args.params.event.data;
145
+ updateChainId(chainId);
146
+ void persistCurrentChainId(instance.client, chainId);
147
+ } else {
148
+ console.log('[WC2] session_event not supported', args.params.event);
149
+ }
150
+ });
151
+
152
+ client.on('session_delete', async (event) => {
153
+ console.log('[WC2] your wallet has requested to delete session.', event);
154
+ void cleanupSingleSession(client, event.topic);
155
+ disconnect();
156
+ });
157
+ };
158
+
159
+ export const switchNetwork: SwitchNetwork = async ({
160
+ network,
161
+ instance,
162
+ meta,
163
+ getState,
164
+ updateChainId,
165
+ }) => {
166
+ const evm = evmBlockchains(meta);
167
+ const chainId = evm.find((chain) => chain.name === network)?.chainId;
168
+ if (!chainId) {
169
+ const error = new Error(`There is no match for ${chainId}`);
170
+ logError(error);
171
+ throw error;
172
+ }
173
+ const chaindIdStr = new ChainId({
174
+ namespace: NAMESPACES.ETHEREUM,
175
+ reference: String(parseInt(chainId)),
176
+ }).toString();
177
+
178
+ const session = instance.session;
179
+ const evmNamespace = session.namespaces[NAMESPACES.ETHEREUM];
180
+ const authorizedChains = evmNamespace?.chains || [];
181
+ const authorizedMethods = evmNamespace?.methods || [];
182
+
183
+ if (
184
+ authorizedMethods.includes(EthereumRPCMethods.SWITCH_CHAIN) &&
185
+ !ignoreNamespaceMethods(instance)
186
+ ) {
187
+ const currentNetwork = getState?.().network || Networks.ETHEREUM;
188
+ await updateSessionAccounts(instance, network, currentNetwork, meta);
189
+ await switchOrAddEvmChain(meta, network, currentNetwork, instance);
190
+ } else if (authorizedChains.includes(chaindIdStr)) {
191
+ updateChainId(chainId);
192
+ return;
193
+ } else {
194
+ const error = new Error(`Chain ${chainId} is not configured.`);
195
+ logError(error);
196
+ throw error;
197
+ }
198
+ };
199
+
200
+ /**
201
+ *
202
+ * Note:
203
+ * There is no straight-forward way to detect the wallet supports which blockchain,
204
+ * So we send request to wallet and expect to be rejected on the wallet if it's not supported.
205
+ *
206
+ */
207
+ export const canSwitchNetworkTo: CanSwitchNetwork = () => true;
208
+
209
+ export const disconnect: Disconnect = async ({ instance }) => {
210
+ const { client } = instance as WCInstance;
211
+
212
+ if (client) {
213
+ void disconnectSessions(client).catch((error) => debug(error));
214
+ }
215
+ };
216
+
217
+ export const getSigners: (provider: WCInstance) => Promise<SignerFactory> =
218
+ signer;
219
+
220
+ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
221
+ allBlockChains
222
+ ) => {
223
+ const evms = evmBlockchains(allBlockChains);
224
+ return {
225
+ name: 'WalletConnect',
226
+ img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/walletconnect/icon.svg',
227
+ installLink: '',
228
+ color: '#b2dbff',
229
+ supportedChains: evms,
230
+ showOnMobile: true,
231
+ mobileWallet: true,
232
+ };
233
+ };
package/src/session.ts ADDED
@@ -0,0 +1,374 @@
1
+ import type {
2
+ ConnectParams,
3
+ CreateSessionParams,
4
+ Environments,
5
+ } from './types.js';
6
+ import type { SignClient } from '@walletconnect/sign-client/dist/types/client';
7
+ import type {
8
+ PairingTypes,
9
+ SessionTypes,
10
+ SignClientTypes,
11
+ } from '@walletconnect/types';
12
+ import type { BlockchainMeta } from 'rango-types';
13
+
14
+ import { Networks, timeout } from '@rango-dev/wallets-shared';
15
+ import { getSdkError } from '@walletconnect/utils';
16
+ import { AccountId } from 'caip';
17
+
18
+ import { CHAIN_ID_STORAGE, PING_TIMEOUT } from './constants.js';
19
+ import {
20
+ generateOptionalNamespace,
21
+ getCurrentEvmAccountAddress,
22
+ getEvmAccount,
23
+ getModal,
24
+ solanaChainIdToNetworkName,
25
+ } from './helpers.js';
26
+
27
+ export function getLastSession(client: SignClient) {
28
+ return client.session.values[client.session.values.length - 1];
29
+ }
30
+
31
+ /**
32
+ *
33
+ * Try to ping the wallet, if wallet responded with `pong`, session is a valid and we will use the session.
34
+ * If the wallet didn't respond during 10 seconds (PING_TIME), we assume the wallet isn't available and we need to create a new session.
35
+ *
36
+ */
37
+ export async function restoreSession(
38
+ client: SignClient,
39
+ pairingTopic: PairingTypes.Struct['topic']
40
+ ): Promise<SessionTypes.Struct | undefined> {
41
+ await timeout(
42
+ client.ping({
43
+ topic: pairingTopic,
44
+ }),
45
+ PING_TIMEOUT
46
+ );
47
+
48
+ // We assume last session is the correct session, beacuse we are doing clean up and keeps only one pairing/session.
49
+ const session = getLastSession(client);
50
+ return session;
51
+ }
52
+
53
+ /**
54
+ *
55
+ * Getting a pair of required and optional namespaces then tries to show a modal and connect (pair)
56
+ * To the wallet.
57
+ * @param client
58
+ * @param options
59
+ * @returns
60
+ */
61
+ export async function createSession(
62
+ client: SignClient,
63
+ options: CreateSessionParams,
64
+ configs: {
65
+ envs: Environments;
66
+ }
67
+ ): Promise<SessionTypes.Struct> {
68
+ const { requiredNamespaces, optionalNamespaces, pairingTopic } = options;
69
+
70
+ try {
71
+ const { uri, approval } = await client.connect({
72
+ requiredNamespaces,
73
+ optionalNamespaces,
74
+ pairingTopic,
75
+ });
76
+
77
+ // Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing).
78
+ let onCloseModal;
79
+ if (uri) {
80
+ /*
81
+ * There are some wallets have been listed in WC itself (https://docs.walletconnect.com/cloud/explorer-submission),
82
+ * Using `DISABLE_MODAL_AND_OPEN_LINK` option, we can directly open a specific desktop wallet.
83
+ */
84
+ const redirectLink = configs.envs.DISABLE_MODAL_AND_OPEN_LINK;
85
+ if (redirectLink) {
86
+ const url = `${redirectLink}/wc?uri=${encodeURIComponent(uri)}`;
87
+ window.open(url, '_blank', 'noreferrer noopener');
88
+ } else {
89
+ // Create a flat array of all requested chains across namespaces.
90
+ const allNamespaces = {
91
+ ...(requiredNamespaces || {}),
92
+ ...(optionalNamespaces || {}),
93
+ };
94
+
95
+ const standaloneChains = Object.values(allNamespaces)
96
+ .map((namespace) => namespace.chains)
97
+ .flat() as string[];
98
+
99
+ const modal = getModal();
100
+ void modal.openModal({ uri, chains: standaloneChains });
101
+
102
+ onCloseModal = new Promise((_, reject) => {
103
+ modal.subscribeModal((state) => {
104
+ // the modal was closed so reject the promise
105
+ if (!state.open) {
106
+ reject(new Error('Modal has been closed.'));
107
+ }
108
+ });
109
+ });
110
+ }
111
+ }
112
+
113
+ const session = approval();
114
+
115
+ if (onCloseModal) {
116
+ const result = await Promise.race([session, onCloseModal]);
117
+ // We know onClose only reject a modal and never returns a value.
118
+ return result as SessionTypes.Struct;
119
+ }
120
+ return await session;
121
+ } finally {
122
+ getModal().closeModal();
123
+ }
124
+ }
125
+
126
+ /**
127
+ *
128
+ * A user (client) can have multiple pairings (to different wallets), we are assuming
129
+ * the last pairing is the active pairing for now. A better UX can be showing a list of pairings
130
+ * and let the user to choose the right pairing manually. Because we don't have that yet, we will pick up the last one.
131
+ *
132
+ */
133
+ export function tryGetPairing(
134
+ client: SignClient
135
+ ): PairingTypes.Struct | undefined {
136
+ const pairings = client.pairing.getAll({ active: true });
137
+ const lastPairing =
138
+ pairings.length > 0 ? pairings[pairings.length - 1] : undefined;
139
+
140
+ return lastPairing;
141
+ }
142
+
143
+ /**
144
+ *
145
+ * Try to restore the session first, if couldn't, create a new session by showing a modal.
146
+ *
147
+ */
148
+ export async function tryConnect(
149
+ client: SignClient,
150
+ params: ConnectParams
151
+ ): Promise<SessionTypes.Struct> {
152
+ const { meta } = params;
153
+
154
+ // We try to get all of our supported chains as optional.
155
+ const optionalNamespaces = generateOptionalNamespace(meta);
156
+
157
+ // Check if the user has a session, if yes, restore the session and use it.
158
+ let session: SessionTypes.Struct | undefined;
159
+ const pairing = tryGetPairing(client);
160
+ if (pairing) {
161
+ try {
162
+ session = await restoreSession(client, pairing.topic);
163
+ } catch (e) {
164
+ await disconnectSessions(client);
165
+ }
166
+ }
167
+
168
+ // In case of connecting for the first time or session couldn't be restored, we will create a new session.
169
+ if (!session) {
170
+ session = await createSession(
171
+ client,
172
+ {
173
+ requiredNamespaces: {},
174
+ optionalNamespaces,
175
+ },
176
+ {
177
+ envs: params.envs,
178
+ }
179
+ );
180
+ }
181
+
182
+ return session;
183
+ }
184
+
185
+ /**
186
+ *
187
+ * Try to find sessions with a topic id and expire them.
188
+ *
189
+ */
190
+ export async function cleanupSingleSession(client: SignClient, topic: string) {
191
+ const sessions = client.session.getAll();
192
+ const pairings = client.pairing.getAll();
193
+
194
+ sessions.forEach((session) => {
195
+ if (session.topic === topic || session.pairingTopic === topic) {
196
+ const requestForDeleteTopic =
197
+ session.pairingTopic === topic ? session.pairingTopic : session.topic;
198
+ client.core.expirer.set(requestForDeleteTopic, 0);
199
+ }
200
+ });
201
+
202
+ pairings.forEach((pairing) => {
203
+ if (pairing.topic === topic) {
204
+ client.core.expirer.set(topic, 0);
205
+ }
206
+ });
207
+ }
208
+
209
+ /**
210
+ *
211
+ * Disconnect means to delete the session on both parties (dApp & wallet) at the same time.
212
+ *
213
+ */
214
+ export async function disconnectSessions(client: SignClient) {
215
+ const allPromises = [];
216
+
217
+ const sessions = client.session.getAll();
218
+ for (const session of sessions) {
219
+ allPromises.push(
220
+ client.disconnect({
221
+ topic: session.topic,
222
+ reason: getSdkError('USER_DISCONNECTED'),
223
+ })
224
+ );
225
+ }
226
+
227
+ const pairings = client.pairing.getAll();
228
+ for (const pairing of pairings) {
229
+ allPromises.push(
230
+ client.disconnect({
231
+ topic: pairing.topic,
232
+ reason: getSdkError('USER_DISCONNECTED'),
233
+ })
234
+ );
235
+ }
236
+
237
+ // reset the current chain id
238
+ void persistCurrentChainId(client, undefined);
239
+
240
+ return await Promise.all(allPromises);
241
+ }
242
+
243
+ export function getAccountsFromSession(session: SessionTypes.Struct) {
244
+ const accounts = Object.values(session.namespaces)
245
+ .map((namespace) => namespace.accounts)
246
+ .flat()
247
+ .map((account) => {
248
+ const { address, chainId } = new AccountId(account);
249
+ /*
250
+ * Note: Solana has a specific ID, we need to convert it back to network name.
251
+ * It will return the chain id itslef if it's not that specific ID.
252
+ */
253
+ const chain = solanaChainIdToNetworkName(chainId.reference);
254
+ return {
255
+ address,
256
+ chainId: chain,
257
+ };
258
+ });
259
+ return accounts;
260
+ }
261
+
262
+ export function getAccountsFromEvent(
263
+ event: SignClientTypes.BaseEventArgs<{
264
+ namespaces: SessionTypes.Namespaces;
265
+ }>
266
+ ) {
267
+ const accounts = Object.values(event.params.namespaces)
268
+ .map((namespace) => namespace.accounts)
269
+ .flat()
270
+ .map((account) => {
271
+ const { address, chainId } = new AccountId(account);
272
+ return {
273
+ accounts: [address],
274
+ chainId:
275
+ chainId.namespace === 'solana' ? Networks.SOLANA : chainId.reference,
276
+ };
277
+ });
278
+
279
+ return accounts;
280
+ }
281
+
282
+ /*
283
+ * Before switch network, we need to update session namespace accounts
284
+ * to contain both current chain and target chain accoutns.
285
+ */
286
+ export async function updateSessionAccounts(
287
+ instance: any,
288
+ requestedNetwork: string,
289
+ currentNetwork: string,
290
+ meta: BlockchainMeta[]
291
+ ) {
292
+ const session = instance.session;
293
+
294
+ const namespaces = session.namespaces;
295
+ let needUpdateNamepspace = false;
296
+ const accounts = namespaces.eip155.accounts;
297
+
298
+ const currentAccountAddress = getCurrentEvmAccountAddress(instance);
299
+ const requestedAccount = getEvmAccount(
300
+ requestedNetwork,
301
+ currentAccountAddress,
302
+ meta
303
+ );
304
+ if (!accounts.includes(requestedAccount)) {
305
+ accounts.push(requestedAccount);
306
+ needUpdateNamepspace = true;
307
+ }
308
+
309
+ const currentAccount = getEvmAccount(
310
+ currentNetwork,
311
+ currentAccountAddress,
312
+ meta
313
+ );
314
+ if (!accounts.includes(currentAccount)) {
315
+ accounts.push(currentAccount);
316
+ needUpdateNamepspace = true;
317
+ }
318
+
319
+ if (needUpdateNamepspace) {
320
+ const updatedNamespaces = {
321
+ ...namespaces,
322
+ eip155: {
323
+ ...namespaces.eip155,
324
+ accounts,
325
+ },
326
+ };
327
+ await instance.client.session
328
+ .update({
329
+ topic: session.topic,
330
+ namespaces: updatedNamespaces,
331
+ })
332
+ .catch((err: unknown) => {
333
+ console.log(err);
334
+ });
335
+ }
336
+ }
337
+
338
+ /*
339
+ * Certain wallets, such as Trust Wallet and 1inch, are providing incorrect methods in
340
+ * response to session proposal requests. These wallets do not support certain optional
341
+ * RPC methods like "wallet_xyz," but they include them in the response under the session namespace.
342
+ * For the time being, we should avoid their session namespace response.
343
+ * see also: https://github.com/trustwallet/wallet-core/issues/3588
344
+ */
345
+ export function ignoreNamespaceMethods(instance: any): boolean {
346
+ const WALLETS_WITH_WRONG_NAMESPACE_METHODS = ['trust', '1inch'];
347
+ const peerName = instance?.session?.peer?.metadata?.name;
348
+ return WALLETS_WITH_WRONG_NAMESPACE_METHODS.some((name) =>
349
+ peerName?.toLowerCase()?.includes(name)
350
+ );
351
+ }
352
+
353
+ export async function persistCurrentChainId(
354
+ client: SignClient,
355
+ chainId?: string
356
+ ) {
357
+ return client.core.storage.setItem(CHAIN_ID_STORAGE, {
358
+ defaultChainId: chainId ? parseInt(chainId) : '',
359
+ });
360
+ }
361
+
362
+ /*
363
+ * get the latest chain id from the storage,
364
+ * used for setting current chain id in session reconnect.
365
+ */
366
+ export async function getPersistedChainId(client: SignClient) {
367
+ try {
368
+ const chainId = (await client.core.storage.getItem(CHAIN_ID_STORAGE))
369
+ ?.defaultChainId;
370
+ return !!chainId ? String(chainId) : undefined;
371
+ } catch {
372
+ return undefined;
373
+ }
374
+ }
package/src/signer.ts ADDED
@@ -0,0 +1,45 @@
1
+ import type { WCInstance } from './types.js';
2
+ import type { SignerFactory } from 'rango-types';
3
+
4
+ import { dynamicImportWithRefinedError } from '@rango-dev/wallets-shared';
5
+ import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';
6
+
7
+ export default async function getSigners(
8
+ instance: WCInstance
9
+ ): Promise<SignerFactory> {
10
+ if (!instance.session) {
11
+ throw new Error('Session is required for wallet connect signers.');
12
+ }
13
+
14
+ const signers = new DefaultSignerFactory();
15
+ const EVMSigner = (
16
+ await dynamicImportWithRefinedError(
17
+ async () => await import('./signers/evm.js')
18
+ )
19
+ ).default;
20
+ const COSMOSSigner = (
21
+ await dynamicImportWithRefinedError(
22
+ async () => await import('./signers/cosmos.js')
23
+ )
24
+ ).default;
25
+ const SOLANASigner = (
26
+ await dynamicImportWithRefinedError(
27
+ async () => await import('./signers/solana.js')
28
+ )
29
+ ).default;
30
+
31
+ signers.registerSigner(
32
+ TxType.EVM,
33
+ new EVMSigner(instance.client, instance.session)
34
+ );
35
+ signers.registerSigner(
36
+ TxType.COSMOS,
37
+ new COSMOSSigner(instance.client, instance.session)
38
+ );
39
+ signers.registerSigner(
40
+ TxType.SOLANA,
41
+ new SOLANASigner(instance.client, instance.session)
42
+ );
43
+
44
+ return signers;
45
+ }