Skip to main content
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.

Step 1: Create a Location Proof

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.
import { AstralSDK, MockPlugin } from '@decentralized-geo/astral-sdk';

const astral = new AstralSDK({
  chainId: 84532,
  signer: wallet,
  apiUrl: 'https://staging-api.astral.global'
});

// 1. Register a proof-of-location plugin. The SDK ships MockPlugin for local
//    development; on a real device, evidence comes from a source like the
//    ProofMode app (GPS, sensors, hardware-backed signatures).
astral.plugins.register(new MockPlugin({ name: 'mock-1', lat: 37.7749, lon: -122.4194 }));

// 2. Collect raw signals (returns an array), then create an unsigned stamp
const signals = await astral.stamps.collect({ plugins: ['mock-1'] });
const unsigned = await astral.stamps.create({ plugin: 'mock-1' }, signals[0]);

// 3. Sign the stamp with the device key
const stamp = await astral.stamps.sign({ plugin: 'mock-1' }, unsigned, deviceSigner);

// 4. Compose a location proof: a claim ("I was here") bundled with signed stamps
const claim = {
  lpVersion: '0.2',
  locationType: 'geojson-point',
  location: { type: 'Point', coordinates: [-122.4194, 37.7749] },
  srs: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84',
  subject: { scheme: 'eth-address', value: '0x1234...' },
  radius: 100,
  time: { start: Date.now() / 1000 - 60, end: Date.now() / 1000 },
};
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.
const claim = {
  lpVersion: '0.2',
  locationType: 'geojson-point',
  location: { type: 'Point', coordinates: [-122.4194, 37.7749] },
  srs: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84',
  subject: { scheme: 'eth-address', value: '0x1234...' },
  radius: 100,                                              // meters
  time: { start: Date.now() / 1000 - 60, end: Date.now() / 1000 },
  eventType: 'presence'                                      // optional
}
See Location Proofs for the full data model.

Step 2: Verify the Proof

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.
// `mode: 'tee'` routes verification to the hosted service and returns a
// VerifiedLocationProof; the default 'local' mode returns the vector directly.
const verified = await astral.proofs.verify(proof, { mode: 'tee', chainId: 84532 });

console.log(verified.credibility);          // a multidimensional credibility vector
const locationUID = verified.attestation.uid;
The result is a credibility vector — not a binary yes/no, and not a single score, but a structured assessment of how strongly the evidence supports the claim across several dimensions (its exact structure is still an open research question). It tells you how well the evidence backs the claim — not, by itself, that the entity was definitely there. How much that’s worth, and what threshold to require, is your application’s call.

Step 3: Run a Spatial Computation

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.
// Arguments are positional: (container, containee, options).
// `schema` is the EAS schema UID the signed result is encoded against.
const inside = await astral.compute.contains(
  geofencePolygon,   // container
  locationUID,       // containee — the verified location
  { schema: SCHEMA_UID }
);

console.log(`Inside geofence: ${inside.result}`);  // true
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.

Step 4: Use the Result

The signed result is portable. Use it directly in your application:
// Agent workflow — branch on the verified spatial answer
if (inside.result) {
  confirmDelivery(inside);  // the signed result is the audit trail
}

// Backend — store as evidence
await 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 can be 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 then trigger token transfers, access grants, escrow releases, or any other onchain action. (This is one path among several — most applications use signed results offchain, as in Step 4 above.)
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'
});

// Arguments are positional: (geometry, target, radius, options).
const result = await astral.compute.within(
  locationUID,         // geometry — the verified location
  landmarkUID,         // target
  500,                 // radius in meters
  { schema: RESOLVER_SCHEMA_UID, recipient: wallet.address }
);

// Submit to EAS — triggers your resolver contract onchain
const { uid } = await astral.compute.submit({
  attestation: result.attestation,
  delegatedAttestation: result.delegatedAttestation,
});
console.log('Onchain attestation:', uid);
For the full blockchain flow — writing resolver contracts, registering schemas, chain configuration — see Blockchain Integration.

Next Steps

Core Concepts

Understand location data, location proofs, and geocomputation

Guides

Walk through common workflows step by step

API Reference

Full API documentation

SDK Reference

TypeScript SDK documentation