Doki Doki
Search
K

For developers

You want to build on top of our gachapons? This is the right place to start!
This guide is under construction, don't hesitate to ping Kirienzo on Discord or Telegram if you have some questions, or would like to suggest some improvements for this guide

Note on Old vs New Gachapons

All gachapons that were created before the 2021/08/19 are considered deprecated.
Essentially, all gachapons that were not created by our factory and are not available in the gachapon subgraph (you can use this subgraph for mumbai, Polygon's testnet) will not be covered by this guide.

The Gachapon Control Tower

The factory that creates the Gachapons on demand is called the Control Tower. It's available on the available networks:
  • Polygon mainnet: 0xC15e5C4fe1730562dC866ad9385F652f1D4C43fd
  • Polygon mumbai testnet: 0xf37988C2E343cB2698c31ECbb57d8C86FAb6Fc5D

The Gachapon Interface

All gachapons created by our platform will implement the IGachapon.sol interface, meaning that it doesn't matter which ones you want to communicate with, they will all have the same entry-points. You can find the Gachapon.sol file and its ABI here: Solidity Interfaces and ABIs

How to add NFTs to a gachapon

To add NFTs to a gachapon, you simply need to send them to the smart contract either by calling safeTransferFrom or safeBatchTransferFrom on your NFT collection smart contract. Simply put, you can use OpenSea's interface to just send the NFTs to the address of the gachapon, they will then be added to the prize pool.

Important notes:

Only ERC1155 NFTs are supported as of today. Trying to send an ERC721 NFT to a gachapon will result in a failed transaction.
You need to be the owner of the gachapon to add NFTs to it, verify that you are the owner by calling the owner method of the smart contract. All gachapons implement the Ownable.sol smart contract from OpenZeppelin.

How to play with a gachapon

The play(uint8 _times) is the method you're looking for. Because of the gas limitations the VRF callback is imposing, the _times argument needs to be between 1 and 10, any other value will throw an error and revert the transaction.
Here is an example using web3js and Typescript:
import Web3 from 'web3';
import { Contract } from "web3-eth-contract";
import { PromiEvent } from 'web3-core';
playGachapon(gachaponAddress: string, userAddress: string, times: number): PromiEvent<any> {
// Inject the wallet of the user
const web3 = new Web3(window.ethereum)
// Create the contract
const contract = new web3.eth.Contract(ABI, gachaponAddress);
// Send the transaction
return contract.methods.play(times).send({ from: userAddress });
}
The playGachapon method will trigger the wallet of your user and, if accepted, will send the TX, and will start what we will call a "round"

Track the status of a round

If the transaction is successful, the receipt will contain an RoundStarted event, this event gives you the _requestId of the round. This ID is the one returned by the VRF oracle so it can call our smart contract back with a random number for a particular round, this ID is unique even across several gachapons.
You can use this request ID to track the rounds status, and do something when the oracle answered, on our side, we use an RPC endpoint that supports websocket connections (usually starts with wss:// instead of the usual https://) to listen to a RoundCompleted event with the same request ID:
const rpcUrl = '<Your RPC URL that supports websocket>';
const web3 = new Web3(rpcUrl);
const contract = new web3.eth.Contract(ABI, gachaponAddress);
// Listen to the next RoundCompleted event with this requestId
contract.once('RoundCompleted', {
filter: {_requestId: requestId},
fromBlock: 'latest'
}, (error: Error, event: EventData) => {
if (error) {
throw error;
}
// Extract the prizes indexes from the event
const nftIndexes: number[] = (event.returnValues._prizes as string[]).map((prize) => +prize);
const timesPlayed: number = +event.returnValues._times;
// By default, a round contains an array of 10 zeros, so you need to
// take only the prizes which have an index lower than the `_times` value
const prizes = nftIndexes.splice(0, timesPlayed);
// This array will contain the index at which the prizes are in the gachapon,
// you can call `getNft()` on the contract to get the details of a particular NFT
console.log(prizes);
});
On average, the oracle will take between 10 and 30 seconds to callback the smart contract, so don't panic if it doesn't answer instantly.