3rd Party Integration

You can easily integrate the File Certification feature into any web application or web site with our Javascript library.

The Javascript Library includes the following libraries:

You can get the library by following this links: TESTNET MAINNET

This library aims to simplify the integration in any Web application or Web site, more libraries will be released in the future based on user needs.

HOW TO IMPLEMENT IT

You can download the complete template here.

EXAMPLE OF THE HTML PART

Create your own simple html to allow users to connect with their Waves Account, select the file they want to certify and then certify the hash of this file using Waves Signer.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Sign signer</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/bs.css">
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="container">
<div class="row">
<div id="userCredit" class="col-lg-12 mt-2"></div>
<div id="userBalance" class="col-lg-12"></div>
<div id="certificationCost" class="col-lg-12 mt-2"></div>
<div class="col-lg-12 mt-4">
<div class="mb-4">
<button id="login" class="btn btn-primary">SIGN IN</button>
<div id="userInfos" class="mt-2"></div>
</div>
<div class="mb-4">
<input type="file" id="selectFile" />
<div id="fileInfos" class="mt-2"></div>
</div>
<div class="mb-4">
<button id="certify" class="btn btn-primary">CERTIFY</button>
<div id="result" class="mt-2"></div>
</div>
</div>
</div>
</div>
<script src="assets/js/testnet-signchain-signer.min.js"></script>
<script src="assets/js/site.js"></script>
</body>
</html>

This library includes three methods that allows you to retrieve a connected user's SIGN balance, his SIGN Certification credit if any as well as the current Certification Cost in SIGN Utility Tokens, this information is displayed in our template as #userCredit, #userBalance and #certificationCost

Then we have the #login button to allow users to log in with Waves Signer, followed by the #userInfos block that will receive Waves Signer data once connected (address and publicKey)

The #selectFile input field will allow file selection on the user's computer, once the file is selected, the hash will be calculated locally client side (files never go online during the hashing process) and then the #fileInfos block will receive the file details (file name and file hash in our example)

Finally, the #certify button once clicked will call the invoke() method of Waves Signer with the appropriate data and ask the user to confirm the transaction. Once confirmed, the block #result will receive the transaction ID.

At the bottom you need to include the two javascript files, the library first (here the testnet version) then your custom javascript.

EXAMPLE OF THE JAVASCRIPT PART

All you need to do is to create your different listener and call the appropriate methods of the library; here each listener associated to our example before we go into detail:

var storeData;
var userData;
document.getElementById("login").addEventListener("click", async function (e) {
e.preventDefault()
let login = await window.signchain.login();
userData = login;
document.getElementById("userInfos").innerHTML = "Address: " + userData.address + "<br>Public Key: " + userData.publicKey
getCredit();
getBalance();
});
document.getElementById("logout").addEventListener("click", async function (e) {
e.preventDefault()
await window.signchain.logout();
storeData = null;
userData = null;
document.getElementById("userInfos").innerHTML = ""
document.getElementById("userBalance").innerHTML = ""
document.getElementById("userCredit").innerHTML = "";
});
document.getElementById("selectFile").addEventListener("change", async function (event) {
await window.signchain.hash(event.target.files[0], function (res) {
storeData = res;
document.getElementById("fileInfos").innerHTML = "Title: " + storeData.title + "<br>Hash sha256: " + storeData.hash
});
});
document.getElementById("certify").addEventListener("click", async function (e) {
e.preventDefault();
document.getElementById("result").innerHTML = "Transaction processing... ";
let credit = await window.signchain.checkUserCredit(userData.address);
let useCredit = false
if(credit > 0){
useCredit = true
}
let certify = await window.signchain.certify(storeData, userData.publicKey, useCredit);
if(certify.id){
document.getElementById("result").innerHTML = "Transaction ID: <a href=\"https://wavesexplorer.com/testnet/tx/" + certify.id + "\" target=\"_blank\">"+certify.id+"</a>";
}else{
document.getElementById("result").innerHTML = "Something went wront: " + certify;
}
getCredit(userData.address);
});
document.addEventListener("hashingProgress", function (e) {
document.getElementById("fileInfos").innerHTML = e.detail + "%";
});
let getPrice = async function(){
let cost = await window.signchain.getCertificationFee();
document.getElementById("certificationCost").innerHTML = "Cost per certification: " + cost + " SIGN"
}
getPrice()
let getBalance = async function(){
let balance = await window.signchain.getUserBalance(userData.address);
let balanceDecimal = balance / Math.pow(10, 8);
document.getElementById("userBalance").innerHTML = "This account have: " + balanceDecimal + " SIGN Token(s)"
}
let getCredit = async function(){
let credit = await window.signchain.checkUserCredit(userData.address);
document.getElementById("userCredit").innerHTML = "This account have: " + credit + " Credit(s)"
}

