├── .github └── workflows │ └── pr-writer.yml ├── .gitmodules ├── .vscode └── launch.json ├── EmojiGotchi ├── .gitignore ├── README.md ├── foundry │ ├── .vscode │ │ └── settings.json │ ├── deploy.sh │ ├── foundry.toml │ ├── remappings.txt │ └── src │ │ ├── Contract.sol │ │ └── test │ │ └── Contract.t.sol ├── foundry_final │ ├── .vscode │ │ └── settings.json │ ├── deploy.sh │ ├── foundry.toml │ ├── remappings.txt │ └── src │ │ ├── Contract.sol │ │ ├── EmojiGotchi.sol │ │ └── test │ │ ├── Contract.t.sol │ │ └── EmojiGotchi.t.sol ├── svelte │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── .prettierrc │ ├── .vscode │ │ └── settings.json │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app.html │ │ └── routes │ │ │ └── index.svelte │ ├── static │ │ └── favicon.png │ └── svelte.config.js └── svelte_final │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── .prettierrc │ ├── .vscode │ └── settings.json │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app.html │ └── routes │ │ └── index.svelte │ ├── static │ └── favicon.png │ └── svelte.config.js ├── LICENSE ├── README.md ├── automation-gas-threshold ├── README.md ├── index.js └── package.json ├── ccip ├── ccip-cla-rate-limits │ ├── .github │ │ └── workflows │ │ │ └── test.yml │ ├── .gitignore │ ├── README.md │ ├── foundry.toml │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── CLAReceiver.sol │ │ ├── CLASender.sol │ │ ├── ExampleConsumer.sol │ │ ├── interfaces │ │ │ ├── AggregatorInterface.sol │ │ │ └── ICLASender.sol │ │ └── utils │ │ │ ├── EncodeExtraArgs.sol │ │ │ ├── Rate.sol │ │ │ └── Withdraw.sol │ └── test │ │ └── StaFi.t.sol ├── cct │ ├── foundry │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── settings.json │ │ ├── LICENSE │ │ ├── README.md │ │ ├── foundry.toml │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── script │ │ │ ├── AcceptAdminRole.s.sol │ │ │ ├── AddRemotePool.s.sol │ │ │ ├── ApplyChainUpdates.s.sol │ │ │ ├── ClaimAdmin.s.sol │ │ │ ├── DeployBurnMintTokenPool.s.sol │ │ │ ├── DeployLockReleaseTokenPool.s.sol │ │ │ ├── DeployToken.s.sol │ │ │ ├── GetCurrentRateLimits.s.sol │ │ │ ├── GetPoolConfig.s.sol │ │ │ ├── HelperConfig.s.sol │ │ │ ├── MintTokens.s.sol │ │ │ ├── RemoveRemotePool.s.sol │ │ │ ├── SetPool.s.sol │ │ │ ├── SetRateLimitAdmin.s.sol │ │ │ ├── TransferTokenAdminRole.s.sol │ │ │ ├── TransferTokens.s.sol │ │ │ ├── UpdateAllowList.s.sol │ │ │ ├── UpdateRateLimiters.s.sol │ │ │ ├── config.json │ │ │ ├── output │ │ │ │ ├── deployedTokenPool_arbitrumSepolia.json │ │ │ │ ├── deployedTokenPool_avalancheFuji.json │ │ │ │ ├── deployedToken_arbitrumSepolia.json │ │ │ │ └── deployedToken_avalancheFuji.json │ │ │ └── utils │ │ │ │ └── HelperUtils.s.sol │ │ └── src │ │ │ └── Dependencies.sol │ └── hardhat │ │ ├── .gitignore │ │ ├── README.md │ │ ├── config │ │ ├── config.json │ │ ├── index.ts │ │ ├── logger.ts │ │ ├── networks.ts │ │ └── types.ts │ │ ├── contracts │ │ ├── Dependencies.sol │ │ └── TokenDependencies.sol │ │ ├── hardhat.config.ts │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── tasks │ │ ├── acceptAdminRole.ts │ │ ├── addRemotePool.ts │ │ ├── applyChainUpdates.ts │ │ ├── claimAdmin.ts │ │ ├── deployToken.ts │ │ ├── deployTokenPool.ts │ │ ├── getCurrentRateLimits.ts │ │ ├── getPoolConfig.ts │ │ ├── index.ts │ │ ├── mintTokens.ts │ │ ├── removeRemotePool.ts │ │ ├── safe-multisig │ │ │ ├── acceptOwnership.ts │ │ │ ├── applyChainUpdates.ts │ │ │ ├── claimAndAcceptAdminRole.ts │ │ │ ├── deploySafe.ts │ │ │ ├── deployToken.ts │ │ │ ├── deployTokenPool.ts │ │ │ ├── grantMintBurnRole.ts │ │ │ ├── index.ts │ │ │ ├── mintTokens.ts │ │ │ └── setPool.ts │ │ ├── setPool.ts │ │ ├── setRateLimitAdmin.ts │ │ ├── transferTokenAdminRole.ts │ │ ├── transferTokens.ts │ │ ├── updateAllowList.ts │ │ └── updateRateLimiters.ts │ │ └── tsconfig.json ├── estimate-gas │ ├── .gitignore │ ├── README.md │ ├── foundry │ │ ├── .github │ │ │ └── workflows │ │ │ │ └── test.yml │ │ ├── README.md │ │ ├── foundry.toml │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ ├── Receiver.sol │ │ │ └── Sender.sol │ │ └── test │ │ │ └── SendReceive.t.sol │ ├── hardhat │ │ ├── README.md │ │ ├── ccip.config.ts │ │ ├── contracts │ │ │ ├── BurnMintERC677.sol │ │ │ ├── MockCCIPRouter.sol │ │ │ ├── Receiver.sol │ │ │ └── Sender.sol │ │ ├── hardhat.config.ts │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── scripts │ │ │ ├── configuration │ │ │ │ ├── allowlistingForReceiver.ts │ │ │ │ └── allowlistingForSender.ts │ │ │ ├── deployment │ │ │ │ ├── deployReceiver.ts │ │ │ │ └── deploySender.ts │ │ │ ├── generatedData.json │ │ │ ├── helper.ts │ │ │ └── testing │ │ │ │ └── sendCCIPMessages.ts │ │ ├── test │ │ │ └── Send-Receive.ts │ │ └── tsconfig.json │ └── offchain │ │ ├── README.md │ │ ├── abis │ │ └── Receiver.json │ │ ├── ccip.config.ts │ │ ├── data.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── estimateGasProvider.ts │ │ ├── estimateGasTenderly.ts │ │ └── helper.ts │ │ └── tsconfig.json ├── offchain │ ├── README.md │ ├── abi │ │ ├── IERC20Metadata.json │ │ ├── OffRamp.json │ │ ├── OnRamp.json │ │ ├── Router.json │ │ ├── TokenAdminRegistry.json │ │ └── TokenPool.json │ ├── config │ │ ├── mainnet.json │ │ ├── messageState.json │ │ └── testnet.json │ ├── javascript │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ └── src │ │ │ ├── config │ │ │ ├── ccip.js │ │ │ ├── env.js │ │ │ ├── index.js │ │ │ └── offramp.js │ │ │ ├── get-status.js │ │ │ ├── supported-tokens.js │ │ │ └── transfer-tokens.js │ └── typescript │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── config │ │ │ ├── ccip.ts │ │ │ ├── env.ts │ │ │ ├── index.ts │ │ │ └── offramp.ts │ │ ├── get-status.ts │ │ ├── supported-tokens.ts │ │ └── transfer-tokens.ts │ │ └── tsconfig.json └── token-transfer-using-arbitrary-messaging │ ├── .github │ └── workflows │ │ └── test.yml │ ├── .gitignore │ ├── README.md │ ├── broadcast │ ├── BurnAndMint.s.sol │ │ └── 43113 │ │ │ ├── run-1716160599.json │ │ │ ├── run-1716160934.json │ │ │ ├── run-1716161212.json │ │ │ └── run-latest.json │ ├── BurnAndRelease.s.sol │ │ └── 421614 │ │ │ ├── run-1716162627.json │ │ │ └── run-latest.json │ ├── LockAndRelease.s.sol │ │ └── 11155111 │ │ │ ├── run-1716162254.json │ │ │ └── run-latest.json │ └── multi │ │ ├── Deploy.s.sol-1716151255 │ │ └── run.json │ │ ├── Deploy.s.sol-1716151851 │ │ └── run.json │ │ ├── Deploy.s.sol-1716152976 │ │ └── run.json │ │ ├── Deploy.s.sol-1716153662 │ │ └── run.json │ │ ├── Deploy.s.sol-1716155380 │ │ └── run.json │ │ ├── Deploy.s.sol-1716155656 │ │ └── run.json │ │ ├── Deploy.s.sol-1716155835 │ │ └── run.json │ │ ├── Deploy.s.sol-1716156968 │ │ └── run.json │ │ ├── Deploy.s.sol-1716157123 │ │ └── run.json │ │ ├── Deploy.s.sol-1716157321 │ │ └── run.json │ │ ├── Deploy.s.sol-1716160550 │ │ └── run.json │ │ └── Deploy.s.sol-latest │ │ └── run.json │ ├── foundry.toml │ ├── img │ ├── tokens-messaging-lock-and-release.jpg │ ├── tokens-messaing-burn-and-mint.jpg │ └── tokens-messaing-lock-and-mint.jpg │ ├── script │ ├── BurnAndMint.s.sol │ ├── BurnAndRelease.s.sol │ ├── Deploy.s.sol │ ├── LockAndMint.s.sol │ └── addresses.json │ ├── src │ ├── bridge │ │ ├── Bridge.sol │ │ └── Configuration.sol │ ├── interfaces │ │ ├── IBridge.sol │ │ ├── IBurnMintERC20.sol │ │ ├── IConfiguration.sol │ │ ├── ILockReleaseTokenPool.sol │ │ └── IPool.sol │ └── pools │ │ ├── BurnMintTokenPool.sol │ │ ├── LockReleaseTokenPool.sol │ │ └── Pool.sol │ └── test │ ├── bridge │ ├── Bridge.t.sol │ ├── BridgeWithSimulator.t.sol │ ├── BridgeWithSimulatorFork.t.sol │ └── Configuration.t.sol │ ├── mocks │ ├── ICustom.sol │ ├── MockBurnMintERC20.sol │ └── MockERC20.sol │ └── pools │ ├── BurnMintTokenPool.t.sol │ └── LockReleaseTokenPool.t.sol ├── counting-svg ├── README.md └── counting-svg.sol ├── dadjokes-onchain ├── README.md ├── frontend │ ├── .eslintrc.json │ ├── .gitignore │ ├── README.md │ ├── jsconfig.json │ ├── next.config.mjs │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.mjs │ ├── public │ │ ├── next.svg │ │ └── vercel.svg │ ├── src │ │ ├── app │ │ │ ├── favicon.ico │ │ │ ├── globals.css │ │ │ ├── layout.jsx │ │ │ └── page.jsx │ │ ├── components │ │ │ ├── Button.js │ │ │ ├── Card.js │ │ │ ├── ConnectButton.js │ │ │ ├── ConnectWallet.js │ │ │ ├── JokeModal.js │ │ │ ├── RewardSection.js │ │ │ └── WithdrawSection.js │ │ ├── hooks │ │ │ ├── useJokes.js │ │ │ ├── useSubmitJoke.js │ │ │ ├── useVote.js │ │ │ ├── useWallet.js │ │ │ └── useWithdraw.js │ │ └── lib │ │ │ ├── client.js │ │ │ └── dadJokesABI.json │ └── tailwind.config.js └── smartcontract │ ├── .github │ └── workflows │ │ └── test.yml │ ├── .gitignore │ ├── foundry.toml │ ├── lib │ └── forge-std │ │ ├── .gitattributes │ │ ├── .github │ │ └── workflows │ │ │ ├── ci.yml │ │ │ └── sync.yml │ │ ├── .gitignore │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── README.md │ │ ├── foundry.toml │ │ ├── package.json │ │ ├── scripts │ │ └── vm.py │ │ ├── src │ │ ├── Base.sol │ │ ├── Script.sol │ │ ├── StdAssertions.sol │ │ ├── StdChains.sol │ │ ├── StdCheats.sol │ │ ├── StdError.sol │ │ ├── StdInvariant.sol │ │ ├── StdJson.sol │ │ ├── StdMath.sol │ │ ├── StdStorage.sol │ │ ├── StdStyle.sol │ │ ├── StdToml.sol │ │ ├── StdUtils.sol │ │ ├── Test.sol │ │ ├── Vm.sol │ │ ├── console.sol │ │ ├── console2.sol │ │ ├── interfaces │ │ │ ├── IERC1155.sol │ │ │ ├── IERC165.sol │ │ │ ├── IERC20.sol │ │ │ ├── IERC4626.sol │ │ │ ├── IERC721.sol │ │ │ └── IMulticall3.sol │ │ ├── mocks │ │ │ ├── MockERC20.sol │ │ │ └── MockERC721.sol │ │ └── safeconsole.sol │ │ └── test │ │ ├── StdAssertions.t.sol │ │ ├── StdChains.t.sol │ │ ├── StdCheats.t.sol │ │ ├── StdError.t.sol │ │ ├── StdJson.t.sol │ │ ├── StdMath.t.sol │ │ ├── StdStorage.t.sol │ │ ├── StdStyle.t.sol │ │ ├── StdToml.t.sol │ │ ├── StdUtils.t.sol │ │ ├── Vm.t.sol │ │ ├── compilation │ │ ├── CompilationScript.sol │ │ ├── CompilationScriptBase.sol │ │ ├── CompilationTest.sol │ │ └── CompilationTestBase.sol │ │ ├── fixtures │ │ ├── broadcast.log.json │ │ ├── test.json │ │ └── test.toml │ │ └── mocks │ │ ├── MockERC20.t.sol │ │ └── MockERC721.t.sol │ ├── remappings.txt │ ├── script │ └── DadJokes.s.sol │ ├── src │ └── DadJokes.sol │ └── test │ └── DadJokes.t.sol ├── data-feeds └── tron │ └── getting-started │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── contracts │ ├── DataFeedReader.sol │ └── Migrations.sol │ ├── migrations │ ├── 1_initial_migration.js │ └── 2_deploy_contracts.js │ ├── offchain │ └── reader.js │ ├── package-lock.json │ ├── package.json │ ├── tronbox-config.js │ └── tronbox-evm-config.js ├── data-streams ├── getting-started │ └── hardhat │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── .solhint.json │ │ ├── .solhintignore │ │ ├── README.md │ │ ├── contracts │ │ ├── LogEmitter.sol │ │ └── StreamsUpkeepRegistrar.sol │ │ ├── hardhat.config.js │ │ ├── helper-hardhat-config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── tasks │ │ ├── deployment │ │ ├── deployLogEmitter.js │ │ ├── deployStreamsUpkeepRegistrar.js │ │ └── main.js │ │ ├── emitLog.js │ │ ├── getLastRetrievedPrice.js │ │ ├── index.js │ │ ├── registerAndFundLogUpkeep.js │ │ ├── transfer-link.js │ │ └── utils │ │ ├── index.js │ │ └── spin.js └── streams-direct │ ├── .gitignore │ ├── README.md │ ├── api │ ├── client │ │ └── client.go │ ├── go.mod │ ├── internal │ │ └── decoder.go │ ├── main-multiple-feeds.go │ └── main-single-feed.go │ └── websocket │ ├── client │ └── clientWs.go │ ├── decodeFullReportHex.go │ ├── go.mod │ ├── internal │ └── decoder.go │ └── main.go ├── datafeeds-in-svelte ├── README.md ├── jsconfig.json ├── package-lock.json ├── package.json ├── src │ ├── app.html │ ├── global.d.ts │ ├── routes │ │ └── index.svelte │ └── utils │ │ └── getETHPrice.js ├── static │ └── favicon.png └── svelte.config.js ├── dynamic-nft-3-services └── SuperDynamicNFT.sol ├── dynamic-nft ├── 1_starter.sol ├── 2_complete.sol └── README.md ├── functions-examples ├── .gitignore ├── README.md ├── abi │ ├── automatedFunctions.json │ ├── functionsClient.json │ └── functionsDecoder.json ├── examples │ ├── 1-simple-computation │ │ ├── request.js │ │ └── source.js │ ├── 10-automate-functions │ │ ├── readLatest.js │ │ ├── source.js │ │ └── updateRequest.js │ ├── 11-package-imports │ │ ├── request.js │ │ └── source.js │ ├── 12-abi-encoding │ │ ├── request.js │ │ └── source.js │ ├── 2-call-api │ │ ├── request.js │ │ └── source.js │ ├── 3-custom-response │ │ ├── request.js │ │ └── source.js │ ├── 4-post-data │ │ ├── request.js │ │ └── source.js │ ├── 5-use-secrets-threshold │ │ ├── request.js │ │ └── source.js │ ├── 6-use-secrets-gist │ │ ├── request.js │ │ └── source.js │ ├── 7-use-secrets-url │ │ ├── gen-offchain-secrets.js │ │ ├── request.js │ │ └── source.js │ ├── 8-multiple-apis │ │ ├── request.js │ │ └── source.js │ ├── 9-send-cbor │ │ ├── request.js │ │ └── source.js │ └── getting-started.js ├── package-lock.json └── package.json ├── lottery ├── .env.example ├── .gitattributes ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .solhint.json ├── .solhintignore ├── README.md ├── contracts │ ├── CharityRaffle.sol │ ├── Raffle.sol │ └── test │ │ └── VRFCoordinatorV2Mock.sol ├── deploy │ ├── 00-deploy-mocks.ts │ ├── 01-deploy-raffle.ts │ ├── 02-update-front-end.ts │ └── deploy-charity-raffle │ │ └── 03-deploy-charity-raffle.ts ├── hardhat.config.ts ├── helper-hardhat-config.ts ├── package.json ├── scripts │ ├── charity-raffle-scripts │ │ ├── enterCharityRaffle.ts │ │ └── mockOffChainCharityRaffle.ts │ ├── enterRaffle.ts │ └── mockOffchain.ts ├── test │ ├── staging │ │ ├── CharityRaffle.staging.test.ts │ │ └── Raffle.staging.test.ts │ └── unit │ │ ├── CharityRaffle.test.ts │ │ └── Raffle.test.ts ├── typechain-types │ ├── @chainlink │ │ ├── contracts │ │ │ ├── index 2.ts │ │ │ ├── index.ts │ │ │ └── src │ │ │ │ ├── index 2.ts │ │ │ │ ├── index.ts │ │ │ │ └── v0.8 │ │ │ │ ├── VRFConsumerBaseV2 2.ts │ │ │ │ ├── VRFConsumerBaseV2.ts │ │ │ │ ├── index 2.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces │ │ │ │ ├── KeeperCompatibleInterface 2.ts │ │ │ │ ├── KeeperCompatibleInterface.ts │ │ │ │ ├── LinkTokenInterface 2.ts │ │ │ │ ├── LinkTokenInterface.ts │ │ │ │ ├── VRFCoordinatorV2Interface 2.ts │ │ │ │ ├── VRFCoordinatorV2Interface.ts │ │ │ │ ├── index 2.ts │ │ │ │ └── index.ts │ │ │ │ └── mocks │ │ │ │ ├── VRFCoordinatorV2Mock 2.ts │ │ │ │ ├── VRFCoordinatorV2Mock.ts │ │ │ │ ├── index 2.ts │ │ │ │ └── index.ts │ │ ├── index 2.ts │ │ └── index.ts │ ├── common 2.ts │ ├── common.ts │ ├── contracts │ │ ├── CharityRaffle 2.ts │ │ ├── CharityRaffle.ts │ │ ├── Raffle 2.ts │ │ ├── Raffle.ts │ │ ├── index 2.ts │ │ └── index.ts │ ├── factories │ │ ├── @chainlink │ │ │ ├── contracts │ │ │ │ ├── index 2.ts │ │ │ │ ├── index.ts │ │ │ │ └── src │ │ │ │ │ ├── index 2.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── v0.8 │ │ │ │ │ ├── VRFConsumerBaseV2__factory 2.ts │ │ │ │ │ ├── VRFConsumerBaseV2__factory.ts │ │ │ │ │ ├── index 2.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── interfaces │ │ │ │ │ ├── KeeperCompatibleInterface__factory 2.ts │ │ │ │ │ ├── KeeperCompatibleInterface__factory.ts │ │ │ │ │ ├── LinkTokenInterface__factory 2.ts │ │ │ │ │ ├── LinkTokenInterface__factory.ts │ │ │ │ │ ├── VRFCoordinatorV2Interface__factory 2.ts │ │ │ │ │ ├── VRFCoordinatorV2Interface__factory.ts │ │ │ │ │ ├── index 2.ts │ │ │ │ │ └── index.ts │ │ │ │ │ └── mocks │ │ │ │ │ ├── VRFCoordinatorV2Mock__factory 2.ts │ │ │ │ │ ├── VRFCoordinatorV2Mock__factory.ts │ │ │ │ │ ├── index 2.ts │ │ │ │ │ └── index.ts │ │ │ ├── index 2.ts │ │ │ └── index.ts │ │ ├── contracts │ │ │ ├── CharityRaffle__factory 2.ts │ │ │ ├── CharityRaffle__factory.ts │ │ │ ├── Raffle__factory 2.ts │ │ │ ├── Raffle__factory.ts │ │ │ ├── index 2.ts │ │ │ └── index.ts │ │ ├── index 2.ts │ │ └── index.ts │ ├── index 2.ts │ └── index.ts ├── utils │ └── verify.ts └── yarn.lock ├── my-crypto-coin ├── .gitignore ├── cli │ └── mcc │ │ ├── balances.go │ │ ├── main.go │ │ ├── tx.go │ │ └── version.go ├── go.mod ├── go.sum └── ledger │ ├── genesis.go │ ├── genesis.json │ ├── ledger.db │ ├── state.go │ └── tx.go ├── my-crypto-wallet ├── 01_newAccount.js ├── 02_restoreWallet.js ├── 03_send.js ├── package.json └── yarn.lock ├── pricefeed-golang ├── .env.example ├── .gitignore ├── README.md ├── aggregatorv3 │ ├── AggregatorV3Interface.abi │ ├── AggregatorV3Interface.sol │ └── aggregator_v3_interface.go ├── go.mod ├── go.sum └── main.go ├── quiz-game ├── .gitignore ├── README.md ├── foundry │ ├── .gitignore │ ├── deploy.sh │ ├── foundry.toml │ └── src │ │ ├── QuizFactory.sol │ │ ├── QuizGame.sol │ │ └── test │ │ ├── QuizFactory.t.sol │ │ └── QuizGame.t.sol └── svelte │ ├── .eslintignore │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── .prettierignore │ ├── .prettierrc │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app.html │ ├── contracts │ │ ├── QuizFactory.json │ │ └── QuizGame.json │ └── routes │ │ └── index.svelte │ ├── static │ └── favicon.png │ └── svelte.config.js ├── random-svg-nft ├── .env.example ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .prettierignore ├── .solhint.json ├── .solhintignore ├── README.md ├── contracts │ ├── EmojiNFT.sol │ └── test │ │ ├── LinkToken.sol │ │ └── VRFCoordinatorV2Mock.sol ├── demo.png ├── hardhat.config.ts ├── package.json ├── scripts │ └── deploy.ts ├── test │ ├── shared │ │ ├── fixtures.ts │ │ ├── helpers.ts │ │ └── types.ts │ └── unit │ │ ├── EmojiNFT │ │ └── EmojiNFTShouldMint.spec.ts │ │ └── index.ts └── tsconfig.json ├── timelocked-contracts ├── .gitignore ├── README.md ├── foundry.toml ├── remappings.txt └── src │ ├── Contract.sol │ └── test │ └── Contract.t.sol ├── ultimate-nft-repo ├── .env.example ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── README.md ├── contracts │ ├── BasicNft.sol │ ├── DynamicSvgNft.sol │ ├── RandomIpfsNft.sol │ └── test │ │ ├── MockV3Aggregator.sol │ │ └── VRFCoordinatorV2Mock.sol ├── deploy │ ├── 00-deploy-mocks.js │ ├── 01-deploy-basic-nft.js │ ├── 02-deploy-dynamic-svg-nft.js │ ├── 03-deploy-random-ipfs-nft.js │ └── 04-mint.js ├── hardhat.config.js ├── helper-hardhat-config.js ├── images │ ├── dynamicNft │ │ ├── frown.svg │ │ └── happy.svg │ └── randomNft │ │ ├── pug.png │ │ ├── shiba-inu.png │ │ └── st-bernard.png ├── package.json ├── test │ └── unit │ │ ├── basicNft.test.js │ │ ├── dynamicSvg.test.js │ │ └── randomIpfs.test.js ├── utils │ ├── uploadToNftStorage.js │ ├── uploadToPinata.js │ └── verify.js └── yarn.lock ├── upkeep-interactions └── custom-logic-upkeep │ ├── .gitignore │ ├── README.md │ ├── UpkeepInteractions.sol │ ├── package.json │ └── upkeepInteractions.js └── vrf-arbitrum-gas-estimation ├── .env-sample ├── README.md ├── package.json └── scripts └── exec.ts /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "ts-node", 9 | "type": "node", 10 | "request": "launch", 11 | "args": [ 12 | "${relativeFile}" 13 | ], 14 | "runtimeArgs": [ 15 | "-r", 16 | "ts-node/register" 17 | ], 18 | "cwd": "${workspaceRoot}", 19 | "protocol": "inspector", 20 | "internalConsoleOptions": "openOnSessionStart" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /EmojiGotchi/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | build 4 | .svelte-kit 5 | package 6 | .env 7 | .env.* 8 | !.env.example 9 | coverage 10 | coverage.json 11 | typechain 12 | 13 | #Solidity files 14 | cache 15 | artifacts 16 | cache/ 17 | out/ 18 | solidity/lib 19 | -------------------------------------------------------------------------------- /EmojiGotchi/README.md: -------------------------------------------------------------------------------- 1 | # EmojiGotchi 2 | This repo will support the Code Along for [Building a Web3 Game](https://www.youtube.com/watch?v=bPfTBr2D1gc) 3 | 4 | ## How to Use The Repo 5 | 6 | The repo is broken down into 3 main sections via directories 7 | ___ 8 | _**foundry & svelte**_ : The initial setup to get started consists of the foundry and svelte directories.These directories have Foundry and SvelteKit setup with a basic installation and a few nice to haves installed. 9 | - ethers.js 10 | - OpenZeppelin Contracts 11 | - remappings.txt 12 | - .gitignore 13 | - Some VS Code tweaks to keep track of editors 14 | 15 | _**foundry_final**_ : Completed smart contract ready to be used and create your EmojiGotchi NFT 16 | 17 | _**svelte_final**_ : The final app in it's completed form. Run via `npm run dev` or deploy to the host of your choice 18 | 19 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "titleBar.activeForeground": "#000", 4 | "titleBar.inactiveForeground": "#000000CC", 5 | "titleBar.activeBackground": "#FFFE95", 6 | "titleBar.inactiveBackground": "#FFFE95CC" 7 | }, 8 | "solidity.packageDefaultDependenciesContractsDirectory": "src", 9 | "solidity.packageDefaultDependenciesDirectory": "lib" 10 | } -------------------------------------------------------------------------------- /EmojiGotchi/foundry/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Read the Mumbai RPC URL 4 | echo Enter Your Mumbai RPC URL: 5 | echo Example: "https://polygon-mumbai.g.alchemy.com/v2/XXXXXXXXXX" 6 | read -s rpc 7 | 8 | # Read the contract name 9 | echo Which contract do you want to deploy \(eg Greeter\)? 10 | read contract 11 | 12 | forge create ./src/${contract}.sol:${contract} -i --rpc-url $rpc 13 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /EmojiGotchi/foundry/remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/=lib/openzeppelin-contracts/ 2 | ds-test/=lib/ds-test/src/ -------------------------------------------------------------------------------- /EmojiGotchi/foundry/src/Contract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.10; 3 | 4 | contract Contract {} 5 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry/src/test/Contract.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.10; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract ContractTest is DSTest { 7 | function setUp() public {} 8 | 9 | function testExample() public { 10 | assertTrue(true); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "titleBar.activeForeground": "#000", 4 | "titleBar.inactiveForeground": "#000000CC", 5 | "titleBar.activeBackground": "#FFFE95", 6 | "titleBar.inactiveBackground": "#FFFE95CC" 7 | }, 8 | "solidity.packageDefaultDependenciesContractsDirectory": "src", 9 | "solidity.packageDefaultDependenciesDirectory": "lib" 10 | } -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Read the Mumbai RPC URL 4 | echo Enter Your Mumbai RPC URL: 5 | echo Example: "https://polygon-mumbai.g.alchemy.com/v2/XXXXXXXXXX" 6 | read -s rpc 7 | 8 | # Read the contract name 9 | echo Which contract do you want to deploy \(eg Greeter\)? 10 | read contract 11 | 12 | forge create ./src/${contract}.sol:${contract} -i --rpc-url $rpc 13 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/=lib/openzeppelin-contracts/ 2 | ds-test/=lib/ds-test/src/ -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/src/Contract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.10; 3 | 4 | contract Contract {} 5 | -------------------------------------------------------------------------------- /EmojiGotchi/foundry_final/src/test/Contract.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.10; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | contract ContractTest is DSTest { 7 | function setUp() public {} 8 | 9 | function testExample() public { 10 | assertTrue(true); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['eslint:recommended', 'prettier'], 4 | plugins: ['svelte3'], 5 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 6 | parserOptions: { 7 | sourceType: 'module', 8 | ecmaVersion: 2020 9 | }, 10 | env: { 11 | browser: true, 12 | es2017: true, 13 | node: true 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100 6 | } 7 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "titleBar.activeForeground": "#000", 4 | "titleBar.inactiveForeground": "#000000CC", 5 | "titleBar.activeBackground": "#FF3E00", 6 | "titleBar.inactiveBackground": "#FF3E00CC" 7 | } 8 | } -------------------------------------------------------------------------------- /EmojiGotchi/svelte/README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 4 | 5 | ## Creating a project 6 | 7 | If you're seeing this, you've probably already done this step. Congrats! 8 | 9 | ```bash 10 | # create a new project in the current directory 11 | npm init svelte 12 | 13 | # create a new project in my-app 14 | npm init svelte my-app 15 | ``` 16 | 17 | ## Developing 18 | 19 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 20 | 21 | ```bash 22 | npm run dev 23 | 24 | # or start the server and open the app in a new browser tab 25 | npm run dev -- --open 26 | ``` 27 | 28 | ## Building 29 | 30 | To create a production version of your app: 31 | 32 | ```bash 33 | npm run build 34 | ``` 35 | 36 | You can preview the production build with `npm run preview`. 37 | 38 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. 39 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview", 9 | "prepare": "svelte-kit sync", 10 | "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", 11 | "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." 12 | }, 13 | "devDependencies": { 14 | "@sveltejs/adapter-auto": "next", 15 | "@sveltejs/kit": "next", 16 | "eslint": "^7.32.0", 17 | "eslint-config-prettier": "^8.3.0", 18 | "eslint-plugin-svelte3": "^3.2.1", 19 | "prettier": "^2.5.1", 20 | "prettier-plugin-svelte": "^2.5.0", 21 | "svelte": "^3.44.0" 22 | }, 23 | "type": "module", 24 | "dependencies": { 25 | "ethers": "^5.6.5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %svelte.head% 8 | 9 | 10 |
%svelte.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 |

