Skip to content

Commit

Permalink
feat: implement full MVP for demo, include Auro Wallet integrationi
Browse files Browse the repository at this point in the history
  • Loading branch information
iluxonchik committed Jan 18, 2024
1 parent e712ddf commit e78e93a
Show file tree
Hide file tree
Showing 11 changed files with 1,366 additions and 298 deletions.
103 changes: 103 additions & 0 deletions ui/src/components/AuroWalletConnector.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<script lang="ts">
import { onMount, createEventDispatcher } from 'svelte';
import { browser } from '$app/environment';
import { Mina, PublicKey } from 'o1js';
import { GeoPointInPolygonCombinedContract } from 'zklocus';
import type { ZKGeoPointInPolygonProof } from 'zklocus/src/api/proofs/ZKGeoPointInPolygonProof';
const dispatch = createEventDispatcher();
let auroWalletInstalled = false;
let connectedAccount = null;
//let zkAppAddress = 'B62qqp4ymLtDwEmHnPF4vb68UjEua9jvbotL6tFZzFM6aTok8wHMSTX'; // non-combined proof
let zkAppAddress = 'B62qqR9tWqHuiYEQz677wP6KL9f54bx3pcwNhFZpNy1qRqrgbVEfwgk';
let transactionHash = '';
let transactionError = '';
export let proof: ZKGeoPointInPolygonProof;
let Berkeley = Mina.Network('https://proxy.berkeley.minaexplorer.com/graphql');
Mina.setActiveInstance(Berkeley);
onMount(() => {
if (browser && typeof window.mina !== 'undefined') {
auroWalletInstalled = true;
}
});
async function connectWallet() {
if (!auroWalletInstalled) return;
const accounts = await window.mina.requestAccounts().catch((err) => {
console.error('Error requesting accounts:', err);
return [];
});
if (accounts.length > 0) {
connectedAccount = accounts[0];
dispatch('walletConnected', { account: connectedAccount });
}
}
async function buildPIPTransaction() {
console.log("Preparing zkLocus transaction...")
const zkAppPublicKey: PublicKey = PublicKey.fromBase58(zkAppAddress);
const zkAppInstance = new GeoPointInPolygonCombinedContract(zkAppPublicKey);
const txn = await Mina.transaction(() => {
zkAppInstance.submitProof(proof.proof);
});
console.log("\tProving transaction...");
await txn.prove();
console.log("\tTransaction perpared! ✅");
return txn;
}
async function submitTransaction() {
if (!zkAppAddress) return;
// Dummy transaction object - replace with actual transaction logic
const transaction = await buildPIPTransaction();
const result = await window.mina.sendTransaction({
transaction: transaction.toJSON(),
feePayer: {
memo: "zkLocus Proof",
},
}).catch((err) => {
transactionError = err.message || 'Unknown error submitting transaction';
console.error('Transaction error:', transactionError);
return null;
});
if (result && result.hash) {
transactionHash = result.hash;
dispatch('transactionSubmitted', { hash: transactionHash });
}
}
</script>

