@dynamic-labs/stellar 4.59.1 → 4.59.2
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 +13 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +8 -4
- package/src/StellarLocalStorageCache.cjs +65 -0
- package/src/StellarLocalStorageCache.d.ts +29 -0
- package/src/StellarLocalStorageCache.js +61 -0
- package/src/connectors/StellarWalletConnector/StellarWalletConnector.cjs +351 -0
- package/src/connectors/StellarWalletConnector/StellarWalletConnector.d.ts +102 -0
- package/src/connectors/StellarWalletConnector/StellarWalletConnector.js +347 -0
- package/src/connectors/StellarWalletConnector/index.d.ts +1 -0
- package/src/index.cjs +9 -1
- package/src/index.d.ts +5 -2
- package/src/index.js +6 -1
- package/src/injected/fetchInjectedWalletConnectors.cjs +50 -0
- package/src/injected/fetchInjectedWalletConnectors.d.ts +16 -0
- package/src/injected/fetchInjectedWalletConnectors.js +46 -0
- package/src/types/FreighterProvider.d.ts +82 -0
- package/src/types/LobstrProvider.d.ts +33 -0
- package/src/types.d.ts +6 -14
- package/src/wallet/StellarWallet.d.ts +3 -13
- package/src/wallet/index.d.ts +1 -0
- package/src/wallet/isStellarWallet/index.d.ts +1 -0
- package/src/wallet/isStellarWallet/isStellarWallet.cjs +8 -0
- package/src/wallet/isStellarWallet/isStellarWallet.js +4 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { Horizon } from '@stellar/stellar-sdk';
|
|
4
|
+
import { Logger } from '@dynamic-labs/logger';
|
|
5
|
+
import { DynamicError } from '@dynamic-labs/utils';
|
|
6
|
+
import { WalletConnectorBase } from '@dynamic-labs/wallet-connector-core';
|
|
7
|
+
import { StellarWallet } from '../../wallet/StellarWallet.js';
|
|
8
|
+
import { getNetworkFromAddress } from '../../utils/getNetworkFromAddress.js';
|
|
9
|
+
import { StellarLocalStorageCache } from '../../StellarLocalStorageCache.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Abstract base class for all Stellar wallet connectors.
|
|
13
|
+
*
|
|
14
|
+
* This class provides the common functionality needed by all
|
|
15
|
+
* Stellar wallet implementations. It handles connection management,
|
|
16
|
+
* network operations, and transaction signing.
|
|
17
|
+
*/
|
|
18
|
+
class StellarWalletConnector extends WalletConnectorBase {
|
|
19
|
+
constructor(name, opts) {
|
|
20
|
+
var _a;
|
|
21
|
+
super({
|
|
22
|
+
metadata: opts.metadata,
|
|
23
|
+
walletBook: opts.walletBook,
|
|
24
|
+
});
|
|
25
|
+
this.name = 'Stellar';
|
|
26
|
+
this.ChainWallet = StellarWallet;
|
|
27
|
+
this.connectedChain = 'STELLAR';
|
|
28
|
+
this.supportedChains = ['STELLAR'];
|
|
29
|
+
/** Connection state */
|
|
30
|
+
this.isConnecting = false;
|
|
31
|
+
/** Flag to track if connection was cancelled by disconnect */
|
|
32
|
+
this.connectionCancelled = false;
|
|
33
|
+
this.name = name;
|
|
34
|
+
this.logger = new Logger(this.name);
|
|
35
|
+
this.stellarNetworks = (_a = opts.stellarNetworks) !== null && _a !== void 0 ? _a : [];
|
|
36
|
+
this.overrideKey = this.key;
|
|
37
|
+
this.cache = new StellarLocalStorageCache(this.overrideKey);
|
|
38
|
+
}
|
|
39
|
+
getEnabledNetworks() {
|
|
40
|
+
return this.stellarNetworks;
|
|
41
|
+
}
|
|
42
|
+
getSelectedNetwork() {
|
|
43
|
+
var _a;
|
|
44
|
+
return (_a = this.stellarNetworks) === null || _a === void 0 ? void 0 : _a[0];
|
|
45
|
+
}
|
|
46
|
+
getNetwork() {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const address = yield this.getAddress();
|
|
49
|
+
if (!address) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
if (!this.stellarNetworks.length) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const network = yield getNetworkFromAddress(address, this.stellarNetworks[0]);
|
|
56
|
+
if (!network) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
this.selectedNetwork = this.stellarNetworks.find((n) => n.chainId.toString() === network);
|
|
60
|
+
return network;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Checks if the provider is already connected.
|
|
65
|
+
*/
|
|
66
|
+
isProviderConnected() {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
const provider = this.getProvider();
|
|
69
|
+
if (!provider) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// Check if provider has an isConnected property (not part of IStellarProvider but some wallets have it)
|
|
73
|
+
const providerWithConnection = provider;
|
|
74
|
+
if (typeof providerWithConnection.isConnected === 'boolean') {
|
|
75
|
+
return providerWithConnection.isConnected;
|
|
76
|
+
}
|
|
77
|
+
// Some providers have isConnected as a method
|
|
78
|
+
if (typeof providerWithConnection.isConnected === 'function') {
|
|
79
|
+
return providerWithConnection.isConnected();
|
|
80
|
+
}
|
|
81
|
+
// If we have a cached public key, assume connected
|
|
82
|
+
return Boolean(this.connectedPublicKey);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Connects to the Stellar wallet.
|
|
87
|
+
*/
|
|
88
|
+
connect() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
// Avoid unnecessary connection attempts
|
|
91
|
+
if (this.isConnecting) {
|
|
92
|
+
this.logger.debug('[connect] Connection already in progress');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Check if already connected
|
|
96
|
+
if (yield this.isProviderConnected()) {
|
|
97
|
+
this.logger.debug('[connect] Provider already connected');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this.isConnecting = true;
|
|
101
|
+
this.connectionCancelled = false;
|
|
102
|
+
this.logger.debug('[connect] Attempting to connect');
|
|
103
|
+
try {
|
|
104
|
+
const provider = this.getProvider();
|
|
105
|
+
if (!provider) {
|
|
106
|
+
throw new DynamicError('No Stellar provider found');
|
|
107
|
+
}
|
|
108
|
+
const publicKey = yield provider.connect();
|
|
109
|
+
// Check if disconnect was called while we were waiting for provider.connect()
|
|
110
|
+
// This prevents a race condition where disconnect() clears state but connect()
|
|
111
|
+
// subsequently sets connectedPublicKey
|
|
112
|
+
if (this.connectionCancelled) {
|
|
113
|
+
this.logger.debug('[connect] Connection cancelled by disconnect');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.connectedPublicKey = publicKey;
|
|
117
|
+
this.logger.debug('[connect] Connected successfully');
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
this.logger.error('[connect] Connection failed:', error);
|
|
121
|
+
throw new DynamicError('Failed to connect to Stellar wallet');
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
this.isConnecting = false;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Disconnects from the wallet.
|
|
130
|
+
*/
|
|
131
|
+
disconnect() {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
this.logger.debug('[disconnect] Disconnecting');
|
|
134
|
+
// Cancel any ongoing connection attempt to prevent race condition
|
|
135
|
+
// where connect() might set connectedPublicKey after we clear it
|
|
136
|
+
if (this.isConnecting) {
|
|
137
|
+
this.logger.debug('[disconnect] Cancelling ongoing connection attempt');
|
|
138
|
+
this.connectionCancelled = true;
|
|
139
|
+
this.isConnecting = false;
|
|
140
|
+
}
|
|
141
|
+
const provider = this.getProvider();
|
|
142
|
+
if (!provider) {
|
|
143
|
+
// Still clear state even if no provider
|
|
144
|
+
this.connectedPublicKey = undefined;
|
|
145
|
+
this.getAddressPromise = undefined;
|
|
146
|
+
yield this.cache.clearConnectedAcccounts();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
yield provider.disconnect();
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
this.logger.debug('[disconnect] Disconnect not supported or failed:', error);
|
|
154
|
+
}
|
|
155
|
+
// Clear all cached state
|
|
156
|
+
this.connectedPublicKey = undefined;
|
|
157
|
+
this.getAddressPromise = undefined;
|
|
158
|
+
yield this.cache.clearConnectedAcccounts();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Signs a Stellar transaction XDR.
|
|
163
|
+
*/
|
|
164
|
+
signTransaction(transactionXdr) {
|
|
165
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
166
|
+
const provider = this.getProvider();
|
|
167
|
+
if (!provider) {
|
|
168
|
+
throw new DynamicError('No Stellar provider found');
|
|
169
|
+
}
|
|
170
|
+
return provider.sign(transactionXdr);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Signs a message.
|
|
175
|
+
*/
|
|
176
|
+
signMessage(messageToSign) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
const provider = this.getProvider();
|
|
179
|
+
if (!provider) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
return provider.signMessage(messageToSign);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
getHorizonServer() {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
var _a, _b;
|
|
188
|
+
return new Horizon.Server((_b = (_a = this.selectedNetwork) === null || _a === void 0 ? void 0 : _a.rpcUrls[0]) !== null && _b !== void 0 ? _b : '');
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
isTestnet() {
|
|
192
|
+
var _a, _b;
|
|
193
|
+
const network = this.getSelectedNetwork();
|
|
194
|
+
if (!network) {
|
|
195
|
+
return Promise.resolve(false);
|
|
196
|
+
}
|
|
197
|
+
return Promise.resolve((_b = (_a = network.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('testnet')) !== null && _b !== void 0 ? _b : false);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Gets the connected public key.
|
|
201
|
+
*/
|
|
202
|
+
getConnectedPublicKey() {
|
|
203
|
+
return this.connectedPublicKey;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Fetches the public address from the wallet provider.
|
|
207
|
+
* This method ensures the wallet is connected before fetching the address.
|
|
208
|
+
* Override this method in child classes if the wallet has a custom way to fetch addresses.
|
|
209
|
+
* @returns The public address from the wallet
|
|
210
|
+
*/
|
|
211
|
+
fetchPublicAddress() {
|
|
212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
var _a;
|
|
214
|
+
const provider = this.getProvider();
|
|
215
|
+
if (!provider) {
|
|
216
|
+
return '';
|
|
217
|
+
}
|
|
218
|
+
// Ensure provider is connected
|
|
219
|
+
yield this.connect();
|
|
220
|
+
// After connection, try to get the public key from the provider
|
|
221
|
+
// Different wallets may store it in different ways (not part of IStellarProvider but some wallets have these)
|
|
222
|
+
const providerWithExtras = provider;
|
|
223
|
+
if (providerWithExtras.publicKey) {
|
|
224
|
+
return providerWithExtras.publicKey;
|
|
225
|
+
}
|
|
226
|
+
// Some wallets require calling getPublicKey()
|
|
227
|
+
if (typeof providerWithExtras.getPublicKey === 'function') {
|
|
228
|
+
return providerWithExtras.getPublicKey();
|
|
229
|
+
}
|
|
230
|
+
// If we still don't have it, the connectedPublicKey should have been set by connect()
|
|
231
|
+
return (_a = this.connectedPublicKey) !== null && _a !== void 0 ? _a : '';
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Gets the address from cache or fetches it from the wallet.
|
|
236
|
+
* This implementation avoids prompting the user unnecessarily by checking cache first.
|
|
237
|
+
* Uses promise caching to prevent multiple simultaneous calls.
|
|
238
|
+
*/
|
|
239
|
+
getAddress() {
|
|
240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
241
|
+
// If there's already a pending getAddress call, return the same promise
|
|
242
|
+
// This prevents multiple simultaneous wallet prompts
|
|
243
|
+
if (this.getAddressPromise) {
|
|
244
|
+
try {
|
|
245
|
+
return yield this.getAddressPromise;
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
this.logger.error('[getAddress] Error fetching address from promise cache:', error);
|
|
249
|
+
this.getAddressPromise = undefined;
|
|
250
|
+
// Fall through to try again
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Return cached public key if already connected
|
|
254
|
+
if (this.connectedPublicKey) {
|
|
255
|
+
return this.connectedPublicKey;
|
|
256
|
+
}
|
|
257
|
+
// Create a new promise and cache it
|
|
258
|
+
this.getAddressPromise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
try {
|
|
260
|
+
// Check cache first to avoid prompting the user
|
|
261
|
+
const cachedAccount = yield this.cache.getActiveAccount();
|
|
262
|
+
if (cachedAccount === null || cachedAccount === void 0 ? void 0 : cachedAccount.address) {
|
|
263
|
+
this.connectedPublicKey = cachedAccount.address;
|
|
264
|
+
return cachedAccount.address;
|
|
265
|
+
}
|
|
266
|
+
// Fetch from wallet provider
|
|
267
|
+
const address = yield this.fetchPublicAddress();
|
|
268
|
+
this.connectedPublicKey = address;
|
|
269
|
+
// Cache the address
|
|
270
|
+
if (address) {
|
|
271
|
+
yield this.cache.setConnectedAccount(address, {
|
|
272
|
+
active: true,
|
|
273
|
+
additionalAddresses: [],
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return address !== null && address !== void 0 ? address : '';
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
// Clear the promise cache after completion
|
|
280
|
+
this.getAddressPromise = undefined;
|
|
281
|
+
}
|
|
282
|
+
}))();
|
|
283
|
+
return this.getAddressPromise;
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Clears all connected accounts from cache.
|
|
288
|
+
*/
|
|
289
|
+
clearConnectedAccounts() {
|
|
290
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
291
|
+
yield this.cache.clearConnectedAcccounts();
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Gets connected accounts from cache.
|
|
296
|
+
*/
|
|
297
|
+
getConnectedAccountsFromCache() {
|
|
298
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
299
|
+
var _a;
|
|
300
|
+
const currentAccount = yield this.cache.getActiveAccount();
|
|
301
|
+
const allAccounts = yield this.cache.getConnectedAccounts();
|
|
302
|
+
const allConnectedAddresses = (_a = Object.keys(allAccounts || {})) !== null && _a !== void 0 ? _a : [];
|
|
303
|
+
if (!(currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.address)) {
|
|
304
|
+
return allConnectedAddresses;
|
|
305
|
+
}
|
|
306
|
+
return [
|
|
307
|
+
currentAccount.address,
|
|
308
|
+
...allConnectedAddresses.filter((address) => address !== currentAccount.address),
|
|
309
|
+
];
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Gets additional addresses for a main address.
|
|
314
|
+
*/
|
|
315
|
+
getAdditionalAddresses(mainAddress) {
|
|
316
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
317
|
+
if (!mainAddress) {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
const currentAccount = yield this.cache.getConnectedAccount(mainAddress);
|
|
321
|
+
return (currentAccount === null || currentAccount === void 0 ? void 0 : currentAccount.additionalAddresses) || [];
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Sets additional addresses for a main address.
|
|
326
|
+
*/
|
|
327
|
+
setAdditionalAddresses(mainAddress, additionalAddresses) {
|
|
328
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
return this.cache.setConnectedAccount(mainAddress, {
|
|
330
|
+
additionalAddresses,
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Ends the session and clears connected accounts.
|
|
336
|
+
*/
|
|
337
|
+
endSession() {
|
|
338
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
339
|
+
this.connectedPublicKey = undefined;
|
|
340
|
+
this.getAddressPromise = undefined;
|
|
341
|
+
this.connectionCancelled = false;
|
|
342
|
+
yield this.cache.clearConnectedAcccounts();
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export { StellarWalletConnector };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StellarWalletConnector } from './StellarWalletConnector';
|
package/src/index.cjs
CHANGED
|
@@ -5,16 +5,24 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
|
|
6
6
|
var assertPackageVersion = require('@dynamic-labs/assert-package-version');
|
|
7
7
|
var _package = require('../package.cjs');
|
|
8
|
+
var fetchInjectedWalletConnectors = require('./injected/fetchInjectedWalletConnectors.cjs');
|
|
8
9
|
var StellarWallet = require('./wallet/StellarWallet.cjs');
|
|
10
|
+
var isStellarWallet = require('./wallet/isStellarWallet/isStellarWallet.cjs');
|
|
11
|
+
var StellarWalletConnector = require('./connectors/StellarWalletConnector/StellarWalletConnector.cjs');
|
|
12
|
+
var StellarLocalStorageCache = require('./StellarLocalStorageCache.cjs');
|
|
9
13
|
var getNetworkFromAddress = require('./utils/getNetworkFromAddress.cjs');
|
|
10
14
|
|
|
11
15
|
assertPackageVersion.assertPackageVersion('@dynamic-labs/stellar', _package.version);
|
|
12
16
|
// Wallet connector factory (to be implemented by specific wallet connectors)
|
|
13
17
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
18
|
const StellarWalletConnectors = (_props) => [
|
|
15
|
-
|
|
19
|
+
...fetchInjectedWalletConnectors.fetchInjectedWalletConnectors(),
|
|
20
|
+
// Specific wallet connectors will be added here by implementers
|
|
16
21
|
];
|
|
17
22
|
|
|
18
23
|
exports.StellarWallet = StellarWallet.StellarWallet;
|
|
24
|
+
exports.isStellarWallet = isStellarWallet.isStellarWallet;
|
|
25
|
+
exports.StellarWalletConnector = StellarWalletConnector.StellarWalletConnector;
|
|
26
|
+
exports.StellarLocalStorageCache = StellarLocalStorageCache.StellarLocalStorageCache;
|
|
19
27
|
exports.getNetworkFromAddress = getNetworkFromAddress.getNetworkFromAddress;
|
|
20
28
|
exports.StellarWalletConnectors = StellarWalletConnectors;
|
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
export { StellarWallet } from './wallet';
|
|
1
|
+
export { StellarWallet, isStellarWallet } from './wallet';
|
|
2
|
+
export { StellarWalletConnector } from './connectors/StellarWalletConnector';
|
|
3
|
+
export { StellarLocalStorageCache, type IStellarSessionCache, type StellarConnectedAccount, } from './StellarLocalStorageCache';
|
|
4
|
+
export type { IStellarProvider, StellarConnectionResult, StellarEventCallback, StellarMethodName, StellarNetworkName, StellarProviderEvent, StellarSendBalanceProps, StellarSignTransactionOptions, StellarWalletConnectorProps, } from './types';
|
|
2
5
|
export { getNetworkFromAddress } from './utils';
|
|
3
|
-
export declare const StellarWalletConnectors: (_props?: unknown) =>
|
|
6
|
+
export declare const StellarWalletConnectors: (_props?: unknown) => import("dist/packages/wallet-connector-core/src").WalletConnectorConstructor[];
|
package/src/index.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { assertPackageVersion } from '@dynamic-labs/assert-package-version';
|
|
3
3
|
import { version } from '../package.js';
|
|
4
|
+
import { fetchInjectedWalletConnectors } from './injected/fetchInjectedWalletConnectors.js';
|
|
4
5
|
export { StellarWallet } from './wallet/StellarWallet.js';
|
|
6
|
+
export { isStellarWallet } from './wallet/isStellarWallet/isStellarWallet.js';
|
|
7
|
+
export { StellarWalletConnector } from './connectors/StellarWalletConnector/StellarWalletConnector.js';
|
|
8
|
+
export { StellarLocalStorageCache } from './StellarLocalStorageCache.js';
|
|
5
9
|
export { getNetworkFromAddress } from './utils/getNetworkFromAddress.js';
|
|
6
10
|
|
|
7
11
|
assertPackageVersion('@dynamic-labs/stellar', version);
|
|
8
12
|
// Wallet connector factory (to be implemented by specific wallet connectors)
|
|
9
13
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
14
|
const StellarWalletConnectors = (_props) => [
|
|
11
|
-
|
|
15
|
+
...fetchInjectedWalletConnectors(),
|
|
16
|
+
// Specific wallet connectors will be added here by implementers
|
|
12
17
|
];
|
|
13
18
|
|
|
14
19
|
export { StellarWalletConnectors };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
7
|
+
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
8
|
+
var logger$1 = require('@dynamic-labs/logger');
|
|
9
|
+
|
|
10
|
+
const logger = new logger$1.Logger('fetchInjectedWalletConnectors');
|
|
11
|
+
const stellarWalletConnectors = [];
|
|
12
|
+
const checkAndEmitWalletConnector = (walletConnector) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
var _a;
|
|
14
|
+
try {
|
|
15
|
+
yield ((_a = walletConnector.isConnected) === null || _a === void 0 ? void 0 : _a.call(walletConnector));
|
|
16
|
+
return walletConnector;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
logger.logVerboseTroubleshootingMessage(`[STELLAR fetchInjectedWalletConnectors] Error checking ${walletConnector.name}:`, error);
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
});
|
|
23
|
+
const setupStellarWalletListener = () => {
|
|
24
|
+
if (typeof window === 'undefined') {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const discoveredWallets = new Set();
|
|
28
|
+
const checkForNewWallets = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
for (const walletConnector of stellarWalletConnectors) {
|
|
30
|
+
if (discoveredWallets.has(walletConnector.name)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const connector = yield checkAndEmitWalletConnector(walletConnector);
|
|
34
|
+
if (connector) {
|
|
35
|
+
discoveredWallets.add(walletConnector.name);
|
|
36
|
+
logger.logVerboseTroubleshootingMessage(`[STELLAR fetchInjectedWalletConnectors] Emitting providerInjected for ${walletConnector.name}`);
|
|
37
|
+
walletConnectorCore.walletConnectorEvents.emit('providerInjected', {
|
|
38
|
+
injectedConnectorConstructor: connector,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
void checkForNewWallets();
|
|
44
|
+
};
|
|
45
|
+
const fetchInjectedWalletConnectors = () => {
|
|
46
|
+
setupStellarWalletListener();
|
|
47
|
+
return [...stellarWalletConnectors];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
exports.fetchInjectedWalletConnectors = fetchInjectedWalletConnectors;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
|
|
2
|
+
interface StellarWalletConnectorWithIsConnected extends WalletConnectorConstructor {
|
|
3
|
+
isConnected?: () => Promise<boolean>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Registers a Stellar wallet connector for injection discovery.
|
|
7
|
+
* @internal - Used for testing and internal registration
|
|
8
|
+
*/
|
|
9
|
+
export declare const registerStellarWalletConnector: (connector: StellarWalletConnectorWithIsConnected) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Clears all registered Stellar wallet connectors.
|
|
12
|
+
* @internal - Used for testing cleanup
|
|
13
|
+
*/
|
|
14
|
+
export declare const clearStellarWalletConnectors: () => void;
|
|
15
|
+
export declare const fetchInjectedWalletConnectors: () => WalletConnectorConstructor[];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
3
|
+
import { walletConnectorEvents } from '@dynamic-labs/wallet-connector-core';
|
|
4
|
+
import { Logger } from '@dynamic-labs/logger';
|
|
5
|
+
|
|
6
|
+
const logger = new Logger('fetchInjectedWalletConnectors');
|
|
7
|
+
const stellarWalletConnectors = [];
|
|
8
|
+
const checkAndEmitWalletConnector = (walletConnector) => __awaiter(void 0, void 0, void 0, function* () {
|
|
9
|
+
var _a;
|
|
10
|
+
try {
|
|
11
|
+
yield ((_a = walletConnector.isConnected) === null || _a === void 0 ? void 0 : _a.call(walletConnector));
|
|
12
|
+
return walletConnector;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
logger.logVerboseTroubleshootingMessage(`[STELLAR fetchInjectedWalletConnectors] Error checking ${walletConnector.name}:`, error);
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
});
|
|
19
|
+
const setupStellarWalletListener = () => {
|
|
20
|
+
if (typeof window === 'undefined') {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const discoveredWallets = new Set();
|
|
24
|
+
const checkForNewWallets = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
for (const walletConnector of stellarWalletConnectors) {
|
|
26
|
+
if (discoveredWallets.has(walletConnector.name)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const connector = yield checkAndEmitWalletConnector(walletConnector);
|
|
30
|
+
if (connector) {
|
|
31
|
+
discoveredWallets.add(walletConnector.name);
|
|
32
|
+
logger.logVerboseTroubleshootingMessage(`[STELLAR fetchInjectedWalletConnectors] Emitting providerInjected for ${walletConnector.name}`);
|
|
33
|
+
walletConnectorEvents.emit('providerInjected', {
|
|
34
|
+
injectedConnectorConstructor: connector,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
void checkForNewWallets();
|
|
40
|
+
};
|
|
41
|
+
const fetchInjectedWalletConnectors = () => {
|
|
42
|
+
setupStellarWalletListener();
|
|
43
|
+
return [...stellarWalletConnectors];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { fetchInjectedWalletConnectors };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Freighter Wallet Provider Types
|
|
3
|
+
*
|
|
4
|
+
* Types for the Freighter wallet API
|
|
5
|
+
* From @stellar/freighter-api package
|
|
6
|
+
*/
|
|
7
|
+
/// <reference types="node" />
|
|
8
|
+
/**
|
|
9
|
+
* Freighter API error type
|
|
10
|
+
*/
|
|
11
|
+
export type FreighterApiError = {
|
|
12
|
+
code: number;
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Freighter API response wrapper
|
|
17
|
+
* All Freighter API methods return responses in this format
|
|
18
|
+
*/
|
|
19
|
+
export type FreighterApiResponse<T> = T & {
|
|
20
|
+
error?: FreighterApiError;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Freighter API methods
|
|
24
|
+
* These are the raw methods provided by @stellar/freighter-api package
|
|
25
|
+
*
|
|
26
|
+
* Note: Freighter uses a functional API (individual exported functions)
|
|
27
|
+
* rather than a provider object at window.freighter
|
|
28
|
+
*/
|
|
29
|
+
export type FreighterApi = {
|
|
30
|
+
/** Get the user's address */
|
|
31
|
+
getAddress: () => Promise<FreighterApiResponse<{
|
|
32
|
+
address: string;
|
|
33
|
+
}>>;
|
|
34
|
+
/** Get current network */
|
|
35
|
+
getNetwork: () => Promise<string>;
|
|
36
|
+
/** Check if extension is installed and accessible */
|
|
37
|
+
isConnected: () => Promise<boolean>;
|
|
38
|
+
/** Check if user has granted access */
|
|
39
|
+
isAllowed: () => Promise<boolean>;
|
|
40
|
+
/** Request access to the wallet */
|
|
41
|
+
requestAccess: () => Promise<FreighterApiResponse<{
|
|
42
|
+
address: string;
|
|
43
|
+
}>>;
|
|
44
|
+
/** Sign a transaction */
|
|
45
|
+
signTransaction: (transactionXdr: string, opts?: {
|
|
46
|
+
networkPassphrase?: string;
|
|
47
|
+
address?: string;
|
|
48
|
+
}) => Promise<FreighterApiResponse<{
|
|
49
|
+
signedTxXdr: string;
|
|
50
|
+
signerAddress: string;
|
|
51
|
+
}>>;
|
|
52
|
+
/** Sign a message */
|
|
53
|
+
signMessage: (message: string, opts?: {
|
|
54
|
+
networkPassphrase?: string;
|
|
55
|
+
address?: string;
|
|
56
|
+
}) => Promise<FreighterApiResponse<{
|
|
57
|
+
signedMessage: string | Buffer | null;
|
|
58
|
+
signerAddress: string;
|
|
59
|
+
}>>;
|
|
60
|
+
/** Sign an auth entry */
|
|
61
|
+
signAuthEntry: (entry: string, opts?: {
|
|
62
|
+
networkPassphrase?: string;
|
|
63
|
+
address?: string;
|
|
64
|
+
}) => Promise<FreighterApiResponse<{
|
|
65
|
+
signedAuthEntry: string;
|
|
66
|
+
signerAddress: string;
|
|
67
|
+
}>>;
|
|
68
|
+
/** Set allowed status (internal use) */
|
|
69
|
+
setAllowed: () => Promise<void>;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Type guard to check if a Freighter API response has an error
|
|
73
|
+
*/
|
|
74
|
+
export declare const isFreighterError: <T>(response: FreighterApiResponse<T>) => response is T & {
|
|
75
|
+
error?: FreighterApiError | undefined;
|
|
76
|
+
} & {
|
|
77
|
+
error: FreighterApiError;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Handle Freighter API response and throw if there's an error
|
|
81
|
+
*/
|
|
82
|
+
export declare const handleFreighterResponse: <T>(response: FreighterApiResponse<T>) => T;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lobstr Signer Extension Provider Types
|
|
3
|
+
*
|
|
4
|
+
* Types for the Lobstr Signer Extension API
|
|
5
|
+
* From @lobstrco/signer-extension-api package
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Lobstr Signer Extension API
|
|
9
|
+
* These are the raw methods provided by @lobstrco/signer-extension-api package
|
|
10
|
+
*
|
|
11
|
+
* Note: Lobstr uses a functional API (individual exported functions)
|
|
12
|
+
* rather than a provider object at window.lobstr
|
|
13
|
+
*/
|
|
14
|
+
export type LobstrSignerApi = {
|
|
15
|
+
/** Get the user's public key */
|
|
16
|
+
getPublicKey: () => Promise<string>;
|
|
17
|
+
/** Sign a transaction */
|
|
18
|
+
signTransaction: (transactionXdr: string) => Promise<string>;
|
|
19
|
+
/** Check if extension is installed and accessible */
|
|
20
|
+
isConnected: () => Promise<boolean>;
|
|
21
|
+
/** Sign a message */
|
|
22
|
+
signMessage: (message: string) => Promise<{
|
|
23
|
+
signedMessage: string;
|
|
24
|
+
signerAddress: string;
|
|
25
|
+
} | null>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Lobstr sign message response
|
|
29
|
+
*/
|
|
30
|
+
export type LobstrSignMessageResponse = {
|
|
31
|
+
signedMessage: string;
|
|
32
|
+
signerAddress: string;
|
|
33
|
+
} | null;
|
package/src/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { Transaction } from '@stellar/stellar-sdk';
|
|
2
1
|
import type { GenericNetwork } from '@dynamic-labs/types';
|
|
3
|
-
import type {
|
|
2
|
+
import type { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
|
|
4
3
|
/**
|
|
5
4
|
* Interface for Stellar wallet providers.
|
|
6
5
|
*
|
|
@@ -100,16 +99,6 @@ export type StellarWalletConnectorProps = {
|
|
|
100
99
|
/** Wallet book schema */
|
|
101
100
|
walletBook: unknown;
|
|
102
101
|
};
|
|
103
|
-
/**
|
|
104
|
-
* Extension locators for identifying Stellar wallet browser extensions.
|
|
105
|
-
* These flags are typically set on the injected provider object to identify
|
|
106
|
-
* which wallet extension is present.
|
|
107
|
-
*/
|
|
108
|
-
export type ExtensionLocator = 'isAlbedo' | 'isFreighter' | 'isLobstr' | 'isRabet' | 'isXBull';
|
|
109
|
-
/**
|
|
110
|
-
* Type for Stellar provider condition used in provider lookup.
|
|
111
|
-
*/
|
|
112
|
-
export type StellarProviderCondition = ProviderCondition<ExtensionLocator>;
|
|
113
102
|
/**
|
|
114
103
|
* Stellar network names
|
|
115
104
|
*/
|
|
@@ -119,6 +108,9 @@ export type StellarNetworkName = 'FUTURENET' | 'PUBLIC' | 'TESTNET';
|
|
|
119
108
|
*/
|
|
120
109
|
export type StellarMethodName = 'close' | 'connect' | 'disconnect' | 'getNetwork' | 'isUnlocked' | 'on' | 'sign' | 'signMessage';
|
|
121
110
|
/**
|
|
122
|
-
* Stellar
|
|
111
|
+
* Stellar wallet connector with isConnected check.
|
|
112
|
+
* Extends WalletConnectorConstructor with an optional isConnected method.
|
|
123
113
|
*/
|
|
124
|
-
export
|
|
114
|
+
export interface StellarWalletConnectorWithIsConnected extends WalletConnectorConstructor {
|
|
115
|
+
isConnected?: () => Promise<boolean>;
|
|
116
|
+
}
|