1use std::collections::BTreeMap;
6
7use fastcrypto::traits::KeyPair as KeypairTraits;
8use iota_sdk_types::crypto::{Intent, IntentMessage};
9use rand::{SeedableRng, rngs::StdRng};
10
11use crate::{
12 IotaAddress,
13 base_types::{ObjectID, dbg_addr},
14 committee::Committee,
15 crypto::{
16 AccountKeyPair, AuthorityKeyPair, AuthorityPublicKeyBytes, IotaKeyPair, Signature, Signer,
17 get_key_pair, get_key_pair_from_rng,
18 },
19 multisig::{MultiSig, MultiSigPublicKey},
20 object::Object,
21 programmable_transaction_builder::ProgrammableTransactionBuilder,
22 signature::GenericSignature,
23 transaction::{
24 SenderSignedData, TEST_ONLY_GAS_UNIT_FOR_TRANSFER, Transaction, TransactionData,
25 },
26};
27
28pub fn make_committee_key<R>(rand: &mut R) -> (Vec<AuthorityKeyPair>, Committee)
29where
30 R: rand::CryptoRng + rand::RngCore,
31{
32 make_committee_key_num(4, rand)
33}
34
35pub fn make_committee_key_num<R>(num: usize, rand: &mut R) -> (Vec<AuthorityKeyPair>, Committee)
36where
37 R: rand::CryptoRng + rand::RngCore,
38{
39 let mut authorities: BTreeMap<AuthorityPublicKeyBytes, u64> = BTreeMap::new();
40 let mut keys = Vec::new();
41
42 for _ in 0..num {
43 let (_, inner_authority_key): (_, AuthorityKeyPair) = get_key_pair_from_rng(rand);
44 authorities.insert(
45 AuthorityPublicKeyBytes::from(inner_authority_key.public()),
47 1,
49 );
50 keys.push(inner_authority_key);
51 }
52
53 let committee = Committee::new_for_testing_with_normalized_voting_power(0, authorities);
54 (keys, committee)
55}
56
57pub fn create_fake_transaction() -> Transaction {
60 let (sender, sender_key): (_, AccountKeyPair) = get_key_pair();
61 let recipient = dbg_addr(2);
62 let object_id = ObjectID::random();
63 let object = Object::immutable_with_id_for_testing(object_id);
64 let pt = {
65 let mut builder = ProgrammableTransactionBuilder::new();
66 builder.transfer_iota(recipient, None);
67 builder.finish()
68 };
69 let data = TransactionData::new_programmable(
70 sender,
71 vec![object.compute_object_reference()],
72 pt,
73 TEST_ONLY_GAS_UNIT_FOR_TRANSFER, 1,
75 );
76 to_sender_signed_transaction(data, &sender_key)
77}
78
79pub fn make_transaction_data(sender: IotaAddress) -> TransactionData {
80 let object = Object::immutable_with_id_for_testing(ObjectID::random_from_rng(
81 &mut StdRng::from_seed([0; 32]),
82 ));
83 let pt = {
84 let mut builder = ProgrammableTransactionBuilder::new();
85 builder.transfer_iota(dbg_addr(2), None);
86 builder.finish()
87 };
88 TransactionData::new_programmable(
89 sender,
90 vec![object.compute_object_reference()],
91 pt,
92 TEST_ONLY_GAS_UNIT_FOR_TRANSFER, 1,
94 )
95}
96
97pub fn make_transaction(sender: IotaAddress, kp: &IotaKeyPair) -> Transaction {
100 let data = make_transaction_data(sender);
101 Transaction::from_data_and_signer(data, vec![kp])
102}
103
104pub fn to_sender_signed_transaction(
106 data: TransactionData,
107 signer: &dyn Signer<Signature>,
108) -> Transaction {
109 to_sender_signed_transaction_with_multi_signers(data, vec![signer])
110}
111
112pub fn to_sender_signed_transaction_with_optional_sponsor(
113 data: TransactionData,
114 sender_signature: GenericSignature,
115 sponsor_signer_opt: Option<&dyn Signer<Signature>>,
116) -> Transaction {
117 let mut signatures = vec![sender_signature];
118 if let Some(sponsor) = sponsor_signer_opt {
119 let sponsor_sig =
120 Transaction::signature_from_signer(data.clone(), Intent::iota_transaction(), sponsor)
121 .into();
122 signatures.push(sponsor_sig);
123 };
124
125 Transaction::from_generic_sig_data(data, signatures)
126}
127
128pub fn to_sender_signed_transaction_with_multi_signers(
129 data: TransactionData,
130 signers: Vec<&dyn Signer<Signature>>,
131) -> Transaction {
132 Transaction::from_data_and_signer(data, signers)
133}
134
135pub fn keys() -> Vec<IotaKeyPair> {
136 let mut seed = StdRng::from_seed([0; 32]);
137 let kp1: IotaKeyPair = IotaKeyPair::Ed25519(get_key_pair_from_rng(&mut seed).1);
138 let kp2: IotaKeyPair = IotaKeyPair::Secp256k1(get_key_pair_from_rng(&mut seed).1);
139 let kp3: IotaKeyPair = IotaKeyPair::Secp256r1(get_key_pair_from_rng(&mut seed).1);
140 vec![kp1, kp2, kp3]
141}
142
143pub fn make_upgraded_multisig_tx() -> Transaction {
144 let keys = keys();
145 let pk1 = &keys[0].public();
146 let pk2 = &keys[1].public();
147 let pk3 = &keys[2].public();
148
149 let multisig_pk = MultiSigPublicKey::new(
150 vec![pk1.clone(), pk2.clone(), pk3.clone()],
151 vec![1, 1, 1],
152 2,
153 )
154 .unwrap();
155 let addr = IotaAddress::from(&multisig_pk);
156 let tx = make_transaction(addr, &keys[0]);
157
158 let msg = IntentMessage::new(Intent::iota_transaction(), tx.transaction_data().clone());
159 let sig1 = Signature::new_secure(&msg, &keys[0]).into();
160 let sig2 = Signature::new_secure(&msg, &keys[1]).into();
161
162 let multi_sig1 = MultiSig::combine(vec![sig1, sig2], multisig_pk).unwrap();
164 Transaction::new(SenderSignedData::new(
165 tx.transaction_data().clone(),
166 vec![GenericSignature::MultiSig(multi_sig1)],
167 ))
168}
169
170mod move_authenticator {
171 pub use crate::move_authenticator::MoveAuthenticator;
172 use crate::{
173 base_types::IotaAddress,
174 object::OBJECT_START_VERSION,
175 signature::GenericSignature,
176 transaction::{CallArg, ObjectArg, SenderSignedData, Transaction},
177 utils::make_transaction_data,
178 };
179
180 pub fn make_move_authenticator_tx(address: IotaAddress) -> Transaction {
182 let data = make_transaction_data(address);
183
184 let self_call_arg = CallArg::Object(ObjectArg::SharedObject {
189 id: address.into(),
190 initial_shared_version: OBJECT_START_VERSION,
191 mutable: false,
192 });
193 let authenticator = GenericSignature::MoveAuthenticator(MoveAuthenticator::new_v1(
194 vec![],
195 vec![],
196 self_call_arg,
197 ));
198
199 Transaction::new(SenderSignedData::new(data, vec![authenticator]))
200 }
201}
202
203pub use move_authenticator::*;