g1gate - follow the g1 - extract Cesium+ blockchain cache and display TX for a G1 Wallet

This commit is contained in:
fred 2024-01-04 17:59:40 +01:00
parent 0e7742f75f
commit ca48901bb4
5 changed files with 169 additions and 72 deletions

View File

@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang=""><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Ğ1Gate 🜶 Là où va la Ğ1</title>
<meta name="description" content="Explorez la blockchain Ğ1 de façon visuelle pour découvrir où partent toutes ces Ğ1.">
<link rel="stylesheet" type="text/css" href="g1gate_fichiers/styles.css" title="G1Gate">
</head>
<body>
<header>
<h1>Où va la Ğ1…</h1>
<p id="description">
Explorez la blockchain Ğ1 pour savoir où va la Ğ1.
</p>
</header>
<form method="get" action="#expenses" id="explore">
<p>
<label>
Clef à explorer&nbsp;:<br>
<input type="text" name="pubkey" size="50" value="EA7Dsw39ShZg4SpURsrgMaMqrweJPUFPYHwZA8e92e3D">
</label>
</p>
<p>
<label>
Limite du nombre de transactions&nbsp;:
<input type="number" name="txLimit" value="30" size="5">
</label>
</p>
<p>
<input type="submit" label="Explorer">
</p>
</form>
<section id="expenses"><h2>Dépenses de <q>sasa vava</q></h2><article class="svg-container"><svg viewBox="0,0,1280,720" width="1280" height="720" style="max-width: 100%; height: auto; height: intrinsic;" font-family="sans-serif" font-size="10"><a xlink:href="#Com8rJukCozHZyFao6AheSsfDQdPApxQRnz7QYFf64mm" target="_self" transform="translate(0,0)"><rect fill="#FFC431" fill-opacity="1" width="1242" height="720"></rect><title>4 DU</title><clipPath id="O-378df07a9583b-clip-0"><rect width="1242" height="720"></rect></clipPath><text clip-path="url(https://g1.quest/g1gate/#O-378df07a9583b-clip-0)"><tspan x="3" y="1.4000000000000001em" fill-opacity="0.7">Tortue</tspan></text></a><a xlink:href="#5nHhk6wwHELKPn5zvUYjzK9gN1iT214udKyXg5PFazq3" target="_self" transform="translate(1242,0)"><rect fill="#548AFF" fill-opacity="1" width="38" height="720"></rect><title>1 DU</title><clipPath id="O-378df07a9583b-clip-1"><rect width="38" height="720"></rect></clipPath><text clip-path="url(https://g1.quest/g1gate/#O-378df07a9583b-clip-1)"><tspan x="3" y="1.4000000000000001em" fill-opacity="0.7">No tune</tspan></text></a></svg></article></section>
<footer>
<blockquote>
Follow the money
</blockquote>
</footer>
<script type="module" src="g1gate_fichiers/app.js">
</script>
</body></html>

64
earth/g1gate/index.html Normal file
View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang=""><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Ğ1Gate 🜶 Là où va la Ğ1</title>
<meta name="description" content="Explorez la blockchain Ğ1 de façon visuelle pour découvrir où partent toutes ces Ğ1.">
<link rel="stylesheet" type="text/css" href="index_fichiers/styles.css" title="G1Gate">
</head>
<body>
<header>
<h1>Où va la Ğ1…</h1>
<p id="description">
Explorez la blockchain Ğ1 pour savoir où va la Ğ1.
</p>
</header>
<form method="get" action="#expenses" id="explore">
<p>
<label>
Clef à explorer&nbsp;:<br>
<input type="text" name="pubkey" size="50">
</label>
</p>
<p>
<label>
Limite du nombre de transactions&nbsp;:
<input type="number" name="txLimit" value="200" size="5">
</label>
</p>
<p>
<label>
Depuis&nbsp;:
<input type="date" name="minDate" value="2023-12-04">
</label>
</p>
<p>
<input type="submit" label="Explorer">
</p>
</form>
<section id="expenses">
</section>
<footer>
<blockquote>
Follow the money
</blockquote>
<p>
<a href="https://g1.quest/g1gate/changelog.html">
Journal de bord
</a>
</p>
</footer>
<script type="module" src="index_fichiers/app.js">
</script>
</body></html>

View File

@ -1,6 +1,8 @@
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm"; import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
export const DU = 10.68; export const DU = 10.68;
export const MAX_NB_TX = 30; export const MAX_NB_TX = 200;
let txLimit = MAX_NB_TX;
let minTime = null;
export const CESIUM_G1_NODES = [ export const CESIUM_G1_NODES = [
"https://g1.data.brussels.ovh", "https://g1.data.brussels.ovh",
@ -185,29 +187,45 @@ export const G12DU = (amount) => {
}; };
export const query__expenses = (walletPk, size = 100) => { export const query__expenses = (walletPk, minTime, size = MAX_NB_TX) => {
return { return {
_source: ["amount", "recipient"] _source: ["amount", "recipient"]
,sort: [
{
"medianTime": "desc"
}
]
,size: size ,size: size
,query: { ,query: {
bool: { bool: {
filter: [ filter: [
{term: {"issuer": walletPk}} {
range: {
"medianTime": {
gte: minTime
}
}
}
,{
term: {
"issuer": walletPk
}
}
] ]
} }
} }
}; };
}; };
export const fetchExpenses = async (pubkey, limit = 100) => { export const fetchExpenses = async (pubkey, minTime, limit = MAX_NB_TX) => {
shuffle(CESIUM_G1_NODES); // Mélanger la liste des noeuds shuffle(CESIUM_G1_NODES); // Mélanger la liste des noeuds
for (let node of CESIUM_G1_NODES) { for (let node of CESIUM_G1_NODES) {
try { try {
const url = `${node}/g1/movement/_search`; const url = `${node}/g1/movement/_search`;
let queryBody = query__expenses(pubkey, limit); let queryBody = query__expenses(pubkey, minTime, limit);
console.log('expenses queryBody : \n', JSON.stringify(queryBody)); console.log('expenses queryBody : \n', JSON.stringify(queryBody));
@ -279,10 +297,11 @@ export const query__cesium_profile = (pubkey) => {
}; };
export const query__cesium_profiles = (pubkeys) => { export const query__cesium_profiles = (pubkeys, limit = 200) => {
return { return {
_source: ["title"] size: limit
,_source: ["title"]
,query: { ,query: {
bool: { bool: {
filter: [ filter: [
@ -334,7 +353,7 @@ export const fetchCesiumProfile = async (pubkey) => {
throw new Error("Failed to fetch data from all nodes"); throw new Error("Failed to fetch data from all nodes");
}; };
export const fetchCesiumProfiles = async (pubkeys) => { export const fetchCesiumProfiles = async (pubkeys, limit) => {
shuffle(CESIUM_G1_NODES); // Mélanger la liste des noeuds shuffle(CESIUM_G1_NODES); // Mélanger la liste des noeuds
@ -342,7 +361,7 @@ export const fetchCesiumProfiles = async (pubkeys) => {
try { try {
const url = `${node}/user/profile/_search`; const url = `${node}/user/profile/_search`;
let queryBody = query__cesium_profiles(pubkeys); let queryBody = query__cesium_profiles(pubkeys, limit);
console.log('cesium_profiles queryBody : \n', JSON.stringify(queryBody)); console.log('cesium_profiles queryBody : \n', JSON.stringify(queryBody));
@ -443,17 +462,21 @@ export const displayExpenses = (expensesByRecipient, expensesTotalAmount, recipi
let formElt = document.querySelector('form#explore'); let formElt = document.querySelector('form#explore');
const treemapIt = async (pubkey, maxNbTx = MAX_NB_TX) => { const treemapIt = async (pubkey, minTime, maxNbTx = MAX_NB_TX) => {
let dotsPos = pubkey.indexOf(':'); let dotsPos = pubkey.indexOf(':');
if (dotsPos != -1) { if (dotsPos != -1) {
pubkey = pubkey.substr(0, dotsPos); pubkey = pubkey.substr(0, dotsPos);
} }
let { expensesTotalAmount, expensesByRecipient } = await fetchExpenses(pubkey, maxNbTx); let { expensesTotalAmount, expensesByRecipient } = await fetchExpenses(pubkey, minTime, maxNbTx);
let nbRecipients = Object.keys(expensesByRecipient).length;
console.log("nb recipients :\n", nbRecipients);
let recipientsList = Object.keys(expensesByRecipient); let recipientsList = Object.keys(expensesByRecipient);
let recipientsCesiumProfiles = await fetchCesiumProfiles(recipientsList); let recipientsCesiumProfiles = await fetchCesiumProfiles(recipientsList, maxNbTx);
let currentProfile = await fetchCesiumProfile(pubkey); let currentProfile = await fetchCesiumProfile(pubkey);
console.log('currentProfile :\n', currentProfile); console.log('currentProfile :\n', currentProfile);
@ -471,18 +494,64 @@ const treemapIt = async (pubkey, maxNbTx = MAX_NB_TX) => {
console.log('linkEvent.currentTarget :\n', linkEvent.currentTarget); console.log('linkEvent.currentTarget :\n', linkEvent.currentTarget);
let pubkey = linkEvent.currentTarget.getAttribute('href').substr(1); let pubkey = linkEvent.currentTarget.getAttribute('href').substr(1);
treemapIt(pubkey); // treemapIt(pubkey, minDate);
}); });
} }
}; };
const getPkInHash = () => {
let hash = window.location.hash;
hash = hash.substring(1);
return hash;
};
window.addEventListener("popstate", (popEvent) => {
let pk = getPkInHash();
console.log('\n\n\npubkey :\n', pk);
if (pk != '') {
treemapIt(pk, minTime, txLimit);
}
});
formElt.addEventListener('submit', (formEvent) => { formElt.addEventListener('submit', (formEvent) => {
formEvent.preventDefault(); formEvent.preventDefault();
txLimit = formEvent.target.querySelector('input[name="txLimit"]').value;
let minDateStr = formEvent.target.querySelector('input[name="minDate"]').value;
let minDate = new Date(minDateStr);
minTime = Math.floor(minDate.valueOf()/1000);
console.log('minTime :\n', minTime);
let pubkey = formEvent.target.querySelector('input[name="pubkey"]').value; let pubkey = formEvent.target.querySelector('input[name="pubkey"]').value;
let txLimit = formEvent.target.querySelector('input[name="txLimit"]').value; window.location = '#';
window.location = '#' + pubkey;
treemapIt(pubkey, txLimit);
}); });
window.addEventListener('DOMContentLoaded', (loadEvent) => {
let formElt = document.getElementById('explore');
let minDateElt = formElt.querySelector('input[name="minDate"]');
let now = Date();
console.log('now : \n', now);
let aMonthAgo = new Date(now);
aMonthAgo.setMonth(aMonthAgo.getMonth() - 1);
console.log('aMonthAgo : ', aMonthAgo);
console.log('aMonthAgo.getMonth() :\n', aMonthAgo.getMonth());
let dateStr = aMonthAgo.getFullYear() + '-' + (aMonthAgo.getMonth()+1).toString().padStart(2,0) + '-' + aMonthAgo.getDate().toString().padStart(2,0);
console.log('dateStr : ', dateStr);
minDateElt.value = dateStr;
});

View File

@ -33,11 +33,25 @@ footer {
margin-bottom: 3rem; margin-bottom: 3rem;
border-top: 2px solid hsl(0, 0%, 95%); border-top: 2px solid hsl(0, 0%, 95%);
text-align: center;
} }
footer blockquote { footer blockquote {
margin: 0; margin: 0;
font-style: italic; font-style: italic;
text-align: center; }
footer a,
footer a:visited {
text-decoration: none;
color: hsl(0, 0%, 50%);
}
footer a:hover {
text-decoration: underline;
} }

View File

@ -166,11 +166,13 @@ console.log(station)
<form id="addressForm"> <form id="addressForm">
<label for="address">Address: </label> <label for="address">Address: </label>
<input type="text" id="address" size=30 required> <input type="text" id="address" size=30 required>
<button type="button" onclick="getCoordinates()">Go There</button> <button type="button" onclick="getCoordinates()">Go</button>
</form> </form>
<br> <h2>
<p id="result">- <a href="mailto:support@qo-op.com">Contact</a> -</p> <a target="pad" href="/ipfs/QmcSkcJ2j7GAsC2XhVqGSNAKVRpXgxfjjvDbhD5YxrncZY/?room=UPLANET">VISIO ROOM</a>
</h2>
<p id="result">- <a href="mailto:support@qo-op.com">support</a> -</p>
<!-- <!--
<div class="code"> <div class="code">