@sundaeswap/wallet-lite 0.1.1 → 0.1.3
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/dist/cjs/classes/ReadOnlyProvider.Blockfrost.class.js +22 -12
- package/dist/cjs/classes/ReadOnlyProvider.Blockfrost.class.js.map +1 -1
- package/dist/cjs/classes/WalletObserver.class.js +105 -17
- package/dist/cjs/classes/WalletObserver.class.js.map +1 -1
- package/dist/cjs/react-components/RenderWallet.js +2 -1
- package/dist/cjs/react-components/RenderWallet.js.map +1 -1
- package/dist/cjs/react-components/RenderWalletHandles.js +2 -1
- package/dist/cjs/react-components/RenderWalletHandles.js.map +1 -1
- package/dist/cjs/react-components/RenderWalletPeerConnect.js +2 -1
- package/dist/cjs/react-components/RenderWalletPeerConnect.js.map +1 -1
- package/dist/cjs/react-components/RenderWalletState.js +2 -1
- package/dist/cjs/react-components/RenderWalletState.js.map +1 -1
- package/dist/cjs/react-components/WalletObserverProvider/WalletObserverProvider.js +60 -3
- package/dist/cjs/react-components/WalletObserverProvider/WalletObserverProvider.js.map +1 -1
- package/dist/cjs/react-components/WalletObserverProvider/hooks/effects/useDerivedState.js +3 -1
- package/dist/cjs/react-components/WalletObserverProvider/hooks/effects/useDerivedState.js.map +1 -1
- package/dist/cjs/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.js +24 -4
- package/dist/cjs/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.js.map +1 -1
- package/dist/cjs/react-components/WalletObserverProvider/hooks/useWalletObserverState.js +38 -36
- package/dist/cjs/react-components/WalletObserverProvider/hooks/useWalletObserverState.js.map +1 -1
- package/dist/cjs/react-components/contexts/observer/context.js +40 -1
- package/dist/cjs/react-components/contexts/observer/context.js.map +1 -1
- package/dist/cjs/react-components/contexts/observer/types.js.map +1 -1
- package/dist/cjs/react-components/hooks/useWalletData.js +6 -5
- package/dist/cjs/react-components/hooks/useWalletData.js.map +1 -1
- package/dist/cjs/react-components/hooks/useWalletHandles.js +11 -7
- package/dist/cjs/react-components/hooks/useWalletHandles.js.map +1 -1
- package/dist/cjs/react-components/hooks/useWalletLoadingState.js +6 -7
- package/dist/cjs/react-components/hooks/useWalletLoadingState.js.map +1 -1
- package/dist/cjs/react-components/hooks/useWalletPeerConnect.js +18 -12
- package/dist/cjs/react-components/hooks/useWalletPeerConnect.js.map +1 -1
- package/dist/esm/classes/ReadOnlyProvider.Blockfrost.class.js +11 -6
- package/dist/esm/classes/ReadOnlyProvider.Blockfrost.class.js.map +1 -1
- package/dist/esm/classes/WalletObserver.class.js +79 -1
- package/dist/esm/classes/WalletObserver.class.js.map +1 -1
- package/dist/esm/react-components/RenderWallet.js +3 -2
- package/dist/esm/react-components/RenderWallet.js.map +1 -1
- package/dist/esm/react-components/RenderWalletHandles.js +3 -2
- package/dist/esm/react-components/RenderWalletHandles.js.map +1 -1
- package/dist/esm/react-components/RenderWalletPeerConnect.js +3 -2
- package/dist/esm/react-components/RenderWalletPeerConnect.js.map +1 -1
- package/dist/esm/react-components/RenderWalletState.js +3 -2
- package/dist/esm/react-components/RenderWalletState.js.map +1 -1
- package/dist/esm/react-components/WalletObserverProvider/WalletObserverProvider.js +55 -4
- package/dist/esm/react-components/WalletObserverProvider/WalletObserverProvider.js.map +1 -1
- package/dist/esm/react-components/WalletObserverProvider/hooks/effects/useDerivedState.js +1 -1
- package/dist/esm/react-components/WalletObserverProvider/hooks/effects/useDerivedState.js.map +1 -1
- package/dist/esm/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.js +2 -2
- package/dist/esm/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.js.map +1 -1
- package/dist/esm/react-components/WalletObserverProvider/hooks/useWalletObserverState.js +4 -4
- package/dist/esm/react-components/WalletObserverProvider/hooks/useWalletObserverState.js.map +1 -1
- package/dist/esm/react-components/contexts/observer/context.js +36 -0
- package/dist/esm/react-components/contexts/observer/context.js.map +1 -1
- package/dist/esm/react-components/contexts/observer/types.js.map +1 -1
- package/dist/esm/react-components/hooks/useWalletData.js +7 -5
- package/dist/esm/react-components/hooks/useWalletData.js.map +1 -1
- package/dist/esm/react-components/hooks/useWalletHandles.js +11 -5
- package/dist/esm/react-components/hooks/useWalletHandles.js.map +1 -1
- package/dist/esm/react-components/hooks/useWalletLoadingState.js +7 -9
- package/dist/esm/react-components/hooks/useWalletLoadingState.js.map +1 -1
- package/dist/esm/react-components/hooks/useWalletPeerConnect.js +14 -11
- package/dist/esm/react-components/hooks/useWalletPeerConnect.js.map +1 -1
- package/dist/types/classes/ReadOnlyProvider.Blockfrost.class.d.ts.map +1 -1
- package/dist/types/classes/WalletObserver.class.d.ts +11 -0
- package/dist/types/classes/WalletObserver.class.d.ts.map +1 -1
- package/dist/types/react-components/RenderWallet.d.ts +0 -6
- package/dist/types/react-components/RenderWallet.d.ts.map +1 -1
- package/dist/types/react-components/RenderWalletHandles.d.ts +0 -5
- package/dist/types/react-components/RenderWalletHandles.d.ts.map +1 -1
- package/dist/types/react-components/RenderWalletPeerConnect.d.ts +0 -5
- package/dist/types/react-components/RenderWalletPeerConnect.d.ts.map +1 -1
- package/dist/types/react-components/RenderWalletState.d.ts +1 -7
- package/dist/types/react-components/RenderWalletState.d.ts.map +1 -1
- package/dist/types/react-components/WalletObserverProvider/WalletObserverProvider.d.ts.map +1 -1
- package/dist/types/react-components/WalletObserverProvider/hooks/effects/useDerivedState.d.ts.map +1 -1
- package/dist/types/react-components/WalletObserverProvider/hooks/useWalletObserverState.d.ts.map +1 -1
- package/dist/types/react-components/contexts/observer/context.d.ts +16 -1
- package/dist/types/react-components/contexts/observer/context.d.ts.map +1 -1
- package/dist/types/react-components/contexts/observer/types.d.ts +48 -1
- package/dist/types/react-components/contexts/observer/types.d.ts.map +1 -1
- package/dist/types/react-components/hooks/useWalletHandles.d.ts.map +1 -1
- package/dist/types/react-components/hooks/useWalletLoadingState.d.ts +1 -2
- package/dist/types/react-components/hooks/useWalletLoadingState.d.ts.map +1 -1
- package/dist/types/react-components/hooks/useWalletPeerConnect.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/classes/ReadOnlyProvider.Blockfrost.class.ts +22 -8
- package/src/classes/WalletObserver.class.ts +97 -1
- package/src/react-components/RenderWallet.tsx +4 -2
- package/src/react-components/RenderWalletHandles.tsx +6 -2
- package/src/react-components/RenderWalletPeerConnect.tsx +6 -2
- package/src/react-components/RenderWalletState.tsx +8 -4
- package/src/react-components/WalletObserverProvider/WalletObserverProvider.tsx +92 -4
- package/src/react-components/WalletObserverProvider/hooks/effects/useDerivedState.ts +5 -2
- package/src/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.ts +2 -2
- package/src/react-components/WalletObserverProvider/hooks/useWalletObserverState.ts +67 -37
- package/src/react-components/contexts/observer/context.ts +71 -1
- package/src/react-components/contexts/observer/types.ts +57 -1
- package/src/react-components/hooks/useWalletData.ts +5 -5
- package/src/react-components/hooks/useWalletHandles.ts +13 -8
- package/src/react-components/hooks/useWalletLoadingState.ts +13 -11
- package/src/react-components/hooks/useWalletPeerConnect.tsx +20 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sundaeswap/wallet-lite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -35,17 +35,16 @@
|
|
|
35
35
|
"version": "standard-version"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@babel/cli": "^7.24.7",
|
|
39
38
|
"@blockfrost/blockfrost-js": "^6.0.0",
|
|
40
39
|
"@fabianbormann/cardano-peer-connect": "^1.2.17",
|
|
41
40
|
"@koralabs/adahandle-sdk": "^1.5.5",
|
|
41
|
+
"lodash": "^4.17.21",
|
|
42
42
|
"rxjs": "^7.8.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": "^18.3.1",
|
|
46
46
|
"react-error-boundary": "^4.0.13",
|
|
47
47
|
"@tanstack/react-query": "^5.51.11",
|
|
48
|
-
"lodash": "^4.17.21",
|
|
49
48
|
"@cardano-sdk/core": "0.45.0",
|
|
50
49
|
"@cardano-sdk/dapp-connector": "^0.13.3",
|
|
51
50
|
"@cardano-sdk/util": "^0.15.5",
|
|
@@ -60,6 +59,7 @@
|
|
|
60
59
|
"@babel/preset-react": "^7.24.7",
|
|
61
60
|
"@babel/preset-typescript": "^7.24.7",
|
|
62
61
|
"@happy-dom/global-registrator": "^16.5.3",
|
|
62
|
+
"@babel/cli": "^7.24.7",
|
|
63
63
|
"@sundaeswap/babel-preset": "^2.0.15",
|
|
64
64
|
"@tanstack/react-query": "^5.51.11",
|
|
65
65
|
"@testing-library/dom": "^10.1.0",
|
|
@@ -14,37 +14,51 @@ export class ReadOnlyBlockfrostProvider implements ReadOnlyProvider {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
async getBalance(address: string, network: 0 | 1) {
|
|
17
|
-
const
|
|
17
|
+
const response = await fetch(
|
|
18
18
|
`https://cardano-${network ? "mainnet" : "preview"}.blockfrost.io/api/v0/addresses/${address}`,
|
|
19
19
|
{
|
|
20
20
|
headers: {
|
|
21
21
|
project_id: this.blockfrostProjectId,
|
|
22
22
|
},
|
|
23
23
|
},
|
|
24
|
-
)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const result = await response.json();
|
|
27
|
+
|
|
28
|
+
if (!response.ok || "error" in result) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Blockfrost getBalance failed: ${result.message || result.error || response.statusText}`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
25
33
|
|
|
26
34
|
// Build our value.
|
|
27
|
-
const value = this.__getValueFromAmount(
|
|
35
|
+
const value = this.__getValueFromAmount(
|
|
36
|
+
(result as Responses["address_content"]).amount,
|
|
37
|
+
);
|
|
28
38
|
|
|
29
39
|
// Return the cbor.
|
|
30
40
|
return value.toCbor();
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
async getUtxos(address: string, network: 0 | 1) {
|
|
34
|
-
const
|
|
44
|
+
const response = await fetch(
|
|
35
45
|
`https://cardano-${network ? "mainnet" : "preview"}.blockfrost.io/api/v0/addresses/${address}/utxos`,
|
|
36
46
|
{
|
|
37
47
|
headers: {
|
|
38
48
|
project_id: this.blockfrostProjectId,
|
|
39
49
|
},
|
|
40
50
|
},
|
|
41
|
-
)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const result = await response.json();
|
|
42
54
|
|
|
43
|
-
if ("error" in result) {
|
|
44
|
-
|
|
55
|
+
if (!response.ok || "error" in result) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Blockfrost getUtxos failed: ${result.message || result.error || response.statusText}`,
|
|
58
|
+
);
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
const formatted = result.map((r) => {
|
|
61
|
+
const formatted = (result as Responses["address_utxo_content"]).map((r) => {
|
|
48
62
|
return Serialization.TransactionUnspentOutput.fromCore([
|
|
49
63
|
Serialization.TransactionInput.fromCore({
|
|
50
64
|
index: r.output_index,
|
|
@@ -53,10 +53,20 @@ export class WalletObserver<
|
|
|
53
53
|
public peerConnectInstance?: import("@fabianbormann/cardano-peer-connect").DAppPeerConnect;
|
|
54
54
|
|
|
55
55
|
private _performingSync: boolean = false;
|
|
56
|
+
private _syncQueue: Promise<IWalletObserverSync<AssetMetadata> | void> =
|
|
57
|
+
Promise.resolve();
|
|
56
58
|
private _options: IResolvedWalletObserverOptions<AssetMetadata>;
|
|
57
59
|
|
|
58
60
|
// Caching
|
|
59
61
|
private _cachedMetadata: Map<string, AssetMetadata> = new Map();
|
|
62
|
+
private _lastBalanceCbor: string | null = null;
|
|
63
|
+
private _lastBalanceMap: WalletBalanceMap<AssetMetadata> | null = null;
|
|
64
|
+
private _lastUsedAddressesCbor: string[] | null = null;
|
|
65
|
+
private _lastUsedAddresses: string[] | null = null;
|
|
66
|
+
private _lastUnusedAddressesCbor: string[] | null = null;
|
|
67
|
+
private _lastUnusedAddresses: string[] | null = null;
|
|
68
|
+
private _lastChangeAddressCbor: string | null = null;
|
|
69
|
+
private _lastChangeAddress: string | null = null;
|
|
60
70
|
|
|
61
71
|
// AbortController for cancelling in-flight metadata fetches when metadataResolver changes
|
|
62
72
|
private _metadataAbortController: AbortController | null = null;
|
|
@@ -120,7 +130,15 @@ export class WalletObserver<
|
|
|
120
130
|
*
|
|
121
131
|
* @returns {Promise<IWalletObserverSync<AssetMetadata>>} - A promise that resolves to the wallet sync data.
|
|
122
132
|
*/
|
|
123
|
-
sync =
|
|
133
|
+
sync = (): Promise<IWalletObserverSync<AssetMetadata>> => {
|
|
134
|
+
const pending = this._syncQueue.then(() => this._doSync());
|
|
135
|
+
// Chain onto queue but swallow rejections in the queue itself
|
|
136
|
+
// so a failed sync doesn't block subsequent syncs.
|
|
137
|
+
this._syncQueue = pending.catch(() => {});
|
|
138
|
+
return pending;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
private _doSync = async (): Promise<IWalletObserverSync<AssetMetadata>> => {
|
|
124
142
|
if (!this.api) {
|
|
125
143
|
throw new Error(
|
|
126
144
|
"Attempted to perform a sync operation without a connected wallet.",
|
|
@@ -320,6 +338,8 @@ export class WalletObserver<
|
|
|
320
338
|
if (metadataResolverChanged) {
|
|
321
339
|
this._metadataAbortController?.abort();
|
|
322
340
|
this._cachedMetadata = new Map();
|
|
341
|
+
this._lastBalanceCbor = null;
|
|
342
|
+
this._lastBalanceMap = null;
|
|
323
343
|
|
|
324
344
|
// Trigger a new sync if there's an active connection
|
|
325
345
|
if (this.hasActiveConnection() && !this._performingSync) {
|
|
@@ -450,6 +470,8 @@ export class WalletObserver<
|
|
|
450
470
|
this._metadataAbortController?.abort();
|
|
451
471
|
// Clear the cache
|
|
452
472
|
this._cachedMetadata = new Map();
|
|
473
|
+
this._lastBalanceCbor = null;
|
|
474
|
+
this._lastBalanceMap = null;
|
|
453
475
|
|
|
454
476
|
// Trigger a new sync if there's an active connection
|
|
455
477
|
if (this.hasActiveConnection()) {
|
|
@@ -462,9 +484,21 @@ export class WalletObserver<
|
|
|
462
484
|
*
|
|
463
485
|
* @returns {void}
|
|
464
486
|
*/
|
|
487
|
+
private _clearSyncCaches = (): void => {
|
|
488
|
+
this._lastBalanceCbor = null;
|
|
489
|
+
this._lastBalanceMap = null;
|
|
490
|
+
this._lastUsedAddressesCbor = null;
|
|
491
|
+
this._lastUsedAddresses = null;
|
|
492
|
+
this._lastUnusedAddressesCbor = null;
|
|
493
|
+
this._lastUnusedAddresses = null;
|
|
494
|
+
this._lastChangeAddressCbor = null;
|
|
495
|
+
this._lastChangeAddress = null;
|
|
496
|
+
};
|
|
497
|
+
|
|
465
498
|
disconnect = (): void => {
|
|
466
499
|
this.activeWallet = undefined;
|
|
467
500
|
this.api = undefined;
|
|
501
|
+
this._clearSyncCaches();
|
|
468
502
|
window.localStorage.removeItem(WalletObserver.PERSISTENCE_CACHE_KEY);
|
|
469
503
|
this.dispatch(EWalletObserverEvents.DISCONNECT);
|
|
470
504
|
};
|
|
@@ -495,8 +529,20 @@ export class WalletObserver<
|
|
|
495
529
|
return e as Error;
|
|
496
530
|
}
|
|
497
531
|
|
|
532
|
+
// Return cached if CBOR hasn't changed
|
|
533
|
+
if (cbor === this._lastChangeAddressCbor && this._lastChangeAddress) {
|
|
534
|
+
const end = performance.now();
|
|
535
|
+
if (this._options.debug) {
|
|
536
|
+
console.log(`getChangeAddress (cached): ${end - start}ms`);
|
|
537
|
+
}
|
|
538
|
+
return this._lastChangeAddress;
|
|
539
|
+
}
|
|
540
|
+
|
|
498
541
|
const data = Cardano.Address.fromBytes(typedHex(cbor)).toBech32();
|
|
499
542
|
|
|
543
|
+
this._lastChangeAddressCbor = cbor;
|
|
544
|
+
this._lastChangeAddress = data;
|
|
545
|
+
|
|
500
546
|
const end = performance.now();
|
|
501
547
|
if (this._options.debug) {
|
|
502
548
|
console.log(`getChangeAddress: ${end - start}ms`);
|
|
@@ -530,6 +576,19 @@ export class WalletObserver<
|
|
|
530
576
|
} catch (e) {
|
|
531
577
|
return e as Error;
|
|
532
578
|
}
|
|
579
|
+
|
|
580
|
+
// Return cached map if CBOR hasn't changed
|
|
581
|
+
if (cbor === this._lastBalanceCbor && this._lastBalanceMap) {
|
|
582
|
+
this.dispatch(EWalletObserverEvents.GET_BALANCE_MAP_END, {
|
|
583
|
+
balanceMap: this._lastBalanceMap,
|
|
584
|
+
});
|
|
585
|
+
const end = performance.now();
|
|
586
|
+
if (this._options.debug) {
|
|
587
|
+
console.log(`getBalanceMap (cached): ${end - start}ms`);
|
|
588
|
+
}
|
|
589
|
+
return this._lastBalanceMap;
|
|
590
|
+
}
|
|
591
|
+
|
|
533
592
|
const data = Serialization.Value.fromCbor(typedHex(cbor));
|
|
534
593
|
const multiassetKeys = data.multiasset()?.keys() ?? [];
|
|
535
594
|
|
|
@@ -554,6 +613,9 @@ export class WalletObserver<
|
|
|
554
613
|
}
|
|
555
614
|
}
|
|
556
615
|
|
|
616
|
+
this._lastBalanceCbor = cbor;
|
|
617
|
+
this._lastBalanceMap = balanceMap;
|
|
618
|
+
|
|
557
619
|
this.dispatch(EWalletObserverEvents.GET_BALANCE_MAP_END, {
|
|
558
620
|
balanceMap,
|
|
559
621
|
});
|
|
@@ -619,10 +681,27 @@ export class WalletObserver<
|
|
|
619
681
|
return e as Error;
|
|
620
682
|
}
|
|
621
683
|
|
|
684
|
+
// Return cached if CBOR hasn't changed
|
|
685
|
+
if (
|
|
686
|
+
this._lastUsedAddressesCbor &&
|
|
687
|
+
this._lastUsedAddresses &&
|
|
688
|
+
cbor.length === this._lastUsedAddressesCbor.length &&
|
|
689
|
+
cbor.every((v, i) => v === this._lastUsedAddressesCbor![i])
|
|
690
|
+
) {
|
|
691
|
+
const end = performance.now();
|
|
692
|
+
if (this._options.debug) {
|
|
693
|
+
console.log(`getUsedAddresses (cached): ${end - start}ms`);
|
|
694
|
+
}
|
|
695
|
+
return this._lastUsedAddresses;
|
|
696
|
+
}
|
|
697
|
+
|
|
622
698
|
const data = cbor.map((val) =>
|
|
623
699
|
Cardano.Address.fromBytes(typedHex(val)).toBech32(),
|
|
624
700
|
);
|
|
625
701
|
|
|
702
|
+
this._lastUsedAddressesCbor = cbor;
|
|
703
|
+
this._lastUsedAddresses = data;
|
|
704
|
+
|
|
626
705
|
const end = performance.now();
|
|
627
706
|
if (this._options.debug) {
|
|
628
707
|
console.log(`getUsedAddresses: ${end - start}ms`);
|
|
@@ -656,10 +735,27 @@ export class WalletObserver<
|
|
|
656
735
|
return e as Error;
|
|
657
736
|
}
|
|
658
737
|
|
|
738
|
+
// Return cached if CBOR hasn't changed
|
|
739
|
+
if (
|
|
740
|
+
this._lastUnusedAddressesCbor &&
|
|
741
|
+
this._lastUnusedAddresses &&
|
|
742
|
+
cbor.length === this._lastUnusedAddressesCbor.length &&
|
|
743
|
+
cbor.every((v, i) => v === this._lastUnusedAddressesCbor![i])
|
|
744
|
+
) {
|
|
745
|
+
const end = performance.now();
|
|
746
|
+
if (this._options.debug) {
|
|
747
|
+
console.log(`getUnusedAddresses (cached): ${end - start}ms`);
|
|
748
|
+
}
|
|
749
|
+
return this._lastUnusedAddresses;
|
|
750
|
+
}
|
|
751
|
+
|
|
659
752
|
const data = cbor.map((val) =>
|
|
660
753
|
Cardano.Address.fromBytes(typedHex(val)).toBech32(),
|
|
661
754
|
);
|
|
662
755
|
|
|
756
|
+
this._lastUnusedAddressesCbor = cbor;
|
|
757
|
+
this._lastUnusedAddresses = data;
|
|
758
|
+
|
|
663
759
|
const end = performance.now();
|
|
664
760
|
if (this._options.debug) {
|
|
665
761
|
console.log(`getUnusedAddresses: ${end - start}ms`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IAssetAmountMetadata } from "@sundaeswap/asset";
|
|
2
|
-
import { ReactElement, ReactNode, Suspense } from "react";
|
|
2
|
+
import { memo, ReactElement, ReactNode, Suspense } from "react";
|
|
3
3
|
|
|
4
4
|
import { ErrorBoundary } from "react-error-boundary";
|
|
5
5
|
import { useWalletObserver } from "./hooks/useWalletObserver.js";
|
|
@@ -26,7 +26,7 @@ export interface IRenderWalletProps<
|
|
|
26
26
|
* compose on this and include state for Handles, PeerConnect (CIP-45),
|
|
27
27
|
* and syncing state (RenderWalletState).
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
const RenderWalletInner = <
|
|
30
30
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
31
31
|
>({
|
|
32
32
|
render,
|
|
@@ -48,3 +48,5 @@ export const RenderWallet = <
|
|
|
48
48
|
</ErrorBoundary>
|
|
49
49
|
);
|
|
50
50
|
};
|
|
51
|
+
|
|
52
|
+
export const RenderWallet = memo(RenderWalletInner) as typeof RenderWalletInner;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IAssetAmountMetadata } from "@sundaeswap/asset";
|
|
2
|
-
import { ReactElement, ReactNode, Suspense } from "react";
|
|
2
|
+
import { memo, ReactElement, ReactNode, Suspense } from "react";
|
|
3
3
|
|
|
4
4
|
import { ErrorBoundary } from "react-error-boundary";
|
|
5
5
|
import { useWalletHandles } from "./hooks/useWalletHandles.js";
|
|
@@ -27,7 +27,7 @@ export interface IRenderWalletHandlesProps<
|
|
|
27
27
|
* fetching and updating wallet Handles with their extra
|
|
28
28
|
* metadata.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
const RenderWalletHandlesInner = <
|
|
31
31
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
32
32
|
>({
|
|
33
33
|
render,
|
|
@@ -52,3 +52,7 @@ export const RenderWalletHandles = <
|
|
|
52
52
|
</ErrorBoundary>
|
|
53
53
|
);
|
|
54
54
|
};
|
|
55
|
+
|
|
56
|
+
export const RenderWalletHandles = memo(
|
|
57
|
+
RenderWalletHandlesInner,
|
|
58
|
+
) as typeof RenderWalletHandlesInner;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IAssetAmountMetadata } from "@sundaeswap/asset";
|
|
2
|
-
import { ReactElement, ReactNode, Suspense } from "react";
|
|
2
|
+
import { memo, ReactElement, ReactNode, Suspense } from "react";
|
|
3
3
|
import { ErrorBoundary } from "react-error-boundary";
|
|
4
4
|
|
|
5
5
|
import { useWalletObserver } from "./hooks/useWalletObserver.js";
|
|
@@ -27,7 +27,7 @@ export interface IRenderWalletPeerConnectProps<
|
|
|
27
27
|
* and exposing them to the render function, including a QR Code
|
|
28
28
|
* element that can be placed in the consuming app.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
const RenderWalletPeerConnectInner = <
|
|
31
31
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
32
32
|
>({
|
|
33
33
|
render,
|
|
@@ -56,3 +56,7 @@ export const RenderWalletPeerConnect = <
|
|
|
56
56
|
</ErrorBoundary>
|
|
57
57
|
);
|
|
58
58
|
};
|
|
59
|
+
|
|
60
|
+
export const RenderWalletPeerConnect = memo(
|
|
61
|
+
RenderWalletPeerConnectInner,
|
|
62
|
+
) as typeof RenderWalletPeerConnectInner;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IAssetAmountMetadata } from "@sundaeswap/asset";
|
|
2
|
-
import { ReactElement, ReactNode, Suspense } from "react";
|
|
2
|
+
import { memo, ReactElement, ReactNode, Suspense } from "react";
|
|
3
3
|
|
|
4
4
|
import { ErrorBoundary } from "react-error-boundary";
|
|
5
5
|
import { useWalletLoadingState } from "./hooks/useWalletLoadingState.js";
|
|
@@ -8,7 +8,7 @@ import { useWalletObserver } from "./hooks/useWalletObserver.js";
|
|
|
8
8
|
export type TRenderWalletStateFunctionState<
|
|
9
9
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
10
10
|
> = ReturnType<typeof useWalletObserver<T>> &
|
|
11
|
-
ReturnType<typeof useWalletLoadingState
|
|
11
|
+
ReturnType<typeof useWalletLoadingState>;
|
|
12
12
|
|
|
13
13
|
export type TRenderWalletStateFunction<
|
|
14
14
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
@@ -28,7 +28,7 @@ export interface IRenderWalletStateProps<
|
|
|
28
28
|
* a sync or connection operation. Useful for displaying
|
|
29
29
|
* internal operation states of the wallet.
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
const RenderWalletStateInner = <
|
|
32
32
|
T extends IAssetAmountMetadata = IAssetAmountMetadata,
|
|
33
33
|
>({
|
|
34
34
|
render,
|
|
@@ -36,7 +36,7 @@ export const RenderWalletState = <
|
|
|
36
36
|
fallback,
|
|
37
37
|
}: IRenderWalletStateProps<T>) => {
|
|
38
38
|
const state = useWalletObserver<T>();
|
|
39
|
-
const loadingState = useWalletLoadingState
|
|
39
|
+
const loadingState = useWalletLoadingState();
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<ErrorBoundary
|
|
@@ -56,3 +56,7 @@ export const RenderWalletState = <
|
|
|
56
56
|
</ErrorBoundary>
|
|
57
57
|
);
|
|
58
58
|
};
|
|
59
|
+
|
|
60
|
+
export const RenderWalletState = memo(
|
|
61
|
+
RenderWalletStateInner,
|
|
62
|
+
) as typeof RenderWalletStateInner;
|
|
@@ -4,6 +4,9 @@ import { WalletObserver } from "../../classes/WalletObserver.class.js";
|
|
|
4
4
|
import {
|
|
5
5
|
IWalletObserverProviderProps,
|
|
6
6
|
IWalletObserverState,
|
|
7
|
+
WalletActionsContext,
|
|
8
|
+
WalletConnectionContext,
|
|
9
|
+
WalletDataContext,
|
|
7
10
|
WalletObserverContext,
|
|
8
11
|
} from "../contexts/observer/index.js";
|
|
9
12
|
import { useDerivedState } from "./hooks/effects/useDerivedState.js";
|
|
@@ -42,7 +45,87 @@ const WalletObserverProvider: FC<
|
|
|
42
45
|
changeAddress: state.changeAddress,
|
|
43
46
|
});
|
|
44
47
|
|
|
45
|
-
//
|
|
48
|
+
// Focused context: stable callbacks and observer ref.
|
|
49
|
+
// Only changes when observer instance is recreated.
|
|
50
|
+
const actionsValue = useMemo(
|
|
51
|
+
() => ({
|
|
52
|
+
observer: observerRef.current,
|
|
53
|
+
observerRef: observerRef,
|
|
54
|
+
connectWallet: state.connectWallet,
|
|
55
|
+
disconnect: state.disconnect,
|
|
56
|
+
syncWallet: state.syncWallet,
|
|
57
|
+
resyncMetadata: state.resyncMetadata,
|
|
58
|
+
}),
|
|
59
|
+
[
|
|
60
|
+
state.connectWallet,
|
|
61
|
+
state.disconnect,
|
|
62
|
+
state.syncWallet,
|
|
63
|
+
state.resyncMetadata,
|
|
64
|
+
],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Focused context: connection and loading state.
|
|
68
|
+
// Changes on connect/disconnect and sync start/end.
|
|
69
|
+
const connectionValue = useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
activeWallet: state.activeWallet,
|
|
72
|
+
ready,
|
|
73
|
+
connectingWallet,
|
|
74
|
+
syncingWallet,
|
|
75
|
+
network: state.network,
|
|
76
|
+
isCip45: state.isCip45,
|
|
77
|
+
switching: state.switching,
|
|
78
|
+
isReadOnlyMode: state.isReadOnlyMode,
|
|
79
|
+
willAutoConnect: state.willAutoConnect,
|
|
80
|
+
errorSyncing: state.errorSyncing,
|
|
81
|
+
mainAddress: derivedState.mainAddress,
|
|
82
|
+
stakeAddress: derivedState.stakeAddress,
|
|
83
|
+
}),
|
|
84
|
+
[
|
|
85
|
+
state.activeWallet,
|
|
86
|
+
ready,
|
|
87
|
+
connectingWallet,
|
|
88
|
+
syncingWallet,
|
|
89
|
+
state.network,
|
|
90
|
+
state.isCip45,
|
|
91
|
+
state.switching,
|
|
92
|
+
state.isReadOnlyMode,
|
|
93
|
+
state.willAutoConnect,
|
|
94
|
+
state.errorSyncing,
|
|
95
|
+
derivedState.mainAddress,
|
|
96
|
+
derivedState.stakeAddress,
|
|
97
|
+
],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Focused context: wallet data that changes every sync cycle.
|
|
101
|
+
const dataValue = useMemo(
|
|
102
|
+
() => ({
|
|
103
|
+
balance: state.balance,
|
|
104
|
+
adaBalance: state.adaBalance,
|
|
105
|
+
usedAddresses: state.usedAddresses,
|
|
106
|
+
unusedAddresses: state.unusedAddresses,
|
|
107
|
+
changeAddress: state.changeAddress,
|
|
108
|
+
feeAddress: state.feeAddress,
|
|
109
|
+
utxos: state.utxos,
|
|
110
|
+
collateral: state.collateral,
|
|
111
|
+
isPending: state.isPending,
|
|
112
|
+
refreshInterval: options?.refreshInterval || 30000,
|
|
113
|
+
}),
|
|
114
|
+
[
|
|
115
|
+
state.balance,
|
|
116
|
+
state.adaBalance,
|
|
117
|
+
state.usedAddresses,
|
|
118
|
+
state.unusedAddresses,
|
|
119
|
+
state.changeAddress,
|
|
120
|
+
state.feeAddress,
|
|
121
|
+
state.utxos,
|
|
122
|
+
state.collateral,
|
|
123
|
+
state.isPending,
|
|
124
|
+
options?.refreshInterval,
|
|
125
|
+
],
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Backward-compatible full context value
|
|
46
129
|
const contextValue: IWalletObserverState = useMemo(
|
|
47
130
|
() => ({
|
|
48
131
|
observerRef: observerRef,
|
|
@@ -57,13 +140,12 @@ const WalletObserverProvider: FC<
|
|
|
57
140
|
},
|
|
58
141
|
}),
|
|
59
142
|
[
|
|
60
|
-
options,
|
|
143
|
+
options?.refreshInterval,
|
|
61
144
|
state,
|
|
62
145
|
derivedState,
|
|
63
146
|
connectingWallet,
|
|
64
147
|
syncingWallet,
|
|
65
148
|
ready,
|
|
66
|
-
observerRef.current,
|
|
67
149
|
],
|
|
68
150
|
);
|
|
69
151
|
|
|
@@ -83,7 +165,13 @@ const WalletObserverProvider: FC<
|
|
|
83
165
|
|
|
84
166
|
return (
|
|
85
167
|
<WalletObserverContext.Provider value={contextValue}>
|
|
86
|
-
{
|
|
168
|
+
<WalletActionsContext.Provider value={actionsValue}>
|
|
169
|
+
<WalletConnectionContext.Provider value={connectionValue}>
|
|
170
|
+
<WalletDataContext.Provider value={dataValue}>
|
|
171
|
+
{children}
|
|
172
|
+
</WalletDataContext.Provider>
|
|
173
|
+
</WalletConnectionContext.Provider>
|
|
174
|
+
</WalletActionsContext.Provider>
|
|
87
175
|
</WalletObserverContext.Provider>
|
|
88
176
|
);
|
|
89
177
|
};
|
|
@@ -11,8 +11,11 @@ export const useDerivedState = (
|
|
|
11
11
|
>,
|
|
12
12
|
) => {
|
|
13
13
|
const [stakeAddress, setStakeAddress] = useState<string>();
|
|
14
|
-
const address =
|
|
15
|
-
|
|
14
|
+
const address = useMemo(
|
|
15
|
+
() =>
|
|
16
|
+
state.changeAddress || state.usedAddresses[0] || state.unusedAddresses[0],
|
|
17
|
+
[state.changeAddress, state.usedAddresses, state.unusedAddresses],
|
|
18
|
+
);
|
|
16
19
|
|
|
17
20
|
useEffect(() => {
|
|
18
21
|
if (!address) {
|
package/src/react-components/WalletObserverProvider/hooks/effects/useSyncWalletWithInterval.ts
CHANGED
|
@@ -14,8 +14,8 @@ export const useSyncWalletWithInterval = (
|
|
|
14
14
|
) => {
|
|
15
15
|
useQuery({
|
|
16
16
|
queryKey: ["useSyncWalletWithInterval"],
|
|
17
|
-
queryFn: () => {
|
|
18
|
-
syncWalletFn();
|
|
17
|
+
queryFn: async () => {
|
|
18
|
+
await syncWalletFn();
|
|
19
19
|
return true;
|
|
20
20
|
},
|
|
21
21
|
refetchInterval: refreshInterval,
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { TransactionUnspentOutput } from "@cardano-sdk/core/dist/cjs/Serialization/TransactionUnspentOutput.js";
|
|
2
2
|
import { AssetAmount, IAssetAmountMetadata } from "@sundaeswap/asset";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState,
|
|
8
|
+
useTransition,
|
|
9
|
+
} from "react";
|
|
4
10
|
|
|
5
11
|
import { IWalletObserverSync } from "../../../@types/observer.js";
|
|
6
12
|
import { ReadOnlyApi } from "../../../classes/ReadOnlyApi.class.js";
|
|
@@ -77,7 +83,7 @@ export const useWalletObserverState = <
|
|
|
77
83
|
setSwitching(() => false);
|
|
78
84
|
return observer.api;
|
|
79
85
|
},
|
|
80
|
-
[observer
|
|
86
|
+
[observer],
|
|
81
87
|
);
|
|
82
88
|
|
|
83
89
|
const resyncMetadata = useCallback(async () => {
|
|
@@ -212,39 +218,63 @@ export const useWalletObserverState = <
|
|
|
212
218
|
};
|
|
213
219
|
}, [syncWallet]);
|
|
214
220
|
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
221
|
+
return useMemo(
|
|
222
|
+
() => ({
|
|
223
|
+
activeWallet,
|
|
224
|
+
adaBalance,
|
|
225
|
+
balance,
|
|
226
|
+
collateral,
|
|
227
|
+
connectWallet,
|
|
228
|
+
disconnect,
|
|
229
|
+
errorSyncing,
|
|
230
|
+
feeAddress,
|
|
231
|
+
isCip45,
|
|
232
|
+
isPending,
|
|
233
|
+
isReadOnlyMode,
|
|
234
|
+
network,
|
|
235
|
+
changeAddress,
|
|
236
|
+
resyncMetadata,
|
|
237
|
+
setActiveWallet,
|
|
238
|
+
setAdaBalance,
|
|
239
|
+
setBalance,
|
|
240
|
+
setCollateral,
|
|
241
|
+
setFeeAddress,
|
|
242
|
+
setIsCip45,
|
|
243
|
+
setIsReadOnlyMode,
|
|
244
|
+
setNetwork,
|
|
245
|
+
setSwitching,
|
|
246
|
+
setUnusedAddresses,
|
|
247
|
+
setUsedAddresses,
|
|
248
|
+
setUtxos,
|
|
249
|
+
setChangeAddress,
|
|
250
|
+
switching,
|
|
251
|
+
syncWallet,
|
|
252
|
+
unusedAddresses,
|
|
253
|
+
usedAddresses,
|
|
254
|
+
utxos,
|
|
255
|
+
willAutoConnect,
|
|
256
|
+
}),
|
|
257
|
+
[
|
|
258
|
+
activeWallet,
|
|
259
|
+
adaBalance,
|
|
260
|
+
balance,
|
|
261
|
+
collateral,
|
|
262
|
+
connectWallet,
|
|
263
|
+
disconnect,
|
|
264
|
+
errorSyncing,
|
|
265
|
+
feeAddress,
|
|
266
|
+
isCip45,
|
|
267
|
+
isPending,
|
|
268
|
+
isReadOnlyMode,
|
|
269
|
+
network,
|
|
270
|
+
changeAddress,
|
|
271
|
+
resyncMetadata,
|
|
272
|
+
switching,
|
|
273
|
+
syncWallet,
|
|
274
|
+
unusedAddresses,
|
|
275
|
+
usedAddresses,
|
|
276
|
+
utxos,
|
|
277
|
+
willAutoConnect,
|
|
278
|
+
],
|
|
279
|
+
);
|
|
250
280
|
};
|