Conflict Resolver Service
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.
1. Endpoints
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 endpoints require JWT bearer authentication. The JWT can be obtained after performing a login with OIDC and presenting valid i3-MARKET credentials.
1.1. POST /verification
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.
1.1.1. Input
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
}
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
por: string
dataExchangeId: string
}
1.1.2. Output
It returns a signed resolution as a compact JWS with payload:
{
proofType: 'resolution'
type: 'verification'
resolution: 'completed' | 'not completed'
dataExchangeId: string
iat: number
iss: string
sub: string
}
1.2. POST /dispute
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.
1.2.1. Input
{
disputeRequest: string
}
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
iat: number
por: string
dataExchangeId: string
}
1.2.2. Output
It returns a signed resolution as a compact JWS with payload:
{
proofType: 'resolution'
type: 'dispute'
resolution: 'accepted' | 'denied'
dataExchangeId: string
iat: number
iss: string
sub: string
}
2. Local setup
You can get a local instance (for development) up and running with NPM or Docker
2.1. NPM
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 privatekey 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
2.2. Docker
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 privatekey 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.