From b5f8364116b549ebfca20d57b71fde54452bf0a7 Mon Sep 17 00:00:00 2001 From: Owen <124691791+PiVortex@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:11:38 +0100 Subject: [PATCH] Fixes to auction series (#2228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add auction series * add more content * updates * more additions * small changes * add updates (#2190) * add auction series * add more content * updates * more additions * accept changes * Monday additions * Tuesday changes --------- Co-authored-by: PiVortex Co-authored-by: Guille * wip: proposal * Wednesday changes * finish part 1 and part 2 * small changes + remove future tutorials from sidebar * fix spelling mistake * update part 3 * hide nft tuotrial on intro page * improved part 4 * complete part 3 & 4 (hidden) * change cusd to dai * add frontend docs WIP * spelling * update 5-frontend * add showSingleFName * add factory contract docs * wip: re-structuring * add indexing page * finished 1st part * finished 1st part * rename files * fix: links * Update docs/6.integrations/create-transactions.md Co-authored-by: Damián Parrino * fix suggested changes * Update docs/3.tutorials/auction/0-intro.md * Update docs/3.tutorials/auction/0-intro.md * Update docs/3.tutorials/auction/3-nft.md --------- Co-authored-by: PiVortex Co-authored-by: gagdiez Co-authored-by: Damián Parrino --- docs/3.tutorials/auction/0-intro.md | 41 ++++++++++++------------- docs/3.tutorials/auction/1.1-basic.md | 6 ++-- docs/3.tutorials/auction/1.2-testing.md | 6 ++-- docs/3.tutorials/auction/1.3-deploy.md | 4 +-- docs/3.tutorials/auction/2-locking.md | 8 ++--- docs/3.tutorials/auction/3-nft.md | 2 +- docs/3.tutorials/auction/4-ft.md | 2 +- docs/3.tutorials/auction/5-frontend.md | 34 ++++++++++---------- docs/3.tutorials/auction/6-indexing.md | 28 ++++++++--------- docs/3.tutorials/auction/7-factory.md | 26 ++++------------ 10 files changed, 68 insertions(+), 89 deletions(-) diff --git a/docs/3.tutorials/auction/0-intro.md b/docs/3.tutorials/auction/0-intro.md index d857c67e61a..dedb3df4462 100644 --- a/docs/3.tutorials/auction/0-intro.md +++ b/docs/3.tutorials/auction/0-intro.md @@ -9,22 +9,21 @@ import TabItem from '@theme/TabItem'; Welcome! In this guide we will help you navigate NEAR tech stack, so you can build Web3 applications from start to finish in no-time. -We'll start from a simple auction contract and slowly build on top of it a full Web3 application to carry on-chain auctions. +We'll start from a simple auction contract and slowly build on top of it to create a full Web3 application to carry out on-chain auctions. -By the time you finish this tutorial, you will have learned how to use several key primitives and concepts along the way: +By the time you finish this tutorial, you will have learned several key concepts: -- Building and testing a contract -- Deploying, updating and locking a contract -- Creating a frontend to interact with the contract -- Using an indexing API to keep track of the contract's activity -- Creating a factory to deploy new contracts +- [Creating a simple smart contract](./1.1-basic.md) +- [Writing tests for a contract](./1.2-testing.md) +- [Deploying a contract to testnet](./1.3-deploy.md) - + --- @@ -73,8 +72,7 @@ Before starting, make sure to set up your development environment! -We will be using the tool [NEAR CLI](../../4.tools/cli.md) to interact with the blockchain through the terminal, and you can choose between JavaScript or Rust to write the contract. - +We will use [NEAR CLI](../../4.tools/cli.md) to interact with the blockchain through the terminal, and you can choose between JavaScript and Rust to write the contract. --- @@ -96,8 +94,7 @@ This series will touch on different level of the NEAR tech stack. Each section w 2. Easily query on-chain data (soon): Use open APIs to keep track of the users and their bidding price #### 3. Factory -1. Creating a factory: Allow users to easily deploy and initialize their own auction contracts - +1. Creating a factory (soon): Allow users to easily deploy and initialize their own auction contracts --- @@ -105,15 +102,15 @@ This series will touch on different level of the NEAR tech stack. Each section w Ready to start? Let's jump to the [The Auction Contract](./1.1-basic.md) and begin your learning journey! +--- + :::note Versioning for this article - near-cli: `0.12.0` -- near-sdk-js: `2.0.0` -- near-sdk-rs: `5.1.0` -- near-workspaces-js: `3.5.0` -- node: `21.6.1` -- near-workspaces-rs: `0.10.0` - rustc: `1.78.0` +- cargo: `1.80.1` - cargo-near: `0.6.2` +- rustc: `1.78.0` +- node: `21.6.1` ::: \ No newline at end of file diff --git a/docs/3.tutorials/auction/1.1-basic.md b/docs/3.tutorials/auction/1.1-basic.md index ecc7ac27d69..4fb8ed22a14 100644 --- a/docs/3.tutorials/auction/1.1-basic.md +++ b/docs/3.tutorials/auction/1.1-basic.md @@ -7,7 +7,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {Github, Language} from "@site/src/components/codetabs" -In this section, we will analyze a simple auction contract, which allows users to place bids and track the highest bidder. After, we will cover how to test the contract, as well as how to deploy it on the testnet. +In this section, we will analyze a simple auction contract, which allows users to place bids and track the highest bidder. After, we will cover how to test the contract, as well as how to deploy it on `testnet`. :::info Documentation @@ -236,7 +236,7 @@ Second, the function is marked as `payable`, this is because by default **functi Notice that the function can access information about the environment in which it is running, such as who called the function (`predecessor account`), how much tokens they attached as deposit (`attached deposit`), and the approximate `unix timestamp` at which the function is executing (`block timestamp`). #### Token Transfer -The function finishes by creating a `Promise` to transfer tokens to the previous bidder. This token amount will be deducted immediately, and transfer in the next block, after the current function has finished executing. +The function finishes by creating a `Promise` to transfer tokens to the previous bidder. This token amount will be deducted immediately and transferred in the next block after the current function has finished executing. Note that on the first bid the contract will send 1 yoctonear to itself, this is fine as we can safely assume that the contract will have the lowest denomination of $NEAR available to send to itself. @@ -261,4 +261,4 @@ You can read more about the environment variables, payable functions and which a ## Conclusion -In this part of the tutorial, we've seen how a smart contract stores data, mutates the stored data and views the data. In the next part, we will cover how to test the contract, so we can ensure it works as expected before deploying it to the testnet. \ No newline at end of file +In this part of the tutorial, we've seen how a smart contract stores data, mutates the stored data, and views the data. In the next part, we will cover how to test the contract, so we can ensure it works as expected before deploying it to `testnet`. diff --git a/docs/3.tutorials/auction/1.2-testing.md b/docs/3.tutorials/auction/1.2-testing.md index 20b03a31c0f..b21413fa87c 100644 --- a/docs/3.tutorials/auction/1.2-testing.md +++ b/docs/3.tutorials/auction/1.2-testing.md @@ -13,7 +13,7 @@ Here, we will focus on the sandbox testing, as it enables to deploy the contract :::info unit testing -Unit tests are built-in in the language, and used to test the contract functions individually. These tests work well when little context is required. However, they cannot test chain interactions - like sending accounts $NEAR tokens - since they need to be processed by the network. +Unit tests are built into the language and are used to test the contract functions individually. These tests work well when little context is required. However, they cannot test chain interactions - like sending accounts $NEAR tokens - since they need to be processed by the network. ::: @@ -45,7 +45,7 @@ The first thing our test does is to create multiple accounts with 10 $NEAR token ## Contract Initialization -To initialize the contract the contract's account calls itself, invoking the `init` function with an `end_time` set to 60 seconds in the future. +To initialize, the contract's account calls itself, invoking the `init` function with an `end_time` set to 60 seconds in the future. @@ -204,4 +204,4 @@ All tests should pass, and you should see the output of the tests in the console In this part of the tutorial, we've seen how to use our sandbox testing environment to test the contract. We've tested the contract's initialization, biding, and time advancement. -You are now ready to move to the next section, in which we will deploy the contract to the testnet and interact with it through the CLI. \ No newline at end of file +You are now ready to move to the next section, where we will deploy the contract to `testnet` and interact with it through the CLI. diff --git a/docs/3.tutorials/auction/1.3-deploy.md b/docs/3.tutorials/auction/1.3-deploy.md index 685207fa356..955c9a3ff33 100644 --- a/docs/3.tutorials/auction/1.3-deploy.md +++ b/docs/3.tutorials/auction/1.3-deploy.md @@ -30,7 +30,7 @@ near create --useFaucet Replace `` with the name you want to give to your account, and make sure it ends with `.testnet`. -The account will be created with **10 NEAR** (this are test tokens). +The account will be created with **10 NEAR** (these are test tokens). :::info Testnet Faucet @@ -110,7 +110,7 @@ For the `get_highest_bid` function, we don't need to specify which user is calli ## Conclusion -We have now seen how to deploy a contract to the testnet and interact with it using the NEAR CLI. +We have now seen how to deploy a contract to `testnet` and interact with it using the NEAR CLI. A word of advice before moving forward. When people learn how to use the CLI, they get lazy and start testing new contract features directly on the testnet. While this is tempting, it is not recommended. diff --git a/docs/3.tutorials/auction/2-locking.md b/docs/3.tutorials/auction/2-locking.md index 96668b19ea6..a89952cc2e5 100644 --- a/docs/3.tutorials/auction/2-locking.md +++ b/docs/3.tutorials/auction/2-locking.md @@ -70,7 +70,7 @@ The `claim` method should only be callable when the auction is over, can only be If we update our contract then we should update our tests accordingly. For example, the tests will now need to add `auctioneer` to the arguments of `init`. -We will also now also test the `claim` method. The test will check that the `auctioneer` account has received the correct amount of $NEAR tokens. +We will now also test the `claim` method. The test will check that the `auctioneer` account has received the correct amount of $NEAR tokens. @@ -98,9 +98,9 @@ Note that the test doesn't check that the auctioneer has exactly 12 $NEAR since ## Deploying and locking -Go ahead and test, build and deploy your new contract, as in part 1. Remember to add the "auctioneer" argument when initializing. +Go ahead and test, build, and deploy your new contract, as in part 1. Remember to add the `auctioneer` argument when initializing. -Now we have the claim method, we can deploy the contract without keys. Later we will introduce a factory contract that deploys auctions to a locked account, but for now, we can manually remove the keys using the CLI to lock the account. +Now that we have the `claim` method, we can deploy the contract without keys. Later, we will introduce a factory contract that deploys auctions to a locked account, but for now, we can manually remove the keys using the CLI to lock the account. ``` near account delete-keys @@ -116,6 +116,6 @@ Be extra careful to delete the keys from the correct account as you'll never be ## Conclusion -In this part of the tutorial, we learned how to lock a contract by creating a new method to claim tokens, specify an account on initialization that will claim the tokens and how to delete the contract account's keys with the CLI. +In this part of the tutorial, you learned how to lock a contract by creating a new method to claim tokens, specify an account on initialization that will claim the tokens, and how to delete the contract account's keys with the CLI. In the [next part](./3-nft.md), we'll add a prize to the auction by introducing a new primitive; spoiler, the primitive is an NFT. We'll look at how to use non-fungible token standards to send NFTs and interact with multiple interacting contracts in sandbox testing. \ No newline at end of file diff --git a/docs/3.tutorials/auction/3-nft.md b/docs/3.tutorials/auction/3-nft.md index 1794842b888..3590afe0cee 100644 --- a/docs/3.tutorials/auction/3-nft.md +++ b/docs/3.tutorials/auction/3-nft.md @@ -43,7 +43,7 @@ When we create an auction we need to list the NFT. To specify which NFT is being ## Transferring the NFT to the winner -When the auction is ended - by calling the method `claim` - the NFT needs to be transferred to the highest bidder. Operations regarding NFTs live on the NFT contract, so we make a cross-contract call to the NFT contract telling it to swap the owner of the NFT to the highest bidder. The method on the NFT contract to do this is `nft_transfer`. +When the method `claim` is called the NFT needs to be transferred to the highest bidder. Operations regarding NFTs live on the NFT contract, so we make a cross-contract call to the NFT contract telling it to swap the owner of the NFT to the highest bidder. The method on the NFT contract to do this is `nft_transfer`. diff --git a/docs/3.tutorials/auction/4-ft.md b/docs/3.tutorials/auction/4-ft.md index ed13cd4cbdf..e2d6d8bc463 100644 --- a/docs/3.tutorials/auction/4-ft.md +++ b/docs/3.tutorials/auction/4-ft.md @@ -420,7 +420,7 @@ However, this architecture could be deemed less secure since if a bad actor were ## Conclusion -In this section, we learned a lot about fungible tokens: how to send and receive FTs in a smart contract, and then in sandbox tests how to deploy and initialize an FT contract, how to register a user in an FT contract, and send them some tokens, how to attach FTs to a smart contract call and finally how to view the FT balance of a user. With that, we now have our completed auction smart contract! +In this section, you learned a lot about fungible tokens: how to send and receive FTs in a smart contract, and then in sandbox tests how to deploy and initialize an FT contract, how to register a user in an FT contract, and send them some tokens, how to attach FTs to a smart contract call and finally how to view the FT balance of a user. With that, we now have our completed auction smart contract! Taking a further step back we've taken a very simple auction contract and transformed it into a more production contract with thorough testing. To improve the auction we learned how to make a contract more secure by locking it, added a prize by introducing NFTs, and enabled auctioneers to host auctions with FTs. diff --git a/docs/3.tutorials/auction/5-frontend.md b/docs/3.tutorials/auction/5-frontend.md index 274c4f3e3ff..2cfbfb351e9 100644 --- a/docs/3.tutorials/auction/5-frontend.md +++ b/docs/3.tutorials/auction/5-frontend.md @@ -62,7 +62,7 @@ For starters, let's take a look at how the code in the frontend is structured by ## Specifying the contract -We have a config file that specifies the contract name of the auction that the frontend will interact with. The example given is a pre-deployed contract from part 4 of the tutorial. The example contract is set up to accept bids in DAI (dai.fakes.testnet), has an NFT token pre-minted and owned by the contract account, and has an end auction time far in the future. Feel free to change the specified contract to your own auction that you deploy. +We have a config file that specifies the contract name of the auction that the frontend will interact with. The example given is a pre-deployed contract from [part 4 of the tutorial](4-ft.md). The example contract is set up to accept bids in DAI (dai.fakes.testnet), has an NFT token pre-minted and owned by the contract account, and has an end auction time far in the future. Feel free to change the specified contract to your own auction that you deploy. + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L129" + start="129" end="129" /> @@ -132,8 +132,8 @@ When we display the latest bid, instead of just showing the bid amount directly + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L75-L93" + start="75" end="93" /> --- @@ -144,8 +144,8 @@ We want to know the highest bid at all times, someone else could have placed a h + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L41-L55" + start="41" end="55" /> --- @@ -155,7 +155,7 @@ The contract stores the end time of the auction in the number of nanoseconds sin --- @@ -166,8 +166,8 @@ We want to show what NFT is being auctioned. To do this we will call `nft_token` + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L57-L73" + start="57" end="73" /> Note that this effect will only run once the `auctionInfo` updates because we first need the NFT contract ID and token ID from `auctionInfo` to make a valid call to `nft_token`. @@ -190,8 +190,8 @@ To make a bid we call the `ft_transfer_call` method on the FT contract which sub + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L95-L105" + start="95" end="105" /> @@ -207,14 +207,14 @@ Once the auction is over (the current time is greater than the end time) the auc + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/index.js#L107-L114" + start="107" end="114" /> --- ## Conclusion -In this part of the tutorial, we have implemented a simple frontend for a NEAR contract. Along the way we have learned how to use the wallet selector to sign the user in and out, how to view the contract’s state, how to sign and send transactions, and use ft_transfer_call from a frontend. +In this part of the tutorial, we have implemented a simple frontend for a NEAR contract. Along the way, you have learned how to use the wallet selector to sign the user in and out, how to view the contract’s state, how to sign and send transactions, and use `ft_transfer_call` from a frontend. -Whilst we can see the highest bid we may want to see the auction's bidding history. Since the contract only stores the most recent bid we need to use an indexer to pull historical data. In the [next part](./6-indexing.md) of the tutorial, we'll look at quering historical data using an API endpoint. +While we can see the highest bid, we may want to see the auction's bidding history. Since the contract only stores the most recent bid, we need to use an indexer to pull historical data. In the [next part](./6-indexing.md) of the tutorial, we'll look at querying historical data using an API endpoint. diff --git a/docs/3.tutorials/auction/6-indexing.md b/docs/3.tutorials/auction/6-indexing.md index 7863fb3ff56..dd4964de609 100644 --- a/docs/3.tutorials/auction/6-indexing.md +++ b/docs/3.tutorials/auction/6-indexing.md @@ -6,25 +6,21 @@ sidebar_label: Indexing historical data import {Github, Language} from "@site/src/components/codetabs" -TODO: change github to main when merged - In our frontend, we can easily display the previous bid since it's stored in the contract's state. However, we're unable to see previous bids to the auction. An indexer is used to fetch historical data from the blockchain and store it in a database. Since indexers can take a while to set up and can be expensive to run, we will use a pre-defined API point provided by NEAR Blocks to query an indexer they run that will fetch us the data we need. --- ## NEAR Blocks API key -NEAR Blocks provides a free tier that allows you to make 6 calls per minute, this will be plenty for our usecase. To get an API key head over to https://dash.nearblocks.io/user/overview and sign up. Once signed go to `API Keys` then click `Add key` and give it whatever name you like. +NEAR Blocks provides a free tier that allows you to make 6 calls per minute, which will be plenty for our use case. To get an API key, head over to https://dash.nearblocks.io/user/overview and sign up. Once signed go to `API Keys` then click `Add key` and give it whatever name you like. -We'll create a new file named `.env.local` to store our API key. Swap the API key in the example with your own. +We'll create a new file named `.env.local` to store our API key. - - - +```env +API_KEY=YOUR_API_KEY_GOES_HERE +``` -We put the API key in a `.env.local` file so the user cannot access it in the browser and use our key elsewhere. We should also add `.env.local` to our `.gitignore` file so it is not pushed to GitHub. However, for the purposes of this tutorial, it has been omitted. +We put the API key in a `.env.local` file so the user cannot access it in the browser and use our key elsewhere. We should also add `.env.local` to our `.gitignore` file so it is not pushed to GitHub. --- @@ -34,8 +30,8 @@ NextJS allows us to easily create server-side functions with API routes. We need + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/api/getBidHistory.js#L1-L13" + start="1" end="13" /> Here we are retrieving the auction contract ID and fungible token contract ID from the API route call and then calling the NEAR Blocks API. This specific API endpoint allows us to retrieve transactions made to a specific contract calling a specific method. Some details are worth discussing here: @@ -54,8 +50,8 @@ The API call itself does not filter out invalid transactions. A transaction may + url="https://github.com/near-examples/auctions-tutorial/blob/main/frontend/src/pages/api/getBidHistory.js#L15-L43" + start="15" end="43" /> --- @@ -66,7 +62,7 @@ In our main page, we'll define a function to call the API route we just created. @@ -82,4 +78,4 @@ You may like to explore NEAR Blocks APIs further to see what other data you can In this short part of the tutorial, we've added the ability to display the previous 5 valid bids made to the auction contract. In doing this we learned how to interact with the NEAR Blocks APIs to retrieve historical data from the blockchain and how to make server-side calls in NextJS to not expose our API key. Now we have a pretty good frontend that displays all the information we need about the auction contract. -In the [final part](./7-factory.md) of this tutorial series we'll learn how to deploy a factory contract - a contract that deploys other contracts - to make it easier for anyone to launch a new auction. \ No newline at end of file +In the [final part](./7-factory.md) of this tutorial series you'll learn how to deploy a factory contract - a contract that deploys other contracts - to make it easier for anyone to launch a new auction. diff --git a/docs/3.tutorials/auction/7-factory.md b/docs/3.tutorials/auction/7-factory.md index 8df903d04a1..95ce83a7f74 100644 --- a/docs/3.tutorials/auction/7-factory.md +++ b/docs/3.tutorials/auction/7-factory.md @@ -6,8 +6,6 @@ sidebar_label: Auction factory import {Github, Language} from "@site/src/components/codetabs" -TODO change code once branch is merged - Since an auction contract hosts a single auction, each time you would like to host a new auction you will need to deploy a new contract. Rather than finding the compiled WASM file, creating a new account, deploying the contract, and then initializing it each time, you can use a factory contract to do this for you. Luckily for us, there is already a [factory contract example](https://github.com/near-examples/factory-rust)! We will fork this example and slightly modify it to suit our use case. If you would like to learn more about how the factory contract works, you can take a look at the [associated documentation](https://docs.near.org/tutorials/examples/factory#generic-factory). @@ -20,7 +18,7 @@ The factory example only comes in rust since, currently, the JavaScript SDK does In the current example, the factory contract deploys the donation contract example. We will change this to deploy our auction contract instead. -Firstly, we'll need the compiled auction contract WASM file. You can get this by running the following command in part four of `contract-rs` +Firstly, we'll need the compiled auction contract WASM file. You can get this by running the following command in [part four](4-ft.md) of `contract-rs` ``` cargo near build @@ -53,7 +51,7 @@ The method to deploy a new contract is specific to the contract being deployed ( url="https://github.com/near-examples/auctions-tutorial/blob/add-factory/factory/src/deploy.rs#L9-L82" start="9" end="82" /> -In this fork, we have also removed the option to add an access key to the contract account since, as discussed in part 2, we want auctions to be locked. +In this fork, we have also removed the option to add an access key to the contract account since, as discussed in [part 2](2-locking.md), we want auctions to be locked. --- @@ -77,15 +75,9 @@ You can now use the factory to deploy new auction contracts, here is an example near contract call-function as-transaction auction-factory.testnet deploy_new_auction json-args '{"name": "new-auction", "end_time": "3000000000000000000", "auctioneer": "pivortex.testnet", "ft_contract": "dai.fakes.testnet", "nft_contract": "nft.examples.testnet", "token_id": "7777", "starting_price": "1000000000000000000"}' prepaid-gas '100.0 Tgas' attached-deposit '1.6 NEAR' ``` -Note that we attach 1.6 $NEAR to the call to cover the storage costs of deploying the new auction. Storage cost on NEAR is 1 $NEAR per 100 kb and our auction contract is around 140 kb, but we'll add a little to cover storage used on initialization. - -
- - Deposit and storage costs - - We attach 1.6 $NEAR to the call to cover the storage costs of deploying the new auction. Storage cost on NEAR is 1 $NEAR per 100 kb and our auction contract is around 140 kb, but we'll add a little to cover storage used on initialization. - -
+:::info Deposit and storage costs +Note that we attach 1.6 $NEAR to the call to cover the storage costs of deploying the new auction. The storage cost on NEAR is 1 $NEAR per 100 kb, and our auction contract is around 140 kb, but we'll add a little to cover the storage used on initialization. +::: The command results in a fresh auction contract being deployed and initialized at `new-auction.auction-factory.testnet`. @@ -93,14 +85,8 @@ The command results in a fresh auction contract being deployed and initialized a ## Conclusion -In this part of the tutorial, we have learned how to fork and modify the factory contract example to deploy our auction contracts. We have also learned how to use the factory to deploy new auction contracts. If you're feeling adventurous you could create a frontend to interact with the factory contract to make it even easier to deploy new auctions. If you do so feel free to share it in our developer [Telegram](https://t.me/neardev) or [Discord](https://discord.gg/vMGH5QywTH) channels! +In this part of the tutorial, you have learned how to fork and modify the factory contract example to deploy our auction contracts. You have also learned how to use the factory to deploy new auction contracts. If you're feeling adventurous you could create a frontend to interact with the factory contract to make it even easier to deploy new auctions. If you do so feel free to share it in our developer [Telegram](https://t.me/neardev) or [Discord](https://discord.gg/vMGH5QywTH) channels! And with that, this tutorial series is over, congratulations! Through this tutorial, we've built an auction contract and iterated on it adding improvements and extending its functionality, created a frontend to interact with the auction, used an API to index previous bids, and deployed a factory contract to make deploying new auctions easier. Along the way we've learned a great deal about NEAR, we learned about the anatomy of smart contracts, how to lock a contract to make it more secure, how to use primitives such as NFTs and FTs, how to perform cross-contract calls, how to use wallets from a frontend to interact with the blockchain and display data about a smart contract, how to pull historical data from the blockchain using an API, how to deploy contracts from other contracts and a lot of other little bits that will help you in the future. That's a lot, so once again congratulations! - ---- - -## What's next? - -TODO add some sort of what they can do from here, particpate in hackathon, build own project, they may be a dev working for someone else, component or page for this...? \ No newline at end of file