On-going Monitoring

For a subset of attributes (ex: AML), the issuer is responsible to perform on-going monitoring and update the attribute values directly in the passport.

Only specific issuers are required to perform on-going monitoring.

Example (change of AML score)

import { ethers } from 'ethers';
import { BytesLike } from '@ethersproject/bytes';

const newAMLScore = hexZeroPad("0x05", 32); // new AML score
const accountToUpdate = "0x......."; // Wallet of the Passport holder to update
const issuer = new Wallet(ISSUER_PRIVATE_KEY); // Loading issuer account from their private key
const attrTypes = [utils.id("AML")];  // List of attributes types
const attrKeys = computeAttrKeys(accountAddress, attrTypes); // List of attributes Identifiers
const attrValues = [newAMLScore]; // List of attributes values
const verifiedAt = Math.floor(new Date().getTime() / 1000) - 60; // we substract 60 seconds to avoid errors during minting passport with long block time
const issuedAt = Math.floor(new Date().getTime() / 1000) - 60; // we substract 60 seconds to avoid errors during minting passport with long block time
const passportAddress = "0x2e779749c40CC4Ba1cAB4c57eF84d90755CC017d";
const chainId = 1; // 1 for Ethereum Mainnet
const fee = utils.parseEther("0"); // No fee to paid as this is an update performed by the issuer themselves
const did = ethers.constants.HashZero; // Leave empty
const signature = await signAttributes(
  accountAddress,
  issuer,
  attrKeys,
  attrValues,
  verifiedAt,
  issuedAt, 
  fee,
  passportAddress,
  chainId
)

const QUAD_PASSPORT_ABI = ''; // Can be retrieve at https://etherscan.io/address/0xebf9b4db6050517e402c578237326b793bf348ff#code

const passportContract = new ethers.Contract(
    passportAddress,
    QUAD_PASSPORT_ABI,
);

const tx = await passportContract.setAttributesIssuer(
    accountAddress,
    [
      attrKeys,
      attrValues,
      attrTypes,
      ethers.constants.HashZero, // Leave bytes32(0)
      0, // Leave 0
      verifiedAt,
      issuedAt,
      fee,
    ],
    sigIssuer,
    {
      value: fee,
    }
  )
)

await tx.wait();

export const signAttributes = async (
  accountAddress: string,
  issuer: typeof Signer,
  attrKeys: BytesLike[],
  attrValues: BytesLike[],
  verifiedAt: number,
  issuedAt: number,
  fee: any,
  passportAddress: string,
  chainId: number,
  did: BytesLike = utils.constants.HashZero,
): Promise<typeof DataHexString> => {
  const attrKeys: string[] = [];
  const attrValues: string[] = [];

  const hash = utils.keccak256(
    utils.defaultAbiCoder.encode(
      [
        "address",
        "bytes32[]",
        "bytes32[]",
        "bytes32",
        "uint256",
        "uint256",
        "uint256",
        "uint256",
        "address",
      ],
      [
        accountAddress,
        attrKeys,
        attrValues,
        did,
        verifiedAt,
        issuedAt,
        fee,
        chainId,
        passportAddress,
      ]
    )
  );

  const sig = await issuer.signMessage(utils.arrayify(hash));

  return sig;
};
`

Last updated