Skip to content

Commit

Permalink
feat: Metamask Identity Controller
Browse files Browse the repository at this point in the history
  • Loading branch information
simonas-notcat committed Dec 17, 2019
1 parent d63d388 commit 720b52c
Show file tree
Hide file tree
Showing 12 changed files with 882 additions and 71 deletions.
3 changes: 3 additions & 0 deletions examples/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
"daf-debug": "^1.2.0",
"daf-did-jwt": "^1.2.0",
"daf-ethr-did-local-storage": "../daf/packages/daf-ethr-did-local-storage",
"daf-ethr-did-metamask": "../daf/packages/daf-ethr-did-metamask",
"daf-resolver-universal": "^1.1.0",
"daf-trust-graph": "^1.2.0",
"daf-w3c": "^1.2.0",
"ethr-did": "^1.1.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-scripts": "3.3.0",
"rimble-ui": "^0.11.1",
"styled-components": "^4.4.1",
"typescript": "~3.7.2"
},
"scripts": {
Expand Down
193 changes: 179 additions & 14 deletions examples/react-app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,185 @@
import React from 'react'
import logo from './logo.svg'
import './App.css'
import React, { useState, useEffect } from 'react'
import * as W3c from 'daf-w3c'
import * as TG from 'daf-trust-graph'
import { core } from './setup'
const {
BaseStyles,
Box,
Flex,
Card,
Heading,
Button,
Radio,
Field,
Form,
Input,
Loader,
ToastMessage,
} = require('rimble-ui')

declare global {
interface Window {
toastProvider: any
}
}

const App: React.FC = () => {
const [isSending, setIsSending] = useState(false)
const [activeDid, setActiveDid] = useState('')
const [receiver, setReceiver] = useState('did:web:uport.me')
const [claimType, setClaimType] = useState('name')
const [claimValue, setClaimValue] = useState('Alice')
const [controllerTypes, setControllerTypes] = useState([''])
const [identities, setIdentities] = useState([{ type: '', did: '' }])

useEffect(() => {
setControllerTypes(core.identityManager.listTypes())
}, [])

const updateIdentityList = () => {
core.identityManager.listIssuers().then(identities => {
setIdentities(identities)
if (identities.length > 0) setActiveDid(identities[0].did)
})
}

useEffect(() => {
updateIdentityList()
}, [])

const send = async () => {
// Sign credential
setIsSending(true)

try {
const credentialSubject: any = {}
credentialSubject[claimType] = claimValue

const credential = await core.handleAction({
type: W3c.ActionTypes.signVc,
did: activeDid,
data: {
sub: receiver,
vc: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential'],
credentialSubject,
},
},
} as W3c.ActionSignW3cVc)

console.log(credential)

// Send credential using TrustGraph
await core.handleAction({
type: TG.ActionTypes.sendJwt,
data: {
from: activeDid,
to: receiver,
jwt: credential,
},
} as TG.ActionSendJWT)

window.toastProvider.addMessage('Credential sent!', { variant: 'success' })
} catch (e) {
window.toastProvider.addMessage('Ooops', { variant: 'failure' })
}

setIsSending(false)
}

const handleSubmit = (e: any) => {
e.preventDefault()
send()
}

return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
Learn React
</a>
</header>
</div>
<BaseStyles>
<ToastMessage.Provider ref={(node: any) => (window.toastProvider = node)} />
<Flex>
<Box p={3}>
<Card width={'auto'} mx={'auto'}>
<Heading>Send Verifiable Credential</Heading>

{controllerTypes.map(type => (
<Button.Outline
mt={3}
mb={3}
mr={3}
key={type}
onClick={async () => {
await core.identityManager.create(type)
updateIdentityList()
}}
>
Create {type} DID
</Button.Outline>
))}

<Form onSubmit={handleSubmit}>
<Field label="Sender" required>
<div>
{identities.map(identity => (
<Radio
key={identity.did}
name="selecedDid"
required
onChange={(e: any) => setActiveDid(identity.did)}
label={`${identity.did} (${identity.type})`}
value={identity.did}
checked={activeDid === identity.did}
/>
))}
</div>
</Field>

<Flex mx={-3} flexWrap={'wrap'}>
<Box width={1} px={3}>
<Field label="Receiver" width={1}>
<Input
type="text"
required
value={receiver}
onChange={(e: any) => setReceiver(e.target.value)}
width={1}
/>
</Field>
</Box>
</Flex>

<Flex mx={-3} flexWrap={'wrap'}>
<Box width={[1, 1, 1 / 2]} px={3}>
<Field label="Claim type" width={1}>
<Input
type="text"
required
value={claimType}
onChange={(e: any) => setClaimType(e.target.value)}
width={1}
/>
</Field>
</Box>
<Box width={[1, 1, 1 / 2]} px={3}>
<Field label="Claim value" width={1}>
<Form.Input
type="text"
required
value={claimValue}
onChange={(e: any) => setClaimValue(e.target.value)}
width={1}
/>
</Field>
</Box>
</Flex>

<Flex flexWrap={'wrap'}>
{isSending ? <Loader size="40px" /> : <Button type="submit">Sign and send</Button>}
</Flex>
</Form>
</Card>
</Box>
</Flex>
</BaseStyles>
)
}

Expand Down
53 changes: 9 additions & 44 deletions examples/react-app/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as DBG from 'daf-debug'
import * as DidJwt from 'daf-did-jwt'
import { DafUniversalResolver } from 'daf-resolver-universal'
import { EthrDidLocalStorageController } from 'daf-ethr-did-local-storage'
import { EthrDidMetamaskController } from 'daf-ethr-did-metamask'

import Debug from 'debug'
Debug.enable('*')
Expand All @@ -15,53 +16,17 @@ messageValidator.setNext(new DidJwt.MessageValidator()).setNext(new W3c.MessageV
const actionHandler = new DBG.ActionHandler()
actionHandler.setNext(new TG.ActionHandler()).setNext(new W3c.ActionHandler())

const identityControllers: Daf.IdentityController[] = [new EthrDidLocalStorageController()]

if (typeof window.ethereum !== 'undefined' && window.ethereum.isMetaMask) {
EthrDidMetamaskController.snapId = 'http://localhost:8081/package.json'
identityControllers.push(new EthrDidMetamaskController())
}

export const core = new Daf.Core({
identityControllers: [new EthrDidLocalStorageController()],
identityControllers,
serviceControllers: [],
didResolver: new DafUniversalResolver({ url: 'https://uniresolver.io/1.0/identifiers/' }),
messageValidator,
actionHandler,
})

async function main() {
// Get or create new issuer
let issuer: Daf.Issuer
const issuers = await core.identityManager.listIssuers()
if (issuers.length > 0) {
issuer = issuers[0]
} else {
const types = core.identityManager.listTypes()
const did = await core.identityManager.create(types[0])
issuer = await core.identityManager.issuer(did)
}

// Sign credential
const credential = await core.handleAction({
type: W3c.ActionTypes.signVc,
did: issuer.did,
data: {
sub: 'did:web:uport.me',
vc: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential'],
credentialSubject: {
you: 'Rock',
},
},
},
} as W3c.ActionSignW3cVc)

console.log(credential)

// Send credential using TrustGraph
await core.handleAction({
type: TG.ActionTypes.sendJwt,
data: {
from: issuer.did,
to: 'did:web:uport.me',
jwt: credential,
},
} as TG.ActionSendJWT)
}

main().catch(console.log)
Loading

0 comments on commit 720b52c

Please sign in to comment.