Skip to content

Commit

Permalink
Add basic demo flow
Browse files Browse the repository at this point in the history
  • Loading branch information
nmattia committed Oct 24, 2023
1 parent 07bd86b commit 7f735a5
Show file tree
Hide file tree
Showing 18 changed files with 984 additions and 328 deletions.
50 changes: 50 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
"watch:showcase": "astro check --root ./src/showcase --watch",
"watch": "npm run check -- --watch",
"opts": "NODE_OPTIONS='--loader ts-node/esm --experimental-specifier-resolution=node' \"$@\"",
"generate": "npm run generate:types && npm run generate:js",
"generate": "npm run generate:types && npm run generate:js && npm run generate:types-issuer && npm run generate:js-issuer",
"generate:types": "didc bind ./src/internet_identity/internet_identity.did -t ts > src/frontend/generated/internet_identity_types.d.ts",
"generate:js": "didc bind ./src/internet_identity/internet_identity.did -t js > src/frontend/generated/internet_identity_idl.js",
"generate:types-issuer": "didc bind ./demos/vc_issuer/vc_issuer.did -t ts > src/frontend/generated/vc_issuer_types.d.ts",
"generate:js-issuer": "didc bind ./demos/vc_issuer/vc_issuer.did -t js > src/frontend/generated/vc_issuer_idl.js",
"build:showcase": "tsc --noEmit && astro check --root ./src/showcase && astro build --root ./src/showcase",
"preview:showcase": "astro preview --root ./src/showcase",
"screenshots": "npm run opts -- ./src/frontend/screenshots.ts",
Expand All @@ -30,6 +32,7 @@
"format-check": "prettier --check src/showcase src/frontend tsconfig.json .eslintrc.json vite.config.ts vite.plugins.ts vitest.config.ts demos"
},
"devDependencies": {
"@dfinity/auth-client": "^0.19.2",
"@types/html-minifier-terser": "^7.0.0",
"@types/selenium-standalone": "^7.0.1",
"@types/ua-parser-js": "^0.7.36",
Expand Down Expand Up @@ -60,6 +63,7 @@
"bip39": "^3.0.4",
"buffer": "^6.0.3",
"idb-keyval": "^6.2.1",
"jose": "^4.15.2",
"lit-html": "^2.7.2",
"process": "^0.11.10",
"qr-creator": "^1.0.0",
Expand Down
79 changes: 79 additions & 0 deletions src/frontend/generated/vc_issuer_idl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
export const idlFactory = ({ IDL }) => {
const Icrc21ConsentPreferences = IDL.Record({ 'language' : IDL.Text });
const Icrc21ConsentMessageRequest = IDL.Record({
'arg' : IDL.Vec(IDL.Nat8),
'method' : IDL.Text,
'preferences' : Icrc21ConsentPreferences,
});
const Icrc21ConsentInfo = IDL.Record({
'consent_message' : IDL.Text,
'language' : IDL.Text,
});
const Icrc21ErrorInfo = IDL.Record({
'description' : IDL.Text,
'error_code' : IDL.Nat64,
});
const Icrc21Error = IDL.Variant({
'GenericError' : Icrc21ErrorInfo,
'MalformedCall' : Icrc21ErrorInfo,
'NotSupported' : Icrc21ErrorInfo,
'Forbidden' : Icrc21ErrorInfo,
});
const Icrc21ConsentMessageResponse = IDL.Variant({
'Ok' : Icrc21ConsentInfo,
'Err' : Icrc21Error,
});
const SignedIdAlias = IDL.Record({
'credential_jws' : IDL.Text,
'id_alias' : IDL.Principal,
'id_dapp' : IDL.Principal,
});
const CredentialSpec = IDL.Record({ 'info' : IDL.Text });
const GetCredentialRequest = IDL.Record({
'signed_id_alias' : SignedIdAlias,
'prepared_context' : IDL.Opt(IDL.Vec(IDL.Nat8)),
'credential_spec' : CredentialSpec,
});
const IssuedCredentialData = IDL.Record({ 'vc_jws' : IDL.Text });
const IssueCredentialError = IDL.Variant({
'Internal' : IDL.Text,
'SignatureNotFound' : IDL.Text,
'InvalidIdAlias' : IDL.Text,
'UnauthorizedSubject' : IDL.Text,
'UnknownSubject' : IDL.Text,
});
const GetCredentialResponse = IDL.Variant({
'Ok' : IssuedCredentialData,
'Err' : IssueCredentialError,
});
const PrepareCredentialRequest = IDL.Record({
'signed_id_alias' : SignedIdAlias,
'credential_spec' : CredentialSpec,
});
const PreparedCredentialData = IDL.Record({
'prepared_context' : IDL.Opt(IDL.Vec(IDL.Nat8)),
});
const PrepareCredentialResponse = IDL.Variant({
'Ok' : PreparedCredentialData,
'Err' : IssueCredentialError,
});
return IDL.Service({
'add_employee' : IDL.Func([IDL.Principal], [IDL.Text], []),
'consent_message' : IDL.Func(
[Icrc21ConsentMessageRequest],
[Icrc21ConsentMessageResponse],
[],
),
'get_credential' : IDL.Func(
[GetCredentialRequest],
[GetCredentialResponse],
['query'],
),
'prepare_credential' : IDL.Func(
[PrepareCredentialRequest],
[PrepareCredentialResponse],
[],
),
});
};
export const init = ({ IDL }) => { return []; };
63 changes: 63 additions & 0 deletions src/frontend/generated/vc_issuer_types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Principal } from '@dfinity/principal';
import type { ActorMethod } from '@dfinity/agent';

