Research Preview — Under active development.
Policy Attestations
Policy Attestations are the signed outputs of geospatial operations. They are signed by the Astral signing key, which is held exclusively inside the TEE (trusted execution environment). This is how you know the computation was performed correctly — only code running inside the TEE can produce valid signatures.
When submitted onchain via EAS resolvers, policy attestations can trigger any smart contract logic on EVM-compatible chains.
What is a Policy Attestation?
When you call a compute operation, Astral returns a Policy Attestation:
Code snippets need testing — Verify against actual implementation before use.
const result = await astral . compute . within ({
geometry: userLocationUID ,
target: landmarkUID ,
radius: 500 ,
chainId: 84532 ,
schema: SCHEMA_UID ,
recipient: userAddress
});
// result is a PolicyAttestationResult
console . log ( result . result ); // true
console . log ( result . operation ); // "within"
console . log ( result . attestation ); // { uid, schema, signature, ... }
The attestation proves:
The computation was performed by the Astral signing key
The inputs were exactly as specified
The result is accurate
Schema Types
Policy Attestations use per-result-type schemas. The SDK auto-selects based on the operation.
BooleanPolicyAttestation
For predicates (contains, within, intersects):
// Schema: "bool result, bytes32[] inputRefs, uint64 timestamp, string operation"
struct BooleanPolicyAttestation {
bool result; // The boolean result
bytes32 [] inputRefs; // Input references (UIDs or hashes)
uint64 timestamp; // When computation was performed
string operation; // "contains", "within", "intersects"
}
NumericPolicyAttestation
For measurements (distance, length, area):
// Schema: "uint256 result, string units, bytes32[] inputRefs, uint64 timestamp, string operation"
struct NumericPolicyAttestation {
uint256 result; // Scaled integer (centimeters)
string units; // "meters" or "square_meters"
bytes32 [] inputRefs; // Input references
uint64 timestamp; // When computation was performed
string operation; // "distance", "length", "area"
}
GeometryPolicyAttestation (Future)
For transformations (buffer, centroid, union):
// Schema: "bytes geometry, string geometryType, bytes32[] inputRefs, uint64 timestamp, string operation"
struct GeometryPolicyAttestation {
bytes geometry; // Encoded geometry result
string geometryType; // "Point", "Polygon", etc.
bytes32 [] inputRefs; // Input references
uint64 timestamp; // When computation was performed
string operation; // "buffer", "centroid", "union"
}
The inputRefs array contains a bytes32 reference for each input:
Input Type Reference Value Location Attestation UID The UID itself Offchain Attestation The attestation UID Raw GeoJSON keccak256(abi.encode(geojson))
This enables verification that specific inputs were used:
// In your resolver
( bool result, bytes32 [] memory inputRefs, , ) = abi . decode (...);
// Verify the expected location was checked
require (inputRefs[ 1 ] == EXPECTED_LANDMARK_UID, "Wrong location checked" );
For raw GeoJSON, the hash allows verification if the original geometry is known, but does not reveal the geometry itself.
SDK Return Object
interface PolicyAttestationResult < T > {
// Decoded result (convenience)
result : T ; // boolean | number | GeoJSON.Geometry
units ?: string ; // For measurements
operation : string ; // Operation name
timestamp : number ; // Unix timestamp
inputRefs : string []; // Input references
// Full attestation data
attestation : {
uid : string ; // EAS UID (if submitted onchain)
schema : string ; // Schema UID
attester : string ; // Astral signer address
recipient : string ; // Developer-specified recipient
data : string ; // ABI-encoded attestation data
signature : string ; // EIP-712 signature
};
// For delegated onchain submission
delegatedAttestation : {
signature : string ; // Astral's signature
attester : string ; // Astral's address
deadline : number ; // Signature expiry
};
}
Using Policy Attestations
Offchain
Use the result directly in your application:
const result = await astral . compute . within ({
geometry: uid1 ,
target: uid2 ,
radius: 500 ,
chainId: 84532 ,
schema: SCHEMA_UID
});
if ( result . result ) {
// User is nearby — enable feature
enableFeature ();
}
Onchain
Submit using delegated attestation :
const result = await astral . compute . within ({
geometry: uid1 ,
target: uid2 ,
radius: 500 ,
chainId: 84532 ,
schema: RESOLVER_SCHEMA_UID ,
recipient: userAddress
});
// Submit to EAS — triggers your resolver
const tx = await astral . eas . submitDelegated ( result . delegatedAttestation );
await tx . wait ();
Result Scaling
Numeric results are stored as scaled integers for determinism:
Original Stored To Recover 523.45 meters 52345 divide by 100 1234.5678 m² 12345678 divide by 10000
// In your resolver
( uint256 resultCm, , , , ) = abi . decode (...);
uint256 meters = resultCm / 100 ;
Attestation Expiry
The delegatedAttestation.deadline indicates when the signature expires. Submissions after the deadline will fail.
if ( Date . now () / 1000 < result . delegatedAttestation . deadline ) {
await astral . eas . submitDelegated ( result . delegatedAttestation );
}
Next: EAS Resolvers Learn how to gate smart contracts with Policy Attestations