Research Preview — Under active development.
Verify Module
The Verify module provides evidence-based verification of location claims. It enables collecting location evidence on client devices, bundling evidence into proofs, and verifying those proofs server-side.
import { AstralSDK } from '@decentralized-geo/astral-sdk' ;
const astral = new AstralSDK ({
chainId: 84532 ,
signer: wallet ,
apiUrl: 'https://api.astral.global'
});
// Evidence collection (client-side)
astral . stamps . collect ( pluginOptions );
astral . stamps . create ( pluginOptions , signals );
astral . stamps . sign ( unsigned , signer );
// Proof construction
astral . proofs . create ( claim , stamps );
// Verification (server-side)
astral . verify . stamp ( stamp );
astral . verify . proof ( proof , options );
Evidence Collection
Methods for collecting and packaging location evidence on the client.
stamps.collect()
Collect raw signals from the environment using a plugin.
astral . stamps . collect (
pluginOptions : PluginOptions
): Promise < RawSignals >
Parameters
Parameter Type Required Description pluginOptions.namestringYes Plugin name: "proofmode" or "witnesschain" pluginOptions.versionstringYes Plugin version (semver) pluginOptions.configobjectNo Plugin-specific configuration
Example
const signals = await astral . stamps . collect ({
name: 'proofmode' ,
version: '0.1.0' ,
config: { timeout: 5000 }
});
stamps.create()
Process raw signals into an unsigned stamp.
astral . stamps . create (
pluginOptions : PluginOptions ,
signals : RawSignals
): Promise < UnsignedStamp >
Parameters
Parameter Type Required Description pluginOptionsPluginOptionsYes Plugin name and version signalsRawSignalsYes Output from collect()
Example
const unsigned = await astral . stamps . create ( pluginOptions , signals );
console . log ( unsigned . location ); // Observed location (LP format)
console . log ( unsigned . temporalFootprint ); // { start, end }
stamps.sign()
Sign an unsigned stamp with a key.
astral . stamps . sign (
unsigned : UnsignedStamp ,
signer : Signer
): Promise < LocationStamp >
Parameters
Parameter Type Required Description unsignedUnsignedStampYes Output from create() signerSignerYes Signing key (ethers Signer or compatible)
Example
const stamp = await astral . stamps . sign ( unsigned , deviceSigner );
// stamp is now ready to include in a proof
Proof Construction
proofs.create()
Bundle a claim with stamps into a location proof.
astral . proofs . create (
claim : LocationClaim ,
stamps : LocationStamp []
): LocationProof
Parameters
Parameter Type Required Description claimLocationClaimYes The location claim stampsLocationStamp[]Yes One or more signed stamps
Example
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: '0x...' },
radius: 100 ,
time: { start: Date . now () / 1000 - 60 , end: Date . now () / 1000 }
};
const proof = astral . proofs . create ( claim , [ stamp ]);
Verification Operations
Methods for verifying location proofs. These run server-side in a TEE.
verify.stamp()
Verify a stamp’s internal validity (no claim assessment).
astral . verify . stamp (
stamp : LocationStamp
): Promise < StampVerificationResult >
Parameters
Parameter Type Required Description stampLocationStampYes The stamp to verify
Example
const result = await astral . verify . stamp ( stamp );
console . log ( result . valid ); // true
console . log ( result . signaturesValid ); // true
console . log ( result . structureValid ); // true
console . log ( result . signalsConsistent ); // true
verify.proof()
Full verification of a location proof against its claim.
astral . verify . proof (
proof : LocationProof ,
options ?: VerifyOptions
): Promise < VerifiedLocationProof >
Parameters
Parameter Type Required Description proofLocationProofYes The proof to verify options.chainIdnumberNo Chain for attestation signing options.submitOnchainbooleanNo Submit attestation onchain (default: false)
Example
const result = await astral . verify . proof ( proof , { chainId: 84532 });
console . log ( result . credibility . confidence ); // 0.85
console . log ( result . uid ); // 0xabc123...
if ( result . credibility . confidence > 0.8 ) {
console . log ( 'High confidence location proof' );
}
Confidence is not probability. A confidence of 0.85 does NOT mean “85% probability the claim is true.” It means “the evidence is reasonably strong.” Calibrating to true probability is future work.
Return Types
StampVerificationResult
interface StampVerificationResult {
valid : boolean ;
signaturesValid : boolean ;
structureValid : boolean ;
signalsConsistent : boolean ;
pluginResult : Record < string , unknown >;
}
VerifiedLocationProof
interface VerifiedLocationProof {
proof : LocationProof ;
credibility : CredibilityAssessment ;
uid : string ;
attester : string ;
timestamp : number ;
chainId ?: number ;
}
CredibilityAssessment
interface CredibilityAssessment {
confidence : number ; // 0-1 (NOT calibrated probability)
stampResults : StampResult [];
correlation ?: CorrelationAssessment ;
dimensions ?: Record < string , number >;
}
interface StampResult {
stampIndex : number ;
plugin : string ;
signaturesValid : boolean ;
structureValid : boolean ;
signalsConsistent : boolean ;
supportsClaim : boolean ;
claimSupportScore : number ;
pluginResult : Record < string , unknown >;
}
interface CorrelationAssessment {
independence : number ; // 0-1
agreement : number ; // 0-1
notes : string [];
}
PluginOptions
interface PluginOptions {
name : string ; // "proofmode" | "witnesschain"
version : string ; // Semantic version
config ?: Record < string , unknown >; // Plugin-specific config
}
LocationClaim
Extends Location Protocol v0.2 with verification-specific fields.
interface LocationClaim {
// Location Protocol fields
lpVersion : string ;
locationType : string ;
location : LocationData ;
srs : string ;
// Verification fields
subject : SubjectIdentifier ;
radius : number ; // Required — meters
time : { start : number ; end : number }; // Unix timestamps (seconds)
eventType ?: string ;
}
SubjectIdentifier
Follows DID pattern.
interface SubjectIdentifier {
scheme : string ; // "eth-address" | "device-pubkey" | "did:web"
value : string ;
}
// Examples:
// { scheme: "eth-address", value: "0x1234..." }
// { scheme: "device-pubkey", value: "0xabcd..." }
LocationStamp
Evidence conforming to Location Protocol for its location data.
interface LocationStamp {
// Location (LP v0.2) — observed location
lpVersion : string ;
locationType : string ;
location : LocationData ;
srs : string ;
// Temporal
temporalFootprint : { start : number ; end : number };
// Plugin
plugin : string ;
pluginVersion : string ;
signals : Record < string , unknown >;
signatures : Signature [];
}
LocationProof
interface LocationProof {
claim : LocationClaim ;
stamps : LocationStamp [];
}
Plugins
Available Plugins
Plugin Environments Evidence Type proofmodeiOS, Android, React Native Hardware attestation, sensor fusion witnesschainNode.js server Network latency, challenger attestations
Plugin-Specific Config
ProofMode:
const signals = await astral . stamps . collect ({
name: 'proofmode' ,
version: '0.1.0' ,
config: {
timeout: 5000 ,
sensors: [ 'accelerometer' , 'gyroscope' ]
}
});
WitnessChain:
const signals = await astral . stamps . collect ({
name: 'witnesschain' ,
version: '0.1.0' ,
config: {
timeout: 10000 ,
minChallengers: 3
}
});
Complete Example
import { AstralSDK } from '@decentralized-geo/astral-sdk' ;
import { ethers } from 'ethers' ;
// Setup
const provider = new ethers . JsonRpcProvider ( 'https://sepolia.base.org' );
const wallet = new ethers . Wallet ( process . env . PRIVATE_KEY , provider );
const astral = new AstralSDK ({
chainId: 84532 ,
signer: wallet ,
apiUrl: 'https://api.astral.global'
});
// 1. Collect evidence on device
const pluginOptions = { name: 'proofmode' , version: '0.1.0' };
const signals = await astral . stamps . collect ( pluginOptions );
const unsigned = await astral . stamps . create ( pluginOptions , signals );
const stamp = await astral . stamps . sign ( unsigned , wallet );
// 2. Create claim
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: wallet . address },
radius: 100 ,
time: { start: Date . now () / 1000 - 60 , end: Date . now () / 1000 }
};
// 3. Bundle into proof
const proof = astral . proofs . create ( claim , [ stamp ]);
// 4. Verify
const result = await astral . verify . proof ( proof , { chainId: 84532 });
console . log ( 'Confidence:' , result . credibility . confidence );
console . log ( 'Attestation UID:' , result . uid );
// Check confidence threshold
if ( result . credibility . confidence > 0.8 ) {
console . log ( 'High confidence - proof accepted' );
}
Multi-Stamp Example
// Collect from multiple independent plugins
const proofmodeStamp = await collectAndSign ({ name: 'proofmode' , version: '0.1.0' });
const witnessStamp = await collectAndSign ({ name: 'witnesschain' , version: '0.1.0' });
// Bundle into proof with multiple stamps
const proof = astral . proofs . create ( claim , [ proofmodeStamp , witnessStamp ]);
// Verify — cross-correlation increases confidence
const result = await astral . verify . proof ( proof );
console . log ( 'Confidence:' , result . credibility . confidence ); // Higher
console . log ( 'Independence:' , result . credibility . correlation . independence ); // 0.95
console . log ( 'Agreement:' , result . credibility . correlation . agreement ); // 0.88
Key principle : Independent, corroborating evidence increases confidence. Redundant stamps from the same system don’t add confidence — but they don’t subtract either.
API Reference: Verify View the HTTP API documentation