g1gate - follow the g1 - extract Cesium+ blockchain cache and display TX for a G1 Wallet
This commit is contained in:
parent
0e7742f75f
commit
ca48901bb4
|
@ -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 :<br>
|
|
||||||
<input type="text" name="pubkey" size="50" value="EA7Dsw39ShZg4SpURsrgMaMqrweJPUFPYHwZA8e92e3D">
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<label>
|
|
||||||
Limite du nombre de transactions :
|
|
||||||
<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>
|
|
|
@ -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 :<br>
|
||||||
|
<input type="text" name="pubkey" size="50">
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Limite du nombre de transactions :
|
||||||
|
<input type="number" name="txLimit" value="200" size="5">
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Depuis :
|
||||||
|
<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>
|
|
@ -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;
|
||||||
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in New Issue