@hashgraph/hedera-wallet-connect 1.5.2-canary.dd48df1.0 → 2.0.0-canary.45f2441.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.
Files changed (54) hide show
  1. package/README.md +127 -68
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +1 -0
  4. package/dist/lib/dapp/DAppSigner.d.ts +2 -1
  5. package/dist/lib/dapp/DAppSigner.js +19 -22
  6. package/dist/lib/dapp/index.d.ts +7 -11
  7. package/dist/lib/dapp/index.js +37 -27
  8. package/dist/lib/shared/accountInfo.d.ts +30 -0
  9. package/dist/lib/shared/accountInfo.js +1 -0
  10. package/dist/lib/shared/index.d.ts +2 -0
  11. package/dist/lib/shared/index.js +2 -0
  12. package/dist/lib/shared/logger.d.ts +2 -1
  13. package/dist/lib/shared/logger.js +6 -5
  14. package/dist/lib/shared/mirrorNode.d.ts +3 -0
  15. package/dist/lib/shared/mirrorNode.js +17 -0
  16. package/dist/lib/shared/payloads.d.ts +1 -5
  17. package/dist/lib/shared/utils.d.ts +2 -20
  18. package/dist/lib/shared/utils.js +3 -30
  19. package/dist/lib/wallet/index.d.ts +8 -8
  20. package/dist/lib/wallet/index.js +7 -2
  21. package/dist/lib/wallet/types.d.ts +5 -5
  22. package/dist/reown/adapter.d.ts +37 -0
  23. package/dist/reown/adapter.js +255 -0
  24. package/dist/reown/connectors/HederaConnector.d.ts +29 -0
  25. package/dist/reown/connectors/HederaConnector.js +35 -0
  26. package/dist/reown/connectors/index.d.ts +1 -0
  27. package/dist/reown/connectors/index.js +1 -0
  28. package/dist/reown/index.d.ts +4 -0
  29. package/dist/reown/index.js +4 -0
  30. package/dist/reown/providers/EIP155Provider.d.ts +33 -0
  31. package/dist/reown/providers/EIP155Provider.js +187 -0
  32. package/dist/reown/providers/HIP820Provider.d.ts +26 -0
  33. package/dist/reown/providers/HIP820Provider.js +69 -0
  34. package/dist/reown/providers/HederaProvider.d.ts +164 -0
  35. package/dist/reown/providers/HederaProvider.js +471 -0
  36. package/dist/reown/providers/index.d.ts +3 -0
  37. package/dist/reown/providers/index.js +3 -0
  38. package/dist/reown/utils/chains.d.ts +18 -0
  39. package/dist/reown/utils/chains.js +152 -0
  40. package/dist/reown/utils/constants.d.ts +16 -0
  41. package/dist/reown/utils/constants.js +18 -0
  42. package/dist/reown/utils/helpers.d.ts +12 -0
  43. package/dist/reown/utils/helpers.js +25 -0
  44. package/dist/reown/utils/index.d.ts +4 -0
  45. package/dist/reown/utils/index.js +4 -0
  46. package/dist/reown/utils/types.d.ts +9 -0
  47. package/dist/reown/utils/types.js +1 -0
  48. package/dist/reown/wallets/EIP155Wallet.d.ts +46 -0
  49. package/dist/reown/wallets/EIP155Wallet.js +136 -0
  50. package/dist/reown/wallets/HIP820Wallet.d.ts +53 -0
  51. package/dist/reown/wallets/HIP820Wallet.js +239 -0
  52. package/dist/reown/wallets/index.d.ts +2 -0
  53. package/dist/reown/wallets/index.js +2 -0
  54. package/package.json +23 -58
package/README.md CHANGED
@@ -1,70 +1,129 @@
1
1
  # Overview
2
2
 
