Skip to main content

For Issuers

The issuance flow is designed to securely issue credentials via the WIDE (Web Identity and Data Exchange) service without leaking personal information from the client to the WIDE server. This is achieved by managing sensitive data entirely within the client's browser and using a popup window to initiate and control the credential issuance process.

Since this flow is meant to allow 3rd parties to issue back credentials to WIDE, it is referred to as the Back Issuance Flow.

Back Issuance Flow

The flow begins by opening a popup directed to https://wid3.app/popup/start. This ensures that all sensitive data handling and credential issuance processes are contained within the user's browser, preventing any leakage of personal information to the WIDE server. The popup serves as the main interface for the WIDE client, allowing the user's browser to interact directly with WIDE without exposing sensitive data to external networks.

An event listener is added to capture and handle messages from the WIDE service. It's crucial for receiving status updates and commands from WIDE. When WIDE indicates it is ready, the payload is sent using the postMessage method, ensuring that the entire transaction remains within the client's control.

Warning

Always verify the origin of messages to ensure they are coming from the WIDE service, protecting against CSRF and other cross-origin attacks.

Responses

Depending on the response status from WIDE (ready, closed, already_exists), appropriate actions are taken, such as registering the user, updating the session, or handling duplicates.

  • ready: Indicates that WIDE is ready to receive data. At this point, the main application sends the structured payload wrapped in a request object to the WIDE popup.
  • closed: Signifies that the credential issuance process is completed, and the credential has been successfully added to WIDE.
  • already_exists: Occurs if the credential is already registered in WIDE, based on the setting allowMultiples: false, which prevents multiple registrations of the same credential.

Preparation and Payload Construction

The payload prepared for the WIDE service contains all necessary data structured to meet specific requirements. The payload structure is as follows:

{
"config": {
"allowMultiples": false,
"logoUri": "https://example.com/logo.png",
"source": "YourApplicationName"
},
"payload": {
"issuer": {
"label": "Raid Guild Dungeon Master Membership",
"type": ["Raid Guild Dungeon Master Membership"],
"issuer": "https://your.domain.com",
"credentialSubject": {
"id": "user-specific-identifier",
"rgdmId": "token-representing-the-user"
}
},
"data": {
"dungeonMasterUserId": "token-representing-the-user",
"daoContract": "specific-dao-contract-id",
"daoName": "Name of the DAO",
"daoCreateDate": "creation-date-of-DAO"
}
}
}

In the above JSON object:

  • issuer: Describes the issuer of the credential.
  • credentialSubject: Contains identifying information about the credential's subject (i.e., the user).
  • data: This JSON object contains additional properties defined by the client which will be added to WIDE, such as identifiers and names relevant to the application.

Sequence Diagram

Code Samples

The below code samples are indicative and meant to be used as a general guideline.

Angular

import { Component } from '@angular/core';

@Component({
selector: 'app-back-issuance',
template: `<button (click)="initiateBackIssuance()">Issue Credential</button>`
})
export class BackIssuanceComponent {
payload = {
config: {
allowMultiples: false,
logoUri: 'https://example.com/logo.png',
source: 'YourApplicationName'
},
payload: {
// add your payload details here
}
};

initiateBackIssuance() {
const wideWindow = window.open('https://wid3.app/popup/start', 'WIDE', 'width=600, height=800');
if (!wideWindow) {
alert('Please enable pop-ups and try again.');
return;
}

window.addEventListener('message', (event) => {
if (event.origin !== 'https://wid3.app') return;

if (event.data.status === 'ready') {
wideWindow.postMessage({ type: 'initiate', payload: this.payload }, 'https://wid3.app');
} else if (event.data.status === 'closed') {
// Handle the closed status
} else if (event.data.status === 'already_exists') {
// Handle the already_exists status
}
}, false);
}
}

React

import React from 'react';

const BackIssuance = () => {
const payload = {
config: {
allowMultiples: false,
logoUri: 'https://example.com/logo.png',
source: 'YourApplicationName'
},
payload: {
// add your payload details here
}
};

const initiateBackIssuance = () => {
const wideWindow = window.open('https://wid3.app/popup/start', 'WIDE', 'width=600, height=800');
if (!wideWindow) {
alert('Please enable pop-ups and try again.');
return;
}

window.addEventListener('message', (event) => {
if (event.origin !== 'https://wid3.app') return;

if (event.data.status === 'ready') {
wideWindow.postMessage({ type: 'initiate', payload: payload }, 'https://wid3.app');
} else if (event.data.status === 'closed') {
// Handle the closed status
} else if (event.data.status === 'already_exists') {
// Handle the already_exists status
}
}, false);
};

return (
<button onClick={initiateBackIssuance}>Issue Credential</button>
);
};

export default BackIssuance;

Next.js

import React from 'react';

export default function BackIssuancePage() {
const payload = {
config: {
allowMultiples: false,
logoUri: 'https://example.com/logo.png',
source: 'YourApplicationName'
},
payload: {
// add your payload details here
}
};

const initiateBackIssuance = () => {
const wideWindow = window.open('https://wid3.app/popup/start', 'WIDE', 'width=600, height=800');
if (!wideWindow) {
alert('Please enable pop-ups and try again.');
return;
}

window.addEventListener('message', (event) => {
if (event.origin !== 'https://wid3.app') return;

if (event.data.status === 'ready') {
wideWindow.postMessage({ type: 'initiate', payload: payload }, 'https://wid3.app');
} else if (event.data.status === 'closed') {
// Handle the closed status
} else if (event.data.status === 'already_exists') {
// Handle the already_exists status
}
}, false);
};

return (
<div>
<button onClick={initiateBackIssuance}>Issue Credential</button>
</div>
);
}