-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement full MVP for demo, include Auro Wallet integrationi
- Loading branch information
1 parent
e712ddf
commit e78e93a
Showing
11 changed files
with
1,366 additions
and
298 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
Oops, something went wrong.