Polygonal Mind
  • Home
  • Metaverse Builder
  • CryptoAvatars
  • MegaCube
  • Blog
  • Decentraland
  • Projects
  • Assets

Blog

Simple MANA transactions in DCL

5/8/2020

1 Comment

 
EspaƱol
The Mission

This is a short guide on how to code in typescript, a simple MANA payment for your scene in Decentraland.
Resources

  • Decentraland SDK
  • Basic DCL project
  • Metamask extension (for test only)
How to make simple MANA transactions in Decentraland
Decentraland official documentation

https://docs.decentraland.org/blockchain-integration/scene-blockchain-operations/
Libraries and imports

You need to install in your typescript project the eth-connect library, to interface with Ethereum contracts and call their functions.
npm install eth-connect
Also, you will need to import the following functions in your file.
​
getUserAccount to obtain the user's ethereum address.

getProvider to create an instance of the web3 provider to interface with Metamask.
​
getUserAccount and getProvider are provided by the decentraland SDK.
import { getProvider } from '@decentraland/web3-provider'
import { getUserAccount } from '@decentraland/EthereumController'
import * as EthConnect from '../node_modules/eth-connect/esm'​
For this libraries to work in the DCL localhost preview, you'll need to paste &ENABLE_WEB3 to the url, example: http://192.168.0.112:8000/?SCENE_DEBUG_PANEL&position=12%2C44&ENABLE_WEB3
Important information needed before start

To perform a MANA payment you need to gather some info.
Ethereum address to pay the mana, this will be the address that will recive the MANA from the user's payments.
example: const PAYMENT_ADDRESS ="0x4tU......8dY"
MANA units you want the user to pay
example: const MANA_PAYMENT = 10
The MANA ethereum contract address
const MANA_ADDRESS = "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942"
Fake MANA contract address (optional), only if you want to do test transations with Fake MANA
const FAKE_MANA_ADDRESS = "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
The MANA contract ABI
https://etherscan.io/address/0x0f5d2fb29fb7d3cfee444a200298f468908cc942#code
Create a empty file inside your project, "/contracts/mana.ts" and paste the MANA ABI in export const abi, or paste the contents of this file.
  • Hide
  • Show