export interface CredentialSpec { 'info' : string }
export interface GetCredentialRequest {
'signed_id_alias' : SignedIdAlias,
'prepared_context' : [] | [Uint8Array | number[]],
'credential_spec' : CredentialSpec,
}
export type GetCredentialResponse = { 'Ok' : IssuedCredentialData } |
{ 'Err' : IssueCredentialError };
export interface Icrc21ConsentInfo {
'consent_message' : string,
'language' : string,
}
export interface Icrc21ConsentMessageRequest {
'arg' : Uint8Array | number[],
'method' : string,
'preferences' : Icrc21ConsentPreferences,
}
export type Icrc21ConsentMessageResponse = { 'Ok' : Icrc21ConsentInfo } |
{ 'Err' : Icrc21Error };
export interface Icrc21ConsentPreferences { 'language' : string }
export type Icrc21Error = { 'GenericError' : Icrc21ErrorInfo } |
{ 'MalformedCall' : Icrc21ErrorInfo } |
{ 'NotSupported' : Icrc21ErrorInfo } |
{ 'Forbidden' : Icrc21ErrorInfo };
export interface Icrc21ErrorInfo {
'description' : string,
'error_code' : bigint,
}
export type IssueCredentialError = { 'Internal' : string } |
{ 'SignatureNotFound' : string } |
{ 'InvalidIdAlias' : string } |
{ 'UnauthorizedSubject' : string } |
{ 'UnknownSubject' : string };
export interface IssuedCredentialData { 'vc_jws' : string }
export interface PrepareCredentialRequest {
'signed_id_alias' : SignedIdAlias,
'credential_spec' : CredentialSpec,
}
export type PrepareCredentialResponse = { 'Ok' : PreparedCredentialData } |
{ 'Err' : IssueCredentialError };
export interface PreparedCredentialData {
'prepared_context' : [] | [Uint8Array | number[]],
}
export interface SignedIdAlias {
'credential_jws' : string,
'id_alias' : Principal,
'id_dapp' : Principal,
}
export interface _SERVICE {
'add_employee' : ActorMethod<[Principal], string>,
'consent_message' : ActorMethod<
[Icrc21ConsentMessageRequest],
Icrc21ConsentMessageResponse
>,
'get_credential' : ActorMethod<[GetCredentialRequest], GetCredentialResponse>,
'prepare_credential' : ActorMethod<
[PrepareCredentialRequest],
PrepareCredentialResponse
>,
}
71 changes: 71 additions & 0 deletions src/frontend/src/flows/verifiableCredentials/allow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { mainWindow } from "$src/components/mainWindow";
import { mount, renderPage } from "$src/utils/lit-html";
import { TemplateResult, html } from "lit-html";

/* VC credential allow/deny screen */

const allowTemplate = ({
relyingOrigin,
providerOrigin,
onAllow,
onCancel,
scrollToTop = false,
}: {
relyingOrigin: string;
providerOrigin: string;
onAllow: () => void;
onCancel: () => void;
/* put the page into view */
scrollToTop?: boolean;
}): TemplateResult => {
const slot = html`
<hgroup ${scrollToTop ? mount(() => window.scrollTo(0, 0)) : undefined}>
<h1 class="t-title t-title--main">Credential Access Request</h1>
</hgroup>
<p class="t-paragraph">
Allow verifying credential
<strong class="t-strong">${providerOrigin}</strong> with
<strong class="t-strong">${relyingOrigin}</strong>?
</p>
<div class="c-button-group">
<button
data-action="cancel"
class="c-button c-button--secondary"
@click="${() => onCancel()}"
>
Cancel
</button>
<button data-action="allow" class="c-button" @click="${() => onAllow()}">
Allow
</button>
</div>
`;

return mainWindow({
showFooter: false,
showLogo: false,
slot,
});
};

export const allowPage = renderPage(allowTemplate);

// Prompt to allow verifying credentials
export const allow = ({
relyingOrigin,
providerOrigin,
}: {
relyingOrigin: string;
providerOrigin: string;
}): Promise<"allowed" | "canceled"> => {
return new Promise((resolve) =>
allowPage({
relyingOrigin,
providerOrigin,
onAllow: () => resolve("allowed"),
onCancel: () => resolve("canceled"),
scrollToTop: true,
})
);
};
Loading

0 comments on commit 7f735a5

Please sign in to comment.