Skip to content

feat(cli) add --custom_signer flag for transactions #6777

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

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

arjanjohan
Copy link

@arjanjohan arjanjohan commented May 6, 2025

Description of change

Add an option --custom_signer to iota client to set a custom sender when creating a transaction.

$ iota client call -h
Call Move function

Usage: iota client call [OPTIONS] --package <PACKAGE> --module <MODULE> --function <FUNCTION>

Options:
      --package <PACKAGE>               Object ID of the package, which contains the module
      --module <MODULE>                 The name of the module in the package
      --function <FUNCTION>             Function name in module
      --type-args <TYPE_ARGS>...        Type arguments to the generic function being called. All must be specified, or the call will fail
      --args <ARGS>...                  Simplified ordered args like in the function syntax ObjectIDs, Addresses must be hex strings
      --gas <GAS>                       ID of the gas object for gas payment. If not provided, a gas object with at least gas_budget value will be selected
      --gas-budget <GAS_BUDGET>         An optional gas budget for this transaction (in NANOS). If gas budget is not provided, the tool will first perform a dry run to estimate the gas cost, and then it will execute the
                                        transaction. Please note that this incurs a small cost in performance due to the additional dry run call
      --dry-run                         Perform a dry run of the transaction, without executing it
      --dev-inspect                     Perform a dev inspect of the transaction, without executing it
      --serialize-unsigned-transaction  Instead of executing the transaction, serialize the bcs bytes of the unsigned transaction data (TransactionData) using base64 encoding, and print out the string <TX_BYTES>. The
                                        string can be used to execute transaction with `iota client execute-signed-tx --tx-bytes <TX_BYTES>`
      --serialize-signed-transaction    Instead of executing the transaction, serialize the bcs bytes of the signed transaction data (SenderSignedData) using base64 encoding, and print out the string <SIGNED_TX_BYTES>.
                                        The string can be used to execute transaction with `iota client execute-combined-signed-tx --signed-tx-bytes <SIGNED_TX_BYTES>`
      --custom-signer <CUSTOM_SIGNER>   Use a custom signer for the transaction
      --display [<DISPLAY>...]          Select which fields of the response to display. If not provided, all fields are displayed. The fields are: input, effects, events, object_changes, balance_changes [default:
                                        input,effects,events,object_changes,balance_changes]
      --json                            Return command outputs in json format
  -h, --help                            Print help
  -V, --version                         Print version

For a hackathon project we built a CLI tool to interact with the IOTA multisig. Under the hood it uses the IOTA CLI, but setting a custom signer on transactions made it impossible to create multisig transactions. See project here.

Links to any relevant issues

  • The IOTA docs on working with multisigs instruct users to create multisig transactions using the IOTA CLI. But these transactions cannot be executed from a multisig, since the signer will be the active address and not the multisig.

Type of change

  • Enhancement (a non-breaking change which adds functionality)

How the change has been tested

Describe the tests that you ran to verify your changes.

In our hackathon project this version of the IOTA CLI is used to creating and executing multisig transactions.

Make sure to provide instructions for the maintainer as well as any relevant configurations.

  • Basic tests (linting, compilation, formatting, unit/integration tests)
  • Patch-specific tests (correctness, functionality coverage)

Change checklist

Tick the boxes that are relevant to your changes, and delete any items that are not.

  • I have followed the contribution guidelines for this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I have checked that new and existing unit tests pass locally with my changes

Release Notes

  • Protocol:
  • Nodes (Validators and Full nodes):
  • Indexer:
  • JSON-RPC:
  • GraphQL:
  • CLI: Add --custom-signer option to iota client commands, allowing users to override the default signer address when creating transactions. This enables compatibility with multisig workflows that require specifying a custom sender.
  • Rust SDK:
  • REST API:

@arjanjohan arjanjohan requested a review from a team as a code owner May 6, 2025 19:41
Copy link

vercel bot commented May 6, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
apps-backend ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 18, 2025 7:50pm
apps-ui-kit ✅ Ready (Inspect) Visit Preview May 18, 2025 7:50pm

Copy link

vercel bot commented May 6, 2025

