Merge request GitLab associée à la proposition: Draft: Resolve "Create a runtime API UniversalDividendApi_account_balances to retrieve total and transferable account balances" (!328) · Merge requests · nodes / rust / Duniter v2S · GitLab
Contexte et problème
Aujourd’hui, la plupart des wallets et applications tierces s’appuient sur un indexeur (par exemple un service GraphQL) pour récupérer la balance d’un compte.
- Pour un utilisateur, savoir « combien de Ğ1 j’ai » est critique : cela doit fonctionner même si l’indexeur est hors-service ou en retard.
- En l’absence d’indexeur, certaines applications peuvent ne pas permettre d’initier un transfert, car elles imposent de connaître d’abord le solde transférable. Or l’utilisateur doit pouvoir initier un transfert sans indexeur.
Proposition
Ajouter une runtime API nommée UniversalDividendApi_account_balances
qui renvoie, pour un AccountId, les champs suivants :
{
/// Total des fonds dont l’utilisateur est propriétaire
total: number,
/// Fonds réellement transférables (inclut les DUs non réclamés, mais exclut le « dépôt d’existence » et les fonds réservés)
transferable: number,
/// Montant total des DUs non-réclamés
unclaim_uds: number
}
Pour rappel, toutes les runtime APIs sont des fonctions « read-only » appelables via RPC avec la méthode state_call(apiName, params)
. La convention substrate pour le nom des runtime API est NameApi_function_name
.
Comme leur nom l’indique, les runtime APIs peuvent être ajoutées ou modifiées uniquement par un changement de runtime ; il n’est pas nécessaire de livrer un nouveau binaire de duniter-v2s.
Exemples d’appel avec curl, Polkadot.js et PAPI
Ces exemples ne fonctionne pas sur la GDev actuelle car le runtime 900 n’inclus pas la MR !328. Pour tester il vous faut une chaine locale avec un runtime qui inclus cette MR.
Curl
RPC_URL="http://127.0.0.1:9933"
HEX_ACCOUNT="0x0123…ef" # Clé publique paddée à 32 octets et encodée en hexadécimal
curl -X POST $RPC_URL \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"state_call",
"params":[
"UniversalDividendApi_account_balances",
"'"${HEX_ACCOUNT}"'"
]
}'
Polkadot.js
import { ApiPromise, WsProvider } from '@polkadot/api';
async function getBalances(ss58) {
const api = await ApiPromise.create({ provider: new WsProvider('ws://127.0.0.1:9944') });
const hex = api.createType('AccountId', ss58).toHex();
const raw = await api.rpc.state.call('UniversalDividendApi_account_balances', hex);
const [ total, transferable, unclaimUds ] = api
.createType('(u64,u64,u64)', raw)
.toJSON();
console.log({ total, transferable, unclaimUds });
}
getBalances('5F3sa2TJAWMqDhXG6jhV4N8ko9E…');
PAPI
import { createClient } from 'polkadot-api';
import { getWsProvider } from 'polkadot-api/ws-provider/web';
async function getBalances(ss58: string) {
const client = createClient(getWsProvider('ws://127.0.0.1:9944'));
const api = client.getTypedApi(gdev);
const { total, transferable, unclaimAmount } =
await api.apis.UniversalDividendApi.accountBalances(ss58);
console.log(total.toString(), transferable.toString(), unclaimAmount.toString());
}
getBalances('5F3sa2TJAWMqDhXG6jhV4N8ko9E…');
Si cela vous donne des idées d’autres runtimes API qui serait utiles pour les wallet et applications, merci de créer un nouveau sujet par runtime API proposée.