diff --git a/docs/fdc/reference/IAddressValidity.mdx b/docs/fdc/reference/IAddressValidity.mdx
index 4384b66f..747edee1 100644
--- a/docs/fdc/reference/IAddressValidity.mdx
+++ b/docs/fdc/reference/IAddressValidity.mdx
@@ -4,6 +4,10 @@ sidebar_position: 6
description: Assert whether a string represents a valid address.
---
+import CodeBlock from "@theme/CodeBlock";
+import AddressVerifier from "!!raw-loader!/examples/developer-hub-solidity/AddressVerifier.sol";
+import Remix from "@site/src/components/remix";
+
Assert whether a string represents a valid address on an external blockchain.
Sourced from `IAddressValidity.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IAddressValidity.sol).
@@ -142,62 +146,7 @@ struct ResponseBody {
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IAddressValidity.sol";
-
-contract AddressVerifier {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_ADDRESS_VALIDITY = 0x0500000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Request address validation
- function requestAddressValidation(string calldata _address) external payable {
- // Create request body
- IAddressValidity.RequestBody memory requestBody = IAddressValidity.RequestBody({
- addressStr: _address
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_ADDRESS_VALIDITY,
- SOURCE_ID_BTC,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided proof
- function verifyAddressProof(IAddressValidity.Proof calldata _proof) external view returns (
- bool isValid,
- string memory standardAddress,
- bytes32 standardAddressHash
- ) {
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyAddressValidity(_proof);
-
- if (proofVerified) {
- // Extract data from the verified proof
- isValid = _proof.data.responseBody.isValid;
- standardAddress = _proof.data.responseBody.standardAddress;
- standardAddressHash = _proof.data.responseBody.standardAddressHash;
- }
-
- return (isValid, standardAddress, standardAddressHash);
- }
-}
-```
+
+ {AddressVerifier}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IBalanceDecreasingTransaction.mdx b/docs/fdc/reference/IBalanceDecreasingTransaction.mdx
index e8880e09..dbdd1b48 100644
--- a/docs/fdc/reference/IBalanceDecreasingTransaction.mdx
+++ b/docs/fdc/reference/IBalanceDecreasingTransaction.mdx
@@ -4,6 +4,10 @@ sidebar_position: 7
description: Detect a transaction that decreases an address balance.
---
+import CodeBlock from "@theme/CodeBlock";
+import LockMonitor from "!!raw-loader!/examples/developer-hub-solidity/LockMonitor.sol";
+import Remix from "@site/src/components/remix";
+
An interface to detect transactions that decrease the balance of a specific address or are signed by that address on external blockchains.
Sourced from `IBalanceDecreasingTransaction.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IBalanceDecreasingTransaction.sol).
@@ -239,75 +243,7 @@ Response body containing details about the balance decreasing transaction.
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IBalanceDecreasingTransaction.sol";
-
-contract LockMonitor {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_BALANCE_DECREASING = 0x0200000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
-
- mapping(bytes32 => bool) public lockedAddresses; // sourceAddressHash => isLocked
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Register an address as locked (should not spend funds)
- function registerLockedAddress(bytes32 sourceAddressHash) external {
- lockedAddresses[sourceAddressHash] = true;
- }
-
- // Request verification of a transaction that might violate lock agreement
- function checkViolation(bytes32 transactionId, bytes32 sourceAddressIndicator) external payable {
- // Create request body
- IBalanceDecreasingTransaction.RequestBody memory requestBody = IBalanceDecreasingTransaction.RequestBody({
- transactionId: transactionId,
- sourceAddressIndicator: sourceAddressIndicator
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_BALANCE_DECREASING,
- SOURCE_ID_BTC,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided proof and take action if a locked address has spent funds
- function verifyViolation(IBalanceDecreasingTransaction.Proof calldata _proof)
- external
- returns (bool isViolation)
- {
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyBalanceDecreasingTransaction(_proof);
-
- if (proofVerified) {
- // Extract the sourceAddressHash
- bytes32 sourceAddressHash = _proof.data.responseBody.sourceAddressHash;
- int256 spentAmount = _proof.data.responseBody.spentAmount;
-
- // Check if this is a locked address and the amount spent is positive
- if (lockedAddresses[sourceAddressHash] && spentAmount > 0) {
- // Take action - e.g., liquidate collateral, notify stakeholders, etc.
- lockedAddresses[sourceAddressHash] = false; // Remove from locked addresses
- return true;
- }
- }
-
- return false;
- }
-}
-```
+
+ {LockMonitor}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IConfirmedBlockHeightExists.mdx b/docs/fdc/reference/IConfirmedBlockHeightExists.mdx
index 7c514af0..8fcf85c8 100644
--- a/docs/fdc/reference/IConfirmedBlockHeightExists.mdx
+++ b/docs/fdc/reference/IConfirmedBlockHeightExists.mdx
@@ -4,6 +4,10 @@ sidebar_position: 8
description: Assert that a block number is confirmed.
---
+import CodeBlock from "@theme/CodeBlock";
+import BlockchainMonitor from "!!raw-loader!/examples/developer-hub-solidity/BlockchainMonitor.sol";
+import Remix from "@site/src/components/remix";
+
An interface to verify that a specified block has been confirmed on an external blockchain and to calculate block production rates.
Sourced from `IConfirmedBlockHeightExists.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol).
@@ -207,79 +211,10 @@ average_block_time = time_elapsed / blocks_produced
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol";
-
-contract BlockchainMonitor {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_CONFIRMED_BLOCK = 0x0200000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Request confirmation of a block
- function requestBlockConfirmation(uint64 blockNumber, uint64 queryWindow) external payable {
- // Create request body
- IConfirmedBlockHeightExists.RequestBody memory requestBody = IConfirmedBlockHeightExists.RequestBody({
- blockNumber: blockNumber,
- queryWindow: queryWindow
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_CONFIRMED_BLOCK,
- SOURCE_ID_BTC,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided proof and calculate block rate
- function verifyBlockAndCalculateRate(IConfirmedBlockHeightExists.Proof calldata _proof)
- external view
- returns (
- bool blockConfirmed,
- uint64 avgBlockTimeSeconds
- )
- {
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyConfirmedBlockHeightExists(_proof);
-
- if (proofVerified) {
- // Extract data for calculation
- uint64 blockNumber = _proof.data.requestBody.blockNumber;
- uint64 blockTimestamp = _proof.data.responseBody.blockTimestamp;
- uint64 lowestNumber = _proof.data.responseBody.lowestQueryWindowBlockNumber;
- uint64 lowestTimestamp = _proof.data.responseBody.lowestQueryWindowBlockTimestamp;
-
- // Calculate average block time
- uint64 blocksProduced = blockNumber - lowestNumber;
- uint64 timeElapsed = blockTimestamp - lowestTimestamp;
-
- if (blocksProduced > 0) {
- avgBlockTimeSeconds = timeElapsed / blocksProduced;
- }
-
- return (true, avgBlockTimeSeconds);
- }
-
- return (false, 0);
- }
-}
-```
+
+ {BlockchainMonitor}
+
+Open example in Remix
## Related Interfaces
diff --git a/docs/fdc/reference/IEVMTransaction.mdx b/docs/fdc/reference/IEVMTransaction.mdx
index 172f67f9..2ce046dc 100644
--- a/docs/fdc/reference/IEVMTransaction.mdx
+++ b/docs/fdc/reference/IEVMTransaction.mdx
@@ -4,6 +4,10 @@ sidebar_position: 9
description: Relay a transaction from an EVM chain.
---
+import CodeBlock from "@theme/CodeBlock";
+import EVMTransactionVerifier from "!!raw-loader!/examples/developer-hub-solidity/EVMTransactionVerifier.sol";
+import Remix from "@site/src/components/remix";
+
An interface to relay and verify transactions from EVM-compatible blockchains.
Sourced from `IEVMTransaction.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IEVMTransaction.sol).
@@ -251,99 +255,7 @@ When working with events, it's important to remember:
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IEVMTransaction.sol";
-
-contract EVMTransactionVerifier {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_EVM_TX = 0x0600000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_ETH = 0x4554480000000000000000000000000000000000000000000000000000000000;
-
- // Event signatures we're interested in
- bytes32 private constant EVENT_TRANSFER = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Request verification of an EVM transaction with specific events
- function requestTransactionVerification(
- bytes32 transactionHash,
- uint16 requiredConfirmations,
- bool includeInput,
- uint32[] calldata eventIndices
- ) external payable {
- // Create request body
- IEVMTransaction.RequestBody memory requestBody = IEVMTransaction.RequestBody({
- transactionHash: transactionHash,
- requiredConfirmations: requiredConfirmations,
- provideInput: includeInput,
- listEvents: eventIndices.length > 0,
- logIndices: eventIndices
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_EVM_TX,
- SOURCE_ID_ETH,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided proof and extract ERC-20 transfer information
- function verifyERC20Transfer(IEVMTransaction.Proof calldata _proof)
- external view
- returns (
- bool success,
- address tokenContract,
- address from,
- address to,
- uint256 amount
- )
- {
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyEVMTransaction(_proof);
-
- if (proofVerified && _proof.data.responseBody.status == 1) {
- // Look for Transfer events in the transaction
- IEVMTransaction.Event[] memory events = _proof.data.responseBody.events;
-
- for (uint i = 0; i < events.length; i++) {
- IEVMTransaction.Event memory evt = events[i];
-
- // Check if this is a Transfer event (topic[0] is the event signature)
- if (evt.topics.length >= 3 && evt.topics[0] == EVENT_TRANSFER) {
- tokenContract = evt.emitterAddress;
-
- // ERC-20 Transfer(address indexed from, address indexed to, uint256 amount)
- // topics[1] is the first indexed parameter (from address)
- // topics[2] is the second indexed parameter (to address)
- // The addresses are padded to 32 bytes, so we need to extract them
- from = address(uint160(uint256(evt.topics[1])));
- to = address(uint160(uint256(evt.topics[2])));
-
- // The amount is in the data field for non-indexed parameters
- // It's a single uint256 value (32 bytes)
- amount = abi.decode(evt.data, (uint256));
-
- return (true, tokenContract, from, to, amount);
- }
- }
- }
-
- return (false, address(0), address(0), address(0), 0);
- }
-}
-```
+
+ {EVMTransactionVerifier.toString()}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IFdcHub.md b/docs/fdc/reference/IFdcHub.md
index a4b48e25..38e2c7b1 100644
--- a/docs/fdc/reference/IFdcHub.md
+++ b/docs/fdc/reference/IFdcHub.md
@@ -4,6 +4,10 @@ sidebar_position: 2
description: Primary interface for interacting with FDC.
---
+import CodeBlock from "@theme/CodeBlock";
+import AddressSolidity from "!!raw-loader!/examples/developer-hub-solidity/AddressSolidity.sol";
+import Remix from "@site/src/components/remix";
+
Primary interface for interacting with the Flare Data Connector (FDC).
Sourced from `IFdcHub.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/IFdcHub.sol).
@@ -127,36 +131,7 @@ event RequestsOffsetSet(
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IAddressValidity.sol";
-
-contract AddressValidator {
- IFdcHub private fdcHub;
-
- constructor(address _fdcHubAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- }
-
- function validateAddress(string memory addressStr, bytes32 sourceId) external payable {
- // Create address validity request
- IAddressValidity.RequestBody memory requestBody = IAddressValidity.RequestBody({
- addressStr: addressStr
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- bytes32(0x05), // attestationType for AddressValidity
- sourceId,
- bytes32(0), // messageIntegrityCode - should be calculated properly
- requestBody
- );
-
- // Submit the request with appropriate fee
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-}
-```
+
+ {AddressSolidity}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IFdcInflationConfigurations.md b/docs/fdc/reference/IFdcInflationConfigurations.md
index 6c0c475d..858847a5 100644
--- a/docs/fdc/reference/IFdcInflationConfigurations.md
+++ b/docs/fdc/reference/IFdcInflationConfigurations.md
@@ -4,6 +4,10 @@ sidebar_position: 5
description: Interface for managing FDC inflation configuration.
---
+import CodeBlock from "@theme/CodeBlock";
+import InflationMonitor from "!!raw-loader!/examples/developer-hub-solidity/InflationMonitor.sol";
+import Remix from "@site/src/components/remix";
+
Interface for managing Flare Data Connector (FDC) inflation configuration.
Sourced from `IFdcInflationConfigurations.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/IFdcInflationConfigurations.sol).
@@ -75,32 +79,7 @@ struct FdcConfiguration {
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcInflationConfigurations.sol";
-
-contract InflationMonitor {
- IFdcHub private fdcHub;
-
- constructor(address _fdcHubAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- }
-
- // Get inflation share for a specific attestation type and source
- function getInflationShare(bytes32 attestationType, bytes32 source) external view returns (uint24) {
- IFdcInflationConfigurations inflationConfigs = fdcHub.fdcInflationConfigurations();
- IFdcInflationConfigurations.FdcConfiguration[] memory configs = inflationConfigs.getFdcConfigurations();
-
- for (uint i = 0; i < configs.length; i++) {
- if (configs[i].attestationType == attestationType && configs[i].source == source) {
- return configs[i].inflationShare;
- }
- }
-
- return 0; // Not found or no inflation share allocated
- }
-}
-```
+
+ {InflationMonitor}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IFdcRequestFeeConfigurations.md b/docs/fdc/reference/IFdcRequestFeeConfigurations.md
index 82ad5e83..237e6c93 100644
--- a/docs/fdc/reference/IFdcRequestFeeConfigurations.md
+++ b/docs/fdc/reference/IFdcRequestFeeConfigurations.md
@@ -4,6 +4,10 @@ sidebar_position: 4
description: Interface for managing FDC request fee configuration.
---
+import CodeBlock from "@theme/CodeBlock";
+import FeeChecker from "!!raw-loader!/examples/developer-hub-solidity/FeeChecker.sol";
+import Remix from "@site/src/components/remix";
+
Interface for managing FDC request fee configuration.
Sourced from `IFdcRequestFeeConfigurations.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/IFdcRequestFeeConfigurations.sol).
@@ -72,34 +76,7 @@ event TypeAndSourceFeeSet(
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcRequestFeeConfigurations.sol";
-
-contract FeeChecker {
- IFdcHub private fdcHub;
- IFdcRequestFeeConfigurations private feeConfigs;
-
- constructor(address _fdcHubAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- feeConfigs = fdcHub.fdcRequestFeeConfigurations();
- }
-
- function checkRequestFee(bytes memory attestationData) external view returns (uint256) {
- // Get the fee required for this attestation request
- return feeConfigs.getRequestFee(attestationData);
- }
-
- function submitRequestWithFee(bytes memory attestationData) external payable {
- // Check if enough fee is provided
- uint256 requiredFee = feeConfigs.getRequestFee(attestationData);
- require(msg.value >= requiredFee, "Insufficient fee");
-
- // Submit the attestation request
- fdcHub.requestAttestation{value: msg.value}(attestationData);
- }
-}
-```
+
+ {FeeChecker}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IFdcVerification.md b/docs/fdc/reference/IFdcVerification.md
index 2f6691f9..59c51bde 100644
--- a/docs/fdc/reference/IFdcVerification.md
+++ b/docs/fdc/reference/IFdcVerification.md
@@ -4,6 +4,10 @@ sidebar_position: 3
description: Interface for verifying FDC requests.
---
+import CodeBlock from "@theme/CodeBlock";
+import AddressSolidity from "!!raw-loader!/examples/developer-hub-solidity/AddressSolidity.sol";
+import Remix from "@site/src/components/remix";
+
Interface for verifying Flare Data Connector (FDC) attestation requests.
Sourced from `IFdcVerification.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/IFdcVerification.sol).
@@ -138,33 +142,7 @@ function verifyReferencedPaymentNonexistence(
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IAddressValidity.sol";
-
-contract AddressValidator {
- IFdcVerification private fdcVerification;
-
- constructor(address _fdcVerificationAddress) {
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Function to verify if an address is valid using a provided proof
- function isAddressValid(IAddressValidity.Proof memory proof) external view returns (bool isValid, string memory standardAddress) {
- bool proofVerified = fdcVerification.verifyAddressValidity(proof);
-
- if (proofVerified) {
- // If proof is valid, extract the response data
- isValid = proof.data.responseBody.isValid;
- standardAddress = proof.data.responseBody.standardAddress;
- return (isValid, standardAddress);
- }
-
- // If proof verification failed
- return (false, "");
- }
-}
-```
+
+ {AddressSolidity}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IPayment.mdx b/docs/fdc/reference/IPayment.mdx
index f4896872..c415c91a 100644
--- a/docs/fdc/reference/IPayment.mdx
+++ b/docs/fdc/reference/IPayment.mdx
@@ -4,6 +4,10 @@ sidebar_position: 10
description: Relay a transaction in native currency.
---
+import CodeBlock from "@theme/CodeBlock";
+import PaymentVerifier from "!!raw-loader!/examples/developer-hub-solidity/PaymentVerifier.sol";
+import Remix from "@site/src/components/remix";
+
An interface to relay and verify payment transactions in native currencies across multiple external blockchains.
Sourced from `IPayment.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IPayment.sol).
@@ -257,89 +261,7 @@ Payment references allow for correlation of payments across chains and facilitat
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IPayment.sol";
-
-contract PaymentVerifier {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_PAYMENT = 0x0100000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
-
- // Store verified payments
- mapping(bytes32 => bool) public verifiedPayments; // transactionId => verified
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Request verification of a payment transaction
- function requestPaymentVerification(
- bytes32 transactionId,
- uint256 inUtxo,
- uint256 utxo
- ) external payable {
- // Create request body
- IPayment.RequestBody memory requestBody = IPayment.RequestBody({
- transactionId: transactionId,
- inUtxo: inUtxo,
- utxo: utxo
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_PAYMENT,
- SOURCE_ID_BTC,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided payment proof
- function verifyPayment(IPayment.Proof calldata _proof)
- external
- returns (
- bool success,
- bytes32 sourceAddressHash,
- bytes32 receivingAddressHash,
- int256 amount,
- bytes32 paymentReference
- )
- {
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyPayment(_proof);
-
- if (proofVerified) {
- // Extract the payment details from the proof
- bytes32 transactionId = _proof.data.requestBody.transactionId;
- IPayment.ResponseBody memory response = _proof.data.responseBody;
-
- // Check if this is a successful payment
- if (response.status == 0) {
- // Store that this transaction has been verified
- verifiedPayments[transactionId] = true;
-
- return (
- true,
- response.sourceAddressHash,
- response.receivingAddressHash,
- response.receivedAmount,
- response.standardPaymentReference
- );
- }
- }
-
- return (false, bytes32(0), bytes32(0), 0, bytes32(0));
- }
-}
-```
+
+ {PaymentVerifier}
+
+Open example in Remix
diff --git a/docs/fdc/reference/IReferencedPaymentNonexistence.mdx b/docs/fdc/reference/IReferencedPaymentNonexistence.mdx
index 145131c2..13f4a795 100644
--- a/docs/fdc/reference/IReferencedPaymentNonexistence.mdx
+++ b/docs/fdc/reference/IReferencedPaymentNonexistence.mdx
@@ -4,6 +4,10 @@ sidebar_position: 11
description: Assert whether an agreed-upon payment has not been made.
---
+import CodeBlock from "@theme/CodeBlock";
+import PaymentDeadlineEnforcer from "!!raw-loader!/examples/developer-hub-solidity/PaymentDeadlineEnforcer.sol";
+import Remix from "@site/src/components/remix";
+
An interface to verify that a specific payment, agreed to be completed by a certain deadline, has **not been made** on an external blockchain.
Sourced from `IReferencedPaymentNonexistence.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IReferencedPaymentNonexistence.sol).
@@ -283,136 +287,7 @@ The standardPaymentReference is critical for this attestation type as it uniquel
## Usage Example
-```solidity
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
-import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IReferencedPaymentNonexistence.sol";
-
-contract PaymentDeadlineEnforcer {
- IFdcHub private fdcHub;
- IFdcVerification private fdcVerification;
-
- bytes32 private constant ATTESTATION_TYPE_PAYMENT_NONEXISTENCE = 0x0400000000000000000000000000000000000000000000000000000000000000;
- bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
-
- struct Agreement {
- bytes32 destinationAddressHash;
- uint256 amount;
- bytes32 paymentReference;
- uint64 startBlockNumber;
- uint64 deadlineBlockNumber;
- uint64 deadlineTimestamp;
- bool checkSourceAddresses;
- bytes32 sourceAddressesRoot;
- bool liquidated;
- }
-
- mapping(uint256 => Agreement) public agreements;
- uint256 public nextAgreementId;
-
- constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
- fdcHub = IFdcHub(_fdcHubAddress);
- fdcVerification = IFdcVerification(_fdcVerificationAddress);
- }
-
- // Create a new payment agreement
- function createAgreement(
- bytes32 destinationAddressHash,
- uint256 amount,
- bytes32 paymentReference,
- uint64 startBlockNumber,
- uint64 deadlineBlockNumber,
- uint64 deadlineTimestamp,
- bool checkSourceAddresses,
- bytes32 sourceAddressesRoot
- ) external returns (uint256 agreementId) {
- require(paymentReference != bytes32(0), "Payment reference cannot be zero");
-
- agreementId = nextAgreementId++;
-
- agreements[agreementId] = Agreement({
- destinationAddressHash: destinationAddressHash,
- amount: amount,
- paymentReference: paymentReference,
- startBlockNumber: startBlockNumber,
- deadlineBlockNumber: deadlineBlockNumber,
- deadlineTimestamp: deadlineTimestamp,
- checkSourceAddresses: checkSourceAddresses,
- sourceAddressesRoot: sourceAddressesRoot,
- liquidated: false
- });
-
- return agreementId;
- }
-
- // Request verification of payment nonexistence for an agreement
- function checkPaymentMissed(uint256 agreementId) external payable {
- Agreement storage agreement = agreements[agreementId];
- require(!agreement.liquidated, "Agreement already liquidated");
-
- // Create request body
- IReferencedPaymentNonexistence.RequestBody memory requestBody = IReferencedPaymentNonexistence.RequestBody({
- minimalBlockNumber: agreement.startBlockNumber,
- deadlineBlockNumber: agreement.deadlineBlockNumber,
- deadlineTimestamp: agreement.deadlineTimestamp,
- destinationAddressHash: agreement.destinationAddressHash,
- amount: agreement.amount,
- standardPaymentReference: agreement.paymentReference,
- checkSourceAddresses: agreement.checkSourceAddresses,
- sourceAddressesRoot: agreement.sourceAddressesRoot
- });
-
- // Encode the full request
- bytes memory encodedRequest = abi.encode(
- ATTESTATION_TYPE_PAYMENT_NONEXISTENCE,
- SOURCE_ID_BTC,
- bytes32(0), // messageIntegrityCode (would need to be calculated properly)
- requestBody
- );
-
- // Submit the request with payment
- fdcHub.requestAttestation{value: msg.value}(encodedRequest);
- }
-
- // Verify a provided proof of payment nonexistence and trigger liquidation
- function verifyMissedPayment(uint256 agreementId, IReferencedPaymentNonexistence.Proof calldata _proof)
- external
- returns (bool liquidated)
- {
- Agreement storage agreement = agreements[agreementId];
- require(!agreement.liquidated, "Agreement already liquidated");
-
- // Verify the proof using FdcVerification
- bool proofVerified = fdcVerification.verifyReferencedPaymentNonexistence(_proof);
-
- if (proofVerified) {
- // Extract request details and validate they match our agreement
- IReferencedPaymentNonexistence.RequestBody memory request = _proof.data.requestBody;
-
- // Verify this proof is for the correct agreement
- require(
- request.minimalBlockNumber == agreement.startBlockNumber &&
- request.deadlineBlockNumber == agreement.deadlineBlockNumber &&
- request.deadlineTimestamp == agreement.deadlineTimestamp &&
- request.destinationAddressHash == agreement.destinationAddressHash &&
- request.amount == agreement.amount &&
- request.standardPaymentReference == agreement.paymentReference,
- "Proof does not match agreement"
- );
-
- // Mark the agreement as liquidated
- agreement.liquidated = true;
-
- // Trigger liquidation logic here
- // ...
-
- return true;
- }
-
- return false;
- }
-}
-```
+
+ {PaymentDeadlineEnforcer}
+
+Open example in Remix
diff --git a/examples/developer-hub-solidity/AddressSolidity.sol b/examples/developer-hub-solidity/AddressSolidity.sol
new file mode 100644
index 00000000..c9806c68
--- /dev/null
+++ b/examples/developer-hub-solidity/AddressSolidity.sol
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IAddressValidity} from "@flarenetwork/flare-periphery-contracts/coston2/IAddressValidity.sol";
+
+interface IAddressRegistry {
+ function registerAddress(
+ IAddressValidity.Proof memory _transaction
+ ) external;
+}
+
+contract AddressRegistry is IAddressRegistry {
+ string[] public verifiedAddresses;
+
+ function registerAddress(
+ IAddressValidity.Proof memory _transaction
+ ) public {
+ // 1. FDC Logic
+ // Check that this AddressValidity has indeed been confirmed by the FDC
+ require(
+ isAddressValidityProofValid(_transaction),
+ "Invalid transaction proof"
+ );
+
+ // 2. Business logic
+ string memory provedAddress = _transaction.data.requestBody.addressStr;
+
+ verifiedAddresses.push(provedAddress);
+ }
+
+ function isAddressValidityProofValid(
+ IAddressValidity.Proof memory transaction
+ ) public view returns (bool) {
+ // Use the library to get the verifier contract and verify that this transaction was proved by state connector
+ IFdcVerification fdc = ContractRegistry.getFdcVerification();
+ return fdc.verifyAddressValidity(transaction);
+ }
+}
diff --git a/examples/developer-hub-solidity/AddressVerifier.sol b/examples/developer-hub-solidity/AddressVerifier.sol
new file mode 100644
index 00000000..1928daa5
--- /dev/null
+++ b/examples/developer-hub-solidity/AddressVerifier.sol
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IAddressValidity} from "@flarenetwork/flare-periphery-contracts/coston2/IAddressValidity.sol";
+
+contract AddressVerifier {
+ // On-chain business logic: stores the verification status of an address string.
+ mapping(string => bool) public isAddressVerified;
+
+ event AddressVerified(
+ string indexed addressStr,
+ string standardAddress,
+ bytes32 standardAddressHash
+ );
+
+ function processAddressProof(
+ IAddressValidity.Proof calldata _proof
+ ) external {
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid address validity proof");
+
+ // 2. Business Logic: Execute actions based on the verified proof data.
+ bool isValid = _proof.data.responseBody.isValid;
+ string calldata originalAddress = _proof.data.requestBody.addressStr;
+
+ // Only take action if the FDC confirms the address is valid.
+ if (isValid) {
+ // Take action: update state and emit an event.
+ isAddressVerified[originalAddress] = true;
+
+ emit AddressVerified(
+ originalAddress,
+ _proof.data.responseBody.standardAddress,
+ _proof.data.responseBody.standardAddressHash
+ );
+ }
+ }
+
+ function isProofValid(
+ IAddressValidity.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyAddressValidity(_proof);
+ }
+}
diff --git a/examples/developer-hub-solidity/BlockchainMonitor.sol b/examples/developer-hub-solidity/BlockchainMonitor.sol
new file mode 100644
index 00000000..5584834c
--- /dev/null
+++ b/examples/developer-hub-solidity/BlockchainMonitor.sol
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IConfirmedBlockHeightExists} from "@flarenetwork/flare-periphery-contracts/coston2/IConfirmedBlockHeightExists.sol";
+
+contract BlockchainMonitor {
+ uint64 public latestAverageBlockTimeSeconds;
+
+ event BlockTimeCalculated(
+ uint64 indexed blockNumber,
+ uint64 averageBlockTime
+ );
+
+ function processBlockHeightProof(
+ IConfirmedBlockHeightExists.Proof calldata _proof
+ ) external {
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid block height proof");
+
+ // 2. Business Logic: Execute actions based on the verified proof data.
+ uint64 blockNumber = _proof.data.requestBody.blockNumber;
+ uint64 blockTimestamp = _proof.data.responseBody.blockTimestamp;
+ uint64 lowestNumber = _proof
+ .data
+ .responseBody
+ .lowestQueryWindowBlockNumber;
+ uint64 lowestTimestamp = _proof
+ .data
+ .responseBody
+ .lowestQueryWindowBlockTimestamp;
+
+ uint64 avgBlockTimeSeconds = 0;
+ if (blockNumber > lowestNumber) {
+ uint64 blocksProduced = blockNumber - lowestNumber;
+ uint64 timeElapsed = blockTimestamp - lowestTimestamp;
+ avgBlockTimeSeconds = timeElapsed / blocksProduced;
+ }
+
+ // Take action: update state and emit an event with the new data.
+ latestAverageBlockTimeSeconds = avgBlockTimeSeconds;
+ emit BlockTimeCalculated(blockNumber, avgBlockTimeSeconds);
+ }
+
+ function isProofValid(
+ IConfirmedBlockHeightExists.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyConfirmedBlockHeightExists(_proof);
+ }
+}
diff --git a/examples/developer-hub-solidity/EVMTransactionVerifier.sol b/examples/developer-hub-solidity/EVMTransactionVerifier.sol
new file mode 100644
index 00000000..106cc56d
--- /dev/null
+++ b/examples/developer-hub-solidity/EVMTransactionVerifier.sol
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IEVMTransaction} from "@flarenetwork/flare-periphery-contracts/coston2/IEVMTransaction.sol";
+
+contract EVMTransactionVerifier {
+ // A struct to hold the data from a verified ERC-20 transfer
+ struct VerifiedTransfer {
+ address tokenContract;
+ address from;
+ address to;
+ uint256 amount;
+ bytes32 transactionHash;
+ }
+
+ // An array to store all transfers verified by this contract
+ VerifiedTransfer[] public verifiedTransfers;
+
+ // The signature of the ERC-20 Transfer event
+ bytes32 private constant EVENT_TRANSFER_SIGNATURE =
+ keccak256(abi.encodePacked("Transfer(address,address,uint256)"));
+
+ event TransferVerified(
+ bytes32 indexed transactionHash,
+ address indexed tokenContract,
+ address from,
+ address to,
+ uint256 amount
+ );
+
+ function processTransactionProof(
+ IEVMTransaction.Proof calldata _proof,
+ address _tokenContract
+ ) external {
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid EVM transaction proof");
+ require(
+ _proof.data.responseBody.status == 1,
+ "Transaction reverted or not found"
+ );
+
+ // 2. Business Logic: Iterate through events to find and record ERC-20 transfers.
+ IEVMTransaction.Event[] memory events = _proof.data.responseBody.events;
+ bytes32 txHash = _proof.data.requestBody.transactionHash;
+
+ for (uint i = 0; i < events.length; i++) {
+ IEVMTransaction.Event memory evt = events[i];
+
+ // Filter for the specific token contract if provided
+ if (
+ _tokenContract != address(0) &&
+ evt.emitterAddress != _tokenContract
+ ) {
+ continue;
+ }
+
+ // Check if the event is an ERC-20 Transfer: Transfer(address,address,uint256)
+ if (
+ evt.topics.length == 3 &&
+ evt.topics[0] == EVENT_TRANSFER_SIGNATURE
+ ) {
+ // Decode the event data
+ address from = address(uint160(uint256(evt.topics[1])));
+ address to = address(uint160(uint256(evt.topics[2])));
+ uint256 amount = abi.decode(evt.data, (uint256));
+
+ // Record the verified transfer
+ verifiedTransfers.push(
+ VerifiedTransfer({
+ tokenContract: evt.emitterAddress,
+ from: from,
+ to: to,
+ amount: amount,
+ transactionHash: txHash
+ })
+ );
+
+ emit TransferVerified(
+ txHash,
+ evt.emitterAddress,
+ from,
+ to,
+ amount
+ );
+ }
+ }
+ }
+
+ function isProofValid(
+ IEVMTransaction.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyEVMTransaction(_proof);
+ }
+}
diff --git a/examples/developer-hub-solidity/FeeChecker.sol b/examples/developer-hub-solidity/FeeChecker.sol
new file mode 100644
index 00000000..70344c8b
--- /dev/null
+++ b/examples/developer-hub-solidity/FeeChecker.sol
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcHub} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcHub.sol";
+import {IFdcRequestFeeConfigurations} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcRequestFeeConfigurations.sol";
+
+contract FeeChecker {
+ function getRequestFee(
+ bytes calldata _attestationData
+ ) external view returns (uint256) {
+ // Use the registry to find the FdcHub
+ IFdcHub fdcHub = ContractRegistry.getFdcHub();
+
+ // From the FdcHub, get the current fee configuration contract
+ IFdcRequestFeeConfigurations feeConfigs = fdcHub
+ .fdcRequestFeeConfigurations();
+
+ // Return the fee for the given request data
+ return feeConfigs.getRequestFee(_attestationData);
+ }
+}
diff --git a/examples/developer-hub-solidity/InflationMonitor.sol b/examples/developer-hub-solidity/InflationMonitor.sol
new file mode 100644
index 00000000..cb9119d9
--- /dev/null
+++ b/examples/developer-hub-solidity/InflationMonitor.sol
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcHub} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcHub.sol";
+import {IFdcInflationConfigurations} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcInflationConfigurations.sol";
+
+contract InflationMonitor {
+ function getInflationShare(
+ bytes32 attestationType,
+ bytes32 source
+ ) external view returns (uint24) {
+ // Fetch the FdcHub from the registry to access other FDC contracts
+ IFdcHub fdcHub = ContractRegistry.getFdcHub();
+
+ // Get the inflation configurations contract
+ IFdcInflationConfigurations inflationConfigs = fdcHub
+ .fdcInflationConfigurations();
+
+ // Retrieve the entire array of configurations
+ IFdcInflationConfigurations.FdcConfiguration[]
+ memory configs = inflationConfigs.getFdcConfigurations();
+
+ // Loop through the array to find the matching configuration
+ for (uint i = 0; i < configs.length; i++) {
+ if (
+ configs[i].attestationType == attestationType &&
+ configs[i].source == source
+ ) {
+ return configs[i].inflationShare;
+ }
+ }
+
+ // Return 0 if no matching configuration is found
+ return 0;
+ }
+}
diff --git a/examples/developer-hub-solidity/LockMonitor.sol b/examples/developer-hub-solidity/LockMonitor.sol
new file mode 100644
index 00000000..03e27776
--- /dev/null
+++ b/examples/developer-hub-solidity/LockMonitor.sol
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IBalanceDecreasingTransaction} from "@flarenetwork/flare-periphery-contracts/coston2/IBalanceDecreasingTransaction.sol";
+
+contract LockMonitor {
+ // Business logic: stores which addresses are being monitored
+ mapping(bytes32 => bool) public lockedAddresses;
+ // Business logic: prevents re-processing the same violation proof
+ mapping(bytes32 => bool) public confirmedViolations;
+
+ event ViolationConfirmed(
+ bytes32 indexed transactionId,
+ bytes32 indexed sourceAddressHash
+ );
+
+ function registerLockedAddress(bytes32 sourceAddressHash) external {
+ lockedAddresses[sourceAddressHash] = true;
+ }
+ function processViolationProof(
+ IBalanceDecreasingTransaction.Proof calldata _proof
+ ) external {
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid transaction proof");
+
+ // 2. Business Logic: Execute actions based on the verified proof data.
+ bytes32 sourceAddressHash = _proof.data.responseBody.sourceAddressHash;
+ int256 spentAmount = _proof.data.responseBody.spentAmount;
+ bytes32 transactionId = _proof.data.requestBody.transactionId;
+
+ // Check if a monitored address spent funds (a violation).
+ if (lockedAddresses[sourceAddressHash] && spentAmount > 0) {
+ require(
+ !confirmedViolations[transactionId],
+ "Violation already confirmed"
+ );
+
+ // Take action: log the violation and update state.
+ confirmedViolations[transactionId] = true;
+ lockedAddresses[sourceAddressHash] = false; // Example: remove from monitoring after violation.
+
+ emit ViolationConfirmed(transactionId, sourceAddressHash);
+ }
+ }
+
+ function isProofValid(
+ IBalanceDecreasingTransaction.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyBalanceDecreasingTransaction(_proof);
+ }
+}
diff --git a/examples/developer-hub-solidity/PaymentDeadlineEnforcer.sol b/examples/developer-hub-solidity/PaymentDeadlineEnforcer.sol
new file mode 100644
index 00000000..a6905350
--- /dev/null
+++ b/examples/developer-hub-solidity/PaymentDeadlineEnforcer.sol
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IReferencedPaymentNonexistence} from "@flarenetwork/flare-periphery-contracts/coston2/IReferencedPaymentNonexistence.sol";
+
+contract PaymentDeadlineEnforcer {
+ struct Agreement {
+ bytes32 destinationAddressHash;
+ uint256 amount;
+ bytes32 paymentReference;
+ uint64 startBlockNumber;
+ uint64 deadlineBlockNumber;
+ uint64 deadlineTimestamp;
+ bool checkSourceAddresses;
+ bytes32 sourceAddressesRoot;
+ bool liquidated;
+ }
+
+ mapping(uint256 => Agreement) public agreements;
+ uint256 public nextAgreementId;
+
+ event AgreementCreated(
+ uint256 indexed agreementId,
+ bytes32 indexed paymentReference
+ );
+ event AgreementLiquidated(
+ uint256 indexed agreementId,
+ bytes32 indexed paymentReference
+ );
+
+ function createAgreement(
+ bytes32 destinationAddressHash,
+ uint256 amount,
+ bytes32 paymentReference,
+ uint64 startBlockNumber,
+ uint64 deadlineBlockNumber,
+ uint64 deadlineTimestamp,
+ bool checkSourceAddresses,
+ bytes32 sourceAddressesRoot
+ ) external returns (uint256 agreementId) {
+ require(
+ paymentReference != bytes32(0),
+ "Payment reference cannot be zero"
+ );
+ agreementId = nextAgreementId++;
+
+ agreements[agreementId] = Agreement({
+ destinationAddressHash: destinationAddressHash,
+ amount: amount,
+ paymentReference: paymentReference,
+ startBlockNumber: startBlockNumber,
+ deadlineBlockNumber: deadlineBlockNumber,
+ deadlineTimestamp: deadlineTimestamp,
+ checkSourceAddresses: checkSourceAddresses,
+ sourceAddressesRoot: sourceAddressesRoot,
+ liquidated: false
+ });
+
+ emit AgreementCreated(agreementId, paymentReference);
+ return agreementId;
+ }
+ function processMissedPaymentProof(
+ uint256 _agreementId,
+ IReferencedPaymentNonexistence.Proof calldata _proof
+ ) external {
+ Agreement storage agreement = agreements[_agreementId];
+ require(!agreement.liquidated, "Agreement already liquidated");
+
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid payment non-existence proof");
+
+ // 2. Business Logic: Ensure the proof corresponds to the correct on-chain agreement.
+ IReferencedPaymentNonexistence.RequestBody memory request = _proof
+ .data
+ .requestBody;
+ require(
+ request.standardPaymentReference == agreement.paymentReference,
+ "Proof reference mismatch"
+ );
+ require(
+ request.destinationAddressHash == agreement.destinationAddressHash,
+ "Proof destination mismatch"
+ );
+ require(request.amount == agreement.amount, "Proof amount mismatch");
+ require(
+ request.deadlineBlockNumber == agreement.deadlineBlockNumber,
+ "Proof deadline block mismatch"
+ );
+ require(
+ request.deadlineTimestamp == agreement.deadlineTimestamp,
+ "Proof deadline timestamp mismatch"
+ );
+
+ // Take action: liquidate the agreement.
+ agreement.liquidated = true;
+ emit AgreementLiquidated(_agreementId, agreement.paymentReference);
+ }
+ function isProofValid(
+ IReferencedPaymentNonexistence.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyReferencedPaymentNonexistence(_proof);
+ }
+}
diff --git a/examples/developer-hub-solidity/PaymentVerifier.sol b/examples/developer-hub-solidity/PaymentVerifier.sol
new file mode 100644
index 00000000..fe0033cf
--- /dev/null
+++ b/examples/developer-hub-solidity/PaymentVerifier.sol
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.25;
+
+import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
+import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";
+import {IPayment} from "@flarenetwork/flare-periphery-contracts/coston2/IPayment.sol";
+
+contract PaymentVerifier {
+ // A struct to store the details of a successfully verified payment.
+ struct VerifiedPayment {
+ bytes32 transactionId;
+ bytes32 sourceAddressHash;
+ bytes32 receivingAddressHash;
+ int256 receivedAmount;
+ bytes32 standardPaymentReference;
+ }
+
+ // A public array to keep a log of all payments verified by this contract.
+ VerifiedPayment[] public verifiedPayments;
+ // A mapping to prevent the same transaction proof from being processed more than once.
+ mapping(bytes32 => bool) public processedTransactions;
+
+ event PaymentVerified(
+ bytes32 indexed transactionId,
+ bytes32 indexed sourceAddressHash,
+ bytes32 indexed receivingAddressHash,
+ int256 receivedAmount,
+ bytes32 standardPaymentReference
+ );
+
+ function processPaymentProof(IPayment.Proof calldata _proof) external {
+ // 1. FDC Logic: Verify the proof's authenticity with the Flare network.
+ require(isProofValid(_proof), "Invalid payment proof");
+
+ // 2. Business Logic: Execute actions based on the verified proof data.
+ bytes32 transactionId = _proof.data.requestBody.transactionId;
+ IPayment.ResponseBody memory response = _proof.data.responseBody;
+
+ // Ensure the payment was successful (status 0) and hasn't been processed before.
+ require(response.status == 0, "Payment status not successful");
+ require(
+ !processedTransactions[transactionId],
+ "Payment already processed"
+ );
+
+ // Take action: update state, store the payment details, and emit an event.
+ processedTransactions[transactionId] = true;
+
+ verifiedPayments.push(
+ VerifiedPayment({
+ transactionId: transactionId,
+ sourceAddressHash: response.sourceAddressHash,
+ receivingAddressHash: response.receivingAddressHash,
+ receivedAmount: response.receivedAmount,
+ standardPaymentReference: response.standardPaymentReference
+ })
+ );
+
+ emit PaymentVerified(
+ transactionId,
+ response.sourceAddressHash,
+ response.receivingAddressHash,
+ response.receivedAmount,
+ response.standardPaymentReference
+ );
+ }
+
+ function isProofValid(
+ IPayment.Proof memory _proof
+ ) public view returns (bool) {
+ IFdcVerification fdcVerification = ContractRegistry
+ .getFdcVerification();
+ return fdcVerification.verifyPayment(_proof);
+ }
+}