decred.org/dcrdex@v1.0.5/client/webserver/site/src/js/register.ts (about) 1 import Doc from './doc' 2 import BasePage from './basepage' 3 import { postJSON } from './http' 4 import { 5 NewWalletForm, 6 DEXAddressForm, 7 DiscoverAccountForm, 8 ConfirmRegistrationForm, 9 FeeAssetSelectionForm, 10 WalletWaitForm, 11 slideSwap 12 } from './forms' 13 import { 14 app, 15 Exchange, 16 PageElement, 17 PrepaidBondID 18 } from './registry' 19 20 interface RegistrationPageData { 21 host: string 22 backTo?: string 23 } 24 25 export default class RegistrationPage extends BasePage { 26 body: HTMLElement 27 data: RegistrationPageData 28 xc: Exchange 29 page: Record<string, PageElement> 30 dexAddrForm: DEXAddressForm 31 discoverAcctForm: DiscoverAccountForm 32 newWalletForm: NewWalletForm 33 regAssetForm: FeeAssetSelectionForm 34 walletWaitForm: WalletWaitForm 35 confirmRegisterForm: ConfirmRegistrationForm 36 37 constructor (body: HTMLElement, data: RegistrationPageData) { 38 super() 39 this.body = body 40 this.data = data 41 const page = this.page = Doc.idDescendants(body) 42 43 if (data.host && page.dexAddrForm.classList.contains('selected')) { 44 page.dexAddrForm.classList.remove('selected') 45 page.discoverAcctForm.classList.add('selected') 46 page.discoverAcctForm.dataset.host = data.host 47 } 48 49 // Hide the form closers for the registration process except for the 50 // password reset form closer. 51 for (const el of body.querySelectorAll('.form-closer')) if (el !== page.resetPassFormCloser) Doc.hide(el) 52 53 this.newWalletForm = new NewWalletForm( 54 page.newWalletForm, 55 assetID => this.newWalletCreated(assetID, this.confirmRegisterForm.tier), 56 () => this.animateRegAsset(page.newWalletForm) 57 ) 58 59 // ADD DEX 60 this.dexAddrForm = new DEXAddressForm(page.dexAddrForm, async (xc, certFile) => { 61 this.requestFeepayment(page.dexAddrForm, xc, certFile) 62 }) 63 64 const addr = page.discoverAcctForm.dataset.host 65 if (addr) { 66 this.discoverAcctForm = new DiscoverAccountForm(page.discoverAcctForm, addr, async (xc) => { 67 this.requestFeepayment(page.discoverAcctForm, xc, '') 68 }) 69 } 70 71 // SELECT REG ASSET 72 this.regAssetForm = new FeeAssetSelectionForm(page.regAssetForm, async (assetID: number, tier: number) => { 73 if (assetID === PrepaidBondID) { 74 this.registerDEXSuccess() 75 return 76 } 77 const asset = app().assets[assetID] 78 const wallet = asset.wallet 79 if (wallet) { 80 const bondAsset = this.xc.bondAssets[asset.symbol] 81 const bondsFeeBuffer = await this.getBondsFeeBuffer(assetID, page.regAssetForm) 82 this.confirmRegisterForm.setAsset(assetID, tier, bondsFeeBuffer) 83 if (wallet.synced && wallet.balance.available >= 2 * bondAsset.amount + bondsFeeBuffer) { 84 this.animateConfirmForm(page.regAssetForm) 85 return 86 } 87 this.walletWaitForm.setWallet(assetID, bondsFeeBuffer, tier) 88 slideSwap(page.regAssetForm, page.walletWait) 89 return 90 } 91 this.confirmRegisterForm.tier = tier 92 this.newWalletForm.setAsset(assetID) 93 slideSwap(page.regAssetForm, page.newWalletForm) 94 }) 95 96 this.walletWaitForm = new WalletWaitForm(page.walletWait, () => { 97 this.animateConfirmForm(page.walletWait) 98 }, () => { this.animateRegAsset(page.walletWait) }) 99 100 // SUBMIT DEX REGISTRATION 101 this.confirmRegisterForm = new ConfirmRegistrationForm(page.confirmRegForm, () => { 102 this.registerDEXSuccess() 103 }, () => { 104 this.animateRegAsset(page.confirmRegForm) 105 }) 106 107 const currentForm = Doc.safeSelector(page.forms, ':scope > form.selected') 108 currentForm.classList.remove('selected') 109 switch (currentForm) { 110 case page.dexAddrForm: 111 this.dexAddrForm.animate() 112 break 113 case page.discoverAcctForm: 114 this.discoverAcctForm.animate() 115 } 116 Doc.show(currentForm) 117 118 // There's nothing on the page.discoverAcctForm except to receive user pass 119 // before attempting to discover user account and there's no need to have 120 // them click another button when we can carry on without user interaction. 121 if (currentForm === page.discoverAcctForm) { 122 this.discoverAcctForm.page.submit.click() 123 } 124 125 if (app().authed) this.auth() 126 } 127 128 // auth should be called once user is known to be authed with the server. 129 async auth () { 130 await app().fetchUser() 131 } 132 133 async requestFeepayment (oldForm: HTMLElement, xc: Exchange, certFile: string) { 134 this.xc = xc 135 this.confirmRegisterForm.setExchange(xc, certFile) 136 this.walletWaitForm.setExchange(xc) 137 this.regAssetForm.setExchange(xc, certFile) 138 this.animateRegAsset(oldForm) 139 } 140 141 /* Swap in the asset selection form and run the animation. */ 142 async animateRegAsset (oldForm: HTMLElement) { 143 Doc.hide(oldForm) 144 this.regAssetForm.animate() 145 Doc.show(this.page.regAssetForm) 146 } 147 148 /* Swap in the confirmation form and run the animation. */ 149 async animateConfirmForm (oldForm: HTMLElement) { 150 this.confirmRegisterForm.animate() 151 Doc.hide(oldForm) 152 Doc.show(this.page.confirmRegForm) 153 } 154 155 // Retrieve an estimate for the tx fee needed to create new bond reserves. 156 async getBondsFeeBuffer (assetID: number, form: HTMLElement) { 157 const loaded = app().loading(form) 158 const res = await postJSON('/api/bondsfeebuffer', { assetID }) 159 loaded() 160 if (!app().checkResponse(res)) { 161 return 0 162 } 163 return res.feeBuffer 164 } 165 166 /* gets the contents of the cert file */ 167 async getCertFile () { 168 let cert = '' 169 if (this.dexAddrForm.page.certFile.value) { 170 const files = this.dexAddrForm.page.certFile.files 171 if (files && files.length) cert = await files[0].text() 172 } 173 return cert 174 } 175 176 /* Called after successful registration to a DEX. */ 177 async registerDEXSuccess () { 178 await app().fetchUser() 179 app().updateMenuItemsDisplay() 180 await app().loadPage(this.data.backTo || 'markets') 181 } 182 183 async newWalletCreated (assetID: number, tier: number) { 184 this.regAssetForm.refresh() 185 const user = await app().fetchUser() 186 if (!user) return 187 const page = this.page 188 const asset = user.assets[assetID] 189 const wallet = asset.wallet 190 const bondAmt = this.xc.bondAssets[asset.symbol].amount 191 192 const bondsFeeBuffer = await this.getBondsFeeBuffer(assetID, page.newWalletForm) 193 this.walletWaitForm.setWallet(assetID, bondsFeeBuffer, tier) 194 this.confirmRegisterForm.setAsset(assetID, tier, bondsFeeBuffer) 195 if (wallet.synced && wallet.balance.available >= 2 * bondAmt + bondsFeeBuffer) { 196 await this.animateConfirmForm(page.newWalletForm) 197 return 198 } 199 200 await slideSwap(page.newWalletForm, page.walletWait) 201 } 202 }