My EmojiGotchi

19 | {#if !web3Props.account} 20 | 21 | {:else} 22 | 23 | {/if} 24 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/EmojiGotchi/svelte/static/favicon.png -------------------------------------------------------------------------------- /EmojiGotchi/svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | kit: { 6 | adapter: adapter() 7 | } 8 | }; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['eslint:recommended', 'prettier'], 4 | plugins: ['svelte3'], 5 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 6 | parserOptions: { 7 | sourceType: 'module', 8 | ecmaVersion: 2020 9 | }, 10 | env: { 11 | browser: true, 12 | es2017: true, 13 | node: true 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100 6 | } 7 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "titleBar.activeForeground": "#000", 4 | "titleBar.inactiveForeground": "#000000CC", 5 | "titleBar.activeBackground": "#FF3E00", 6 | "titleBar.inactiveBackground": "#FF3E00CC" 7 | } 8 | } -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 4 | 5 | ## Creating a project 6 | 7 | If you're seeing this, you've probably already done this step. Congrats! 8 | 9 | ```bash 10 | # create a new project in the current directory 11 | npm init svelte 12 | 13 | # create a new project in my-app 14 | npm init svelte my-app 15 | ``` 16 | 17 | ## Developing 18 | 19 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 20 | 21 | ```bash 22 | npm run dev 23 | 24 | # or start the server and open the app in a new browser tab 25 | npm run dev -- --open 26 | ``` 27 | 28 | ## Building 29 | 30 | To create a production version of your app: 31 | 32 | ```bash 33 | npm run build 34 | ``` 35 | 36 | You can preview the production build with `npm run preview`. 37 | 38 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. 39 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview", 9 | "prepare": "svelte-kit sync", 10 | "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", 11 | "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." 12 | }, 13 | "devDependencies": { 14 | "@sveltejs/adapter-auto": "next", 15 | "@sveltejs/kit": "next", 16 | "eslint": "^7.32.0", 17 | "eslint-config-prettier": "^8.3.0", 18 | "eslint-plugin-svelte3": "^3.2.1", 19 | "prettier": "^2.5.1", 20 | "prettier-plugin-svelte": "^2.5.0", 21 | "svelte": "^3.44.0" 22 | }, 23 | "type": "module", 24 | "dependencies": { 25 | "ethers": "^5.6.5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %svelte.head% 8 | 9 | 10 |
%svelte.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 |

My EmojiGotchi

19 | {#if !web3Props.account} 20 | 21 | {:else} 22 | 23 | {/if} 24 | -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/EmojiGotchi/svelte_final/static/favicon.png -------------------------------------------------------------------------------- /EmojiGotchi/svelte_final/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | kit: { 6 | adapter: adapter() 7 | } 8 | }; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 SmartContract ChainLink Limited SEZC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /automation-gas-threshold/README.md: -------------------------------------------------------------------------------- 1 | # Setting a gas price threshold on Chainlink Automation upkeeps 2 | 3 | This project provides a script you can use to configure and set a maximum gas price for your Automation upkeep. 4 | 5 | ## Installation 6 | 7 | To set up the project, follow these steps: 8 | 9 | 1. Clone the repository: 10 | ```bash 11 | git clone https://github.com/smartcontractkit 12 | ``` 13 | 1. Navigate to the directory for this script: 14 | ```bash 15 | cd automation-gas-threshold 16 | ``` 17 | 1. Install the required dependencies: 18 | 19 | ```bash 20 | npm install 21 | ``` 22 | 23 | ## Usage 24 | 25 | 1. Set the following variables: 26 | 27 | - YOUR_RPC_URL: The RPC URL for your provider (such as Alchemy or Infura) 28 | - YOUR_PRIVATE_KEY: Your wallet's private key 29 | - YOUR_UPKEEP_ID: The ID of the Automation upkeep you want to configure. 30 | 31 | 1. Within the `offchainConfig` variable, set your `maxGasPrice` in wei. Do not use 32 | quotation marks around the value you set for `maxGasPrice`. If this string 33 | is formatted incorrectly, the feature does not work. 34 | 35 | `{"maxGasPrice":2000000000}` 36 | 37 | 1. Run the script: 38 | ```bash 39 | node index.js 40 | ``` 41 | -------------------------------------------------------------------------------- /automation-gas-threshold/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automation-gas-threshold", 3 | "version": "1.0.0", 4 | "description": "Set a gas price threshold on Automation upkeeps", 5 | "main": "index.js", 6 | "author": "", 7 | "license": "MIT", 8 | "dependencies": { 9 | "cbor": "^9.0.2", 10 | "ethers": "^5.7.2" 11 | } 12 | } -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | 16 | # Node modules 17 | node_modules/ -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/README.md: -------------------------------------------------------------------------------- 1 | ## CCIP + CLA Rate Limits 2 | 3 | Showcase example that combines Chainlink CCIP and Chainlink Automation to deliver exchange rates of StaFi Staked ETH (rETH). 4 | 5 | ## Usage 6 | 7 | Create an `.env` file and provide the following variables: 8 | 9 | ``` 10 | ETHEREUM_MAINNET_RPC_URL = https://eth-mainnet.g.alchemy.com/v2/ 11 | POLYGON_MAINNET_RPC_URL = https://polygon-mainnet.g.alchemy.com/v2/ 12 | ``` 13 | 14 | ### Build 15 | 16 | ```shell 17 | $ forge build 18 | ``` 19 | 20 | ### Test 21 | 22 | ```shell 23 | $ forge test 24 | ``` 25 | 26 | ### Format 27 | 28 | ```shell 29 | $ forge fmt 30 | ``` 31 | 32 |
33 | 34 | > _This tutorial represents an educational example to use a Chainlink system, product, or service and is provided to demonstrate how to interact with Chainlink’s systems, products, and services to integrate them into your own. This template is provided “AS IS” and “AS AVAILABLE” without warranties of any kind, it has not been audited, and it may be missing key checks or error handling to make the usage of the system, product or service more clear. Do not use the code in this example in a production environment without completing your own audits and application of best practices. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs that are generated due to errors in code._ 35 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | solc = '0.8.24' 6 | evm_version = 'paris' 7 | remappings = [ 8 | '@chainlink/contracts=node_modules/@chainlink/contracts', 9 | '@chainlink/contracts-ccip=node_modules/@chainlink/contracts-ccip', 10 | '@chainlink/local=node_modules/@chainlink/local', 11 | '@openzeppelin/contracts=node_modules/@openzeppelin/contracts', 12 | ] 13 | 14 | # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options 15 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ccip-cla-rate-limits", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@chainlink/contracts": "^1.4.0", 6 | "@chainlink/contracts-ccip": "^1.6.0", 7 | "@chainlink/local": "^0.2.5-beta.0", 8 | "@openzeppelin/contracts": "^5.0.2" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/src/ExampleConsumer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity 0.8.24; 3 | 4 | import {AggregatorInterface} from "./interfaces/AggregatorInterface.sol"; 5 | 6 | /** 7 | * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. 8 | * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. 9 | * DO NOT USE THIS CODE IN PRODUCTION. 10 | */ 11 | contract ExampleConsumer { 12 | AggregatorInterface immutable i_aggregator; 13 | 14 | constructor(address aggregator) { 15 | i_aggregator = AggregatorInterface(aggregator); 16 | } 17 | 18 | function getLatestExchangeRate() public view returns (uint256) { 19 | return i_aggregator.latestRoundData().exchangeRate; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/src/interfaces/AggregatorInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {Rate} from "../utils/Rate.sol"; 5 | 6 | /** 7 | * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. 8 | * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. 9 | * DO NOT USE THIS CODE IN PRODUCTION. 10 | */ 11 | interface AggregatorInterface { 12 | event NewReport(uint80 roundId, Rate.RateDetailsV1 rateDetails); 13 | 14 | function decimals() external view returns (uint8); 15 | 16 | function description() external view returns (string memory); 17 | 18 | function version() external view returns (uint256); 19 | 20 | function getRoundData(uint80 _roundId) external view returns (Rate.RateDetailsV1 memory); 21 | 22 | function latestRoundData() external view returns (Rate.RateDetailsV1 memory); 23 | } 24 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/src/interfaces/ICLASender.sol: -------------------------------------------------------------------------------- 1 | // SPDX-Licene-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import {Rate} from "../utils/Rate.sol"; 5 | 6 | /** 7 | * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. 8 | * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. 9 | * DO NOT USE THIS CODE IN PRODUCTION. 10 | */ 11 | interface ICLASender { 12 | error OnlyAutomationForwarderCanCall(); 13 | error NotEnoughBalanceForCCIPFees(uint256 currentBalance, uint256 requiredFees); 14 | 15 | event NewRateReported( 16 | bytes32 indexed ccipMessageId, 17 | uint256 indexed latestExchangeRate, 18 | uint256 blockTimestamp, 19 | uint256 blockNumber, 20 | address claReceiver, 21 | uint64 destinationChainSelector 22 | ); 23 | 24 | function getTarget() external view returns (address); 25 | 26 | function getLatestRate() external view returns (Rate.RateDetailsV1 memory); 27 | 28 | function description() external view returns (string memory); 29 | } 30 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/src/utils/Rate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | /** 5 | * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. 6 | * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. 7 | * DO NOT USE THIS CODE IN PRODUCTION. 8 | */ 9 | library Rate { 10 | struct RateDetailsV1 { 11 | uint256 exchangeRate; 12 | address srcTokenAddress; 13 | uint48 srcBlockTimestamp; 14 | uint48 srcBlockNumber; 15 | } 16 | 17 | /** 18 | * @notice Decodes the received bytes data into the Rate details array 19 | * @param receivedData - The encoded data received from the CLASender contract 20 | * @return length - The length of the rate details array 21 | * @return rate - The array of decoded rate details 22 | */ 23 | function decodeRate(bytes memory receivedData) internal pure returns (uint256, RateDetailsV1[] memory) { 24 | (uint256 length, RateDetailsV1[] memory rate) = abi.decode(receivedData, (uint256, RateDetailsV1[])); 25 | 26 | return (length, rate); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ccip/ccip-cla-rate-limits/src/utils/Withdraw.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {OwnerIsCreator} from "@chainlink/contracts/src/v0.8/shared/access/OwnerIsCreator.sol"; 5 | import {IERC20} from 6 | "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; 7 | import {SafeERC20} from 8 | "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; 9 | 10 | /** 11 | * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. 12 | * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. 13 | * DO NOT USE THIS CODE IN PRODUCTION. 14 | */ 15 | contract Withdraw is OwnerIsCreator { 16 | using SafeERC20 for IERC20; 17 | 18 | error FailedToWithdrawEth(address owner, address target, uint256 value); 19 | 20 | function withdraw(address beneficiary, uint256 amount) public onlyOwner { 21 | (bool sent,) = beneficiary.call{value: amount}(""); 22 | if (!sent) revert FailedToWithdrawEth(msg.sender, beneficiary, amount); 23 | } 24 | 25 | function withdrawToken(address beneficiary, address token, uint256 amount) public onlyOwner { 26 | IERC20(token).safeTransfer(beneficiary, amount); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ccip/cct/foundry/.env.example: -------------------------------------------------------------------------------- 1 | PRIVATE_KEY= 2 | RPC_URL_FUJI= 3 | RPC_URL_ARBITRUM_SEPOLIA= 4 | ETHERSCAN_API_KEY= 5 | ARBISCAN_API_KEY= -------------------------------------------------------------------------------- /ccip/cct/foundry/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | # Compiler files 4 | cache/ 5 | out/ 6 | 7 | # Ignores all broadcast logs except specific exclusions 8 | /broadcast/*/ 9 | /broadcast/**/dry-run/ 10 | /broadcast/**/31337/ 11 | 12 | # Docs 13 | docs/ 14 | 15 | # Dotenv file 16 | .env 17 | 18 | .DS_Store 19 | -------------------------------------------------------------------------------- /ccip/cct/foundry/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "solidity.compileUsingRemoteVersion": "v0.8.24+commit.e11b9ed9" 3 | } -------------------------------------------------------------------------------- /ccip/cct/foundry/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 SmartContract Chainlink Limited SEZC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ccip/cct/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | solc_version = "0.8.24" 6 | optimizer = true 7 | optimizer_runs = 200 8 | 9 | remappings = [ 10 | '@chainlink/contracts-ccip/=node_modules/@chainlink/contracts-ccip/', 11 | '@chainlink/contracts/=node_modules/@chainlink/contracts/', 12 | ] 13 | 14 | fs_permissions = [{ access = "read-write", path = "./" }] 15 | 16 | [etherscan] 17 | avalanche-fuji = { key = "${ETHERSCAN_API_KEY}", chain = 43113, url = "https://api-testnet.snowtrace.io/api" } 18 | arbitrum-sepolia = { key = "${ARBISCAN_API_KEY}", chain = 421613, url = "https://api-sepolia.arbiscan.io/api" } 19 | 20 | # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options 21 | -------------------------------------------------------------------------------- /ccip/cct/foundry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@chainlink/contracts": "^1.4.0", 4 | "@chainlink/contracts-ccip": "^1.6.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ccip/cct/foundry/script/SetRateLimitAdmin.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {Script, console} from "forge-std/Script.sol"; 5 | import {TokenPool} from "@chainlink/contracts-ccip/contracts/pools/TokenPool.sol"; 6 | 7 | contract SetRateLimitAdmin is Script { 8 | function run(address poolAddress, address adminAddress) external { 9 | // Validate the provided addresses 10 | require(poolAddress != address(0), "Invalid pool address"); 11 | require(adminAddress != address(0), "Invalid admin address"); 12 | 13 | // Get the signer address (the account running the script) 14 | address signer = vm.addr(uint256(vm.envBytes32("PRIVATE_KEY"))); 15 | 16 | // Log the operation being performed 17 | console.log("Setting rate limit admin to", adminAddress, "for pool at", poolAddress); 18 | 19 | // Start broadcasting transactions 20 | vm.startBroadcast(signer); 21 | 22 | // Instantiate the TokenPool contract 23 | TokenPool poolContract = TokenPool(poolAddress); 24 | 25 | // Call setRateLimitAdmin on the pool contract 26 | poolContract.setRateLimitAdmin(adminAddress); 27 | 28 | // Log success 29 | console.log("Rate limit admin updated successfully"); 30 | 31 | // Stop broadcasting 32 | vm.stopBroadcast(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ccip/cct/foundry/script/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "BnMToken": { 3 | "name": "BnM KH", 4 | "symbol": "BnMkh", 5 | "decimals": 18, 6 | "maxSupply": 0, 7 | "preMint": 0, 8 | "ccipAdminAddress": "0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA" 9 | }, 10 | "tokenAmountToMint": 1000000000000000000000, 11 | "tokenAmountToTransfer": 100000000000000000000, 12 | "feeType": "link", 13 | "remoteChains": { 14 | "43113": 421614, 15 | "421614": 43113 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ccip/cct/foundry/script/output/deployedTokenPool_arbitrumSepolia.json: -------------------------------------------------------------------------------- 1 | { 2 | "deployedTokenPool_arbitrumSepolia": "0x346e11C1a869b88A8033e40B18Efdc4eCD9FFd02" 3 | } -------------------------------------------------------------------------------- /ccip/cct/foundry/script/output/deployedTokenPool_avalancheFuji.json: -------------------------------------------------------------------------------- 1 | { 2 | "deployedTokenPool_avalancheFuji": "0xeB841acbc25549D4deB6Ed9401f3CbB529F3DC3e" 3 | } -------------------------------------------------------------------------------- /ccip/cct/foundry/script/output/deployedToken_arbitrumSepolia.json: -------------------------------------------------------------------------------- 1 | { 2 | "deployedToken_arbitrumSepolia": "0x8E9A370Ff35E9A5C081818B5C9EcC3E3EA89396b" 3 | } -------------------------------------------------------------------------------- /ccip/cct/foundry/script/output/deployedToken_avalancheFuji.json: -------------------------------------------------------------------------------- 1 | { 2 | "deployedToken_avalancheFuji": "0x56e4CFf5009908D8d8C5Aac5479574f9aC66e145" 3 | } -------------------------------------------------------------------------------- /ccip/cct/foundry/src/Dependencies.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {BurnMintTokenPool} from "@chainlink/contracts-ccip/contracts/pools/BurnMintTokenPool.sol"; 5 | import {LockReleaseTokenPool} from "@chainlink/contracts-ccip/contracts/pools/LockReleaseTokenPool.sol"; 6 | import {RegistryModuleOwnerCustom} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/RegistryModuleOwnerCustom.sol"; 7 | import {TokenAdminRegistry} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/TokenAdminRegistry.sol"; 8 | import {IGetCCIPAdmin} from "@chainlink/contracts-ccip/contracts/interfaces/IGetCCIPAdmin.sol"; 9 | import {RateLimiter} from "@chainlink/contracts-ccip/contracts/libraries/RateLimiter.sol"; 10 | import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol"; 11 | import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol"; 12 | import {OnRamp} from "@chainlink/contracts-ccip/contracts/onRamp/OnRamp.sol"; -------------------------------------------------------------------------------- /ccip/cct/hardhat/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .env.enc 4 | 5 | # Hardhat files 6 | /cache 7 | /artifacts 8 | 9 | # TypeChain files 10 | /typechain 11 | /typechain-types 12 | 13 | # solidity-coverage files 14 | /coverage 15 | /coverage.json 16 | 17 | # Hardhat Ignition default folder for deployments against a local node 18 | ignition/deployments/chain-31337 19 | 20 | .DS_Store 21 | .vscode -------------------------------------------------------------------------------- /ccip/cct/hardhat/config/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | Chains, 3 | Networks, 4 | PoolType, 5 | TokenContractName, 6 | TokenPoolContractName, 7 | } from "./types"; 8 | export { networks, etherscan } from "./networks"; 9 | export { logger } from "./logger"; 10 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/config/logger.ts: -------------------------------------------------------------------------------- 1 | import { createLogger, format, transports } from "winston"; 2 | 3 | const { combine, timestamp, printf, colorize } = format; 4 | 5 | const logFormat = printf(({ level, message, timestamp }) => { 6 | return `${timestamp} ${level}: ${message}`; 7 | }); 8 | 9 | export const logger = createLogger({ 10 | format: combine(colorize(), timestamp(), logFormat), 11 | transports: [new transports.Console()], 12 | }); 13 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/config/types.ts: -------------------------------------------------------------------------------- 1 | export interface ChainConfig { 2 | chainId?: number; 3 | chainSelector: string; 4 | router: string; 5 | rmnProxy: string; 6 | tokenAdminRegistry: string; 7 | registryModuleOwnerCustom: string; 8 | link: string; 9 | confirmations: number; 10 | nativeCurrencySymbol: string; 11 | } 12 | 13 | export enum Chains { 14 | avalancheFuji = "avalancheFuji", 15 | arbitrumSepolia = "arbitrumSepolia", 16 | sepolia = "sepolia", 17 | baseSepolia = "baseSepolia", 18 | } 19 | 20 | export type Configs = { 21 | [key in Chains]: ChainConfig; 22 | }; 23 | 24 | export interface NetworkConfig extends ChainConfig { 25 | url: string; 26 | gasPrice?: number; 27 | nonce?: number; 28 | accounts: string[]; 29 | } 30 | 31 | export type Networks = Partial<{ 32 | [key in Chains]: NetworkConfig; 33 | }>; 34 | 35 | type ApiKeyConfig = Partial<{ 36 | [key in Chains]: string; 37 | }>; 38 | 39 | interface Urls { 40 | apiURL: string; 41 | browserURL: string; 42 | } 43 | 44 | interface CustomChain { 45 | network: string; 46 | chainId: number; 47 | urls: Urls; 48 | } 49 | 50 | export interface EtherscanConfig { 51 | apiKey: ApiKeyConfig; 52 | customChains: CustomChain[]; 53 | } 54 | 55 | export enum TokenContractName { 56 | BurnMintERC20 = "BurnMintERC20" 57 | } 58 | 59 | export enum TokenPoolContractName { 60 | BurnMintTokenPool = "BurnMintTokenPool", 61 | LockReleaseTokenPool = "LockReleaseTokenPool", 62 | } 63 | 64 | export enum PoolType { 65 | burnMint = "burnMint", 66 | lockRelease = "lockRelease", 67 | } 68 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/contracts/Dependencies.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {BurnMintTokenPool} from "@chainlink/contracts-ccip/contracts/pools/BurnMintTokenPool.sol"; 5 | import {LockReleaseTokenPool} from "@chainlink/contracts-ccip/contracts/pools/LockReleaseTokenPool.sol"; 6 | import {RegistryModuleOwnerCustom} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/RegistryModuleOwnerCustom.sol"; 7 | import {TokenAdminRegistry} from "@chainlink/contracts-ccip/contracts/tokenAdminRegistry/TokenAdminRegistry.sol"; 8 | import {IGetCCIPAdmin} from "@chainlink/contracts-ccip/contracts/interfaces/IGetCCIPAdmin.sol"; 9 | import {RateLimiter} from "@chainlink/contracts-ccip/contracts/libraries/RateLimiter.sol"; 10 | import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol"; 11 | import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol"; 12 | import {OnRamp} from "@chainlink/contracts-ccip/contracts/onRamp/OnRamp.sol"; 13 | import {OwnerIsCreator} from "@chainlink/contracts/src/v0.8/shared/access/OwnerIsCreator.sol"; -------------------------------------------------------------------------------- /ccip/cct/hardhat/contracts/TokenDependencies.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {BurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol"; 5 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig } from "hardhat/config"; 2 | import "@nomicfoundation/hardhat-toolbox"; 3 | import { etherscan, networks } from "./config"; 4 | import "./tasks"; 5 | 6 | const SOLC_SETTINGS = { 7 | optimizer: { 8 | enabled: true, 9 | runs: 1_000, 10 | }, 11 | }; 12 | 13 | const config: HardhatUserConfig = { 14 | solidity: { 15 | compilers: [ 16 | { 17 | version: "0.8.24", 18 | settings: SOLC_SETTINGS, 19 | }, 20 | ], 21 | }, 22 | etherscan: { ...etherscan }, 23 | networks: { ...networks }, 24 | }; 25 | 26 | export default config; 27 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "self-serve-tokens", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "keywords": [], 7 | "author": "", 8 | "license": "ISC", 9 | "scripts": { 10 | "compile:hardhat": "hardhat compile", 11 | "compile:typechain": "hardhat typechain", 12 | "compile:typescript": "tsc --noEmit", 13 | "compile": "npm run compile:hardhat && npm run compile:typescript" 14 | }, 15 | "devDependencies": { 16 | "@nomicfoundation/hardhat-toolbox": "^5.0.0", 17 | "@types/chai": "^4.3.16", 18 | "@types/mocha": "^10.0.6", 19 | "@types/node": "^20.12.12", 20 | "chai": "^4.4.1", 21 | "hardhat": "^2.22.4", 22 | "ts-node": "^10.9.2", 23 | "typescript": "^5.4.5" 24 | }, 25 | "dependencies": { 26 | "@chainlink/contracts": "^1.4.0", 27 | "@chainlink/contracts-ccip": "^1.6.0", 28 | "@chainlink/env-enc": "^1.0.5", 29 | "@safe-global/api-kit": "^2.4.5", 30 | "@safe-global/protocol-kit": "^4.1.0", 31 | "@safe-global/safe-core-sdk-types": "^5.1.0", 32 | "winston": "^3.13.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/tasks/index.ts: -------------------------------------------------------------------------------- 1 | import "./deployToken"; 2 | import "./deployTokenPool"; 3 | import "./getPoolConfig"; 4 | import "./claimAdmin"; 5 | import "./acceptAdminRole"; 6 | import "./setPool"; 7 | import "./applyChainUpdates"; 8 | import "./transferTokens"; 9 | import "./mintTokens"; 10 | import "./updateRateLimiters"; 11 | import "./updateAllowList"; 12 | import "./safe-multisig"; 13 | import "./getPoolConfig"; 14 | import "./getCurrentRateLimits"; 15 | import "./setRateLimitAdmin"; 16 | import "./transferTokenAdminRole"; 17 | import "./addRemotePool"; 18 | import "./removeRemotePool"; 19 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/tasks/safe-multisig/index.ts: -------------------------------------------------------------------------------- 1 | import "./deployToken"; 2 | import "./deployTokenPool"; 3 | import "./claimAndAcceptAdminRole"; 4 | import "./setPool"; 5 | import "./applyChainUpdates"; 6 | import "./mintTokens"; 7 | import "./deploySafe"; 8 | import "./acceptOwnership"; 9 | import "./grantMintBurnRole"; 10 | -------------------------------------------------------------------------------- /ccip/cct/hardhat/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ccip/estimate-gas/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .env.enc 4 | 5 | # Hardhat files 6 | cache 7 | artifacts 8 | 9 | # TypeChain files 10 | typechain 11 | typechain-types 12 | 13 | # solidity-coverage files 14 | coverage 15 | coverage.json 16 | 17 | 18 | 19 | out/ 20 | .dist/ 21 | 22 | # Ignores development broadcast logs 23 | !/broadcast 24 | /broadcast/*/31337/ 25 | /broadcast/**/dry-run/ 26 | 27 | # Docs 28 | docs/ 29 | 30 | 31 | -------------------------------------------------------------------------------- /ccip/estimate-gas/README.md: -------------------------------------------------------------------------------- 1 | - [foundry](./foundry/README.md) 2 | - [hardhat](./hardhat/README.md) 3 | - [offchain](./offchain/README.md) 4 | -------------------------------------------------------------------------------- /ccip/estimate-gas/foundry/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /ccip/estimate-gas/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | gas_reports = ["*"] 6 | solc = '0.8.24' 7 | optimizer = true 8 | optimizer_runs = 200 9 | 10 | remappings = [ 11 | '@chainlink/contracts-ccip/=node_modules/@chainlink/contracts-ccip/', 12 | '@chainlink/contracts/=node_modules/@chainlink/contracts/', 13 | ] 14 | 15 | # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options 16 | -------------------------------------------------------------------------------- /ccip/estimate-gas/foundry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@chainlink/contracts": "^1.4.0", 4 | "@chainlink/contracts-ccip": "^1.6.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/ccip.config.ts: -------------------------------------------------------------------------------- 1 | const networks = { 2 | ethereumSepolia: { 3 | router: "0x0bf3de8c5d3e8a2b34d2beeb17abfcebaf363a59", 4 | chainSelector: "16015286601757825753", 5 | linkToken: "0x779877A7B0D9E8603169DdbD7836e478b4624789", 6 | }, 7 | avalancheFuji: { 8 | router: "0xf694e193200268f9a4868e4aa017a0118c9a8177", 9 | chainSelector: "14767482510784806043", 10 | linkToken: "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846", 11 | }, 12 | }; 13 | 14 | type SupportedNetworks = keyof typeof networks; 15 | 16 | const getCCIPConfig = (network: SupportedNetworks) => { 17 | if (networks[network]) { 18 | return networks[network]; 19 | } 20 | throw new Error("Unknown network: " + network); 21 | }; 22 | 23 | export { getCCIPConfig, SupportedNetworks }; 24 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/contracts/BurnMintERC677.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {BurnMintERC677} from "@chainlink/contracts/src/v0.8/shared/token/ERC677/BurnMintERC677.sol"; -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/contracts/MockCCIPRouter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | import {MockCCIPRouter} from "@chainlink/contracts-ccip/contracts/test/mocks/MockRouter.sol"; 5 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig } from "hardhat/config"; 2 | import "@nomicfoundation/hardhat-toolbox"; 3 | require("@chainlink/env-enc").config(); 4 | 5 | const SOLC_SETTINGS = { 6 | optimizer: { 7 | enabled: true, 8 | runs: 1_000, 9 | }, 10 | }; 11 | 12 | const PRIVATE_KEY = process.env.PRIVATE_KEY || ""; 13 | const accounts = [PRIVATE_KEY]; 14 | 15 | const config: HardhatUserConfig = { 16 | solidity: { 17 | compilers: [ 18 | { 19 | version: "0.8.24", 20 | settings: SOLC_SETTINGS, 21 | }, 22 | ], 23 | }, 24 | networks: { 25 | ethereumSepolia: { 26 | url: process.env.ETHEREUM_SEPOLIA_RPC_URL || "UNSET", 27 | chainId: 11155111, 28 | accounts, 29 | }, 30 | avalancheFuji: { 31 | url: process.env.AVALANCHE_FUJI_RPC_URL || "UNSET", 32 | chainId: 43113, 33 | accounts, 34 | }, 35 | }, 36 | etherscan: { 37 | apiKey: { 38 | sepolia: process.env.ETHERSCAN_API_KEY || "UNSET", 39 | avalancheFuji: "avalancheFuji", 40 | }, 41 | customChains: [ 42 | { 43 | network: "avalancheFuji", 44 | chainId: 43113, 45 | urls: { 46 | apiURL: 47 | "https://api.routescan.io/v2/network/testnet/evm/43113/etherscan", 48 | browserURL: "https://testnet.snowtrace.io", 49 | }, 50 | }, 51 | ], 52 | }, 53 | }; 54 | 55 | export default config; 56 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "estimate-gas", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@chainlink/contracts-ccip": "^1.6.0", 14 | "@chainlink/env-enc": "^1.0.5", 15 | "@nomicfoundation/hardhat-toolbox": "^4.0.0", 16 | "hardhat": "^2.20.1" 17 | }, 18 | "dependencies": { 19 | "@chainlink/contracts": "^1.4.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/scripts/configuration/allowlistingForReceiver.ts: -------------------------------------------------------------------------------- 1 | import { ethers, network } from "hardhat"; 2 | import { SupportedNetworks, getCCIPConfig } from "../../ccip.config"; 3 | import deployedContracts from "../generatedData.json"; 4 | 5 | async function allowlistingForReceiver(currentNetwork: SupportedNetworks) { 6 | // Get the Receiver contract instance 7 | const receiverAddress = ( 8 | deployedContracts[currentNetwork] as { receiver: string } 9 | ).receiver; 10 | const receiver = await ethers.getContractAt("Receiver", receiverAddress); 11 | 12 | // Iterate over each supported network 13 | for (const network in deployedContracts) { 14 | const supportedNetwork = network as SupportedNetworks; 15 | const sender = (deployedContracts[supportedNetwork] as { sender: string }) 16 | .sender; 17 | 18 | if (sender) { 19 | // Fetch the destination chain selector 20 | const sourceChainSelector = getCCIPConfig(supportedNetwork).chainSelector; 21 | 22 | await receiver.allowlistSourceChain(sourceChainSelector, true); 23 | await receiver.allowlistSender(sender, true); 24 | 25 | console.log(`Allowlisted: ${supportedNetwork} , ${sender}`); 26 | } 27 | } 28 | } 29 | 30 | allowlistingForReceiver(network.name as SupportedNetworks).catch((error) => { 31 | console.error(error); 32 | process.exit(1); 33 | }); 34 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/scripts/configuration/allowlistingForSender.ts: -------------------------------------------------------------------------------- 1 | import { ethers, network } from "hardhat"; 2 | import { SupportedNetworks, getCCIPConfig } from "../../ccip.config"; 3 | import deployedContracts from "../generatedData.json"; 4 | 5 | async function allowlistingForSender(currentNetwork: SupportedNetworks) { 6 | // Get the Sender contract instance 7 | const senderAddress = ( 8 | deployedContracts[currentNetwork] as { sender: string } 9 | ).sender; 10 | const sender = await ethers.getContractAt("Sender", senderAddress); 11 | 12 | // Iterate over each supported network 13 | for (const network in deployedContracts) { 14 | const supportedNetwork = network as SupportedNetworks; 15 | const receiver = ( 16 | deployedContracts[supportedNetwork] as { receiver: string } 17 | ).receiver; 18 | 19 | if (receiver) { 20 | // Fetch the destination chain selector 21 | const destinationChainSelector = 22 | getCCIPConfig(supportedNetwork).chainSelector; 23 | 24 | await sender.allowlistDestinationChain(destinationChainSelector, true); 25 | 26 | console.log(`Allowlisted: ${supportedNetwork}`); 27 | } 28 | } 29 | } 30 | 31 | allowlistingForSender(network.name as SupportedNetworks).catch((error) => { 32 | console.error(error); 33 | process.exit(1); 34 | }); 35 | -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/scripts/generatedData.json: -------------------------------------------------------------------------------- 1 | { 2 | "ethereumSepolia": { 3 | "receiver": "" 4 | }, 5 | "avalancheFuji": { 6 | "sender": "" 7 | } 8 | } -------------------------------------------------------------------------------- /ccip/estimate-gas/hardhat/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ccip/estimate-gas/offchain/ccip.config.ts: -------------------------------------------------------------------------------- 1 | const networks = { 2 | ethereumSepolia: { 3 | router: "0x0bf3de8c5d3e8a2b34d2beeb17abfcebaf363a59", 4 | chainSelector: "16015286601757825753", 5 | linkToken: "0x779877A7B0D9E8603169DdbD7836e478b4624789", 6 | }, 7 | avalancheFuji: { 8 | router: "0xf694e193200268f9a4868e4aa017a0118c9a8177", 9 | chainSelector: "14767482510784806043", 10 | linkToken: "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846", 11 | }, 12 | }; 13 | 14 | type SupportedNetworks = keyof typeof networks; 15 | 16 | const getCCIPConfig = (network: SupportedNetworks) => { 17 | if (networks[network]) { 18 | return networks[network]; 19 | } 20 | throw new Error("Unknown network: " + network); 21 | }; 22 | 23 | export { getCCIPConfig, SupportedNetworks }; 24 | -------------------------------------------------------------------------------- /ccip/estimate-gas/offchain/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "ethereumSepolia": { 3 | "receiver": "REPLACE_WITH_YOUR_RECEIVER_ADDRESS" 4 | }, 5 | "avalancheFuji": { 6 | "sender": "REPLACE_WITH_YOUR_SENDER_ADDRESS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ccip/estimate-gas/offchain/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "offchain-simulator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "generate-types": "typechain --target ethers-v6 --out-dir src/typechain-types './abis/*.json'", 8 | "estimate-gas-provider": "ts-node src/estimateGasProvider.ts", 9 | "estimate-gas-tenderly": "ts-node src/estimateGasTenderly.ts" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@types/node": "^20.11.24", 16 | "ts-node": "^10.9.2", 17 | "typescript": "^5.3.3" 18 | }, 19 | "dependencies": { 20 | "@chainlink/env-enc": "^1.0.5", 21 | "@typechain/ethers-v6": "^0.5.1", 22 | "axios": "^1.6.7", 23 | "ethers": "^6.11.1", 24 | "uid": "^2.0.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ccip/offchain/README.md: -------------------------------------------------------------------------------- 1 | This repository is dedicated to providing examples on how to interact with the CCIP Router contract in an offchain context. 2 | You can use your Externally Owned Account (EOA) to directly initiate transactions and invoke the router's functions. 3 | -------------------------------------------------------------------------------- /ccip/offchain/config/messageState.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": "UNTOUCHED", 3 | "1": "IN_PROGRESS", 4 | "2": "SUCCESS", 5 | "3": "FAILURE" 6 | } 7 | -------------------------------------------------------------------------------- /ccip/offchain/javascript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env.enc 3 | lanes-and-tokens.js 4 | -------------------------------------------------------------------------------- /ccip/offchain/javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ccip-offchain-examples-js", 3 | "version": "1.0.0", 4 | "description": "provide typescript examples of interacting with Chainlink CCIP from your EOA", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@chainlink/env-enc": "^1.0.5", 13 | "ethers": "^6.11.1", 14 | "lodash": "^4.17.21" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ccip/offchain/javascript/src/config/env.js: -------------------------------------------------------------------------------- 1 | const { supportedNetworks } = require("./ccip"); 2 | 3 | const getRpcUrlName = (network) => 4 | network.replace(/([A-Z])/g, "_$1").toUpperCase() + "_RPC_URL"; 5 | 6 | const getProviderRpcUrl = (network) => { 7 | require("@chainlink/env-enc").config(); 8 | if (!supportedNetworks.includes(network)) 9 | throw new Error( 10 | `[ERROR] Network '${network}' is not supported. Supported networks: ${supportedNetworks.join(", ")}` 11 | ); 12 | 13 | const environmentVariableName = getRpcUrlName(network); 14 | const rpcUrl = process.env[environmentVariableName]; 15 | 16 | if (!rpcUrl) 17 | throw new Error( 18 | `[ERROR] RPC URL not found for network '${network}'. Please set ${environmentVariableName} in your environment variables` 19 | ); 20 | return rpcUrl; 21 | }; 22 | 23 | const getPrivateKey = () => { 24 | require("@chainlink/env-enc").config(); 25 | const privateKey = process.env.PRIVATE_KEY; 26 | if (!privateKey) 27 | throw new Error( 28 | `[ERROR] PRIVATE_KEY not found in environment variables. Please set PRIVATE_KEY using chainlink env-enc` 29 | ); 30 | return privateKey; 31 | }; 32 | 33 | module.exports = { 34 | getPrivateKey, 35 | getProviderRpcUrl, 36 | }; 37 | -------------------------------------------------------------------------------- /ccip/offchain/javascript/src/config/index.js: -------------------------------------------------------------------------------- 1 | const env = require("./env"); 2 | const ccip = require("./ccip"); 3 | const offramp = require("./offramp"); 4 | 5 | // override console.log to disable ethersjs warning when there are duplicates in ABI 6 | 7 | const oldLog = console.log; 8 | 9 | const log = (...args) => { 10 | const msg = args.length > 0 ? args[0] : ""; 11 | 12 | if (/Duplicate definition of/.test(msg)) { 13 | return; 14 | } 15 | 16 | oldLog(...args); // This will pass all the arguments to the original console.log function 17 | }; 18 | 19 | console.log = log; 20 | 21 | module.exports = { 22 | ...ccip, 23 | ...env, 24 | ...offramp, 25 | }; 26 | -------------------------------------------------------------------------------- /ccip/offchain/javascript/src/config/offramp.js: -------------------------------------------------------------------------------- 1 | const messageExecutionState = require("../../../config/messageState.json"); 2 | 3 | const getMessageStatus = (status) => { 4 | if (status in messageExecutionState) { 5 | return messageExecutionState[status]; 6 | } 7 | return "unknown"; 8 | }; 9 | 10 | module.exports = { 11 | getMessageStatus, 12 | }; 13 | -------------------------------------------------------------------------------- /ccip/offchain/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env.enc 3 | typechain-types 4 | dist 5 | -------------------------------------------------------------------------------- /ccip/offchain/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "generate-types": "typechain --target ethers-v6 --out-dir src/typechain-types '../abi/*.json'", 9 | "postinstall": "echo 'generate typechain types' && npm run generate-types" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@typechain/ethers-v6": "^0.5.1", 16 | "@types/lodash": "^4.14.202", 17 | "@types/node": "^20.11.25", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.4.2" 20 | }, 21 | "dependencies": { 22 | "@chainlink/env-enc": "^1.0.5", 23 | "ethers": "^6.11.1", 24 | "lodash": "^4.17.21" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ccip/offchain/typescript/src/config/env.ts: -------------------------------------------------------------------------------- 1 | import { NETWORK, supportedNetworks } from "."; 2 | 3 | const getRpcUrlName = (network: NETWORK) => 4 | network.replace(/([A-Z])/g, "_$1").toUpperCase() + "_RPC_URL"; 5 | 6 | const getProviderRpcUrl = (network: NETWORK) => { 7 | require("@chainlink/env-enc").config(); 8 | if (!supportedNetworks.includes(network)) 9 | throw new Error(`[ERROR] Network '${network}' is not supported. Supported networks: ${supportedNetworks.join(", ")}`); 10 | 11 | const environmentVariableName = getRpcUrlName(network); 12 | const rpcUrl = process.env[environmentVariableName]; 13 | 14 | if (!rpcUrl) 15 | throw new Error( 16 | `[ERROR] RPC URL not found for network '${network}'. Please set ${environmentVariableName} in your environment variables` 17 | ); 18 | return rpcUrl; 19 | }; 20 | 21 | const getPrivateKey = () => { 22 | require("@chainlink/env-enc").config(); 23 | const privateKey = process.env.PRIVATE_KEY; 24 | if (!privateKey) 25 | throw new Error( 26 | `[ERROR] PRIVATE_KEY not found in environment variables. Please set PRIVATE_KEY using chainlink env-enc` 27 | ); 28 | return privateKey; 29 | }; 30 | 31 | export { getPrivateKey, getProviderRpcUrl }; 32 | -------------------------------------------------------------------------------- /ccip/offchain/typescript/src/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./env"; 2 | export * from "./ccip"; 3 | export * from "./offramp"; 4 | 5 | // override console.log to disable ethersjs warning when there are duplicates in ABI 6 | 7 | const oldLog = console.log; 8 | 9 | const log = (...args: any[]) => { 10 | const msg = args.length > 0 ? args[0] : ""; 11 | 12 | if (/Duplicate definition of/.test(msg)) { 13 | return; 14 | } 15 | 16 | oldLog(...args); // This will pass all the arguments to the original console.log function 17 | }; 18 | 19 | console.log = log; 20 | -------------------------------------------------------------------------------- /ccip/offchain/typescript/src/config/offramp.ts: -------------------------------------------------------------------------------- 1 | import messageExecutionState from "../../../config/messageState.json"; 2 | 3 | const getMessageStatus = (status: bigint): string => { 4 | const statusKey = status.toString() as keyof typeof messageExecutionState; 5 | if (statusKey in messageExecutionState) { 6 | return messageExecutionState[statusKey]; 7 | } 8 | return "unknown"; 9 | }; 10 | 11 | export { getMessageStatus }; 12 | -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | fs_permissions = [{ access = "read-write", path = "./script/addresses.json"}] 6 | remappings = [ 7 | "@chainlink/contracts-ccip/=lib/ccip/contracts/", 8 | "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", 9 | "@chainlink/local/=lib/chainlink-local/", 10 | ] 11 | gas_reports = ["*"] 12 | # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaging-lock-and-release.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaging-lock-and-release.jpg -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaing-burn-and-mint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaing-burn-and-mint.jpg -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaing-lock-and-mint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ccip/token-transfer-using-arbitrary-messaging/img/tokens-messaing-lock-and-mint.jpg -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/script/addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "ArbitrumSepolia_bridge": "0xc201125662bdDB9A52193e563345C25CcD6641b8", 3 | "ArbitrumSepolia_burnMintPool": "0x4c964e79b8AEC623BeDf75Fe43D998179F2c52f7", 4 | "ArbitrumSepolia_burnMintToken": "0x8B6F6816745eB409f0d8A2eEd3E9dD6Fb4377940", 5 | "ArbitrumSepolia_configuration": "0x0829696E956d08f179ae36f4F40698167f449c09", 6 | "ArbitrumSepolia_lockReleasePool": "0xc9E837EDd2bb0b613A178ff2D7F4DED09C04D4b6", 7 | "ArbitrumSepolia_lockableToken": "0x586db463e50dB53ADc15d2F22f08308aECc171D9", 8 | "Fuji_bridge": "0x2E685f521F351781815aF1E075B4Bbd831693368", 9 | "Fuji_burnMintPool": "0x4caAc735ECfcAC34db062d655141C915c810857a", 10 | "Fuji_burnMintToken": "0x59cc0a2F462aca8b8d2363032b0BBb719c6F0b93", 11 | "Fuji_configuration": "0xeF9A5F3bb1eC2f8c0E7bade286D3fE870810e351", 12 | "Fuji_lockReleasePool": "0x1D5735D0B79FE88E813A4DB85040B06Ba25Ed8C3", 13 | "Fuji_lockableToken": "0xFeb598F3F146d7b785C621c3d931F332De1A8939", 14 | "Sepolia_bridge": "0xd9A6e10A3D7247725851EAffD7690B8BD93FAA57", 15 | "Sepolia_burnMintPool": "0x909FDa73a1ceDB0Dd8951b6660603dAA65fEA2c1", 16 | "Sepolia_burnMintToken": "0x2E58D5f253a791e10d51fE4D8d92D0867bD8a4Bf", 17 | "Sepolia_configuration": "0xcd9B7F6D9c2CcaE0FC07847398a1534c7886c05b", 18 | "Sepolia_lockReleasePool": "0x96F8d40Bc9354E9A4eb774f0Ba043C90d7c2f14d", 19 | "Sepolia_lockableToken": "0xdbFdC1E2E4a2858595c3202530517F6dAcd55999", 20 | "completed": true 21 | } -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/src/interfaces/IBurnMintERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | /** 5 | * @notice This contract is provided "AS IS" without warranties of any kind, as an example and has not been audited. 6 | * Users are advised to thoroughly test and audit their own implementations 7 | * before deploying to mainnet or any production environment. 8 | * 9 | * @dev This code is intended for educational and illustrative purposes only. 10 | * Use it at your own risk. The authors are not responsible for any loss of 11 | * funds or other damages caused by the use of this code. 12 | */ 13 | 14 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 15 | 16 | interface IBurnMintERC20 is IERC20 { 17 | /// @notice Mints new tokens for a given address. 18 | /// @param account The address to mint the new tokens to. 19 | /// @param amount The number of tokens to be minted. 20 | /// @dev this function increases the total supply. 21 | function mint(address account, uint256 amount) external; 22 | 23 | /// @notice Burns tokens from the sender. 24 | /// @param amount The number of tokens to be burned. 25 | /// @dev this function decreases the total supply. 26 | function burn(uint256 amount) external; 27 | } 28 | -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/src/pools/BurnMintTokenPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | /** 5 | * @notice This contract is provided "AS IS" without warranties of any kind, as an example and has not been audited. 6 | * Users are advised to thoroughly test and audit their own implementations 7 | * before deploying to mainnet or any production environment. 8 | * 9 | * @dev This code is intended for educational and illustrative purposes only. 10 | * Use it at your own risk. The authors are not responsible for any loss of 11 | * funds or other damages caused by the use of this code. 12 | */ 13 | import {IBurnMintERC20} from "../interfaces/IBurnMintERC20.sol"; 14 | import {Pool} from "./Pool.sol"; 15 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 16 | import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 17 | 18 | contract BurnMintTokenPool is Pool { 19 | constructor( 20 | IERC20 token, 21 | address bridge 22 | ) Pool(token, TokenPoolType.BurnMint, bridge) {} 23 | 24 | function _lockOrBurn(uint256 amount) internal override { 25 | IBurnMintERC20(address(i_token)).burn(amount); 26 | emit Burned(msg.sender, amount); 27 | } 28 | 29 | function _releaseOrMint( 30 | uint256 amount, 31 | address receiver 32 | ) internal override { 33 | IBurnMintERC20(address(i_token)).mint(receiver, amount); 34 | emit Minted(msg.sender, receiver, amount); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ccip/token-transfer-using-arbitrary-messaging/test/mocks/MockERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.24; 3 | 4 | /** 5 | * @notice This contract is provided "AS IS" without warranties of any kind, as an example and has not been audited. 6 | * Users are advised to thoroughly test and audit their own implementations 7 | * before deploying to mainnet or any production environment. 8 | * 9 | * @dev This code is intended for educational and illustrative purposes only. 10 | * Use it at your own risk. The authors are not responsible for any loss of 11 | * funds or other damages caused by the use of this code. 12 | */ 13 | 14 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 15 | 16 | contract MockERC20 is ERC20 { 17 | constructor( 18 | string memory name, 19 | string memory symbol, 20 | uint256 initialSupply 21 | ) ERC20(name, symbol) { 22 | _mint(msg.sender, initialSupply); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /counting-svg/README.md: -------------------------------------------------------------------------------- 1 | # Counting SVG NFT 2 | This repo houses an example that automates counting with a dynamic SVG. 3 | 4 | ## How to Use The Repo 5 | 6 | This repo consists of one file: 7 | - **counting-svg.sol**: This is the contract that will be automated to count and create a 100% on chain svg. 8 | 9 | This contract can be deployed as is via a tool like [Remix](https://remix.ethereum.org/). 10 | -------------------------------------------------------------------------------- /dadjokes-onchain/README.md: -------------------------------------------------------------------------------- 1 | # Dad Jokes On Chain 2 | > Dad jokes, they used to be off the chain. 3 | 4 | **_TODO: YT LINK_** 5 | This repo supports the tutorial [Dad Jokes On Chain]() 6 | 7 | ## How To Use The Repo 8 | The repo is broken into 2 main sections via folders 9 | **smartcontract**: This folder contains a foundry project with the smart contract which will hold the dad jokes and any reward that has been given to them. 10 | 11 | **frontend**: This folder contains the next.js project which will act as the front end for interacting with the smart contract. 12 | 13 | ### Running the frontend 14 | Clone the repo and then run `npm install` within the next folder. Once that completes you can start the front end via `npm run dev` 15 | 16 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/babel", "next/core-web-vitals"] 3 | } 4 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | First, install everything 5 | ``` 6 | npm install 7 | ``` 8 | 9 | Then, run the development server: 10 | 11 | ```bash 12 | npm run dev 13 | # or 14 | yarn dev 15 | # or 16 | pnpm dev 17 | # or 18 | bun dev 19 | ``` 20 | 21 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 22 | 23 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 24 | 25 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 26 | 27 | ## Learn More 28 | 29 | To learn more about Next.js, take a look at the following resources: 30 | 31 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 32 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 33 | 34 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 35 | 36 | ## Deploy on Vercel 37 | 38 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 39 | 40 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 41 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "14.2.3", 13 | "react": "^18", 14 | "react-dom": "^18", 15 | "viem": "^2.13.7" 16 | }, 17 | "devDependencies": { 18 | "eslint": "^8", 19 | "eslint-config-next": "14.2.3", 20 | "postcss": "^8", 21 | "tailwindcss": "^3.4.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/dadjokes-onchain/frontend/src/app/favicon.ico -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap'); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | 8 | :root { 9 | --foreground-rgb: 0, 0, 0; 10 | --background-start-rgb: 214, 219, 220; 11 | --background-end-rgb: 255, 255, 255; 12 | } 13 | 14 | @media (prefers-color-scheme: dark) { 15 | :root { 16 | --foreground-rgb: 255, 255, 255; 17 | --background-start-rgb: 0, 0, 0; 18 | --background-end-rgb: 0, 0, 0; 19 | } 20 | } 21 | 22 | body { 23 | color: rgb(var(--foreground-rgb)); 24 | background: linear-gradient( 25 | to bottom, 26 | transparent, 27 | rgb(var(--background-end-rgb)) 28 | ) 29 | rgb(var(--background-start-rgb)); 30 | } 31 | 32 | @layer utilities { 33 | .text-balance { 34 | text-wrap: balance; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/app/layout.jsx: -------------------------------------------------------------------------------- 1 | import "./globals.css"; 2 | 3 | export const metadata = { 4 | title: "Dad Jokes", 5 | description: "Jokes so bad, you might just be a father.", 6 | }; 7 | 8 | export default function RootLayout({ children }) { 9 | return ( 10 | 11 | {children} 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/components/Button.js: -------------------------------------------------------------------------------- 1 | export const Button = ({ onClick, children }) => ( 2 | 8 | ); 9 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/components/Card.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | const Card = ({ joke }) => { 4 | console.log(joke); 5 | if (!joke) { 6 | return null; // or you can render a loading state or placeholder 7 | } 8 | return ( 9 |
10 |

11 | {joke.setup} 12 |

13 |

{joke.punchline}

14 |
15 | ); 16 | }; 17 | export default Card; 18 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/components/ConnectButton.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Image from "next/image"; 3 | 4 | const ConnectButton = ({ handleClick }) => { 5 | return ( 6 |
7 | 20 |
21 | ); 22 | }; 23 | 24 | export default ConnectButton; 25 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/components/RewardSection.js: -------------------------------------------------------------------------------- 1 | const RewardSection = ({ index, handleVote }) => { 2 | return ( 3 | <> 4 |
5 | Reward The Joke 6 |
7 |
8 | 14 | 20 | 26 |
27 | 28 | ); 29 | }; 30 | export default RewardSection; 31 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/components/WithdrawSection.js: -------------------------------------------------------------------------------- 1 | const WithdrawSection = ({ balance, handleWithdraw }) => { 2 | return ( 3 | <> 4 | {balance !== null && parseFloat(balance) > 0 && ( 5 |
6 | Balance: {balance} ETH 7 | 13 |
14 | )} 15 | 16 | ); 17 | }; 18 | 19 | export default WithdrawSection; 20 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/hooks/useJokes.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useState } from "react"; 4 | import { ConnectPublicClient } from "@/lib/client"; 5 | import { getContract } from "viem"; 6 | import dadJokesABI from "@/lib/dadJokesABI.json"; 7 | 8 | const publicClient = ConnectPublicClient(); 9 | const dadJokesContract = getContract({ 10 | address: "0x4fF652D3C68F488D6c99ca796581d3c4a83f56ED", 11 | abi: dadJokesABI, 12 | client: { public: publicClient }, 13 | }); 14 | 15 | export const useJokes = () => { 16 | // Specify the type of the state 17 | const [jokes, setJokes] = useState([]); 18 | useEffect(() => { 19 | const fetchJokes = async () => { 20 | try { 21 | // Specify the type of the fetched jokes 22 | const fetchedJokes = await dadJokesContract.read.getJokes(); 23 | setJokes(fetchedJokes); 24 | } catch (error) { 25 | console.error("Error fetching jokes:", error); 26 | } 27 | }; 28 | fetchJokes(); 29 | }, []); 30 | 31 | return jokes; 32 | }; 33 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/hooks/useSubmitJoke.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import { sepolia } from "viem/chains"; 3 | 4 | export function useSubmitJoke(publicClient, walletClient, dadJokesContract) { 5 | const [isModalOpen, setIsModalOpen] = useState(false); 6 | 7 | const handleSubmit = async (setup, punchline) => { 8 | // const walletClient = await ConnectWalletClient(); 9 | // Retrieve the wallet address using the Wallet Client 10 | const [address] = await walletClient.requestAddresses(); 11 | await walletClient.switchChain({ id: sepolia.id }); 12 | 13 | const { request } = await publicClient.simulateContract({ 14 | address: dadJokesContract.address, 15 | abi: dadJokesContract.abi, 16 | functionName: "addJoke", 17 | args: [setup, punchline], 18 | account: address, 19 | }); 20 | await walletClient.writeContract(request); 21 | setIsModalOpen(false); 22 | }; 23 | return { isModalOpen, setIsModalOpen, handleSubmit }; 24 | } 25 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/hooks/useVote.js: -------------------------------------------------------------------------------- 1 | import { sepolia } from "viem/chains"; 2 | import { parseEther } from "viem/utils"; 3 | 4 | export function useVote(dadJokesContract, walletClient, publicClient) { 5 | async function handleVote(index, type) { 6 | const reward = type + 1; 7 | // Instantiate a Wallet Client and a Public Client 8 | // const walletClient = await ConnectWalletClient(); 9 | // Retrieve the wallet address using the Wallet Client 10 | const [address] = await walletClient.requestAddresses(); 11 | await walletClient.switchChain({ id: sepolia.id }); 12 | 13 | let rewardAmount; 14 | 15 | switch (type) { 16 | case 0: 17 | rewardAmount = parseEther("0.001"); 18 | break; 19 | case 1: 20 | rewardAmount = parseEther("0.005"); 21 | break; 22 | case 2: 23 | rewardAmount = parseEther("0.01"); 24 | break; 25 | default: 26 | throw new Error("Invalid reward type"); 27 | } 28 | // Simulate the contract call to rewardJoke with the specified index and reward 29 | // this will return a request object that can be used to write the contract. 30 | const { request } = await publicClient.simulateContract({ 31 | address: dadJokesContract.address, 32 | abi: dadJokesContract.abi, 33 | functionName: "rewardJoke", 34 | args: [index, reward], 35 | account: address, 36 | value: rewardAmount, 37 | }); 38 | await walletClient.writeContract(request); 39 | console.log(request); 40 | } 41 | return { handleVote }; 42 | } 43 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/hooks/useWallet.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import { ConnectWalletClient } from "@/lib/client"; 3 | import { formatEther } from "viem"; 4 | 5 | export function useWallet(dadJokesContract) { 6 | const [address, setAddress] = useState(null); 7 | const [balance, setBalance] = useState(null); 8 | 9 | async function handleClick() { 10 | try { 11 | const walletClient = await ConnectWalletClient(); 12 | if (walletClient !== null) { 13 | const [address] = await walletClient.requestAddresses(); 14 | setAddress(address); 15 | // Retrieve the balance of the address using the Public Client 16 | const balance = parseInt( 17 | await dadJokesContract.read.creatorBalances([address]) 18 | ); 19 | setAddress(address); 20 | setBalance(formatEther(BigInt(balance))); 21 | } 22 | } catch (error) { 23 | alert(`Transaction failed: ${error}`); 24 | } 25 | } 26 | 27 | return { address, balance, handleClick }; 28 | } 29 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/hooks/useWithdraw.js: -------------------------------------------------------------------------------- 1 | import { sepolia } from "viem/chains"; 2 | 3 | export function useWithdraw(dadJokesContract, walletClient, publicClient) { 4 | async function handleWithdraw() { 5 | // Instantiate a Wallet Client and a Public Client 6 | // const walletClient = await ConnectWalletClient(); 7 | // Retrieve the wallet address using the Wallet Client 8 | const [address] = await walletClient.requestAddresses(); 9 | await walletClient.switchChain({ id: sepolia.id }); 10 | 11 | const { request } = await publicClient.simulateContract({ 12 | address: dadJokesContract.address, 13 | abi: dadJokesContract.abi, 14 | functionName: "withdrawBalance", 15 | account: address, 16 | }); 17 | await walletClient.writeContract(request); 18 | } 19 | return { handleWithdraw }; 20 | } 21 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/src/lib/client.js: -------------------------------------------------------------------------------- 1 | import { createWalletClient, createPublicClient, custom, http } from "viem"; 2 | import { sepolia } from "viem/chains"; 3 | import "viem/window"; 4 | 5 | export async function ConnectWalletClient() { 6 | // Check for window.ethereum 7 | // window.ethereum is an object provided by MetaMask or other web3 wallets 8 | let transport; 9 | if (typeof window !== "undefined" && window.ethereum) { 10 | // If window.ethereum exists, create a custom transport using it 11 | transport = custom(window.ethereum); 12 | } else { 13 | return null; 14 | } 15 | 16 | // Declare a Wallet Client 17 | // This creates a wallet client using the Sepolia chain and the custom transport 18 | const walletClient = createWalletClient({ 19 | chain: sepolia, 20 | transport: transport, 21 | }); 22 | 23 | // Return the wallet client 24 | return walletClient; 25 | } 26 | 27 | export function ConnectPublicClient() { 28 | // Declare a Public Client 29 | // This creates a public client using the Sepolia chain and an HTTP transport 30 | const publicClient = createPublicClient({ 31 | chain: sepolia, 32 | transport: http("https://rpc.sepolia.org"), 33 | }); 34 | 35 | // Return the public client 36 | return publicClient; 37 | } 38 | -------------------------------------------------------------------------------- /dadjokes-onchain/frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | content: [ 3 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 4 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 5 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 6 | ], 7 | theme: { 8 | extend: { 9 | backgroundImage: { 10 | "person-background": `linear-gradient( 11 | to bottom, 12 | #FEFAF6 0%, 13 | #FEFAF6 40%, 14 | #8b4513 40%, 15 | #8b4513 45%, 16 | #DAC0A3 45%, 17 | #DAC0A3 100% 18 | )`, 19 | }, 20 | colors: { 21 | primaryDark: "#102C57", 22 | secondaryDark: "#DAC0A3", 23 | secondaryLight: "#EADBC8", 24 | primaryLight: "#FEFAF6", 25 | }, 26 | fontFamily: { 27 | sans: ['"Comic Neue"', "sans-serif"], 28 | }, 29 | }, 30 | }, 31 | plugins: [], 32 | }; 33 | export default config; 34 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/.gitattributes: -------------------------------------------------------------------------------- 1 | src/Vm.sol linguist-generated 2 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/.github/workflows/sync.yml: -------------------------------------------------------------------------------- 1 | name: Sync Release Branch 2 | 3 | on: 4 | release: 5 | types: 6 | - created 7 | 8 | jobs: 9 | sync-release-branch: 10 | runs-on: ubuntu-latest 11 | if: startsWith(github.event.release.tag_name, 'v1') 12 | steps: 13 | - name: Check out the repo 14 | uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | ref: v1 18 | 19 | - name: Configure Git 20 | run: | 21 | git config user.name github-actions[bot] 22 | git config user.email 41898282+github-actions[bot]@users.noreply.github.com 23 | 24 | - name: Sync Release Branch 25 | run: | 26 | git fetch --tags 27 | git checkout v1 28 | git reset --hard ${GITHUB_REF} 29 | git push --force 30 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | .vscode 4 | .idea 5 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright Contributors to Forge Standard Library 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE.R 26 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | fs_permissions = [{ access = "read-write", path = "./"}] 3 | 4 | [rpc_endpoints] 5 | # The RPC URLs are modified versions of the default for testing initialization. 6 | mainnet = "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX" # Different API key. 7 | optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. 8 | arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. 9 | needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" 10 | 11 | [fmt] 12 | # These are all the `forge fmt` defaults. 13 | line_length = 120 14 | tab_width = 4 15 | bracket_spacing = false 16 | int_types = 'long' 17 | multiline_func_header = 'attributes_first' 18 | quote_style = 'double' 19 | number_underscore = 'preserve' 20 | single_line_statement_blocks = 'preserve' 21 | ignore = ["src/console.sol", "src/console2.sol"] -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forge-std", 3 | "version": "1.7.6", 4 | "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", 5 | "homepage": "https://book.getfoundry.sh/forge/forge-std", 6 | "bugs": "https://github.com/foundry-rs/forge-std/issues", 7 | "license": "(Apache-2.0 OR MIT)", 8 | "author": "Contributors to Forge Standard Library", 9 | "files": [ 10 | "src/**/*" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/foundry-rs/forge-std.git" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/src/Script.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | // 💬 ABOUT 5 | // Forge Std's default Script. 6 | 7 | // 🧩 MODULES 8 | import {console} from "./console.sol"; 9 | import {console2} from "./console2.sol"; 10 | import {safeconsole} from "./safeconsole.sol"; 11 | import {StdChains} from "./StdChains.sol"; 12 | import {StdCheatsSafe} from "./StdCheats.sol"; 13 | import {stdJson} from "./StdJson.sol"; 14 | import {stdMath} from "./StdMath.sol"; 15 | import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; 16 | import {StdStyle} from "./StdStyle.sol"; 17 | import {StdUtils} from "./StdUtils.sol"; 18 | import {VmSafe} from "./Vm.sol"; 19 | 20 | // 📦 BOILERPLATE 21 | import {ScriptBase} from "./Base.sol"; 22 | 23 | // ⭐️ SCRIPT 24 | abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { 25 | // Note: IS_SCRIPT() must return true. 26 | bool public IS_SCRIPT = true; 27 | } 28 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/src/StdError.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test 3 | pragma solidity >=0.6.2 <0.9.0; 4 | 5 | library stdError { 6 | bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); 7 | bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); 8 | bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); 9 | bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); 10 | bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); 11 | bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); 12 | bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); 13 | bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); 14 | bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); 15 | } 16 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/src/StdMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | library stdMath { 5 | int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; 6 | 7 | function abs(int256 a) internal pure returns (uint256) { 8 | // Required or it will fail when `a = type(int256).min` 9 | if (a == INT256_MIN) { 10 | return 57896044618658097711785492504343953926634992332820282019728792003956564819968; 11 | } 12 | 13 | return uint256(a > 0 ? a : -a); 14 | } 15 | 16 | function delta(uint256 a, uint256 b) internal pure returns (uint256) { 17 | return a > b ? a - b : b - a; 18 | } 19 | 20 | function delta(int256 a, int256 b) internal pure returns (uint256) { 21 | // a and b are of the same sign 22 | // this works thanks to two's complement, the left-most bit is the sign bit 23 | if ((a ^ b) > -1) { 24 | return delta(abs(a), abs(b)); 25 | } 26 | 27 | // a and b are of opposite signs 28 | return abs(a) + abs(b); 29 | } 30 | 31 | function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { 32 | uint256 absDelta = delta(a, b); 33 | 34 | return absDelta * 1e18 / b; 35 | } 36 | 37 | function percentDelta(int256 a, int256 b) internal pure returns (uint256) { 38 | uint256 absDelta = delta(a, b); 39 | uint256 absB = abs(b); 40 | 41 | return absDelta * 1e18 / absB; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/src/Test.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | // 💬 ABOUT 7 | // Forge Std's default Test. 8 | 9 | // 🧩 MODULES 10 | import {console} from "./console.sol"; 11 | import {console2} from "./console2.sol"; 12 | import {safeconsole} from "./safeconsole.sol"; 13 | import {StdAssertions} from "./StdAssertions.sol"; 14 | import {StdChains} from "./StdChains.sol"; 15 | import {StdCheats} from "./StdCheats.sol"; 16 | import {stdError} from "./StdError.sol"; 17 | import {StdInvariant} from "./StdInvariant.sol"; 18 | import {stdJson} from "./StdJson.sol"; 19 | import {stdMath} from "./StdMath.sol"; 20 | import {StdStorage, stdStorage} from "./StdStorage.sol"; 21 | import {StdStyle} from "./StdStyle.sol"; 22 | import {stdToml} from "./StdToml.sol"; 23 | import {StdUtils} from "./StdUtils.sol"; 24 | import {Vm} from "./Vm.sol"; 25 | 26 | // 📦 BOILERPLATE 27 | import {TestBase} from "./Base.sol"; 28 | 29 | // ⭐️ TEST 30 | abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { 31 | // Note: IS_TEST() must return true. 32 | bool public IS_TEST = true; 33 | } 34 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/src/interfaces/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2; 3 | 4 | interface IERC165 { 5 | /// @notice Query if a contract implements an interface 6 | /// @param interfaceID The interface identifier, as specified in ERC-165 7 | /// @dev Interface identification is specified in ERC-165. This function 8 | /// uses less than 30,000 gas. 9 | /// @return `true` if the contract implements `interfaceID` and 10 | /// `interfaceID` is not 0xffffffff, `false` otherwise 11 | function supportsInterface(bytes4 interfaceID) external view returns (bool); 12 | } 13 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/StdJson.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | import "../src/Test.sol"; 5 | 6 | contract StdJsonTest is Test { 7 | using stdJson for string; 8 | 9 | string root; 10 | string path; 11 | 12 | function setUp() public { 13 | root = vm.projectRoot(); 14 | path = string.concat(root, "/test/fixtures/test.json"); 15 | } 16 | 17 | struct SimpleJson { 18 | uint256 a; 19 | string b; 20 | } 21 | 22 | struct NestedJson { 23 | uint256 a; 24 | string b; 25 | SimpleJson c; 26 | } 27 | 28 | function test_readJson() public view { 29 | string memory json = vm.readFile(path); 30 | assertEq(json.readUint(".a"), 123); 31 | } 32 | 33 | function test_writeJson() public { 34 | string memory json = "json"; 35 | json.serialize("a", uint256(123)); 36 | string memory semiFinal = json.serialize("b", string("test")); 37 | string memory finalJson = json.serialize("c", semiFinal); 38 | finalJson.write(path); 39 | 40 | string memory json_ = vm.readFile(path); 41 | bytes memory data = json_.parseRaw("$"); 42 | NestedJson memory decodedData = abi.decode(data, (NestedJson)); 43 | 44 | assertEq(decodedData.a, 123); 45 | assertEq(decodedData.b, "test"); 46 | assertEq(decodedData.c.a, 123); 47 | assertEq(decodedData.c.b, "test"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/StdToml.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | import "../src/Test.sol"; 5 | 6 | contract StdTomlTest is Test { 7 | using stdToml for string; 8 | 9 | string root; 10 | string path; 11 | 12 | function setUp() public { 13 | root = vm.projectRoot(); 14 | path = string.concat(root, "/test/fixtures/test.toml"); 15 | } 16 | 17 | struct SimpleToml { 18 | uint256 a; 19 | string b; 20 | } 21 | 22 | struct NestedToml { 23 | uint256 a; 24 | string b; 25 | SimpleToml c; 26 | } 27 | 28 | function test_readToml() public view { 29 | string memory json = vm.readFile(path); 30 | assertEq(json.readUint(".a"), 123); 31 | } 32 | 33 | function test_writeToml() public { 34 | string memory json = "json"; 35 | json.serialize("a", uint256(123)); 36 | string memory semiFinal = json.serialize("b", string("test")); 37 | string memory finalJson = json.serialize("c", semiFinal); 38 | finalJson.write(path); 39 | 40 | string memory toml = vm.readFile(path); 41 | bytes memory data = toml.parseRaw("$"); 42 | NestedToml memory decodedData = abi.decode(data, (NestedToml)); 43 | 44 | assertEq(decodedData.a, 123); 45 | assertEq(decodedData.b, "test"); 46 | assertEq(decodedData.c.a, 123); 47 | assertEq(decodedData.c.b, "test"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/Vm.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | import {Test} from "../src/Test.sol"; 5 | import {Vm, VmSafe} from "../src/Vm.sol"; 6 | 7 | contract VmTest is Test { 8 | // This test ensures that functions are never accidentally removed from a Vm interface, or 9 | // inadvertently moved between Vm and VmSafe. This test must be updated each time a function is 10 | // added to or removed from Vm or VmSafe. 11 | function test_interfaceId() public pure { 12 | assertEq(type(VmSafe).interfaceId, bytes4(0xce9c7617), "VmSafe"); 13 | assertEq(type(Vm).interfaceId, bytes4(0xaf68a970), "Vm"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/compilation/CompilationScript.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../../src/Script.sol"; 7 | 8 | // The purpose of this contract is to benchmark compilation time to avoid accidentally introducing 9 | // a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 10 | contract CompilationScript is Script {} 11 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/compilation/CompilationScriptBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../../src/Script.sol"; 7 | 8 | // The purpose of this contract is to benchmark compilation time to avoid accidentally introducing 9 | // a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 10 | contract CompilationScriptBase is ScriptBase {} 11 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/compilation/CompilationTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../../src/Test.sol"; 7 | 8 | // The purpose of this contract is to benchmark compilation time to avoid accidentally introducing 9 | // a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 10 | contract CompilationTest is Test {} 11 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/compilation/CompilationTestBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.2 <0.9.0; 3 | 4 | pragma experimental ABIEncoderV2; 5 | 6 | import "../../src/Test.sol"; 7 | 8 | // The purpose of this contract is to benchmark compilation time to avoid accidentally introducing 9 | // a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 10 | contract CompilationTestBase is TestBase {} 11 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/fixtures/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 123, 3 | "b": "test", 4 | "c": { 5 | "a": 123, 6 | "b": "test" 7 | } 8 | } -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/lib/forge-std/test/fixtures/test.toml: -------------------------------------------------------------------------------- 1 | a = 123 2 | b = "test" 3 | 4 | [c] 5 | a = 123 6 | b = "test" 7 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/remappings.txt: -------------------------------------------------------------------------------- 1 | forge-std/=lib/forge-std/src/ 2 | -------------------------------------------------------------------------------- /dadjokes-onchain/smartcontract/script/DadJokes.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "forge-std/Script.sol"; 5 | import "../src/DadJokes.sol"; 6 | 7 | contract DeployDadJokes is Script { 8 | function run() public { 9 | // Start broadcasting transactions 10 | vm.startBroadcast(); 11 | 12 | // Deploy the DadJokes contract 13 | DadJokes dadJokes = new DadJokes(); 14 | 15 | // Print the address of the deployed contract 16 | console.log("DadJokes contract deployed at:", address(dadJokes)); 17 | 18 | // Stop broadcasting transactions 19 | vm.stopBroadcast(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/.env.example: -------------------------------------------------------------------------------- 1 | export PRIVATE_KEY_NILE=0000000000000000000000000000000000000000000000000000000000000001 2 | -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | build -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.22 <0.9.0; 3 | 4 | contract Migrations { 5 | address public owner = msg.sender; 6 | uint public last_completed_migration; 7 | 8 | modifier restricted() { 9 | require(msg.sender == owner, "This function is restricted to the contract's owner"); 10 | _; 11 | } 12 | 13 | function setCompleted(uint completed) public restricted { 14 | last_completed_migration = completed; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require('./Migrations.sol'); 2 | 3 | module.exports = function (deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | const DataFeedReader = artifacts.require("./DataFeedReader.sol"); 2 | 3 | module.exports = function (deployer) { 4 | deployer.deploy(DataFeedReader); 5 | }; 6 | -------------------------------------------------------------------------------- /data-feeds/tron/getting-started/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@chainlink/contracts": "^1.4.0", 4 | "dotenv": "^16.5.0", 5 | "tronweb": "^6.0.3" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .env.enc 4 | /build 5 | 6 | # Hardhat files 7 | /cache 8 | /artifacts 9 | 10 | # TypeChain files 11 | /typechain 12 | /typechain-types 13 | 14 | # solidity-coverage files 15 | /coverage 16 | /coverage.json -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.npmignore: -------------------------------------------------------------------------------- 1 | hardhat.config.js 2 | scripts 3 | test 4 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage* 5 | gasReporterOutput.json 6 | img 7 | .env 8 | .* 9 | README.md 10 | coverage.json 11 | deployments -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "semi": false, 5 | "singleQuote": false, 6 | "printWidth": 100, 7 | "overrides": [ 8 | { 9 | "files": "*.sol", 10 | "options": { 11 | "printWidth": 80, 12 | "tabWidth": 4, 13 | "useTabs": false, 14 | "singleQuote": false, 15 | "bracketSpacing": false, 16 | "explicitTypes": "always" 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "compiler-version": ["warn", "^0.8.19"], 5 | "func-visibility": ["warn", { "ignoreConstructors": true }] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/contracts/LogEmitter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.19; 3 | 4 | /** 5 | * @title Log Emitter Contract 6 | * @dev This contract is designed to emit an event whenever the `emitLog` function is called. 7 | */ 8 | contract LogEmitter { 9 | // Define an event that logs the address of the sender who triggered the event. 10 | event Log(address indexed msgSender); 11 | 12 | /** 13 | * @dev Emits a `Log` event with the sender's address. 14 | */ 15 | function emitLog() public { 16 | emit Log(msg.sender); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@chainlink/env-enc").config() 2 | require("@nomicfoundation/hardhat-toolbox") 3 | require("./tasks") 4 | 5 | // Set EVM private keys (required) 6 | const PRIVATE_KEY = process.env.PRIVATE_KEY 7 | 8 | const COMPILER_SETTINGS = { 9 | optimizer: { 10 | enabled: true, 11 | runs: 1000000, 12 | }, 13 | metadata: { 14 | bytecodeHash: "none", 15 | }, 16 | } 17 | 18 | module.exports = { 19 | solidity: { 20 | compilers: [ 21 | { 22 | version: "0.8.19", 23 | settings: COMPILER_SETTINGS, 24 | }, 25 | ], 26 | }, 27 | networks: { 28 | arbitrumSepolia: { 29 | url: process.env.ARBITRUM_SEPOLIA_RPC_URL || "UNSET", 30 | accounts: [PRIVATE_KEY], 31 | chainId: 421614, 32 | }, 33 | }, 34 | paths: { 35 | sources: "./contracts", 36 | cache: "./build/cache", 37 | artifacts: "./build/artifacts", 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/helper-hardhat-config.js: -------------------------------------------------------------------------------- 1 | const networkConfig = { 2 | 421614: { 3 | name: "arbitrumSepolia", 4 | linkToken: "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E", 5 | verifierProxyAddress: "0x2ff010DEbC1297f19579B4246cad07bd24F2488A", 6 | automationRegistrarAddress: "0x881918E24290084409DaA91979A30e6f0dB52eBe", 7 | }, 8 | } 9 | 10 | module.exports = { 11 | networkConfig, 12 | } 13 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Getting Started with Data Streams", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "description": "A getting started guide for using Chainlink Data Streams", 6 | "scripts": { 7 | "compile": "hardhat compile", 8 | "deploy": "hardhat run scripts/deployment/main.js --network arbitrumSepolia", 9 | "lint": "npm run lint:contracts && npm run format:check", 10 | "lint:fix": "solhint 'contracts/**/*.sol' --fix", 11 | "lint:contracts": "solhint 'contracts/*.sol'", 12 | "lint:contracts:fix": "solhint 'contracts/**/*.sol' --fix", 13 | "format:check": "prettier --check .", 14 | "format:fix": "prettier --write ." 15 | }, 16 | "dependencies": { 17 | "@chainlink/contracts": "1.3.0", 18 | "@chainlink/env-enc": "^1.0.5", 19 | "@nomiclabs/hardhat-ethers": "^2.1.1", 20 | "@nomicfoundation/hardhat-toolbox": "^2.0.0", 21 | "ethers": "^5.7.2", 22 | "hardhat": "^2.20.1", 23 | "lint-staged": "^13.0.3", 24 | "ora": "5.4.1", 25 | "prettier": "^2.7.1", 26 | "prettier-plugin-solidity": "^1.0.0-beta.24", 27 | "solhint": "^3.3.7", 28 | "solhint-plugin-prettier": "^0.0.5" 29 | }, 30 | "lint-staged": { 31 | "*.{js,json,yml,yaml}": [ 32 | "prettier --write" 33 | ], 34 | "*.sol": [ 35 | "prettier --write", 36 | "solhint" 37 | ] 38 | }, 39 | "prettier": { 40 | "trailingComma": "es5", 41 | "tabWidth": 2, 42 | "semi": false, 43 | "singleQuote": false, 44 | "printWidth": 120 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/tasks/deployment/deployLogEmitter.js: -------------------------------------------------------------------------------- 1 | const utils = require("../utils") 2 | 3 | // Define a Hardhat task named "deployLogEmitter" to deploy the LogEmitter contract. 4 | task("deployLogEmitter", "Deploys the LogEmitter contract").setAction(async () => { 5 | // Set the log level to ignore non-error logs for cleaner output. 6 | ethers.utils.Logger.setLogLevel(ethers.utils.Logger.levels.ERROR) 7 | 8 | // Retrieve the deployer/signer account. 9 | const [deployer] = await ethers.getSigners() 10 | 11 | // Initialize the spinner 12 | const spinner = utils.spin() 13 | spinner.start(`Deploying the LogEmitter contract with the account: ${deployer.address}`) 14 | 15 | try { 16 | // Get the contract factory for the LogEmitter contract. 17 | const LogEmitter = await ethers.getContractFactory("LogEmitter") 18 | 19 | // Deploy the LogEmitter contract. 20 | const logEmitter = await LogEmitter.deploy() 21 | 22 | // Wait for the contract deployment transaction to be mined. 23 | await logEmitter.deployed() 24 | 25 | // Stop the spinner with a success message, including the deployed contract address. 26 | spinner.succeed(`LogEmitter deployed at: ${logEmitter.address}`) 27 | } catch (error) { 28 | // In case of error, stop the spinner with a failure message. 29 | spinner.fail("Failed to deploy LogEmitter contract.") 30 | throw error 31 | } 32 | }) 33 | 34 | module.exports = {} 35 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/tasks/deployment/main.js: -------------------------------------------------------------------------------- 1 | // Import the utils for spinner functionality 2 | const utils = require("../utils") 3 | 4 | // This script serves as the main entry point to deploy both the LogEmitter and StreamsUpkeepRegistrar contracts. 5 | task("deployAll", "Deploys both LogEmitter and StreamsUpkeepRegistrar contracts").setAction(async (_, { run }) => { 6 | const spinner = utils.spin() 7 | spinner.start("Starting deployment of LogEmitter and StreamsUpkeepRegistrar contracts...") 8 | 9 | try { 10 | // Compile the contracts before deployment 11 | spinner.info("Compiling contracts...") 12 | await run("compile") 13 | 14 | // Deploy the StreamsUpkeepRegistrar contract 15 | spinner.info("Deploying StreamsUpkeepRegistrar contract...") 16 | await run("deployStreamsUpkeepRegistrar") 17 | 18 | // Deploy the LogEmitter contract 19 | spinner.info("Deploying LogEmitter contract...") 20 | await run("deployLogEmitter") 21 | 22 | // All deployments completed 23 | spinner.succeed("All contracts deployed successfully.") 24 | } catch (error) { 25 | spinner.fail("Deployment failed.") 26 | console.error(error) 27 | throw error // Rethrow the error to ensure the task fails properly 28 | } 29 | }) 30 | 31 | module.exports = {} 32 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/tasks/index.js: -------------------------------------------------------------------------------- 1 | // This file serves as an aggregator for all Hardhat tasks defined in the project. 2 | // It imports each task script and exports them as named exports. 3 | // This organization facilitates easy inclusion of all tasks in the Hardhat environment 4 | // by requiring just this single file in the Hardhat configuration. 5 | 6 | // Import and export the task for transferring LINK tokens. 7 | exports.transferLink = require("./transfer-link.js") 8 | 9 | // Import and export the task for registering a log upkeep with Chainlink Automation. 10 | exports.registerAndFundLogUpkeep = require("./registerAndFundLogUpkeep.js") 11 | 12 | // Import and export the task for emitting a log from the LogEmitter contract. 13 | exports.emitLog = require("./emitLog.js") 14 | 15 | // Import and export the task for retrieving the last price updated in the StreamsUpkeep contract. 16 | exports.getLastRetrievedPrice = require("./getLastRetrievedPrice.js") 17 | 18 | // Import and export the task for deploying the LogEmitter contract. 19 | exports.deployLogEmitter = require("./deployment/deployLogEmitter.js") 20 | 21 | // Import and export the task for deploying the StreamsUpkeepRegistrar contract. 22 | exports.deployStreamsUpkeepRegistrar = require("./deployment/deployStreamsUpkeepRegistrar.js") 23 | 24 | // Import and export the main deployment task that launches other deployment tasks. 25 | exports.deployAll = require("./deployment/main.js") 26 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/tasks/utils/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("./spin.js"), 3 | } 4 | -------------------------------------------------------------------------------- /data-streams/getting-started/hardhat/tasks/utils/spin.js: -------------------------------------------------------------------------------- 1 | const ora = require("ora") 2 | 3 | function spin(config = {}) { 4 | const spinner = ora({ spinner: "dots2", ...config }) 5 | spinner.start() 6 | return spinner 7 | } 8 | 9 | module.exports = { 10 | spin, 11 | } 12 | -------------------------------------------------------------------------------- /data-streams/streams-direct/.gitignore: -------------------------------------------------------------------------------- 1 | **/go.sum 2 | **/go.mod -------------------------------------------------------------------------------- /data-streams/streams-direct/README.md: -------------------------------------------------------------------------------- 1 | # Using Data Streams with the Streams Direct implementation 2 | 3 | This folder contains **deprecated examples**. 4 | 5 | You can now follow [Data Streams SDK guides](https://docs.chain.link/data-streams/tutorials/streams-direct/) to learn how to use the [Streams Direct](https://docs.chain.link/data-streams#streams-direct-using-data-streams-with-your-own-bot) implementation. 6 | -------------------------------------------------------------------------------- /data-streams/streams-direct/api/go.mod: -------------------------------------------------------------------------------- 1 | module data-streams-direct 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/ethereum/go-ethereum v1.12.2 // Ethereum blockchain interaction library 7 | github.com/pkg/errors v0.9.1 // Library for handling errors 8 | github.com/smartcontractkit/chainlink/v2 v2.2.1-0.20230823171354-1ead9ee6f6bb // Chainlink core components library 9 | ) 10 | 11 | replace ( 12 | // Resolves version mismatch between cosmosSDK and hdevalence/ed25519consensus 13 | filippo.io/edwards25519 => filippo.io/edwards25519 v1.0.0-rc.1 14 | 15 | // Adds ARM support by updating CosmWasm to v1.2.4 16 | github.com/CosmWasm/wasmvm => github.com/CosmWasm/wasmvm v1.2.4 17 | 18 | //// Fix go mod tidy issue for ambiguous imports from go-ethereum 19 | //// See https://github.com/ugorji/go/issues/279 20 | github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.1 21 | 22 | // Aligns protobuf version with cosmos SDK requirements 23 | github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 24 | ) -------------------------------------------------------------------------------- /data-streams/streams-direct/websocket/go.mod: -------------------------------------------------------------------------------- 1 | module data-streams-direct-ws 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/ethereum/go-ethereum v1.12.2 // Ethereum blockchain interaction library 7 | github.com/gorilla/websocket v1.5.0 // Websocket library 8 | github.com/pkg/errors v0.9.1 // Library for handling errors 9 | github.com/smartcontractkit/chainlink/v2 v2.2.1-0.20230823171354-1ead9ee6f6bb // Chainlink core components library 10 | ) 11 | 12 | replace ( 13 | // Resolves version mismatch between cosmosSDK and hdevalence/ed25519consensus 14 | filippo.io/edwards25519 => filippo.io/edwards25519 v1.0.0-rc.1 15 | 16 | // Adds ARM support by updating CosmWasm to v1.2.4 17 | github.com/CosmWasm/wasmvm => github.com/CosmWasm/wasmvm v1.2.4 18 | 19 | //// Fix go mod tidy issue for ambiguous imports from go-ethereum 20 | //// See https://github.com/ugorji/go/issues/279 21 | github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.1 22 | 23 | // Aligns protobuf version with cosmos SDK requirements 24 | github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 25 | ) -------------------------------------------------------------------------------- /data-streams/streams-direct/websocket/main.go: -------------------------------------------------------------------------------- 1 | // main.go 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | "data-streams-direct-ws/client" 8 | "log" 9 | "os" 10 | ) 11 | 12 | func main() { 13 | if len(os.Args) < 2 { 14 | log.Fatalf("Usage: %s ...", os.Args[0]) 15 | } 16 | 17 | feedIds := os.Args[1:] 18 | 19 | ctx := context.Background() 20 | 21 | // Pass feed IDs to the ConnectAndListen function 22 | if err := client.ConnectAndListen(ctx, feedIds); err != nil { 23 | log.Fatalf("Error connecting and listening: %v", err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /datafeeds-in-svelte/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "$lib": ["src/lib"], 6 | "$lib/*": ["src/lib/*"] 7 | } 8 | }, 9 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] 10 | } 11 | -------------------------------------------------------------------------------- /datafeeds-in-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "price-feed-demo", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview" 9 | }, 10 | "devDependencies": { 11 | "@sveltejs/adapter-auto": "next", 12 | "@sveltejs/kit": "next", 13 | "ethers": "^5.5.3", 14 | "svelte": "^3.44.0" 15 | }, 16 | "type": "module" 17 | } -------------------------------------------------------------------------------- /datafeeds-in-svelte/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %svelte.head% 9 | 10 | 11 |
%svelte.body%
12 | 13 | 14 | -------------------------------------------------------------------------------- /datafeeds-in-svelte/src/global.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /datafeeds-in-svelte/src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |

Current ETH Price in USD

11 |

12 | $ {(1 * value).toFixed(2)} USD 13 |

14 | -------------------------------------------------------------------------------- /datafeeds-in-svelte/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/datafeeds-in-svelte/static/favicon.png -------------------------------------------------------------------------------- /datafeeds-in-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | kit: { 6 | adapter: adapter(), 7 | 8 | // hydrate the
element in src/app.html 9 | target: '#svelte' 10 | } 11 | }; 12 | 13 | export default config; 14 | -------------------------------------------------------------------------------- /dynamic-nft/README.md: -------------------------------------------------------------------------------- 1 | # Dynamic NFTs 2 | This repo will support the [Creating Dynamic NFTs](https://www.youtube.com/watch?v=E7Rm1LUKhj4) tutorial. 3 | 4 | ## How to Use The Repo 5 | 6 | This repo consists of two files: 7 | - **1_starter.sol**: This is the starter file with the basic OpenZeppelin contract plus helper functions 8 | - **2_complete.sol**: the final contract for use with keepers 9 | 10 | Both versions of the contracts can be deployed as is via a tool like [Remix](https://remix.ethereum.org/). 11 | -------------------------------------------------------------------------------- /functions-examples/README.md: -------------------------------------------------------------------------------- 1 | # Chainlink Functions Examples 2 | 3 | This project is an example of a command-line interface (CLI) that uses the [functions-toolkit](https://github.com/smartcontractkit/functions-toolkit) to interact with Chainlink Functions. 4 | 5 | ## Installation 6 | 7 | To set up the project, follow these steps: 8 | 9 | 1. Clone the repository. 10 | ```bash 11 | git clone https://github.com/smartcontractkit/functions-example 12 | ``` 13 | 1. Clone the repository. 14 | ```bash 15 | cd functions-example 16 | ``` 17 | 1. Install the required dependencies. 18 | 19 | ```bash 20 | npm install 21 | ``` 22 | 23 | 1. We use [@chainlink/env-enc](https://www.npmjs.com/package/@chainlink/env-enc) package to encrypt environment variables at rest. Set the password to encrypt and decrypt the environment varilable file `.env.enc`: 24 | 25 | ```bash 26 | npx env-enc set-pw 27 | ``` 28 | 29 | 1. Set the following variables: 30 | 31 | - PRIVATE_KEY 32 | - ETHEREUM_SEPOLIA_RPC_URL 33 | -------------------------------------------------------------------------------- /functions-examples/examples/1-simple-computation/source.js: -------------------------------------------------------------------------------- 1 | // calculate geometric mean off-chain by a DON then return the result 2 | // valures provided in args array 3 | 4 | console.log(`calculate geometric mean of ${args}`); 5 | 6 | // make sure arguments are provided 7 | if (!args || args.length === 0) throw new Error("input not provided"); 8 | 9 | const product = args.reduce((accumulator, currentValue) => { 10 | const numValue = parseInt(currentValue); 11 | if (isNaN(numValue)) throw Error(`${currentValue} is not a number`); 12 | return accumulator * numValue; 13 | }, 1); // calculate the product of numbers provided in args array 14 | 15 | const geometricMean = Math.pow(product, 1 / args.length); // geometric mean = length-root of (product) 16 | console.log(`geometric mean is: ${geometricMean.toFixed(2)}`); 17 | 18 | // Decimals are not handled in Solidity so multiply by 100 (for 2 decimals) and round to the nearest integer 19 | // Functions.encodeUint256: Return a buffer from uint256 20 | return Functions.encodeUint256(Math.round(geometricMean * 100)); 21 | -------------------------------------------------------------------------------- /functions-examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions-examples", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@chainlink/env-enc": "^1.0.5", 13 | "@chainlink/functions-toolkit": "^0.2.7", 14 | "ethers": "^5.7.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lottery/.env.example: -------------------------------------------------------------------------------- 1 | KOVAN_RPC_URL='https://kovan.infura.io/v3/1234567890' 2 | RINKEBY_RPC_URL='https://alchemy.infura.io/v3/1234567890' 3 | POLYGON_MAINNET_RPC_URL='https://rpc-mainnet.maticvigil.com' 4 | PRIVATE_KEY='abcdefg' 5 | ALCHEMY_MAINNET_RPC_URL="https://eth-mainnet.alchemyapi.io/v2/your-api-key" 6 | REPORT_GAS=true 7 | COINMARKETCAP_API_KEY="YOUR_KEY" 8 | AUTO_FUND=true 9 | -------------------------------------------------------------------------------- /lottery/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /lottery/.npmignore: -------------------------------------------------------------------------------- 1 | hardhat.config.js 2 | scripts 3 | test 4 | -------------------------------------------------------------------------------- /lottery/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage* 5 | gasReporterOutput.json 6 | package.json 7 | img 8 | .env 9 | .* 10 | README.md 11 | coverage.json 12 | deployments -------------------------------------------------------------------------------- /lottery/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "semi": false, 5 | "singleQuote": false, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /lottery/.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "compiler-version": ["error", "^0.8.0"], 5 | "func-visibility": ["warn", { "ignoreConstructors": true }] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lottery/.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | contracts/test -------------------------------------------------------------------------------- /lottery/contracts/test/VRFCoordinatorV2Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@chainlink/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol"; -------------------------------------------------------------------------------- /lottery/deploy/00-deploy-mocks.ts: -------------------------------------------------------------------------------- 1 | import { DeployFunction } from "hardhat-deploy/types" 2 | import { HardhatRuntimeEnvironment } from "hardhat/types" 3 | 4 | const BASE_FEE = "250000000000000000" // 0.25 is this the premium in LINK? 5 | const GAS_PRICE_LINK = 1e9 // link per gas, is this the gas lane? // 0.000000001 LINK per gas 6 | 7 | const deployMocks: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 8 | const { deployments, getNamedAccounts, network } = hre 9 | const { deploy, log } = deployments 10 | const { deployer } = await getNamedAccounts() 11 | const chainId = network.config.chainId 12 | // If we are on a local development network, we need to deploy mocks! 13 | if (chainId == 31337) { 14 | log("Local network detected! Deploying mocks...") 15 | await deploy("VRFCoordinatorV2Mock", { 16 | from: deployer, 17 | log: true, 18 | args: [BASE_FEE, GAS_PRICE_LINK], 19 | }) 20 | 21 | log("Mocks Deployed!") 22 | log("----------------------------------") 23 | 24 | log("You are deploying to a local network, you'll need a local network running to interact") 25 | log( 26 | "Please run `yarn hardhat console --network localhost` to interact with the deployed smart contracts!" 27 | ) 28 | log("----------------------------------") 29 | } 30 | } 31 | export default deployMocks 32 | deployMocks.tags = ["all", "mocks"] 33 | -------------------------------------------------------------------------------- /lottery/deploy/02-update-front-end.ts: -------------------------------------------------------------------------------- 1 | import { frontEndContractsFile } from "../helper-hardhat-config" 2 | import fs from "fs" 3 | import { DeployFunction } from "hardhat-deploy/types" 4 | import { HardhatRuntimeEnvironment } from "hardhat/types" 5 | 6 | const updateUI: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 7 | const { network, ethers } = hre 8 | const chainId = "31337" 9 | 10 | if (process.env.UPDATE_FRONT_END) { 11 | console.log("Writing to front end...") 12 | const fundMe = await ethers.getContract("Raffle") 13 | const contractAddresses = JSON.parse(fs.readFileSync(frontEndContractsFile, "utf8")) 14 | if (chainId in contractAddresses) { 15 | if (!contractAddresses[network.config.chainId!].includes(fundMe.address)) { 16 | contractAddresses[network.config.chainId!].push(fundMe.address) 17 | } 18 | } else { 19 | contractAddresses[network.config.chainId!] = [fundMe.address] 20 | } 21 | fs.writeFileSync(frontEndContractsFile, JSON.stringify(contractAddresses)) 22 | console.log("Front end written!") 23 | } 24 | } 25 | export default updateUI 26 | updateUI.tags = ["all", "frontend"] 27 | -------------------------------------------------------------------------------- /lottery/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-smartcontract-lottery-fcc", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "yarn hardhat test", 7 | "test-staging": "yarn hardhat test --network rinkeby", 8 | "lint": "yarn solhint 'contracts/*.sol'", 9 | "lint:fix": "yarn solhint 'contracts/**/*.sol' --fix", 10 | "format": "yarn prettier --write .", 11 | "coverage": "yarn hardhat coverage", 12 | "typechain": "yarn hardhat typechain" 13 | }, 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@chainlink/contracts": "^0.4.0", 17 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", 18 | "@nomiclabs/hardhat-etherscan": "^3.0.0", 19 | "@nomiclabs/hardhat-waffle": "^2.0.1", 20 | "@openzeppelin/contracts": "^4.5.0", 21 | "@types/chai": "^4.3.0", 22 | "@types/mocha": "^9.1.0", 23 | "@types/node": "^17.0.13", 24 | "babel-eslint": "^10.1.0", 25 | "chai": "^4.3.4", 26 | "dotenv": "^14.2.0", 27 | "ethereum-waffle": "^3.4.0", 28 | "ethers": "^5.5.1", 29 | "hardhat": "^2.6.7", 30 | "hardhat-contract-sizer": "^2.4.0", 31 | "hardhat-deploy": "^0.9.29", 32 | "hardhat-deploy-ethers": "^0.3.0-beta.13", 33 | "hardhat-gas-reporter": "^1.0.7", 34 | "prettier": "^2.4.1", 35 | "prettier-plugin-solidity": "^1.0.0-beta.19", 36 | "solhint": "^3.3.6", 37 | "solidity-coverage": "^0.7.13", 38 | "ts-node": "^10.4.0", 39 | "typechain": "^8.0.0", 40 | "typescript": "^4.5.5", 41 | "@typechain/ethers-v5": "^10.0.0", 42 | "@typechain/hardhat": "^6.0.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lottery/scripts/charity-raffle-scripts/enterCharityRaffle.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { ethers } from "hardhat" 3 | import { CharityRaffle } from "../../typechain-types" 4 | 5 | async function enterCharityRaffle(): Promise { 6 | const charityRaffle: CharityRaffle = await ethers.getContract("CharityRaffle") 7 | const entranceFee: number = (await charityRaffle.getEntranceFee()).toNumber() 8 | await charityRaffle.enterRaffle(0, { value: entranceFee + 1 }) 9 | console.log("Entered Charity Raffle!") 10 | } 11 | 12 | enterCharityRaffle() 13 | .then(() => process.exit(0)) 14 | .catch((error) => { 15 | console.error(error) 16 | process.exit(1) 17 | }) 18 | -------------------------------------------------------------------------------- /lottery/scripts/enterRaffle.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { ethers } from "hardhat" 3 | import { Raffle } from '../typechain-types' 4 | 5 | async function enterRaffle():Promise { 6 | const raffle: Raffle = await ethers.getContract("Raffle") 7 | const entranceFee: number = (await raffle.getEntranceFee()).toNumber() 8 | await raffle.enterRaffle({ value: entranceFee + 1 }) 9 | console.log("Entered!") 10 | } 11 | 12 | enterRaffle() 13 | .then(() => process.exit(0)) 14 | .catch((error) => { 15 | console.error(error) 16 | process.exit(1) 17 | }) 18 | -------------------------------------------------------------------------------- /lottery/scripts/mockOffchain.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { ethers, network } from "hardhat" 3 | import { Raffle } from "../typechain-types" 4 | import { BigNumber } from "ethers" 5 | 6 | async function mockKeepers() { 7 | const raffle: Raffle = await ethers.getContract("Raffle") 8 | const checkData = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("")) 9 | const { upkeepNeeded } = await raffle.callStatic.checkUpkeep(checkData) 10 | if (upkeepNeeded) { 11 | const tx = await raffle.performUpkeep(checkData) 12 | const txReceipt = await tx.wait(1) 13 | const requestId: BigNumber = txReceipt.events[1].args.requestId 14 | console.log(`Performed upkeep with RequestId: ${requestId}`) 15 | if (network.config.chainId == 31337) { 16 | await mockVrf(requestId, raffle) 17 | } 18 | } else { 19 | console.log("No upkeep needed!") 20 | } 21 | } 22 | 23 | async function mockVrf(requestId: BigNumber, raffle: Raffle) { 24 | console.log("We on a local network? Ok let's pretend...") 25 | const vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock") 26 | await vrfCoordinatorV2Mock.fulfillRandomWords(requestId, raffle.address) 27 | console.log("Responded!") 28 | const recentWinner = await raffle.getRecentWinner() 29 | console.log(`The winner is: ${recentWinner}`) 30 | } 31 | 32 | mockKeepers() 33 | .then(() => process.exit(0)) 34 | .catch((error) => { 35 | console.error(error) 36 | process.exit(1) 37 | }) 38 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as src from "./src"; 5 | export type { src }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as src from "./src"; 5 | export type { src }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as v08 from "./v0.8"; 5 | export type { v08 }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as v08 from "./v0.8"; 5 | export type { v08 }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as interfaces from "./interfaces"; 5 | export type { interfaces }; 6 | import type * as mocks from "./mocks"; 7 | export type { mocks }; 8 | export type { VRFConsumerBaseV2 } from "./VRFConsumerBaseV2"; 9 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as interfaces from "./interfaces"; 5 | export type { interfaces }; 6 | import type * as mocks from "./mocks"; 7 | export type { mocks }; 8 | export type { VRFConsumerBaseV2 } from "./VRFConsumerBaseV2"; 9 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/interfaces/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { KeeperCompatibleInterface } from "./KeeperCompatibleInterface"; 5 | export type { LinkTokenInterface } from "./LinkTokenInterface"; 6 | export type { VRFCoordinatorV2Interface } from "./VRFCoordinatorV2Interface"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { KeeperCompatibleInterface } from "./KeeperCompatibleInterface"; 5 | export type { LinkTokenInterface } from "./LinkTokenInterface"; 6 | export type { VRFCoordinatorV2Interface } from "./VRFCoordinatorV2Interface"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/mocks/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { VRFCoordinatorV2Mock } from "./VRFCoordinatorV2Mock"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/contracts/src/v0.8/mocks/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { VRFCoordinatorV2Mock } from "./VRFCoordinatorV2Mock"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as contracts from "./contracts"; 5 | export type { contracts }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/@chainlink/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type * as contracts from "./contracts"; 5 | export type { contracts }; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/common 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { Listener } from "@ethersproject/providers"; 5 | import type { Event, EventFilter } from "ethers"; 6 | 7 | export interface TypedEvent< 8 | TArgsArray extends Array = any, 9 | TArgsObject = any 10 | > extends Event { 11 | args: TArgsArray & TArgsObject; 12 | } 13 | 14 | export interface TypedEventFilter<_TEvent extends TypedEvent> 15 | extends EventFilter {} 16 | 17 | export interface TypedListener { 18 | (...listenerArg: [...__TypechainArgsArray, TEvent]): void; 19 | } 20 | 21 | type __TypechainArgsArray = T extends TypedEvent ? U : never; 22 | 23 | export interface OnEvent { 24 | ( 25 | eventFilter: TypedEventFilter, 26 | listener: TypedListener 27 | ): TRes; 28 | (eventName: string, listener: Listener): TRes; 29 | } 30 | 31 | export type MinEthersFactory = { 32 | deploy(...a: ARGS[]): Promise; 33 | }; 34 | 35 | export type GetContractTypeFromFactory = F extends MinEthersFactory< 36 | infer C, 37 | any 38 | > 39 | ? C 40 | : never; 41 | 42 | export type GetARGsTypeFromFactory = F extends MinEthersFactory 43 | ? Parameters 44 | : never; 45 | -------------------------------------------------------------------------------- /lottery/typechain-types/common.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { Listener } from "@ethersproject/providers"; 5 | import type { Event, EventFilter } from "ethers"; 6 | 7 | export interface TypedEvent< 8 | TArgsArray extends Array = any, 9 | TArgsObject = any 10 | > extends Event { 11 | args: TArgsArray & TArgsObject; 12 | } 13 | 14 | export interface TypedEventFilter<_TEvent extends TypedEvent> 15 | extends EventFilter {} 16 | 17 | export interface TypedListener { 18 | (...listenerArg: [...__TypechainArgsArray, TEvent]): void; 19 | } 20 | 21 | type __TypechainArgsArray = T extends TypedEvent ? U : never; 22 | 23 | export interface OnEvent { 24 | ( 25 | eventFilter: TypedEventFilter, 26 | listener: TypedListener 27 | ): TRes; 28 | (eventName: string, listener: Listener): TRes; 29 | } 30 | 31 | export type MinEthersFactory = { 32 | deploy(...a: ARGS[]): Promise; 33 | }; 34 | 35 | export type GetContractTypeFromFactory = F extends MinEthersFactory< 36 | infer C, 37 | any 38 | > 39 | ? C 40 | : never; 41 | 42 | export type GetARGsTypeFromFactory = F extends MinEthersFactory 43 | ? Parameters 44 | : never; 45 | -------------------------------------------------------------------------------- /lottery/typechain-types/contracts/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { CharityRaffle } from "./CharityRaffle"; 5 | export type { Raffle } from "./Raffle"; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/contracts/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export type { CharityRaffle } from "./CharityRaffle"; 5 | export type { Raffle } from "./Raffle"; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as src from "./src"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as src from "./src"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as v08 from "./v0.8"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as v08 from "./v0.8"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as interfaces from "./interfaces"; 5 | export * as mocks from "./mocks"; 6 | export { VRFConsumerBaseV2__factory } from "./VRFConsumerBaseV2__factory"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as interfaces from "./interfaces"; 5 | export * as mocks from "./mocks"; 6 | export { VRFConsumerBaseV2__factory } from "./VRFConsumerBaseV2__factory"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/interfaces/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { KeeperCompatibleInterface__factory } from "./KeeperCompatibleInterface__factory"; 5 | export { LinkTokenInterface__factory } from "./LinkTokenInterface__factory"; 6 | export { VRFCoordinatorV2Interface__factory } from "./VRFCoordinatorV2Interface__factory"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { KeeperCompatibleInterface__factory } from "./KeeperCompatibleInterface__factory"; 5 | export { LinkTokenInterface__factory } from "./LinkTokenInterface__factory"; 6 | export { VRFCoordinatorV2Interface__factory } from "./VRFCoordinatorV2Interface__factory"; 7 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/mocks/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { VRFCoordinatorV2Mock__factory } from "./VRFCoordinatorV2Mock__factory"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/contracts/src/v0.8/mocks/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { VRFCoordinatorV2Mock__factory } from "./VRFCoordinatorV2Mock__factory"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as contracts from "./contracts"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/@chainlink/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as contracts from "./contracts"; 5 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/contracts/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { CharityRaffle__factory } from "./CharityRaffle__factory"; 5 | export { Raffle__factory } from "./Raffle__factory"; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/contracts/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export { CharityRaffle__factory } from "./CharityRaffle__factory"; 5 | export { Raffle__factory } from "./Raffle__factory"; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/index 2.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as chainlink from "./@chainlink"; 5 | export * as contracts from "./contracts"; 6 | -------------------------------------------------------------------------------- /lottery/typechain-types/factories/index.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | export * as chainlink from "./@chainlink"; 5 | export * as contracts from "./contracts"; 6 | -------------------------------------------------------------------------------- /lottery/utils/verify.ts: -------------------------------------------------------------------------------- 1 | import { run } from "hardhat" 2 | 3 | const verify = async (contractAddress: string, args: any[]) => { 4 | console.log("Verifying contract...") 5 | try { 6 | await run("verify:verify", { 7 | address: contractAddress, 8 | constructorArguments: args, 9 | }) 10 | } catch (e: any) { 11 | if (e.message.toLowerCase().includes("already verified")) { 12 | console.log("Already verified!") 13 | } else { 14 | console.log(e) 15 | } 16 | } 17 | } 18 | 19 | export default verify 20 | -------------------------------------------------------------------------------- /my-crypto-coin/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode -------------------------------------------------------------------------------- /my-crypto-coin/cli/mcc/balances.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "my-crypto-coin/ledger" 6 | "fmt" 7 | "os" 8 | ) 9 | 10 | func balancesCmd() *cobra.Command { 11 | var balancesCmd = &cobra.Command{ 12 | Use: "balances", 13 | Short: "Interact with balances (list...).", 14 | Run: func(cmd *cobra.Command, args []string) { 15 | }, 16 | } 17 | 18 | balancesCmd.AddCommand(balancesListCmd) 19 | 20 | return balancesCmd 21 | } 22 | 23 | var balancesListCmd = &cobra.Command{ 24 | Use: "list", 25 | Short: "Lists all balances.", 26 | Run: func(cmd *cobra.Command, args []string) { 27 | state, err := ledger.SyncState() 28 | if err != nil { 29 | fmt.Fprintln(os.Stderr, err) 30 | os.Exit(1) 31 | } 32 | defer state.Close() 33 | 34 | fmt.Println("Accounts balances:") 35 | fmt.Println("__________________") 36 | fmt.Println("") 37 | for account, balance := range state.Balances { 38 | fmt.Println(fmt.Sprintf("%s: %d", account, balance)) 39 | } 40 | }, 41 | } -------------------------------------------------------------------------------- /my-crypto-coin/cli/mcc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "os" 6 | "fmt" 7 | ) 8 | 9 | func main() { 10 | var mccCmd = &cobra.Command{ 11 | Use: "mcc", 12 | Short: "My Crypto Coin CLI", 13 | Run: func(cmd *cobra.Command, args []string) { 14 | }, 15 | } 16 | 17 | mccCmd.AddCommand(versionCmd) 18 | mccCmd.AddCommand(balancesCmd()) 19 | mccCmd.AddCommand(txCmd()) 20 | 21 | err := mccCmd.Execute() 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | os.Exit(1) 25 | } 26 | } -------------------------------------------------------------------------------- /my-crypto-coin/cli/mcc/tx.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "my-crypto-coin/ledger" 6 | "fmt" 7 | "os" 8 | ) 9 | 10 | func txCmd() *cobra.Command { 11 | var txsCmd = &cobra.Command{ 12 | Use: "tx", 13 | Short: "Interact with transactions (new...).", 14 | Run: func(cmd *cobra.Command, args []string) { 15 | }, 16 | } 17 | 18 | txsCmd.AddCommand(newTxCmd()) 19 | 20 | return txsCmd 21 | } 22 | 23 | 24 | func newTxCmd() *cobra.Command { 25 | var cmd = &cobra.Command{ 26 | Use: "new", 27 | Short: "Adds new TX to the ledger.", 28 | Run: func(cmd *cobra.Command, args []string) { 29 | from, _ := cmd.Flags().GetString("from") 30 | to, _ := cmd.Flags().GetString("to") 31 | value, _ := cmd.Flags().GetUint("value") 32 | 33 | tx := ledger.NewTx(ledger.NewAccount(from), ledger.NewAccount(to), value) 34 | 35 | state, err := ledger.SyncState() 36 | if err != nil { 37 | fmt.Fprintln(os.Stderr, err) 38 | os.Exit(1) 39 | } 40 | defer state.Close() 41 | 42 | err = state.WriteToLedger(tx) 43 | if err != nil { 44 | fmt.Fprintln(os.Stderr, err) 45 | os.Exit(1) 46 | } 47 | 48 | fmt.Println("TX successfully added to the ledger.") 49 | }, 50 | } 51 | 52 | cmd.Flags().String("from", "", "From what account to send coins") 53 | cmd.MarkFlagRequired("from") 54 | 55 | cmd.Flags().String("to", "", "To what account to send coins") 56 | cmd.MarkFlagRequired("to") 57 | 58 | cmd.Flags().Uint("value", 0, "How many coins to send") 59 | cmd.MarkFlagRequired("value") 60 | 61 | return cmd 62 | } -------------------------------------------------------------------------------- /my-crypto-coin/cli/mcc/version.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | const Major = "0" 9 | const Minor = "1" 10 | const Fix = "0" 11 | const Verbal = "Genesis" 12 | 13 | var versionCmd = &cobra.Command{ 14 | Use: "version", 15 | Short: "Describes version.", 16 | Run: func(cmd *cobra.Command, args []string) { 17 | fmt.Println(fmt.Sprintf("Version: %s.%s.%s-beta %s", Major, Minor, Fix, Verbal)) 18 | }, 19 | } -------------------------------------------------------------------------------- /my-crypto-coin/go.mod: -------------------------------------------------------------------------------- 1 | module my-crypto-coin 2 | 3 | go 1.16 4 | 5 | require github.com/spf13/cobra v1.4.0 // indirect 6 | -------------------------------------------------------------------------------- /my-crypto-coin/go.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 2 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 3 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 4 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 5 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 6 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 7 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 8 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 10 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 11 | -------------------------------------------------------------------------------- /my-crypto-coin/ledger/genesis.go: -------------------------------------------------------------------------------- 1 | package ledger 2 | 3 | import ( 4 | "io/ioutil" 5 | "encoding/json" 6 | ) 7 | 8 | type Genesis struct { 9 | Balances map[Account]uint `json:"balances"` 10 | } 11 | 12 | func loadGenesis(path string) (Genesis, error) { 13 | genesisFileContent, err := ioutil.ReadFile(path) 14 | if err != nil { 15 | return Genesis{}, err 16 | } 17 | 18 | var loadedGenesis Genesis 19 | 20 | err = json.Unmarshal(genesisFileContent, &loadedGenesis) 21 | if err != nil { 22 | return Genesis{}, err 23 | } 24 | 25 | return loadedGenesis, nil 26 | } -------------------------------------------------------------------------------- /my-crypto-coin/ledger/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "genesis_time": "2022-04-12T00:00:00.000000000Z", 3 | "chain_id": "our-blockchain", 4 | "balances": { 5 | "alice": 1000000 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /my-crypto-coin/ledger/ledger.db: -------------------------------------------------------------------------------- 1 | {"from":"alice","to":"bob","value":10} 2 | {"from":"alice","to":"alice","value":3} 3 | {"from":"alice","to":"alice","value":500} 4 | {"from":"alice","to":"bob","value":100} 5 | {"from":"bob","to":"alice","value":5} 6 | {"from":"bob","to":"carol","value":10} 7 | {"from":"alice","to":"carol","value":10} 8 | -------------------------------------------------------------------------------- /my-crypto-coin/ledger/tx.go: -------------------------------------------------------------------------------- 1 | package ledger 2 | 3 | type Account string 4 | 5 | type Tx struct { 6 | From Account `json:"from"` 7 | To Account `json:"to"` 8 | Value uint `json:"value"` 9 | } 10 | 11 | func NewAccount(value string) Account { 12 | return Account(value) 13 | } 14 | 15 | func NewTx(from Account, to Account, value uint) Tx { 16 | return Tx{from, to, value} 17 | } 18 | -------------------------------------------------------------------------------- /my-crypto-wallet/02_restoreWallet.js: -------------------------------------------------------------------------------- 1 | const { mnemonicToEntropy } = require("ethereum-cryptography/bip39"); 2 | const { wordlist } = require("ethereum-cryptography/bip39/wordlists/english"); 3 | const { HDKey } = require("ethereum-cryptography/hdkey"); 4 | const { getPublicKey } = require("ethereum-cryptography/secp256k1"); 5 | const { keccak256 } = require("ethereum-cryptography/keccak"); 6 | const { bytesToHex } = require("ethereum-cryptography/utils"); 7 | const { writeFileSync } = require("fs"); 8 | 9 | async function main(_mnemonic) { 10 | const entropy = mnemonicToEntropy(_mnemonic, wordlist); 11 | const hdRootKey = HDKey.fromMasterSeed(entropy); 12 | const privateKey = hdRootKey.deriveChild(0).privateKey; 13 | const publicKey = getPublicKey(privateKey); 14 | const address = keccak256(publicKey).slice(-20); 15 | console.log(`Account One Wallet Address: 0x${bytesToHex(address)}`); 16 | 17 | const accountOne = { 18 | privateKey: privateKey, 19 | publicKey: publicKey, 20 | address: address, 21 | }; 22 | const accountOneData = JSON.stringify(accountOne); 23 | writeFileSync("account 1.json", accountOneData); 24 | } 25 | 26 | main(process.argv[2]) 27 | .then(() => process.exit(0)) 28 | .catch((error) => { 29 | console.error(error); 30 | process.exit(1); 31 | }); 32 | -------------------------------------------------------------------------------- /my-crypto-wallet/03_send.js: -------------------------------------------------------------------------------- 1 | const { getDefaultProvider, Wallet, utils } = require("ethers"); 2 | const { readFileSync } = require("fs"); 3 | 4 | async function main(_receiverAddress, _ethAmount) { 5 | const network = "goerli"; 6 | const provider = getDefaultProvider(network); 7 | 8 | const accountRawData = readFileSync("account 1.json", "utf8"); 9 | const accountData = JSON.parse(accountRawData); 10 | 11 | const privateKey = Object.values(accountData.privateKey); 12 | 13 | const signer = new Wallet(privateKey, provider); 14 | 15 | const transaction = await signer.sendTransaction({ 16 | to: _receiverAddress, 17 | value: utils.parseEther(_ethAmount), 18 | }); 19 | 20 | console.log(transaction); 21 | } 22 | 23 | main(process.argv[2], process.argv[3]) 24 | .then(() => process.exit(0)) 25 | .catch((error) => { 26 | console.error(error); 27 | process.exit(1); 28 | }); 29 | -------------------------------------------------------------------------------- /my-crypto-wallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-crypto-wallet", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "ethereum-cryptography": "^1.0.3", 8 | "ethers": "^5.6.8" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /pricefeed-golang/.env.example: -------------------------------------------------------------------------------- 1 | RPC_URL=REPLACE_BY_YOUR_RPC_URL 2 | DEFAULT_FEED_ADDR=REPLACE_BY_PRICE_FEED_PROXY_ADDR -------------------------------------------------------------------------------- /pricefeed-golang/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /pricefeed-golang/aggregatorv3/AggregatorV3Interface.abi: -------------------------------------------------------------------------------- 1 | [{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /pricefeed-golang/aggregatorv3/AggregatorV3Interface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface AggregatorV3Interface { 5 | function decimals() external view returns (uint8); 6 | 7 | function description() external view returns (string memory); 8 | 9 | function version() external view returns (uint256); 10 | 11 | // getRoundData and latestRoundData should both raise "No data present" 12 | // if they do not have data to report, instead of returning unset values 13 | // which could be misinterpreted as actual reported values. 14 | function getRoundData(uint80 _roundId) 15 | external 16 | view 17 | returns ( 18 | uint80 roundId, 19 | int256 answer, 20 | uint256 startedAt, 21 | uint256 updatedAt, 22 | uint80 answeredInRound 23 | ); 24 | 25 | function latestRoundData() 26 | external 27 | view 28 | returns ( 29 | uint80 roundId, 30 | int256 answer, 31 | uint256 startedAt, 32 | uint256 updatedAt, 33 | uint80 answeredInRound 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /pricefeed-golang/go.mod: -------------------------------------------------------------------------------- 1 | module chainlink-price-feed 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/ethereum/go-ethereum v1.10.17 7 | github.com/joho/godotenv v1.4.0 8 | ) 9 | 10 | require ( 11 | github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect 12 | github.com/btcsuite/btcd/btcec/v2 v2.1.2 // indirect 13 | github.com/deckarep/golang-set v1.8.0 // indirect 14 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect 15 | github.com/go-ole/go-ole v1.2.1 // indirect 16 | github.com/go-stack/stack v1.8.0 // indirect 17 | github.com/google/uuid v1.2.0 // indirect 18 | github.com/gorilla/websocket v1.4.2 // indirect 19 | github.com/rjeczalik/notify v0.9.1 // indirect 20 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect 21 | github.com/tklauser/go-sysconf v0.3.5 // indirect 22 | github.com/tklauser/numcpus v0.2.2 // indirect 23 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect 24 | golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 // indirect 25 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /quiz-game/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | .DS_Store 4 | node_modules 5 | /build 6 | /.svelte-kit 7 | /package 8 | .env 9 | .env.* 10 | !.env.example 11 | -------------------------------------------------------------------------------- /quiz-game/foundry/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | -------------------------------------------------------------------------------- /quiz-game/foundry/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Read the RPC URL 4 | echo Enter Your RPC URL: 5 | echo Example: "https://eth-goerli.alchemyapi.io/v2//XXXXXXXXXX" 6 | read -s rpc 7 | 8 | # Read the contract name 9 | echo Which contract do you want to deploy \(eg Greeter\)? 10 | read contract 11 | 12 | forge create ./src/${contract}.sol:${contract} -i --rpc-url $rpc -------------------------------------------------------------------------------- /quiz-game/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /quiz-game/foundry/src/QuizFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "./QuizGame.sol"; 5 | 6 | contract QuizFactory { 7 | QuizGame[] public quizzes; 8 | event QuizCreated(QuizGame indexed quiz); 9 | 10 | constructor() {} 11 | 12 | function createQuiz(string memory question, bytes32 answer) public { 13 | QuizGame quiz = new QuizGame(question, answer); 14 | quizzes.push(quiz); 15 | emit QuizCreated(quiz); 16 | } 17 | 18 | function getQuizzes() public view returns (QuizGame[] memory) { 19 | return quizzes; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /quiz-game/foundry/src/QuizGame.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | contract QuizGame { 5 | bytes32 public salt = bytes32("123123123"); 6 | bytes32 public hashedAnswer; 7 | string public question; 8 | event QuizFunded(uint256 amount); 9 | event AnswerGuessed(); 10 | 11 | constructor(string memory _question, bytes32 _hashedAnswer) { 12 | question = _question; 13 | hashedAnswer = _hashedAnswer; 14 | } 15 | 16 | function guess(string calldata answer) public { 17 | require(keccak256(abi.encodePacked(salt, answer)) == hashedAnswer); 18 | if (address(this).balance > 0) { 19 | emit AnswerGuessed(); 20 | (bool sent, bytes memory data) = payable(msg.sender).call{value: address(this).balance}(""); 21 | require(sent, "Failed to send"); 22 | } 23 | } 24 | 25 | fallback() external payable { 26 | emit QuizFunded(address(this).balance); 27 | } 28 | 29 | receive() external payable { 30 | emit QuizFunded(address(this).balance); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /quiz-game/foundry/src/test/QuizFactory.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | import "../QuizFactory.sol"; 7 | 8 | contract QuizFactoryTest is DSTest { 9 | QuizFactory public factory; 10 | 11 | function setUp() public { 12 | factory = new QuizFactory(); 13 | } 14 | 15 | function testCreateQuiz() public { 16 | string 17 | memory question = "What is the answer to life, the universe, and everything?"; 18 | string memory answer = "42"; 19 | bytes32 salt = bytes32("123123123"); 20 | bytes32 hashedAnswer = keccak256(abi.encodePacked(salt, answer)); 21 | factory.createQuiz(question, hashedAnswer); 22 | QuizGame quiz = factory.quizzes(0); 23 | assertEq( 24 | keccak256(abi.encodePacked(quiz.question())), 25 | keccak256(abi.encodePacked(question)) 26 | ); 27 | } 28 | 29 | function testCountQuizzes() public { 30 | string 31 | memory question = "What is the answer to life, the universe, and everything?"; 32 | string memory answer = "42"; 33 | bytes32 salt = bytes32("123123123"); 34 | bytes32 hashedAnswer = keccak256(abi.encodePacked(salt, answer)); 35 | factory.createQuiz(question, hashedAnswer); 36 | factory.createQuiz(question, hashedAnswer); 37 | QuizGame[] memory quizzes = factory.getQuizzes(); 38 | assertEq(quizzes.length, 2); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /quiz-game/foundry/src/test/QuizGame.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "ds-test/test.sol"; 5 | 6 | import "../QuizGame.sol"; 7 | 8 | interface CheatCodes { 9 | function deal(address, uint256) external; 10 | } 11 | 12 | contract QuizGameTest is DSTest { 13 | QuizGame public game; 14 | CheatCodes constant cheats = CheatCodes(HEVM_ADDRESS); 15 | 16 | function setUp() public { 17 | // Create a question 18 | string 19 | memory question = "What is the answer to life, the universe, and everything?"; 20 | string memory answer = "42"; 21 | bytes32 salt = bytes32("123123123"); 22 | bytes32 hashedAnswer = keccak256(abi.encodePacked(salt, answer)); 23 | emit log_bytes32(hashedAnswer); 24 | game = new QuizGame(question, hashedAnswer); 25 | emit log(game.question()); 26 | } 27 | 28 | function testQuizFail() public { 29 | try game.guess("1") { 30 | assertTrue(false); 31 | } catch { 32 | assertTrue(true); 33 | } 34 | } 35 | 36 | function testQuizPass() public { 37 | uint256 beginBalance = address(this).balance; 38 | cheats.deal(address(game), 10000); 39 | game.guess("42"); 40 | assertEq(address(this).balance, beginBalance + 10000); 41 | } 42 | 43 | fallback() external payable {} 44 | 45 | receive() external payable {} 46 | } 47 | -------------------------------------------------------------------------------- /quiz-game/svelte/.eslintignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /quiz-game/svelte/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['eslint:recommended', 'prettier'], 4 | plugins: ['svelte3'], 5 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 6 | parserOptions: { 7 | sourceType: 'module', 8 | ecmaVersion: 2020 9 | }, 10 | env: { 11 | browser: true, 12 | es2017: true, 13 | node: true 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /quiz-game/svelte/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /quiz-game/svelte/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /quiz-game/svelte/.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /quiz-game/svelte/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100 6 | } 7 | -------------------------------------------------------------------------------- /quiz-game/svelte/README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 4 | 5 | ## Creating a project 6 | 7 | If you're seeing this, you've probably already done this step. Congrats! 8 | 9 | ```bash 10 | # create a new project in the current directory 11 | npm init svelte 12 | 13 | # create a new project in my-app 14 | npm init svelte my-app 15 | ``` 16 | 17 | ## Developing 18 | 19 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 20 | 21 | ```bash 22 | npm run dev 23 | 24 | # or start the server and open the app in a new browser tab 25 | npm run dev -- --open 26 | ``` 27 | 28 | ## Building 29 | 30 | To create a production version of your app: 31 | 32 | ```bash 33 | npm run build 34 | ``` 35 | 36 | You can preview the production build with `npm run preview`. 37 | 38 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. 39 | -------------------------------------------------------------------------------- /quiz-game/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview", 9 | "prepare": "svelte-kit sync", 10 | "lint": "prettier --check --plugin-search-dir=. . && eslint .", 11 | "format": "prettier --write --plugin-search-dir=. ." 12 | }, 13 | "devDependencies": { 14 | "@sveltejs/adapter-auto": "next", 15 | "@sveltejs/kit": "next", 16 | "eslint": "^8.12.0", 17 | "eslint-config-prettier": "^8.3.0", 18 | "eslint-plugin-svelte3": "^4.0.0", 19 | "prettier": "^2.5.1", 20 | "prettier-plugin-svelte": "^2.5.0", 21 | "svelte": "^3.44.0" 22 | }, 23 | "type": "module", 24 | "dependencies": { 25 | "ethers": "^5.6.8" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /quiz-game/svelte/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /quiz-game/svelte/src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |

