Large contents don’t fit in QR codes so this service is designed to receive an encrypted file, store it in IPFS and also store the file in memory. It returns the cid of the stored file and a convey-uri that indicates that this kind of files should be gotten from a convey service implementation
Read the running guide to run the whole project or browse the open-source repo to run locally (please use tag v0.1.0
)
Find the protocol specification here.
The Convey service has been built to act as a content relayer in front of IPFS. Let’s imagine that Bob wants to share a JWT with Alice through a QR code. If the content is too large, it will not fit in a QR code, so there is where the Convey service acts. It allows to transport and caché files that can be accessed via HTTPS, and provides a tiny URL that can fit in any QR code. The service exposes two main endpoints: POST and GET files. Please refer to the protocol description here for more details about it.
See the DID Authentication protocol for more details.
Example
import axios from 'axios'
import { createVerifiableCredentialJwt } from 'did-jwt-vc'
import RSKEthrDID from '@rsksmart/ethr-did'
const identity = new RSKEthrDID({
address: '0xDe9D2B98E1c23E2765c06C5057723a6c1c453147',
privateKey: '2f86e57652ee906707d4415105228b4fda7b1b900cfd0871cd5d17277ad084b8'
})
axios.post(`${serviceUrl}/request-auth`, { did: identity.did })
.then(res => res.status === 200 && !!res.data && res.data.challenge)
.then(challenge => createVerifiableCredentialJwt({
vc: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential'],
credentialSubject: {
claims: [
{ claimType: 'challenge', claimValue: challenge }
]
}
}
}, identity))
.then(jwt => axios.post(`${serviceUrl}/auth`, { jwt }))
.then(res => res.status === 200 && !!res.data && res.data.token)
convey://{CID}#{key}
Example
import axios from 'axios'
const content = 'myLargeContent'
const { encrypted, encriptionKey } = encrypt(content)
login()
.then(token => axios.post(`${serviceUrl}/file`, { file: encrypted }, { headers: { 'Authorization': token }))
.then(res => res.status === 200 && !!res.data && res.data)
.then({ cid, url } => generateQr(`${url}#${encriptionKey}`))
http://{conveyService}/file/{CID}
https://{ipfsGateway}/ipfs/{CID}
)Example
import axios from 'axios'
const qrContent = `convey://${cid}#${ecKey}`
const index = 'convey://'.length
const identifier = uri.substring(index)
const [cid, encryptionKey] = identifier.split('#')
login()
.then(token => axios.get(`${serviceUrl}/file/${cid}`, { headers: { 'Authorization': token }))
.then(res => res.status === 200 && !!res.data && res.data.file)
.then(file => decrypt(file, encryptionKey))
.then(content => console.log(`Decrypted content: ${content}`))
This service uses a simplified version of DID Auth protocol
Generates a random 64 bytes challenge that is associated to the received DID. It is part of the implementation of the DID Authentication protocol
Parameter
did
- string
DID that will be associated with the generated challenge.Returns
{ challenge: generatedChallenge }
Example with Axios
import axios from 'axios'
const did = 'did:ethr:rsk:testnet:0x....1234'
axios.post(`${serviceUrl}/request-auth`, { did })
.then(res => res.status === 200 && !!res.data && res.data.challenge)
.then(challenge => console.log(`The challenge is: ${challenge}`))
Verifies challenge and did of the received VC, if it is ok, it emits another VC and responds with the JWT representation of it. It will act as the authentication token. It is part of the implementation of the DID Authentication protocol.
Parameter
jwt
- jwt
representation of a VC signed by the client with the received challenge. That VC should be signed by the DID sent before and follow this format:
vc: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential'],
credentialSubject: {
claims: [
{ claimType: 'challenge', claimValue: RECEIVED_CHALLENGE }
]
}
}
Returns
{ token: generatedToken }
Example with Axios
and did-jwt-vc
import axios from 'axios'
import { createVerifiableCredentialJwt } from 'did-jwt-vc'
const jwt = await createVerifiableCredentialJwt({
vc: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential'],
credentialSubject: {
claims: [
{ claimType: 'challenge', claimValue: theReceivedChallenge }
]
}
}
}, identity) // this identity should be associated to the did sent in /request_auth
axios.post(`${serviceUrl}/auth`, { jwt }))
.then(res => res.status === 200 && !!res.data && res.data.token)
.then(token => console.log(`The authentication token is: ${token}`))
Use this API to send and receive files using the convey
It stores the file in IPFS and then saves in the service memory the original content associated to its IPFS hash (cid)
Parameter
file
- string content to be savedReturns
{
url: `convey://${cid}`,
cid: generatedCid
}
Example with Axios
import axios from 'axios'
const content = 'myLargeContent'
const { encrypted, encriptionKey } = encrypt(content)
const token = thePreviouslyReceivedToken
axios.post(`${serviceUrl}/file`, { file: encrypted }, { headers: { 'Authorization': token }))
.then(res => res.status === 200 && !!res.data && res.data)
.then({ cid, url } => console.log(`The Convey uri: ${url}. The CID: ${cid}`))
It looks for the given CID in the service memory and responds with it in case it is found. If not, returns an HTTP 404.
Parameter
cid
- CID of the desired contentReturns
{
file: retrievedFileFromMemory
}
Example with Axios
import axios from 'axios'
const token = thePreviouslyReceivedToken
const cid = theOneGottenFromTheQr
axios.get(`${serviceUrl}/file/${cid}`, { headers: { 'Authorization': token }))
.then(res => res.status === 200 && !!res.data && res.data.file)
.then(file => console.log(`The retrieved file is: ${file}.`))
The service source code is hosted in Github, so please refer directly to the README and check there the detailed guide to install and test the service locally or with a Docker container.
Go to top