avail_rust_client/transaction_api.rs
1//! Builders for transactions targeting specific Avail pallets.
2
3use crate::{Client, SubmittableTransaction};
4use avail_rust_core::{
5 AccountId, AccountIdLike, ExtrinsicCall, H256, MultiAddress,
6 avail::{
7 self,
8 multisig::types::Timepoint,
9 nomination_pools::types::{BondExtraValue, ClaimPermission, ConfigOpAccount, PoolState},
10 proxy::types::ProxyType,
11 staking::types::{RewardDestination, ValidatorPrefs},
12 },
13 types::{
14 HashString,
15 metadata::{MultiAddressLike, StringOrBytes},
16 substrate::Weight,
17 },
18};
19
20/// Entry point for constructing pallet-specific transaction builders.
21///
22/// Each accessor clones the underlying [`Client`] and returns a lightweight helper that can compose
23/// extrinsics without contacting the node. The returned builders produce [`SubmittableTransaction`]s
24/// which must be signed—and optionally submitted—separately.
25pub struct TransactionApi(pub(crate) Client);
26impl TransactionApi {
27 /// Returns helpers for composing `balances` pallet extrinsics.
28 ///
29 /// # Returns
30 /// Returns a [`Balances`] builder that clones this client.
31 pub fn balances(&self) -> Balances {
32 Balances(self.0.clone())
33 }
34
35 /// Returns helpers for composing data availability submissions.
36 ///
37 /// # Returns
38 /// Returns a [`DataAvailability`] builder that clones this client.
39 pub fn data_availability(&self) -> DataAvailability {
40 DataAvailability(self.0.clone())
41 }
42
43 /// Returns helpers for multisig transaction approval flows.
44 ///
45 /// # Returns
46 /// Returns a [`Multisig`] builder that clones this client.
47 pub fn multisig(&self) -> Multisig {
48 Multisig(self.0.clone())
49 }
50
51 /// Returns helpers for batching extrinsics via the utility pallet.
52 ///
53 /// # Returns
54 /// Returns a [`Utility`] builder that clones this client.
55 pub fn utility(&self) -> Utility {
56 Utility(self.0.clone())
57 }
58
59 /// Returns helpers for proxy management extrinsics.
60 ///
61 /// # Returns
62 /// Returns a [`Proxy`] builder that clones this client.
63 pub fn proxy(&self) -> Proxy {
64 Proxy(self.0.clone())
65 }
66
67 /// Returns helpers for staking-related extrinsics.
68 ///
69 /// # Returns
70 /// Returns a [`Staking`] builder that clones this client.
71 pub fn staking(&self) -> Staking {
72 Staking(self.0.clone())
73 }
74
75 /// Returns helpers for Vector message passing extrinsics.
76 ///
77 /// # Returns
78 /// Returns a [`Vector`] builder that clones this client.
79 pub fn vector(&self) -> Vector {
80 Vector(self.0.clone())
81 }
82
83 /// Returns helpers for system-level extrinsics.
84 ///
85 /// # Returns
86 /// Returns a [`System`] builder that clones this client.
87 pub fn system(&self) -> System {
88 System(self.0.clone())
89 }
90
91 /// Returns helpers for nomination pool extrinsics.
92 ///
93 /// # Returns
94 /// Returns a [`NominationPools`] builder that clones this client.
95 pub fn nomination_pools(&self) -> NominationPools {
96 NominationPools(self.0.clone())
97 }
98
99 /// Returns helpers for validator session key management.
100 ///
101 /// # Returns
102 /// Returns a [`Session`] builder that clones this client.
103 pub fn session(&self) -> Session {
104 Session(self.0.clone())
105 }
106}
107
108/// Builds extrinsics for the `session` pallet.
109///
110/// The helper clones the underlying client; composing calls does not contact the node until the
111/// resulting [`SubmittableTransaction`] is signed or submitted.
112pub struct Session(Client);
113impl Session {
114 /// Updates the node's session keys with new authorities and proof data.
115 ///
116 /// # Panics
117 /// Panics when any supplied key fails to decode into an `H256` hash.
118 ///
119 /// # Arguments
120 /// * `babe` - BABE authority key encoded as a hash string.
121 /// * `grandpa` - GRANDPA authority key encoded as a hash string.
122 /// * `authority_discovery` - Authority discovery key encoded as a hash string.
123 /// * `im_online` - Im-online session key encoded as a hash string.
124 /// * `proof` - Proof bytes returned by the session key generator.
125 ///
126 /// # Returns
127 /// Returns a [`SubmittableTransaction`] that sets the supplied session keys.
128 ///
129 /// # Errors
130 /// Does not perform network calls; transaction construction never fails.
131 pub fn set_key(
132 &self,
133 babe: impl Into<HashString>,
134 grandpa: impl Into<HashString>,
135 authority_discovery: impl Into<HashString>,
136 im_online: impl Into<HashString>,
137 proof: Vec<u8>,
138 ) -> SubmittableTransaction {
139 let babe: HashString = babe.into();
140 let babe: H256 = babe.try_into().expect("Invalid string for H256");
141
142 let grandpa: HashString = grandpa.into();
143 let grandpa: H256 = grandpa.try_into().expect("Invalid string for H256");
144
145 let authority_discovery: HashString = authority_discovery.into();
146 let authority_discovery: H256 = authority_discovery.try_into().expect("Invalid string for H256");
147
148 let im_online: HashString = im_online.into();
149 let im_online: H256 = im_online.try_into().expect("Invalid string for H256");
150
151 let value = avail::session::tx::SetKeys { babe, grandpa, authority_discovery, im_online, proof };
152 SubmittableTransaction::from_encodable(self.0.clone(), value)
153 }
154
155 /// Removes the stored session keys from on-chain storage.
156 ///
157 /// # Returns
158 /// Returns a [`SubmittableTransaction`] that clears session keys for the signing account.
159 ///
160 /// # Errors
161 /// Does not perform network calls; transaction construction never fails.
162 pub fn purge_key(&self) -> SubmittableTransaction {
163 let value = avail::session::tx::PurgeKeys {};
164 SubmittableTransaction::from_encodable(self.0.clone(), value)
165 }
166}
167
168/// Builds extrinsics for the `nomination_pools` pallet.
169///
170/// Many helpers accept `MultiAddressLike` values and will panic if those cannot be converted into
171/// on-chain account identifiers. Constructing the [`SubmittableTransaction`] itself does not hit the
172/// network; signing or submitting it will.
173pub struct NominationPools(Client);
174impl NominationPools {
175 /// Contributes additional stake from the pool's bonded account.
176 ///
177 /// # Arguments
178 /// * `value` - Amount to bond, expressed as a [`BondExtraValue`].
179 ///
180 /// # Returns
181 /// Returns a [`SubmittableTransaction`] that bonds the extra amount for the pool.
182 ///
183 /// # Errors
184 /// Does not perform network calls; transaction construction never fails.
185 pub fn bond_extra(&self, value: BondExtraValue) -> SubmittableTransaction {
186 let value = avail::nomination_pools::tx::BondExtra { value };
187 SubmittableTransaction::from_encodable(self.0.clone(), value)
188 }
189
190 /// Bonds additional stake on behalf of another member.
191 ///
192 /// # Panics
193 /// Panics if `member` cannot be converted into a `MultiAddress`.
194 ///
195 /// # Arguments
196 /// * `member` - Account that receives the increased bonded amount.
197 /// * `value` - Amount to bond, expressed as a [`BondExtraValue`].
198 ///
199 /// # Returns
200 /// Returns a [`SubmittableTransaction`] that bonds extra stake for the specified member.
201 ///
202 /// # Errors
203 /// Does not perform network calls; transaction construction never fails.
204 pub fn bond_extra_other(
205 &self,
206 member: impl Into<MultiAddressLike>,
207 value: BondExtraValue,
208 ) -> SubmittableTransaction {
209 let member: MultiAddressLike = member.into();
210 let member: MultiAddress = member.try_into().expect("Malformed string is passed for AccountId");
211
212 let value = avail::nomination_pools::tx::BondExtraOther { member, value };
213 SubmittableTransaction::from_encodable(self.0.clone(), value)
214 }
215
216 /// Requests the pool to chill its nominations.
217 ///
218 /// # Arguments
219 /// * `pool_id` - Identifier of the pool that should chill.
220 ///
221 /// # Returns
222 /// Returns a [`SubmittableTransaction`] that issues the `chill` request.
223 ///
224 /// # Errors
225 /// Does not perform network calls; transaction construction never fails.
226 pub fn chill(&self, pool_id: u32) -> SubmittableTransaction {
227 let value = avail::nomination_pools::tx::Chill { pool_id };
228 SubmittableTransaction::from_encodable(self.0.clone(), value)
229 }
230
231 /// Claims pending commission for the given pool.
232 ///
233 /// # Arguments
234 /// * `pool_id` - Identifier of the pool that should pay out commission.
235 ///
236 /// # Returns
237 /// Returns a [`SubmittableTransaction`] that claims the commission.
238 ///
239 /// # Errors
240 /// Does not perform network calls; transaction construction never fails.
241 pub fn claim_commission(&self, pool_id: u32) -> SubmittableTransaction {
242 let value = avail::nomination_pools::tx::ClaimCommission { pool_id };
243 SubmittableTransaction::from_encodable(self.0.clone(), value)
244 }
245
246 /// Claims a pending payout for the caller.
247 ///
248 /// # Returns
249 /// Returns a [`SubmittableTransaction`] that claims unpaid rewards for the signer.
250 ///
251 /// # Errors
252 /// Does not perform network calls; transaction construction never fails.
253 pub fn claim_payout(&self) -> SubmittableTransaction {
254 let value = avail::nomination_pools::tx::ClaimPayout {};
255 SubmittableTransaction::from_encodable(self.0.clone(), value)
256 }
257
258 /// Claims a pending payout for another pool member.
259 ///
260 /// # Panics
261 /// Panics if `owner` cannot be converted into an `AccountId`.
262 ///
263 /// # Arguments
264 /// * `owner` - Account that receives the payout.
265 ///
266 /// # Returns
267 /// Returns a [`SubmittableTransaction`] that claims unpaid rewards on behalf of `owner`.
268 ///
269 /// # Errors
270 /// Does not perform network calls; transaction construction never fails.
271 pub fn claim_payout_other(&self, owner: impl Into<AccountIdLike>) -> SubmittableTransaction {
272 let owner: AccountIdLike = owner.into();
273 let owner: AccountId = owner.try_into().expect("Malformed string is passed for AccountId");
274
275 let value = avail::nomination_pools::tx::ClaimPayoutOther { owner };
276 SubmittableTransaction::from_encodable(self.0.clone(), value)
277 }
278
279 /// Creates a new nomination pool with freshly provided roles.
280 ///
281 /// # Panics
282 /// Panics if any of `root`, `nominator`, or `bouncer` cannot be converted into a `MultiAddress`.
283 ///
284 /// # Arguments
285 /// * `amount` - Initial bonded amount for the pool.
286 /// * `root` - Root account controlling pool administration.
287 /// * `nominator` - Account authorised to nominate validators.
288 /// * `bouncer` - Account that manages membership access.
289 ///
290 /// # Returns
291 /// Returns a [`SubmittableTransaction`] that creates the pool with the supplied roles.
292 ///
293 /// # Errors
294 /// Does not perform network calls; transaction construction never fails.
295 pub fn create(
296 &self,
297 amount: u128,
298 root: impl Into<MultiAddressLike>,
299 nominator: impl Into<MultiAddressLike>,
300 bouncer: impl Into<MultiAddressLike>,
301 ) -> SubmittableTransaction {
302 let root: MultiAddressLike = root.into();
303 let root: MultiAddress = root.try_into().expect("Malformed string is passed for AccountId");
304 let nominator: MultiAddressLike = nominator.into();
305 let nominator: MultiAddress = nominator.try_into().expect("Malformed string is passed for AccountId");
306 let bouncer: MultiAddressLike = bouncer.into();
307 let bouncer: MultiAddress = bouncer.try_into().expect("Malformed string is passed for AccountId");
308
309 let value = avail::nomination_pools::tx::Create { amount, root, nominator, bouncer };
310 SubmittableTransaction::from_encodable(self.0.clone(), value)
311 }
312
313 /// Creates a new nomination pool using a specific pool identifier.
314 ///
315 /// # Panics
316 /// Panics if any of `root`, `nominator`, or `bouncer` cannot be converted into a `MultiAddress`.
317 ///
318 /// # Arguments
319 /// * `amount` - Initial bonded amount for the pool.
320 /// * `root` - Root account controlling pool administration.
321 /// * `nominator` - Account authorised to nominate validators.
322 /// * `bouncer` - Account that manages membership access.
323 /// * `pool_id` - Identifier to assign to the new pool.
324 ///
325 /// # Returns
326 /// Returns a [`SubmittableTransaction`] that creates the pool with an explicit identifier.
327 ///
328 /// # Errors
329 /// Does not perform network calls; transaction construction never fails.
330 pub fn create_with_pool_id(
331 &self,
332 amount: u128,
333 root: impl Into<MultiAddressLike>,
334 nominator: impl Into<MultiAddressLike>,
335 bouncer: impl Into<MultiAddressLike>,
336 pool_id: u32,
337 ) -> SubmittableTransaction {
338 let root: MultiAddressLike = root.into();
339 let root: MultiAddress = root.try_into().expect("Malformed string is passed for AccountId");
340 let nominator: MultiAddressLike = nominator.into();
341 let nominator: MultiAddress = nominator.try_into().expect("Malformed string is passed for AccountId");
342 let bouncer: MultiAddressLike = bouncer.into();
343 let bouncer: MultiAddress = bouncer.try_into().expect("Malformed string is passed for AccountId");
344
345 let value = avail::nomination_pools::tx::CreateWithPoolId { amount, root, nominator, bouncer, pool_id };
346 SubmittableTransaction::from_encodable(self.0.clone(), value)
347 }
348
349 /// Joins an existing pool by contributing the requested amount.
350 ///
351 /// # Arguments
352 /// * `amount` - Amount of stake contributed by the caller.
353 /// * `pool_id` - Identifier of the pool to join.
354 ///
355 /// # Returns
356 /// Returns a [`SubmittableTransaction`] that adds the caller to the pool.
357 ///
358 /// # Errors
359 /// Does not perform network calls; transaction construction never fails.
360 pub fn join(&self, amount: u128, pool_id: u32) -> SubmittableTransaction {
361 let value = avail::nomination_pools::tx::Join { amount, pool_id };
362 SubmittableTransaction::from_encodable(self.0.clone(), value)
363 }
364
365 /// Sets nominations for the pool to a new validator set.
366 ///
367 /// # Panics
368 /// Panics if any validator identifier cannot be converted into an `AccountId`.
369 ///
370 /// # Arguments
371 /// * `pool_id` - Identifier of the pool whose nominations are updated.
372 /// * `validators` - Validators that the pool should nominate.
373 ///
374 /// # Returns
375 /// Returns a [`SubmittableTransaction`] that updates the pool's nominations.
376 ///
377 /// # Errors
378 /// Does not perform network calls; transaction construction never fails.
379 pub fn nominate(&self, pool_id: u32, validators: Vec<impl Into<AccountIdLike>>) -> SubmittableTransaction {
380 let validators: Vec<AccountIdLike> = validators.into_iter().map(|x| x.into()).collect();
381 let validators: Result<Vec<AccountId>, _> = validators.into_iter().map(AccountId::try_from).collect();
382 let validators = validators.expect("Malformed string is passed for AccountId");
383
384 let value = avail::nomination_pools::tx::Nominate { pool_id, validators };
385 SubmittableTransaction::from_encodable(self.0.clone(), value)
386 }
387
388 /// Updates who is allowed to claim rewards for the pool.
389 ///
390 /// # Arguments
391 /// * `permission` - Claim policy applied to the pool.
392 ///
393 /// # Returns
394 /// Returns a [`SubmittableTransaction`] that adjusts the pool's claim permission.
395 ///
396 /// # Errors
397 /// Does not perform network calls; transaction construction never fails.
398 pub fn set_claim_permission(&self, permission: ClaimPermission) -> SubmittableTransaction {
399 let value = avail::nomination_pools::tx::SetClaimPermission { permission };
400 SubmittableTransaction::from_encodable(self.0.clone(), value)
401 }
402
403 /// Updates the commission settings for the pool, optionally setting a payee.
404 ///
405 /// # Panics
406 /// Panics if the payee provided in `new_commission` cannot be converted into an `AccountId`.
407 ///
408 /// # Arguments
409 /// * `pool_id` - Identifier of the pool whose commission is updated.
410 /// * `new_commission` - Optional tuple of `(commission, payee)` describing the new rate and payee.
411 ///
412 /// # Returns
413 /// Returns a [`SubmittableTransaction`] that updates commission settings.
414 ///
415 /// # Errors
416 /// Does not perform network calls; transaction construction never fails.
417 pub fn set_commission(&self, pool_id: u32, new_commission: Option<(u32, AccountIdLike)>) -> SubmittableTransaction {
418 let new_commission =
419 new_commission.map(|x| (x.0, AccountId::try_from(x.1).expect("Malformed string is passed for AccountId")));
420 let value = avail::nomination_pools::tx::SetCommission { pool_id, new_commission };
421 SubmittableTransaction::from_encodable(self.0.clone(), value)
422 }
423
424 /// Configures how frequently pool commission may change.
425 ///
426 /// # Arguments
427 /// * `pool_id` - Identifier of the pool being updated.
428 /// * `max_increase` - Maximum commission increase allowed per change.
429 /// * `min_delay` - Minimum number of eras between commission updates.
430 ///
431 /// # Returns
432 /// Returns a [`SubmittableTransaction`] that applies the new change rate.
433 ///
434 /// # Errors
435 /// Does not perform network calls; transaction construction never fails.
436 pub fn set_commission_change_rate(
437 &self,
438 pool_id: u32,
439 max_increase: u32,
440 min_delay: u32,
441 ) -> SubmittableTransaction {
442 let value = avail::nomination_pools::tx::SetCommissionChangeRate { pool_id, max_increase, min_delay };
443 SubmittableTransaction::from_encodable(self.0.clone(), value)
444 }
445
446 /// Caps commission at the provided maximum percentage.
447 ///
448 /// # Arguments
449 /// * `pool_id` - Identifier of the pool being updated.
450 /// * `max_commission` - Maximum commission percentage allowed.
451 ///
452 /// # Returns
453 /// Returns a [`SubmittableTransaction`] that stores the new commission cap.
454 ///
455 /// # Errors
456 /// Does not perform network calls; transaction construction never fails.
457 pub fn set_commission_max(&self, pool_id: u32, max_commission: u32) -> SubmittableTransaction {
458 let value = avail::nomination_pools::tx::SetCommissionMax { pool_id, max_commission };
459 SubmittableTransaction::from_encodable(self.0.clone(), value)
460 }
461
462 /// Updates pool metadata stored on chain.
463 ///
464 /// # Arguments
465 /// * `pool_id` - Identifier of the pool being updated.
466 /// * `metadata` - Metadata payload encoded as bytes or string.
467 ///
468 /// # Returns
469 /// Returns a [`SubmittableTransaction`] that writes the metadata to storage.
470 ///
471 /// # Errors
472 /// Does not perform network calls; transaction construction never fails.
473 pub fn set_metadata<'a>(&self, pool_id: u32, metadata: impl Into<StringOrBytes<'a>>) -> SubmittableTransaction {
474 let metadata: StringOrBytes = metadata.into();
475 let metadata: Vec<u8> = metadata.into();
476 let value = avail::nomination_pools::tx::SetMetadata { pool_id, metadata };
477 SubmittableTransaction::from_encodable(self.0.clone(), value)
478 }
479
480 /// Transitions the pool into a new lifecycle state.
481 ///
482 /// # Arguments
483 /// * `pool_id` - Identifier of the pool being updated.
484 /// * `state` - New lifecycle state to apply.
485 ///
486 /// # Returns
487 /// Returns a [`SubmittableTransaction`] that updates the pool state.
488 ///
489 /// # Errors
490 /// Does not perform network calls; transaction construction never fails.
491 pub fn set_state(&self, pool_id: u32, state: PoolState) -> SubmittableTransaction {
492 let value = avail::nomination_pools::tx::SetState { pool_id, state };
493 SubmittableTransaction::from_encodable(self.0.clone(), value)
494 }
495
496 /// Starts the unbonding process for the specified member account.
497 ///
498 /// # Panics
499 /// Panics if `member_account` cannot be converted into a `MultiAddress`.
500 ///
501 /// # Arguments
502 /// * `member_account` - Account leaving the pool.
503 /// * `unbonding_points` - Amount of stake to unbond, expressed in pool points.
504 ///
505 /// # Returns
506 /// Returns a [`SubmittableTransaction`] that schedules the unbonding.
507 ///
508 /// # Errors
509 /// Does not perform network calls; transaction construction never fails.
510 pub fn unbond(
511 &self,
512 member_account: impl Into<MultiAddressLike>,
513 unbonding_points: u128,
514 ) -> SubmittableTransaction {
515 let member_account: MultiAddressLike = member_account.into();
516 let member_account: MultiAddress = member_account
517 .try_into()
518 .expect("Malformed string is passed for AccountId");
519
520 let value = avail::nomination_pools::tx::Unbond { member_account, unbonding_points };
521 SubmittableTransaction::from_encodable(self.0.clone(), value)
522 }
523
524 /// Updates the pool's root, nominator, and bouncer roles.
525 ///
526 /// # Arguments
527 /// * `pool_id` - Identifier of the pool being updated.
528 /// * `new_root` - Operation describing how to update the root account.
529 /// * `new_nominator` - Operation describing how to update the nominator account.
530 /// * `new_bouncer` - Operation describing how to update the bouncer account.
531 ///
532 /// # Returns
533 /// Returns a [`SubmittableTransaction`] that applies the new role assignments.
534 ///
535 /// # Errors
536 /// Does not perform network calls; transaction construction never fails.
537 pub fn update_roles(
538 &self,
539 pool_id: u32,
540 new_root: ConfigOpAccount,
541 new_nominator: ConfigOpAccount,
542 new_bouncer: ConfigOpAccount,
543 ) -> SubmittableTransaction {
544 let value = avail::nomination_pools::tx::UpdateRoles { pool_id, new_root, new_nominator, new_bouncer };
545 SubmittableTransaction::from_encodable(self.0.clone(), value)
546 }
547
548 /// Withdraws fully unbonded funds for the given member account.
549 ///
550 /// # Panics
551 /// Panics if `member_account` cannot be converted into a `MultiAddress`.
552 ///
553 /// # Arguments
554 /// * `member_account` - Account withdrawing previously unbonded funds.
555 /// * `num_slashing_spans` - Number of slashing spans to consider when finalising the withdrawal.
556 ///
557 /// # Returns
558 /// Returns a [`SubmittableTransaction`] that withdraws the unbonded amount.
559 ///
560 /// # Errors
561 /// Does not perform network calls; transaction construction never fails.
562 pub fn withdraw_unbonded(
563 &self,
564 member_account: impl Into<MultiAddressLike>,
565 num_slashing_spans: u32,
566 ) -> SubmittableTransaction {
567 let member_account: MultiAddressLike = member_account.into();
568 let member_account: MultiAddress = member_account
569 .try_into()
570 .expect("Malformed string is passed for AccountId");
571
572 let value = avail::nomination_pools::tx::WithdrawUnbonded { member_account, num_slashing_spans };
573 SubmittableTransaction::from_encodable(self.0.clone(), value)
574 }
575}
576
577/// Builds extrinsics for the `staking` pallet.
578///
579/// Methods that accept `AccountIdLike` or `MultiAddressLike` parameters will panic if the provided
580/// value cannot be converted into the expected on-chain representation.
581pub struct Staking(Client);
582impl Staking {
583 /// Bonds funds from the controller with the provided reward destination.
584 ///
585 /// # Arguments
586 /// * `value` - Amount of stake to bond.
587 /// * `payee` - Destination where rewards should be paid.
588 ///
589 /// # Returns
590 /// Returns a [`SubmittableTransaction`] that bonds the specified amount.
591 ///
592 /// # Errors
593 /// Does not perform network calls; transaction construction never fails.
594 pub fn bond(&self, value: u128, payee: RewardDestination) -> SubmittableTransaction {
595 let value = avail::staking::tx::Bond { value, payee };
596 SubmittableTransaction::from_encodable(self.0.clone(), value)
597 }
598
599 /// Adds additional stake on top of an existing bond.
600 ///
601 /// # Arguments
602 /// * `value` - Additional stake to add to the bonded balance.
603 ///
604 /// # Returns
605 /// Returns a [`SubmittableTransaction`] that increases the bonded amount.
606 ///
607 /// # Errors
608 /// Does not perform network calls; transaction construction never fails.
609 pub fn bond_extra(&self, value: u128) -> SubmittableTransaction {
610 let value = avail::staking::tx::BondExtra { value };
611 SubmittableTransaction::from_encodable(self.0.clone(), value)
612 }
613
614 /// Starts unbonding the given amount of funds.
615 ///
616 /// # Arguments
617 /// * `value` - Amount of stake to unbond.
618 ///
619 /// # Returns
620 /// Returns a [`SubmittableTransaction`] that schedules the unbonding.
621 ///
622 /// # Errors
623 /// Does not perform network calls; transaction construction never fails.
624 pub fn unbond(&self, value: u128) -> SubmittableTransaction {
625 let value = avail::staking::tx::Unbond { value };
626 SubmittableTransaction::from_encodable(self.0.clone(), value)
627 }
628
629 /// Re-bonds a portion of funds that are currently unbonding.
630 ///
631 /// # Arguments
632 /// * `value` - Amount of stake to re-bond.
633 ///
634 /// # Returns
635 /// Returns a [`SubmittableTransaction`] that re-bonds the requested amount.
636 ///
637 /// # Errors
638 /// Does not perform network calls; transaction construction never fails.
639 pub fn rebond(&self, value: u128) -> SubmittableTransaction {
640 let value = avail::staking::tx::Rebond { value };
641 SubmittableTransaction::from_encodable(self.0.clone(), value)
642 }
643
644 /// Advertises validator preferences for the caller.
645 ///
646 /// # Arguments
647 /// * `commission` - Desired commission percentage.
648 /// * `blocked` - Flag indicating whether new nominations are rejected.
649 ///
650 /// # Returns
651 /// Returns a [`SubmittableTransaction`] that publishes the validator preferences.
652 ///
653 /// # Errors
654 /// Does not perform network calls; transaction construction never fails.
655 pub fn validate(&self, commission: u32, blocked: bool) -> SubmittableTransaction {
656 let value = avail::staking::tx::Validate { prefs: ValidatorPrefs { commission, blocked } };
657 SubmittableTransaction::from_encodable(self.0.clone(), value)
658 }
659
660 /// Nominates a new set of validator targets.
661 ///
662 /// # Panics
663 /// Panics if any provided target cannot be converted into a `MultiAddress`.
664 ///
665 /// # Arguments
666 /// * `targets` - Validators to nominate.
667 ///
668 /// # Returns
669 /// Returns a [`SubmittableTransaction`] that updates the nomination targets.
670 ///
671 /// # Errors
672 /// Does not perform network calls; transaction construction never fails.
673 pub fn nominate(&self, targets: Vec<impl Into<MultiAddressLike>>) -> SubmittableTransaction {
674 let targets: Vec<MultiAddressLike> = targets.into_iter().map(|x| x.into()).collect();
675 let targets: Result<Vec<MultiAddress>, _> = targets.into_iter().map(MultiAddress::try_from).collect();
676 let targets = targets.expect("Malformed string is passed for AccountId");
677
678 let value = avail::staking::tx::Nominate { targets };
679 SubmittableTransaction::from_encodable(self.0.clone(), value)
680 }
681
682 /// Pays out staking rewards for the given validator and era.
683 ///
684 /// # Panics
685 /// Panics if `validator_stash` cannot be converted into an `AccountId`.
686 ///
687 /// # Arguments
688 /// * `validator_stash` - Stash account whose rewards are claimed.
689 /// * `era` - Era for which rewards are paid out.
690 ///
691 /// # Returns
692 /// Returns a [`SubmittableTransaction`] that triggers the payout.
693 ///
694 /// # Errors
695 /// Does not perform network calls; transaction construction never fails.
696 pub fn payout_stakers(&self, validator_stash: impl Into<AccountIdLike>, era: u32) -> SubmittableTransaction {
697 let validator_stash: AccountIdLike = validator_stash.into();
698 let validator_stash = AccountId::try_from(validator_stash).expect("Malformed string is passed for AccountId");
699
700 let value = avail::staking::tx::PayoutStakers { validator_stash, era };
701 SubmittableTransaction::from_encodable(self.0.clone(), value)
702 }
703
704 /// Switches the controller account for the stash.
705 ///
706 /// # Returns
707 /// Returns a [`SubmittableTransaction`] that sets a new controller (based on the signature).
708 ///
709 /// # Errors
710 /// Does not perform network calls; transaction construction never fails.
711 pub fn set_controller(&self) -> SubmittableTransaction {
712 let value = avail::staking::tx::SetController {};
713 SubmittableTransaction::from_encodable(self.0.clone(), value)
714 }
715
716 /// Updates the staking reward destination.
717 ///
718 /// # Arguments
719 /// * `payee` - Destination where new rewards should be deposited.
720 ///
721 /// # Returns
722 /// Returns a [`SubmittableTransaction`] that updates the reward destination.
723 ///
724 /// # Errors
725 /// Does not perform network calls; transaction construction never fails.
726 pub fn set_payee(&self, payee: RewardDestination) -> SubmittableTransaction {
727 let value = avail::staking::tx::SetPayee { payee };
728 SubmittableTransaction::from_encodable(self.0.clone(), value)
729 }
730
731 /// Stops nominating for the caller.
732 ///
733 /// # Returns
734 /// Returns a [`SubmittableTransaction`] that chills the caller's nominations.
735 ///
736 /// # Errors
737 /// Does not perform network calls; transaction construction never fails.
738 pub fn chill(&self) -> SubmittableTransaction {
739 let value = avail::staking::tx::Chill {};
740 SubmittableTransaction::from_encodable(self.0.clone(), value)
741 }
742
743 /// Issues a chill for another stash account.
744 ///
745 /// # Panics
746 /// Panics if `stash` cannot be converted into an `AccountId`.
747 ///
748 /// # Arguments
749 /// * `stash` - Stash account to chill.
750 ///
751 /// # Returns
752 /// Returns a [`SubmittableTransaction`] that chills the specified stash.
753 ///
754 /// # Errors
755 /// Does not perform network calls; transaction construction never fails.
756 pub fn chill_other(&self, stash: impl Into<AccountIdLike>) -> SubmittableTransaction {
757 let stash: AccountIdLike = stash.into();
758 let stash = AccountId::try_from(stash).expect("Malformed string is passed for AccountId");
759
760 let value = avail::staking::tx::ChillOther { stash };
761 SubmittableTransaction::from_encodable(self.0.clone(), value)
762 }
763
764 /// Withdraws funds that have completed the unbonding period.
765 ///
766 /// # Arguments
767 /// * `num_slashing_spans` - Number of slashing spans to consider when finalising the withdrawal.
768 ///
769 /// # Returns
770 /// Returns a [`SubmittableTransaction`] that withdraws matured unbonded funds.
771 ///
772 /// # Errors
773 /// Does not perform network calls; transaction construction never fails.
774 pub fn withdraw_unbonded(&self, num_slashing_spans: u32) -> SubmittableTransaction {
775 let value = avail::staking::tx::WithdrawUnbonded { num_slashing_spans };
776 SubmittableTransaction::from_encodable(self.0.clone(), value)
777 }
778
779 /// Removes a stash that no longer has bonded funds.
780 ///
781 /// # Panics
782 /// Panics if `stash` cannot be converted into an `AccountId`.
783 ///
784 /// # Arguments
785 /// * `stash` - Stash account to reap.
786 /// * `num_slashing_spans` - Number of slashing spans considered during reaping.
787 ///
788 /// # Returns
789 /// Returns a [`SubmittableTransaction`] that reaps the empty stash.
790 ///
791 /// # Errors
792 /// Does not perform network calls; transaction construction never fails.
793 pub fn reap_stash(&self, stash: impl Into<AccountIdLike>, num_slashing_spans: u32) -> SubmittableTransaction {
794 let stash: AccountIdLike = stash.into();
795 let stash = AccountId::try_from(stash).expect("Malformed string is passed for AccountId");
796
797 let value = avail::staking::tx::ReapStash { stash, num_slashing_spans };
798 SubmittableTransaction::from_encodable(self.0.clone(), value)
799 }
800
801 /// Removes the provided nominees from the caller's nomination list.
802 ///
803 /// # Panics
804 /// Panics if any identifier in `who` cannot be converted into a `MultiAddress`.
805 ///
806 /// # Arguments
807 /// * `who` - Nominees to remove.
808 ///
809 /// # Returns
810 /// Returns a [`SubmittableTransaction`] that removes the specified nominees.
811 ///
812 /// # Errors
813 /// Does not perform network calls; transaction construction never fails.
814 pub fn kick(&self, who: Vec<impl Into<MultiAddressLike>>) -> SubmittableTransaction {
815 let who: Vec<MultiAddressLike> = who.into_iter().map(|x| x.into()).collect();
816 let who: Result<Vec<MultiAddress>, _> = who.into_iter().map(MultiAddress::try_from).collect();
817 let who = who.expect("Malformed string is passed for AccountId");
818
819 let value = avail::staking::tx::Kick { who };
820 SubmittableTransaction::from_encodable(self.0.clone(), value)
821 }
822
823 /// Forces the commission for the given validator to the chain minimum.
824 ///
825 /// # Panics
826 /// Panics if `validator_stash` cannot be converted into an `AccountId`.
827 ///
828 /// # Arguments
829 /// * `validator_stash` - Stash account whose commission is being forced.
830 ///
831 /// # Returns
832 /// Returns a [`SubmittableTransaction`] that enforces the minimum commission.
833 ///
834 /// # Errors
835 /// Does not perform network calls; transaction construction never fails.
836 pub fn force_apply_min_commission(&self, validator_stash: impl Into<AccountIdLike>) -> SubmittableTransaction {
837 let validator_stash: AccountIdLike = validator_stash.into();
838 let validator_stash = AccountId::try_from(validator_stash).expect("Malformed string is passed for AccountId");
839
840 let value = avail::staking::tx::ForceApplyMinCommission { validator_stash };
841 SubmittableTransaction::from_encodable(self.0.clone(), value)
842 }
843
844 /// Pays out staking rewards for a subset of nominators.
845 ///
846 /// # Panics
847 /// Panics if `validator_stash` cannot be converted into an `AccountId`.
848 ///
849 /// # Arguments
850 /// * `validator_stash` - Stash account whose rewards are being claimed.
851 /// * `era` - Era for which rewards are paid.
852 /// * `page` - Page index selecting which nominators to payout.
853 ///
854 /// # Returns
855 /// Returns a [`SubmittableTransaction`] that triggers the paged payout.
856 ///
857 /// # Errors
858 /// Does not perform network calls; transaction construction never fails.
859 pub fn payout_stakers_by_page(
860 &self,
861 validator_stash: impl Into<AccountIdLike>,
862 era: u32,
863 page: u32,
864 ) -> SubmittableTransaction {
865 let validator_stash: AccountIdLike = validator_stash.into();
866 let validator_stash = AccountId::try_from(validator_stash).expect("Malformed string is passed for AccountId");
867
868 let value = avail::staking::tx::PayoutStakersByPage { validator_stash, era, page };
869 SubmittableTransaction::from_encodable(self.0.clone(), value)
870 }
871}
872
873/// Builds extrinsics for the `balances` pallet.
874///
875/// All helpers expect account identifiers that can be converted into `MultiAddress` values and will
876/// panic if the conversion fails.
877pub struct Balances(Client);
878impl Balances {
879 /// Transfers funds allowing the sender's account to be removed if depleted.
880 ///
881 /// # Panics
882 /// Panics if `dest` cannot be converted into a `MultiAddress`.
883 ///
884 /// # Arguments
885 /// * `dest` - Destination account receiving the transfer.
886 /// * `amount` - Amount to transfer.
887 ///
888 /// # Returns
889 /// Returns a [`SubmittableTransaction`] that performs the transfer.
890 ///
891 /// # Errors
892 /// Does not perform network calls; transaction construction never fails.
893 pub fn transfer_allow_death(&self, dest: impl Into<MultiAddressLike>, amount: u128) -> SubmittableTransaction {
894 let dest: MultiAddressLike = dest.into();
895 let dest: MultiAddress = dest.try_into().expect("Malformed string is passed for AccountId");
896
897 let value = avail::balances::tx::TransferAllowDeath { dest, value: amount };
898 SubmittableTransaction::from_encodable(self.0.clone(), value)
899 }
900
901 /// Transfers funds while keeping the sender's account alive.
902 ///
903 /// # Panics
904 /// Panics if `dest` cannot be converted into a `MultiAddress`.
905 ///
906 /// # Arguments
907 /// * `dest` - Destination account receiving the transfer.
908 /// * `amount` - Amount to transfer.
909 ///
910 /// # Returns
911 /// Returns a [`SubmittableTransaction`] that performs the keep-alive transfer.
912 ///
913 /// # Errors
914 /// Does not perform network calls; transaction construction never fails.
915 pub fn transfer_keep_alive(&self, dest: impl Into<MultiAddressLike>, amount: u128) -> SubmittableTransaction {
916 let dest: MultiAddressLike = dest.into();
917 let dest: MultiAddress = dest.try_into().expect("Malformed string is passed for AccountId");
918
919 let value = avail::balances::tx::TransferKeepAlive { dest, value: amount };
920 SubmittableTransaction::from_encodable(self.0.clone(), value)
921 }
922
923 /// Transfers the entire free balance to the destination.
924 ///
925 /// # Panics
926 /// Panics if `dest` cannot be converted into a `MultiAddress`.
927 ///
928 /// # Arguments
929 /// * `dest` - Destination account receiving the transfer.
930 /// * `keep_alive` - When `true`, leaves the minimum balance to keep the account alive.
931 ///
932 /// # Returns
933 /// Returns a [`SubmittableTransaction`] that transfers the full balance.
934 ///
935 /// # Errors
936 /// Does not perform network calls; transaction construction never fails.
937 pub fn transfer_all(&self, dest: impl Into<MultiAddressLike>, keep_alive: bool) -> SubmittableTransaction {
938 let dest: MultiAddressLike = dest.into();
939 let dest: MultiAddress = dest.try_into().expect("Malformed string is passed for AccountId");
940
941 let value = avail::balances::tx::TransferAll { dest, keep_alive };
942 SubmittableTransaction::from_encodable(self.0.clone(), value)
943 }
944}
945
946/// Builds extrinsics for the `multisig` pallet.
947///
948/// Helper methods convert `AccountIdLike` and `HashString` inputs into on-chain representations and
949/// panic if the conversion fails; they also sort the provided signatories to match runtime
950/// expectations.
951pub struct Multisig(Client);
952impl Multisig {
953 /// Approves a multisig call by reference to its hash.
954 ///
955 /// # Panics
956 /// Panics if any signatory identifier fails to convert into an `AccountId` or if `call_hash`
957 /// cannot be converted into `H256`.
958 ///
959 /// # Arguments
960 /// * `threshold` - Total number of approvals required to execute the call.
961 /// * `other_signatories` - Remaining signatories excluding the caller.
962 /// * `maybe_timepoint` - Optional timepoint identifying the in-progress multisig.
963 /// * `call_hash` - Hash of the call being approved.
964 /// * `max_weight` - Execution weight budget for the call.
965 ///
966 /// # Returns
967 /// Returns a [`SubmittableTransaction`] that records the approval.
968 ///
969 /// # Errors
970 /// Does not perform network calls; transaction construction never fails.
971 pub fn approve_as_multi(
972 &self,
973 threshold: u16,
974 other_signatories: Vec<impl Into<AccountIdLike>>,
975 maybe_timepoint: Option<Timepoint>,
976 call_hash: impl Into<HashString>,
977 max_weight: Weight,
978 ) -> SubmittableTransaction {
979 fn inner(
980 client: Client,
981 threshold: u16,
982 other_signatories: Vec<AccountIdLike>,
983 maybe_timepoint: Option<Timepoint>,
984 call_hash: HashString,
985 max_weight: Weight,
986 ) -> SubmittableTransaction {
987 let other_signatories: Result<Vec<AccountId>, _> =
988 other_signatories.into_iter().map(|x| x.try_into()).collect();
989 let mut other_signatories = other_signatories.expect("Malformed string is passed for AccountId");
990 other_signatories.sort();
991
992 let call_hash: H256 = call_hash.try_into().expect("Malformed string is passed for H256");
993
994 let value = avail::multisig::tx::ApproveAsMulti {
995 threshold,
996 other_signatories,
997 maybe_timepoint,
998 call_hash,
999 max_weight,
1000 };
1001 SubmittableTransaction::from_encodable(client, value)
1002 }
1003
1004 let other_signatories: Vec<AccountIdLike> = other_signatories.into_iter().map(|x| x.into()).collect();
1005 let call_hash: HashString = call_hash.into();
1006 inner(self.0.clone(), threshold, other_signatories, maybe_timepoint, call_hash, max_weight)
1007 }
1008
1009 /// Executes a multisig call with full call data.
1010 ///
1011 /// # Panics
1012 /// Panics if any signatory identifier fails to convert into an `AccountId`.
1013 ///
1014 /// # Arguments
1015 /// * `threshold` - Total number of approvals required to execute the call.
1016 /// * `other_signatories` - Remaining signatories excluding the caller.
1017 /// * `maybe_timepoint` - Optional timepoint identifying the in-progress multisig.
1018 /// * `call` - Call payload to execute once approvals are satisfied.
1019 /// * `max_weight` - Execution weight budget for the call.
1020 ///
1021 /// # Returns
1022 /// Returns a [`SubmittableTransaction`] that submits the multisig call.
1023 ///
1024 /// # Errors
1025 /// Does not perform network calls; transaction construction never fails.
1026 pub fn as_multi(
1027 &self,
1028 threshold: u16,
1029 other_signatories: Vec<impl Into<AccountIdLike>>,
1030 maybe_timepoint: Option<Timepoint>,
1031 call: impl Into<ExtrinsicCall>,
1032 max_weight: Weight,
1033 ) -> SubmittableTransaction {
1034 fn inner(
1035 client: Client,
1036 threshold: u16,
1037 other_signatories: Vec<AccountIdLike>,
1038 maybe_timepoint: Option<Timepoint>,
1039 call: ExtrinsicCall,
1040 max_weight: Weight,
1041 ) -> SubmittableTransaction {
1042 let other_signatories: Result<Vec<AccountId>, _> =
1043 other_signatories.into_iter().map(|x| x.try_into()).collect();
1044 let mut other_signatories = other_signatories.expect("Malformed string is passed for AccountId");
1045 other_signatories.sort();
1046
1047 let value = avail::multisig::tx::AsMulti {
1048 threshold,
1049 other_signatories,
1050 maybe_timepoint,
1051 call,
1052 max_weight,
1053 };
1054 SubmittableTransaction::from_encodable(client, value)
1055 }
1056
1057 let other_signatories: Vec<AccountIdLike> = other_signatories.into_iter().map(|x| x.into()).collect();
1058 inner(self.0.clone(), threshold, other_signatories, maybe_timepoint, call.into(), max_weight)
1059 }
1060
1061 /// Executes a multisig call with a threshold of one.
1062 ///
1063 /// # Panics
1064 /// Panics if any signatory identifier fails to convert into an `AccountId`.
1065 ///
1066 /// # Arguments
1067 /// * `other_signatories` - Remaining signatories excluding the caller; used to derive the multisig account.
1068 /// * `call` - Call payload to execute.
1069 ///
1070 /// # Returns
1071 /// Returns a [`SubmittableTransaction`] that executes the call with a threshold of one.
1072 ///
1073 /// # Errors
1074 /// Does not perform network calls; transaction construction never fails.
1075 pub fn as_multi_threshold_1(
1076 &self,
1077 other_signatories: Vec<impl Into<AccountIdLike>>,
1078 call: impl Into<ExtrinsicCall>,
1079 ) -> SubmittableTransaction {
1080 fn inner(client: Client, other_signatories: Vec<AccountIdLike>, call: ExtrinsicCall) -> SubmittableTransaction {
1081 let other_signatories: Result<Vec<AccountId>, _> =
1082 other_signatories.into_iter().map(|x| x.try_into()).collect();
1083 let mut other_signatories = other_signatories.expect("Malformed string is passed for AccountId");
1084 other_signatories.sort();
1085
1086 let value = avail::multisig::tx::AsMultiThreshold1 { other_signatories, call };
1087 SubmittableTransaction::from_encodable(client, value)
1088 }
1089
1090 let other_signatories: Vec<AccountIdLike> = other_signatories.into_iter().map(|x| x.into()).collect();
1091 inner(self.0.clone(), other_signatories, call.into())
1092 }
1093
1094 /// Cancels a previously scheduled multisig call.
1095 ///
1096 /// # Panics
1097 /// Panics if any signatory identifier fails to convert into an `AccountId` or if `call_hash`
1098 /// cannot be converted into `H256`.
1099 ///
1100 /// # Arguments
1101 /// * `threshold` - Total number of approvals required by the multisig.
1102 /// * `other_signatories` - Remaining signatories excluding the caller.
1103 /// * `timepoint` - Timepoint returned when the call was created.
1104 /// * `call_hash` - Hash of the call being cancelled.
1105 ///
1106 /// # Returns
1107 /// Returns a [`SubmittableTransaction`] that cancels the multisig operation.
1108 ///
1109 /// # Errors
1110 /// Does not perform network calls; transaction construction never fails.
1111 pub fn cancel_as_multi(
1112 &self,
1113 threshold: u16,
1114 other_signatories: Vec<impl Into<AccountIdLike>>,
1115 timepoint: Timepoint,
1116 call_hash: impl Into<HashString>,
1117 ) -> SubmittableTransaction {
1118 fn inner(
1119 client: Client,
1120 threshold: u16,
1121 other_signatories: Vec<AccountIdLike>,
1122 timepoint: Timepoint,
1123 call_hash: HashString,
1124 ) -> SubmittableTransaction {
1125 let other_signatories: Result<Vec<AccountId>, _> =
1126 other_signatories.into_iter().map(|x| x.try_into()).collect();
1127 let mut other_signatories = other_signatories.expect("Malformed string is passed for AccountId");
1128 other_signatories.sort();
1129
1130 let call_hash: H256 = call_hash.try_into().expect("Malformed string is passed for H256");
1131
1132 let value = avail::multisig::tx::CancelAsMulti { threshold, other_signatories, timepoint, call_hash };
1133 SubmittableTransaction::from_encodable(client, value)
1134 }
1135
1136 let other_signatories: Vec<AccountIdLike> = other_signatories.into_iter().map(|x| x.into()).collect();
1137 let call_hash: HashString = call_hash.into();
1138 inner(self.0.clone(), threshold, other_signatories, timepoint, call_hash)
1139 }
1140}
1141
1142/// Builds extrinsics for the `data_availability` pallet.
1143pub struct DataAvailability(Client);
1144impl DataAvailability {
1145 /// Registers a new application key for data availability submissions.
1146 ///
1147 /// # Arguments
1148 /// * `key` - Application key bytes or string accepted by the runtime.
1149 ///
1150 /// # Returns
1151 /// Returns a [`SubmittableTransaction`] that registers the application key.
1152 ///
1153 /// # Errors
1154 /// Does not perform network calls; transaction construction never fails.
1155 pub fn create_application_key<'a>(&self, key: impl Into<StringOrBytes<'a>>) -> SubmittableTransaction {
1156 let key: Vec<u8> = Into::<StringOrBytes>::into(key).into();
1157 let value = avail::data_availability::tx::CreateApplicationKey { key };
1158 SubmittableTransaction::from_encodable(self.0.clone(), value)
1159 }
1160
1161 /// Submits application data for availability guarantees.
1162 ///
1163 /// # Arguments
1164 /// * `data` - Data payload to submit.
1165 ///
1166 /// # Returns
1167 /// Returns a [`SubmittableTransaction`] that submits the data for availability.
1168 ///
1169 /// # Errors
1170 /// Does not perform network calls; transaction construction never fails.
1171 pub fn submit_data<'a>(&self, data: impl Into<StringOrBytes<'a>>) -> SubmittableTransaction {
1172 let data: Vec<u8> = Into::<StringOrBytes>::into(data).into();
1173 let value = avail::data_availability::tx::SubmitData { data };
1174 SubmittableTransaction::from_encodable(self.0.clone(), value)
1175 }
1176
1177 #[cfg(feature = "next")]
1178 /// Submits metadata describing an out-of-band blob.
1179 ///
1180 /// # Arguments
1181 /// * `blob_hash` - Hash identifying the blob payload.
1182 /// * `size` - Size of the blob in bytes.
1183 /// * `commitments` - Commitment bytes used for verification.
1184 ///
1185 /// # Returns
1186 /// Returns a [`SubmittableTransaction`] ready to be signed and submitted.
1187 ///
1188 /// # Errors
1189 /// Does not perform network calls; transaction construction never fails.
1190 pub fn submit_blob_metadata(&self, blob_hash: H256, size: u64, commitments: Vec<u8>) -> SubmittableTransaction {
1191 let value = avail::data_availability::tx::SubmitBlobMetadata { blob_hash, size, commitments };
1192 SubmittableTransaction::from_encodable(self.0.clone(), value)
1193 }
1194}
1195
1196/// Builds extrinsics for the `utility` pallet.
1197pub struct Utility(Client);
1198impl Utility {
1199 /// Dispatches a set of calls sequentially, aborting on failure.
1200 ///
1201 /// # Arguments
1202 /// * `calls` - Calls executed in sequence.
1203 ///
1204 /// # Returns
1205 /// Returns a [`SubmittableTransaction`] that batches the supplied calls.
1206 ///
1207 /// # Errors
1208 /// Does not perform network calls; transaction construction never fails.
1209 pub fn batch(&self, calls: Vec<impl Into<ExtrinsicCall>>) -> SubmittableTransaction {
1210 let mut batch = avail::utility::tx::Batch::new();
1211 batch.add_calls(calls.into_iter().map(|x| x.into()).collect());
1212 SubmittableTransaction::from_encodable(self.0.clone(), batch)
1213 }
1214
1215 /// Dispatches a set of calls and reverts the whole batch if any fail.
1216 ///
1217 /// # Arguments
1218 /// * `calls` - Calls executed atomically; any failure rolls back the batch.
1219 ///
1220 /// # Returns
1221 /// Returns a [`SubmittableTransaction`] that executes the all-or-nothing batch.
1222 ///
1223 /// # Errors
1224 /// Does not perform network calls; transaction construction never fails.
1225 pub fn batch_all(&self, calls: Vec<impl Into<ExtrinsicCall>>) -> SubmittableTransaction {
1226 let mut batch = avail::utility::tx::BatchAll::new();
1227 batch.add_calls(calls.into_iter().map(|x| x.into()).collect());
1228 SubmittableTransaction::from_encodable(self.0.clone(), batch)
1229 }
1230
1231 /// Dispatches a set of calls while ignoring failures.
1232 ///
1233 /// # Arguments
1234 /// * `calls` - Calls executed sequentially; individual failures are ignored.
1235 ///
1236 /// # Returns
1237 /// Returns a [`SubmittableTransaction`] that executes the tolerant batch.
1238 ///
1239 /// # Errors
1240 /// Does not perform network calls; transaction construction never fails.
1241 pub fn force_batch(&self, calls: Vec<impl Into<ExtrinsicCall>>) -> SubmittableTransaction {
1242 let mut batch = avail::utility::tx::ForceBatch::new();
1243 batch.add_calls(calls.into_iter().map(|x| x.into()).collect());
1244 SubmittableTransaction::from_encodable(self.0.clone(), batch)
1245 }
1246}
1247
1248/// Builds extrinsics for the `proxy` pallet.
1249///
1250/// Methods converting `MultiAddressLike` parameters will panic if the provided values cannot be
1251/// decoded into `MultiAddress` instances.
1252pub struct Proxy(Client);
1253impl Proxy {
1254 /// Dispatches a call through an existing proxy relationship.
1255 ///
1256 /// # Panics
1257 /// Panics if `id` cannot be converted into a `MultiAddress`.
1258 ///
1259 /// # Arguments
1260 /// * `id` - Proxy account that will dispatch the call.
1261 /// * `force_proxy_type` - Optional proxy type override.
1262 /// * `call` - Call to execute through the proxy.
1263 ///
1264 /// # Returns
1265 /// Returns a [`SubmittableTransaction`] that executes the proxied call.
1266 ///
1267 /// # Errors
1268 /// Does not perform network calls; transaction construction never fails.
1269 pub fn proxy(
1270 &self,
1271 id: impl Into<MultiAddressLike>,
1272 force_proxy_type: Option<ProxyType>,
1273 call: impl Into<ExtrinsicCall>,
1274 ) -> SubmittableTransaction {
1275 let id: MultiAddressLike = id.into();
1276 let id: MultiAddress = id.try_into().expect("Malformed string is passed for AccountId");
1277
1278 let value = avail::proxy::tx::Proxy { id, force_proxy_type, call: call.into() };
1279 SubmittableTransaction::from_encodable(self.0.clone(), value)
1280 }
1281
1282 /// Registers a new proxy delegate for the caller.
1283 ///
1284 /// # Panics
1285 /// Panics if `id` cannot be converted into a `MultiAddress`.
1286 ///
1287 /// # Arguments
1288 /// * `id` - Delegate account that gains proxy rights.
1289 /// * `proxy_type` - Proxy type applied to the delegate.
1290 /// * `delay` - Number of blocks the proxy must wait before first use.
1291 ///
1292 /// # Returns
1293 /// Returns a [`SubmittableTransaction`] that adds the proxy.
1294 ///
1295 /// # Errors
1296 /// Does not perform network calls; transaction construction never fails.
1297 pub fn add_proxy(
1298 &self,
1299 id: impl Into<MultiAddressLike>,
1300 proxy_type: ProxyType,
1301 delay: u32,
1302 ) -> SubmittableTransaction {
1303 let id: MultiAddressLike = id.into();
1304 let id: MultiAddress = id.try_into().expect("Malformed string is passed for AccountId");
1305
1306 let value = avail::proxy::tx::AddProxy { id, proxy_type, delay };
1307 SubmittableTransaction::from_encodable(self.0.clone(), value)
1308 }
1309
1310 /// Removes a specific proxy delegate.
1311 ///
1312 /// # Panics
1313 /// Panics if `delegate` cannot be converted into a `MultiAddress`.
1314 ///
1315 /// # Arguments
1316 /// * `delegate` - Delegate being removed.
1317 /// * `proxy_type` - Proxy type to revoke.
1318 /// * `delay` - Expected delay recorded for the delegate.
1319 ///
1320 /// # Returns
1321 /// Returns a [`SubmittableTransaction`] that removes the proxy.
1322 ///
1323 /// # Errors
1324 /// Does not perform network calls; transaction construction never fails.
1325 pub fn remove_proxy(
1326 &self,
1327 delegate: impl Into<MultiAddressLike>,
1328 proxy_type: ProxyType,
1329 delay: u32,
1330 ) -> SubmittableTransaction {
1331 let delegate: MultiAddressLike = delegate.into();
1332 let delegate: MultiAddress = delegate.try_into().expect("Malformed string is passed for AccountId");
1333
1334 let value = avail::proxy::tx::RemoveProxy { delegate, proxy_type, delay };
1335 SubmittableTransaction::from_encodable(self.0.clone(), value)
1336 }
1337
1338 /// Removes all proxies belonging to the caller.
1339 ///
1340 /// # Returns
1341 /// Returns a [`SubmittableTransaction`] that clears the caller's proxies.
1342 ///
1343 /// # Errors
1344 /// Does not perform network calls; transaction construction never fails.
1345 pub fn remove_proxies(&self) -> SubmittableTransaction {
1346 let value = avail::proxy::tx::RemoveProxies {};
1347 SubmittableTransaction::from_encodable(self.0.clone(), value)
1348 }
1349
1350 /// Creates a pure proxy account with the requested parameters.
1351 ///
1352 /// # Arguments
1353 /// * `proxy_type` - Proxy type to associate with the pure proxy.
1354 /// * `delay` - Number of blocks the proxy must wait before use.
1355 /// * `index` - Index differentiating multiple pure proxies.
1356 ///
1357 /// # Returns
1358 /// Returns a [`SubmittableTransaction`] that spawns the pure proxy.
1359 ///
1360 /// # Errors
1361 /// Does not perform network calls; transaction construction never fails.
1362 pub fn create_pure(&self, proxy_type: ProxyType, delay: u32, index: u16) -> SubmittableTransaction {
1363 let value = avail::proxy::tx::CreatePure { proxy_type, delay, index };
1364 SubmittableTransaction::from_encodable(self.0.clone(), value)
1365 }
1366
1367 /// Kills a pure proxy that was previously spawned by the provided account.
1368 ///
1369 /// # Panics
1370 /// Panics if `spawner` cannot be converted into a `MultiAddress`.
1371 ///
1372 /// # Arguments
1373 /// * `spawner` - Account that originally spawned the pure proxy.
1374 /// * `proxy_type` - Proxy type associated with the pure proxy.
1375 /// * `index` - Index of the pure proxy to kill.
1376 /// * `height` - Block height recorded at spawn time.
1377 /// * `ext_index` - Extrinsic index recorded at spawn time.
1378 ///
1379 /// # Returns
1380 /// Returns a [`SubmittableTransaction`] that destroys the pure proxy.
1381 ///
1382 /// # Errors
1383 /// Does not perform network calls; transaction construction never fails.
1384 pub fn kill_pure(
1385 &self,
1386 spawner: impl Into<MultiAddressLike>,
1387 proxy_type: ProxyType,
1388 index: u16,
1389 height: u32,
1390 ext_index: u32,
1391 ) -> SubmittableTransaction {
1392 let spawner: MultiAddressLike = spawner.into();
1393 let spawner: MultiAddress = spawner.try_into().expect("Malformed string is passed for AccountId");
1394
1395 let value = avail::proxy::tx::KillPure { spawner, proxy_type, index, height, ext_index };
1396 SubmittableTransaction::from_encodable(self.0.clone(), value)
1397 }
1398}
1399
1400/// Builds extrinsics for the `vector` pallet.
1401///
1402/// Several helpers convert hash-like parameters into `H256` values and will panic if the provided
1403/// data cannot be parsed.
1404pub struct Vector(Client);
1405impl Vector {
1406 /// Submits a fulfillment proof for a pending cross-chain call.
1407 ///
1408 /// # Arguments
1409 /// * `function_id` - Identifier of the function being fulfilled.
1410 /// * `input` - Encoded input payload.
1411 /// * `output` - Encoded output payload.
1412 /// * `proof` - Proof bytes attesting to the fulfillment.
1413 /// * `slot` - Slot in which the message was queued.
1414 ///
1415 /// # Returns
1416 /// Returns a [`SubmittableTransaction`] that fulfills the cross-chain call.
1417 ///
1418 /// # Errors
1419 /// Does not perform network calls; transaction construction never fails.
1420 pub fn batch(
1421 &self,
1422 function_id: H256,
1423 input: Vec<u8>,
1424 output: Vec<u8>,
1425 proof: Vec<u8>,
1426 slot: u64,
1427 ) -> SubmittableTransaction {
1428 let value = avail::vector::tx::FulfillCall { function_id, input, output, proof, slot };
1429 SubmittableTransaction::from_encodable(self.0.clone(), value)
1430 }
1431
1432 /// Executes a vector addressed message with witness data.
1433 ///
1434 /// # Arguments
1435 /// * `slot` - Slot to execute.
1436 /// * `addr_message` - Addressed message payload.
1437 /// * `account_proof` - Proof for the account tree.
1438 /// * `storage_proof` - Proof for the storage entries.
1439 ///
1440 /// # Returns
1441 /// Returns a [`SubmittableTransaction`] that executes the message.
1442 ///
1443 /// # Errors
1444 /// Does not perform network calls; transaction construction never fails.
1445 pub fn execute(
1446 &self,
1447 slot: u64,
1448 addr_message: avail::vector::types::AddressedMessage,
1449 account_proof: Vec<Vec<u8>>,
1450 storage_proof: Vec<Vec<u8>>,
1451 ) -> SubmittableTransaction {
1452 let value = avail::vector::tx::Execute { slot, addr_message, account_proof, storage_proof };
1453 SubmittableTransaction::from_encodable(self.0.clone(), value)
1454 }
1455
1456 /// Toggles whether a source chain is frozen.
1457 ///
1458 /// # Arguments
1459 /// * `source_chain_id` - Identifier of the source chain.
1460 /// * `frozen` - Boolean indicating the desired freeze state.
1461 ///
1462 /// # Returns
1463 /// Returns a [`SubmittableTransaction`] that updates the frozen state.
1464 ///
1465 /// # Errors
1466 /// Does not perform network calls; transaction construction never fails.
1467 pub fn source_chain_froze(&self, source_chain_id: u32, frozen: bool) -> SubmittableTransaction {
1468 let value = avail::vector::tx::SourceChainFroze { source_chain_id, frozen };
1469 SubmittableTransaction::from_encodable(self.0.clone(), value)
1470 }
1471
1472 /// Sends a vector message to the specified domain.
1473 ///
1474 /// # Panics
1475 /// Panics if `to` cannot be converted into an `H256`.
1476 ///
1477 /// # Arguments
1478 /// * `message` - Message payload to send.
1479 /// * `to` - Destination address encoded as a hash string.
1480 /// * `domain` - Destination domain identifier.
1481 ///
1482 /// # Returns
1483 /// Returns a [`SubmittableTransaction`] that enqueues the message.
1484 ///
1485 /// # Errors
1486 /// Does not perform network calls; transaction construction never fails.
1487 pub fn send_message(
1488 &self,
1489 message: avail::vector::types::Message,
1490 to: impl Into<HashString>,
1491 domain: u32,
1492 ) -> SubmittableTransaction {
1493 let to: HashString = to.into();
1494 let to: H256 = to.try_into().expect("Malformed string is passed for H256");
1495
1496 let value = avail::vector::tx::SendMessage { message, to, domain };
1497 SubmittableTransaction::from_encodable(self.0.clone(), value)
1498 }
1499
1500 /// Marks previous outbound messages as failed by index.
1501 ///
1502 /// # Arguments
1503 /// * `failed_txs` - Indices of failed outbound messages.
1504 ///
1505 /// # Returns
1506 /// Returns a [`SubmittableTransaction`] that records the failure.
1507 ///
1508 /// # Errors
1509 /// Does not perform network calls; transaction construction never fails.
1510 pub fn failed_send_message_txs(&self, failed_txs: Vec<u32>) -> SubmittableTransaction {
1511 let value = avail::vector::tx::FailedSendMessageTxs { failed_txs };
1512 SubmittableTransaction::from_encodable(self.0.clone(), value)
1513 }
1514
1515 /// Updates the Poseidon hash commitment for a sync period.
1516 ///
1517 /// # Arguments
1518 /// * `period` - Period identifier.
1519 /// * `poseidon_hash` - Poseidon hash commitment bytes.
1520 ///
1521 /// # Returns
1522 /// Returns a [`SubmittableTransaction`] that stores the commitment.
1523 ///
1524 /// # Errors
1525 /// Does not perform network calls; transaction construction never fails.
1526 pub fn set_poseidon_hash(&self, period: u64, poseidon_hash: Vec<u8>) -> SubmittableTransaction {
1527 let value = avail::vector::tx::SetPoseidonHash { period: period.into(), poseidon_hash };
1528 SubmittableTransaction::from_encodable(self.0.clone(), value)
1529 }
1530
1531 /// Registers the broadcaster for a specific domain.
1532 ///
1533 /// # Arguments
1534 /// * `broadcaster_domain` - Domain where the broadcaster operates.
1535 /// * `broadcaster` - Broadcaster identifier.
1536 ///
1537 /// # Returns
1538 /// Returns a [`SubmittableTransaction`] that sets the broadcaster.
1539 ///
1540 /// # Errors
1541 /// Does not perform network calls; transaction construction never fails.
1542 pub fn set_broadcaster(&self, broadcaster_domain: u32, broadcaster: H256) -> SubmittableTransaction {
1543 let value = avail::vector::tx::SetBroadcaster { broadcaster_domain: broadcaster_domain.into(), broadcaster };
1544 SubmittableTransaction::from_encodable(self.0.clone(), value)
1545 }
1546
1547 /// Overwrites the set of domains allowed to send messages.
1548 ///
1549 /// # Arguments
1550 /// * `value` - Domains permitted to send messages.
1551 ///
1552 /// # Returns
1553 /// Returns a [`SubmittableTransaction`] that updates the whitelist.
1554 ///
1555 /// # Errors
1556 /// Does not perform network calls; transaction construction never fails.
1557 pub fn set_whitelisted_domains(&self, value: Vec<u32>) -> SubmittableTransaction {
1558 let value = avail::vector::tx::SetWhitelistedDomains { value };
1559 SubmittableTransaction::from_encodable(self.0.clone(), value)
1560 }
1561
1562 /// Updates the vector configuration parameters.
1563 ///
1564 /// # Arguments
1565 /// * `value` - Configuration structure applied to the pallet.
1566 ///
1567 /// # Returns
1568 /// Returns a [`SubmittableTransaction`] that stores the configuration.
1569 ///
1570 /// # Errors
1571 /// Does not perform network calls; transaction construction never fails.
1572 pub fn set_configuration(&self, value: avail::vector::types::Configuration) -> SubmittableTransaction {
1573 let value = avail::vector::tx::SetConfiguration { value };
1574 SubmittableTransaction::from_encodable(self.0.clone(), value)
1575 }
1576
1577 /// Updates the function identifiers used by the pallet.
1578 ///
1579 /// # Arguments
1580 /// * `value` - Optional tuple containing new function identifiers.
1581 ///
1582 /// # Returns
1583 /// Returns a [`SubmittableTransaction`] that records the identifiers.
1584 ///
1585 /// # Errors
1586 /// Does not perform network calls; transaction construction never fails.
1587 pub fn set_function_ids(&self, value: Option<(H256, H256)>) -> SubmittableTransaction {
1588 let value = avail::vector::tx::SetFunctionIds { value };
1589 SubmittableTransaction::from_encodable(self.0.clone(), value)
1590 }
1591
1592 /// Sets the verification key for the step circuit.
1593 ///
1594 /// # Arguments
1595 /// * `value` - Optional verification key bytes.
1596 ///
1597 /// # Returns
1598 /// Returns a [`SubmittableTransaction`] that updates the verification key.
1599 ///
1600 /// # Errors
1601 /// Does not perform network calls; transaction construction never fails.
1602 pub fn set_step_verification_key(&self, value: Option<Vec<u8>>) -> SubmittableTransaction {
1603 let value = avail::vector::tx::SetStepVerificationKey { value };
1604 SubmittableTransaction::from_encodable(self.0.clone(), value)
1605 }
1606
1607 /// Updates the updater account hash.
1608 ///
1609 /// # Arguments
1610 /// * `updater` - New updater hash.
1611 ///
1612 /// # Returns
1613 /// Returns a [`SubmittableTransaction`] that stores the updater hash.
1614 ///
1615 /// # Errors
1616 /// Does not perform network calls; transaction construction never fails.
1617 pub fn set_updater(&self, updater: H256) -> SubmittableTransaction {
1618 let value = avail::vector::tx::SetUpdater { updater };
1619 SubmittableTransaction::from_encodable(self.0.clone(), value)
1620 }
1621
1622 /// Submits a zero-knowledge proof fulfilling a pending message.
1623 ///
1624 /// # Arguments
1625 /// * `proof` - Proof bytes attesting to message fulfillment.
1626 /// * `public_values` - Public inputs used during verification.
1627 ///
1628 /// # Returns
1629 /// Returns a [`SubmittableTransaction`] that fulfills the message.
1630 ///
1631 /// # Errors
1632 /// Does not perform network calls; transaction construction never fails.
1633 pub fn fulfill(&self, proof: Vec<u8>, public_values: Vec<u8>) -> SubmittableTransaction {
1634 let value = avail::vector::tx::Fulfill { proof, public_values };
1635 SubmittableTransaction::from_encodable(self.0.clone(), value)
1636 }
1637
1638 /// Sets the verification key for SP1 proofs.
1639 ///
1640 /// # Arguments
1641 /// * `sp1_vk` - SP1 verification key hash.
1642 ///
1643 /// # Returns
1644 /// Returns a [`SubmittableTransaction`] that stores the key.
1645 ///
1646 /// # Errors
1647 /// Does not perform network calls; transaction construction never fails.
1648 pub fn set_sp1_verification_key(&self, sp1_vk: H256) -> SubmittableTransaction {
1649 let value = avail::vector::tx::SetSp1VerificationKey { sp1_vk };
1650 SubmittableTransaction::from_encodable(self.0.clone(), value)
1651 }
1652
1653 /// Updates the sync committee hash for the provided period.
1654 ///
1655 /// # Arguments
1656 /// * `period` - Period identifier.
1657 /// * `hash` - New sync committee hash.
1658 ///
1659 /// # Returns
1660 /// Returns a [`SubmittableTransaction`] that stores the sync committee hash.
1661 ///
1662 /// # Errors
1663 /// Does not perform network calls; transaction construction never fails.
1664 pub fn set_sync_committee_hash(&self, period: u64, hash: H256) -> SubmittableTransaction {
1665 let value = avail::vector::tx::SetSyncCommitteeHash { period, hash };
1666 SubmittableTransaction::from_encodable(self.0.clone(), value)
1667 }
1668
1669 /// Enables or disables mock execution mode.
1670 ///
1671 /// # Arguments
1672 /// * `value` - `true` to enable mock mode, `false` to disable.
1673 ///
1674 /// # Returns
1675 /// Returns a [`SubmittableTransaction`] that toggles mock mode.
1676 ///
1677 /// # Errors
1678 /// Does not perform network calls; transaction construction never fails.
1679 pub fn enable_mock(&self, value: bool) -> SubmittableTransaction {
1680 let value = avail::vector::tx::EnableMock { value };
1681 SubmittableTransaction::from_encodable(self.0.clone(), value)
1682 }
1683
1684 /// Fulfills a message when running in mock mode.
1685 ///
1686 /// # Arguments
1687 /// * `public_values` - Mock public values consumed by the fulfillment.
1688 ///
1689 /// # Returns
1690 /// Returns a [`SubmittableTransaction`] that fulfills the message in mock mode.
1691 ///
1692 /// # Errors
1693 /// Does not perform network calls; transaction construction never fails.
1694 pub fn mock_fulfill(&self, public_values: Vec<u8>) -> SubmittableTransaction {
1695 let value = avail::vector::tx::MockFulfill { public_values };
1696 SubmittableTransaction::from_encodable(self.0.clone(), value)
1697 }
1698}
1699
1700/// Builds extrinsics for the `system` pallet.
1701pub struct System(Client);
1702impl System {
1703 /// Emits a remark event containing arbitrary bytes.
1704 ///
1705 /// # Arguments
1706 /// * `remark` - Payload recorded on chain.
1707 ///
1708 /// # Returns
1709 /// Returns a [`SubmittableTransaction`] that emits the remark.
1710 ///
1711 /// # Errors
1712 /// Does not perform network calls; transaction construction never fails.
1713 pub fn remark(&self, remark: Vec<u8>) -> SubmittableTransaction {
1714 let value = avail::system::tx::Remark { remark };
1715 SubmittableTransaction::from_encodable(self.0.clone(), value)
1716 }
1717
1718 /// Replaces the runtime code with a new version.
1719 ///
1720 /// # Arguments
1721 /// * `code` - WASM runtime bytecode.
1722 ///
1723 /// # Returns
1724 /// Returns a [`SubmittableTransaction`] that schedules the code upgrade.
1725 ///
1726 /// # Errors
1727 /// Does not perform network calls; transaction construction never fails.
1728 pub fn set_code(&self, code: Vec<u8>) -> SubmittableTransaction {
1729 let value = avail::system::tx::SetCode { code };
1730 SubmittableTransaction::from_encodable(self.0.clone(), value)
1731 }
1732
1733 /// Replaces the runtime code without performing standard checks.
1734 ///
1735 /// # Arguments
1736 /// * `code` - WASM runtime bytecode.
1737 ///
1738 /// # Returns
1739 /// Returns a [`SubmittableTransaction`] that forces the code upgrade.
1740 ///
1741 /// # Errors
1742 /// Does not perform network calls; transaction construction never fails.
1743 pub fn set_code_without_checks(&self, code: Vec<u8>) -> SubmittableTransaction {
1744 let value = avail::system::tx::SetCodeWithoutChecks { code };
1745 SubmittableTransaction::from_encodable(self.0.clone(), value)
1746 }
1747
1748 /// Emits a remark while guaranteeing an event is produced.
1749 ///
1750 /// # Arguments
1751 /// * `remark` - Payload recorded on chain.
1752 ///
1753 /// # Returns
1754 /// Returns a [`SubmittableTransaction`] that emits the remark alongside an event.
1755 ///
1756 /// # Errors
1757 /// Does not perform network calls; transaction construction never fails.
1758 pub fn remark_with_event(&self, remark: Vec<u8>) -> SubmittableTransaction {
1759 let value = avail::system::tx::RemarkWithEvent { remark };
1760 SubmittableTransaction::from_encodable(self.0.clone(), value)
1761 }
1762}