@hashgraph/hedera-wallet-connect 1.3.7-canary.de9fb58.0 → 1.3.8-canary.0924bc2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{src/lib → lib}/dapp/DAppSigner.d.ts +19 -2
- package/dist/{src/lib → lib}/dapp/DAppSigner.js +126 -30
- package/dist/lib/dapp/SessionNotFoundError.d.ts +3 -0
- package/dist/lib/dapp/SessionNotFoundError.js +6 -0
- package/dist/{src/lib → lib}/dapp/index.d.ts +10 -4
- package/dist/{src/lib → lib}/dapp/index.js +66 -43
- package/dist/{src/lib → lib}/shared/logger.d.ts +4 -2
- package/dist/{src/lib → lib}/shared/logger.js +3 -0
- package/dist/{src/lib → lib}/shared/utils.d.ts +8 -2
- package/dist/{src/lib → lib}/shared/utils.js +10 -2
- package/package.json +5 -4
- package/dist/test/_helpers.d.ts +0 -38
- package/dist/test/_helpers.js +0 -95
- package/dist/test/dapp/DAppConnector.test.d.ts +0 -1
- package/dist/test/dapp/DAppConnector.test.js +0 -232
- package/dist/test/dapp/DAppSigner.test.d.ts +0 -1
- package/dist/test/dapp/DAppSigner.test.js +0 -625
- package/dist/test/shared/logger.test.d.ts +0 -1
- package/dist/test/shared/logger.test.js +0 -129
- package/dist/test/utils.test.d.ts +0 -1
- package/dist/test/utils.test.js +0 -201
- package/dist/test/wallet/methods/wallet-executeTransaction.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-executeTransaction.test.js +0 -43
- package/dist/test/wallet/methods/wallet-getNodeAddresses.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-getNodeAddresses.test.js +0 -40
- package/dist/test/wallet/methods/wallet-signAndExecuteQuery.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-signAndExecuteQuery.test.js +0 -41
- package/dist/test/wallet/methods/wallet-signAndExecuteTransaction.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-signAndExecuteTransaction.test.js +0 -48
- package/dist/test/wallet/methods/wallet-signMessage.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-signMessage.test.js +0 -60
- package/dist/test/wallet/methods/wallet-signTransaction.test.d.ts +0 -1
- package/dist/test/wallet/methods/wallet-signTransaction.test.js +0 -47
- package/dist/test/wallet/wallet-init.test.d.ts +0 -1
- package/dist/test/wallet/wallet-init.test.js +0 -53
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
- /package/dist/{src/index.js → index.js} +0 -0
- /package/dist/{src/lib → lib}/index.d.ts +0 -0
- /package/dist/{src/lib → lib}/index.js +0 -0
- /package/dist/{src/lib → lib}/shared/chainIds.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/chainIds.js +0 -0
- /package/dist/{src/lib → lib}/shared/errors.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/errors.js +0 -0
- /package/dist/{src/lib → lib}/shared/events.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/events.js +0 -0
- /package/dist/{src/lib → lib}/shared/extensionController.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/extensionController.js +0 -0
- /package/dist/{src/lib → lib}/shared/index.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/index.js +0 -0
- /package/dist/{src/lib → lib}/shared/methods.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/methods.js +0 -0
- /package/dist/{src/lib → lib}/shared/payloads.d.ts +0 -0
- /package/dist/{src/lib → lib}/shared/payloads.js +0 -0
- /package/dist/{src/lib → lib}/wallet/index.d.ts +0 -0
- /package/dist/{src/lib → lib}/wallet/index.js +0 -0
- /package/dist/{src/lib → lib}/wallet/provider.d.ts +0 -0
- /package/dist/{src/lib → lib}/wallet/provider.js +0 -0
- /package/dist/{src/lib → lib}/wallet/types.d.ts +0 -0
- /package/dist/{src/lib → lib}/wallet/types.js +0 -0
@@ -1,12 +1,19 @@
|
|
1
1
|
import { Signer, AccountBalance, AccountId, AccountInfo, Executable, Key, LedgerId, SignerSignature, Transaction, TransactionRecord } from '@hashgraph/sdk';
|
2
2
|
import type { CoreTypes, ISignClient } from '@walletconnect/types';
|
3
|
+
import { LogLevel } from '../shared/logger';
|
3
4
|
export declare class DAppSigner implements Signer {
|
4
5
|
private readonly accountId;
|
5
6
|
private readonly signClient;
|
6
7
|
readonly topic: string;
|
7
8
|
private readonly ledgerId;
|
8
9
|
readonly extensionId?: string | undefined;
|
9
|
-
|
10
|
+
private logger;
|
11
|
+
constructor(accountId: AccountId, signClient: ISignClient, topic: string, ledgerId?: LedgerId, extensionId?: string | undefined, logLevel?: LogLevel);
|
12
|
+
/**
|
13
|
+
* Sets the logging level for the DAppSigner
|
14
|
+
* @param level - The logging level to set
|
15
|
+
*/
|
16
|
+
setLogLevel(level: LogLevel): void;
|
10
17
|
private _getHederaClient;
|
11
18
|
private get _signerAccountId();
|
12
19
|
private _getRandomNodes;
|
@@ -25,7 +32,9 @@ export declare class DAppSigner implements Signer {
|
|
25
32
|
getAccountInfo(): Promise<AccountInfo>;
|
26
33
|
getAccountRecords(): Promise<TransactionRecord[]>;
|
27
34
|
getMetadata(): CoreTypes.Metadata;
|
28
|
-
sign(data: Uint8Array[], signOptions?:
|
35
|
+
sign(data: Uint8Array[], signOptions?: {
|
36
|
+
encoding?: 'utf-8' | 'base64';
|
37
|
+
}): Promise<SignerSignature[]>;
|
29
38
|
checkTransaction<T extends Transaction>(transaction: T): Promise<T>;
|
30
39
|
populateTransaction<T extends Transaction>(transaction: T): Promise<T>;
|
31
40
|
/**
|
@@ -39,6 +48,14 @@ export declare class DAppSigner implements Signer {
|
|
39
48
|
signTransaction<T extends Transaction>(transaction: T): Promise<T>;
|
40
49
|
private _tryExecuteTransactionRequest;
|
41
50
|
private _parseQueryResponse;
|
51
|
+
/**
|
52
|
+
* Executes a free receipt query without signing a transaction.
|
53
|
+
* Enables the DApp to fetch the receipt of a transaction without making a new request
|
54
|
+
* to the wallet.
|
55
|
+
* @param request - The query to execute
|
56
|
+
* @returns The result of the query
|
57
|
+
*/
|
58
|
+
private executeReceiptQueryFromRequest;
|
42
59
|
private _tryExecuteQueryRequest;
|
43
60
|
call<RequestT, ResponseT, OutputT>(request: Executable<RequestT, ResponseT, OutputT>): Promise<OutputT>;
|
44
61
|
}
|
@@ -19,15 +19,27 @@
|
|
19
19
|
*/
|
20
20
|
import { AccountBalance, AccountId, 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,
|
22
|
+
import { HederaJsonRpcMethod, base64StringToSignatureMap, base64StringToUint8Array, ledgerIdToCAIPChainId, queryToBase64String, transactionBodyToBase64String, transactionToBase64String, transactionToTransactionBody, extensionOpen, Uint8ArrayToBase64String, Uint8ArrayToString, } from '../shared';
|
23
|
+
import { DefaultLogger } from '../shared/logger';
|
24
|
+
import { SessionNotFoundError } from './SessionNotFoundError';
|
23
25
|
const clients = {};
|
24
26
|
export class DAppSigner {
|
25
|
-
constructor(accountId, signClient, topic, ledgerId = LedgerId.MAINNET, extensionId) {
|
27
|
+
constructor(accountId, signClient, topic, ledgerId = LedgerId.MAINNET, extensionId, logLevel = 'debug') {
|
26
28
|
this.accountId = accountId;
|
27
29
|
this.signClient = signClient;
|
28
30
|
this.topic = topic;
|
29
31
|
this.ledgerId = ledgerId;
|
30
32
|
this.extensionId = extensionId;
|
33
|
+
this.logger = new DefaultLogger(logLevel);
|
34
|
+
}
|
35
|
+
/**
|
36
|
+
* Sets the logging level for the DAppSigner
|
37
|
+
* @param level - The logging level to set
|
38
|
+
*/
|
39
|
+
setLogLevel(level) {
|
40
|
+
if (this.logger instanceof DefaultLogger) {
|
41
|
+
this.logger.setLogLevel(level);
|
42
|
+
}
|
31
43
|
}
|
32
44
|
_getHederaClient() {
|
33
45
|
const ledgerIdString = this.ledgerId.toString();
|
@@ -49,6 +61,21 @@ export class DAppSigner {
|
|
49
61
|
return allNodes.slice(0, numberOfNodes);
|
50
62
|
}
|
51
63
|
request(request) {
|
64
|
+
var _a, _b;
|
65
|
+
// Avoid a wallet call if the session is no longer valid
|
66
|
+
if (!((_b = (_a = this === null || this === void 0 ? void 0 : this.signClient) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.get(this.topic))) {
|
67
|
+
this.logger.error('Session no longer exists, signer will be removed. Please reconnect to the wallet.');
|
68
|
+
// Notify DAppConnector to remove this signer
|
69
|
+
this.signClient.emit({
|
70
|
+
topic: this.topic,
|
71
|
+
event: {
|
72
|
+
name: 'session_delete',
|
73
|
+
data: { topic: this.topic },
|
74
|
+
},
|
75
|
+
chainId: ledgerIdToCAIPChainId(this.ledgerId),
|
76
|
+
});
|
77
|
+
throw new SessionNotFoundError('Session no longer exists. Please reconnect to the wallet.');
|
78
|
+
}
|
52
79
|
if (this.extensionId)
|
53
80
|
extensionOpen(this.extensionId);
|
54
81
|
return this.signClient.request({
|
@@ -84,22 +111,34 @@ export class DAppSigner {
|
|
84
111
|
getMetadata() {
|
85
112
|
return this.signClient.metadata;
|
86
113
|
}
|
87
|
-
async sign(data, signOptions
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
114
|
+
async sign(data, signOptions = {
|
115
|
+
encoding: 'utf-8',
|
116
|
+
}) {
|
117
|
+
try {
|
118
|
+
const messageToSign = signOptions.encoding === 'base64'
|
119
|
+
? Uint8ArrayToBase64String(data[0])
|
120
|
+
: Uint8ArrayToString(data[0]);
|
121
|
+
const { signatureMap } = await this.request({
|
122
|
+
method: HederaJsonRpcMethod.SignMessage,
|
123
|
+
params: {
|
124
|
+
signerAccountId: this._signerAccountId,
|
125
|
+
message: messageToSign,
|
126
|
+
},
|
127
|
+
});
|
128
|
+
const sigmap = base64StringToSignatureMap(signatureMap);
|
129
|
+
const signerSignature = new SignerSignature({
|
130
|
+
accountId: this.getAccountId(),
|
131
|
+
publicKey: PublicKey.fromBytes(sigmap.sigPair[0].pubKeyPrefix),
|
132
|
+
signature: sigmap.sigPair[0].ed25519 ||
|
133
|
+
sigmap.sigPair[0].ECDSASecp256k1,
|
134
|
+
});
|
135
|
+
this.logger.debug('Data signed successfully');
|
136
|
+
return [signerSignature];
|
137
|
+
}
|
138
|
+
catch (error) {
|
139
|
+
this.logger.error('Error signing data:', error);
|
140
|
+
throw error;
|
141
|
+
}
|
103
142
|
}
|
104
143
|
async checkTransaction(transaction) {
|
105
144
|
throw new Error('Method not implemented.');
|
@@ -141,7 +180,10 @@ export class DAppSigner {
|
|
141
180
|
}
|
142
181
|
async _tryExecuteTransactionRequest(request) {
|
143
182
|
try {
|
144
|
-
const
|
183
|
+
const requestToBytes = request.toBytes();
|
184
|
+
this.logger.debug('Creating transaction from bytes', requestToBytes, request);
|
185
|
+
const transaction = Transaction.fromBytes(requestToBytes);
|
186
|
+
this.logger.debug('Executing transaction request', transaction);
|
145
187
|
const result = await this.request({
|
146
188
|
method: HederaJsonRpcMethod.SignAndExecuteTransaction,
|
147
189
|
params: {
|
@@ -149,9 +191,11 @@ export class DAppSigner {
|
|
149
191
|
transactionList: transactionToBase64String(transaction),
|
150
192
|
},
|
151
193
|
});
|
194
|
+
this.logger.debug('Transaction request completed successfully');
|
152
195
|
return { result: TransactionResponse.fromJSON(result) };
|
153
196
|
}
|
154
197
|
catch (error) {
|
198
|
+
this.logger.error('Error executing transaction request:', error);
|
155
199
|
return { error };
|
156
200
|
}
|
157
201
|
}
|
@@ -178,9 +222,44 @@ export class DAppSigner {
|
|
178
222
|
throw new Error('Unsupported query type');
|
179
223
|
}
|
180
224
|
}
|
225
|
+
/**
|
226
|
+
* Executes a free receipt query without signing a transaction.
|
227
|
+
* Enables the DApp to fetch the receipt of a transaction without making a new request
|
228
|
+
* to the wallet.
|
229
|
+
* @param request - The query to execute
|
230
|
+
* @returns The result of the query
|
231
|
+
*/
|
232
|
+
async executeReceiptQueryFromRequest(request) {
|
233
|
+
try {
|
234
|
+
const isMainnet = this.ledgerId === LedgerId.MAINNET;
|
235
|
+
const client = isMainnet ? Client.forMainnet() : Client.forTestnet();
|
236
|
+
const receipt = TransactionReceiptQuery.fromBytes(request.toBytes());
|
237
|
+
const result = await receipt.execute(client);
|
238
|
+
return { result };
|
239
|
+
}
|
240
|
+
catch (error) {
|
241
|
+
return { error };
|
242
|
+
}
|
243
|
+
}
|
181
244
|
async _tryExecuteQueryRequest(request) {
|
182
245
|
try {
|
183
|
-
const
|
246
|
+
const isReceiptQuery = request instanceof TransactionReceiptQuery;
|
247
|
+
if (isReceiptQuery) {
|
248
|
+
this.logger.debug('Attempting to execute free receipt query', request);
|
249
|
+
const result = await this.executeReceiptQueryFromRequest(request);
|
250
|
+
if (!(result === null || result === void 0 ? void 0 : result.error)) {
|
251
|
+
return { result: result.result };
|
252
|
+
}
|
253
|
+
this.logger.error('Error executing free receipt query. Sending to wallet.', result.error);
|
254
|
+
}
|
255
|
+
/**
|
256
|
+
* Note, should we be converting these to specific query types?
|
257
|
+
* Left alone to avoid changing the API for other requests.
|
258
|
+
*/
|
259
|
+
const query = isReceiptQuery
|
260
|
+
? TransactionReceiptQuery.fromBytes(request.toBytes())
|
261
|
+
: Query.fromBytes(request.toBytes());
|
262
|
+
this.logger.debug('Executing query request', query, queryToBase64String(query), isReceiptQuery);
|
184
263
|
const result = await this.request({
|
185
264
|
method: HederaJsonRpcMethod.SignAndExecuteQuery,
|
186
265
|
params: {
|
@@ -188,34 +267,51 @@ export class DAppSigner {
|
|
188
267
|
query: queryToBase64String(query),
|
189
268
|
},
|
190
269
|
});
|
270
|
+
this.logger.debug('Query request completed successfully', result);
|
191
271
|
return { result: this._parseQueryResponse(query, result.response) };
|
192
272
|
}
|
193
273
|
catch (error) {
|
274
|
+
this.logger.error('Error executing query request:', error);
|
194
275
|
return { error };
|
195
276
|
}
|
196
277
|
}
|
197
278
|
async call(request) {
|
198
|
-
var _a, _b, _c, _d, _e, _f;
|
199
|
-
const
|
200
|
-
|
201
|
-
|
279
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
280
|
+
const isReceiptQuery = request instanceof TransactionReceiptQuery;
|
281
|
+
let txResult = undefined;
|
282
|
+
// a receipt query is a free query and we should not execute a transaction.
|
283
|
+
if (!isReceiptQuery) {
|
284
|
+
txResult = await this._tryExecuteTransactionRequest(request);
|
285
|
+
if (txResult.result) {
|
286
|
+
return txResult.result;
|
287
|
+
}
|
202
288
|
}
|
203
289
|
const queryResult = await this._tryExecuteQueryRequest(request);
|
204
290
|
if (queryResult.result) {
|
205
291
|
return queryResult.result;
|
206
292
|
}
|
207
293
|
// TODO: make this error more usable
|
294
|
+
if (isReceiptQuery) {
|
295
|
+
throw new Error('Error executing receipt query: \n' +
|
296
|
+
JSON.stringify({
|
297
|
+
queryError: {
|
298
|
+
name: (_a = queryResult.error) === null || _a === void 0 ? void 0 : _a.name,
|
299
|
+
message: (_b = queryResult.error) === null || _b === void 0 ? void 0 : _b.message,
|
300
|
+
stack: (_c = queryResult.error) === null || _c === void 0 ? void 0 : _c.stack,
|
301
|
+
},
|
302
|
+
}));
|
303
|
+
}
|
208
304
|
throw new Error('Error executing transaction or query: \n' +
|
209
305
|
JSON.stringify({
|
210
306
|
txError: {
|
211
|
-
name: (
|
212
|
-
message: (
|
213
|
-
stack: (
|
307
|
+
name: (_d = txResult === null || txResult === void 0 ? void 0 : txResult.error) === null || _d === void 0 ? void 0 : _d.name,
|
308
|
+
message: (_e = txResult === null || txResult === void 0 ? void 0 : txResult.error) === null || _e === void 0 ? void 0 : _e.message,
|
309
|
+
stack: (_f = txResult === null || txResult === void 0 ? void 0 : txResult.error) === null || _f === void 0 ? void 0 : _f.stack,
|
214
310
|
},
|
215
311
|
queryError: {
|
216
|
-
name: (
|
217
|
-
message: (
|
218
|
-
stack: (
|
312
|
+
name: (_g = queryResult.error) === null || _g === void 0 ? void 0 : _g.name,
|
313
|
+
message: (_h = queryResult.error) === null || _h === void 0 ? void 0 : _h.message,
|
314
|
+
stack: (_j = queryResult.error) === null || _j === void 0 ? void 0 : _j.stack,
|
219
315
|
},
|
220
316
|
}, null, 2));
|
221
317
|
}
|
@@ -2,6 +2,7 @@ import { AccountId, LedgerId } from '@hashgraph/sdk';
|
|
2
2
|
import { SessionTypes, SignClientTypes } from '@walletconnect/types';
|
3
3
|
import { WalletConnectModal } from '@walletconnect/modal';
|
4
4
|
import SignClient from '@walletconnect/sign-client';
|
5
|
+
import { LogLevel } from '../shared/logger';
|
5
6
|
import { GetNodeAddressesResult, ExecuteTransactionParams, ExecuteTransactionResult, SignMessageParams, SignMessageResult, SignAndExecuteQueryResult, SignAndExecuteQueryParams, SignAndExecuteTransactionParams, SignAndExecuteTransactionResult, SignTransactionParams, SignTransactionResult, ExtensionData } from '../shared';
|
6
7
|
import { DAppSigner } from './DAppSigner';
|
7
8
|
export * from './DAppSigner';
|
@@ -30,12 +31,12 @@ export declare class DAppConnector {
|
|
30
31
|
* @param chains - Array of supported chains for the DApp (optional).
|
31
32
|
* @param logLevel - Logging level for the DAppConnector (optional).
|
32
33
|
*/
|
33
|
-
constructor(metadata: SignClientTypes.Metadata, network: LedgerId, projectId: string, methods?: string[], events?: string[], chains?: string[], logLevel?:
|
34
|
+
constructor(metadata: SignClientTypes.Metadata, network: LedgerId, projectId: string, methods?: string[], events?: string[], chains?: string[], logLevel?: LogLevel);
|
34
35
|
/**
|
35
36
|
* Sets the logging level for the DAppConnector
|
36
37
|
* @param level - The logging level to set
|
37
38
|
*/
|
38
|
-
setLogLevel(level:
|
39
|
+
setLogLevel(level: LogLevel): void;
|
39
40
|
/**
|
40
41
|
* Initializes the DAppConnector instance.
|
41
42
|
* @param logger - `BaseLogger` for logging purposes (optional).
|
@@ -79,9 +80,10 @@ export declare class DAppConnector {
|
|
79
80
|
*/
|
80
81
|
connectExtension(extensionId: string, pairingTopic?: string): Promise<SessionTypes.Struct>;
|
81
82
|
/**
|
82
|
-
* Validates the session by checking if the session exists.
|
83
|
+
* Validates the session by checking if the session exists and is valid.
|
84
|
+
* Also ensures the signer exists for the session.
|
83
85
|
* @param topic - The topic of the session to validate.
|
84
|
-
* @returns {boolean} - True if the session exists, false otherwise.
|
86
|
+
* @returns {boolean} - True if the session exists and has a valid signer, false otherwise.
|
85
87
|
*/
|
86
88
|
private validateSession;
|
87
89
|
/**
|
@@ -211,5 +213,9 @@ export declare class DAppConnector {
|
|
211
213
|
* ```
|
212
214
|
*/
|
213
215
|
signTransaction(params: SignTransactionParams): Promise<SignTransactionResult>;
|
216
|
+
private handleSessionEvent;
|
217
|
+
private handleSessionUpdate;
|
218
|
+
private handleSessionDelete;
|
219
|
+
private handlePairingDelete;
|
214
220
|
}
|
215
221
|
export default DAppConnector;
|
@@ -110,45 +110,12 @@ export class DAppConnector {
|
|
110
110
|
this.signers = existingSessions.flatMap((session) => this.createSigners(session));
|
111
111
|
else
|
112
112
|
this.checkIframeConnect();
|
113
|
-
this.walletConnectClient.on('session_event', (
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
this.walletConnectClient.on('
|
119
|
-
// Handle session update
|
120
|
-
const { namespaces } = params;
|
121
|
-
const _session = this.walletConnectClient.session.get(topic);
|
122
|
-
// Overwrite the `namespaces` of the existing session with the incoming one.
|
123
|
-
const updatedSession = Object.assign(Object.assign({}, _session), { namespaces });
|
124
|
-
// Integrate the updated session state into your dapp state.
|
125
|
-
this.logger.info('Session updated:', updatedSession);
|
126
|
-
this.signers = this.signers.filter((signer) => signer.topic !== topic);
|
127
|
-
this.signers.push(...this.createSigners(updatedSession));
|
128
|
-
});
|
129
|
-
this.walletConnectClient.on('session_delete', (pairing) => {
|
130
|
-
this.logger.info('Session deleted:', pairing);
|
131
|
-
this.signers = this.signers.filter((signer) => signer.topic !== pairing.topic);
|
132
|
-
// Session was deleted -> reset the dapp state, clean up from user session, etc.
|
133
|
-
try {
|
134
|
-
this.disconnect(pairing.topic);
|
135
|
-
}
|
136
|
-
catch (e) {
|
137
|
-
this.logger.error('Error disconnecting session:', e);
|
138
|
-
}
|
139
|
-
this.logger.info('Session deleted by wallet');
|
140
|
-
});
|
141
|
-
this.walletConnectClient.core.pairing.events.on('pairing_delete', (pairing) => {
|
142
|
-
this.logger.info('Pairing deleted:', pairing);
|
143
|
-
this.signers = this.signers.filter((signer) => signer.topic !== pairing.topic);
|
144
|
-
try {
|
145
|
-
this.disconnect(pairing.topic);
|
146
|
-
}
|
147
|
-
catch (e) {
|
148
|
-
this.logger.error('Error disconnecting pairing:', e);
|
149
|
-
}
|
150
|
-
this.logger.info('Pairing deleted by wallet');
|
151
|
-
});
|
113
|
+
this.walletConnectClient.on('session_event', this.handleSessionEvent.bind(this));
|
114
|
+
this.walletConnectClient.on('session_update', this.handleSessionUpdate.bind(this));
|
115
|
+
this.walletConnectClient.on('session_delete', this.handleSessionDelete.bind(this));
|
116
|
+
// Listen for custom session_delete events from DAppSigner
|
117
|
+
this.walletConnectClient.core.events.on('session_delete', this.handleSessionDelete.bind(this));
|
118
|
+
this.walletConnectClient.core.pairing.events.on('pairing_delete', this.handlePairingDelete.bind(this));
|
152
119
|
}
|
153
120
|
catch (e) {
|
154
121
|
this.logger.error('Error initializing DAppConnector:', e);
|
@@ -252,9 +219,10 @@ export class DAppConnector {
|
|
252
219
|
}, pairingTopic, extension.availableInIframe ? undefined : extensionId);
|
253
220
|
}
|
254
221
|
/**
|
255
|
-
* Validates the session by checking if the session exists.
|
222
|
+
* Validates the session by checking if the session exists and is valid.
|
223
|
+
* Also ensures the signer exists for the session.
|
256
224
|
* @param topic - The topic of the session to validate.
|
257
|
-
* @returns {boolean} - True if the session exists, false otherwise.
|
225
|
+
* @returns {boolean} - True if the session exists and has a valid signer, false otherwise.
|
258
226
|
*/
|
259
227
|
validateSession(topic) {
|
260
228
|
try {
|
@@ -262,12 +230,23 @@ export class DAppConnector {
|
|
262
230
|
return false;
|
263
231
|
}
|
264
232
|
const session = this.walletConnectClient.session.get(topic);
|
233
|
+
const hasSigner = this.signers.some((signer) => signer.topic === topic);
|
265
234
|
if (!session) {
|
235
|
+
// If session doesn't exist but we have a signer for it, clean up
|
236
|
+
if (hasSigner) {
|
237
|
+
this.logger.warn(`Signer exists but no session found for topic: ${topic}`);
|
238
|
+
this.handleSessionDelete({ topic });
|
239
|
+
}
|
240
|
+
return false;
|
241
|
+
}
|
242
|
+
if (!hasSigner) {
|
243
|
+
this.logger.warn(`Session exists but no signer found for topic: ${topic}`);
|
266
244
|
return false;
|
267
245
|
}
|
268
246
|
return true;
|
269
247
|
}
|
270
|
-
catch (
|
248
|
+
catch (e) {
|
249
|
+
this.logger.error('Error validating session:', e);
|
271
250
|
return false;
|
272
251
|
}
|
273
252
|
}
|
@@ -344,7 +323,7 @@ export class DAppConnector {
|
|
344
323
|
const allNamespaceAccounts = accountAndLedgerFromSession(session);
|
345
324
|
return allNamespaceAccounts.map(({ account, network }) => {
|
346
325
|
var _a;
|
347
|
-
return new DAppSigner(account, this.walletConnectClient, session.topic, network, (_a = session.sessionProperties) === null || _a === void 0 ? void 0 : _a.extensionId);
|
326
|
+
return new DAppSigner(account, this.walletConnectClient, session.topic, network, (_a = session.sessionProperties) === null || _a === void 0 ? void 0 : _a.extensionId, this.logger instanceof DefaultLogger ? this.logger.getLogLevel() : 'debug');
|
348
327
|
});
|
349
328
|
}
|
350
329
|
async onSessionConnected(session) {
|
@@ -542,5 +521,49 @@ export class DAppConnector {
|
|
542
521
|
params,
|
543
522
|
});
|
544
523
|
}
|
524
|
+
handleSessionEvent(args) {
|
525
|
+
this.logger.debug('Session event received:', args);
|
526
|
+
this.validateAndRefreshSigners();
|
527
|
+
}
|
528
|
+
handleSessionUpdate({ topic, params, }) {
|
529
|
+
const { namespaces } = params;
|
530
|
+
const _session = this.walletConnectClient.session.get(topic);
|
531
|
+
const updatedSession = Object.assign(Object.assign({}, _session), { namespaces });
|
532
|
+
this.logger.info('Session updated:', updatedSession);
|
533
|
+
this.signers = this.signers.filter((signer) => signer.topic !== topic);
|
534
|
+
this.signers.push(...this.createSigners(updatedSession));
|
535
|
+
}
|
536
|
+
handleSessionDelete(event) {
|
537
|
+
this.logger.info('Session deleted:', event);
|
538
|
+
let deletedSigner = false;
|
539
|
+
this.signers = this.signers.filter((signer) => {
|
540
|
+
if (signer.topic !== event.topic) {
|
541
|
+
return true;
|
542
|
+
}
|
543
|
+
deletedSigner = true;
|
544
|
+
return false;
|
545
|
+
});
|
546
|
+
// prevent emitting disconnected event if signers is untouched.
|
547
|
+
if (deletedSigner) {
|
548
|
+
try {
|
549
|
+
this.disconnect(event.topic);
|
550
|
+
}
|
551
|
+
catch (e) {
|
552
|
+
this.logger.error('Error disconnecting session:', e);
|
553
|
+
}
|
554
|
+
this.logger.info('Session deleted and signer removed');
|
555
|
+
}
|
556
|
+
}
|
557
|
+
handlePairingDelete(event) {
|
558
|
+
this.logger.info('Pairing deleted:', event);
|
559
|
+
this.signers = this.signers.filter((signer) => signer.topic !== event.topic);
|
560
|
+
try {
|
561
|
+
this.disconnect(event.topic);
|
562
|
+
}
|
563
|
+
catch (e) {
|
564
|
+
this.logger.error('Error disconnecting pairing:', e);
|
565
|
+
}
|
566
|
+
this.logger.info('Pairing deleted by wallet');
|
567
|
+
}
|
545
568
|
}
|
546
569
|
export default DAppConnector;
|
@@ -4,10 +4,12 @@ export interface ILogger {
|
|
4
4
|
info(message: string, ...args: any[]): void;
|
5
5
|
debug(message: string, ...args: any[]): void;
|
6
6
|
}
|
7
|
+
export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'off';
|
7
8
|
export declare class DefaultLogger implements ILogger {
|
8
9
|
private logLevel;
|
9
|
-
constructor(logLevel?:
|
10
|
-
setLogLevel(level:
|
10
|
+
constructor(logLevel?: LogLevel);
|
11
|
+
setLogLevel(level: LogLevel): void;
|
12
|
+
getLogLevel(): LogLevel;
|
11
13
|
error(message: string, ...args: any[]): void;
|
12
14
|
warn(message: string, ...args: any[]): void;
|
13
15
|
info(message: string, ...args: any[]): void;
|
@@ -6,6 +6,9 @@ export class DefaultLogger {
|
|
6
6
|
setLogLevel(level) {
|
7
7
|
this.logLevel = level;
|
8
8
|
}
|
9
|
+
getLogLevel() {
|
10
|
+
return this.logLevel;
|
11
|
+
}
|
9
12
|
error(message, ...args) {
|
10
13
|
if (['error', 'warn', 'info', 'debug'].includes(this.logLevel)) {
|
11
14
|
console.error(`[ERROR] ${message}`, ...args);
|
@@ -49,8 +49,8 @@ export declare function base64StringToTransaction<T extends Transaction>(transac
|
|
49
49
|
* @param transaction - a base64 encoded string of proto.TransactionBody.encode().finish()
|
50
50
|
* @returns `string`
|
51
51
|
* */
|
52
|
-
export declare function transactionToTransactionBody<T extends Transaction>(transaction: T, nodeAccountId: AccountId):
|
53
|
-
export declare function transactionBodyToBase64String(transactionBody:
|
52
|
+
export declare function transactionToTransactionBody<T extends Transaction>(transaction: T, nodeAccountId: AccountId): any;
|
53
|
+
export declare function transactionBodyToBase64String(transactionBody: proto.ITransactionBody): string;
|
54
54
|
/**
|
55
55
|
* @param transactionList - a proto.TransactionList object
|
56
56
|
* @returns `string`
|
@@ -85,6 +85,12 @@ export declare function base64StringToSignatureMap(base64string: string): proto.
|
|
85
85
|
* @returns Base64-encoded string representation of the input `Uint8Array`
|
86
86
|
*/
|
87
87
|
export declare function Uint8ArrayToBase64String(binary: Uint8Array): string;
|
88
|
+
/**
|
89
|
+
* Encodes the binary data represented by the `Uint8Array` to a UTF-8 string.
|
90
|
+
* @param binary - The `Uint8Array` containing binary data to be converted
|
91
|
+
* @returns UTF-8 string representation of the input `Uint8Array`
|
92
|
+
*/
|
93
|
+
export declare function Uint8ArrayToString(binary: Uint8Array): string;
|
88
94
|
/**
|
89
95
|
* Converts a Base64-encoded string to a `Uint8Array`.
|
90
96
|
* @param base64string - Base64-encoded string to be converted
|
@@ -86,10 +86,10 @@ export function base64StringToTransaction(transactionBytes) {
|
|
86
86
|
export function transactionToTransactionBody(transaction, nodeAccountId) {
|
87
87
|
// This is a private function, though provides the capabilities to construct a proto.TransactionBody
|
88
88
|
//@ts-ignore
|
89
|
-
return transaction.
|
89
|
+
return transaction._makeTransactionBody(nodeAccountId);
|
90
90
|
}
|
91
91
|
export function transactionBodyToBase64String(transactionBody) {
|
92
|
-
return Uint8ArrayToBase64String(transactionBody);
|
92
|
+
return Uint8ArrayToBase64String(proto.TransactionBody.encode(transactionBody).finish());
|
93
93
|
}
|
94
94
|
/**
|
95
95
|
* @param transactionList - a proto.TransactionList object
|
@@ -139,6 +139,14 @@ export function base64StringToSignatureMap(base64string) {
|
|
139
139
|
export function Uint8ArrayToBase64String(binary) {
|
140
140
|
return Buffer.from(binary).toString('base64');
|
141
141
|
}
|
142
|
+
/**
|
143
|
+
* Encodes the binary data represented by the `Uint8Array` to a UTF-8 string.
|
144
|
+
* @param binary - The `Uint8Array` containing binary data to be converted
|
145
|
+
* @returns UTF-8 string representation of the input `Uint8Array`
|
146
|
+
*/
|
147
|
+
export function Uint8ArrayToString(binary) {
|
148
|
+
return Buffer.from(binary).toString('utf-8');
|
149
|
+
}
|
142
150
|
/**
|
143
151
|
* Converts a Base64-encoded string to a `Uint8Array`.
|
144
152
|
* @param base64string - Base64-encoded string to be converted
|
package/package.json
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hashgraph/hedera-wallet-connect",
|
3
|
-
"version": "1.3.
|
3
|
+
"version": "1.3.8-canary.0924bc2.0",
|
4
4
|
"description": "A library to facilitate integrating Hedera with WalletConnect",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
7
7
|
"url": "git+https://github.com/hashgraph/hedera-wallet-connect.git"
|
8
8
|
},
|
9
|
-
"main": "./dist/
|
10
|
-
"types": "./dist/
|
9
|
+
"main": "./dist/index.js",
|
10
|
+
"types": "./dist/index.d.ts",
|
11
11
|
"author": "Hgraph <support@hgraph.io>",
|
12
12
|
"keywords": [
|
13
13
|
"hedera",
|
@@ -28,7 +28,7 @@
|
|
28
28
|
"concurrently": "^9.0.1",
|
29
29
|
"esbuild": "^0.24.0",
|
30
30
|
"esbuild-plugin-copy": "^2.1.1",
|
31
|
-
"eslint-plugin-tsdoc": "^0.
|
31
|
+
"eslint-plugin-tsdoc": "^0.4.0",
|
32
32
|
"husky": "^9.0.6",
|
33
33
|
"jest": "^29.7.0",
|
34
34
|
"lint-staged": "^15.1.0",
|
@@ -55,6 +55,7 @@
|
|
55
55
|
"dev:ts-demo": "rimraf dist && npm run build && concurrently --raw \"npm run watch\" \"node scripts/demos/typescript/dev.mjs\"",
|
56
56
|
"dev:react-demo": "rimraf dist && npm run build && concurrently --raw \"npm run watch\" \"node scripts/demos/react/dev.mjs\"",
|
57
57
|
"test": "jest",
|
58
|
+
"test:watch": "jest --watch",
|
58
59
|
"test:connect": "jest --testMatch '**/DAppConnector.test.ts' --verbose",
|
59
60
|
"test:signer": "jest --testMatch '**/DAppSigner.test.ts' --verbose",
|
60
61
|
"prepublishOnly": "rm -Rf dist && npm run build",
|
package/dist/test/_helpers.d.ts
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
import { AccountId, Query, Transaction, TransactionId } from '@hashgraph/sdk';
|
2
|
-
export declare const projectId = "ce06497abf4102004138a10edd29c921";
|
3
|
-
export declare const walletMetadata: {
|
4
|
-
name: string;
|
5
|
-
url: string;
|
6
|
-
description: string;
|
7
|
-
icons: string[];
|
8
|
-
};
|
9
|
-
export declare const dAppMetadata: {
|
10
|
-
name: string;
|
11
|
-
url: string;
|
12
|
-
description: string;
|
13
|
-
icons: string[];
|
14
|
-
};
|
15
|
-
export declare const requestId = 1;
|
16
|
-
export declare const requestTopic = "test-topic";
|
17
|
-
export declare const defaultAccountNumber = 12345;
|
18
|
-
export declare const defaultNodeId = 3;
|
19
|
-
export declare const testUserAccountId: AccountId;
|
20
|
-
export declare const testNodeAccountId: AccountId;
|
21
|
-
/** Fixed to a specific timestamp */
|
22
|
-
export declare const testTransactionId: TransactionId;
|
23
|
-
type TransactionOptions = {
|
24
|
-
setNodeAccountIds?: boolean;
|
25
|
-
setTransactionId?: boolean;
|
26
|
-
freeze?: boolean;
|
27
|
-
operatorAccountId?: number;
|
28
|
-
};
|
29
|
-
export declare function prepareTestTransaction<T extends Transaction = Transaction>(transaction: T, options?: TransactionOptions): T;
|
30
|
-
type QueryOptions = {
|
31
|
-
setNodeAccountIds?: boolean;
|
32
|
-
};
|
33
|
-
export declare function prepareTestQuery<Q extends Query<OutputT>, OutputT>(query: Q, options?: QueryOptions): Q;
|
34
|
-
export declare const testPrivateKeyECDSA = "3030020100300706052b8104000a042204203ce31ffad30d6db47c315bbea08232aad2266d8800a12aa3d8a812486e782759";
|
35
|
-
export declare const testPrivateKeyED25519 = "302e020100300506032b657004220420133eefea772add1f995c96bccf42b08b76daf67665f0c4c5ae308fae9275c142";
|
36
|
-
export declare function useJsonFixture(filename: string): any;
|
37
|
-
export declare function writeJsonFixture(filename: string, data: any): void;
|
38
|
-
export {};
|