Skip to content

Commit abeb496

Browse files
committed
Adds support for shielded masp frontend fees
1 parent 46dd514 commit abeb496

File tree

4 files changed

+290
-115
lines changed

4 files changed

+290
-115
lines changed

crates/apps_lib/src/cli.rs

Lines changed: 133 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3696,7 +3696,7 @@ pub mod args {
36963696
// FIXME: add the test prelude in the cli args too
36973697
// WARNING: use only for testing purposes, MASP frontend fees don't make
36983698
// sense when operating from the CLI
3699-
pub const __TEST_FRONTEND_SUS_FEE: ArgOpt<WalletAddress> =
3699+
pub const __TEST_FRONTEND_SUS_FEE: ArgOpt<WalletTransferTarget> =
37003700
arg_opt("frontend-sus-fee");
37013701
// WARNING: use only for testing purposes, MASP frontend fees don't make
37023702
// sense when operating from the CLI
@@ -4960,11 +4960,27 @@ pub mod args {
49604960
}
49614961
let mut frontend_sus_fee = vec![];
49624962
for fee in self.frontend_sus_fee {
4963-
frontend_sus_fee.push(TxTransparentTarget {
4964-
target: chain_ctx.get(&fee.target),
4965-
token: chain_ctx.get(&fee.token),
4966-
amount: fee.amount,
4967-
});
4963+
match fee {
4964+
Either::Left(transparent_target) => {
4965+
frontend_sus_fee.push(Either::Left(
4966+
TxTransparentTarget {
4967+
target: chain_ctx
4968+
.get(&transparent_target.target),
4969+
token: chain_ctx.get(&transparent_target.token),
4970+
amount: transparent_target.amount,
4971+
},
4972+
));
4973+
}
4974+
Either::Right(shielded_target) => {
4975+
frontend_sus_fee.push(Either::Right(
4976+
TxShieldedTarget {
4977+
target: chain_ctx.get(&shielded_target.target),
4978+
token: chain_ctx.get(&shielded_target.token),
4979+
amount: shielded_target.amount,
4980+
},
4981+
));
4982+
}
4983+
}
49684984
}
49694985

49704986
Ok(TxShieldingTransfer::<SdkTypes> {
@@ -4986,49 +5002,40 @@ pub mod args {
49865002
let raw_amount = AMOUNT.parse(matches);
49875003
let amount = InputAmount::Unvalidated(raw_amount);
49885004
let tx_code_path = PathBuf::from(TX_TRANSFER_WASM);
5005+
let sources = vec![TxTransparentSource {
5006+
source: source.clone(),
5007+
token: token.clone(),
5008+
amount,
5009+
}];
5010+
let targets = vec![TxShieldedTarget {
5011+
target,
5012+
token: token.clone(),
5013+
amount,
5014+
}];
49895015
let frontend_sus_fee = __TEST_FRONTEND_SUS_FEE
49905016
.parse(matches)
4991-
.map_or(vec![], |target| {
4992-
vec![TxTransparentTarget {
4993-
target,
4994-
token: token.clone(),
4995-
amount: InputAmount::Unvalidated(
4996-
token::DenominatedAmount::new(
4997-
// Take a constant fee of 1 on top of the input
4998-
// amount
4999-
1.into(),
5000-
raw_amount.denom(),
5001-
),
5002-
),
5003-
}]
5004-
});
5005-
5006-
let mut sources = if frontend_sus_fee.is_empty() {
5007-
vec![]
5008-
} else {
5009-
// Adjust the inputs to account for the extra token
5010-
vec![TxTransparentSource {
5011-
source: source.clone(),
5012-
token: token.clone(),
5013-
amount: InputAmount::Unvalidated(
5017+
.map_or(Default::default(), |fee_target| {
5018+
// Take a constant fee of 1 on top of the input amount
5019+
let amount = InputAmount::Unvalidated(
50145020
token::DenominatedAmount::new(
50155021
1.into(),
50165022
raw_amount.denom(),
50175023
),
5018-
),
5019-
}]
5020-
};
5024+
);
50215025

5022-
sources.push(TxTransparentSource {
5023-
source,
5024-
token: token.clone(),
5025-
amount,
5026-
});
5027-
let targets = vec![TxShieldedTarget {
5028-
target,
5029-
token,
5030-
amount,
5031-
}];
5026+
vec![match PaymentAddress::from_str(&fee_target.raw) {
5027+
Ok(_) => Either::Right(TxShieldedTarget {
5028+
target: fee_target.to_payment_address(),
5029+
token: token.clone(),
5030+
amount,
5031+
}),
5032+
Err(_) => Either::Left(TxTransparentTarget {
5033+
target: fee_target.to_address(),
5034+
token,
5035+
amount,
5036+
}),
5037+
}]
5038+
});
50325039

50335040
Self {
50345041
tx,
@@ -5092,6 +5099,31 @@ pub mod args {
50925099
amount: transfer_data.amount,
50935100
});
50945101
}
5102+
5103+
let mut frontend_sus_fee = vec![];
5104+
for fee in self.frontend_sus_fee {
5105+
match fee {
5106+
Either::Left(transparent_target) => {
5107+
frontend_sus_fee.push(Either::Left(
5108+
TxTransparentTarget {
5109+
target: chain_ctx
5110+
.get(&transparent_target.target),
5111+
token: chain_ctx.get(&transparent_target.token),
5112+
amount: transparent_target.amount,
5113+
},
5114+
));
5115+
}
5116+
Either::Right(shielded_target) => {
5117+
frontend_sus_fee.push(Either::Right(
5118+
TxShieldedTarget {
5119+
target: chain_ctx.get(&shielded_target.target),
5120+
token: chain_ctx.get(&shielded_target.token),
5121+
amount: shielded_target.amount,
5122+
},
5123+
));
5124+
}
5125+
}
5126+
}
50955127
let gas_spending_key =
50965128
self.gas_spending_key.map(|key| chain_ctx.get_cached(&key));
50975129

@@ -5101,6 +5133,7 @@ pub mod args {
51015133
gas_spending_key,
51025134
sources,
51035135
tx_code_path: self.tx_code_path.to_path_buf(),
5136+
frontend_sus_fee,
51045137
})
51055138
}
51065139
}
@@ -5114,49 +5147,50 @@ pub mod args {
51145147
let raw_amount = AMOUNT.parse(matches);
51155148
let amount = InputAmount::Unvalidated(raw_amount);
51165149
let tx_code_path = PathBuf::from(TX_TRANSFER_WASM);
5117-
let mut targets = vec![TxTransparentTarget {
5150+
let targets = vec![TxTransparentTarget {
51185151
target: target.clone(),
51195152
token: token.clone(),
51205153
amount,
51215154
}];
5122-
let mut sources = vec![TxShieldedSource {
5155+
let sources = vec![TxShieldedSource {
51235156
source: source.clone(),
51245157
token: token.clone(),
51255158
amount,
51265159
}];
51275160
let gas_spending_key = GAS_SPENDING_KEY.parse(matches);
51285161

5129-
if let Some(fee_target) = __TEST_FRONTEND_SUS_FEE.parse(matches) {
5130-
// Take a constant fee of 1 on top of the input amount
5131-
targets.push(TxTransparentTarget {
5132-
target: fee_target,
5133-
token: token.clone(),
5134-
amount: InputAmount::Unvalidated(
5162+
let frontend_sus_fee = __TEST_FRONTEND_SUS_FEE
5163+
.parse(matches)
5164+
.map_or(Default::default(), |fee_target| {
5165+
// Take a constant fee of 1 on top of the input amount
5166+
let amount = InputAmount::Unvalidated(
51355167
token::DenominatedAmount::new(
51365168
1.into(),
51375169
raw_amount.denom(),
51385170
),
5139-
),
5140-
});
5171+
);
51415172

5142-
sources.push(TxShieldedSource {
5143-
source,
5144-
token,
5145-
amount: InputAmount::Unvalidated(
5146-
token::DenominatedAmount::new(
5147-
1.into(),
5148-
raw_amount.denom(),
5149-
),
5150-
),
5151-
})
5152-
}
5173+
vec![match PaymentAddress::from_str(&fee_target.raw) {
5174+
Ok(_) => Either::Right(TxShieldedTarget {
5175+
target: fee_target.to_payment_address(),
5176+
token: token.clone(),
5177+
amount,
5178+
}),
5179+
Err(_) => Either::Left(TxTransparentTarget {
5180+
target: fee_target.to_address(),
5181+
token,
5182+
amount,
5183+
}),
5184+
}]
5185+
});
51535186

51545187
Self {
51555188
tx,
51565189
sources,
51575190
targets,
51585191
gas_spending_key,
51595192
tx_code_path,
5193+
frontend_sus_fee,
51605194
}
51615195
}
51625196

@@ -5201,12 +5235,22 @@ pub mod args {
52015235
let chain_ctx = ctx.borrow_mut_chain_or_exit();
52025236
let gas_spending_key =
52035237
self.gas_spending_key.map(|key| chain_ctx.get_cached(&key));
5204-
let frontend_sus_fee =
5205-
self.frontend_sus_fee.map(|fee| TxTransparentTarget {
5206-
target: chain_ctx.get(&fee.target),
5207-
token: chain_ctx.get(&fee.token),
5208-
amount: fee.amount,
5209-
});
5238+
let frontend_sus_fee = self.frontend_sus_fee.map(|fee| match fee {
5239+
Either::Left(transparent_target) => {
5240+
Either::Left(TxTransparentTarget {
5241+
target: chain_ctx.get(&transparent_target.target),
5242+
token: chain_ctx.get(&transparent_target.token),
5243+
amount: transparent_target.amount,
5244+
})
5245+
}
5246+
Either::Right(shielded_target) => {
5247+
Either::Right(TxShieldedTarget {
5248+
target: chain_ctx.get(&shielded_target.target),
5249+
token: chain_ctx.get(&shielded_target.token),
5250+
amount: shielded_target.amount,
5251+
})
5252+
}
5253+
});
52105254

52115255
Ok(TxIbcTransfer::<SdkTypes> {
52125256
tx,
@@ -5253,18 +5297,27 @@ pub mod args {
52535297
let gas_spending_key = GAS_SPENDING_KEY.parse(matches);
52545298
let tx_code_path = PathBuf::from(TX_IBC_WASM);
52555299
let frontend_sus_fee =
5256-
__TEST_FRONTEND_SUS_FEE.parse(matches).map(|target|
5257-
// Take a constant fee of 1 on top of the input amount
5258-
TxTransparentTarget {
5259-
target,
5300+
__TEST_FRONTEND_SUS_FEE.parse(matches).map(|fee_target| {
5301+
// Take a constant fee of 1 on top of the input amount
5302+
let amount = InputAmount::Unvalidated(
5303+
token::DenominatedAmount::new(
5304+
1.into(),
5305+
raw_amount.denom(),
5306+
),
5307+
);
5308+
match PaymentAddress::from_str(&fee_target.raw) {
5309+
Ok(_) => Either::Right(TxShieldedTarget {
5310+
target: fee_target.to_payment_address(),
52605311
token: token.clone(),
5261-
amount: InputAmount::Unvalidated(
5262-
token::DenominatedAmount::new(
5263-
1.into(),
5264-
raw_amount.denom(),
5265-
),
5266-
),
5267-
});
5312+
amount,
5313+
}),
5314+
Err(_) => Either::Left(TxTransparentTarget {
5315+
target: fee_target.to_address(),
5316+
token: token.clone(),
5317+
amount,
5318+
}),
5319+
}
5320+
});
52685321

52695322
Self {
52705323
tx,

crates/sdk/src/args.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,10 @@ pub struct TxShieldingTransfer<C: NamadaTypes = SdkTypes> {
390390
/// Transfer source data
391391
pub sources: Vec<TxTransparentSource<C>>,
392392
/// The optional data for the frontend sustainability fee
393-
pub frontend_sus_fee: Vec<TxTransparentTarget<C>>,
393+
// FIXME: should join this with sources? No maybe better to define a single
394+
// percentage to apply to all inputs and a single receiver
395+
pub frontend_sus_fee:
396+
Vec<Either<TxTransparentTarget<C>, TxShieldedTarget<C>>>,
394397
/// Path to the TX WASM code file
395398
pub tx_code_path: PathBuf,
396399
}
@@ -436,11 +439,13 @@ pub struct TxUnshieldingTransfer<C: NamadaTypes = SdkTypes> {
436439
pub tx: Tx<C>,
437440
/// Transfer source data
438441
pub sources: Vec<TxShieldedSource<C>>,
439-
/// Transfer target data (potentially also carries data for the frontend
440-
/// sustainability fee)
442+
/// Transfer target data
441443
pub targets: Vec<TxTransparentTarget<C>>,
442444
/// Optional additional key for gas payment
443445
pub gas_spending_key: Option<C::SpendingKey>,
446+
/// The optional data for the frontend sustainability fee
447+
pub frontend_sus_fee:
448+
Vec<Either<TxTransparentTarget<C>, TxShieldedTarget<C>>>,
444449
/// Path to the TX WASM code file
445450
pub tx_code_path: PathBuf,
446451
}
@@ -829,7 +834,8 @@ pub struct TxIbcTransfer<C: NamadaTypes = SdkTypes> {
829834
/// Optional additional keys for gas payment
830835
pub gas_spending_key: Option<C::SpendingKey>,
831836
/// The optional data for the frontend sustainability fee
832-
pub frontend_sus_fee: Option<TxTransparentTarget<C>>,
837+
pub frontend_sus_fee:
838+
Option<Either<TxTransparentTarget<C>, TxShieldedTarget<C>>>,
833839
/// Path to the TX WASM code file
834840
pub tx_code_path: PathBuf,
835841
}

crates/sdk/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ pub trait Namada: NamadaIo {
191191
&self,
192192
targets: Vec<args::TxShieldedTarget>,
193193
sources: Vec<args::TxTransparentSource>,
194-
frontend_sus_fee: Vec<args::TxTransparentTarget>,
194+
frontend_sus_fee: Vec<
195+
either::Either<args::TxTransparentTarget, args::TxShieldedTarget>,
196+
>,
195197
) -> args::TxShieldingTransfer {
196198
args::TxShieldingTransfer {
197199
sources,
@@ -209,13 +211,17 @@ pub trait Namada: NamadaIo {
209211
sources: Vec<args::TxShieldedSource>,
210212
targets: Vec<args::TxTransparentTarget>,
211213
gas_spending_key: Option<PseudoExtendedKey>,
214+
frontend_sus_fee: Vec<
215+
either::Either<args::TxTransparentTarget, args::TxShieldedTarget>,
216+
>,
212217
) -> args::TxUnshieldingTransfer {
213218
args::TxUnshieldingTransfer {
214219
sources,
215220
targets,
216221
gas_spending_key,
217222
tx_code_path: PathBuf::from(TX_TRANSFER_WASM),
218223
tx: self.tx_builder(),
224+
frontend_sus_fee,
219225
}
220226
}
221227

@@ -303,7 +309,9 @@ pub trait Namada: NamadaIo {
303309
token: Address,
304310
amount: InputAmount,
305311
channel_id: ChannelId,
306-
frontend_sus_fee: Option<args::TxTransparentTarget>,
312+
frontend_sus_fee: Option<
313+
either::Either<args::TxTransparentTarget, args::TxShieldedTarget>,
314+
>,
307315
) -> args::TxIbcTransfer {
308316
args::TxIbcTransfer {
309317
source,

0 commit comments

Comments
 (0)