Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework workshop to use new SDK methods #306

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1213e05
Draft
ChrisChinchilla Mar 21, 2024
3156664
Factor into tests
ChrisChinchilla Mar 26, 2024
9daa9a3
Update docs
ChrisChinchilla Mar 26, 2024
b2b37ba
Lint
ChrisChinchilla Mar 26, 2024
802d3ab
Draft
ChrisChinchilla Mar 28, 2024
3bb9568
Lint
ChrisChinchilla Mar 28, 2024
90dc96e
Update dependencies
ChrisChinchilla Apr 2, 2024
2e030ec
Revert
ChrisChinchilla Apr 2, 2024
02b7db9
Update docs
ChrisChinchilla Apr 2, 2024
0075bb4
Merge branch 'master' into 3130-add-the-new-dispatchas-function-in-th…
ChrisChinchilla Apr 2, 2024
8b3022c
Respond to feedback
ChrisChinchilla Apr 9, 2024
ec8eb9c
Merge branch '3130-add-the-new-dispatchas-function-in-the-documentati…
ChrisChinchilla Apr 9, 2024
3087168
Draft
ChrisChinchilla Apr 9, 2024
a1c2a2a
Test
ChrisChinchilla Apr 9, 2024
2112d9d
Draft
ChrisChinchilla Apr 11, 2024
742a679
Merge branch 'master' into 3130-add-the-new-dispatchas-function-in-th…
ChrisChinchilla Apr 15, 2024
75167da
Prettier
ChrisChinchilla Apr 15, 2024
13d7fc7
Merge branch '3130-add-the-new-dispatchas-function-in-the-documentati…
ChrisChinchilla Apr 15, 2024
77bb3b2
Fix mnemonic vs seed confusion
ntn-x2 Apr 16, 2024
c9454a2
Fixes!
ChrisChinchilla Apr 16, 2024
f3338d3
Tweaks
ChrisChinchilla Apr 16, 2024
a527385
Update code_examples/sdk_examples/src/workshop/attester/generateDid.ts
ChrisChinchilla Apr 16, 2024
8b730f7
Respond to feedback
ChrisChinchilla Apr 16, 2024
44c6d12
Merge branch '3130-add-the-new-dispatchas-function-in-the-documentati…
ChrisChinchilla Apr 16, 2024
d5e9dfd
Update
ChrisChinchilla Apr 17, 2024
d4f8c09
Update docs/develop/03_workshop/04_attester/01_account.md
ChrisChinchilla Apr 17, 2024
db6a5f5
Remove defunct function
ChrisChinchilla Apr 17, 2024
1c53279
Merge branch '3130-add-the-new-dispatchas-function-in-the-documentati…
ChrisChinchilla Apr 17, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
env:
NODE_OPTIONS: --unhandled-rejections=strict
BASE_MNEMONIC: ${{ secrets.BASE_MNEMONIC }}
FAUCET_SEED: ${{ secrets.FAUCET_SEED }}
run: |
yarn install --frozen-lockfile
yarn test ${{ matrix.test_case }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

export function main() {
const MAX_ACCEPTED_AGE = 60_000 // ms -> 1 minute
const MIN_ACCEPTED_AGE = -1_000 // allow for some imprecision in system time
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

import { blake2AsHex } from '@polkadot/util-crypto'

import * as Kilt from '@kiltprotocol/sdk-js'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

export function main(
submissions: Map<string, number>,
MAX_ACCEPTED_AGE: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useSignExtrinsicCallback } from './useExtrinsicCallback'
import { useStoreTxSignCallback } from './useStoreTxSignCallback'

// The _keyUri parameter is there to show that the DID key pair is looked up using the URI
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function lookupDidKeyPair(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_keyUri: Kilt.DidResourceUri
): Kilt.KiltKeyringPair {
return Kilt.Utils.Crypto.makeKeypairFromSeed()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import * as Kilt from '@kiltprotocol/sdk-js'

/* eslint-disable @typescript-eslint/no-unused-vars */
export async function main(): Promise<Kilt.ICType> {
const {
creator,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import * as Kilt from '@kiltprotocol/sdk-js'

export async function main({
Expand All @@ -12,14 +13,15 @@ export async function main({
domainLinkageCredential: Kilt.ICredential
}) {
const api = Kilt.ConfigService.get('api')

const { cTypeHash, claimHash } = Kilt.Attestation.fromCredentialAndDid(
domainLinkageCredential,
didUri
)
const attestationTx = api.tx.attestation.add(claimHash, cTypeHash, null)

// We authorize the call using the attestation key of the Dapps DID.
const extrinsic = api.tx.did.dispatchAs(dappAccount.address, attestationTx)

const submitTx = await Kilt.Did.authorizeTx(
ChrisChinchilla marked this conversation as resolved.
Show resolved Hide resolved
didUri,
attestationTx,
Expand All @@ -31,7 +33,7 @@ export async function main({
)

// Since DIDs can not hold any balance, we pay for the transaction using our blockchain account
const result = await Kilt.Blockchain.signAndSubmitTx(submitTx, dappAccount)
const result = await Kilt.Blockchain.signAndSubmitTx(extrinsic, dappAccount)

if (result.isError) {
console.log('Attestation failed')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import * as Kilt from '@kiltprotocol/sdk-js'

// `window` object: Should be used only in the following example.
Expand Down
6 changes: 2 additions & 4 deletions code_examples/sdk_examples/src/dapp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ export async function testDapp(account: Kilt.KeyringPair, wssAddress: string) {
await getFunds(account, dappAccount.address, 4)

// Create attester DID & ensure CType.
const { fullDid: attesterDid, mnemonic: attesterMnemonic } =
await createFullDid(dappAccount)
const { assertionMethod: assertionMethodKey } =
generateAttesterKeypairs(attesterMnemonic)
const { fullDid: attesterDid } = await createFullDid(dappAccount)
const { assertionMethod: assertionMethodKey } = generateAttesterKeypairs()

const domainLinkageCType = await getDomainLinkageCType()
const { domainLinkageCredential } = getDomainLinkageCredential({
Expand Down
50 changes: 8 additions & 42 deletions code_examples/sdk_examples/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import { testCoreFeatures } from './core_features'
import { testDapp } from './dapp'
import { testStaking } from './staking'
import { testWorkshop } from './workshop'

const MNEMONIC_ENV = 'BASE_MNEMONIC'
const FAUCET_SEED_ENV = 'FAUCET_SEED'

;(async () => {
const whichToRun = {
workshop: false,
Expand Down Expand Up @@ -57,48 +53,18 @@ const FAUCET_SEED_ENV = 'FAUCET_SEED'

envConfig()
await Kilt.init()

const wssAddress = process.env.WSS_ADDRESS || 'wss://peregrine.kilt.io'
const mnemonic = process.env[MNEMONIC_ENV]
const faucetSeed = process.env[FAUCET_SEED_ENV]

let baseAccountStrategy: 'base-mnemonic' | 'faucet-seed' = 'base-mnemonic'

// Faucet seed only a fallback if mnemonic is not specified. Otherwise mnemonic always wins.
if (!mnemonic && faucetSeed) {
baseAccountStrategy = 'faucet-seed'
} else if (!mnemonic && !faucetSeed) {
console.log(
`Neither base mnemonic "${MNEMONIC_ENV}" nor faucet seed "${FAUCET_SEED_ENV}" have been specified.
Please specify at least one of them.`
)
throw new Error('Account mnemonic or faucet seed is missing.')
}
const faucetSeed = process.env.FAUCET_SEED

let [workshopAccount, dappAccount, coreAccount] = new Array(3)

switch (baseAccountStrategy) {
case 'base-mnemonic': {
const baseAccount = new Kilt.Utils.Keyring({
type: 'sr25519',
ss58Format: Kilt.Utils.ss58Format
}).addFromMnemonic(mnemonic as string)
workshopAccount = baseAccount.derive('//workshop')
dappAccount = baseAccount.derive('//dapp')
coreAccount = baseAccount.derive('//core')

break
}
case 'faucet-seed': {
const faucetAccount = Kilt.Utils.Crypto.makeKeypairFromSeed(
hexToU8a(faucetSeed),
'sr25519'
) as Kilt.KeyringPair
workshopAccount = faucetAccount
dappAccount = faucetAccount
coreAccount = faucetAccount
}
}
const faucetAccount = Kilt.Utils.Crypto.makeKeypairFromSeed(
hexToU8a(faucetSeed),
'sr25519'
) as Kilt.KeyringPair
workshopAccount = faucetAccount
dappAccount = faucetAccount
coreAccount = faucetAccount

// If any of these flows fail, just send some more tokens to the account that is failing.
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { generateLightDid } from '../claimer/generateLightDid'
export async function attestCredential(
attesterAccount: Kilt.KiltKeyringPair,
attesterDid: Kilt.DidUri,
credential: Kilt.ICredential,
signCallback: Kilt.SignExtrinsicCallback
credential: Kilt.ICredential
): Promise<void> {
const api = Kilt.ConfigService.get('api')

Expand All @@ -23,12 +22,7 @@ export async function attestCredential(

// Create the tx and authorize it.
const tx = api.tx.attestation.add(claimHash, cTypeHash, null)
const extrinsic = await Kilt.Did.authorizeTx(
attesterDid,
tx,
signCallback,
attesterAccount.address
)
const extrinsic = api.tx.did.dispatchAs(attesterAccount.address, tx)

// Submit the tx to write the attestation to the chain.
console.log('Attester -> create attestation...')
Expand All @@ -39,6 +33,7 @@ export async function attestingFlow(
claimerDid: Kilt.DidUri,
attesterAccount: Kilt.KiltKeyringPair,
attesterDid: Kilt.DidUri,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
signCallback: Kilt.SignExtrinsicCallback
): Promise<Kilt.ICredential> {
// First the claimer.
Expand All @@ -50,7 +45,7 @@ export async function attestingFlow(
// ... send the request to the attester

// The attester checks the attributes and attests the provided credential.
await attestCredential(attesterAccount, attesterDid, credential, signCallback)
await attestCredential(attesterAccount, attesterDid, credential)

// Return the generated credential.
return credential
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as Kilt from '@kiltprotocol/sdk-js'
export function generateAccount(
mnemonic = Kilt.Utils.Crypto.mnemonicGenerate()
): {
account: Kilt.KiltKeyringPair
account: Kilt.KiltKeyringPair & { type: 'ed25519' }
mnemonic: string
} {
return {
Expand Down
56 changes: 22 additions & 34 deletions code_examples/sdk_examples/src/workshop/attester/generateDid.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,40 @@
import { config as envConfig } from 'dotenv'

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

import { config as envConfig } from 'dotenv'
import { generateAccount } from './generateAccount'
import { generateKeypairs } from './generateKeypairs'
ChrisChinchilla marked this conversation as resolved.
Show resolved Hide resolved

export async function createFullDid(
submitterAccount: Kilt.KiltKeyringPair
creatorAccount: Kilt.KiltKeyringPair & {
type: 'ed25519' | 'sr25519' | 'ecdsa'
}
): Promise<{
mnemonic: string
fullDid: Kilt.DidDocument
}> {
const api = Kilt.ConfigService.get('api')

const mnemonic = Kilt.Utils.Crypto.mnemonicGenerate()
const {
authentication,
keyAgreement,
assertionMethod,
capabilityDelegation
} = generateKeypairs(mnemonic)
// Get tx that will create the DID on chain and DID-URI that can be used to resolve the DID Document.
const fullDidCreationTx = await Kilt.Did.getStoreTx(
{
authentication: [authentication],
keyAgreement: [keyAgreement],
assertionMethod: [assertionMethod],
capabilityDelegation: [capabilityDelegation]
},
submitterAccount.address,
async ({ data }) => ({
signature: authentication.sign(data),
keyType: authentication.type
})
)
const verificationMethod = Kilt.Did.publicKeyToChain(creatorAccount)

await Kilt.Blockchain.signAndSubmitTx(fullDidCreationTx, submitterAccount)
const txs = [
api.tx.did.createFromAccount(verificationMethod),
api.tx.did.dispatchAs(
creatorAccount.address,
api.tx.did.setAttestationKey(verificationMethod)
)
]

const didUri = Kilt.Did.getFullDidUriFromKey(authentication)
console.log('Creating DID from account…')
await Kilt.Blockchain.signAndSubmitTx(
api.tx.utility.batch(txs),
creatorAccount
)
const didUri = Kilt.Did.getFullDidUriFromKey(creatorAccount)
const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(didUri))
const { document } = Kilt.Did.linkedInfoFromChain(encodedFullDid)
const { document: didDocument } = Kilt.Did.linkedInfoFromChain(encodedFullDid)

if (!document) {
if (!didDocument) {
throw new Error('Full DID was not successfully created.')
}

return { mnemonic, fullDid: document }
return { fullDid: didDocument }
}

// Don't execute if this is imported by another file.
Expand All @@ -59,10 +48,9 @@ if (require.main === module) {
// Load attester account
const accountMnemonic = process.env.ATTESTER_ACCOUNT_MNEMONIC as string
const { account } = generateAccount(accountMnemonic)
const { mnemonic, fullDid } = await createFullDid(account)
const { fullDid } = await createFullDid(account)

console.log('\nsave following to .env to continue\n')
console.error(`ATTESTER_DID_MNEMONIC="${mnemonic}"\n`)
console.error(`ATTESTER_DID_URI="${fullDid.uri}"\n`)
} catch (e) {
console.log('Error while creating attester DID')
Expand Down
5 changes: 2 additions & 3 deletions code_examples/sdk_examples/src/workshop/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ export async function testWorkshop(
await getFunds(account, attesterAccount.address, 5)

// Create attester DID & ensure CType.
const { fullDid: attesterDid, mnemonic: attesterMnemonic } =
await createFullDid(attesterAccount)
const { assertionMethod } = generateAttesterKeypairs(attesterMnemonic)
const { fullDid: attesterDid } = await createFullDid(attesterAccount)
const { assertionMethod } = generateAttesterKeypairs()

await ensureStoredCtype(
attesterAccount,
Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/07_dip/02_provider.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Decentralized Identity Provider (DIP) provider pallet
# Provider pallet

This pallet is a core component of the Decentralized Identity Provider protocol.
It enables a Substrate-based chain (provider) to bridge the identities of its users to other connected chains (consumers) trustlessly.
Expand All @@ -21,7 +21,7 @@ After removal, the identity becomes unusable cross-chain, although it will still
Being chain-agnostic, most of the runtime configurations must be passed to the pallet's `Config` trait. Specifically:

* `type CommitOriginCheck: EnsureOrigin<Self::RuntimeOrigin, Success = Self::CommitOrigin>`: The check ensuring a given runtime origin is allowed to generate and remove identity commitments.
* `type CommitOrigin: SubmitterInfo<Submitter = Self::AccountId>`: The resulting origin if `CommitOriginCheck` returns with errors. The origin is not required to be an `AccountId`, but must include information about the `AccountId` of the tx submitter.
* `type CommitOrigin: SubmitterInfo<Submitter = Self::AccountId>`: The resulting origin if `CommitOriginCheck` returns without errors. The origin is not required to be an `AccountId`, but must include information about the `AccountId` of the tx submitter.
* `type Identifier: Parameter + MaxEncodedLen`: The type of an identifier used to retrieve identity information about a subject.
* `type IdentityCommitmentGenerator: IdentityCommitmentGenerator<Self>`: The type responsible for generating identity commitments, given the identity information associated to a given `Identifier`.
* `type IdentityProvider: IdentityProvider<Self>`: The type responsible for retrieving the information associated to a subject given their identifier. The information can potentially be retrieved from any source, using a combination of on-chain and off-chain solutions.
Expand Down
9 changes: 2 additions & 7 deletions docs/develop/03_workshop/04_attester/01_account.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,9 @@ The `generateAccount` method returns an object with the following two properties
Generating these values takes two steps:

1. Create the `mnemonic` value using the `mnemonicGenerate()` method from the `Utils.Crypto` package.
2. The `account` value first needs a `keyring` value defined, which is a data structure for defining the key pair type with the following parameters:
2. The `account` value first needs a `keyring` value defined, which is a data structure for defining the key pair type. This example uses `ed25519`, but `sr25519`, `ed25519`, or `ecdsa` are also valid.
ChrisChinchilla marked this conversation as resolved.
Show resolved Hide resolved

1. `ss58Format`: Specifies the encoding format for the key. Substrate-based blockchains commonly use [SS58](https://docs.substrate.io/reference/address-formats/).
The value `38` represents the KILT blockchain prefix.
2. `type`: Specifies the user's cryptographic algorithm.
Substrate-based blockchains commonly use sr25519.

The function then returns the value using the `addFromMnemonic()` method to create a key pair for the address using the given mnemonic.
The function then returns the value using the `makeKeypairFromUri()` method to create a key pair for the address using the given mnemonic.

The rest of the code runs the `generateAccount` function and logs the results to the console.

Expand Down
Loading
Loading