Skip to content

Commit

Permalink
Generify Account::client over Rc, Arc (#707)
Browse files Browse the repository at this point in the history
* Change Account to be generic over Rc/Arc<Client>

* Remove Client::clone, update Wasm bindings

* Move SharedPtr to identity-iota, refactor Resolver

* Fix formatting

* Remove unnecessary drop
  • Loading branch information
cycraig authored Mar 14, 2022
1 parent 105536d commit 874d77d
Show file tree
Hide file tree
Showing 19 changed files with 233 additions and 145 deletions.
12 changes: 6 additions & 6 deletions bindings/wasm/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ See <code>IVerifierOptions</code>.</p>
## Members

<dl>
<dt><a href="#KeyType">KeyType</a></dt>
<dd></dd>
<dt><a href="#DIDMessageEncoding">DIDMessageEncoding</a></dt>
<dd></dd>
<dt><a href="#KeyType">KeyType</a></dt>
<dd></dd>
<dt><a href="#MethodRelationship">MethodRelationship</a></dt>
<dd></dd>
<dt><a href="#Digest">Digest</a></dt>
Expand Down Expand Up @@ -3519,14 +3519,14 @@ Throws an error if any of the options are invalid.
Creates a new `VerifierOptions` with default options.

**Kind**: static method of [<code>VerifierOptions</code>](#VerifierOptions)
<a name="KeyType"></a>

## KeyType
**Kind**: global variable
<a name="DIDMessageEncoding"></a>

## DIDMessageEncoding
**Kind**: global variable
<a name="KeyType"></a>

## KeyType
**Kind**: global variable
<a name="MethodRelationship"></a>

## MethodRelationship
Expand Down
21 changes: 9 additions & 12 deletions bindings/wasm/src/account/wasm_account/account.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::cell::Ref;
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
Expand All @@ -14,6 +13,7 @@ use identity::account::Storage;
use identity::crypto::SetSignature;
use identity::crypto::SignatureOptions;
use identity::did::verifiable::VerifiableProperties;
use identity::iota::Client;
use identity::iota::IotaDID;
use identity::iota::IotaDocument;
use js_sys::Promise;
Expand All @@ -33,20 +33,21 @@ use crate::did::WasmResolvedDocument;
use crate::error::Result;
use crate::error::WasmResult;

pub(crate) type AccountRc = Account<Rc<Client>>;

/// An account manages one identity.
///
/// It handles private keys, writing to storage and
/// publishing to the Tangle.
#[wasm_bindgen(js_name = Account)]
pub struct WasmAccount(pub(crate) Rc<RefCell<Account>>);
pub struct WasmAccount(pub(crate) Rc<RefCell<AccountRc>>);

#[wasm_bindgen(js_class = Account)]
impl WasmAccount {
/// Returns the {@link DID} of the managed identity.
#[wasm_bindgen(js_name = did)]
pub fn did(&self) -> WasmDID {
let account: Ref<Account> = self.0.borrow();
WasmDID::from(account.did().clone())
WasmDID::from(self.0.borrow().did().clone())
}

/// Returns whether auto-publish is enabled.
Expand All @@ -71,7 +72,7 @@ impl WasmAccount {
/// Resolves the DID Document associated with this `Account` from the Tangle.
#[wasm_bindgen(js_name = resolveIdentity)]
pub fn resolve_identity(&self) -> PromiseResolvedDocument {
let account = self.0.clone();
let account: Rc<RefCell<AccountRc>> = self.0.clone();

let promise: Promise = future_to_promise(async move {
account
Expand All @@ -95,13 +96,9 @@ impl WasmAccount {
let did: IotaDID = self.0.borrow().did().to_owned();
let storage: Arc<dyn Storage> = Arc::clone(self.0.borrow().storage());

// Drop account should release the DIDLease because we cannot take ownership of the Rc.
// Note that this will still fail if anyone else has a reference to the Account.
std::mem::drop(self.0);

future_to_promise(async move {
// Create a new account since `delete_identity` consumes it.
let account: Result<Account> = AccountBuilder::new()
let account: Result<AccountRc> = AccountBuilder::new()
.storage(AccountStorage::Custom(storage))
.load_identity(did)
.await
Expand Down Expand Up @@ -246,8 +243,8 @@ impl WasmAccount {
}
}

impl From<Account> for WasmAccount {
fn from(account: Account) -> WasmAccount {
impl From<AccountRc> for WasmAccount {
fn from(account: AccountRc) -> WasmAccount {
WasmAccount(Rc::new(RefCell::new(account)))
}
}
Expand Down
18 changes: 11 additions & 7 deletions bindings/wasm/src/account/wasm_account/account_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use std::sync::Arc;
use identity::account::AccountBuilder;
use identity::account::AccountStorage;
use identity::account::IdentitySetup;
use identity::iota::Client;
use identity::iota::IotaDID;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
Expand All @@ -24,6 +26,8 @@ use crate::error::WasmResult;
use crate::tangle::Config;
use crate::tangle::WasmClient;

type AccountBuilderRc = AccountBuilder<Rc<Client>>;

/// An [`Account`] builder for easy account configuration.
///
/// To reduce memory usage, accounts created from the same builder share the same `Storage`
Expand All @@ -33,14 +37,14 @@ use crate::tangle::WasmClient;
/// This means a builder can be reconfigured in-between account creations, without affecting
/// the configuration of previously built accounts.
#[wasm_bindgen(js_name = AccountBuilder)]
pub struct WasmAccountBuilder(Rc<RefCell<AccountBuilder>>);
pub struct WasmAccountBuilder(Rc<RefCell<AccountBuilderRc>>);

#[wasm_bindgen(js_class = AccountBuilder)]
impl WasmAccountBuilder {
/// Creates a new `AccountBuilder`.
#[wasm_bindgen(constructor)]
pub fn new(options: Option<AccountBuilderOptions>) -> Result<WasmAccountBuilder> {
let mut builder = AccountBuilder::new();
let mut builder: AccountBuilderRc = AccountBuilderRc::new();

if let Some(builder_options) = options {
if let Some(autopublish) = builder_options.autopublish() {
Expand All @@ -53,7 +57,7 @@ impl WasmAccountBuilder {

if let Some(mut config) = builder_options.clientConfig() {
let client: WasmClient = WasmClient::from_config(&mut config)?;
builder = builder.client(Arc::new(client.client.as_ref().clone()));
builder = builder.client(client.client);
};

if let Some(storage) = builder_options.storage() {
Expand All @@ -68,13 +72,13 @@ impl WasmAccountBuilder {
/// The identity must exist in the configured `Storage`.
#[wasm_bindgen(js_name = loadIdentity)]
pub fn load_identity(&mut self, did: &WasmDID) -> Result<PromiseAccount> {
let builder = self.0.clone();
let did = did.clone();
let builder: Rc<RefCell<AccountBuilderRc>> = self.0.clone();
let did: IotaDID = did.0.clone();
let promise: Promise = future_to_promise(async move {
builder
.as_ref()
.borrow_mut()
.load_identity(did.0)
.load_identity(did)
.await
.map(WasmAccount::from)
.map(Into::into)
Expand All @@ -94,7 +98,7 @@ impl WasmAccountBuilder {
pub fn create_identity(&mut self, identity_setup: Option<WasmIdentitySetup>) -> Result<PromiseAccount> {
let setup: IdentitySetup = identity_setup.map(IdentitySetup::from).unwrap_or_default();

let builder: Rc<RefCell<AccountBuilder>> = self.0.clone();
let builder: Rc<RefCell<AccountBuilderRc>> = self.0.clone();
let promise: Promise = future_to_promise(async move {
builder
.as_ref()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ use std::cell::RefCell;
use std::cell::RefMut;
use std::rc::Rc;

use identity::account::Account;
use identity::account::AttachMethodRelationshipBuilder;
use identity::account::IdentityUpdater;
use identity::account::UpdateError::MissingRequiredField;
use identity::core::OneOrMany;
use identity::did::MethodRelationship;
use identity::iota::Client;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;

use crate::account::wasm_account::account::AccountRc;
use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::did::WasmMethodRelationship;
Expand Down Expand Up @@ -44,14 +45,14 @@ impl WasmAccount {
.ok_or(MissingRequiredField("fragment"))
.wasm_result()?;

let account: Rc<RefCell<Account>> = Rc::clone(&self.0);
let account: Rc<RefCell<AccountRc>> = Rc::clone(&self.0);
let promise: Promise = future_to_promise(async move {
if relationships.is_empty() {
return Ok(JsValue::undefined());
}
let mut account: RefMut<Account> = account.borrow_mut();
let mut updater: IdentityUpdater<'_> = account.update_identity();
let mut attach_relationship: AttachMethodRelationshipBuilder<'_> =
let mut account: RefMut<AccountRc> = account.borrow_mut();
let mut updater: IdentityUpdater<'_, Rc<Client>> = account.update_identity();
let mut attach_relationship: AttachMethodRelationshipBuilder<'_, Rc<Client>> =
updater.attach_method_relationship().fragment(fragment);

for relationship in relationships {
Expand Down
11 changes: 6 additions & 5 deletions bindings/wasm/src/account/wasm_account/update/create_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ use std::cell::RefCell;
use std::cell::RefMut;
use std::rc::Rc;

use identity::account::Account;
use identity::account::CreateMethodBuilder;
use identity::account::IdentityUpdater;
use identity::account::MethodSecret;
use identity::account::UpdateError::MissingRequiredField;
use identity::did::MethodScope;
use identity::did::MethodType;
use identity::iota::Client;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;

use crate::account::types::WasmMethodSecret;
use crate::account::wasm_account::account::AccountRc;
use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::did::WasmMethodScope;
Expand All @@ -41,11 +42,11 @@ impl WasmAccount {

let method_secret: Option<MethodSecret> = options.methodSecret().map(|ms| ms.0);

let account: Rc<RefCell<Account>> = Rc::clone(&self.0);
let account: Rc<RefCell<AccountRc>> = Rc::clone(&self.0);
let promise: Promise = future_to_promise(async move {
let mut account: RefMut<Account> = account.borrow_mut();
let mut updater: IdentityUpdater<'_> = account.update_identity();
let mut create_method: CreateMethodBuilder<'_> = updater.create_method().fragment(fragment);
let mut account: RefMut<AccountRc> = account.borrow_mut();
let mut updater: IdentityUpdater<'_, Rc<Client>> = account.update_identity();
let mut create_method: CreateMethodBuilder<'_, Rc<Client>> = updater.create_method().fragment(fragment);

if let Some(type_) = method_type {
create_method = create_method.type_(type_);
Expand Down
13 changes: 7 additions & 6 deletions bindings/wasm/src/account/wasm_account/update/create_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ use std::cell::RefCell;
use std::cell::RefMut;
use std::rc::Rc;

use identity::account::Account;
use identity::account::CreateServiceBuilder;
use identity::account::IdentityUpdater;
use identity::account::UpdateError::MissingRequiredField;
use identity::core::Object;
use identity::core::Url;
use identity::iota::Client;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;

use crate::account::wasm_account::account::AccountRc;
use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::error::Result;
Expand All @@ -39,11 +40,11 @@ impl WasmAccount {
let endpoint: Url = Url::parse(endpoint.as_str()).wasm_result()?;
let properties: Option<Object> = options.properties().into_serde().wasm_result()?;

let account: Rc<RefCell<Account>> = Rc::clone(&self.0);
let account: Rc<RefCell<AccountRc>> = Rc::clone(&self.0);
let promise: Promise = future_to_promise(async move {
let mut account: RefMut<Account> = account.borrow_mut();
let mut updater: IdentityUpdater<'_> = account.update_identity();
let mut create_service: CreateServiceBuilder<'_> = updater
let mut account: RefMut<AccountRc> = account.borrow_mut();
let mut updater: IdentityUpdater<'_, Rc<Client>> = account.update_identity();
let mut create_service: CreateServiceBuilder<'_, Rc<Client>> = updater
.create_service()
.fragment(fragment)
.type_(service_type)
Expand All @@ -68,7 +69,7 @@ extern "C" {
#[wasm_bindgen(getter, method)]
pub fn fragment(this: &CreateServiceOptions) -> Option<String>;

#[wasm_bindgen(getter, method, js_name= type)]
#[wasm_bindgen(getter, method, js_name = type)]
pub fn type_(this: &CreateServiceOptions) -> Option<String>;

#[wasm_bindgen(getter, method)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ use std::cell::RefCell;
use std::cell::RefMut;
use std::rc::Rc;

use identity::account::Account;
use identity::account::DetachMethodRelationshipBuilder;
use identity::account::IdentityUpdater;
use identity::account::UpdateError::MissingRequiredField;
use identity::core::OneOrMany;
use identity::did::MethodRelationship;
use identity::iota::Client;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;

use crate::account::wasm_account::account::AccountRc;
use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::did::WasmMethodRelationship;
Expand All @@ -41,15 +42,15 @@ impl WasmAccount {
.ok_or(MissingRequiredField("fragment"))
.wasm_result()?;

let account: Rc<RefCell<Account>> = Rc::clone(&self.0);
let account: Rc<RefCell<AccountRc>> = Rc::clone(&self.0);

let promise: Promise = future_to_promise(async move {
if relationships.is_empty() {
return Ok(JsValue::undefined());
}
let mut account: RefMut<Account> = account.borrow_mut();
let mut updater: IdentityUpdater<'_> = account.update_identity();
let mut detach_relationship: DetachMethodRelationshipBuilder<'_> =
let mut account: RefMut<AccountRc> = account.borrow_mut();
let mut updater: IdentityUpdater<'_, Rc<Client>> = account.update_identity();
let mut detach_relationship: DetachMethodRelationshipBuilder<'_, Rc<Client>> =
updater.detach_method_relationship().fragment(fragment);

for relationship in relationships {
Expand Down
19 changes: 10 additions & 9 deletions bindings/wasm/src/account/wasm_account/update/set_also_known_as.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::error::Result;
use crate::error::WasmResult;
use identity::account::Account;
use std::cell::RefCell;
use std::rc::Rc;

use identity::core::OneOrMany;
use identity::core::OrderedSet;
use identity::core::Url;

use js_sys::Promise;
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;

use crate::account::wasm_account::account::AccountRc;
use crate::account::wasm_account::WasmAccount;
use crate::common::PromiseVoid;
use crate::error::Result;
use crate::error::WasmResult;

#[wasm_bindgen(js_class = Account)]
impl WasmAccount {
/// Sets the `alsoKnownAs` property in the DID document.
Expand All @@ -31,7 +32,7 @@ impl WasmAccount {
}
}

let account: Rc<RefCell<Account>> = Rc::clone(&self.0);
let account: Rc<RefCell<AccountRc>> = Rc::clone(&self.0);
let promise: Promise = future_to_promise(async move {
account
.borrow_mut()
Expand Down
Loading

0 comments on commit 874d77d

Please sign in to comment.