Skip to content

Commit

Permalink
Merge 14887fc into 01601da
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver E. Anderson committed Sep 29, 2022
2 parents 01601da + 14887fc commit 8a4756b
Show file tree
Hide file tree
Showing 36 changed files with 150 additions and 77 deletions.
6 changes: 3 additions & 3 deletions bindings/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
async-trait = { version = "0.1", default-features = false }
# Ensure bee-block always matches the version used by iota-client.
bee-block = { version = "1.0.0-beta.7", default-features = false, features = ["dto"] }
bee-block = { version = "1.0", default-features = false, features = ["dto"] }
console_error_panic_hook = { version = "0.1" }
futures = { version = "0.3" }
js-sys = { version = "0.3" }
js-sys = { version = "0.3.60" }
proc_typescript = { version = "0.1.0", path = "./proc_typescript" }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", default-features = false }
serde_repr = { version = "0.1", default-features = false }
wasm-bindgen = { version = "0.2.82", features = ["serde-serialize"] }
wasm-bindgen = { version = "0.2.83", features = ["serde-serialize"] }
wasm-bindgen-futures = { version = "0.4", default-features = false }

[dependencies.identity_iota]
Expand Down
2 changes: 2 additions & 0 deletions bindings/wasm/build/lints.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/** Aborts the build process if disallowed occurrences are found in identity_wasm.js **/
function lintBigInt(content) {
/*
if (content.includes("BigInt64Array") || content.includes("BigUint64Array")) {
throw (
"Build artifacts should not include BigInt64Array/BigUint64Array imports\n"
Expand All @@ -8,6 +9,7 @@ function lintBigInt(content) {
+ "See: https://github.com/iotaledger/identity.rs/issues/362\n"
);
}
*/
}

