@rango-dev/widget-embedded 0.0.0-experimental-1624fbb4-20260708 → 0.0.0-experimental-a84f27a7-20260921
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 +47 -0
- package/dist/QueueManager.d.ts.map +1 -1
- package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -1
- package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
- package/dist/components/CustomDestination/CustomDestination.styles.d.ts +4 -4
- package/dist/components/CustomDestination/CustomDestination.styles.d.ts.map +1 -1
- package/dist/components/CustomTokenModal/CustomTokenModal.styles.d.ts +169 -169
- package/dist/components/CustomTokenModal/CustomTokenModal.styles.d.ts.map +1 -1
- package/dist/components/FilterSelector/FilterSelector.style.d.ts +1 -1
- package/dist/components/FilterSelector/FilterSelector.style.d.ts.map +1 -1
- package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +1 -1
- package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts.map +1 -1
- package/dist/components/NamespaceItem/NamespaceItem.d.ts.map +1 -1
- package/dist/components/NamespaceItem/NamespaceItem.styles.d.ts +1 -1
- package/dist/components/NamespaceItem/NamespaceItem.styles.d.ts.map +1 -1
- package/dist/components/NamespaceItem/NamespaceItem.types.d.ts +3 -3
- package/dist/components/NamespaceItem/NamespaceItem.types.d.ts.map +1 -1
- package/dist/components/Quote/Quote.d.ts.map +1 -1
- package/dist/components/Quote/Quote.styles.d.ts +171 -171
- package/dist/components/Quote/Quote.styles.d.ts.map +1 -1
- package/dist/components/Quote/Quote.types.d.ts +0 -2
- package/dist/components/Quote/Quote.types.d.ts.map +1 -1
- package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
- package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts +169 -169
- package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
- package/dist/components/RefreshModal/RefreshModal.styles.d.ts +168 -168
- package/dist/components/RefreshModal/RefreshModal.styles.d.ts.map +1 -1
- package/dist/components/StatefulConnectModal/StatefulConnectModal.d.ts.map +1 -1
- package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
- package/dist/components/SwapDetails/SwapDetails.styles.d.ts +1 -1
- package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
- package/dist/components/SwapDetailsModal/SwapDetailsModal.ConnectWallet.d.ts.map +1 -1
- package/dist/components/SwapDetailsModal/SwapDetailsModal.InstallWallet.d.ts.map +1 -1
- package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts +3 -3
- package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts.map +1 -1
- package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts +1 -1
- package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts.map +1 -1
- package/dist/components/TokenList/TokenList.styles.d.ts +2 -2
- package/dist/components/TokenList/TokenList.styles.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/DerivationPath.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts +7 -3
- package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/DerivationPath.helpers.test.d.ts +2 -0
- package/dist/components/WalletStatefulConnect/DerivationPath.helpers.test.d.ts.map +1 -0
- package/dist/components/WalletStatefulConnect/DerivationPath.styles.d.ts +169 -169
- package/dist/components/WalletStatefulConnect/DerivationPath.styles.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/Detached.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts +168 -168
- package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts.map +1 -1
- package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts +3 -3
- package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts.map +1 -1
- package/dist/constants/errors.d.ts +1 -0
- package/dist/constants/errors.d.ts.map +1 -1
- package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
- package/dist/containers/Wallets/Wallets.helpers.d.ts +2 -2
- package/dist/containers/Wallets/Wallets.helpers.d.ts.map +1 -1
- package/dist/containers/Wallets/Wallets.types.d.ts +4 -4
- package/dist/containers/Wallets/Wallets.types.d.ts.map +1 -1
- package/dist/containers/Wallets/useUpdates.d.ts +1 -1
- package/dist/containers/Wallets/useUpdates.d.ts.map +1 -1
- package/dist/containers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
- package/dist/containers/WidgetProvider/WidgetProvider.helpers.d.ts +5 -0
- package/dist/containers/WidgetProvider/WidgetProvider.helpers.d.ts.map +1 -0
- package/dist/containers/WidgetProvider/WidgetProvider.types.d.ts +1 -1
- package/dist/containers/WidgetProvider/WidgetProvider.types.d.ts.map +1 -1
- package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
- package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts +5 -4
- package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts.map +1 -1
- package/dist/hooks/useWalletList.d.ts.map +1 -1
- package/dist/hooks/useWalletProviders/useWalletProviders.d.ts +2 -2
- package/dist/hooks/useWalletProviders/useWalletProviders.d.ts.map +1 -1
- package/dist/hooks/useWalletProviders/useWalletProviders.helpers.d.ts +2 -3
- package/dist/hooks/useWalletProviders/useWalletProviders.helpers.d.ts.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +4 -4
- package/dist/store/AppStore.d.ts +2 -2
- package/dist/store/AppStore.d.ts.map +1 -1
- package/dist/store/app.d.ts +2 -2
- package/dist/store/app.d.ts.map +1 -1
- package/dist/store/slices/config.d.ts +5 -5
- package/dist/store/slices/config.d.ts.map +1 -1
- package/dist/test-utils/fixtures.d.ts +2 -2
- package/dist/test-utils/fixtures.d.ts.map +1 -1
- package/dist/types/config.d.ts +25 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/wallets.d.ts +1 -1
- package/dist/types/wallets.d.ts.map +1 -1
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/connectionReporting.d.ts +24 -0
- package/dist/utils/connectionReporting.d.ts.map +1 -0
- package/dist/utils/connectionReporting.test.d.ts +2 -0
- package/dist/utils/connectionReporting.test.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +14 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.test.d.ts +2 -0
- package/dist/utils/errors.test.d.ts.map +1 -0
- package/dist/utils/providers.d.ts +3 -6
- package/dist/utils/providers.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +1 -1
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/utils/wallets.d.ts +2 -1
- package/dist/utils/wallets.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/QueueManager.tsx +17 -8
- package/src/components/NamespaceItem/NamespaceItem.styles.ts +1 -0
- package/src/components/NamespaceItem/NamespaceItem.tsx +5 -1
- package/src/components/NamespaceItem/NamespaceItem.types.ts +3 -3
- package/src/components/Quote/Quote.tsx +0 -2
- package/src/components/Quote/Quote.types.ts +0 -2
- package/src/components/Quote/QuoteCostDetails.tsx +15 -4
- package/src/components/StatefulConnectModal/StatefulConnectModal.tsx +8 -2
- package/src/components/SwapDetails/SwapDetails.tsx +18 -6
- package/src/components/SwapDetailsModal/SwapDetailsModal.ConnectWallet.tsx +23 -23
- package/src/components/SwapDetailsModal/SwapDetailsModal.InstallWallet.tsx +8 -2
- package/src/components/SwapDetailsModal/SwapDetailsModal.types.ts +3 -3
- package/src/components/TokenList/LoadingTokenList.tsx +2 -2
- package/src/components/WalletStatefulConnect/DerivationPath.helpers.test.ts +98 -0
- package/src/components/WalletStatefulConnect/DerivationPath.helpers.ts +14 -10
- package/src/components/WalletStatefulConnect/DerivationPath.tsx +14 -7
- package/src/components/WalletStatefulConnect/Detached.tsx +17 -8
- package/src/components/WalletStatefulConnect/NamespaceDetachedItem.tsx +2 -1
- package/src/components/WalletStatefulConnect/Namespaces.tsx +6 -12
- package/src/components/WalletStatefulConnect/Namespaces.types.tsx +3 -3
- package/src/constants/errors.ts +3 -0
- package/src/containers/Wallets/Wallets.helpers.ts +4 -4
- package/src/containers/Wallets/Wallets.tsx +20 -3
- package/src/containers/Wallets/Wallets.types.ts +4 -7
- package/src/containers/Wallets/useUpdates.ts +4 -119
- package/src/containers/WidgetProvider/WidgetProvider.helpers.ts +10 -0
- package/src/containers/WidgetProvider/WidgetProvider.tsx +12 -1
- package/src/containers/WidgetProvider/WidgetProvider.types.ts +1 -1
- package/src/hooks/useStatefulConnect/useStatefulConnect.ts +30 -31
- package/src/hooks/useStatefulConnect/useStatefulConnect.types.ts +6 -3
- package/src/hooks/useWalletList.ts +10 -7
- package/src/hooks/useWalletProviders/useWalletProviders.helpers.ts +3 -10
- package/src/hooks/useWalletProviders/useWalletProviders.ts +2 -2
- package/src/index.ts +10 -11
- package/src/store/AppStore.tsx +4 -2
- package/src/store/app.ts +7 -2
- package/src/store/slices/config.ts +36 -25
- package/src/store/slices/data.test.ts +2 -2
- package/src/test-utils/fixtures.ts +6 -2
- package/src/types/config.ts +31 -4
- package/src/types/wallets.ts +1 -1
- package/src/utils/common.ts +6 -0
- package/src/utils/connectionReporting.test.ts +379 -0
- package/src/utils/connectionReporting.ts +94 -0
- package/src/utils/errors.test.ts +125 -0
- package/src/utils/errors.ts +88 -0
- package/src/utils/providers.ts +16 -50
- package/src/utils/swap.ts +8 -1
- package/src/utils/wallets.ts +12 -15
- package/dist/widget-embedded.build.json +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { WalletType } from '@hub3js/core';
|
|
2
|
+
|
|
3
|
+
import { getRangoError, WalletConnectionError } from '@hub3js/std/utils';
|
|
4
|
+
import { error as logError } from '@rango-dev/logging-core';
|
|
5
|
+
|
|
6
|
+
export type ConnectionTrigger =
|
|
7
|
+
| 'wallet-modal'
|
|
8
|
+
| 'wallet-modal-namespace'
|
|
9
|
+
| 'swap-details-modal'
|
|
10
|
+
| 'swap-details'
|
|
11
|
+
| 'queue-manager';
|
|
12
|
+
|
|
13
|
+
export type ConnectionSource = 'user' | 'auto-connect';
|
|
14
|
+
|
|
15
|
+
export type ConnectionReportContext = {
|
|
16
|
+
trigger: ConnectionTrigger;
|
|
17
|
+
source: ConnectionSource;
|
|
18
|
+
walletType: WalletType;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type ConnectionAttemptContext = ConnectionReportContext & {
|
|
22
|
+
namespaces?: string[];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// 3 minutes
|
|
26
|
+
export const CONNECTION_TIMEOUT_MS = 180_000;
|
|
27
|
+
|
|
28
|
+
// The user's own doing: dropped, never downgraded to a lower level.
|
|
29
|
+
const NOT_REPORTED_TYPES: readonly string[] = ['rejected', 'locked'];
|
|
30
|
+
|
|
31
|
+
function logConnectionError(error: unknown, context: ConnectionReportContext) {
|
|
32
|
+
try {
|
|
33
|
+
const { trigger, source, walletType } = context;
|
|
34
|
+
const rangoError = getRangoError(error, { trigger, source, walletType });
|
|
35
|
+
|
|
36
|
+
if (NOT_REPORTED_TYPES.includes(rangoError.type)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
logError(rangoError, {
|
|
41
|
+
tags: rangoError.getErrorTags(),
|
|
42
|
+
context: rangoError.getErrorContext(),
|
|
43
|
+
});
|
|
44
|
+
} catch {
|
|
45
|
+
// Reporting must never change what the caller sees.
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Logs a connection failure unless the user caused it, then throws the
|
|
51
|
+
* original error, the same object, for the caller's own handling.
|
|
52
|
+
*/
|
|
53
|
+
export function reportConnectionError(
|
|
54
|
+
error: unknown,
|
|
55
|
+
context: ConnectionReportContext
|
|
56
|
+
): never {
|
|
57
|
+
logConnectionError(error, context);
|
|
58
|
+
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Follows a connection attempt: reports its failure and rethrows it, and
|
|
64
|
+
* reports a `timeout` when an attempt the user started is still pending after
|
|
65
|
+
* 3 minutes. The timer never cancels or rejects the attempt.
|
|
66
|
+
*/
|
|
67
|
+
export async function trackConnection<T>(
|
|
68
|
+
attempt: Promise<T>,
|
|
69
|
+
context: ConnectionAttemptContext
|
|
70
|
+
): Promise<T> {
|
|
71
|
+
const { namespaces = [], ...reportContext } = context;
|
|
72
|
+
|
|
73
|
+
const timeoutTimer =
|
|
74
|
+
reportContext.source === 'user'
|
|
75
|
+
? setTimeout(() => {
|
|
76
|
+
logConnectionError(
|
|
77
|
+
new WalletConnectionError({
|
|
78
|
+
walletType: reportContext.walletType,
|
|
79
|
+
namespace: [...new Set(namespaces)].sort().join(','),
|
|
80
|
+
type: 'timeout',
|
|
81
|
+
}),
|
|
82
|
+
reportContext
|
|
83
|
+
);
|
|
84
|
+
}, CONNECTION_TIMEOUT_MS)
|
|
85
|
+
: undefined;
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
return await attempt;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return reportConnectionError(error, reportContext);
|
|
91
|
+
} finally {
|
|
92
|
+
clearTimeout(timeoutTimer);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
isModuleLoadError,
|
|
5
|
+
tryRefineError,
|
|
6
|
+
tryRefineErrorMessage,
|
|
7
|
+
} from './errors';
|
|
8
|
+
|
|
9
|
+
describe('error refinement', () => {
|
|
10
|
+
describe('recognizing a failed dynamic import', () => {
|
|
11
|
+
test('should match a thrown error', () => {
|
|
12
|
+
const error = new TypeError(
|
|
13
|
+
'Failed to fetch dynamically imported module: https://cdn.example/signer.js'
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(isModuleLoadError(error)).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('should match webpack failures named instead of worded', () => {
|
|
20
|
+
const error = new Error('Loading failed');
|
|
21
|
+
error.name = 'ChunkLoadError';
|
|
22
|
+
|
|
23
|
+
expect(isModuleLoadError(error)).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should match a message that was already stringified', () => {
|
|
27
|
+
expect(
|
|
28
|
+
isModuleLoadError('TypeError: importing a module script failed')
|
|
29
|
+
).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('match a failed import carried as the cause of another error', () => {
|
|
33
|
+
const failedImport = new TypeError(
|
|
34
|
+
'Failed to fetch dynamically imported module: https://cdn.example/ledger.js'
|
|
35
|
+
);
|
|
36
|
+
const connectionError = new Error("Couldn't connect to your wallet.", {
|
|
37
|
+
cause: failedImport,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(isModuleLoadError(connectionError)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('match a failed import several causes down', () => {
|
|
44
|
+
const failedImport = new TypeError('loading chunk 42 failed');
|
|
45
|
+
const error = new Error('outer', {
|
|
46
|
+
cause: new Error('middle', { cause: failedImport }),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(isModuleLoadError(error)).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('stop following causes that refer to each other', () => {
|
|
53
|
+
const first = new Error('first');
|
|
54
|
+
const second = new Error('second', { cause: first });
|
|
55
|
+
first.cause = second;
|
|
56
|
+
|
|
57
|
+
expect(isModuleLoadError(first)).toBe(false);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('leaving unrecognized failures alone', () => {
|
|
62
|
+
test('should not match an unrelated error', () => {
|
|
63
|
+
expect(
|
|
64
|
+
isModuleLoadError(new Error('User rejected the transaction'))
|
|
65
|
+
).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should not match empty input', () => {
|
|
69
|
+
expect(isModuleLoadError(null)).toBe(false);
|
|
70
|
+
expect(isModuleLoadError(undefined)).toBe(false);
|
|
71
|
+
expect(isModuleLoadError('')).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('leave an error whose cause is unrelated alone', () => {
|
|
75
|
+
const error = new Error("Couldn't connect to your wallet.", {
|
|
76
|
+
cause: { code: 4001, message: 'User rejected the request.' },
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(isModuleLoadError(error)).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('refining into a user facing error', () => {
|
|
84
|
+
test('should keep the original as the cause', () => {
|
|
85
|
+
const error = new TypeError('failed to load module script');
|
|
86
|
+
const refined = tryRefineError(error);
|
|
87
|
+
|
|
88
|
+
expect(refined).toBeInstanceOf(Error);
|
|
89
|
+
expect(refined?.cause).toBe(error);
|
|
90
|
+
expect(refined?.message).not.toBe(error.message);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('refine a connection failure that carries a failed import as its cause', () => {
|
|
94
|
+
const failedImport = new TypeError('failed to load module script');
|
|
95
|
+
const connectionError = new Error("Couldn't connect to your wallet.", {
|
|
96
|
+
cause: failedImport,
|
|
97
|
+
});
|
|
98
|
+
const refined = tryRefineError(connectionError);
|
|
99
|
+
|
|
100
|
+
expect(refined?.cause).toBe(connectionError);
|
|
101
|
+
expect(refined?.message).not.toBe(connectionError.message);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should return null for an unrecognized failure', () => {
|
|
105
|
+
expect(tryRefineError(new Error('boom'))).toBeNull();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('should fall back to the given message', () => {
|
|
109
|
+
const fallback = 'An unknown error happened during connecting wallet.';
|
|
110
|
+
|
|
111
|
+
expect(tryRefineErrorMessage(new Error('boom'), fallback)).toBe(fallback);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should refine instead of falling back when recognized', () => {
|
|
115
|
+
const fallback = 'An unknown error happened during connecting wallet.';
|
|
116
|
+
|
|
117
|
+
expect(
|
|
118
|
+
tryRefineErrorMessage(
|
|
119
|
+
new TypeError('loading chunk 42 failed'),
|
|
120
|
+
fallback
|
|
121
|
+
)
|
|
122
|
+
).not.toBe(fallback);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { errorMessages } from '../constants/errors';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* A failed `import()` has no standard error, so each engine and bundler words
|
|
5
|
+
* it differently. Lowercase, they are matched against a lowercased message.
|
|
6
|
+
*/
|
|
7
|
+
const MODULE_LOAD_ERROR_MESSAGES = [
|
|
8
|
+
// Chromium
|
|
9
|
+
'failed to fetch dynamically imported module',
|
|
10
|
+
// Firefox
|
|
11
|
+
'error loading dynamically imported module',
|
|
12
|
+
// Safari
|
|
13
|
+
'importing a module script failed',
|
|
14
|
+
// A stale chunk answered with the index page instead of a module
|
|
15
|
+
'failed to load module script',
|
|
16
|
+
// Vite
|
|
17
|
+
'unable to preload css',
|
|
18
|
+
// Webpack
|
|
19
|
+
'loading chunk',
|
|
20
|
+
'loading css chunk',
|
|
21
|
+
'chunkloaderror',
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const MAX_CAUSE_DEPTH = 5;
|
|
25
|
+
|
|
26
|
+
function toMessage(value: unknown): string {
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (value instanceof Error) {
|
|
32
|
+
// Webpack names its failures rather than wording them.
|
|
33
|
+
return `${value.name} ${value.message}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function isModuleLoadError(value: unknown): boolean {
|
|
40
|
+
/*
|
|
41
|
+
* A connection failure carries the wallet's own error as its cause, so a
|
|
42
|
+
* failed import can sit a few causes down.
|
|
43
|
+
*/
|
|
44
|
+
let current = value;
|
|
45
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth++) {
|
|
46
|
+
const message = toMessage(current).toLowerCase();
|
|
47
|
+
if (
|
|
48
|
+
message &&
|
|
49
|
+
MODULE_LOAD_ERROR_MESSAGES.some((candidate) =>
|
|
50
|
+
message.includes(candidate)
|
|
51
|
+
)
|
|
52
|
+
) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!(current instanceof Error)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
current = current.cause;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Replace a failure we recognize with one worth showing to a user.
|
|
67
|
+
*
|
|
68
|
+
* Every place the widget calls into another package routes its failures through
|
|
69
|
+
* here, so a new class of failure only has to be taught to the widget once.
|
|
70
|
+
*
|
|
71
|
+
* @param error - a thrown error, or a message already stringified from one.
|
|
72
|
+
* @returns a user facing error keeping the original as `cause`, or `null` when
|
|
73
|
+
* the failure is not one we recognize.
|
|
74
|
+
*/
|
|
75
|
+
export function tryRefineError(error: unknown): Error | null {
|
|
76
|
+
if (isModuleLoadError(error)) {
|
|
77
|
+
return new Error(errorMessages().moduleLoadError, { cause: error });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function tryRefineErrorMessage(
|
|
84
|
+
error: unknown,
|
|
85
|
+
fallback: string
|
|
86
|
+
): string {
|
|
87
|
+
return tryRefineError(error)?.message ?? fallback;
|
|
88
|
+
}
|
package/src/utils/providers.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { WidgetConfig } from '../types';
|
|
2
|
-
import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';
|
|
3
2
|
|
|
4
3
|
import { Provider } from '@hub3js/core';
|
|
5
4
|
import {
|
|
@@ -19,11 +18,10 @@ export interface ProvidersOptions {
|
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
*
|
|
22
|
-
* Generate a list of providers by passing a provider name (e.g. metamask) or a custom
|
|
23
|
-
* @returns
|
|
21
|
+
* Generate a list of providers by passing a provider name (e.g. metamask) or a custom hub `Provider`.
|
|
22
|
+
* @returns VersionedProviders[] a list of VersionedProviders
|
|
24
23
|
*
|
|
25
24
|
*/
|
|
26
|
-
type BothProvidersInterface = LegacyProviderInterface | Provider;
|
|
27
25
|
export function matchAndGenerateProviders({
|
|
28
26
|
allProviders,
|
|
29
27
|
configWallets,
|
|
@@ -43,30 +41,13 @@ export function matchAndGenerateProviders({
|
|
|
43
41
|
/*
|
|
44
42
|
* There are two types of provider we get, the first one is only passing the wallet name
|
|
45
43
|
* then we will match the wallet name with our providers (@rango-dev/provider-*).
|
|
46
|
-
* The second way is passing a custom
|
|
44
|
+
* The second way is passing a custom hub `Provider` instance.
|
|
47
45
|
*/
|
|
48
46
|
if (typeof requestedWallet === 'string') {
|
|
49
|
-
const result = allProviders.find(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* a version of each provider should be picked
|
|
53
|
-
* and validated based on that version scheme.
|
|
54
|
-
* If the corresponding provider to a wallet was found in allProvider,
|
|
55
|
-
* it will be add to selected providers.
|
|
56
|
-
*/
|
|
57
|
-
const versionedProvider =
|
|
58
|
-
pickProviderVersionWithFallbackToLegacy(provider);
|
|
59
|
-
if (versionedProvider instanceof Provider) {
|
|
60
|
-
return versionedProvider.id === requestedWallet;
|
|
61
|
-
}
|
|
62
|
-
return versionedProvider.config.type === requestedWallet;
|
|
63
|
-
});
|
|
47
|
+
const result = allProviders.find(
|
|
48
|
+
(provider) => pickProviderVersion(provider).id === requestedWallet
|
|
49
|
+
);
|
|
64
50
|
|
|
65
|
-
/*
|
|
66
|
-
* A provider may have multiple versions
|
|
67
|
-
* (e.g., 0.0, also known as legacy, and 1.0, also known as hub).
|
|
68
|
-
* We should ensure that all existing versions of a provider are added to selectedProviders.
|
|
69
|
-
*/
|
|
70
51
|
if (result) {
|
|
71
52
|
selectedProviders.push(result);
|
|
72
53
|
} else {
|
|
@@ -77,15 +58,15 @@ export function matchAndGenerateProviders({
|
|
|
77
58
|
}
|
|
78
59
|
} else {
|
|
79
60
|
// It's a custom provider so we directly push it to the list.
|
|
80
|
-
if (requestedWallet instanceof Provider) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
} else {
|
|
85
|
-
selectedProviders.push(
|
|
86
|
-
defineVersions().version('0.0.0', requestedWallet).build()
|
|
61
|
+
if (!(requestedWallet instanceof Provider)) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Legacy providers aren't supported anymore. Pass a hub 'Provider' instance in 'wallets' instead.`
|
|
87
64
|
);
|
|
88
65
|
}
|
|
66
|
+
|
|
67
|
+
selectedProviders.push(
|
|
68
|
+
defineVersions().version('1.0.0', requestedWallet).build()
|
|
69
|
+
);
|
|
89
70
|
}
|
|
90
71
|
});
|
|
91
72
|
|
|
@@ -95,27 +76,12 @@ export function matchAndGenerateProviders({
|
|
|
95
76
|
return allProviders;
|
|
96
77
|
}
|
|
97
78
|
|
|
98
|
-
export function
|
|
99
|
-
provider
|
|
100
|
-
): BothProvidersInterface {
|
|
101
|
-
try {
|
|
102
|
-
return pickVersion(provider, '1.0.0')[1];
|
|
103
|
-
} catch {
|
|
104
|
-
// Fallback to legacy version, if target version doesn't exists.
|
|
105
|
-
return pickVersion(provider, '0.0.0')[1];
|
|
106
|
-
}
|
|
79
|
+
export function pickProviderVersion(provider: VersionedProviders): Provider {
|
|
80
|
+
return pickVersion(provider, '1.0.0')[1];
|
|
107
81
|
}
|
|
108
82
|
|
|
109
83
|
export function configWalletsToWalletName(
|
|
110
84
|
providers: VersionedProviders[]
|
|
111
85
|
): string[] {
|
|
112
|
-
|
|
113
|
-
.map((provider) => pickProviderVersionWithFallbackToLegacy(provider))
|
|
114
|
-
.map((provider) => {
|
|
115
|
-
if (provider instanceof Provider) {
|
|
116
|
-
return provider.id;
|
|
117
|
-
}
|
|
118
|
-
return provider.config.type;
|
|
119
|
-
});
|
|
120
|
-
return names;
|
|
86
|
+
return providers.map((provider) => pickProviderVersion(provider).id);
|
|
121
87
|
}
|
package/src/utils/swap.ts
CHANGED
|
@@ -9,8 +9,8 @@ import type {
|
|
|
9
9
|
SwapButtonState,
|
|
10
10
|
Wallet,
|
|
11
11
|
} from '../types';
|
|
12
|
+
import type { WalletType } from '@hub3js/core';
|
|
12
13
|
import type { ExtendedWalletInfo } from '@rango-dev/wallets-react';
|
|
13
|
-
import type { WalletType } from '@rango-dev/wallets-shared';
|
|
14
14
|
import type {
|
|
15
15
|
BestRouteRequest,
|
|
16
16
|
BlockchainMeta,
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
TOKEN_AMOUNT_MIN_DECIMALS,
|
|
50
50
|
} from '../constants/routing';
|
|
51
51
|
|
|
52
|
+
import { tryRefineError } from './errors';
|
|
52
53
|
import { getBlockchainShortNameFor, isValidTokenAddress } from './meta';
|
|
53
54
|
import { numberToString } from './numbers';
|
|
54
55
|
import { getRequiredBalanceOfWallet } from './quote';
|
|
@@ -737,6 +738,12 @@ export function getSwapMessages(
|
|
|
737
738
|
}
|
|
738
739
|
detailedMessage = detailedMessage || '';
|
|
739
740
|
message = message || '';
|
|
741
|
+
const refined = tryRefineError(message) ?? tryRefineError(detailedMessage);
|
|
742
|
+
if (refined) {
|
|
743
|
+
detailedMessage = [message, detailedMessage].filter(Boolean).join('\n');
|
|
744
|
+
message = refined.message;
|
|
745
|
+
}
|
|
746
|
+
|
|
740
747
|
const isRpc =
|
|
741
748
|
message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
|
|
742
749
|
|
package/src/utils/wallets.ts
CHANGED
|
@@ -5,30 +5,27 @@ import type {
|
|
|
5
5
|
Wallet,
|
|
6
6
|
WalletInfoWithExtra,
|
|
7
7
|
} from '../types';
|
|
8
|
+
import type { WalletType } from '@hub3js/core';
|
|
9
|
+
import type { Network } from '@rango-dev/internal-blockchains';
|
|
8
10
|
import type {
|
|
9
11
|
ExtendedWalletInfo,
|
|
10
12
|
ProviderContext,
|
|
11
13
|
} from '@rango-dev/wallets-react';
|
|
12
|
-
import type {
|
|
13
|
-
Network,
|
|
14
|
-
WalletType,
|
|
15
|
-
WalletTypes,
|
|
16
|
-
} from '@rango-dev/wallets-shared';
|
|
17
14
|
import type { BlockchainMeta, Token, TransactionType } from 'rango-sdk';
|
|
18
15
|
|
|
16
|
+
import {
|
|
17
|
+
getBlockChainNameFromId,
|
|
18
|
+
HYPERLIQUID_SIGN_NETWORK,
|
|
19
|
+
Networks,
|
|
20
|
+
readAccountAddress,
|
|
21
|
+
} from '@rango-dev/internal-blockchains';
|
|
19
22
|
import {
|
|
20
23
|
BlockchainCategories,
|
|
24
|
+
detectInstallLink,
|
|
21
25
|
WalletState as WalletStatus,
|
|
22
26
|
} from '@rango-dev/ui';
|
|
23
|
-
import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy';
|
|
24
|
-
import {
|
|
25
|
-
detectInstallLink,
|
|
26
|
-
HYPERLIQUID_SIGN_NETWORK,
|
|
27
|
-
getBlockChainNameFromId,
|
|
28
|
-
isEvmAddress,
|
|
29
|
-
Networks,
|
|
30
|
-
} from '@rango-dev/wallets-shared';
|
|
31
27
|
import BigNumber from 'bignumber.js';
|
|
28
|
+
import { isAddress as isEvmAddress } from 'ethers';
|
|
32
29
|
|
|
33
30
|
import { ZERO } from '../constants/numbers';
|
|
34
31
|
import {
|
|
@@ -86,7 +83,7 @@ export function mapWalletTypesToWalletInfo(
|
|
|
86
83
|
chain?: string
|
|
87
84
|
): ExtendedModalWalletInfo[] {
|
|
88
85
|
return list
|
|
89
|
-
.filter((wallet) => !EXCLUDED_WALLETS.includes(wallet
|
|
86
|
+
.filter((wallet) => !EXCLUDED_WALLETS.includes(wallet))
|
|
90
87
|
.filter((wallet) => {
|
|
91
88
|
const { supportedChains, isContractWallet } = getWalletInfo(wallet);
|
|
92
89
|
|
|
@@ -528,7 +525,7 @@ export function checkIsWalletPartiallyConnected(
|
|
|
528
525
|
wallet: ExtendedWalletInfo,
|
|
529
526
|
walletState: ReturnType<ProviderContext['state']>
|
|
530
527
|
) {
|
|
531
|
-
if (!wallet.
|
|
528
|
+
if (!wallet.needsNamespace || !walletState.connected) {
|
|
532
529
|
return false;
|
|
533
530
|
}
|
|
534
531
|
const namespaces = wallet.needsNamespace.data;
|