@i3m/non-repudiation-library
Library for handling non-repudiation proofs in the i3-MARKET ecosystem. It is a core element of the Conflict Resolution system in i3-MARKET (Read more here).
The library enables implementation of:
- The non-repudiation protocol of a data exchange
- The Conflict-Resolver Service, which can be queried to check completeness of the non-repudiation protocol and/or solve a dispute.
API reference documentation
Check the API
Usage
@i3m/non-repudiation-library
can be imported to your project with npm
:
npm install @i3m/non-repudiation-library
Then either require (Node.js CJS):
const nonRepudiationLibrary = require('@i3m/non-repudiation-library')
or import (JavaScript ES module):
import * as nonRepudiationLibrary from '@i3m/non-repudiation-library'
The appropriate version for browser or node is automatically exported.
You can also download the IIFE bundle, the ESM bundle or the UMD bundle and manually add it to your project, or, if you have already installed @i3m/non-repudiation-library
in your project, just get the bundles from node_modules/@i3m/non-repudiation-library/dist/bundles/
.
Example for an i3-MARKET Provider using the Non-Repudiation Protocol
Before starting the agreement you need:
-
A private key for signing the non-repudiation proofs. You should generate a public-private key pair in one of the EC supported curves (P-256, P-384, P-521). Key format must be JSON Web Key (JWK).
You can easily create the key pair with the generateKeys
utility function. For example:
const providerJwks = await nonRepudiationLibrary.generateKeys('ES256')
-
An Ethereum address with enough funds on the ledger and a NrpDltAgentOrig
instance that can handle signing of the transactions needed to publish the secret to the ledger.
And now you are ready to start a dataExchange
for a given block of a given DataExchangeAgreement
.
async nrp() => {
const dataExchangeAgreement: nonRepudiationLibrary.DataExchangeAgreement = {
orig: '{"kty":"EC","crv":"P-256","x":"4sxPPpsZomxPmPwDAsqSp94QpZ3iXP8xX4VxWCSCfms","y":"8YI_bvVrKPW63bGAsHgRvwXE6uj3TlnHwoQi9XaEBBE","alg":"ES256"}',
dest: '{"kty":"EC","crv":"P-256","x":"6MGDu3EsCdEJZVV2KFhnF2lxCRI5yNpf4vWQrCIMk5M","y":"0OZbKAdooCqrQcPB3Bfqy0g-Y5SmnTyovFoFY35F00M","alg":"ES256"}',
encAlg: 'A256GCM',
signingAlg: 'ES256',
hashAlg: 'SHA-256',
ledgerContractAddress: '0x7B7C7c0c8952d1BDB7E4D90B1B7b7C48c13355D1',
ledgerSignerAddress: '0x17bd12C2134AfC1f6E9302a532eFE30C19B9E903',
pooToPorDelay: 10000,
pooToPopDelay: 20000,
pooToSecretDelay: 150000
}
const identities = await providerWallet.identityList({})
const identity = identities[0]
providerDltAgent = new nonRepudiationLibrary.I3mServerWalletAgentOrig(providerWallet, identity.did)
if (dataExchangeAgreement.ledgerSignerAddress !== await providerWallet.getAddress()) {
throw new Error('not maching')
}
const nrpProvider = new nonRepudiationLibrary.NonRepudiationProtocol.NonRepudiationOrig(dataExchangeAgreement, providerJwks.privateJwk, block, providerDltAgent)
const poo = await nrpProvider.generatePoO()
...
...
await nrpProvider.verifyPoR(por)
const pop = await nrpProvider.generatePoP()
...
verificationRequest = await nrpProvider.generateVerificationRequest()
...
const { payload } = await nonRepudiationLibrary.ConflictResolution.verifyResolution<nonRepudiationLibrary.VerificationResolutionPayload>(resolution, crsPublicKey)
if (payload.resolution === 'completed') {
}
)
nrp()
Example for an i3-MARKET Consumer using the Non-Repudiation Protocol
Before starting the agreement, you need a pair of public private keys. You can easily create the key pair with the generateKeys
utility function:
const consumerJwks = await nonRepudiationLibrary.generateKeys('ES256')
And now you are ready to start a DataExchange
for a given block of a given DataExchangeAgreement
.
async nrp() => {
const dataExchangeAgreement: nonRepudiationLibrary.DataExchangeAgreement = {
orig: '{"kty":"EC","crv":"P-256","x":"4sxPPpsZomxPmPwDAsqSp94QpZ3iXP8xX4VxWCSCfms","y":"8YI_bvVrKPW63bGAsHgRvwXE6uj3TlnHwoQi9XaEBBE","alg":"ES256"}',
dest: '{"kty":"EC","crv":"P-256","x":"6MGDu3EsCdEJZVV2KFhnF2lxCRI5yNpf4vWQrCIMk5M","y":"0OZbKAdooCqrQcPB3Bfqy0g-Y5SmnTyovFoFY35F00M","alg":"ES256"}',
encAlg: 'A256GCM',
signingAlg: 'ES256',
hashAlg: 'SHA-256',
ledgerContractAddress: '0x7b7c7c0c8952d1bdb7e4d90b1b7b7c48c13355d1',
ledgerSignerAddress: '0x17bd12c2134afc1f6e9302a532efe30c19b9e903',
pooToPorDelay: 10000,
pooToPopDelay: 20000,
pooToSecretDelay: 180000
}
const dltConfig: Partial<nonRepudiationLibrary.DltConfig> = {
rpcProviderUrl: 'http://89.111.35.214:8545'
}
consumerDltAgent = new nonRepudiationLibrary.EthersIoAgentDest(dltConfig)
const nrpConsumer = new nonRepudiationLibrary.NonRepudiationProtocol.NonRepudiationDest(dataExchangeAgreement, consumerJwks.privateJwk, consumerDltAgent)
...
await nrpConsumer.verifyPoO(poo.jws, cipherblock)
const por = await nrpConsumer.generatePoR()
...
...
await nrpConsumer.verifyPoP(pop)
await nrpConsumer.getSecretFromLedger()
try {
const decryptedBlock = await nrpConsumer.decrypt()
} catch(error) {
const disputeRequest = await nrpConsumer.generateDisputeRequest()
...
const { resolutionPayload } = await nonRepudiationLibrary.ConflictResolution.verifyResolution<nonRepudiationLibrary.DisputeResolutionPayload>(disputeResolution)
if (resolutionPayload.resolution === 'accepted') {
} else {
}
}
)
nrp()