Skip to content

Commit

Permalink
feat: CredentialIssuerEIP712 (#899)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonas-notcat authored Jun 3, 2022
1 parent 7b520ab commit 5d62c52
Show file tree
Hide file tree
Showing 19 changed files with 2,064 additions and 20 deletions.
6 changes: 6 additions & 0 deletions __tests__/localAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AliasDiscoveryProvider, DIDManager } from '../packages/did-manager/src'
import { DIDResolverPlugin } from '../packages/did-resolver/src'
import { JwtMessageHandler } from '../packages/did-jwt/src'
import { CredentialIssuer, ICredentialIssuer, W3cMessageHandler } from '../packages/credential-w3c/src'
import { CredentialIssuerEIP712, ICredentialIssuerEIP712 } from '../packages/credential-eip712/src'
import {
CredentialIssuerLD,
ICredentialIssuerLD,
Expand Down Expand Up @@ -63,6 +64,7 @@ import * as fs from 'fs'
// Shared tests
import verifiableDataJWT from './shared/verifiableDataJWT'
import verifiableDataLD from './shared/verifiableDataLD'
import verifiableDataEIP712 from './shared/verifiableDataEIP712'
import handleSdrMessage from './shared/handleSdrMessage'
import resolveDid from './shared/resolveDid'
import webDidFlow from './shared/webDidFlow'
Expand Down Expand Up @@ -91,6 +93,7 @@ let agent: TAgent<
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure &
IDIDDiscovery
>
Expand Down Expand Up @@ -125,6 +128,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure &
IDIDDiscovery
>({
Expand Down Expand Up @@ -208,6 +212,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
}),
new DIDComm([new DIDCommHttpTransport()]),
new CredentialIssuer(),
new CredentialIssuerEIP712(),
new CredentialIssuerLD({
contextMaps: [LdDefaultContexts, credential_contexts as any],
suites: [new VeramoEcdsaSecp256k1RecoverySignature2020(), new VeramoEd25519Signature2018()],
Expand Down Expand Up @@ -244,6 +249,7 @@ const testContext = { getAgent, setup, tearDown }
describe('Local integration tests', () => {
verifiableDataJWT(testContext)
verifiableDataLD(testContext)
verifiableDataEIP712(testContext)
handleSdrMessage(testContext)
resolveDid(testContext)
webDidFlow(testContext)
Expand Down
6 changes: 6 additions & 0 deletions __tests__/localJsonStoreAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { DIDManager } from '../packages/did-manager/src'
import { DIDResolverPlugin } from '../packages/did-resolver/src'
import { JwtMessageHandler } from '../packages/did-jwt/src'
import { CredentialIssuer, ICredentialIssuer, W3cMessageHandler } from '../packages/credential-w3c/src'
import { CredentialIssuerEIP712, ICredentialIssuerEIP712 } from '../packages/credential-eip712/src'
import {
CredentialIssuerLD,
ICredentialIssuerLD,
Expand Down Expand Up @@ -56,6 +57,7 @@ import * as fs from 'fs'
// Shared tests
import verifiableDataJWT from './shared/verifiableDataJWT'
import verifiableDataLD from './shared/verifiableDataLD'
import verifiableDataEIP712 from './shared/verifiableDataEIP712'
import handleSdrMessage from './shared/handleSdrMessage'
import resolveDid from './shared/resolveDid'
import webDidFlow from './shared/webDidFlow'
Expand All @@ -82,6 +84,7 @@ let agent: TAgent<
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure
>

Expand All @@ -105,6 +108,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure
>({
...options,
Expand Down Expand Up @@ -170,6 +174,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
}),
new DIDComm(),
new CredentialIssuer(),
new CredentialIssuerEIP712(),
new CredentialIssuerLD({
contextMaps: [LdDefaultContexts, credential_contexts as any],
suites: [new VeramoEcdsaSecp256k1RecoverySignature2020(), new VeramoEd25519Signature2018()],
Expand Down Expand Up @@ -203,6 +208,7 @@ const testContext = { getAgent, setup, tearDown }
describe('Local json-data-store integration tests', () => {
verifiableDataJWT(testContext)
verifiableDataLD(testContext)
verifiableDataEIP712(testContext)
handleSdrMessage(testContext)
resolveDid(testContext)
webDidFlow(testContext)
Expand Down
6 changes: 6 additions & 0 deletions __tests__/localMemoryStoreAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Connection, createConnection } from 'typeorm'
import { DIDResolverPlugin } from '../packages/did-resolver/src'
import { JwtMessageHandler } from '../packages/did-jwt/src'
import { CredentialIssuer, ICredentialIssuer, W3cMessageHandler } from '../packages/credential-w3c/src'
import { CredentialIssuerEIP712, ICredentialIssuerEIP712 } from '../packages/credential-eip712/src'
import {
CredentialIssuerLD,
ICredentialIssuerLD,
Expand Down Expand Up @@ -49,6 +50,7 @@ import * as fs from 'fs'
// Shared tests
import verifiableDataJWT from './shared/verifiableDataJWT'
import verifiableDataLD from './shared/verifiableDataLD'
import verifiableDataEIP712 from './shared/verifiableDataEIP712'
import handleSdrMessage from './shared/handleSdrMessage'
import resolveDid from './shared/resolveDid'
import webDidFlow from './shared/webDidFlow'
Expand All @@ -74,6 +76,7 @@ let agent: TAgent<
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure
>
let dbConnection: Promise<Connection>
Expand All @@ -100,6 +103,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure
>({
...options,
Expand Down Expand Up @@ -166,6 +170,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
}),
new DIDComm(),
new CredentialIssuer(),
new CredentialIssuerEIP712(),
new CredentialIssuerLD({
contextMaps: [LdDefaultContexts, credential_contexts as any],
suites: [new VeramoEcdsaSecp256k1RecoverySignature2020(), new VeramoEd25519Signature2018()],
Expand Down Expand Up @@ -199,6 +204,7 @@ const testContext = { getAgent, setup, tearDown }
describe('Local in-memory integration tests', () => {
verifiableDataJWT(testContext)
verifiableDataLD(testContext)
verifiableDataEIP712(testContext)
handleSdrMessage(testContext)
resolveDid(testContext)
webDidFlow(testContext)
Expand Down
5 changes: 5 additions & 0 deletions __tests__/restAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { AliasDiscoveryProvider, DIDManager } from '../packages/did-manager/src'
import { DIDResolverPlugin } from '../packages/did-resolver/src'
import { JwtMessageHandler } from '../packages/did-jwt/src'
import { CredentialIssuer, ICredentialIssuer, W3cMessageHandler } from '../packages/credential-w3c/src'
import { CredentialIssuerEIP712, ICredentialIssuerEIP712 } from '../packages/credential-eip712/src'
import {
CredentialIssuerLD,
ICredentialIssuerLD,
Expand Down Expand Up @@ -69,6 +70,7 @@ import * as fs from 'fs'
// Shared tests
import verifiableDataJWT from './shared/verifiableDataJWT'
import verifiableDataLD from './shared/verifiableDataLD'
import verifiableDataEIP712 from './shared/verifiableDataEIP712'
import handleSdrMessage from './shared/handleSdrMessage'
import resolveDid from './shared/resolveDid'
import webDidFlow from './shared/webDidFlow'
Expand Down Expand Up @@ -103,6 +105,7 @@ const getAgent = (options?: IAgentOptions) =>
IDIDComm &
ICredentialIssuer &
ICredentialIssuerLD &
ICredentialIssuerEIP712 &
ISelectiveDisclosure &
IDIDDiscovery
>({
Expand Down Expand Up @@ -191,6 +194,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
}),
new DIDComm([new DIDCommHttpTransport()]),
new CredentialIssuer(),
new CredentialIssuerEIP712(),
new CredentialIssuerLD({
contextMaps: [LdDefaultContexts, credential_contexts as any],
suites: [new VeramoEcdsaSecp256k1RecoverySignature2020(), new VeramoEd25519Signature2018()],
Expand Down Expand Up @@ -248,6 +252,7 @@ const testContext = { getAgent, setup, tearDown }
describe('REST integration tests', () => {
verifiableDataJWT(testContext)
verifiableDataLD(testContext)
verifiableDataEIP712(testContext)
handleSdrMessage(testContext)
resolveDid(testContext)
webDidFlow(testContext)
Expand Down
186 changes: 185 additions & 1 deletion __tests__/shared/keyManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { IAgentOptions, IDIDManager, IKeyManager, TAgent, TKeyType } from '../../packages/core/src'
import { computeAddress, serialize } from '@ethersproject/transactions'
import { mapIdentifierKeysToDoc } from '../../packages/utils/src'
import { IResolver } from '../../packages/core/src'
import { recoverTypedSignature, normalize, SignTypedDataVersion } from '@metamask/eth-sig-util'

type ConfiguredAgent = TAgent<IDIDManager & IKeyManager>
type ConfiguredAgent = TAgent<IDIDManager & IKeyManager & IResolver>

export default (testContext: {
getAgent: () => ConfiguredAgent
Expand Down Expand Up @@ -415,5 +418,186 @@ export default (testContext: {
)
})
})

it('should sign with eth_signTypedData', async () => {
// https://github.com/MetaMask/test-dapp/blob/5719808b2a589be92b50fecc1d479fb1e63341c1/src/index.js#L1097
const msgParams = {
domain: {
chainId: 4,
name: 'Ether Mail',
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
version: '1',
},
message: {
contents: 'Hello, Bob!',
from: {
name: 'Cow',
wallets: [
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
],
},
to: [
{
name: 'Bob',
wallets: [
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
'0xB0B0b0b0b0b0B000000000000000000000000000',
],
},
],
},
types: {

Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person[]' },
{ name: 'contents', type: 'string' },
],
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallets', type: 'address[]' },
],
},
};

const identifier = await agent.didManagerCreate({ kms: 'local' })

const extendedKeys = await mapIdentifierKeysToDoc(identifier, 'verificationMethod', { agent })
const extendedKey = extendedKeys[0]

const signature = await agent.keyManagerSign({
data: JSON.stringify(msgParams),
keyRef: extendedKey.kid,
algorithm: 'eth_signTypedData'
})

const address = extendedKey.meta.ethereumAddress

const data = {
...msgParams,
primaryType: 'Mail',
types: {
...msgParams.types,
EIP712Domain: [
// Order of these elements matters!
// https://github.com/ethers-io/ethers.js/blob/a71f51825571d1ea0fa997c1352d5b4d85643416/packages/hash/src.ts/typed-data.ts#L385
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
],
},
}

//@ts-ignore
const recovered = recoverTypedSignature({data, signature: signature, version: SignTypedDataVersion.V4})
expect(address.toLowerCase()).toEqual(recovered)
})

it('should sign credential with eth_signTypedData', async () => {
const msgParams = {
"domain": {
"chainId": 4,
"name": "VerifiableCredential",
"version": "1"
},
"types": {
"CredentialSubject": [
{
"name": "id",
"type": "string"
},
{
"name": "you",
"type": "string"
}
],
"Issuer": [
{
"name": "id",
"type": "string"
}
],
"VerifiableCredential": [
{
"name": "@context",
"type": "string[]"
},
{
"name": "credentialSubject",
"type": "CredentialSubject"
},
{
"name": "issuanceDate",
"type": "string"
},
{
"name": "issuer",
"type": "Issuer"
},
{
"name": "type",
"type": "string[]"
}
]
},
"message": {
"issuer": {
"id": "did:fake:123"
},
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://example.com/1/2/3"
],
"type": [
"VerifiableCredential",
"Custom"
],
"issuanceDate": "2022-05-31T14:02:06.109Z",
"credentialSubject": {
"id": "did:web:example.com",
"you": "Rock"
}
}
}

const identifier = await agent.didManagerCreate({ kms: 'local' })

const extendedKeys = await mapIdentifierKeysToDoc(identifier, 'verificationMethod', { agent })
const extendedKey = extendedKeys[0]

const signature = await agent.keyManagerSign({
data: JSON.stringify(msgParams),
keyRef: extendedKey.kid,
algorithm: 'eth_signTypedData'
})

const address = extendedKey.meta.ethereumAddress

const data = {
...msgParams,
primaryType: 'VerifiableCredential',
types: {
...msgParams.types,
EIP712Domain: [
// Order of these elements matters!
// https://github.com/ethers-io/ethers.js/blob/a71f51825571d1ea0fa997c1352d5b4d85643416/packages/hash/src.ts/typed-data.ts#L385
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
],
},
}

const args = {data, signature: signature, version: SignTypedDataVersion.V4}
//@ts-ignore
const recovered = recoverTypedSignature(args)
expect(address.toLowerCase()).toEqual(recovered)
})

})


}
Loading

0 comments on commit 5d62c52

Please sign in to comment.