Your first location proof and verified spatial computation in 5 minutes
Research Preview — Astral is under active development and not yet production-ready. APIs may change. We’re building in public and welcome feedback.
This guide walks through both of Astral’s core capabilities: creating and verifying a location proof, then running a verified spatial computation with it.
A location proof starts on the device. You collect signals from proof-of-location systems, process them into stamps, sign them, and compose the proof.
Copy
import { AstralSDK } from '@decentralized-geo/astral-sdk';const astral = new AstralSDK({ chainId: 84532, apiUrl: 'https://staging-api.astral.global'});// 1. Collect raw signals from a proof-of-location plugin on the device// ProofMode reads GPS, accelerometer, cell towers, and signs with the Secure Enclaveconst signals = await astral.stamps.collect({ name: 'proofmode', version: '0.1.0', config: { timeout: 5000 }});// 2. Create an unsigned stamp from the raw signalsconst unsigned = await astral.stamps.create( { name: 'proofmode', version: '0.1.0' }, signals);// 3. Sign the stamp with the device keyconst stamp = await astral.stamps.sign(unsigned, deviceSigner);// 4. Compose a location proof: a claim ("I was here") bundled with signed stampsconst claim = { location: { type: 'Point', coordinates: [-122.4194, 37.7749] }, subject: { scheme: 'eth-address', value: '0x1234...' }, radius: 100, time: { start: Date.now() / 1000 - 60, end: Date.now() / 1000 }, // lpVersion, locationType, srs — Location Protocol v0.2 defaults}const proof = astral.proofs.create(claim, [stamp]);
Each step adds a layer. The signals are raw sensor data. The stamp processes them into a structured artifact. The signature binds the stamp to a specific identity. The proof bundles the claim with the evidence.
Submit the location proof to Astral’s Verify endpoint. Verification runs inside a TEE — each stamp is checked for signature validity, structural integrity, and consistency with the claim. Multiple stamps from independent systems are cross-correlated to strengthen confidence.
The result is a credibility score — not a binary yes/no, but a structured assessment of how strongly the evidence supports the claim. You now have a verified, signed answer to “was this entity actually at this location?”
Now use the verified location in a spatial operation. The computation runs inside the same TEE — PostGIS computes the spatial relationship and the TEE signs the result.
The signed result proves the computation was performed correctly on the stated inputs. Because the input was a verified location proof, the full chain of trust is preserved: who claimed to be where, the evidence supporting that claim, and the spatial relationship the system computed.Raw GeoJSON also works — useful for reference geometries like official boundaries or known landmarks. But raw coordinates carry no proof of origin. The computation is still verified, but the inputs are unverified.
The signed result is portable. Use it directly in your application:
Copy
// Agent workflow — branch on the verified spatial answerif (inside.result) { confirmDelivery(inside); // the signed result is the audit trail}// Backend — store as evidenceawait db.insert({ delivery_id, proof: inside });
Or submit it onchain. EAS (the Ethereum Attestation Service) is an open protocol for structured, signed attestations, plus a smart contract to register attestations onchain.Astral’s signed results are pre-packaged as EAS attestations. EAS supports resolver contracts — smart contracts that execute arbitrary logic when an attestation is created onchain. A verified spatial result can directly trigger token transfers, access grants, escrow releases, or any other onchain action.
Copy
import { ethers } from 'ethers';const wallet = new ethers.Wallet(PRIVATE_KEY, provider);const astral = new AstralSDK({ chainId: 84532, signer: wallet, apiUrl: 'https://staging-api.astral.global'});const result = await astral.compute.within({ geometry: verified.uid, target: landmarkUID, radius: 500, chainId: 84532, schema: RESOLVER_SCHEMA_UID, recipient: wallet.address});// Submit to EAS — triggers your resolver contract onchainconst tx = await astral.eas.submitDelegated(result.delegatedAttestation);console.log('Onchain:', tx.hash);
For the full blockchain flow — writing resolver contracts, registering schemas, chain configuration — see Blockchain Integration.