Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add connection module in sdk #5

Merged
merged 8 commits into from
Oct 6, 2023
Merged
146 changes: 146 additions & 0 deletions packages/ssi/src/connections/connections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import type {
CreateLegacyInvitationConfig,
CreateOutOfBandInvitationConfig,
ReceiveOutOfBandInvitationConfig
} from '@aries-framework/core'

import { useAdeyaAgent } from '../providers'

/**
* Creates an invitation with RFC 0160: Connection Protocol and returns it together with out-of-band record and invitationUrl.
*
* @param domain domain of the agent
* @param config configuration of how a connection invitation should be created
* @returns out-of-band record and connection invitation together with invitationUrl
*/
export const createLegacyInvitation = async (domain: string, config?: CreateLegacyInvitationConfig) => {
const { agent } = useAdeyaAgent()

const record = await agent?.oob.createLegacyInvitation(config)

const invitationUrl = record.invitation.toUrl({ domain })

return {
record,
invitation: record.invitation,
invitationUrl
}
}

/**
* Creates an out-of-band invitation for establishing a connection with another agent.
*
* @param domain The domain to use for the invitation URL.
* @param config Optional configuration for the invitation.
* @returns An object containing the invitation record, the invitation object, and the invitation URL.
*/
export const createInvitation = async (domain: string, config?: CreateOutOfBandInvitationConfig) => {
const { agent } = useAdeyaAgent()

const record = await agent?.oob.createInvitation(config)

const invitationUrl = record.outOfBandInvitation.toUrl({ domain })

return {
record,
invitation: record.outOfBandInvitation,
invitationUrl
}
}

/**
* Parses an invitation from a URL using the Adeya agent.
*
* @param invitationUrl The URL of the invitation to parse.
* @returns A Promise that resolves with the parsed invitation.
*/
export const parseInvitationFromUrl = async (invitationUrl: string) => {
const { agent } = useAdeyaAgent()

return agent.oob.parseInvitation(invitationUrl)
}

/**
* Accepts a connection invitation from a URL.
*
* @param invitationUrl The URL of the connection invitation.
* @param config Optional configuration for receiving the out-of-band invitation.
* @returns A Promise that resolves to the connection record and out of band record.
* @throws An error if the invitation cannot be parsed from the URL or if the connection does not have an ID.
*/
export const acceptInvitationFromUrl = async (invitationUrl: string, config?: ReceiveOutOfBandInvitationConfig) => {
const { agent } = useAdeyaAgent()
const invitation = await agent?.oob.parseInvitation(invitationUrl)

if (!invitation) {
throw new Error('Could not parse invitation from URL')
}

const record = await agent?.oob.receiveInvitation(invitation, config)
const connectionRecord = record?.connectionRecord
if (!connectionRecord?.id) {
throw new Error('Connection does not have an ID')
}

return record
}

/**
* Returns all connections from the agent.
*
* @returns A promise that resolves to an array of Connection objects.
*/
export const getAllConnections = async () => {
const { agent } = useAdeyaAgent()

return agent.connections.getAll()
}

/**
* Retrieves a connection record by connectionId.
*
* @param connectionId The ID of the connection to retrieve.
* @returns A Promise that resolves to the connection object.
*/
export const getConnectionById = async (connectionId: string) => {
const { agent } = useAdeyaAgent()

return agent.connections.getById(connectionId)
}

/**
* Finds a connection record by its ID.
*
* @param connectionId The ID of the connection to find.
* @returns A Promise that resolves with the connection object, or null if not found.
*/
export const findConnectionById = async (connectionId: string) => {
const { agent } = useAdeyaAgent()

return await agent.connections.findById(connectionId)
}

/**
* Finds an out-of-band record by its connection ID.
*
* @param connectionId The ID of the connection to find.
* @returns A Promise that resolves to the out-of-band record with the given ID.
*/
export const findOutOfBandRecordById = async (connectionId: string) => {
const { agent } = useAdeyaAgent()

return await agent.oob.findById(connectionId)
}

