diff --git a/Cargo.lock b/Cargo.lock
index 62fcd0501d66723f7b0ff836208fce95d19f648c..b5b2550d8e0a38ae975f0e3b1d98c7a54e2db300 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1131,6 +1131,7 @@ name = "duniter-gva"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "arrayvec",
  "async-graphql",
  "async-trait",
  "dubp",
@@ -1147,7 +1148,6 @@ dependencies = [
  "resiter",
  "serde",
  "serde_urlencoded 0.7.0",
- "smallvec",
  "tokio",
  "unwrap",
  "warp",
diff --git a/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs b/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs
index bcdd0a333bf886faad345144b87b9f01316459fe..8bdef91f8c4096f148659a21199e68157669a24f 100644
--- a/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs
+++ b/rust-libs/duniter-dbs-read-ops/src/find_inputs.rs
@@ -22,7 +22,6 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
     txs_mp_db: &TxsMpDb,
     amount: SourceAmount,
     script: &WalletScriptV10,
-    max_inputs_count: usize,
 ) -> KvResult<(BlockMetaV2, Vec<TransactionInputV10>, SourceAmount)> {
     if let Some(current_block) = crate::get_current_block_meta(bc_db)? {
         let (mut inputs, uds_sum) = if script.nodes.is_empty() {
@@ -38,7 +37,6 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
                     issuer,
                     ..,
                     Some(&pending_uds_bn),
-                    Some(max_inputs_count),
                     Some(amount),
                 )?;
                 let inputs = uds
@@ -59,13 +57,8 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
             (vec![], SourceAmount::ZERO)
         };
         if uds_sum < amount {
-            let (utxos, utxos_sum) = crate::utxos::find_script_utxos(
-                gva_db,
-                txs_mp_db,
-                amount - uds_sum,
-                max_inputs_count - inputs.len(),
-                &script,
-            )?;
+            let (utxos, utxos_sum) =
+                crate::utxos::find_script_utxos(gva_db, txs_mp_db, amount - uds_sum, &script)?;
             inputs.extend(
                 utxos
                     .into_iter()
@@ -76,17 +69,9 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
                         },
                     ),
             );
-            let inputs_sum = uds_sum + utxos_sum;
-            if inputs_sum < amount {
-                Err(KvError::Custom(
-                    "Amount need too many sources or issuer's account has an insufficient balance."
-                        .into(),
-                ))
-            } else {
-                Ok::<_, KvError>((current_block, inputs, inputs_sum))
-            }
+            Ok((current_block, inputs, uds_sum + utxos_sum))
         } else {
-            Ok::<_, KvError>((current_block, inputs, uds_sum))
+            Ok((current_block, inputs, uds_sum))
         }
     } else {
         Err(KvError::Custom("no blockchain".into()))
@@ -156,7 +141,6 @@ mod tests {
             &txs_mp_db,
             SourceAmount::with_base0(55),
             &script,
-            2,
         )?;
         assert_eq!(cb, b0);
         assert_eq!(inputs.len(), 2);
@@ -177,7 +161,6 @@ mod tests {
             &txs_mp_db,
             SourceAmount::with_base0(55),
             &script,
-            2,
         )?;
         assert_eq!(cb, b0);
         assert_eq!(inputs.len(), 1);
diff --git a/rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs b/rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs
index 4d5f8ccf97fd10e5f9db54e1af6c0f01827e1ca1..2afc04f696ee20d8201f58de2c88ed4f4ae15b6f 100644
--- a/rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs
+++ b/rust-libs/duniter-dbs-read-ops/src/uds_of_pubkey.rs
@@ -22,7 +22,6 @@ pub fn uds_of_pubkey<BcDb: BcV2DbReadable, R: 'static + RangeBounds<BlockNumber>
     pubkey: PublicKey,
     range: R,
     bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>,
-    limit_opt: Option<usize>,
     total_opt: Option<SourceAmount>,
 ) -> KvResult<(Vec<(BlockNumber, SourceAmount)>, SourceAmount)> {
     let start = match range.start_bound() {
@@ -42,7 +41,7 @@ pub fn uds_of_pubkey<BcDb: BcV2DbReadable, R: 'static + RangeBounds<BlockNumber>
                 .collect::<KvResult<Vec<_>>>()
         })?;
         if blocks_numbers.is_empty() {
-            Ok((vec![], SourceAmount::ZERO))
+            Ok((Vec::default(), SourceAmount::ZERO))
         } else {
             let first_reval = uds_reval
                 .iter(..=U32BE(blocks_numbers[0].0), |it| {
@@ -57,27 +56,29 @@ pub fn uds_of_pubkey<BcDb: BcV2DbReadable, R: 'static + RangeBounds<BlockNumber>
                     true
                 }
             });
-            if let Some(limit) = limit_opt {
-                collect_uds(
-                    blocks_numbers.take(limit),
-                    blocks_numbers_len,
-                    first_reval,
-                    uds_reval,
-                    total_opt,
-                )
-            } else {
-                collect_uds(
-                    blocks_numbers,
-                    blocks_numbers_len,
-                    first_reval,
-                    uds_reval,
-                    total_opt,
-                )
-            }
+            collect_uds(
+                blocks_numbers,
+                blocks_numbers_len,
+                first_reval,
+                uds_reval,
+                total_opt,
+            )
         }
     })
 }
 
+macro_rules! collect_one_ud {
+    ($block_number:ident, $current_ud:ident, $uds:ident, $sum:ident, $amount_target_opt:ident) => {
+        $uds.push(($block_number, $current_ud));
+        $sum = $sum + $current_ud;
+        if let Some(amount_target) = $amount_target_opt {
+            if $sum >= amount_target {
+                return Ok(($uds, $sum));
+            }
+        }
+    };
+}
+
 fn collect_uds<BC: BackendCol, I: Iterator<Item = BlockNumber>>(
     mut blocks_numbers: I,
     blocks_numbers_len: usize,
@@ -88,7 +89,7 @@ fn collect_uds<BC: BackendCol, I: Iterator<Item = BlockNumber>>(
     let uds_revals = uds_reval.iter(first_reval.., |it| it.collect::<KvResult<Vec<_>>>())?;
 
     if uds_revals.is_empty() {
-        Ok((vec![], SourceAmount::ZERO))
+        Ok((Vec::default(), SourceAmount::ZERO))
     } else {
         let mut current_ud = (uds_revals[0].1).0;
         let mut uds = Vec::with_capacity(blocks_numbers_len);
@@ -99,37 +100,63 @@ fn collect_uds<BC: BackendCol, I: Iterator<Item = BlockNumber>>(
             'blocks_numbers: while let Some(block_number) = blocks_numbers.next() {
                 if block_number.0 >= block_reval.0 {
                     current_ud = amount_reval.0;
-                    uds.push((block_number, current_ud));
-                    sum = sum + current_ud;
-                    if let Some(amount_target) = amount_opt {
-                        if sum >= amount_target {
-                            return Ok((uds, sum));
-                        }
-                    }
+                    collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
                     break 'blocks_numbers;
                 } else {
-                    uds.push((block_number, current_ud));
-                    sum = sum + current_ud;
-                    if let Some(amount_target) = amount_opt {
-                        if sum >= amount_target {
-                            return Ok((uds, sum));
-                        }
-                    }
+                    collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
                 }
             }
         }
 
         // Uds after last reval
         for block_number in blocks_numbers {
-            uds.push((block_number, current_ud));
-            sum = sum + current_ud;
-            if let Some(amount_target) = amount_opt {
-                if sum >= amount_target {
-                    return Ok((uds, sum));
-                }
-            }
+            collect_one_ud!(block_number, current_ud, uds, sum, amount_opt);
         }
 
         Ok((uds, sum))
     }
 }
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use duniter_dbs::{bc_v2::BcV2DbWritable, SourceAmountValV2, UdIdV2};
+
+    #[test]
+    fn test_uds_of_pubkey() -> KvResult<()> {
+        let bc_db = duniter_dbs::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
+
+        let pk = PublicKey::default();
+
+        bc_db
+            .uds_reval_write()
+            .upsert(U32BE(0), SourceAmountValV2(SourceAmount::with_base0(10)))?;
+        bc_db
+            .uds_reval_write()
+            .upsert(U32BE(40), SourceAmountValV2(SourceAmount::with_base0(12)))?;
+
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(0)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(10)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(20)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(30)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(40)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(50)), ())?;
+        bc_db.uds_write().upsert(UdIdV2(pk, BlockNumber(60)), ())?;
+
+        // Get all uds
+        let (uds, uds_sum) = uds_of_pubkey(&bc_db, pk, .., None, None)?;
+        assert_eq!(uds.len(), 7);
+        assert_eq!(
+            uds.first(),
+            Some(&(BlockNumber(0), SourceAmount::with_base0(10)))
+        );
+        assert_eq!(
+            uds.last(),
+            Some(&(BlockNumber(60), SourceAmount::with_base0(12)))
+        );
+        assert_eq!(uds_sum, SourceAmount::with_base0(76));
+
+        Ok(())
+    }
+}
diff --git a/rust-libs/duniter-dbs-read-ops/src/utxos.rs b/rust-libs/duniter-dbs-read-ops/src/utxos.rs
index d77f6d60097de7711b05c60483aa0a0587a81343..2b12831383cc7ca9e2395861be70f4d0a40ec844 100644
--- a/rust-libs/duniter-dbs-read-ops/src/utxos.rs
+++ b/rust-libs/duniter-dbs-read-ops/src/utxos.rs
@@ -25,7 +25,7 @@ pub fn get_script_utxos<GvaDb: GvaV1DbReadable>(
     script: &WalletScriptV10,
 ) -> KvResult<(Vec<UtxoV10>, SourceAmount)> {
     find_script_utxos_inner::<_, duniter_dbs::txs_mp_v2::TxsMpV2DbRo<Mem>>(
-        gva_db_ro, None, script, None, None,
+        gva_db_ro, None, script, None,
     )
 }
 
@@ -33,30 +33,21 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
     gva_db_ro: &GvaDb,
     txs_mp_db_ro: &TxsMpDb,
     amount: SourceAmount,
-    limit: usize,
     script: &WalletScriptV10,
 ) -> KvResult<(Vec<UtxoV10>, SourceAmount)> {
-    find_script_utxos_inner(
-        gva_db_ro,
-        Some(txs_mp_db_ro),
-        script,
-        Some(limit),
-        Some(amount),
-    )
+    find_script_utxos_inner(gva_db_ro, Some(txs_mp_db_ro), script, Some(amount))
 }
 
 fn find_script_utxos_inner<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
     gva_db_ro: &GvaDb,
     txs_mp_db_ro: Option<&TxsMpDb>,
     script: &WalletScriptV10,
-    limit_opt: Option<usize>,
     total_opt: Option<SourceAmount>,
 ) -> KvResult<(Vec<UtxoV10>, SourceAmount)> {
     if let Some(utxos_of_script) = gva_db_ro
         .utxos_by_script()
         .get(&WalletConditionsV2::from_ref(script))?
     {
-        let mut count = 0;
         let mut total = SourceAmount::ZERO;
         let mut utxos: Vec<(i64, UtxoIdV10, SourceAmount)> =
             Vec::with_capacity(utxos_of_script.0.len() * 2);
@@ -73,12 +64,6 @@ fn find_script_utxos_inner<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
                 {
                     utxos.push((written_time, utxo_id, source_amount));
                     total = total + source_amount;
-                    if let Some(limit) = limit_opt {
-                        count += 1;
-                        if count == limit {
-                            return Ok((utxos, total));
-                        }
-                    }
                     if let Some(total_target) = total_opt {
                         if total >= total_target {
                             return Ok((utxos, total));
diff --git a/rust-libs/modules/duniter-gva/Cargo.toml b/rust-libs/modules/duniter-gva/Cargo.toml
index 7d252b7d1153292323daadb92806095a2f268f97..015bdf8d4b32310dac0017c3c887d0b17cbf91ef 100644
--- a/rust-libs/modules/duniter-gva/Cargo.toml
+++ b/rust-libs/modules/duniter-gva/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2018"
 
 [dependencies]
 anyhow = "1.0.33"
+arrayvec = "0.5.1"
 async-graphql = "2.0.0"
 async-trait = "0.1.41"
 dubp = { version = "0.31.0" }
@@ -23,7 +24,6 @@ log = "0.4.11"
 resiter = "0.4.0"
 serde = { version = "1.0.105", features = ["derive"] }
 serde_urlencoded = "0.7.0"
-smallvec = { version = "1.4.0", features = ["serde", "write"] }
 tokio = { version = "0.2.22", features = ["io-util", "rt-threaded"] }
 warp = "0.2"
 
diff --git a/rust-libs/modules/duniter-gva/src/lib.rs b/rust-libs/modules/duniter-gva/src/lib.rs
index e680ee61689e22b1b7923ec21759363a468b8de2..a40daf97d9d7bb4f435029576aa64490297ead7f 100644
--- a/rust-libs/modules/duniter-gva/src/lib.rs
+++ b/rust-libs/modules/duniter-gva/src/lib.rs
@@ -41,10 +41,7 @@ use async_graphql::http::GraphQLPlaygroundConfig;
 use dubp::common::crypto::keys::{ed25519::PublicKey, KeyPair as _, PublicKey as _};
 use dubp::common::prelude::*;
 use dubp::documents::prelude::*;
-use dubp::documents::transaction::{
-    TransactionDocumentTrait, TransactionDocumentV10, TransactionDocumentV10Builder,
-    TransactionInputUnlocksV10, TransactionInputV10, TransactionOutputV10, UTXOConditions,
-};
+use dubp::documents::transaction::{TransactionDocumentTrait, TransactionDocumentV10};
 use dubp::documents_parser::prelude::*;
 use dubp::wallet::prelude::*;
 use duniter_dbs::prelude::*;
@@ -52,7 +49,6 @@ use duniter_dbs::{kv_typed::prelude::*, TxDbV2, TxsMpV2DbReadable};
 use duniter_mempools::{Mempools, TxsMempool};
 use futures::{StreamExt, TryStreamExt};
 use resiter::map::Map;
-use smallvec::smallvec as svec;
 use std::convert::Infallible;
 use std::ops::Deref;
 use warp::{http::Response as HttpResponse, Filter as _, Rejection, Stream};
diff --git a/rust-libs/modules/duniter-gva/src/queries/gen_txs.rs b/rust-libs/modules/duniter-gva/src/queries/gen_txs.rs
index df736ad0fe539d78be7c39d24f7cc2d86f196ee7..515aa170cf3451e3995730e013ac6aa0bb24dd02 100644
--- a/rust-libs/modules/duniter-gva/src/queries/gen_txs.rs
+++ b/rust-libs/modules/duniter-gva/src/queries/gen_txs.rs
@@ -15,6 +15,8 @@
 
 use crate::*;
 
+const MAX_INPUTS_PER_TX: usize = 40;
+
 #[derive(Default)]
 pub(crate) struct GenTxsQuery;
 #[async_graphql::Object]
@@ -48,75 +50,27 @@ impl GenTxsQuery {
                     &dbs.txs_mp_db,
                     amount,
                     &WalletScriptV10::single(WalletConditionV10::Sig(issuer)),
-                    40,
                 )
             })
             .await??;
 
+        if inputs_sum < amount {
+            return Err(async_graphql::Error::new("insufficient balance"));
+        }
+
         let current_blockstamp = Blockstamp {
             number: BlockNumber(current_block.number),
             hash: BlockHash(current_block.hash),
         };
 
-        Ok(vec![gen_tx_with_inputs(
-            amount,
+        Ok(TransactionDocumentV10::generate_simple_txs(
             current_blockstamp,
-            comment,
             currency,
             (inputs, inputs_sum),
+            MAX_INPUTS_PER_TX,
             issuer,
             recipient,
-        )])
-    }
-}
-
-fn gen_tx_with_inputs(
-    amount: SourceAmount,
-    blockstamp: Blockstamp,
-    comment: String,
-    currency: String,
-    inputs_with_sum: (Vec<TransactionInputV10>, SourceAmount),
-    issuer: PublicKey,
-    recipient: PublicKey,
-) -> String {
-    let (inputs, inputs_sum) = inputs_with_sum;
-    let inputs_len = inputs.len();
-    let unlocks = (0..inputs_len)
-        .into_iter()
-        .map(TransactionInputUnlocksV10::single_index)
-        .collect::<Vec<_>>();
-
-    let rest = inputs_sum - amount;
-    let main_output = TransactionOutputV10 {
-        amount,
-        conditions: UTXOConditions::from(WalletScriptV10::single(WalletConditionV10::Sig(
-            recipient,
-        ))),
-    };
-    let outputs = if rest.amount() > 0 {
-        svec![
-            main_output,
-            TransactionOutputV10 {
-                amount: rest,
-                conditions: UTXOConditions::from(WalletScriptV10::single(WalletConditionV10::Sig(
-                    issuer,
-                ))),
-            },
-        ]
-    } else {
-        svec![main_output]
-    };
-
-    TransactionDocumentV10Builder {
-        currency: &currency,
-        blockstamp,
-        locktime: 0,
-        issuers: svec![issuer],
-        inputs: &inputs,
-        unlocks: &unlocks,
-        outputs,
-        comment: &comment,
-        hash: None,
+            (amount, comment),
+        ))
     }
-    .generate_text()
 }
diff --git a/rust-libs/modules/duniter-gva/src/queries/uds.rs b/rust-libs/modules/duniter-gva/src/queries/uds.rs
index bc36f3b8f688ad7dba026256dca2c1a4ec857931..7cab2002838c19e1422775a411d671e046b9b29e 100644
--- a/rust-libs/modules/duniter-gva/src/queries/uds.rs
+++ b/rust-libs/modules/duniter-gva/src/queries/uds.rs
@@ -55,7 +55,6 @@ impl UdsQuery {
                     ..,
                     None,
                     None,
-                    None,
                 )
             })
             .await??;