Parametric Insurance MGA Implementation Guide with TrustWeave

Building “Atlas Parametric” - An EO-Driven Parametric Insurance MGA

This comprehensive guide shows you how to build your parametric insurance MGA solution using TrustWeave as the trust and integrity foundation. This implementation covers SAR flood, heatwave, solar attenuation, hurricane, and drought parametric products with instant payouts and objective EO triggers.

Executive Summary

What You’re Building:

  • A parametric insurance MGA (Managing General Agent) platform
  • EO-driven triggers (SAR, NDVI, AOD, LST, InSAR)
  • Automated 24-72 hour payouts
  • Multi-provider EO data acceptance
  • Tamper-proof trigger verification
  • Regulatory-compliant audit trails

Why TrustWeave:

  • Trust Foundation: Verifiable Credentials for EO data integrity
  • Multi-Provider Support: Accept data from ESA, Planet, NASA, NOAA without custom integrations
  • Blockchain Anchoring: Tamper-proof trigger records for regulatory compliance
  • Standardization: W3C-compliant format works across all providers
  • Automation: Enable instant payouts with verifiable triggers

Architecture Overview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────────────────────┐
│                    Atlas Parametric MGA Platform                │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  ┌──────────────────┐  ┌──────────────────┐  ┌─────────────────┐  │
│  │  EO Data        │  │  Pricing        │  │  Payout        │  │
│  │  Ingestion      │  │  Engine         │  │  Automation    │  │
│  │  (SAR, NDVI,    │  │  (Actuarial)    │  │  (Banking API) │  │
│  │   AOD, LST)     │  │                 │  │                │  │
│  └────────┬────────┘  └────────┬────────┘  └────────┬───────┘  │
│           │                    │                     │          │
│           └────────────────────┼─────────────────────┘          │
│                                │                                 │
│                    ┌───────────▼────────────┐                   │
│                    │   TrustWeave Trust Layer │                   │
│                    │  ┌──────────────────┐  │                   │
│                    │  │ DID Management   │  │                   │
│                    │  │ VC Issuance      │  │                   │
│                    │  │ VC Verification │  │                   │
│                    │  │ Blockchain Anchor│  │                   │
│                    │  │ Data Integrity  │  │                   │
│                    │  └──────────────────┘  │                   │
│                    └───────────┬────────────┘                   │
│                                │                                 │
│  ┌──────────────────┐  ┌────────▼────────┐  ┌──────────────────┐  │
│  │  Broker Portal  │  │  Trigger       │  │  Reinsurer      │  │
│  │  (Distribution)  │  │  Engine        │  │  Dashboard      │  │
│  └──────────────────┘  └────────────────┘  └──────────────────┘  │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘

Core Components

1. TrustWeave Trust Layer

TrustWeave provides:

  • DID Management: Identity for insurers, EO providers, reinsurers, brokers
  • Verifiable Credentials: EO data wrapped in VCs for integrity
  • Blockchain Anchoring: Tamper-proof trigger records
  • Multi-Provider Support: Accept EO data from any certified provider

2. EO Data Ingestion Pipeline

Processes:

  • Sentinel-1 SAR (flood detection)
  • MODIS/VIIRS LST (heatwave)
  • AOD + irradiance (solar attenuation)
  • NDVI (drought/agriculture)
  • GPM/IMERG (rainfall)
  • InSAR (deformation)

3. Trigger Engine

Evaluates parametric triggers:

  • Real-time EO data ingestion
  • Threshold evaluation
  • Tiered payout calculation
  • Automatic trigger verification

4. Pricing Engine

Actuarial pricing:

  • EO climate archive (20-40 years)
  • Hazard-frequency modeling
  • Geographic risk scoring
  • Reinsurer-approved rates

5. Payout Automation

Automated payouts:

  • KYC/AML integration
  • Banking API integration
  • Reinsurer notification
  • Audit trail generation

Implementation: Product Suite

Product 1: SAR-Based Flood Parametric

Data Sources: Sentinel-1 SAR + DEM Markets: US (NC, SC, FL, GA) Payout Range: $25k - $5M Triggers: Depth thresholds (20cm, 50cm, 1m)

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
package com.atlasparametric.products.flood

import com.trustweave.TrustWeave
import com.trustweave.contract.models.*
import com.trustweave.core.*
import com.trustweave.json.DigestUtils
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import java.time.Instant

/**
 * SAR Flood Parametric Product using Smart Contracts
 *
 * Uses Sentinel-1 SAR data to detect flood depth and trigger automatic payouts
 */
