Skip to content

Commit

Permalink
Expose nonmediated connection in node wrapper (#738)
Browse files Browse the repository at this point in the history
* Expose nonmediated connection in node wrapper

Signed-off-by: Miroslav Kovar <miroslav.kovar@absa.africa>
  • Loading branch information
mirgee committed Jan 25, 2023
1 parent 06aa3d6 commit 66ee076
Show file tree
Hide file tree
Showing 24 changed files with 5,158 additions and 74 deletions.
7 changes: 4 additions & 3 deletions agents/node/vcxagent-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"demo:faber:mysql": "node demo/faber.js --mysql",
"demo:alice:sign": "node demo/alice-signature.js",
"demo:faber:verify": "node demo/faber-verify-signature.js",
"test:integration": "npm run test:integration:issue-verify && npm run test:integration:signing && npm run test:integration:messaging && npm run test:integration:tails && npm run test:integration:trustping && npm run test:integration:feature-discovery && npm run test:integration:public-invite && npm run test:integration:out-of-band && npm run test:integration:nonmediation",
"test:integration": "npm run test:integration:issue-verify && npm run test:integration:signing && npm run test:integration:messaging && npm run test:integration:tails && npm run test:integration:trustping && npm run test:integration:feature-discovery && npm run test:integration:public-invite && npm run test:integration:out-of-band && npm run test:integration:nonmediated-endpoint && npm run test:integration:nonmediated-connection",
"test:integration:issue-verify": "jest --forceExit --env=node --runInBand test/issue-verify.spec.js",
"test:integration:signing": "jest --forceExit --env=node --runInBand test/sign-verify.spec.js",
"test:integration:messaging": "jest --forceExit --env=node --runInBand test/messaging.spec.js",
Expand All @@ -44,8 +44,9 @@
"test:integration:feature-discovery": "jest --forceExit --env=node --runInBand test/feature-discovery.spec.js",
"test:integration:public-invite": "jest --forceExit --env=node --runInBand test/public-invite.spec.js",
"test:integration:out-of-band": "jest --forceExit --env=node --runInBand test/out-of-band.spec.js",
"test:integration:nonmediation": "jest --forceExit --env=node --runInBand test/nonmediated-endpoint.spec.js"
},
"test:integration:nonmediated-endpoint": "jest --forceExit --env=node --runInBand test/nonmediated-endpoint.spec.js",
"test:integration:nonmediated-connection": "jest --forceExit --env=node --runInBand test/nonmediated-connection.spec.js"
},
"dependencies": {
"axios": "^0.27.2",
"ffi-napi": "^4.0.3",
Expand Down
26 changes: 18 additions & 8 deletions agents/node/vcxagent-core/src/agent.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const { getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta } = require('@hyperledger/node-vcx-wrapper')
const { getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, defaultLogger } = require('@hyperledger/node-vcx-wrapper')
const { createServiceLedgerCredDef } = require('./services/service-ledger-creddef')
const { createServiceLedgerSchema } = require('./services/service-ledger-schema')
const { createServiceVerifier } = require('./services/service-verifier')
const { createServiceProver } = require('./services/service-prover')
const { createServiceCredHolder } = require('./services/service-cred-holder')
const { createServiceCredIssuer } = require('./services/service-cred-issuer')
const { createServiceConnections } = require('./services/service-connections')
const { createServiceNonmediatedConnections } = require('./services/service-nonmediated-connections')
const { createServiceOutOfBand } = require('./services/service-out-of-band')
const { createServiceLedgerRevocationRegistry } = require('./services/service-revocation-registry')
const { provisionAgentInAgency } = require('./utils/vcx-workflows')
Expand All @@ -20,7 +21,7 @@ const {
const { createStorageService } = require('./storage/storage-service')
const { waitUntilAgencyIsReady, getAgencyConfig } = require('./common')

async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, walletExtraConfigs, logger }) {
async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletExtraConfigs, endpointInfo, logger }) {
genesisPath = genesisPath || `${__dirname}/../resources/docker.txn`

await waitUntilAgencyIsReady(agencyUrl, logger)
Expand All @@ -34,8 +35,9 @@ async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, wallet
const agentProvision = await storageService.loadAgentProvision()
const issuerDid = agentProvision.issuerConfig.institution_did

async function agentInitVcx () {
async function agentInitVcx() {
logger.info(`Initializing ${agentName} vcx session.`)

logger.silly(`Using following agent provision to initialize VCX settings ${JSON.stringify(agentProvision, null, 2)}`)
logger.silly('Initializing issuer config')
await initIssuerConfig(agentProvision.issuerConfig)
Expand All @@ -47,17 +49,17 @@ async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, wallet
await openMainPool({ genesis_path: genesisPath })
}

async function agentShutdownVcx () {
async function agentShutdownVcx() {
logger.debug(`Shutting down ${agentName} vcx session.`)
shutdownVcx()
}

async function updateWebhookUrl (webhookUrl) {
async function updateWebhookUrl(webhookUrl) {
logger.info(`Updating webhook url to ${webhookUrl}`)
await vcxUpdateWebhookUrl({ webhookUrl })
}

async function acceptTaa () {
async function acceptTaa() {
const taa = await getLedgerAuthorAgreement()
const taaJson = JSON.parse(taa)
const utime = Math.floor(new Date() / 1000)
Expand All @@ -66,17 +68,24 @@ async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, wallet
await setActiveTxnAuthorAgreementMeta(taaJson.text, taaJson.version, null, acceptanceMechanism, utime)
}

function getInstitutionDid () {
function getInstitutionDid() {
return issuerDid
}

const serviceConnections = createServiceConnections({
logger,
saveConnection: storageService.saveConnection,
loadConnection: storageService.loadConnection,
loadAgent: storageService.loadAgent,
listConnectionIds: storageService.listConnectionKeys
})

const serviceNonmediatedConnections = createServiceNonmediatedConnections({
logger,
saveNonmediatedConnection: storageService.saveNonmediatedConnection,
loadNonmediatedConnection: storageService.loadNonmediatedConnection,
endpointInfo
})

const serviceLedgerSchema = createServiceLedgerSchema({
logger,
saveSchema: storageService.saveSchema,
Expand Down Expand Up @@ -147,6 +156,7 @@ async function createVcxAgent ({ agentName, genesisPath, agencyUrl, seed, wallet

// connections
serviceConnections,
serviceNonmediatedConnections,

// credex
serviceCredIssuer,
Expand Down
15 changes: 1 addition & 14 deletions agents/node/vcxagent-core/src/services/service-connections.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
} = require('@hyperledger/node-vcx-wrapper')
const { pollFunction } = require('../common')

module.exports.createServiceConnections = function createServiceConnections ({ logger, saveConnection, loadConnection, loadAgent, listConnectionIds }) {
module.exports.createServiceConnections = function createServiceConnections ({ logger, saveConnection, loadConnection, listConnectionIds }) {
async function inviterConnectionCreate (connectionId, cbInvitation) {
logger.info(`InviterConnectionSM creating connection ${connectionId}`)
const connection = await Connection.create({ id: connectionId })
Expand All @@ -22,18 +22,6 @@ module.exports.createServiceConnections = function createServiceConnections ({ l
return invite
}

async function inviterConnectionCreateFromRequest (connectionId, agentId, request) {
logger.info(`InviterConnectionSM creating connection ${connectionId} from received request ${request} and agent id ${agentId}`)
const agent = await loadAgent(agentId)
const connection = await Connection.createWithConnectionRequest({
id: connectionId,
agent,
request
})
await saveConnection(connectionId, connection)
return connection
}

async function inviterConnectionCreateFromRequestV2 (connectionId, pwInfo, request) {
logger.info(`InviterConnectionSM creating connection ${connectionId} from received request ${request} and pw info ${pwInfo}`)
const connection = await Connection.createWithConnectionRequestV2({
Expand Down Expand Up @@ -195,7 +183,6 @@ module.exports.createServiceConnections = function createServiceConnections ({ l
return {
// inviter
inviterConnectionCreate,
inviterConnectionCreateFromRequest,
inviterConnectionCreateFromRequestV2,
inviterConnectionCreateAndAccept,

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const { NonmediatedConnection } = require('@hyperledger/node-vcx-wrapper')

module.exports.createServiceNonmediatedConnections = function createServiceNonmediatedConnections ({ logger, saveNonmediatedConnection, loadNonmediatedConnection, endpointInfo }) {

async function inviterConnectionCreatePwInvite (connectionId) {
logger.info(`inviterConnectionCreatePwInvite >> connectionId=${connectionId}`)
const connection = await NonmediatedConnection.createInviter()
logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`)
await connection.createInvite(endpointInfo)
logger.debug(`InviterConnectionSM after invitation was generated:\n${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
const invite = connection.getInvitation()
logger.debug(`InviterConnectionSM created invitation ${invite}`)
return invite
}

async function inviterConnectionCreateFromRequest (connectionId, request, pwInfo) {
logger.info(`inviterConnectionCreateFromRequest >> connectionId=${connectionId}, request: ${request}, pwInfo: ${pwInfo}`)
const connection = await NonmediatedConnection.createInviter(pwInfo)
logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`)
await connection.processRequest(request, endpointInfo)
logger.debug(`InviterConnectionSM after processing request:\n${JSON.stringify(connection.serialize())}`)
await connection.sendResponse()
logger.debug(`InviterConnectionSM after sending response:\n${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
}

async function inviterConnectionProcessRequest (connectionId, request) {
logger.info(`inviterConnectionProcessRequest >> connectionId=${connectionId}, request: ${request}`)
const connection = await loadNonmediatedConnection(connectionId)
await connection.processRequest(request, endpointInfo)
logger.info(`InviterConnectionSM after processing request:\n${JSON.stringify(connection.serialize())}`)
await connection.sendResponse()
logger.info(`InviterConnectionSM after sending response:\n${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
}

async function inviterConnectionProcessAck (connectionId, ack) {
logger.info(`inviterConnectionProcessAck >> connectionId=${connectionId}, ack: ${ack}`)
const connection = await loadNonmediatedConnection(connectionId)
await connection.processAck(ack)
logger.debug(`InviterConnectionSM after processing ack: ${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
}

async function inviteeConnectionCreateFromInvite (connectionId, invite) {
logger.info(`inviteeConnectionCreateFromInvite >> connectionId=${connectionId}, invite: ${invite}`)
const connection = await NonmediatedConnection.createInvitee(invite)
logger.debug(`InviteeConnectionSM after created from invitation:\n${JSON.stringify(connection.serialize())}`)
connection.processInvite(invite)
await connection.sendRequest(endpointInfo)
logger.debug(`InviteeConnectionSM after sending request:\n${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
}

async function inviteeConnectionProcessResponse (connectionId, response) {
logger.info(`inviteeConnectionProcessResponse >> connectionId=${connectionId}, response: ${response}`)
const connection = await loadNonmediatedConnection(connectionId)
await connection.processResponse(response)
logger.debug(`InviteeConnectionSM after processing response:\n${JSON.stringify(connection.serialize())}`)
await connection.sendAck()
logger.debug(`InviteeConnectionSM connection after sending ack:\n${JSON.stringify(connection.serialize())}`)
await saveNonmediatedConnection(connectionId, connection)
}

async function sendMessage (connectionId, content) {
logger.info(`nonmediatedConnectionSendMessage >> connectionId=${connectionId}, content: ${content}`)
const connection = await loadNonmediatedConnection(connectionId)
await connection.sendMessage(content)
}

async function getState (connectionId) {
const connection = await loadNonmediatedConnection(connectionId)
return connection.getState()
}

return {
inviterConnectionCreatePwInvite,
inviterConnectionCreateFromRequest,
inviterConnectionProcessRequest,
inviterConnectionProcessAck,
inviteeConnectionCreateFromInvite,
inviteeConnectionProcessResponse,
sendMessage,
getState,
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { OutOfBandSender, OutOfBandReceiver } = require('@hyperledger/node-vcx-wrapper')
const assert = require('assert')

module.exports.createServiceOutOfBand = function createServiceOutOfBand ({ logger, saveConnection, loadConnection }) {
function _createOobSender (message, label) {
Expand Down
19 changes: 19 additions & 0 deletions agents/node/vcxagent-core/src/storage/storage-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const { createFileStorage } = require('./storage-file')
const mkdirp = require('mkdirp')
const {
Connection,
NonmediatedConnection,
Credential,
IssuerCredential,
CredentialDef,
Expand All @@ -14,12 +15,14 @@ const {
async function createStorageService (agentName) {
mkdirp.sync('storage-agentProvisions/')
mkdirp.sync('storage-connections/')
mkdirp.sync('storage-nonmediated-connections/')
mkdirp.sync('storage-credentialDefinitions/')
mkdirp.sync('storage-revocationRegistries/')
mkdirp.sync('storage-schemas/')

const storageAgentProvisions = await createFileStorage(`storage-agentProvisions/${agentName}`)
const storageConnections = await createFileStorage(`storage-connections/${agentName}`)
const storageNonmediatedConnections = await createFileStorage(`storage-connections/${agentName}`)
const storageCredIssuer = await createFileStorage(`storage-credsIssuer/${agentName}`)
const storageCredHolder = await createFileStorage(`storage-credsHolder/${agentName}`)
const storageProof = await createFileStorage(`storage-proofs/${agentName}`)
Expand Down Expand Up @@ -53,6 +56,19 @@ async function createStorageService (agentName) {
return Connection.deserialize(serialized)
}

async function saveNonmediatedConnection (name, connection) {
const serialized = await connection.serialize()
await storageNonmediatedConnections.set(`${name}`, serialized)
}

async function loadNonmediatedConnection (name) {
const serialized = await storageNonmediatedConnections.get(`${name}`)
if (!serialized) {
throw Error(`Nonmediated connection ${name} was not found.`)
}
return NonmediatedConnection.deserialize(serialized)
}

async function saveSchema (name, schema) {
const serialized = await schema.serialize()
await storageSchemas.set(name, serialized)
Expand Down Expand Up @@ -184,6 +200,9 @@ async function createStorageService (agentName) {
saveConnection,
loadConnection,

saveNonmediatedConnection,
loadNonmediatedConnection,

saveSchema,
loadSchema,

Expand Down

0 comments on commit 66ee076

Please sign in to comment.