Gataca-QR
This component built using stencyl allows an easy integration to display a gataca QR.
You only need to install on a front component to scan presentation requests from the (Gataca Wallet)[https://gataca.io/solutions] app.
Installing this component
Script tag
- Put a script tag similar to this
<script src='https://unpkg.com/gatacaqr@1.1.2/dist/gatacaqr.js'></script>
in the head of your index.html - Then you can use the element anywhere in your template, JSX, html etc
Node Modules
- Run
npm install gatacaqr --save
- Put a script tag similar to this
<script src='node_modules/gatacaqr/dist/gatacaqr.js'></script>
in the head of your index.html - Then you can use the element anywhere in your template, JSX, html etc
Styles & Personification
It allows to integrate 2 slots, named "title" and "description", to provide further integration to the user upon display of the QR.
Usage
This component should be used with the prerequisite of having an application which can be integrated with Gataca Connect. More precisely, your application will need to be able to perform the two operations against your connect server:
- Create sessions
- Consult sessions
Therefore, in order to make it work, you will need at least:
- A connect server
- An application integrated with that server to perform the basic operations.
Note: Direct integration with Gataca Connect is not recommended and should be used only for demo purposes.
To better understand how the QR works, this diagram details its work:

Configurations
To understand all possible configurations. Check the properties section below. Here is a recap of all possible combinations:
- You can choose if to generate a QR used for scanning credentials or to issue new credentials, by setting the qrRole property to scan or credential respectively.
- You need to configure a callbackServer to display on the QR, so that the wallet knows the location of the server to share the data with.
- a. You can use this component with an already created session, which can be inserted on the sessionId property on the element, or passed via query parameter id or sessionId on the current URL.
b. If you want the event of pushing the button to trigger the creation of the session, you can also provide a method to generate a new session providing the
createSession property.
c. If your application matches the gataca-login interface, you can avoid defining your own implementation and use the default implementation just by providing the generationEndpoint.
- a. If you have defined your own service to get the session on the connect, you should implement a checkStatus property. The method needs to return 0, 1 or 2 depending if the credential sharing process is still ongoing, succesfully finished or finished with error respectively.
b. If your application matches the gataca-login interface, you can avoid defining your own implementation and use the default implementation just by providing the sessionEndpoint.
c. You can optionally configure your own frequency for the polling and the session expiration time with the pollingFrequency and sessionTimeout properties.
- To keep the logic on your client-side, your shall configure the sucessCallback and the errorCallback properties, to implement alerts, redirections or further logic upon the ending of the process.
- You can choose to display the component as a button or avoid to display the button and manually trigger the QR using the asButton property. To manually trigger the QR, use javascript to invoke the open() method
- You can choose not display a dynamic link and make the QR lighter by setting the dynamicLink property to false, but it is not recommended for better compatibility and user experience.
To better understand the different relation between properties, this decision diagram explains the relation between them:

You can also check the examples below to check which configuration is more suitable for your case.
Examples
HTML Only
This example shows how to integrate the QR Component on a normal scenario, on the easiest case: the application server exposes the same interface as the Gataca Login Module.
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
<title>Gataca QR Component</title>
<script src='https://unpkg.com/gatacaqr@1.1.2/dist/gatacaqr.js'></script>
<style type="text/css">
.qrTitle {
color: #181B5E;
align-self: center;
text-align: center;
}
.qrDesc {
color: #181B5E;
}
</style>
</head>
<body>
<gataca-qr id="gataca-qr" session-timeout="300" polling-frequency="3" generation-endpoint ='https://connect.gataca.io:9090/admin/v1/login/request'
session-endpoint = "https://connect.gataca.io:9090/admin/v1/login/gataca">
<h1 class="qrTitle" slot="title" id="qrTitle">Login with Gataca</h1>
<h5 class="qrDesc" slot="description">Scan this QR to open your gataca wallet</h5>
</gataca-qr>
<script>
const qr = document.getElementById('gataca-qr');
const qrTitle = document.getElementById('qrTitle');
qrTitle.onClick = (e) => {
qr.open = false;
}
qr.successCallback = (data, token) => {
alert("LOGIN OK: " + data)
};
qr.errorCallback = () => {
alert("Wrong credentials!")
};
</script>
</body>
</html>
The definition of the default interface is can be found on the Gataca Connect documentation:

The first request - the gataca login request- is the default session generation endpoint, whereas the second one -Gataca Login- Post response is the session consultation endpoint.
Note: The default values provided for demo will always result in rejected sessions.
Application rendering HTML Only
This example shows how to integrate the QR Component on a normal scenario, where the application defines its own interface for the services.
You can find an example of that kind of simple application (written in Go) on the Gataca Authorizer, which we will use as example to explain the component's usage.
Gataca Authorizer creates the sessionId before rendering the page and provides it as a parameter on the HTML template. To query the status of the session, it offers the following endpoint:
- /login/status : Check the status of the created session
Continuing with the example as before, you could integrate with that kind of application - running at $APP_DOMAIN- by modifying the following pieces of code
- Add JQuery Library in HEAD
<head>
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
...
</head>
- Modify the parameters of the QR to present the connect server and the session id renderized on the HTML template when loaded by the backend.
<body>
...
<gataca-qr id="gataca-qr" callback-server="{{.ConnectServer}}" session-id="{{.SessionId}}">
...
</body>
- Include a checkStatus implementation to retrieve the session data.
<script>
const qr = document.getElementById('gataca-qr');
....
qr.checkStatus = async (id) => {
console.log("Check status called for session", id)
try {
response = await $.get("login/status")
console.log("Got Status Response", response)
qr.sessionData = (await response.json()).data;
return 1;
} catch (err) {
console.log("Error", err)
switch (err.status) {
case 428:
return 0;
default:
return 2
}
}
}
...
</script>
Note: If you want to retrieve the data on the successCallback, you need to store on the checkStatus invocation the session data in the sessionData property from the qr
Note 2: If Gataca Authorizer also had an endpoint to generate the sessionId, and in case we wanted that the sessionId is not generated before serving the HTML file, but when clicking the button, we could do it just by modifying the previous example:
- Modify the parameters of the QR to remove the session-id parameter.
<body>
...
<gataca-qr id="gataca-qr" callback-server="{{.ConnectServer}}">
...
</body>
- Include a createSession implementation to retrieve the session data.
<script>
const qr = document.getElementById('gataca-qr');
....
qr.createSession = async (id) => {
}
...
</script>
SPA React Application
In this example, we will show how to integrate it with a full react application.
- Run
npm install gatacaqr --save
- In index.js, include the following code at the beggining:
import { applyPolyfills, defineCustomElements } from 'gatacaqr/loader';
applyPolyfills().then(() => {
defineCustomElements(window);
});
- Create a JS component to use the QR or just invoke it from your component:
import React, { useEffect, useState, useRef } from 'react'
export const QRLogin: React.FC = () => {
const qr = useRef(null)
const gatacaLoginSuccess = (data: any, token: string) => {
alert('Gataca Login Successful')
}
const gatacaLoginError = error => {
alert('Gataca Login Error')
}
useEffect(() => {
qr.current.generationEndpoint =
process.env.REACT_APP_CONNECT_HOST + '/admin/v1/login/request'
qr.current.sessionEndpoint =
process.env.REACT_APP_CONNECT_HOST + '/admin/v1/login/gataca'
qr.current.successCallback = gatacaLoginSuccess
qr.current.errorCallback = gatacaLoginError
}, [username, password])
return (<gataca-qr
callback-server={process.env.REACT_APP_CONNECT_HOST}
ref={qr}
polling-frequency="15"/>
)
}
Properties
Property | Attribute | Description | Type | Default |
---|
sessionId | session-id | [Optional] Generated session Id, which is required. Without session Id, the QR will not work. If the property is unset, it will check for an id or sessionId query parameter on the current URL. If there is no sessionId, it will fallback to the createSession method to generate a new Session.↓ | string | - |
createSession | -- | [Optional] Create session function to generate a new Session If the property is unset, it will fallback to the generation Endpoint property.↓ | () => Promise<string> | undefined |
generationEndpoint | generation-endpoint | [Optional] Session Generation URL to create a new Session. It will expect to receive the session Id from the response header 'X-Connect-Id'. If not set, it would use a default endpoint to the same window URL under the path /auth | string | https://$DOMAIN:9090/admin/v1/login/request |
checkStatus | -- | [Optional] Check status function to query the current status of the session If not set, it would fallback to the session Endpoint property. ↓ | (id?: string) => Promise<RESULT_STATUS> | undefined |
sessionEndpoint | session-endpoint | [Optional] EndpointURL to fetch data for the status. The endpoint URL will send a GET request with the session id on a parameter; concatenated to this string. It can be used if your API fulfills the requirement. If not, use the checkStatus property. If not set, it would use a default endpoint to the same window URL under the path /auth | string | https://$CURRENT_DOMAIN:9090/admin/v1/login/gataca |
successCallback | -- | Mandatory Callback fired upon session correctly verified If not set, session validation wouldn't trigger any action The session data and a possible token will be sent as parameters to the callback | (data?: any, token?: string) => void | - |
errorCallback | -- | Mandatory Callback fired upon session expired or invalid If not set, session error would not be handled An error containing information will be passed as parameter | (error?: Error) => void | - |
callbackServer | callback-server | Mandatory Connect Server where the wallet will send the data | string | https://connect.gatacaid.com:9090 |
pollingFrequency | polling-frequency | [Optional] Frequency in seconds to check if the session has been validated | number | 3 |
sessionTimeout | session-timeout | [Optional] Maximum time window to display the session | number | 180 |
dynamicLink | dynamic-link | [Optional] Display a link containing a dynamic link to invoke the wallet if closed | boolean | true |
qrRole | qr-role | [Optional] Decide if scanning the credential as a verifier to request credentials or as an issuer too issue credentials. Options: scan (default) | credential | string | scan |
asButton | as-button | [Optional] Decide if to show it as a button to display the QR Or display directly the QR. Default: true (display button) | boolean | true |
Events
Event | Description | Type |
---|
gatacaLoginCompleted | GatacaLoginCompleted event, triggered with session data upon login success | CustomEvent<any> |
gatacaLoginFailed | GatacaLoginFailed event, triggered with error upon login failure | CustomEvent<any> |
Methods
display() => Promise<void>
Force manually the display of a QR
Returns
Type: Promise<void>
getSessionData() => Promise<any>
Retrieve manually the session data on a successful login
Returns
Type: Promise<any>
getToken() => Promise<string>
Retrieve manually a possible token retrieved upon login on the Header 'token'
Returns
Type: Promise<string>
stop() => Promise<void>
Stop manually an ongoing session
Returns
Type: Promise<void>
Javascript invocation
You can display or hide the displayed QR by setting it's open state property.
Overriding styles
TBD...
Built with StencilJS