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  }