The Conflict-Resolver Service (CRS) can be queried to provide a signed resolution about the non-repudiation protocol associated to an invoice being valid or invalid. It could be invoked by either the consumer or the provider.
Just download the OpenAPI specification at CRS OAS or visualize it online at editor.swagger.io.
It is a core element of the Conflict Resolution system in i3-MARKET. Read more here.
The CRS provides two endpoints: one for checking that the protocol was executed properly, and other one to initiate a dispute when a Consumer B claims that he cannot decrypt the cipherblock he has been invoiced for.
Check the OpenAPI specification at CRS OAS or visualize it online at editor.swagger.io for more details.
The CRS can be queried to provide a signed resolution about a data exchanged successfully performed or not. It could be invoked by either the consumer or the provider. The provider should query this endpoint and send it along with the invoice to the consumer.
This endpoint can be accessed at POST /verification
and is requires valid i3-MARKET Consumer or Provider's credentials.
A verification request as a compact JSON Web Signature (JWS). For the request to be accepted, it MUST be signed with the same key it was used during the data exchange for this verification.
{
verificationRequest: string // the verification request in compact JWS format
}
A verification request is a JWS signed by either the consumer or the provider using the same key he/she used for the data exchange. The verification request payload holds a valid PoR:
{
type: 'verificationRequest'
proofType: 'request'
iss: 'orig' | 'dest'
iat: number // unix timestamp for issued at
por: string // a compact JWS holding a PoR. The proof MUST be signed with the same key as either 'orig' or 'dest' of the payload proof.
dataExchangeId: string // the unique id of this data exchange
}
It returns a signed resolution as a compact JWS with payload:
{
proofType: 'resolution'
type: 'verification'
resolution: 'completed' | 'not completed' // whether the data exchange has been verified to be complete
dataExchangeId: string // the unique id of this data exchange
iat: number // unix timestamp stating when it was resolved
iss: string // the public key of the CRS in JWK
sub: string // the public key (JWK) of the entity that requested a resolution
}
Notice that the signed resolution obtained from POST /verification
does not ensure that the published secret could be used to decrypt the encrypted block of data. If the consumer B is not able to decrypt the cipherblock, he could initiate a dispute on the CRS. The CRS will also provide signed resolution of whether B is right or not.
All this is handled in this endpoint, which can only be queried if in possession of valid i3-MARKET Consumer's credentials.
{
disputeRequest: string // the dispute request in compact JWS format
}
A dispute request as a compact JSON Web Signature (JWS). For the request to be accepted, it MUST be signed with the same key it was used during the data exchange for this verification.
The payload of a decoded disputeRequest
holds a valid PoR, and the received cipherblock:
{
proofType: 'request'
type: 'disputeRequest'
iss: 'dest'
cipherblock: string // the cipherblock as a JWE string
iat: number // unix timestamp for issued at
por: string // a compact JWS holding a PoR. The proof MUST be signed with the same key as either 'orig' or 'dest' of the payload proof.
dataExchangeId: string // the unique id of this data exchange
}
It returns a signed resolution as a compact JWS with payload:
{
proofType: 'resolution'
type: 'dispute'
resolution: 'accepted' | 'denied' // resolution is 'denied' if the cipherblock can be properly decrypted; otherwise is 'accepted'
dataExchangeId: string // the unique id of this data exchange
iat: number // unix timestamp stating when it was resolved
iss: string // the public key of the CRS in JWK
sub: string // the public key (JWK) of the entity that requested a resolution
}
You can get a local instance (for development) up and running with NPM or Docker
Install the service as:
npm install @i3m/conflict-resolver-service
Copy template.env
into that directory and name it .env
.
Fill in the required variables (it is self-explanatory).
You need a pair of private/public keys in JWK format. You have two options: 1) to let the server generate them when it is first started (leave the CRS_PRIVATE_JWK
and CRS_PUBLIC_JWK
empty); 2) create them as follows and adding the to your .env file.
- [new keys]
npx generateJwks ES256
- [using a private key in hex]
node generateJwks ES256 <your private key in hex>
Just call
npx generateJwks -h
for further help.
You must also state an RPC endpoint for accessing the ledger RPC_PROVIDER_URL
Run your CRS as:
npx crs
Download Dockerfile
to a directory. From that directory, built it as:
docker build -t crs .
Copy template.env
into that directory and name it .env
.
Fill in the required variables (it is self-explanatory).
You need a pair of private/public keys in JWK format. You have two options: 1) to let the server generate them when it is first started (leave the CRS_PRIVATE_JWK
and CRS_PUBLIC_JWK
empty); 2) create them as follows and adding the to your .env file.
- [new keys]
docker run -it --init crs generateJwks ES256
- [using a private key in hex]
docker run -it --init crs generateJwks ES256 <your private key in hex>
Just call
docker run -it --init crs generateJwks -h
for further help.
Run your CRS as:
-
If you are using env variables for you JWKs:
docker run -it --init -p 127.0.0.1:3000:3000 --env-file .env crs
-
Otherwise, for your keys to persist you also need to mount a volume in the container's
/app/.keys
:docker run -it --init -p 127.0.0.1:3000:3000 --env-file .env -v keys:/app/.keys crs
Notice that we are just exposing
localhost
at tcp port 3000. Use the configuration you need. In production, you will likely have it behind a reverse proxy providing TLS.