@rango-dev/provider-walletconnect-2 0.1.1-next.0
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.
- package/dist/constants.d.ts +53 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/helpers.d.ts +20 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/session.d.ts +63 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/signer.d.ts +4 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signers/cosmos.d.ts +16 -0
- package/dist/signers/cosmos.d.ts.map +1 -0
- package/dist/signers/evm.d.ts +16 -0
- package/dist/signers/evm.d.ts.map +1 -0
- package/dist/signers/helper.d.ts +3 -0
- package/dist/signers/helper.d.ts.map +1 -0
- package/dist/signers/mock.d.ts +3 -0
- package/dist/signers/mock.d.ts.map +1 -0
- package/dist/signers/solana.d.ts +15 -0
- package/dist/signers/solana.d.ts.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +41 -0
- package/readme.md +10 -0
- package/src/constants.ts +83 -0
- package/src/helpers.ts +165 -0
- package/src/index.ts +177 -0
- package/src/session.ts +308 -0
- package/src/signer.ts +32 -0
- package/src/signers/cosmos.ts +243 -0
- package/src/signers/evm.ts +134 -0
- package/src/signers/helper.ts +73 -0
- package/src/signers/mock.ts +3675 -0
- package/src/signers/solana.ts +155 -0
- package/src/types.ts +25 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { SignClient } from '@walletconnect/sign-client/dist/types/client';
|
|
2
|
+
import { PairingTypes, SessionTypes, SignClientTypes } from '@walletconnect/types';
|
|
3
|
+
import { ConnectParams, CreateSessionParams, WCInstance } from './types';
|
|
4
|
+
export declare function getLastSession(client: SignClient): SessionTypes.Struct;
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Try to ping the wallet, if wallet responded with `pong`, session is a valid and we will use the session.
|
|
8
|
+
* 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.
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export declare function restoreSession(client: SignClient, pairing: PairingTypes.Struct): Promise<SessionTypes.Struct | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Getting a pair of required and optional namespaces then tries to show a modal and connect (pair)
|
|
15
|
+
* To the wallet.
|
|
16
|
+
* @param client
|
|
17
|
+
* @param options
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export declare function createSession(client: SignClient, options: CreateSessionParams): Promise<SessionTypes.Struct>;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* A user (client) can have multiple pairings (to different wallets), we are assuming
|
|
24
|
+
* the last pairing is the active pairing for now. A better UX can be showing a list of pairings
|
|
25
|
+
* and let the user to choose the right pairing manually. Because we don't have that yet, we will pick up the last one.
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
export declare function tryGetPairing(client: SignClient): PairingTypes.Struct | undefined;
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* Try to restore the session first, if couldn't, create a new session by showing a modal.
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
export declare function tryConnect(client: SignClient, params: ConnectParams): Promise<SessionTypes.Struct>;
|
|
35
|
+
/**
|
|
36
|
+
* Wallet connect is a multichain protocol and we can not determine the connected wallet
|
|
37
|
+
* supports which wallet, `extend`ing session doesn't work during a bug in their utils packages.
|
|
38
|
+
* So we will try to make a new session with `network` that user needs to switch.
|
|
39
|
+
*/
|
|
40
|
+
export declare function trySwitchByCreatingNewSession(instance: WCInstance, params: ConnectParams): Promise<SessionTypes.Struct>;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* Try to find sessions with a topic id and expire them.
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
export declare function cleanupSingleSession(client: SignClient, topic: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* Disconnect means to delete the session on both parties (dApp & wallet) at the same time.
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
export declare function disconnectSessions(client: SignClient): Promise<void[]>;
|
|
53
|
+
export declare function getAccountsFromSession(session: SessionTypes.Struct): {
|
|
54
|
+
accounts: string[];
|
|
55
|
+
chainId: string;
|
|
56
|
+
}[];
|
|
57
|
+
export declare function getAccountsFromEvent(event: SignClientTypes.BaseEventArgs<{
|
|
58
|
+
namespaces: SessionTypes.Namespaces;
|
|
59
|
+
}>): {
|
|
60
|
+
accounts: string[];
|
|
61
|
+
chainId: string;
|
|
62
|
+
}[];
|
|
63
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC/E,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAW9B,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAWzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,uBAEhD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,CAAC,MAAM,GAC3B,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,CAW1C;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAiC9B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,GACjB,YAAY,CAAC,MAAM,GAAG,SAAS,CAMjC;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAkC9B;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,UAAU,EACpB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CA0B9B;AAoBD;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAiB3E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,UAAU,mBAwB1D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,CAAC,MAAM;;;IAgBlE;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,CAAC,aAAa,CAAC;IACnC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC;CACrC,CAAC;;;IAeH"}
|
package/dist/signer.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKrC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,QAAQ,EAAE,UAAU,GAAG,aAAa,CAoBtE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SignClient } from '@walletconnect/sign-client/dist/types/client';
|
|
2
|
+
import { SessionTypes } from '@walletconnect/types';
|
|
3
|
+
import type { GenericSigner } from 'rango-types';
|
|
4
|
+
import { CosmosTransaction } from 'rango-types';
|
|
5
|
+
declare class COSMOSSigner implements GenericSigner<CosmosTransaction> {
|
|
6
|
+
private client;
|
|
7
|
+
private session;
|
|
8
|
+
constructor(client: SignClient, session: SessionTypes.Struct);
|
|
9
|
+
signMessage(): Promise<string>;
|
|
10
|
+
signAndSendTx(tx: CosmosTransaction, address: string, chainId: string | null): Promise<{
|
|
11
|
+
hash: string;
|
|
12
|
+
}>;
|
|
13
|
+
private isNetworkAndAccountExistInSession;
|
|
14
|
+
}
|
|
15
|
+
export default COSMOSSigner;
|
|
16
|
+
//# sourceMappingURL=cosmos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cosmos.d.ts","sourceRoot":"","sources":["../../src/signers/cosmos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAe,iBAAiB,EAAmB,MAAM,aAAa,CAAC;AA8B9E,cAAM,YAAa,YAAW,aAAa,CAAC,iBAAiB,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM;IAK/C,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAIrC,aAAa,CACjB,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAoJ5B,OAAO,CAAC,iCAAiC;CAyC1C;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SignClient } from '@walletconnect/sign-client/dist/types/client';
|
|
2
|
+
import { SessionTypes } from '@walletconnect/types';
|
|
3
|
+
import type { GenericSigner } from 'rango-types';
|
|
4
|
+
import { EvmTransaction } from 'rango-types/lib/api/main';
|
|
5
|
+
declare class EVMSigner implements GenericSigner<EvmTransaction> {
|
|
6
|
+
private client;
|
|
7
|
+
private session;
|
|
8
|
+
constructor(client: SignClient, session: SessionTypes.Struct);
|
|
9
|
+
signMessage(msg: string, address: string, chainId: string | null): Promise<string>;
|
|
10
|
+
signAndSendTx(tx: EvmTransaction, address: string, chainId: string | null): Promise<{
|
|
11
|
+
hash: string;
|
|
12
|
+
}>;
|
|
13
|
+
private isNetworkAndAccountExistInSession;
|
|
14
|
+
}
|
|
15
|
+
export default EVMSigner;
|
|
16
|
+
//# sourceMappingURL=evm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/signers/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,cAAM,SAAU,YAAW,aAAa,CAAC,cAAc,CAAC;IACtD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM;IAK/C,WAAW,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,CAAC;IA8BZ,aAAa,CACjB,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAoB5B,OAAO,CAAC,iCAAiC;CAsD1C;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/signers/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAqB,MAAM,aAAa,CAAC;AAChE,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,EAChC,eAAe,EAAE,cAAc,EAAE,GAChC,OAAO,CAAC,UAAU,CAAC,CAgErB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/signers/mock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,eAAe,EAAE,cAAc,EAwlH3C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SignClient } from '@walletconnect/sign-client/dist/types/client';
|
|
2
|
+
import { SessionTypes } from '@walletconnect/types';
|
|
3
|
+
import type { GenericSigner, SolanaTransaction } from 'rango-types';
|
|
4
|
+
declare class SOLANASigner implements GenericSigner<SolanaTransaction> {
|
|
5
|
+
private client;
|
|
6
|
+
private session;
|
|
7
|
+
constructor(client: SignClient, session: SessionTypes.Struct);
|
|
8
|
+
signMessage(msg: string, address: string, chainId: string | null): Promise<string>;
|
|
9
|
+
signAndSendTx(tx: SolanaTransaction, address: string, chainId: string | null): Promise<{
|
|
10
|
+
hash: string;
|
|
11
|
+
}>;
|
|
12
|
+
private isNetworkAndAccountExistInSession;
|
|
13
|
+
}
|
|
14
|
+
export default SOLANASigner;
|
|
15
|
+
//# sourceMappingURL=solana.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../src/signers/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAWpE,cAAM,YAAa,YAAW,aAAa,CAAC,iBAAiB,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM;IAK/C,WAAW,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,CAAC;IAkCZ,aAAa,CACjB,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAgC5B,OAAO,CAAC,iCAAiC;CAuD1C;AAED,eAAe,YAAY,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SignClient } from '@walletconnect/sign-client/dist/types/client';
|
|
2
|
+
import type { ProposalTypes, SessionTypes } from '@walletconnect/types';
|
|
3
|
+
import type { BlockchainMeta, CosmosBlockchainMeta } from 'rango-types/lib';
|
|
4
|
+
export interface WCInstance {
|
|
5
|
+
client: SignClient;
|
|
6
|
+
session: SessionTypes.Struct | null;
|
|
7
|
+
request: (params: any) => Promise<string>;
|
|
8
|
+
}
|
|
9
|
+
export interface CreateSessionParams {
|
|
10
|
+
requiredNamespaces: ProposalTypes.RequiredNamespaces;
|
|
11
|
+
optionalNamespaces?: ProposalTypes.OptionalNamespaces;
|
|
12
|
+
pairingTopic?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConnectParams {
|
|
15
|
+
network: string;
|
|
16
|
+
meta: BlockchainMeta[];
|
|
17
|
+
}
|
|
18
|
+
export interface CosmosMeta extends CosmosBlockchainMeta {
|
|
19
|
+
chainId: string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,EAAE,aAAa,CAAC,kBAAkB,CAAC;IACrD,kBAAkB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IAEtD,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rango-dev/provider-walletconnect-2",
|
|
3
|
+
"version": "0.1.1-next.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"typings": "dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"src"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "node ../../scripts/build/command.mjs --path wallets/provider-walletconnect-2",
|
|
18
|
+
"clean": "rimraf dist",
|
|
19
|
+
"format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
|
|
20
|
+
"lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@keplr-wallet/simple-fetch": "^0.12.14",
|
|
24
|
+
"@rango-dev/signer-evm": "^0.8.1-next.2",
|
|
25
|
+
"@rango-dev/wallets-shared": "^0.8.1-next.2",
|
|
26
|
+
"@walletconnect/encoding": "^1.0.2",
|
|
27
|
+
"@walletconnect/sign-client": "^2.8.1",
|
|
28
|
+
"@walletconnect/utils": "^2.9.1",
|
|
29
|
+
"@web3modal/standalone": "^2.4.3",
|
|
30
|
+
"bs58": "^5.0.0",
|
|
31
|
+
"caip": "^1.1.0",
|
|
32
|
+
"cosmos-wallet": "^1.2.0",
|
|
33
|
+
"rango-types": "^0.1.47"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@walletconnect/types": "^2.8.1"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# @rango-dev/provider-walletconnect2
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Known issues
|
|
5
|
+
|
|
6
|
+
- Trust wallet doesn't return optional namespaces other than evms on its response. So Solana and Cosmos will be ask for connect in wallet but we can not use them.
|
|
7
|
+
- Using Private key to import wallets other than `Ethereum` will be problematic. Because it imports only a single blockchain and we are by default asking for `Ethereum`.
|
|
8
|
+
- Signing a transaction on Metamask goes through an internal error.
|
|
9
|
+
- We couldn't update exist session during a bug in `@walletconnect/utils`, so we are creating new session for accessing to new chains.
|
|
10
|
+
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Networks } from '@rango-dev/wallets-shared';
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_NETWORK = Networks.ETHEREUM;
|
|
4
|
+
export const PING_TIMEOUT = 10_000;
|
|
5
|
+
|
|
6
|
+
export enum NAMESPACES {
|
|
7
|
+
ETHEREUM = 'eip155',
|
|
8
|
+
SOLANA = 'solana',
|
|
9
|
+
COSMOS = 'cosmos',
|
|
10
|
+
POLKADOT = 'polkadot',
|
|
11
|
+
CARDANO = 'cip34',
|
|
12
|
+
ERLOND = 'elrond',
|
|
13
|
+
MULTIVERSX = 'multiversx',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/solana-rpc
|
|
17
|
+
export enum SolanaRPCMethods {
|
|
18
|
+
GET_ACCOUNTS = 'solana_getAccounts',
|
|
19
|
+
REQUEST_ACCOUNTS = 'solana_requestAccounts',
|
|
20
|
+
SIGN_TRANSACTION = 'solana_signTransaction',
|
|
21
|
+
SIGN_MESSAGE = 'solana_signMessage',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/cosmos-rpc
|
|
25
|
+
export enum CosmosRPCMethods {
|
|
26
|
+
GET_ACCOUNTS = 'cosmos_getAccounts',
|
|
27
|
+
SIGN_DIRECT = 'cosmos_signDirect',
|
|
28
|
+
SIGN_AMINO = 'cosmos_signAmino',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/ethereum-rpc
|
|
32
|
+
export enum EthereumRPCMethods {
|
|
33
|
+
PERSONAL_SIGN = 'personal_sign',
|
|
34
|
+
SIGN = 'eth_sign',
|
|
35
|
+
SIGN_TYPED_DATA = 'eth_signTypedData',
|
|
36
|
+
SIGN_TRANSACTION = 'eth_signTransaction',
|
|
37
|
+
SEND_TRANSACTION = 'eth_sendTransaction',
|
|
38
|
+
SEND_RAW_TRANSACTION = 'eth_sendRawTransaction',
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export enum StarknetRPCMethods {
|
|
42
|
+
REQUEST_ADD_INVOKE_TRANSACTION = 'starknet_requestAddInvokeTransaction',
|
|
43
|
+
SIGN_TYPED_DATA = 'starknet_signTypedData',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export enum EthereumEvents {
|
|
47
|
+
CHAIN_CHANGED = 'chainChanged',
|
|
48
|
+
ACCOUNTS_CHANGED = 'accountsChanged',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const DEFAULT_ETHEREUM_EVENTS: EthereumEvents[] = [
|
|
52
|
+
EthereumEvents.CHAIN_CHANGED,
|
|
53
|
+
EthereumEvents.ACCOUNTS_CHANGED,
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export const DEFAULT_ETHEREUM_METHODS = [
|
|
57
|
+
EthereumRPCMethods.PERSONAL_SIGN,
|
|
58
|
+
EthereumRPCMethods.SEND_TRANSACTION,
|
|
59
|
+
EthereumRPCMethods.SIGN_TRANSACTION,
|
|
60
|
+
];
|
|
61
|
+
export const DEFAULT_SOLANA_METHODS = [
|
|
62
|
+
SolanaRPCMethods.SIGN_TRANSACTION,
|
|
63
|
+
SolanaRPCMethods.SIGN_MESSAGE,
|
|
64
|
+
];
|
|
65
|
+
export const DEFAULT_COSMOS_METHODS = [
|
|
66
|
+
CosmosRPCMethods.GET_ACCOUNTS,
|
|
67
|
+
CosmosRPCMethods.SIGN_AMINO,
|
|
68
|
+
CosmosRPCMethods.SIGN_DIRECT,
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
// refrence: https://github.com/ChainAgnostic/namespaces/blob/main/solana/caip2.md
|
|
72
|
+
export const DEFAULT_SOLANA_CHAIN_ID = '4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ';
|
|
73
|
+
|
|
74
|
+
export const DEFAULT_APP_METADATA = {
|
|
75
|
+
name: 'Rango Exchange',
|
|
76
|
+
description:
|
|
77
|
+
'Easiest DEX UX with best price to exchange all coins on all blockchains.',
|
|
78
|
+
url: 'https://app.rango.exchange/',
|
|
79
|
+
icons: ['https://avatars.githubusercontent.com/u/37784886'],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const PROJECT_ID = 'f5196d081862c6f2b81c04520ea9301c';
|
|
83
|
+
export const RELAY_URL = 'wss://relay.walletconnect.com';
|
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { WalletState } from '@rango-dev/wallets-shared';
|
|
2
|
+
import { Networks } from '@rango-dev/wallets-shared';
|
|
3
|
+
import { ProposalTypes } from '@walletconnect/types';
|
|
4
|
+
import { ChainId } from 'caip';
|
|
5
|
+
import { BlockchainMeta, cosmosBlockchains, evmBlockchains } from 'rango-types';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
DEFAULT_COSMOS_METHODS,
|
|
9
|
+
DEFAULT_ETHEREUM_EVENTS,
|
|
10
|
+
DEFAULT_ETHEREUM_METHODS,
|
|
11
|
+
DEFAULT_SOLANA_CHAIN_ID,
|
|
12
|
+
DEFAULT_SOLANA_METHODS,
|
|
13
|
+
NAMESPACES,
|
|
14
|
+
} from './constants';
|
|
15
|
+
import { getLastSession } from './session';
|
|
16
|
+
import { CosmosMeta } from './types';
|
|
17
|
+
|
|
18
|
+
type FinalNamespaces = {
|
|
19
|
+
[key in NAMESPACES]?: ProposalTypes.BaseRequiredNamespace;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function generateRequiredNamespace(
|
|
23
|
+
meta: BlockchainMeta[],
|
|
24
|
+
network: string
|
|
25
|
+
): FinalNamespaces | undefined {
|
|
26
|
+
const evm = evmBlockchains(meta);
|
|
27
|
+
const cosmos = cosmosBlockchains(meta);
|
|
28
|
+
|
|
29
|
+
const requiredEvmChain = evm.find((chain) => chain.name === network);
|
|
30
|
+
const requiredCosmosChain = cosmos.find((chain) => chain.name === network);
|
|
31
|
+
const requiredSolanaChain = network === Networks.SOLANA;
|
|
32
|
+
|
|
33
|
+
if (requiredEvmChain) {
|
|
34
|
+
return {
|
|
35
|
+
[NAMESPACES.ETHEREUM]: {
|
|
36
|
+
events: DEFAULT_ETHEREUM_EVENTS,
|
|
37
|
+
methods: DEFAULT_ETHEREUM_METHODS,
|
|
38
|
+
chains: [
|
|
39
|
+
new ChainId({
|
|
40
|
+
namespace: NAMESPACES.ETHEREUM,
|
|
41
|
+
reference: String(parseInt(requiredEvmChain.chainId)),
|
|
42
|
+
}).toString(),
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
} else if (!!requiredCosmosChain) {
|
|
47
|
+
return {
|
|
48
|
+
[NAMESPACES.COSMOS]: {
|
|
49
|
+
events: [],
|
|
50
|
+
methods: DEFAULT_COSMOS_METHODS,
|
|
51
|
+
chains: [
|
|
52
|
+
new ChainId({
|
|
53
|
+
namespace: NAMESPACES.COSMOS,
|
|
54
|
+
reference: requiredCosmosChain.chainId!,
|
|
55
|
+
}).toString(),
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
} else if (requiredSolanaChain) {
|
|
60
|
+
return {
|
|
61
|
+
[NAMESPACES.SOLANA]: {
|
|
62
|
+
events: [],
|
|
63
|
+
methods: DEFAULT_SOLANA_METHODS,
|
|
64
|
+
chains: [`solana:${DEFAULT_SOLANA_CHAIN_ID}`],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function generateOptionalNamespace(
|
|
73
|
+
meta: BlockchainMeta[]
|
|
74
|
+
): FinalNamespaces | undefined {
|
|
75
|
+
const evm = evmBlockchains(meta);
|
|
76
|
+
const cosmos = cosmosBlockchains(meta);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
[NAMESPACES.ETHEREUM]: {
|
|
80
|
+
methods: DEFAULT_ETHEREUM_METHODS,
|
|
81
|
+
events: DEFAULT_ETHEREUM_EVENTS,
|
|
82
|
+
chains: evm.map((chain) => {
|
|
83
|
+
return new ChainId({
|
|
84
|
+
namespace: NAMESPACES.ETHEREUM,
|
|
85
|
+
reference: String(parseInt(chain.chainId)),
|
|
86
|
+
}).toString();
|
|
87
|
+
}),
|
|
88
|
+
},
|
|
89
|
+
[NAMESPACES.COSMOS]: {
|
|
90
|
+
methods: DEFAULT_COSMOS_METHODS,
|
|
91
|
+
events: [],
|
|
92
|
+
chains: cosmos
|
|
93
|
+
.filter((chain): chain is CosmosMeta => !!chain.chainId)
|
|
94
|
+
.map((chain) => {
|
|
95
|
+
return new ChainId({
|
|
96
|
+
namespace: NAMESPACES.COSMOS,
|
|
97
|
+
reference: chain.chainId,
|
|
98
|
+
}).toString();
|
|
99
|
+
}),
|
|
100
|
+
},
|
|
101
|
+
[NAMESPACES.SOLANA]: {
|
|
102
|
+
methods: DEFAULT_SOLANA_METHODS,
|
|
103
|
+
events: [],
|
|
104
|
+
chains: [`solana:${DEFAULT_SOLANA_CHAIN_ID}`],
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function solanaChainIdToNetworkName(chainId: string): string {
|
|
110
|
+
return chainId === DEFAULT_SOLANA_CHAIN_ID ? Networks.SOLANA : chainId;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
* In `rango-preset` we are working with `window.ethereum.request()`,
|
|
116
|
+
* this is an interceptor for some RPC methods (e.g. eth_chainId).
|
|
117
|
+
*
|
|
118
|
+
*/
|
|
119
|
+
export async function simulateRequest(
|
|
120
|
+
params: any,
|
|
121
|
+
provider: any,
|
|
122
|
+
meta: BlockchainMeta[],
|
|
123
|
+
getState: () => WalletState
|
|
124
|
+
) {
|
|
125
|
+
if (params.method === 'eth_chainId') {
|
|
126
|
+
const currentSession = getLastSession(provider);
|
|
127
|
+
const standaloneChains = Object.values(currentSession.namespaces)
|
|
128
|
+
.map((namespace) => namespace.chains)
|
|
129
|
+
.flat() as string[];
|
|
130
|
+
|
|
131
|
+
const network = getState().network;
|
|
132
|
+
|
|
133
|
+
if (standaloneChains.length > 0) {
|
|
134
|
+
const chainId = network
|
|
135
|
+
? getChainIdByNetworkName(network, meta)
|
|
136
|
+
: undefined;
|
|
137
|
+
|
|
138
|
+
if (chainId) {
|
|
139
|
+
return chainId;
|
|
140
|
+
} else {
|
|
141
|
+
const firstChain = standaloneChains[0];
|
|
142
|
+
const chainId = new ChainId(firstChain);
|
|
143
|
+
return chainId.reference;
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error(`Couldn't find any chain on namespace`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
throw new Error('Dissallowed method:', params);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function getChainIdByNetworkName(
|
|
153
|
+
network: string,
|
|
154
|
+
meta: BlockchainMeta[]
|
|
155
|
+
): string | undefined {
|
|
156
|
+
const targetBlockchain = meta.find(
|
|
157
|
+
(blockchain) => blockchain.name === network
|
|
158
|
+
);
|
|
159
|
+
const chainIdInHex = targetBlockchain?.chainId;
|
|
160
|
+
if (!chainIdInHex) return undefined;
|
|
161
|
+
|
|
162
|
+
const chainId = String(parseInt(chainIdInHex));
|
|
163
|
+
|
|
164
|
+
return chainId;
|
|
165
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WalletTypes,
|
|
3
|
+
CanSwitchNetwork,
|
|
4
|
+
Connect,
|
|
5
|
+
Disconnect,
|
|
6
|
+
GetInstance,
|
|
7
|
+
Subscribe,
|
|
8
|
+
SwitchNetwork,
|
|
9
|
+
WalletConfig,
|
|
10
|
+
WalletInfo,
|
|
11
|
+
} from '@rango-dev/wallets-shared';
|
|
12
|
+
import { SignerFactory, BlockchainMeta } from 'rango-types';
|
|
13
|
+
import type { ISignClient } from '@walletconnect/types';
|
|
14
|
+
import Client from '@walletconnect/sign-client';
|
|
15
|
+
|
|
16
|
+
import signer from './signer';
|
|
17
|
+
import {
|
|
18
|
+
disconnectSessions,
|
|
19
|
+
cleanupSingleSession,
|
|
20
|
+
getAccountsFromEvent,
|
|
21
|
+
getAccountsFromSession,
|
|
22
|
+
tryConnect,
|
|
23
|
+
trySwitchByCreatingNewSession,
|
|
24
|
+
} from './session';
|
|
25
|
+
import {
|
|
26
|
+
DEFAULT_APP_METADATA,
|
|
27
|
+
DEFAULT_NETWORK,
|
|
28
|
+
EthereumEvents,
|
|
29
|
+
PROJECT_ID,
|
|
30
|
+
RELAY_URL,
|
|
31
|
+
} from './constants';
|
|
32
|
+
import { simulateRequest } from './helpers';
|
|
33
|
+
import type { WCInstance } from './types';
|
|
34
|
+
|
|
35
|
+
const WALLET = WalletTypes.WALLET_CONNECT_2;
|
|
36
|
+
|
|
37
|
+
export const config: WalletConfig = {
|
|
38
|
+
type: WALLET,
|
|
39
|
+
checkInstallation: false,
|
|
40
|
+
isAsyncInstance: true,
|
|
41
|
+
defaultNetwork: DEFAULT_NETWORK,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const getInstance: GetInstance = async (options) => {
|
|
45
|
+
const { currentProvider, getState, meta } = options;
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
Create a new pair, if exists use the pair,
|
|
49
|
+
Or use the already created one.
|
|
50
|
+
*/
|
|
51
|
+
let provider: ISignClient;
|
|
52
|
+
if (!currentProvider) {
|
|
53
|
+
provider = await Client.init({
|
|
54
|
+
relayUrl: RELAY_URL,
|
|
55
|
+
projectId: PROJECT_ID,
|
|
56
|
+
metadata: DEFAULT_APP_METADATA,
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
provider = currentProvider;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
client: provider,
|
|
64
|
+
session: null,
|
|
65
|
+
request: (params: any) => simulateRequest(params, provider, meta, getState),
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const connect: Connect = async ({ instance, network, meta }) => {
|
|
70
|
+
const { client } = instance as WCInstance;
|
|
71
|
+
|
|
72
|
+
const requestedNetwork = network || DEFAULT_NETWORK;
|
|
73
|
+
|
|
74
|
+
// Try to restore the session first, if couldn't, create a new session by showing a modal.
|
|
75
|
+
const session = await tryConnect(client, {
|
|
76
|
+
network: requestedNetwork,
|
|
77
|
+
meta,
|
|
78
|
+
});
|
|
79
|
+
// Override the value (session).
|
|
80
|
+
instance.session = session;
|
|
81
|
+
|
|
82
|
+
const accounts = getAccountsFromSession(session);
|
|
83
|
+
return accounts;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const subscribe: Subscribe = ({
|
|
87
|
+
instance,
|
|
88
|
+
updateChainId,
|
|
89
|
+
updateAccounts,
|
|
90
|
+
disconnect,
|
|
91
|
+
}) => {
|
|
92
|
+
const { client } = instance as WCInstance;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Session events refrence:
|
|
96
|
+
* https://docs.walletconnect.com/2.0/specs/clients/sign/session-events
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
// Listen to updating the session by adding a new chain, method, or event
|
|
100
|
+
client.on('session_update', (args) => {
|
|
101
|
+
const allAccounts = getAccountsFromEvent(args);
|
|
102
|
+
allAccounts.forEach((accountsWithChain) => {
|
|
103
|
+
updateAccounts(accountsWithChain.accounts, accountsWithChain.chainId);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Listen to events triggred by wallet. (e.g. accountsChanged and chainChanged)
|
|
108
|
+
client.on('session_event', (args) => {
|
|
109
|
+
if (args.params.event.name === EthereumEvents.ACCOUNTS_CHANGED) {
|
|
110
|
+
const accounts = args.params.event.data;
|
|
111
|
+
const chainId = args.params.chainId;
|
|
112
|
+
updateAccounts(accounts);
|
|
113
|
+
updateChainId(chainId);
|
|
114
|
+
} else if (args.params.event.name === EthereumEvents.CHAIN_CHANGED) {
|
|
115
|
+
const chainId = args.params.chainId;
|
|
116
|
+
updateChainId(chainId);
|
|
117
|
+
} else {
|
|
118
|
+
console.log('[WC2] session_event not supported', args.params.event);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
client.on('session_delete', async (event) => {
|
|
123
|
+
console.log('[WC2] your wallet has requested to delete session.', event);
|
|
124
|
+
cleanupSingleSession(client, event.topic);
|
|
125
|
+
disconnect();
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const switchNetwork: SwitchNetwork = async ({
|
|
130
|
+
network,
|
|
131
|
+
instance,
|
|
132
|
+
meta,
|
|
133
|
+
}) => {
|
|
134
|
+
/**
|
|
135
|
+
* Wallet connect is a multichain protocol and we can not determine the connected wallet
|
|
136
|
+
* supports which wallet, `extend`ing session doesn't work during a bug in their utils packages.
|
|
137
|
+
* So we will try to make a new session with `network` that user needs to switch.
|
|
138
|
+
*/
|
|
139
|
+
const session = await trySwitchByCreatingNewSession(instance, {
|
|
140
|
+
network,
|
|
141
|
+
meta,
|
|
142
|
+
});
|
|
143
|
+
instance.session = session;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
* Note:
|
|
149
|
+
* There is no straight-forward way to detect the wallet supports which blockchain,
|
|
150
|
+
* So we send request to wallet and expect to be rejected on the wallet if it's not supported.
|
|
151
|
+
*
|
|
152
|
+
*/
|
|
153
|
+
export const canSwitchNetworkTo: CanSwitchNetwork = () => true;
|
|
154
|
+
|
|
155
|
+
export const disconnect: Disconnect = async ({ instance }) => {
|
|
156
|
+
const { client } = instance as WCInstance;
|
|
157
|
+
|
|
158
|
+
if (client) {
|
|
159
|
+
disconnectSessions(client);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const getSigners: (provider: WCInstance) => SignerFactory = signer;
|
|
164
|
+
|
|
165
|
+
export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
|
|
166
|
+
allBlockChains
|
|
167
|
+
) => {
|
|
168
|
+
return {
|
|
169
|
+
name: 'WalletConnect',
|
|
170
|
+
img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/walletconnect.svg',
|
|
171
|
+
installLink: '',
|
|
172
|
+
color: '#b2dbff',
|
|
173
|
+
supportedChains: allBlockChains,
|
|
174
|
+
showOnMobile: true,
|
|
175
|
+
mobileWallet: true,
|
|
176
|
+
};
|
|
177
|
+
};
|