@w3ux/react-connect-kit 3.2.10 → 3.2.12
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createSafeContext, useEffectIgnoreInitial } from '@w3ux/hooks';
|
|
3
|
-
import { getAccountsFromExtensions, processExtensionAccounts, } from '@w3ux/observables-connect/accounts';
|
|
3
|
+
import { addUnsub, getAccountsFromExtensions, processExtensionAccounts, unsubAll, } from '@w3ux/observables-connect/accounts';
|
|
4
4
|
import { connectExtensions, getActiveExtensionsLocal, } from '@w3ux/observables-connect/extensions';
|
|
5
5
|
import { initialisedExtensions$ } from '@w3ux/observables-connect/extensions/observables';
|
|
6
6
|
import { formatAccountSs58, localStorageOrDefault, setStateWithRef, } from '@w3ux/utils';
|
|
@@ -14,7 +14,6 @@ export const ExtensionAccountsProvider = ({ children, network, ss58, dappName, a
|
|
|
14
14
|
const extensionAccountsRef = useRef(extensionAccounts);
|
|
15
15
|
const [extensionAccountsSynced, setExtensionAccountsSynced] = useState('unsynced');
|
|
16
16
|
const [extensionsInitialised, setExtensionsInitialised] = useState([]);
|
|
17
|
-
const unsubs = useRef({});
|
|
18
17
|
const maybeSetActiveAccount = (address) => {
|
|
19
18
|
if (typeof setActiveAccount === 'function') {
|
|
20
19
|
setActiveAccount(address ?? null);
|
|
@@ -42,20 +41,21 @@ export const ExtensionAccountsProvider = ({ children, network, ss58, dappName, a
|
|
|
42
41
|
.find(({ address }) => address === getActiveAccountLocal(network, ss58));
|
|
43
42
|
updateExtensionAccounts({ add: initialAccounts, remove: [] });
|
|
44
43
|
const handleAccounts = (extensionId, accounts, signer) => {
|
|
45
|
-
const
|
|
44
|
+
const result = processExtensionAccounts({
|
|
46
45
|
source: extensionId,
|
|
47
46
|
network,
|
|
48
47
|
ss58,
|
|
49
48
|
}, extensionAccountsRef.current, signer, accounts);
|
|
49
|
+
const { newAccounts, meta: { accountsToRemove }, } = result;
|
|
50
50
|
updateExtensionAccounts({ add: newAccounts, remove: accountsToRemove });
|
|
51
|
-
return
|
|
51
|
+
return result;
|
|
52
52
|
};
|
|
53
53
|
for (const [id, { extension }] of Array.from(connected.entries())) {
|
|
54
54
|
if (extensionHasFeature(id, 'subscribeAccounts')) {
|
|
55
55
|
const unsub = extension.accounts.subscribe((accounts) => {
|
|
56
56
|
handleAccounts(id, accounts || [], extension.signer);
|
|
57
57
|
});
|
|
58
|
-
|
|
58
|
+
addUnsub(id, unsub);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
if (activeAccountInInitial) {
|
|
@@ -70,45 +70,49 @@ export const ExtensionAccountsProvider = ({ children, network, ss58, dappName, a
|
|
|
70
70
|
}
|
|
71
71
|
const { extension } = connected.get(id);
|
|
72
72
|
const handleAccounts = (extensionId, accounts, signer) => {
|
|
73
|
-
const
|
|
73
|
+
const result = processExtensionAccounts({
|
|
74
74
|
source: extensionId,
|
|
75
75
|
network,
|
|
76
76
|
ss58,
|
|
77
77
|
}, extensionAccountsRef.current, signer, accounts);
|
|
78
|
-
|
|
79
|
-
const activeExtensionAccount = getActiveExtensionAccount(network, ss58, newAccounts);
|
|
80
|
-
if (activeExtensionAccount?.address !== removedActiveAccount &&
|
|
81
|
-
removedActiveAccount !== null) {
|
|
82
|
-
connectActiveExtensionAccount(activeExtensionAccount, connectToAccount);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
78
|
+
const { newAccounts, meta: { accountsToRemove }, } = result;
|
|
85
79
|
updateExtensionAccounts({
|
|
86
80
|
add: newAccounts,
|
|
87
81
|
remove: accountsToRemove,
|
|
88
82
|
});
|
|
89
|
-
return
|
|
83
|
+
return result;
|
|
90
84
|
};
|
|
91
85
|
maybeOnExtensionEnabled(id);
|
|
92
86
|
if (!extensionHasFeature(id, 'subscribeAccounts')) {
|
|
93
87
|
const accounts = await extension.accounts.get();
|
|
94
|
-
handleAccounts(id, accounts, extension.signer);
|
|
88
|
+
const result = handleAccounts(id, accounts, extension.signer);
|
|
89
|
+
checkActiveAccount(result);
|
|
95
90
|
}
|
|
96
91
|
else {
|
|
97
92
|
const unsub = extension.accounts.subscribe((accounts) => {
|
|
98
|
-
handleAccounts(id, accounts || [], extension.signer);
|
|
93
|
+
const result = handleAccounts(id, accounts || [], extension.signer);
|
|
94
|
+
checkActiveAccount(result);
|
|
99
95
|
});
|
|
100
|
-
|
|
96
|
+
addUnsub(id, unsub);
|
|
101
97
|
}
|
|
102
98
|
return true;
|
|
103
99
|
}
|
|
104
100
|
return false;
|
|
105
101
|
};
|
|
102
|
+
const checkActiveAccount = ({ newAccounts, meta: { removedActiveAccount }, }) => {
|
|
103
|
+
if (!activeAccount) {
|
|
104
|
+
const activeExtensionAccount = getActiveExtensionAccount(network, ss58, newAccounts);
|
|
105
|
+
if (activeExtensionAccount?.address !== removedActiveAccount &&
|
|
106
|
+
removedActiveAccount !== null) {
|
|
107
|
+
connectActiveExtensionAccount(activeExtensionAccount, connectToAccount);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
106
111
|
const updateExtensionAccounts = ({ add, remove, }) => {
|
|
107
112
|
const newAccounts = [...extensionAccountsRef.current]
|
|
108
113
|
.concat(add)
|
|
109
114
|
.filter((a) => remove.find((s) => s.address === a.address) === undefined);
|
|
110
115
|
if (remove.length) {
|
|
111
|
-
unsubAccounts(remove);
|
|
112
116
|
if (activeAccount &&
|
|
113
117
|
remove.find(({ address }) => address === activeAccount) !== undefined) {
|
|
114
118
|
maybeSetActiveAccount(null);
|
|
@@ -116,30 +120,9 @@ export const ExtensionAccountsProvider = ({ children, network, ss58, dappName, a
|
|
|
116
120
|
}
|
|
117
121
|
setStateWithRef(newAccounts, setExtensionAccounts, extensionAccountsRef);
|
|
118
122
|
};
|
|
119
|
-
const addToUnsubscribe = (id, unsub) => {
|
|
120
|
-
unsubs.current[id] = unsub;
|
|
121
|
-
};
|
|
122
|
-
const unsubAccounts = (accounts) => {
|
|
123
|
-
if (accounts.length) {
|
|
124
|
-
for (const { address } of accounts) {
|
|
125
|
-
if (extensionAccountsRef.current.find((a) => a.address === address)) {
|
|
126
|
-
const unsub = unsubs.current[address];
|
|
127
|
-
if (unsub) {
|
|
128
|
-
unsub();
|
|
129
|
-
delete unsubs.current[address];
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
const unsubscribe = () => {
|
|
136
|
-
Object.values(unsubs.current).forEach((unsub) => {
|
|
137
|
-
unsub();
|
|
138
|
-
});
|
|
139
|
-
};
|
|
140
123
|
const handleSyncExtensionAccounts = async () => {
|
|
141
124
|
if (!gettingExtensions && extensionAccountsSynced === 'unsynced') {
|
|
142
|
-
|
|
125
|
+
unsubAll();
|
|
143
126
|
setStateWithRef([], setExtensionAccounts, extensionAccountsRef);
|
|
144
127
|
if (Object.keys(extensionsStatus).length) {
|
|
145
128
|
const localExtensions = localStorageOrDefault(`active_extensions`, [], true);
|
|
@@ -165,7 +148,7 @@ export const ExtensionAccountsProvider = ({ children, network, ss58, dappName, a
|
|
|
165
148
|
.filter((account) => account !== null);
|
|
166
149
|
useEffect(() => {
|
|
167
150
|
handleSyncExtensionAccounts();
|
|
168
|
-
return () =>
|
|
151
|
+
return () => unsubAll();
|
|
169
152
|
}, [extensionsStatus, gettingExtensions, extensionAccountsSynced]);
|
|
170
153
|
useEffectIgnoreInitial(() => {
|
|
171
154
|
if (!gettingExtensions &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ExtensionAccountsProvider/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { createSafeContext, useEffectIgnoreInitial } from '@w3ux/hooks'\nimport {\n getAccountsFromExtensions,\n processExtensionAccounts,\n} from '@w3ux/observables-connect/accounts'\nimport {\n connectExtensions,\n getActiveExtensionsLocal,\n} from '@w3ux/observables-connect/extensions'\nimport { initialisedExtensions$ } from '@w3ux/observables-connect/extensions/observables'\nimport type {\n ExtensionAccount,\n ImportedAccount,\n Sync,\n VoidFn,\n} from '@w3ux/types'\nimport {\n formatAccountSs58,\n localStorageOrDefault,\n setStateWithRef,\n} from '@w3ux/utils'\nimport { useEffect, useRef, useState } from 'react'\nimport { useExtensions } from '../ExtensionsProvider'\nimport type {\n ExtensionAccountsContextInterface,\n ExtensionAccountsProviderProps,\n} from './types'\nimport {\n connectActiveExtensionAccount,\n getActiveAccountLocal,\n getActiveExtensionAccount,\n} from './utils'\n\nexport const [ExtensionAccountsContext, useExtensionAccounts] =\n createSafeContext<ExtensionAccountsContextInterface>()\n\nexport const ExtensionAccountsProvider = ({\n children,\n network,\n ss58,\n dappName,\n activeAccount,\n setActiveAccount,\n onExtensionEnabled,\n}: ExtensionAccountsProviderProps) => {\n const {\n extensionsStatus,\n gettingExtensions,\n extensionHasFeature,\n extensionCanConnect,\n } = useExtensions()\n\n // Store connected extension accounts\n const [extensionAccounts, setExtensionAccounts] = useState<ImportedAccount[]>(\n []\n )\n const extensionAccountsRef = useRef(extensionAccounts)\n\n // Store whether extension accounts have been synced\n // TODO: Use observable to update this state\n const [extensionAccountsSynced, setExtensionAccountsSynced] =\n useState<Sync>('unsynced')\n\n // Stores initialised extensions\n const [extensionsInitialised, setExtensionsInitialised] = useState<string[]>(\n []\n )\n\n // Store unsubscribe handlers for connected extensions\n const unsubs = useRef<Record<string, VoidFn>>({})\n\n // Helper for setting active account. Ignores if not a valid function\n const maybeSetActiveAccount = (address: string) => {\n if (typeof setActiveAccount === 'function') {\n setActiveAccount(address ?? null)\n }\n }\n\n // Helper for calling extension enabled callback. Ignores if not a valid function\n const maybeOnExtensionEnabled = (id: string) => {\n if (typeof onExtensionEnabled === 'function') {\n onExtensionEnabled(id)\n }\n }\n\n const connectToAccount = (account: ImportedAccount | null) => {\n maybeSetActiveAccount(account?.address ?? null)\n }\n\n // Connects to extensions that already have been connected to and stored in localStorage. Loop\n // through extensions and connect to accounts. If `activeAccount` exists locally, we wait until\n // all extensions are looped before connecting to it; there is no guarantee it still exists - must\n // explicitly find it\n const connectActiveExtensions = async () => {\n const { connected } = await connectExtensions(\n dappName,\n getActiveExtensionsLocal()\n )\n if (connected.size === 0) {\n return\n }\n\n // Get full list of imported accounts\n const initialAccounts = await getAccountsFromExtensions(connected, ss58)\n\n // Get the active account if found in initial accounts. Format initial account addresses to the\n // correct ss58 format before finding\n const activeAccountInInitial = initialAccounts\n .map((acc) => ({\n ...acc,\n address: formatAccountSs58(acc.address, ss58),\n }))\n .find(({ address }) => address === getActiveAccountLocal(network, ss58))\n\n // Perform initial account state update\n updateExtensionAccounts({ add: initialAccounts, remove: [] })\n\n // Initiate account subscriptions for connected extensions\n // --------------------------------------------------------\n\n // Handler function for each extension accounts subscription\n const handleAccounts = (\n extensionId: string,\n accounts: ExtensionAccount[],\n signer: unknown\n ) => {\n const {\n newAccounts,\n meta: { accountsToRemove },\n } = processExtensionAccounts(\n {\n source: extensionId,\n network,\n ss58,\n },\n extensionAccountsRef.current,\n signer,\n accounts\n )\n\n // Update added and removed accounts\n // TODO: Use account observables instead\n updateExtensionAccounts({ add: newAccounts, remove: accountsToRemove })\n return newAccounts\n }\n\n // Try to subscribe to accounts for each connected extension\n for (const [id, { extension }] of Array.from(connected.entries())) {\n // If enabled, subscribe to accounts.\n if (extensionHasFeature(id, 'subscribeAccounts')) {\n const unsub = extension.accounts.subscribe((accounts) => {\n handleAccounts(id, accounts || [], extension.signer)\n })\n // Add unsub to context ref\n addToUnsubscribe(id, unsub)\n }\n }\n\n // Connect to active account if found in initial accounts\n if (activeAccountInInitial) {\n connectActiveExtensionAccount(activeAccountInInitial, connectToAccount)\n }\n }\n\n // Connects to a single extension. If activeAccount is not found here, it is simply ignored\n const connectExtensionAccounts = async (id: string): Promise<boolean> => {\n if (extensionCanConnect(id)) {\n const { connected } = await connectExtensions(dappName, [id])\n if (connected.size === 0) {\n return\n }\n const { extension } = connected.get(id)\n\n // Handler for new accounts\n const handleAccounts = (\n extensionId: string,\n accounts: ExtensionAccount[],\n signer: unknown\n ) => {\n const {\n newAccounts,\n meta: { removedActiveAccount, accountsToRemove },\n } = processExtensionAccounts(\n {\n source: extensionId,\n network,\n ss58,\n },\n extensionAccountsRef.current,\n signer,\n accounts\n )\n // Set active account for network if not yet set\n // TODO: Move out of this callback function\n if (!activeAccount) {\n const activeExtensionAccount = getActiveExtensionAccount(\n network,\n ss58,\n newAccounts\n )\n if (\n activeExtensionAccount?.address !== removedActiveAccount &&\n removedActiveAccount !== null\n ) {\n connectActiveExtensionAccount(\n activeExtensionAccount,\n connectToAccount\n )\n }\n }\n\n // Update extension accounts state\n // TODO: Use account observables instead\n updateExtensionAccounts({\n add: newAccounts,\n remove: accountsToRemove,\n })\n return newAccounts\n }\n\n // Call optional `onExtensionEnabled` callback\n maybeOnExtensionEnabled(id)\n\n // If account subscriptions are not supported, simply get the account(s) from the extension. Otherwise, subscribe to accounts\n if (!extensionHasFeature(id, 'subscribeAccounts')) {\n const accounts = await extension.accounts.get()\n handleAccounts(id, accounts, extension.signer)\n } else {\n const unsub = extension.accounts.subscribe((accounts) => {\n handleAccounts(id, accounts || [], extension.signer)\n })\n addToUnsubscribe(id, unsub)\n }\n return true\n }\n return false\n }\n\n // Add an extension account to context state\n const updateExtensionAccounts = ({\n add,\n remove,\n }: {\n add: ExtensionAccount[]\n remove: ExtensionAccount[]\n }) => {\n // Add new accounts and remove any removed accounts\n const newAccounts = [...extensionAccountsRef.current]\n .concat(add)\n .filter((a) => remove.find((s) => s.address === a.address) === undefined)\n\n if (remove.length) {\n // Unsubscribe from removed accounts\n unsubAccounts(remove)\n\n // Remove active account if it is being forgotten\n if (\n activeAccount &&\n remove.find(({ address }) => address === activeAccount) !== undefined\n ) {\n maybeSetActiveAccount(null)\n }\n }\n\n setStateWithRef(newAccounts, setExtensionAccounts, extensionAccountsRef)\n }\n\n // Add an extension id to unsubscribe state\n const addToUnsubscribe = (id: string, unsub: VoidFn) => {\n unsubs.current[id] = unsub\n }\n\n // Handle unsubscribing of an removed extension accounts\n const unsubAccounts = (accounts: ImportedAccount[]) => {\n // Unsubscribe and remove unsub from context ref\n if (accounts.length) {\n for (const { address } of accounts) {\n if (extensionAccountsRef.current.find((a) => a.address === address)) {\n const unsub = unsubs.current[address]\n if (unsub) {\n unsub()\n delete unsubs.current[address]\n }\n }\n }\n }\n }\n\n // Unsubscribe all account subscriptions\n const unsubscribe = () => {\n Object.values(unsubs.current).forEach((unsub) => {\n unsub()\n })\n }\n\n const handleSyncExtensionAccounts = async () => {\n // Wait for injectedWeb3 check to finish before starting account import process\n if (!gettingExtensions && extensionAccountsSynced === 'unsynced') {\n // Unsubscribe from all accounts and reset state\n unsubscribe()\n setStateWithRef([], setExtensionAccounts, extensionAccountsRef)\n // If extensions have been fetched, get accounts if extensions exist and local extensions\n // exist (previously connected)\n if (Object.keys(extensionsStatus).length) {\n // get active extensions\n const localExtensions = localStorageOrDefault(\n `active_extensions`,\n [],\n true\n )\n if (Object.keys(extensionsStatus).length && localExtensions.length) {\n setExtensionAccountsSynced('syncing')\n await connectActiveExtensions()\n }\n }\n\n // Syncing is complete. Also covers case where no extensions were found\n setExtensionAccountsSynced('synced')\n }\n }\n\n // Get extension accounts based on the provided ss58 prefix\n const getExtensionAccounts = (ss58Prefix: number): ImportedAccount[] =>\n extensionAccounts\n .map((account) => {\n const formattedAddress = formatAccountSs58(account.address, ss58Prefix)\n if (!formattedAddress) {\n return null\n }\n return {\n ...account,\n address: formattedAddress,\n }\n })\n // Remove null entries resulting from invalid formatted addresses\n .filter((account) => account !== null)\n\n // Re-sync extensions accounts on `unsynced`\n useEffect(() => {\n handleSyncExtensionAccounts()\n\n return () => unsubscribe()\n }, [extensionsStatus, gettingExtensions, extensionAccountsSynced])\n\n // Once initialised extensions equal total extensions present in `injectedWeb3`, mark extensions\n // as fetched\n useEffectIgnoreInitial(() => {\n if (\n !gettingExtensions &&\n extensionsInitialised.length === Object.keys(extensionsStatus).length\n ) {\n setExtensionAccountsSynced('synced')\n }\n }, [gettingExtensions, extensionsInitialised])\n\n // Subscribes to observables and updates state\n useEffect(() => {\n const sub = initialisedExtensions$.subscribe((initialised) => {\n setExtensionsInitialised(initialised)\n })\n return () => {\n sub.unsubscribe()\n }\n }, [])\n\n return (\n <ExtensionAccountsContext.Provider\n value={{\n connectExtensionAccounts,\n extensionAccountsSynced,\n getExtensionAccounts,\n }}\n >\n {children}\n </ExtensionAccountsContext.Provider>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ExtensionAccountsProvider/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { createSafeContext, useEffectIgnoreInitial } from '@w3ux/hooks'\nimport {\n addUnsub,\n getAccountsFromExtensions,\n processExtensionAccounts,\n unsubAll,\n} from '@w3ux/observables-connect/accounts'\nimport {\n connectExtensions,\n getActiveExtensionsLocal,\n} from '@w3ux/observables-connect/extensions'\nimport { initialisedExtensions$ } from '@w3ux/observables-connect/extensions/observables'\nimport type {\n ExtensionAccount,\n ImportedAccount,\n ProcessExtensionAccountsResult,\n Sync,\n} from '@w3ux/types'\nimport {\n formatAccountSs58,\n localStorageOrDefault,\n setStateWithRef,\n} from '@w3ux/utils'\nimport { useEffect, useRef, useState } from 'react'\nimport { useExtensions } from '../ExtensionsProvider'\nimport type {\n ExtensionAccountsContextInterface,\n ExtensionAccountsProviderProps,\n} from './types'\nimport {\n connectActiveExtensionAccount,\n getActiveAccountLocal,\n getActiveExtensionAccount,\n} from './utils'\n\nexport const [ExtensionAccountsContext, useExtensionAccounts] =\n createSafeContext<ExtensionAccountsContextInterface>()\n\nexport const ExtensionAccountsProvider = ({\n children,\n network,\n ss58,\n dappName,\n activeAccount,\n setActiveAccount,\n onExtensionEnabled,\n}: ExtensionAccountsProviderProps) => {\n const {\n extensionsStatus,\n gettingExtensions,\n extensionHasFeature,\n extensionCanConnect,\n } = useExtensions()\n\n // Store connected extension accounts\n const [extensionAccounts, setExtensionAccounts] = useState<ImportedAccount[]>(\n []\n )\n const extensionAccountsRef = useRef(extensionAccounts)\n\n // Store whether extension accounts have been synced\n // TODO: Use observable to update this state\n const [extensionAccountsSynced, setExtensionAccountsSynced] =\n useState<Sync>('unsynced')\n\n // Stores initialised extensions\n const [extensionsInitialised, setExtensionsInitialised] = useState<string[]>(\n []\n )\n\n // Helper for setting active account. Ignores if not a valid function\n const maybeSetActiveAccount = (address: string) => {\n if (typeof setActiveAccount === 'function') {\n setActiveAccount(address ?? null)\n }\n }\n\n // Helper for calling extension enabled callback. Ignores if not a valid function\n const maybeOnExtensionEnabled = (id: string) => {\n if (typeof onExtensionEnabled === 'function') {\n onExtensionEnabled(id)\n }\n }\n\n const connectToAccount = (account: ImportedAccount | null) => {\n maybeSetActiveAccount(account?.address ?? null)\n }\n\n // Connects to extensions that already have been connected to and stored in localStorage. Loop\n // through extensions and connect to accounts. If `activeAccount` exists locally, we wait until\n // all extensions are looped before connecting to it; there is no guarantee it still exists - must\n // explicitly find it\n const connectActiveExtensions = async () => {\n const { connected } = await connectExtensions(\n dappName,\n getActiveExtensionsLocal()\n )\n if (connected.size === 0) {\n return\n }\n\n // Get full list of imported accounts\n const initialAccounts = await getAccountsFromExtensions(connected, ss58)\n\n // Get the active account if found in initial accounts. Format initial account addresses to the\n // correct ss58 format before finding\n const activeAccountInInitial = initialAccounts\n .map((acc) => ({\n ...acc,\n address: formatAccountSs58(acc.address, ss58),\n }))\n .find(({ address }) => address === getActiveAccountLocal(network, ss58))\n\n // Perform initial account state update\n updateExtensionAccounts({ add: initialAccounts, remove: [] })\n\n // Initiate account subscriptions for connected extensions\n // --------------------------------------------------------\n\n // Handler function for each extension accounts subscription\n const handleAccounts = (\n extensionId: string,\n accounts: ExtensionAccount[],\n signer: unknown\n ) => {\n const result = processExtensionAccounts(\n {\n source: extensionId,\n network,\n ss58,\n },\n extensionAccountsRef.current,\n signer,\n accounts\n )\n\n const {\n newAccounts,\n meta: { accountsToRemove },\n } = result\n\n // Update added and removed accounts\n // TODO: Use account observables instead\n updateExtensionAccounts({ add: newAccounts, remove: accountsToRemove })\n return result\n }\n\n // Try to subscribe to accounts for each connected extension\n for (const [id, { extension }] of Array.from(connected.entries())) {\n // If enabled, subscribe to accounts.\n if (extensionHasFeature(id, 'subscribeAccounts')) {\n const unsub = extension.accounts.subscribe((accounts) => {\n handleAccounts(id, accounts || [], extension.signer)\n })\n // Store unsub\n addUnsub(id, unsub)\n }\n }\n\n // Connect to active account if found in initial accounts\n if (activeAccountInInitial) {\n connectActiveExtensionAccount(activeAccountInInitial, connectToAccount)\n }\n }\n\n // Connects to a single extension. If activeAccount is not found here, it is simply ignored\n const connectExtensionAccounts = async (id: string): Promise<boolean> => {\n if (extensionCanConnect(id)) {\n const { connected } = await connectExtensions(dappName, [id])\n if (connected.size === 0) {\n return\n }\n const { extension } = connected.get(id)\n\n // Handler for new accounts\n const handleAccounts = (\n extensionId: string,\n accounts: ExtensionAccount[],\n signer: unknown\n ) => {\n const result = processExtensionAccounts(\n {\n source: extensionId,\n network,\n ss58,\n },\n extensionAccountsRef.current,\n signer,\n accounts\n )\n const {\n newAccounts,\n meta: { accountsToRemove },\n } = result\n\n // Update extension accounts state\n // TODO: Use account observables instead\n updateExtensionAccounts({\n add: newAccounts,\n remove: accountsToRemove,\n })\n return result\n }\n\n // Call optional `onExtensionEnabled` callback\n maybeOnExtensionEnabled(id)\n\n // If account subscriptions are not supported, simply get the account(s) from the extension. Otherwise, subscribe to accounts\n if (!extensionHasFeature(id, 'subscribeAccounts')) {\n const accounts = await extension.accounts.get()\n const result = handleAccounts(id, accounts, extension.signer)\n checkActiveAccount(result)\n } else {\n const unsub = extension.accounts.subscribe((accounts) => {\n const result = handleAccounts(id, accounts || [], extension.signer)\n checkActiveAccount(result)\n })\n addUnsub(id, unsub)\n }\n return true\n }\n return false\n }\n\n // Set active account if found in new accounts\n const checkActiveAccount = ({\n newAccounts,\n meta: { removedActiveAccount },\n }: ProcessExtensionAccountsResult) => {\n // Set active account for network if not yet set\n if (!activeAccount) {\n const activeExtensionAccount = getActiveExtensionAccount(\n network,\n ss58,\n newAccounts\n )\n if (\n activeExtensionAccount?.address !== removedActiveAccount &&\n removedActiveAccount !== null\n ) {\n connectActiveExtensionAccount(activeExtensionAccount, connectToAccount)\n }\n }\n }\n\n // Add an extension account to context state\n const updateExtensionAccounts = ({\n add,\n remove,\n }: {\n add: ExtensionAccount[]\n remove: ExtensionAccount[]\n }) => {\n // Add new accounts and remove any removed accounts\n const newAccounts = [...extensionAccountsRef.current]\n .concat(add)\n .filter((a) => remove.find((s) => s.address === a.address) === undefined)\n\n if (remove.length) {\n // Remove active account if it is being forgotten\n if (\n activeAccount &&\n remove.find(({ address }) => address === activeAccount) !== undefined\n ) {\n maybeSetActiveAccount(null)\n }\n }\n setStateWithRef(newAccounts, setExtensionAccounts, extensionAccountsRef)\n }\n\n const handleSyncExtensionAccounts = async () => {\n // Wait for injectedWeb3 check to finish before starting account import process\n if (!gettingExtensions && extensionAccountsSynced === 'unsynced') {\n // Unsubscribe from all accounts and reset state\n unsubAll()\n setStateWithRef([], setExtensionAccounts, extensionAccountsRef)\n // If extensions have been fetched, get accounts if extensions exist and local extensions\n // exist (previously connected)\n if (Object.keys(extensionsStatus).length) {\n // get active extensions\n const localExtensions = localStorageOrDefault(\n `active_extensions`,\n [],\n true\n )\n if (Object.keys(extensionsStatus).length && localExtensions.length) {\n setExtensionAccountsSynced('syncing')\n await connectActiveExtensions()\n }\n }\n\n // Syncing is complete. Also covers case where no extensions were found\n setExtensionAccountsSynced('synced')\n }\n }\n\n // Get extension accounts based on the provided ss58 prefix\n const getExtensionAccounts = (ss58Prefix: number): ImportedAccount[] =>\n extensionAccounts\n .map((account) => {\n const formattedAddress = formatAccountSs58(account.address, ss58Prefix)\n if (!formattedAddress) {\n return null\n }\n return {\n ...account,\n address: formattedAddress,\n }\n })\n // Remove null entries resulting from invalid formatted addresses\n .filter((account) => account !== null)\n\n // Re-sync extensions accounts on `unsynced`\n useEffect(() => {\n handleSyncExtensionAccounts()\n\n return () => unsubAll()\n }, [extensionsStatus, gettingExtensions, extensionAccountsSynced])\n\n // Once initialised extensions equal total extensions present in `injectedWeb3`, mark extensions\n // as fetched\n useEffectIgnoreInitial(() => {\n if (\n !gettingExtensions &&\n extensionsInitialised.length === Object.keys(extensionsStatus).length\n ) {\n setExtensionAccountsSynced('synced')\n }\n }, [gettingExtensions, extensionsInitialised])\n\n // Subscribes to observables and updates state\n useEffect(() => {\n const sub = initialisedExtensions$.subscribe((initialised) => {\n setExtensionsInitialised(initialised)\n })\n return () => {\n sub.unsubscribe()\n }\n }, [])\n\n return (\n <ExtensionAccountsContext.Provider\n value={{\n connectExtensionAccounts,\n extensionAccountsSynced,\n getExtensionAccounts,\n }}\n >\n {children}\n </ExtensionAccountsContext.Provider>\n )\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@w3ux/react-connect-kit",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.12",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@w3ux/extension-assets": "^2.2.0",
|
|
7
7
|
"@w3ux/hooks": "^2.1.0",
|
|
8
|
-
"@w3ux/observables-connect": "0.9.
|
|
8
|
+
"@w3ux/observables-connect": "0.9.22",
|
|
9
9
|
"@w3ux/utils": "^2.0.8"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
package/types.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import type { ExtensionInjected } from '@w3ux/types';
|
|
2
|
-
declare global {
|
|
3
|
-
interface Window {
|
|
4
|
-
injectedWeb3?: Record<string, ExtensionInjected>;
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
1
|
export * from './ExtensionAccountsProvider/types';
|
|
8
2
|
export * from './ExtensionsProvider/types';
|
|
9
3
|
export * from './LedgerAccountsProvider/types';
|
package/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":"AAGA,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA","file":"types.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from './ExtensionAccountsProvider/types'\nexport * from './ExtensionsProvider/types'\nexport * from './LedgerAccountsProvider/types'\nexport * from './VaultAccountsProvider/types'\n"]}
|