-
Notifications
You must be signed in to change notification settings - Fork 10
/
ProvisionSmartWalletNoticeDialog.tsx
128 lines (115 loc) · 3.87 KB
/
ProvisionSmartWalletNoticeDialog.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { useAtomValue } from 'jotai';
import { useEffect, useState } from 'react';
import { querySwingsetParams } from 'utils/swingsetParams';
import { displayFunctionsAtom, pursesAtom, rpcNodeAtom } from 'store/app';
import ActionsDialog from './ActionsDialog';
import LeapLiquidityModal, { Direction } from './leap-elements/LiquidityModal';
import type { PursesJSONState } from '@agoric/wallet-backend';
const useSmartWalletFeeQuery = (rpc: string | null) => {
const [smartWalletFee, setFee] = useState<{
fee: bigint;
feeUnit: bigint;
} | null>(null);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchParams = async () => {
assert(rpc);
try {
const params = await querySwingsetParams(rpc);
console.debug('swingset params', params);
const beansPerSmartWallet = params.params.beansPerUnit.find(
({ key }: { key: string }) => key === 'smartWalletProvision',
)?.beans;
const feeUnit = params.params.beansPerUnit.find(
({ key }: { key: string }) => key === 'feeUnit',
)?.beans;
assert(feeUnit);
setFee({ fee: BigInt(beansPerSmartWallet), feeUnit: BigInt(feeUnit) });
} catch (e) {
setError(e as Error);
}
};
if (rpc) {
fetchParams();
}
}, [rpc]);
return { smartWalletFee, error };
};
type Props = {
onConfirm: () => void;
isOpen: boolean;
onClose: () => void;
};
const ProvisionSmartWalletNoticeDialog = ({
onConfirm,
isOpen,
onClose,
}: Props) => {
const rpc = useAtomValue(rpcNodeAtom);
const { smartWalletFee, error: _smartWalletFeeError } =
useSmartWalletFeeQuery(rpc);
const smartWalletFeeForDisplay = smartWalletFee
? String(smartWalletFee.fee / smartWalletFee.feeUnit) + ' IST'
: null;
const purses = useAtomValue(pursesAtom);
const istPurse = purses?.find(p => p.brandPetname === 'IST') as
| PursesJSONState<'nat'>
| undefined;
const { displayAmount, getDecimalPlaces } =
useAtomValue(displayFunctionsAtom) ?? {};
const body = (
<>
<div>
To interact with contracts on the Agoric chain, a smart wallet must be
created for your account. You will need{' '}
{smartWalletFeeForDisplay && <b>{smartWalletFeeForDisplay}</b>} to fund
its provision which will be deposited into the reserve pool. Click
"Proceed" to provision wallet and submit transaction.
</div>
<div className="my-4 flex justify-center gap-4">
{istPurse && displayAmount && (
<div className="flex items-center">
<span>
IST Balance: <b>{displayAmount(istPurse.currentAmount)}</b>
</span>
</div>
)}
{istPurse && (
<LeapLiquidityModal
selectedAsset={istPurse.brand}
direction={Direction.deposit}
/>
)}
</div>
</>
);
const istDecimals =
istPurse && getDecimalPlaces && getDecimalPlaces(istPurse.brand);
// "feeUnit" is observed to be 1000000000000n, so when "fee" is 1000000000000n
// that means 1 IST (after dividing "fee" by "feeUnit"). To convert to uIST,
// we then multiply by 10^6.
const denominatedSmartWalletFee =
istDecimals &&
smartWalletFee &&
(smartWalletFee.fee / smartWalletFee.feeUnit) * 10n ** BigInt(istDecimals);
const hasRequiredFee =
denominatedSmartWalletFee &&
istPurse !== undefined &&
istPurse.currentAmount.value >= denominatedSmartWalletFee;
return (
<ActionsDialog
body={body}
isOpen={isOpen}
title="Smart Wallet Required"
primaryAction={{ label: 'Proceed', action: onConfirm }}
secondaryAction={{
label: 'Go Back',
action: onClose,
}}
onClose={onClose}
initialFocusPrimary={true}
primaryActionDisabled={!hasRequiredFee}
/>
);
};
export default ProvisionSmartWalletNoticeDialog;