@abstraxn/signer-react 3.3.9 → 4.0.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 +44 -0
- package/dist/src/ConnectButton.css.d.ts +2 -0
- package/dist/src/ConnectButton.css.js +1 -0
- package/dist/src/ConnectButton.d.ts +0 -1
- package/dist/src/ConnectButton.js +7 -6
- package/dist/src/ExternalWalletButtons.css.d.ts +2 -0
- package/dist/src/ExternalWalletButtons.css.js +1 -0
- package/dist/src/ExternalWalletButtons.d.ts +4 -1
- package/dist/src/ExternalWalletButtons.js +6 -1
- package/dist/src/WalletModal.css +2 -0
- package/dist/src/WalletModal.css.d.ts +2 -0
- package/dist/src/WalletModal.css.js +1 -0
- package/dist/src/WalletModal.d.ts +2 -2
- package/dist/src/WalletModal.js +113 -59
- package/dist/src/components/AbstraxnLogo.d.ts +17 -0
- package/dist/src/components/AbstraxnLogo.js +29 -0
- package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js +406 -338
- package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.d.ts +7 -0
- package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.js +9 -0
- package/dist/src/components/AbstraxnProvider/useWalletInitialization.js +41 -6
- package/dist/src/components/OnboardingUI/OnboardingUI.css +99 -4
- package/dist/src/components/OnboardingUI/OnboardingUI.css.d.ts +2 -0
- package/dist/src/components/OnboardingUI/OnboardingUI.css.js +1 -0
- package/dist/src/components/OnboardingUI/OnboardingUIReact.d.ts +0 -1
- package/dist/src/components/OnboardingUI/OnboardingUIReact.js +46 -19
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +24 -1
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +348 -160
- package/dist/src/components/OnboardingUI/components/Divider.d.ts +7 -0
- package/dist/src/components/OnboardingUI/components/Divider.js +9 -0
- package/dist/src/components/OnboardingUI/components/EmailForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/EmailForm.js +1 -2
- package/dist/src/components/OnboardingUI/components/MfaForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/MfaForm.js +2 -3
- package/dist/src/components/OnboardingUI/components/Modal.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/Modal.js +12 -4
- package/dist/src/components/OnboardingUI/components/OtpForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/OtpForm.js +2 -3
- package/dist/src/components/OnboardingUI/components/PasskeyButton.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/PasskeyButton.js +2 -2
- package/dist/src/components/OnboardingUI/components/SocialButtons.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/SocialButtons.js +3 -3
- package/dist/src/components/OnboardingUI/onboardingShadowContainer.d.ts +9 -0
- package/dist/src/components/OnboardingUI/onboardingShadowContainer.js +36 -0
- package/dist/src/components/ShadowHost/ShadowHost.d.ts +18 -0
- package/dist/src/components/ShadowHost/ShadowHost.js +123 -0
- package/dist/src/components/ShadowHost/ShadowHostContext.d.ts +10 -0
- package/dist/src/components/ShadowHost/ShadowHostContext.js +14 -0
- package/dist/src/components/ShadowHost/index.d.ts +2 -0
- package/dist/src/components/ShadowHost/index.js +3 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css +9 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css.js +1 -0
- package/dist/src/components/WalletModal/components/ChainSelector.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ChainSelector.js +78 -23
- package/dist/src/components/WalletModal/components/CodeInput.d.ts +12 -0
- package/dist/src/components/WalletModal/components/CodeInput.js +39 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +0 -2
- package/dist/src/components/WalletModal/components/ExportKeyModal.js +2 -4
- package/dist/src/components/WalletModal/components/ExportWarningModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +0 -2
- package/dist/src/components/WalletModal/components/ExportWarningModal.js +2 -4
- package/dist/src/components/WalletModal/components/ManageWalletModal.css +27 -1
- package/dist/src/components/WalletModal/components/ManageWalletModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ManageWalletModal.js +66 -148
- package/dist/src/components/WalletModal/components/MfaVerifyModal.d.ts +15 -0
- package/dist/src/components/WalletModal/components/MfaVerifyModal.js +98 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +2 -12
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.js +0 -1
- package/dist/src/components/WalletModal/components/ReceiveModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ReceiveModal.js +2 -2
- package/dist/src/components/WalletModal/components/SendModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/SendModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/SendModal.d.ts +5 -2
- package/dist/src/components/WalletModal/components/SendModal.js +25 -82
- package/dist/src/components/WalletModal/components/SignMfaModalHost.d.ts +1 -0
- package/dist/src/components/WalletModal/components/SignMfaModalHost.js +50 -0
- package/dist/src/components/WalletModal/components/SuccessModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/SuccessModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/SuccessModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/SuccessModal.js +0 -1
- package/dist/src/components/WalletModal/components/TokenSelectorModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/TokenSelectorModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/TokenSelectorModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/TokenSelectorModal.js +0 -1
- package/dist/src/components/WalletModal/components/UserAvatar.js +2 -1
- package/dist/src/components/WalletModal/components/index.d.ts +3 -0
- package/dist/src/components/WalletModal/components/index.js +2 -0
- package/dist/src/components/WalletModal/hooks/useSendTransaction.js +18 -6
- package/dist/src/components/icons.d.ts +2 -0
- package/dist/src/components/icons.js +4 -0
- package/dist/src/hooks.d.ts +81 -20
- package/dist/src/hooks.js +194 -36
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +2 -2
- package/dist/src/signMfaBridge.d.ts +7 -0
- package/dist/src/signMfaBridge.js +20 -0
- package/dist/src/types.d.ts +4 -0
- package/dist/src/utils/shadowFocus.d.ts +8 -0
- package/dist/src/utils/shadowFocus.js +15 -0
- package/dist/src/utils/shadowRegistry.d.ts +23 -0
- package/dist/src/utils/shadowRegistry.js +36 -0
- package/dist/src/walletConnectMobile.d.ts +9 -5
- package/dist/src/walletConnectMobile.js +152 -51
- package/package.json +9 -4
package/dist/src/hooks.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
5
5
|
import { useAbstraxnWallet } from './AbstraxnProvider';
|
|
6
6
|
import { InvalidDeviceIdError, SignMfaRequiredError } from '@abstraxn/signer-core';
|
|
7
|
+
import { requestSignMfaCode } from './signMfaBridge';
|
|
8
|
+
import { TURNKEY_SUPPORTED_CAIP2, NATIVE_ASSET_SENTINEL, chainIdToCaip2, isNativeAssetEntry, extractAssetAddress, } from '@abstraxn/signer-core';
|
|
7
9
|
import { createPublicClient, createWalletClient, http, getContract, serializeTransaction, encodeFunctionData, hashTypedData, hashMessage, parseSignature } from 'viem';
|
|
8
10
|
import { toAccount } from 'viem/accounts';
|
|
9
11
|
import { Connection as SolanaConnection, Transaction as SolanaTransaction, SystemProgram, PublicKey, LAMPORTS_PER_SOL, TransactionInstruction, } from '@solana/web3.js';
|
|
@@ -12,7 +14,7 @@ import { useWalletClient as useWagmiWalletClient, useAccount, useConfig, useChai
|
|
|
12
14
|
import { getWalletClient, switchChain, getPublicClient } from '@wagmi/core';
|
|
13
15
|
import { getConnectorMeta } from './connectors';
|
|
14
16
|
import { getChainById } from './chains';
|
|
15
|
-
import { waitUntilDocumentVisible, pollForOutgoingTx, clearWalletConnectPendingState, isWalletConnectConnector, isMobileDevice, } from './walletConnectMobile';
|
|
17
|
+
import { waitUntilDocumentVisible, pollForOutgoingTx, clearWalletConnectPendingState, isWalletConnectConnector, isMobileDevice, isUserRejectionError, toUserRejectionError, } from './walletConnectMobile';
|
|
16
18
|
/**
|
|
17
19
|
* Hook to check if wallet is connected
|
|
18
20
|
*/
|
|
@@ -233,15 +235,8 @@ function isInvalidDeviceIdError(error) {
|
|
|
233
235
|
candidate?.name === 'InvalidDeviceIdError' ||
|
|
234
236
|
(typeof candidate?.message === 'string' && candidate.message.includes('INVALID_DEVICE_ID')));
|
|
235
237
|
}
|
|
236
|
-
function
|
|
237
|
-
|
|
238
|
-
throw new Error('MFA step-up is required to sign, but no prompt UI is available in this environment.');
|
|
239
|
-
}
|
|
240
|
-
const code = window.prompt('Enter your MFA code to approve this signing request');
|
|
241
|
-
if (!code || code.trim() === '') {
|
|
242
|
-
throw new Error('MFA code is required to continue signing.');
|
|
243
|
-
}
|
|
244
|
-
return code.trim().toUpperCase();
|
|
238
|
+
async function requestSignMfaCodeFromUi() {
|
|
239
|
+
return requestSignMfaCode();
|
|
245
240
|
}
|
|
246
241
|
async function runWithSignStepUpRetry(performSign, verifySignMfa) {
|
|
247
242
|
try {
|
|
@@ -257,7 +252,7 @@ async function runWithSignStepUpRetry(performSign, verifySignMfa) {
|
|
|
257
252
|
if (!verifySignMfa) {
|
|
258
253
|
throw new Error('MFA step-up is required, but sign verification is not available.');
|
|
259
254
|
}
|
|
260
|
-
const code =
|
|
255
|
+
const code = await requestSignMfaCodeFromUi();
|
|
261
256
|
let verifyResponse;
|
|
262
257
|
try {
|
|
263
258
|
verifyResponse = await verifySignMfa(code);
|
|
@@ -399,11 +394,11 @@ export function useEnableMfa() {
|
|
|
399
394
|
* auth (otp/recovery) -> confirm disable.
|
|
400
395
|
*/
|
|
401
396
|
export function useDisableMfa() {
|
|
402
|
-
const {
|
|
397
|
+
const { verifySignMfa, disableMfaWithSignedPayload } = useAbstraxnWallet();
|
|
403
398
|
const [disableState, setDisableState] = useState(null);
|
|
404
399
|
const [isLoading, setIsLoading] = useState(false);
|
|
405
400
|
const [error, setError] = useState(null);
|
|
406
|
-
const canDisableMfaFlow = !!
|
|
401
|
+
const canDisableMfaFlow = !!verifySignMfa && !!disableMfaWithSignedPayload;
|
|
407
402
|
const reset = useCallback(() => {
|
|
408
403
|
setDisableState(null);
|
|
409
404
|
setIsLoading(false);
|
|
@@ -420,7 +415,8 @@ export function useDisableMfa() {
|
|
|
420
415
|
setDisableState({ step: 'auth', method });
|
|
421
416
|
}, []);
|
|
422
417
|
const verifyCode = useCallback(async (code) => {
|
|
423
|
-
|
|
418
|
+
// Sign step-up is required: disable MFA signs a payload via /sign/transaction.
|
|
419
|
+
if (!verifySignMfa || disableState?.step !== 'auth')
|
|
424
420
|
return false;
|
|
425
421
|
const { method } = disableState;
|
|
426
422
|
const trimmed = method === 'recovery' ? code.trim().toUpperCase() : code.trim();
|
|
@@ -434,7 +430,7 @@ export function useDisableMfa() {
|
|
|
434
430
|
setIsLoading(true);
|
|
435
431
|
setError(null);
|
|
436
432
|
try {
|
|
437
|
-
await
|
|
433
|
+
await verifySignMfa(trimmed);
|
|
438
434
|
setDisableState({ step: 'confirm' });
|
|
439
435
|
return true;
|
|
440
436
|
}
|
|
@@ -446,7 +442,7 @@ export function useDisableMfa() {
|
|
|
446
442
|
finally {
|
|
447
443
|
setIsLoading(false);
|
|
448
444
|
}
|
|
449
|
-
}, [
|
|
445
|
+
}, [verifySignMfa, disableState]);
|
|
450
446
|
const confirmDisable = useCallback(async () => {
|
|
451
447
|
if (!disableMfaWithSignedPayload)
|
|
452
448
|
return null;
|
|
@@ -1049,7 +1045,7 @@ export function useSolanaPublicKey() {
|
|
|
1049
1045
|
* RPC endpoint is taken from the current Solana ChainData (configured in AbstraxnProvider).
|
|
1050
1046
|
*/
|
|
1051
1047
|
export function useSolanaBalance() {
|
|
1052
|
-
const { currentChain, whoami, solanaWallet, solanaConnection } = useAbstraxnWallet();
|
|
1048
|
+
const { currentChain, whoami, solanaWallet, solanaConnection, wallet } = useAbstraxnWallet();
|
|
1053
1049
|
const [lamports, setLamports] = useState(null);
|
|
1054
1050
|
const [formattedBalance, setFormattedBalance] = useState('0');
|
|
1055
1051
|
const [loading, setLoading] = useState(false);
|
|
@@ -1062,6 +1058,9 @@ export function useSolanaBalance() {
|
|
|
1062
1058
|
: null) ||
|
|
1063
1059
|
// Fallback to provider connection endpoint
|
|
1064
1060
|
(providerConnection && providerConnection.rpcEndpoint) || null;
|
|
1061
|
+
// An external wallet (Phantom) address isn't a Turnkey wallet-account - only try
|
|
1062
|
+
// Turnkey when using the embedded wallet's own address.
|
|
1063
|
+
const isExternalSolanaWallet = !!solanaWallet?.publicKey;
|
|
1065
1064
|
const address = (solanaWallet?.publicKey && solanaWallet.publicKey.toBase58()) ||
|
|
1066
1065
|
whoami?.solanaAddress ||
|
|
1067
1066
|
null;
|
|
@@ -1074,14 +1073,35 @@ export function useSolanaBalance() {
|
|
|
1074
1073
|
return;
|
|
1075
1074
|
}
|
|
1076
1075
|
let cancelled = false;
|
|
1076
|
+
const fetchViaRpc = async () => {
|
|
1077
|
+
const connection = new SolanaConnection(rpcUrl, 'confirmed');
|
|
1078
|
+
const balance = await connection.getBalance(new PublicKey(address), 'confirmed');
|
|
1079
|
+
return BigInt(balance);
|
|
1080
|
+
};
|
|
1077
1081
|
const fetchBalance = async () => {
|
|
1078
1082
|
setLoading(true);
|
|
1079
1083
|
try {
|
|
1080
|
-
|
|
1081
|
-
|
|
1084
|
+
let asBigInt = null;
|
|
1085
|
+
if (!isExternalSolanaWallet && wallet && currentChain) {
|
|
1086
|
+
const caip2 = chainIdToCaip2(currentChain.id, TURNKEY_SUPPORTED_CAIP2);
|
|
1087
|
+
if (caip2) {
|
|
1088
|
+
try {
|
|
1089
|
+
const entries = await wallet.getTurnkeyBalances(caip2, address);
|
|
1090
|
+
const nativeEntry = entries.find((entry) => isNativeAssetEntry({ caip19: entry.caip19, symbol: entry.symbol, decimals: entry.decimals }, currentChain.nativeCurrency));
|
|
1091
|
+
if (nativeEntry?.balance !== undefined) {
|
|
1092
|
+
asBigInt = BigInt(nativeEntry.balance);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
catch (turnkeyError) {
|
|
1096
|
+
console.warn('Turnkey Solana balance fetch failed, falling back to RPC:', turnkeyError);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
if (asBigInt === null) {
|
|
1101
|
+
asBigInt = await fetchViaRpc();
|
|
1102
|
+
}
|
|
1082
1103
|
if (cancelled)
|
|
1083
1104
|
return;
|
|
1084
|
-
const asBigInt = BigInt(balance);
|
|
1085
1105
|
setLamports(asBigInt);
|
|
1086
1106
|
const sol = Number(asBigInt) / LAMPORTS_PER_SOL;
|
|
1087
1107
|
setFormattedBalance(sol.toFixed(6));
|
|
@@ -1101,7 +1121,7 @@ export function useSolanaBalance() {
|
|
|
1101
1121
|
return () => {
|
|
1102
1122
|
cancelled = true;
|
|
1103
1123
|
};
|
|
1104
|
-
}, [providerConnection, rpcUrl, address]);
|
|
1124
|
+
}, [providerConnection, rpcUrl, address, isExternalSolanaWallet, wallet, currentChain]);
|
|
1105
1125
|
return {
|
|
1106
1126
|
address,
|
|
1107
1127
|
lamports,
|
|
@@ -1110,6 +1130,124 @@ export function useSolanaBalance() {
|
|
|
1110
1130
|
error,
|
|
1111
1131
|
};
|
|
1112
1132
|
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Hook to get the full non-zero token list (native + SPL) for the active embedded
|
|
1135
|
+
* Solana address, sourced from Turnkey with an RPC-derived native-only fallback.
|
|
1136
|
+
* Mirrors useSolanaBalance()'s shape. Safe to call unconditionally regardless of the
|
|
1137
|
+
* current chain type - no-ops (returns an empty, non-loading result) when the current
|
|
1138
|
+
* chain isn't Solana or there's no embedded Solana address.
|
|
1139
|
+
*/
|
|
1140
|
+
export function useSolanaTokenBalances() {
|
|
1141
|
+
const { currentChain, whoami, solanaWallet, wallet } = useAbstraxnWallet();
|
|
1142
|
+
const [tokens, setTokens] = useState([]);
|
|
1143
|
+
const [loading, setLoading] = useState(false);
|
|
1144
|
+
const [error, setError] = useState(null);
|
|
1145
|
+
const isSolanaChain = currentChain && currentChain.type === 'solana';
|
|
1146
|
+
const isExternalSolanaWallet = !!solanaWallet?.publicKey;
|
|
1147
|
+
const address = !isExternalSolanaWallet ? whoami?.solanaAddress ?? null : null;
|
|
1148
|
+
useEffect(() => {
|
|
1149
|
+
setTokens([]);
|
|
1150
|
+
setError(null);
|
|
1151
|
+
if (!isSolanaChain || !address || !wallet || !currentChain) {
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const caip2 = chainIdToCaip2(currentChain.id, TURNKEY_SUPPORTED_CAIP2);
|
|
1155
|
+
if (!caip2) {
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
let cancelled = false;
|
|
1159
|
+
const fetchTokens = async () => {
|
|
1160
|
+
setLoading(true);
|
|
1161
|
+
try {
|
|
1162
|
+
const entries = await wallet.getTurnkeyBalances(caip2, address);
|
|
1163
|
+
if (cancelled)
|
|
1164
|
+
return;
|
|
1165
|
+
const nextTokens = [];
|
|
1166
|
+
for (const entry of entries) {
|
|
1167
|
+
try {
|
|
1168
|
+
const isNative = isNativeAssetEntry({ caip19: entry.caip19, symbol: entry.symbol, decimals: entry.decimals }, currentChain.nativeCurrency);
|
|
1169
|
+
const tokenAddress = isNative
|
|
1170
|
+
? NATIVE_ASSET_SENTINEL
|
|
1171
|
+
: extractAssetAddress({ caip19: entry.caip19 });
|
|
1172
|
+
if (!isNative && tokenAddress === undefined) {
|
|
1173
|
+
console.warn('Skipping unrecognized Solana asset in balance list:', entry.caip19);
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
nextTokens.push({
|
|
1177
|
+
address: tokenAddress,
|
|
1178
|
+
symbol: entry.symbol ?? '',
|
|
1179
|
+
name: entry.name ?? entry.symbol ?? '',
|
|
1180
|
+
decimals: entry.decimals ?? 9,
|
|
1181
|
+
balance: entry.balance !== undefined ? BigInt(entry.balance) : 0n,
|
|
1182
|
+
isNative,
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
catch (entryError) {
|
|
1186
|
+
console.warn('Skipping malformed Solana balance entry:', entryError);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
setTokens(nextTokens);
|
|
1190
|
+
setError(null);
|
|
1191
|
+
}
|
|
1192
|
+
catch (turnkeyError) {
|
|
1193
|
+
console.warn('Turnkey Solana token list fetch failed, falling back to RPC native-only:', turnkeyError);
|
|
1194
|
+
// Fall back to a single native-only entry via RPC, so the list stays
|
|
1195
|
+
// consistent with useSolanaBalance()'s own RPC fallback rather than going
|
|
1196
|
+
// empty on a Turnkey outage.
|
|
1197
|
+
try {
|
|
1198
|
+
const connection = new SolanaConnection(currentChain.rpcUrl, 'confirmed');
|
|
1199
|
+
const lamports = await connection.getBalance(new PublicKey(address), 'confirmed');
|
|
1200
|
+
if (cancelled)
|
|
1201
|
+
return;
|
|
1202
|
+
setTokens([
|
|
1203
|
+
{
|
|
1204
|
+
address: NATIVE_ASSET_SENTINEL,
|
|
1205
|
+
symbol: currentChain.nativeCurrency.symbol,
|
|
1206
|
+
name: currentChain.nativeCurrency.name,
|
|
1207
|
+
decimals: currentChain.nativeCurrency.decimals,
|
|
1208
|
+
balance: BigInt(lamports),
|
|
1209
|
+
isNative: true,
|
|
1210
|
+
},
|
|
1211
|
+
]);
|
|
1212
|
+
setError(null);
|
|
1213
|
+
}
|
|
1214
|
+
catch (rpcError) {
|
|
1215
|
+
if (cancelled)
|
|
1216
|
+
return;
|
|
1217
|
+
setTokens([]);
|
|
1218
|
+
setError(rpcError instanceof Error ? rpcError : new Error('Failed to load Solana token balances'));
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
finally {
|
|
1222
|
+
if (!cancelled) {
|
|
1223
|
+
setLoading(false);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
};
|
|
1227
|
+
fetchTokens();
|
|
1228
|
+
return () => {
|
|
1229
|
+
cancelled = true;
|
|
1230
|
+
};
|
|
1231
|
+
}, [isSolanaChain, address, wallet, currentChain]);
|
|
1232
|
+
return { tokens, loading, error };
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Hook to get the full non-zero token list (native + ERC-20) for the current EVM
|
|
1236
|
+
* chain, sourced from AbstraxnProvider's centralized state (Turnkey-first with an
|
|
1237
|
+
* RPC-derived native-only fallback - see AbstraxnProviderInner's refetchWalletBalance).
|
|
1238
|
+
* Safe to call unconditionally regardless of the current chain type - no-ops (returns
|
|
1239
|
+
* an empty, non-loading result) when the current chain isn't EVM.
|
|
1240
|
+
*/
|
|
1241
|
+
export function useTokenBalances() {
|
|
1242
|
+
const { currentChain, tokenBalances, tokenBalancesLoading, tokenBalancesError, refetchTokenBalances } = useAbstraxnWallet();
|
|
1243
|
+
const isEvmChain = currentChain && currentChain.type === 'evm';
|
|
1244
|
+
return {
|
|
1245
|
+
tokens: isEvmChain ? tokenBalances : [],
|
|
1246
|
+
loading: isEvmChain ? tokenBalancesLoading : false,
|
|
1247
|
+
error: isEvmChain ? tokenBalancesError : null,
|
|
1248
|
+
refetch: refetchTokenBalances,
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1113
1251
|
function base64ToUint8Array(base64) {
|
|
1114
1252
|
if (typeof atob !== 'function') {
|
|
1115
1253
|
throw new Error('Base64 decoding is not available in this environment');
|
|
@@ -1794,18 +1932,20 @@ export function useSignTxn(provider) {
|
|
|
1794
1932
|
value: valueInWei,
|
|
1795
1933
|
nonce,
|
|
1796
1934
|
};
|
|
1797
|
-
// Add gas properties if they exist
|
|
1935
|
+
// Add gas properties if they exist. Never set both legacy and EIP-1559 —
|
|
1936
|
+
// viem serializes as type-2 whenever maxFeePerGas is present, which can
|
|
1937
|
+
// underpay Ethermint minimum-global-fee when gasPrice was the real floor.
|
|
1798
1938
|
const unsignedTx = { ...baseTx };
|
|
1799
1939
|
if (gas?.gasLimit !== undefined) {
|
|
1800
1940
|
unsignedTx.gas = gas.gasLimit;
|
|
1801
1941
|
}
|
|
1802
|
-
|
|
1942
|
+
const hasEip1559 = gas?.maxFeePerGas !== undefined && gas?.maxPriorityFeePerGas !== undefined;
|
|
1943
|
+
const hasLegacy = gas?.gasPrice !== undefined;
|
|
1944
|
+
if (hasLegacy && (!hasEip1559 || gas.gasPrice >= gas.maxFeePerGas)) {
|
|
1803
1945
|
unsignedTx.gasPrice = gas.gasPrice;
|
|
1804
1946
|
}
|
|
1805
|
-
if (
|
|
1947
|
+
else if (hasEip1559) {
|
|
1806
1948
|
unsignedTx.maxFeePerGas = gas.maxFeePerGas;
|
|
1807
|
-
}
|
|
1808
|
-
if (gas?.maxPriorityFeePerGas !== undefined) {
|
|
1809
1949
|
unsignedTx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
|
|
1810
1950
|
}
|
|
1811
1951
|
// Serialize transaction
|
|
@@ -1999,18 +2139,20 @@ export function useSignAndSendTxn(provider) {
|
|
|
1999
2139
|
value: valueInWei,
|
|
2000
2140
|
nonce,
|
|
2001
2141
|
};
|
|
2002
|
-
// Add gas properties if they exist
|
|
2142
|
+
// Add gas properties if they exist. Never set both legacy and EIP-1559 —
|
|
2143
|
+
// viem serializes as type-2 whenever maxFeePerGas is present, which can
|
|
2144
|
+
// underpay Ethermint minimum-global-fee when gasPrice was the real floor.
|
|
2003
2145
|
const unsignedTx = { ...baseTx };
|
|
2004
2146
|
if (gas?.gasLimit !== undefined) {
|
|
2005
2147
|
unsignedTx.gas = gas.gasLimit;
|
|
2006
2148
|
}
|
|
2007
|
-
|
|
2149
|
+
const hasEip1559 = gas?.maxFeePerGas !== undefined && gas?.maxPriorityFeePerGas !== undefined;
|
|
2150
|
+
const hasLegacy = gas?.gasPrice !== undefined;
|
|
2151
|
+
if (hasLegacy && (!hasEip1559 || gas.gasPrice >= gas.maxFeePerGas)) {
|
|
2008
2152
|
unsignedTx.gasPrice = gas.gasPrice;
|
|
2009
2153
|
}
|
|
2010
|
-
if (
|
|
2154
|
+
else if (hasEip1559) {
|
|
2011
2155
|
unsignedTx.maxFeePerGas = gas.maxFeePerGas;
|
|
2012
|
-
}
|
|
2013
|
-
if (gas?.maxPriorityFeePerGas !== undefined) {
|
|
2014
2156
|
unsignedTx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
|
|
2015
2157
|
}
|
|
2016
2158
|
// Serialize transaction
|
|
@@ -2057,7 +2199,7 @@ export function useSignAndSendTxn(provider) {
|
|
|
2057
2199
|
* ```
|
|
2058
2200
|
*/
|
|
2059
2201
|
export function useWaitForTxnReceipt(provider) {
|
|
2060
|
-
const waitForTxnReceipt = useCallback(async ({ hash, confirmations, timeout, }) => {
|
|
2202
|
+
const waitForTxnReceipt = useCallback(async ({ hash, confirmations, timeout, throwOnRevert = true, }) => {
|
|
2061
2203
|
if (!provider) {
|
|
2062
2204
|
throw new Error('Provider (publicClient) is required');
|
|
2063
2205
|
}
|
|
@@ -2080,9 +2222,18 @@ export function useWaitForTxnReceipt(provider) {
|
|
|
2080
2222
|
timeout: Math.min(20_000, remaining),
|
|
2081
2223
|
pollingInterval: 1_500,
|
|
2082
2224
|
});
|
|
2225
|
+
if (throwOnRevert &&
|
|
2226
|
+
(receipt.status === 'reverted' ||
|
|
2227
|
+
receipt.status === 0 ||
|
|
2228
|
+
receipt.status === '0x0')) {
|
|
2229
|
+
throw new Error('Transaction reverted');
|
|
2230
|
+
}
|
|
2083
2231
|
return receipt;
|
|
2084
2232
|
}
|
|
2085
2233
|
catch (error) {
|
|
2234
|
+
if (error instanceof Error && error.message === 'Transaction reverted') {
|
|
2235
|
+
throw error;
|
|
2236
|
+
}
|
|
2086
2237
|
lastError = error;
|
|
2087
2238
|
await waitUntilDocumentVisible();
|
|
2088
2239
|
await new Promise((resolve) => setTimeout(resolve, 1_000));
|
|
@@ -2096,6 +2247,9 @@ export function useWaitForTxnReceipt(provider) {
|
|
|
2096
2247
|
: new Error('Failed to wait for transaction receipt');
|
|
2097
2248
|
}
|
|
2098
2249
|
catch (error) {
|
|
2250
|
+
if (error instanceof Error && error.message === 'Transaction reverted') {
|
|
2251
|
+
throw error;
|
|
2252
|
+
}
|
|
2099
2253
|
if (error instanceof Error && error.message.startsWith('Failed to wait for transaction receipt')) {
|
|
2100
2254
|
throw error;
|
|
2101
2255
|
}
|
|
@@ -2523,7 +2677,12 @@ export function useWriteContract() {
|
|
|
2523
2677
|
// Matching without selector is still useful (from + to).
|
|
2524
2678
|
}
|
|
2525
2679
|
const cancelPoll = { cancelled: false };
|
|
2526
|
-
const sendPromise = sendWrite()
|
|
2680
|
+
const sendPromise = sendWrite().then((hash) => hash, (err) => {
|
|
2681
|
+
if (isUserRejectionError(err))
|
|
2682
|
+
throw toUserRejectionError(err);
|
|
2683
|
+
throw err;
|
|
2684
|
+
});
|
|
2685
|
+
// Success-only chain recovery when WC hash never arrives.
|
|
2527
2686
|
const pollPromise = pollForOutgoingTx({
|
|
2528
2687
|
publicClient,
|
|
2529
2688
|
from: fromAddress,
|
|
@@ -2532,12 +2691,11 @@ export function useWriteContract() {
|
|
|
2532
2691
|
value,
|
|
2533
2692
|
startBlock,
|
|
2534
2693
|
signal: cancelPoll,
|
|
2535
|
-
initialDelayMs:
|
|
2536
|
-
timeoutMs:
|
|
2694
|
+
initialDelayMs: 1_000,
|
|
2695
|
+
timeoutMs: 60_000,
|
|
2537
2696
|
});
|
|
2538
2697
|
try {
|
|
2539
2698
|
const hash = await Promise.race([sendPromise, pollPromise]);
|
|
2540
|
-
// Poll may win while WC is still hanging — ignore a late reject.
|
|
2541
2699
|
void sendPromise.then(() => undefined, () => undefined);
|
|
2542
2700
|
return hash;
|
|
2543
2701
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* when used in a React project
|
|
5
5
|
*/
|
|
6
6
|
export { AbstraxnProvider, useAbstraxnWallet } from './AbstraxnProvider';
|
|
7
|
-
export { useIsConnected, useAddress, useAuthContext, useChainId, useError, useEnableMfa, useDisableMfa, useAuthMethodLinking, useEmailForOtp, useWallet, useSmartAccountOwner, useExportWallet, useWhoami, useExternalWallet, useExternalWalletBalance, useExternalWalletChain, useExternalWalletInfo, usePublicClient, useWalletClient, useContract, usePrepareRawTxn, useSignTxn, useSignTypedTx, useSignAndSendTxn, useWaitForTxnReceipt, useReadContract, useExternalWalletClient, useWriteContract, useConnectionType, useSwitchChain, useSignMessage, useEstimateGas, useGetGasPrice, useSolanaConnection, useSolanaPublicKey, useSolanaBalance, usePrepareSolanaTxn, useSolanaExternalWallet, usePrepareSolanaProgramTxn, useSolanaProgramTransaction, useSignSolanaTxn, useSignAndSendSolanaTxn, useSolanaGasless, useSignAndSendSolanaGaslessTxn, useWaitForSolanaConfirmation, usePolicies, usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy, usePublishPolicy, useUnpublishPolicy, usePolicyTemplates, } from './hooks';
|
|
7
|
+
export { useIsConnected, useAddress, useAuthContext, useChainId, useError, useEnableMfa, useDisableMfa, useAuthMethodLinking, useEmailForOtp, useWallet, useSmartAccountOwner, useExportWallet, useWhoami, useExternalWallet, useExternalWalletBalance, useExternalWalletChain, useExternalWalletInfo, usePublicClient, useWalletClient, useContract, usePrepareRawTxn, useSignTxn, useSignTypedTx, useSignAndSendTxn, useWaitForTxnReceipt, useReadContract, useExternalWalletClient, useWriteContract, useConnectionType, useSwitchChain, useSignMessage, useEstimateGas, useGetGasPrice, useSolanaConnection, useSolanaPublicKey, useSolanaBalance, useSolanaTokenBalances, useTokenBalances, usePrepareSolanaTxn, useSolanaExternalWallet, usePrepareSolanaProgramTxn, useSolanaProgramTransaction, useSignSolanaTxn, useSignAndSendSolanaTxn, useSolanaGasless, useSignAndSendSolanaGaslessTxn, useWaitForSolanaConfirmation, usePolicies, usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy, usePublishPolicy, useUnpublishPolicy, usePolicyTemplates, } from './hooks';
|
|
8
8
|
export { ConnectButton } from './ConnectButton';
|
|
9
9
|
export type { ConnectButtonProps, ConnectButtonVariant, ConnectButtonSize } from './ConnectButton';
|
|
10
10
|
export { WalletModal } from './WalletModal';
|
|
@@ -16,4 +16,4 @@ export type { OnboardingUIComponentProps, OnboardingUIComponentRef } from './Onb
|
|
|
16
16
|
export { ALL_CHAINS, EVM_CHAINS, SOLANA_CHAINS, getChainById, getChainsByType, getDefaultChains, toCoreChain, type ChainData, } from './chains';
|
|
17
17
|
export { CONNECTORS, getConnectorMeta, isOAuthConnector, isWalletConnector, isAuthConnector, type ConnectorType, type ConnectorMeta, } from './connectors';
|
|
18
18
|
export { createWagmiConfig } from './wagmiConfig';
|
|
19
|
-
export { pollForOutgoingTx, clearWalletConnectPendingState, waitUntilDocumentVisible, isWalletConnectConnector, isMobileDevice, } from './walletConnectMobile';
|
|
19
|
+
export { pollForOutgoingTx, clearWalletConnectPendingState, waitUntilDocumentVisible, isWalletConnectConnector, isMobileDevice, forceResumeWalletConnectOnReturn, isUserRejectionError, toUserRejectionError, } from './walletConnectMobile';
|
package/dist/src/index.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* when used in a React project
|
|
5
5
|
*/
|
|
6
6
|
export { AbstraxnProvider, useAbstraxnWallet } from './AbstraxnProvider';
|
|
7
|
-
export { useIsConnected, useAddress, useAuthContext, useChainId, useError, useEnableMfa, useDisableMfa, useAuthMethodLinking, useEmailForOtp, useWallet, useSmartAccountOwner, useExportWallet, useWhoami, useExternalWallet, useExternalWalletBalance, useExternalWalletChain, useExternalWalletInfo, usePublicClient, useWalletClient, useContract, usePrepareRawTxn, useSignTxn, useSignTypedTx, useSignAndSendTxn, useWaitForTxnReceipt, useReadContract, useExternalWalletClient, useWriteContract, useConnectionType, useSwitchChain, useSignMessage, useEstimateGas, useGetGasPrice, useSolanaConnection, useSolanaPublicKey, useSolanaBalance, usePrepareSolanaTxn, useSolanaExternalWallet, usePrepareSolanaProgramTxn, useSolanaProgramTransaction, useSignSolanaTxn, useSignAndSendSolanaTxn, useSolanaGasless, useSignAndSendSolanaGaslessTxn, useWaitForSolanaConfirmation, usePolicies, usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy, usePublishPolicy, useUnpublishPolicy, usePolicyTemplates, } from './hooks';
|
|
7
|
+
export { useIsConnected, useAddress, useAuthContext, useChainId, useError, useEnableMfa, useDisableMfa, useAuthMethodLinking, useEmailForOtp, useWallet, useSmartAccountOwner, useExportWallet, useWhoami, useExternalWallet, useExternalWalletBalance, useExternalWalletChain, useExternalWalletInfo, usePublicClient, useWalletClient, useContract, usePrepareRawTxn, useSignTxn, useSignTypedTx, useSignAndSendTxn, useWaitForTxnReceipt, useReadContract, useExternalWalletClient, useWriteContract, useConnectionType, useSwitchChain, useSignMessage, useEstimateGas, useGetGasPrice, useSolanaConnection, useSolanaPublicKey, useSolanaBalance, useSolanaTokenBalances, useTokenBalances, usePrepareSolanaTxn, useSolanaExternalWallet, usePrepareSolanaProgramTxn, useSolanaProgramTransaction, useSignSolanaTxn, useSignAndSendSolanaTxn, useSolanaGasless, useSignAndSendSolanaGaslessTxn, useWaitForSolanaConfirmation, usePolicies, usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy, usePublishPolicy, useUnpublishPolicy, usePolicyTemplates, } from './hooks';
|
|
8
8
|
export { ConnectButton } from './ConnectButton';
|
|
9
9
|
export { WalletModal } from './WalletModal';
|
|
10
10
|
export { OnboardingUIComponent as OnboardingUI } from './OnboardingUI';
|
|
11
11
|
export { ALL_CHAINS, EVM_CHAINS, SOLANA_CHAINS, getChainById, getChainsByType, getDefaultChains, toCoreChain, } from './chains';
|
|
12
12
|
export { CONNECTORS, getConnectorMeta, isOAuthConnector, isWalletConnector, isAuthConnector, } from './connectors';
|
|
13
13
|
export { createWagmiConfig } from './wagmiConfig';
|
|
14
|
-
export { pollForOutgoingTx, clearWalletConnectPendingState, waitUntilDocumentVisible, isWalletConnectConnector, isMobileDevice, } from './walletConnectMobile';
|
|
14
|
+
export { pollForOutgoingTx, clearWalletConnectPendingState, waitUntilDocumentVisible, isWalletConnectConnector, isMobileDevice, forceResumeWalletConnectOnReturn, isUserRejectionError, toUserRejectionError, } from './walletConnectMobile';
|
|
15
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge so non-React signing helpers can request an MFA code via the
|
|
3
|
+
* provider-mounted MfaVerifyModal (replaces window.prompt).
|
|
4
|
+
*/
|
|
5
|
+
export type SignMfaCodeRequester = () => Promise<string>;
|
|
6
|
+
export declare function registerSignMfaCodeRequester(requester: SignMfaCodeRequester | null): () => void;
|
|
7
|
+
export declare function requestSignMfaCode(): Promise<string>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
let signMfaCodeRequester = null;
|
|
2
|
+
export function registerSignMfaCodeRequester(requester) {
|
|
3
|
+
signMfaCodeRequester = requester;
|
|
4
|
+
return () => {
|
|
5
|
+
if (signMfaCodeRequester === requester) {
|
|
6
|
+
signMfaCodeRequester = null;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export async function requestSignMfaCode() {
|
|
11
|
+
if (!signMfaCodeRequester) {
|
|
12
|
+
throw new Error("MFA step-up is required to sign, but no MFA UI is available. Ensure AbstraxnProvider is mounted.");
|
|
13
|
+
}
|
|
14
|
+
const code = await signMfaCodeRequester();
|
|
15
|
+
if (!code || code.trim() === "") {
|
|
16
|
+
throw new Error("MFA code is required to continue signing.");
|
|
17
|
+
}
|
|
18
|
+
return code.trim().toUpperCase();
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=signMfaBridge.js.map
|
package/dist/src/types.d.ts
CHANGED
|
@@ -313,6 +313,10 @@ export interface AbstraxnContextValue {
|
|
|
313
313
|
walletBalance?: bigint | null;
|
|
314
314
|
/** Refetch wallet balance from RPC (Abstraxn or external). Call when UI screen changes (e.g. back button, modal open/close). */
|
|
315
315
|
refetchBalance?: () => Promise<void>;
|
|
316
|
+
tokenBalances: import("./components/WalletModal/components/TokenSelectorModal").TokenData[];
|
|
317
|
+
tokenBalancesLoading: boolean;
|
|
318
|
+
tokenBalancesError: Error | null;
|
|
319
|
+
refetchTokenBalances: () => Promise<void>;
|
|
316
320
|
connectionType?: string | null;
|
|
317
321
|
emailForOtp?: string;
|
|
318
322
|
setEmailForOtp?: (email: string) => void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* document.activeElement returns the shadow HOST element when focus is
|
|
3
|
+
* actually on a descendant inside its shadow tree, not the focused element
|
|
4
|
+
* itself. Tab-trap logic comparing `document.activeElement === someElement`
|
|
5
|
+
* silently breaks once that element lives inside a shadow root — this walks
|
|
6
|
+
* down through nested shadow roots to find the real focused element.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDeepActiveElement(): Element | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* document.activeElement returns the shadow HOST element when focus is
|
|
3
|
+
* actually on a descendant inside its shadow tree, not the focused element
|
|
4
|
+
* itself. Tab-trap logic comparing `document.activeElement === someElement`
|
|
5
|
+
* silently breaks once that element lives inside a shadow root — this walks
|
|
6
|
+
* down through nested shadow roots to find the real focused element.
|
|
7
|
+
*/
|
|
8
|
+
export function getDeepActiveElement() {
|
|
9
|
+
let active = document.activeElement;
|
|
10
|
+
while (active && active.shadowRoot && active.shadowRoot.activeElement) {
|
|
11
|
+
active = active.shadowRoot.activeElement;
|
|
12
|
+
}
|
|
13
|
+
return active;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=shadowFocus.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared registry of every currently-mounted shadow root (both React
|
|
3
|
+
* ShadowHost instances and the vanilla OnboardingUIWeb instances). Plain TS,
|
|
4
|
+
* no framework dependency, so both sides can use it.
|
|
5
|
+
*
|
|
6
|
+
* Invariant: every registerShadowRoot() call must be paired with exactly one
|
|
7
|
+
* call to its returned unregister function when — and only when — that
|
|
8
|
+
* specific shadow root is torn down. Violating this either leaks a reference
|
|
9
|
+
* to a detached shadow root (memory leak) or silently drops an active
|
|
10
|
+
* boundary from cross-boundary queries (correctness bug).
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerShadowRoot(root: ShadowRoot): () => void;
|
|
13
|
+
/**
|
|
14
|
+
* Unions document.querySelectorAll(selector) with the same query run against
|
|
15
|
+
* every currently-registered shadow root. Restores the pre-shadow-DOM
|
|
16
|
+
* cross-boundary "hide the other open modal overlay" behavior without
|
|
17
|
+
* requiring the separate shadow roots to nest inside one another.
|
|
18
|
+
*
|
|
19
|
+
* One-directional in practice today: only OnboardingUIWeb.showLoadingModal()
|
|
20
|
+
* calls this (to hide an open WalletModal). No symmetric call exists on the
|
|
21
|
+
* WalletModal/React side, matching pre-migration behavior exactly.
|
|
22
|
+
*/
|
|
23
|
+
export declare function queryAllAcrossShadowRoots(selector: string): Element[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared registry of every currently-mounted shadow root (both React
|
|
3
|
+
* ShadowHost instances and the vanilla OnboardingUIWeb instances). Plain TS,
|
|
4
|
+
* no framework dependency, so both sides can use it.
|
|
5
|
+
*
|
|
6
|
+
* Invariant: every registerShadowRoot() call must be paired with exactly one
|
|
7
|
+
* call to its returned unregister function when — and only when — that
|
|
8
|
+
* specific shadow root is torn down. Violating this either leaks a reference
|
|
9
|
+
* to a detached shadow root (memory leak) or silently drops an active
|
|
10
|
+
* boundary from cross-boundary queries (correctness bug).
|
|
11
|
+
*/
|
|
12
|
+
const shadowRoots = new Set();
|
|
13
|
+
export function registerShadowRoot(root) {
|
|
14
|
+
shadowRoots.add(root);
|
|
15
|
+
return () => {
|
|
16
|
+
shadowRoots.delete(root);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Unions document.querySelectorAll(selector) with the same query run against
|
|
21
|
+
* every currently-registered shadow root. Restores the pre-shadow-DOM
|
|
22
|
+
* cross-boundary "hide the other open modal overlay" behavior without
|
|
23
|
+
* requiring the separate shadow roots to nest inside one another.
|
|
24
|
+
*
|
|
25
|
+
* One-directional in practice today: only OnboardingUIWeb.showLoadingModal()
|
|
26
|
+
* calls this (to hide an open WalletModal). No symmetric call exists on the
|
|
27
|
+
* WalletModal/React side, matching pre-migration behavior exactly.
|
|
28
|
+
*/
|
|
29
|
+
export function queryAllAcrossShadowRoots(selector) {
|
|
30
|
+
const results = Array.from(document.querySelectorAll(selector));
|
|
31
|
+
for (const root of shadowRoots) {
|
|
32
|
+
results.push(...Array.from(root.querySelectorAll(selector)));
|
|
33
|
+
}
|
|
34
|
+
return results;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=shadowRegistry.js.map
|
|
@@ -107,9 +107,12 @@ export declare function waitUntilDocumentVisible(): Promise<void>;
|
|
|
107
107
|
* (poll won while eth_sendTransaction is still hanging).
|
|
108
108
|
*/
|
|
109
109
|
export declare function clearWalletConnectPendingState(provider: any): void;
|
|
110
|
+
/** EIP-1193 4001 / WC 5000 (and common message shapes). */
|
|
111
|
+
export declare function isUserRejectionError(error: unknown): boolean;
|
|
112
|
+
export declare function toUserRejectionError(error?: unknown): Error;
|
|
110
113
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
114
|
+
* Success-only recovery: find an on-chain hash when WC never returns one.
|
|
115
|
+
* Does not infer reject (that is handled by relay resume + reject fallback).
|
|
113
116
|
*/
|
|
114
117
|
export declare function pollForOutgoingTx(params: {
|
|
115
118
|
publicClient: {
|
|
@@ -123,7 +126,6 @@ export declare function pollForOutgoingTx(params: {
|
|
|
123
126
|
};
|
|
124
127
|
from: string;
|
|
125
128
|
to: string;
|
|
126
|
-
/** Match tx.input prefix (e.g. 0x + 4-byte selector). */
|
|
127
129
|
dataPrefix?: string;
|
|
128
130
|
value?: bigint;
|
|
129
131
|
startBlock: bigint;
|
|
@@ -133,13 +135,15 @@ export declare function pollForOutgoingTx(params: {
|
|
|
133
135
|
timeoutMs?: number;
|
|
134
136
|
initialDelayMs?: number;
|
|
135
137
|
}): Promise<`0x${string}`>;
|
|
138
|
+
/** Time-bounded force-resume (must not hang on transportOpen). */
|
|
139
|
+
export declare function forceResumeWalletConnectOnReturn(provider: any, timeoutMs?: number): Promise<void>;
|
|
136
140
|
/**
|
|
137
141
|
* Patch the EIP-1193 provider so signing/tx requests resume the relay first.
|
|
138
142
|
* Covers wagmi hooks, viem walletClient, and direct provider.request calls.
|
|
139
143
|
*/
|
|
140
144
|
export declare function patchWalletConnectProviderForMobile(provider: any): void;
|
|
141
145
|
/**
|
|
142
|
-
* When the dapp tab is shown again
|
|
143
|
-
*
|
|
146
|
+
* When the dapp tab is shown again, restart the relay so pending
|
|
147
|
+
* approve/reject responses can be delivered (WalletConnect mobile linking).
|
|
144
148
|
*/
|
|
145
149
|
export declare function subscribeWalletConnectForegroundResume(provider: any): () => void;
|