@dynamic-labs/midnight 4.79.1 → 4.80.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 +16 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +7 -5
- package/src/MidnightProviderHelper/MidnightProviderHelper.cjs +143 -20
- package/src/MidnightProviderHelper/MidnightProviderHelper.d.ts +18 -2
- package/src/MidnightProviderHelper/MidnightProviderHelper.js +144 -21
- package/src/MidnightWalletConnectors.cjs +13 -0
- package/src/MidnightWalletConnectors.d.ts +3 -0
- package/src/MidnightWalletConnectors.js +9 -0
- package/src/connectors/MidnightWalletConnector.cjs +117 -1
- package/src/connectors/MidnightWalletConnector.d.ts +46 -8
- package/src/connectors/MidnightWalletConnector.js +117 -1
- package/src/constants.cjs +29 -0
- package/src/constants.d.ts +17 -0
- package/src/constants.js +27 -1
- package/src/index.cjs +13 -2
- package/src/index.d.ts +4 -1
- package/src/index.js +7 -2
- package/src/injected/InjectedWalletBase/InjectedWalletBase.cjs +89 -1
- package/src/injected/InjectedWalletBase/InjectedWalletBase.d.ts +19 -1
- package/src/injected/InjectedWalletBase/InjectedWalletBase.js +89 -1
- package/src/types.d.ts +10 -0
- package/src/utils/formatMidnightNativeUnshieldedBalance/formatMidnightNativeUnshieldedBalance.cjs +32 -0
- package/src/utils/formatMidnightNativeUnshieldedBalance/formatMidnightNativeUnshieldedBalance.d.ts +5 -0
- package/src/utils/formatMidnightNativeUnshieldedBalance/formatMidnightNativeUnshieldedBalance.js +28 -0
- package/src/utils/formatMidnightNativeUnshieldedBalance/index.d.ts +1 -0
- package/src/utils/toMidnightNetworks/index.d.ts +1 -0
- package/src/utils/toMidnightNetworks/toMidnightNetworks.cjs +8 -0
- package/src/utils/toMidnightNetworks/toMidnightNetworks.d.ts +3 -0
- package/src/utils/toMidnightNetworks/toMidnightNetworks.js +4 -0
- package/src/wallet/MidnightWallet.cjs +55 -3
- package/src/wallet/MidnightWallet.d.ts +20 -2
- package/src/wallet/MidnightWallet.js +55 -3
- package/src/wallet/isMidnightWallet/index.d.ts +1 -0
- package/src/wallet/isMidnightWallet/isMidnightWallet.cjs +8 -0
- package/src/wallet/isMidnightWallet/isMidnightWallet.d.ts +3 -0
- package/src/wallet/isMidnightWallet/isMidnightWallet.js +4 -0
- package/src/injected/Midnight1am/Midnight1am.cjs +0 -16
- package/src/injected/Midnight1am/Midnight1am.d.ts +0 -5
- package/src/injected/Midnight1am/Midnight1am.js +0 -12
- package/src/injected/Midnight1am/index.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.80.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.79.2...v4.80.0) (2026-05-05)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **aleo:** Aleo wallet connectors + send/shield token registries + UI transaction type ([#11101](https://github.com/dynamic-labs/dynamic-auth/issues/11101)) ([5478d9c](https://github.com/dynamic-labs/dynamic-auth/commit/5478d9c21ee065e2e6c8e96d37ab17b74c5aa0f8))
|
|
8
|
+
* **midnight:** add address query methods and getProvider to InjectedWalletBase ([#11082](https://github.com/dynamic-labs/dynamic-auth/issues/11082)) ([9b6a870](https://github.com/dynamic-labs/dynamic-auth/commit/9b6a8709f83d04673e9dbe23bb0caae5827b036c))
|
|
9
|
+
* **ton:** recognize v3R1/v3R2/v4 wallets in TonConnect proof verification ([#11130](https://github.com/dynamic-labs/dynamic-auth/issues/11130)) ([6c40ab1](https://github.com/dynamic-labs/dynamic-auth/commit/6c40ab11e56d56e278aeb5ee2ae982a42767b5cb))
|
|
10
|
+
|
|
11
|
+
### [4.79.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.79.1...v4.79.2) (2026-05-04)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **react-native:** remove extra react-native turbo modules instructions ([#11126](https://github.com/dynamic-labs/dynamic-auth/issues/11126))
|
|
17
|
+
|
|
2
18
|
### [4.79.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.79.0...v4.79.1) (2026-05-01)
|
|
3
19
|
|
|
4
20
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/midnight",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.80.0",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,11 +18,13 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@dynamic-labs/assert-package-version": "4.
|
|
21
|
+
"@dynamic-labs/assert-package-version": "4.80.0",
|
|
22
|
+
"@dynamic-labs/sdk-api-core": "0.0.964",
|
|
22
23
|
"@midnight-ntwrk/dapp-connector-api": "4.0.1",
|
|
23
|
-
"@dynamic-labs/
|
|
24
|
-
"@dynamic-labs/
|
|
25
|
-
"@dynamic-labs/wallet-
|
|
24
|
+
"@dynamic-labs/types": "4.80.0",
|
|
25
|
+
"@dynamic-labs/utils": "4.80.0",
|
|
26
|
+
"@dynamic-labs/wallet-book": "4.80.0",
|
|
27
|
+
"@dynamic-labs/wallet-connector-core": "4.80.0"
|
|
26
28
|
},
|
|
27
29
|
"peerDependencies": {}
|
|
28
30
|
}
|
|
@@ -8,13 +8,46 @@ var utils = require('@dynamic-labs/utils');
|
|
|
8
8
|
var walletBook = require('@dynamic-labs/wallet-book');
|
|
9
9
|
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
10
10
|
var constants = require('../constants.cjs');
|
|
11
|
+
var formatMidnightNativeUnshieldedBalance = require('../utils/formatMidnightNativeUnshieldedBalance/formatMidnightNativeUnshieldedBalance.cjs');
|
|
11
12
|
|
|
13
|
+
const STORAGE_KEY_PREFIX = 'midnight.connected';
|
|
12
14
|
class MidnightProviderHelper {
|
|
13
15
|
constructor(connector) {
|
|
14
|
-
this.
|
|
16
|
+
this._autoConnectAttempted = false;
|
|
15
17
|
this.walletBookWallet = walletBook.findWalletBookWallet(connector.walletBook, connector.key);
|
|
16
18
|
this.connector = connector;
|
|
17
19
|
}
|
|
20
|
+
get storageKey() {
|
|
21
|
+
const { key } = this.connector;
|
|
22
|
+
if (!key) {
|
|
23
|
+
throw new Error('[MidnightProviderHelper] connector.key is required for session persistence');
|
|
24
|
+
}
|
|
25
|
+
return `${STORAGE_KEY_PREFIX}.${key}`;
|
|
26
|
+
}
|
|
27
|
+
persistConnection(rdns) {
|
|
28
|
+
try {
|
|
29
|
+
localStorage.setItem(this.storageKey, rdns);
|
|
30
|
+
}
|
|
31
|
+
catch (_a) {
|
|
32
|
+
// localStorage may be unavailable (SSR, private mode, quota exceeded)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
clearPersistedConnection() {
|
|
36
|
+
try {
|
|
37
|
+
localStorage.removeItem(this.storageKey);
|
|
38
|
+
}
|
|
39
|
+
catch (_a) {
|
|
40
|
+
// localStorage may be unavailable
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
hasPersistedConnection() {
|
|
44
|
+
try {
|
|
45
|
+
return localStorage.getItem(this.storageKey) !== null;
|
|
46
|
+
}
|
|
47
|
+
catch (_a) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
18
51
|
getInjectedConfig() {
|
|
19
52
|
var _a, _b;
|
|
20
53
|
return (_b = (_a = this.walletBookWallet) === null || _a === void 0 ? void 0 : _a.injectedConfig) === null || _b === void 0 ? void 0 : _b.find((c) => c.chain === constants.MIDNIGHT_CHAIN);
|
|
@@ -26,7 +59,10 @@ class MidnightProviderHelper {
|
|
|
26
59
|
return undefined;
|
|
27
60
|
for (const windowLocation of config.windowLocations) {
|
|
28
61
|
const [provider] = utils.getProvidersFromWindow(windowLocation);
|
|
29
|
-
|
|
62
|
+
// Guard against a partially-initialised provider: the wallet shell can
|
|
63
|
+
// appear in window.midnight before its internal registry is ready.
|
|
64
|
+
// rdns being present signals the provider is fully initialised.
|
|
65
|
+
if (provider === null || provider === void 0 ? void 0 : provider.rdns)
|
|
30
66
|
return provider;
|
|
31
67
|
}
|
|
32
68
|
return undefined;
|
|
@@ -36,30 +72,83 @@ class MidnightProviderHelper {
|
|
|
36
72
|
}
|
|
37
73
|
getConnectedAPI() {
|
|
38
74
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
if (this._connectedAPI)
|
|
40
|
-
|
|
75
|
+
if (this._connectedAPI) {
|
|
76
|
+
try {
|
|
77
|
+
const { status } = yield this._connectedAPI.getConnectionStatus();
|
|
78
|
+
if (status === 'connected')
|
|
79
|
+
return this._connectedAPI;
|
|
80
|
+
}
|
|
81
|
+
catch (_a) {
|
|
82
|
+
// Status check failed — treat as disconnected and reconnect below.
|
|
83
|
+
}
|
|
84
|
+
this._connectedAPI = undefined;
|
|
85
|
+
}
|
|
41
86
|
if (this._connectPromise)
|
|
42
87
|
return this._connectPromise;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
88
|
+
// Assigned synchronously so concurrent callers share the same promise.
|
|
89
|
+
// waitForProvider() polls window.midnight because extensions inject async.
|
|
90
|
+
const connectPromise = this.waitForProvider()
|
|
91
|
+
.then((initialProvider) => {
|
|
92
|
+
if (!initialProvider)
|
|
93
|
+
return undefined;
|
|
94
|
+
return initialProvider
|
|
95
|
+
.connect(this.connector.networkId)
|
|
96
|
+
.then((api) => {
|
|
97
|
+
// Only cache if this promise is still the active one.
|
|
98
|
+
// disconnect() nulls _connectPromise, so a stale resolve after
|
|
99
|
+
// disconnect won't overwrite the cleared connection state.
|
|
100
|
+
if (this._connectPromise === connectPromise) {
|
|
101
|
+
this._connectedAPI = api;
|
|
102
|
+
this.persistConnection(initialProvider.rdns);
|
|
103
|
+
}
|
|
104
|
+
return api;
|
|
105
|
+
});
|
|
54
106
|
})
|
|
55
107
|
.catch((err) => {
|
|
56
108
|
walletConnectorCore.logger.error('[MidnightProviderHelper] getConnectedAPI - Error connecting to wallet', err);
|
|
57
109
|
return undefined;
|
|
58
110
|
})
|
|
59
111
|
.finally(() => {
|
|
60
|
-
this._connectPromise
|
|
112
|
+
if (this._connectPromise === connectPromise) {
|
|
113
|
+
this._connectPromise = undefined;
|
|
114
|
+
}
|
|
61
115
|
});
|
|
62
|
-
|
|
116
|
+
this._connectPromise = connectPromise;
|
|
117
|
+
return connectPromise;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// Polls window.midnight until the provider injects (extensions inject async).
|
|
121
|
+
// Resolves undefined after timeoutMs if still not present.
|
|
122
|
+
waitForProvider(timeoutMs = 2000) {
|
|
123
|
+
const immediate = this.getInstalledProvider();
|
|
124
|
+
if (immediate)
|
|
125
|
+
return Promise.resolve(immediate);
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
const deadline = Date.now() + timeoutMs;
|
|
128
|
+
const poll = () => {
|
|
129
|
+
const provider = this.getInstalledProvider();
|
|
130
|
+
if (provider)
|
|
131
|
+
return resolve(provider);
|
|
132
|
+
if (Date.now() >= deadline)
|
|
133
|
+
return resolve(undefined);
|
|
134
|
+
setTimeout(poll, 100);
|
|
135
|
+
};
|
|
136
|
+
setTimeout(poll, 100);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// Attempts a silent reconnect using the persisted session. Only tries once per
|
|
140
|
+
// page load — PermissionRejected is tab-scoped so retrying would just fail again.
|
|
141
|
+
// Delegates to getConnectedAPI() so status checks and deduplication are shared.
|
|
142
|
+
tryAutoConnect() {
|
|
143
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
if (this._connectPromise)
|
|
145
|
+
return this._connectPromise;
|
|
146
|
+
if (this._autoConnectAttempted)
|
|
147
|
+
return undefined;
|
|
148
|
+
if (!this.hasPersistedConnection())
|
|
149
|
+
return undefined;
|
|
150
|
+
this._autoConnectAttempted = true;
|
|
151
|
+
return this.getConnectedAPI();
|
|
63
152
|
});
|
|
64
153
|
}
|
|
65
154
|
getAddress() {
|
|
@@ -71,6 +160,11 @@ class MidnightProviderHelper {
|
|
|
71
160
|
return unshieldedAddress;
|
|
72
161
|
});
|
|
73
162
|
}
|
|
163
|
+
getNetwork() {
|
|
164
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
return this.connector.networkId;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
74
168
|
getAddressIfConnected() {
|
|
75
169
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
76
170
|
if (!this._connectedAPI)
|
|
@@ -79,23 +173,52 @@ class MidnightProviderHelper {
|
|
|
79
173
|
return unshieldedAddress;
|
|
80
174
|
});
|
|
81
175
|
}
|
|
176
|
+
getUnshieldedBalance() {
|
|
177
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
const api = yield this.getConnectedAPI();
|
|
179
|
+
if (!api)
|
|
180
|
+
return undefined;
|
|
181
|
+
const response = yield api.getUnshieldedBalances();
|
|
182
|
+
const raw = response[constants.MIDNIGHT_NATIVE_TOKEN_TYPE];
|
|
183
|
+
if (raw === undefined)
|
|
184
|
+
return undefined;
|
|
185
|
+
return formatMidnightNativeUnshieldedBalance.formatMidnightNativeUnshieldedBalance(raw);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
getBalances() {
|
|
189
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
const api = yield this.getConnectedAPI();
|
|
191
|
+
if (!api) {
|
|
192
|
+
throw new Error('[MidnightProviderHelper] getBalances requires a connected Midnight wallet');
|
|
193
|
+
}
|
|
194
|
+
const [shielded, unshielded, dust] = yield Promise.all([
|
|
195
|
+
api.getShieldedBalances(),
|
|
196
|
+
api.getUnshieldedBalances(),
|
|
197
|
+
api.getDustBalance(),
|
|
198
|
+
]);
|
|
199
|
+
return { dust, shielded, unshielded };
|
|
200
|
+
});
|
|
201
|
+
}
|
|
82
202
|
signMessage(messageToSign) {
|
|
83
203
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
84
204
|
const api = yield this.getConnectedAPI();
|
|
85
205
|
if (!api)
|
|
86
206
|
return undefined;
|
|
87
|
-
|
|
207
|
+
// hintUsage pre-fetches signing permission; wallet resolves this only after
|
|
208
|
+
// the user grants it, ensuring signData succeeds immediately on first call.
|
|
209
|
+
yield api.hintUsage(['signData']);
|
|
210
|
+
const { signature, verifyingKey } = yield api.signData(messageToSign, {
|
|
88
211
|
encoding: 'text',
|
|
89
212
|
keyType: 'unshielded',
|
|
90
213
|
});
|
|
91
|
-
return signature;
|
|
214
|
+
return JSON.stringify({ signature, verifyingKey });
|
|
92
215
|
});
|
|
93
216
|
}
|
|
94
217
|
disconnect() {
|
|
95
218
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
96
|
-
this._connectionGeneration++;
|
|
97
219
|
this._connectedAPI = undefined;
|
|
98
220
|
this._connectPromise = undefined;
|
|
221
|
+
this.clearPersistedConnection();
|
|
99
222
|
});
|
|
100
223
|
}
|
|
101
224
|
// Midnight ConnectedAPI does not expose event listeners.
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import type { ConnectedAPI, InitialAPI } from '@midnight-ntwrk/dapp-connector-api';
|
|
1
|
+
import type { ConnectedAPI, InitialAPI, TokenType } from '@midnight-ntwrk/dapp-connector-api';
|
|
2
2
|
import type { InjectedWalletBase } from '../injected/InjectedWalletBase/InjectedWalletBase';
|
|
3
3
|
export declare class MidnightProviderHelper {
|
|
4
4
|
private walletBookWallet;
|
|
5
5
|
private connector;
|
|
6
6
|
private _connectedAPI;
|
|
7
7
|
private _connectPromise;
|
|
8
|
-
private
|
|
8
|
+
private _autoConnectAttempted;
|
|
9
9
|
constructor(connector: InjectedWalletBase);
|
|
10
|
+
private get storageKey();
|
|
11
|
+
private persistConnection;
|
|
12
|
+
private clearPersistedConnection;
|
|
13
|
+
hasPersistedConnection(): boolean;
|
|
10
14
|
getInjectedConfig(): {
|
|
11
15
|
chain: string;
|
|
12
16
|
extensionLocators: {
|
|
@@ -28,8 +32,20 @@ export declare class MidnightProviderHelper {
|
|
|
28
32
|
getInstalledProvider(): InitialAPI | undefined;
|
|
29
33
|
isInstalledHelper(): boolean;
|
|
30
34
|
getConnectedAPI(): Promise<ConnectedAPI | undefined>;
|
|
35
|
+
private waitForProvider;
|
|
36
|
+
tryAutoConnect(): Promise<ConnectedAPI | undefined>;
|
|
31
37
|
getAddress(): Promise<string | undefined>;
|
|
38
|
+
getNetwork(): Promise<string | undefined>;
|
|
32
39
|
getAddressIfConnected(): Promise<string | undefined>;
|
|
40
|
+
getUnshieldedBalance(): Promise<string | undefined>;
|
|
41
|
+
getBalances(): Promise<{
|
|
42
|
+
dust: {
|
|
43
|
+
balance: bigint;
|
|
44
|
+
cap: bigint;
|
|
45
|
+
};
|
|
46
|
+
shielded: Record<TokenType, bigint>;
|
|
47
|
+
unshielded: Record<TokenType, bigint>;
|
|
48
|
+
}>;
|
|
33
49
|
signMessage(messageToSign: string): Promise<string | undefined>;
|
|
34
50
|
disconnect(): Promise<void>;
|
|
35
51
|
_setupEventListeners(): void;
|
|
@@ -3,14 +3,47 @@ import { __awaiter } from '../../_virtual/_tslib.js';
|
|
|
3
3
|
import { getProvidersFromWindow } from '@dynamic-labs/utils';
|
|
4
4
|
import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
5
5
|
import { logger } from '@dynamic-labs/wallet-connector-core';
|
|
6
|
-
import { MIDNIGHT_CHAIN } from '../constants.js';
|
|
6
|
+
import { MIDNIGHT_CHAIN, MIDNIGHT_NATIVE_TOKEN_TYPE } from '../constants.js';
|
|
7
|
+
import { formatMidnightNativeUnshieldedBalance } from '../utils/formatMidnightNativeUnshieldedBalance/formatMidnightNativeUnshieldedBalance.js';
|
|
7
8
|
|
|
9
|
+
const STORAGE_KEY_PREFIX = 'midnight.connected';
|
|
8
10
|
class MidnightProviderHelper {
|
|
9
11
|
constructor(connector) {
|
|
10
|
-
this.
|
|
12
|
+
this._autoConnectAttempted = false;
|
|
11
13
|
this.walletBookWallet = findWalletBookWallet(connector.walletBook, connector.key);
|
|
12
14
|
this.connector = connector;
|
|
13
15
|
}
|
|
16
|
+
get storageKey() {
|
|
17
|
+
const { key } = this.connector;
|
|
18
|
+
if (!key) {
|
|
19
|
+
throw new Error('[MidnightProviderHelper] connector.key is required for session persistence');
|
|
20
|
+
}
|
|
21
|
+
return `${STORAGE_KEY_PREFIX}.${key}`;
|
|
22
|
+
}
|
|
23
|
+
persistConnection(rdns) {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem(this.storageKey, rdns);
|
|
26
|
+
}
|
|
27
|
+
catch (_a) {
|
|
28
|
+
// localStorage may be unavailable (SSR, private mode, quota exceeded)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
clearPersistedConnection() {
|
|
32
|
+
try {
|
|
33
|
+
localStorage.removeItem(this.storageKey);
|
|
34
|
+
}
|
|
35
|
+
catch (_a) {
|
|
36
|
+
// localStorage may be unavailable
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
hasPersistedConnection() {
|
|
40
|
+
try {
|
|
41
|
+
return localStorage.getItem(this.storageKey) !== null;
|
|
42
|
+
}
|
|
43
|
+
catch (_a) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
14
47
|
getInjectedConfig() {
|
|
15
48
|
var _a, _b;
|
|
16
49
|
return (_b = (_a = this.walletBookWallet) === null || _a === void 0 ? void 0 : _a.injectedConfig) === null || _b === void 0 ? void 0 : _b.find((c) => c.chain === MIDNIGHT_CHAIN);
|
|
@@ -22,7 +55,10 @@ class MidnightProviderHelper {
|
|
|
22
55
|
return undefined;
|
|
23
56
|
for (const windowLocation of config.windowLocations) {
|
|
24
57
|
const [provider] = getProvidersFromWindow(windowLocation);
|
|
25
|
-
|
|
58
|
+
// Guard against a partially-initialised provider: the wallet shell can
|
|
59
|
+
// appear in window.midnight before its internal registry is ready.
|
|
60
|
+
// rdns being present signals the provider is fully initialised.
|
|
61
|
+
if (provider === null || provider === void 0 ? void 0 : provider.rdns)
|
|
26
62
|
return provider;
|
|
27
63
|
}
|
|
28
64
|
return undefined;
|
|
@@ -32,30 +68,83 @@ class MidnightProviderHelper {
|
|
|
32
68
|
}
|
|
33
69
|
getConnectedAPI() {
|
|
34
70
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
if (this._connectedAPI)
|
|
36
|
-
|
|
71
|
+
if (this._connectedAPI) {
|
|
72
|
+
try {
|
|
73
|
+
const { status } = yield this._connectedAPI.getConnectionStatus();
|
|
74
|
+
if (status === 'connected')
|
|
75
|
+
return this._connectedAPI;
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
// Status check failed — treat as disconnected and reconnect below.
|
|
79
|
+
}
|
|
80
|
+
this._connectedAPI = undefined;
|
|
81
|
+
}
|
|
37
82
|
if (this._connectPromise)
|
|
38
83
|
return this._connectPromise;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
84
|
+
// Assigned synchronously so concurrent callers share the same promise.
|
|
85
|
+
// waitForProvider() polls window.midnight because extensions inject async.
|
|
86
|
+
const connectPromise = this.waitForProvider()
|
|
87
|
+
.then((initialProvider) => {
|
|
88
|
+
if (!initialProvider)
|
|
89
|
+
return undefined;
|
|
90
|
+
return initialProvider
|
|
91
|
+
.connect(this.connector.networkId)
|
|
92
|
+
.then((api) => {
|
|
93
|
+
// Only cache if this promise is still the active one.
|
|
94
|
+
// disconnect() nulls _connectPromise, so a stale resolve after
|
|
95
|
+
// disconnect won't overwrite the cleared connection state.
|
|
96
|
+
if (this._connectPromise === connectPromise) {
|
|
97
|
+
this._connectedAPI = api;
|
|
98
|
+
this.persistConnection(initialProvider.rdns);
|
|
99
|
+
}
|
|
100
|
+
return api;
|
|
101
|
+
});
|
|
50
102
|
})
|
|
51
103
|
.catch((err) => {
|
|
52
104
|
logger.error('[MidnightProviderHelper] getConnectedAPI - Error connecting to wallet', err);
|
|
53
105
|
return undefined;
|
|
54
106
|
})
|
|
55
107
|
.finally(() => {
|
|
56
|
-
this._connectPromise
|
|
108
|
+
if (this._connectPromise === connectPromise) {
|
|
109
|
+
this._connectPromise = undefined;
|
|
110
|
+
}
|
|
57
111
|
});
|
|
58
|
-
|
|
112
|
+
this._connectPromise = connectPromise;
|
|
113
|
+
return connectPromise;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
// Polls window.midnight until the provider injects (extensions inject async).
|
|
117
|
+
// Resolves undefined after timeoutMs if still not present.
|
|
118
|
+
waitForProvider(timeoutMs = 2000) {
|
|
119
|
+
const immediate = this.getInstalledProvider();
|
|
120
|
+
if (immediate)
|
|
121
|
+
return Promise.resolve(immediate);
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
const deadline = Date.now() + timeoutMs;
|
|
124
|
+
const poll = () => {
|
|
125
|
+
const provider = this.getInstalledProvider();
|
|
126
|
+
if (provider)
|
|
127
|
+
return resolve(provider);
|
|
128
|
+
if (Date.now() >= deadline)
|
|
129
|
+
return resolve(undefined);
|
|
130
|
+
setTimeout(poll, 100);
|
|
131
|
+
};
|
|
132
|
+
setTimeout(poll, 100);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Attempts a silent reconnect using the persisted session. Only tries once per
|
|
136
|
+
// page load — PermissionRejected is tab-scoped so retrying would just fail again.
|
|
137
|
+
// Delegates to getConnectedAPI() so status checks and deduplication are shared.
|
|
138
|
+
tryAutoConnect() {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
if (this._connectPromise)
|
|
141
|
+
return this._connectPromise;
|
|
142
|
+
if (this._autoConnectAttempted)
|
|
143
|
+
return undefined;
|
|
144
|
+
if (!this.hasPersistedConnection())
|
|
145
|
+
return undefined;
|
|
146
|
+
this._autoConnectAttempted = true;
|
|
147
|
+
return this.getConnectedAPI();
|
|
59
148
|
});
|
|
60
149
|
}
|
|
61
150
|
getAddress() {
|
|
@@ -67,6 +156,11 @@ class MidnightProviderHelper {
|
|
|
67
156
|
return unshieldedAddress;
|
|
68
157
|
});
|
|
69
158
|
}
|
|
159
|
+
getNetwork() {
|
|
160
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
return this.connector.networkId;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
70
164
|
getAddressIfConnected() {
|
|
71
165
|
return __awaiter(this, void 0, void 0, function* () {
|
|
72
166
|
if (!this._connectedAPI)
|
|
@@ -75,23 +169,52 @@ class MidnightProviderHelper {
|
|
|
75
169
|
return unshieldedAddress;
|
|
76
170
|
});
|
|
77
171
|
}
|
|
172
|
+
getUnshieldedBalance() {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
const api = yield this.getConnectedAPI();
|
|
175
|
+
if (!api)
|
|
176
|
+
return undefined;
|
|
177
|
+
const response = yield api.getUnshieldedBalances();
|
|
178
|
+
const raw = response[MIDNIGHT_NATIVE_TOKEN_TYPE];
|
|
179
|
+
if (raw === undefined)
|
|
180
|
+
return undefined;
|
|
181
|
+
return formatMidnightNativeUnshieldedBalance(raw);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
getBalances() {
|
|
185
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
+
const api = yield this.getConnectedAPI();
|
|
187
|
+
if (!api) {
|
|
188
|
+
throw new Error('[MidnightProviderHelper] getBalances requires a connected Midnight wallet');
|
|
189
|
+
}
|
|
190
|
+
const [shielded, unshielded, dust] = yield Promise.all([
|
|
191
|
+
api.getShieldedBalances(),
|
|
192
|
+
api.getUnshieldedBalances(),
|
|
193
|
+
api.getDustBalance(),
|
|
194
|
+
]);
|
|
195
|
+
return { dust, shielded, unshielded };
|
|
196
|
+
});
|
|
197
|
+
}
|
|
78
198
|
signMessage(messageToSign) {
|
|
79
199
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
200
|
const api = yield this.getConnectedAPI();
|
|
81
201
|
if (!api)
|
|
82
202
|
return undefined;
|
|
83
|
-
|
|
203
|
+
// hintUsage pre-fetches signing permission; wallet resolves this only after
|
|
204
|
+
// the user grants it, ensuring signData succeeds immediately on first call.
|
|
205
|
+
yield api.hintUsage(['signData']);
|
|
206
|
+
const { signature, verifyingKey } = yield api.signData(messageToSign, {
|
|
84
207
|
encoding: 'text',
|
|
85
208
|
keyType: 'unshielded',
|
|
86
209
|
});
|
|
87
|
-
return signature;
|
|
210
|
+
return JSON.stringify({ signature, verifyingKey });
|
|
88
211
|
});
|
|
89
212
|
}
|
|
90
213
|
disconnect() {
|
|
91
214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
this._connectionGeneration++;
|
|
93
215
|
this._connectedAPI = undefined;
|
|
94
216
|
this._connectPromise = undefined;
|
|
217
|
+
this.clearPersistedConnection();
|
|
95
218
|
});
|
|
96
219
|
}
|
|
97
220
|
// Midnight ConnectedAPI does not expose event listeners.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var fetchInjectedWalletConnectors = require('./injected/fetchInjectedWalletConnectors/fetchInjectedWalletConnectors.cjs');
|
|
7
|
+
|
|
8
|
+
const MidnightWalletConnectors = (props) => [
|
|
9
|
+
...fetchInjectedWalletConnectors.injectedWalletOverrides,
|
|
10
|
+
...fetchInjectedWalletConnectors.fetchInjectedWalletConnectors(Object.assign(Object.assign({}, props), { walletsWithCustomConnectors: [] })),
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
exports.MidnightWalletConnectors = MidnightWalletConnectors;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { injectedWalletOverrides, fetchInjectedWalletConnectors } from './injected/fetchInjectedWalletConnectors/fetchInjectedWalletConnectors.js';
|
|
3
|
+
|
|
4
|
+
const MidnightWalletConnectors = (props) => [
|
|
5
|
+
...injectedWalletOverrides,
|
|
6
|
+
...fetchInjectedWalletConnectors(Object.assign(Object.assign({}, props), { walletsWithCustomConnectors: [] })),
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export { MidnightWalletConnectors };
|