CryptoDappy is the fastest way to get started with Flow.

Overview

CI Badge

CryptoDappy Cover


What's CryptoDappy?

CryptoDappy is the fastest way to get started with blockchain development on Flow. Our learning hub offers various mission-based scenarios, in which you will build your own full-stack blockchain application that allows for querying, minting and transfering NFTs. You will also learn how to sell these NFTs in packs for a given price of FUSD (Flow's first stablecoin). The NFTs of this application are Dappies, cute little monsters that come with different stripes, rarities and colors.

The missions of this course are:

  • Onboarding: Getting started
  • Mission #1: Authentication
  • Mission #2: Scripts
  • Mission #3: Collections and NFTs
  • Mission #4: FUSD and Fungible Tokens
  • Mission #5: Minting

By the end of this course, you will have build your own NFT application that looks like the demo application of CryptoDappy, and deploy it to Flow's testnet. You'll be ready to write, test and deploy your own blockchain applications on Flow.


Who's behind CryptoDappy?

CryptoDappy is a personal project created by Dapper Labs' Technical Content Marketing Manager Benjamin Ebner (Twitter|Medium), with the goal of becoming a fully community-owned project in the future - that's why we're looking for community members that want to contribute and/or take ownerhip of the project! CryptoDappy is not an official Flow project. The standard reference app of Flow is Kitty Items.


Where to get help?

If you feel stuck building the project or you have any questions regarding the course, you can get help in the dedicated Flow community forum.

Comments
  • localhost:3000 connect refuse when try to sign in(#mission 1 / run with wsl2)

    localhost:3000 connect refuse when try to sign in(#mission 1 / run with wsl2)

    Describe the bug I use windows WSL2 (ubuntu 20.04) When I try to complete my mission#1, my browser show connect refuesd.
    Not sure if WSL2 is compatible for that.

    To Reproduce Steps to reproduce the behavior:

    1. run ''npm start"
    2. go to "localhost:3000"
    3. Click on 'sign in to start '
    4. See error "localhost:3000 connect refused"

    Screenshots If applicable, add screenshots to help explain your problem. image

    Desktop (please complete the following information):

    • OS: windows 10 run WSL2(ubuntu 20.04)
    • Browser: chrome &Edge
    opened by willy20040711 1
  • Update dappies.config.js

    Update dappies.config.js

    Following mission 5.2 of crypto dappy, I minted a dappy and found an issue : I add minted "Lucienne Dappy" (id 15) and was seeing "Mohammad Dappy" (id 16) in my collection.

    I realised there was differences between:

    • the IDs I was seeing on the Dappies.page.js (which query directly DappyContract.listTemplates() at address export DAPPY_CONTRACT=0xdb3d539e48a805b7) and
    • the IDs I was seeing in Collection.page.js (which use the addDappy function from use-user-dappies.hook.js)

    Not sure if that PR is needed, as this problem disappears in 5.3 when we query the blockchain for the dappies array.

    opened by louisguitton 0
  • Create FUSD vault does not work

    Create FUSD vault does not work

    Hi,

    for me the creation of a FUSD vault is not working. I compared the code produced using the video tutorial with the one in the repo and it is 1:1 identical.

    I'm working on MacOS 11.5.2, using Chrome and Safari. The Webbrowser developer console does not show any error. However it is still stuck with the saying "Enable FUSD". It initiates the transaction (Approval via blocto).

    Besides that the swap of Flow to FUSD is not working due to unavailable FUSD resource. Is there any cycle when there will be new FUSD available for swap on testnet ?

    opened by fyrz 0
  • Move Admin Deposit in Init To Use Named Path

    Move Admin Deposit in Init To Use Named Path

    https://github.com/bebner/crypto-dappy/blob/a6cae18e019715e1d7e449339dba8be2a4ea007e/cadence/contracts/DappyContract.cdc#L308

    i.e.

    self.AdminStoragePath = /storage/DappyAdmin
    self.account.save<@Admin>(<- create Admin(), to: self.AdminStoragePath)`
    
    good first issue 
    opened by rheaplex 0
  • 【mission-2】Error Type mismatch

    【mission-2】Error Type mismatch

    Describe the bug Error Type mismatch occured in mission-2. it's LIST_DAPPY_TEMPLATE script.

    To Reproduce Steps to reproduce the behavior:

    1. add this scripts to list-dappy-templates.script.js
    export const LIST_DAPPY_TEMPLATE = `
        import DappyContract from 0xDappy
    
        pub fun main(): { UInt32: DappyContract.Template } {
            return DappyContract.listTemplates()
        }
    `;
    
    1. execute a command sh run.sh
    2. Go to dappies page.
    3. error occured

    Expected behavior console

    {
    	"code": 400,
    	"message": "Invalid Flow argument: failed to execute the script on the execution node execution-5f6c73a22445d7d958c6a37c1f3be99c72cacd39894a3e46d6647a9adb007b4d@execution-001.devnet38.nodes.onflow.org:3569=100: rpc error: code = InvalidArgument desc = failed to execute script: failed to execute script at block (39e392a18fe68ade2fc4a1a4461f48472bd0c0a36c1e3bd71ea78f0927b0bb4c): [Error Code: 1101] error caused by: [Error Code: 1101] cadence runtime error: Execution failed:\nerror: mismatched types\n   --\u003e db3d539e48a805b7.DappyContract:225:21\n    |\n225 |     let familyRef = \u0026self.families[familyID] as! \u0026Family\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^ expected `DappyContract.Family`, got `DappyContract.Family?`\n\nerror: mismatched types\n   --\u003e db3d539e48a805b7.DappyContract:240:21\n    |\n240 |     let familyRef = \u0026self.families[familyID] as! \u0026Family\n    |          ...  find type in this scope: `DappyContract`\n --\u003e 89f4de94e0a12e080f0d2facf1e3ff0213e4dc5001a93b5f94b2ec3454194088:4:30\n  |\n4 |     pub fun main(): { UInt32: DappyContract.Template } {\n  |                               ^^^^^^^^^^^^^ not found in this scope\n\nerror: cannot find variable in this scope: `DappyContract`\n --\u003e 89f4de94e0a12e080f0d2facf1e3ff0213e4dc5001a93b5f94b2ec3454194088:5:15\n  |\n5 |         return DappyContract.listTemplates()\n  |                ^^^^^^^^^^^^^ not found in this scope\n"
    }
    

    Screenshots スクリーンショット 2022-11-09 22 54 24

    Desktop (please complete the following information):

    • OS: Mac OS (M1)
    • Browser chrome
    • Version 107.0.5304.87
    opened by mashharuki 1
  • cors

    cors

    I have implemented the code in misson-3, however the following issue happens when loading the http://localhost:3000/dappies page. Access to fetch at 'https://access-testnet.onflow.org/v1/scripts?block_height=sealed' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. http-request.js:102 POST https://access-testnet.onflow.org/v1/scripts?block_height=sealed net::ERR_FAILED 404

    opened by dajuguan 0
  • Flip Fest - First Milestone - Team Ancient Machine

    Flip Fest - First Milestone - Team Ancient Machine

    Hi @bebner,

    Here are the code changes I made to show PackPanel on the left and BreedPanel on the right. This patch comes with capability to drag-n-drop Dappies into PackPanel and toggle a hidden div for each collected Dappy to enter price and list it for sale.

    Here are the link to the demo: https://youtu.be/8M75G43ISXM

    UI Sketch

    opened by NguyenIvan 1
  • Expand Template functionality

    Expand Template functionality

    Is your feature request related to a problem? Please describe. I would like to extend the Template struct functionality and wanted to get your advice on the best way to organize the code for it:

    1. Would like to restrict minting of Dappies from a template by introducing a retired flag, similar to what the TopShot did.
    2. Would like to keep track how many Dappies were minted for each Template.
    3. Would like to set a maximum number of Dappies that can be minted for each Template.

    Describe the solution you'd like Here are the most obvious solutions based on CryptoKitties and TopShot codebases:

    1. Add the retired flag to the Template struct.
      However, the side effect of it would be passing that information to the Dappy since the data field on a Dappy is a Template.

    2. A common approach seems to be a dictionary of totals per Template. For example:

    access(self) var mintCountPerTemplate: {UInt32: UInt32}
    

    However, the Template struct itself seems to be a more logical place to keep track of the minted Dappies count.

    1. Add the maxQuantity flag to the Template struct itself similar to the suggested place for the retired flag above.
      However, the same problem as in 1 above. That information will be passed on to the Dappy via data and that's not a good place for it.

    Describe alternatives you've considered

    Solution 1: Introduce a DappyData struct and move all the current Template fields there. Also, add template-specific fields to the Template struct.

    public struct DappyData {
        pub let templateID: UInt32
        pub let dna: String
        pub let name: String
        pub let price: UFix64
    ...
    }
    
    pub struct Template {
        pub let templateID: UInt32
        pub let data: DappyData
        pub let maxQuantity: UInt32
        access(self) retired: Bool
        access(self) mintCount: UInt32
    ...
    }
    
    pub resource Dappy {
        pub let id: UInt64  // Global unique NFT ID
        pub let serialNumber: UInt32  // Based on number of Dappies minted with this template
        pub let data: DappyData
    ...
    }
    

    Solution 2:

    pub struct Template {
        pub let templateID: UInt32
        pub let dna: String
        pub let name: String
        pub let price: UFix64
        pub let maxQuantity: UInt32
        access(self) retired: Bool
        access(self) mintCount: UInt32
    ...
    }
    pub resource Dappy {
        pub let id: UInt64  
        pub let templateID: UInt32
        pub let serialNumber: UInt32
    ...
    }
    

    These are the two alternative solutions for all 3 points above. However, I'm afraid I'm overlooking something and would like your opinion on it. For example,

    1. I understand that having the access(self) access modifier for both retired and mintCount fields keeps them secure so nobody can do something like:
    DappyContract.templates[templateID]!.retired = true
    

    However, what would be the best way to update these values for Admins only then? Could you point me to some examples?

    1. As a side effect of Solution 1 I would need to introduce the dappyDatas dictionary to keep track of data for all Dappies. I would like to avoid doing so.

    Could you please provide your opinion on the best way to restructure the code based on the Template functionality expansion I've described above?

    Additional context Thanks for putting together CryptoDappy project and, especially, recording videos and explaining how everything fits together. I'm just trying to find the best place to ask questions similar to the ones above and I hope this is it.

    opened by iliawx 1
  • Implement the NonFungibleToken and INFT interfaces

    Implement the NonFungibleToken and INFT interfaces

    Is your feature request related to a problem? Please describe. The cryptodappy DappyContract smart contract does not implement the NonFungibleToken contract interface and the Dappy resource does not implement the INFT interface.

    It would be good for it to be consistent with how NFTs should be created practically.

    Describe the solution you'd like Create a new optional, advanced mission that walks user through the step of implementing the interfaces.

    Another option is to give users hints and notes that the DappyContract smart contract requires implementation of the aforementioned interfaces in practical applications.

    Either way, there should be a DappyNFTContract.cdc file in the final mission's code that shows how the smart contract with the interfaces implemented should look so users who are keen to learn more have a reference point.

    Additional context Since cryptodappy was created for learning purposes, it is understandable why it doesn't comply with the interfaces but it would still be a good idea to let users understand the implementation of the interfaces.

    opened by D10100111001 1
Owner
Benjamin Ebner
Blockchain developer, content creator, educator. Currently working at Dapper Labs/Flow.
Benjamin Ebner
Fastest way to get financial data from Plaid into your Postgres database. Go from zero to live in 5 minutes without a single line of code.

Venice Venice is a the fastest way to get financial data from Plaid into your Postgres database. Zero to production in 5 minutes without a single line

Venice 93 Dec 12, 2022
The Omnibookmarks browser extension is the fastest way to open bookmarks

★ Omnibookmarks The Omnibookmarks browser extension is the fastest way to open bookmarks. Just type a keyword into the address bar to quickly open or

Nate Hill 16 Aug 20, 2022
An efficient (and the fastest!) way to search the web privately using Brave Search Engine

Brave Search An efficient (and the fastest) way to search the web privately using Brave Search Engine. Not affiliated with Brave Search. Tested on Chr

Jishan Shaikh 7 Jun 2, 2022
The fastest way ⚡️ to create sitemap in your Deno Fresh project 🍋

Fresh SEO ??     Quickly creating sitemaps for your Deno Fresh project. Getting Started Run the setup at the root of your project. deno run

Steven Yung 34 Dec 19, 2022
Functions Recipes is a library of examples to help you getting started with Salesforce Functions and get used to their main features.

Functions Recipes Introduction Salesforce Functions lets you use the Salesforce Platform for building event-driven, elastically scalable apps and expe

Trailhead Apps 172 Dec 29, 2022
Get started on Remix with TypeScript and Tailwind CSS in seconds

remix-typescript-tailwind-quickstart Get started on Remix with TypeScript and Tailwind CSS in seconds. This is an example setup of Remix building on t

Resi Respati 12 Mar 16, 2022
A simple template to get started with a non-profit website.

Next.js Non-Profit Website A non-profit website template powered by the Cosmic headless CMS. Uses Next.js, Tailwind CSS, and Stripe for donation payme

Cosmic 5 Sep 6, 2022
TechSquad Community is what you need to get started in Coding and Development

TechSquad Community is what you need to get started in Coding and Development This is a Community website under development. This community aims to cr

TechSquad Community 18 Dec 16, 2022
This SDK helps developers get started with the on-chain tools provided by Metaplex.

Metaplex JavaScript SDK ⛔️ DO NOT USE IN PRODUCTION, THIS SDK IS IN VERY EARLY ALPHA STAGES! This SDK helps developers get started with the on-chain t

Metaplex Foundation 263 Dec 27, 2022
Minimal template to get started with Foundry + Hardhat

Hardhat x Foundry Template Template repository for getting started quickly with Hardhat and Foundry in one project Getting Started Use Foundry: forge

Foundry 158 Jan 3, 2023
Get started with AI vision at the edge with no coding experience at all!

No-Code Edge AI Vision with Node-RED Now you can get started with AI vision at the edge in just THREE STEPS with no coding experience at all! Prerequi

Seeed Studio 47 Dec 5, 2022
Get started with GatsbyJS straight away without having to spend a whole day configuring your usual addons.

Gatsby Starter Infinite Get started with GatsbyJS straight away without having to spend a whole day configuring your usual addons. This starter includ

Matt Patterson 3 Jun 27, 2022
🏄‍♂️ A node.js template to quickly get started building

hacky-node-template ??‍♂️ A type-safe Node.js template to quickly get started building. Tech-stack Express.js - Fast, un-opinionated, minimalist web f

Mukesh 7 Jan 4, 2023
A great place for platforms to get started on Cloudflare Workers!

Workers for Platforms Example Project Blog post Docs For SaaS companies, it's challenging to keep up with the never ending requests for customizations

Cloudflare 29 Dec 23, 2022
An NPM package to help you get started with modern javascript tooling easier & faster

MODERNIZE.JS Creating config files for webpack and babel can be an hell of stress, this NPM package helps you get started with writing code as soon as

Kelechi Okoronkwo 5 Sep 22, 2022
CloudCrafter CLI is a command-line interface tool that provides templates for common cloud resources to help you get started quickly.

CloudCrafter CLI CloudCrafter CLI is a command-line interface tool that provides templates for common cloud resources to help you get started quickly.

Missio 7 May 5, 2023
One-page checkout flow

Medusa Express Medusa is an open-source headless commerce engine that enables developers to create amazing digital commerce experiences. Built with Me

Medusa 49 Oct 11, 2022
Marquee is a VS Code extension designed to naturally integrate with your development flow, so that you will no longer lose track of your thoughts while you're coding

Marquee Stay organized with minimal context switching, all inside your Visual Studio Code. Marquee is a VS Code extension designed to naturally integr

stateful 60 Dec 13, 2022
A simple NEXT.js app that lists NFTs within a contract address from a Buildable Flow.

NFT Marketplace Demo This is a basic Next.js app for listing NFTs in a given contract address. The purpose of this repository is to showcase the simpl

Buildable 16 Dec 12, 2022