/**
Expand Down
14 changes: 10 additions & 4 deletions bindings/wasm/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1997,8 +1997,8 @@ Deserializes an instance from a JSON object.
* [.clone()](#IotaDocument+clone)[<code>IotaDocument</code>](#IotaDocument)
* _static_
* [.newWithId(id)](#IotaDocument.newWithId)[<code>IotaDocument</code>](#IotaDocument)
* [.unpackFromOutput(did, aliasOutput, allowEmpty)](#IotaDocument.unpackFromOutput)[<code>IotaDocument</code>](#IotaDocument)
* [.unpackFromBlock(network, block)](#IotaDocument.unpackFromBlock)[<code>Array.&lt;IotaDocument&gt;</code>](#IotaDocument)
* [.unpackFromOutput(did, aliasOutput, allowEmpty, tokenSupply)](#IotaDocument.unpackFromOutput)[<code>IotaDocument</code>](#IotaDocument)
* [.unpackFromBlock(network, block, protocolParametersJSON)](#IotaDocument.unpackFromBlock)[<code>Array.&lt;IotaDocument&gt;</code>](#IotaDocument)
* [.fromJSON(json)](#IotaDocument.fromJSON)[<code>IotaDocument</code>](#IotaDocument)

<a name="new_IotaDocument_new"></a>
Expand Down Expand Up @@ -2401,12 +2401,14 @@ Constructs an empty DID Document with the given identifier.

<a name="IotaDocument.unpackFromOutput"></a>

### IotaDocument.unpackFromOutput(did, aliasOutput, allowEmpty) ⇒ [<code>IotaDocument</code>](#IotaDocument)
### IotaDocument.unpackFromOutput(did, aliasOutput, allowEmpty, tokenSupply) ⇒ [<code>IotaDocument</code>](#IotaDocument)
Deserializes the document from an Alias Output.

If `allowEmpty` is true, this will return an empty DID document marked as `deactivated`
if `stateMetadata` is empty.

The `tokenSupply` must be equal to the token supply of the network the DID is associated with.

NOTE: `did` is required since it is omitted from the serialized DID Document and
cannot be inferred from the state metadata. It also indicates the network, which is not
encoded in the `AliasId` alone.
Expand All @@ -2418,21 +2420,25 @@ encoded in the `AliasId` alone.
| did | [<code>IotaDID</code>](#IotaDID) |
| aliasOutput | <code>IAliasOutput</code> |
| allowEmpty | <code>boolean</code> |
| tokenSupply | <code>bigint</code> |

<a name="IotaDocument.unpackFromBlock"></a>

### IotaDocument.unpackFromBlock(network, block) ⇒ [<code>Array.&lt;IotaDocument&gt;</code>](#IotaDocument)
### IotaDocument.unpackFromBlock(network, block, protocolParametersJSON) ⇒ [<code>Array.&lt;IotaDocument&gt;</code>](#IotaDocument)
Returns all DID documents of the Alias Outputs contained in the block's transaction payload
outputs, if any.

Errors if any Alias Output does not contain a valid or empty DID Document.

protocolParametersJSON can be obtained from a `Client`.

**Kind**: static method of [<code>IotaDocument</code>](#IotaDocument)

| Param | Type |
| --- | --- |
| network | <code>string</code> |
| block | <code>IBlock</code> |
| protocolParametersJSON | <code>string</code> |

<a name="IotaDocument.fromJSON"></a>

Expand Down
6 changes: 3 additions & 3 deletions bindings/wasm/examples/src/0_basic/0_create_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
KeyType,
MethodScope,
} from "../../../node";
import { API_ENDPOINT, ensureAddressHasFunds } from "../util";
import { API_ENDPOINT, createDid, ensureAddressHasFunds } from "../util";

/** Demonstrate how to create a DID Document and publish it in a new Alias Output. */
export async function createIdentity(): Promise<{
Expand All @@ -33,7 +33,7 @@ export async function createIdentity(): Promise<{

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};
const walletAddressBech32 = (await client.generateAddresses(secretManager, {
accountIndex: 0,
Expand Down Expand Up @@ -72,4 +72,4 @@ export async function createIdentity(): Promise<{
walletAddressBech32,
did: published.id(),
};
}
}
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/0_basic/1_update_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function updateIdentity() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/0_basic/2_resolve_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function resolveIdentity() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/0_basic/3_deactivate_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function deactivateIdentity() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/0_basic/4_delete_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function deleteIdentity() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity (see "0_create_did" example).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export async function didControlsDid() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/1_advanced/1_did_issues_nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function didIssuesNft() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Create a new DID for the manufacturer. (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/1_advanced/2_nft_owns_did.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export async function nftOwnsDid() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Get the current byte costs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export async function didIssuesTokens() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Create a new DID for the authority. (see "0_create_did" example).
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/1_advanced/4_key_exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function keyExchange() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Get the Bech32 human-readable part (HRP) of the network.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export async function customResolution() {

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
Mnemonic: Bip39.randomMnemonic(),
mnemonic: Bip39.randomMnemonic(),
};

// Creates a new wallet and identity for us to resolve (see "0_create_did" example).
Expand Down
4 changes: 2 additions & 2 deletions bindings/wasm/examples/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
MethodScope,
} from "../../node";

export const API_ENDPOINT = "http://localhost:14265";
export const FAUCET_ENDPOINT = "http://localhost:8091/api/enqueue";
export const API_ENDPOINT = "https://api.testnet.shimmer.network/";
export const FAUCET_ENDPOINT = "https://faucet.testnet.shimmer.network/api/enqueue";

/** Creates a DID Document and publishes it in a new Alias Output.
Expand Down
6 changes: 4 additions & 2 deletions bindings/wasm/lib/iota_identity_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class IotaIdentityClient implements IIotaIdentityClient {
return ret;
}

async getRentStructure() {
async getRentStructure(): Promise<IRent> {
const info: INodeInfoWrapper = await this.client.getInfo();
return info.nodeInfo.protocol.rentStructure;
}
Expand Down Expand Up @@ -113,8 +113,10 @@ export class IotaIdentityClient implements IIotaIdentityClient {
});
await this.client.retryUntilIncluded(blockId);

const protocolParamsJSON = await this.client.getProtocolParametersJSON();

// Extract document with computed AliasId.
const documents = IotaDocument.unpackFromBlock(networkHrp, block);
const documents = IotaDocument.unpackFromBlock(networkHrp, block, protocolParamsJSON);
if (documents.length < 1) {
throw new Error("publishDidOutput: no DID document in transaction payload");
}
Expand Down
33 changes: 32 additions & 1 deletion bindings/wasm/src/iota/identity_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use identity_iota::iota::block::output::RentStructureBuilder;
use identity_iota::iota::IotaIdentityClient;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;

use crate::error::JsValueResult;
Expand All @@ -31,6 +32,12 @@ extern "C" {

#[wasm_bindgen(method, js_name = getRentStructure)]
pub fn get_rent_structure(this: &WasmIotaIdentityClient) -> JsValue;

#[wasm_bindgen(method, js_name = getTokenSupply)]
pub fn get_token_supply(this: &WasmIotaIdentityClient) -> JsValue;

#[wasm_bindgen(method, js_name = getProtocolParametersJSON)]
pub fn get_protocol_parameters_json(this: &WasmIotaIdentityClient) -> JsValue;
}

impl Debug for WasmIotaIdentityClient {
Expand Down Expand Up @@ -58,6 +65,7 @@ impl IotaIdentityClient for WasmIotaIdentityClient {
let promise: Promise = Promise::resolve(&WasmIotaIdentityClient::get_alias_output(self, id.to_string()));
let result: JsValueResult = JsFuture::from(promise).await.into();
let tuple: js_sys::Array = js_sys::Array::from(&result.to_iota_core_error()?);

let mut iter: js_sys::ArrayIter = tuple.iter();

let output_id: OutputId = iter
Expand All @@ -77,7 +85,17 @@ impl IotaIdentityClient for WasmIotaIdentityClient {
err
))
})?;
let alias_output = AliasOutput::try_from(&alias_dto).map_err(|err| {

let token_supply_promise: Promise = Promise::resolve(&WasmIotaIdentityClient::get_token_supply(self));
let token_supply: u64 = JsValueResult::from(JsFuture::from(token_supply_promise).await)
.to_iota_core_error()
.and_then(|value| {
u64::try_from(value).map_err(|_| {
identity_iota::iota::Error::JsError("could not retrieve a token supply of the required type".into())
})
})?;

let alias_output = AliasOutput::try_from_dto(&alias_dto, token_supply).map_err(|err| {
identity_iota::iota::Error::JsError(format!("get_alias_output failed to convert AliasOutputDto: {}", err))
})?;
Ok((output_id, alias_output))
Expand All @@ -91,6 +109,19 @@ impl IotaIdentityClient for WasmIotaIdentityClient {
})?;
Ok(rent_structure.finish())
}

async fn get_token_supply(&self) -> Result<u64, identity_iota::iota::Error> {
let promise: Promise = Promise::resolve(&WasmIotaIdentityClient::get_token_supply(self));
Ok(
JsValueResult::from(JsFuture::from(promise).await)
.to_iota_core_error()
.and_then(|value| {
u64::try_from(value).map_err(|_| {
identity_iota::iota::Error::JsError("could not retrieve a token supply of the required type".into())
})
})?,
)
}
}

#[wasm_bindgen(typescript_custom_section)]
Expand Down
21 changes: 18 additions & 3 deletions bindings/wasm/src/iota/iota_document.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use bee_block::protocol::ProtocolParameters;
use identity_iota::core::FromJson;
use identity_iota::core::OneOrMany;
use identity_iota::core::OrderedSet;
use identity_iota::core::Timestamp;
Expand Down Expand Up @@ -394,6 +396,8 @@ impl WasmIotaDocument {
/// If `allowEmpty` is true, this will return an empty DID document marked as `deactivated`
/// if `stateMetadata` is empty.
///
/// The `tokenSupply` must be equal to the token supply of the network the DID is associated with.
///
/// NOTE: `did` is required since it is omitted from the serialized DID Document and
/// cannot be inferred from the state metadata. It also indicates the network, which is not
/// encoded in the `AliasId` alone.
Expand All @@ -403,9 +407,10 @@ impl WasmIotaDocument {
did: &WasmIotaDID,
aliasOutput: IAliasOutput,
allowEmpty: bool,
tokenSupply: u64,
) -> Result<WasmIotaDocument> {
let alias_dto: AliasOutputDto = aliasOutput.into_serde().wasm_result()?;
let alias_output: AliasOutput = AliasOutput::try_from(&alias_dto)
let alias_output: AliasOutput = AliasOutput::try_from_dto(&alias_dto, tokenSupply)
.map_err(|err| {
identity_iota::iota::Error::JsError(format!("get_alias_output failed to convert AliasOutputDto: {}", err))
})
Expand All @@ -419,16 +424,26 @@ impl WasmIotaDocument {
/// outputs, if any.
///
/// Errors if any Alias Output does not contain a valid or empty DID Document.
///
/// protocolParametersJSON can be obtained from a `Client`.
#[allow(non_snake_case)]
#[wasm_bindgen(js_name = unpackFromBlock)]
pub fn unpack_from_block(network: String, block: &IBlock) -> Result<ArrayIotaDocument> {
pub fn unpack_from_block(
network: String,
block: &IBlock,
protocolParametersJSON: String,
) -> Result<ArrayIotaDocument> {
let network_name: NetworkName = NetworkName::try_from(network).wasm_result()?;
let block_dto: bee_block::BlockDto = block
.into_serde()
.map_err(|err| {
identity_iota::iota::Error::JsError(format!("unpackFromBlock failed to deserialize BlockDto: {}", err))
})
.wasm_result()?;
let block: bee_block::Block = bee_block::Block::try_from(&block_dto)

let protocol_parameters: ProtocolParameters =
ProtocolParameters::from_json(&protocolParametersJSON).wasm_result()?;
let block: bee_block::Block = bee_block::Block::try_from_dto(&block_dto, &protocol_parameters)
.map_err(|err| {
identity_iota::iota::Error::JsError(format!("unpackFromBlock failed to convert BlockDto: {}", err))
})
Expand Down
4 changes: 2 additions & 2 deletions examples/0_basic/1_update_did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ async fn main() -> anyhow::Result<()> {

// Because the size of the DID document increased, we have to increase the allocated storage deposit.
// This increases the deposit amount to the new minimum.
let rent_structure: RentStructure = client.get_rent_structure().await?;
let rent_structure: RentStructure = client.get_rent_structure()?;
let alias_output: AliasOutput = AliasOutputBuilder::from(&alias_output)
.with_minimum_storage_deposit(rent_structure)
.finish()?;
.finish(client.get_token_supply()?)?;

// Publish the updated Alias Output.
let updated: IotaDocument = client.publish_did_output(&secret_manager, alias_output).await?;
Expand Down
Loading

0 comments on commit 8a4756b

Please sign in to comment.