class SarFloodProduct(
    private val TrustWeave: TrustWeave,
    private val eoProviderDid: String
) {

    /**
     * Create a flood insurance contract
     */
    suspend fun createFloodContract(
        insurerDid: String,
        insuredDid: String,
        coverageAmount: Double,
        location: Location
    ): SmartContract {

        val contract = trustWeave.contracts.draft(
            request = ContractDraftRequest(
                contractType = ContractType.Insurance,
                executionModel = ExecutionModel.Parametric(
                    triggerType = TriggerType.EarthObservation,
                    evaluationEngine = "parametric-insurance"
                ),
                parties = ContractParties(
                    primaryPartyDid = insurerDid,
                    counterpartyDid = insuredDid
                ),
                terms = ContractTerms(
                    obligations = listOf(
                        Obligation(
                            id = "payout-obligation",
                            partyDid = insurerDid,
                            description = "Pay out based on flood depth tier",
                            obligationType = ObligationType.PAYMENT
                        )
                    ),
                    conditions = listOf(
                        ContractCondition(
                            id = "flood-threshold-20cm",
                            description = "Flood depth >= 20cm (Tier 1)",
                            conditionType = ConditionType.THRESHOLD,
                            expression = "$.floodDepthCm >= 20"
                        ),
                        ContractCondition(
                            id = "flood-threshold-50cm",
                            description = "Flood depth >= 50cm (Tier 2)",
                            conditionType = ConditionType.THRESHOLD,
                            expression = "$.floodDepthCm >= 50"
                        ),
                        ContractCondition(
                            id = "flood-threshold-100cm",
                            description = "Flood depth >= 100cm (Tier 3)",
                            conditionType = ConditionType.THRESHOLD,
                            expression = "$.floodDepthCm >= 100"
                        )
                    ),
                    jurisdiction = "US",
                    governingLaw = "State of North Carolina"
                ),
                effectiveDate = Instant.now().toString(),
                expirationDate = Instant.now().plusSeconds(365 * 24 * 60 * 60).toString(),
                contractData = buildJsonObject {
                    "productType" to "SarFlood"
                    "coverageAmount" to coverageAmount
                    "location" {
                        "latitude" to location.latitude
                        "longitude" to location.longitude
                        "address" to location.address
                        "region" to location.region
                    }
                    "thresholds" {
                        "tier1Cm" to 20.0
                        "tier2Cm" to 50.0
                        "tier3Cm" to 100.0
                    }
                    "payoutTiers" {
                        "tier1" to 0.25  // 25% of coverage
                        "tier2" to 0.50  // 50% of coverage
                        "tier3" to 1.0   // 100% of coverage
                    }
                }
            )
        ).getOrThrow()

        println("✅ Flood contract draft created: ${contract.id}")
        return contract
    }

    /**
     * Bind contract (issue VC and anchor to blockchain)
     */
    suspend fun bindFloodContract(
        contract: SmartContract,
        insurerDid: String,
        insurerKeyId: String
    ): BoundContract {

        val bound = trustWeave.contracts.bindContract(
            contractId = contract.id,
            issuerDid = insurerDid,
            issuerKeyId = insurerKeyId,
            chainId = "algorand:mainnet"
        ).getOrThrow()

        println("✅ Contract bound: ${bound.credentialId}, anchored: ${bound.anchorRef.txHash}")
        return bound
    }

    /**
     * Process SAR flood data and issue verifiable credential
     */
    suspend fun processSarFloodData(
        location: Location,
        sarData: SarFloodMeasurement,
        timestamp: Instant
    ): Result<VerifiableCredential> = trustweaveCatching {

        // Step 1: Create EO data payload
        val floodData = buildJsonObject {
            put("id", "sar-flood-${location.id}-${timestamp.toEpochMilli()}")
            put("type", "SarFloodMeasurement")
            put("location", buildJsonObject {
                put("latitude", location.latitude)
                put("longitude", location.longitude)
                put("address", location.address)
                put("region", location.region)
            })
            put("measurement", buildJsonObject {
                put("floodDepthCm", sarData.floodDepthCm)
                put("floodAreaSqKm", sarData.floodAreaSqKm)
                put("confidence", sarData.confidence)
                put("source", "Sentinel-1 SAR")
                put("processingMethod", "SAR Flood Extraction")
                put("demUsed", sarData.demUsed)
                put("timestamp", timestamp.toString())
            })
            put("quality", buildJsonObject {
                put("validationStatus", "validated")
                put("dataQuality", sarData.quality)
            })
        }

        // Step 2: Compute data digest for integrity
        val dataDigest = DigestUtils.sha256DigestMultibase(floodData)

        // Step 3: Issue verifiable credential for EO data
        // Note: eoProviderDid is a String (DID value), so we need to create a Did object for resolveDid
        import com.trustweave.core.Did
        val eoProviderDidObj = Did(eoProviderDid)
        val resolution = trustWeave.resolveDid(eoProviderDidObj)
        val eoProviderDoc = when (resolution) {
            is DidResolutionResult.Success -> resolution.document
            else -> throw IllegalStateException("Failed to resolve EO provider DID")
        }
        val eoProviderKeyId = eoProviderDoc.verificationMethod.firstOrNull()?.id?.substringAfter("#")
            ?: throw IllegalStateException("No verification method found")

        val floodIssuanceResult = trustWeave.issue {
            credential {
                id("sar-flood-${location.id}-${timestamp.toEpochMilli()}")
                type("VerifiableCredential", "EarthObservationCredential", "InsuranceOracleCredential", "SarFloodCredential")
                issuer(eoProviderDid)
                subject {
                    id("sar-flood-${location.id}-${timestamp.toEpochMilli()}")
                    "dataType" to "SarFloodMeasurement"
                    "data" to floodData
                    "dataDigest" to dataDigest
                    "provider" to eoProviderDid
                    "timestamp" to timestamp.toString()
                }
                issued(Instant.now())
            }
            by(issuerDid = eoProviderDid, keyId = eoProviderKeyId)
        }
        
        val floodCredential = when (floodIssuanceResult) {
            is IssuanceResult.Success -> floodIssuanceResult.credential
            else -> throw IllegalStateException("Failed to issue flood credential")
        }

        // Step 4: Anchor to blockchain for tamper-proof record
        val anchorResult = trustWeave.blockchains.anchor(
            data = floodCredential,
            serializer = VerifiableCredential.serializer(),
            chainId = "algorand:mainnet"
        )
        
        anchorResult.fold(
            onSuccess = { anchor ->
                println("✅ SAR Flood Credential issued and anchored: ${anchor.ref.txHash}")
            },
            onFailure = { error ->
                throw IllegalStateException("Failed to anchor credential: ${error.message}")
            }
        )

        floodCredential
    }

    /**
     * Execute contract with flood data
     */
    suspend fun executeFloodContract(
        contract: SmartContract,
        floodCredential: VerifiableCredential
    ): ExecutionResult {

        // Extract flood depth from credential
        val credentialSubject = floodCredential.credentialSubject
        val floodDepthCm = credentialSubject.jsonObject["data"]
            ?.jsonObject?.get("measurement")
            ?.jsonObject?.get("floodDepthCm")
            ?.jsonPrimitive?.content?.toDouble()
            ?: error("Flood depth not found in credential")

        // Create execution context with trigger data
        val executionContext = ExecutionContext(
            triggerData = buildJsonObject {
                put("floodDepthCm", floodDepthCm)
                put("credentialId", floodCredential.id)
                put("timestamp", Instant.now().toString())
            }
        )

        // Execute contract
        val result = trustWeave.contracts.executeContract(
            contract = contract,
            executionContext = executionContext
        ).getOrThrow()

        if (result.executed) {
            println("✅ Contract executed! Payout triggered for flood depth: ${floodDepthCm}cm")
            result.outcomes.forEach { outcome ->
                println("   Outcome: ${outcome.description}")
                outcome.monetaryImpact?.let {
                    println("   Amount: ${it.amount} ${it.currency}")
                }
            }
        } else {
            println("⚠️  Contract conditions not met (flood depth: ${floodDepthCm}cm)")
        }

        return result
    }
}

