1+ <script lang="ts" setup>
2+
3+ import { computed , onMounted , PropType , ref } from ' vue' ;
4+ import { Coin , CoinMetadata } from ' ../../../utils/type' ;
5+ import { TokenUnitConverter } from ' ../../../utils/TokenUnitConverter' ;
6+
7+ import { MsgSubmitProposal } from ' cosmjs-types/cosmos/gov/v1/tx' ;
8+ import { MsgCommunityPoolSpend } from ' cosmjs-types/cosmos/distribution/v1beta1/tx' ;
9+ import { getAuthority , getCommunityPool } from ' ../../../utils/http' ;
10+
11+ const props = defineProps ({
12+ endpoint: { type: String , required: true },
13+ sender: { type: String , required: true },
14+ balances: Object as PropType <Coin []>,
15+ metadata: Object as PropType <Record <string , CoinMetadata >>,
16+ params: String ,
17+ });
18+
19+ const denom = ref (" " )
20+ const deposit = ref (" " )
21+ const amountDenom = ref (" hp" )
22+ const title = ref (" " )
23+ const summary = ref (" " )
24+ const authority = ref (" " )
25+ const recipient = ref (" " )
26+ const amount = ref (" " )
27+ const communityPoolAvailable = ref (
28+ { amount: " 0" , denom: " ahp" }
29+ )
30+
31+ const convert = new TokenUnitConverter (
32+ // below can be simplied to props.metadata if metadata api works.
33+ {
34+ ahp: {
35+ name: ' hp' ,
36+ description: ' The native staking token of the Hippo Protocol.' ,
37+ denom_units: [
38+ {
39+ denom: ' ahp' ,
40+ exponent: 0 ,
41+ aliases: [],
42+ },
43+ {
44+ denom: ' hp' ,
45+ exponent: 18 ,
46+ aliases: [],
47+ },
48+ ],
49+ base: ' ahp' ,
50+ display: ' hp' ,
51+ symbol: ' hp' ,
52+ },
53+ }
54+ );
55+ const available = computed (() => {
56+ const base = props .balances ?.find (x => x .denom === denom .value ) || { amount: " 0" , denom: denom .value }
57+ return {
58+ base ,
59+ display: convert .baseToUnit (base , amountDenom .value )
60+ }
61+ })
62+
63+ const msgs = computed (() => {
64+ return [{
65+ typeUrl: MsgSubmitProposal .typeUrl , value: MsgSubmitProposal .fromPartial ({
66+ messages: [{
67+ typeUrl: MsgCommunityPoolSpend .typeUrl ,
68+ value: MsgCommunityPoolSpend .encode ({
69+ authority: authority .value ,
70+ recipient: recipient .value ,
71+ amount: [convert .displayToBase (denom .value , {
72+ amount: String (amount .value ),
73+ denom: amountDenom .value
74+ })]
75+ }).finish (),
76+ }],
77+ initialDeposit: [convert .displayToBase (denom .value , {
78+ amount: String (deposit .value ),
79+ denom: amountDenom .value
80+ })],
81+ proposer: props .sender ,
82+ title: title .value ,
83+ summary: summary .value ,
84+ })
85+ }]
86+ })
87+
88+
89+ const units = computed (() => {
90+ return [{ denom: ' hp' , exponent: 18 , aliases: [] }];
91+ })
92+
93+ const isValid = computed (() => {
94+ let ok = true
95+ let error = " "
96+
97+ if (! authority .value ) {
98+ ok = false
99+ error = " failed to fetch Authority"
100+ }
101+ if (! recipient .value ) {
102+ ok = false
103+ error = " Recipient is required"
104+ }
105+ if (! (Number (deposit .value ) > 0 )) {
106+ ok = false
107+ error = " Initial deposit should be great than 0"
108+ }
109+ if (! (Number (amount .value ) > 0 )) {
110+ ok = false
111+ error = " Spend amount should be great than 0"
112+ }
113+ return { ok , error }
114+ })
115+
116+ function initial() {
117+ denom .value = ' ahp'
118+ }
119+
120+ onMounted (() => {
121+ getAuthority (props .endpoint ).then ((res ) => {
122+ authority .value = res .address ;
123+ }).catch ((err ) => {
124+ console .error (" Failed to fetch authority:" , err );
125+ });
126+
127+ getCommunityPool (props .endpoint ).then ((res ) => {
128+ if (! res .pool [0 ]) throw new Error (" Failed to fetch community pool" );
129+ const communityPoolBalance = res .pool [0 ];
130+ communityPoolAvailable .value = convert .baseToDisplay ({ amount: communityPoolBalance .amount , denom: communityPoolBalance .denom });
131+ }).catch ((err ) => {
132+ console .error (" Failed to fetch community pool:" , err );
133+ });
134+ })
135+
136+ defineExpose ({ msgs , isValid , initial })
137+
138+ </script >
139+ <template >
140+ <div >
141+ <div class =" form-control" >
142+ <label class =" label" >
143+ <span class =" label-text" >Sender</span >
144+ </label >
145+ <input :value =" sender" type =" text"
146+ class =" text-gray-600 dark:text-white input border !border-gray-300 dark:!border-gray-600" />
147+ </div >
148+ <div class =" form-control" >
149+ <label class =" label" >
150+ <span class =" label-text" >Title</span >
151+ <input v-model =" title" type =" text"
152+ class =" text-gray-600 dark:text-white input border !border-gray-300 dark:!border-gray-600" />
153+ </label >
154+ </div >
155+ <div class =" form-control" >
156+ <label class =" label" >
157+ <span class =" label-text" >Summary</span >
158+ <input v-model =" summary" type =" text"
159+ class =" text-gray-600 dark:text-white input border !border-gray-300 dark:!border-gray-600" />
160+ </label >
161+ </div >
162+ <div class =" form-control" >
163+ <label class =" label" >
164+ <span class =" label-text" >Initial Deposit</span >
165+ <span >{{ available?.display.amount }}{{ available?.display.denom }}</span >
166+ </label >
167+ <label class =" input-group" >
168+ <input v-model =" deposit" type =" number" :placeholder =" `Available: ${available?.display.amount}`"
169+ class =" input border border-gray-300 dark:border-gray-600 w-full dark:text-white" />
170+ <select v-model =" amountDenom" class =" select select-bordered dark:text-white" >
171+ <option v-for =" u in units" >{{ u.denom }}</option >
172+ </select >
173+ </label >
174+ </div >
175+ <div class =" form-control" >
176+ <label class =" label" >
177+ <span class =" label-text" >Recipient</span >
178+ </label >
179+ <input v-model =" recipient" type =" text"
180+ class =" text-gray-600 dark:text-white input border !border-gray-300 dark:!border-gray-600" />
181+ </div >
182+ <div class =" form-control" >
183+ <label class =" label" >
184+ <span class =" label-text" >Amount</span >
185+ <span >{{ communityPoolAvailable.amount }}{{ communityPoolAvailable.denom }}</span >
186+ </label >
187+ <label class =" input-group" >
188+ <input v-model =" amount" type =" number" :placeholder =" `Available: ${communityPoolAvailable.amount}`"
189+ class =" input border border-gray-300 dark:border-gray-600 w-full dark:text-white" />
190+ <select v-model =" amountDenom" class =" select select-bordered dark:text-white" >
191+ <option v-for =" u in units" >{{ u.denom }}</option >
192+ </select >
193+ </label >
194+ </div >
195+ </div >
196+ </template >
0 commit comments