@hub3js/core 0.58.2-next.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/CHANGELOG.md +375 -0
- package/dist/hub/store/mod.js +2 -0
- package/dist/hub/store/mod.js.map +7 -0
- package/dist/legacy/mod.js +2 -0
- package/dist/legacy/mod.js.map +7 -0
- package/dist/mod.js +2 -0
- package/dist/mod.js.map +7 -0
- package/dist/namespaces/common/mod.js +2 -0
- package/dist/namespaces/common/mod.js.map +7 -0
- package/dist/namespaces/cosmos/mod.js +2 -0
- package/dist/namespaces/cosmos/mod.js.map +7 -0
- package/dist/namespaces/evm/mod.js +2 -0
- package/dist/namespaces/evm/mod.js.map +7 -0
- package/dist/namespaces/solana/mod.js +2 -0
- package/dist/namespaces/solana/mod.js.map +7 -0
- package/dist/namespaces/starknet/mod.js +2 -0
- package/dist/namespaces/starknet/mod.js.map +7 -0
- package/dist/namespaces/sui/mod.js +2 -0
- package/dist/namespaces/sui/mod.js.map +7 -0
- package/dist/namespaces/tron/mod.js +2 -0
- package/dist/namespaces/tron/mod.js.map +7 -0
- package/dist/namespaces/utxo/mod.js +2 -0
- package/dist/namespaces/utxo/mod.js.map +7 -0
- package/dist/namespaces/xrpl/mod.js +2 -0
- package/dist/namespaces/xrpl/mod.js.map +7 -0
- package/dist/utils/mod.js +2 -0
- package/dist/utils/mod.js.map +7 -0
- package/legacy/package.json +8 -0
- package/namespaces/common/package.json +8 -0
- package/namespaces/cosmos/package.json +8 -0
- package/namespaces/evm/package.json +8 -0
- package/namespaces/solana/package.json +8 -0
- package/namespaces/starknet/package.json +8 -0
- package/namespaces/sui/package.json +8 -0
- package/namespaces/tron/package.json +8 -0
- package/namespaces/utxo/package.json +8 -0
- package/namespaces/xrpl/package.json +8 -0
- package/package.json +100 -0
- package/readme.md +4 -0
- package/src/builders/action.ts +86 -0
- package/src/builders/mod.ts +5 -0
- package/src/builders/namespace.ts +258 -0
- package/src/builders/provider.ts +61 -0
- package/src/builders/types.ts +26 -0
- package/src/hub/helpers.ts +11 -0
- package/src/hub/hub.ts +128 -0
- package/src/hub/mod.ts +18 -0
- package/src/hub/namespaces/errors.ts +11 -0
- package/src/hub/namespaces/mod.ts +10 -0
- package/src/hub/namespaces/namespace.test.ts +443 -0
- package/src/hub/namespaces/namespace.ts +470 -0
- package/src/hub/namespaces/types.ts +58 -0
- package/src/hub/provider/mod.ts +10 -0
- package/src/hub/provider/provider.test.ts +232 -0
- package/src/hub/provider/provider.ts +335 -0
- package/src/hub/provider/types.ts +54 -0
- package/src/hub/store/events.ts +89 -0
- package/src/hub/store/extend.ts +125 -0
- package/src/hub/store/hub.ts +18 -0
- package/src/hub/store/mod.ts +25 -0
- package/src/hub/store/namespaces.ts +177 -0
- package/src/hub/store/providers.ts +169 -0
- package/src/hub/store/selectors.ts +59 -0
- package/src/hub/store/store.test.ts +50 -0
- package/src/hub/store/store.ts +30 -0
- package/src/legacy/helpers.ts +75 -0
- package/src/legacy/mod.ts +44 -0
- package/src/legacy/persistor.ts +19 -0
- package/src/legacy/types.ts +303 -0
- package/src/legacy/utils.ts +20 -0
- package/src/legacy/wallet.ts +552 -0
- package/src/mod.ts +44 -0
- package/src/namespaces/common/actions.ts +12 -0
- package/src/namespaces/common/after.ts +8 -0
- package/src/namespaces/common/and.ts +42 -0
- package/src/namespaces/common/before.ts +9 -0
- package/src/namespaces/common/builders.ts +14 -0
- package/src/namespaces/common/helpers.ts +10 -0
- package/src/namespaces/common/hooks/changeAccountSubscriber.test.ts +173 -0
- package/src/namespaces/common/hooks/changeAccountSubscriber.ts +236 -0
- package/src/namespaces/common/mod.ts +23 -0
- package/src/namespaces/common/or.ts +17 -0
- package/src/namespaces/common/types.ts +27 -0
- package/src/namespaces/common/utils.ts +43 -0
- package/src/namespaces/cosmos/actions.ts +3 -0
- package/src/namespaces/cosmos/after.ts +3 -0
- package/src/namespaces/cosmos/and.ts +5 -0
- package/src/namespaces/cosmos/before.ts +3 -0
- package/src/namespaces/cosmos/builders.ts +15 -0
- package/src/namespaces/cosmos/constants.ts +1 -0
- package/src/namespaces/cosmos/mod.ts +15 -0
- package/src/namespaces/cosmos/types.ts +31 -0
- package/src/namespaces/cosmos/utils.ts +21 -0
- package/src/namespaces/evm/actions.ts +134 -0
- package/src/namespaces/evm/after.ts +3 -0
- package/src/namespaces/evm/and.ts +5 -0
- package/src/namespaces/evm/before.ts +3 -0
- package/src/namespaces/evm/builders.ts +52 -0
- package/src/namespaces/evm/constants.ts +2 -0
- package/src/namespaces/evm/eip1193.ts +1415 -0
- package/src/namespaces/evm/hooks.ts +43 -0
- package/src/namespaces/evm/mod.ts +10 -0
- package/src/namespaces/evm/types.ts +36 -0
- package/src/namespaces/evm/utils.ts +106 -0
- package/src/namespaces/solana/actions.ts +44 -0
- package/src/namespaces/solana/after.ts +3 -0
- package/src/namespaces/solana/and.ts +5 -0
- package/src/namespaces/solana/before.ts +3 -0
- package/src/namespaces/solana/builders.ts +40 -0
- package/src/namespaces/solana/constants.ts +2 -0
- package/src/namespaces/solana/hooks.ts +10 -0
- package/src/namespaces/solana/mod.ts +10 -0
- package/src/namespaces/solana/types.ts +25 -0
- package/src/namespaces/solana/utils.ts +36 -0
- package/src/namespaces/starknet/actions.ts +19 -0
- package/src/namespaces/starknet/after.ts +3 -0
- package/src/namespaces/starknet/and.ts +5 -0
- package/src/namespaces/starknet/before.ts +3 -0
- package/src/namespaces/starknet/builders.ts +18 -0
- package/src/namespaces/starknet/constants.ts +8 -0
- package/src/namespaces/starknet/mod.ts +9 -0
- package/src/namespaces/starknet/types.ts +18 -0
- package/src/namespaces/starknet/utils.ts +35 -0
- package/src/namespaces/sui/actions.ts +27 -0
- package/src/namespaces/sui/builders.ts +77 -0
- package/src/namespaces/sui/constants.ts +8 -0
- package/src/namespaces/sui/hooks.ts +10 -0
- package/src/namespaces/sui/mod.ts +8 -0
- package/src/namespaces/sui/types.ts +25 -0
- package/src/namespaces/sui/utils.ts +56 -0
- package/src/namespaces/tron/actions.ts +3 -0
- package/src/namespaces/tron/after.ts +3 -0
- package/src/namespaces/tron/and.ts +5 -0
- package/src/namespaces/tron/before.ts +3 -0
- package/src/namespaces/tron/builders.ts +15 -0
- package/src/namespaces/tron/constants.ts +8 -0
- package/src/namespaces/tron/mod.ts +8 -0
- package/src/namespaces/tron/types.ts +14 -0
- package/src/namespaces/tron/utils.ts +18 -0
- package/src/namespaces/utxo/actions.ts +3 -0
- package/src/namespaces/utxo/after.ts +3 -0
- package/src/namespaces/utxo/and.ts +5 -0
- package/src/namespaces/utxo/before.ts +3 -0
- package/src/namespaces/utxo/builders.ts +12 -0
- package/src/namespaces/utxo/constants.ts +2 -0
- package/src/namespaces/utxo/mod.ts +8 -0
- package/src/namespaces/utxo/types.ts +14 -0
- package/src/namespaces/utxo/utils.ts +18 -0
- package/src/namespaces/xrpl/builders.ts +14 -0
- package/src/namespaces/xrpl/constants.ts +7 -0
- package/src/namespaces/xrpl/mod.ts +5 -0
- package/src/namespaces/xrpl/types.ts +16 -0
- package/src/namespaces/xrpl/utils.ts +15 -0
- package/src/test-utils/fixtures.ts +13 -0
- package/src/types/accounts.ts +12 -0
- package/src/types/actions.ts +13 -0
- package/src/types/mod.ts +1 -0
- package/src/types/utils.ts +7 -0
- package/src/utils/mod.ts +8 -0
- package/src/utils/versions.test.ts +24 -0
- package/src/utils/versions.ts +64 -0
- package/store/package.json +8 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConnectOptions,
|
|
3
|
+
EvmActions,
|
|
4
|
+
ProviderAccounts,
|
|
5
|
+
ProviderAPI,
|
|
6
|
+
} from './types.js';
|
|
7
|
+
import type { Context } from '../../hub/namespaces/mod.js';
|
|
8
|
+
import type { CanEagerConnect } from '../../hub/namespaces/types.js';
|
|
9
|
+
import type { FunctionWithContext } from '../../types/actions.js';
|
|
10
|
+
|
|
11
|
+
import { recommended as commonRecommended } from '../common/actions.js';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
filterAndGetEvmBlockchainNames,
|
|
15
|
+
formatAccountsToCAIP,
|
|
16
|
+
getAccounts,
|
|
17
|
+
switchOrAddNetwork,
|
|
18
|
+
} from './utils.js';
|
|
19
|
+
|
|
20
|
+
export const recommended = [...commonRecommended];
|
|
21
|
+
export function connect(
|
|
22
|
+
instance: () => ProviderAPI,
|
|
23
|
+
options?: ConnectOptions,
|
|
24
|
+
): FunctionWithContext<EvmActions['connect'], Context> {
|
|
25
|
+
return async (context, chain) => {
|
|
26
|
+
// Setting connect args to be used on other actions
|
|
27
|
+
const [, setState] = context.state();
|
|
28
|
+
setState('connectArgs', { chain });
|
|
29
|
+
const evmInstance = instance();
|
|
30
|
+
|
|
31
|
+
if (!evmInstance) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
'Do your wallet injected correctly and is evm compatible?',
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (chain) {
|
|
38
|
+
/*
|
|
39
|
+
* The `switchOrAddNetwork` function can be optionally provided through `options`
|
|
40
|
+
* to handle network switching or addition in a way that is compatible with the specific wallet provider.
|
|
41
|
+
* This approach is necessary because not all providers follow the same conventions—
|
|
42
|
+
* for example, Rabby uses a different error code for "chain not found".
|
|
43
|
+
*/
|
|
44
|
+
if (options?.switchOrAddNetwork) {
|
|
45
|
+
await options.switchOrAddNetwork(evmInstance, chain);
|
|
46
|
+
} else {
|
|
47
|
+
await switchOrAddNetwork(evmInstance, chain);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let providerAccounts: ProviderAccounts;
|
|
52
|
+
/*
|
|
53
|
+
* The `getAccounts` function can be optionally provided through `options`
|
|
54
|
+
* to handle getting address and chainId of the specific wallet provider.
|
|
55
|
+
* This approach is necessary because not all providers follow the same conventions.
|
|
56
|
+
*/
|
|
57
|
+
if (options?.getAccounts) {
|
|
58
|
+
providerAccounts = await options.getAccounts(evmInstance);
|
|
59
|
+
} else {
|
|
60
|
+
providerAccounts = await getAccounts(evmInstance);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Ensure that the provider returns at least one valid account before proceeding.
|
|
65
|
+
* This prevents cases (e.g., MetaMask bug) where a user connects with an account
|
|
66
|
+
* that has no associated EVM address, leaving the dApp without any usable accounts.
|
|
67
|
+
*/
|
|
68
|
+
if (!providerAccounts.accounts || !providerAccounts.accounts.length) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
'No accounts were returned by the provider. Please make sure your wallet has an active EVM-compatible account selected.',
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const formattedAccounts = formatAccountsToCAIP(
|
|
74
|
+
providerAccounts.accounts,
|
|
75
|
+
providerAccounts.chainId,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
accounts: formattedAccounts,
|
|
80
|
+
network: providerAccounts.chainId,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function canEagerConnect(
|
|
86
|
+
instance: () => ProviderAPI | undefined,
|
|
87
|
+
): CanEagerConnect<EvmActions> {
|
|
88
|
+
return async () => {
|
|
89
|
+
const evmInstance = instance();
|
|
90
|
+
|
|
91
|
+
if (!evmInstance) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
'Trying to eagerly connect to your EVM wallet, but seems its instance is not available.',
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const accounts: string[] = await evmInstance.request({
|
|
99
|
+
method: 'eth_accounts',
|
|
100
|
+
});
|
|
101
|
+
if (accounts.length) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
} catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function canSwitchNetwork(): FunctionWithContext<
|
|
111
|
+
EvmActions['canSwitchNetwork'],
|
|
112
|
+
Context
|
|
113
|
+
> {
|
|
114
|
+
return (context, params) => {
|
|
115
|
+
const { network, supportedChains } = params;
|
|
116
|
+
return filterAndGetEvmBlockchainNames(supportedChains).includes(network);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function getChainId(
|
|
121
|
+
instance: () => ProviderAPI | undefined,
|
|
122
|
+
): FunctionWithContext<EvmActions['getChainId'], Context> {
|
|
123
|
+
return async () => {
|
|
124
|
+
const evmInstance = instance();
|
|
125
|
+
|
|
126
|
+
if (!evmInstance) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
'Trying to get chain id from your EVM wallet, but instance is not available.',
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return evmInstance.request({ method: 'eth_chainId' });
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EvmActions, ProviderAPI } from './types.js';
|
|
2
|
+
|
|
3
|
+
import { ActionBuilder } from '../../mod.js';
|
|
4
|
+
import { ChangeAccountSubscriberBuilder } from '../common/hooks/changeAccountSubscriber.js';
|
|
5
|
+
import {
|
|
6
|
+
connectAndUpdateStateForMultiNetworks,
|
|
7
|
+
intoConnecting,
|
|
8
|
+
intoConnectionFinished,
|
|
9
|
+
} from '../common/mod.js';
|
|
10
|
+
|
|
11
|
+
import { formatAccountsToCAIP } from './utils.js';
|
|
12
|
+
|
|
13
|
+
// Actions
|
|
14
|
+
export const connect = () =>
|
|
15
|
+
new ActionBuilder<EvmActions, 'connect'>('connect')
|
|
16
|
+
.and(connectAndUpdateStateForMultiNetworks)
|
|
17
|
+
.before(intoConnecting)
|
|
18
|
+
.after(intoConnectionFinished);
|
|
19
|
+
|
|
20
|
+
export const canEagerConnect = () =>
|
|
21
|
+
new ActionBuilder<EvmActions, 'canEagerConnect'>('canEagerConnect');
|
|
22
|
+
export const canSwitchNetwork = () =>
|
|
23
|
+
new ActionBuilder<EvmActions, 'canSwitchNetwork'>('canSwitchNetwork');
|
|
24
|
+
|
|
25
|
+
// Hooks
|
|
26
|
+
export const changeAccountSubscriber = (getInstance: () => ProviderAPI) =>
|
|
27
|
+
new ChangeAccountSubscriberBuilder<string[], ProviderAPI, EvmActions>()
|
|
28
|
+
.getInstance(getInstance)
|
|
29
|
+
/*
|
|
30
|
+
* In some wallets, when a user switches to an account not yet connected to the dApp, it returns null.
|
|
31
|
+
* A null value indicates no access to the account, requiring a disconnect and user reconnection.
|
|
32
|
+
* This behavior may vary across different wallets, and if so, a different approach may be needed.
|
|
33
|
+
*/
|
|
34
|
+
.onSwitchAccount((event, context) => {
|
|
35
|
+
if (!event.payload || !event.payload.length) {
|
|
36
|
+
context.action('disconnect');
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.format(async (instance, accounts) => {
|
|
41
|
+
const chainId = await instance.request({ method: 'eth_chainId' });
|
|
42
|
+
return formatAccountsToCAIP(accounts, chainId);
|
|
43
|
+
})
|
|
44
|
+
.addEventListener((instance, callback) => {
|
|
45
|
+
instance.on('accountsChanged', callback);
|
|
46
|
+
})
|
|
47
|
+
.removeEventListener((instance, callback) => {
|
|
48
|
+
instance.removeListener?.('accountsChanged', callback);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const getChainId = () =>
|
|
52
|
+
new ActionBuilder<EvmActions, 'getChainId'>('getChainId');
|