diff --git a/examples/contracts/aggregator-consumer/.gitignore b/examples/contracts/aggregator-consumer/.gitignore deleted file mode 100644 index 96611b42c..000000000 --- a/examples/contracts/aggregator-consumer/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target -cache/ -starknet-artifacts/ diff --git a/examples/contracts/aggregator-consumer/README.md b/examples/contracts/aggregator-consumer/README.md deleted file mode 100644 index e390b44ef..000000000 --- a/examples/contracts/aggregator-consumer/README.md +++ /dev/null @@ -1,70 +0,0 @@ -This example demonstrates how consumer contracts can read from the aggregator, with and without consideration of the uptime feed address. Recall that the purpose of the uptime feed is to let consumer contracts know if the L2 layer is up and healthy. - -We demonstrate these examples by mocking an aggregator to return stubbed values. - -You can run this example on your local devnet or on goerli (up to you). NOTE: at the time of writing, the examples only work against devnet due to Starknet version incompatability. - -Note: `.env` will contain account details, such as DEPLOYER_ACCOUNT_ADDRESS and DEPLOYER_PRIVATE_KEY - -## Deploy on Devnet - -### 1. Install Local Dev Environment - -Follow [steps 1 and 2 here](../proxy_consumer/README.md) - -At this point, you should have starknet-devnet, cairo, and scarb installed. Your virtualenv will also have the starknet cli tool but we won't be using that to test against devnet - -All instructions begin at the root of this folder -### 2. Compile cairo 1 contracts - -``` - yarn compile:cairo -``` - - -### 3. Setup Starknet Devnet - -In a seperate terminal, run: -``` - starknet-devnet --cairo-compiler-manifest ../../vendor/cairo/Cargo.toml --seed 0 --lite-mode ../../../vendor/cairo/Cargo.toml -``` -This will start up the devnet and enable you to deploy and run cairo 1 contracts against it - -### 4. Deploy Devnet Account - -This command will deploy a devnet account onto devnet and write the DEPLOYER_ACCOUNT_ADDRESS and DEPLOYER_PRIVATE_KEY into a .env file in the current directory (it will create .env if it doesn't exist). This account will be utilized for deploying and interacting with the rest of the contracts in this section. - -``` - yarn deployAccount -``` - -## 5. Deploy Contracts - -This will deploy the following contracts: -* SequencerUptimeFeed: Displays the status of the L2 layer. If it is up, then it is safe to read from the aggregator contract. For more information please see this [document](../../../docs/emergency-protocol/README.md). -* MockAggregator: A mocked version of the aggregator with limited functionality. It gives the reader the ability to set and view the latest round data in order so the reader can familiarize themselves for testing purposes. -* AggregatorConsumer: Simply reads the mocked aggregator's latest values -* AggregatorPriceConsumerWithSequencer: Reads the mocked aggregator's values but also queries the SequencerUptimeFeed to determine if the value should be used or not. If the SequencerUptimeFeed is too stale, then that means the L2 layer is down. We've arbitrarily chosen the threshold of 60 seconds. - - -``` - yarn deployContracts -``` - -## 6. Interact with Contracts - -``` -# deployer calls AggregatorConsumer to read the decimals method of the MockAggregator -yarn readDecimals - -# deployer calls AggregatorConsumer to read the latest round of the MockAggregator -yarn readLatestRound - -# deployer calls Aggregator Consumer to poll decimals AND latest round of MockAggregator -yarn readContinuously - -# deployer calls MockAggregator to manually set the new round's data -yarn updateLatestRound - -# deployer calls AggregatorPriceConsumerWithSequencer to read latest round or revert if uptime feed is stale -yarn getLatestPriceSeqCheck diff --git a/examples/contracts/aggregator-consumer/Scarb.toml b/examples/contracts/aggregator-consumer/Scarb.toml deleted file mode 100644 index 18ac52c35..000000000 --- a/examples/contracts/aggregator-consumer/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "chainlink_examples" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] - chainlink = { path = "../../../contracts" } - -[[target.starknet-contract]] -# note these two options only work on scarb 0.2.0 and forward -casm = true -# Emit Python-powered hints in order to run compiled CASM class with legacy Cairo VM. -casm-add-pythonic-hints = true diff --git a/examples/contracts/aggregator-consumer/cairo_project.toml b/examples/contracts/aggregator-consumer/cairo_project.toml deleted file mode 100644 index e2ab1041e..000000000 --- a/examples/contracts/aggregator-consumer/cairo_project.toml +++ /dev/null @@ -1,2 +0,0 @@ -[crate_roots] -chainlink_examples = "src" diff --git a/examples/contracts/aggregator-consumer/example.env b/examples/contracts/aggregator-consumer/example.env deleted file mode 100644 index 7d29ecc93..000000000 --- a/examples/contracts/aggregator-consumer/example.env +++ /dev/null @@ -1,11 +0,0 @@ -# This is a an example .env file that contains pre-deployed and pre-funded account that come with starknet-devnet -# To see a complete list of pre-deployed starknet-devnet accounts just run `starknet-devnet` - -# hypothetical devnet account -DEPLOYER_ACCOUNT_ADDRESS= -DEPLOYER_PRIVATE_KEY= - -# Below is what you'd set to run these examples on GOERLI -# DEPLOYER_ACCOUNT_ADDRESS= -# DEPLOYER_PRIVATE_KEY= -# NETWORK=GOERLI diff --git a/examples/contracts/aggregator-consumer/hardhat.config.ts b/examples/contracts/aggregator-consumer/hardhat.config.ts deleted file mode 100644 index 965b87a03..000000000 --- a/examples/contracts/aggregator-consumer/hardhat.config.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { HardhatUserConfig } from 'hardhat/types' -import '@shardlabs/starknet-hardhat-plugin' -import '@nomiclabs/hardhat-ethers' - -const config: HardhatUserConfig = { - solidity: '0.8.14', - starknet: { - venv: 'active', - network: 'devnet', - wallets: { - OpenZeppelin: { - accountName: 'OpenZeppelin', - modulePath: 'starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount', - accountPath: '~/.starknet_accounts', - }, - }, - }, - networks: { - devnet: { - url: 'http://127.0.0.1:5050', - args: ['--cairo-compiler-manifest', '../../../vendor/cairo/Cargo.toml'], - }, - integratedDevnet: { - url: 'http://127.0.0.1:5050', - venv: 'active', - args: ['--cairo-compiler-manifest', '../../../vendor/cairo/Cargo.toml', '--lite-mode'], - // dockerizedVersion: "0.2.0" - }, - }, - paths: { - cairoPaths: ['../../contracts/src'], - }, -} - -export default config diff --git a/examples/contracts/aggregator-consumer/package.json b/examples/contracts/aggregator-consumer/package.json deleted file mode 100644 index 2aff8abbe..000000000 --- a/examples/contracts/aggregator-consumer/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@chainlink/latest-starknet-ocr2-consumer", - "version": "0.1.0", - "description": "", - "main": "index.js", - "scripts": { - "compile:cairo": "scarb --profile release build", - "compile": "yarn compile:cairo", - "test": "yarn hardhat --network localhost test", - "deployAccount": "yarn ts-node ./scripts/deploy_accounts.ts", - "deployContracts": "yarn ts-node ./scripts/deploy_contracts.ts", - "readDecimals": "yarn ts-node ./scripts/readDecimals.ts", - "readLatestRound": "yarn ts-node ./scripts/readLatestRound.ts", - "readContinuously": "yarn ts-node ./scripts/readContinuously.ts", - "updateLatestRound": "yarn ts-node ./scripts/updateLatestRound.ts", - "getLatestPriceSeqCheck": "yarn ts-node ./scripts/getLatestPriceSeqCheck.ts" - }, - "keywords": [], - "author": "", - "license": "MIT", - "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.1.0", - "@shardlabs/starknet-hardhat-plugin": "^0.8.0-alpha.0", - "@types/chai": "^4.3.3", - "@types/mocha": "^9.1.1", - "chai": "^4.3.6", - "hardhat": "^*" - }, - "dependencies": { - "@chainlink/starknet": "^1.0.0", - "dotenv": "^16.0.1" - } -} diff --git a/examples/contracts/aggregator-consumer/scripts/consumerValidator.ts b/examples/contracts/aggregator-consumer/scripts/consumerValidator.ts deleted file mode 100644 index 6441c3ff2..000000000 --- a/examples/contracts/aggregator-consumer/scripts/consumerValidator.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { ethers, starknet, network } from 'hardhat' -import { Contract, ContractFactory } from 'ethers' -import { HttpNetworkConfig } from 'hardhat/types' - -import dotenv from 'dotenv' -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { deployMockContract, MockContract } from '@ethereum-waffle/mock-contract' -import { Account, CompiledContract, Contract as StarknetContract } from 'starknet' -import { - createDeployerAccount, - loadContractPath, - loadContract_Solidity, - loadContract_Solidity_V8, - makeProvider, -} from './utils' - -dotenv.config({ path: __dirname + '/../.env' }) -const UPTIME_FEED_PATH = '../../../../contracts/target/release/chainlink_SequencerUptimeFeed' - -// TODO: need to modify when the cairo-1.0 branch is rebased to include StarknetValidator changes - -let validator: Contract -let mockStarknetMessengerFactory: ContractFactory -let mockStarknetMessenger: Contract -let deployer: SignerWithAddress -let eoaValidator: SignerWithAddress -let networkUrl: string -let account: Account - -let mockGasPriceFeed: MockContract -let mockAccessController: MockContract -let mockAggregator: MockContract - -export async function consumerValidator() { - const provider = makeProvider() - - account = createDeployerAccount(provider) - - networkUrl = (network.config as HttpNetworkConfig).url - const accounts = await ethers.getSigners() - deployer = accounts[0] - eoaValidator = accounts[1] - - const aggregatorAbi = loadContract_Solidity_V8('AggregatorV3Interface') - const accessControllerAbi = loadContract_Solidity_V8('AccessControllerInterface') - - // Deploy the mock feed - mockGasPriceFeed = await deployMockContract(deployer, aggregatorAbi.abi) - await mockGasPriceFeed.mock.latestRoundData.returns( - '73786976294838220258' /** roundId */, - '96800000000' /** answer */, - '163826896' /** startedAt */, - '1638268960' /** updatedAt */, - '73786976294838220258' /** answeredInRound */, - ) - - // Deploy the mock access controller - mockAccessController = await deployMockContract(deployer, accessControllerAbi.abi) - - // Deploy the mock aggregator - mockAggregator = await deployMockContract(deployer, aggregatorAbi.abi) - await mockAggregator.mock.latestRoundData.returns( - '73786976294838220258' /** roundId */, - 1 /** answer */, - '163826896' /** startedAt */, - '1638268960' /** updatedAt */, - '73786976294838220258' /** answeredInRound */, - ) - - const validatorArtifact = await loadContract_Solidity('emergency', 'StarknetValidator') - const validatorFactory = await ethers.getContractFactoryFromArtifact(validatorArtifact, deployer) - - const mockStarknetMessagingArtifact = await loadContract_Solidity( - 'mocks', - 'MockStarknetMessaging', - ) - mockStarknetMessengerFactory = await ethers.getContractFactoryFromArtifact( - mockStarknetMessagingArtifact, - deployer, - ) - - const messageCancellationDelay = 5 * 60 // seconds - mockStarknetMessenger = await mockStarknetMessengerFactory.deploy(messageCancellationDelay) - await mockStarknetMessenger.deployed() - - const UptimeFeedArtifact = loadContractPath(UPTIME_FEED_PATH) as CompiledContract - - const mockUptimeFeedDeploy = new StarknetContract( - UptimeFeedArtifact.abi, - process.env.UPTIME_FEED as string, - provider, - ) - - mockUptimeFeedDeploy.connect(account) - - validator = await validatorFactory.deploy( - mockStarknetMessenger.address, - mockAccessController.address, - mockGasPriceFeed.address, - mockAggregator.address, - mockUptimeFeedDeploy.address, - 0, - ) - - console.log('Validator address: ', validator.address) - - const tx = await mockUptimeFeedDeploy.invoke('set_l1_sender', [validator.address]) - - await provider.waitForTransaction(tx.transaction_hash) - - await validator.addAccess(eoaValidator.address) - setInterval(callFunction, 60_000) -} - -async function callFunction() { - await starknet.devnet.loadL1MessagingContract(networkUrl, mockStarknetMessenger.address) - - await validator.connect(eoaValidator).validate(0, 0, 1, 1) - - const flushL1Response = await starknet.devnet.flush() - flushL1Response.consumed_messages.from_l1 -} -consumerValidator() diff --git a/examples/contracts/aggregator-consumer/scripts/deploy_accounts.ts b/examples/contracts/aggregator-consumer/scripts/deploy_accounts.ts deleted file mode 100644 index e031c63fa..000000000 --- a/examples/contracts/aggregator-consumer/scripts/deploy_accounts.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as fs from 'fs' -import * as dotenv from 'dotenv' -import { starknet } from 'hardhat' -import { exit } from 'node:process' -import { loadContract_Account, makeProvider } from './utils' -import { Account, CallData, ec, hash } from 'starknet' - -const ENV_PATH = __dirname + '/../.env' - -dotenv.config({ path: ENV_PATH }) - -interface UserAccount { - address: string - privateKey: string -} - -export async function deployAccount() { - const account = await createAccount() - - try { - fs.appendFileSync(ENV_PATH, '\n# Autogenerated Dev Account from ./scripts/deploy_account.ts') - fs.appendFileSync(ENV_PATH, '\nDEPLOYER_ACCOUNT_ADDRESS=' + account.address) - fs.appendFileSync(ENV_PATH, '\nDEPLOYER_PRIVATE_KEY=' + account.privateKey) - } catch (err) { - throw err - } - - exit(0) // must manually exit due to ts-node weirdness -} - -async function createAccount(): Promise { - // use pre-deployed accounts to deploy new OZ account - const accounts = await starknet.devnet.getPredeployedAccounts() - const account = accounts[0] - const provider = makeProvider() - const fundedAccount = new Account(provider, account.address, account.private_key) - - // define account parameters - const OZaccountClassHash = '0x4d07e40e93398ed3c76981e72dd1fd22557a78ce36c0515f679e27f0bb5bc5f' - const compiledAccount = loadContract_Account('Account') - const privateKey = ec.starkCurve.utils.randomPrivateKey() - const starkKeyPub = ec.starkCurve.getStarkKey(privateKey) - const OZaccountConstructorCallData = CallData.compile({ publicKey: starkKeyPub }) - - // declare OZ account - const declareTx = await fundedAccount.declare({ - classHash: OZaccountClassHash, - contract: compiledAccount, - }) - console.log('Declare new Account...') - await provider.waitForTransaction(declareTx.transaction_hash) - - // fund OZ account - const OZcontractAddress = hash.calculateContractAddressFromHash( - starkKeyPub, - OZaccountClassHash, - OZaccountConstructorCallData, - 0, - ) - console.log('hash calculation contract address', OZcontractAddress) - await starknet.devnet.mint(OZcontractAddress, 1e22, true) - - // // deploy - const OZaccount = new Account(provider, OZcontractAddress, privateKey) - - const { transaction_hash, contract_address } = await OZaccount.deployAccount({ - classHash: OZaccountClassHash, - constructorCalldata: OZaccountConstructorCallData, - addressSalt: starkKeyPub, - }) - - console.log('Waiting for Tx to be Accepted on Starknet - OZ Account Deployment...') - await provider.waitForTransaction(transaction_hash) - - console.log('actual contract address', contract_address) - - return { address: contract_address, privateKey: '0x' + Buffer.from(privateKey).toString('hex') } -} - -deployAccount() diff --git a/examples/contracts/aggregator-consumer/scripts/deploy_contracts.ts b/examples/contracts/aggregator-consumer/scripts/deploy_contracts.ts deleted file mode 100644 index ece2fed60..000000000 --- a/examples/contracts/aggregator-consumer/scripts/deploy_contracts.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { CairoAssembly, CallData, CompiledContract, Contract } from 'starknet' -import { - loadContract, - createDeployerAccount, - loadContractPath, - makeProvider, - loadCasmContract, -} from './utils' -import * as fs from 'fs' -import * as dotenv from 'dotenv' - -const AGGREGATOR = 'MockAggregator' - -const AGGREGATOR_PATH = '../../../../contracts/target/release/chainlink_MockAggregator' - -const CONSUMER = 'AggregatorConsumer' - -const UPTIME_FEED_PATH = '../../../../contracts/target/release/chainlink_SequencerUptimeFeed' - -const PRICE_CONSUMER = 'AggregatorPriceConsumerWithSequencer' - -const DECIMALS = '18' - -dotenv.config({ path: __dirname + '/../.env' }) - -export async function deployContract() { - const provider = makeProvider() - const AggregatorArtifact = loadContractPath(`${AGGREGATOR_PATH}.sierra`) as CompiledContract - const ConsumerArtifact = loadContract(CONSUMER) - const PriceConsumerArtifact = loadContract(PRICE_CONSUMER) - const UptimeFeedArtifact = loadContractPath(`${UPTIME_FEED_PATH}.sierra`) as CompiledContract - - const account = createDeployerAccount(provider) - - console.log('Deploying Contracts...(this may take 3-5 minutes)') - - const declareDeployAggregator = await account.declareAndDeploy({ - casm: loadContractPath(`${AGGREGATOR_PATH}.casm`) as CairoAssembly, - contract: AggregatorArtifact, - constructorCalldata: [DECIMALS], - }) - - const aggregatorDeploy = new Contract( - AggregatorArtifact.abi, - declareDeployAggregator.deploy.contract_address, - provider, - ) - - const declareDeployConsumer = await account.declareAndDeploy({ - casm: loadCasmContract(CONSUMER), - contract: ConsumerArtifact, - constructorCalldata: [aggregatorDeploy.address as string], - }) - - const consumerDeploy = new Contract( - ConsumerArtifact.abi, - declareDeployConsumer.deploy.contract_address, - provider, - ) - - const declareDeployUptimeFeed = await account.declareAndDeploy({ - casm: loadContractPath(`${UPTIME_FEED_PATH}.casm`) as CairoAssembly, - contract: UptimeFeedArtifact, - constructorCalldata: ['0', account.address], - }) - - const uptimeFeedDeploy = new Contract( - UptimeFeedArtifact.abi, - declareDeployUptimeFeed.deploy.contract_address, - provider, - ) - - const declareDeployPriceConsumer = await account.declareAndDeploy({ - casm: loadCasmContract(PRICE_CONSUMER), - contract: PriceConsumerArtifact, - constructorCalldata: [uptimeFeedDeploy.address as string, aggregatorDeploy.address as string], - }) - - const priceConsumerDeploy = new Contract( - PriceConsumerArtifact.abi, - declareDeployPriceConsumer.deploy.contract_address, - provider, - ) - - fs.appendFile(__dirname + '/../.env', '\nCONSUMER=' + consumerDeploy.address, function (err) { - if (err) throw err - }) - fs.appendFile(__dirname + '/../.env', '\nMOCK=' + aggregatorDeploy.address, function (err) { - if (err) throw err - }) - fs.appendFile( - __dirname + '/../.env', - '\nPRICE_CONSUMER=' + priceConsumerDeploy.address, - function (err) { - if (err) throw err - }, - ) - fs.appendFile(__dirname + '/../.env', '\nUPTIME_FEED=' + uptimeFeedDeploy.address, function ( - err, - ) { - if (err) throw err - }) -} - -deployContract() diff --git a/examples/contracts/aggregator-consumer/scripts/getLatestPriceSeqCheck.ts b/examples/contracts/aggregator-consumer/scripts/getLatestPriceSeqCheck.ts deleted file mode 100644 index d58cb9c27..000000000 --- a/examples/contracts/aggregator-consumer/scripts/getLatestPriceSeqCheck.ts +++ /dev/null @@ -1,79 +0,0 @@ -import dotenv from 'dotenv' -import { createDeployerAccount, loadContract, loadContractPath, makeProvider } from './utils' -import { CompiledContract, Contract, GatewayError } from 'starknet' - -const PRICE_CONSUMER_NAME = 'AggregatorPriceConsumerWithSequencer' -const UPTIME_FEED_PATH = '../../../../contracts/target/release/chainlink_SequencerUptimeFeed.sierra' - -dotenv.config({ path: __dirname + '/../.env' }) - -const SEQ_UP_REPORT_STALE = 'L2 seq up & report stale' -const SEQ_DOWN_REPORT_STALE = 'L2 seq down & report stale' -const SEQ_DOWN_REPORT_OK = 'L2 seq down & report ok' - -const HEX_SEQ_UP_REPORT_STALE = revertMessageHex(SEQ_UP_REPORT_STALE) -const HEX_SEQ_DOWN_REPORT_STALE = revertMessageHex(SEQ_DOWN_REPORT_STALE) -const HEX_SEQ_DOWN_REPORT_OK = revertMessageHex(SEQ_DOWN_REPORT_OK) - -function revertMessageHex(msg: string): string { - return Buffer.from(msg, 'utf8').toString('hex') -} - -export async function getLatestPrice() { - const provider = makeProvider() - - const account = createDeployerAccount(provider) - - const priceConsumerArtifact = loadContract(PRICE_CONSUMER_NAME) - const UptimeFeedArtifact = loadContractPath(UPTIME_FEED_PATH) as CompiledContract - - const priceConsumer = new Contract( - priceConsumerArtifact.abi, - process.env.PRICE_CONSUMER as string, - provider, - ) - const uptimeFeed = new Contract( - UptimeFeedArtifact.abi, - process.env.UPTIME_FEED as string, - provider, - ) - - priceConsumer.connect(account) - uptimeFeed.connect(account) - - let res = await uptimeFeed.invoke('add_access', [priceConsumer.address]) - console.log('Waiting for add_access Tx to be Accepted on Starknet...') - await provider.waitForTransaction(res.transaction_hash) - - try { - console.log('Waiting to get latest price') - const latestPrice = await priceConsumer.call('get_latest_price', []) - console.log('answer= ', latestPrice) - } catch (e) { - // transaction reverted because sequencer is down or report is stale - console.log('Getting latest price not possible (reason below)') - if (e instanceof GatewayError) { - switch (true) { - case e.message.includes(HEX_SEQ_UP_REPORT_STALE): { - console.log(SEQ_UP_REPORT_STALE) - break - } - case e.message.includes(HEX_SEQ_DOWN_REPORT_STALE): { - console.log(SEQ_DOWN_REPORT_STALE) - break - } - case e.message.includes(HEX_SEQ_DOWN_REPORT_OK): { - console.log(SEQ_DOWN_REPORT_OK) - break - } - default: - console.log(e) - break - } - } else { - console.log(e) - } - } -} - -getLatestPrice() diff --git a/examples/contracts/aggregator-consumer/scripts/readContinuously.ts b/examples/contracts/aggregator-consumer/scripts/readContinuously.ts deleted file mode 100644 index 442c732f9..000000000 --- a/examples/contracts/aggregator-consumer/scripts/readContinuously.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Contract, Account, CallContractResponse, Result } from 'starknet' - -import { createDeployerAccount, loadContract, makeProvider } from './utils' -import dotenv from 'dotenv' - -const CONTRACT_NAME = 'AggregatorConsumer' -let account: Account -let consumer: Contract - -dotenv.config({ path: __dirname + '/../.env' }) - -async function readContinuously() { - const provider = makeProvider() - - account = createDeployerAccount(provider) - - const AggregatorArtifact = loadContract(CONTRACT_NAME) - - consumer = new Contract(AggregatorArtifact.abi, process.env.CONSUMER as string) - consumer.connect(account) - setInterval(callFunction, 3000) -} - -async function callFunction() { - const latestRound = await consumer.call('read_latest_round') - const decimals = await consumer.call('read_decimals') - printResult(latestRound, decimals) -} - -function printResult(latestRound: Result, decimals: Result) { - console.log('---------------') - console.log('round_id= ', latestRound['round_id']) - console.log('answer= ', latestRound['answer']) - console.log('block_num= ', latestRound['block_num']) - console.log('started_at= ', latestRound['started_at']) - console.log('updated_at= ', latestRound['updated_at']) - console.log('decimals= ', decimals.toString()) -} - -readContinuously() diff --git a/examples/contracts/aggregator-consumer/scripts/readDecimals.ts b/examples/contracts/aggregator-consumer/scripts/readDecimals.ts deleted file mode 100644 index 7d76b80bb..000000000 --- a/examples/contracts/aggregator-consumer/scripts/readDecimals.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Account, Contract } from 'starknet' -import { createDeployerAccount, loadContract, makeProvider } from './utils' -import dotenv from 'dotenv' - -const CONSUMER_NAME = 'AggregatorConsumer' -let account: Account -let consumer: Contract - -dotenv.config({ path: __dirname + '/../.env' }) - -export async function readDecimals() { - const provider = makeProvider() - account = createDeployerAccount(provider) - - const AggregatorArtifact = loadContract(CONSUMER_NAME) - consumer = new Contract(AggregatorArtifact.abi, process.env.CONSUMER as string) - - consumer.connect(account) - - const decimals = await consumer.call('read_decimals') - - console.log('decimals= ', decimals.toString()) - return decimals -} - -readDecimals() diff --git a/examples/contracts/aggregator-consumer/scripts/readLatestRound.ts b/examples/contracts/aggregator-consumer/scripts/readLatestRound.ts deleted file mode 100644 index 762144a1b..000000000 --- a/examples/contracts/aggregator-consumer/scripts/readLatestRound.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Account, Contract, Result } from 'starknet' - -import { createDeployerAccount, loadContract, makeProvider } from './utils' -import dotenv from 'dotenv' - -const CONSUMER_NAME = 'AggregatorConsumer' -let account: Account -let consumer: Contract - -dotenv.config({ path: __dirname + '/../.env' }) - -export async function readLatestRound() { - const provider = makeProvider() - account = createDeployerAccount(provider) - - const AggregatorArtifact = loadContract(CONSUMER_NAME) - consumer = new Contract(AggregatorArtifact.abi, process.env.CONSUMER as string) - - consumer.connect(account) - - const latestRound = await consumer.call('read_latest_round') - - printResult(latestRound) - return latestRound -} - -function printResult(latestRound: Result) { - console.log('round_id= ', latestRound['round_id']) - console.log('answer= ', latestRound['answer']) - console.log('block_num= ', latestRound['block_num']) - console.log('started_at= ', latestRound['started_at']) - console.log('updated_at= ', latestRound['updated_at']) -} - -readLatestRound() diff --git a/examples/contracts/aggregator-consumer/scripts/updateLatestRound.ts b/examples/contracts/aggregator-consumer/scripts/updateLatestRound.ts deleted file mode 100644 index 5d0b1bcd4..000000000 --- a/examples/contracts/aggregator-consumer/scripts/updateLatestRound.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Account, CompiledContract, Contract, Provider, ec, number } from 'starknet' -import { loadContract, loadContractPath, makeProvider } from './utils' -import dotenv from 'dotenv' - -interface Transmission { - answer: number - block_num: number - observation_timestamp: number - transmission_timestamp: number -} - -const CONTRACT_NAME = 'MockAggregator' -const CONTRACT_PATH = '../../../../contracts/target/release/chainlink_MockAggregator' -let account: Account -let mock: Contract -let transmission: Transmission -let provider: Provider - -dotenv.config({ path: __dirname + '/../.env' }) - -const rl = require('readline').createInterface({ - input: process.stdin, - output: process.stdout, -}) - -async function updateLatestRound() { - provider = makeProvider() - - transmission = { - answer: 0, - block_num: 0, - observation_timestamp: 0, - transmission_timestamp: 0, - } - - const privateKey = process.env.DEPLOYER_PRIVATE_KEY as string - account = new Account(provider, process.env.DEPLOYER_ACCOUNT_ADDRESS as string, privateKey) - - const MockArtifact = loadContractPath(`${CONTRACT_PATH}.sierra`) as CompiledContract - - mock = new Contract(MockArtifact.abi, process.env.MOCK as string) - mock.connect(account) - - transmission.answer = Number(await input('Enter a number for new answer: ')) - transmission.block_num = Number(await input('Enter a number for new block_num: ')) - transmission.observation_timestamp = Number( - await input('Enter a number for new observation_timestamp: '), - ) - transmission.transmission_timestamp = Number( - await input('Enter a number for new transmission_timestamp: '), - ) - rl.close() - - await callFunction(transmission) -} - -async function callFunction(transmission: Transmission) { - const tx = await mock.invoke('set_latest_round_data', [ - transmission.answer, - transmission.block_num, - transmission.observation_timestamp, - transmission.transmission_timestamp, - ]) - - console.log('Waiting for Tx to be Accepted on Starknet: Updating Latest Round') - await provider.waitForTransaction(tx.transaction_hash) -} - -function input(prompt: string) { - return new Promise((callbackFn, errorFn) => { - rl.question(prompt, (uinput: string) => { - switch (isNaN(Number(uinput))) { - case true: - console.log('input is not a number we will use the default value of 1') - uinput = '1' - break - default: - break - } - callbackFn(uinput) - }) - }) -} - -updateLatestRound() diff --git a/examples/contracts/aggregator-consumer/scripts/utils.ts b/examples/contracts/aggregator-consumer/scripts/utils.ts deleted file mode 100644 index ef4e8cf54..000000000 --- a/examples/contracts/aggregator-consumer/scripts/utils.ts +++ /dev/null @@ -1,85 +0,0 @@ -import fs from 'fs' -import dotenv from 'dotenv' -import { CompiledContract, json, ec, Account, Provider, constants, CairoAssembly } from 'starknet' - -const DEVNET_NAME = 'devnet' - -export const loadContract_Account = (name: string): CompiledContract => { - return json.parse( - fs - .readFileSync( - `${__dirname}/../../../../node_modules/@shardlabs/starknet-hardhat-plugin/dist/contract-artifacts/OpenZeppelinAccount/0.5.1/${name}.cairo/${name}.json`, - ) - .toString('ascii'), - ) -} - -export const loadContract = (name: string): CompiledContract => { - return json.parse( - fs - .readFileSync(`${__dirname}/../target/release/chainlink_examples_${name}.sierra.json`) - .toString('ascii'), - ) -} - -export const loadCasmContract = (name: string): CairoAssembly => { - return json.parse( - fs - .readFileSync(`${__dirname}/../target/release/chainlink_examples_${name}.casm.json`) - .toString('ascii'), - ) -} - -export const loadContractPath = (path: string): CompiledContract | CairoAssembly => { - return json.parse(fs.readFileSync(`${__dirname}/${path}.json`).toString('ascii')) -} - -export const loadContract_Solidity = (path: string, name: string): any => { - return json.parse( - fs - .readFileSync( - `${__dirname}/../../../../contracts/artifacts/src/chainlink/solidity/${path}/${name}.sol/${name}.json`, - ) - .toString('ascii'), - ) -} -export const loadContract_Solidity_V8 = (name: string): any => { - return json.parse( - fs - .readFileSync( - `${__dirname}/../../../../contracts/artifacts/@chainlink/contracts/src/v0.8/interfaces/${name}.sol/${name}.json`, - ) - .toString('ascii'), - ) -} - -export function createDeployerAccount(provider: Provider): Account { - dotenv.config({ path: __dirname + '/../.env' }) - - const privateKey: string = process.env.DEPLOYER_PRIVATE_KEY as string - const accountAddress: string = process.env.DEPLOYER_ACCOUNT_ADDRESS as string - if (!privateKey || !accountAddress) { - throw new Error('Deployer account address or private key is undefined!') - } - - return new Account(provider, accountAddress, privateKey) -} - -export const makeProvider = () => { - const network = process.env.NETWORK || DEVNET_NAME - if (network === DEVNET_NAME) { - return new Provider({ - sequencer: { - baseUrl: 'http://127.0.0.1:5050/', - feederGatewayUrl: 'feeder_gateway', - gatewayUrl: 'gateway', - }, - }) - } else { - return new Provider({ - sequencer: { - network: constants.NetworkName.SN_GOERLI, - }, - }) - } -} diff --git a/examples/contracts/aggregator-consumer/src/lib.cairo b/examples/contracts/aggregator-consumer/src/lib.cairo deleted file mode 100644 index f14ff3b83..000000000 --- a/examples/contracts/aggregator-consumer/src/lib.cairo +++ /dev/null @@ -1 +0,0 @@ -mod ocr2; diff --git a/examples/contracts/aggregator-consumer/src/ocr2.cairo b/examples/contracts/aggregator-consumer/src/ocr2.cairo deleted file mode 100644 index 6c9dcdfe1..000000000 --- a/examples/contracts/aggregator-consumer/src/ocr2.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod consumer; -mod price_consumer_with_sequencer; diff --git a/examples/contracts/aggregator-consumer/src/ocr2/consumer.cairo b/examples/contracts/aggregator-consumer/src/ocr2/consumer.cairo deleted file mode 100644 index 3b3916316..000000000 --- a/examples/contracts/aggregator-consumer/src/ocr2/consumer.cairo +++ /dev/null @@ -1,30 +0,0 @@ -#[starknet::contract] -mod AggregatorConsumer { - use starknet::ContractAddress; - - use chainlink::ocr2::aggregator::Round; - - use chainlink::ocr2::aggregator_proxy::IAggregator; - use chainlink::ocr2::aggregator_proxy::IAggregatorDispatcher; - use chainlink::ocr2::aggregator_proxy::IAggregatorDispatcherTrait; - - #[storage] - struct Storage { - _ocr_address: ContractAddress, - } - - #[constructor] - fn constructor(ref self: ContractState, ocr_address: ContractAddress) { - self._ocr_address.write(ocr_address); - } - - #[external(v0)] - fn read_latest_round(self: @ContractState) -> Round { - IAggregatorDispatcher { contract_address: self._ocr_address.read() }.latest_round_data() - } - - #[external(v0)] - fn read_decimals(self: @ContractState) -> u8 { - IAggregatorDispatcher { contract_address: self._ocr_address.read() }.decimals() - } -} diff --git a/examples/contracts/aggregator-consumer/src/ocr2/price_consumer_with_sequencer.cairo b/examples/contracts/aggregator-consumer/src/ocr2/price_consumer_with_sequencer.cairo deleted file mode 100644 index 06ddd331a..000000000 --- a/examples/contracts/aggregator-consumer/src/ocr2/price_consumer_with_sequencer.cairo +++ /dev/null @@ -1,63 +0,0 @@ -#[starknet::contract] -mod AggregatorPriceConsumerWithSequencer { - use box::BoxTrait; - use starknet::ContractAddress; - use zeroable::Zeroable; - use traits::Into; - - use chainlink::ocr2::aggregator::Round; - use chainlink::ocr2::aggregator_proxy::IAggregator; - use chainlink::ocr2::aggregator_proxy::IAggregatorDispatcher; - use chainlink::ocr2::aggregator_proxy::IAggregatorDispatcherTrait; - - #[storage] - struct Storage { - _uptime_feed_address: ContractAddress, - _aggregator_address: ContractAddress, - } - - // Sequencer-aware aggregator consumer - // retrieves the latest price from the data feed only if - // the uptime feed is not stale (stale = older than 60 seconds) - #[constructor] - fn constructor( - ref self: ContractState, - uptime_feed_address: ContractAddress, - aggregator_address: ContractAddress - ) { - assert(!uptime_feed_address.is_zero(), 'uptime feed is 0'); - assert(!aggregator_address.is_zero(), 'aggregator is 0'); - self._uptime_feed_address.write(uptime_feed_address); - self._aggregator_address.write(aggregator_address); - } - - - #[extrnal(v0)] - fn get_latest_price(self: @ContractState) -> u128 { - assert_sequencer_healthy(self); - let round = IAggregatorDispatcher { contract_address: self._aggregator_address.read() } - .latest_round_data(); - round.answer - } - - fn assert_sequencer_healthy(self: @ContractState) { - let round = IAggregatorDispatcher { contract_address: self._uptime_feed_address.read() } - .latest_round_data(); - let timestamp = starknet::info::get_block_info().unbox().block_timestamp; - - // After 60 sec the report is considered stale - let report_stale = timestamp - round.updated_at > 60_u64; - - // 0 if the sequencer is up and 1 if it is down. No other options besides 1 and 0 - match round.answer.into() { - 0 => { - assert(!report_stale, 'L2 seq up & report stale'); - }, - 1 | _ => { - assert(!report_stale, 'L2 seq down & report stale'); - assert(false, 'L2 seq down & report ok'); - } - } - } -} - diff --git a/examples/contracts/aggregator-consumer/tsconfig.json b/examples/contracts/aggregator-consumer/tsconfig.json deleted file mode 100644 index 445119cd5..000000000 --- a/examples/contracts/aggregator-consumer/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist", - }, - "include": [ - "scripts/**/*" - ], - "exclude": [ - "dist", - "**/*.spec.ts", - "**/*.test.ts" - ], - "files": [ - "./hardhat.config.ts" - ] -}