// Data Models
data class Location(
    val id: String,
    val latitude: Double,
    val longitude: Double,
    val address: String,
    val region: String
)

data class SarFloodMeasurement(
    val floodDepthCm: Double,
    val floodAreaSqKm: Double,
    val confidence: Double,
    val demUsed: String,
    val quality: String
)

Product 2: Heatwave Parametric

Data Sources: MODIS LST + ERA5 Markets: GCC (Saudi Arabia, UAE) Triggers: > X°C for Y days Clients: Construction, energy, government

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package com.atlasparametric.products.heatwave

import com.trustweave.TrustWeave
import com.trustweave.core.*
import com.trustweave.json.DigestUtils
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import java.time.Instant
import java.time.Duration

class HeatwaveProduct(
    private val TrustWeave: TrustWeave,
    private val eoProviderDid: String
) {

    /**
     * Process heatwave data from MODIS LST
     */
    suspend fun processHeatwaveData(
        location: Location,
        lstData: List<LstMeasurement>,
        threshold: HeatwaveThreshold
    ): Result<VerifiableCredential> = trustweaveCatching {

        // Calculate consecutive days above threshold
        val consecutiveDays = calculateConsecutiveDays(lstData, threshold.temperatureC)

        val heatwaveData = buildJsonObject {
            put("id", "heatwave-${location.id}-${Instant.now().toEpochMilli()}")
            put("type", "HeatwaveMeasurement")
            put("location", buildJsonObject {
                put("latitude", location.latitude)
                put("longitude", location.longitude)
                put("region", location.region)
            })
            put("measurement", buildJsonObject {
                put("maxTemperatureC", lstData.maxOf { it.temperatureC })
                put("avgTemperatureC", lstData.average { it.temperatureC })
                put("consecutiveDays", consecutiveDays)
                put("thresholdC", threshold.temperatureC)
                put("minDaysRequired", threshold.minDays)
                put("source", "MODIS LST + ERA5")
                put("timestamp", Instant.now().toString())
            })
        }

        val dataDigest = DigestUtils.sha256DigestMultibase(heatwaveData)

        // Resolve DID from string (eoProviderDid is a DID string)
        import com.trustweave.core.Did
        val eoProviderDidObj = Did(eoProviderDid)
        val eoProviderResolution = trustWeave.resolveDid(eoProviderDidObj)
        val eoProviderDoc = when (eoProviderResolution) {
            is DidResolutionResult.Success -> eoProviderResolution.document
            else -> throw IllegalStateException("Failed to resolve EO provider DID")
        }
        val eoProviderKeyId = eoProviderDoc.verificationMethod.firstOrNull()?.id?.substringAfter("#")
            ?: throw IllegalStateException("No verification method found")

        val heatwaveIssuanceResult = trustWeave.issue {
            credential {
                id("heatwave-${location.id}-${Instant.now().toEpochMilli()}")
                type("EarthObservationCredential", "InsuranceOracleCredential", "HeatwaveCredential")
                issuer(eoProviderDid)
                subject {
                    id("heatwave-${location.id}-${Instant.now().toEpochMilli()}")
                    "dataType" to "HeatwaveMeasurement"
                    "data" to heatwaveData
                    "dataDigest" to dataDigest
                    "provider" to eoProviderDid
                    "timestamp" to Instant.now().toString()
                }
                issued(Instant.now())
            }
            by(issuerDid = eoProviderDid, keyId = eoProviderKeyId)
        }
        
        val heatwaveCredential = when (heatwaveIssuanceResult) {
            is IssuanceResult.Success -> heatwaveIssuanceResult.credential
            else -> throw IllegalStateException("Failed to issue heatwave credential")
        }

        // Anchor to blockchain
        val anchorResult = trustWeave.blockchains.anchor(
            data = heatwaveCredential,
            serializer = VerifiableCredential.serializer(),
            chainId = "algorand:mainnet"
        )
        
        anchorResult.fold(
            onSuccess = { anchor ->
                // Credential anchored successfully
            },
            onFailure = { error ->
                throw IllegalStateException("Failed to anchor credential: ${error.message}")
            }
        )

        heatwaveCredential
    }

    /**
     * Create heatwave insurance contract
     */
    suspend fun createHeatwaveContract(
        insurerDid: String,
        insuredDid: String,
        basePayout: Double,
        threshold: HeatwaveThreshold,
        location: Location
    ): SmartContract {

        val contract = trustWeave.contracts.draft(
            request = ContractDraftRequest(
                contractType = ContractType.Insurance,
                executionModel = ExecutionModel.Parametric(
                    triggerType = TriggerType.EarthObservation,
                    evaluationEngine = "parametric-insurance"
                ),
                parties = ContractParties(
                    primaryPartyDid = insurerDid,
                    counterpartyDid = insuredDid
                ),
                terms = ContractTerms(
                    obligations = listOf(
                        Obligation(
                            id = "heatwave-payout",
                            partyDid = insurerDid,
                            description = "Pay out for consecutive days above threshold",
                            obligationType = ObligationType.PAYMENT
                        )
                    ),
                    conditions = listOf(
                        ContractCondition(
                            id = "heatwave-threshold",
                            description = "Temperature >= ${threshold.temperatureC}°C for ${threshold.minDays} days",
                            conditionType = ConditionType.COMPOSITE,
                            expression = "$.consecutiveDays >= ${threshold.minDays} && $.maxTemperatureC >= ${threshold.temperatureC}"
                        )
                    )
                ),
                effectiveDate = Instant.now().toString(),
                expirationDate = Instant.now().plusSeconds(365 * 24 * 60 * 60).toString(),
                contractData = buildJsonObject {
                    put("productType", "Heatwave")
                    put("basePayout", basePayout)
                    put("threshold", buildJsonObject {
                        put("temperatureC", threshold.temperatureC)
                        put("minDays", threshold.minDays)
                    })
                    put("location", buildJsonObject {
                        put("latitude", location.latitude)
                        put("longitude", location.longitude)
                        put("region", location.region)
                    })
                }
            )
        ).getOrThrow()

        return contract
    }

    /**
     * Execute heatwave contract
     */
    suspend fun executeHeatwaveContract(
        contract: SmartContract,
        heatwaveCredential: VerifiableCredential
    ): ExecutionResult {

        val credentialSubject = heatwaveCredential.credentialSubject
        val consecutiveDays = credentialSubject.jsonObject["data"]
            ?.jsonObject?.get("measurement")
            ?.jsonObject?.get("consecutiveDays")
            ?.jsonPrimitive?.content?.toInt()
            ?: error("Consecutive days not found")

        val maxTemp = credentialSubject.jsonObject["data"]
            ?.jsonObject?.get("measurement")
            ?.jsonObject?.get("maxTemperatureC")
            ?.jsonPrimitive?.content?.toDouble()
            ?: error("Max temperature not found")

        val executionContext = ExecutionContext(
            triggerData = buildJsonObject {
                put("consecutiveDays", consecutiveDays)
                put("maxTemperatureC", maxTemp)
                put("credentialId", heatwaveCredential.id)
            }
        )

        return trustWeave.contracts.executeContract(
            contract = contract,
            executionContext = executionContext
        ).getOrThrow()
    }

    private fun calculateConsecutiveDays(
        lstData: List<LstMeasurement>,
        thresholdC: Double
    ): Int {
        var maxConsecutive = 0
        var currentConsecutive = 0

        for (measurement in lstData.sortedBy { it.timestamp }) {
            if (measurement.temperatureC > thresholdC) {
                currentConsecutive++
                maxConsecutive = maxOf(maxConsecutive, currentConsecutive)
            } else {
                currentConsecutive = 0
            }
        }

        return maxConsecutive
    }
}

