diff --git a/.github/config/ignored-words.txt b/.github/config/ignored-words.txt
index 81fb6fb4..390ae0f0 100644
--- a/.github/config/ignored-words.txt
+++ b/.github/config/ignored-words.txt
@@ -4,4 +4,5 @@ devlop
bU
whats
WNAT
-wNat
\ No newline at end of file
+wNat
+crate
\ No newline at end of file
diff --git a/.github/workflows/spell-check.yml b/.github/workflows/spell-check.yml
index ca90670e..d3c546b2 100644
--- a/.github/workflows/spell-check.yml
+++ b/.github/workflows/spell-check.yml
@@ -14,6 +14,7 @@ on:
- "**/*.html"
- "**/*.rst"
- "!**/*.svg" # Exclude svg files from triggering the workflow
+ - "!**/*.sol"
- "**/*.go"
- "!**/*.sum"
- "!**/*.mod"
diff --git a/docs/ftso/scaling/2-getting-started.mdx b/docs/ftso/scaling/2-getting-started.mdx
index 663b7e72..3af82347 100644
--- a/docs/ftso/scaling/2-getting-started.mdx
+++ b/docs/ftso/scaling/2-getting-started.mdx
@@ -20,7 +20,11 @@ import Remix from "@site/src/components/remix";
import FetchAnchorFeedsJs from "!!raw-loader!/examples/developer-hub-javascript/fetch_anchor_feeds.js";
import FetchAnchorFeedsPy from "!!raw-loader!/examples/developer-hub-python/fetch_anchor_feeds.py";
import FetchAnchorFeedsGo from "!!raw-loader!/examples/developer-hub-go/flare/fetch_anchor_feeds.go";
+import FetchAnchorFeedsRs from "!!raw-loader!/examples/developer-hub-rust/src/bin/fetch_anchor_feeds.rs";
import FetchAndVerifyAnchorOnchainJs from "!!raw-loader!/examples/developer-hub-javascript/fetch_and_verify_anchor_onchain.js";
+import FetchAndVerifyAnchorOnchainPy from "!!raw-loader!/examples/developer-hub-python/fetch_and_verify_anchor_onchain.py";
+import FetchAndVerifyAnchorOnchainRs from "!!raw-loader!/examples/developer-hub-rust/src/bin/fetch_and_verify_anchor_onchain.rs";
+import FetchAndVerifyAnchorOnchainGo from "!!raw-loader!/examples/developer-hub-go/flare/fetch_and_verify_anchor_onchain.go";
import FtsoV2AnchorFeedConsumer from "!!raw-loader!/examples/developer-hub-solidity/FtsoV2AnchorFeedConsumer.sol";
Scaling enables offchain access to anchor feeds by leveraging Flare's network of 100 independent data providers and a robust commit-reveal process every 90 seconds.
@@ -103,6 +107,13 @@ To fetch the feed values for FLR/USD, BTC/USD, and ETH/USD at the latest voting
+
+
+
+ {FetchAnchorFeedsRs}
+
+
+
#### API response structure
@@ -199,3 +210,12 @@ The following example shows how to query feed and proof data from DA Layer and s
{FetchAndVerifyAnchorOnchainJs}
+
+ {FetchAndVerifyAnchorOnchainPy}
+
+
+ {FetchAndVerifyAnchorOnchainRs}
+
+
+ {FetchAndVerifyAnchorOnchainGo}
+
diff --git a/examples/developer-hub-go/build/FtsoV2FeedConsumer.abi b/examples/developer-hub-go/build/FtsoV2FeedConsumer.abi
deleted file mode 100644
index 9992e1c8..00000000
--- a/examples/developer-hub-go/build/FtsoV2FeedConsumer.abi
+++ /dev/null
@@ -1 +0,0 @@
-[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"feedIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFtsoV2CurrentFeedValues","outputs":[{"internalType":"uint256[]","name":"_feedValues","type":"uint256[]"},{"internalType":"int8[]","name":"_decimals","type":"int8[]"},{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"stateMutability":"view","type":"function"}]
\ No newline at end of file
diff --git a/examples/developer-hub-go/coston2/FtsoV2FeedConsumer.go b/examples/developer-hub-go/coston2/FtsoV2FeedConsumer.go
index 9363fba7..9beeb38e 100644
--- a/examples/developer-hub-go/coston2/FtsoV2FeedConsumer.go
+++ b/examples/developer-hub-go/coston2/FtsoV2FeedConsumer.go
@@ -32,7 +32,7 @@ var (
// FtsoV2FeedConsumerMetaData contains all meta data concerning the FtsoV2FeedConsumer contract.
var FtsoV2FeedConsumerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedIndexes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFtsoV2CurrentFeedValues\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_feedValues\",\"type\":\"uint256[]\"},{\"internalType\":\"int8[]\",\"name\":\"_decimals\",\"type\":\"int8[]\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x60806040526040518060600160405280600060ff168152602001600260ff168152602001600960ff16815250600290600361003b92919061017a565b5034801561004857600080fd5b5073ad67fe66660fb8dfe9d6b1b4240d8650e30f60196000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382760fca6040518163ffffffff1660e01b81526004016100f490610246565b602060405180830381865afa158015610111573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013591906102c9565b600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f6565b8280548282559060005260206000209081019282156101bb579160200282015b828111156101ba578251829060ff1690559160200191906001019061019a565b5b5090506101c891906101cc565b5090565b5b808211156101e55760008160009055506001016101cd565b5090565b600082825260208201905092915050565b7f4661737455706461746572000000000000000000000000000000000000000000600082015250565b6000610230600b836101e9565b915061023b826101fa565b602082019050919050565b6000602082019050818103600083015261025f81610223565b9050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102968261026b565b9050919050565b6102a68161028b565b81146102b157600080fd5b50565b6000815190506102c38161029d565b92915050565b6000602082840312156102df576102de610266565b5b60006102ed848285016102b4565b91505092915050565b610845806103056000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063dae2f4bc1461003b578063f601bc8b1461006b575b600080fd5b610055600480360381019061005091906101bb565b61008b565b60405161006291906101f7565b60405180910390f35b6100736100af565b604051610082939291906103be565b60405180910390f35b6002818154811061009b57600080fd5b906000526020600020016000915090505481565b606080600080600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166345a15d3c60026040518263ffffffff1660e01b815260040161011491906104d9565b600060405180830381865afa158015610131573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061015a9190610784565b925092509250828282955095509550505050909192565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61019881610185565b81146101a357600080fd5b50565b6000813590506101b58161018f565b92915050565b6000602082840312156101d1576101d061017b565b5b60006101df848285016101a6565b91505092915050565b6101f181610185565b82525050565b600060208201905061020c60008301846101e8565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61024781610185565b82525050565b6000610259838361023e565b60208301905092915050565b6000602082019050919050565b600061027d82610212565b610287818561021d565b93506102928361022e565b8060005b838110156102c35781516102aa888261024d565b97506102b583610265565b925050600181019050610296565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60008160000b9050919050565b610312816102fc565b82525050565b60006103248383610309565b60208301905092915050565b6000602082019050919050565b6000610348826102d0565b61035281856102db565b935061035d836102ec565b8060005b8381101561038e5781516103758882610318565b975061038083610330565b925050600181019050610361565b5085935050505092915050565b600067ffffffffffffffff82169050919050565b6103b88161039b565b82525050565b600060608201905081810360008301526103d88186610272565b905081810360208301526103ec818561033d565b90506103fb60408301846103af565b949350505050565b600081549050919050565b60008190508160005260206000209050919050565b60008160001c9050919050565b6000819050919050565b600061044d61044883610423565b610430565b9050919050565b6000610460825461043a565b9050919050565b6000600182019050919050565b600061047f82610403565b610489818561021d565b93506104948361040e565b8060005b838110156104cc576104a982610454565b6104b3888261024d565b97506104be83610467565b925050600181019050610498565b5085935050505092915050565b600060208201905081810360008301526104f38184610474565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61054982610500565b810181811067ffffffffffffffff8211171561056857610567610511565b5b80604052505050565b600061057b610171565b90506105878282610540565b919050565b600067ffffffffffffffff8211156105a7576105a6610511565b5b602082029050602081019050919050565b600080fd5b6000815190506105cc8161018f565b92915050565b60006105e56105e08461058c565b610571565b90508083825260208201905060208402830185811115610608576106076105b8565b5b835b81811015610631578061061d88826105bd565b84526020840193505060208101905061060a565b5050509392505050565b600082601f8301126106505761064f6104fb565b5b81516106608482602086016105d2565b91505092915050565b600067ffffffffffffffff82111561068457610683610511565b5b602082029050602081019050919050565b61069e816102fc565b81146106a957600080fd5b50565b6000815190506106bb81610695565b92915050565b60006106d46106cf84610669565b610571565b905080838252602082019050602084028301858111156106f7576106f66105b8565b5b835b81811015610720578061070c88826106ac565b8452602084019350506020810190506106f9565b5050509392505050565b600082601f83011261073f5761073e6104fb565b5b815161074f8482602086016106c1565b91505092915050565b6107618161039b565b811461076c57600080fd5b50565b60008151905061077e81610758565b92915050565b60008060006060848603121561079d5761079c61017b565b5b600084015167ffffffffffffffff8111156107bb576107ba610180565b5b6107c78682870161063b565b935050602084015167ffffffffffffffff8111156107e8576107e7610180565b5b6107f48682870161072a565b92505060406108058682870161076f565b915050925092509256fea2646970667358221220eb33bd14ba21e825dfd87aec9ad44e3f2bb8f9c567df65246a6c05c998d410c764736f6c63430008190033",
+ Bin: "0x608060405260405180606001604052805f60ff168152602001600260ff168152602001600960ff16815250600290600361003a929190610173565b50348015610046575f80fd5b5073ad67fe66660fb8dfe9d6b1b4240d8650e30f60195f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382760fca6040518163ffffffff1660e01b81526004016100f090610238565b602060405180830381865afa15801561010b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061012f91906102b4565b60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102df565b828054828255905f5260205f209081019282156101b2579160200282015b828111156101b1578251829060ff16905591602001919060010190610191565b5b5090506101bf91906101c3565b5090565b5b808211156101da575f815f9055506001016101c4565b5090565b5f82825260208201905092915050565b7f46617374557064617465720000000000000000000000000000000000000000005f82015250565b5f610222600b836101de565b915061022d826101ee565b602082019050919050565b5f6020820190508181035f83015261024f81610216565b9050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102838261025a565b9050919050565b61029381610279565b811461029d575f80fd5b50565b5f815190506102ae8161028a565b92915050565b5f602082840312156102c9576102c8610256565b5b5f6102d6848285016102a0565b91505092915050565b6107f8806102ec5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063dae2f4bc14610038578063f601bc8b14610068575b5f80fd5b610052600480360381019061004d91906101a7565b610088565b60405161005f91906101e1565b60405180910390f35b6100706100a8565b60405161007f93929190610395565b60405180910390f35b60028181548110610097575f80fd5b905f5260205f20015f915090505481565b6060805f805f8060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166345a15d3c60026040518263ffffffff1660e01b815260040161010a91906104a2565b5f60405180830381865afa158015610124573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061014c919061073a565b925092509250828282955095509550505050909192565b5f604051905090565b5f80fd5b5f80fd5b5f819050919050565b61018681610174565b8114610190575f80fd5b50565b5f813590506101a18161017d565b92915050565b5f602082840312156101bc576101bb61016c565b5b5f6101c984828501610193565b91505092915050565b6101db81610174565b82525050565b5f6020820190506101f45f8301846101d2565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61022c81610174565b82525050565b5f61023d8383610223565b60208301905092915050565b5f602082019050919050565b5f61025f826101fa565b6102698185610204565b935061027483610214565b805f5b838110156102a457815161028b8882610232565b975061029683610249565b925050600181019050610277565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f815f0b9050919050565b6102ee816102da565b82525050565b5f6102ff83836102e5565b60208301905092915050565b5f602082019050919050565b5f610321826102b1565b61032b81856102bb565b9350610336836102cb565b805f5b8381101561036657815161034d88826102f4565b97506103588361030b565b925050600181019050610339565b5085935050505092915050565b5f67ffffffffffffffff82169050919050565b61038f81610373565b82525050565b5f6060820190508181035f8301526103ad8186610255565b905081810360208301526103c18185610317565b90506103d06040830184610386565b949350505050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f815f1c9050919050565b5f819050919050565b5f61041a610415836103f4565b6103ff565b9050919050565b5f61042c8254610408565b9050919050565b5f600182019050919050565b5f610449826103d8565b6104538185610204565b935061045e836103e2565b805f5b838110156104955761047282610421565b61047c8882610232565b975061048783610433565b925050600181019050610461565b5085935050505092915050565b5f6020820190508181035f8301526104ba818461043f565b905092915050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61050c826104c6565b810181811067ffffffffffffffff8211171561052b5761052a6104d6565b5b80604052505050565b5f61053d610163565b90506105498282610503565b919050565b5f67ffffffffffffffff821115610568576105676104d6565b5b602082029050602081019050919050565b5f80fd5b5f8151905061058b8161017d565b92915050565b5f6105a361059e8461054e565b610534565b905080838252602082019050602084028301858111156105c6576105c5610579565b5b835b818110156105ef57806105db888261057d565b8452602084019350506020810190506105c8565b5050509392505050565b5f82601f83011261060d5761060c6104c2565b5b815161061d848260208601610591565b91505092915050565b5f67ffffffffffffffff8211156106405761063f6104d6565b5b602082029050602081019050919050565b61065a816102da565b8114610664575f80fd5b50565b5f8151905061067581610651565b92915050565b5f61068d61068884610626565b610534565b905080838252602082019050602084028301858111156106b0576106af610579565b5b835b818110156106d957806106c58882610667565b8452602084019350506020810190506106b2565b5050509392505050565b5f82601f8301126106f7576106f66104c2565b5b815161070784826020860161067b565b91505092915050565b61071981610373565b8114610723575f80fd5b50565b5f8151905061073481610710565b92915050565b5f805f606084860312156107515761075061016c565b5b5f84015167ffffffffffffffff81111561076e5761076d610170565b5b61077a868287016105f9565b935050602084015167ffffffffffffffff81111561079b5761079a610170565b5b6107a7868287016106e3565b92505060406107b886828701610726565b915050925092509256fea2646970667358221220ec64100f9062f5749e6541df584b0fc7e497728a2d80fa8301fb24b3b1e2692c64736f6c63430008190033",
}
// FtsoV2FeedConsumerABI is the input ABI used to generate the binding from.
diff --git a/examples/developer-hub-go/flare/FtsoV2AnchorFeedConsumer.go b/examples/developer-hub-go/flare/FtsoV2AnchorFeedConsumer.go
new file mode 100644
index 00000000..9d5b1aba
--- /dev/null
+++ b/examples/developer-hub-go/flare/FtsoV2AnchorFeedConsumer.go
@@ -0,0 +1,299 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package flare
+
+import (
+ "errors"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+// FtsoV2InterfaceFeedData is an auto generated low-level Go binding around an user-defined struct.
+type FtsoV2InterfaceFeedData struct {
+ VotingRoundId uint32
+ Id [21]byte
+ Value int32
+ TurnoutBIPS uint16
+ Decimals int8
+}
+
+// FtsoV2InterfaceFeedDataWithProof is an auto generated low-level Go binding around an user-defined struct.
+type FtsoV2InterfaceFeedDataWithProof struct {
+ Proof [][32]byte
+ Body FtsoV2InterfaceFeedData
+}
+
+// FtsoV2AnchorFeedConsumerMetaData contains all meta data concerning the FtsoV2AnchorFeedConsumer contract.
+var FtsoV2AnchorFeedConsumerMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes21\",\"name\":\"\",\"type\":\"bytes21\"}],\"name\":\"provenFeeds\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"votingRoundId\",\"type\":\"uint32\"},{\"internalType\":\"bytes21\",\"name\":\"id\",\"type\":\"bytes21\"},{\"internalType\":\"int32\",\"name\":\"value\",\"type\":\"int32\"},{\"internalType\":\"uint16\",\"name\":\"turnoutBIPS\",\"type\":\"uint16\"},{\"internalType\":\"int8\",\"name\":\"decimals\",\"type\":\"int8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"votingRoundId\",\"type\":\"uint32\"},{\"internalType\":\"bytes21\",\"name\":\"id\",\"type\":\"bytes21\"},{\"internalType\":\"int32\",\"name\":\"value\",\"type\":\"int32\"},{\"internalType\":\"uint16\",\"name\":\"turnoutBIPS\",\"type\":\"uint16\"},{\"internalType\":\"int8\",\"name\":\"decimals\",\"type\":\"int8\"}],\"internalType\":\"structFtsoV2Interface.FeedData\",\"name\":\"body\",\"type\":\"tuple\"}],\"internalType\":\"structFtsoV2Interface.FeedDataWithProof\",\"name\":\"data\",\"type\":\"tuple\"}],\"name\":\"savePrice\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b50610f23806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806387179d281461003b578063be2efe0914610057575b600080fd5b61005560048036038101906100509190610345565b61008b565b005b610071600480360381019061006c9190610422565b6101d6565b6040516100829594939291906104d5565b60405180910390f35b61009361025e565b73ffffffffffffffffffffffffffffffffffffffff1663ceb05472826040518263ffffffff1660e01b81526004016100cb9190610841565b602060405180830381865afa1580156100e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010c919061089b565b61014b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161014290610925565b60405180910390fd5b806020016000808360200160000160208101906101689190610945565b63ffffffff1663ffffffff168152602001908152602001600020600083602001602001602081019061019a9190610972565b6affffffffffffffffffffff19166affffffffffffffffffffff1916815260200190815260200160002081816101d09190610db4565b90505050565b6000602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900463ffffffff16908060000160049054906101000a900460581b908060000160199054906101000a900460030b9080600001601d9054906101000a900461ffff169080600001601f9054906101000a900460000b905085565b600073ad67fe66660fb8dfe9d6b1b4240d8650e30f601973ffffffffffffffffffffffffffffffffffffffff1663159354a260405160200161029f90610e0e565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016102d19190610e47565b602060405180830381865afa1580156102ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103129190610ec0565b905090565b600080fd5b600080fd5b600080fd5b600060c0828403121561033c5761033b610321565b5b81905092915050565b60006020828403121561035b5761035a610317565b5b600082013567ffffffffffffffff8111156103795761037861031c565b5b61038584828501610326565b91505092915050565b600063ffffffff82169050919050565b6103a78161038e565b81146103b257600080fd5b50565b6000813590506103c48161039e565b92915050565b60007fffffffffffffffffffffffffffffffffffffffffff000000000000000000000082169050919050565b6103ff816103ca565b811461040a57600080fd5b50565b60008135905061041c816103f6565b92915050565b6000806040838503121561043957610438610317565b5b6000610447858286016103b5565b92505060206104588582860161040d565b9150509250929050565b61046b8161038e565b82525050565b61047a816103ca565b82525050565b60008160030b9050919050565b61049681610480565b82525050565b600061ffff82169050919050565b6104b38161049c565b82525050565b60008160000b9050919050565b6104cf816104b9565b82525050565b600060a0820190506104ea6000830188610462565b6104f76020830187610471565b610504604083018661048d565b61051160608301856104aa565b61051e60808301846104c6565b9695505050505050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261055457610553610532565b5b83810192508235915060208301925067ffffffffffffffff82111561057c5761057b610528565b5b6020820236038313156105925761059161052d565b5b509250929050565b600082825260208201905092915050565b600080fd5b82818337505050565b60006105c5838561059a565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156105f8576105f76105ab565b5b6020830292506106098385846105b0565b82840190509392505050565b600082905092915050565b600061062f60208401846103b5565b905092915050565b6106408161038e565b82525050565b6000610655602084018461040d565b905092915050565b610666816103ca565b82525050565b61067581610480565b811461068057600080fd5b50565b6000813590506106928161066c565b92915050565b60006106a76020840184610683565b905092915050565b6106b881610480565b82525050565b6106c78161049c565b81146106d257600080fd5b50565b6000813590506106e4816106be565b92915050565b60006106f960208401846106d5565b905092915050565b61070a8161049c565b82525050565b610719816104b9565b811461072457600080fd5b50565b60008135905061073681610710565b92915050565b600061074b6020840184610727565b905092915050565b61075c816104b9565b82525050565b60a082016107736000830183610620565b6107806000850182610637565b5061078e6020830183610646565b61079b602085018261065d565b506107a96040830183610698565b6107b660408501826106af565b506107c460608301836106ea565b6107d16060850182610701565b506107df608083018361073c565b6107ec6080850182610753565b50505050565b600060c083016108056000840184610537565b85830360008701526108188382846105b9565b925050506108296020840184610615565b6108366020860182610762565b508091505092915050565b6000602082019050818103600083015261085b81846107f2565b905092915050565b60008115159050919050565b61087881610863565b811461088357600080fd5b50565b6000815190506108958161086f565b92915050565b6000602082840312156108b1576108b0610317565b5b60006108bf84828501610886565b91505092915050565b600082825260208201905092915050565b7f496e76616c69642070726f6f6600000000000000000000000000000000000000600082015250565b600061090f600d836108c8565b915061091a826108d9565b602082019050919050565b6000602082019050818103600083015261093e81610902565b9050919050565b60006020828403121561095b5761095a610317565b5b6000610969848285016103b5565b91505092915050565b60006020828403121561098857610987610317565b5b60006109968482850161040d565b91505092915050565b600081356109ac8161039e565b80915050919050565b60008160001b9050919050565b600063ffffffff6109d2846109b5565b9350801983169250808416831791505092915050565b6000819050919050565b6000610a0d610a08610a038461038e565b6109e8565b61038e565b9050919050565b6000819050919050565b610a27826109f2565b610a3a610a3382610a14565b83546109c2565b8255505050565b60008135610a4e816103f6565b80915050919050565b60008160201b9050919050565b600078ffffffffffffffffffffffffffffffffffffffffff00000000610a8984610a57565b9350801983169250808416831791505092915050565b6000610aaa826103ca565b9050919050565b60008160581c9050919050565b6000610ac982610ab1565b9050919050565b610ad982610a9f565b610aec610ae582610abe565b8354610a64565b8255505050565b60008135610b008161066c565b80915050919050565b60008160c81b9050919050565b60007cffffffff00000000000000000000000000000000000000000000000000610b3f84610b09565b9350801983169250808416831791505092915050565b6000610b70610b6b610b6684610480565b6109e8565b610480565b9050919050565b6000819050919050565b610b8a82610b55565b610b9d610b9682610b77565b8354610b16565b8255505050565b60008135610bb1816106be565b80915050919050565b60008160e81b9050919050565b60007effff0000000000000000000000000000000000000000000000000000000000610bf284610bba565b9350801983169250808416831791505092915050565b6000610c23610c1e610c198461049c565b6109e8565b61049c565b9050919050565b6000819050919050565b610c3d82610c08565b610c50610c4982610c2a565b8354610bc7565b8255505050565b60008135610c6481610710565b80915050919050565b60008160f81b9050919050565b60007fff00000000000000000000000000000000000000000000000000000000000000610ca684610c6d565b9350801983169250808416831791505092915050565b6000610cd7610cd2610ccd846104b9565b6109e8565b6104b9565b9050919050565b6000819050919050565b610cf182610cbc565b610d04610cfd82610cde565b8354610c7a565b8255505050565b600081016000830180610d1d8161099f565b9050610d298184610a1e565b505050600081016020830180610d3e81610a41565b9050610d4a8184610ad0565b505050600081016040830180610d5f81610af3565b9050610d6b8184610b81565b505050600081016060830180610d8081610ba4565b9050610d8c8184610c34565b505050600081016080830180610da181610c57565b9050610dad8184610ce8565b5050505050565b610dbe8282610d0b565b5050565b7f4674736f56320000000000000000000000000000000000000000000000000000600082015250565b6000610df86006836108c8565b9150610e0382610dc2565b602082019050919050565b60006020820190508181036000830152610e2781610deb565b9050919050565b6000819050919050565b610e4181610e2e565b82525050565b6000602082019050610e5c6000830184610e38565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e8d82610e62565b9050919050565b610e9d81610e82565b8114610ea857600080fd5b50565b600081519050610eba81610e94565b92915050565b600060208284031215610ed657610ed5610317565b5b6000610ee484828501610eab565b9150509291505056fea26469706673582212208cebfd4f48357fe08a81979822b20cc1469fa8d28a77962c8b461b2f66651ff364736f6c63430008130033",
+}
+
+// FtsoV2AnchorFeedConsumerABI is the input ABI used to generate the binding from.
+// Deprecated: Use FtsoV2AnchorFeedConsumerMetaData.ABI instead.
+var FtsoV2AnchorFeedConsumerABI = FtsoV2AnchorFeedConsumerMetaData.ABI
+
+// FtsoV2AnchorFeedConsumerBin is the compiled bytecode used for deploying new contracts.
+// Deprecated: Use FtsoV2AnchorFeedConsumerMetaData.Bin instead.
+var FtsoV2AnchorFeedConsumerBin = FtsoV2AnchorFeedConsumerMetaData.Bin
+
+// DeployFtsoV2AnchorFeedConsumer deploys a new Ethereum contract, binding an instance of FtsoV2AnchorFeedConsumer to it.
+func DeployFtsoV2AnchorFeedConsumer(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *FtsoV2AnchorFeedConsumer, error) {
+ parsed, err := FtsoV2AnchorFeedConsumerMetaData.GetAbi()
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ if parsed == nil {
+ return common.Address{}, nil, nil, errors.New("GetABI returned nil")
+ }
+
+ address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FtsoV2AnchorFeedConsumerBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &FtsoV2AnchorFeedConsumer{FtsoV2AnchorFeedConsumerCaller: FtsoV2AnchorFeedConsumerCaller{contract: contract}, FtsoV2AnchorFeedConsumerTransactor: FtsoV2AnchorFeedConsumerTransactor{contract: contract}, FtsoV2AnchorFeedConsumerFilterer: FtsoV2AnchorFeedConsumerFilterer{contract: contract}}, nil
+}
+
+// FtsoV2AnchorFeedConsumer is an auto generated Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumer struct {
+ FtsoV2AnchorFeedConsumerCaller // Read-only binding to the contract
+ FtsoV2AnchorFeedConsumerTransactor // Write-only binding to the contract
+ FtsoV2AnchorFeedConsumerFilterer // Log filterer for contract events
+}
+
+// FtsoV2AnchorFeedConsumerCaller is an auto generated read-only Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumerCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FtsoV2AnchorFeedConsumerTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumerTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FtsoV2AnchorFeedConsumerFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type FtsoV2AnchorFeedConsumerFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FtsoV2AnchorFeedConsumerSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type FtsoV2AnchorFeedConsumerSession struct {
+ Contract *FtsoV2AnchorFeedConsumer // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// FtsoV2AnchorFeedConsumerCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type FtsoV2AnchorFeedConsumerCallerSession struct {
+ Contract *FtsoV2AnchorFeedConsumerCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// FtsoV2AnchorFeedConsumerTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type FtsoV2AnchorFeedConsumerTransactorSession struct {
+ Contract *FtsoV2AnchorFeedConsumerTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// FtsoV2AnchorFeedConsumerRaw is an auto generated low-level Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumerRaw struct {
+ Contract *FtsoV2AnchorFeedConsumer // Generic contract binding to access the raw methods on
+}
+
+// FtsoV2AnchorFeedConsumerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumerCallerRaw struct {
+ Contract *FtsoV2AnchorFeedConsumerCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// FtsoV2AnchorFeedConsumerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type FtsoV2AnchorFeedConsumerTransactorRaw struct {
+ Contract *FtsoV2AnchorFeedConsumerTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewFtsoV2AnchorFeedConsumer creates a new instance of FtsoV2AnchorFeedConsumer, bound to a specific deployed contract.
+func NewFtsoV2AnchorFeedConsumer(address common.Address, backend bind.ContractBackend) (*FtsoV2AnchorFeedConsumer, error) {
+ contract, err := bindFtsoV2AnchorFeedConsumer(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &FtsoV2AnchorFeedConsumer{FtsoV2AnchorFeedConsumerCaller: FtsoV2AnchorFeedConsumerCaller{contract: contract}, FtsoV2AnchorFeedConsumerTransactor: FtsoV2AnchorFeedConsumerTransactor{contract: contract}, FtsoV2AnchorFeedConsumerFilterer: FtsoV2AnchorFeedConsumerFilterer{contract: contract}}, nil
+}
+
+// NewFtsoV2AnchorFeedConsumerCaller creates a new read-only instance of FtsoV2AnchorFeedConsumer, bound to a specific deployed contract.
+func NewFtsoV2AnchorFeedConsumerCaller(address common.Address, caller bind.ContractCaller) (*FtsoV2AnchorFeedConsumerCaller, error) {
+ contract, err := bindFtsoV2AnchorFeedConsumer(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FtsoV2AnchorFeedConsumerCaller{contract: contract}, nil
+}
+
+// NewFtsoV2AnchorFeedConsumerTransactor creates a new write-only instance of FtsoV2AnchorFeedConsumer, bound to a specific deployed contract.
+func NewFtsoV2AnchorFeedConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*FtsoV2AnchorFeedConsumerTransactor, error) {
+ contract, err := bindFtsoV2AnchorFeedConsumer(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FtsoV2AnchorFeedConsumerTransactor{contract: contract}, nil
+}
+
+// NewFtsoV2AnchorFeedConsumerFilterer creates a new log filterer instance of FtsoV2AnchorFeedConsumer, bound to a specific deployed contract.
+func NewFtsoV2AnchorFeedConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*FtsoV2AnchorFeedConsumerFilterer, error) {
+ contract, err := bindFtsoV2AnchorFeedConsumer(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &FtsoV2AnchorFeedConsumerFilterer{contract: contract}, nil
+}
+
+// bindFtsoV2AnchorFeedConsumer binds a generic wrapper to an already deployed contract.
+func bindFtsoV2AnchorFeedConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := FtsoV2AnchorFeedConsumerMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _FtsoV2AnchorFeedConsumer.Contract.FtsoV2AnchorFeedConsumerCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.FtsoV2AnchorFeedConsumerTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.FtsoV2AnchorFeedConsumerTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _FtsoV2AnchorFeedConsumer.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.contract.Transact(opts, method, params...)
+}
+
+// ProvenFeeds is a free data retrieval call binding the contract method 0xbe2efe09.
+//
+// Solidity: function provenFeeds(uint32 , bytes21 ) view returns(uint32 votingRoundId, bytes21 id, int32 value, uint16 turnoutBIPS, int8 decimals)
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerCaller) ProvenFeeds(opts *bind.CallOpts, arg0 uint32, arg1 [21]byte) (struct {
+ VotingRoundId uint32
+ Id [21]byte
+ Value int32
+ TurnoutBIPS uint16
+ Decimals int8
+}, error) {
+ var out []interface{}
+ err := _FtsoV2AnchorFeedConsumer.contract.Call(opts, &out, "provenFeeds", arg0, arg1)
+
+ outstruct := new(struct {
+ VotingRoundId uint32
+ Id [21]byte
+ Value int32
+ TurnoutBIPS uint16
+ Decimals int8
+ })
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.VotingRoundId = *abi.ConvertType(out[0], new(uint32)).(*uint32)
+ outstruct.Id = *abi.ConvertType(out[1], new([21]byte)).(*[21]byte)
+ outstruct.Value = *abi.ConvertType(out[2], new(int32)).(*int32)
+ outstruct.TurnoutBIPS = *abi.ConvertType(out[3], new(uint16)).(*uint16)
+ outstruct.Decimals = *abi.ConvertType(out[4], new(int8)).(*int8)
+
+ return *outstruct, err
+
+}
+
+// ProvenFeeds is a free data retrieval call binding the contract method 0xbe2efe09.
+//
+// Solidity: function provenFeeds(uint32 , bytes21 ) view returns(uint32 votingRoundId, bytes21 id, int32 value, uint16 turnoutBIPS, int8 decimals)
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerSession) ProvenFeeds(arg0 uint32, arg1 [21]byte) (struct {
+ VotingRoundId uint32
+ Id [21]byte
+ Value int32
+ TurnoutBIPS uint16
+ Decimals int8
+}, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.ProvenFeeds(&_FtsoV2AnchorFeedConsumer.CallOpts, arg0, arg1)
+}
+
+// ProvenFeeds is a free data retrieval call binding the contract method 0xbe2efe09.
+//
+// Solidity: function provenFeeds(uint32 , bytes21 ) view returns(uint32 votingRoundId, bytes21 id, int32 value, uint16 turnoutBIPS, int8 decimals)
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerCallerSession) ProvenFeeds(arg0 uint32, arg1 [21]byte) (struct {
+ VotingRoundId uint32
+ Id [21]byte
+ Value int32
+ TurnoutBIPS uint16
+ Decimals int8
+}, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.ProvenFeeds(&_FtsoV2AnchorFeedConsumer.CallOpts, arg0, arg1)
+}
+
+// SavePrice is a paid mutator transaction binding the contract method 0x87179d28.
+//
+// Solidity: function savePrice((bytes32[],(uint32,bytes21,int32,uint16,int8)) data) returns()
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerTransactor) SavePrice(opts *bind.TransactOpts, data FtsoV2InterfaceFeedDataWithProof) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.contract.Transact(opts, "savePrice", data)
+}
+
+// SavePrice is a paid mutator transaction binding the contract method 0x87179d28.
+//
+// Solidity: function savePrice((bytes32[],(uint32,bytes21,int32,uint16,int8)) data) returns()
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerSession) SavePrice(data FtsoV2InterfaceFeedDataWithProof) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.SavePrice(&_FtsoV2AnchorFeedConsumer.TransactOpts, data)
+}
+
+// SavePrice is a paid mutator transaction binding the contract method 0x87179d28.
+//
+// Solidity: function savePrice((bytes32[],(uint32,bytes21,int32,uint16,int8)) data) returns()
+func (_FtsoV2AnchorFeedConsumer *FtsoV2AnchorFeedConsumerTransactorSession) SavePrice(data FtsoV2InterfaceFeedDataWithProof) (*types.Transaction, error) {
+ return _FtsoV2AnchorFeedConsumer.Contract.SavePrice(&_FtsoV2AnchorFeedConsumer.TransactOpts, data)
+}
diff --git a/examples/developer-hub-go/flare/FtsoV2FeedConsumer.go b/examples/developer-hub-go/flare/FtsoV2FeedConsumer.go
index d41cd4a2..adcde2ff 100644
--- a/examples/developer-hub-go/flare/FtsoV2FeedConsumer.go
+++ b/examples/developer-hub-go/flare/FtsoV2FeedConsumer.go
@@ -32,7 +32,7 @@ var (
// FtsoV2FeedConsumerMetaData contains all meta data concerning the FtsoV2FeedConsumer contract.
var FtsoV2FeedConsumerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedIndexes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFtsoV2CurrentFeedValues\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_feedValues\",\"type\":\"uint256[]\"},{\"internalType\":\"int8[]\",\"name\":\"_decimals\",\"type\":\"int8[]\"},{\"internalType\":\"uint64\",\"name\":\"_timestamp\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x60806040526040518060600160405280600060ff168152602001600260ff168152602001600960ff16815250600290600361003b92919061017a565b5034801561004857600080fd5b5073ad67fe66660fb8dfe9d6b1b4240d8650e30f60196000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382760fca6040518163ffffffff1660e01b81526004016100f490610246565b602060405180830381865afa158015610111573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013591906102c9565b600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f6565b8280548282559060005260206000209081019282156101bb579160200282015b828111156101ba578251829060ff1690559160200191906001019061019a565b5b5090506101c891906101cc565b5090565b5b808211156101e55760008160009055506001016101cd565b5090565b600082825260208201905092915050565b7f4661737455706461746572000000000000000000000000000000000000000000600082015250565b6000610230600b836101e9565b915061023b826101fa565b602082019050919050565b6000602082019050818103600083015261025f81610223565b9050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102968261026b565b9050919050565b6102a68161028b565b81146102b157600080fd5b50565b6000815190506102c38161029d565b92915050565b6000602082840312156102df576102de610266565b5b60006102ed848285016102b4565b91505092915050565b610845806103056000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063dae2f4bc1461003b578063f601bc8b1461006b575b600080fd5b610055600480360381019061005091906101bb565b61008b565b60405161006291906101f7565b60405180910390f35b6100736100af565b604051610082939291906103be565b60405180910390f35b6002818154811061009b57600080fd5b906000526020600020016000915090505481565b606080600080600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166345a15d3c60026040518263ffffffff1660e01b815260040161011491906104d9565b600060405180830381865afa158015610131573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061015a9190610784565b925092509250828282955095509550505050909192565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61019881610185565b81146101a357600080fd5b50565b6000813590506101b58161018f565b92915050565b6000602082840312156101d1576101d061017b565b5b60006101df848285016101a6565b91505092915050565b6101f181610185565b82525050565b600060208201905061020c60008301846101e8565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61024781610185565b82525050565b6000610259838361023e565b60208301905092915050565b6000602082019050919050565b600061027d82610212565b610287818561021d565b93506102928361022e565b8060005b838110156102c35781516102aa888261024d565b97506102b583610265565b925050600181019050610296565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60008160000b9050919050565b610312816102fc565b82525050565b60006103248383610309565b60208301905092915050565b6000602082019050919050565b6000610348826102d0565b61035281856102db565b935061035d836102ec565b8060005b8381101561038e5781516103758882610318565b975061038083610330565b925050600181019050610361565b5085935050505092915050565b600067ffffffffffffffff82169050919050565b6103b88161039b565b82525050565b600060608201905081810360008301526103d88186610272565b905081810360208301526103ec818561033d565b90506103fb60408301846103af565b949350505050565b600081549050919050565b60008190508160005260206000209050919050565b60008160001c9050919050565b6000819050919050565b600061044d61044883610423565b610430565b9050919050565b6000610460825461043a565b9050919050565b6000600182019050919050565b600061047f82610403565b610489818561021d565b93506104948361040e565b8060005b838110156104cc576104a982610454565b6104b3888261024d565b97506104be83610467565b925050600181019050610498565b5085935050505092915050565b600060208201905081810360008301526104f38184610474565b905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61054982610500565b810181811067ffffffffffffffff8211171561056857610567610511565b5b80604052505050565b600061057b610171565b90506105878282610540565b919050565b600067ffffffffffffffff8211156105a7576105a6610511565b5b602082029050602081019050919050565b600080fd5b6000815190506105cc8161018f565b92915050565b60006105e56105e08461058c565b610571565b90508083825260208201905060208402830185811115610608576106076105b8565b5b835b81811015610631578061061d88826105bd565b84526020840193505060208101905061060a565b5050509392505050565b600082601f8301126106505761064f6104fb565b5b81516106608482602086016105d2565b91505092915050565b600067ffffffffffffffff82111561068457610683610511565b5b602082029050602081019050919050565b61069e816102fc565b81146106a957600080fd5b50565b6000815190506106bb81610695565b92915050565b60006106d46106cf84610669565b610571565b905080838252602082019050602084028301858111156106f7576106f66105b8565b5b835b81811015610720578061070c88826106ac565b8452602084019350506020810190506106f9565b5050509392505050565b600082601f83011261073f5761073e6104fb565b5b815161074f8482602086016106c1565b91505092915050565b6107618161039b565b811461076c57600080fd5b50565b60008151905061077e81610758565b92915050565b60008060006060848603121561079d5761079c61017b565b5b600084015167ffffffffffffffff8111156107bb576107ba610180565b5b6107c78682870161063b565b935050602084015167ffffffffffffffff8111156107e8576107e7610180565b5b6107f48682870161072a565b92505060406108058682870161076f565b915050925092509256fea2646970667358221220eb33bd14ba21e825dfd87aec9ad44e3f2bb8f9c567df65246a6c05c998d410c764736f6c63430008190033",
+ Bin: "0x608060405260405180606001604052805f60ff168152602001600260ff168152602001600960ff16815250600290600361003a929190610173565b50348015610046575f80fd5b5073ad67fe66660fb8dfe9d6b1b4240d8650e30f60195f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382760fca6040518163ffffffff1660e01b81526004016100f090610238565b602060405180830381865afa15801561010b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061012f91906102b4565b60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102df565b828054828255905f5260205f209081019282156101b2579160200282015b828111156101b1578251829060ff16905591602001919060010190610191565b5b5090506101bf91906101c3565b5090565b5b808211156101da575f815f9055506001016101c4565b5090565b5f82825260208201905092915050565b7f46617374557064617465720000000000000000000000000000000000000000005f82015250565b5f610222600b836101de565b915061022d826101ee565b602082019050919050565b5f6020820190508181035f83015261024f81610216565b9050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102838261025a565b9050919050565b61029381610279565b811461029d575f80fd5b50565b5f815190506102ae8161028a565b92915050565b5f602082840312156102c9576102c8610256565b5b5f6102d6848285016102a0565b91505092915050565b6107f8806102ec5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063dae2f4bc14610038578063f601bc8b14610068575b5f80fd5b610052600480360381019061004d91906101a7565b610088565b60405161005f91906101e1565b60405180910390f35b6100706100a8565b60405161007f93929190610395565b60405180910390f35b60028181548110610097575f80fd5b905f5260205f20015f915090505481565b6060805f805f8060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166345a15d3c60026040518263ffffffff1660e01b815260040161010a91906104a2565b5f60405180830381865afa158015610124573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061014c919061073a565b925092509250828282955095509550505050909192565b5f604051905090565b5f80fd5b5f80fd5b5f819050919050565b61018681610174565b8114610190575f80fd5b50565b5f813590506101a18161017d565b92915050565b5f602082840312156101bc576101bb61016c565b5b5f6101c984828501610193565b91505092915050565b6101db81610174565b82525050565b5f6020820190506101f45f8301846101d2565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61022c81610174565b82525050565b5f61023d8383610223565b60208301905092915050565b5f602082019050919050565b5f61025f826101fa565b6102698185610204565b935061027483610214565b805f5b838110156102a457815161028b8882610232565b975061029683610249565b925050600181019050610277565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f815f0b9050919050565b6102ee816102da565b82525050565b5f6102ff83836102e5565b60208301905092915050565b5f602082019050919050565b5f610321826102b1565b61032b81856102bb565b9350610336836102cb565b805f5b8381101561036657815161034d88826102f4565b97506103588361030b565b925050600181019050610339565b5085935050505092915050565b5f67ffffffffffffffff82169050919050565b61038f81610373565b82525050565b5f6060820190508181035f8301526103ad8186610255565b905081810360208301526103c18185610317565b90506103d06040830184610386565b949350505050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f815f1c9050919050565b5f819050919050565b5f61041a610415836103f4565b6103ff565b9050919050565b5f61042c8254610408565b9050919050565b5f600182019050919050565b5f610449826103d8565b6104538185610204565b935061045e836103e2565b805f5b838110156104955761047282610421565b61047c8882610232565b975061048783610433565b925050600181019050610461565b5085935050505092915050565b5f6020820190508181035f8301526104ba818461043f565b905092915050565b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61050c826104c6565b810181811067ffffffffffffffff8211171561052b5761052a6104d6565b5b80604052505050565b5f61053d610163565b90506105498282610503565b919050565b5f67ffffffffffffffff821115610568576105676104d6565b5b602082029050602081019050919050565b5f80fd5b5f8151905061058b8161017d565b92915050565b5f6105a361059e8461054e565b610534565b905080838252602082019050602084028301858111156105c6576105c5610579565b5b835b818110156105ef57806105db888261057d565b8452602084019350506020810190506105c8565b5050509392505050565b5f82601f83011261060d5761060c6104c2565b5b815161061d848260208601610591565b91505092915050565b5f67ffffffffffffffff8211156106405761063f6104d6565b5b602082029050602081019050919050565b61065a816102da565b8114610664575f80fd5b50565b5f8151905061067581610651565b92915050565b5f61068d61068884610626565b610534565b905080838252602082019050602084028301858111156106b0576106af610579565b5b835b818110156106d957806106c58882610667565b8452602084019350506020810190506106b2565b5050509392505050565b5f82601f8301126106f7576106f66104c2565b5b815161070784826020860161067b565b91505092915050565b61071981610373565b8114610723575f80fd5b50565b5f8151905061073481610710565b92915050565b5f805f606084860312156107515761075061016c565b5b5f84015167ffffffffffffffff81111561076e5761076d610170565b5b61077a868287016105f9565b935050602084015167ffffffffffffffff81111561079b5761079a610170565b5b6107a7868287016106e3565b92505060406107b886828701610726565b915050925092509256fea2646970667358221220ec64100f9062f5749e6541df584b0fc7e497728a2d80fa8301fb24b3b1e2692c64736f6c63430008190033",
}
// FtsoV2FeedConsumerABI is the input ABI used to generate the binding from.
diff --git a/examples/developer-hub-go/flare/fetch_anchor_feeds.go b/examples/developer-hub-go/flare/fetch_anchor_feeds.go
index 5245f1b2..c42edfc7 100644
--- a/examples/developer-hub-go/flare/fetch_anchor_feeds.go
+++ b/examples/developer-hub-go/flare/fetch_anchor_feeds.go
@@ -57,11 +57,11 @@ func FetchAnchorFeeds() ([]AnchorFeed, error) {
return feeds, json.Unmarshal(body, &feeds)
}
-func main() {
- feeds, err := FetchAnchorFeeds()
- if err != nil {
- fmt.Printf("Error: %v\n", err)
- return
- }
- fmt.Printf("Anchor feeds: %+v\n", feeds)
-}
\ No newline at end of file
+func main() {
+ feeds, err := FetchAnchorFeeds()
+ if err != nil {
+ fmt.Printf("Error: %v\n", err)
+ return
+ }
+ fmt.Printf("Anchor feeds: %+v\n", feeds)
+}
diff --git a/examples/developer-hub-go/flare/fetch_and_verify_anchor_onchain.go b/examples/developer-hub-go/flare/fetch_and_verify_anchor_onchain.go
new file mode 100644
index 00000000..79511a67
--- /dev/null
+++ b/examples/developer-hub-go/flare/fetch_and_verify_anchor_onchain.go
@@ -0,0 +1,128 @@
+package flare
+
+import (
+ "context"
+ "crypto/ecdsa"
+ "encoding/hex"
+ "fmt"
+ "log"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethclient"
+)
+
+func convertToByteArray(proof []string) ([][32]byte, error) {
+ var result [][32]byte
+
+ for _, str := range proof {
+
+ decoded, err := hex.DecodeString(str)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode string: %v", err)
+ }
+
+ if len(decoded) != 32 {
+ return nil, fmt.Errorf("decoded string is not 32 bytes: got %d bytes", len(decoded))
+ }
+
+ var byteArray [32]byte
+ copy(byteArray[:], decoded)
+
+ result = append(result, byteArray)
+ }
+
+ return result, nil
+}
+
+func VerifyAnchorFeedsOnchain() {
+ const (
+ PRIVATE_KEY = "your_private_key_here"
+ RPC_URL = "https://coston2-api.flare.network/ext/C/rpc"
+ DEPLOYED_CONTRACT_ADDRESS = "0x069227C6A947d852c55655e41C6a382868627920"
+ )
+
+ var feed_Id [21]byte
+ var proof [][32]byte
+
+ feeds, err := FetchAnchorFeeds()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ copy(feed_Id[:], feeds[0].Body.ID)
+ votingRoundId := uint32(feeds[0].Body.VotingRoundID)
+ feedBody := FtsoV2InterfaceFeedData{
+ votingRoundId,
+ feed_Id,
+ int32(feeds[0].Body.Value),
+ uint16(feeds[0].Body.TurnoutBIPS),
+ int8(feeds[0].Body.Decimals),
+ }
+ proof, _ = convertToByteArray(feeds[0].Proof)
+
+ var feedWithProof = FtsoV2InterfaceFeedDataWithProof{
+ proof,
+ feedBody,
+ }
+
+ client, err := ethclient.Dial(RPC_URL)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ privateKey, err := crypto.HexToECDSA(PRIVATE_KEY)
+ if err != nil {
+ log.Fatalf("Failed to parse private key: %v", err)
+ }
+
+ publicKey := privateKey.Public()
+ publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
+ if !ok {
+ log.Fatal("Invalid public key type")
+ }
+ fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
+
+ nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
+ if err != nil {
+ log.Fatalf("Failed to fetch nonce: %v", err)
+ }
+
+ gasPrice, err := client.SuggestGasPrice(context.Background())
+ if err != nil {
+ log.Fatalf("Failed to fetch gas price: %v", err)
+ }
+
+ chainID, err := client.NetworkID(context.Background())
+ if err != nil {
+ log.Fatalf("Failed to fetch chain ID: %v", err)
+ }
+
+ auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
+ if err != nil {
+ log.Fatalf("Failed to create transactor: %v", err)
+ }
+ auth.Nonce = big.NewInt(int64(nonce))
+ auth.Value = big.NewInt(0) //
+ auth.GasLimit = uint64(3000000)
+ auth.GasPrice = gasPrice
+ consumerAddr := common.HexToAddress(DEPLOYED_CONTRACT_ADDRESS)
+ anchorFeed, err := NewFtsoV2AnchorFeedConsumer(consumerAddr, client)
+ if err != nil {
+ log.Fatalf("Failed to initialize consumer contract: %v", err)
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ tx, err := anchorFeed.SavePrice(auth, feedWithProof)
+ if err != nil {
+ log.Fatalf("Failed to save price: %v", err)
+ }
+ fmt.Printf("SavePrice transaction hash: %s\n", tx.Hash().Hex())
+
+ savedPrice, _ := anchorFeed.ProvenFeeds(&bind.CallOpts{}, votingRoundId, feed_Id)
+ fmt.Printf("%+v\n", savedPrice)
+}
diff --git a/examples/developer-hub-go/go.mod b/examples/developer-hub-go/go.mod
index 35fa5cd3..cc650717 100644
--- a/examples/developer-hub-go/go.mod
+++ b/examples/developer-hub-go/go.mod
@@ -7,7 +7,7 @@ require github.com/ethereum/go-ethereum v1.14.12
require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/bits-and-blooms/bitset v1.20.0 // indirect
- github.com/consensys/bavard v0.1.24 // indirect
+ github.com/consensys/bavard v0.1.25 // indirect
github.com/consensys/gnark-crypto v0.14.0 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect
@@ -26,9 +26,9 @@ require (
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
- golang.org/x/crypto v0.31.0 // indirect
- golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
+ golang.org/x/crypto v0.32.0 // indirect
+ golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
golang.org/x/sync v0.10.0 // indirect
- golang.org/x/sys v0.28.0 // indirect
+ golang.org/x/sys v0.29.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
diff --git a/examples/developer-hub-go/go.sum b/examples/developer-hub-go/go.sum
index ba53351b..ae3070f6 100644
--- a/examples/developer-hub-go/go.sum
+++ b/examples/developer-hub-go/go.sum
@@ -26,6 +26,8 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAK
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/consensys/bavard v0.1.24 h1:Lfe+bjYbpaoT7K5JTFoMi5wo9V4REGLvQQbHmatoN2I=
github.com/consensys/bavard v0.1.24/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
+github.com/consensys/bavard v0.1.25 h1:5YcSBnp03/HvfpKaIQLr/ecspTp2k8YNR5rQLOWvUyc=
+github.com/consensys/bavard v0.1.25/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E=
github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
@@ -151,14 +153,20 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
+golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
+golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
+golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
+golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
diff --git a/examples/developer-hub-go/main.go b/examples/developer-hub-go/main.go
index e718d852..f2fbd6b1 100644
--- a/examples/developer-hub-go/main.go
+++ b/examples/developer-hub-go/main.go
@@ -15,6 +15,7 @@ import (
// flare package ABIs
//go:generate abigen --abi FlareContractRegistry.abi --pkg flare --type FlareContractRegistry --out flare/FlareContractRegistry.go
//go:generate abigen --bin=build/FtsoV2FeedConsumer.bin --abi=build/FtsoV2FeedConsumer.abi --pkg flare --type FtsoV2FeedConsumer --out flare/FtsoV2FeedConsumer.go
+//go:generate abigen --bin=build/FtsoV2AnchorFeedConsumer.bin --abi=build/FtsoV2AnchorFeedConsumer.abi --pkg flare --type FtsoV2AnchorFeedConsumer --out flare/FtsoV2AnchorFeedConsumer.go
/* Note: Call `go generate` before executing these functions. */
@@ -32,4 +33,5 @@ func main() {
coston2.MakeVolatilityIncentive()
coston2.SecureRandom()
flare.FetchAnchorFeeds()
+ flare.VerifyAnchorFeedsOnchain()
}
diff --git a/examples/developer-hub-python/fetch_and_verify_anchor_onchain.py b/examples/developer-hub-python/fetch_and_verify_anchor_onchain.py
new file mode 100644
index 00000000..5e4c7048
--- /dev/null
+++ b/examples/developer-hub-python/fetch_and_verify_anchor_onchain.py
@@ -0,0 +1,111 @@
+import asyncio
+
+from web3 import AsyncHTTPProvider, AsyncWeb3
+
+from fetch_anchor_feeds import fetch_anchor_feeds
+
+RPC_URL = "https://coston2-api.flare.network/ext/C/rpc"
+
+contract_abi = [
+ {
+ "inputs": [
+ {"internalType": "uint32", "name": "", "type": "uint32"},
+ {"internalType": "bytes21", "name": "", "type": "bytes21"},
+ ],
+ "name": "provenFeeds",
+ "outputs": [
+ {"internalType": "uint32", "name": "votingRoundId", "type": "uint32"},
+ {"internalType": "bytes21", "name": "id", "type": "bytes21"},
+ {"internalType": "int32", "name": "value", "type": "int32"},
+ {"internalType": "uint16", "name": "turnoutBIPS", "type": "uint16"},
+ {"internalType": "int8", "name": "decimals", "type": "int8"},
+ ],
+ "stateMutability": "view",
+ "type": "function",
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {"internalType": "bytes32[]", "name": "proof", "type": "bytes32[]"},
+ {
+ "components": [
+ {
+ "internalType": "uint32",
+ "name": "votingRoundId",
+ "type": "uint32",
+ },
+ {
+ "internalType": "bytes21",
+ "name": "id",
+ "type": "bytes21",
+ },
+ {"internalType": "int32", "name": "value", "type": "int32"},
+ {
+ "internalType": "uint16",
+ "name": "turnoutBIPS",
+ "type": "uint16",
+ },
+ {
+ "internalType": "int8",
+ "name": "decimals",
+ "type": "int8",
+ },
+ ],
+ "internalType": "struct FtsoV2Interface.FeedData",
+ "name": "body",
+ "type": "tuple",
+ },
+ ],
+ "internalType": "struct FtsoV2Interface.FeedDataWithProof",
+ "name": "data",
+ "type": "tuple",
+ }
+ ],
+ "name": "savePrice",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function",
+ },
+]
+
+contract_address = "0x069227C6A947d852c55655e41C6a382868627920"
+w3 = AsyncWeb3(
+ AsyncHTTPProvider(RPC_URL),
+)
+
+# Create contract instance
+contract = w3.eth.contract(address=contract_address, abi=contract_abi)
+
+# Feed IDs and target voting round
+BTC_USD_FEED_ID = "0x014254432f55534400000000000000000000000000"
+TARGET_VOTING_ROUND = 823402
+
+
+async def main() -> None:
+ try:
+ feed_data = await fetch_anchor_feeds([BTC_USD_FEED_ID], TARGET_VOTING_ROUND)
+
+ proof = feed_data[0]["proof"]
+ body = feed_data[0]["body"]
+
+ # Create transaction
+ txn_hash = await contract.functions.savePrice(
+ {"proof": proof, "body": body}
+ ).transact()
+ tx_receipt = await w3.eth.wait_for_transaction_receipt(txn_hash)
+
+ print(f"Transaction sent with hash: {tx_receipt}")
+
+ saved_price = await contract.functions.provenFeeds(
+ TARGET_VOTING_ROUND, BTC_USD_FEED_ID
+ ).call()
+ formatted_price = saved_price[2] * (10 ** -saved_price[4])
+ print(f"Saved price: {formatted_price} USD at voting round: {saved_price[0]}")
+ except Exception as err:
+ print(f"Error: {err}")
+
+
+# Run the main function
+if __name__ == "__main__":
+ asyncio.run(main())
diff --git a/examples/developer-hub-rust/Cargo.lock b/examples/developer-hub-rust/Cargo.lock
index 452e7170..730254b8 100644
--- a/examples/developer-hub-rust/Cargo.lock
+++ b/examples/developer-hub-rust/Cargo.lock
@@ -276,7 +276,7 @@ dependencies = [
"futures-utils-wasm",
"lru",
"pin-project",
- "reqwest",
+ "reqwest 0.12.8",
"serde",
"serde_json",
"tokio",
@@ -340,7 +340,7 @@ dependencies = [
"alloy-transport-ws",
"futures",
"pin-project",
- "reqwest",
+ "reqwest 0.12.8",
"serde",
"serde_json",
"tokio",
@@ -540,7 +540,7 @@ checksum = "2437d145d80ea1aecde8574d2058cceb8b3c9cba05f6aea8e67907c660d46698"
dependencies = [
"alloy-json-rpc",
"alloy-transport",
- "reqwest",
+ "reqwest 0.12.8",
"serde_json",
"tower",
"tracing",
@@ -575,7 +575,7 @@ dependencies = [
"alloy-pubsub",
"alloy-transport",
"futures",
- "http",
+ "http 1.1.0",
"rustls",
"serde_json",
"tokio",
@@ -787,7 +787,7 @@ dependencies = [
"miniz_oxide",
"object",
"rustc-demangle",
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -835,6 +835,12 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
[[package]]
name = "bitflags"
version = "2.6.0"
@@ -1098,6 +1104,10 @@ version = "0.1.0"
dependencies = [
"alloy",
"eyre",
+ "hex",
+ "reqwest 0.11.27",
+ "serde",
+ "serde_json",
"tokio",
]
@@ -1173,6 +1183,15 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "encoding_rs"
+version = "0.8.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -1422,6 +1441,25 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "h2"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http 0.2.12",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
[[package]]
name = "hashbrown"
version = "0.14.5"
@@ -1475,6 +1513,17 @@ dependencies = [
"digest 0.10.7",
]
+[[package]]
+name = "http"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
[[package]]
name = "http"
version = "1.1.0"
@@ -1486,6 +1535,17 @@ dependencies = [
"itoa",
]
+[[package]]
+name = "http-body"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
+dependencies = [
+ "bytes",
+ "http 0.2.12",
+ "pin-project-lite",
+]
+
[[package]]
name = "http-body"
version = "1.0.1"
@@ -1493,7 +1553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
- "http",
+ "http 1.1.0",
]
[[package]]
@@ -1504,8 +1564,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
- "http",
- "http-body",
+ "http 1.1.0",
+ "http-body 1.0.1",
"pin-project-lite",
]
@@ -1515,6 +1575,36 @@ version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "0.14.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http 0.2.12",
+ "http-body 0.4.6",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
[[package]]
name = "hyper"
version = "1.5.0"
@@ -1524,8 +1614,8 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
- "http",
- "http-body",
+ "http 1.1.0",
+ "http-body 1.0.1",
"httparse",
"itoa",
"pin-project-lite",
@@ -1534,6 +1624,19 @@ dependencies = [
"want",
]
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper 0.14.32",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -1542,7 +1645,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
- "hyper",
+ "hyper 1.5.0",
"hyper-util",
"native-tls",
"tokio",
@@ -1559,9 +1662,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
- "http",
- "http-body",
- "hyper",
+ "http 1.1.0",
+ "http-body 1.0.1",
+ "hyper 1.5.0",
"pin-project-lite",
"socket2",
"tokio",
@@ -1892,7 +1995,7 @@ version = "0.10.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"cfg-if",
"foreign-types",
"libc",
@@ -1966,7 +2069,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -2136,7 +2239,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d"
dependencies = [
"bit-set",
"bit-vec",
- "bitflags",
+ "bitflags 2.6.0",
"lazy_static",
"num-traits",
"rand",
@@ -2220,7 +2323,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
]
[[package]]
@@ -2229,6 +2332,46 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+[[package]]
+name = "reqwest"
+version = "0.11.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
+dependencies = [
+ "base64 0.21.7",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http 0.2.12",
+ "http-body 0.4.6",
+ "hyper 0.14.32",
+ "hyper-tls 0.5.0",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pemfile 1.0.4",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper 0.1.2",
+ "system-configuration",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
[[package]]
name = "reqwest"
version = "0.12.8"
@@ -2239,11 +2382,11 @@ dependencies = [
"bytes",
"futures-core",
"futures-util",
- "http",
- "http-body",
+ "http 1.1.0",
+ "http-body 1.0.1",
"http-body-util",
- "hyper",
- "hyper-tls",
+ "hyper 1.5.0",
+ "hyper-tls 0.6.0",
"hyper-util",
"ipnet",
"js-sys",
@@ -2253,11 +2396,11 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
- "rustls-pemfile",
+ "rustls-pemfile 2.2.0",
"serde",
"serde_json",
"serde_urlencoded",
- "sync_wrapper",
+ "sync_wrapper 1.0.1",
"tokio",
"tokio-native-tls",
"tower-service",
@@ -2369,7 +2512,7 @@ version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
@@ -2390,6 +2533,15 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.7",
+]
+
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
@@ -2475,7 +2627,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -2735,6 +2887,12 @@ dependencies = [
"syn 2.0.79",
]
+[[package]]
+name = "sync_wrapper"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
+
[[package]]
name = "sync_wrapper"
version = "1.0.1"
@@ -2744,6 +2902,27 @@ dependencies = [
"futures-core",
]
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
[[package]]
name = "tap"
version = "1.0.1"
@@ -3027,7 +3206,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
- "http",
+ "http 1.1.0",
"httparse",
"log",
"rand",
@@ -3260,7 +3439,7 @@ checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
dependencies = [
"windows-result",
"windows-strings",
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -3269,7 +3448,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -3279,7 +3458,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
- "windows-targets",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
]
[[package]]
@@ -3288,7 +3476,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -3297,7 +3485,22 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
]
[[package]]
@@ -3306,28 +3509,46 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
]
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@@ -3340,24 +3561,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
@@ -3373,6 +3618,16 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
[[package]]
name = "ws_stream_wasm"
version = "0.7.4"
diff --git a/examples/developer-hub-rust/Cargo.toml b/examples/developer-hub-rust/Cargo.toml
index 1c5488e2..64bb7bc7 100644
--- a/examples/developer-hub-rust/Cargo.toml
+++ b/examples/developer-hub-rust/Cargo.toml
@@ -9,3 +9,8 @@ edition = "2021"
alloy = { version = "0.2", features = ["full"] }
eyre = "0.6"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
+reqwest = { version = "0.11", features = ["json"] }
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+hex = "0.4"
+
diff --git a/examples/developer-hub-rust/FtsoV2AnchorFeedConsumer.json b/examples/developer-hub-rust/FtsoV2AnchorFeedConsumer.json
new file mode 100644
index 00000000..71fbcbd7
--- /dev/null
+++ b/examples/developer-hub-rust/FtsoV2AnchorFeedConsumer.json
@@ -0,0 +1,107 @@
+{
+ "_format": "hh-sol-artifact-1",
+ "contractName": "FtsoV2AnchorFeedConsumer",
+ "sourceName": "contracts/FtsoV2AnchorFeedConsumer.sol",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes21",
+ "name": "",
+ "type": "bytes21"
+ }
+ ],
+ "name": "provenFeeds",
+ "outputs": [
+ {
+ "internalType": "uint32",
+ "name": "votingRoundId",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes21",
+ "name": "id",
+ "type": "bytes21"
+ },
+ {
+ "internalType": "int32",
+ "name": "value",
+ "type": "int32"
+ },
+ {
+ "internalType": "uint16",
+ "name": "turnoutBIPS",
+ "type": "uint16"
+ },
+ {
+ "internalType": "int8",
+ "name": "decimals",
+ "type": "int8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "bytes32[]",
+ "name": "proof",
+ "type": "bytes32[]"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint32",
+ "name": "votingRoundId",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes21",
+ "name": "id",
+ "type": "bytes21"
+ },
+ {
+ "internalType": "int32",
+ "name": "value",
+ "type": "int32"
+ },
+ {
+ "internalType": "uint16",
+ "name": "turnoutBIPS",
+ "type": "uint16"
+ },
+ {
+ "internalType": "int8",
+ "name": "decimals",
+ "type": "int8"
+ }
+ ],
+ "internalType": "struct FtsoV2Interface.FeedData",
+ "name": "body",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct FtsoV2Interface.FeedDataWithProof",
+ "name": "data",
+ "type": "tuple"
+ }
+ ],
+ "name": "savePrice",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "bytecode": "0x6080604052348015600f57600080fd5b50610f238061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806387179d281461003b578063be2efe0914610057575b600080fd5b61005560048036038101906100509190610345565b61008b565b005b610071600480360381019061006c9190610422565b6101d6565b6040516100829594939291906104d5565b60405180910390f35b61009361025e565b73ffffffffffffffffffffffffffffffffffffffff1663ceb05472826040518263ffffffff1660e01b81526004016100cb9190610841565b602060405180830381865afa1580156100e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010c919061089b565b61014b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161014290610925565b60405180910390fd5b806020016000808360200160000160208101906101689190610945565b63ffffffff1663ffffffff168152602001908152602001600020600083602001602001602081019061019a9190610972565b6affffffffffffffffffffff19166affffffffffffffffffffff1916815260200190815260200160002081816101d09190610db4565b90505050565b6000602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900463ffffffff16908060000160049054906101000a900460581b908060000160199054906101000a900460030b9080600001601d9054906101000a900461ffff169080600001601f9054906101000a900460000b905085565b600073ad67fe66660fb8dfe9d6b1b4240d8650e30f601973ffffffffffffffffffffffffffffffffffffffff1663159354a260405160200161029f90610e0e565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016102d19190610e47565b602060405180830381865afa1580156102ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103129190610ec0565b905090565b600080fd5b600080fd5b600080fd5b600060c0828403121561033c5761033b610321565b5b81905092915050565b60006020828403121561035b5761035a610317565b5b600082013567ffffffffffffffff8111156103795761037861031c565b5b61038584828501610326565b91505092915050565b600063ffffffff82169050919050565b6103a78161038e565b81146103b257600080fd5b50565b6000813590506103c48161039e565b92915050565b60007fffffffffffffffffffffffffffffffffffffffffff000000000000000000000082169050919050565b6103ff816103ca565b811461040a57600080fd5b50565b60008135905061041c816103f6565b92915050565b6000806040838503121561043957610438610317565b5b6000610447858286016103b5565b92505060206104588582860161040d565b9150509250929050565b61046b8161038e565b82525050565b61047a816103ca565b82525050565b60008160030b9050919050565b61049681610480565b82525050565b600061ffff82169050919050565b6104b38161049c565b82525050565b60008160000b9050919050565b6104cf816104b9565b82525050565b600060a0820190506104ea6000830188610462565b6104f76020830187610471565b610504604083018661048d565b61051160608301856104aa565b61051e60808301846104c6565b9695505050505050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261055457610553610532565b5b83810192508235915060208301925067ffffffffffffffff82111561057c5761057b610528565b5b6020820236038313156105925761059161052d565b5b509250929050565b600082825260208201905092915050565b600080fd5b82818337505050565b60006105c5838561059a565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156105f8576105f76105ab565b5b6020830292506106098385846105b0565b82840190509392505050565b600082905092915050565b600061062f60208401846103b5565b905092915050565b6106408161038e565b82525050565b6000610655602084018461040d565b905092915050565b610666816103ca565b82525050565b61067581610480565b811461068057600080fd5b50565b6000813590506106928161066c565b92915050565b60006106a76020840184610683565b905092915050565b6106b881610480565b82525050565b6106c78161049c565b81146106d257600080fd5b50565b6000813590506106e4816106be565b92915050565b60006106f960208401846106d5565b905092915050565b61070a8161049c565b82525050565b610719816104b9565b811461072457600080fd5b50565b60008135905061073681610710565b92915050565b600061074b6020840184610727565b905092915050565b61075c816104b9565b82525050565b60a082016107736000830183610620565b6107806000850182610637565b5061078e6020830183610646565b61079b602085018261065d565b506107a96040830183610698565b6107b660408501826106af565b506107c460608301836106ea565b6107d16060850182610701565b506107df608083018361073c565b6107ec6080850182610753565b50505050565b600060c083016108056000840184610537565b85830360008701526108188382846105b9565b925050506108296020840184610615565b6108366020860182610762565b508091505092915050565b6000602082019050818103600083015261085b81846107f2565b905092915050565b60008115159050919050565b61087881610863565b811461088357600080fd5b50565b6000815190506108958161086f565b92915050565b6000602082840312156108b1576108b0610317565b5b60006108bf84828501610886565b91505092915050565b600082825260208201905092915050565b7f496e76616c69642070726f6f6600000000000000000000000000000000000000600082015250565b600061090f600d836108c8565b915061091a826108d9565b602082019050919050565b6000602082019050818103600083015261093e81610902565b9050919050565b60006020828403121561095b5761095a610317565b5b6000610969848285016103b5565b91505092915050565b60006020828403121561098857610987610317565b5b60006109968482850161040d565b91505092915050565b600081356109ac8161039e565b80915050919050565b60008160001b9050919050565b600063ffffffff6109d2846109b5565b9350801983169250808416831791505092915050565b6000819050919050565b6000610a0d610a08610a038461038e565b6109e8565b61038e565b9050919050565b6000819050919050565b610a27826109f2565b610a3a610a3382610a14565b83546109c2565b8255505050565b60008135610a4e816103f6565b80915050919050565b60008160201b9050919050565b600078ffffffffffffffffffffffffffffffffffffffffff00000000610a8984610a57565b9350801983169250808416831791505092915050565b6000610aaa826103ca565b9050919050565b60008160581c9050919050565b6000610ac982610ab1565b9050919050565b610ad982610a9f565b610aec610ae582610abe565b8354610a64565b8255505050565b60008135610b008161066c565b80915050919050565b60008160c81b9050919050565b60007cffffffff00000000000000000000000000000000000000000000000000610b3f84610b09565b9350801983169250808416831791505092915050565b6000610b70610b6b610b6684610480565b6109e8565b610480565b9050919050565b6000819050919050565b610b8a82610b55565b610b9d610b9682610b77565b8354610b16565b8255505050565b60008135610bb1816106be565b80915050919050565b60008160e81b9050919050565b60007effff0000000000000000000000000000000000000000000000000000000000610bf284610bba565b9350801983169250808416831791505092915050565b6000610c23610c1e610c198461049c565b6109e8565b61049c565b9050919050565b6000819050919050565b610c3d82610c08565b610c50610c4982610c2a565b8354610bc7565b8255505050565b60008135610c6481610710565b80915050919050565b60008160f81b9050919050565b60007fff00000000000000000000000000000000000000000000000000000000000000610ca684610c6d565b9350801983169250808416831791505092915050565b6000610cd7610cd2610ccd846104b9565b6109e8565b6104b9565b9050919050565b6000819050919050565b610cf182610cbc565b610d04610cfd82610cde565b8354610c7a565b8255505050565b600081016000830180610d1d8161099f565b9050610d298184610a1e565b505050600081016020830180610d3e81610a41565b9050610d4a8184610ad0565b505050600081016040830180610d5f81610af3565b9050610d6b8184610b81565b505050600081016060830180610d8081610ba4565b9050610d8c8184610c34565b505050600081016080830180610da181610c57565b9050610dad8184610ce8565b5050505050565b610dbe8282610d0b565b5050565b7f4674736f56320000000000000000000000000000000000000000000000000000600082015250565b6000610df86006836108c8565b9150610e0382610dc2565b602082019050919050565b60006020820190508181036000830152610e2781610deb565b9050919050565b6000819050919050565b610e4181610e2e565b82525050565b6000602082019050610e5c6000830184610e38565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e8d82610e62565b9050919050565b610e9d81610e82565b8114610ea857600080fd5b50565b600081519050610eba81610e94565b92915050565b600060208284031215610ed657610ed5610317565b5b6000610ee484828501610eab565b9150509291505056fea2646970667358221220cb4a481bd7152d851d3925792e28e73d10426823cf62f83d916e51a0fd1ce1de64736f6c634300081c0033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806387179d281461003b578063be2efe0914610057575b600080fd5b61005560048036038101906100509190610345565b61008b565b005b610071600480360381019061006c9190610422565b6101d6565b6040516100829594939291906104d5565b60405180910390f35b61009361025e565b73ffffffffffffffffffffffffffffffffffffffff1663ceb05472826040518263ffffffff1660e01b81526004016100cb9190610841565b602060405180830381865afa1580156100e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010c919061089b565b61014b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161014290610925565b60405180910390fd5b806020016000808360200160000160208101906101689190610945565b63ffffffff1663ffffffff168152602001908152602001600020600083602001602001602081019061019a9190610972565b6affffffffffffffffffffff19166affffffffffffffffffffff1916815260200190815260200160002081816101d09190610db4565b90505050565b6000602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900463ffffffff16908060000160049054906101000a900460581b908060000160199054906101000a900460030b9080600001601d9054906101000a900461ffff169080600001601f9054906101000a900460000b905085565b600073ad67fe66660fb8dfe9d6b1b4240d8650e30f601973ffffffffffffffffffffffffffffffffffffffff1663159354a260405160200161029f90610e0e565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016102d19190610e47565b602060405180830381865afa1580156102ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103129190610ec0565b905090565b600080fd5b600080fd5b600080fd5b600060c0828403121561033c5761033b610321565b5b81905092915050565b60006020828403121561035b5761035a610317565b5b600082013567ffffffffffffffff8111156103795761037861031c565b5b61038584828501610326565b91505092915050565b600063ffffffff82169050919050565b6103a78161038e565b81146103b257600080fd5b50565b6000813590506103c48161039e565b92915050565b60007fffffffffffffffffffffffffffffffffffffffffff000000000000000000000082169050919050565b6103ff816103ca565b811461040a57600080fd5b50565b60008135905061041c816103f6565b92915050565b6000806040838503121561043957610438610317565b5b6000610447858286016103b5565b92505060206104588582860161040d565b9150509250929050565b61046b8161038e565b82525050565b61047a816103ca565b82525050565b60008160030b9050919050565b61049681610480565b82525050565b600061ffff82169050919050565b6104b38161049c565b82525050565b60008160000b9050919050565b6104cf816104b9565b82525050565b600060a0820190506104ea6000830188610462565b6104f76020830187610471565b610504604083018661048d565b61051160608301856104aa565b61051e60808301846104c6565b9695505050505050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261055457610553610532565b5b83810192508235915060208301925067ffffffffffffffff82111561057c5761057b610528565b5b6020820236038313156105925761059161052d565b5b509250929050565b600082825260208201905092915050565b600080fd5b82818337505050565b60006105c5838561059a565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156105f8576105f76105ab565b5b6020830292506106098385846105b0565b82840190509392505050565b600082905092915050565b600061062f60208401846103b5565b905092915050565b6106408161038e565b82525050565b6000610655602084018461040d565b905092915050565b610666816103ca565b82525050565b61067581610480565b811461068057600080fd5b50565b6000813590506106928161066c565b92915050565b60006106a76020840184610683565b905092915050565b6106b881610480565b82525050565b6106c78161049c565b81146106d257600080fd5b50565b6000813590506106e4816106be565b92915050565b60006106f960208401846106d5565b905092915050565b61070a8161049c565b82525050565b610719816104b9565b811461072457600080fd5b50565b60008135905061073681610710565b92915050565b600061074b6020840184610727565b905092915050565b61075c816104b9565b82525050565b60a082016107736000830183610620565b6107806000850182610637565b5061078e6020830183610646565b61079b602085018261065d565b506107a96040830183610698565b6107b660408501826106af565b506107c460608301836106ea565b6107d16060850182610701565b506107df608083018361073c565b6107ec6080850182610753565b50505050565b600060c083016108056000840184610537565b85830360008701526108188382846105b9565b925050506108296020840184610615565b6108366020860182610762565b508091505092915050565b6000602082019050818103600083015261085b81846107f2565b905092915050565b60008115159050919050565b61087881610863565b811461088357600080fd5b50565b6000815190506108958161086f565b92915050565b6000602082840312156108b1576108b0610317565b5b60006108bf84828501610886565b91505092915050565b600082825260208201905092915050565b7f496e76616c69642070726f6f6600000000000000000000000000000000000000600082015250565b600061090f600d836108c8565b915061091a826108d9565b602082019050919050565b6000602082019050818103600083015261093e81610902565b9050919050565b60006020828403121561095b5761095a610317565b5b6000610969848285016103b5565b91505092915050565b60006020828403121561098857610987610317565b5b60006109968482850161040d565b91505092915050565b600081356109ac8161039e565b80915050919050565b60008160001b9050919050565b600063ffffffff6109d2846109b5565b9350801983169250808416831791505092915050565b6000819050919050565b6000610a0d610a08610a038461038e565b6109e8565b61038e565b9050919050565b6000819050919050565b610a27826109f2565b610a3a610a3382610a14565b83546109c2565b8255505050565b60008135610a4e816103f6565b80915050919050565b60008160201b9050919050565b600078ffffffffffffffffffffffffffffffffffffffffff00000000610a8984610a57565b9350801983169250808416831791505092915050565b6000610aaa826103ca565b9050919050565b60008160581c9050919050565b6000610ac982610ab1565b9050919050565b610ad982610a9f565b610aec610ae582610abe565b8354610a64565b8255505050565b60008135610b008161066c565b80915050919050565b60008160c81b9050919050565b60007cffffffff00000000000000000000000000000000000000000000000000610b3f84610b09565b9350801983169250808416831791505092915050565b6000610b70610b6b610b6684610480565b6109e8565b610480565b9050919050565b6000819050919050565b610b8a82610b55565b610b9d610b9682610b77565b8354610b16565b8255505050565b60008135610bb1816106be565b80915050919050565b60008160e81b9050919050565b60007effff0000000000000000000000000000000000000000000000000000000000610bf284610bba565b9350801983169250808416831791505092915050565b6000610c23610c1e610c198461049c565b6109e8565b61049c565b9050919050565b6000819050919050565b610c3d82610c08565b610c50610c4982610c2a565b8354610bc7565b8255505050565b60008135610c6481610710565b80915050919050565b60008160f81b9050919050565b60007fff00000000000000000000000000000000000000000000000000000000000000610ca684610c6d565b9350801983169250808416831791505092915050565b6000610cd7610cd2610ccd846104b9565b6109e8565b6104b9565b9050919050565b6000819050919050565b610cf182610cbc565b610d04610cfd82610cde565b8354610c7a565b8255505050565b600081016000830180610d1d8161099f565b9050610d298184610a1e565b505050600081016020830180610d3e81610a41565b9050610d4a8184610ad0565b505050600081016040830180610d5f81610af3565b9050610d6b8184610b81565b505050600081016060830180610d8081610ba4565b9050610d8c8184610c34565b505050600081016080830180610da181610c57565b9050610dad8184610ce8565b5050505050565b610dbe8282610d0b565b5050565b7f4674736f56320000000000000000000000000000000000000000000000000000600082015250565b6000610df86006836108c8565b9150610e0382610dc2565b602082019050919050565b60006020820190508181036000830152610e2781610deb565b9050919050565b6000819050919050565b610e4181610e2e565b82525050565b6000602082019050610e5c6000830184610e38565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e8d82610e62565b9050919050565b610e9d81610e82565b8114610ea857600080fd5b50565b600081519050610eba81610e94565b92915050565b600060208284031215610ed657610ed5610317565b5b6000610ee484828501610eab565b9150509291505056fea2646970667358221220cb4a481bd7152d851d3925792e28e73d10426823cf62f83d916e51a0fd1ce1de64736f6c634300081c0033",
+ "linkReferences": {},
+ "deployedLinkReferences": {}
+}
diff --git a/examples/developer-hub-rust/src/bin/fetch_anchor_feeds.rs b/examples/developer-hub-rust/src/bin/fetch_anchor_feeds.rs
new file mode 100644
index 00000000..1e7979c5
--- /dev/null
+++ b/examples/developer-hub-rust/src/bin/fetch_anchor_feeds.rs
@@ -0,0 +1,45 @@
+#![allow(dead_code)]
+#![allow(unused)]
+
+use reqwest::Client;
+use serde_json::json;
+
+const BASE_URL: &str = "https://flr-data-availability.flare.network/";
+const API_KEY: &str = "";
+
+const FEED_IDS: &[&str] = &[
+ "0x01464c522f55534400000000000000000000000000", // FLR/USD
+ "0x014254432f55534400000000000000000000000000", // BTC/USD
+ "0x014554482f55534400000000000000000000000000", // ETH/USD
+];
+
+pub async fn fetch_anchor_feed(
+ feed_ids: &[&str],
+ voting_round_id: Option,
+) -> Result, reqwest::Error> {
+ let client = Client::new();
+
+ let mut url = format!("{BASE_URL}api/v0/ftso/anchor-feeds-with-proof");
+ if let Some(id) = voting_round_id {
+ url.push_str(&format!("?voting_round_id={}", id));
+ }
+
+ let response = client
+ .post(&url)
+ .header("X-API-KEY", API_KEY)
+ .header("Content-Type", "application/json")
+ .json(&json!({ "feed_ids": feed_ids }))
+ .send()
+ .await?;
+
+ let json: Vec = response.json().await?;
+ Ok(json)
+}
+
+#[tokio::main]
+async fn main() {
+ match fetch_anchor_feed(FEED_IDS, None).await {
+ Ok(data) => println!("Anchor feeds data: {:?}", data),
+ Err(err) => eprintln!("Error fetching anchor feeds: {}", err),
+ }
+}
diff --git a/examples/developer-hub-rust/src/bin/fetch_and_verify_anchor_onchain.rs b/examples/developer-hub-rust/src/bin/fetch_and_verify_anchor_onchain.rs
new file mode 100644
index 00000000..020037b3
--- /dev/null
+++ b/examples/developer-hub-rust/src/bin/fetch_and_verify_anchor_onchain.rs
@@ -0,0 +1,172 @@
+use crate::FtsoV2AnchorFeedConsumer::{FeedData, FeedDataWithProof};
+use alloy::{
+ network::EthereumWallet,
+ primitives::{address, hex, FixedBytes},
+ providers::{Provider, ProviderBuilder},
+ signers::local::PrivateKeySigner,
+ sol,
+};
+use hex::FromHex;
+use serde_json::Value;
+
+// Import the fetch_anchor_feeds module
+mod fetch_anchor_feeds;
+
+// ABI bindings for the Solidity contract
+sol!(
+ #[sol(rpc)]
+ FtsoV2AnchorFeedConsumer,
+ "FtsoV2AnchorFeedConsumer.json"
+);
+
+const BTC_USD_FEED_ID: &str = "0x014254432f55534400000000000000000000000000";
+const TARGET_VOTING_ROUND: u32 = 823402;
+
+mod convert_type {
+ use super::*;
+
+ // Functions for type conversion
+ pub fn as_u16(value: &Value) -> Result> {
+ value
+ .as_u64()
+ .and_then(|v| v.try_into().ok())
+ .ok_or("Invalid u16 value".into())
+ }
+
+ pub fn as_u32(value: &Value) -> Result> {
+ value
+ .as_u64()
+ .and_then(|v| v.try_into().ok())
+ .ok_or("Invalid u32 value".into())
+ }
+
+ pub fn as_i8(value: &Value) -> Result> {
+ value
+ .as_i64()
+ .and_then(|v| v.try_into().ok())
+ .ok_or("Invalid i8 value".into())
+ }
+
+ pub fn as_i32(value: &Value) -> Result> {
+ value
+ .as_i64()
+ .and_then(|v| v.try_into().ok())
+ .ok_or("Invalid i32 value".into())
+ }
+
+ // Function to convert JSON proofs to FixedBytes
+ pub fn json_proofs_to_fixed_bytes(
+ proofs: &[Value],
+ ) -> Result>, Box> {
+ let mut result = Vec::new();
+
+ for proof in proofs {
+ let proof_str = proof.as_str().ok_or("Proof value is not a string")?;
+
+ // Validate and convert hex string
+ let fixed_bytes = hex_to_fixed_bytes_32(proof_str)?;
+ result.push(fixed_bytes);
+ }
+
+ Ok(result)
+ }
+
+ // Function to convert hex string to FixedBytes<32>
+ pub fn hex_to_fixed_bytes_32(
+ hex_str: &str,
+ ) -> Result, Box> {
+ // Handle both 0x-prefixed and unprefixed hex strings
+ let clean_hex = if hex_str.starts_with("0x") || hex_str.starts_with("0X") {
+ &hex_str[2..]
+ } else {
+ hex_str
+ };
+
+ // Validate length (64 characters = 32 bytes)
+ if clean_hex.len() != 64 {
+ return Err(format!(
+ "Hex string must be 64 characters (32 bytes), got {} characters",
+ clean_hex.len()
+ )
+ .into());
+ }
+
+ // Convert hex to bytes using the hex crate
+ let mut bytes = [0u8; 32];
+ hex::decode_to_slice(clean_hex, &mut bytes)
+ .map_err(|e| format!("Hex decoding failed: {}", e))?;
+
+ Ok(FixedBytes::<32>::from(bytes))
+ }
+}
+
+#[tokio::main]
+async fn main() -> Result<(), Box> {
+ let feed_data: Vec =
+ fetch_anchor_feeds::fetch_anchor_feed(&[BTC_USD_FEED_ID], Some(TARGET_VOTING_ROUND))
+ .await?;
+
+ let raw_proofs = feed_data[0]["proof"]
+ .as_array()
+ .ok_or("Missing or invalid proof array")?;
+ let raw_body = feed_data[0]["body"]
+ .as_object()
+ .ok_or("Missing or invalid body object")?;
+
+ let byte_proof = convert_type::json_proofs_to_fixed_bytes(raw_proofs)?;
+
+ let body_data = FeedData {
+ decimals: convert_type::as_i8(&raw_body["decimals"])?,
+ id: FixedBytes::<21>::from_slice(&hex::decode(
+ raw_body["id"].as_str().ok_or("Invalid id format")?,
+ )?),
+ turnoutBIPS: convert_type::as_u16(&raw_body["turnoutBIPS"])?,
+ value: convert_type::as_i32(&raw_body["value"])?,
+ votingRoundId: convert_type::as_u32(&raw_body["votingRoundId"])?,
+ };
+
+ let contract_address = address!("069227C6A947d852c55655e41C6a382868627920");
+ let private_key = " your_private_key_here";
+
+ let signer: PrivateKeySigner = private_key.parse()?;
+ let wallet = EthereumWallet::from(signer.clone());
+
+ let provider = ProviderBuilder::new()
+ .with_recommended_fillers()
+ .wallet(wallet)
+ .on_http("https://coston2-api.flare.network/ext/C/rpc".parse()?);
+
+ let latest_block = provider.get_block_number().await?;
+ println!("Latest block number: {latest_block}");
+
+ let contract = FtsoV2AnchorFeedConsumer::new(contract_address, provider);
+
+ let feed_data_with_proof = FeedDataWithProof {
+ proof: byte_proof,
+ body: body_data,
+ };
+
+ let tx_hash = contract
+ .savePrice(feed_data_with_proof)
+ .send()
+ .await?
+ .watch()
+ .await?;
+
+ println!("Save Price transaction hash: {}", tx_hash);
+
+ let feed_id: FixedBytes<21> = {
+ let hex_str = BTC_USD_FEED_ID
+ .strip_prefix("0x")
+ .unwrap_or(BTC_USD_FEED_ID);
+ let bytes: [u8; 21] = <[u8; 21]>::from_hex(hex_str)?;
+ FixedBytes::new(bytes)
+ };
+ let saved_price = contract
+ .provenFeeds(TARGET_VOTING_ROUND, feed_id)
+ .call()
+ .await?;
+ println!("Saved Price is {}", saved_price.value);
+
+ Ok(())
+}