<
>
export const abi = [{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}
Fake MANA contract ABI (optional)
  • Hide
  • Show
<
>
export const abi = [
{
constant: true,
inputs: [],
name: 'mintingFinished',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'name',
outputs: [
{
name: '',
type: 'string'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_spender',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'approve',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'totalSupply',
outputs: [
{
name: '',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_from',
type: 'address'
},
{
name: '_to',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'transferFrom',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'decimals',
outputs: [
{
name: '',
type: 'uint8'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'unpause',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_to',
type: 'address'
},
{
name: '_amount',
type: 'uint256'
}
],
name: 'mint',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_value',
type: 'uint256'
}
],
name: 'burn',
outputs: [],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'paused',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address'
}
],
name: 'balanceOf',
outputs: [
{
name: 'balance',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'finishMinting',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'pause',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'owner',
outputs: [
{
name: '',
type: 'address'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'symbol',
outputs: [
{
name: '',
type: 'string'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_to',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'transfer',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address'
},
{
name: '_spender',
type: 'address'
}
],
name: 'allowance',
outputs: [
{
name: 'remaining',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: 'to',
type: 'address'
},
{
name: 'amount',
type: 'uint256'
}
],
name: 'setBalance',
outputs: [],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: 'newOwner',
type: 'address'
}
],
name: 'transferOwnership',
outputs: [],
payable: false,
type: 'function'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'to',
type: 'address'
},
{
indexed: false,
name: 'amount',
type: 'uint256'
}
],
name: 'Mint',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'MintFinished',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'Pause',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'Unpause',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'burner',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Burn',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'owner',
type: 'address'
},
{
indexed: true,
name: 'spender',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Approval',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'from',
type: 'address'
},
{
indexed: true,
name: 'to',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Transfer',
type: 'event'
}
]
Code

Now that we have all the info and libraries we need it's time to develop or code.
Import the functions you'll need at the begining of the file.
import { getProvider } from '@decentraland/web3-provider'
import { getUserAccount } from '@decentraland/EthereumController'
import * as EthConnect from '../node_modules/eth-connect/esm'
Import the MANA ABI (or the fake MANA ABI for test only)
import { abi } from './contracts/mana'
Now you can create a simple payment function, to call when you want the user to pay.
const PAYMENT_ADDRESS ="0x4tU......8dY"
const MANA_ADDRESS = "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942"
const MANA_PAYMENT = 10
function payment(callback = function(error?, result?){}) {
  executeTask(async () => {
    try {
      const provider = await getProvider()
      const requestManager = new EthConnect.RequestManager(provider)

      const factory = new EthConnect.ContractFactory(requestManager, abi)
      const contract = (await factory.at(
        MANA_ADDRESS
      )) as any
      const address = await getUserAccount()

      const res = await contract.transfer(
         PAYMENT_ADDRESS, MANA_PAYMENT*1000000000000000000,
         { from: address }
      )
    } catch (error) {
      callback(error)
      log(error.toString())
    }
  })
When this function is called, the user's Metamask extension will popup a comfirmation for the payment, if there is a problem with the payment or the user rejects it, the payment() function will throw an error. If oyu want you can add your own callback(error, result) function to manage the success or fail of the payment request.
payment(function(error, result){
if (!error) {
//Payment success
}
else{
//Payment fail
}
})
Test with fake MANA payments

Before you run your code for the first time, maybe you want to test it with fake MANA and fake etherium, to check if everything works fine, and don't lose real MANA in the proccess.
First, you need to change the network in your Metamask extension to the Ropsten Test Network.
MetaMask Ropsten Test Network
Second, you need to obtain free fake ethereum and mana in the Ropsten Test Network.
Fake ethereum: 
https://faucet.ropsten.be/
Fake MANA: 
https://faucet.decentraland.today/
MetaMask with fake Ethereum and MANA
For the last step, you need to change the MANA contract address and the MANA ABI in your code for the fake ones.
import { abi } from './contracts/fakemana'
const MANA_ADDRESS = "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
With this your test MANA payments will be done with the fake in the Ropsten Test Network, and will be sent to the PAYMENT_ADDRESS in the Ropsten network as well.

Picture
Alex Picazo
PROGRAMMER
Videogame programmer, love developing cool stuff. Always searching for new interesting stories.
LinkedIn
1 Comment
kitchen faucet gold link
2/22/2021 10:13:17 pm

Finally I got this!
Cant really read codes in this time. Gonna need it for future. Thanks!

Reply



Leave a Reply.

    Categories

    All
    Blender
    CryptoAvatars
    Decentraland
    Decentraland En Español
    Maya
    Metaverse
    Mixamo
    Morphite
    Substance Painter
    The Sandbox
    Totally Reliable Delivery Service
    Unity 3D
    Updates
    Vrchat

    Archives

    March 2022
    July 2021
    June 2021
    May 2021
    April 2021
    March 2021
    February 2021
    January 2021
    December 2020
    October 2020
    August 2020
    July 2020
    June 2020
    May 2020
    April 2020
    March 2020
    February 2020
    December 2019
    October 2019
    September 2019
    August 2019
    June 2019
    May 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2016

    Picture
Home
Projects
Assets

Picture
Crypto
Friendly
Picture

Subscribe to get some 💚 in your inbox once in a while.

Follow us and your visit will never be forgotten!
Picture
Picture
Picture

 © 2015-2022 POLYGONAL MIND LTD. ALL RIGHTS RESERVED.
  • Home
  • Metaverse Builder
  • CryptoAvatars
  • MegaCube
  • Blog
  • Decentraland
  • Projects
  • Assets