1
1
import { useState } from 'react' ;
2
- import { cosmos } from 'interchain-query' ;
3
- import { StdFee } from '@cosmjs/amino' ;
4
- import { useChain } from '@cosmos-kit/react' ;
5
- import { ChainName } from 'cosmos-kit' ;
2
+ import { StdFee } from '@interchainjs/cosmos-types/types' ;
3
+ import { useChain } from '@interchain-kit/react' ;
6
4
import BigNumber from 'bignumber.js' ;
7
5
import {
8
6
BasicModal ,
@@ -12,26 +10,29 @@ import {
12
10
Callout ,
13
11
Text ,
14
12
} from '@interchain-ui/react' ;
13
+ import { useDelegate } from '@interchainjs/react/cosmos/staking/v1beta1/tx.rpc.react' ;
14
+ import { MsgDelegate } from '@interchainjs/react/cosmos/staking/v1beta1/tx' ;
15
+ import { defaultContext } from '@tanstack/react-query' ;
15
16
16
17
import {
17
18
type ExtendedValidator as Validator ,
18
19
formatValidatorMetaInfo ,
19
20
getAssetLogoUrl ,
20
21
isGreaterThanZero ,
21
- shiftDigits ,
22
22
calcDollarValue ,
23
23
toBaseAmount ,
24
24
getExponentFromAsset ,
25
25
getNativeAsset ,
26
+ convertGasToTokenAmount ,
26
27
} from '@/utils' ;
27
- import { Prices , UseDisclosureReturn , useTx } from '@/hooks' ;
28
-
29
- const { delegate } = cosmos . staking . v1beta1 . MessageComposer . fromPartial ;
28
+ import {
29
+ Prices ,
30
+ UseDisclosureReturn ,
31
+ useSigningClient ,
32
+ useToastHandlers ,
33
+ } from '@/hooks' ;
30
34
31
- export type MaxAmountAndFee = {
32
- maxAmount : number ;
33
- fee : StdFee ;
34
- } ;
35
+ const DEFAULT_DELEGATION_GAS = '200000' ;
35
36
36
37
export const DelegateModal = ( {
37
38
balance,
@@ -49,7 +50,7 @@ export const DelegateModal = ({
49
50
balance : string ;
50
51
updateData : ( ) => void ;
51
52
unbondingDays : string ;
52
- chainName : ChainName ;
53
+ chainName : string ;
53
54
modalControl : UseDisclosureReturn ;
54
55
selectedValidator : Validator ;
55
56
logoUrl : string ;
@@ -59,87 +60,78 @@ export const DelegateModal = ({
59
60
showDescription ?: boolean ;
60
61
} ) => {
61
62
const { isOpen, onClose } = modalControl ;
62
- const { address, estimateFee , assets } = useChain ( chainName ) ;
63
+ const { address, assetList , chain } = useChain ( chainName ) ;
63
64
64
65
const [ amount , setAmount ] = useState < number | undefined > ( 0 ) ;
65
- const [ isDelegating , setIsDelegating ] = useState ( false ) ;
66
- const [ isSimulating , setIsSimulating ] = useState ( false ) ;
67
- const [ maxAmountAndFee , setMaxAmountAndFee ] = useState < MaxAmountAndFee > ( ) ;
68
66
69
- const coin = getNativeAsset ( assets ! ) ;
67
+ const coin = getNativeAsset ( assetList ) ;
70
68
const exp = getExponentFromAsset ( coin ) ;
71
- const { tx } = useTx ( chainName ) ;
69
+
70
+ const toastHandlers = useToastHandlers ( ) ;
71
+ const { data : signingClient } = useSigningClient ( chainName ) ;
72
+ const { mutate : delegate , isLoading : isDelegating } = useDelegate ( {
73
+ clientResolver : signingClient ,
74
+ options : {
75
+ context : defaultContext ,
76
+ ...toastHandlers ,
77
+ } ,
78
+ } ) ;
72
79
73
80
const onModalClose = ( ) => {
74
81
onClose ( ) ;
75
82
setAmount ( 0 ) ;
76
- setIsDelegating ( false ) ;
77
- setIsSimulating ( false ) ;
78
83
} ;
79
84
80
- const onDelegateClick = async ( ) => {
85
+ const onDelegateClick = ( ) => {
81
86
if ( ! address || ! amount ) return ;
82
87
83
- setIsDelegating ( true ) ;
84
-
85
- const msg = delegate ( {
88
+ const msg = MsgDelegate . fromPartial ( {
86
89
delegatorAddress : address ,
87
90
validatorAddress : selectedValidator . address ,
88
91
amount : {
89
- amount : toBaseAmount ( amount , exp ) , // shiftDigits(amount, exp),
92
+ amount : toBaseAmount ( amount , exp ) ,
90
93
denom : coin . base ,
91
94
} ,
92
95
} ) ;
93
96
94
- const isMaxAmountAndFeeExists =
95
- maxAmountAndFee &&
96
- new BigNumber ( amount ) . isEqualTo ( maxAmountAndFee . maxAmount ) ;
97
-
98
- await tx ( [ msg ] , {
99
- fee : isMaxAmountAndFeeExists ? maxAmountAndFee . fee : null ,
100
- onSuccess : ( ) => {
101
- setMaxAmountAndFee ( undefined ) ;
102
- closeOuterModal && closeOuterModal ( ) ;
103
- updateData ( ) ;
104
- onModalClose ( ) ;
97
+ const fee : StdFee = {
98
+ amount : [
99
+ {
100
+ denom : coin . base ,
101
+ amount : '0' ,
102
+ } ,
103
+ ] ,
104
+ gas : DEFAULT_DELEGATION_GAS ,
105
+ } ;
106
+
107
+ delegate (
108
+ {
109
+ signerAddress : address ,
110
+ message : msg ,
111
+ fee,
112
+ memo : 'Delegate' ,
105
113
} ,
106
- } ) ;
107
-
108
- setIsDelegating ( false ) ;
114
+ {
115
+ onSuccess : ( ) => {
116
+ closeOuterModal ?.( ) ;
117
+ updateData ( ) ;
118
+ onModalClose ( ) ;
119
+ } ,
120
+ }
121
+ ) ;
109
122
} ;
110
123
111
- const handleMaxClick = async ( ) => {
112
- if ( ! address ) return ;
113
-
114
- if ( Number ( balance ) === 0 ) {
115
- setAmount ( 0 ) ;
116
- return ;
117
- }
118
-
119
- setIsSimulating ( true ) ;
120
-
121
- const msg = delegate ( {
122
- delegatorAddress : address ,
123
- validatorAddress : selectedValidator . address ,
124
- amount : {
125
- amount : shiftDigits ( balance , exp ) ,
126
- denom : coin . base ,
127
- } ,
128
- } ) ;
129
-
130
- try {
131
- const fee = await estimateFee ( [ msg ] ) ;
132
- const feeAmount = new BigNumber ( fee . amount [ 0 ] . amount ) . shiftedBy ( - exp ) ;
133
- const balanceAfterFee = new BigNumber ( balance )
134
- . minus ( feeAmount )
135
- . toNumber ( ) ;
136
- setMaxAmountAndFee ( { fee, maxAmount : balanceAfterFee } ) ;
137
- setAmount ( balanceAfterFee ) ;
138
- } catch ( error ) {
139
- console . log ( error ) ;
140
- } finally {
141
- setIsSimulating ( false ) ;
142
- }
124
+ const handleMaxClick = ( ) => {
125
+ const feeAmount = convertGasToTokenAmount (
126
+ DEFAULT_DELEGATION_GAS ,
127
+ chain ,
128
+ exp
129
+ ) ;
130
+ const balanceAfterFee = Math . max (
131
+ new BigNumber ( balance ) . minus ( feeAmount ) . toNumber ( ) ,
132
+ 0
133
+ ) ;
134
+ setAmount ( balanceAfterFee ) ;
143
135
} ;
144
136
145
137
const headerExtra = (
@@ -195,7 +187,7 @@ export const DelegateModal = ({
195
187
? calcDollarValue ( coin . base , amount , prices )
196
188
: undefined ,
197
189
minValue : 0 ,
198
- maxValue : maxAmountAndFee ?. maxAmount ?? Number ( balance ) ,
190
+ maxValue : Number ( balance ) ,
199
191
value : amount ,
200
192
onValueChange : ( val ) => {
201
193
setAmount ( val ) ;
@@ -222,17 +214,15 @@ export const DelegateModal = ({
222
214
} ,
223
215
{
224
216
label : 'Max' ,
225
- onClick : ( ) => setAmount ( Number ( balance ) ) ,
217
+ onClick : handleMaxClick ,
226
218
} ,
227
219
] ,
228
220
} }
229
221
footer = {
230
222
< Button
231
223
intent = "tertiary"
232
224
onClick = { onDelegateClick }
233
- disabled = {
234
- ! isGreaterThanZero ( amount ) || isDelegating || isSimulating
235
- }
225
+ disabled = { ! isGreaterThanZero ( amount ) || isDelegating }
236
226
isLoading = { isDelegating }
237
227
>
238
228
Delegate
0 commit comments