Web client integration – import tokens

This article covers the integration of Universa Web Client with external systems delivering some Universa-based tokens to the users – e.g. when executing a ICO/Token Sale procedure.


  • issuer: some web-service that wants to issue some contracts to its clients (users) identified by email, SMS or like

  • user: the person which wants to receive a contract to own possession

  • web or web client or client: Universa's main web interface (v1 or v2)


Suppose we have a service that can send a link to the user to let him or her receive the token. The process is shown on the diagram:

sequenceDiagram participant U as User participant I as Issuer participant W as Web client I ->> U: emailing link/code note over U, I: user is identified with email U ->> I: received link I ->> W: redirect to access.mainnetwork.io W ->> I: get issuing details I -->> W: caption, text, urls W -->> U: login/registration page loop registration/login U --> W: registration/ogin procedure end note over U, W: user now has logged in and has/can create keys W ->> U: Show select address dialog U ->> W: create/select address to issue the token W ->> I: request token loop wait issuing W --> I: check status end W ->> I: get token I -->> W: token


To simplify the explanation the suppose some hypothetic SheToken service, having the domain https://she-token.com, wants to issue universa contracts to its clients.

Email/SMS/code input

Issuer must be able to send some unique URL or code to SMS and/or email of its users so they can somehow open the access interface with special integration query that must look somehow like

GET https://mainnetwork.io?iv=1&cb=https://issuer.com/callbacks/somed_codelksu37lsabjwqli7eflgwqb

here parameters are:

  • iv: required to 1, integration API protocol version
  • cb: the callback that the client calls to get generation data. Can be any, https is required.

Issuer callback

The Universa web interface saves the initial query parameters and returns to it when initial registration or logging in is performed. The client then calls the cb url as JSON POST and expects the following answer. (this is a sample data):

   caption: "She-Token generation",
   text: "The She-Token service is ready to generate your 120SHT tokens. Just select or generate the address to receive it to",
   action: "select_address",
   ok_url: "https://she-token.com/tokens/generate/llkuh345i2384kjkerwq/ok",
   cancel_url: "https://she-token.com/tokens/generate/llkuh345i2384kjkerwq/cancel",
   check_url: "https://she-token.com/tokens/generate/llkuh345i2384kjkerwq/check",
   state: string

Parameters are required unless specified otherwise:

  • caption: the title of the popup to present to the user
  • text: the popup text
  • action: must be select_address string.
  • ok_url: URL to call to start token generation
  • cancel_url: optional. URL to call if the client declines token generation
  • check_url: URL to poll the status
  • state: new, in_progress, 'cancelledorready`

All callbacks (ok_url, cancel_url and check_url) are called by the client using AJAX calls so the issuer must set up CORS properly. All callbacks are issued with POST action.


The initial state should always be new. Other values are:

state meaning
new initial
in_progress contract is being generated
ready the contract is ready and will be returned on next check
cancelled cancel_url was called, generation is no more possible

Web client callbacks


When the user is presented with a popup, the address (of some key) is selected and the "ok" button must be pressed explicitly to start the generation. When it is done, the web client issues AJAX POST request to ok_url passing the only parameter

  • address: universa address in string form (either short or long) the user has selected

The issuer must return common response with the poll_seconds: int setting up desired poll time for the web client. Web client then must check the generation state with check_url preferably with specified timeout.


The client issues checks as AJAX POST as many times as needed until it receives the generated token. The issuer returns common response like:

  state: state_string, // same as in issuer callback
  poll_seconds: int,
  base64_contract: base64_string

If poll_seconds is presented, then token_base64 must not be set. It means that the issuer ask some more time to generate.

If base64_contract is presented, the generation is done and the issued token is returned.


If specified, the web client sends AJAX POST request on it when the user selects "cancel" in the popup.

Restore from premature browser page close

It may happen that the user closes the page before the contract is issued and downloaded. To handle this both web client and an issuer must support restore procedure.

Web client restore support

Web client must store the data on the contract being generated in the local storage and cloud of available and continue polling on next page load.

Issuer restore support

Issuer must allow some procedure to redirect to the same link any number of times so the user can re-reqeust the contract. It is crucial that the callback (cb) parameter would be the same and the returned data must match what was send the first time except the state field, that must reflect the current state of the contract.

Callbacks security

It is highly recommended the issuer selects random sequences to identify "valid" callbacks. The https protocol is required. The URL form can be virtually any, different paths, domains, or only differ in query part. The callbacks used int the cb parameter and its returned data are not restricted to lead to same domain, still, the CORS must be properly set up on any of them.

Using SMS instead of email

In this case the issuer sends short url which leads to its own website and the code as some clients will not be able to effectively follow long links from SMS. The issuer then checks the code and degenerates data (URLs) for the integration procedure and redirects to the web client.

2-phase verification

If the issuer needs to check the address one more time using user's email or SMS, it could be easily done:

  • Add information to the issuer callback text that user will receive an extra notification email

  • After receiving POST ok_url send confirmation to user with email/sms including the address to check, ask to confirm it with issuer web service

  • do not issue contract until this extra confirmation