@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.
- package/README.md +127 -68
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/dapp/DAppSigner.d.ts +2 -1
- package/dist/lib/dapp/DAppSigner.js +19 -22
- package/dist/lib/dapp/index.d.ts +7 -11
- package/dist/lib/dapp/index.js +37 -27
- package/dist/lib/shared/accountInfo.d.ts +30 -0
- package/dist/lib/shared/accountInfo.js +1 -0
- package/dist/lib/shared/index.d.ts +2 -0
- package/dist/lib/shared/index.js +2 -0
- package/dist/lib/shared/logger.d.ts +2 -1
- package/dist/lib/shared/logger.js +6 -5
- package/dist/lib/shared/mirrorNode.d.ts +3 -0
- package/dist/lib/shared/mirrorNode.js +17 -0
- package/dist/lib/shared/payloads.d.ts +1 -5
- package/dist/lib/shared/utils.d.ts +2 -20
- package/dist/lib/shared/utils.js +3 -30
- package/dist/lib/wallet/index.d.ts +8 -8
- package/dist/lib/wallet/index.js +7 -2
- package/dist/lib/wallet/types.d.ts +5 -5
- package/dist/reown/adapter.d.ts +37 -0
- package/dist/reown/adapter.js +255 -0
- package/dist/reown/connectors/HederaConnector.d.ts +29 -0
- package/dist/reown/connectors/HederaConnector.js +35 -0
- package/dist/reown/connectors/index.d.ts +1 -0
- package/dist/reown/connectors/index.js +1 -0
- package/dist/reown/index.d.ts +4 -0
- package/dist/reown/index.js +4 -0
- package/dist/reown/providers/EIP155Provider.d.ts +33 -0
- package/dist/reown/providers/EIP155Provider.js +187 -0
- package/dist/reown/providers/HIP820Provider.d.ts +26 -0
- package/dist/reown/providers/HIP820Provider.js +69 -0
- package/dist/reown/providers/HederaProvider.d.ts +164 -0
- package/dist/reown/providers/HederaProvider.js +471 -0
- package/dist/reown/providers/index.d.ts +3 -0
- package/dist/reown/providers/index.js +3 -0
- package/dist/reown/utils/chains.d.ts +18 -0
- package/dist/reown/utils/chains.js +152 -0
- package/dist/reown/utils/constants.d.ts +16 -0
- package/dist/reown/utils/constants.js +18 -0
- package/dist/reown/utils/helpers.d.ts +12 -0
- package/dist/reown/utils/helpers.js +25 -0
- package/dist/reown/utils/index.d.ts +4 -0
- package/dist/reown/utils/index.js +4 -0
- package/dist/reown/utils/types.d.ts +9 -0
- package/dist/reown/utils/types.js +1 -0
- package/dist/reown/wallets/EIP155Wallet.d.ts +46 -0
- package/dist/reown/wallets/EIP155Wallet.js +136 -0
- package/dist/reown/wallets/HIP820Wallet.d.ts +53 -0
- package/dist/reown/wallets/HIP820Wallet.js +239 -0
- package/dist/reown/wallets/index.d.ts +2 -0
- package/dist/reown/wallets/index.js +2 -0
- package/package.json +23 -58
package/README.md
CHANGED
@@ -1,70 +1,129 @@
|
|
1
1
|
# Overview
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Hedera
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
package/dist/index.js
CHANGED
@@ -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,
|
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
|
-
|
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
|
-
|
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({
|
package/dist/lib/dapp/index.d.ts
CHANGED
@@ -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
|
-
|
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
|
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;
|
package/dist/lib/dapp/index.js
CHANGED
@@ -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
|
-
|
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
|
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 {};
|
package/dist/lib/shared/index.js
CHANGED
@@ -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
|
-
|
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,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: {
|