data class LstMeasurement(
    val temperatureC: Double,
    val timestamp: Instant
)

data class HeatwaveThreshold(
    val temperatureC: Double,
    val minDays: Int
)

data class HeatwavePolicy(
    val id: String,
    val location: Location,
    val threshold: HeatwaveThreshold,
    val basePayout: Double,
    val dailyIncrement: Double
)

Product 3: Solar Attenuation Parametric

Data Sources: AOD (MODIS, VIIRS) + Irradiance (CERES) Markets: GCC (Solar farms) Triggers: >30% irradiance drop Clients: ACWA Power, NEOM, UAE utilities

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package com.atlasparametric.products.solar

import com.trustweave.TrustWeave
import com.trustweave.core.*
import com.trustweave.json.DigestUtils
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import java.time.Instant

class SolarAttenuationProduct(
    private val TrustWeave: TrustWeave,
    private val eoProviderDid: String
) {

    /**
     * Process solar attenuation data
     */
    suspend fun processSolarAttenuation(
        location: Location,
        aodData: AodMeasurement,
        irradianceData: IrradianceMeasurement
    ): Result<VerifiableCredential> = trustweaveCatching {

        // Calculate attenuation percentage
        val baselineIrradiance = irradianceData.baselineWattPerSqM
        val currentIrradiance = irradianceData.currentWattPerSqM
        val attenuationPercent = ((baselineIrradiance - currentIrradiance) / baselineIrradiance) * 100.0

        val solarData = buildJsonObject {
            put("id", "solar-attenuation-${location.id}-${Instant.now().toEpochMilli()}")
            put("type", "SolarAttenuationMeasurement")
            put("location", buildJsonObject {
                put("latitude", location.latitude)
                put("longitude", location.longitude)
                put("solarFarmId", location.solarFarmId)
            })
            put("measurement", buildJsonObject {
                put("aod", aodData.aodValue)
                put("baselineIrradiance", baselineIrradiance)
                put("currentIrradiance", currentIrradiance)
                put("attenuationPercent", attenuationPercent)
                put("source", "MODIS/VIIRS AOD + CERES Irradiance")
                put("timestamp", Instant.now().toString())
            })
        }

        val dataDigest = DigestUtils.sha256DigestMultibase(solarData)

        // Resolve DID from string (eoProviderDid is a DID string)
        import com.trustweave.core.Did
        val eoProviderDidObj = Did(eoProviderDid)
        val eoProviderResolution = trustWeave.resolveDid(eoProviderDidObj)
        val eoProviderDoc = when (eoProviderResolution) {
            is DidResolutionResult.Success -> eoProviderResolution.document
            else -> throw IllegalStateException("Failed to resolve EO provider DID")
        }
        val eoProviderKeyId = eoProviderDoc.verificationMethod.firstOrNull()?.id?.substringAfter("#")
            ?: throw IllegalStateException("No verification method found")

        val solarIssuanceResult = trustWeave.issue {
            credential {
                id("solar-attenuation-${location.id}-${Instant.now().toEpochMilli()}")
                type("EarthObservationCredential", "InsuranceOracleCredential", "SolarAttenuationCredential")
                issuer(eoProviderDid)
                subject {
                    id("solar-attenuation-${location.id}-${Instant.now().toEpochMilli()}")
                    "dataType" to "SolarAttenuationMeasurement"
                    "data" to solarData
                    "dataDigest" to dataDigest
                    "provider" to eoProviderDid
                    "timestamp" to Instant.now().toString()
                }
                issued(Instant.now())
            }
            by(issuerDid = eoProviderDid, keyId = eoProviderKeyId)
        }
        
        val solarCredential = when (solarIssuanceResult) {
            is IssuanceResult.Success -> solarIssuanceResult.credential
            else -> throw IllegalStateException("Failed to issue solar credential")
        }

        // Anchor to blockchain
        val anchorResult = trustWeave.blockchains.anchor(
            data = solarCredential,
            serializer = VerifiableCredential.serializer(),
            chainId = "algorand:mainnet"
        )
        
        anchorResult.fold(
            onSuccess = { anchor ->
                // Credential anchored successfully
            },
            onFailure = { error ->
                throw IllegalStateException("Failed to anchor credential: ${error.message}")
            }
        )

        solarCredential
    }

    /**
     * Evaluate solar attenuation trigger
     */
    suspend fun evaluateSolarTrigger(
        policy: SolarPolicy,
        solarCredential: VerifiableCredential
    ): TriggerResult {

        val verification = trustWeave.verify {
            credential(solarCredential)
        }
        when (verification) {
            is VerificationResult.Valid -> {
                // Credential is valid, continue
            }
            is VerificationResult.Invalid -> {
                return TriggerResult(triggered = false, reason = "Credential invalid: ${verification.reason}")
            }
        }

        val credentialSubject = solarCredential.credentialSubject
        val attenuationPercent = credentialSubject.jsonObject["data"]
            ?.jsonObject?.get("measurement")
            ?.jsonObject?.get("attenuationPercent")
            ?.jsonPrimitive?.content?.toDouble()
            ?: return TriggerResult(triggered = false, reason = "Attenuation not found")

        val thresholdPercent = policy.thresholdPercent

        if (attenuationPercent < thresholdPercent) {
            return TriggerResult(
                triggered = false,
                reason = "Attenuation ($attenuationPercent%) below threshold ($thresholdPercent%)"
            )
        }

        // Calculate payout based on attenuation severity
        val excessAttenuation = attenuationPercent - thresholdPercent
        val payoutAmount = when {
            excessAttenuation >= 20 -> policy.coverageAmount * 1.0  // Full payout
            excessAttenuation >= 10 -> policy.coverageAmount * 0.75
            else -> policy.coverageAmount * 0.50
        }

        return TriggerResult(
            triggered = true,
            attenuationPercent = attenuationPercent,
            payoutAmount = payoutAmount,
            dataCredentialId = solarCredential.id
        )
    }
}

