How I Develop with Bitcoin and Nostr
The first step for me was to come up with an idea. Inspiration struck after a discussion with a friend about an app called arcade.city. I told my friend that arcade.city is a ridesharing startup with bitcoin as the main payment method. A few days later I thought about that conversation while wondering what project to do next. It occurred to me that a ridesharing app might be fun to build. I wondered how hard it is to do the mapping stuff and send a lightning payment automatically when you reach your destination. That’s when I started building.
My first step was to create a directory called “bitcoin uber project.” Inside it I created a file called rider.html and gave it the skeleton of an html page:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
Here were the contents of my “bitcoin uber project” directory at a slightly later stage of development:
With my html file ready for development, I went to a previous project where I remembered using some map software. It was a combination of openstreetmap.org (for “map tiles”, basically images of streets and highways) and leaflet.js (for adding markers to my map as well as calculating distances between items). I created a map div, imported the map library, and added map tiles from openstreetmap:
<div id="mapid"></div>
<script type="text/javascript">
var link = document.createElement('link')
link.rel = 'stylesheet'
link.href = 'https://unpkg.com/[email protected]/dist/leaflet.css'
link.integrity = 'sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=='
link.setAttribute('crossorigin', '')
document.getElementsByTagName('head')[0].appendChild(link)
</script>
<script
src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
crossorigin=""
></script>
<script type="text/javascript">
var style = document.createElement('style')
var css = document.createTextNode('#mapid {height: 100vh;}')
style.appendChild(css)
document.getElementsByTagName('head')[0].appendChild(style)
</script>
<script>
var lat = 38
var lng = -95
var zm = 5
var mymap = L.map('mapid').setView([lat, lng], zm)
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}
).addTo(mymap)
</script>
<script type="text/javascript">
var link = document.createElement('link')
link.rel = 'stylesheet'
link.href = 'https://unpkg.com/[email protected]/dist/leaflet.css'
link.integrity =
'sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=='
link.setAttribute('crossorigin', '')
document.getElementsByTagName('head')[0].appendChild(link)
</script>
When I opened rider.html in my browser with all this code inside, it displayed a basic map of the united states.
Next I played around with putting a pin on the map at my current location. I knew I wanted to put a second pin on the map later and calculate the distance between them, so I created three global variables: “from,” “to,” and “olddist.” (“Olddist” means “old distance” and it is in contrast with “new distance.” I’ll eventually calculate “new distance” every few seconds and compare it with “old distance,” which is the distance I was at the last time I measured it.)
To get the “from” pin, I needed the coordinates of my user’s device to ensure they get picked up from their current location. I remembered that modern browsers have built in location tools so I googled “gps coordinates w3schools” to learn how it works. (W3schools is a popular website that teaches web developers basic tools and provides sample code.) It turns out, you need to create several variables and functions as a precursor to getting the user’s location: (1) the geolocation api only gives accurate data if you use a variable called “option” where you instruct your browser to provide high fidelity location data (called “enableHighAccuracy”), (2) but using that optional parameter requires that you first create an “error” function that your browser can trigger if it can’t provide high fidelity location data, and (3) you also have to pass the user’s coordinates to a “watching” function (which you have to write) that does something with the location data. I created all of this stuff and ended up with the following:
<script type="text/javascript">
var from = {}
var to = {}
var olddist = ''
var options = {
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 5000,
}
function error(err) {
console.warn('ERROR( ' + err.code + ' ): ' + err.message)
}
if (navigator.geolocation) {
id = navigator.geolocation.watchPosition(
watchUsersPosition,
error,
options
)
} else {
console.error(
'Geolocation is not supported by this browser.'
)
}
function watchUsersPosition(position) {
if (from != {}) {
mymap.removeLayer(from)
}
from = L.marker(
[position.coords.latitude, position.coords.longitude],
{ icon: redIcon }
).addTo(mymap)
if (Object.keys(to).length > 0) {
newdist = getDistance(from.getLatLng(), to.getLatLng())
if (newdist != olddist) {
console.log(newdist + ' mi')
olddist = newdist
if (newdist < 0.021) {
navigator.geolocation.clearWatch(id)
alert("you made it, you're there!")
}
}
}
}
var redIcon = new L.Icon({
iconUrl: 'https://streetevangelization.com/wp-content/uploads/2019/09/marker-icon-red.png',
shadowUrl: 'https://streetevangelization.com/wp-content/uploads/2019/09/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41],
})
function getDistance(from, to) {
return (from.distanceTo(to).toFixed(0) / 1609.344).toFixed(3)
}
</script>
The watchUsersPosition function removes the current “from” marker – if one exists – and replaces it with a new one based on the last position the user’s device reported. If a “to” marker exists, it also checks the distance to that and fires an alert that says “you made it, you're there!”
I ran this code in my browser and noticed that, after getting my location, it placed a nice red pin where I am.
Ok im bored thats all youre getting…