Skip to content

Instantly share code, notes, and snippets.

@DrI-T
Last active April 14, 2021 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DrI-T/fcc1743a2ab6f1b9675e7aa4c9a26f0d to your computer and use it in GitHub Desktop.
Save DrI-T/fcc1743a2ab6f1b9675e7aa4c9a26f0d to your computer and use it in GitHub Desktop.
proof of location and time
sitename: stamped
netname: adoring-babbage-fef8c2
badgeid: 7c75d385-56ca-45af-825f-5c0f419aba9a
<meta charset="utf8">
<title>Prior Date ... Time roll</title><meta charset="utf8">
<link rel=icon href=favicon.png>
<link rel=stylesheet href=style.css>
<div id=container>
<img id=bot>
<h2>Proof of location and time</h2>
<code>
<span id=time><i>:time</i></span>
<br><span id=ip><i>:ip</i></span>
<br><span id=qm><i>:qm</i></span>
</code>
<!--
proof of location is done by peers signing IPs
proof of time is done my peers signing timestamp with non predictable artifacts.
future we can have certified "DHCP" who allocate physical-location addresses
or w/ short range beacon reading.
-->
<h4>signing peers</h4>
<div id=peers><i>:peers</i></div>
<div id=note><small>you need to add this.origin to your Allowed.Origins list for this page to work</small></div>
</div>
<div id=stream><i>:streem</i></div>
<script>
var gw_url = 'https://ipfs.blockringtm.ml';
var api_url = 'https://ipfs.blockringtm.ml/api/v0/';
if (location.hostname == 'localhost') {
api_url = 'http://127.0.0.1:5001/api/v0/';
gw_url = 'http://127.0.0.1:8080';
//gw_url = 'https://dweb.link';
//gw_url = 'https://gateway.ipfs.io';
//api_url = 'https://local.wring.ml/api/v0/';
api_url = 'https://ipfs.blockringtm.ml/api/v0/';
//gw_url = 'https://ipfs.blockringtm.ml';
}
let note = document.getElementById('note')
note.innerHTML = note.innerHTML.replace('this.origin',location.origin);
const date = new Date; date.getDate();
var provs = [];
var stream = '';
document.getElementById('time').innerText = date.toISOString();
get_ip().then( ip => {
let p = ip.lastIndexOf('.');
let netn = ip.substr(0,p);
let hostn = parseInt( ip.substr(p+1) ) + 1;
let ip1 = `${netn}.${hostn}`
let botn = ip1.replace(/\./g,'');
let tics = date.getTime();
let toms = Math.floor(tics / 1000 / 29 / 59);
console.log('netn:',netn)
console.log('hostn:',hostn)
console.log('ip1:',ip1)
let el = document.getElementById('ip');
el.innerHTML = `<a href="https://www.iplocation.net/ip-lookup?query=${ip1}">${ip1}</a>`;
let im = document.getElementById('bot');
im.title = `${botn}-${tics}`;
im.src = `https://robohash.org/${botn}-${toms}`;
return ip1;
}).catch(console.error);
get_qm().then(async path => {
let el = document.getElementById('qm');
if (typeof(path) != 'undefined') {
let qm = path.replace('/ipfs/','');
el.innerHTML = `<a href="https://gateway.pinata.cloud${path}/ts/timestamp.htm">${qm}</a>`
//let api_url = 'https://local.wring.ml/api/v0/';
let headers = new Headers();
let api_auth = await get_api_key('api_auth');
//headers.set('Authorization', `Basic ${api_auth}`);
headers.set('x-apikey', await get_api_key('findprovs'));
//headers.set('Access-Control-Request-Headers', 'x-apikey'); // normally set by the browser ...
//return fetch(api_url+'dht/findprovs?arg='+path+'&num-providers=12', { method: 'POST', credentials: 'include', mode: 'cors', headers: headers });
return fetch(api_url+'dht/findprovs?arg='+path+'&num-providers=12', { method: 'POST', mode: 'cors', headers: headers }).
then( resp => { console.log(resp.body); return resp.body.getReader(); }).
then( reader => { return readStream(reader,get_peerids); }).
catch(console.error);
} else {
el.innerText = 'offline';
return {}
}
}).catch(console.error);
function get_ip() {
// let gw_url = 'https://local.wring.ml';
let url = 'https://ipfs.blockringtm.ml/cgi-bin/remote_addr.txt';
//let url = 'https://dynsm.ml/cgi-bin/remote_addr.pl';
return fetch(url,{ mode: 'cors' }).then(resp => resp.text()).
then( txt => { return txt.split('\n')[0]; }).
catch(console.warn);
}
async function get_qm() {
//let api_url = 'https://gateway.ipfs.io/api/v0/';
// timestamp: QmRozn3EJUeuFajuv471ieEi6zL5owkSMsCmLGEzjLFwRX
// _dnlink.stamped.ml TXT dnslink=/ipns/k2k4r8kpamoz0ge53yz5rqulnqypm22uiau7vtt8wfbin2soi5ra3qme
let url = api_url + 'resolve?arg=/ipns/stampedtm.ml'
let headers = new Headers(); headers.set('x-apikey', await get_api_key('resolve'));
return fetch(url,{ method: 'POST', headers: headers}).then(resp => {
console.log('resp:',resp);
for (let pair of resp.headers.entries()) {
console.log(pair[0]+ ': '+ pair[1]);
}
return resp.json()
}).
then( obj => { return obj.Path; }).
catch(console.warn);
}
function get_peerids(objs) {
provs.push(...objs.filter( (o) => o.Type == 4 ));
if (provs.length > 0) {
let peerids = provs.map((o) => o.Responses[0].ID );
display_peers(peerids);
display_stream(objs);
return peerids
}
}
function display_peers(peers) {
let d = document.getElementById('peers');
let buf = '<ol>';
if (typeof(peers) == 'undefined') { return void(0); }
for (p of peers) {
buf += `<li><a href=https://duckduckgo.com/?q=%2B%22${p}%22>${p}</a> <a href="http://127.0.0.1:8080/ipns/${p}">🔗</a>`;
}
buf += '</ol>';
d.innerHTML = buf;
}
function display_stream(data) {
let el = document.getElementById('stream');
let buf = '';
for (d of data) {
buf += '<li>'+JSON.stringify(d);
}
stream += buf;
el.innerHTML = '<ol>'+stream+'</ol>';
return buf;
}
function readStream(reader, callback) {
let read;
var buf = ''
return reader.read().
then(read = ({ value, done }) => {
if (done) return buf;
console.debug('value.buffer:',value.buffer)
if (buf != '') { console.debug('buf:',buf) }
buf += String.fromCharCode.apply(String, value);
// spliting the NDJSON
let lines = buf.replace(/(\n|\r)+$/, '').split("\n")
buf = (lines[lines.length-1].match(/}$/)) ? '' : lines.pop();
let objs = lines.map(JSON.parse)
// console.log('objs:',objs)
callback(objs);
if (objs.length > 0) {
return reader.read().then(read).catch(console.warn); // recursion !
} else {
return Promise.reject(String.fromCharCode.apply(String, value));
}
});
}
async function get_api_key(hint) {
//let url = gw_url+'/ipfs/Qmc6LGHFpSqYdVvUs2fF2myqRapKAWTJYobJi9VVBbxBCt/key_map.json';
//let url = gw_url+'/ipns/12D3KooWLNsfTqosoi34iSSeCutbatGjfS9tnqUyBhWAYXSw5bvZ/key_map.json';
//let url = 'https://k51qzi5uqu5dk3dlyn67w3njbyc4ngwvmv95kgevzh0czbue4gcifw3z1g3h56.ipns.dweb.link/key_map.json';
let url = 'https://ipfs.blockringtm.ml/ipns/k51qzi5uqu5dk3dlyn67w3njbyc4ngwvmv95kgevzh0czbue4gcifw3z1g3h56/key_map.json';
let headers = new Headers();
if (url.match('blockring')) {
headers.set('x-apikey', 'mst4dVsdMT1tw349XLyK-w==');
}
let map = await fetch(url,{ method: 'GET', headers: headers }).then(resp => resp.json()).catch(console.warn);
console.log('map[%s]: %s',hint,map[hint]);
return map[hint];
}
</script>
/* this is a styling sheet */
body {
background-image: url(https://gateway.pinata.cloud/ipfs/z8bvizzeGD35w7NUcj6dMcniFrEr8xFkP/img/i-negud.png);
background-size: 100% 100%;
background-attachment: fixed;
}
img[id^="bot"] {
border: 2px dotted white;
float: right;
max-width: 18vw;
}
#stream { display: none; }
#container {
max-width: 640px;
min-height: 40vh;
margin: auto;
margin-top: 10vh;
padding: 1.6rem;
background-color: white;
opacity: 0.94;
box-shadow: 5px 5px 15px 2px rgba(4,3,5,0.9);
}
#note {
display: block;
height: 1.6rem;
position: absolute;
bottom: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment