-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: better API surface and atomic features (#8)
* Intermediate refactoring work * Make defaultValues uniform * Fix up stuff * Add flag to disable node verifier process * All tests passing * Update comments * Yarn lint * Lint * Fix * Yarn version
- Loading branch information
Showing
21 changed files
with
672 additions
and
602 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
declined: | ||
- "@kiltprotocol/dip-sdk" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
export type * from "./types.js" | ||
|
||
export * as timeBoundDidSignature from "./timeBoundDidSignature.js" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { toChain as didToChain } from "@kiltprotocol/did" | ||
import { BN, u8aToHex } from "@polkadot/util" | ||
|
||
import type { | ||
DidUri, | ||
SignExtrinsicCallback, | ||
VerificationKeyRelationship, | ||
VerificationKeyType, | ||
} from "@kiltprotocol/types" | ||
import type { ApiPromise } from "@polkadot/api" | ||
import type { KeyringPair } from "@polkadot/keyring/types" | ||
import type { Call, Hash } from "@polkadot/types/interfaces" | ||
import type { Option } from "@polkadot/types-codec" | ||
import type { Codec } from "@polkadot/types-codec/types" | ||
|
||
const defaultValues = { | ||
accountIdRuntimeType: async () => "AccountId", | ||
blockNumberRuntimeType: async () => "u64", | ||
identityDetailsRuntimeType: async () => "Option<u128>", | ||
validUntilOffset: async () => new BN(50), | ||
} | ||
|
||
/** | ||
* The options regarding the provider chain provided when generating a cross-chain mortal DID signature. | ||
*/ | ||
export type TimeBoundDidSignatureProviderOpts = { | ||
/** The `DidUri` of the DIP subject that is performing the cross-chain operation. */ | ||
didUri: DidUri | ||
/** The `VerificationKeyRelationship` to use from the provided DID Document to sign the cross-chain payload. */ | ||
keyRelationship: VerificationKeyRelationship | ||
/** The list of `Signers` to use to sign the cross-chain payload. */ | ||
signer: SignExtrinsicCallback | ||
} | ||
/** | ||
* The options regarding the consumer chain when generating a cross-chain mortal DID signature. | ||
*/ | ||
export type TimeBoundDidSignatureConsumerOpts = { | ||
/** The runtime definition of an `AccountId`. If not provided, the `AccountId` type is used. */ | ||
accountIdRuntimeType?: string | ||
/** The `ApiPromise` instance of the provider chain. */ | ||
api: ApiPromise | ||
/** The runtime definition of a `BlockNumber`. If not provided, the `u64` type is used. */ | ||
blockNumberRuntimeType?: string | ||
/** The `Call` to DID-authorize. */ | ||
call: Call | ||
/** The genesis hash to use for the DID signature. If not provided, it is retrieved at runtime from the consumer chain. */ | ||
genesisHash?: Hash | ||
/** The runtime definition of the `IdentityDetails`. If not provided, the `Option<u128>` type is used. */ | ||
identityDetailsRuntimeType?: string | ||
/** The address of the submitter account on the consumer chain. */ | ||
submitterAddress: KeyringPair["address"] | ||
/** The block number until which the DID signature is to be considered fresh. If not provided, the latest best block number + an offset of 50 blocks is used. */ | ||
validUntil?: BN | ||
} | ||
/** | ||
* The options object provided when generating a cross-chain mortal DID signature. | ||
*/ | ||
export type TimeBoundDidSignatureOpts = { | ||
consumer: TimeBoundDidSignatureConsumerOpts | ||
provider: TimeBoundDidSignatureProviderOpts | ||
} | ||
/** | ||
* The cross-chain DID signature details to be included in the cross-chain DIP proof. | ||
*/ | ||
export type TimeBoundDidSignatureRes = { | ||
signature: Uint8Array | ||
type: VerificationKeyType | ||
validUntil: BN | ||
} | ||
/** | ||
* Generate a DID signature to be used in conjunction with a DIP proof to DID-authorize a cross-chain operation. | ||
* | ||
* @param params The signature generation parameters. | ||
* | ||
* @returns The generated cross-chain DID signature. | ||
*/ | ||
export async function generateDidSignature({ | ||
provider: { didUri, signer, keyRelationship }, | ||
consumer: { | ||
api, | ||
call, | ||
submitterAddress, | ||
// Optional | ||
accountIdRuntimeType, | ||
blockNumberRuntimeType, | ||
genesisHash, | ||
identityDetailsRuntimeType, | ||
validUntil, | ||
}, | ||
}: TimeBoundDidSignatureOpts): Promise<TimeBoundDidSignatureRes> { | ||
const blockNumber: BN = | ||
validUntil ?? | ||
(await api.query.system.number()) | ||
.toBn() | ||
.add(await defaultValues.validUntilOffset()) | ||
const genesis = genesisHash ?? (await api.query.system.blockHash(0)) | ||
const actualIdentityDetailsRuntimeType = | ||
identityDetailsRuntimeType ?? | ||
(await defaultValues.identityDetailsRuntimeType()) | ||
const identityDetails = ( | ||
await api.query.dipConsumer.identityEntries<Option<Codec>>( | ||
didToChain(didUri), | ||
) | ||
).unwrapOr(api.createType(actualIdentityDetailsRuntimeType, null)) | ||
|
||
const signaturePayload = api | ||
.createType( | ||
`(Call, ${identityDetailsRuntimeType}, ${ | ||
accountIdRuntimeType ?? (await defaultValues.accountIdRuntimeType()) | ||
}, ${ | ||
blockNumberRuntimeType ?? (await defaultValues.blockNumberRuntimeType()) | ||
}, Hash)`, | ||
[call, identityDetails, submitterAddress, blockNumber, genesis], | ||
) | ||
.toU8a() | ||
const { signature, keyType } = await signer({ | ||
data: signaturePayload, | ||
did: didUri, | ||
keyRelationship, | ||
}) | ||
return { | ||
validUntil: blockNumber, | ||
signature, | ||
type: keyType, | ||
} | ||
} | ||
|
||
/** | ||
* Transform a [[TimeBoundDidSignatureRes]] into an object that can be used to extend the basic DIP proof generated by [[generateDipSiblingBaseProof]]. | ||
* | ||
* @param params The cross-chain DID signature as generated by [[generateDidSignature]]. | ||
* | ||
* @returns The CODEC-ready version of the signature. | ||
*/ | ||
export function toChain( | ||
signature: TimeBoundDidSignatureRes, | ||
): Record<string, Codec> { | ||
const encodedSignature = { | ||
signature: { | ||
[signature.type]: u8aToHex(signature.signature), | ||
}, | ||
validUntil: signature.validUntil, | ||
} as any as Codec | ||
return { | ||
signature: encodedSignature, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
export type * from "./timeBoundDidSignature.js" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
export type * from "./types.js" | ||
|
||
export * from "./subjectIdentity.js" | ||
export * as extensions from "./extensions/index.js" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { toChain } from "@kiltprotocol/did" | ||
|
||
import type { PalletDidLookupLinkableAccountLinkableAccountId } from "@kiltprotocol/augment-api" | ||
import type { DidUri, DidKey } from "@kiltprotocol/types" | ||
import type { ApiPromise } from "@polkadot/api" | ||
import type { Hash } from "@polkadot/types/interfaces" | ||
import type { Codec } from "@polkadot/types-codec/types" | ||
|
||
/** | ||
* The options object provided when generating a DIP identity proof. | ||
*/ | ||
export type DipIdentityProofOpts = { | ||
/** The `DID` of the subject. */ | ||
didUri: DidUri | ||
/** The list of DID verification methods to include in the DIP proof and to reveal to the consumer chain. */ | ||
keyIds: Array<DidKey["id"]> | ||
/** A flag indicating whether the web3name should be included in the DIP proof. */ | ||
includeWeb3Name: boolean | ||
/** The list of accounts linked to the DID to include in the DIP proof and to reveal to the consumer chain. */ | ||
linkedAccounts: readonly PalletDidLookupLinkableAccountLinkableAccountId[] | ||
/** The `ApiPromise` instance for the provider chain. */ | ||
providerApi: ApiPromise | ||
/** The version of the DIP proof to generate. */ | ||
version: number | ||
} | ||
/** | ||
* The response object for a generated DIP proof. | ||
*/ | ||
export type DipIdentityProofRes = { | ||
/** The generated storage proof. */ | ||
proof: { | ||
/** The Merkle proof blinded (not revealed) leaves. */ | ||
blinded: Codec | ||
/** The Merkle proof revealed leaves. */ | ||
revealed: Codec | ||
} | ||
/** The Merkle root hash which the proof is anchored to. */ | ||
root: Hash | ||
} | ||
/** | ||
* Generate a DIP proof that reveals the specified information about the DID subject. | ||
* | ||
* @param params The DIP proof params. | ||
* | ||
* @returns The generated basic DIP proof that reveals the specified parts of the DID Document, optionally revealing its web3name and any linked accounts as specified. | ||
*/ | ||
export async function generateDipIdentityProof({ | ||
didUri, | ||
keyIds, | ||
includeWeb3Name, | ||
linkedAccounts, | ||
providerApi, | ||
version, | ||
}: DipIdentityProofOpts): Promise<DipIdentityProofRes> { | ||
const proof = await providerApi.call.dipProvider.generateProof({ | ||
identifier: toChain(didUri), | ||
version, | ||
proofKeys: keyIds.map((keyId) => keyId.substring(1)), | ||
accounts: linkedAccounts, | ||
shouldIncludeWeb3Name: includeWeb3Name, | ||
}) | ||
|
||
if (proof.isErr) { | ||
throw new Error(providerApi.findError(proof.asErr.toHex()).docs.join("\n")) | ||
} | ||
|
||
// TODO: Better way to cast this? | ||
const okProof = proof.asOk.toJSON() as any | ||
|
||
return okProof | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Copyright (c) 2024, BOTLabs GmbH. | ||
* | ||
* This source code is licensed under the BSD 4-Clause "Original" license | ||
* found in the LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
export type * from "./subjectIdentity.js" | ||
export type * from "./extensions/types.js" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.