# KILT protocol
## Index
- 1. Sporran & KILT login
- 1.1. APIs flow **[developers]**
- 1.2. Install Sporran & create identity **[users]**
- 2. AssetDID for NFTs
- 2.1. Sign the assetDID and make identity B act on behalf of identity A **[developers]**
- 2.1.1. Make identity B act on behalf of identity A
- 2.1.2. Sign the assetDID
- 2.2. Verify the attester identity and the artist claim **[users]**
- 2.2.1. How to verify that the NFT has been attested by Public Pressure through Kilt Protocol
- 2.2.2. How to view the claim content and see who is the artist
## 1. Sporran & KILT login
Public Pressure's brand new feature consists in an alternative way to login. This is made through Sporran extension, which is available [for Firefox](https://addons.mozilla.org/en-US/firefox/addon/sporran/) and [for Chrome](https://chrome.google.com/webstore/detail/sporran/djdnajgjcbjhhbdblkegbcgodlkkfhcl).
This document intends to guide you through the entire implementation process and teaches the final user how to setup and use the extension.
### 1.1. APIs flow [developers]
[Here is the reference repository](https://github.com/KILTprotocol/nextjs-sporran-credential-login). This project implements both frontend and backend side.
- On the BE side, you need to have a verifier identity in order to verify the presentation provided by the user during the login process. The verifier identity needs to have an on-chain DID, which costs around 2-3 KILTs. If you're testing on the Peregrine (the testnet), you can use [the faucet](https://faucet.peregrine.kilt.io); otherwise, if you're on the Spiritnet (the mainnet) you need to pay in order to create an on-chain DID.
- In your BE, you need to store some secrets related to the verifier identity. To be precise, you need:
- its mnemonic
- its address
- its DID
### 1.2. Install Sporran & create identity [users]
Once the extension is installed in your browser, you need to create an identity. If you already have one, you can import it.
- While creating the identity, Sporran provides you a mnemonic, which is a 12-words secret phrase that you need to carefully store in a safe place. If you lose your mnemonic, you lose your identity!
- Once created the account, Sporran asks you to provide a local password for the extension. This step is less important than the mnemonic; if you lose the local password you don't lose your identity, but you need to re-import the mnemonic.
- Now that you have an identity, you need to add a credential to the extension. In order to be able to login to Public Pressure, you need an `email` credential. To do so, open the Sporran extension and click on `Show credentials` and `How to Get Credentials`. This will redirect you to [socialkyc.io](https://socialkyc.io/). Follow the instructions and select `>Email Address`: **you need to use the same email address you have in your Public Pressure account**. Following the instructions, socialKYC will send you a confirmation email, so confirm it and this will generate a credential file. We recommend you to download it and store it carefully. Finally, import the credential and your setup is done!
- Visit [Public Pressure's login page](https://app.publicpressure.io/login) and click on `Login with KILT`. This will open up the Sporran extension; be sure to check the email address you just added, confirm with your local password and you're logged in.
## 2. AssetDID for NFTs
### 2.1. Sign the assetDID and make identity B act on behalf of identity A [developers]
[Here is the reference repository](https://github.com/BTE-Trusted-Entity/asset-did-credentials). This repository uses the Sporran extension to sign AssetDIDs; Public Pressure automated this process for each NFT deployed on each chain.
### 2.1.1. Make identity B act on behalf of identity A
The reason we need to make an identity B act on behalf of identity A (a "delegation" mechanism) is that if the identity gets compromised, at least this is a rotatable credential: identity A can revoke permissions to attest from identity B, and "delegate" to a newer identity C.
- We need to set the assertion of identity B as the attestation key of identity A. Here is a sample snippet:
```javascript
import {
Blockchain,
ConfigService,
Did,
connect,
disconnect
} from '@kiltprotocol/sdk-js';
const WSS_ADDRESS = "wss://peregrine.kilt.io/parachain-public-ws";
const mnemonicA = "one two three four five six seven eight nine ten eleven twelve";
const mnemonicB = "thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone twentytwo twentythree twentyfour";
const didA = "did:kilt:did";
const main = async () => {
const api = ConfigService.get('api');
const { authentication: authenticationA } = await getKeypairs(mnemonicA);
const { assertion: assertionB } = await getKeypairs(mnemonicB);
const account = await getAccount(mnemonicB);
const extrinsic = api.tx.did.setAttestationKey(Did.publicKeyToChain(assertionB));
const tx = await Did.authorizeTx(
didA,
extrinsic,
await authenticationSigner({
authentication: authenticationA
}),
account.address
);
try {
const result = await Blockchain.signAndSubmitTx(tx, account);
console.log({ result });
} catch (error) {
console.log({ error });
return false;
}
};
connect(WSS_ADDRESS);
main();
disconnect();
```
Be sure to replace the value of `WSS_ADDRESS`, `mnemonicA`, `mnemonicB` and `didA`.
- The process needed to sign the assetDID can be resumed by this snippet:
```javascript
export const signAssetDID = async (contractAddress, chainId, artist) => {
const api = ConfigService.get('api');
const { assertion } = await getKeypairs(VERIFIER_MNEMONIC_B);
const assetDidUri = `did:asset:eip155:${chainId}.erc721:${contractAddress}`;
const claim = {
cTypeHash: CType.idToChain(CTYTPEHASH),
contents: { artist },
subject: assetDidUri
};
const credential = PublicCredential.fromClaim(claim);
const extrinsic = api.tx.publicCredentials.add(PublicCredential.toChain(credential));
const fullDid: any = await Did.resolve(VERIFIER_DID_URI_A);
const sign: any = ({ data, keyRelationship }) => {
const signingKey: any =
keyRelationship === 'assertionMethod' ?
assertion :
[];
const signature = signingKey.sign(data, { withType: false });
const keyType = signingKey.type;
const keyUri = `${fullDid.uri}${fullDid.document.assertionMethod[0].id}`;
return { signature, keyType, keyUri };
};
const account = await getAccount(VERIFIER_MNEMONIC_B);
const authorized = await Did.authorizeTx(
VERIFIER_DID_URI_A,
extrinsic,
sign,
account.address
);
const signedTx = await authorized.signAsync(account, {});
try {
await Blockchain.submitSignedTx(signedTx);
} catch (error) {
// console.log({ KILTerror: error });
return false;
}
return signedTx.hash.toHex();
};
```
This will return the transaction hash. You can visit the subscan website:
- [Peregrine](https://kilt-testnet.subscan.io/)
- [Spiritnet](https://spiritnet.subscan.io/)
and search for the transaction hash, which is called "extrinsic".
### 2.2. Verify the attester identity and the artist claim [users]
#### 2.2.1. How to verify that the NFT has been attested by Public Pressure through Kilt Protocol
- Visiting the NFT page, under the voice `Kilt attestations`, you can see one or more button that proves you the attestation process of the NFT, attested by Public Pressure. The Public Pressure's DID is `did:kilt:4qHgPwSDG7gxvCWSSeiNaW22DvApUFCFFyfqieEGrH3AshvK`: this identifies uniquely Public Pressure, [as verifiable here](https://w3n.id/publicpressure).
- When you click the button, it will redirects you to [subscan](https://spiritnet.subscan.io), pointing to the extrinsic in which Public Pressure verified this NFT. There you should see a `Block number` section: copy it's value.
- Visit [polkadot website](https://polkadot.js.org/apps/#/explorer): here you can view all information related to the specific block. **Be sure you're on the right chain, which should be `Kilt Spiritnet` (under `Polkadot & parachains`)**, and eventually press `Switch` in the top-left corner, and paste the block number you just copied in the top-right corner and press enter.
- In the left column, open the link in the third voice, called `did.submitDidCall`.
- Here you can see the identity of the attester, under the voice `did: AccountId32`. Its value should be as the one in the top of this document, `4qHgPwSDG7gxvCWSSeiNaW22DvApUFCFFyfqieEGrH3AshvK`.
- If you're curious, here you can also see the assetDID under the voice `subject: Bytes`. Its format is `did:asset:chainID.tokenStandard:contractAddress`. Back to the NFT page:
- if you clicked Moonbeam, the `chainID` is `1284`
- if you clicked Exosama, the `chainID` is `2109`
- The `contractAddress` is the actual address in which the NFT has been minted.
#### 2.2.2. How to view the claim content and see who is the artist
- Visiting the NFT page and following the button link under `Kilt attestations` you can see a voice called `Parameter`: scrolling down, there's a voice called `"claims"`. It's value is the hexadecimal encoding of the artist.
- You can search online for an hexadecimal decoder, paste the value and see who the artist is.