data class AodMeasurement(
    val aodValue: Double,
    val timestamp: Instant
)

data class IrradianceMeasurement(
    val baselineWattPerSqM: Double,
    val currentWattPerSqM: Double,
    val timestamp: Instant
)

data class SolarPolicy(
    val id: String,
    val location: Location,
    val thresholdPercent: Double = 30.0,
    val coverageAmount: Double
)

Complete Workflow Example

Complete Flood Insurance Workflow with Smart Contracts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
suspend fun completeFloodInsuranceWorkflow() {
    // Step 1: Initialize TrustWeave
    val trustWeave = TrustWeave.build {
        factories(
            kmsFactory = TestkitKmsFactory(),
            didMethodFactory = TestkitDidMethodFactory()
        )
        keys { provider("inMemory"); algorithm("Ed25519") }
        did { method("key") { algorithm("Ed25519") } }
        blockchains {
            "algorand:mainnet" to algorandClient
        }
    }

    // Step 2: Create DIDs for parties
    import com.trustweave.trust.types.DidCreationResult
    import com.trustweave.trust.types.DidResolutionResult
    import com.trustweave.trust.types.IssuanceResult
    import com.trustweave.trust.types.VerificationResult
    
    val insurerDidResult = trustWeave.createDid { method("key") }
    val insurerDid = when (insurerDidResult) {
        is DidCreationResult.Success -> insurerDidResult.did
        else -> throw IllegalStateException("Failed to create insurer DID")
    }
    
    val insuredDidResult = trustWeave.createDid { method("key") }
    val insuredDid = when (insuredDidResult) {
        is DidCreationResult.Success -> insuredDidResult.did
        else -> throw IllegalStateException("Failed to create insured DID")
    }
    
    val eoProviderDidResult = trustWeave.createDid { method("key") }
    val eoProviderDid = when (eoProviderDidResult) {
        is DidCreationResult.Success -> eoProviderDidResult.did
        else -> throw IllegalStateException("Failed to create EO provider DID")
    }
    
    val insurerResolution = trustWeave.resolveDid(insurerDid)
    val insurerDoc = when (insurerResolution) {
        is DidResolutionResult.Success -> insurerResolution.document
        else -> throw IllegalStateException("Failed to resolve insurer DID")
    }
    val insurerKeyId = insurerDoc.verificationMethod.firstOrNull()?.id?.substringAfter("#")
        ?: throw IllegalStateException("No key found")

    // Step 3: Initialize product
    val floodProduct = SarFloodProduct(trustWeave, eoProviderDid.value)

    // Step 4: Create contract
    val contract = floodProduct.createFloodContract(
        insurerDid = insurerDid.value,
        insuredDid = insuredDid.value,
        coverageAmount = 1_000_000.0,
        location = Location(
            id = "loc-001",
            latitude = 35.2271,
            longitude = -80.8431,
            address = "Charlotte, NC",
            region = "North Carolina"
        )
    )

    // Step 5: Bind contract (issue VC and anchor)
    val bound = floodProduct.bindFloodContract(
        contract = contract,
        insurerDid = insurerDid.value,
        insurerKeyId = insurerKeyId
    )

    // Step 6: Activate contract
    val activeResult = trustWeave.contracts.activateContract(bound.contract.id)
    val active = activeResult.getOrThrow()

    // Step 7: Process EO data (in production, this comes from EO provider)
    val floodCredentialResult = floodProduct.processSarFloodData(
        location = Location(
            id = "loc-001",
            latitude = 35.2271,
            longitude = -80.8431,
            address = "Charlotte, NC",
            region = "North Carolina"
        ),
        sarData = SarFloodMeasurement(
            floodDepthCm = 75.0,
            floodAreaSqKm = 15.5,
            confidence = 0.95,
            demUsed = "SRTM",
            quality = "high"
        ),
        timestamp = Instant.now()
    )
    
    val floodCredential = floodCredentialResult.getOrThrow()

    // Step 8: Execute contract
    val executionResult = floodProduct.executeFloodContract(
        contract = active,
        floodCredential = floodCredential
    )

    // Step 9: Process payout (application-specific)
    if (executionResult.executed) {
        processPayout(executionResult)
    }
}