{#if auroWalletInstalled}
{#if connectedAccount}
<div>
Connected as: {connectedAccount}
<input bind:value={zkAppAddress} placeholder="Enter zkApp Address" class="input input-bordered" />
<button on:click={submitTransaction} class="btn btn-primary" disabled={!zkAppAddress}>Submit Proof</button>
</div>
{#if transactionHash}
<div>
<p><a href={`https://minascan.io/berkeley/tx/${transactionHash}?type=zk-tx`} target="_blank">🔗 View Transaction On MinaScan.io</a></p>
<p>Transaction Hash: {transactionHash} </p>
</div>
{/if}
{#if transactionError}
<div class="text-error">Error: {transactionError}</div>
{/if}
{:else}
<button on:click={connectWallet} class="btn btn-primary">Connect to Auro Wallet</button>
{/if}
{:else}
<div class="text-error">Auro Wallet is not installed.</div>
{/if}

<style>
/* Additional styling as needed */
</style>

103 changes: 103 additions & 0 deletions ui/src/components/AuroWalletConnectorExact.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<script lang="ts">
import { onMount, createEventDispatcher } from 'svelte';
import { browser } from '$app/environment';
import { Mina, PublicKey } from 'o1js';
import type { ZKGeoPointInPolygonProof } from 'zklocus/src/api/proofs/ZKGeoPointInPolygonProof';
import {GeoPointWithMetadataContract} from 'zklocus';
const dispatch = createEventDispatcher();
let auroWalletInstalled = false;
let connectedAccount = null;
//let zkAppAddress = 'B62qqp4ymLtDwEmHnPF4vb68UjEua9jvbotL6tFZzFM6aTok8wHMSTX'; // non-combined proof
let zkAppAddress = 'B62qkvhdMJsbThRqF7e8myUVonw8hAodUFFT2RmRb2tirqw1U7Jv9q1';
let transactionHash = '';
let transactionError = '';
export let proof: ZKGeoPointInPolygonProof;
let Berkeley = Mina.Network('https://proxy.berkeley.minaexplorer.com/graphql');
Mina.setActiveInstance(Berkeley);
onMount(() => {
if (browser && typeof window.mina !== 'undefined') {
auroWalletInstalled = true;
}
});
async function connectWallet() {
if (!auroWalletInstalled) return;
const accounts = await window.mina.requestAccounts().catch((err) => {
console.error('Error requesting accounts:', err);
return [];
});
if (accounts.length > 0) {
connectedAccount = accounts[0];
dispatch('walletConnected', { account: connectedAccount });
}
}
async function buildPIPTransaction() {
console.log("Preparing zkLocus transaction...")
const zkAppPublicKey: PublicKey = PublicKey.fromBase58(zkAppAddress);
const zkAppInstance = new GeoPointWithMetadataContract(zkAppPublicKey);
const txn = await Mina.transaction(() => {
zkAppInstance.submitProof(proof.proof);
});
console.log("\tProving transaction...");
await txn.prove();
console.log("\tTransaction perpared! ✅");
return txn;
}
async function submitTransaction() {
if (!zkAppAddress) return;
// Dummy transaction object - replace with actual transaction logic
const transaction = await buildPIPTransaction();
const result = await window.mina.sendTransaction({
transaction: transaction.toJSON(),
feePayer: {
memo: "zkLocus Proof + Metadata",
},
}).catch((err) => {
transactionError = err.message || 'Unknown error submitting transaction';
console.error('Transaction error:', transactionError);
return null;
});
if (result && result.hash) {
transactionHash = result.hash;
dispatch('transactionSubmitted', { hash: transactionHash });
}
}
</script>

{#if auroWalletInstalled}
{#if connectedAccount}
<div>
Connected as: {connectedAccount}
<input bind:value={zkAppAddress} placeholder="Enter zkApp Address" class="input input-bordered" />
<button on:click={submitTransaction} class="btn btn-primary" disabled={!zkAppAddress}>Submit Proof</button>
</div>
{#if transactionHash}
<div>
<p><a href={`https://minascan.io/berkeley/tx/${transactionHash}?type=zk-tx`} target="_blank">🔗 View Transaction On MinaScan.io</a></p>
<p>Transaction Hash: {transactionHash} </p>
</div>
{/if}
{#if transactionError}
<div class="text-error">Error: {transactionError}</div>
{/if}
{:else}
<button on:click={connectWallet} class="btn btn-primary">Connect to Auro Wallet</button>
{/if}
{:else}
<div class="text-error">Auro Wallet is not installed.</div>
{/if}

<style>
/* Additional styling as needed */
</style>

3 changes: 2 additions & 1 deletion ui/src/components/LocateMe.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
export let handler;
export let isDisabled = false;
</script>
<button on:click={handler} class="btn btn-primary">Locate me</button>
<button on:click={handler} class="btn btn-primary" disabled={isDisabled}>Locate me</button>
138 changes: 68 additions & 70 deletions ui/src/components/MapComponent.svelte
Original file line number Diff line number Diff line change
@@ -1,88 +1,86 @@
<script lang="ts">
import { onMount } from 'svelte';
import { createEventDispatcher } from 'svelte'
let L;
import { onMount } from 'svelte';
import { createEventDispatcher } from 'svelte';
let L;
export let latitude;
export let longitude;
export let setPolygonPoints;
export let proofGenerated = false;
export let mapId: string = 'map';
export let latitude;
export let longitude;
export let setPolygonPoints;
export let proofGenerated = false;
export let mapId: string = 'map';
let map;
let marker;
let polygon;
let polygonPoints = [];
let map;
let marker;
let polygon;
let polygonPoints = [];
let polygons = [];
const dispatch = createEventDispatcher()
const dispatch = createEventDispatcher();
onMount(async () => {
L = await import('leaflet');
initializeMap();
map.on('click', addPolygonPoint);
});
onMount(async () => {
L = await import('leaflet');
initializeMap();
map.on('click', addPolygonPoint);
});
function createDotIcon() {
return L.divIcon({
html: '<div class="leaflet-dot-icon"></div>',
iconSize: [10, 10], // size of the icon
iconAnchor: [5, 5] // point of the icon which will correspond to marker's location
});
}
function createDotIcon() {
return L.divIcon({
html: '<div class="leaflet-dot-icon"></div>',
iconSize: [10, 10], // size of the icon
iconAnchor: [5, 5] // point of the icon which will correspond to marker's location
});
}
function initializeMap() {
map = L.map(mapId).setView([latitude, longitude], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
function initializeMap() {
map = L.map(mapId).setView([latitude, longitude], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
marker = L.marker([latitude, longitude], { draggable: true }).addTo(map);
marker.on('dragend', function (event) {
var position = event.target.getLatLng();
latitude = position.lat.toFixed(7); // Update latitude with precision
longitude = position.lng.toFixed(7); // Update longitude with precision
// Dispatch a custom event or call a prop method to update the parent's state
dispatch('updateCoords', { latitude, longitude });
});
}
marker = L.marker([latitude, longitude], { draggable: true }).addTo(map);
marker.on('dragend', function(event) {
var position = event.target.getLatLng();
latitude = position.lat.toFixed(7); // Update latitude with precision
longitude = position.lng.toFixed(7); // Update longitude with precision
// Dispatch a custom event or call a prop method to update the parent's state
dispatch('updateCoords', { latitude, longitude });
});
$: if (map && marker) {
marker.setLatLng([latitude, longitude]);
map.panTo([latitude, longitude]);
}
}
$: if (polygon && proofGenerated) {
polygon.setStyle({ fillColor: 'yellow' });
}
$: if (map && marker) {
marker.setLatLng([latitude, longitude]);
map.panTo([latitude, longitude]);
}
function addPolygonPoint(e) {
polygonPoints.push(e.latlng);
L.marker(e.latlng, { icon: createDotIcon() }).addTo(map);
$: if (polygon && proofGenerated) {
polygon.setStyle({ fillColor: 'yellow' });
}
if (polygonPoints.length === 3) {
// Create a polygon from the points
let newPolygon = L.polygon(polygonPoints, { color: 'blue' }).addTo(map);
polygons.push(polygonPoints);
function addPolygonPoint(e) {
if (polygonPoints.length < 3) {
polygonPoints.push(e.latlng);
L.marker(e.latlng, { icon: createDotIcon() }).addTo(map);
// Reset polygonPoints for a new polygon and dispatch the array of polygons
polygonPoints = [];
dispatch('polygonsChange', { polygons });
}
}
if (polygonPoints.length === 3) {
if(polygon) {
polygon.remove();
}
polygon = L.polygon(polygonPoints).addTo(map);
setPolygonPoints(polygonPoints);
}
}
}
</script>

<div id="{mapId}" style="height: 400px;"></div>
<div id={mapId} style="height: 400px;" />

<style>
.leaflet-dot-icon {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: blue;
}
</style>
.leaflet-dot-icon {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: blue;
}
</style>
Loading

0 comments on commit e78e93a

Please sign in to comment.