Welcome to My Quiz

16 | {#if !web3Props.account} 17 | 18 | {:else} 19 | 20 | 21 | {/if} 22 | -------------------------------------------------------------------------------- /quiz-game/svelte/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/quiz-game/svelte/static/favicon.png -------------------------------------------------------------------------------- /quiz-game/svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | kit: { 6 | adapter: adapter() 7 | } 8 | }; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /random-svg-nft/.env.example: -------------------------------------------------------------------------------- 1 | ETHERSCAN_API_KEY= 2 | SEPOLIA_URL=https://eth-rinkeby.alchemyapi.io/v2/ 3 | PRIVATE_KEY= 4 | SUBSCRIPTION_ID= 5 | -------------------------------------------------------------------------------- /random-svg-nft/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage 5 | -------------------------------------------------------------------------------- /random-svg-nft/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es2021: true, 5 | mocha: true, 6 | node: true, 7 | }, 8 | plugins: ["@typescript-eslint"], 9 | extends: [ 10 | "standard", 11 | "plugin:prettier/recommended", 12 | "plugin:node/recommended", 13 | ], 14 | parser: "@typescript-eslint/parser", 15 | parserOptions: { 16 | ecmaVersion: 12, 17 | }, 18 | rules: { 19 | "node/no-unsupported-features/es-syntax": [ 20 | "error", 21 | { ignores: ["modules"] }, 22 | ], 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /random-svg-nft/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | 7 | #Hardhat files 8 | cache 9 | artifacts 10 | 11 | yarn.lock 12 | package-lock.json -------------------------------------------------------------------------------- /random-svg-nft/.npmignore: -------------------------------------------------------------------------------- 1 | hardhat.config.ts 2 | scripts 3 | test 4 | -------------------------------------------------------------------------------- /random-svg-nft/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage* 5 | gasReporterOutput.json 6 | -------------------------------------------------------------------------------- /random-svg-nft/.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "compiler-version": ["error", "^0.8.0"], 5 | "func-visibility": ["warn", { "ignoreConstructors": true }] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /random-svg-nft/.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /random-svg-nft/contracts/test/LinkToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.4.24; 3 | 4 | import "@chainlink/contracts/src/v0.4/LinkToken.sol"; 5 | -------------------------------------------------------------------------------- /random-svg-nft/contracts/test/VRFCoordinatorV2Mock.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@chainlink/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol"; 5 | -------------------------------------------------------------------------------- /random-svg-nft/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/random-svg-nft/demo.png -------------------------------------------------------------------------------- /random-svg-nft/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | 3 | import { HardhatUserConfig } from "hardhat/config"; 4 | import "@nomiclabs/hardhat-etherscan"; 5 | import "@nomiclabs/hardhat-waffle"; 6 | import "@typechain/hardhat"; 7 | import "hardhat-gas-reporter"; 8 | import "solidity-coverage"; 9 | 10 | dotenv.config(); 11 | 12 | const config: HardhatUserConfig = { 13 | solidity: { 14 | compilers: [ 15 | { 16 | version: "0.8.7", 17 | }, 18 | { 19 | version: "0.4.24", 20 | }, 21 | ], 22 | }, 23 | networks: { 24 | rinkeby: { 25 | url: process.env.SEPOLIA_URL || "", 26 | accounts: 27 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], 28 | }, 29 | }, 30 | gasReporter: { 31 | enabled: process.env.REPORT_GAS !== undefined, 32 | currency: "USD", 33 | }, 34 | etherscan: { 35 | apiKey: { 36 | rinkeby: process.env.ETHERSCAN_API_KEY, 37 | }, 38 | }, 39 | }; 40 | 41 | export default config; 42 | -------------------------------------------------------------------------------- /random-svg-nft/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emoji-nft", 3 | "license": "MIT", 4 | "scripts": { 5 | "compile": "hardhat compile", 6 | "test": "hardhat test", 7 | "coverage": "hardhat coverage", 8 | "deploy": "hardhat run --network rinkeby scripts/deploy.ts" 9 | }, 10 | "devDependencies": { 11 | "@chainlink/contracts": "^0.4.0", 12 | "@nomiclabs/hardhat-ethers": "^2.0.4", 13 | "@nomiclabs/hardhat-etherscan": "^3.0.1", 14 | "@nomiclabs/hardhat-waffle": "^2.0.2", 15 | "@openzeppelin/contracts": "^4.5.0", 16 | "@typechain/ethers-v5": "^7.2.0", 17 | "@typechain/hardhat": "^2.3.1", 18 | "@types/chai": "^4.3.0", 19 | "@types/mocha": "^9.1.0", 20 | "@types/node": "^12.20.42", 21 | "@typescript-eslint/eslint-plugin": "^4.33.0", 22 | "@typescript-eslint/parser": "^4.33.0", 23 | "chai": "^4.3.6", 24 | "dotenv": "^10.0.0", 25 | "eslint": "^7.32.0", 26 | "eslint-config-prettier": "^8.3.0", 27 | "eslint-config-standard": "^16.0.3", 28 | "eslint-plugin-import": "^2.25.4", 29 | "eslint-plugin-node": "^11.1.0", 30 | "eslint-plugin-prettier": "^3.4.1", 31 | "eslint-plugin-promise": "^5.2.0", 32 | "ethereum-waffle": "^3.4.0", 33 | "ethers": "^5.5.3", 34 | "hardhat": "^2.8.3", 35 | "hardhat-gas-reporter": "^1.0.7", 36 | "prettier": "^2.5.1", 37 | "prettier-plugin-solidity": "^1.0.0-beta.13", 38 | "solhint": "^3.3.6", 39 | "solidity-coverage": "^0.7.18", 40 | "ts-node": "^10.4.0", 41 | "typechain": "^5.2.0", 42 | "typescript": "^4.5.5" 43 | }, 44 | "dependencies": {} 45 | } 46 | -------------------------------------------------------------------------------- /random-svg-nft/test/shared/helpers.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber, Wallet } from "ethers"; 2 | import { parseEther } from "ethers/lib/utils"; 3 | import { VRFCoordinatorV2Mock } from "../../typechain"; 4 | 5 | export const createAndFundMockSubscription = async ( 6 | vrfCoordinatorMock: VRFCoordinatorV2Mock, 7 | deployer: Wallet 8 | ): Promise => { 9 | const tx = await vrfCoordinatorMock.connect(deployer).createSubscription(); 10 | const txReceipt = await tx.wait(); 11 | const subscriptionId = BigNumber.from(txReceipt.logs[0].topics[1]); 12 | await vrfCoordinatorMock.fundSubscription(subscriptionId, parseEther(`1`)); 13 | 14 | return subscriptionId; 15 | }; 16 | -------------------------------------------------------------------------------- /random-svg-nft/test/shared/types.ts: -------------------------------------------------------------------------------- 1 | import { Fixture } from "ethereum-waffle"; 2 | import { Wallet } from "@ethersproject/wallet"; 3 | import { EmojiNFT, VRFCoordinatorV2Mock } from "../../typechain"; 4 | 5 | declare module "mocha" { 6 | export interface Context { 7 | loadFixture: (fixture: Fixture) => Promise; 8 | signers: Signers; 9 | emojiNft: EmojiNFT; 10 | vrfCoordinatorMock: VRFCoordinatorV2Mock; 11 | } 12 | } 13 | 14 | export interface Signers { 15 | deployer: Wallet; 16 | alice: Wallet; 17 | bob: Wallet; 18 | } 19 | -------------------------------------------------------------------------------- /random-svg-nft/test/unit/EmojiNFT/EmojiNFTShouldMint.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, assert } from "chai"; 2 | import { BigNumber } from "ethers"; 3 | import { ethers } from "hardhat"; 4 | 5 | export const shouldMint = (): void => { 6 | // to silent warning for duplicate definition of Transfer event 7 | ethers.utils.Logger.setLogLevel(ethers.utils.Logger.levels.OFF); 8 | 9 | context(`#mint`, async function () { 10 | it(`should mint new NFT`, async function () { 11 | const requestId: BigNumber = await this.emojiNft.callStatic.mint(); 12 | 13 | await expect(this.emojiNft.connect(this.signers.alice).mint()) 14 | .to.emit(this.emojiNft, `RandomnessRequested`) 15 | .withArgs(requestId); 16 | 17 | await this.vrfCoordinatorMock.fulfillRandomWords( 18 | requestId, 19 | this.emojiNft.address 20 | ); 21 | 22 | const aliceBalance: BigNumber = await this.emojiNft.balanceOf( 23 | this.signers.alice.address 24 | ); 25 | 26 | assert(aliceBalance.eq(ethers.constants.One)); 27 | }); 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /random-svg-nft/test/unit/index.ts: -------------------------------------------------------------------------------- 1 | import { waffle } from "hardhat"; 2 | import { unitEmojiNftFixture } from "../shared/fixtures"; 3 | import { Signers } from "../shared/types"; 4 | import { shouldMint } from "./EmojiNFT/EmojiNFTShouldMint.spec"; 5 | 6 | describe(`Unit tests`, async () => { 7 | before(async function () { 8 | const wallets = waffle.provider.getWallets(); 9 | 10 | this.signers = {} as Signers; 11 | this.signers.deployer = wallets[0]; 12 | this.signers.alice = wallets[1]; 13 | this.signers.bob = wallets[2]; 14 | 15 | this.loadFixture = waffle.createFixtureLoader(wallets); 16 | }); 17 | 18 | describe(`EmojiNFT`, async () => { 19 | beforeEach(async function () { 20 | const { emojiNft, vrfCoordinatorMock } = await this.loadFixture( 21 | unitEmojiNftFixture 22 | ); 23 | 24 | this.emojiNft = emojiNft; 25 | this.vrfCoordinatorMock = vrfCoordinatorMock; 26 | }); 27 | 28 | shouldMint(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /random-svg-nft/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "declaration": true 9 | }, 10 | "include": ["./scripts", "./test", "./typechain"], 11 | "files": ["./hardhat.config.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /timelocked-contracts/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | -------------------------------------------------------------------------------- /timelocked-contracts/README.md: -------------------------------------------------------------------------------- 1 | # Timelocked Contracts 2 | This repo supports the blog post [posthere](https://blog.chain.link) 3 | 4 | ## How to Use The Repo 5 | 6 | This repo was developed using [Foundry](https://github.com/foundry-rs/foundry) 7 | 8 | Use `forge test` to run the test suite. -------------------------------------------------------------------------------- /timelocked-contracts/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /timelocked-contracts/remappings.txt: -------------------------------------------------------------------------------- 1 | @openzeppelin/=lib/openzeppelin-contracts/ 2 | ds-test/=lib/ds-test/src/ -------------------------------------------------------------------------------- /ultimate-nft-repo/.env.example: -------------------------------------------------------------------------------- 1 | NFT_STORAGE_KEY='asdfasdfasdf' 2 | PINATA_API_KEY='asdfasdfasdf' 3 | PINATA_API_SECRET='asdfasdfasdf' 4 | UPLOAD_TO_PINATA=true 5 | ETHERSCAN_API_KEY='asdfasdfasdf' 6 | COINMARKETCAP_API_KEY='asdfasdfasdf' 7 | SEPOLIA_RPC_URL='asdfasdfasdf' -------------------------------------------------------------------------------- /ultimate-nft-repo/.npmignore: -------------------------------------------------------------------------------- 1 | hardhat.config.js 2 | scripts 3 | test 4 | -------------------------------------------------------------------------------- /ultimate-nft-repo/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage* 5 | gasReporterOutput.json 6 | package.json 7 | img 8 | .env 9 | .* 10 | README.md 11 | coverage.json 12 | deployments -------------------------------------------------------------------------------- /ultimate-nft-repo/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "semi": false, 5 | "singleQuote": false, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /ultimate-nft-repo/contracts/BasicNft.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.8; 3 | 4 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | 6 | contract BasicNft is ERC721 { 7 | string public constant TOKEN_URI = 8 | "ipfs://bafybeig37ioir76s7mg5oobetncojcm3c3hxasyd4rvid4jqhy4gkaheg4/?filename=0-PUG.json"; 9 | uint256 private s_tokenCounter; 10 | 11 | constructor() ERC721("Dogie", "DOG") { 12 | s_tokenCounter = 0; 13 | } 14 | 15 | function mintNft() public returns (uint256) { 16 | _safeMint(msg.sender, s_tokenCounter); 17 | s_tokenCounter = s_tokenCounter + 1; 18 | return s_tokenCounter; 19 | } 20 | 21 | function tokenURI(uint256 tokenId) public view override returns (string memory) { 22 | // require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); 23 | return TOKEN_URI; 24 | } 25 | 26 | function getTokenCounter() public view returns (uint256) { 27 | return s_tokenCounter; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ultimate-nft-repo/contracts/test/MockV3Aggregator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.0; 3 | 4 | import "@chainlink/contracts/src/v0.6/tests/MockV3Aggregator.sol"; 5 | -------------------------------------------------------------------------------- /ultimate-nft-repo/contracts/test/VRFCoordinatorV2Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@chainlink/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol"; 5 | -------------------------------------------------------------------------------- /ultimate-nft-repo/deploy/00-deploy-mocks.js: -------------------------------------------------------------------------------- 1 | const { network } = require("hardhat") 2 | const { DECIMALS, INITIAL_PRICE } = require("../helper-hardhat-config") 3 | 4 | const BASE_FEE = "250000000000000000" // 0.25 is this the premium in LINK? 5 | const GAS_PRICE_LINK = 1e9 // link per gas, is this the gas lane? // 0.000000001 LINK per gas 6 | 7 | module.exports = async ({ getNamedAccounts, deployments }) => { 8 | const { deploy, log } = deployments 9 | const { deployer } = await getNamedAccounts() 10 | const chainId = network.config.chainId 11 | // If we are on a local development network, we need to deploy mocks! 12 | if (chainId == 31337) { 13 | log("Local network detected! Deploying mocks...") 14 | await deploy("VRFCoordinatorV2Mock", { 15 | from: deployer, 16 | log: true, 17 | args: [BASE_FEE, GAS_PRICE_LINK], 18 | }) 19 | await deploy("MockV3Aggregator", { 20 | from: deployer, 21 | log: true, 22 | args: [DECIMALS, INITIAL_PRICE], 23 | }) 24 | 25 | log("Mocks Deployed!") 26 | log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") 27 | log("You are deploying to a local network, you'll need a local network running to interact") 28 | log( 29 | "Please run `yarn hardhat console --network localhost` to interact with the deployed smart contracts!" 30 | ) 31 | log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") 32 | } 33 | } 34 | module.exports.tags = ["all", "mocks", "main"] 35 | -------------------------------------------------------------------------------- /ultimate-nft-repo/deploy/01-deploy-basic-nft.js: -------------------------------------------------------------------------------- 1 | const { network } = require("hardhat") 2 | const { developmentChains } = require("../helper-hardhat-config") 3 | const { verify } = require("../utils/verify") 4 | 5 | module.exports = async ({ getNamedAccounts, deployments }) => { 6 | const { deploy, log } = deployments 7 | const { deployer } = await getNamedAccounts() 8 | 9 | log("----------------------------------------------------") 10 | arguments = [] 11 | const basicNft = await deploy("BasicNft", { 12 | from: deployer, 13 | args: arguments, 14 | log: true, 15 | waitConfirmations: network.config.blockConfirmations || 1, 16 | }) 17 | 18 | // Verify the deployment 19 | if (!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) { 20 | log("Verifying...") 21 | await verify(basicNft.address, arguments) 22 | } 23 | } 24 | 25 | module.exports.tags = ["all", "basicnft", "main"] 26 | -------------------------------------------------------------------------------- /ultimate-nft-repo/helper-hardhat-config.js: -------------------------------------------------------------------------------- 1 | const networkConfig = { 2 | 31337: { 3 | name: "localhost", 4 | ethUsdPriceFeed: "0x9326BFA02ADD2366b30bacB125260Af641031331", 5 | gasLane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc", // 30 gwei 6 | mintFee: "10000000000000000", // 0.01 ETH 7 | callbackGasLimit: "500000", // 500,000 gas 8 | }, 9 | // Price Feed Address, values can be obtained at https://docs.chain.link/docs/reference-contracts 10 | // Default one is ETH/USD contract on Kovan 11 | 11155111: { 12 | name: "sepolia", 13 | ethUsdPriceFeed: "0x694AA1769357215DE4FAC081bf1f309aDC325306", 14 | vrfCoordinatorV2: "0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625", 15 | gasLane: "0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c", 16 | callbackGasLimit: "500000", // 500,000 gas 17 | mintFee: "10000000000000000", // 0.01 ETH 18 | subscriptionId: "", // add your ID here! 19 | }, 20 | } 21 | 22 | const DECIMALS = "18" 23 | const INITIAL_PRICE = "200000000000000000000" 24 | const developmentChains = ["hardhat", "localhost"] 25 | 26 | module.exports = { 27 | networkConfig, 28 | developmentChains, 29 | DECIMALS, 30 | INITIAL_PRICE, 31 | } 32 | -------------------------------------------------------------------------------- /ultimate-nft-repo/images/dynamicNft/frown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ultimate-nft-repo/images/dynamicNft/happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ultimate-nft-repo/images/randomNft/pug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ultimate-nft-repo/images/randomNft/pug.png -------------------------------------------------------------------------------- /ultimate-nft-repo/images/randomNft/shiba-inu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ultimate-nft-repo/images/randomNft/shiba-inu.png -------------------------------------------------------------------------------- /ultimate-nft-repo/images/randomNft/st-bernard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartcontractkit/smart-contract-examples/32bb95e558bdd6a4ebab4b6c1eadbfc83668c539/ultimate-nft-repo/images/randomNft/st-bernard.png -------------------------------------------------------------------------------- /ultimate-nft-repo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers", 5 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 6 | "@nomiclabs/hardhat-waffle": "^2.0.3", 7 | "chai": "^4.3.4", 8 | "ethereum-waffle": "^3.4.0", 9 | "ethers": "^5.5.4", 10 | "hardhat": "^2.9.0", 11 | "hardhat-deploy": "^0.10.5", 12 | "hardhat-gas-reporter": "^1.0.7", 13 | "prettier": "^2.5.1", 14 | "solidity-coverage": "^0.7.18" 15 | }, 16 | "dependencies": { 17 | "@aave/protocol-v2": "^1.0.1", 18 | "@chainlink/contracts": "^0.4.0", 19 | "@ethersproject/bignumber": "^5.5.0", 20 | "@openzeppelin/contracts": "^4.5.0", 21 | "@pinata/sdk": "^1.1.23", 22 | "base64-sol": "^1.1.0", 23 | "dotenv": "^16.0.0", 24 | "fs": "^0.0.1-security", 25 | "mime": "^3.0.0", 26 | "nft.storage": "^6.0.1", 27 | "path": "^0.12.7", 28 | "prettier-plugin-solidity": "^1.0.0-beta.19", 29 | "solhint": "^3.3.7" 30 | }, 31 | "scripts": { 32 | "lint": "solhint 'contracts/*.sol'", 33 | "lint:fix": "solhint 'contracts/**/*.sol' --fix", 34 | "format": "prettier --write ." 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ultimate-nft-repo/test/unit/basicNft.test.js: -------------------------------------------------------------------------------- 1 | // We are going to skimp a bit on these tests... 2 | 3 | const { assert } = require("chai") 4 | const { network, deployments, ethers } = require("hardhat") 5 | const { developmentChains } = require("../../helper-hardhat-config") 6 | 7 | !developmentChains.includes(network.name) 8 | ? describe.skip 9 | : describe("Basic NFT Unit Tests", async function () { 10 | let basicNft, deployer 11 | 12 | beforeEach(async () => { 13 | accounts = await ethers.getSigners() 14 | deployer = accounts[0] 15 | await deployments.fixture(["mocks", "basicnft"]) 16 | basicNft = await ethers.getContract("BasicNft") 17 | }) 18 | 19 | it("Allows users to mint an NFT, and updates appropriately", async function () { 20 | const txResponse = await basicNft.mintNft() 21 | await txResponse.wait(1) 22 | const tokenURI = await basicNft.tokenURI(0) 23 | const tokenCounter = await basicNft.getTokenCounter() 24 | 25 | assert.equal(tokenCounter.toString(), "1") 26 | assert.equal(tokenURI, await basicNft.TOKEN_URI()) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /ultimate-nft-repo/utils/uploadToPinata.js: -------------------------------------------------------------------------------- 1 | const pinataSDK = require("@pinata/sdk") 2 | const fs = require("fs") 3 | const path = require("path") 4 | 5 | const pinataApiKey = process.env.PINATA_API_KEY || "" 6 | const pinataApiSecret = process.env.PINATA_API_SECRET || "" 7 | const pinata = pinataSDK(pinataApiKey, pinataApiSecret) 8 | 9 | async function storeImages(imagesFilePath) { 10 | const fullImagesPath = path.resolve(imagesFilePath) 11 | const files = fs.readdirSync(fullImagesPath) 12 | let responses = [] 13 | for (fileIndex in files) { 14 | const readableStreamForFile = fs.createReadStream(`${fullImagesPath}/${files[fileIndex]}`) 15 | try { 16 | const response = await pinata.pinFileToIPFS(readableStreamForFile) 17 | responses.push(response) 18 | } catch (error) { 19 | console.log(error) 20 | } 21 | } 22 | return { responses, files } 23 | } 24 | 25 | async function storeTokeUriMetadata(metadata) { 26 | try { 27 | const response = await pinata.pinJSONToIPFS(metadata) 28 | return response 29 | } catch (error) { 30 | console.log(error) 31 | } 32 | return null 33 | } 34 | 35 | module.exports = { storeImages, storeTokeUriMetadata } 36 | -------------------------------------------------------------------------------- /ultimate-nft-repo/utils/verify.js: -------------------------------------------------------------------------------- 1 | // we can't have these functions in our `helper-hardhat-config` 2 | // since these use the hardhat library 3 | // and it would be a circular dependency 4 | const { run, network } = require("hardhat") 5 | const { networkConfig } = require("../helper-hardhat-config") 6 | 7 | const verify = async (contractAddress, args) => { 8 | console.log("Verifying contract...") 9 | try { 10 | await run("verify:verify", { 11 | address: contractAddress, 12 | constructorArguments: args, 13 | }) 14 | } catch (e) { 15 | if (e.message.toLowerCase().includes("already verified")) { 16 | console.log("Already verified!") 17 | } else { 18 | console.log(e) 19 | } 20 | } 21 | } 22 | 23 | module.exports = { 24 | verify, 25 | } 26 | -------------------------------------------------------------------------------- /upkeep-interactions/custom-logic-upkeep/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .env.enc 4 | .env -------------------------------------------------------------------------------- /upkeep-interactions/custom-logic-upkeep/README.md: -------------------------------------------------------------------------------- 1 | # Custom Logic Upkeep Interactions 2 | 3 | ### UpkeepInteractions.sol 4 | 5 | A solidity contract showcasing the interaction with `AutomationRegistrar` and `KeeperRegistry` contracts, for **registration** of **Custom Logic Upkeep** and performing other operations like **pause upkeep**, **unpause upkeep**, **cancel upkeep**, **add funds to upkeep**, **withdraw funds from upkeep**, and **edit gas limit of upkeep**. 6 | 7 | **Note:** The upkeep that will be registered using the contract won't be visible in the [Automation UI](https://automation.chain.link/) because the `adminAddress` is being set to the address of the contract (not to any wallet). 8 | 9 | ### upkeepInteractions.js 10 | 11 | A script in JS containing the functions to interact with the registered **Custom Logic Upkeep**. 12 | 13 | Run the script using this command: 14 | 15 | ```js 16 | node upkeepInteractions.js ${KEEPER_REGISTRY_ADDRESS} ${LINK_TOKEN_ADDRESS} 17 | ``` -------------------------------------------------------------------------------- /upkeep-interactions/custom-logic-upkeep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@chainlink/env-enc": "^1.0.5", 4 | "ethers": "^6.13.2" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /vrf-arbitrum-gas-estimation/.env-sample: -------------------------------------------------------------------------------- 1 | # Hosted Aggregator Node (JSON-RPC Endpoint). This is Arbitrum Goerli Testnet, can use any Arbitrum chain 2 | L2RPC="https://goerli-rollup.arbitrum.io/rpc" -------------------------------------------------------------------------------- /vrf-arbitrum-gas-estimation/README.md: -------------------------------------------------------------------------------- 1 | # VRF / Arbitrum gas estimation tutorial 2 | 3 | This extends the [**original Arbitrum gas estimation tutorial**](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation) to add [gas estimate calculations for Chainlink VRF](https://docs.chain.link/vrf/v2/estimating-costs#arbitrum). 4 | 5 | --- 6 | 7 | # Gas estimation tutorial 8 | 9 | `gas-estimation` is a simple demo of how a developer can estimate transaction fees on Arbitrum. 10 | 11 | It uses the formula described in this Medium article to estimate the fees to be paid on a transaction, also estimating each component of the formula separately: [Understanding Arbitrum: 2-Dimensional Fees](https://medium.com/offchainlabs/understanding-arbitrum-2-dimensional-fees-fd1d582596c9). 12 | 13 | See [./exec.ts](./scripts/exec.ts) for inline explanations. 14 | 15 | Inside the script, you can edit `txData` constant to suit your needs. 16 | 17 | To run: 18 | 19 | ``` 20 | yarn run exec 21 | ``` 22 | 23 | ## Config Environment Variables 24 | 25 | Set the values shown in `.env-sample` as environmental variables. To copy it into a `.env` file: 26 | 27 | ```bash 28 | cp .env-sample .env 29 | ``` 30 | 31 | (you'll still need to edit some variables, i.e., `L2RPC`) 32 | -------------------------------------------------------------------------------- /vrf-arbitrum-gas-estimation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gas-estimation", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "exec": "ts-node scripts/exec.ts" 7 | }, 8 | "dependencies": { 9 | "@arbitrum/sdk": "^v3.1.2", 10 | "ts-node": "^10.8.1", 11 | "typescript": "^4.7.3" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } --------------------------------------------------------------------------------