diff --git a/.release-it.json b/.release-it.json index 01122e8..645afae 100644 --- a/.release-it.json +++ b/.release-it.json @@ -1,6 +1,7 @@ { "git": { - "commitMessage": "chore: release v${version}" + "commitMessage": "chore: release v${version} [skip ci]", + "commitArgs": ["--signoff"] }, "github": { "release": true diff --git a/packages/ssi/package.json b/packages/ssi/package.json index 200f584..71cc493 100644 --- a/packages/ssi/package.json +++ b/packages/ssi/package.json @@ -1,6 +1,6 @@ { "name": "@adeya/ssi", - "version": "0.0.0", + "version": "0.0.1-alpha.1", "license": "Apache-2.0", "main": "build/index", "source": "src/index", diff --git a/packages/ssi/src/agent.ts b/packages/ssi/src/agent.ts index ddba4e7..c3ec8af 100644 --- a/packages/ssi/src/agent.ts +++ b/packages/ssi/src/agent.ts @@ -43,7 +43,10 @@ import { anoncreds } from '@hyperledger/anoncreds-react-native' import { ariesAskar } from '@hyperledger/aries-askar-react-native' import { indyVdr } from '@hyperledger/indy-vdr-react-native' -const getAgentModules = (mediatorInvitationUrl: string, indyNetworks: [IndyVdrPoolConfig, ...IndyVdrPoolConfig[]]) => { +export const getAgentModules = ( + mediatorInvitationUrl: string, + indyNetworks: [IndyVdrPoolConfig, ...IndyVdrPoolConfig[]] +) => { return { askar: new AskarModule({ ariesAskar diff --git a/packages/ssi/src/index.ts b/packages/ssi/src/index.ts index de5548a..4588eee 100644 --- a/packages/ssi/src/index.ts +++ b/packages/ssi/src/index.ts @@ -26,10 +26,11 @@ import { LogLevel, ConsoleLogger } from '@aries-framework/core' // Indy VDR import { IndyVdrPoolConfig } from '@aries-framework/indy-vdr' -export { initializeAgent, AdeyaAgent } from './agent' -export { LogLevel, ConsoleLogger, InitConfig, IndyVdrPoolConfig } export * from './providers' export * from './hooks' +export * from './wallet' +export { initializeAgent, AdeyaAgent } from './agent' +export { LogLevel, ConsoleLogger, InitConfig, IndyVdrPoolConfig } export { V1RequestPresentationMessage, AnonCredsCredentialOffer, diff --git a/packages/ssi/src/wallet/index.ts b/packages/ssi/src/wallet/index.ts new file mode 100644 index 0000000..20f5e6d --- /dev/null +++ b/packages/ssi/src/wallet/index.ts @@ -0,0 +1,3 @@ +import { importWalletWithAgent, isWalletImportable, isWalletPinCorrect } from './wallet' + +export { importWalletWithAgent, isWalletImportable, isWalletPinCorrect } diff --git a/packages/ssi/src/wallet/wallet.ts b/packages/ssi/src/wallet/wallet.ts new file mode 100644 index 0000000..1f2b595 --- /dev/null +++ b/packages/ssi/src/wallet/wallet.ts @@ -0,0 +1,109 @@ +// NOTE: We need to import these to be able to use the AskarWallet in this file. +import '@hyperledger/aries-askar-react-native' + +import type { InitConfig } from '@aries-framework/core' +import type { IndyVdrPoolConfig } from '@aries-framework/indy-vdr' + +import { AskarWallet } from '@aries-framework/askar' +import { + Agent, + ConsoleLogger, + HttpOutboundTransport, + LogLevel, + SigningProviderRegistry, + WsOutboundTransport, + type WalletConfig, + type WalletExportImportConfig +} from '@aries-framework/core' +import { agentDependencies } from '@aries-framework/react-native' + +import { getAgentModules } from '../agent' + +interface WalletImportConfigWithAgent { + agentConfig: InitConfig + importConfig: WalletExportImportConfig + mediatorInvitationUrl: string + indyNetworks: [IndyVdrPoolConfig, ...IndyVdrPoolConfig[]] +} + +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. + // We create an AskarWallet instance and open the wallet with the given secret. + const askarWallet = new AskarWallet( + new ConsoleLogger(LogLevel.off), + new agentDependencies.FileSystem(), + new SigningProviderRegistry([]) + ) + await askarWallet.open(walletConfig) + + await askarWallet.close() + return true + } catch (e) { + // eslint-disable-next-line no-console + console.log('Error opening wallet', e) + return false + } +} + +export const isWalletImportable = async ( + walletConfig: WalletConfig, + importConfig: WalletExportImportConfig +): Promise => { + const fileSystem = new agentDependencies.FileSystem() + try { + const tempImportPath = fileSystem.tempPath + '/importTemp' + // Add temp path to wallet config + walletConfig.storage = { + type: 'sqlite', + path: tempImportPath + } + // NOTE: a custom wallet is used to check if the wallet passphrase is correct and can be imported successfully. + const askarWallet = new AskarWallet(new ConsoleLogger(LogLevel.off), fileSystem, new SigningProviderRegistry([])) + await askarWallet.import(walletConfig, importConfig) + + await fileSystem.delete(importConfig.path) + return true + } catch (e) { + // eslint-disable-next-line no-console + console.log('Error importing wallet', e) + await fileSystem.delete(importConfig.path) + return false + } +} + +export const importWalletWithAgent = async ({ + importConfig, + agentConfig, + mediatorInvitationUrl, + indyNetworks +}: WalletImportConfigWithAgent) => { + if (!agentConfig.walletConfig?.id || !agentConfig.walletConfig.key) { + // Cannot find wallet id/key in agent config, so we cannot import the wallet + return + } + + if (!importConfig.key || !importConfig.path) { + throw new Error('Please enter a valid passphrase') + } + + const agent = new Agent({ + dependencies: agentDependencies, + config: { + autoUpdateStorageOnStartup: true, + ...agentConfig + }, + modules: getAgentModules(mediatorInvitationUrl, indyNetworks) + }) + + agent.registerOutboundTransport(new HttpOutboundTransport()) + agent.registerOutboundTransport(new WsOutboundTransport()) + + await agent.wallet.import(agentConfig.walletConfig, importConfig) + + await agent.wallet.initialize(agentConfig.walletConfig) + + await agent.initialize() + + return agent +}