Complete System Integration

Main Application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.atlasparametric

import com.trustweave.TrustWeave
import com.trustweave.chains.algorand.AlgorandBlockchainAnchorClient
import com.atlasparametric.products.flood.SarFloodProduct
import com.atlasparametric.products.heatwave.HeatwaveProduct
import com.atlasparametric.products.solar.SolarAttenuationProduct
import kotlinx.coroutines.runBlocking

/**
 * Atlas Parametric MGA Platform
 *
 * Main application entry point
 */
class AtlasParametricPlatform {

    private val TrustWeave: TrustWeave
    private val sarFloodProduct: SarFloodProduct
    private val heatwaveProduct: HeatwaveProduct
    private val solarProduct: SolarAttenuationProduct

    init {
        // Initialize TrustWeave with blockchain anchoring
        TrustWeave = TrustWeave.create {
            blockchains {
                "algorand:mainnet" to AlgorandBlockchainAnchorClient(
                    chainId = "algorand:mainnet",
                    apiKey = System.getenv("ALGORAND_API_KEY")
                )
            }
        }

        // Create DIDs for EO providers
        val eoProviderDidResult = runBlocking {
            trustWeave.createDid { method("key") }
        }
        
        val eoProviderDid = when (eoProviderDidResult) {
            is DidCreationResult.Success -> eoProviderDidResult.did
            else -> throw IllegalStateException("Failed to create EO provider DID")
        }

        // Initialize products
        sarFloodProduct = SarFloodProduct(trustWeave, eoProviderDid.value)
        heatwaveProduct = HeatwaveProduct(trustWeave, eoProviderDid.value)
        solarProduct = SolarAttenuationProduct(trustWeave, eoProviderDid.value)
    }

