@turnkey/core 1.0.0-beta.2 → 1.0.0-beta.5
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/__clients__/core.d.ts +92 -9
- package/dist/__clients__/core.d.ts.map +1 -1
- package/dist/__clients__/core.js +699 -535
- package/dist/__clients__/core.js.map +1 -1
- package/dist/__clients__/core.mjs +702 -538
- package/dist/__clients__/core.mjs.map +1 -1
- package/dist/__generated__/sdk-client-base.d.ts +1 -1
- package/dist/__generated__/sdk-client-base.d.ts.map +1 -1
- package/dist/__generated__/sdk-client-base.js +156 -253
- package/dist/__generated__/sdk-client-base.js.map +1 -1
- package/dist/__generated__/sdk-client-base.mjs +156 -253
- package/dist/__generated__/sdk-client-base.mjs.map +1 -1
- package/dist/__generated__/version.d.ts +1 -1
- package/dist/__generated__/version.js +1 -1
- package/dist/__generated__/version.mjs +1 -1
- package/dist/__inputs__/public_api.types.d.ts +377 -504
- package/dist/__inputs__/public_api.types.d.ts.map +1 -1
- package/dist/__types__/base.d.ts +193 -75
- package/dist/__types__/base.d.ts.map +1 -1
- package/dist/__types__/base.js +14 -13
- package/dist/__types__/base.js.map +1 -1
- package/dist/__types__/base.mjs +15 -14
- package/dist/__types__/base.mjs.map +1 -1
- package/dist/__wallet__/base.d.ts +11 -0
- package/dist/__wallet__/base.d.ts.map +1 -1
- package/dist/__wallet__/base.js +12 -1
- package/dist/__wallet__/base.js.map +1 -1
- package/dist/__wallet__/base.mjs +12 -1
- package/dist/__wallet__/base.mjs.map +1 -1
- package/dist/__wallet__/connector.d.ts +31 -4
- package/dist/__wallet__/connector.d.ts.map +1 -1
- package/dist/__wallet__/connector.js +35 -5
- package/dist/__wallet__/connector.js.map +1 -1
- package/dist/__wallet__/connector.mjs +35 -5
- package/dist/__wallet__/connector.mjs.map +1 -1
- package/dist/__wallet__/mobile/manager.d.ts +21 -5
- package/dist/__wallet__/mobile/manager.d.ts.map +1 -1
- package/dist/__wallet__/mobile/manager.js +28 -11
- package/dist/__wallet__/mobile/manager.js.map +1 -1
- package/dist/__wallet__/mobile/manager.mjs +28 -11
- package/dist/__wallet__/mobile/manager.mjs.map +1 -1
- package/dist/__wallet__/stamper.d.ts +73 -2
- package/dist/__wallet__/stamper.d.ts.map +1 -1
- package/dist/__wallet__/stamper.js +81 -15
- package/dist/__wallet__/stamper.js.map +1 -1
- package/dist/__wallet__/stamper.mjs +82 -16
- package/dist/__wallet__/stamper.mjs.map +1 -1
- package/dist/__wallet__/wallet-connect/base.d.ts +102 -19
- package/dist/__wallet__/wallet-connect/base.d.ts.map +1 -1
- package/dist/__wallet__/wallet-connect/base.js +198 -77
- package/dist/__wallet__/wallet-connect/base.js.map +1 -1
- package/dist/__wallet__/wallet-connect/base.mjs +198 -77
- package/dist/__wallet__/wallet-connect/base.mjs.map +1 -1
- package/dist/__wallet__/wallet-connect/client.d.ts +50 -17
- package/dist/__wallet__/wallet-connect/client.d.ts.map +1 -1
- package/dist/__wallet__/wallet-connect/client.js +76 -19
- package/dist/__wallet__/wallet-connect/client.js.map +1 -1
- package/dist/__wallet__/wallet-connect/client.mjs +76 -19
- package/dist/__wallet__/wallet-connect/client.mjs.map +1 -1
- package/dist/__wallet__/web/manager.d.ts +20 -12
- package/dist/__wallet__/web/manager.d.ts.map +1 -1
- package/dist/__wallet__/web/manager.js +29 -21
- package/dist/__wallet__/web/manager.js.map +1 -1
- package/dist/__wallet__/web/manager.mjs +29 -21
- package/dist/__wallet__/web/manager.mjs.map +1 -1
- package/dist/__wallet__/web/native/ethereum.d.ts +45 -11
- package/dist/__wallet__/web/native/ethereum.d.ts.map +1 -1
- package/dist/__wallet__/web/native/ethereum.js +58 -17
- package/dist/__wallet__/web/native/ethereum.js.map +1 -1
- package/dist/__wallet__/web/native/ethereum.mjs +58 -17
- package/dist/__wallet__/web/native/ethereum.mjs.map +1 -1
- package/dist/__wallet__/web/native/solana.d.ts +56 -3
- package/dist/__wallet__/web/native/solana.d.ts.map +1 -1
- package/dist/__wallet__/web/native/solana.js +95 -36
- package/dist/__wallet__/web/native/solana.js.map +1 -1
- package/dist/__wallet__/web/native/solana.mjs +95 -36
- package/dist/__wallet__/web/native/solana.mjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/utils.d.ts +59 -13
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +105 -30
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +103 -29
- package/dist/utils.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -8,14 +8,28 @@ export declare class WalletConnectWallet implements WalletConnectInterface {
|
|
|
8
8
|
private ethChain;
|
|
9
9
|
private solChain;
|
|
10
10
|
private uri?;
|
|
11
|
+
private changeListeners;
|
|
12
|
+
private addChangeListener;
|
|
13
|
+
private notifyChange;
|
|
14
|
+
/**
|
|
15
|
+
* Constructs a WalletConnectWallet bound to a WalletConnect client.
|
|
16
|
+
*
|
|
17
|
+
* - Subscribes to session deletions and automatically re-initiates pairing,
|
|
18
|
+
* updating `this.uri` so the UI can present a fresh QR/deeplink.
|
|
19
|
+
*
|
|
20
|
+
* @param client - The low-level WalletConnect client used for session/RPC.
|
|
21
|
+
*/
|
|
11
22
|
constructor(client: WalletConnectClient);
|
|
12
23
|
/**
|
|
13
|
-
* Initializes WalletConnect pairing flow with the specified
|
|
14
|
-
*
|
|
24
|
+
* Initializes WalletConnect pairing flow with the specified namespaces.
|
|
25
|
+
*
|
|
26
|
+
* - Saves the requested chain namespaces (e.g., `["eip155:1", "eip155:137", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]`).
|
|
27
|
+
* - If an active session already has connected accounts, pairing is skipped.
|
|
28
|
+
* - Otherwise initiates a pairing and stores the resulting URI.
|
|
15
29
|
*
|
|
16
|
-
* @param opts.
|
|
17
|
-
* @param opts.
|
|
18
|
-
* @throws {Error} If no
|
|
30
|
+
* @param opts.ethereumNamespaces - List of EVM CAIP IDs (e.g., "eip155:1").
|
|
31
|
+
* @param opts.solanaNamespaces - List of Solana CAIP IDs (e.g., "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp").
|
|
32
|
+
* @throws {Error} If no namespaces are provided for either chain.
|
|
19
33
|
*/
|
|
20
34
|
init(opts: {
|
|
21
35
|
ethereumNamespaces: string[];
|
|
@@ -23,61 +37,130 @@ export declare class WalletConnectWallet implements WalletConnectInterface {
|
|
|
23
37
|
}): Promise<void>;
|
|
24
38
|
/**
|
|
25
39
|
* Returns WalletConnect providers with associated chain/account metadata.
|
|
40
|
+
*
|
|
41
|
+
* - Builds an EVM provider (if Ethereum namespaces are enabled).
|
|
42
|
+
* - Builds a Solana provider (if Solana namespaces are enabled).
|
|
43
|
+
*
|
|
44
|
+
* @returns A promise resolving to an array of WalletProvider objects.
|
|
26
45
|
*/
|
|
27
46
|
getProviders(): Promise<WalletProvider[]>;
|
|
28
47
|
/**
|
|
29
48
|
* Approves the session if needed and ensures at least one account is available.
|
|
49
|
+
*
|
|
50
|
+
* - Calls `approve()` on the underlying client when pairing is pending.
|
|
51
|
+
* - Throws if the approved session contains no connected accounts.
|
|
52
|
+
*
|
|
53
|
+
* @param _provider - Unused (present for interface compatibility).
|
|
54
|
+
* @throws {Error} If the session contains no accounts.
|
|
30
55
|
*/
|
|
31
56
|
connectWalletAccount(_provider: WalletProvider): Promise<void>;
|
|
32
57
|
/**
|
|
33
|
-
*
|
|
58
|
+
* Switches the user’s WalletConnect session to a new EVM chain.
|
|
34
59
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
60
|
+
* - Ethereum-only: only supported for providers on the Ethereum namespace.
|
|
61
|
+
* - No add-then-switch: WalletConnect cannot add chains mid-session. The target chain
|
|
62
|
+
* must be present in `ethereumNamespaces` negotiated at pairing time. To support a new chain,
|
|
63
|
+
* you must include it in the walletConfig.
|
|
64
|
+
* - Accepts a hex chain ID (e.g., "0x1"). If a `SwitchableChain` is passed, only its `id`
|
|
65
|
+
* (hex chain ID) is used; metadata is ignored for WalletConnect.
|
|
66
|
+
*
|
|
67
|
+
* @param provider - The WalletProvider returned by `getProviders()`.
|
|
68
|
+
* @param chainOrId - Hex chain ID (e.g., "0x1") or a `SwitchableChain` (its `id` is used).
|
|
69
|
+
* @returns A promise that resolves when the switch completes.
|
|
70
|
+
* @throws {Error} If no active session, provider is non-EVM, the chain is not in `ethereumNamespaces`,
|
|
71
|
+
* or the switch RPC fails.
|
|
39
72
|
*/
|
|
40
73
|
switchChain(provider: WalletProvider, chainOrId: string | SwitchableChain): Promise<void>;
|
|
41
74
|
/**
|
|
42
|
-
* Signs a message or transaction using the specified provider and intent.
|
|
75
|
+
* Signs a message or transaction using the specified wallet provider and intent.
|
|
76
|
+
*
|
|
77
|
+
* - Ensures an active WalletConnect session:
|
|
78
|
+
* - If a pairing is in progress (URI shown but not yet approved), this call will
|
|
79
|
+
* wait for the user to approve the session and may appear stuck until they do.
|
|
80
|
+
* - If no pairing is in progress, this will throw (e.g., "call pair() before approve()").
|
|
81
|
+
* - Ethereum:
|
|
82
|
+
* - `SignMessage` → `personal_sign` (returns hex signature).
|
|
83
|
+
* - `SignAndSendTransaction` → `eth_sendTransaction` (returns tx hash).
|
|
84
|
+
* - Solana:
|
|
85
|
+
* - `SignMessage` → `solana_signMessage` (returns hex signature).
|
|
86
|
+
* - `SignTransaction` → `solana_signTransaction` (returns hex signature).
|
|
87
|
+
* - `SignAndSendTransaction` → `solana_sendTransaction` (returns hex signature of the submitted tx).
|
|
43
88
|
*
|
|
44
|
-
* @param
|
|
89
|
+
* @param payload - Payload or serialized transaction to sign.
|
|
45
90
|
* @param provider - The WalletProvider to use.
|
|
46
|
-
* @param intent - The
|
|
91
|
+
* @param intent - The signing intent.
|
|
92
|
+
* @returns A hex string (signature or transaction hash, depending on intent).
|
|
93
|
+
* @throws {Error} If no account is available, no pairing is in progress, or the intent is unsupported.
|
|
47
94
|
*/
|
|
48
|
-
sign(
|
|
95
|
+
sign(payload: string, provider: WalletProvider, intent: SignIntent): Promise<string>;
|
|
49
96
|
/**
|
|
50
97
|
* Retrieves the public key of the connected wallet.
|
|
51
98
|
*
|
|
99
|
+
* - Ethereum: signs a fixed challenge and recovers the compressed secp256k1 public key.
|
|
100
|
+
* - Solana: decodes the base58-encoded address to raw bytes.
|
|
101
|
+
*
|
|
52
102
|
* @param provider - The WalletProvider to fetch the key from.
|
|
53
|
-
* @returns
|
|
103
|
+
* @returns A compressed public key as a hex string.
|
|
104
|
+
* @throws {Error} If no account is available or the namespace is unsupported.
|
|
54
105
|
*/
|
|
55
106
|
getPublicKey(provider: WalletProvider): Promise<string>;
|
|
56
107
|
/**
|
|
57
108
|
* Disconnects the current session and re-initiates a fresh pairing URI.
|
|
109
|
+
*
|
|
110
|
+
* - Calls `disconnect()` on the client, then `pair()` with current namespaces.
|
|
111
|
+
* - Updates `this.uri` so the UI can present a new QR/deeplink.
|
|
58
112
|
*/
|
|
59
113
|
disconnectWalletAccount(_provider: WalletProvider): Promise<void>;
|
|
60
114
|
/**
|
|
61
115
|
* Builds a lightweight provider interface for the given chain.
|
|
62
116
|
*
|
|
63
|
-
* @param chainId -
|
|
64
|
-
* @returns A WalletConnect-compatible provider
|
|
117
|
+
* @param chainId - Namespace chain ID (e.g., "eip155:1" or "solana:101").
|
|
118
|
+
* @returns A WalletConnect-compatible provider that proxies JSON-RPC via WC.
|
|
65
119
|
*/
|
|
66
120
|
private makeProvider;
|
|
67
121
|
/**
|
|
68
122
|
* Ensures there is an active WalletConnect session, initiating approval if necessary.
|
|
69
123
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
124
|
+
* - If a session exists, returns it immediately.
|
|
125
|
+
* - If no session exists but a pairing is in progress, awaits `approve()` —
|
|
126
|
+
* this will block until the user approves (or rejects) in their wallet.
|
|
127
|
+
* - If no session exists and no pairing is in progress, throws; the caller
|
|
128
|
+
* must have initiated pairing via `pair()` elsewhere.
|
|
129
|
+
*
|
|
130
|
+
* @returns The active WalletConnect session.
|
|
131
|
+
* @throws {Error} If approval is rejected, completes without establishing a session,
|
|
132
|
+
* or no pairing is in progress.
|
|
72
133
|
*/
|
|
73
134
|
private ensureSession;
|
|
74
135
|
/**
|
|
75
136
|
* Builds a WalletProvider descriptor for an EVM chain.
|
|
137
|
+
*
|
|
138
|
+
* - Extracts the connected address (if any) and current chain ID.
|
|
139
|
+
* - Includes the pairing `uri` if available.
|
|
140
|
+
*
|
|
141
|
+
* @param session - Current WalletConnect session (or null).
|
|
142
|
+
* @param info - Provider branding info (name, icon).
|
|
143
|
+
* @returns A WalletProvider object for Ethereum.
|
|
76
144
|
*/
|
|
77
145
|
private buildEthProvider;
|
|
78
146
|
/**
|
|
79
147
|
* Builds a WalletProvider descriptor for Solana.
|
|
148
|
+
*
|
|
149
|
+
* - Extracts the connected address (if any).
|
|
150
|
+
* - Includes the fresh pairing `uri` if available.
|
|
151
|
+
*
|
|
152
|
+
* @param session - Current WalletConnect session (or null).
|
|
153
|
+
* @param info - Provider branding info (name, icon).
|
|
154
|
+
* @returns A WalletProvider object for Solana.
|
|
80
155
|
*/
|
|
81
156
|
private buildSolProvider;
|
|
157
|
+
/**
|
|
158
|
+
* Builds the requested WalletConnect namespaces from the current config.
|
|
159
|
+
*
|
|
160
|
+
* - Includes methods and events for Ethereum and/or Solana based on enabled namespaces.
|
|
161
|
+
*
|
|
162
|
+
* @returns A namespaces object suitable for `WalletConnectClient.pair()`.
|
|
163
|
+
*/
|
|
164
|
+
private buildNamespaces;
|
|
82
165
|
}
|
|
83
166
|
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/__wallet__/wallet-connect/base.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,mBAAmB,EACnB,cAAc,EAEd,UAAU,EAEV,sBAAsB,EACtB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/__wallet__/wallet-connect/base.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,mBAAmB,EACnB,cAAc,EAEd,UAAU,EAEV,sBAAsB,EACtB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AASpD,qBAAa,mBAAoB,YAAW,sBAAsB;IAkCpD,OAAO,CAAC,MAAM;IAjC1B,QAAQ,CAAC,aAAa,qCAAqC;IAE3D,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,gBAAgB,CAAgB;IAExC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,GAAG,CAAC,CAAS;IAErB,OAAO,CAAC,eAAe,CAEnB;IAEJ,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;IAIpB;;;;;;;OAOG;gBACiB,MAAM,EAAE,mBAAmB;IAuB/C;;;;;;;;;;OAUG;IACG,IAAI,CAAC,IAAI,EAAE;QACf,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,gBAAgB,EAAE,MAAM,EAAE,CAAC;KAC5B,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjB;;;;;;;OAOG;IACG,YAAY,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAqB/C;;;;;;;;OAQG;IACG,oBAAoB,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpE;;;;;;;;;;;;;;;OAeG;IACG,WAAW,CACf,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,MAAM,GAAG,eAAe,GAClC,OAAO,CAAC,IAAI,CAAC;IAmChB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,IAAI,CACR,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC;IAuGlB;;;;;;;;;OASG;IACG,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAyC7D;;;;;OAKG;IACG,uBAAuB,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvE;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAepB;;;;;;;;;;;;OAYG;YACW,aAAa;IAU3B;;;;;;;;;OASG;YACW,gBAAgB;IAwB9B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;CA+BxB"}
|
|
@@ -8,20 +8,55 @@ var base = require('../../__types__/base.js');
|
|
|
8
8
|
var ethers = require('ethers');
|
|
9
9
|
|
|
10
10
|
class WalletConnectWallet {
|
|
11
|
+
addChangeListener(listener) {
|
|
12
|
+
this.changeListeners.add(listener);
|
|
13
|
+
return () => this.changeListeners.delete(listener);
|
|
14
|
+
}
|
|
15
|
+
notifyChange(event) {
|
|
16
|
+
this.changeListeners.forEach((listener) => listener(event));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Constructs a WalletConnectWallet bound to a WalletConnect client.
|
|
20
|
+
*
|
|
21
|
+
* - Subscribes to session deletions and automatically re-initiates pairing,
|
|
22
|
+
* updating `this.uri` so the UI can present a fresh QR/deeplink.
|
|
23
|
+
*
|
|
24
|
+
* @param client - The low-level WalletConnect client used for session/RPC.
|
|
25
|
+
*/
|
|
11
26
|
constructor(client) {
|
|
12
27
|
this.client = client;
|
|
13
28
|
this.interfaceType = base.WalletInterfaceType.WalletConnect;
|
|
14
29
|
this.ethereumNamespaces = [];
|
|
15
30
|
this.solanaNamespaces = [];
|
|
16
|
-
this.
|
|
31
|
+
this.changeListeners = new Set();
|
|
32
|
+
// session disconnected
|
|
33
|
+
this.client.onSessionDelete(() => {
|
|
34
|
+
this.notifyChange({ type: "disconnect" });
|
|
35
|
+
});
|
|
36
|
+
// session updated (actual update to the session for example adding a chain to namespaces)
|
|
37
|
+
this.client.onSessionUpdate(() => {
|
|
38
|
+
this.notifyChange({ type: "update" });
|
|
39
|
+
});
|
|
40
|
+
// chain switched
|
|
41
|
+
this.client.onSessionEvent(({ event }) => {
|
|
42
|
+
if (event?.name === "chainChanged" || event?.name === "accountsChanged") {
|
|
43
|
+
const chainId = typeof event.data?.chainId === "string"
|
|
44
|
+
? event.data.chainId
|
|
45
|
+
: undefined;
|
|
46
|
+
this.notifyChange({ type: "chainChanged", chainId });
|
|
47
|
+
}
|
|
48
|
+
});
|
|
17
49
|
}
|
|
18
50
|
/**
|
|
19
|
-
* Initializes WalletConnect pairing flow with the specified
|
|
20
|
-
* If an active session already exists, pairing is skipped.
|
|
51
|
+
* Initializes WalletConnect pairing flow with the specified namespaces.
|
|
21
52
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
53
|
+
* - Saves the requested chain namespaces (e.g., `["eip155:1", "eip155:137", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]`).
|
|
54
|
+
* - If an active session already has connected accounts, pairing is skipped.
|
|
55
|
+
* - Otherwise initiates a pairing and stores the resulting URI.
|
|
56
|
+
*
|
|
57
|
+
* @param opts.ethereumNamespaces - List of EVM CAIP IDs (e.g., "eip155:1").
|
|
58
|
+
* @param opts.solanaNamespaces - List of Solana CAIP IDs (e.g., "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp").
|
|
59
|
+
* @throws {Error} If no namespaces are provided for either chain.
|
|
25
60
|
*/
|
|
26
61
|
async init(opts) {
|
|
27
62
|
this.ethereumNamespaces = opts.ethereumNamespaces;
|
|
@@ -36,39 +71,23 @@ class WalletConnectWallet {
|
|
|
36
71
|
this.solanaNamespaces.length === 0) {
|
|
37
72
|
throw new Error("At least one namespace must be enabled for WalletConnect");
|
|
38
73
|
}
|
|
74
|
+
// we don't want to create more than one active session
|
|
75
|
+
// so we don't make a pair request if one is already active
|
|
76
|
+
// since pairing would mean initializing a new session
|
|
39
77
|
const session = this.client.getSession();
|
|
40
78
|
if (hasConnectedAccounts(session)) {
|
|
41
79
|
return;
|
|
42
80
|
}
|
|
43
|
-
const namespaces =
|
|
44
|
-
if (this.ethereumNamespaces.length > 0) {
|
|
45
|
-
namespaces.eip155 = {
|
|
46
|
-
methods: [
|
|
47
|
-
"personal_sign",
|
|
48
|
-
"eth_sendTransaction",
|
|
49
|
-
"eth_chainId",
|
|
50
|
-
"wallet_switchEthereumChain",
|
|
51
|
-
"wallet_addEthereumChain",
|
|
52
|
-
],
|
|
53
|
-
chains: this.ethereumNamespaces,
|
|
54
|
-
events: ["accountsChanged", "chainChanged"],
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
if (this.solanaNamespaces.length > 0) {
|
|
58
|
-
namespaces.solana = {
|
|
59
|
-
methods: [
|
|
60
|
-
"solana_signMessage",
|
|
61
|
-
"solana_signTransaction",
|
|
62
|
-
"solana_sendTransaction",
|
|
63
|
-
],
|
|
64
|
-
chains: this.solanaNamespaces,
|
|
65
|
-
events: ["accountsChanged", "chainChanged"],
|
|
66
|
-
};
|
|
67
|
-
}
|
|
81
|
+
const namespaces = this.buildNamespaces();
|
|
68
82
|
this.uri = await this.client.pair(namespaces);
|
|
69
83
|
}
|
|
70
84
|
/**
|
|
71
85
|
* Returns WalletConnect providers with associated chain/account metadata.
|
|
86
|
+
*
|
|
87
|
+
* - Builds an EVM provider (if Ethereum namespaces are enabled).
|
|
88
|
+
* - Builds a Solana provider (if Solana namespaces are enabled).
|
|
89
|
+
*
|
|
90
|
+
* @returns A promise resolving to an array of WalletProvider objects.
|
|
72
91
|
*/
|
|
73
92
|
async getProviders() {
|
|
74
93
|
const session = this.client.getSession();
|
|
@@ -87,6 +106,12 @@ class WalletConnectWallet {
|
|
|
87
106
|
}
|
|
88
107
|
/**
|
|
89
108
|
* Approves the session if needed and ensures at least one account is available.
|
|
109
|
+
*
|
|
110
|
+
* - Calls `approve()` on the underlying client when pairing is pending.
|
|
111
|
+
* - Throws if the approved session contains no connected accounts.
|
|
112
|
+
*
|
|
113
|
+
* @param _provider - Unused (present for interface compatibility).
|
|
114
|
+
* @throws {Error} If the session contains no accounts.
|
|
90
115
|
*/
|
|
91
116
|
async connectWalletAccount(_provider) {
|
|
92
117
|
const session = await this.client.approve();
|
|
@@ -94,12 +119,20 @@ class WalletConnectWallet {
|
|
|
94
119
|
throw new Error("No account found in session");
|
|
95
120
|
}
|
|
96
121
|
/**
|
|
97
|
-
*
|
|
122
|
+
* Switches the user’s WalletConnect session to a new EVM chain.
|
|
123
|
+
*
|
|
124
|
+
* - Ethereum-only: only supported for providers on the Ethereum namespace.
|
|
125
|
+
* - No add-then-switch: WalletConnect cannot add chains mid-session. The target chain
|
|
126
|
+
* must be present in `ethereumNamespaces` negotiated at pairing time. To support a new chain,
|
|
127
|
+
* you must include it in the walletConfig.
|
|
128
|
+
* - Accepts a hex chain ID (e.g., "0x1"). If a `SwitchableChain` is passed, only its `id`
|
|
129
|
+
* (hex chain ID) is used; metadata is ignored for WalletConnect.
|
|
98
130
|
*
|
|
99
|
-
* @param provider
|
|
100
|
-
* @param chainOrId
|
|
101
|
-
*
|
|
102
|
-
*
|
|
131
|
+
* @param provider - The WalletProvider returned by `getProviders()`.
|
|
132
|
+
* @param chainOrId - Hex chain ID (e.g., "0x1") or a `SwitchableChain` (its `id` is used).
|
|
133
|
+
* @returns A promise that resolves when the switch completes.
|
|
134
|
+
* @throws {Error} If no active session, provider is non-EVM, the chain is not in `ethereumNamespaces`,
|
|
135
|
+
* or the switch RPC fails.
|
|
103
136
|
*/
|
|
104
137
|
async switchChain(provider, chainOrId) {
|
|
105
138
|
if (provider.chainInfo.namespace !== base.Chain.Ethereum) {
|
|
@@ -126,13 +159,27 @@ class WalletConnectWallet {
|
|
|
126
159
|
}
|
|
127
160
|
}
|
|
128
161
|
/**
|
|
129
|
-
* Signs a message or transaction using the specified provider and intent.
|
|
162
|
+
* Signs a message or transaction using the specified wallet provider and intent.
|
|
130
163
|
*
|
|
131
|
-
*
|
|
164
|
+
* - Ensures an active WalletConnect session:
|
|
165
|
+
* - If a pairing is in progress (URI shown but not yet approved), this call will
|
|
166
|
+
* wait for the user to approve the session and may appear stuck until they do.
|
|
167
|
+
* - If no pairing is in progress, this will throw (e.g., "call pair() before approve()").
|
|
168
|
+
* - Ethereum:
|
|
169
|
+
* - `SignMessage` → `personal_sign` (returns hex signature).
|
|
170
|
+
* - `SignAndSendTransaction` → `eth_sendTransaction` (returns tx hash).
|
|
171
|
+
* - Solana:
|
|
172
|
+
* - `SignMessage` → `solana_signMessage` (returns hex signature).
|
|
173
|
+
* - `SignTransaction` → `solana_signTransaction` (returns hex signature).
|
|
174
|
+
* - `SignAndSendTransaction` → `solana_sendTransaction` (returns hex signature of the submitted tx).
|
|
175
|
+
*
|
|
176
|
+
* @param payload - Payload or serialized transaction to sign.
|
|
132
177
|
* @param provider - The WalletProvider to use.
|
|
133
|
-
* @param intent - The
|
|
178
|
+
* @param intent - The signing intent.
|
|
179
|
+
* @returns A hex string (signature or transaction hash, depending on intent).
|
|
180
|
+
* @throws {Error} If no account is available, no pairing is in progress, or the intent is unsupported.
|
|
134
181
|
*/
|
|
135
|
-
async sign(
|
|
182
|
+
async sign(payload, provider, intent) {
|
|
136
183
|
const session = await this.ensureSession();
|
|
137
184
|
if (!hasConnectedAccounts(session)) {
|
|
138
185
|
await this.connectWalletAccount(provider);
|
|
@@ -145,12 +192,12 @@ class WalletConnectWallet {
|
|
|
145
192
|
switch (intent) {
|
|
146
193
|
case base.SignIntent.SignMessage:
|
|
147
194
|
return (await this.client.request(this.ethChain, "personal_sign", [
|
|
148
|
-
|
|
195
|
+
payload,
|
|
149
196
|
address,
|
|
150
197
|
]));
|
|
151
198
|
case base.SignIntent.SignAndSendTransaction:
|
|
152
199
|
const account = provider.connectedAddresses[0];
|
|
153
|
-
const tx = ethers.Transaction.from(
|
|
200
|
+
const tx = ethers.Transaction.from(payload);
|
|
154
201
|
const txParams = {
|
|
155
202
|
from: account,
|
|
156
203
|
to: tx.to?.toString(),
|
|
@@ -174,7 +221,7 @@ class WalletConnectWallet {
|
|
|
174
221
|
}
|
|
175
222
|
switch (intent) {
|
|
176
223
|
case base.SignIntent.SignMessage: {
|
|
177
|
-
const msgBytes = new TextEncoder().encode(
|
|
224
|
+
const msgBytes = new TextEncoder().encode(payload);
|
|
178
225
|
const msgB58 = bs58.encode(msgBytes);
|
|
179
226
|
const { signature: sigB58 } = await this.client.request(this.solChain, "solana_signMessage", {
|
|
180
227
|
pubkey: address,
|
|
@@ -183,7 +230,7 @@ class WalletConnectWallet {
|
|
|
183
230
|
return encoding.uint8ArrayToHexString(bs58.decode(sigB58));
|
|
184
231
|
}
|
|
185
232
|
case base.SignIntent.SignTransaction: {
|
|
186
|
-
const txBytes = encoding.uint8ArrayFromHexString(
|
|
233
|
+
const txBytes = encoding.uint8ArrayFromHexString(payload);
|
|
187
234
|
const txBase64 = encoding.stringToBase64urlString(String.fromCharCode(...txBytes));
|
|
188
235
|
const { signature: sigB58 } = await this.client.request(this.solChain, "solana_signTransaction", {
|
|
189
236
|
feePayer: address,
|
|
@@ -192,7 +239,7 @@ class WalletConnectWallet {
|
|
|
192
239
|
return encoding.uint8ArrayToHexString(bs58.decode(sigB58));
|
|
193
240
|
}
|
|
194
241
|
case base.SignIntent.SignAndSendTransaction: {
|
|
195
|
-
const txBytes = encoding.uint8ArrayFromHexString(
|
|
242
|
+
const txBytes = encoding.uint8ArrayFromHexString(payload);
|
|
196
243
|
const txBase64 = encoding.stringToBase64urlString(String.fromCharCode(...txBytes));
|
|
197
244
|
const sigB58 = await this.client.request(this.solChain, "solana_sendTransaction", {
|
|
198
245
|
feePayer: address,
|
|
@@ -210,8 +257,12 @@ class WalletConnectWallet {
|
|
|
210
257
|
/**
|
|
211
258
|
* Retrieves the public key of the connected wallet.
|
|
212
259
|
*
|
|
260
|
+
* - Ethereum: signs a fixed challenge and recovers the compressed secp256k1 public key.
|
|
261
|
+
* - Solana: decodes the base58-encoded address to raw bytes.
|
|
262
|
+
*
|
|
213
263
|
* @param provider - The WalletProvider to fetch the key from.
|
|
214
|
-
* @returns
|
|
264
|
+
* @returns A compressed public key as a hex string.
|
|
265
|
+
* @throws {Error} If no account is available or the namespace is unsupported.
|
|
215
266
|
*/
|
|
216
267
|
async getPublicKey(provider) {
|
|
217
268
|
const session = this.client.getSession();
|
|
@@ -247,34 +298,13 @@ class WalletConnectWallet {
|
|
|
247
298
|
}
|
|
248
299
|
/**
|
|
249
300
|
* Disconnects the current session and re-initiates a fresh pairing URI.
|
|
301
|
+
*
|
|
302
|
+
* - Calls `disconnect()` on the client, then `pair()` with current namespaces.
|
|
303
|
+
* - Updates `this.uri` so the UI can present a new QR/deeplink.
|
|
250
304
|
*/
|
|
251
305
|
async disconnectWalletAccount(_provider) {
|
|
252
306
|
await this.client.disconnect();
|
|
253
|
-
const namespaces =
|
|
254
|
-
if (this.ethereumNamespaces.length > 0) {
|
|
255
|
-
namespaces.eip155 = {
|
|
256
|
-
methods: [
|
|
257
|
-
"personal_sign",
|
|
258
|
-
"eth_sendTransaction",
|
|
259
|
-
"eth_chainId",
|
|
260
|
-
"wallet_switchEthereumChain",
|
|
261
|
-
"wallet_addEthereumChain",
|
|
262
|
-
],
|
|
263
|
-
chains: this.ethereumNamespaces,
|
|
264
|
-
events: ["accountsChanged", "chainChanged"],
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
if (this.solanaNamespaces.length > 0) {
|
|
268
|
-
namespaces.solana = {
|
|
269
|
-
methods: [
|
|
270
|
-
"solana_signMessage",
|
|
271
|
-
"solana_signTransaction",
|
|
272
|
-
"solana_sendTransaction",
|
|
273
|
-
],
|
|
274
|
-
chains: this.solanaNamespaces,
|
|
275
|
-
events: ["accountsChanged", "chainChanged"],
|
|
276
|
-
};
|
|
277
|
-
}
|
|
307
|
+
const namespaces = this.buildNamespaces();
|
|
278
308
|
await this.client.pair(namespaces).then((newUri) => {
|
|
279
309
|
this.uri = newUri;
|
|
280
310
|
});
|
|
@@ -282,21 +312,35 @@ class WalletConnectWallet {
|
|
|
282
312
|
/**
|
|
283
313
|
* Builds a lightweight provider interface for the given chain.
|
|
284
314
|
*
|
|
285
|
-
* @param chainId -
|
|
286
|
-
* @returns A WalletConnect-compatible provider
|
|
315
|
+
* @param chainId - Namespace chain ID (e.g., "eip155:1" or "solana:101").
|
|
316
|
+
* @returns A WalletConnect-compatible provider that proxies JSON-RPC via WC.
|
|
287
317
|
*/
|
|
288
318
|
makeProvider(chainId) {
|
|
289
319
|
return {
|
|
290
|
-
request: ({ method, params }) =>
|
|
291
|
-
|
|
320
|
+
request: ({ method, params }) => this.client.request(chainId, method, params),
|
|
321
|
+
features: {
|
|
322
|
+
"standard:events": {
|
|
323
|
+
on: (event, callback) => {
|
|
324
|
+
if (event !== "change")
|
|
325
|
+
return () => { };
|
|
326
|
+
return this.addChangeListener(callback);
|
|
327
|
+
},
|
|
328
|
+
},
|
|
292
329
|
},
|
|
293
330
|
};
|
|
294
331
|
}
|
|
295
332
|
/**
|
|
296
333
|
* Ensures there is an active WalletConnect session, initiating approval if necessary.
|
|
297
334
|
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
335
|
+
* - If a session exists, returns it immediately.
|
|
336
|
+
* - If no session exists but a pairing is in progress, awaits `approve()` —
|
|
337
|
+
* this will block until the user approves (or rejects) in their wallet.
|
|
338
|
+
* - If no session exists and no pairing is in progress, throws; the caller
|
|
339
|
+
* must have initiated pairing via `pair()` elsewhere.
|
|
340
|
+
*
|
|
341
|
+
* @returns The active WalletConnect session.
|
|
342
|
+
* @throws {Error} If approval is rejected, completes without establishing a session,
|
|
343
|
+
* or no pairing is in progress.
|
|
300
344
|
*/
|
|
301
345
|
async ensureSession() {
|
|
302
346
|
let session = this.client.getSession();
|
|
@@ -310,6 +354,13 @@ class WalletConnectWallet {
|
|
|
310
354
|
}
|
|
311
355
|
/**
|
|
312
356
|
* Builds a WalletProvider descriptor for an EVM chain.
|
|
357
|
+
*
|
|
358
|
+
* - Extracts the connected address (if any) and current chain ID.
|
|
359
|
+
* - Includes the pairing `uri` if available.
|
|
360
|
+
*
|
|
361
|
+
* @param session - Current WalletConnect session (or null).
|
|
362
|
+
* @param info - Provider branding info (name, icon).
|
|
363
|
+
* @returns A WalletProvider object for Ethereum.
|
|
313
364
|
*/
|
|
314
365
|
async buildEthProvider(session, info) {
|
|
315
366
|
const raw = session?.namespaces.eip155?.accounts?.[0] ?? "";
|
|
@@ -331,6 +382,13 @@ class WalletConnectWallet {
|
|
|
331
382
|
}
|
|
332
383
|
/**
|
|
333
384
|
* Builds a WalletProvider descriptor for Solana.
|
|
385
|
+
*
|
|
386
|
+
* - Extracts the connected address (if any).
|
|
387
|
+
* - Includes the fresh pairing `uri` if available.
|
|
388
|
+
*
|
|
389
|
+
* @param session - Current WalletConnect session (or null).
|
|
390
|
+
* @param info - Provider branding info (name, icon).
|
|
391
|
+
* @returns A WalletProvider object for Solana.
|
|
334
392
|
*/
|
|
335
393
|
buildSolProvider(session, info) {
|
|
336
394
|
const raw = session?.namespaces.solana?.accounts?.[0] ?? "";
|
|
@@ -344,15 +402,78 @@ class WalletConnectWallet {
|
|
|
344
402
|
...(this.uri && { uri: this.uri }),
|
|
345
403
|
};
|
|
346
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Builds the requested WalletConnect namespaces from the current config.
|
|
407
|
+
*
|
|
408
|
+
* - Includes methods and events for Ethereum and/or Solana based on enabled namespaces.
|
|
409
|
+
*
|
|
410
|
+
* @returns A namespaces object suitable for `WalletConnectClient.pair()`.
|
|
411
|
+
*/
|
|
412
|
+
buildNamespaces() {
|
|
413
|
+
const namespaces = {};
|
|
414
|
+
if (this.ethereumNamespaces.length > 0) {
|
|
415
|
+
namespaces.eip155 = {
|
|
416
|
+
methods: [
|
|
417
|
+
"personal_sign",
|
|
418
|
+
"eth_sendTransaction",
|
|
419
|
+
"eth_chainId",
|
|
420
|
+
"wallet_switchEthereumChain",
|
|
421
|
+
"wallet_addEthereumChain",
|
|
422
|
+
],
|
|
423
|
+
chains: this.ethereumNamespaces,
|
|
424
|
+
events: ["accountsChanged", "chainChanged"],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (this.solanaNamespaces.length > 0) {
|
|
428
|
+
namespaces.solana = {
|
|
429
|
+
methods: [
|
|
430
|
+
"solana_signMessage",
|
|
431
|
+
"solana_signTransaction",
|
|
432
|
+
"solana_sendTransaction",
|
|
433
|
+
],
|
|
434
|
+
chains: this.solanaNamespaces,
|
|
435
|
+
events: ["accountsChanged", "chainChanged"],
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
return namespaces;
|
|
439
|
+
}
|
|
347
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Determines whether the session has at least one connected account
|
|
443
|
+
* across any namespace.
|
|
444
|
+
*
|
|
445
|
+
* - Safe to call with `null` (returns `false`).
|
|
446
|
+
* - Checks all namespaces for a non-empty `accounts` array.
|
|
447
|
+
*
|
|
448
|
+
* @param session - The current WalletConnect session, or `null`.
|
|
449
|
+
* @returns `true` if any namespace has ≥1 account; otherwise `false`.
|
|
450
|
+
*/
|
|
348
451
|
function hasConnectedAccounts(session) {
|
|
349
452
|
return (!!session &&
|
|
350
453
|
Object.values(session.namespaces).some((ns) => ns.accounts?.length > 0));
|
|
351
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Retrieves the first connected Ethereum account.
|
|
457
|
+
*
|
|
458
|
+
* - Safe to call with `null` (returns `undefined`).
|
|
459
|
+
* - Returns only the address portion (e.g., `0xabc...`), not the full CAIP string.
|
|
460
|
+
*
|
|
461
|
+
* @param session - The current WalletConnect session, or `null`.
|
|
462
|
+
* @returns The connected EVM address, or `undefined` if none.
|
|
463
|
+
*/
|
|
352
464
|
function getConnectedEthereum(session) {
|
|
353
465
|
const acc = session?.namespaces.eip155?.accounts?.[0];
|
|
354
466
|
return acc ? acc.split(":")[2] : undefined;
|
|
355
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Retrieves the first connected Solana account.
|
|
470
|
+
*
|
|
471
|
+
* - Safe to call with `null` (returns `undefined`).
|
|
472
|
+
* - Returns only the base58 address portion, not the full CAIP string.
|
|
473
|
+
*
|
|
474
|
+
* @param session - The current WalletConnect session, or `null`.
|
|
475
|
+
* @returns The connected Solana address (base58), or `undefined` if none.
|
|
476
|
+
*/
|
|
356
477
|
function getConnectedSolana(session) {
|
|
357
478
|
const acc = session?.namespaces.solana?.accounts?.[0];
|
|
358
479
|
return acc ? acc.split(":")[2] : undefined;
|