Skip to content

Commit

Permalink
feat: break out indy wallet, better indy handling (#396)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimoGlastra authored Aug 4, 2021
1 parent 4bc05e2 commit 9f1a4a7
Show file tree
Hide file tree
Showing 54 changed files with 817 additions and 781 deletions.
35 changes: 18 additions & 17 deletions docs/getting-started/0-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,29 @@ Before initializing your agent, make sure you have followed the setup guide for
You can set up an agent by importing the `Agent` class. It requires you to pass in a JSON object to configure the agent. The following is an example with only the required configuration options specified. The agent by itself can't do much yet, we need [transports](1-transports.md) to be able to interact with other agents.

```ts
import indy from 'indy-sdk'
import { NodeFileSystem } from 'aries-framework/build/storage/fs/NodeFileSystem'

import { Agent, InitConfig } from 'aries-framework'
import { Agent, InitConfig } from '@aries-framework/core'
import { agentDependencies } from '@aries-framework/node'

const agentConfig: InitConfig = {
// The label is used for communication with other
label: 'My Agent',
walletConfig: { id: 'walletId' },
walletCredentials: { key: 'testKey0000000000000000000000000' },
indy,
fileSystem: new NodeFileSystem(),
walletConfig: {
id: 'walletId',
key: 'testKey0000000000000000000000000',
},
}

const agent = new Agent(agentConfig)
const agent = new Agent(agentConfig, agentDependencies)
```

## Configuration Options

The agent currently supports the following configuration options. Fields marked with a **\*** are required. Other parts of this documentation go into more depth on the different configuration options.

- `label`\*: The label to use for invitations.
- `indy`\*: The indy sdk to use for indy operations. This is different for NodeJS / React Native
- `fileSystem`\*: The file system instance used for reading and writing files.
- `walletConfig`: The wallet config to use for creating and unlocking the wallet
- `walletCredentials`: The wallet credentials to use for creating and unlocking the wallet
- `host`: The host to use for invitations.
- `post`: The port to append to host for invitations.
- `endpoint`: The endpoint (host + port) to use for invitations. Has priority over `host` and `port.
- `walletConfig`: The wallet config to use for creating and unlocking the wallet. Not required, but requires extra setup if not passed in constructor
- `endpoint`: The endpoint (schema + host + port) to use for invitations.
- `publicDidSeed`: The seed to use for initializing the public did of the agent. This does not register the DID on the ledger.
- `autoAcceptConnections`: Whether to auto accept all incoming connections. Default false
- `genesisPath`: The path to the genesis file to use for connecting to an Indy ledger.
- `genesisTransactions`: String of genesis transactions to use for connecting to an Indy ledger.
- `poolName`: The name of the pool to use for the specified `genesisPath`. Default `default-pool`
Expand All @@ -55,3 +47,12 @@ The agent currently supports the following configuration options. Fields marked
- `mediationConnectionsInvitation` - Connection invitation to use for default mediator. If specified the agent will create a connection, request mediation and store the mediator as default for all connections.
- `defaultMediatorId` - Mediator id to use as default mediator. Use this if you want to override the currently default mediator.
- `clearDefaultMediator` - Will clear the default mediator
- `autoAcceptConnections`: Whether to auto accept all incoming connections. Default false
- `autoAcceptProofs`: Whether to auto accept all incoming proofs:
- `AutoAcceptProof.Always`: Always auto accepts the proof no matter if it changed in subsequent steps
- `AutoAcceptProof.ContentApproved`: Needs one acceptation and the rest will be automated if nothing changes
- `AutoAcceptProof.Never`: Default. Never auto accept a proof
- `autoAcceptCredentials`: Whether to auto accept all incoming proofs:
- `AutoAcceptCredential.Always`: Always auto accepts the credential no matter if it changed in subsequent steps
- `AutoAcceptCredential.ContentApproved`: Needs one acceptation and the rest will be automated if nothing changes
- `AutoAcceptCredential.Never`: Default. Never auto accept a credential
2 changes: 1 addition & 1 deletion docs/getting-started/1-transports.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ An agent needs an inbound and outbound transporter. At this current time, the ou
Outbound transports allow you to send messages to other agents. Currently, only a single outbound transport can be used. See [Issue 268: Add support for multiple transports](https://github.com/hyperledger/aries-framework-javascript/issues/268) for progress on supporting multiple outbound transports.

```ts
import { HttpOutboundTransporter, WsOutboundTransporter Agent } from 'aries-framework'
import { HttpOutboundTransporter, WsOutboundTransporter Agent } from '@aries-framework/core'

const agent = new Agent({
/* config */
Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started/7-logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
To enable logging inside the framework a logger must be passed to the agent config. A simple `ConsoleLogger` can be imported from the framework.

```ts
import { ConsoleLogger, LogLevel } from 'aries-framework'
import { ConsoleLogger, LogLevel } from '@aries-framework/core'

const agentConfig = {
// ... other config properties ...
Expand All @@ -18,7 +18,7 @@ const agentConfig = {
For more advanced use cases the `Logger` interface can be implemented. See the example below.

```ts
import { Logger, LogLevel } from 'aries-framework'
import { Logger, LogLevel } from '@aries-framework/core'

class MyCustomLogger implements Logger {
public logLevel: LogLevel
Expand Down
6 changes: 4 additions & 2 deletions docs/setup-electron.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ const indyWithErrorHandling = Object.fromEntries(
// This creates an agent with all the specified configuration data
const agent = new Agent({
label: 'my-agent',
walletConfig: { id: 'walletId' },
walletCredentials: { key: 'testkey0000000000000000000000000' },
walletConfig: {
id: 'walletId',
key: 'testkey0000000000000000000000000',
},
// used custom indyWithErrorHandling created above
indy: indyWithErrorHandling as unknown as typeof Indy,
// Use fs exposed on window from main world
Expand Down
6 changes: 4 additions & 2 deletions docs/setup-nodejs.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ import { agentDependencies } from '@aries-framework/node'
const agent = new Agent(
{
label: 'my-agent',
walletConfig: { id: 'walletId' },
walletCredentials: { key: 'testkey0000000000000000000000000' },
walletConfig: {
id: 'walletId',
key: 'testkey0000000000000000000000000',
},
},
agentDependencies
)
Expand Down
6 changes: 4 additions & 2 deletions docs/setup-react-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ import { agentDependencies } from '@aries-framework/react-native'
const agent = new Agent(
{
label: 'my-agent',
walletConfig: { id: 'walletId' },
walletCredentials: { key: 'testkey0000000000000000000000000' },
walletConfig: {
id: 'walletId',
key: 'testkey0000000000000000000000000',
},
},
agentDependencies
)
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@types/eslint": "^7.2.13",
"@types/express": "^4.17.13",
"@types/jest": "^26.0.23",
"@types/node": "^15.14.1",
"@types/node": "^15.14.4",
"@types/uuid": "^8.3.1",
"@types/ws": "^7.4.6",
"@typescript-eslint/eslint-plugin": "^4.26.1",
Expand All @@ -54,6 +54,9 @@
"typescript": "^4.3.0",
"ws": "^7.4.6"
},
"resolutions": {
"@types/node": "^15.14.4"
},
"engines": {
"node": ">= 12"
}
Expand Down
3 changes: 0 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,5 @@
"rimraf": "~3.0.2",
"tslog": "^3.2.0",
"typescript": "~4.3.0"
},
"resolutions": {
"@types/node": "^15.14.1"
}
}
12 changes: 6 additions & 6 deletions packages/core/src/agent/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ export class Agent {
logger: initialConfig.logger != undefined,
})

if (!this.agentConfig.walletConfig || !this.agentConfig.walletCredentials) {
if (!this.agentConfig.walletConfig) {
this.logger.warn(
'Wallet config and/or credentials have not been set on the agent config. ' +
'Wallet config has not been set on the agent config. ' +
'Make sure to initialize the wallet yourself before initializing the agent, ' +
'or provide the required wallet configuration in the agent constructor'
)
Expand Down Expand Up @@ -135,19 +135,19 @@ export class Agent {
}

public async initialize() {
const { publicDidSeed, walletConfig, walletCredentials, mediatorConnectionsInvite } = this.agentConfig
const { publicDidSeed, walletConfig, mediatorConnectionsInvite } = this.agentConfig

if (this._isInitialized) {
throw new AriesFrameworkError(
'Agent already initialized. Currently it is not supported to re-initialize an already initialized agent.'
)
}

if (!this.wallet.isInitialized && walletConfig && walletCredentials) {
await this.wallet.initialize(walletConfig, walletCredentials)
if (!this.wallet.isInitialized && walletConfig) {
await this.wallet.initialize(walletConfig)
} else if (!this.wallet.isInitialized) {
throw new WalletError(
'Wallet config and/or credentials have not been set on the agent config. ' +
'Wallet config has not been set on the agent config. ' +
'Make sure to initialize the wallet yourself before initializing the agent, ' +
'or provide the required wallet configuration in the agent constructor'
)
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/agent/AgentConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ export class AgentConfig {
return this.initConfig.walletConfig
}

public get walletCredentials() {
return this.initConfig.walletCredentials
}

public get autoAcceptConnections() {
return this.initConfig.autoAcceptConnections ?? false
}
Expand Down
13 changes: 6 additions & 7 deletions packages/core/src/agent/EnvelopeService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Logger } from '../logger'
import type { UnpackedMessageContext, WireMessage } from '../types'
import type { AgentMessage } from './AgentMessage'
import type { Verkey } from 'indy-sdk'

import { inject, scoped, Lifecycle } from 'tsyringe'

Expand All @@ -12,9 +11,9 @@ import { Wallet } from '../wallet/Wallet'
import { AgentConfig } from './AgentConfig'

export interface EnvelopeKeys {
recipientKeys: Verkey[]
routingKeys: Verkey[]
senderKey: Verkey | null
recipientKeys: string[]
routingKeys: string[]
senderKey: string | null
}

@scoped(Lifecycle.ContainerScoped)
Expand All @@ -28,12 +27,12 @@ class EnvelopeService {
}

public async packMessage(payload: AgentMessage, keys: EnvelopeKeys): Promise<WireMessage> {
const { routingKeys, recipientKeys, senderKey: senderVk } = keys
const { routingKeys, recipientKeys, senderKey } = keys
const message = payload.toJSON()

this.logger.debug(`Pack outbound message ${payload.type}`)

let wireMessage = await this.wallet.pack(message, recipientKeys, senderVk)
let wireMessage = await this.wallet.pack(message, recipientKeys, senderKey ?? undefined)

if (routingKeys && routingKeys.length > 0) {
for (const routingKey of routingKeys) {
Expand All @@ -44,7 +43,7 @@ class EnvelopeService {
message: wireMessage,
})
this.logger.debug('Forward message created', forwardMessage)
wireMessage = await this.wallet.pack(forwardMessage.toJSON(), [routingKey], senderVk)
wireMessage = await this.wallet.pack(forwardMessage.toJSON(), [routingKey], senderKey ?? undefined)
}
}
return wireMessage
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/agent/__tests__/Agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ConnectionService } from '../../modules/connections/services/Connection
import { TrustPingService } from '../../modules/connections/services/TrustPingService'
import { CredentialRepository, CredentialService } from '../../modules/credentials'
import { CredentialsModule } from '../../modules/credentials/CredentialsModule'
import { LedgerService } from '../../modules/ledger'
import { IndyLedgerService } from '../../modules/ledger'
import { LedgerModule } from '../../modules/ledger/LedgerModule'
import { ProofRepository, ProofService } from '../../modules/proofs'
import { ProofsModule } from '../../modules/proofs/ProofsModule'
Expand Down Expand Up @@ -71,7 +71,7 @@ describe('Agent', () => {
it('wallet must be initialized if wallet config is not set before agent can be initialized', async () => {
expect.assertions(9)

const { walletConfig, walletCredentials, ...withoutWalletConfig } = config
const { walletConfig, ...withoutWalletConfig } = config
agent = new Agent(withoutWalletConfig, dependencies)

const wallet = agent.injectionContainer.resolve<Wallet>(InjectionSymbols.Wallet)
Expand All @@ -84,7 +84,7 @@ describe('Agent', () => {
expect(wallet.isInitialized).toBe(false)

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await wallet.initialize(walletConfig!, walletCredentials!)
await wallet.initialize(walletConfig!)
expect(agent.isInitialized).toBe(false)
expect(wallet.isInitialized).toBe(true)

Expand Down Expand Up @@ -124,7 +124,7 @@ describe('Agent', () => {
expect(container.resolve(MediationRecipientService)).toBeInstanceOf(MediationRecipientService)

expect(container.resolve(LedgerModule)).toBeInstanceOf(LedgerModule)
expect(container.resolve(LedgerService)).toBeInstanceOf(LedgerService)
expect(container.resolve(IndyLedgerService)).toBeInstanceOf(IndyLedgerService)

// Symbols, interface based
expect(container.resolve(InjectionSymbols.Wallet)).toBeInstanceOf(IndyWallet)
Expand Down Expand Up @@ -168,7 +168,7 @@ describe('Agent', () => {
expect(container.resolve(MediationRecipientService)).toBe(container.resolve(MediationRecipientService))

expect(container.resolve(LedgerModule)).toBe(container.resolve(LedgerModule))
expect(container.resolve(LedgerService)).toBe(container.resolve(LedgerService))
expect(container.resolve(IndyLedgerService)).toBe(container.resolve(IndyLedgerService))

// Symbols, interface based
expect(container.resolve(InjectionSymbols.Wallet)).toBe(container.resolve(InjectionSymbols.Wallet))
Expand Down
9 changes: 4 additions & 5 deletions packages/core/src/agent/models/InboundMessageContext.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import type { ConnectionRecord } from '../../modules/connections'
import type { AgentMessage } from '../AgentMessage'
import type { Verkey } from 'indy-sdk'

import { AriesFrameworkError } from '../../error'

export interface MessageContextParams {
connection?: ConnectionRecord
senderVerkey?: Verkey
recipientVerkey?: Verkey
senderVerkey?: string
recipientVerkey?: string
}

export class InboundMessageContext<T extends AgentMessage = AgentMessage> {
public message: T
public connection?: ConnectionRecord
public senderVerkey?: Verkey
public recipientVerkey?: Verkey
public senderVerkey?: string
public recipientVerkey?: string

public constructor(message: T, context: MessageContextParams = {}) {
this.message = message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('Decorators | Signature | SignatureDecoratorUtils', () => {
const config = getAgentConfig('SignatureDecoratorUtilsTest')
wallet = new IndyWallet(config)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await wallet.initialize(config.walletConfig!, config.walletCredentials!)
await wallet.initialize(config.walletConfig!)
})

afterAll(async () => {
Expand All @@ -52,7 +52,7 @@ describe('Decorators | Signature | SignatureDecoratorUtils', () => {

test('signData signs json object and returns SignatureDecorator', async () => {
const seed1 = '00000000000000000000000000000My1'
const [, verkey] = await wallet.createDid({ seed: seed1 })
const { verkey } = await wallet.createDid({ seed: seed1 })

const result = await signData(data, wallet, verkey)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Wallet } from '../../wallet/Wallet'
import type { Verkey } from 'indy-sdk'

import { AriesFrameworkError } from '../../error'
import { BufferEncoder } from '../../utils/BufferEncoder'
Expand Down Expand Up @@ -46,7 +45,7 @@ export async function unpackAndVerifySignatureDecorator(
*
* @returns Resulting signature decorator.
*/
export async function signData(data: unknown, wallet: Wallet, signerKey: Verkey): Promise<SignatureDecorator> {
export async function signData(data: unknown, wallet: Wallet, signerKey: string): Promise<SignatureDecorator> {
const dataBuffer = Buffer.concat([timestamp(), JsonEncoder.toBuffer(data)])

const signatureBuffer = await wallet.sign(dataBuffer, signerKey)
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/error/BaseError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class BaseError extends makeError.BaseError {
super(message)

Object.defineProperty(this, 'cause', {
value: cause,
writable: false,
enumerable: false,
configurable: false,
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/error/IndySdkError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { IndyError } from '../utils/indyError'

import { AriesFrameworkError } from './AriesFrameworkError'

export class IndySdkError extends AriesFrameworkError {
public constructor(indyError: IndyError, message?: string) {
const base = `${indyError.name}(${indyError.indyName}): ${indyError.message}`

super(message ? `${message}: ${base}` : base, { cause: indyError })
}
}
1 change: 1 addition & 0 deletions packages/core/src/error/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './AriesFrameworkError'
export * from './RecordNotFoundError'
export * from './RecordDuplicateError'
export * from './IndySdkError'
Loading

0 comments on commit 9f1a4a7

Please sign in to comment.