    /**
     * Process EO data and execute contracts
     */
    suspend fun processEoDataAndExecute(
        productType: ProductType,
        eoData: Any,
        contracts: List<SmartContract>
    ): List<ExecutionResult> {

        return when (productType) {
            ProductType.SAR_FLOOD -> {
                val floodData = eoData as SarFloodMeasurement
                processFloodExecutions(floodData, contracts)
            }
            ProductType.HEATWAVE -> {
                val heatData = eoData as List<LstMeasurement>
                processHeatwaveExecutions(heatData, contracts)
            }
            ProductType.SOLAR_ATTENUATION -> {
                val solarData = eoData as Pair<AodMeasurement, IrradianceMeasurement>
                processSolarExecutions(solarData, contracts)
            }
        }
    }

    private suspend fun processFloodExecutions(
        floodData: SarFloodMeasurement,
        contracts: List<SmartContract>
    ): List<ExecutionResult> {

        val results = mutableListOf<ExecutionResult>()

        for (contract in contracts.filter {
            it.contractData.jsonObject["productType"]?.jsonPrimitive?.content == "SarFlood"
        }) {
            // Process SAR data and issue credential
            val location = extractLocation(contract)
            val floodCredentialResult = sarFloodProduct.processSarFloodData(
                location = location,
                sarData = floodData,
                timestamp = Instant.now()
            )
            
            val floodCredential = floodCredentialResult.getOrNull() ?: run {
                println("Failed to process flood data")
                continue
            }

            // Execute contract
            val executionResult = sarFloodProduct.executeFloodContract(
                contract = contract,
                floodCredential = floodCredential
            )

            if (executionResult.executed) {
                // Process payout
                processPayout(executionResult)
            }

            results.add(executionResult)
        }

        return results
    }

    private fun extractLocation(contract: SmartContract): Location {
        val locationData = contract.contractData.jsonObject["location"]?.jsonObject
            ?: error("Location not found in contract")

        return Location(
            id = locationData["address"]?.jsonPrimitive?.content ?: "unknown",
            latitude = locationData["latitude"]?.jsonPrimitive?.content?.toDouble() ?: 0.0,
            longitude = locationData["longitude"]?.jsonPrimitive?.content?.toDouble() ?: 0.0,
            address = locationData["address"]?.jsonPrimitive?.content ?: "",
            region = locationData["region"]?.jsonPrimitive?.content ?: ""
        )
    }

    private suspend fun processPayout(executionResult: ExecutionResult) {
        // Integrate with banking API (Stripe, Plaid, etc.)
        // Extract payout amount from executionResult.outcomes
        executionResult.outcomes.forEach { outcome ->
            outcome.monetaryImpact?.let { amount ->
                // Execute payout via banking API
                println("Processing payout: ${amount.amount} ${amount.currency}")
            }
        }
    }
}

enum class ProductType {
    SAR_FLOOD,
    HEATWAVE,
    SOLAR_ATTENUATION,
    HURRICANE,
    DROUGHT
}

data class PayoutResult(
    val policyId: String,
    val amount: Double,
    val status: String,
    val payoutCredentialId: String,
    val timestamp: Instant
)

Multi-Provider EO Data Acceptance

One of TrustWeave’s key advantages is accepting EO data from multiple providers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
 * Accept EO data from any certified provider
 */
