Skip to content

Commit

Permalink
feat: sign verifiable claims with jsonld-signatures
Browse files Browse the repository at this point in the history
feat: sign verifiable claims with jsonld-signatures

use jsonld-signatures to create and verify Linked Data Signature Proofs for Verifiable Claims

BREAKING CHANGE: the mechanism to create a verifiable claim and sign it has changed dramatically. 

Refer to the README for details. Use the method below to create a claim. 

```
import { configureCreateVerifiableClaim, createIssuerFromPrivateKey, getVerifiableClaimSigner } from '@po.et/poet-js'

const { configureSignVerifiableClaim } = getVerifiableClaimSigner()

const issuerPrivateKey = '<Ed25519Base58PrivateKey>' 
const issuer = createIssuerFromPrivateKey(issuerPrivateKey)

const createVerifiableWorkClaim = configureCreateVerifiableClaim({ issuer })
const signVerifiableClaim = configureSignVerifiableClaim({ privateKey: issuerPrivateKey })

const workClaim = {
  name: 'The Raven',
  author: 'Edgar Allan Poe',
  tags: 'poem',
  dateCreated: '',
  datePublished: '1845-01-29T03:00:00.000Z',
  archiveUrl: 'https://example.com/raven',
  hash: '<hash of content>',
}

const unsignedVerifiableClaim = await createVerifiableWorkClaim(workClaim)
const signedWorkClaim = await signVerifiableClaim(unsignedVerifiableClaim)
```
  • Loading branch information
