CDD with the SDK
You ought to look at the previous chapter on KYC with the SDK first.
A CDD service provider is a privileged KYC service provider with a permissioned role to create DID's and add CDD claims to DID's.
See the introduction on identity for a refresher.
In particular:
- For brand new users of Polymesh, the CDD provider needs to:
- Create a new account controlled by the primary key asked by the user, and return the DID to the user;
- Add a CDD claim to that DID to verify they have gone through verification with them;
- For existing users that need a new CDD attestation, the CDD provider needs to re-verify the individual or entity and attach a new CDD claim to their existing DID;
See distribute with the SDK for a reminder of the process.
We assume the CDD service provider is named EzCdd and has a way to instantiate a Polymesh client.
- TypeScript
- JavaScript
const signingManagerEzCdd: LocalSigningManager =
await LocalSigningManager.create({
accounts: [
{
mnemonic: 'word51 word52 ...',
},
],
});
const apiEzCdd: Polymesh = await Polymesh.connect({
nodeUrl: 'wss://testnet-rpc.polymesh.live', // or your preferred node
signingManager: signingManagerEzCdd,
});
const signingManagerEzCdd = await LocalSigningManager.create({
accounts: [
{
mnemonic: 'word51 word52 ...',
},
],
});
const apiEzCdd = await Polymesh.connect({
nodeUrl: 'wss://testnet-rpc.polymesh.live', // or your preferred node
signingManager: signingManagerEzCdd,
});
How to create a new account
This part only applies if the user, say Bob, is brand new to Polymesh, or if Bob wants to create another account for himself.
In that case, the CDD provider needs to create an account. This is a privileged operation, too, one that only a CDD service provider can accomplish. The CDD provider needs to ask Bob for the public key, or address, he wishes to associate with the account.
Information collection
Bob creates a private key and returns the computed address. For instance:
- TypeScript
- JavaScript
const bobAddress: string = '5ED27JHWh9dPVnhvRfazMRNqrfMgcAUdvgD7hs3969PBuxqe'; // For instance
const bobAddress = '5ED27JHWh9dPVnhvRfazMRNqrfMgcAUdvgD7hs3969PBuxqe'; // For instance
The provider needs to confirm that this key is not yet assigned to any other account.
- TypeScript
- JavaScript
const bobKeyInfo: Account = apiEzCdd.accountManagement.getAccount({
address: bobAddress,
});
const bob: Identity = await bobKeyInfo.getIdentity();
assert(bob === null);
const bobKeyInfo = apiEzCdd.accountManagement.getAccount({
address: bobAddress,
});
const bob = await bobKeyInfo.getIdentity();
assert(bob === null);
Create the account
With the certainty that the key is not associated with any existing account, it is time to create a new account with this key:
- TypeScript
- JavaScript
const newAccountQueue: TransactionQueue<Identity> =
await apiEzCdd.identities.registerIdentity({
targetAccount: bobAddress,
});
const bob: Identity = await newAccountQueue.run();
const newAccountQueue = await apiEzCdd.identities.registerIdentity({
targetAccount: bobAddress,
});
const bob = await newAccountQueue.run();
So does Bob have a new account on-chain? Not yet, sadly. Or rather, fortunately. You see, it is worth repeating that all actions of consequence need approval on both ends, and this is no different here. Bob needs to use his private key to approve having it associated with this new account.
So, either Bob goes to his Portal, and looks for incoming authorisation requests, or Bob fires up his own apiBob
and uses the SDK. We assume that EzCdd gave him their const ezCddDid: string
.
- TypeScript
- JavaScript
const bobAccount: Account = apiBob.accountManagement.getSigningAccount();
const pendingAuthorizations: AuthorizationRequest[] =
await bobAccount.authorizations.getReceived();
const ezCddAuthorization: AuthorizationRequest = pendingAuthorizations.find(
(pendingAuthorization: AuthorizationRequest) => {
return pendingAuthorization.issuer.did === ezCddDid;
}
);
const acceptQueue: TransactionQueue<void> = await ezCddAuthorization.accept();
await acceptQueue.run();
const bobAccount = apiBob.accountManagement.getSigningAccount();
const pendingAuthorizations = await bobAccount.authorizations.getReceived();
const ezCddAuthorization = pendingAuthorizations.find(
(pendingAuthorization) => {
return pendingAuthorization.issuer.did === ezCddDid;
}
);
const acceptQueue = await ezCddAuthorization.accept();
await acceptQueue.run();
There is only a slight problem with the above. Bob has not yet received his CDD attestation, and therefore cannot publish a transaction to the Polymesh network. So we showed the above to stay in context, but really, Bob has to wait for the below CDD attestation to be published before he can approve, or reject, the account association.
Additionally, the address needs some POLYX to pay for transaction fees. Bob can purchase them from an exchange, or he can have an agreement with EzCdd to send some to his address. Once again, only after the CDD attestation has been published.
The CDD attestation
Before an account can transact on chain it requires a valid CDD claim to be added to the DID. The CDD provider constructs a transaction to add a claim type of CustomerDueDiligence
providing Bob's DID as the target and an expiry date for the claim. The claim can include an optional cddId
should the CDD provider wish to use it as a reference.
- TypeScript
- JavaScript
const nextYear: Date = new Date();
nextYear.setFullYear(nextYear.getFullYear() + 1);
const cddClaimQueue: TransactionQueue<void> = await apiEzCdd.claims.addClaims({
claims: [
{
claim: {
type: ClaimType.CustomerDueDiligence,
id: cddId,
},
target: bob.did,
expiry: nextYear,
},
],
});
await cddClaimQueue.run();
const nextYear = new Date();
nextYear.setFullYear(nextYear.getFullYear() + 1);
const cddClaimQueue = await apiEzCdd.claims.addClaims({
claims: [
{
claim: {
type: ClaimType.CustomerDueDiligence,
id: cddId,
},
target: bob.did,
expiry: nextYear,
},
],
});
await cddClaimQueue.run();
With this transaction submitted Bob is now CDD'd and can transact in materially-significant ways, including, as mentioned earlier by accepting the authorisation request.
Conclusion
We have seen how a CDD service provider needs to:
- create new accounts on Polymesh, and
- publish CDD attestations.