Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IotaDocument::from_keypair_with_network() and WASM binding. #276

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions bindings/wasm/README.md
Expand Up @@ -108,6 +108,8 @@ import * as identity from "@iota/identity-wasm/web";
identity.init().then(() => {
const key = new identity.KeyPair(identity.KeyType.Ed25519)
const doc = identity.Document.fromKeyPair(key)
// Or, if using the testnet:
// const doc = identity.Document.fromKeyPair(key, "test")
console.log("Key Pair", key)
console.log("DID Document: ", doc)
});
Expand All @@ -118,6 +120,8 @@ identity.init().then(() => {
await identity.init()
const key = new identity.KeyPair(identity.KeyType.Ed25519)
const doc = identity.Document.fromKeyPair(key)
// Or, if using the testnet:
// const doc = identity.Document.fromKeyPair(key, "test")
console.log("Key Pair", key)
console.log("DID Document: ", doc)
})()
Expand Down
5 changes: 4 additions & 1 deletion bindings/wasm/docs/api-reference.md
Expand Up @@ -725,13 +725,16 @@ Serializes a `Document` object as a JSON object.
<a name="Document.fromKeyPair"></a>

### Document.fromKeyPair(key) ⇒ [<code>Document</code>](#Document)
Creates a new DID Document from the given KeyPair.
Creates a new DID Document from the given KeyPair and optional network.

If unspecified, the network defaults to the mainnet.

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

| Param | Type |
| --- | --- |
| key | [<code>KeyPair</code>](#KeyPair) |
| network | <code>string</code> \| <code>undefined</code> |

<a name="Document.fromAuthentication"></a>

Expand Down
12 changes: 9 additions & 3 deletions bindings/wasm/src/wasm_document.rs
Expand Up @@ -80,10 +80,16 @@ impl WasmDocument {
})
}

/// Creates a new DID Document from the given KeyPair.
/// Creates a new DID Document from the given KeyPair and optional network.
///
/// If unspecified, network defaults to the mainnet.
#[wasm_bindgen(js_name = fromKeyPair)]
pub fn from_keypair(key: &KeyPair) -> Result<WasmDocument, JsValue> {
IotaDocument::from_keypair(&key.0).map_err(err).map(Self)
pub fn from_keypair(key: &KeyPair, network: Option<String>) -> Result<WasmDocument, JsValue> {
let doc = match network {
Some(net) => IotaDocument::from_keypair_with_network(&key.0, &net),
None => IotaDocument::from_keypair(&key.0)
}
m-renaud marked this conversation as resolved.
Show resolved Hide resolved
doc.map_err(err).map(Self)
}

/// Creates a new DID Document from the given verification [`method`][`Method`].
Expand Down
39 changes: 39 additions & 0 deletions identity-iota/src/did/doc/iota_document.rs
Expand Up @@ -82,6 +82,22 @@ impl IotaDocument {
Ok(unsafe { Self::from_authentication_unchecked(method) })
}

/// Creates a new DID Document from the given KeyPair and network.
///
/// The DID Document will be pre-populated with a single authentication
/// method based on the provided [KeyPair].
///
/// The authentication method will have the DID URL fragment `#authentication`
/// and can be easily retrieved with [Document::authentication].
pub fn from_keypair_with_network(keypair: &KeyPair, network: &str) -> Result<Self> {
let method: IotaVerificationMethod =
IotaVerificationMethod::from_keypair_with_network(keypair, "authentication", network)?;

// SAFETY: We don't create invalid Methods. Method::from_keypair() uses the MethodBuilder
// internally which verifies correctness on construction.
Ok(unsafe { Self::from_authentication_unchecked(method) })
}

/// Creates a new DID Document from the given verification [`method`][VerificationMethod].
pub fn from_authentication(method: IotaVerificationMethod) -> Result<Self> {
Self::check_authentication(&method)?;
Expand Down Expand Up @@ -631,6 +647,8 @@ mod tests {

const DID_ID: &str = "did:iota:HGE4tecHWL2YiZv5qAGtH7gaeQcaz2Z1CR15GWmMjY1M";
const DID_AUTH: &str = "did:iota:HGE4tecHWL2YiZv5qAGtH7gaeQcaz2Z1CR15GWmMjY1M#authentication";
const DID_TESTNET_ID: &str = "did:iota:test:HGE4tecHWL2YiZv5qAGtH7gaeQcaz2Z1CR15GWmMjY1M";
const DID_TESTNET_AUTH: &str = "did:iota:test:HGE4tecHWL2YiZv5qAGtH7gaeQcaz2Z1CR15GWmMjY1M#authentication";

fn valid_did() -> DID {
DID_ID.parse().unwrap()
Expand Down Expand Up @@ -716,6 +734,19 @@ mod tests {
);
}

fn compare_document_testnet(document: &IotaDocument) {
assert_eq!(document.id().to_string(), DID_TESTNET_ID);
assert_eq!(document.authentication_id(), DID_TESTNET_AUTH);
assert_eq!(
document.authentication().key_type(),
MethodType::Ed25519VerificationKey2018
);
assert_eq!(
document.authentication().key_data(),
&MethodData::PublicKeyBase58(String::from("FJsXMk9UqpJf3ZTKnfEQAhvBrVLKMSx9ZeYwQME6c6tT"))
);
}

#[test]
fn test_invalid_try_from_core_invalid_id() {
let invalid_did: DID = "did:invalid:HGE4tecHWL2YiZv5qAGtH7gaeQcaz2Z1CR15GWmMjY1M"
Expand Down Expand Up @@ -891,6 +922,14 @@ mod tests {
compare_document(&document);
}

#[test]
fn test_from_keypair_with_network() {
//from keypair
let keypair: KeyPair = generate_testkey();
let document: IotaDocument = IotaDocument::from_keypair_with_network(&keypair, "test").unwrap();
compare_document_testnet(&document);
}

#[test]
fn test_no_controler() {
let keypair: KeyPair = generate_testkey();
Expand Down
11 changes: 11 additions & 0 deletions identity-iota/src/did/doc/iota_verification_method.rs
Expand Up @@ -66,6 +66,17 @@ impl IotaVerificationMethod {
Self::from_did(did, keypair, fragment)
}

/// Creates a new [`IotaVerificationMethod`] object from the given `keypair` on the specified `network`.
pub fn from_keypair_with_network<'a, F>(keypair: &KeyPair, fragment: F, network: &str) -> Result<Self>
where
F: Into<Option<&'a str>>,
{
let key: &[u8] = keypair.public().as_ref();
let did: IotaDID = IotaDID::with_network(key, &network)?;

Self::from_did(did, keypair, fragment)
}

/// Creates a new [`Method`] object from the given `did` and `keypair`.
///
/// If the `fragment` resolves to `Option::None` then the default verification method tag will be
Expand Down