class MultiProviderEoDataService(
    private val TrustWeave: TrustWeave
) {

    private val certifiedProviders = setOf(
        "did:key:esa-provider",
        "did:key:planet-provider",
        "did:key:nasa-provider",
        "did:key:noaa-provider"
    )

    /**
     * Accept EO data credential from any certified provider
     */
    suspend fun acceptEoDataCredential(
        dataCredential: VerifiableCredential
    ): Result<EoData> = trustweaveCatching {

        // Step 1: Verify credential
        val verificationResult = trustWeave.verify {
            credential(dataCredential)
        }
        
        when (verificationResult) {
            is VerificationResult.Valid -> {
                // Credential is valid, continue
            }
            is VerificationResult.Invalid -> {
                error("Credential verification failed: ${verificationResult.errors}")
            }
        }

        // Step 2: Check if provider is certified
        val issuerDid = dataCredential.issuer.firstOrNull()?.id
            ?: error("No issuer found in credential")

        if (!certifiedProviders.contains(issuerDid)) {
            error("Provider $issuerDid is not certified")
        }

        // Step 3: Extract and return data
        val credentialSubject = dataCredential.credentialSubject
        val dataType = credentialSubject.jsonObject["dataType"]?.jsonPrimitive?.content
        val data = credentialSubject.jsonObject["data"]?.jsonObject

        EoData(
            type = dataType ?: "Unknown",
            data = data ?: buildJsonObject {},
            provider = issuerDid,
            credentialId = dataCredential.id
        )
    }
}

data class EoData(
    val type: String,
    val data: JsonObject,
    val provider: String,
    val credentialId: String
)

Broker Portal Integration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 * Broker Portal API
 */
@RestController
@RequestMapping("/api/broker")
class BrokerPortalController(
    private val platform: AtlasParametricPlatform,
    private val pricingEngine: PricingEngine
) {

    /**
     * Get quote for parametric insurance
     */
    @PostMapping("/quote")
    suspend fun getQuote(
        @RequestBody request: QuoteRequest
    ): QuoteResponse {

        val premium = pricingEngine.calculatePremium(
            productType = request.productType,
            location = request.location,
            coverageAmount = request.coverageAmount
        )

        return QuoteResponse(
            premium = premium,
            coverageAmount = request.coverageAmount,
            productType = request.productType
        )
    }

    /**
     * Bind policy
     */
    @PostMapping("/bind")
    suspend fun bindPolicy(
        @RequestBody request: BindRequest
    ): PolicyResponse {

        // Create policy
        val policy = createPolicy(request)

        // Issue policy credential
        val policyCredential = issuePolicyCredential(policy)

        return PolicyResponse(
            policyId = policy.id,
            policyCredentialId = policyCredential.id,
            status = "BOUND"
        )
    }
}

Regulatory Compliance & Audit Trails

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * Audit Trail Service using TrustWeave blockchain anchoring
 */
class AuditTrailService(
    private val TrustWeave: TrustWeave
) {

    /**
     * Record audit event and anchor to blockchain
     */
    suspend fun recordAuditEvent(
        event: AuditEvent
    ): AuditRecord {

        // Create audit record
        val auditRecord = buildJsonObject {
            put("id", event.id)
            put("timestamp", event.timestamp.toString())
            put("eventType", event.type)
            put("actor", event.actor)
            put("resource", event.resource)
            put("details", event.details)
        }

        // Anchor to blockchain for immutability
        val anchorResult = trustWeave.blockchains.anchor(
            data = auditRecord,
            serializer = JsonObject.serializer(),
            chainId = "algorand:mainnet"
        ).getOrThrow()

        return AuditRecord(
            eventId = event.id,
            anchorRef = anchorResult.ref,
            timestamp = event.timestamp
        )
    }

    /**
     * Verify audit record integrity
     */
    suspend fun verifyAuditRecord(
        record: AuditRecord
    ): Boolean {

        // Read from blockchain
        val client = TrustWeave.getBlockchainClient(record.anchorRef.chainId)
            ?: return false

        val anchorResult = client.readPayload(record.anchorRef)

        // Verify integrity
        return anchorResult.payload.jsonObject["id"]?.jsonPrimitive?.content == record.eventId
    }
}

Deployment Strategy

Phase 1: MVP (Weeks 1-6)

  1. Setup TrustWeave
    • Initialize TrustWeave with Algorand or Polygon
    • Create DIDs for EO providers
    • Setup blockchain anchoring
  2. Build SAR Flood Product
    • Implement SAR flood detection
    • Create trigger evaluation logic
    • Build payout automation
  3. Broker Portal MVP
    • Quote generation
    • Policy binding
    • Trigger dashboard

Phase 2: Production (Months 2-12)

  1. Add Heatwave Product
  2. Add Solar Attenuation Product
  3. Multi-provider EO data acceptance
  4. Regulatory compliance features
  5. Reinsurer dashboard

Key Benefits of Using TrustWeave

  1. Standardization: W3C-compliant format works with all EO providers
  2. Trust: Cryptographic proof of data integrity
  3. Multi-Provider: Accept data from ESA, Planet, NASA without custom integrations
  4. Regulatory Compliance: Blockchain-anchored audit trails
  5. Automation: Enable instant payouts with verifiable triggers
  6. Cost Reduction: Eliminate custom API integrations

Next Steps

  1. Review Existing Scenarios:
  2. Explore TrustWeave APIs:
  3. Start Building:
    • Clone TrustWeave repository
    • Follow Quick Start Guide
    • Implement SAR flood product first