Skip to main content
Research Preview — APIs may change. GitHub

Geofence compliance

You’re managing a drone fleet. Regulators require proof that each drone stayed within its approved flight corridor. Astral’s contains operation produces a signed result recording whether each reported position fell inside the corridor — verifiable, auditable evidence of the check.
The drone’s reported position is supplied as coordinates. The signed result proves the containment computation was performed correctly on those coordinates — it does not, by itself, prove the drone was physically there. Raw GPS can be spoofed. To strengthen the position itself, attach location proofs (for example, hardware-attested device evidence) so the input carries its own credibility, not just the computation. This is a Research Preview — be direct with regulators about which inputs are evidence-backed and which are self-reported.

How it works

  1. Define the approved corridor as a polygon
  2. Periodically check the drone’s position with compute.contains
  3. Each check produces a signed result
  4. A compliance report is a series of signed results covering the flight duration

Define the approved corridor

Register the approved flight corridor as an onchain location record.
import { AstralSDK } from '@decentralized-geo/astral-sdk';

const astral = new AstralSDK({ chainId: 84532, signer: wallet });

// Register approved flight corridor
const corridor = await astral.location.onchain.create({
  location: {
    type: 'Polygon',
    coordinates: [[
      [-122.420, 37.780],
      [-122.410, 37.780],
      [-122.410, 37.790],
      [-122.420, 37.790],
      [-122.420, 37.780]
    ]]
  },
  memo: "Approved flight corridor — permit #DR-2025-0042"
});

console.log('Corridor UID:', corridor.uid);

Periodic compliance checks

At regular intervals during the flight, check whether the drone’s position falls within the corridor.
async function checkCompliance(
  droneCoords: [number, number],
  corridorUID: string,
  wallet: Signer
) {
  const astral = new AstralSDK({ chainId: 84532, signer: wallet });

  // Register current drone position
  const dronePosition = await astral.location.onchain.create({
    location: { type: 'Point', coordinates: droneCoords }
  });

  // Check containment — args are positional: (container, containee, options)
  const result = await astral.compute.contains(
    corridorUID,
    dronePosition.uid,
    { schema: SCHEMA_UID }
  );

  return {
    inCorridor: result.result,
    timestamp: result.timestamp,
    attestation: result.attestation
  };
}

Building a compliance report

A compliance report is a time series of signed results. Each one is independently verifiable.
interface ComplianceRecord {
  timestamp: number;
  inCorridor: boolean;
  attestationUID: string;
}

async function runComplianceLoop(
  corridorUID: string,
  getDronePosition: () => Promise<[number, number]>,
  intervalMs: number,
  wallet: Signer
): Promise<ComplianceRecord[]> {
  // `records` is returned immediately and filled over time as the interval
  // fires (the caller holds the same array reference). In real use you'd
  // persist each record as it's produced and clear the interval when the
  // flight ends — illustrative here.
  const records: ComplianceRecord[] = [];

  const interval = setInterval(async () => {
    const coords = await getDronePosition();
    const result = await checkCompliance(coords, corridorUID, wallet);

    records.push({
      timestamp: result.timestamp,
      inCorridor: result.inCorridor,
      attestationUID: result.attestation.uid
    });

    // Alert on violation
    if (!result.inCorridor) {
      console.warn(`Corridor violation at ${new Date(result.timestamp * 1000).toISOString()}`);
    }
  }, intervalMs);

  return records;
}

Submitting compliance onchain

For regulatory requirements that demand onchain proof, submit each signed result as an EAS attestation.
async function submitComplianceProof(
  result: BooleanComputeResponse,
  wallet: Signer
) {
  const astral = new AstralSDK({ chainId: 84532, signer: wallet });

  const { uid } = await astral.compute.submit({
    attestation: result.attestation,
    delegatedAttestation: result.delegatedAttestation,
  });

  return uid;
}

What the regulator sees

Each signed result in the compliance report includes:
FieldValue
Operationcontains
Resulttrue (in corridor) or false (violation)
Input referencesHashes of the drone position and corridor polygon
TimestampWhen the check was performed
AttesterAstral’s TEE signing key
The regulator can verify each result independently — the Astral signature proves the containment computation was performed correctly and the input references tie it to the specific corridor and reported position. What it does not prove on its own is that the drone was physically at that position: that depends on how the position was sourced (see the note above). A compliance story is only as strong as its weakest input.

Variations

  • Maritime shipping — verify vessels stay within approved shipping lanes
  • Autonomous vehicles — prove a vehicle stayed within its operational design domain
  • Asset tracking — verify high-value goods remained within approved transit routes
  • Environmental monitoring — confirm survey equipment stayed within permitted research areas

Next: Onchain attestation

End-to-end blockchain flow from computation to smart contract