/**
* Deletes a connection by its ID.
*
* @param connectionId The ID of the connection to be deleted.
* @returns A boolean indicating whether the connection was successfully deleted or not.
*/
export const deleteConnectionById = async (connectionId: string) => {
const { agent } = useAdeyaAgent()

await agent.connections.deleteById(connectionId)
return true
}
1 change: 1 addition & 0 deletions packages/ssi/src/connections/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './connections'
49 changes: 47 additions & 2 deletions packages/ssi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,60 @@ import {
} from '@aries-framework/anoncreds'
import { AnonCredsCredentialMetadataKey } from '@aries-framework/anoncreds/build/utils/metadata'
// Core
import { LogLevel, ConsoleLogger } from '@aries-framework/core'
import {
LogLevel,
ConsoleLogger,
BasicMessageRecord,
ConnectionRecord,
CredentialExchangeRecord,
ProofExchangeRecord,
ProofState,
W3cCredentialRecord,
DidExchangeState,
OutOfBandRecord,
CredentialState,
CredentialPreviewAttribute,
JsonLdFormatDataCredentialDetail,
Buffer,
BasicMessageRole,
GetCredentialFormatDataReturn,
ProofFormatPayload,
AgentMessage,
AutoAcceptProof
} from '@aries-framework/core'
// Indy VDR
import { IndyVdrPoolConfig } from '@aries-framework/indy-vdr'

export * from './providers'
export * from './hooks'
export * from './wallet'
export * from './connections'
export { initializeAgent, AdeyaAgent } from './agent'
export { LogLevel, ConsoleLogger, InitConfig, IndyVdrPoolConfig }
// Core
export {
LogLevel,
ConsoleLogger,
InitConfig,
IndyVdrPoolConfig,
BasicMessageRecord,
ConnectionRecord,
OutOfBandRecord,
CredentialExchangeRecord,
W3cCredentialRecord,
ProofExchangeRecord,
ProofState,
DidExchangeState,
CredentialState,
CredentialPreviewAttribute,
JsonLdFormatDataCredentialDetail,
Buffer,
BasicMessageRole,
GetCredentialFormatDataReturn,
ProofFormatPayload,
AgentMessage,
AutoAcceptProof
}
// Anoncreds
export {
V1RequestPresentationMessage,
AnonCredsCredentialOffer,
Expand Down
9 changes: 8 additions & 1 deletion packages/ssi/src/providers/AgentProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import type { AdeyaAgent } from '../agent'

import AgentProvider, { useAgent } from '@aries-framework/react-hooks'

export { useAgent as useAdeyaAgent, AgentProvider as AdeyaAgentProvider }
const useAdeyaAgent: () => {
loading: boolean
agent: AdeyaAgent
} = useAgent

export { useAdeyaAgent, AgentProvider as AdeyaAgentProvider }
4 changes: 1 addition & 3 deletions packages/ssi/src/wallet/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import { importWalletWithAgent, isWalletImportable, isWalletPinCorrect } from './wallet'

export { importWalletWithAgent, isWalletImportable, isWalletPinCorrect }
export * from './wallet'
23 changes: 23 additions & 0 deletions packages/ssi/src/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ interface WalletImportConfigWithAgent {
indyNetworks: [IndyVdrPoolConfig, ...IndyVdrPoolConfig[]]
}

/**
* Checks if the given wallet pin is correct by opening a custom wallet instance with the provided secret.
*
* @param walletConfig - The configuration object for the wallet.
* @returns A Promise that resolves to a boolean indicating whether the wallet pin is correct or not.
*/
export const isWalletPinCorrect = async (walletConfig: WalletConfig) => {
try {
// NOTE: a custom wallet is used to check if the wallet key is correct. This is different from the wallet used in the rest of the app.
Expand All @@ -46,6 +52,13 @@ export const isWalletPinCorrect = async (walletConfig: WalletConfig) => {
}
}

/**
* Checks if a wallet can be imported successfully with the given configuration.
*
* @param walletConfig The configuration for the wallet.
* @param importConfig The configuration for importing the wallet.
* @returns A Promise that resolves to a boolean indicating whether the wallet can be imported successfully.
*/
export const isWalletImportable = async (
walletConfig: WalletConfig,
importConfig: WalletExportImportConfig
Expand All @@ -72,6 +85,16 @@ export const isWalletImportable = async (
}
}

/**
* Imports a wallet with an agent.
*
* @param importConfig The configuration for importing the wallet.
* @param agentConfig The configuration for the agent.
* @param mediatorInvitationUrl The mediator invitation URL.
* @param indyNetworks The Indy networks.
* @returns The agent with the imported wallet.
* @throws An error if the passphrase is invalid.
*/
export const importWalletWithAgent = async ({
importConfig,
agentConfig,
Expand Down