Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ If a call requires a DID assertion method key, either `ATT_MNEMONIC` or `DID_MNE

To run this script, execute `yarn call-authorize` and then copy the HEX-encoded operation to be submitted via [PolkadotJS Apps][polkadot-apps] in `Developer > Extrinsics > Decode`, using the account specified in `SUBMITTER_ADDRESS`.

## Generate a DIP signature with a DID key
## Generate a DIP signature for a sibling parachain with a DID key

This script signs any valid HEX-encoded call of any other parachain with the right key re-generated from the provided seedling information, i.e., either with the provided mnemonic, or with the provided combination of base mnemonic and derivation path.

Expand All @@ -68,6 +68,8 @@ Once the right call (i.e., the right pallet and right method) with the right par

The following env variables are required:

- `RELAY_WS_ADDRESS`: The endpoint address of the relaychain.
- `PROVIDER_WS_ADDRESS`: The endpoint address of the DIP provider chain.
- `CONSUMER_WS_ADDRESS`: The endpoint address of the consumer chain on which DIP is to be used.
- `SUBMITTER_ADDRESS`: The address (encoded with the target chain network prefix `38`) that is authorized to submit the transaction on the target chain.
- `ENCODED_CALL`: The HEX-encoded call to DID-sign.
Expand All @@ -76,16 +78,47 @@ The following env variables are required:

The following optional env variables can be passed:

- `IDENTITY_DETAILS`: The runtime type definition of the identity details stored on the consumer chain, according to the DIP protocol. It defaults to `u128`, which represents a simple nonce value.
- `IDENTITY_DETAILS`: The runtime type definition of the identity details stored on the consumer chain, according to the DIP protocol. It defaults to `Option<u128>`, which represents a simple (optional) nonce value.
- `ACCOUNT_ID`: The runtime type definition of account address on the consumer chain. It defaults to `AccountId32`, which is the default of most Substrate-based chains. Some chains might use `AccountId20`.
- `INCLUDE_WEB3NAME`: Wether the web3name of the DID should be added to the DIP proof of not. Values can be anything that is truthy in JS terms. It defaults to `false`. **The proof generation will fail if this value is `true` but the DID does not have a web3name.**

As with DID creation, there is no strong requirement on what other variables must be set.
Depending on the expected key to be used to sign the call, the right mnemonic or the right base mnemonic + derivation path must be provided.

For instance, if a call requires a DID authentication key, either `AUTH_MNEMONIC` or `DID_MNEMONIC` and `AUTH_DERIVATION_PATH` must be specified.
If a call requires a DID assertion method key, either `ATT_MNEMONIC` or `DID_MNEMONIC` and `ATT_DERIVATION_PATH` must be specified.

To run this script, execute `yarn dip-sign` and then copy the generated signature and block number to be submitted via [PolkadotJS Apps][polkadot-apps] as part of the DIP tx submission process, using the account specified in `SUBMITTER_ADDRESS`.
To run this script, execute `yarn dip-sign:sibling` and then copy the generated signature and block number to be submitted via [PolkadotJS Apps][polkadot-apps] as part of the DIP tx submission process, using the account specified in `SUBMITTER_ADDRESS`.

## Generate a DIP signature for the parent relaychain with a DID key

This script signs any valid HEX-encoded call of the parent relaychain with the right key re-generated from the provided seedling information, i.e., either with the provided mnemonic, or with the provided combination of base mnemonic and derivation path.

Valid HEX-encoded calls can be generated by interacting with [PolkadotJS Apps][polkadot-apps] under the `Developer > Extrinsics` menu.
Once the right call (i.e., the right pallet and right method) with the right parameters has been specified, the HEX-encoded value under `encoded call data` can be copied and passed as parameter to this script.

The following env variables are required:

- `RELAY_WS_ADDRESS`: The endpoint address of the relaychain.
- `PROVIDER_WS_ADDRESS`: The endpoint address of the DIP provider chain.
- `SUBMITTER_ADDRESS`: The address (encoded with the target chain network prefix `38`) that is authorized to submit the transaction on the target chain.
- `ENCODED_CALL`: The HEX-encoded call to DID-sign.
- `DID_URI`: The URI of the DID authorizing the operation
- `VERIFICATION_METHOD`: The verification method of the DID key to use. Because this script is not able to automatically derive the DID key required to sign the call on the target chain, it has to be explicitely set with this variable. Example values are `authentication`, `assertionMethod`, and `capabilityDelegation`.

The following optional env variables can be passed:

- `IDENTITY_DETAILS`: The runtime type definition of the identity details stored on the consumer chain, according to the DIP protocol. It defaults to `Option<u128>`, which represents a simple (optional) nonce value.
- `ACCOUNT_ID`: The runtime type definition of account address on the consumer chain. It defaults to `AccountId32`, which is the default of most Substrate-based chains. Some chains might use `AccountId20`.
- `INCLUDE_WEB3NAME`: Wether the web3name of the DID should be added to the DIP proof of not. Values can be anything that is truthy in JS terms. It defaults to `false`. **The proof generation will fail if this value is `true` but the DID does not have a web3name.**

As with DID creation, there is no strong requirement on what other variables must be set.
Depending on the expected key to be used to sign the call, the right mnemonic or the right base mnemonic + derivation path must be provided.

For instance, if a call requires a DID authentication key, either `AUTH_MNEMONIC` or `DID_MNEMONIC` and `AUTH_DERIVATION_PATH` must be specified.
If a call requires a DID assertion method key, either `ATT_MNEMONIC` or `DID_MNEMONIC` and `ATT_DERIVATION_PATH` must be specified.

To run this script, execute `yarn dip-sign:parent` and then copy the generated signature and block number to be submitted via [PolkadotJS Apps][polkadot-apps] as part of the DIP tx submission process, using the account specified in `SUBMITTER_ADDRESS`.

## Change a DID key

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"att-key-set": "ts-node src/att-key-set.ts",
"del-key-set": "ts-node src/del-key-set.ts",
"did-create": "ts-node src/did-create.ts",
"dip-sign": "ts-node src/dip-sign.ts",
"dip-sign:parent": "ts-node src/dip-parent-sign.ts",
"dip-sign:sibling": "ts-node src/dip-sibling-sign.ts",
"call-authorize": "ts-node src/call-sign",
"check-ts": "tsc src/** --skipLibCheck --noEmit",
"lint": "eslint . --ext .ts --format=codeframe",
Expand All @@ -30,4 +31,4 @@
"typescript": "^4.7.4"
},
"packageManager": "yarn@3.6.0"
}
}
112 changes: 112 additions & 0 deletions src/dip-parent-sign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import 'dotenv/config'

import * as Kilt from '@kiltprotocol/sdk-js'
import { ApiPromise, WsProvider } from '@polkadot/api'
import { dipProviderCalls, types } from '@kiltprotocol/type-definitions'
import { cryptoWaitReady } from '@polkadot/util-crypto'

import * as utils from './utils'

async function main() {
const relayWsAddress = process.env[utils.envNames.relayWsAddress]
const providerWsAddress = process.env[utils.envNames.providerWsAddress]
if (relayWsAddress === undefined) {
throw new Error(
`No ${utils.envNames.relayWsAddress} env variable specified.`
)
}
if (providerWsAddress === undefined) {
throw new Error(
`No ${utils.envNames.providerWsAddress} env variable specified.`
)
}
const submitterAddress = process.env[
utils.envNames.submitterAddress
] as Kilt.KiltAddress
if (submitterAddress === undefined) {
throw new Error(
`No "${utils.envNames.submitterAddress}" env variable specified.`
)
}

await cryptoWaitReady()
// eslint-disable-next-line max-len
const authKey =
utils.generateAuthenticationKey() ??
Kilt.Utils.Crypto.makeKeypairFromUri('//Alice')
const assertionKey = utils.generateAttestationKey()
const delegationKey = utils.generateDelegationKey()

const didUri = process.env[utils.envNames.didUri] as Kilt.DidUri
if (didUri === undefined) {
throw new Error(`"${utils.envNames.didUri}" not specified.`)
}

const consumerApi = await ApiPromise.create({
provider: new WsProvider(relayWsAddress),
})

const encodedCall = process.env[utils.envNames.encodedCall]
const decodedCall = consumerApi.createType('Call', encodedCall)

const [requiredKey, verificationMethod] = (() => {
const providedMethod = utils.parseVerificationMethod()
switch (providedMethod) {
case 'authentication':
return [authKey, providedMethod]
case 'assertionMethod':
return [assertionKey, providedMethod]
case 'capabilityDelegation':
return [delegationKey, providedMethod]
}
})()
if (requiredKey === undefined) {
throw new Error(
'The DID key to authorize the operation is not part of the DID Document. Please add such a key before re-trying.'
)
}

const providerApi = await ApiPromise.create({
provider: new WsProvider(providerWsAddress),
runtime: dipProviderCalls,
types,
})
const didKeyId = utils.computeDidKeyId(
providerApi,
requiredKey.publicKey,
requiredKey.type
)

const includeWeb3Name =
process.env[utils.envNames.includeWeb3Name]?.toLowerCase() === 'true' ||
utils.defaults.includeWeb3Name
const signedExtrinsic = await utils.generateParentDipTx(
consumerApi,
providerApi,
didUri,
decodedCall,
submitterAddress,
didKeyId,
verificationMethod,
includeWeb3Name,
utils.getKeypairTxSigningCallback(requiredKey)
)

const encodedOperation = signedExtrinsic.toHex()
console.log(
`
DIP tx: ${encodedOperation}.
Please add these details to the "dipConsumer.dispatchAs" function in PolkadotJS.
`
)
console.log(
`Direct link: ${utils.generatePolkadotJSLink(
relayWsAddress,
encodedOperation
)}`
)
}

main()
.catch((e) => console.error(e))
.then(() => process.exit(0))
61 changes: 49 additions & 12 deletions src/dip-sign.ts → src/dip-sibling-sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,30 @@ import 'dotenv/config'

import * as Kilt from '@kiltprotocol/sdk-js'
import { ApiPromise, WsProvider } from '@polkadot/api'
import { dipProviderCalls, types } from '@kiltprotocol/type-definitions'
import { cryptoWaitReady } from '@polkadot/util-crypto'

import * as utils from './utils'

async function main() {
const relayWsAddress = process.env[utils.envNames.relayWsAddress]
const providerWsAddress = process.env[utils.envNames.providerWsAddress]
const consumerWsAddress = process.env[utils.envNames.consumerWsAddress]
if (relayWsAddress === undefined) {
throw new Error(
`No ${utils.envNames.relayWsAddress} env variable specified.`
)
}
if (providerWsAddress === undefined) {
throw new Error(
`No ${utils.envNames.providerWsAddress} env variable specified.`
)
}
if (consumerWsAddress === undefined) {
throw new Error(
`No ${utils.envNames.consumerWsAddress} env variable specified.`
)
}
const api = await ApiPromise.create({
provider: new WsProvider(consumerWsAddress),
})

const submitterAddress = process.env[
utils.envNames.submitterAddress
Expand All @@ -25,6 +36,7 @@ async function main() {
)
}

await cryptoWaitReady()
// eslint-disable-next-line max-len
const authKey =
utils.generateAuthenticationKey() ??
Expand All @@ -37,8 +49,12 @@ async function main() {
throw new Error(`"${utils.envNames.didUri}" not specified.`)
}

const consumerApi = await ApiPromise.create({
provider: new WsProvider(consumerWsAddress),
})

const encodedCall = process.env[utils.envNames.encodedCall]
const decodedCall = api.createType('Call', encodedCall)
const decodedCall = consumerApi.createType('Call', encodedCall)

const [requiredKey, verificationMethod] = (() => {
const providedMethod = utils.parseVerificationMethod()
Expand All @@ -56,26 +72,47 @@ async function main() {
'The DID key to authorize the operation is not part of the DID Document. Please add such a key before re-trying.'
)
}
const [dipSignature, blockNumber] = await utils.generateDipTxSignature(
api,

const providerApi = await ApiPromise.create({
provider: new WsProvider(providerWsAddress),
runtime: dipProviderCalls,
types,
})
const didKeyId = utils.computeDidKeyId(
providerApi,
requiredKey.publicKey,
requiredKey.type
)

const includeWeb3Name =
process.env[utils.envNames.includeWeb3Name]?.toLowerCase() === 'true' ||
utils.defaults.includeWeb3Name
const signedExtrinsic = await utils.generateSiblingDipTx(
await ApiPromise.create({ provider: new WsProvider(relayWsAddress) }),
providerApi,
consumerApi,
didUri,
decodedCall,
submitterAddress,
didKeyId,
verificationMethod,
includeWeb3Name,
utils.getKeypairTxSigningCallback(requiredKey)
)

const encodedOperation = signedExtrinsic.toHex()
console.log(
`
DID signature for submission via DIP: ${JSON.stringify(
utils.hexifyDipSignature(dipSignature),
null,
2
)}.
Block number used for signature generation: ${blockNumber.toString()}.
DIP tx: ${encodedOperation}.
Please add these details to the "dipConsumer.dispatchAs" function in PolkadotJS.
`
)
console.log(
`Direct link: ${utils.generatePolkadotJSLink(
consumerWsAddress,
encodedOperation
)}`
)
}

main()
Expand Down
Loading