@arjanjohan is attempting to deploy a commit to the IOTA Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@arjanjohan arjanjohan requested a review from a team as a code owner May 7, 2025 05:40
@github-actions github-actions bot added the documentation Improvements or additions to documentation label May 7, 2025
@thibault-martinez thibault-martinez added the dev-tools Issues related to the Developer Tools Team label May 7, 2025
@DaughterOfMars
Copy link
Contributor

Mind making the release note a bit more descriptive?

@arjanjohan
Copy link
Author

Mind making the release note a bit more descriptive?

I just updated the release not

@@ -110,6 +112,7 @@ impl<'a, I: Iterator<Item = &'a str>> ProgramParser<'a, I> {
match lexeme {
L(T::Command, A::SERIALIZE_UNSIGNED) => flag!(serialize_unsigned_set),
L(T::Command, A::SERIALIZE_SIGNED) => flag!(serialize_signed_set),
L(T::Command, A::CUSTOM_SIGNER) => flag!(custom_signer_set),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you have to parse the address here and store it somewhere

This currently doesn't work (also without @)

ADDRESS=$(iota client active-address)
cargo run client ptb \
--assign to_address @$ADDRESS \
--split-coins gas "[1000000000]" \
--assign coin \
--transfer-objects "[coin]" to_address \
--custom-signer @0x111111111504e9350e635d65cd38ccd2c029434c6a3a480d8947a9ba6a15b215 \
--serialize-unsigned-transaction
 4 │ --transfer-objects [coin] to_address
 5 │ --custom-signer @0x111111111504e9350e635d65cd38ccd2c029434c6a3a480d8947a9ba6a15b215
   ·                 ┬
   ·                 ╰── Unexpected '@'

I think @ should be used to keep it consistent, in the other commands addresses are also marked with an @ before

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed some changes to make it work with the ptb commands as well, here the @ is required for custom-signer.
For the 'regular' commands (like cargo run client call) still work only without @ in the address. That's okay?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I closed this branch by accident after making these changes it seems. I restored it and fixed the merge conflict.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, just tried and can confirm that it works now!
Yes, client call without @ is fine
Do you mind also adding a test for the PTB similar to

#[sim_test]
async fn test_ptb_dev_inspect() -> Result<(), anyhow::Error> {
let mut test_cluster = TestClusterBuilder::new()
.with_num_validators(2)
.build()
.await;
let context = &mut test_cluster.wallet;
let publish_ptb_string = r#"
--assign hello_option "some('Hello')" \
--move-call std::option::borrow "<std::string::String>" hello_option \
--dev-inspect
"#;
let args = shlex::split(publish_ptb_string).unwrap();
let res = iota::client_ptb::ptb::PTB {
args,
display: HashSet::new(),
}
.execute(context)
.await?;
assert!(res.contains("Execution Result\n Return values\n IOTA TypeTag: IotaTypeTag(\"0x1::string::String\")\n Bytes: [5, 72, 101, 108, 108, 111]"));
Ok(())
}
?
For example use 0xdbcd4c41bd078067c1fed6382ce014771529f37087d02a48f927d678f96064fa hardcoded as multisig address (no need to actually have the keys, could be a random hash, but I generated it with iota keytool multi-sig-address --pks ADtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop --weights 1 --threshold 1 in case I want to use it for other tests in the future as well), then send some funds to it (like here
let transfer = IotaClientCommands::Transfer {
to: KeyIdentity::Address(address2),
object_id: object_id1,
opts: OptsWithGas::for_testing(Some(object_id1), rgp * TEST_ONLY_GAS_UNIT_FOR_TRANSFER),
}
.execute(context)
.await;
) and afterwards do a PTB with the --custom-signer argument

I can also add this if you are not sure about it, just let me know

@arjanjohan arjanjohan closed this May 14, 2025
@arjanjohan arjanjohan deleted the custom-sender-cli branch May 14, 2025 19:27
@arjanjohan arjanjohan restored the custom-sender-cli branch May 18, 2025 19:42
@arjanjohan arjanjohan reopened this May 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dev-tools Issues related to the Developer Tools Team documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants