# Ğcli: Un client GVA en ligne de commande écrit en Rust

**URL:** https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818
**Category:** Ğ1cli
**Tags:** rust, gva
**Created:** [4 December 2020 21:39 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818 "2020-12-04T21:39:41Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [4 December 2020 21:39 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/1 "2020-12-04T21:39:41Z")

</div>

C’est frustrant d’être toujours uniquement coté serveur.

Si j’avais plus de temps j’aurais beaucoup aimé développer un client Ğ1 complet en Rust, mais je ne pourrais pas, car j’ai déjà beaucoup trop de travail coté Duniter 😕

Alors dans l’espoir que quelqu’un développera un jour un client en Rust, j’ai pris une petite heure pour développer ce prototype :

> **[clients / Rust / gva-rust-client](https://git.duniter.org/clients/rust/gcli)**
>
> A simple command line client written in Rust that use Duniter GVA API.

J’espère que ce prototype en inspirera certains, en tout cas je suis dispo pour en expliquer le code à qui veut 😃

J’ai utilisé la crate [**graphql\_client**](https://github.com/graphql-rust/graphql-client) qui permet de vérifier **à la compilation** la validité de chaque requête graphql, et de générer automatiquement le typage des variables et de la réponse !!

Les requêtes sont écrites directement en language graphql dans le fichier [**gva\_queries.gql**](https://git.duniter.org/clients/rust/gva-rust-client/-/blob/master/gql/gva_queries.gql).

Les options cli permettent déjà de choisir son serveur GVA, et de demander le DU courant et le solde d’un compte :

```
rust-gva-client 0.1.0
Client use GVA API of Duniter.

USAGE:
    gva-rust-client [OPTIONS] <SUBCOMMAND>

FLAGS:
    -h, --help Prints help information
    -V, --version Prints version information

OPTIONS:
    -s, --server <server> GVA server url [default: https://g1.librelois.fr/gva]

SUBCOMMANDS:
    balance Get account balance
    current-ud Get current UD value
    help Prints this message or the help of the given subcommand(s)

```

Ça m’a permis également de mesurer le temps que met mon serveur GVA pour répondre :

```
$ cargo run current-ud
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/gva-rust-client current-ud`
The server responded in 225 ms.
The current UD value is 10.23 Ğ1 !

```

C’était rafraîchissant en tout cas, ça fait du bien de coder un truc simple pour une fois 😊

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [4 December 2020 23:33 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/2 "2020-12-04T23:33:52Z")

</div>

Je pourrais peut-être m’y pencher, j’ai déjà codé quelques fonction clientes de GVA avec `graphql_client` et `reqwest` dans ĞMixer (demander les sources, l’historique, envoyer une tx).

---

<div class="post-metadata">

### Author: ![vit](https://forum.duniter.org/user_avatar/forum.duniter.org/vit/32/2775_2.png) [@vit](https://forum.duniter.org/u/vit)
#### Post date: [5 December 2020 13:39 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/3 "2020-12-05T13:39:03Z")

</div>

C’est marrant que tu dises ça, parce que moi c’est l’inverse ! 😁

J’en ai un peu marre de coder côté client, à cause des limitations de l’api, entre autres. Et te sachant seul côté serveur, je pensais à essayer de voir si je pouvais me mettre au Rust pour aider au développement de GVA et pourquoi pas, bien plus tard, du cœur. Mais bon, j’ai trop de projets en cours, à voir si j’arrive à ajouter l’apprentissage du Rust en plus, ou pas… 😉

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [5 December 2020 14:37 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/4 "2020-12-05T14:37:40Z")

</div>

> [@vit](#):
>
> Et te sachant seul côté serveur, je pensais à essayer de voir si je pouvais me mettre au Rust pour aider au développement de GVA

Justement je serai bientôt enfin prêt à accueillir des contributeurs sur Duniter, mais sur GVA uniquement, car c’est la seule partie suffisamment balisée et simple pour que je puisse accompagner dessus.

Si d’autres contributeurs arrivent à prendre en main le dev de GVA ça me permettrait de me concentrer sur les nombreux autres gros chantier de Duniter.

Alors évidemment je me rendrais dispo pour de l’accompagnement renforcé et des revus de code, surtout au début. L’idée est d’accompagner fortement au début puis de moins en moins au fur et à mesure 🙂

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [17 December 2020 16:52 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/5 "2020-12-17T16:52:53Z")

</div>

Pour m’essayer un peu sur ce projet, j’ai réalisé [une MR](https://git.duniter.org/clients/rust/gva-rust-client/-/merge_requests/1) pour ajouter une requête sur le nombre de membres. J’ai quelques remarques et questions :

1. Les macros `#[derive(GraphQLQuery)]` et `#[graphql(schema_path, query_path)]` sont très pratiques, mais il est un peu difficile de savoir les noms des structs et enums générés. Où est-ce documenté ?
2. Le schéma est défini en format `.gql`, ce qui ne fait pas partie des formats proposés par [https://g1.librelois.fr/gva](https://g1.librelois.fr/gva). Comment est-ce qu’on obtient ce format ? (pour l’instant j’ai ajouté une entrée manuellement, mais je suppose qu’il y a une manière automatique de faire)
3. Pourquoi le schéma utilisé est-il légèrement différent de celui disponible sur ton interface web? Par exemple, dans le QueryRoot, il manque la ligne currentBlock sur le client. (c’est celle que j’ai ajouté)

En tout cas, joli travail, GVA va nous simplifier la vie à tous, j’espère que l’on pourra accueillir des contributeurs sérieux sur ce chantier !

```auto
hugo@squid:~/dev/gva-rust-client$ ./target/debug/gcli members-count
The server responded in 523 ms.
There is currently 2876 members in Ğ1 WoT!

```

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [17 December 2020 18:14 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/6 "2020-12-17T18:14:55Z")

</div>

> [@HugoTrentesaux](#):
>
> Les macros `#[derive(GraphQLQuery)]` et `#[graphql(schema_path, query_path)]` sont très pratiques, mais il est un peu difficile de savoir les noms des structs et enums générés. Où est-ce documenté ?

> **[graphql\_client - Rust](https://docs.rs/graphql_client/latest/graphql_client/)**
>
> The top-level documentation resides on the project README at the moment.

> [@HugoTrentesaux](#):
>
> Le schéma est défini en format `.gql`, ce qui ne fait pas partie des formats proposés par [https://g1.librelois.fr/gva](https://g1.librelois.fr/gva). Comment est-ce qu’on obtient ce format ? (pour l’instant j’ai ajouté une entrée manuellement, mais je suppose qu’il y a une manière automatique de faire)

Alors en fait le schéma est au format SDL (Schéma Description Langage).  
Oui il est généré automatiquement à partir du code de GVA 🙂

> [@HugoTrentesaux](#):
>
> Pourquoi le schéma utilisé est-il légèrement différent de celui disponible sur ton interface web? Par exemple, dans le QueryRoot, il manque la ligne currentBlock sur le client. (c’est celle que j’ai ajouté)

Parce qu’il n’est pas à jour à cause de Cargo.lock, pour maj le scéma :

```
cargo update -p duniter-gva-gql

```

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [17 December 2020 19:20 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/7 "2020-12-17T19:20:47Z")

</div>

Je viens de baptiser le projet ğcli 😃

Je ne pourrais pas y consacrer du temps significatif, mais j’y ajouterai une commande de temps en temps selon mes besoins et mes envies.

Et j’invite bien sur tous ceux qu le souhaitent à y implémenter les commandes dont ils ont besoin, c’est un client collaboratif 😊

Je peux former @HugoTrentesaux, @tuxmain et qui veut sur ğcli, c’est un petit projet très simple 🙂

Tout ce que je demande c’est que toute nouvelle commande soit obligatoirement testée !

«Si c’est pas testé, c’est pas mergé». Et ce sera vrai aussi pour ceux qui voudraient contribuer à GVA 😉

Ce projet n’a pas d’objectif particulier, il permettra ce que ses contributeurs en feront.

---

<div class="post-metadata">

### Author: ![Candidesk8](https://forum.duniter.org/user_avatar/forum.duniter.org/candidesk8/32/1461_2.png) [@Candidesk8](https://forum.duniter.org/u/Candidesk8)
#### Post date: [17 December 2020 19:56 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/8 "2020-12-17T19:56:58Z")

</div>

Liberté, ğcli ton nom !

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [18 December 2020 11:16 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/9 "2020-12-18T11:16:51Z")

</div>

J’ai commencé à faire une commande pour afficher l’historique des transactions.

Je ne sais pas encore comment intégrer la pagination dans l’interface, c’est peu pratique de recopier le curseur dans la commande pour chaque page. Sinon un truc interactif qui avance d’une page à l’appui d’une touche ?

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [18 December 2020 13:56 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/10 "2020-12-18T13:56:01Z")

</div>

> [@tuxmain](#):
>
> Sinon un truc interactif qui avance d’une page à l’appui d’une touche ?

Oui par exemple 🙂

EDIT: Pour la gestion interactive du terminal je te recommande [**termion**](https://crates.io/crates/termion).

Le mieux est de pouvoir permettre aussi le retour à la page précédente 🙂

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [18 December 2020 21:53 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/11 "2020-12-18T21:53:37Z")

</div>

En fait l’affichage des transactions est très complexe, on ne peut pas se contenter d’écrire «&nbsp;X : envoyé/reçu Y Ğ1&nbsp;», il faut gérer les conditions et les cas où on s’envoie à soi-même…

Une même transaction peut-elle apparaître à la fois dans sent et dans received dans GVA et BMA ? Comment Duniter choisit ?

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [18 December 2020 22:01 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/12 "2020-12-18T22:01:13Z")

</div>

> [@tuxmain](#):
>
> Une même transaction peut-elle apparaître à la fois dans sent et dans received dans GVA et BMA ?  
> Comment Duniter choisit ?

Non elle ne peut pas, un compte est inscrit comme `receiver` uniquement s’il n’est pas `issuer`, c’est fait ici :

> **[Files · dev · nodes / typescript / duniter · GitLab](https://git.duniter.org/nodes/typescript/duniter/-/tree/dev)**
>
> Crypto-currency software to operate Ğ1 libre currency

Dans Duniter 1.9, le code javascript qui fourni l’historique des transactions n’existe plus, il a été migré en Rust. Donc BMA se base sur ce même code Rust donc elle fournit les mêmes données que GVA.

EDIT: cela implique notamment qu’une transaction de change n’a pas de destinataire, ce qui est cohérent 🙂

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [19 December 2020 17:16 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/13 "2020-12-19T17:16:25Z")

</div>

> [@tuxmain](#):
>
> Une même transaction peut-elle apparaître à la fois dans sent et dans received dans GVA

@tuxmain attention il faut que tu utilises `both` et pas `sent` ou `received` !

En effet supposons que tu veuilles afficher les 10 dernières transactions d’un compte.  
Tu ne peux pas prendre les 5 dernières émises et les 5 dernières reçues ça ne fonctionne pas.  
Un compte peut très bien avoir émis 8 transactions sur les 10 dernières et reçus 2, et vice-versa, où n’importe quelle proportion entre les deux.

Il faut donc fusionner les transactions émises et reçus dans ure seule liste, la triée par date d’écriture, puis tronquer à la taille de la page voulue. C’est exactement ce que fait `both` coté serveur pour vous éviter d’avoir à coder cette logique côté client !

---

<div class="post-metadata">

### Author: ![poka](https://forum.duniter.org/user_avatar/forum.duniter.org/poka/32/6827_2.png) [@poka](https://forum.duniter.org/u/poka)
#### Post date: [19 December 2020 17:54 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/14 "2020-12-19T17:54:13Z")

</div>

Oui c’est ce que j’ai fait sur Ḡecko et jaklis, pourquoi ne pas avoir fait ça aussi pour les transcations en mempool ? Un both ? C’est moins utile peut être ?

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [19 December 2020 17:58 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/15 "2020-12-19T17:58:57Z")

</div>

> [@poka](#):
>
> pourquoi ne pas avoir fait ça aussi pour les transcations en mempool ? Un both ?

Il n’y a aucune raison, je n’y ai juste pas pensé, car c’est surtout pour la pagination que j’ai pensé `both`. Un contributeur pourra rajouter ça à GVA si c’est souhaité 🙂

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [20 December 2020 13:12 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/16 "2020-12-20T13:12:22Z")

</div>

3 messages ont été scindés en un nouveau sujet : [Comment faut-il afficher les transactions complexes?](https://forum.duniter.org/t/comment-faut-il-afficher-les-transactions-complexes/7885)

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [21 December 2020 14:42 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/17 "2020-12-21T14:42:29Z")

</div>

Pour le moment j’ai ça&nbsp;:

```auto
2020-10-17T08:16:16+00:00 #365512
8AURKq5gWeESdPzgqL2fJYFoJv89X2wiSsWbx8Am2W3w + 2 Ğ1 Commentaire

2020-10-17T12:24:07+00:00 #365694
SIG(9oca3YvBuJBYdK5tdJESbT4tPVfxkDBtjGetU8jnkRpp) - 204.6 Ğ1 Commentaire
SIG(45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ) - 123 Ğ1
Total: 317.6 Ğ1

```

Pour les txs reçues on affiche la liste des issuers.

Pour les txs envoyées on affiche la liste des scripts d’outputs. On ignore les outputs `SIG(issuer)`. Les txs de change apparaissent donc vides. S’il y a plusieurs outputs, on affiche le total en bas.

Le commentaire est écrit à la fin de la première ligne d’outputs/issuers. Il y a une option pour afficher en DU.

Est-ce que vous préféreriez une forme tabulaire, comme dans Silkaj ? On pourrait aussi mettre des couleurs (rouge/vert pour dépense/gain, gris pour le numéro de bloc). Ou aussi afficher conjointement Ğ1 et DU.

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [21 December 2020 15:26 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/18 "2020-12-21T15:26:14Z")

</div>

Merci @tuxmain 🙂

Puisque tu demandes des avis, voici le mien :

A titre perso je préférerai un tableau avec une vue condensée sur une ligne pour chaque tx. Et une possibilité de voir plus en détail une seule tx si on en a besoin 🙂

---

<div class="post-metadata">

### Author: ![poka](https://forum.duniter.org/user_avatar/forum.duniter.org/poka/32/6827_2.png) [@poka](https://forum.duniter.org/u/poka)
#### Post date: [22 December 2020 01:12 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/19 "2020-12-22T01:12:05Z")

</div>

@tuxmain j’ai hâte que tu intègres la gestion de la pagination de l’historique à ḡcli, parce-que dans Ḡecko j’ai des artefacts étrange au bout de plusieurs pages, je voudrais être sûr que le soucis ne vient pas de GVA …

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [22 December 2020 10:21 UTC](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818/20 "2020-12-22T10:21:04Z")

</div>

@tuxmain je viens d’ajouter les conventions du projet dans CONTRIBUTING 🙂

Le plus important est surtout de bien découpler l’affichage de la logique en créant un type `AccountHistoryView` qui contiendra toutes les données à afficher et un type `AccountHistoryState` qui contiendra «l’état» courant de l’application.

L’idée étant que les actions utilisateur (appui sur urne touche) mettent à jour le State uniquement. Puis que séparément, le State met à jour la View.

Ainsi tu peux injecter la logique dans des fonctions pure, donc testable 🙂

Aussi pense bien à découper en plusieurs fichiers. Prends de temps de faire un code lisible, ça ne sert à rien de se presser 😉

[Next page](https://forum.duniter.org/t/gcli-un-client-gva-en-ligne-de-commande-ecrit-en-rust/7818.md?page=2)
