@hashgraph/hedera-wallet-connect 2.0.4-canary.46d8648.0 → 2.0.4-canary.5aac7b5.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 +6 -6
- package/dist/reown/adapter.js +23 -3
- package/dist/reown/connectors/HederaConnector.d.ts +0 -1
- package/dist/reown/connectors/HederaConnector.js +3 -50
- package/dist/reown/providers/EIP155Provider.js +1 -3
- package/dist/reown/providers/HIP820Provider.js +1 -3
- package/dist/reown/providers/HederaProvider.js +21 -66
- package/package.json +2 -1
package/README.md
CHANGED
@@ -13,7 +13,7 @@ read transactions. Hedera implements EVM compatible smart contracts using
|
|
13
13
|
[Hyperledger Besu](https://besu.hyperledger.org/) under the hood.
|
14
14
|
|
15
15
|
Ethereum developers and toolsets often expect to interact with Ethereum compatible chains using
|
16
|
-
the [Ethereum JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/). To
|
16
|
+
the [Ethereum JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/). To achieve
|
17
17
|
compatibility with this API,
|
18
18
|
[Hedera JSON-RPC Providers](https://docs.hedera.com/hedera/core-concepts/smart-contracts/json-rpc-relay#community-hosted-json-rpc-relays)
|
19
19
|
operate a software middlelayer that translates Ethereum JSON-RPC compatible API calls into
|
@@ -26,7 +26,7 @@ transactions to wallets over the WalletConnect network using the JSON-RPC spec d
|
|
26
26
|
Hedera native transactions or use Ethereum JSON-RPC calls sent to a Hedera JSON-RPC Relay
|
27
27
|
provider which then communicates with Hedera consensus and mirror nodes.
|
28
28
|
|
29
|
-
On a high level, JSON-RPC is a type of API
|
29
|
+
On a high level, JSON-RPC is a type of API structure, such as SOAP, gRPC, REST, GraphQL, etc. In
|
30
30
|
the Hedera ecosystem, there are distinct concepts regarding JSON-RPC APIs to consider:
|
31
31
|
|
32
32
|
- Ethereum JSON-RPC spec defines how to interact with Ethereum compatible networks
|
@@ -34,7 +34,7 @@ the Hedera ecosystem, there are distinct concepts regarding JSON-RPC APIs to con
|
|
34
34
|
- Wallets in the Hedera ecosystem also support a separate specification that defines how to send
|
35
35
|
transactions and messages to wallets over the WalletConnect network without relying on a
|
36
36
|
Hedera JSON-RPC Relay provider. This is a Hedera specific specification defined for utilizing
|
37
|
-
the WalletConnect network
|
37
|
+
the WalletConnect network distinct from other JSON-RPC specs such as the one defined by the
|
38
38
|
Ethereum network.
|
39
39
|
|
40
40
|
For more information see:
|
@@ -64,7 +64,7 @@ reviewing the [Reown docs](https://docs.reown.com/overview).
|
|
64
64
|
1. Add Hedera dependencies to your project:
|
65
65
|
|
66
66
|
```sh
|
67
|
-
npm install @hashgraph/hedera-wallet-connect@2.0.
|
67
|
+
npm install @hashgraph/hedera-wallet-connect@2.0.4-canary.3ca04e9.0 @hashgraph/sdk @walletconnect/modal
|
68
68
|
```
|
69
69
|
|
70
70
|
2. Initialize dApp Connector
|
@@ -121,7 +121,7 @@ await dAppConnector.openModal()
|
|
121
121
|
2. Add Hedera dependencies to your project:
|
122
122
|
|
123
123
|
```sh
|
124
|
-
npm install @hashgraph/hedera-wallet-connect@2.0.
|
124
|
+
npm install @hashgraph/hedera-wallet-connect@2.0.4-canary.3ca04e9.0 @hashgraph/sdk @walletconnect/universal-provider
|
125
125
|
```
|
126
126
|
|
127
127
|
3. Update `createAppKit` with adapters and a universal provider for Hedera. Note the
|
@@ -154,7 +154,7 @@ const hederaEVMAdapter = new HederaAdapter({
|
|
154
154
|
})
|
155
155
|
|
156
156
|
const universalProvider = (await HederaProvider.init({
|
157
|
-
projectId: "YOUR_PROJECT_ID"
|
157
|
+
projectId: "YOUR_PROJECT_ID",
|
158
158
|
metadata,
|
159
159
|
})) as unknown as UniversalProvider, // avoid type mismatch error due to missing of private properties in HederaProvider
|
160
160
|
|
package/dist/reown/adapter.js
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
import { CoreHelperUtil, WcHelpersUtil } from '@reown/appkit';
|
2
2
|
import { isReownName } from '@reown/appkit-common';
|
3
3
|
import { AdapterBlueprint } from '@reown/appkit/adapters';
|
4
|
-
import { ProviderUtil } from '@reown/appkit/store';
|
5
4
|
import { LedgerId } from '@hashgraph/sdk';
|
6
5
|
import { BrowserProvider, Contract, formatUnits, JsonRpcSigner, parseUnits } from 'ethers';
|
7
6
|
import { HederaConnector } from './connectors';
|
8
|
-
import { hederaNamespace, getAccountBalance } from './utils';
|
7
|
+
import { hederaNamespace, getAccountBalance, HederaChainDefinition } from './utils';
|
9
8
|
import { createLogger } from '../lib/shared/logger';
|
10
9
|
export class HederaAdapter extends AdapterBlueprint {
|
11
10
|
constructor(params) {
|
@@ -25,6 +24,27 @@ export class HederaAdapter extends AdapterBlueprint {
|
|
25
24
|
}
|
26
25
|
super(Object.assign({}, params));
|
27
26
|
this.logger = createLogger('HederaAdapter');
|
27
|
+
// Override getCaipNetworks to return appropriate networks based on namespace
|
28
|
+
this.getCaipNetworks = (namespace) => {
|
29
|
+
const targetNamespace = namespace || this.namespace;
|
30
|
+
if (targetNamespace === 'eip155') {
|
31
|
+
// Return EIP155 Hedera networks
|
32
|
+
return [HederaChainDefinition.EVM.Mainnet, HederaChainDefinition.EVM.Testnet];
|
33
|
+
}
|
34
|
+
else if (targetNamespace === hederaNamespace) {
|
35
|
+
// Return native Hedera networks
|
36
|
+
return [HederaChainDefinition.Native.Mainnet, HederaChainDefinition.Native.Testnet];
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
// Return all Hedera networks if no specific namespace is requested
|
40
|
+
return [
|
41
|
+
HederaChainDefinition.EVM.Mainnet,
|
42
|
+
HederaChainDefinition.EVM.Testnet,
|
43
|
+
HederaChainDefinition.Native.Mainnet,
|
44
|
+
HederaChainDefinition.Native.Testnet,
|
45
|
+
];
|
46
|
+
}
|
47
|
+
};
|
28
48
|
}
|
29
49
|
async setUniversalProvider(universalProvider) {
|
30
50
|
this.addConnector(new HederaConnector({
|
@@ -200,7 +220,7 @@ export class HederaAdapter extends AdapterBlueprint {
|
|
200
220
|
if (this.namespace !== 'eip155') {
|
201
221
|
throw new Error('Namespace is not eip155');
|
202
222
|
}
|
203
|
-
const provider =
|
223
|
+
const provider = this.provider;
|
204
224
|
if (!provider) {
|
205
225
|
throw new Error('Provider is undefined');
|
206
226
|
}
|
@@ -10,7 +10,6 @@ export declare class HederaConnector implements ChainAdapterConnector {
|
|
10
10
|
readonly chain: ChainNamespace;
|
11
11
|
provider: UniversalProvider;
|
12
12
|
protected caipNetworks: CaipNetwork[];
|
13
|
-
private logger;
|
14
13
|
constructor({ provider, caipNetworks, namespace }: HederaConnector.Options);
|
15
14
|
get chains(): CaipNetwork[];
|
16
15
|
connectWalletConnect(): Promise<{
|
@@ -1,14 +1,12 @@
|
|
1
1
|
import { ConstantsUtil } from '@reown/appkit-common';
|
2
2
|
import { PresetsUtil } from '@reown/appkit-utils';
|
3
3
|
import { createNamespaces } from '../utils';
|
4
|
-
import { createLogger } from '../../lib/shared/logger';
|
5
4
|
export class HederaConnector {
|
6
5
|
constructor({ provider, caipNetworks, namespace }) {
|
7
6
|
this.id = ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT;
|
8
7
|
this.name = PresetsUtil.ConnectorNamesMap[ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT];
|
9
8
|
this.type = 'WALLET_CONNECT';
|
10
9
|
this.imageId = PresetsUtil.ConnectorImageIds[ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT];
|
11
|
-
this.logger = createLogger('HederaConnector');
|
12
10
|
this.caipNetworks = caipNetworks;
|
13
11
|
this.provider = provider;
|
14
12
|
this.chain = namespace;
|
@@ -17,54 +15,9 @@ export class HederaConnector {
|
|
17
15
|
return this.caipNetworks;
|
18
16
|
}
|
19
17
|
async connectWalletConnect() {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
this.logger.debug('Provider session exists:', !!((_c = this.provider) === null || _c === void 0 ? void 0 : _c.session));
|
24
|
-
const isAuthenticated = await this.authenticate();
|
25
|
-
this.logger.debug('Is authenticated:', isAuthenticated);
|
26
|
-
if (!isAuthenticated) {
|
27
|
-
// Check for stored connection params from the dApp
|
28
|
-
let connectParams = undefined;
|
29
|
-
this.logger.debug('Checking for stored params');
|
30
|
-
if (typeof window !== 'undefined' && window.sessionStorage) {
|
31
|
-
const storedParams = sessionStorage.getItem('hwcV2ConnectionParams');
|
32
|
-
this.logger.debug('Stored params in sessionStorage:', storedParams);
|
33
|
-
if (storedParams) {
|
34
|
-
try {
|
35
|
-
connectParams = JSON.parse(storedParams);
|
36
|
-
this.logger.info('Using stored connection params from dApp in connector:', connectParams);
|
37
|
-
// Don't clear here - let the provider handle it
|
38
|
-
}
|
39
|
-
catch (e) {
|
40
|
-
this.logger.warn('Failed to parse stored connection params in connector:', e);
|
41
|
-
}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
// If no stored params, create default namespaces
|
45
|
-
if (!connectParams) {
|
46
|
-
const namespaces = createNamespaces(this.caipNetworks);
|
47
|
-
connectParams = { optionalNamespaces: namespaces };
|
48
|
-
this.logger.debug('No stored params, using default namespaces:', connectParams);
|
49
|
-
}
|
50
|
-
this.logger.debug('Connecting with params:', {
|
51
|
-
namespace: this.chain,
|
52
|
-
caipNetworks: this.caipNetworks.map((n) => ({
|
53
|
-
id: n.id,
|
54
|
-
chainNamespace: n.chainNamespace,
|
55
|
-
caipNetworkId: n.caipNetworkId,
|
56
|
-
name: n.name,
|
57
|
-
})),
|
58
|
-
connectParams,
|
59
|
-
});
|
60
|
-
this.logger.debug('Final params before provider.connect:', connectParams);
|
61
|
-
this.logger.debug('Calling provider.connect with params');
|
62
|
-
await this.provider.connect(connectParams);
|
63
|
-
this.logger.info('Provider.connect completed successfully');
|
64
|
-
}
|
65
|
-
else {
|
66
|
-
this.logger.info('Already authenticated, skipping namespace setup');
|
67
|
-
}
|
18
|
+
const namespaces = createNamespaces(this.caipNetworks);
|
19
|
+
const connectParams = { optionalNamespaces: namespaces };
|
20
|
+
await this.provider.connect(connectParams);
|
68
21
|
return {
|
69
22
|
clientId: await this.provider.client.core.crypto.getClientId(),
|
70
23
|
session: this.provider.session,
|
@@ -53,9 +53,7 @@ class EIP155Provider {
|
|
53
53
|
return this.chainId.toString();
|
54
54
|
if (this.namespace.defaultChain)
|
55
55
|
return this.namespace.defaultChain;
|
56
|
-
const chainId = this.namespace.chains[0];
|
57
|
-
if (!chainId)
|
58
|
-
throw new Error(`ChainId not found`);
|
56
|
+
const chainId = this.namespace.chains[0] || 'eip155:295'; // default to mainnet
|
59
57
|
return chainId.split(':')[1];
|
60
58
|
}
|
61
59
|
// ---------- Private ----------------------------------------------- //
|
@@ -42,9 +42,7 @@ class HIP820Provider {
|
|
42
42
|
return this.chainId;
|
43
43
|
if (this.namespace.defaultChain)
|
44
44
|
return this.namespace.defaultChain;
|
45
|
-
const chainId = this.namespace.chains[0];
|
46
|
-
if (!chainId)
|
47
|
-
throw new Error(`ChainId not found`);
|
45
|
+
const chainId = this.namespace.chains[0] || 'hedera:mainnet'; // default to mainnet
|
48
46
|
return chainId.split(':')[1];
|
49
47
|
}
|
50
48
|
// create signer on demand
|
@@ -13,19 +13,11 @@ export class HederaProvider extends UniversalProvider {
|
|
13
13
|
this.hederaLogger = createLogger('HederaProvider');
|
14
14
|
}
|
15
15
|
static async init(opts) {
|
16
|
-
var _a, _b
|
16
|
+
var _a, _b;
|
17
17
|
const provider = new HederaProvider(opts);
|
18
|
-
//@ts-expect-error
|
18
|
+
//@ts-expect-error
|
19
19
|
await provider.initialize();
|
20
|
-
provider.namespaces = Object.assign(Object.assign({}, (((_a = provider.
|
21
|
-
? {
|
22
|
-
eip155: Object.assign(Object.assign({}, (_b = provider.namespaces) === null || _b === void 0 ? void 0 : _b.eip155), { rpcMap: ((_d = (_c = provider.optionalNamespaces) === null || _c === void 0 ? void 0 : _c.eip155) === null || _d === void 0 ? void 0 : _d.rpcMap) || {} }),
|
23
|
-
}
|
24
|
-
: {})), (((_e = provider.namespaces) === null || _e === void 0 ? void 0 : _e.hedera)
|
25
|
-
? {
|
26
|
-
hedera: Object.assign(Object.assign({}, (_f = provider.namespaces) === null || _f === void 0 ? void 0 : _f.hedera), { rpcMap: ((_h = (_g = provider.optionalNamespaces) === null || _g === void 0 ? void 0 : _g.hedera) === null || _h === void 0 ? void 0 : _h.rpcMap) || {} }),
|
27
|
-
}
|
28
|
-
: {}));
|
20
|
+
provider.namespaces = Object.assign(Object.assign({}, (((_a = provider.providerOpts) === null || _a === void 0 ? void 0 : _a.optionalNamespaces) || {})), (((_b = provider.providerOpts) === null || _b === void 0 ? void 0 : _b.requiredNamespaces) || {}));
|
29
21
|
if (provider.session)
|
30
22
|
provider.initProviders();
|
31
23
|
return provider;
|
@@ -34,13 +26,13 @@ export class HederaProvider extends UniversalProvider {
|
|
34
26
|
this.events.emit(event, data);
|
35
27
|
}
|
36
28
|
getAccountAddresses() {
|
37
|
-
if (!this.session
|
29
|
+
if (!this.session) {
|
38
30
|
throw new Error('Not initialized. Please call connect()');
|
39
31
|
}
|
40
32
|
return Object.values(this.session.namespaces).flatMap((namespace) => { var _a; return (_a = namespace.accounts.map((account) => account.split(':')[2])) !== null && _a !== void 0 ? _a : []; });
|
41
33
|
}
|
42
34
|
async request(args, chain, expiry) {
|
43
|
-
var _a, _b, _c, _d;
|
35
|
+
var _a, _b, _c, _d, _e;
|
44
36
|
if (!this.session || !this.namespaces) {
|
45
37
|
throw new Error('Please call connect() before request()');
|
46
38
|
}
|
@@ -61,8 +53,8 @@ export class HederaProvider extends UniversalProvider {
|
|
61
53
|
if (!this.eip155Provider) {
|
62
54
|
throw new Error('eip155Provider not initialized');
|
63
55
|
}
|
64
|
-
chainId = chainId !== null && chainId !== void 0 ? chainId : (_c = this.namespaces
|
65
|
-
return (
|
56
|
+
chainId = chainId !== null && chainId !== void 0 ? chainId : (_d = (_c = this.namespaces) === null || _c === void 0 ? void 0 : _c.eip155) === null || _d === void 0 ? void 0 : _d.chains[0];
|
57
|
+
return (_e = this.eip155Provider) === null || _e === void 0 ? void 0 : _e.request({
|
66
58
|
request: Object.assign({}, args),
|
67
59
|
chainId: chainId,
|
68
60
|
topic: this.session.topic,
|
@@ -415,54 +407,6 @@ export class HederaProvider extends UniversalProvider {
|
|
415
407
|
}
|
416
408
|
async connect(params) {
|
417
409
|
this.hederaLogger.debug('connect called with params:', params);
|
418
|
-
// Check for stored connection params from the dApp
|
419
|
-
if (!params || (!params.requiredNamespaces && !params.optionalNamespaces)) {
|
420
|
-
// Try to get params from sessionStorage (set by the dApp)
|
421
|
-
if (typeof window !== 'undefined' && window.sessionStorage) {
|
422
|
-
const storedParams = sessionStorage.getItem('hwcV2ConnectionParams');
|
423
|
-
this.hederaLogger.debug('Stored params in sessionStorage:', storedParams);
|
424
|
-
if (storedParams) {
|
425
|
-
try {
|
426
|
-
params = JSON.parse(storedParams);
|
427
|
-
this.hederaLogger.info('Using stored connection params from dApp:', params);
|
428
|
-
// Clear the stored params after using them
|
429
|
-
sessionStorage.removeItem('hwcV2ConnectionParams');
|
430
|
-
}
|
431
|
-
catch (e) {
|
432
|
-
this.hederaLogger.warn('Failed to parse stored connection params:', e);
|
433
|
-
}
|
434
|
-
}
|
435
|
-
}
|
436
|
-
}
|
437
|
-
// If still no params provided or empty namespaces, create default namespaces
|
438
|
-
if (!params || (!params.requiredNamespaces && !params.optionalNamespaces)) {
|
439
|
-
this.hederaLogger.info('No namespaces provided, creating default namespaces');
|
440
|
-
// Create default namespaces based on initialized state
|
441
|
-
const defaultNamespaces = {
|
442
|
-
hedera: {
|
443
|
-
methods: Object.values(HederaJsonRpcMethod),
|
444
|
-
chains: ['hedera:testnet', 'hedera:mainnet'],
|
445
|
-
events: ['accountsChanged', 'chainChanged'],
|
446
|
-
},
|
447
|
-
eip155: {
|
448
|
-
methods: [
|
449
|
-
'eth_sendTransaction',
|
450
|
-
'eth_signTransaction',
|
451
|
-
'eth_sign',
|
452
|
-
'personal_sign',
|
453
|
-
'eth_signTypedData',
|
454
|
-
'eth_signTypedData_v4',
|
455
|
-
'eth_accounts',
|
456
|
-
'eth_chainId',
|
457
|
-
],
|
458
|
-
chains: ['eip155:296', 'eip155:295'],
|
459
|
-
events: ['accountsChanged', 'chainChanged'],
|
460
|
-
},
|
461
|
-
};
|
462
|
-
params = Object.assign({ requiredNamespaces: defaultNamespaces }, params);
|
463
|
-
this.hederaLogger.debug('Using default namespaces:', params.requiredNamespaces);
|
464
|
-
}
|
465
|
-
this.hederaLogger.debug('Final params before super.connect:', params);
|
466
410
|
// Update the internal namespace properties before connecting
|
467
411
|
if (params) {
|
468
412
|
if (params.requiredNamespaces) {
|
@@ -471,10 +415,15 @@ export class HederaProvider extends UniversalProvider {
|
|
471
415
|
this.requiredNamespaces = params.requiredNamespaces;
|
472
416
|
}
|
473
417
|
if (params.optionalNamespaces) {
|
474
|
-
this.hederaLogger.debug('Setting optionalNamespaces:', params.
|
418
|
+
this.hederaLogger.debug('Setting optionalNamespaces:', params.requiredNamespaces);
|
475
419
|
// @ts-ignore - accessing private property
|
476
420
|
this.optionalNamespaces = params.optionalNamespaces;
|
477
421
|
}
|
422
|
+
if (params.namespaces) {
|
423
|
+
this.hederaLogger.debug('Setting namespaces:', params.namespaces);
|
424
|
+
// @ts-ignore - accessing private property
|
425
|
+
this.namespaces = params.namespaces;
|
426
|
+
}
|
478
427
|
}
|
479
428
|
this.hederaLogger.debug('Calling super.connect with params');
|
480
429
|
// Try to directly pass the namespaces to the parent connect
|
@@ -492,6 +441,9 @@ export class HederaProvider extends UniversalProvider {
|
|
492
441
|
return result;
|
493
442
|
}
|
494
443
|
async pair(pairingTopic) {
|
444
|
+
console.log(pairingTopic);
|
445
|
+
//@ts-expect-error
|
446
|
+
console.log(this.requiredNamespaces);
|
495
447
|
const session = await super.pair(pairingTopic);
|
496
448
|
this.initProviders();
|
497
449
|
return session;
|
@@ -506,10 +458,13 @@ export class HederaProvider extends UniversalProvider {
|
|
506
458
|
const namespaces = Object.keys(this.namespaces);
|
507
459
|
const providers = {};
|
508
460
|
namespaces.forEach((namespace) => {
|
509
|
-
|
461
|
+
var _a, _b, _c, _d;
|
462
|
+
const accounts = ((_b = (_a = this.session) === null || _a === void 0 ? void 0 : _a.namespaces[namespace]) === null || _b === void 0 ? void 0 : _b.accounts) || [];
|
510
463
|
const approvedChains = getChainsFromApprovedSession(accounts);
|
511
464
|
const mergedNamespaces = mergeRequiredOptionalNamespaces(this.namespaces, this.optionalNamespaces);
|
512
|
-
const combinedNamespace = Object.assign(Object.assign({}, mergedNamespaces[namespace]), { accounts, chains: approvedChains })
|
465
|
+
const combinedNamespace = Object.assign(Object.assign(Object.assign({}, mergedNamespaces[namespace]), { accounts, chains: approvedChains }), (((_d = (_c = this.optionalNamespaces) === null || _c === void 0 ? void 0 : _c[namespace]) === null || _d === void 0 ? void 0 : _d.rpcMap) && {
|
466
|
+
rpcMap: this.optionalNamespaces[namespace].rpcMap,
|
467
|
+
}));
|
513
468
|
switch (namespace) {
|
514
469
|
case 'hedera': {
|
515
470
|
const provider = new HIP820Provider({
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hashgraph/hedera-wallet-connect",
|
3
|
-
"version": "2.0.4-canary.
|
3
|
+
"version": "2.0.4-canary.5aac7b5.0",
|
4
4
|
"description": "A library to facilitate integrating Hedera with WalletConnect",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -38,6 +38,7 @@
|
|
38
38
|
"@swc/jest": "^0.2.37",
|
39
39
|
"@types/jest": "^30.0.0",
|
40
40
|
"jest": "^30.0.3",
|
41
|
+
"nodemon": "^3.1.10",
|
41
42
|
"prettier": "^3.5.3",
|
42
43
|
"ts-node": "^10.9.2",
|
43
44
|
"typescript": "^5.8.2"
|