LOGIN window.signchain.login()

document.getElementById("login").addEventListener("click", async function (e) {
e.preventDefault()
let login = await window.signchain.login();
userData = login;
document.getElementById("userInfos").innerHTML = "Address: " + userData.address + "<br>Public Key: " + userData.publicKey
getCredit();
getBalance();
});

This calls Waves Signer login() method, once logged in, the data (address and publicKey are stored in a userData variable, this information is displayed in the page and we call it the getCredit() and getBalance() methods we will define later

LOGOUT window.signchain.logout()

document.getElementById("logout").addEventListener("click", async function (e) {
e.preventDefault()
await window.signchain.logout();
storeData = null;
userData = null;
document.getElementById("userInfos").innerHTML = ""
document.getElementById("userBalance").innerHTML = ""
document.getElementById("userCredit").innerHTML = "";
});

HASH FILE window.signchain.hash()

document.getElementById("selectFile").addEventListener("change", async function (event) {
await window.signchain.hash(event.target.files[0], function (res) {
storeData = res;
document.getElementById("fileInfos").innerHTML = "Title: " + storeData.title + "<br>Hash sha256: " + storeData.hash
});
});

This listener listens to any changes on our input file field and calls the hash method from the signchain library, the response object will include the title, the hash and the file in byteArray if the file is under 10Mb or null for bigger file (at the moment we limitate IPFS upload at 10Mb), this data is stored in a storeData object and the title and hash are displayed on the page

CERTIFY THE FILE window.signchain.certify(data: object, pubKey: string, credit: boolean)

document.getElementById("certify").addEventListener("click", async function (e) {
e.preventDefault();
document.getElementById("result").innerHTML = "Transaction processing... ";
let credit = await window.signchain.checkUserCredit(userData.address);
let useCredit = false
if(credit > 0){
useCredit = true
}
let certify = await window.signchain.certify(storeData, userData.publicKey, useCredit);
if(certify.id){
document.getElementById("result").innerHTML = "Transaction ID: <a href=\"https://wavesexplorer.com/testnet/tx/" + certify.id + "\" target=\"_blank\">"+certify.id+"</a>";
}else{
document.getElementById("result").innerHTML = "Something went wront: " + certify;
}
getCredit(userData.address);
});

After clicking on the #certify button, the certify() method is called with the storeData object (which includes the result from the hashing function), the public key of the connected account and a boolean to use credits or tokens as parameters. In this example we'll first check if the Certification Credit balance of the user is superior to 0, if so, we use credit, if not, we use SIGN's Utility token as payment. storeData structure { buffer: ArrayBuffer(98093) {}, hash: "788ce1b308d265efad63373183ce563e6b90b2364a978cbfdb948314a72ac8f8", index: "a6049a50-a259-11ea-b11c-6d336bf17b27", title: "Send_Curl_Commands_Online.png" }

userData structure { address: "3MsG6jPNCrVJUtYB7XJBxS7utWsXAf4n9Vp", publicKey: "CqbpJxfYeagkaT7sXQpxsfJXS1ZPxjM1Giw94n3y4Tp5" } HASHING PROGRESS LISTENER hashingProgress: event During the file hashing process, which can take some time if the size of the file is big, the library emits an event called hashingProgress and you can use it as followed to display progress

document.addEventListener("hashingProgress", function (e) {
document.getElementById("fileInfos").innerHTML = e.detail+"%";
});

GET THE CERTIFICATION PRICE window.signchain.getCertificationFee()

let getPrice = async function(){
let cost = await window.signchain.getCertificationFee();
document.getElementById("certificationCost").innerHTML = "Cost per certification: " + cost + " SIGN"
}

GET THE USER SIGN TOKEN BALANCE window.signchain.getUserBalance(address: string)

let getBalance = async function(){
let balance = await window.signchain.getUserBalance(userData.address);
let balanceDecimal = balance / Math.pow(10, 8);
document.getElementById("userBalance").innerHTML = "This account have: " + balanceDecimal + " SIGN Token(s)"
}

GET THE USER CERTIFICATION CREDIT BALANCE window.signchain.checkUserCredit(address: string)

let getCredit = async function(){
let credit = await window.signchain.checkUserCredit(userData.address);
document.getElementById("userCredit").innerHTML = "This account have: " + credit + " Credit(s)"
}