2

I would like to create a system whereby a client signs a message to authenticate itself in Shimmer.

What are my options?

Antonio Nardella
  • 1,074
  • 5
  • 17

1 Answers1

2

This snipped shows how to sign a transaction using the JS/TS binding⁣ of the wallet.rs library. Further below the example in Rust for offline signing.

/**⁣
  • Sign a prepared transaction, useful for offline signing.⁣

  • @param preparedTransactionData The prepared transaction data to sign.⁣

  • @returns The signed transaction essence.⁣

*/⁣

async signTransactionEssence(⁣

preparedTransactionData: PreparedTransactionData,⁣

): Promise<SignedTransactionEssence> {⁣

const response = await this.messageHandler.callAccountMethod(⁣

    this.meta.index,⁣

    {⁣

        name: 'signTransactionEssence',⁣

        data: {⁣

            preparedTransactionData,⁣

        },⁣

    },⁣

);⁣

return JSON.parse(response).payload;⁣

}⁣

Source: https://github.com/iotaledger/wallet.rs/blob/cacde454c9c27435622f16b15f97649c2fc52672/wallet/bindings/nodejs/lib/Account.ts

Here the exmaple in Rust:

// Copyright 2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! In this example we sign the prepared transaction. //! This example uses dotenv, which is not safe for use in production. //! cargo run --example 2_sign_transaction --release.

use std::{ env, fs::File, io::{prelude::*, BufWriter}, path::{Path, PathBuf}, };

use dotenv::dotenv; use iota_client::{ api::{ transaction::validate_transaction_payload_length, PreparedTransactionData, PreparedTransactionDataDto, SignedTransactionData, SignedTransactionDataDto, }, block::{output::RentStructureBuilder, payload::TransactionPayload, protocol::ProtocolParameters}, secret::{stronghold::StrongholdSecretManager, SecretManageExt, SecretManager}, }; use iota_wallet::Result;

const PREPARED_TRANSACTION_FILE_NAME: &str = "examples/offline_signing/prepared_transaction.json"; const SIGNED_TRANSACTION_FILE_NAME: &str = "examples/offline_signing/signed_transaction.json";

#[tokio::main] async fn main() -> Result<()> { dotenv().ok();

// Setup Stronghold secret_manager
let mut secret_manager = StrongholdSecretManager::builder()
    .password(&amp;env::var(&quot;STRONGHOLD_PASSWORD&quot;).unwrap())
    .build(PathBuf::from(&quot;examples/offline_signing/offline_signing.stronghold&quot;))?;

// Load snapshot file
secret_manager.read_stronghold_snapshot().await?;

// TODO: read from file, similar to https://github.com/iotaledger/iota.rs/issues/1267
// Make sure that these values match the network you use.
let protocol_parameters = ProtocolParameters::new(
    2,
    String::from(&quot;testnet&quot;),
    String::from(&quot;smr&quot;),
    1500,
    15,
    RentStructureBuilder::new()
        .byte_cost(100)
        .byte_factor_key(1)
        .byte_factor_data(10)
        .finish(),
    1813620509061365,
)
.unwrap();

let prepared_transaction_data =
    read_prepared_transaction_from_file(PREPARED_TRANSACTION_FILE_NAME, &amp;protocol_parameters)?;

// Signs prepared transaction offline.
let unlocks = SecretManager::Stronghold(secret_manager)
    .sign_transaction_essence(&amp;prepared_transaction_data, None)
    .await?;
let signed_transaction = TransactionPayload::new(prepared_transaction_data.essence.clone(), unlocks)?;

validate_transaction_payload_length(&amp;signed_transaction)?;

let signed_transaction_data = SignedTransactionData {
    transaction_payload: signed_transaction,
    inputs_data: prepared_transaction_data.inputs_data,
};

println!(&quot;Signed transaction.&quot;);

write_signed_transaction_to_file(SIGNED_TRANSACTION_FILE_NAME, &amp;signed_transaction_data)?;

Ok(())

}

fn read_prepared_transaction_from_file<P: AsRef<Path>>( path: P, protocol_parameters: &ProtocolParameters, ) -> Result<PreparedTransactionData> { let mut file = File::open(&path)?; let mut json = String::new(); file.read_to_string(&mut json)?;

Ok(PreparedTransactionData::try_from_dto(
    &amp;serde_json::from_str::&lt;PreparedTransactionDataDto&gt;(&amp;json)?,
    protocol_parameters,
)?)

}

fn write_signed_transaction_to_file<P: AsRef<Path>>( path: P, signed_transaction_data: &SignedTransactionData, ) -> Result<()> { let dto = SignedTransactionDataDto::from(signed_transaction_data); let json = serde_json::to_string_pretty(&dto)?; let mut file = BufWriter::new(File::create(path)?);

println!(&quot;{json}&quot;);

file.write_all(json.as_bytes())?;

Ok(())

}

Source: https://github.com/iotaledger/wallet.rs/blob/develop/wallet/examples/offline_signing/2_sign_transaction.rs

Antonio Nardella
  • 1,074
  • 5
  • 17