Po.et Documentation
Technical documentation for the Po.et Network

About Po.et
Use Po.et

Updating to Signed Verifiable Claims and Separate File Uploads

Possible Conflicts



Out of scope


Each step should be one or more pull requests.

poet-js: Adjust Work Claim (Completed)


In poet-js we need to adjust the verifiable claims of type Work to contain archiveUrl and hash instead of content.

See: Creative Work.

node: Add File Upload Endpoint to node


Create an API endpoint that allows files to be uploaded directly to IPFS. This endpoint will return an IPFS hash (hash). It may also return an archiveUrl if it make sense to do so. For debugging purposes the node will store the IPFS hash in the database.

The endpoint needs to support all types of file formats: audio, video, image and text. More research will need to be done on this specifically for its own PR.

node: Update to New poet-js (Completed)



Update the node’s poet-js dependency to allow the new version of signed verifiable Work and Identity claims.

The endpoint POST /works should validate the signed verifiable claims.

frost-api: Hide node Changes


The node will now require signed verifiable claims. Signed verifiable claims have a few requirements that frost-api will need to be adjusted to handle. The goal is to remain compatible with the existing Frost API exposed to users, while automating the transition behind the scenes to these new signed verifiable claims.

Requirements for Signed Verifiable Claims

Once these requirements are met we can send the signed verifiable claims to node.


Frost will need to provide an issuer property that is a URI which resolves to an issuer. The issuer of a Work claim is the account/profile that submits the claim. issuer will be a data: URI until we introduce identity claim functionality. Because we are currently signing with ED25519, we will need to generate an ED25519 public/private key pair for each account.

The issuer data URI will be generated from the submitter’s private key using poet-js’s createIssuerFromPrivateKey function.

Note: despite the name of the function, no data about the actual private key is leaked in the data URL. A public key is generated from it instead, and that is stored in the data URL, along with other information required to verify the signature.

In the future issuer will be a URI that resolves to an identity claim.




Frost will need to provide an author property that is a URI which resolves to an author. Previous claims took an author property which was the author’s name. For backwards compatibility, if the submitted Work claim does not designate a URI for author, Frost will generate a data: URI using the string value of author as a name property.

Actually instead of creating a data URL, we might just include the object for author in the claim:

  claim: {
    author: {
      '@type': 'schema:Person',
      name: 'Sir Author Conan Doyle'

author should never resolve to an identity claim unless the issuer submits the value. We should minimize modifying the claim portion of a signed verifiable claim as much as possible.


frost-api will need to sign any verifiable claim it creates with the issuer’s private key that will be eventually be related to the issuer’s identity claim in the future. poet-js provides the configureSignVerifiableClaim function to sign claims.

frost-api: Replace content with archiveUrl & hash


Replace content with archiveUrl & hash by uploading the value of the content object to IPFS and using the resulting hash from IPFS (hash). archiveUrl for now will just be the IPFS url of the file: ipfs.io/ipfs/{hash}

content will become a reserved property of claims for frost-api in order to maintain backwards compatibility. content being a reserved property will not be respected by the node; it does not need to know anything about content being reserved for frost-api backwards compatibility.

explorer-web: Handle Claim Properties Dynamically


Explorer Web may need to be updated to show any properties a claim contains instead of fixed properties.

frost-api: (future) Identity Public/Private Key


The key pair for Frost (the issuer) should be generated using @poet/poetjs:generateED25519Base58Keys.

The key pair will be stored in mongo db and will be encrypted/decrypted by the vault. If the key pair is not loaded into the app correctly the app should throw/crash.

frost-api: (future) User Default Public/Private Key


User key pairs will be stored in mongo db and will be encrypted/decrypted by the vault. The key pairs should be generated on account creation using @poet/poetjs:generateED25519Base58Keys.

A solution will need to be implemented to create key pairs for existing accounts.

frost-api: (future) Add Ability to Upload Files Separately

At a later point frost-api will also need to support uploading of files separate from the claim itself.

In order to accommodate the use case and avoid breaking the user-facing API we need frost-api to handle both the content version and the archiveUrl/hash version of Work claims.

If the user wants us to store the file for them in IPFS:

If the user wants to handle the storage of the file oneself (whether in IPFS or some other file storage system):

node: (future) Add archiveUrl/hash Validation

When the archiveUrl points to an IPFS file, the validation can be skipped entirely since IPFS content is immutable.

For archiveUrls pointing to mutable storage, clients of the node should verify that the hash of the contents dereferenced from archiveUrl does match hash.

Frost API will only support IPFS initially, so there is no need to address this more complex scenario for the initial mainnet release.