3
- This library is the result of Hedera community collaboration to bring Hedera into the
4
- WalletConnect ecosystem and vice versa.
5
-
6
- The goal of this repository is to be a reference for wallets and dApps integrating the
7
- WalletConnect <> Hedera JSON-RPC reference. Additionally, this library is meant to be included
8
- in projects supporting WalletConnect and Hedera, providing utility functions useful to
9
- validating requests and resposes in both the WalletConnect JSON-RPC context as well as the
10
- Hedera context.
11
-
12
- A few useful resources include:
13
-
14
- - [HIP-820](https://hips.hedera.com/hip/hip-820)
15
- - [WalletConnect <> Hedera JSON-RPC spec](https://specs.walletconnect.com/2.0/blockchain-rpc/hedera-rpc).
16
-
17
- > WalletConnect brings the ecosystem together by enabling wallets and apps to securely connect
18
- > and interact.
19
- >
20
- > -- <cite> https://walletconnect.com
21
-
22
- Hedera aims to be:
23
-
24
- > The open source public ledger for everyone
25
- >
26
- > -- <cite> https://hedera.com
27
-
28
- ---
29
-
30
- This package managed by the Hedera community and is intended to be a standard for ecosystem
31
- wallets and dApp providers utilizing [WalletConnect](https://walletconnect.com) as a their
32
- communications protocol. It utilizes the
33
- [`@hashgraph/sdk`](https://www.npmjs.com/package/@hashgraph/sdk) and provides functions to
34
- facilitate implementing the
35
- [WalletConnect <> Hedera JSON-RPC spec](https://specs.walletconnect.com/2.0/blockchain-rpc/hedera-rpc)
36
- which has been defined through the collaborative HIP process in
37
- [HIP-820](https://hips.hedera.com/hip/hip-820).
38
-
39
- This library facilitates the implementation of the **WalletConnect <> Hedera Spec** which allows
40
- wallets and dApps to natively integrate with Hedera. It provides additional, out of network
41
- functionality with the `hedera_signMessage` function.
42
-
43
- In short, it uses the Hedera javascript SDK to build transactions, serialize them, send to
44
- wallets for processing and return responses back to dApps.
45
-
46
- _Please note, this is distinct from the
47
- [Implementation of Ethereum JSON-RPC APIs for Hedera](https://github.com/hashgraph/hedera-json-rpc-relay).
48
- At the time of this writing, "the Hedera JSON-RPC relay implementation is in beta, offers
49
- limited functionality today, and is only available to developers."_
50
-
51
- _The relay and this library have different intentions and serve different purposes - namely
52
- native Hedera integration vs. Ethereum compatability layers to ease developer onboarding for
53
- those more familiar with the Ethereum ecosystem._
54
-
55
- # Documentation
56
-
57
- WalletConnect <> Hedera docs are fully hosted on [https://hwc-docs.hgraph.app/](https://hwc-docs.hgraph.app/)
58
-
59
- - [Installation](/docs/docs/installation.md)
60
- - [dApp Guide](/docs/docs/dapp-guide.md)
61
- - [Wallet Guide](/docs/docs/wallet-guide.md)
62
- - [Signing Messages](/docs/docs/sign-messages.md)
63
- - [Demos](/docs/docs/demos.md)
64
-
65
- # Accessing the docs locally
66
-
67
- - `cd docs`
68
- - `npm install`
69
- - `npm run docs`
70
- - Navigating to `localhost:3000`
3
+ Hedera is a public distributed ledger that is EVM compatible. This library provides tools to
4
+ integrate Hedera using Reown's AppKit and WalletKit.
5
+
6
+ There are 2 distict paths to integrate Hedera. Hedera natively operates using a gRPC based API
7
+ for write transactions and a REST API for read transactions. To acheive EVM compatibility, there
8
+ is a software middlelayer called the Hedera JSON-RPC Relay that translates Ethereum JSON-RPC
9
+ compatible API calls into the Hedera gRPC and REST API calls.
10
+
11
+ When integrating, app developers can choose to use the Hedera native approach and send
12
+ transactions to wallets over the WalletConnect relays using the JSON-RPC spec defined for Hedera
13
+ native transactions or use Ethereum JSON-RPC calls sent to a Hedera JSON-RPC provider which then
14
+ communicates with Hedera consensus and mirror nodes.
15
+
16
+ In short, JSON-RPC is a type of API stucture, such as SOAP, gRPC, REST, GraphQL, etc. In the
17
+ Hedera ecosystem, there are distinct concepts regarding JSON-RPC APIs to consider:
18
+
19
+ - Ethereum JSON-RPC spec defines how to interact with Ethereum compatible networks
20
+ - Hedera JSON-RPC Relay implements the Ethereum JSON-RPC spec for Hedera
21
+ - Wallets in the Hedera ecosystem support a separate JSON-RPC spec that defines how to send
22
+ transactions to wallets over the WalletConnect relays. This is a Hedera specific spec that is
23
+ not compatible with the Ethereum JSON-RPC spec, rather is used to interact with the Hedera
24
+ network without the JSON-RPC Relay.
25
+
26
+ For more information see:
27
+
28
+ - [Ethereum JSON-RPC Specification ](https://ethereum.github.io/execution-apis/api-documentation/)
29
+ - [Hedera EVM: JSON-RPC relay](https://docs.hedera.com/hedera/core-concepts/smart-contracts/json-rpc-relay)
30
+ - [Hedera Native: JSON-RPC spec](https://docs.reown.com/advanced/multichain/rpc-reference/hedera-rpc).
31
+ - [@hashgraph/sdk](https://www.npmjs.com/package/@hashgraph/sdk)
32
+
33
+ ## Getting started
34
+
35
+ 1. Follow one of the quickstart instructions at
36
+ https://docs.reown.com/appkit/overview#quickstart
37
+
38
+ 2. Add Hedera dependencies to your project:
39
+
40
+ ```sh
41
+ npm install @hashgraph/hedera-wallet-connect@2.0.0-canary.811af2f.0 @hashgraph/sdk @walletconnect/universal-provider
42
+ ```
43
+
44
+ 3. Update `createAppKit` with adapters and a universal provider for Hedera. Note the
45
+ HederaAdapter will need to come before the WagmiAdapter in the adapters array.
46
+
47
+ ```typescript
48
+ import type UniversalProvider from '@walletconnect/universal-provider'
49
+
50
+ import {
51
+ HederaProvider,
52
+ HederaAdapter,
53
+ HederaChainDefinition,
54
+ hederaNamespace,
55
+ } from '@hashgraph/hedera-wallet-connect'
56
+
57
+ const metadata = {
58
+ name: 'AppKit w/ Hedera',
59
+ description: 'Hedera AppKit Example',
60
+ url: 'https://example.com', // origin must match your domain & subdomain
61
+ icons: ['https://avatars.githubusercontent.com/u/179229932']
62
+ }
63
+
64
+ const hederaEVMAdapter = new HederaAdapter({
65
+ projectId,
66
+ networks: [
67
+ HederaChainDefinition.EVM.Mainnet,
68
+ HederaChainDefinition.EVM.Testnet,
69
+ ],
70
+ namespace: 'eip155',
71
+ })
72
+
73
+ const universalProvider = (await HederaProvider.init({
74
+ projectId: "YOUR_PROJECT_ID"
75
+ metadata,
76
+ })) as unknown as UniversalProvider, // avoid type mismatch error due to missing of private properties in HederaProvider
77
+
78
+ // ...
79
+ createAppKit({
80
+ adapters: [ hederaEVMAdapter ],
81
+ //@ts-expect-error expected type error
82
+ universalProvider,
83
+ projectId,
84
+ metadata,
85
+ networks: [
86
+ // EVM
87
+ HederaChainDefinition.EVM.Mainnet,
88
+ HederaChainDefinition.EVM.Testnet,
89
+ ],
90
+ })
91
+
92
+ // ...
93
+ ```
94
+
95
+ 4. Recommended: Add Hedera Native WalletConnect Adapter
96
+
97
+ ```typescript
98
+ import { HederaChainDefinition, hederaNamespace } from '@hashgraph/hedera-wallet-connect'
99
+
100
+ // ...
101
+
102
+ const hederaNativeAdapter = new HederaAdapter({
103
+ projectId,
104
+ networks: [HederaChainDefinition.Native.Mainnet, HederaChainDefinition.Native.Testnet],
105
+ namespace: hederaNamespace, // 'hedera' as CaipNamespace,
106
+ })
107
+
108
+ // ...
109
+
110
+ createAppKit({
111
+ adapters: [hederaEVMAdapter, hederaNativeAdapter],
112
+ projectId,
113
+ metadata,
114
+ networks: [
115
+ // EVM
116
+ HederaChainDefinition.EVM.Mainnet,
117
+ HederaChainDefinition.EVM.Testnet,
118
+ // Native
119
+ HederaChainDefinition.Native.Mainnet,
120
+ HederaChainDefinition.Native.Testnet,
121
+ ],
122
+ })
123
+ ```
124
+
125
+ ## Examples and Demos
126
+
127
+ - [Example App by Hgraph](https://github.com/hgraph-io/hedera-app)
128
+ - [Example Wallet by Hgraph](https://github.com/hgraph-io/hedera-wallet)
129
+ - [Hashgraph React Wallets by Buidler Labs](https://github.com/buidler-labs/hashgraph-react-wallets)
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './lib';
2
+ export * from './reown';
package/dist/index.js CHANGED
@@ -18,3 +18,4 @@
18
18
  *
19
19
  */
20
20
  export * from './lib';
21
+ export * from './reown';
@@ -8,6 +8,7 @@ export declare class DAppSigner implements Signer {
8
8
  private readonly ledgerId;
9
9
  readonly extensionId?: string | undefined;
10
10
  private logger;
11
+ private publicKey;
11
12
  constructor(accountId: AccountId, signClient: ISignClient, topic: string, ledgerId?: LedgerId, extensionId?: string | undefined, logLevel?: LogLevel);
12
13
  /**
13
14
  * Sets the logging level for the DAppSigner
@@ -16,13 +17,13 @@ export declare class DAppSigner implements Signer {
16
17
  setLogLevel(level: LogLevel): void;
17
18
  private _getHederaClient;
18
19
  private get _signerAccountId();
19
- private _getRandomNodes;
20
20
  request<T>(request: {
21
21
  method: string;
22
22
  params: any;
23
23
  }): Promise<T>;
24
24
  getAccountId(): AccountId;
25
25
  getAccountKey(): Key;
26
+ getAccountKeyAsync(): Promise<Key | null>;
26
27
  getLedgerId(): LedgerId;
27
28
  getNetwork(): {
28
29
  [key: string]: string | AccountId;
@@ -17,9 +17,9 @@
17
17
  * limitations under the License.
18
18
  *
19
19
  */
20
- import { AccountBalance, AccountId, AccountInfo, LedgerId, SignerSignature, Transaction, TransactionRecord, Client, PublicKey, TransactionId, TransactionResponse, Query, AccountRecordsQuery, AccountInfoQuery, AccountBalanceQuery, TransactionReceiptQuery, TransactionReceipt, TransactionRecordQuery, } from '@hashgraph/sdk';
20
+ import { AccountBalance, AccountInfo, LedgerId, SignerSignature, Transaction, TransactionRecord, Client, PublicKey, TransactionId, TransactionResponse, Query, AccountRecordsQuery, AccountInfoQuery, AccountBalanceQuery, TransactionReceiptQuery, TransactionReceipt, TransactionRecordQuery, } from '@hashgraph/sdk';
21
21
  import { proto } from '@hashgraph/proto';
22
- import { HederaJsonRpcMethod, base64StringToSignatureMap, base64StringToUint8Array, ledgerIdToCAIPChainId, queryToBase64String, transactionBodyToBase64String, transactionToBase64String, transactionToTransactionBody, extensionOpen, Uint8ArrayToBase64String, Uint8ArrayToString, } from '../shared';
22
+ import { HederaJsonRpcMethod, base64StringToSignatureMap, base64StringToUint8Array, ledgerIdToCAIPChainId, queryToBase64String, transactionBodyToBase64String, transactionToBase64String, transactionToTransactionBody, extensionOpen, Uint8ArrayToBase64String, Uint8ArrayToString, getAccountInfo, } from '../shared';
23
23
  import { DefaultLogger } from '../shared/logger';
24
24
  import { SessionNotFoundError } from './SessionNotFoundError';
25
25
  const clients = {};
@@ -31,6 +31,11 @@ export class DAppSigner {
31
31
  this.ledgerId = ledgerId;
32
32
  this.extensionId = extensionId;
33
33
  this.logger = new DefaultLogger(logLevel);
34
+ this.publicKey = null;
35
+ // cache public key from mirror node
36
+ this.getAccountKeyAsync()
37
+ .then((key) => (this.publicKey = key))
38
+ .catch((error) => this.logger.error('Error when receiving a public key:', error.message));
34
39
  }
35
40
  /**
36
41
  * Sets the logging level for the DAppSigner
@@ -51,15 +56,6 @@ export class DAppSigner {
51
56
  get _signerAccountId() {
52
57
  return `${ledgerIdToCAIPChainId(this.ledgerId)}:${this.accountId.toString()}`;
53
58
  }
54
- _getRandomNodes(numberOfNodes) {
55
- const allNodes = Object.values(this._getHederaClient().network).map((o) => typeof o === 'string' ? AccountId.fromString(o) : o);
56
- // shuffle nodes
57
- for (let i = allNodes.length - 1; i > 0; i--) {
58
- const j = Math.floor(Math.random() * (i + 1));
59
- [allNodes[i], allNodes[j]] = [allNodes[j], allNodes[i]];
60
- }
61
- return allNodes.slice(0, numberOfNodes);
62
- }
63
59
  request(request) {
64
60
  var _a, _b;
65
61
  // Avoid a wallet call if the session is no longer valid
@@ -88,7 +84,16 @@ export class DAppSigner {
88
84
  return this.accountId;
89
85
  }
90
86
  getAccountKey() {
91
- throw new Error('Method not implemented.');
87
+ if (this.publicKey == null) {
88
+ throw new Error('No key was received from the mirror node');
89
+ }
90
+ return this.publicKey;
91
+ }
92
+ async getAccountKeyAsync() {
93
+ const accountInfo = await getAccountInfo(this.ledgerId, this.accountId.toString());
94
+ if (!(accountInfo === null || accountInfo === void 0 ? void 0 : accountInfo.key))
95
+ return null;
96
+ return PublicKey.fromString(accountInfo.key.key);
92
97
  }
93
98
  getLedgerId() {
94
99
  return this.ledgerId;
@@ -144,9 +149,7 @@ export class DAppSigner {
144
149
  throw new Error('Method not implemented.');
145
150
  }
146
151
  async populateTransaction(transaction) {
147
- return transaction
148
- .setNodeAccountIds(this._getRandomNodes(10)) // allow retrying on up to 10 nodes
149
- .setTransactionId(TransactionId.generate(this.getAccountId()));
152
+ return transaction.setTransactionId(TransactionId.generate(this.getAccountId()));
150
153
  }
151
154
  /**
152
155
  * Prepares a transaction object for signing using a single node account id.
@@ -157,12 +160,7 @@ export class DAppSigner {
157
160
  * @returns transaction - `Transaction` object with signature
158
161
  */
159
162
  async signTransaction(transaction) {
160
- let nodeAccountId;
161
- if (!transaction.nodeAccountIds || transaction.nodeAccountIds.length === 0)
162
- nodeAccountId = this._getRandomNodes(1)[0];
163
- else
164
- nodeAccountId = transaction.nodeAccountIds[0];
165
- const transactionBody = transactionToTransactionBody(transaction, nodeAccountId);
163
+ const transactionBody = transactionToTransactionBody(transaction);
166
164
  if (!transactionBody)
167
165
  throw new Error('Failed to serialize transaction body');
168
166
  const transactionBodyBase64 = transactionBodyToBase64String(transactionBody);
@@ -290,7 +288,6 @@ export class DAppSigner {
290
288
  if (queryResult.result) {
291
289
  return queryResult.result;
292
290
  }
293
- // TODO: make this error more usable
294
291
  if (isReceiptQuery) {
295
292
  throw new Error('Error executing receipt query: \n' +
296
293
  JSON.stringify({
@@ -1,10 +1,11 @@
1
1
  import { AccountId, LedgerId, Transaction } from '@hashgraph/sdk';
2
- import { SessionTypes, SignClientTypes } from '@walletconnect/types';
2
+ import { EngineTypes, SessionTypes, SignClientTypes } from '@walletconnect/types';
3
3
  import { WalletConnectModal } from '@walletconnect/modal';
4
4
  import SignClient from '@walletconnect/sign-client';
5
5
  import { LogLevel } from '../shared/logger';
6
6
  import { GetNodeAddressesResult, ExecuteTransactionParams, ExecuteTransactionResult, SignMessageParams, SignMessageResult, SignAndExecuteQueryResult, SignAndExecuteQueryParams, SignAndExecuteTransactionParams, SignAndExecuteTransactionResult, SignTransactionParams, SignTransactionResult, ExtensionData } from '../shared';
7
7
  import { DAppSigner } from './DAppSigner';
8
+ import { JsonRpcResult } from '@walletconnect/jsonrpc-types';
8
9
  export * from './DAppSigner';
9
10
  export { SessionNotFoundError } from './SessionNotFoundError';
10
11
  type BaseLogger = 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'fatal';
@@ -22,6 +23,7 @@ export declare class DAppConnector {
22
23
  walletConnectModal: WalletConnectModal;
23
24
  signers: DAppSigner[];
24
25
  isInitializing: boolean;
26
+ private storagePrefix;
25
27
  /**
26
28
  * Initializes the DAppConnector instance.
27
29
  * @param metadata - SignClientTypes.Metadata object for the DApp metadata.
@@ -53,13 +55,6 @@ export declare class DAppConnector {
53
55
  * @throws {Error} - If no signer is found for the provided account ID.
54
56
  */
55
57
  getSigner(accountId: AccountId): DAppSigner;
56
- /**
57
- * Initiates the WalletConnect connection flow using a QR code.
58
- * @deprecated Use `openModal` instead.
59
- * @param pairingTopic - The pairing topic for the connection (optional).
60
- * @returns A Promise that resolves when the connection process is complete.
61
- */
62
- connectQR(pairingTopic?: string): Promise<void>;
63
58
  /**
64
59
  * Initiates the WalletConnect connection flow using a QR code.
65
60
  * @param pairingTopic - The pairing topic for the connection (optional).
@@ -113,7 +108,7 @@ export declare class DAppConnector {
113
108
  private createSigners;
114
109
  private onSessionConnected;
115
110
  private connectURI;
116
- private request;
111
+ request<Req extends EngineTypes.RequestParams, Res extends JsonRpcResult>({ method, params, }: Req['request']): Promise<Res>;
117
112
  /**
118
113
  * Retrieves the node addresses associated with the current Hedera network.
119
114
  *
@@ -199,8 +194,7 @@ export declare class DAppConnector {
199
194
  *
200
195
  * @param {SignTransactionParams} params - The parameters of type {@link SignTransactionParams | `SignTransactionParams`} required for `Transaction` signing.
201
196
  * @param {string} params.signerAccountId - a signer Hedera Account identifier in {@link https://hips.hedera.com/hip/hip-30 | HIP-30} (`<nework>:<shard>.<realm>.<num>`) form.
202
- * @param {Transaction | string} params.transactionBody - a built Transaction object, or a base64 string of a transaction body (deprecated).
203
- * @deprecated Using string for params.transactionBody is deprecated and will be removed in a future version. Please migrate to using Transaction objects directly.
197
+ * @param {Transaction} params.transactionBody - a Transaction object built with the @hashgraph/sdk
204
198
  * @returns Promise\<{@link SignTransactionResult}\>
205
199
  * @example
206
200
  * ```ts
@@ -218,5 +212,7 @@ export declare class DAppConnector {
218
212
  private handleSessionUpdate;
219
213
  private handleSessionDelete;
220
214
  private handlePairingDelete;
215
+ private handleRelayConnected;
216
+ private verifyLastConnectedInstance;
221
217
  }
222
218
  export default DAppConnector;
@@ -18,10 +18,10 @@
18
18
  *
19
19
  */
20
20
  import { LedgerId, Transaction } from '@hashgraph/sdk';
21
- import QRCodeModal from '@walletconnect/qrcode-modal';
22
21
  import { WalletConnectModal } from '@walletconnect/modal';
23
22
  import SignClient from '@walletconnect/sign-client';
24
- import { getSdkError } from '@walletconnect/utils';
23
+ import { getSdkError, isOnline } from '@walletconnect/utils';
24
+ import { RELAYER_EVENTS } from '@walletconnect/core';
25
25
  import { DefaultLogger } from '../shared/logger';
26
26
  import { HederaJsonRpcMethod, accountAndLedgerFromSession, networkNamespaces, extensionConnect, findExtensions, } from '../shared';
27
27
  import { DAppSigner } from './DAppSigner';
@@ -47,11 +47,12 @@ export class DAppConnector {
47
47
  this.onSessionIframeCreated = null;
48
48
  this.signers = [];
49
49
  this.isInitializing = false;
50
+ this.storagePrefix = 'hedera-wc/dapp-connector/';
50
51
  this.abortableConnect = async (callback) => {
51
52
  return new Promise(async (resolve, reject) => {
52
53
  const pairTimeoutMs = 480000;
53
54
  const timeout = setTimeout(() => {
54
- QRCodeModal.close();
55
+ this.walletConnectModal.closeModal();
55
56
  reject(new Error(`Connect timed out after ${pairTimeoutMs}(ms)`));
56
57
  }, pairTimeoutMs);
57
58
  try {
@@ -111,6 +112,9 @@ export class DAppConnector {
111
112
  this.signers = existingSessions.flatMap((session) => this.createSigners(session));
112
113
  else
113
114
  this.checkIframeConnect();
115
+ //manual call after init before relayer connect event handler is attached
116
+ this.handleRelayConnected();
117
+ this.walletConnectClient.core.relayer.on(RELAYER_EVENTS.connect, this.handleRelayConnected.bind(this));
114
118
  this.walletConnectClient.on('session_event', this.handleSessionEvent.bind(this));
115
119
  this.walletConnectClient.on('session_update', this.handleSessionUpdate.bind(this));
116
120
  this.walletConnectClient.on('session_delete', this.handleSessionDelete.bind(this));
@@ -141,28 +145,6 @@ export class DAppConnector {
141
145
  throw new Error('Signer is not found for this accountId');
142
146
  return signer;
143
147
  }
144
- /**
145
- * Initiates the WalletConnect connection flow using a QR code.
146
- * @deprecated Use `openModal` instead.
147
- * @param pairingTopic - The pairing topic for the connection (optional).
148
- * @returns A Promise that resolves when the connection process is complete.
149
- */
150
- async connectQR(pairingTopic) {
151
- return this.abortableConnect(async () => {
152
- try {
153
- const { uri, approval } = await this.connectURI(pairingTopic);
154
- if (!uri)
155
- throw new Error('URI is not defined');
156
- QRCodeModal.open(uri, () => {
157
- throw new Error('User rejected pairing');
158
- });
159
- await this.onSessionConnected(await approval());
160
- }
161
- finally {
162
- QRCodeModal.close();
163
- }
164
- });
165
- }
166
148
  /**
167
149
  * Initiates the WalletConnect connection flow using a QR code.
168
150
  * @param pairingTopic - The pairing topic for the connection (optional).
@@ -402,6 +384,7 @@ export class DAppConnector {
402
384
  if (!signer) {
403
385
  throw new Error('There is no active session. Connect to the wallet at first.');
404
386
  }
387
+ await this.verifyLastConnectedInstance();
405
388
  this.logger.debug(`Using signer: ${signer.getAccountId().toString()}: ${signer.topic} - about to request.`);
406
389
  return await signer.request({
407
390
  method: method,
@@ -518,8 +501,7 @@ export class DAppConnector {
518
501
  *
519
502
  * @param {SignTransactionParams} params - The parameters of type {@link SignTransactionParams | `SignTransactionParams`} required for `Transaction` signing.
520
503
  * @param {string} params.signerAccountId - a signer Hedera Account identifier in {@link https://hips.hedera.com/hip/hip-30 | HIP-30} (`<nework>:<shard>.<realm>.<num>`) form.
521
- * @param {Transaction | string} params.transactionBody - a built Transaction object, or a base64 string of a transaction body (deprecated).
522
- * @deprecated Using string for params.transactionBody is deprecated and will be removed in a future version. Please migrate to using Transaction objects directly.
504
+ * @param {Transaction} params.transactionBody - a Transaction object built with the @hashgraph/sdk
523
505
  * @returns Promise\<{@link SignTransactionResult}\>
524
506
  * @example
525
507
  * ```ts
@@ -598,5 +580,33 @@ export class DAppConnector {
598
580
  }
599
581
  this.logger.info('Pairing deleted by wallet');
600
582
  }
583
+ // Store the last connected randomSessionIdentifier
584
+ async handleRelayConnected() {
585
+ if (!this.walletConnectClient) {
586
+ this.logger.error('walletConnectClient not found');
587
+ return;
588
+ }
589
+ const core = this.walletConnectClient.core;
590
+ const instanceId = core.crypto.randomSessionIdentifier;
591
+ await core.storage.setItem(this.storagePrefix + 'last-connected-instance', instanceId);
592
+ }
593
+ // In the event of another tab being connected after the current one,
594
+ // the current tab will be forcibly reconnected to the relay so that
595
+ // a response to the request can be received.
596
+ // https://github.com/hashgraph/hedera-wallet-connect/issues/387
597
+ async verifyLastConnectedInstance() {
598
+ if (!this.walletConnectClient) {
599
+ this.logger.error('walletConnectClient not found');
600
+ return;
601
+ }
602
+ const core = this.walletConnectClient.core;
603
+ const instanceId = core.crypto.randomSessionIdentifier;
604
+ const isOnlineStatus = await isOnline();
605
+ const lastConnectedInstanceId = await core.storage.getItem(this.storagePrefix + 'last-connected-instance');
606
+ if (lastConnectedInstanceId != instanceId && isOnlineStatus) {
607
+ this.logger.info('Forced reconnecting to the relay');
608
+ await core.relayer.restartTransport();
609
+ }
610
+ }
601
611
  }
602
612
  export default DAppConnector;
@@ -0,0 +1,30 @@
1
+ export interface AccountInfo {
2
+ account: string;
3
+ alias: string;
4
+ auto_renew_period: number;
5
+ balance: Balance;
6
+ created_timestamp: string;
7
+ decline_reward: boolean;
8
+ deleted: boolean;
9
+ ethereum_nonce: number;
10
+ evm_address: string;
11
+ expiry_timestamp: string;
12
+ key: Key | null;
13
+ max_automatic_token_associations: number;
14
+ memo: string;
15
+ pending_reward: number;
16
+ receiver_sig_required: boolean;
17
+ }
18
+ export interface Balance {
19
+ balance: number;
20
+ timestamp: string;
21
+ tokens: Token[];
22
+ }
23
+ export interface Token {
24
+ token_id: string;
25
+ balance: number;
26
+ }
27
+ export interface Key {
28
+ _type: string;
29
+ key: string;
30
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -5,3 +5,5 @@ export * from './methods';
5
5
  export * from './payloads';
6
6
  export * from './utils';
7
7
  export * from './extensionController';
8
+ export * from './mirrorNode';
9
+ export * from './accountInfo';
@@ -24,3 +24,5 @@ export * from './methods';
24
24
  export * from './payloads';
25
25
  export * from './utils';
26
26
  export * from './extensionController';
27
+ export * from './mirrorNode';
28
+ export * from './accountInfo';
@@ -7,7 +7,8 @@ export interface ILogger {
7
7
  export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'off';
8
8
  export declare class DefaultLogger implements ILogger {
9
9
  private logLevel;
10
- constructor(logLevel?: LogLevel);
10
+ name: string;
11
+ constructor(logLevel?: LogLevel, name?: string);
11
12
  setLogLevel(level: LogLevel): void;
12
13
  getLogLevel(): LogLevel;
13
14
  error(message: string, ...args: any[]): void;
@@ -1,7 +1,8 @@
1
1
  export class DefaultLogger {
2
- constructor(logLevel = 'info') {
2
+ constructor(logLevel = 'info', name) {
3
3
  this.logLevel = 'info';
4
4
  this.logLevel = logLevel;
5
+ this.name = name || 'Logger';
5
6
  }
6
7
  setLogLevel(level) {
7
8
  this.logLevel = level;
@@ -11,22 +12,22 @@ export class DefaultLogger {
11
12
  }
12
13
  error(message, ...args) {
13
14
  if (['error', 'warn', 'info', 'debug'].includes(this.logLevel)) {
14
- console.error(`[ERROR] ${message}`, ...args);
15
+ console.error(`[ERROR - ${this.name}] ${message}`, ...args);
15
16
  }
16
17
  }
17
18
  warn(message, ...args) {
18
19
  if (['warn', 'info', 'debug'].includes(this.logLevel)) {
19
- console.warn(`[WARN] ${message}`, ...args);
20
+ console.warn(`[WARN - ${this.name}] ${message}`, ...args);
20
21
  }
21
22
  }
22
23
  info(message, ...args) {
23
24
  if (['info', 'debug'].includes(this.logLevel)) {
24
- console.info(`[INFO] ${message}`, ...args);
25
+ console.info(`[INFO - ${this.name}] ${message}`, ...args);
25
26
  }
26
27
  }
27
28
  debug(message, ...args) {
28
29
  if (this.logLevel === 'debug') {
29
- console.debug(`[DEBUG] ${message}`, ...args);
30
+ console.debug(`[DEBUG - ${this.name}] ${message}`, ...args);
30
31
  }
31
32
  }
32
33
  }
@@ -0,0 +1,3 @@
1
+ import { LedgerId } from '@hashgraph/sdk';
2
+ import { AccountInfo } from '.';
3
+ export declare function getAccountInfo(ledgerId: LedgerId, address: string): Promise<AccountInfo | null>;
@@ -0,0 +1,17 @@
1
+ function getMirrorNodeUrl(ledgerId) {
2
+ return `https://${ledgerId.toString()}.mirrornode.hedera.com`;
3
+ }
4
+ export async function getAccountInfo(ledgerId, address) {
5
+ const mirrorNodeApiUrl = getMirrorNodeUrl(ledgerId);
6
+ const url = `${mirrorNodeApiUrl}/api/v1/accounts/${address}`;
7
+ const result = await fetch(url, {
8
+ headers: {
9
+ accept: 'application/json',
10
+ },
11
+ });
12
+ if (result.status !== 200) {
13
+ return null;
14
+ }
15
+ const response = await result.json();
16
+ return response;
17
+ }
@@ -84,11 +84,7 @@ export interface SignAndExecuteTransactionResponse extends EngineTypes.RespondPa
84
84
  }
85
85
  export interface SignTransactionParams {
86
86
  signerAccountId: string;
87
- /**
88
- * @deprecated Using string for transactionBody is deprecated and will be removed in a future version.
89
- * Please migrate to using Transaction objects directly.
90
- */
91
- transactionBody: Transaction | string;
87
+ transactionBody: Transaction;
92
88
  }
93
89
  export interface SignTransactionRequest extends EngineTypes.RequestParams {
94
90
  request: {