Skip to content

Commit

Permalink
Added capability of migrating wallet through the node.js wrapper (#895)
Browse files Browse the repository at this point in the history
* Added capability of migrating wallet through the node.js wrapper

Signed-off-by: Bogdan Mircea <[email protected]>
Signed-off-by: Patrik Stas <[email protected]>
  • Loading branch information
bobozaur authored and Patrik-Stas committed Jul 29, 2023
1 parent a1b1e9a commit 35be8c3
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libvcx_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ uuid = { version = "0.7.4", default-features = false, features = ["v4"] }
agency_client = { path = "../agency_client" }
async-trait = "0.1.61"
url = "2.3.1"
wallet_migrator = { path = "../wallet_migrator" }

[dev-dependencies]
tokio = { version = "1.20", features = [ "rt", "macros" ] }
45 changes: 44 additions & 1 deletion libvcx_core/src/api_vcx/api_global/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use aries_vcx::aries_vcx_core::wallet::base_wallet::BaseWallet;
use aries_vcx::aries_vcx_core::wallet::indy::internal::{
close_search_wallet, fetch_next_records_wallet, open_search_wallet,
};
use aries_vcx::aries_vcx_core::wallet::indy::wallet::import;
use aries_vcx::aries_vcx_core::wallet::indy::wallet::{close_wallet, create_and_open_wallet, delete_wallet, import};
use aries_vcx::aries_vcx_core::wallet::indy::{IndySdkWallet, IssuerConfig, RestoreWalletConfigs, WalletConfig};
use aries_vcx::aries_vcx_core::{indy, wallet, SearchHandle};
use aries_vcx::aries_vcx_core::{WalletHandle, INVALID_WALLET_HANDLE};
Expand Down Expand Up @@ -224,6 +224,26 @@ pub async fn wallet_import(config: &RestoreWalletConfigs) -> LibvcxResult<()> {
map_ariesvcx_core_result(import(config).await)
}

pub async fn wallet_migrate(wallet_config: &WalletConfig) -> LibvcxResult<()> {
let src_wallet_handle = get_main_wallet_handle()?;
let dest_wallet_handle = create_and_open_wallet(wallet_config).await?;

let migration_res = wallet_migrator::migrate_wallet(
src_wallet_handle,
dest_wallet_handle,
wallet_migrator::vdrtools2credx::migrate_any_record,
)
.await;

if let Err(e) = migration_res {
close_wallet(dest_wallet_handle).await.ok();
delete_wallet(wallet_config).await.ok();
Err(LibvcxError::from_msg(LibvcxErrorKind::WalletMigrationFailed, e))
} else {
Ok(())
}
}

#[allow(clippy::unwrap_used)]
pub mod test_utils {
use aries_vcx::aries_vcx_core::wallet::indy::WalletConfig;
Expand Down Expand Up @@ -305,6 +325,29 @@ pub mod tests {
};
use crate::errors::error::{LibvcxErrorKind, LibvcxResult};

#[tokio::test]
async fn test_wallet_migrate() {
let wallet_name = format!("test_create_wallet_{}", uuid::Uuid::new_v4());
let config: WalletConfig = serde_json::from_value(json!({
"wallet_name": wallet_name,
"wallet_key": DEFAULT_WALLET_KEY,
"wallet_key_derivation": WALLET_KDF_RAW
}))
.unwrap();

create_and_open_as_main_wallet(&config).await.unwrap();

let wallet_name = format!("test_migrate_wallet_{}", uuid::Uuid::new_v4());
let new_config: WalletConfig = serde_json::from_value(json!({
"wallet_name": wallet_name,
"wallet_key": DEFAULT_WALLET_KEY,
"wallet_key_derivation": WALLET_KDF_RAW
}))
.unwrap();

super::wallet_migrate(&new_config).await.unwrap();
}

#[tokio::test]
async fn test_wallet_create() {
let _setup = SetupEmpty::init();
Expand Down
2 changes: 2 additions & 0 deletions libvcx_core/src/errors/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ pub enum LibvcxErrorKind {
DuplicationWallet,
#[error("Wallet record not found")]
WalletRecordNotFound,
#[error("Wallet migration failed")]
WalletMigrationFailed,
#[error("Record already exists in the wallet")]
DuplicationWalletRecord,
#[error("Wallet not found")]
Expand Down
6 changes: 6 additions & 0 deletions libvdrtools/indy-api-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ pub type IndyHandle = i32;
pub struct WalletHandle(pub i32);
pub const INVALID_WALLET_HANDLE: WalletHandle = WalletHandle(0);

impl From<i32> for WalletHandle {
fn from(value: i32) -> Self {
Self(value)
}
}

pub type CallbackHandle = i32;

pub type CommandHandle = i32;
Expand Down
8 changes: 8 additions & 0 deletions wrappers/node/src/api/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ export async function createWallet(config: object): Promise<void> {
}
}

export async function migrateWallet(config: object): Promise<void> {
try {
return await ffi.walletMigrate(JSON.stringify(config));
} catch (err: any) {
throw new VCXInternalError(err);
}
}

export async function configureIssuerWallet(seed: string): Promise<string> {
try {
return await ffi.configureIssuerWallet(seed);
Expand Down
1 change: 1 addition & 0 deletions wrappers/vcx-napi-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ anoncreds_vdrtools = ["libvcx_core/anoncreds_vdrtools"]

[dependencies]
libvcx_core = { path = "../../libvcx_core" }
wallet_migrator = { path = "../../wallet_migrator" }
log = "0.4.16"
napi = { version = "2.10.14", default-features = false, features = [ "async" ] }
napi-derive = { version = "2.10.1" }
Expand Down
1 change: 1 addition & 0 deletions wrappers/vcx-napi-rs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export function unpack(data: Buffer): Promise<string>
export function createPairwiseInfo(): Promise<string>
export function walletImport(config: string): Promise<void>
export function walletExport(path: string, backupKey: string): Promise<void>
export function walletMigrate(walletConfig: string): Promise<void>
export function getVerkeyFromWallet(did: string): Promise<string>
export function rotateVerkey(did: string): Promise<void>
export function rotateVerkeyStart(did: string): Promise<string>
Expand Down
9 changes: 8 additions & 1 deletion wrappers/vcx-napi-rs/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/* tslint:disable */
/* eslint-disable */
/* prettier-ignore */

/* auto-generated by NAPI-RS */

const { existsSync, readFileSync } = require('fs')
const { join } = require('path')

Expand Down Expand Up @@ -246,7 +252,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetRemoteVk, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionProcessProblemReport, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionSendAriesMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialUpdateStateWithMessageNonmediated, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialGetRevocationId, issuerCredentialSendCredential, issuerCredentialSendCredentialNonmediated, issuerCredentialSendOfferV2, issuerCredentialSendOfferNonmediated, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, createServiceV2, getServiceFromLedger, getAttrFromLedger, clearAttrFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandBuildHandshakeReuseAcceptedMsg, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverNonmediatedConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetPresentationMsg, proofGetPresentationRequestAttachment, proofGetPresentationAttachment, proofRelease, proofSendRequest, proofSendRequestNonmediated, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofUpdateStateWithMessageNonmediated, proofGetState, proofGetVerificationStatus, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, trustpingBuildResponseMsg, trustpingBuildPing, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding
const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetRemoteVk, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionProcessProblemReport, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionSendAriesMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialUpdateStateWithMessageNonmediated, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialGetRevocationId, issuerCredentialSendCredential, issuerCredentialSendCredentialNonmediated, issuerCredentialSendOfferV2, issuerCredentialSendOfferNonmediated, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, createServiceV2, getServiceFromLedger, getAttrFromLedger, clearAttrFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandBuildHandshakeReuseAcceptedMsg, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverNonmediatedConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetPresentationMsg, proofGetPresentationRequestAttachment, proofGetPresentationAttachment, proofRelease, proofSendRequest, proofSendRequestNonmediated, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofUpdateStateWithMessageNonmediated, proofGetState, proofGetVerificationStatus, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, trustpingBuildResponseMsg, trustpingBuildPing, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, walletMigrate, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding

module.exports.updateWebhookUrl = updateWebhookUrl
module.exports.createAgencyClientForMainWallet = createAgencyClientForMainWallet
Expand Down Expand Up @@ -440,6 +446,7 @@ module.exports.unpack = unpack
module.exports.createPairwiseInfo = createPairwiseInfo
module.exports.walletImport = walletImport
module.exports.walletExport = walletExport
module.exports.walletMigrate = walletMigrate
module.exports.getVerkeyFromWallet = getVerkeyFromWallet
module.exports.rotateVerkey = rotateVerkey
module.exports.rotateVerkeyStart = rotateVerkeyStart
Expand Down
16 changes: 16 additions & 0 deletions wrappers/vcx-napi-rs/src/api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ pub async fn wallet_export(path: String, backup_key: String) -> napi::Result<()>
.map_err(to_napi_err)
}

#[napi]
pub async fn wallet_migrate(wallet_config: String) -> napi::Result<()> {
let wallet_config = serde_json::from_str(&wallet_config)
.map_err(|err| {
LibvcxError::from_msg(
LibvcxErrorKind::InvalidConfiguration,
format!("Serialization error: {:?}", err),
)
})
.map_err(to_napi_err)?;

wallet::wallet_migrate(&wallet_config)
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}

#[napi]
pub async fn get_verkey_from_wallet(did: String) -> napi::Result<String> {
wallet::key_for_local_did(&did).await.map_err(to_napi_err)
Expand Down

0 comments on commit 35be8c3

Please sign in to comment.