Create a DID on a Private Tangle
Example
This example shows how you can create a DID on a private tangle. You can run it together with a local Hornet node.
Account Module (Recommended)
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
//! cargo run --example account_config
use identity_iota::account::Account;
use identity_iota::account::AccountBuilder;
use identity_iota::account::AutoSave;
use identity_iota::account::IdentitySetup;
use identity_iota::account::Result;
use identity_iota::account_storage::MemStore;
use identity_iota::client::ClientBuilder;
use identity_iota::client::ExplorerUrl;
use identity_iota::iota_core::IotaDID;
use identity_iota::iota_core::Network;
#[tokio::main]
async fn main() -> Result<()> {
pretty_env_logger::init();
// Set-up for a private Tangle
// You can use https://github.com/iotaledger/one-click-tangle for a local setup.
// The `network_name` needs to match the id of the network or a part of it.
// As an example we are treating the devnet as a private tangle, so we use `dev`.
// When running the local setup, we can use `tangle` since the id of the one-click
// private tangle is `private-tangle`, but we can only use 6 characters.
// Keep in mind, there are easier ways to change to devnet via `Network::Devnet`
let network_name = "dev";
let network = Network::try_from_name(network_name)?;
// If you deployed an explorer locally this would usually be `http://127.0.0.1:8082`
let explorer = ExplorerUrl::parse("https://explorer.iota.org/devnet")?;
// In a locally running one-click tangle, this would usually be `http://127.0.0.1:14265`
let private_node_url = "https://api.lb-0.h.chrysalis-devnet.iota.cafe";
// Create a new Account with explicit configuration
let mut builder: AccountBuilder = Account::builder()
.autosave(AutoSave::Never) // never auto-save. rely on the drop save
.autosave(AutoSave::Every) // save immediately after every action
.autosave(AutoSave::Batch(10)) // save after every 10 actions
.autopublish(true) // publish to the tangle automatically on every update
.storage(MemStore::new()) // use the default in-memory storage
.client_builder(
// Configure a client for the private network
ClientBuilder::new()
.network(network.clone())
.primary_node(private_node_url, None, None)?,
// set a permanode for the same network
// .permanode(<permanode_url>, None, None)?
);
// Create an identity and publish it.
// The created DID will use the network name configured for the client.
let identity: Account = match builder.create_identity(IdentitySetup::default()).await {
Ok(identity) => identity,
Err(err) => {
eprintln!("[Example] Error: {:?}", err);
eprintln!("[Example] Is your Tangle node listening on {}?", private_node_url);
return Ok(());
}
};
// Prints the Identity Resolver Explorer URL.
// The entire history can be observed on this page by clicking "Loading History".
let iota_did: &IotaDID = identity.did();
println!(
"[Example] Explore the DID Document = {}",
explorer.resolver_url(iota_did)?
);
Ok(())
}
Low-level API
- Rust
- Node.js
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
//! A basic example that generates and publishes a DID Document
//! to a private tangle.
//! It can be run together with a local hornet node.
//! Refer to https://github.com/iotaledger/one-click-tangle/tree/chrysalis/hornet-private-net
//! for setup instructions.
//!
//! cargo run --example private_tangle
use identity_iota::client::ClientBuilder;
use identity_iota::client::DIDMessageEncoding;
use identity_iota::client::ExplorerUrl;
use identity_iota::client::Receipt;
use identity_iota::crypto::KeyType;
use identity_iota::iota_core::Network;
use identity_iota::prelude::*;
#[tokio::main]
pub async fn main() -> Result<()> {
// Set-up for private Tangle
// You can use https://github.com/iotaledger/one-click-tangle for a local setup.
// The `network_name` needs to match the id of the network or a part of it.
// As an example we are treating the devnet as a private tangle, so we use `dev`.
// When running the local setup, we can use `tangle` since the id of the one-click
// private tangle is `private-tangle`, but we can only use 6 characters.
// Keep in mind, there are easier ways to change to devnet via `Network::Devnet`
let network_name = "dev";
let network = Network::try_from_name(network_name)?;
// If you deployed an explorer locally this would usually be `http://127.0.0.1:8082`
let explorer = ExplorerUrl::parse("https://explorer.iota.org/devnet")?;
// In a locally running one-click tangle, this would usually be `http://127.0.0.1:14265`
let private_node_url = "https://api.lb-0.h.chrysalis-devnet.iota.cafe";
// Use DIDMessageEncoding::Json instead to publish plaintext messages to the Tangle for debugging.
let encoding = DIDMessageEncoding::JsonBrotli;
let client: Client = ClientBuilder::new()
.network(network.clone())
.encoding(encoding)
.primary_node(private_node_url, None, None)?
.build()
.await?;
// Generate a new Ed25519 public/private key pair.
let keypair: KeyPair = KeyPair::new(KeyType::Ed25519)?;
// Create a DID with the network set explicitly.
let mut document: IotaDocument = IotaDocument::new_with_options(&keypair, Some(client.network().name()), None)?;
// Sign the DID Document with the default signing method.
document.sign_self(keypair.private(), document.default_signing_method()?.id().clone())?;
// Publish the DID Document to the Tangle.
let receipt: Receipt = match client.publish_document(&document).await {
Ok(receipt) => receipt,
Err(err) => {
eprintln!("Error > {:?}", err);
eprintln!("Is your private Tangle node listening on {}?", private_node_url);
return Ok(());
}
};
println!("Publish Receipt > {:#?}", receipt);
// Prints the Identity Resolver Explorer URL, the entire history can be observed on this page by "Loading History".
println!(
"[Example] Explore the DID Document = {}",
explorer.resolver_url(document.id())?
);
Ok(())
}
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
import {Client, DIDMessageEncoding, Document, ExplorerUrl, KeyPair, KeyType, Network} from '@iota/identity-wasm';
/**
This example shows how a DID document can be created on a private tangle.
It can be run together with a local hornet node.
Refer to https://github.com/iotaledger/one-click-tangle/tree/chrysalis/hornet-private-net
for setup instructions.
**/
async function privateTangle(restURL, networkName) {
// This name needs to match the id of the network or part of it.
// Since the id of the one-click private tangle is `private-tangle`
// but we can only use 6 characters, we use just `tangle`.
const network = Network.tryFromName(networkName || "tangle");
// Optionally point to a locally-deployed Tangle explorer.
const explorer = ExplorerUrl.parse("http://127.0.0.1:8082/");
// Create a client instance with a custom configuration to publish messages to our private Tangle.
const client = await Client.fromConfig({
network: network,
// This URL points to the REST API of the locally running hornet node.
primaryNode: {url: restURL || "http://127.0.0.1:14265/"},
// Use DIDMessageEncoding.Json instead to publish plaintext messages to the Tangle for debugging.
encoding: DIDMessageEncoding.JsonBrotli,
});
// Generate a new ed25519 public/private key pair.
const key = new KeyPair(KeyType.Ed25519);
// Create a DID with the network set explicitly.
// This will result in a DID prefixed by `did:iota:tangle`.
const doc = new Document(key, network.name());
// Sign the DID Document with the generated key.
doc.signSelf(key, doc.defaultSigningMethod().id());
// Publish the Identity to the IOTA Network, this may take a few seconds to complete Proof-of-Work.
const receipt = await client.publishDocument(doc);
// Make sure the DID can be resolved on the private tangle
const resolved = await client.resolve(doc.id());
console.log(`Published the DID document to the private tangle:`);
console.log(resolved);
console.log(`Explore the DID Document: ${explorer.resolverUrl(doc.id())}`);
// Return the results.
return {key, resolved, receipt};
}
export {privateTangle};