Skip to main content

Link an Account to a KILT DID

Sometimes there is the need to link a DID to an account publicly. The link makes it possible to lookup a DID for an account. The other directions is also possible. With a DID you can lookup a list of linked account.

Linking accounts can be useful when your account should have an identity. E.g. as a collator, you might want to provide some public information so that delegator can better decide who earned their stake.

An account can be linked to a DID in one of two ways. Either the account that sends the transaction links itself to the DID, or the sender is unrelated to the DID and a third account is linked. In the latter case, a challenge needs to be signed using the third account, to prove ownership.

The second option is useful in cases where the account that should be linked doesn't own KILT tokens and the transaction is paid for by a third party. This option also allows to link account schemes that are not native to the Spiritnet Blockchain. Right now the only other address scheme supported are ethereum accounts.

Don't use linked accounts for asset transfers

Don't use these linked accounts for asset transfers. Since these accounts are not limited to KILT accounts, but can be used on any chain, the recipient might not be able to access the transferred asset on other chains. When a link to an account on a different Polkadot chain is created, this account might only be usable on this specific chain.

If you want transfer assets to a DID have a look at the asset transfer service.

Linking the sender to a DID

Link the sender of the transaction to the DID. The sender will provide the deposit and pay the fees. They will also be linked to the DID.

import * as Kilt from '@kiltprotocol/sdk-js'

export async function linkDidToAccount(
did: Kilt.DidUri,
submitterAccount: Kilt.KiltKeyringPair,
signCallback: Kilt.SignExtrinsicCallback
): Promise<void> {
const api = Kilt.ConfigService.get('api')

// Authorizing the tx with the full DID and submitting it with the provided account
// results in the submitter's account being linked to the DID authorizing the operation.
const accountLinkingTx = api.tx.didLookup.associateSender()
const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(
did,
accountLinkingTx,
signCallback,
submitterAccount.address
)

await Kilt.Blockchain.signAndSubmitTx(
authorizedAccountLinkingTx,
submitterAccount
)
}

Linking an account to a DID

Link another account to the DID. The sender will provide the deposit and pay the fees, but will not be linked to the DID in any way. The account that should be linked must sign a challenge to prove that the account agrees to be linked.

The proof contains the DID that the account will be linked to and an expiration date (in terms of blocks), to prevent replay attacks. The proof will only be valid up until the blocknumber is reached.

With this option you can link addresses that are supported by the Spiritnet blockchain (Sr25519, Ed25519, Ecdsa), but also ethereum addresses.

import * as Kilt from '@kiltprotocol/sdk-js'

export async function linkAccountToDid(
did: Kilt.DidUri,
submitterAccount: Kilt.KiltKeyringPair,
linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' },
signCallback: Kilt.SignExtrinsicCallback
): Promise<void> {
const api = Kilt.ConfigService.get('api')

// Generate the parameters for the extrinsic that links account and DID.
// This will contain the signature of the account that will be linked to the DID
// and therefore signals the agreement of the account to be linked.
const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(
linkedAccount.address,
did,
async (payload) => linkedAccount.sign(payload)
)

// Afterwards we build the extrinsic using the parameters from above.
const accountLinkingTx = await api.tx.didLookup.associateAccount(
...accountLinkingParameters
)

// Next the DID signs the extrinsic.
// This signals the agreement of the DID owner to be linked to the account.
const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(
did,
accountLinkingTx,
signCallback,
submitterAccount.address
)

// finally we need to submit everything to the blockchain, so that the link gets
// registered.
// This account will provide the required deposit and pay the fees.
await Kilt.Blockchain.signAndSubmitTx(
authorizedAccountLinkingTx,
submitterAccount
)
}