# @truestamp/verify

This library provides a TypeScript/JavaScript API for verifying [Truestamp](https://www.truestamp.com) Commitments. If you are simply looking to verify a Commitment by ID you should instead visit the website [verify.truestamp.com](https://verify.truestamp.com)

This library is for developers and performs a thorough cryptographic verification of a Truestamp Commitment. This verification is independent of the Truestamp services or APIs but it does make HTTP calls to external services such as blockchain explorer style APIs. This library has no external JavaScript dependencies.

This independence helps provides users with the confidence that their Commitments are verifiable for the long term. The code for this verification is intended
to be simple to audit so as to provide confidence in its functionality and security.

The verification of the cryptographic integrity of the Commitment is **always** performed locally wherever this code is run. There are requests
made to external services for the purpose of comparing locally calculated results to the values expected to be stored on-chain and to determine the timestamps
that a Commitment is bound to.

If an array of signed public keys is provided as an argument to the various verification functions, as can be found on the server
[https://keys.truestamp.com](https://keys.truestamp.com), they will be used and no connections to a key server will be attempted.

## About Commitments

A Truestamp Commitment is the cryptographic "glue" that binds your original data, and additional metadata, to one or more public blockchains.

You'll note that Commitments do not attest to the "answer" to a question. They are more analogous to the left side of a math equation. All of the elements are
there to do the math and calculate an answer, and this calculated answer is then compared to what is found on the blockchain. The "math" is check along the way
to ensure that a series of equations generate consistent results.

If the verification of the Commitment is a match to what is found on the blockchain, we can be certain of the integrity of the data reflected in the Commitment.

Once this verification of integrity is confirmed, the timestamp of the data can then be extracted from the blockchain block the data was committed to.

If any part of the equation fails, or if the data was changed by even a single bit, then the Commitment verification will fail return an error.

## Install

```sh
npm install @truestamp/verify
```

## Sample Usage

Node.js:

```javascript
// Node.js Require
const { assertVerified, isVerified, verify } = require('@truestamp/verify')

// ES Modules Import
// import { assertVerified, isVerified, verify } from '@truestamp/verify';

// Substitute with a Truestamp commitment object to be verified.
const commitment = {...}

// Returns a Promise that resolves to an object that details commitment
// properties and a summary of what this commitment attests to.
// It also provides pointers to the web URL's (e.g. blockchain explorer API)
// that were used to verify transactions and where commitments can be
// manually verified by comparing a hash with your own eyes.
console.log('verify', await verify(commitment))

// Resolves to boolean `true` or `false` and will not throw Errors
if (await isVerified(commitment)) {
  console.log('verified')
} else {
  console.log('bad commitment')
}

// Throws an Error on commitment validation issue,
// or external service verification failure. Resolves
// to `void` (returns nothing) if verified OK.
await assertVerified(commitment)
```

A more detailed version of this example can be found in [examples/nodejs/index.cjs].

## Sample JSON Verifier Output

Any errors in the verification process will result in a `VerificationCommitment` type that has only `"verified: false` and `error` properties.

The `verified` property will be set to true if the entirety of the Commitment is valid and at least one on-chain transaction was able to be verified.

The `commitsTo` property contains values that are verifiable and are derived from
the successful verification of a Commitment.

- `submittedAfter` : A timestamp retrieved from Observable Entropy that your Item must have been submitted after.
- `submittedAt` : A timestamp that was embedded in the Truestamp Id, representing the time we recorded submission via the API.
- `submittedBefore` : An ordered Array of all timestamps that the Commitment's `transactions` are verified against. This is retrieved from on-chain block/ledger data and ordered by transacted first.
- `submitWindowMilliseconds` : The time difference, in milliseconds, between `submittedAfter` and `submittedBefore`.

```json
{
  "verified": true,
  "id": "truestamp-2SF5JQLhBHmtRC35G6z4M7bjhcnJrGs99nEg6reqW61ThzXLx1pzk3VXjNQsw",
  "idData": {
    "test": true,
    "timestamp": "1660146374950000",
    "ulid": "01GA46YNT1HWZV86YM43B43QQT"
  },
  "itemData": {
    "hash": "d19fdb42a6396f46d7cd0a381d64afce1c818db8dec67f02c660db6f3b84427c",
    "hashType": "sha-256",
    "signaturesCount": 0
  },
  "item": {
    "hash": "0283ebb23421be145efc24e94fae1958a87bc301310bbb0f577b72131070a446",
    "hashType": "sha-256"
  },
  "commitmentData": {
    "hash": "ba912e7bec57b82e88667b3c0c5ff507c14bc2c699be829755ec1035a8b5273a",
    "hashType": "sha-256",
    "signaturesCount": 1
  },
  "proofs": [
    {
      "inputHash": "0283ebb23421be145efc24e94fae1958a87bc301310bbb0f577b72131070a446",
      "merkleRoot": "465363d5eb179bdd2582c2c254e0c7dfe511944cbfa5d31cf0dadd6b4aefe02e"
    }
  ],
  "transactions": [
    {
      "intent": "stellar",
      "verified": true,
      "transaction": {
        "inputHash": "465363d5eb179bdd2582c2c254e0c7dfe511944cbfa5d31cf0dadd6b4aefe02e",
        "intent": "stellar",
        "hash": "254bc53e9dfafd63c6a9b084c5d03a9e25cc27975e57d00572843d8437817af4",
        "ledger": 807126
      },
      "timestamp": "2022-08-10T15:48:08Z",
      "urls": {
        "machine": [
          "https://horizon-testnet.stellar.org/transactions/254bc53e9dfafd63c6a9b084c5d03a9e25cc27975e57d00572843d8437817af4"
        ],
        "human": [
          "https://stellar.expert/explorer/testnet/tx/254bc53e9dfafd63c6a9b084c5d03a9e25cc27975e57d00572843d8437817af4"
        ]
      }
    }
  ],
  "commitsTo": {
    "hashes": [
      {
        "hash": "5519b7d4aa338523943ba5ade6c9b63d57b68a7a17cf7f309ad1707e586688cb",
        "hashType": "sha-256"
      },
      {
        "hash": "5519b7d4aa338523943ba5ade6c9b63d57b68a7a17cf7f309ad1707e586688cb",
        "hashType": "sha-256"
      }
    ],
    "observableEntropy": "a782babda3045b75120cb37d5a569d958ff690a8dfdc6cbae9788b5eb42d8980",
    "timestamps": {
      "submittedAfter": "2022-08-10T15:45:29.597Z",
      "submittedAt": "2022-08-10T15:46:14.950Z",
      "submittedBefore": [
        "2022-08-10T15:48:08Z"
      ],
      "submitWindowMilliseconds": 158403
    }
  }
}
```

## API Documentation

The [TypeScript API documentation](https://truestamp.github.io/truestamp-verify/) for this project is generated and published upon each new release.

## Testing

```sh
npm install
npm test
```

## Contributing

We'd love you to join our network of contributors. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for help getting started.

### Releasing

- Commit changes, merge PR's to `main` branch
- Bump `version` field in `package.json`
- Cut a new [release](https://github.com/truestamp/truestamp-verify/releases)
- New release will trigger workflow to build, test, and publish package to [Github Package Registry](https://github.com/truestamp/truestamp-verify/packages) and
  [NPM.js](https://www.npmjs.com/package/@truestamp/verify).

## Code of Conduct

We expect all members of the community to respect our [Code of Conduct](CODE_OF_CONDUCT.md) at all times.

## Legal

Copyright © 2022 Truestamp Inc. All Rights Reserved.
