### Install Astral SDK Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start.md Installs the Astral SDK using pnpm, npm, or yarn. This is the first step before using any SDK functionality. ```bash pnpm add @decentralized-geo/astral-sdk # or npm/yarn ``` -------------------------------- ### Bash: Setup Test Environment Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Commands to set up the local environment for running tests, including copying an example environment file and adding necessary test credentials. ```bash # Ensure test environment cp .env.example .env.test # Add your test RPC and private key ``` -------------------------------- ### Initialize Astral SDK for Offchain Workflow (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md This code creates an instance of the Astral SDK configured for offchain operations without requiring a wallet initially. It depends on the installed @decentralized-geo/astral-sdk package. Inputs include configuration options like mode and debug; outputs an SDK instance for building attestations. Limitation: No signing capability until a signer is added. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; // Create SDK instance - no wallet required for basic operations const sdk = new AstralSDK({ mode: 'offchain', // Focus on offchain features debug: true // See what's happening under the hood }); ``` -------------------------------- ### Configure Astral SDK with Environment Variables Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Shows how to configure the Astral SDK using environment variables, particularly for on-chain operations. It details the necessary variables in a `.env.local` file (like `TEST_PRIVATE_KEY` and `INFURA_API_KEY`) and how to load and use them when initializing the SDK with ethers.js. ```bash # Required for onchain operations TEST_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef INFURA_API_KEY=your_infura_project_id # Optional configuration ASTRAL_API_URL=https://api.astral-protocol.com SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/your_project_id ``` ```typescript import * as dotenv from 'dotenv'; dotenv.config({ path: '.env.local' }); const sdk = new AstralSDK({ provider: new ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL), signer: new ethers.Wallet(process.env.TEST_PRIVATE_KEY!), defaultChain: 'sepolia' }); ``` -------------------------------- ### Create Offchain Location Attestation with Media Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Creates an off-chain location attestation that includes media attachments, such as images or videos. This example demonstrates attaching a Base64 encoded PNG image. The output shows the media types and the number of media data entries. ```typescript // Base64 encoded image data (1x1 pixel PNG for demo) const imageData = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=='; const attestationWithMedia = await sdk.createOffchainLocationAttestation({ location: [-0.1276, 51.5074], // London coordinates memo: 'Photo evidence from London', media: [ { mediaType: 'image/png', data: imageData } ] }); console.log('Media types:', attestationWithMedia.mediaType); console.log('Media data entries:', attestationWithMedia.mediaData.length); ``` -------------------------------- ### Initialize SDK Extensions Before Usage Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Shows how to properly initialize SDK extensions before using the location attestation features. Essential pattern to avoid 'No extension found for location type' errors. Must be awaited before any attestation operations. ```typescript // Wait for extensions to load before using the SDK await sdk.extensions.ensureInitialized(); ``` -------------------------------- ### Import Astral SDK Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/installation.md Import the AstralSDK class into your project. The example shows how to import using ES Modules and CommonJS, which are standard module systems in JavaScript environments. ```typescript // ES Modules (recommended) import { AstralSDK } from '@decentralized-geo/astral-sdk'; // CommonJS const { AstralSDK } = require('@decentralized-geo/astral-sdk'); ``` -------------------------------- ### Initialize Astral SDK for Onchain Workflow (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md This code sets up the Astral SDK with a provider and signer for onchain operations on Sepolia testnet. Dependencies: @decentralized-geo/astral-sdk and ethers; requires Infura key and test private key. Inputs: RPC URL and private key; outputs configured SDK instance and checks wallet balance. Limitation: Incurs gas costs; needs testnet ETH. ```typescript import { ethers } from 'ethers'; // Setup provider and signer for blockchain interaction const provider = new ethers.JsonRpcProvider('https://sepolia.infura.io/v3/YOUR_INFURA_KEY'); const privateKey = 'YOUR_TEST_PRIVATE_KEY'; // Use a test wallet! const signer = new ethers.Wallet(privateKey, provider); const sdk = new AstralSDK({ provider, signer, defaultChain: 'sepolia', debug: true }); // Check balance before proceeding const balance = await provider.getBalance(signer.address); console.log('Balance:', ethers.formatEther(balance), 'sepETH'); ``` -------------------------------- ### Use GeoJSON Location Format for Attestations Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Demonstrates how to use the currently supported GeoJSON format for building location attestations. It includes examples for Point, Feature, and Polygon types with associated metadata. The output logs the location type of each built attestation. ```typescript // Currently supported: GeoJSON format const geoJsonFormats = [ // Point in Lagos, Nigeria { type: 'Point', coordinates: [3.3792, 6.5244] }, // Feature with metadata in Jakarta { type: 'Feature', properties: { name: 'National Monument', type: 'landmark' }, geometry: { type: 'Point', coordinates: [106.8272, -6.1751] } }, // Polygon boundary around Sydney harbor area { type: 'Polygon', coordinates: [[[ [151.2000, -33.8500], [151.2500, -33.8500], [151.2500, -33.8800], [151.2000, -33.8800], [151.2000, -33.8500] ]]] } ]; // Use GeoJSON format for (const location of geoJsonFormats) { const attestation = await sdk.buildLocationAttestation({ location, memo: `Spatial record: ${location.type || location.geometry?.type} feature` }); console.log('Location type:', attestation.locationType); } ``` -------------------------------- ### Install Astral SDK using Package Managers Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/installation.md Add the Astral SDK to your project using your preferred package manager. Supported managers include pnpm, npm, and yarn. pnpm is recommended for optimal performance. ```bash # Using pnpm (recommended) pnpm add @decentralized-geo/astral-sdk # Using npm npm install @decentralized-geo/astral-sdk # Using yarn yarn add @decentralized-geo/astral-sdk ``` -------------------------------- ### Create and Sign Offchain Location Attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md This code sets up a signer using ethers and creates a signed offchain attestation in one step. Dependencies include @decentralized-geo/astral-sdk and ethers; requires browser wallet like MetaMask for signing. Inputs: location data; outputs a signed attestation with UID and signer info. Limitation: Needs user wallet connection and Sepolia testnet. ```typescript import { ethers } from 'ethers'; // Connect to user's wallet (in browser) const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); // Create SDK with signer const signingSDK = new AstralSDK({ signer, defaultChain: 'sepolia', // Use Sepolia testnet debug: true }); // Create and sign in one step const offchainAttestation = await signingSDK.createOffchainLocationAttestation({ location: [-0.1276, 51.5074], memo: 'My first signed location attestation!' }); console.log('🎉 Signed attestation created!'); console.log('UID:', offchainAttestation.uid); console.log('Signer:', offchainAttestation.signer); ``` -------------------------------- ### Verify Astral SDK Installation Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/installation.md A simple TypeScript code snippet to verify that the Astral SDK has been successfully imported into your project. This confirms the installation and import process. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; console.log('Astral SDK imported successfully!'); ``` -------------------------------- ### Unit Test Setup (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Sets up a unit test environment using Vitest, mocking the ethers provider. Creates an instance of AstralSDK for testing. ```typescript import { vi } from 'vitest'; import { AstralSDK } from '@/core/AstralSDK'; // Mock provider const mockProvider = { request: vi.fn(), getSigner: vi.fn() }; // Test instance const sdk = new AstralSDK({ provider: mockProvider }); ``` -------------------------------- ### Location Attestation Type Safety with TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Demonstrates how to use TypeScript types for location attestations, including input type validation and type guards for handling mixed offchain/onchain attestation types. Shows proper imports, type definitions, and runtime type checking. ```typescript import { LocationAttestationInput, OffchainLocationAttestation, OnchainLocationAttestation, isOffchainLocationAttestation } from '@decentralized-geo/astral-sdk'; // Input type ensures you provide required fields const input: LocationAttestationInput = { location: { type: 'Point', coordinates: [100.5018, 13.7563] }, // Bangkok memo: 'Type-safe spatial record', timestamp: new Date() // Optional but typed }; // Type guards help handle mixed attestation types function handleAttestation(attestation: OffchainLocationAttestation | OnchainLocationAttestation) { if (isOffchainLocationAttestation(attestation)) { // TypeScript knows this is offchain console.log('Signer:', attestation.signer); console.log('Signature:', attestation.signature); } else { // TypeScript knows this is onchain console.log('Transaction:', attestation.txHash); console.log('Block:', attestation.blockNumber); } } ``` -------------------------------- ### Create Onchain Location Attestation Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Creates an on-chain location attestation by submitting a transaction to the blockchain. It requires location coordinates and an optional memo. Outputs include the attestation UID, transaction hash, block number, and a link to view the transaction on Etherscan. ```typescript const onchainAttestation = await sdk.createOnchainLocationAttestation({ location: { type: 'Point', coordinates: [2.3522, 48.8566] // Paris coordinates }, memo: 'Permanent record from the Eiffel Tower' }); console.log('🎉 Onchain attestation created!'); console.log('UID:', onchainAttestation.uid); console.log('Transaction hash:', onchainAttestation.txHash); console.log('Block number:', onchainAttestation.blockNumber); console.log('View on Etherscan:', `https://sepolia.etherscan.io/tx/${onchainAttestation.txHash}`); ``` -------------------------------- ### Create Location Attestation - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/index.md Initialize the Astral SDK with Ethereum provider and default blockchain network, then create an offchain location attestation using decimal coordinates. The example demonstrates basic setup and creates a signed location proof for London coordinates with a memo. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; // Connect to your wallet const sdk = new AstralSDK({ provider: window.ethereum, defaultChain: 'sepolia' }); // Create a location attestation const attestation = await sdk.createOffchainLocationAttestation({ location: [-0.163808, 51.5101], // London coordinates memo: 'Visited Big Ben today!' }); // ✅ Done! You have a cryptographically signed location attestation console.log('Attestation UID:', attestation.uid); ``` -------------------------------- ### Install Astral SDK with npm Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/README.md Installs the Astral SDK package using npm. This is the first step for integrating the SDK into your project. ```bash npm install @decentralized-geo/astral-sdk ``` -------------------------------- ### Secure Private Key Management with Astral SDK and ethers.js Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md This example shows secure methods for managing private keys when initializing the Astral SDK. It highlights the danger of hardcoding keys and demonstrates best practices: using environment variables for server-side applications and relying on wallet connections (like MetaMask) for client-side interactions. This ensures sensitive keys are not exposed in the codebase. ```typescript // ❌ Never hardcode private keys const badSDK = new AstralSDK({ signer: new ethers.Wallet('0x1234567890abcdef...') }); // ✅ Use environment variables for server-side const serverSDK = new AstralSDK({ signer: new ethers.Wallet(process.env.PRIVATE_KEY!) }); // ✅ Use wallet connection for client-side const clientSDK = new AstralSDK({ signer: await provider.getSigner() }); ``` -------------------------------- ### Create Off-Chain Attestation with Express.js Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md This example demonstrates how to create an off-chain location attestation using the Astral SDK within an Express.js API endpoint. It utilizes the `@astral-protocol/sdk` library and requires a private key set as an environment variable. ```typescript import express from 'express'; import { AstralSDK } from '@astral-protocol/sdk'; const app = express(); const sdk = new AstralSDK({ signer: new ethers.Wallet(process.env.PRIVATE_KEY!) }); app.post('/api/attestations', async (req, res) => { try { const { location, memo } = req.body; const attestation = await sdk.createOffchainLocationAttestation({ location, memo, timestamp: new Date() }); res.json({ success: true, uid: attestation.uid, signer: attestation.signer }); } catch (error) { res.status(400).json({ success: false, error: error.message }); } }); ``` -------------------------------- ### Verify Onchain Location Attestation Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Verifies an on-chain location attestation that has already been created. It takes the attestation object as input and returns a verification result indicating if the attestation is valid, the address of the signer, and if it has been revoked. ```typescript const verification = await sdk.verifyOnchainLocationAttestation(onchainAttestation); console.log('Verification result:', { isValid: verification.isValid, attester: verification.signerAddress, revoked: verification.revoked }); ``` -------------------------------- ### Create Onchain Location Attestation - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start.md Creates an onchain location attestation, which is a permanent record on the blockchain. This method requires testnet ETH and uses the same API as the offchain version but with a different method call. ```typescript // Same API, different method - creates permanent blockchain record const onchainAttestation = await astral.createOnchainLocationAttestation({ location: { type: 'Point', coordinates: [-58.3816, -34.6037] // Buenos Aires }, memo: 'Monitoring station deployment coordinates' }); console.log('Transaction hash:', onchainAttestation.txHash); console.log('View on Etherscan:', `https://sepolia.etherscan.io/tx/${onchainAttestation.txHash}`); ``` -------------------------------- ### Build Unsigned Location Attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md This snippet builds an unsigned location attestation structure using the SDK. It requires the Astral SDK instance and location data as input (coordinates, memo, timestamp). Outputs an unsigned attestation object with detected location type and timestamp. Supports multiple location formats; does not include signing. ```typescript // Define your location (multiple formats supported) const locationData = { location: [-0.1276, 51.5074], // London coordinates [longitude, latitude] memo: 'Visited London Eye today!', timestamp: new Date() }; // Build the attestation structure const unsignedAttestation = await sdk.buildLocationAttestation(locationData); console.log('✅ Unsigned attestation created'); console.log('Location type detected:', unsignedAttestation.locationType); console.log('Event timestamp:', new Date(unsignedAttestation.eventTimestamp * 1000)); ``` -------------------------------- ### Basic SDK Setup with Test Wallet (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/configuration.md Initializes the Astral SDK using a randomly generated test wallet. This is suitable for development and testing purposes. It requires the 'ethers' library and '@decentralized-geo/astral-sdk'. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; import { Wallet } from 'ethers'; // Create a test wallet (for production, use your actual wallet) const privateKey = Wallet.createRandom().privateKey; const wallet = new Wallet(privateKey); // Initialize SDK with the signer const sdk = new AstralSDK({ signer: wallet }); ``` -------------------------------- ### Offchain Workflow Example - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/CLAUDE.md Demonstrates how to create, sign, and optionally publish an offchain location attestation using the Astral SDK. It requires an Ethereum provider and a chain ID. ```typescript const sdk = new AstralSDK({ provider: window.ethereum, chainId: 11155111 // Sepolia }); // Create an unsigned proof const unsignedProof = await sdk.buildLocationAttestation({ location: { "type": "Feature", "properties": {}, "geometry": { "coordinates": [ -0.163808, 51.5101 ], "type": "Point" } }, locationType: 'geojson-point', memo: 'Testing offchain workflow' }); // Sign the proof to create an offchain location attestation const offchainProof = await sdk.signOffchainLocationAttestation(unsignedProof); // Optionally publish the proof to Astral's API const publishedProof = await sdk.publishOffchainLocationAttestation(offchainProof); ``` -------------------------------- ### Verify Offchain Location Attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md This snippet verifies the signature of an offchain attestation using the SDK. Requires the signing SDK instance and the attestation object as input. Outputs a verification result with validity status, signer address, or reason for invalidity. Limitation: Only verifies offchain types; assumes prior creation. ```typescript // Verify the signature const verification = await signingSDK.verifyOffchainLocationAttestation(offchainAttestation); if (verification.isValid) { console.log('✅ Signature is valid!'); console.log('Signed by:', verification.signerAddress); } else { console.log('❌ Invalid signature:', verification.reason); } ``` -------------------------------- ### Handle Astral SDK Errors Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Provides a pattern for handling errors that may occur when using the Astral SDK. It differentiates between specific error types like `ValidationError`, `NetworkError`, and `AstralError`, as well as catching unexpected errors. This improves robustness by allowing specific error management. ```typescript import { AstralError, ValidationError, NetworkError } from '@astral-protocol/sdk'; try { const attestation = await sdk.createOffchainLocationAttestation({ location: null, // This will cause a validation error memo: 'Invalid location' }); } catch (error) { if (error instanceof ValidationError) { console.log('❌ Invalid input:', error.message); } else if (error instanceof NetworkError) { console.log('🌐 Network problem:', error.message); } else if (error instanceof AstralError) { console.log('⚠️ SDK error:', error.message); } else { console.log('💥 Unexpected error:', error); } } ``` -------------------------------- ### Import Specific Types from Astral SDK Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/installation.md Import specific types and classes from the Astral SDK for use in your TypeScript projects. This allows for better type checking and autocompletion. ```typescript import { AstralSDK, UnsignedLocationAttestation, OffchainLocationAttestation, OnchainLocationAttestation } from '@decentralized-geo/astral-sdk'; ``` -------------------------------- ### Configure Astral SDK with Chain Name (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Initializes the Astral SDK by providing the default chain name. The SDK will use the corresponding Chain ID for this network. Requires a signer instance. ```typescript const sdkBase = new AstralSDK({ signer, defaultChain: 'base' }); ``` -------------------------------- ### Create Offchain Location Attestation - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start.md Creates an offchain location attestation without requiring blockchain interaction or gas fees. It takes location coordinates and an optional memo, then returns a signed attestation. The signature can be verified using the SDK. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; // Connect to your wallet const astral = new AstralSDK({ provider: window.ethereum, defaultChain: 'sepolia' }); // Create a location attestation const attestation = await astral.createOffchainLocationAttestation({ location: [-0.163808, 51.5101], // London coordinates [lng, lat] memo: 'GPS reading at Westminster Bridge' }); // ✅ Done! You have a cryptographically signed location attestation console.log('Attestation UID:', attestation.uid); console.log('Signed by:', attestation.signer); // Verify it works const verification = await astral.verifyOffchainLocationAttestation(attestation); console.log('Valid signature:', verification.isValid); ``` -------------------------------- ### Onchain Workflow Example - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/CLAUDE.md Illustrates how to create and register an onchain location attestation using the Astral SDK. This process involves building an unsigned proof and then registering it on the blockchain. Requires an Ethereum provider and chain ID. ```typescript const sdk = new AstralSDK({ provider: window.ethereum, chainId: 11155111 // Sepolia }); // Create an unsigned proof const unsignedProof = await sdk.buildLocationAttestation({ location: [12.34, 56.78], locationType: 'coordinates-decimal+lon-lat', memo: 'Testing onchain workflow' }); // Register the proof on-chain const onchainProof = await sdk.registerOnchainLocationAttestation(unsignedProof); ``` -------------------------------- ### Development workflow for offchain to onchain attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/core-concepts/index.md Shows a typical development sequence: start with an offchain attestation, verify it locally, then create an onchain version for production. This pattern helps iterate quickly while preserving a final onchain record. ```typescript // 1. Start with offchain for development const offchainAttestation = await sdk.createOffchainLocationAttestation(data); // 2. Test verification const isValid = await sdk.verifyOffchainLocationAttestation(offchainAttestation); // 3. Move to onchain for production const onchainAttestation = await sdk.createOnchainLocationAttestation(data); ``` -------------------------------- ### Enabling SDK Debug Mode - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/CLAUDE.md Example of how to enable debug mode for the Astral SDK during initialization. This is useful for troubleshooting by providing more verbose logging. ```typescript new AstralSDK({ debug: true }) ``` -------------------------------- ### Access Extension Registry (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/extensions.md Shows how to access and retrieve registered extensions from the Astral SDK instance. It covers getting all location extensions, all media extensions, and specific extensions by their format identifiers. ```typescript import { AstralSDK } from '@astral-sdk/core'; const sdk = new AstralSDK(); // Get all registered location extensions const locationExtensions = sdk.extensions.getAllLocationExtensions(); // Get all registered media extensions const mediaExtensions = sdk.extensions.getAllMediaExtensions(); // Get an extension for a specific format const geoJsonExtension = sdk.extensions.getLocationExtension('geojson'); const jpegExtension = sdk.extensions.getMediaExtension('image/jpeg'); ``` -------------------------------- ### GeoJSON Feature Types for Attestations - TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start.md Demonstrates how to use different GeoJSON feature types (Point, Feature, Polygon) as input for creating location attestations. The SDK supports these formats for spatial records. ```typescript // Currently supported: GeoJSON format const geoJsonExamples = [ // Point in London { type: 'Point', coordinates: [-0.163808, 51.5101] }, // Feature with metadata in Mumbai { type: 'Feature', properties: { name: 'Gateway of India' }, geometry: { type: 'Point', coordinates: [72.8347, 18.9220] } }, // Polygon boundary in Denver { type: 'Polygon', coordinates: [[[ [-104.9903, 39.7392], [-104.9903, 39.7642], [-104.9503, 39.7642], [-104.9503, 39.7392], [-104.9903, 39.7392] ]]] } ]; for (const location of geoJsonExamples) { const attestation = await astral.createOffchainLocationAttestation({ location, memo: `Spatial record using ${location.type} geometry` }); console.log('Created:', attestation.uid); } ``` -------------------------------- ### Preload Astral SDK Extensions for Performance in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md This code snippet demonstrates how to preload Astral SDK extensions to avoid loading delays during high-frequency operations. By calling `sdk.extensions.ensureInitialized()`, you ensure that all necessary extensions are ready before proceeding with tasks like creating multiple attestations concurrently using `Promise.all`. ```typescript // Ensure extensions are loaded before high-frequency operations await sdk.extensions.ensureInitialized(); // Now create attestations without loading delays const attestations = await Promise.all( locations.map(loc => sdk.createOffchainLocationAttestation(loc)) ); ``` -------------------------------- ### Batch Create Offchain Location Attestations (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Efficiently creates multiple offchain location attestations in a single operation. It takes an array of location objects and generates a promise for each, which are then resolved in parallel. Useful for bulk data entry. ```typescript const locations = [ { coords: { type: 'Point', coordinates: [-0.1276, 51.5074] }, name: 'London' }, { coords: { type: 'Point', coordinates: [139.6917, 35.6895] }, name: 'Tokyo' }, { coords: { type: 'Point', coordinates: [-105.0178, 39.7392] }, name: 'Denver' } ]; const attestations = await Promise.all( locations.map(loc => sdk.createOffchainLocationAttestation({ location: loc.coords, memo: `Spatial record at ${loc.name}` }) ) ); console.log(`Created ${attestations.length} attestations`); ``` -------------------------------- ### Build Unsigned Location Attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Shows how to construct an unsigned attestation object using the Astral SDK. This step prepares the attestation data, including location, memo, timestamp, and optional media attachments, before it is signed. The function returns an object containing the attestation's schema fields and event timestamp. ```typescript // Create the attestation structure without signing const unsignedAttestation = await sdk.buildLocationAttestation({ location: { type: 'Point', coordinates: [55.2708, 25.2048] // Dubai }, memo: 'Infrastructure monitoring point', timestamp: new Date(), // Optional: attach media media: [ { mediaType: 'image/jpeg', data: base64ImageData } ] }); console.log('Unsigned attestation built:'); console.log('- Location type:', unsignedAttestation.locationType); console.log('- Event timestamp:', new Date(unsignedAttestation.eventTimestamp * 1000)); console.log('- Schema fields:', { mediaType: unsignedAttestation.mediaType, proofType: unsignedAttestation.proofType }); ``` -------------------------------- ### Sign Offchain Attestation with EIP-712 (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md This snippet demonstrates how to sign a previously built unsigned attestation using the EIP-712 standard via the Astral SDK. It takes the unsigned attestation object and returns a signed attestation containing the UID, signer's address, version, and the cryptographic signature. ```typescript // Sign the unsigned attestation with EIP-712 const signedAttestation = await sdk.signOffchainLocationAttestation(unsignedAttestation); console.log('Signed attestation:'); console.log('- UID:', signedAttestation.uid); console.log('- Signer:', signedAttestation.signer); console.log('- Version:', signedAttestation.version); console.log('- Signature:', signedAttestation.signature); ``` -------------------------------- ### Batch Verification of Offchain Location Attestations (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Verifies multiple offchain location attestations concurrently using `Promise.all`. It processes an array of attestations and categorizes the results into valid and invalid groups, providing a summary count. Useful for verifying bulk data. ```typescript async function verifyBatch(attestations: OffchainLocationAttestation[]) { const results = await Promise.all( attestations.map(attestation => sdk.verifyOffchainLocationAttestation(attestation) ) ); const valid = results.filter(r => r.isValid); const invalid = results.filter(r => !r.isValid); console.log(`${valid.length} valid, ${invalid.length} invalid`); return { valid, invalid }; } ``` -------------------------------- ### Create Offchain Location Attestation with Media Attachments (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Generates an offchain location attestation with associated media files. Supports multiple media types like images, audio, and PDFs, specified by their MIME type and base64 encoded data. This is useful for documenting physical locations with rich media. ```typescript const mediaAttestation = await sdk.createOffchainLocationAttestation({ location: { type: 'Point', coordinates: [12.4964, 41.9028] }, // Rome memo: 'Archaeological site documentation', media: [ { mediaType: 'image/jpeg', data: photoBase64 }, { mediaType: 'audio/mp3', data: audioRecordingBase64 }, { mediaType: 'application/pdf', data: ticketPdfBase64 } ] }); console.log('Media types attached:', mediaAttestation.mediaType); ``` -------------------------------- ### Initialize Astral SDK and Build Location Proof (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/extensions.md Demonstrates creating a new AstralSDK instance and building a location proof using GeoJSON format. The SDK automatically handles extension registration and data formatting. ```typescript import { AstralSDK } from '@astral-sdk/core'; // Create a new SDK instance const sdk = new AstralSDK(); // Build a location proof using GeoJSON format const unsignedProof = await sdk.buildLocationProof({ location: { type: 'Point', coordinates: [12.34, 56.78] }, memo: 'Using GeoJSON format' }); ``` -------------------------------- ### Chain ID Precedence Example (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Demonstrates that when both `chainId` and `defaultChain` are provided during Astral SDK initialization, the `chainId` setting takes precedence. The SDK will log a warning in debug mode if both are specified. ```typescript const sdk = new AstralSDK({ signer, chainId: 42220, // ✅ This will be used defaultChain: 'sepolia' // ⚠️ This will be ignored }); ``` -------------------------------- ### Environment Configuration (.env file) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Sets up environment variables for on-chain and API operations. Includes RPC URLs and private keys. Security note: do not commit sensitive information. ```bash # Required for onchain operations ETHEREUM_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY PRIVATE_KEY=your_test_wallet_private_key # Required for API operations ASTRAL_API_URL=https://api.astral.global # Optional DEBUG=astral:* ``` -------------------------------- ### GeoJSON Coordinate Order in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/getting-started.md Demonstrates proper GeoJSON coordinate formatting with explicit longitude, latitude order. Important for avoiding type errors and ensuring correct spatial data handling. Shows the correct Point geometry structure. ```typescript // Be explicit about GeoJSON coordinate order: [longitude, latitude] const point = { type: 'Point', coordinates: [31.2357, 30.0444] // Cairo: lng, lat }; ``` -------------------------------- ### Running Tests - pnpm Commands Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Provides pnpm commands for executing tests, including running all tests, specific files, watch mode, and generating coverage reports. ```bash # All tests pnpm test # Specific test file pnpm test MyFormat.test.ts # Watch mode pnpm test -- --watch # Coverage pnpm test -- --coverage ``` -------------------------------- ### Implement Signature Caching with ethers.js in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md This TypeScript class, `SignerCache`, demonstrates how to cache an `ethers.Signer` instance to avoid repeated initialization for frequent operations. It uses `ethers.BrowserProvider` to get the signer from `window.ethereum`. This is useful for optimizing interactions with Ethereum wallets in client-side applications. ```typescript // Cache signer for repeated operations class SignerCache { private cachedSigner?: ethers.Signer; async getSigner(): Promise { if (!this.cachedSigner) { const provider = new ethers.BrowserProvider(window.ethereum); this.cachedSigner = await provider.getSigner(); } return this.cachedSigner; } } const signerCache = new SignerCache(); const sdk = new AstralSDK({ signer: await signerCache.getSigner() }); ``` -------------------------------- ### Initialize SDK with Onchain Mode Source: https://context7.com/decentralizedgeo/astral-sdk/llms.txt Sets up the Astral SDK for onchain attestations by connecting to a blockchain provider and wallet. Requires environment variables for API keys and private keys. Checks wallet balance before initialization to ensure sufficient funds for transactions. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; import { ethers } from 'ethers'; import * as dotenv from 'dotenv'; dotenv.config({ path: '.env.local' }); // Create provider connected to blockchain network const provider = new ethers.JsonRpcProvider( `https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}` ); // Create wallet with provider for sending transactions const wallet = new ethers.Wallet(process.env.TEST_PRIVATE_KEY!, provider); // Check balance before initializing const balance = await provider.getBalance(wallet.address); console.log('Wallet address:', wallet.address); console.log('Balance:', ethers.formatEther(balance), 'sepETH'); if (balance === 0n) { throw new Error('No balance! Get sepolia ETH from https://sepoliafaucet.com/'); } // Initialize SDK for onchain attestations const sdk = new AstralSDK({ provider, signer: wallet, chainId: 11155111, // Sepolia testnet mode: 'onchain', debug: true }); await sdk.extensions.ensureInitialized(); console.log('SDK initialized for onchain workflow on Sepolia'); // Output: // Wallet address: 0x1234... // Balance: 0.5 sepETH // SDK initialized for onchain workflow on Sepolia ``` -------------------------------- ### Project File Organization Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Illustrates a recommended directory structure for the Astral SDK project, categorizing code into core logic, specific modules (EAS), extensions, API clients, storage, and utilities. ```directory src/ ├── core/ # Core SDK logic ├── eas/ # EAS-specific code ├── extensions/ # Extension system ├── api/ # External API clients ├── storage/ # Storage adapters └── utils/ # Shared utilities ``` -------------------------------- ### Testing Registration Process - Bash Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/CLAUDE.md Command to run tests specifically targeting the onchain registration process using pnpm. This focuses on test cases that verify the functionality of registering data on the blockchain. ```bash pnpm test -- -t "onchain registration" ``` -------------------------------- ### Create Basic Offchain Location Attestation (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/offchain-workflow.md Demonstrates how to initialize the Astral SDK and create an offchain location attestation. This function bundles the building and signing steps. It requires a wallet connection via ethers.js and accepts chain names or IDs for SDK configuration. The output includes the attestation's unique identifier and signer's address. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; import { ethers } from 'ethers'; // Setup with wallet connection const provider = new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); // Option 1: Using chain name (e.g., 'sepolia', 'celo', 'arbitrum', 'base') const sdk = new AstralSDK({ signer, defaultChain: 'sepolia' }); // Option 2: Using chain ID directly (recommended for explicit chain selection) const sdkCelo = new AstralSDK({ signer, chainId: 42220 // Celo mainnet }); // Create attestation (builds + signs in one step) const attestation = await sdk.createOffchainLocationAttestation({ location: { type: 'Point', coordinates: [-0.1276, 51.5074] }, // London coordinates memo: 'Geocache location verification' }); console.log('Attestation created:', attestation.uid); console.log('Signed by:', attestation.signer); ``` -------------------------------- ### Bash: Pre-submission Checks Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Lists the essential commands to run before submitting a Pull Request, ensuring code quality, type correctness, and passing tests. ```bash # Run all checks: pnpm run lint pnpm run typecheck pnpm test ``` -------------------------------- ### GeoJSON Point and Feature Examples (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/core-concepts/index.md Demonstrates the structure of GeoJSON Point and Feature objects, commonly used for representing single coordinates and geographical features with associated metadata. These are examples of data structures that can be included in location attestations. ```typescript // Point - single coordinate { type: 'Point', coordinates: [-0.1276, 51.5074] } // Feature with metadata { type: 'Feature', properties: { name: 'London Eye' }, geometry: { type: 'Point', coordinates: [-0.1276, 51.5074] } } ``` -------------------------------- ### Get Schema Information - TypeScript Source: https://context7.com/decentralizedgeo/astral-sdk/llms.txt Shows how to retrieve schema UIDs for different blockchain networks (Sepolia, Celo, Base) and get the raw schema definition string that defines the structure of location attestations. Uses the @decentralized-geo/astral-sdk package and requires initialization before schema operations. ```typescript import { AstralSDK } from '@decentralized-geo/astral-sdk'; const sdk = new AstralSDK({ mode: 'offchain' }); try { // Get schema UID for specific chain const sepoliaUID = sdk.getSchemaUID(11155111); // Sepolia const celoUID = sdk.getSchemaUID(42220); // Celo const baseUID = sdk.getSchemaUID(8453); // Base console.log('Schema UIDs:'); console.log('Sepolia:', sepoliaUID); console.log('Celo:', celoUID); console.log('Base:', baseUID); // Get raw schema string const schemaString = sdk.getSchemaString(); console.log('\nSchema definition:', schemaString); // Output: // Schema UIDs: // Sepolia: 0xabcd1234567890... // Celo: 0xdef456789012345... // Base: 0x789012345678901... // // Schema definition: uint256 eventTimestamp,string srs,string locationType,string location,string[] recipeType,bytes[] recipePayload,string[] mediaType,string[] mediaData,string memo } catch (error) { console.error('Failed to get schema info:', error.message); } ``` -------------------------------- ### Bash: Regenerate TypeScript Types Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Command to regenerate TypeScript types, typically used after installing or updating dependencies to ensure type definitions are up-to-date. ```bash # Regenerate types pnpm run build ``` -------------------------------- ### Integration Test Pattern (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Demonstrates an integration test workflow using ethers.js and AstralSDK. Includes setting up a signer and testing off-chain attestation creation and verification. ```typescript describe('Offchain Workflow', () => { let sdk: AstralSDK; beforeEach(async () => { // Use test wallet const provider = new ethers.JsonRpcProvider(process.env.TEST_RPC); const signer = new ethers.Wallet(process.env.TEST_PRIVATE_KEY, provider); sdk = new AstralSDK({ signer }); }); it('creates and verifies attestation', async () => { const attestation = await sdk.createOffchainLocationAttestation({ location: { type: 'Point', coordinates: [0, 0] } }); const result = await sdk.verifyOffchainLocationAttestation(attestation); expect(result.isValid).toBe(true); }); }); ``` -------------------------------- ### GeoJSON Point Example in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/README.md Demonstrates the GeoJSON Point format for representing geographic coordinates, compatible with the Astral SDK. This format is standard for web-based geographic data. ```typescript // Points (coordinates) { type: 'Point', coordinates: [-122.4194, 37.7749] } ``` -------------------------------- ### GeoJSON Polygon Example in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/README.md Illustrates the GeoJSON Polygon format for defining geographic areas, suitable for use with the Astral SDK. This format represents boundaries with an array of coordinate rings. ```typescript // Areas (polygons) { type: 'Polygon', coordinates: [[[-122.4, 37.8], [-122.4, 37.7], [-122.3, 37.7], [-122.4, 37.8]]] } ``` -------------------------------- ### TypeScript Batch vs. Sequential Operations Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Illustrates performance optimization by comparing efficient batch operations using `Promise.all` with less efficient sequential operations in a loop for creating attestations. ```typescript // Good: Batch attestations const attestations = await Promise.all( locations.map(location => sdk.createOffchainLocationAttestation({ location }) ) ); // Avoid: Sequential operations for (const location of locations) { await sdk.createOffchainLocationAttestation({ location }); } ``` -------------------------------- ### Get Schema Information Source: https://context7.com/decentralizedgeo/astral-sdk/llms.txt Retrieves schema UIDs for different blockchain networks and the raw schema string definition. This is useful for verifying and working with attestations on various chains. ```APIDOC ## Get Schema Information ### Description Retrieves schema UIDs for different blockchain networks and the raw schema string definition. ### Method N/A (SDK utility functions) ### Endpoint N/A (Client-side operations) ### Parameters #### Path Parameters - **chainId** (number) - Required - Blockchain network identifier ### Request Example N/A (Function calls with chain IDs) ### Response #### Success Response (200) - **schemaUID** (string) - Unique identifier for the schema on the specified chain - **schemaString** (string) - Raw schema definition #### Response Example { "sepoliaUID": "0xabcd1234567890...", "celoUID": "0xdef456789012345...", "baseUID": "0x789012345678901...", "schemaString": "uint256 eventTimestamp,string srs,string locationType,string location,string[] recipeType,bytes[] recipePayload,string[] mediaType,string[] mediaData,string memo" } ``` -------------------------------- ### Astral SDK Full Configuration Options (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/configuration.md Demonstrates the full range of configuration options for the Astral SDK, including specifying the chain ID, custom API endpoint, and enabling debug logging. Requires a wallet signer. ```typescript const sdk = new AstralSDK({ // Required signer: wallet, // Wallet signer // Optional chainId: 11155111, // Chain ID (11155111 = Sepolia) apiUrl: 'https://api.astral.com', // Custom API endpoint debug: true // Enable debug logging }); ``` -------------------------------- ### Mocking Best Practices (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Shows how to mock external modules like 'ethers' and '@/@/api/AstralApiClient' using Vitest. Useful for isolating components during testing. ```typescript // Mock ethers provider vi.mock('ethers', () => ({ ethers: { JsonRpcProvider: vi.fn(() => mockProvider), Wallet: vi.fn(() => mockSigner) } })); // Mock network requests vi.mock('@/api/AstralApiClient', () => ({ AstralApiClient: vi.fn(() => ({ publishAttestation: vi.fn().mockResolvedValue({ uid: '0x123' }) })) })); ``` -------------------------------- ### SDK Configuration for Offchain Attestations (TypeScript) Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/quick-start/configuration.md Configures the Astral SDK for offchain attestations, which do not require gas. This setup uses a simple wallet without connecting to an Ethereum provider. Requires 'ethers' and '@decentralized-geo/astral-sdk'. ```typescript // Simple wallet without provider - perfect for offchain attestations const wallet = new Wallet(privateKey); const sdk = new AstralSDK({ signer: wallet }); ``` -------------------------------- ### Build Process - TypeScript to JavaScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/docs/guides/development.md Command to compile TypeScript source files into JavaScript output for the NPM package. Shows the expected output structure. ```bash # TypeScript source → JavaScript output pnpm run build # Output structure: dist/ ├── index.js # Transpiled JavaScript ├── index.d.ts # Type declarations └── index.js.map # Source maps ``` -------------------------------- ### GeoJSON Feature Example with Properties in TypeScript Source: https://github.com/decentralizedgeo/astral-sdk/blob/main/README.md Shows the GeoJSON Feature format, which includes geometry and associated properties, for representing places with metadata. This is useful for adding context to geographic data within the Astral SDK. ```typescript // Places with metadata { type: 'Feature', geometry: { type: 'Point', coordinates: [-122.4194, 37.7749] }, properties: { name: 'Moscone Center', event: 'Conference 2024' } } ```