Skip to content

Commit

Permalink
add deep link test case
Browse files Browse the repository at this point in the history
Signed-off-by: Clécio Varjão <[email protected]>
  • Loading branch information
cvarjao committed Oct 31, 2024
1 parent 9e7a0e4 commit c2b8efc
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/AgentManual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export class AgentManual implements AriesAgent {
const relativePath = './tmp/__qrcode.png'
const QRCodePath = path.resolve(process.cwd() as string, relativePath)
fs.mkdirSync(path.dirname(QRCodePath), { recursive: true })
fs.writeFileSync(path.join(process.cwd(), 'invitation_url.txt'), ref.payload.invitation_url)
fs.writeFileSync(path.join(process.cwd(), 'invitation.json'), JSON.stringify((ref.payload.invitation as any)))
//fs.writeFileSync(path.join(process.cwd(), 'invitation_url.txt'), ref.payload.invitation_url)
//fs.writeFileSync(path.join(process.cwd(), 'invitation.json'), JSON.stringify((ref.payload.invitation as any)))
await QRCode.toFile(
QRCodePath,
ref.payload.invitation_url,
Expand Down
96 changes: 96 additions & 0 deletions src/deep-links.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { describe, test } from "@jest/globals";
import { AgentTraction } from "./AgentTraction";
import { AgentCredo } from "./AgentCredo";
import { LogLevel } from "@credo-ts/core";
import { PersonSchemaV1_1 } from "./mocks";
import { CredentialDefinitionBuilder, PinoLogger, withDeepLinkPage, withRedirectUrl } from "./lib";
import pino from "pino";

const stepTimeout = 120_000
const shortTimeout = 40_000
import { dir as console_dir } from "console"
import { setGlobalDispatcher, Agent} from 'undici';
import { AriesAgent, INVITATION_TYPE } from "./Agent";
import { AgentManual } from "./AgentManual";
import { cache_requests } from "./axios-traction-serializer";
setGlobalDispatcher(new Agent({connect: { timeout: 20_000 }}));

export const loggerTransport = pino.transport({
targets: [
{
level: 'trace',
target: 'pino/file',
options: {
destination: `./logs/run-${Date.now()}.log.ndjson`,
autoEnd: true,
},
}
],
})

describe("deep-links", () => {
const _logger = pino({ level: 'trace', timestamp: pino.stdTimeFunctions.isoTime, }, loggerTransport);
const logger = new PinoLogger(_logger, LogLevel.trace)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const config = require("../local.env.json")
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ledgers = require("../ledgers.json");
const agentSchemaOwner = new AgentTraction(config.schema_owner, logger);
const agentIssuer = new AgentTraction(config.issuer, logger);
const agentVerifier = new AgentTraction(config.verifier, logger);
//const agentB: AriesAgent = new AgentManual(config, new ConsoleLogger(LogLevel.trace))
const agentB: AriesAgent = process.env.HOLDER_TYPE === 'manual'? new AgentManual(config.holder, logger): new AgentCredo(config.holder,ledgers, logger)
//new PinoLogger(logger, LogLevel.trace));
const schema = new PersonSchemaV1_1();
const credDef = new CredentialDefinitionBuilder()
.setSchema(schema)
.setSupportRevocation(true)
.setTag('Revocable Credential')
const requests: unknown[] = []
beforeAll(async () => {
logger.info('1 - beforeAll')
await agentSchemaOwner.startup()
await agentIssuer.startup()
await agentB.startup()
await agentVerifier.startup()
//await Promise.all([agentA.startup(), agentB.startup()]);
agentSchemaOwner.axios.interceptors.request.use(cache_requests(requests))
agentIssuer.axios.interceptors.request.use(cache_requests(requests))
agentVerifier.axios.interceptors.request.use(cache_requests(requests))
agentIssuer.axios.interceptors.response.use( async (response) => {
return response
}, (error) => {
console_dir(error.response)
return Promise.reject(error);
})

await agentSchemaOwner.createSchema(schema);
await agentIssuer.createSchemaCredDefinition(credDef);
}, stepTimeout);
afterAll(async () => {
logger.info('1 - afterAll')
await agentB.shutdown();
_logger.flush();
//loggerTransport.end();
}, stepTimeout);
beforeEach(async () => {
requests.length = 0
})
test("OOB/connected/messaging", async () => {
const issuer = agentIssuer
const holder = agentB
logger.info(`Executing ${expect.getState().currentTestName}`)
const remoteInvitation = await withDeepLinkPage(await withRedirectUrl(await issuer.createInvitationToConnect(INVITATION_TYPE.OOB_DIDX_1_1)))
logger.info(`waiting for holder to accept connection`)
const agentBConnectionRef1 = await holder.receiveInvitation(remoteInvitation)
logger.info(`waiting for issuer to accept connection`)
const {connection_id} = await issuer.waitForOOBConnectionReady(remoteInvitation.payload.invi_msg_id)
logger.info(`${connection_id} connected to ${agentBConnectionRef1.connectionRecord?.connection_id}`)
logger.info('agentBConnectionRef1', agentBConnectionRef1)
const msgSent: any = await issuer.sendBasicMessage(connection_id, 'Hello')
logger.info('Message Sent:', msgSent)
await holder.sendBasicMessage(agentBConnectionRef1.connectionRecord?.connection_id as string, 'ok')
const msgRcvd = await issuer.waitForBasicMessage(connection_id, Date.parse(msgSent.created_at as string), ["k", "ok"])
logger.info('Message Received:', msgRcvd)
}, stepTimeout);
});
18 changes: 15 additions & 3 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import axios, {AxiosInstance} from 'axios';
import { PersonCredential1 } from './mocks';
import { BaseLogger, InvitationType, LogLevel, ProofExchangeRecord } from '@credo-ts/core';
import { BaseLogger, LogLevel, ProofExchangeRecord } from '@credo-ts/core';
import { Logger } from 'pino';
import { AgentTraction } from './AgentTraction';
import { AriesAgent, INVITATION_TYPE, ResponseCreateInvitation, ResponseCreateInvitationV1, ResponseCreateInvitationV2 } from './Agent';
import { AriesAgent, CreateInvitationResponse, INVITATION_TYPE, ResponseCreateInvitationV1, ResponseCreateInvitationV2 } from './Agent';
import fs from 'node:fs';
import path from 'node:path';
import { log, dir} from "console"
Expand Down Expand Up @@ -921,7 +921,19 @@ export const verifyCredentialA2 = async (verifier:AriesAgent, holder: AriesAgent
logger.info('Verifier is waiting for proofs')
await verifier.waitForPresentation(remoteInvitation3.payload.presentation_exchange_id as string)
}
export const withRedirectUrl = async (remoteInvitation3: ResponseCreateInvitation): Promise<ResponseCreateInvitation> => {
export function base64URLencode(str: string) {
const base64Encoded = encodeURIComponent(str)
return base64Encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
export const withDeepLinkPage = async <T extends INVITATION_TYPE>(remoteInvitation3: CreateInvitationResponse<T>): Promise<CreateInvitationResponse<T>> => {
const invitationFile = `${remoteInvitation3.payload.invitation['@id']}.html`
fs.writeFileSync(path.join(process.cwd(), `/tmp/${invitationFile}`), `<html><body><h1 style="font-size: 80pt"><a href="bcwallet://?_url=${Buffer.from(remoteInvitation3.payload.invitation_url).toString('base64url')}">click here</a></h1></body></html>`)
const publicUrl = await axios.get('http://127.0.0.1:4040/api/tunnels').then((response)=>{return response.data.tunnels[0].public_url as string})
remoteInvitation3.payload.invitation_url = `${publicUrl}/${invitationFile}`

return remoteInvitation3
}
export const withRedirectUrl = async <T extends INVITATION_TYPE>(remoteInvitation3: CreateInvitationResponse<T>): Promise<CreateInvitationResponse<T>> => {
const invitationFile = `${remoteInvitation3.payload.invitation['@id']}.json`
fs.writeFileSync(path.join(process.cwd(), `/tmp/${invitationFile}`), JSON.stringify(remoteInvitation3.payload.invitation, undefined, 2))
const publicUrl = await axios.get('http://127.0.0.1:4040/api/tunnels').then((response)=>{return response.data.tunnels[0].public_url as string})
Expand Down

0 comments on commit c2b8efc

Please sign in to comment.