diff --git a/docs/3.tutorials/auction/0-intro.md b/docs/3.tutorials/auction/0-intro.md index e42a596e7a..6915a24e7f 100644 --- a/docs/3.tutorials/auction/0-intro.md +++ b/docs/3.tutorials/auction/0-intro.md @@ -13,17 +13,16 @@ We'll start from a simple auction contract and slowly build on top of it to crea By the time you finish this tutorial, you will have learned several concepts and how to use many key privitives along the way: -- [Creating a simple smart contract](./1.1-basic.md) +- [Creating a simple smart contract](./1.1-basic.md#the-contracts-state) - [Writing tests for a contract](./1.2-testing.md) - [Deploying a contract to testnet](./1.3-deploy.md) - - +- [Locking a contract](./1.3-deploy.md#locking-the-contract) +- [Creating a frontend to interact with the contract](./2.1-frontend.md) +- [Using an indexing API to view historical bids](./6-indexing.md) +- [Making cross-contract calls](./3.1-nft.md#transferring-the-nft-to-the-winner) +- [Using Non-Fungible Tokens](./3.1-nft.md) +- [Using Fungible Tokens](./3.2-ft.md) +- [Modifying a factory contract to deploy your own contracts](./4-factory.md) --- @@ -80,21 +79,23 @@ We will be using [NEAR CLI](../../4.tools/cli.md) to interact with the blockchai This series will touch on different level of the NEAR tech stack. Each section will be independent of the previous one, so feel free to jump into the section that interests you the most. -#### 1. Smart Contract +#### 1. Smart contracts 101 1. [The Auction Contract](./1.1-basic.md): We cover a simple auction smart contract 2. [Testing the Contract](./1.2-testing.md): Learn how to test your contract in a realistic environment 3. [Deploying the Contract](./1.3-deploy.md): Deploy your contract to the NEAR blockchain -4. Updating and Locking a Contract (soon): Discover what it means to lock a contract -5. Giving an NFT to the Winner (soon) : Give the highest bidder an NFT to signal their win -6. Integrating Fungible Tokens (soon) : Allow people to use fungible tokens to bid (e.g. stable coins) -#### 2. Frontend +#### 2. Frontends 101 + +1. [Creating the frontend](./2.1-frontend.md): Lets learn how to connect a frontend with your smart contract +2. [indexing historical data](./2.2-indexing.md): Use APIs to keep track of historical bids -1. Creating the frontend (soon): Lets learn how to connect a frontend with your smart contract -2. Easily query on-chain data (soon): Use open APIs to keep track of the users and their bidding price +#### 3. Using Primitives +1. [Giving an NFT to the Winner](./3.1-nft.md): Give the highest bidder an NFT to signal their win +2. [Integrating Fungible Tokens](./3.2-ft.md): Allow people to use fungible tokens to bid (e.g. stable coins) +3. [Updating the frontend](./3.3-new-frontend.md): Update the frontend to use the extended functionality of the contract. -#### 3. Factory -1. Creating a factory (soon): Allow users to easily deploy and initialize their own auction contracts +#### 3. Auction Factory +1. [Creating a factory](./4-factory.md): Allow users to easily deploy and initialize their own auction contracts --- diff --git a/docs/3.tutorials/auction/1.2-testing.md b/docs/3.tutorials/auction/1.2-testing.md index 8ad2758ab2..5cf5d8944c 100644 --- a/docs/3.tutorials/auction/1.2-testing.md +++ b/docs/3.tutorials/auction/1.2-testing.md @@ -134,7 +134,7 @@ When testing we should also check that the contract does not allow invalid calls @@ -159,7 +159,7 @@ After which the auction can now be claimed. Once claimed the test checks that th diff --git a/docs/3.tutorials/auction/1.3-deploy.md b/docs/3.tutorials/auction/1.3-deploy.md index 8bac918deb..89eebfe9d6 100644 --- a/docs/3.tutorials/auction/1.3-deploy.md +++ b/docs/3.tutorials/auction/1.3-deploy.md @@ -114,7 +114,7 @@ We are now ready to start bidding by calling the `bid` function on the contract. ```bash # call the contract to bid -near call bid --accountId --amount 1 +near call bid --accountId --amount 1 # get the highest bid near view get_highest_bid diff --git a/docs/3.tutorials/auction/3.1-nft.md b/docs/3.tutorials/auction/3.1-nft.md index 3acdb94169..eabe0e05a5 100644 --- a/docs/3.tutorials/auction/3.1-nft.md +++ b/docs/3.tutorials/auction/3.1-nft.md @@ -15,7 +15,6 @@ No one will enter an auction if there's nothing to win, so let's add a prize. Wh When we create an auction we need to list the NFT. To specify which NFT is being auctioned off we need the account ID of the NFT contract and the token ID of the NFT. We will specify these when the contract is initialized; amend `init` to add `nft_contract` and `token_id` as such: - @@ -85,6 +84,38 @@ In our contract, we perform no checks to verify whether the contract actually ow --- +## Displaying the contract object + +Since we are now dealing with more information in our contract, instead of implementing a function to display each field we'll create a function to display the entire contract object. Since the contract doesn't include large complex data structures like a map displaying the contract state in its entirety is easily done. + + + + + + + + + + + + + + We add the `serilizers` macro to enable json serialization so the object as a whole can easily be displayed to the frontend without having to output each field individually. + + + + + + + + + ## Testing with multiple contracts In our tests, we're now going to be using two contracts; the auction contract and an NFT contract. Sandbox testing is great as it allows us to test multiple contracts in a realistic environment. @@ -171,8 +202,8 @@ After `claim` is called, the test should verify that the auction winner now owns If you would like to interact with the new contract via the CLI you can mint an NFT from a pre-deployed NFT contract -``` -near contract call-function as-transaction nft.examples.testnet nft_mint json-args '{"token_id": "TYPE_A_UNIQUE_VALUE_HERE", "receiver_id": "", "metadata": { "title": "GO TEAM", "description": "The Team Goes", "media": "https://bafybeidl4hjbpdr6u6xvlrizwxbrfcyqurzvcnn5xoilmcqbxfbdwrmp5m.ipfs.dweb.link/", "copies": 1}}' prepaid-gas '100.0 Tgas' attached-deposit '0.1 NEAR' sign-as network-config testnet +```bash +near call nft.examples.testnet nft_mint '{"token_id": "TYPE_A_UNIQUE_VALUE_HERE", "receiver_id": "", "metadata": { "title": "GO TEAM", "description": "The Team Goes", "media": "https://bafybeidl4hjbpdr6u6xvlrizwxbrfcyqurzvcnn5xoilmcqbxfbdwrmp5m.ipfs.dweb.link/", "copies": 1}}' --accountId --deposit 0.1 ``` You can also just buy an NFT with testnet $NEAR on a testnet marketplace like [Mintbase](https://testnet.mintbase.xyz/explore/new/0). diff --git a/docs/3.tutorials/auction/3.2-ft.md b/docs/3.tutorials/auction/3.2-ft.md index 823843a2b2..2bf5c455c1 100644 --- a/docs/3.tutorials/auction/3.2-ft.md +++ b/docs/3.tutorials/auction/3.2-ft.md @@ -118,11 +118,11 @@ When we want to return the funds to the previous bidder we now make a cross-cont + url="https://github.com/near-examples/auctions-tutorial/blob/reorg-auction/contract-ts/03-bid-with-fts/src/contract.ts#L45-L51" + start="45" end="51" /> + start="68" end="71" /> In JavaScript, we have to return the Promise to transfer the FTs but we also need to return how much to refund the user. So after transferring the FTs, we make a `callback` to our own contract to resume the contract flow. Note that the callback is private so it can only be called by the contract. We return 0 because the method uses all the FTs in the call. @@ -150,7 +150,7 @@ When we want to return the funds to the previous bidder we now make a cross-cont - If the calls was to fail the FT contract will automatically refund the user their FTs. + If the call was to fail the FT contract will automatically refund the user their FTs.
@@ -173,8 +173,8 @@ When the auction is complete we need to send the fungible tokens to the auctione + url="https://github.com/near-examples/auctions-tutorial/blob/reorg-auction/contract-ts/03-bid-with-fts/src/contract.ts#L61-L65" + start="61" end="65" /> In JavaScript, since we need to return each cross-contract call we chain the NFT and FT transfer. @@ -377,14 +377,14 @@ When deploying the contract make sure to specify the FT contract `dai.fakes.test The auction contract will need to be registered as well, you could do this by sending it an arbitrary amount of $DAI from the faucet or you can just register it since it doesn't need any FTs. You should also register the auctioneer, -``` -near contract call-function as-transaction dai.fakes.testnet storage_deposit json-args '{"account_id": ""}' prepaid-gas '100.0 Tgas' attached-deposit '0.1 NEAR' +```bash +near call dai.fakes.testnet storage_deposit '{"account_id": ""}' --accountId --deposit 0.1 ``` Now you can go ahead and place a bid. DAI has 18 decimals meaning that 1 $DAI is made up of 10^24 smallest units. To make a bid of 2 $DAI you can use the command: -``` -near contract call-function as-transaction dai.fakes.testnet ft_transfer_call json-args '{"receiver_id": "", "amount": "2000000000000000000", "msg": ""}' prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' +```bash +near call dai.fakes.testnet ft_transfer_call '{"receiver_id": "", "amount": "2000000000000000000", "msg": ""}' --accountId --depositYocto 1 ``` ## Auction architecture @@ -423,6 +423,6 @@ However, this architecture could be deemed less secure since if a bad actor were 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. +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 add a prize by introducing NFTs, and enabled auctioneers to host auctions with FTs. -Up to now, we've just interacted with the contract via the CLI. In the [next part](./5-frontend.md), we'll learn the basics of creating frontends for NEAR contracts by creating a simple frontend for our auction contract so users can seamlessly interact with it. \ No newline at end of file +In the [next part of the tutorial](./3.3-new-frontend.md), we're going to update the frontend to interact with the new features of the contract. \ No newline at end of file diff --git a/docs/3.tutorials/auction/3.3-new-frontend.md b/docs/3.tutorials/auction/3.3-new-frontend.md index 6f36cdabb9..c0a0ba8d07 100644 --- a/docs/3.tutorials/auction/3.3-new-frontend.md +++ b/docs/3.tutorials/auction/3.3-new-frontend.md @@ -7,215 +7,94 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {Github, Language} from "@site/src/components/codetabs" -Now that we have successfully created a contract, it's time to build a frontend to provide a user-friendly interface for interacting with it. Up until now, we have been using the CLI to send transactions and view the contract's state. However, frontends offer a more intuitive way for end users to interact with the contract. They can display all the relevant information in one place, allow users to make calls with a simple button click, and only require a wallet as a prerequisite. +Now we've updated the contract to include an NFT as a reward and changed the contract such that it accepts bids in fungible tokens, we need to update the frontend accordingly. -## Starting the frontend +## Getting the data from the contract -Before we look at the code let's start up the frontend and have a peak at what it looks like. Feel free to interact with the application and place some bids. To place bids you will need to retrieve some testnet DAI from the [faucet](https://near-faucet.io/). - -Navigate to the `frontend` directory then install dependencies and start the frontend. - - - - - - ``` - yarn install - yarn dev - ``` - - - - - - ``` - npm install - npm run dev - ``` - - - - - - -## Frontend structure - -In our frontend directory, we have a simple Next.js frontend that we'll walk through to understand the basics of creating a frontend for a NEAR smart contract. - -For starters, let's take a look at how the code in the frontend is structured by doing a quick overview of the important files. - -| File | Description | -|----------------------------------|---------------------------------------------------------------------------------| -| **_app.js** | Responsible for rending the page, initiates the wallet object and adds it to global context | -| **index.js** | The main page where most of the projects components are loaded into and contains most of the logic for the application like viewing the state of the contract and logic for placing a bid | -| **near.js** | Contains the wallet class that has methods to interact with the wallet and blockchain | -| **context.js** | Holds the global context - the wallet object and the signed in account ID - that can be accessed anywhere | -| **config.js** | Specifies the account ID of the auction contract | -| **Navigation.jsx** | A component that contains a button to sign users in and out of wallets | -| **Bid.jsx** | A component allowing a user to make a bid | -| **LastBid.jsx** | A component that displays the highest bid and when the highest bid will next refresh | -| **AuctionItem.jsx** | A component that displays information about the NFT being auctioned | -| **Timer.jsx** | A component that shows how long till the auction is over, or, if over, displays a button to claim the auction and then states the auction is over | - ---- - -## 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](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. +Now we have a function to output the whole contract state we will call this function in our frontend - - - ---- - -## Setting up wallets - -To be able to fully interact with the contract - send bids or claim the auction - you'll need a `wallet` to sign transactions. Wallets securely store your private keys and allow you to sign transactions without exposing your private key to the frontend. The wallet selector allows users to choose between a selection of wallets. - -We abstract the wallet selector in our `near.js` file by exposing methods to complete various tasks. Feel free to [explore the file](https://github.com/near-examples/auctions-tutorial/blob/reorg-auction/frontend/src/wallets/near.js) to understand how the wallet selector is implemented. - -We implement a sign-in and sign-out button in the navigation component to call the respective methods in the `near.js` file. When a wallet is signed in a function call access key is created. This allows the frontend to sign nonpayable transactions on behalf of the user, to the specified contract, without requiring the user to sign each transaction in the wallet; this allows for a better user experience. However, in this example, the main transaction we'll send is to make bids, which is payable so the wallet will prompt the user to sign each transaction. - - - - + -We add the wallet and the account ID that is signed in to the global context making it easier to access anywhere in the application. - - - - - +This call will deliver us the contract Ids of the FT and NFT contracts along with the token Id of the NFT. We will then use this information to call the `ft_metadata` and `nft_token` methods on the FT and NFT contracts respectively to get information about the FT and NFT. --- -## Displaying the highest bid - -To get all the information about the auction we call the method `get_auction_info`. This will be used to display the highest bidder, the auction end time, the NFT contract ID and token ID, and FT contract IDs. - - - - - - -In the wallet file, you'll see that we make a query to the RPC provider, since we are not signing a transaction the wallet isn't required here. Here we are using https://rpc.testnet.near.org but note there are [many different providers available](../../5.api/rpc/providers.md). We are querying the RPC with optimistic finality, which queries the latest block recorded on the node. Alternatively, one could use final finality where the block has been validated by at least 66% of the validators on the network but this will provide slightly delayed information (only by a couple of seconds). - -We then pass the information about the highest bidder into the `LastBid` component to display the bid amount and the bidder's account ID. - - - - - +## Displaying the NFT -When we display the latest bid, instead of just showing the bid amount directly we divide the amount by the decimals of the FT. In this example, we are using DAI which has 18 decimals meaning that 1 DAI equals 10^18 units. We also display information about the token that is being used. We get this information from the FT contract by calling the `ft_metadata` method (remember that the FT contract ID is stored on the auction contract). +We want to show what NFT is being auctioned. To do this we will call `nft_token` on the NFT contract to get the NFT metadata. To call this method we need to specify the NFT `contractId` and the `token_id`, which can be found in the auction information. `nft_token` also returns the owner of the NFT, so we'll check this against the contract account to verify that the auction is valid. + url="https://github.com/near-examples/auctions-tutorial/blob/reorg-auction/frontends/03-frontend/src/pages/index.js#L57-L73" + start="57" end="73" /> ---- - -## Updating the highest bid +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`. -We want to know the highest bid at all times, someone else could have placed a higher bid since the page was loaded. To solve this we fetch the contract information every 5 seconds using `setInterval`. +In a new component named `AuctionItem` we display the NFT image, name, and description. - + +Note that an image caching service is used to display the NFT image for better performance. + --- -## Auction end time +## Fetching FT information -The contract stores the end time of the auction in the number of nanoseconds since the Unix epoch (1 January 1970 00:00:00 UTC). To make this look nicer we will display the time left in days, hours, minutes, and seconds. +Using the FT contract ID from the auction information, we can call the `ft_metadata` method on the FT contract to get information about the fungible token that is being used for the auction. - + +We set the FT image, symbol, icon, and decimals in state. We use the decimals to format the amount of tokens being bid. In the case of DAI it divides the amount by 10^18. The reverse process is used when making a bid, the bid amount is multiplied by 10^18 before being sent to the contract. + --- -## Displaying the NFT +## Bidding with FTs -We want to show what NFT is being auctioned. To do this we will call `nft_token` on the NFT contract to get the NFT metadata. To call this method we need to specify the NFT `contractId` and the `token_id`, which can be found in the auction information. `nft_token` also returns the owner of the NFT, so we'll check this against the contract account to verify that the auction is valid. +Instead of calling the function `bid` on the contract we now call the `ft_transfer_call` function on the FT contract. This function transfers the FTs to the auction contract and calls the `ft_on_transfer` on the auction contract. - - -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`. - -In the `AuctionItem` component we display the NFT image, name, and description. - - - + url="https://github.com/near-examples/auctions-tutorial/blob/reorg-auction/frontends/03-frontend/src/pages/index.js#L95-L105" + start="95" end="105" /> -Note that an image caching service is used to display the NFT image for better performance. - --- -## Making a bid +## Updating the indexing API call -To make a bid we call the `ft_transfer_call` method on the FT contract which subsequently calls `ft_on_transfer` on the auction contract and attaches fungible tokens to the call. +We need to update the API call that fetches historical bids to now index each time `ft_on_transfer` is called on the auction contract from the FT contract. - - - + + -We now multiply the bid amount by the decimals of the FT to get the correct amount to send. Since this method requires a 1 yoctoNEAR deposit the wallet will prompt the user to sign the transaction. - ---- - -## Claiming the auction - -Once the auction is over (the current time is greater than the end time) the auction can be claimed. At this point, the timer will be hidden and a button to claim the auction will be displayed. Once clicked the `claim` method will be called on the auction contract to send the highest bidder the NFT and the auctioneer the FTs. +And now instead of getting the the bid amount from the deposit, it is now retrieved from the calls argument, from `amount`. The case is the same for the account Id of the bidder, from `sender_id`. - + --- ## Conclusion -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. +Ok nice, that didn't take too long. To look back, we updated the frontend to now display the NFT being auctioned, to display bid amounts - both the current and historical bids - in terms of the FT being used, and changed the bidding process to now use FTs. -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. +In the [final section](./4-factory.md) of this mega tutorial we'll create an auction factory contract that is used to deploy and initialize new auction contracts. \ No newline at end of file diff --git a/docs/3.tutorials/auction/4-factory.md b/docs/3.tutorials/auction/4-factory.md index d28646fa57..374dc9fd99 100644 --- a/docs/3.tutorials/auction/4-factory.md +++ b/docs/3.tutorials/auction/4-factory.md @@ -28,17 +28,17 @@ You will find the resulting WASM file in `target/near`; copy this file and use i On initialization, the factory will add the auction contracts WASM, as bytes, to the factory's state. It is more efficient to not store the WASM in the factory's state, however, we may want to update the auction contract if we find a bug or want to add new features. The factory implements a method to update the auction contract - we'll change the name to `update_auction_contract` as this factory will only deploy auction contracts. --- @@ -48,7 +48,7 @@ On initialization, the factory will add the auction contracts WASM, as bytes, to The method to deploy a new contract is specific to the contract being deployed (in the case the contract has custom initialization parameters). We will modify the method to take in the auction contract's initialization parameters. 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. @@ -59,20 +59,20 @@ In this fork, we have also removed the option to add an access key to the contra Build and deploy the factory like you would any other contract, this time without any initialization parameters. -``` +```bash cargo near build ``` then -``` +```bash cargo near deploy without-init-call network-config testnet sign-with-legacy-keychain send ``` You can now use the factory to deploy new auction contracts, here is an example command. -``` -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' +```bash +near call auction-factory.testnet deploy_new_auction '{"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"}' --accountId --deposit '1.6 NEAR' ``` :::info Deposit and storage costs diff --git a/docs/3.tutorials/auction/old-indexing.md b/docs/3.tutorials/auction/old-indexing.md deleted file mode 100644 index 830077f0c2..0000000000 --- a/docs/3.tutorials/auction/old-indexing.md +++ /dev/null @@ -1,75 +0,0 @@ -import {Github, Language} from "@site/src/components/codetabs" - -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 end 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, 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. - -```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. - ---- - -## Calling the API endpoint - -NextJS allows us to easily create server-side functions with API routes. We need to make this API call on the server-side rather than the client side so as to not expose our API key. We'll create a new file in src/pages/api named `getBidHistory.js`. Here we'll define our function to get the bid history. - - - - - -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: - -- We pass the account ID of the auction contract, which is `auction-example.testnet` in the example repo. -- We specify the method name on the auction contract that we want the transactions for, this will be `ft_on_transfer` as it will give all bids made to the auction. -- We pass the fungible token account ID as the sender since we know only transactions from the correct FT contract will be successful. -- We'll receive a JSON object of 25 transactions, ordered by the most recent first. -- We pass our API key to authenticate the request. - ---- - -## Filtering out invalid transactions - -The API call itself does not filter out invalid transactions. A transaction may be rejected for example if the bid is lower than the current highest bid. To check whether a transaction was successful, therefore the bid was valid, we check that the `receipt outcome status` is `true`. If a transaction is valid we store the account ID of the bidder and the amount they bid, gathered from the args of the transaction. We loop through each transaction until we either have 5 valid transactions or we've looped through the whole page of 25. Note that, in our example, if the previous 25 bids were invalid the API will return an empty array. - - - - - ---- - -## Using the API Route - -In our main page, we'll define a function to call the API route we just created. This function will be called as soon as the fungible token account ID is set and each time the page timer reaches zero. - - - - - -The `pastBids` will then be passed into the `Bid` component to be displayed. - ---- - -You may like to explore NEAR Blocks APIs further to see what other data you can retrieve from the blockchain. You can find the documentation at https://api.nearblocks.io/api-docs/ - ---- - -## Conclusion - -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 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. \ No newline at end of file