krobi64 authored Oct 10, 2018
1 parent a6c9c06 commit 9fe5933
Show file tree
Hide file tree
Showing 22 changed files with 2,143 additions and 814 deletions.
175 changes: 147 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,51 @@
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![Join the chat at https://gitter.im/poetapp/Lobby](https://badges.gitter.im/poetapp/Lobby.svg)](https://gitter.im/poetapp/Lobby)

Po.et JS is a small library that provides methods to easily create and sign Po.et Claims.
Po.et JS is a small library that provides methods to easily create and sign Po.et Claims according to the
[Verifiable Credentials Data Model](https://w3c.github.io/vc-data-model). These claims are [JSON-LD](https://w3c.github.io/json-ld-syntax/)
documents. As such, you can define your own JSON-LD `@context` to map your submitted Claims.

Po.et does provide a few default `@context` objects that you can extend or override in the `createClaim` function. The current defaults are as follows:

```typescript
export const DefaultClaimContext: ClaimContext = {
cred: 'https://w3id.org/credentials#',
dc: 'http://purl.org/dc/terms/',
schema: 'http://schema.org/',
sec: 'https://w3id.org/security#',

id: 'sec:digestValue',
issuer: 'cred:issuer',
issuanceDate: 'cred:issued',
type: 'schema:additionalType',
claim: 'schema:Thing', // The most generic definition in schema.org,
}

export const DefaultWorkClaimContext: ClaimContext = {
archiveUrl: 'schema:url',
author: 'schema:author',
canonicalUrl: 'schema:url',
claim: 'schema:CreativeWork',
contributors: {
'@id': 'schema:ItemList',
'@container': '@list',
'@type': 'schema:contributor',
},
copyrightHolder: 'schema:copyrightHolder',
dateCreated: 'schema:dateCreated',
datePublished: 'schema:datePublished',
license: 'schema:license',
name: 'schema:name',
tags: 'schema:keywords',
hash: 'sec:digestValue',
}

export const DefaultIdentityClaimContext: ClaimContext = {
publicKey: 'sec:publicKeyBase58',
profileUrl: 'sec:owner',
}

```

## Installation

Expand All @@ -15,29 +59,54 @@ npm i @po.et/poet-js

## Usage

The main function you'll be using is `createClaim`:
Note that the Po.et network currently uses
[Ed25519Signature2018](https://w3c-dvcg.github.io/lds-ed25519-2018/), which requires a Base58
form of the Ed25519 Private Key. You can use the KeyHelper utility to generate a base58 public/privateKey pair, if you
do not yet have one.

### Example 1: createClaim for Work Claims <!-- TODO: link to glossary -->
**WARNING**
Do not use the example private key in these documents. No one should have access to your private key, and it certainly should not be in the example documents of a library. If you
use the example private key, others can make additional claims using the same key.

```ts
import { Claim, ClaimType, createClaim } from '@po.et/poet-js'
```typescript
import { createIssuerFromPrivateKey, generateED25519Base58Keys } from '@po.et/poet-js'

const { privateKey } = generateED25519Base58Keys('entropy_phrase') // e.g 'LWgo1jraJrCB2QT64UVgRemepsNopBF3eJaYMPYVTxpEoFx7sSzCb1QysHeJkH2fnGFgHirgVR35Hz5A1PpXuH6'

const issuer = createIssuerFromPrivateKey(privateKey)

const workAttributes = {
```

----

Use `configureCreateVerifiableClaim()` to create a `createVerifiableClaim` function to create an unsigned Verifiable Claim.
Then use `configureSignVerifiableClaim` from `getVerifiableClaimSigner()` to create the proper function to sign and verify your claims.

### Example 1: Create and Sign a Verifiable Work Claims <!-- TODO: link to glossary -->

```typescript
import { configureCreateVerifiableClaim, createIssuerFromPrivateKey, getVerifiableClaimSigner } from '@po.et/poet-js'

const { configureSignVerifiableClaim } = getVerifiableClaimSigner()

const issuerPrivateKey = 'LWgo1jraJrCB2QT64UVgRemepsNopBF3eJaYMPYVTxpEoFx7sSzCb1QysHeJkH2fnGFgHirgVR35Hz5A1PpXuH6'
const issuer = createIssuerFromPrivateKey(issuerPrivateKey)

const createVerifiableWorkClaim = configureCreateVerifiableClaim({ issuer })
const signVerifiableClaim = configureSignVerifiableClaim({ privateKey: issuerPrivateKey })

const workClaim = {
name: 'The Raven',
author: 'Edgar Allan Poe',
tags: 'poem',
dateCreated: '',
datePublished: '1845-01-29T03:00:00.000Z',
content: 'Once upon a midnight dreary...'
archiveUrl: 'https://example.com/raven',
hash: '<hash of content>',
}

const Issuer = 'po.et://entities/<identity claim id>'

const claim = createClaim(
Issuer,
ClaimType.Work,
workAttributes
)
const unsignedVerifiableClaim = await createVerifiableWorkClaim(workClaim)
const signedWorkClaim = await signVerifiableClaim(unsignedVerifiableClaim)
```

Once this claim is created, you can publish it to a Po.et Node:
Expand All @@ -49,28 +118,77 @@ const response = await fetch(poetNodeUrl + '/works/', {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(claim)
body: JSON.stringify(signedWorkClaim)
})
```

Note, if you are creating an identity claim, your Identity Provider (IDP) <!-- TODO: link to glossary --> will be the issuer of the claim. If you are self-serving your own IDP, you will have to create an IdentityClaim for the IDP from which you can issue all further identities.
### Example 2: Create and sign a Verifiable Work Claim with overriding context

### Example 2: createClaim for Identity Claims <!-- TODO: link to glossary -->
If you want to extend or override the default context defined by Po.et, you simply need to pass a context object into
the `configureCreateVerifiableClaim` function:

```ts
import { Claim, ClaimType, createClaim } from '@po.et/poet-js'
```typescript
import { ClaimType, configureCreateVerifiableClaim, createIssuerFromPrivateKey, getVerifiableClaimSigner } from '@po.et/poet-js'

const identityAttributes = {
publicKey: ''
const { configureSignVerifiableClaim } = getVerifiableClaimSigner()

const issuerPrivateKey = 'LWgo1jraJrCB2QT64UVgRemepsNopBF3eJaYMPYVTxpEoFx7sSzCb1QysHeJkH2fnGFgHirgVR35Hz5A1PpXuH6'
const issuer = createIssuerFromPrivateKey(issuerPrivateKey)

const externalContext: any = {
claim: 'schema:Book',
edition: 'schema:bookEdition',
isbn: 'schema.org/isbn',
}

const createVerifiableWorkClaim = configureCreateVerifiableClaim({ issuer, type: ClaimType.Work, context: externalContext })
const signVerifiableClaim = configureSignVerifiableClaim({ privateKey: issuerPrivateKey })


const workClaim = {
name: 'The Raven',
author: 'Edgar Allan Poe',
tags: 'poem',
dateCreated: '',
datePublished: '1845-01-29T03:00:00.000Z',
archiveUrl: 'https://example.com/raven',
hash: '<hash of content>',
isbn: '9781458318404',
edition: '1',
}

const Issuer = 'po.et://entities/<idp identity claim id>'
const unsignedVerifiableClaim = await createVerifiableWorkClaim(workClaim)
const signedWorkClaim = await signVerifiableClaim(unsignedVerifiableClaim)
```

### Example 3: createClaim for Identity Claims <!-- TODO: link to glossary -->
Note, if you are creating an identity claim, your IDP will be the issuer of the claim. [Frost](https://frost.po.et/) is one such IDP.
If you are self-serving your own identity claim, your identity provider (IDP) will have to create an IdentityClaim for
itself from which you can issue all further identities. Currently the Po.et network uses the [Ed25519Signature2018](https://w3c-dvcg.github.io/lds-ed25519-2018/),
which requires a Base58 form of the Ed25519 Public Key.


```typescript
import { ClaimType, configureCreateVerifiableClaim, createIssuerFromPrivateKey, getVerifiableClaimSigner, KeyHelper } from '@po.et/poet-js'

const { configureSignVerifiableClaim } = getVerifiableClaimSigner()

const issuerPrivateKey = 'LWgo1jraJrCB2QT64UVgRemepsNopBF3eJaYMPYVTxpEoFx7sSzCb1QysHeJkH2fnGFgHirgVR35Hz5A1PpXuH6'
// Issuer is the IDP
const issuer = createIssuerFromPrivateKey(issuerPrivateKey)

const createVerifiableIdentityClaim = configureCreateVerifiableClaim({ issuer, type: ClaimType.Identity })
const signVerifiableClaim = configureSignVerifiableClaim({ privateKey: issuerPrivateKey })

// Store the privateKey for this profile for signing future claims
const { publicKey, privateKey } = KeyHelper.generateED25519Base58Keys('entropy_phrase')

const identityClaim = {
publicKey,
}

const claim = createClaim(
Issuer,
ClaimType.Identity,
identityAttributes
)
const unsignedVerifiableClaim = await createVerifiableIdentityClaim(identityClaim)
const signedWorkClaim = await signVerifiableClaim(unsignedVerifiableClaim)
```

Once this claim is created, you can publish it to a Po.et Node:
Expand All @@ -86,7 +204,8 @@ const response = await fetch(poetNodeUrl + '/identities/', {
})
```

Notice you don't need to wait for the server's response to know the claim's ID. You don't even need to publish it! `claim.id` is readily available right after calling `createClaim`.
Notice you don't need to wait for the server's response to know the claim's ID. You don't even need to publish it!
`claim.id` is readily available right after creating the unsigned verifiable claim.

## Contributing

Expand Down
Loading

0 comments on commit 9fe5933

Please sign in to comment.