evolutionland/ethereum/index.js

  1. import BigNumber from 'bignumber.js'
  2. import EthereumTx from "ethereumjs-tx";
  3. import {
  4. Env,
  5. getABIConfig
  6. } from './env'
  7. import ClientFetch from '../utils/clientFetch'
  8. import bancorABI from './env/abi/ethereum/abi-bancor'
  9. import actionABI from './env/abi/ethereum/abi-auction'
  10. import ringABI from './env/abi/ethereum/abi-ring'
  11. import withdrawABI from './env/abi/ethereum/abi-withdraw'
  12. import bankABI from './env/abi/ethereum/abi-bank'
  13. import ktonABI from './env/abi/ethereum/abi-kton'
  14. import landABI from './env/abi/ethereum/abi-land'
  15. import lotteryABI from './env/abi/ethereum/abi-lottery'
  16. import rolesUpdaterABI from './env/abi/ethereum/abi-rolesUpdater'
  17. import landResourceABI from './env/abi/ethereum/abi-landResource'
  18. import apostleAuctionABI from './env/abi/ethereum/abi-apostleAuction'
  19. import apostleTakeBackABI from './env/abi/ethereum/abi-takeBack'
  20. import apostleSiringABI from './env/abi/ethereum/abi-apostleSiring'
  21. import apostleBaseABI from './env/abi/ethereum/abi-apostleBase'
  22. import tokenUseABI from './env/abi/ethereum/abi-tokenUse'
  23. import petBaseABI from './env/abi/ethereum/abi-petbase'
  24. import uniswapExchangeABI from './env/abi/ethereum/abi-uniswapExchangeV2'
  25. import swapBridgeABI from './env/abi/ethereum/abi-swapBridge'
  26. import luckyBoxABI from './env/abi/ethereum/abi-luckyBag'
  27. import itemTreasureABI from './env/abi/ethereum/abi-itemTreasure'
  28. import itemTakeBackABI from './env/abi/ethereum/abi-itemTakeBack'
  29. import furnaceItemBaseABI from './env/abi/ethereum/abi-furnaceItemBase'
  30. import Utils from '../utils/index'
  31. import UniswapUtils from '../utils/uniswap'
  32. import { Currency, ChainId, Token, TokenAmount, Pair, WETH, Fetcher, Percent, Route, TradeType, Trade, JSBI, CurrencyAmount } from '@uniswap/sdk'
  33. const loop = function () { }
  34. /**
  35. * @class
  36. * Evolution Land for Ethereum
  37. */
  38. class EthereumEvolutionLand {
  39. /**
  40. * constructor function.
  41. * @param {object} web3js - web3js instance
  42. * @param {string} network
  43. */
  44. constructor(web3js, network, option = {}) {
  45. this.version = '1.0.0'
  46. this._web3js = web3js
  47. this.env = Env(network)
  48. this.ABIs = getABIConfig(network)
  49. this.ABIClientFetch = new ClientFetch({
  50. baseUrl: this.env.ABI_DOMAIN,
  51. chainId: 60
  52. })
  53. this.ClientFetch = new ClientFetch({
  54. baseUrl: this.env.DOMAIN,
  55. chainId: 60
  56. })
  57. this.option = {
  58. sign: true,
  59. address: null,
  60. ...option
  61. }
  62. }
  63. setCustomAccount(account) {
  64. this.option.address = account
  65. }
  66. /**
  67. * get web3js Current address.
  68. * @returns {Promise<any>}
  69. */
  70. getCurrentAccount() {
  71. return new Promise((resolve, reject) => {
  72. if (this.option.address) {
  73. resolve(this.option.address)
  74. }
  75. this._web3js.eth.getAccounts((error, accounts) => {
  76. if (error) {
  77. reject(error)
  78. } else {
  79. resolve(accounts[0])
  80. }
  81. })
  82. })
  83. }
  84. /**
  85. * Interact with a contract.
  86. * @param {string} methodName - contract method name
  87. * @param {string} abiKey - If the contract exists in the configuration file, you can use the key in the configuration to get it directly.
  88. * @param {json} abiString - ethereum ABI json
  89. * @param contractParams - contract function with arguments
  90. * @param sendParams - web3js send() arguments
  91. * @param beforeFetch
  92. * @param transactionHashCallback
  93. * @param confirmationCallback
  94. * @param receiptCallback
  95. * @param errorCallback
  96. * @returns {Promise<PromiEvent<any>>}
  97. */
  98. async triggerContract({
  99. methodName,
  100. abiKey,
  101. abiString,
  102. contractParams = [],
  103. sendParams = {}
  104. }, {
  105. beforeFetch = loop,
  106. transactionHashCallback = loop,
  107. confirmationCallback = loop,
  108. receiptCallback = loop,
  109. errorCallback = loop,
  110. receiptFinal = loop,
  111. unSignedTx = loop,
  112. payload = {}
  113. } = {}) {
  114. try {
  115. beforeFetch && beforeFetch();
  116. let _contract = null;
  117. let contractAddress = await this.getContractAddress(abiKey);
  118. _contract = new this._web3js.eth.Contract(abiString, contractAddress);
  119. const extendPayload = { ...payload, _contractAddress: contractAddress };
  120. const _method = _contract.methods[methodName].apply(this, contractParams)
  121. const from = await this.getCurrentAccount()
  122. const gasRes = await this.ClientFetch.apiGasPrice({ wallet: this.option.address || from })
  123. let estimateGas = 300000;
  124. try {
  125. let hexSendParams = { value: 0 }
  126. Object.keys(sendParams).forEach((item) => {
  127. hexSendParams[item] = Utils.toHex(sendParams[item])
  128. })
  129. estimateGas = await this.estimateGas(_method, this.option.address || from, gasRes.data.gas_price.standard, hexSendParams.value) || 300000;
  130. } catch (e) {
  131. console.log('estimateGas', e)
  132. }
  133. if (!this.option.sign) {
  134. if (!this.option.address) {
  135. throw Error('from account is empty!')
  136. }
  137. let hexSendParams = {}
  138. Object.keys(sendParams).forEach((item) => {
  139. hexSendParams[item] = Utils.toHex(sendParams[item])
  140. })
  141. const tx = new EthereumTx({
  142. to: contractAddress,
  143. value: 0,
  144. nonce: gasRes.data.nonce,
  145. gasPrice: gasRes.data.gas_price.standard,
  146. gasLimit: Utils.toHex(estimateGas + 30000),
  147. chainId: parseInt(await this.getNetworkId()),
  148. data: _method ? _method.encodeABI() : '',
  149. ...hexSendParams
  150. })
  151. const serializedTx = tx.serialize().toString("hex")
  152. unSignedTx && unSignedTx(serializedTx, extendPayload)
  153. return serializedTx;
  154. }
  155. return _method.send({
  156. from: await this.getCurrentAccount(),
  157. value: 0,
  158. gasLimit: Utils.toHex(estimateGas + 30000),
  159. ...sendParams
  160. })
  161. .once('transactionHash', (hash) => {
  162. transactionHashCallback && transactionHashCallback(hash, extendPayload)
  163. })
  164. .once('confirmation', (confirmationNumber, receipt) => {
  165. confirmationCallback && confirmationCallback(confirmationNumber, receipt, extendPayload)
  166. })
  167. .once('receipt', (receipt) => {
  168. receiptCallback && receiptCallback(receipt, extendPayload)
  169. })
  170. .once('error', (error) => {
  171. errorCallback && errorCallback(error, extendPayload)
  172. })
  173. // .then((receipt) =>{
  174. // receiptFinal && receiptFinal(receipt, extendPayload);
  175. // })
  176. } catch (e) {
  177. console.error('triggerContract', e)
  178. const extendPayload = { ...payload, _contractAddress: contractAddress };
  179. errorCallback && errorCallback(e, extendPayload)
  180. }
  181. // return _method.send.bind(this,{
  182. // from: await this.getCurrentAccount(),
  183. // value: 0,
  184. // ...sendParams
  185. // })
  186. }
  187. /**
  188. * Interact with a contract.
  189. * @param {string} methodName - contract method name
  190. * @param {string} abiKey - If the contract exists in the configuration file, you can use the key in the configuration to get it directly.
  191. * @param {json} abiString - ethereum ABI json
  192. * @param contractParams - contract function with arguments
  193. * @param sendParams - web3js send() arguments
  194. * @param beforeFetch
  195. * @param transactionHashCallback
  196. * @param confirmationCallback
  197. * @param receiptCallback
  198. * @param errorCallback
  199. * @returns {Promise<PromiEvent<any>>}
  200. */
  201. async callContract({
  202. methodName,
  203. abiKey,
  204. abiString,
  205. contractParams = [],
  206. }, {
  207. beforeFetch = loop,
  208. errorCallback = loop
  209. } = {}) {
  210. try {
  211. beforeFetch && beforeFetch()
  212. let _contract = null
  213. let contractAddress = await this.getContractAddress(abiKey);
  214. _contract = new this._web3js.eth.Contract(abiString, contractAddress);
  215. const _method = _contract.methods[methodName].apply(this, contractParams)
  216. return _method.call({
  217. from: await this.getCurrentAccount(),
  218. })
  219. } catch (e) {
  220. console.error('triggerContract', e)
  221. errorCallback && errorCallback(e)
  222. }
  223. }
  224. /**
  225. * Get the contract address of evolution land by key.
  226. * @param {*} tokenKey ring | kton | gold ...
  227. */
  228. async getContractAddress(tokenKey) {
  229. let token = (this.ABIs[tokenKey] && this.ABIs[tokenKey].address) || tokenKey;
  230. // if(Array.isArray(tokenKey) && tokenKey.length === 2) {
  231. // const pair = await this.getDerivedPairInfo(...tokenKey)
  232. // token = pair.liquidityToken.address
  233. // }
  234. return token;
  235. }
  236. /**
  237. * Query if an address is an authorized operator for another address
  238. * @param {*} owner The address that owns the NFTs
  239. * @param {*} operator The address that acts on behalf of the owner
  240. * @param {*} contractAddress ERC721 contract address
  241. */
  242. erc721IsApprovedForAll(owner, operator, contractAddress, callback={}) {
  243. return this.callContract({
  244. methodName: 'isApprovedForAll',
  245. abiKey: contractAddress,
  246. abiString: this.ABIs['erc721'].abi,
  247. contractParams: [owner, operator],
  248. }, callback)
  249. }
  250. /**
  251. * Returns whether `spender` is allowed to manage `tokenId`.
  252. * @param {*} spender The address that acts on behalf of the owner
  253. * @param {*} contractAddress The factory of tokenId.
  254. * @param {*} tokenId ERC721 token Id;
  255. */
  256. async erc721IsApprovedOrOwner(spender, contractAddress, tokenId) {
  257. const owner = await this.callContract({
  258. methodName: 'ownerOf',
  259. abiKey: contractAddress,
  260. abiString: this.ABIs['erc721'].abi,
  261. contractParams: [tokenId],
  262. });
  263. const approvedAddress = await this.callContract({
  264. methodName: 'getApproved',
  265. abiKey: contractAddress,
  266. abiString: this.ABIs['erc721'].abi,
  267. contractParams: [tokenId],
  268. });
  269. const isApprovedForAll = await this.erc721IsApprovedForAll(owner, spender, contractAddress);
  270. return (owner.toLowerCase() === spender.toLowerCase() || approvedAddress.toLowerCase() === spender.toLowerCase() || isApprovedForAll);
  271. }
  272. /**
  273. *
  274. * @param {*} owner
  275. * @param {*} operator
  276. * @param {*} contractAddress
  277. * @param {*} callback
  278. */
  279. erc721IsApprovedForAll(owner, operator, contractAddress, callback={}) {
  280. return this.callContract({
  281. methodName: 'isApprovedForAll',
  282. abiKey: contractAddress,
  283. abiString: this.ABIs['erc721'].abi,
  284. contractParams: [owner, operator],
  285. }, callback)
  286. }
  287. /**
  288. * Change or reaffirm the approved address for an NFT
  289. * @param {*} to The new approved NFT controller
  290. * @param {*} tokenId The NFT to approve
  291. */
  292. async erc721Approve(to, tokenId, contractAddress, callback={}) {
  293. return this.triggerContract({
  294. methodName: 'approve',
  295. abiKey: contractAddress,
  296. abiString: this.ABIs['erc721'].abi,
  297. contractParams: [to, tokenId],
  298. }, callback)
  299. }
  300. /**
  301. * Enable or disable approval for a third party ("operator") to manage
  302. * @param {*} to Address to add to the set of authorized operators
  303. * @param {*} approved True if the operator is approved, false to revoke approval
  304. * @param {*} contractAddress ERC721 contract address
  305. * @param {*} callback
  306. */
  307. async erc721SetApprovalForAll(to, approved, contractAddress, callback={}) {
  308. return this.triggerContract({
  309. methodName: 'setApprovalForAll',
  310. abiKey: contractAddress,
  311. abiString: this.ABIs['erc721'].abi,
  312. contractParams: [to, approved],
  313. }, callback)
  314. }
  315. /**
  316. * Atlantis swap fee
  317. * @param {string} value amount of rings to be swaped
  318. * @param {*} callback
  319. */
  320. async fetchAtlantisSwapFee(value, callback = {}) {
  321. return this.callContract({
  322. methodName: 'querySwapFee',
  323. abiKey: 'swapBridge',
  324. abiString: swapBridgeABI,
  325. contractParams: [value],
  326. }, callback)
  327. }
  328. getSimpleBridgeStatus(callback = {}) {
  329. return this.callContract({
  330. methodName: 'paused',
  331. abiKey: 'swapBridge',
  332. abiString: swapBridgeABI,
  333. contractParams: [],
  334. }, callback)
  335. }
  336. /**
  337. * Atlantis ring transfer to Byzantium
  338. * @param {string} value amount of rings to be swaped
  339. * @param {string} value tron address (bs58)
  340. * @param {*} callback
  341. */
  342. async AtlantisSwapBridge(value, targetAddress, symbol = 'ring', callback = {}) {
  343. if (!targetAddress) {
  344. throw Error('empty targetAddress')
  345. }
  346. const fee = await this.fetchAtlantisSwapFee(value)
  347. const hexTargetAddress = Utils.decodeBase58Address(targetAddress);
  348. const extraData = `${Utils.toHexAndPadLeft(value)}${Utils.toHexAndPadLeft(2).slice(2)}${Utils.padLeft(hexTargetAddress.substring(2), 64, '0')}`
  349. return this.triggerContract({
  350. methodName: 'approveAndCall',
  351. abiKey: symbol.toLowerCase(),
  352. abiString: ringABI,
  353. contractParams: [this.ABIs['swapBridge'].address, new BigNumber(fee).plus(1).plus(new BigNumber(value)).toFixed(0), extraData],
  354. }, callback)
  355. }
  356. /**
  357. * Swap Ether to Ring token - Powered by uniswap.
  358. * @param {string} value - amount for Ring, unit of measurement(wei)
  359. * @returns {Promise<PromiEvent<any>>}
  360. */
  361. async buyRingUniswap(value, callback = {}) {
  362. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  363. const pair = await Fetcher.fetchPairData(WETH[RING.chainId], RING)
  364. const route = new Route([pair], WETH[RING.chainId])
  365. const amountIn = value
  366. const trade = new Trade(route, new TokenAmount(RING, amountIn), TradeType.EXACT_OUTPUT)
  367. const slippageTolerance = new Percent('0', '10000') // 30 bips, or 0.30%
  368. const amountInMax = trade.maximumAmountIn(slippageTolerance).raw // needs to be converted to e.g. hex
  369. const path = [WETH[RING.chainId].address, RING.address]
  370. const to = await this.getCurrentAccount() // should be a checksummed recipient address
  371. const deadline = Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
  372. const outputAmount = trade.outputAmount.raw // // needs to be converted to e.g. hex
  373. return this.triggerContract({
  374. methodName: 'swapETHForExactTokens',
  375. abiKey: 'uniswapExchange',
  376. abiString: uniswapExchangeABI,
  377. contractParams: [
  378. outputAmount.toString(10),
  379. path,
  380. to,
  381. deadline
  382. ],
  383. sendParams: {
  384. value: amountInMax.toString(10)
  385. }
  386. }, callback)
  387. }
  388. /**
  389. * Swap Ring token to Ether - Powered by uniswap.
  390. * @param {string} value - amount for Ring, unit of measurement(wei)
  391. * @returns {Promise<PromiEvent<any>>}
  392. */
  393. async sellRingUniswap(value, callback = {}) {
  394. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  395. const pair = await Fetcher.fetchPairData(RING, WETH[RING.chainId])
  396. const route = new Route([pair], RING)
  397. const amountIn = value
  398. const trade = new Trade(route, new TokenAmount(RING, amountIn), TradeType.EXACT_INPUT)
  399. const slippageTolerance = new Percent('0', '10000') // 30 bips, or 0.30%
  400. const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw // needs to be converted to e.g. hex
  401. const path = [RING.address, WETH[RING.chainId].address]
  402. const to = await this.getCurrentAccount() // should be a checksummed recipient address
  403. const deadline = Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
  404. const inputAmount = trade.inputAmount.raw // // needs to be converted to e.g. hex
  405. return this.triggerContract({
  406. methodName: 'swapExactTokensForETH',
  407. abiKey: 'uniswapExchange',
  408. abiString: uniswapExchangeABI,
  409. contractParams: [
  410. inputAmount.toString(10),
  411. amountOutMin.toString(10),
  412. path,
  413. to,
  414. deadline
  415. ],
  416. sendParams: {
  417. value: 0
  418. }
  419. }, callback)
  420. }
  421. /**
  422. * Transfers value amount of tokens to address to
  423. * @param {string} value - amount of tokens
  424. * @param {string} to - receiving address
  425. * @param {string} symbol - symbol of token [ring, kton, gold, wood, water, fire, soil]
  426. * @param {*} callback
  427. */
  428. async tokenTransfer(value, to, symbol, callback = {}) {
  429. if (!to || to === "0x0000000000000000000000000000000000000000") return;
  430. let abiString = ''
  431. if (symbol === 'kton') {
  432. abiString = ktonABI
  433. } else {
  434. abiString = ringABI
  435. }
  436. return this.triggerContract({
  437. methodName: 'transfer',
  438. abiKey: symbol,
  439. abiString: abiString,
  440. contractParams: [to, value],
  441. }, callback)
  442. }
  443. /**
  444. * Ethereum Function, Approve Ring to Uniswap Exchange
  445. * @param {*} callback
  446. */
  447. async approveRingToUniswap(callback = {}, value="20000000000000000000000000") {
  448. return this.triggerContract({
  449. methodName: 'approve',
  450. abiKey: 'ring',
  451. abiString: ringABI,
  452. contractParams: [this.ABIs['uniswapExchange'].address, value],
  453. }, callback)
  454. }
  455. /**
  456. * Allows Uniswap to withdraw from your account multiple times, up to the value amount.
  457. * @param {*} addressOrType ERC20 token contract address.
  458. * @param {*} value
  459. * @param {*} callback
  460. */
  461. approveTokenToUniswap(addressOrType, value="0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", callback = {}) {
  462. if(!addressOrType) {
  463. throw 'ethereum::approveTokenToUniswap: missing addressOrType param'
  464. }
  465. return this.triggerContract({
  466. methodName: 'approve',
  467. abiKey: addressOrType,
  468. abiString: ringABI,
  469. contractParams: [this.ABIs['uniswapExchange'].address, value],
  470. }, callback)
  471. }
  472. /**
  473. * Approve liquidity to uniswap
  474. * @param {*} tokenAType Token 0 contract address
  475. * @param {*} tokenBType Token 1 contract address
  476. * @param {*} value Approved value
  477. * @param {*} callback
  478. */
  479. async approveLiquidityTokenToUniswap(tokenAType, tokenBType, value="0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", callback = {}) {
  480. if(!tokenAType || !tokenBType) {
  481. throw 'ethereum::approveLiquidityTokenToUniswap: missing addressOrType param'
  482. }
  483. const pair = await this.getDerivedPairInfo(tokenAType, tokenBType);
  484. return this.approveTokenToUniswap(pair.liquidityToken.address, value, callback);
  485. }
  486. /**
  487. * Allows spender to withdraw from your account multiple times, up to the value amount. If this function is called again it overwrites the current allowance with value.
  488. * @param {*} tokenContractOrType Erc20 token contract address
  489. * @param {*} spender
  490. * @param {*} value
  491. * @param {*} callback
  492. */
  493. async approveToken(tokenContractOrType, spender, value="0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", callback = {}) {
  494. if(!spender) {
  495. return;
  496. }
  497. return this.triggerContract({
  498. methodName: 'approve',
  499. abiKey: tokenContractOrType,
  500. abiString: ringABI,
  501. contractParams: [spender, value],
  502. }, callback)
  503. }
  504. /**
  505. * Approve uniswap liquidity token to spender.
  506. * @param {*} tokenAType
  507. * @param {*} tokenBType
  508. * @param {*} value
  509. * @param {*} callback
  510. */
  511. async approveUniswapLiquidityToken(tokenAType, tokenBType, spender, value="0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", callback = {}) {
  512. if(!tokenAType || !tokenBType) {
  513. throw 'ethereum::approveUniswapLiquidityToken: missing addressOrType param'
  514. }
  515. const pair = await this.getDerivedPairInfo(tokenAType, tokenBType);
  516. return this.triggerContract({
  517. methodName: 'approve',
  518. abiKey: pair.liquidityToken.address,
  519. abiString: ringABI,
  520. contractParams: [spender, value],
  521. }, callback)
  522. }
  523. /**
  524. * Check if uniswap has sufficient transfer authority
  525. * @param {*} amount
  526. * @param {*} tokenAddressOrType
  527. * @param {*} account
  528. */
  529. async checkUniswapAllowance(amount, tokenAddressOrType = 'ring', account) {
  530. const from = account || await this.getCurrentAccount();
  531. const token = await this.getContractAddress(tokenAddressOrType);
  532. const erc20Contract = new this._web3js.eth.Contract(ringABI, token)
  533. const allowanceAmount = await erc20Contract.methods.allowance(from, this.ABIs['uniswapExchange'].address).call()
  534. return !Utils.toBN(allowanceAmount).lt(Utils.toBN(amount || '1000000000000000000000000'))
  535. }
  536. /**
  537. * Check if spender has sufficient transfer authority
  538. * @param {*} amount
  539. * @param {*} tokenAddressOrType,
  540. * @param {*} account
  541. * @param {*} spender
  542. */
  543. async checkTokenAllowance(amount, tokenAddressOrType, account, spender) {
  544. if(!amount || !tokenAddressOrType || !spender) {
  545. throw 'ethereum::checkTokenAllowance: missing param'
  546. }
  547. const from = account || await this.getCurrentAccount();
  548. const token = await this.getContractAddress(tokenAddressOrType);
  549. const erc20Contract = new this._web3js.eth.Contract(ringABI, token)
  550. const allowanceAmount = await erc20Contract.methods.allowance(from, spender).call()
  551. return !Utils.toBN(allowanceAmount).lt(Utils.toBN(amount || '1000000000000000000000000'))
  552. }
  553. /**
  554. * get amount of ether in uniswap exchange
  555. */
  556. async getUniswapEthBalance() {
  557. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  558. const pair = await Fetcher.fetchPairData(WETH[RING.chainId], RING)
  559. return pair.tokenAmounts[1].raw.toString(10)
  560. }
  561. /**
  562. * get amount of ring in uniswap exchange
  563. */
  564. async getUniswapTokenBalance() {
  565. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  566. const pair = await Fetcher.fetchPairData(WETH[RING.chainId], RING)
  567. return pair.tokenAmounts[0].raw.toString(10)
  568. }
  569. /**
  570. * Eth will be cost to swap 1 Ring
  571. * @param {*} tokens_bought
  572. */
  573. async getEthToTokenOutputPrice(tokens_bought = '1000000000000000000') {
  574. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  575. const pair = await Fetcher.fetchPairData(WETH[RING.chainId], RING)
  576. const route = new Route([pair], WETH[RING.chainId])
  577. const amountIn = tokens_bought
  578. const trade = new Trade(route, new TokenAmount(RING, amountIn), TradeType.EXACT_OUTPUT)
  579. const slippageTolerance = new Percent('0', '10000')
  580. const amountInMax = trade.maximumAmountIn(slippageTolerance).raw
  581. return [new BigNumber(amountInMax.toString(10)).times('1000000000000000000').div(tokens_bought).toFixed(0), amountInMax.toString(10)];
  582. }
  583. /**
  584. * Eth will be got to swap 1 Ring
  585. * @param {*} tokens_bought
  586. */
  587. async getTokenToEthInputPrice(tokens_bought = '1000000000000000000') {
  588. const RING = new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token")
  589. const pair = await Fetcher.fetchPairData(RING, WETH[RING.chainId])
  590. const route = new Route([pair], RING)
  591. const amountIn = tokens_bought // 1 WETH
  592. const trade = new Trade(route, new TokenAmount(RING, amountIn), TradeType.EXACT_INPUT)
  593. const slippageTolerance = new Percent('0', '10000') // 50 bips, or 0.50%
  594. const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw // needs to be converted to e.g. hex
  595. return [new BigNumber(amountOutMin.toString(10)).times('1000000000000000000').div(tokens_bought).toFixed(0), amountOutMin.toString(10)];
  596. }
  597. /**
  598. * Buy ring token with Ether.
  599. * @param {string} value - amount for Ether, unit of measurement(wei)
  600. * @returns {Promise<PromiEvent<any>>}
  601. */
  602. buyRing(value, callback = {}) {
  603. return this.triggerContract({
  604. methodName: 'buyRING',
  605. abiKey: 'bancor',
  606. abiString: bancorABI,
  607. contractParams: [1],
  608. sendParams: {
  609. value: value
  610. }
  611. }, callback)
  612. }
  613. /**
  614. * Claim land asset
  615. * @param tokenId - Land tokenId
  616. * @returns {Promise<PromiEvent<any>>}
  617. */
  618. claimLandAsset(tokenId, callback = {}) {
  619. return this.triggerContract({
  620. methodName: 'claimLandAsset',
  621. abiKey: 'auction',
  622. abiString: actionABI,
  623. contractParams: ['0x' + tokenId],
  624. }, callback)
  625. }
  626. /**
  627. * Bid Land Assets with Ring token.
  628. * @param amount - bid price with ring token
  629. * @param tokenId - tokenid of land
  630. * @param referrer - Referrer address
  631. * @returns {Promise<PromiEvent<any>>}
  632. */
  633. buyLandContract(amount, tokenId, referrer, callback = {}) {
  634. const finalReferrer = referrer
  635. const data =
  636. finalReferrer && Utils.isAddress(finalReferrer) ?
  637. `0x${tokenId}${Utils.padLeft(finalReferrer.substring(2), 64, '0')}` :
  638. `0x${tokenId}`
  639. return this.triggerContract({
  640. methodName: 'transfer',
  641. abiKey: 'ring',
  642. abiString: ringABI,
  643. contractParams: [this.ABIs['auction'].address, amount, data],
  644. }, callback)
  645. }
  646. /**
  647. * Sell land asset
  648. * @param tokenId - Land tokenId
  649. * @param start - start price
  650. * @param end - end price
  651. * @param duration - bid duration time in second
  652. * @returns {Promise<PromiEvent<any>>}
  653. */
  654. async setLandPrice(tokenId, start, end, duration, callback = {}) {
  655. const from = await this.getCurrentAccount()
  656. const _from = Utils.padLeft(from.slice(2), 64, '0')
  657. const _start = Utils.toHexAndPadLeft(start).slice(2)
  658. const _end = Utils.toHexAndPadLeft(end).slice(2)
  659. const _duration = Utils.toHexAndPadLeft(duration).slice(2)
  660. const data = `0x${_start}${_end}${_duration}${_from}`
  661. return this.triggerContract({
  662. methodName: 'approveAndCall',
  663. abiKey: 'land',
  664. abiString: landABI,
  665. contractParams: [this.ABIs['auction'].address, '0x' + tokenId, data],
  666. }, callback)
  667. }
  668. /**
  669. * Bid Land Assets with Ether.
  670. * @param tokenId - tokenid of land
  671. * @param referer - Referrer address
  672. * @param value - bid price with ether
  673. * @returns {Promise<PromiEvent<any>>}
  674. */
  675. buyLandWithETHContract(tokenId, referer, value, callback = {}) {
  676. return this.triggerContract({
  677. methodName: "bidWithETH",
  678. abiString: actionABI,
  679. contractParams: ['0x' + tokenId, referer],
  680. abiKey: "auction",
  681. sendParams: {
  682. value: value
  683. }
  684. }, callback)
  685. }
  686. /**
  687. * Withdraw ring from the channel
  688. * @param nonce
  689. * @param value
  690. * @param hash
  691. * @param v
  692. * @param r
  693. * @param s
  694. * @returns {Promise<PromiEvent<any>>}
  695. */
  696. withdrawRing({
  697. nonce,
  698. value,
  699. hash,
  700. v,
  701. r,
  702. s
  703. }, callback = {}) {
  704. return this.triggerContract({
  705. methodName: "takeBack",
  706. abiString: withdrawABI,
  707. contractParams: [nonce, value, hash, v, r, s],
  708. abiKey: "withdraw",
  709. }, callback);
  710. }
  711. /**
  712. * Withdraw kton from the channel
  713. * @param nonce
  714. * @param value
  715. * @param hash
  716. * @param v
  717. * @param r
  718. * @param s
  719. * @returns {Promise<PromiEvent<any>>}
  720. */
  721. withdrawKton({
  722. nonce,
  723. value,
  724. hash,
  725. v,
  726. r,
  727. s
  728. }, callback = {}) {
  729. return this.triggerContract({
  730. methodName: "takeBack",
  731. abiString: withdrawABI,
  732. contractParams: [nonce, value, hash, v, r, s],
  733. abiKey: "withdrawKton",
  734. }, callback);
  735. }
  736. /**
  737. * Cancel the Land being auctioned.
  738. * @param {string} tokenId - tokenid of land
  739. * @returns {Promise<PromiEvent<any>>}
  740. */
  741. cancelAuction(tokenId, callback = {}) {
  742. return this.triggerContract({
  743. methodName: "cancelAuction",
  744. abiString: actionABI,
  745. contractParams: ['0x' + tokenId],
  746. abiKey: "auction",
  747. }, callback);
  748. }
  749. /**
  750. * Convert Ring token to Ether via bancor exchange
  751. * @param amount - ring token amount
  752. * @returns {Promise<PromiEvent<any>>}
  753. */
  754. sellRing(amount, callback = {}) {
  755. return this.triggerContract({
  756. methodName: 'transfer',
  757. abiKey: 'ring',
  758. abiString: ringABI,
  759. contractParams: [this.ABIs['bancor'].address, amount, '0x0000000000000000000000000000000000000000000000000000000000000001'],
  760. }, callback)
  761. }
  762. /**
  763. * Lock ring token to get Kton token
  764. * @param amount - ring amount
  765. * @param month - Locking time(unit: month)
  766. * @returns {Promise<PromiEvent<any>>}
  767. */
  768. saveRing(amount, month, callback = {}) {
  769. return this.triggerContract({
  770. methodName: 'transfer',
  771. abiKey: 'ring',
  772. abiString: ringABI,
  773. contractParams: [this.ABIs['bank'].address, amount, Utils.toTwosComplement(month)],
  774. }, callback)
  775. }
  776. /**
  777. * Redemption of unexpired ring.
  778. * @param amount - penalty Kton amount
  779. * @param id - deposit ID
  780. * @returns {Promise<PromiEvent<any>>}
  781. */
  782. redeemRing(amount, id, callback = {}) {
  783. return this.triggerContract({
  784. methodName: 'transfer',
  785. abiKey: 'kton',
  786. abiString: ktonABI,
  787. contractParams: [this.ABIs['bank'].address, amount, Utils.toTwosComplement(id)],
  788. }, callback)
  789. }
  790. /**
  791. * Redemption ring without penalty kton
  792. * @param id - deposit ID
  793. * @returns {Promise<PromiEvent<any>>}
  794. */
  795. withdrawBankRing(id, callback = {}) {
  796. return this.triggerContract({
  797. methodName: 'claimDeposit',
  798. abiKey: 'bank',
  799. abiString: bankABI,
  800. contractParams: [Utils.toTwosComplement(id)],
  801. }, callback)
  802. }
  803. /**
  804. * Play a ticket game
  805. * @param type - ['small':playWithSmallTicket , 'large': playWithLargeTicket]
  806. * @returns {Promise<PromiEvent<any>>}
  807. */
  808. lotteryFromPoint(type = "small", callback = {}) {
  809. return this.triggerContract({
  810. methodName: type === "small" ? "playWithSmallTicket" : "playWithLargeTicket",
  811. abiKey: 'lottery',
  812. abiString: lotteryABI,
  813. contractParams: [],
  814. }, callback)
  815. }
  816. /**
  817. * Binding tester code
  818. * @param _nonce
  819. * @param _testerCodeHash
  820. * @param _hashmessage
  821. * @param _v
  822. * @param _r
  823. * @param _s
  824. * @returns {Promise<PromiEvent<any>>}
  825. */
  826. updateTesterRole(_nonce, _testerCodeHash, _hashmessage, _v, _r, _s, callback = {}) {
  827. return this.triggerContract({
  828. methodName: 'updateTesterRole',
  829. abiKey: 'rolesUpdater',
  830. abiString: rolesUpdaterABI,
  831. contractParams: [_nonce, _testerCodeHash, _hashmessage, _v, _r, _s],
  832. }, callback)
  833. }
  834. /**
  835. * create a red package
  836. * @param amount - amount of red package
  837. * @param number - number of received
  838. * @param packetId - packet ID
  839. * @returns {Promise<PromiEvent<any>>}
  840. */
  841. createRedPackageContract(amount, number, packetId, callback = {}) {
  842. const model = 0;
  843. const _data = `0x${Utils.toHexAndPadLeft(number).slice(2)}${Utils.toHexAndPadLeft(model).slice(2)}${Utils.toHexAndPadLeft(packetId).slice(2)}`
  844. return this.triggerContract({
  845. methodName: 'transfer',
  846. abiKey: 'ring',
  847. abiString: ringABI,
  848. contractParams: [this.ABIs['redPackage'].address, amount, _data],
  849. }, callback)
  850. }
  851. /**
  852. * tansfer the Land
  853. * @param {address} from - sender address
  854. * @param {address} to - receiver
  855. * @param {string} tokenId - Land token ID
  856. * @returns {*}
  857. */
  858. async transferFromLand(to, tokenId, callback = {}) {
  859. if (!to) {
  860. return null
  861. }
  862. const from = await this.getCurrentAccount()
  863. return this.triggerContract({
  864. methodName: 'transferFrom',
  865. abiKey: 'land',
  866. abiString: landABI,
  867. contractParams: [from, to, '0x' + tokenId],
  868. }, callback)
  869. }
  870. /**
  871. * claim resource on the Land
  872. * @param tokenId Land token Id.
  873. * @returns {Promise<PromiEvent<any>>}
  874. */
  875. claimLandResource(tokenId, callback = {}) {
  876. return this.triggerContract({
  877. methodName: 'claimLandResource',
  878. abiKey: 'apostleLandResource',
  879. abiString: landResourceABI,
  880. contractParams: ['0x' + tokenId],
  881. }, callback)
  882. }
  883. /**
  884. * Bid apostle by RING token
  885. * @param amount - RING amount
  886. * @param tokenId - Apostle token ID
  887. * @param referrer - refer address
  888. * @returns {Promise<PromiEvent<any>>}
  889. */
  890. apostleBid(amount, tokenId, referrer, callback = {}) {
  891. const finalReferrer = referrer
  892. const data =
  893. finalReferrer && Utils.isAddress(finalReferrer) ?
  894. `0x${tokenId}${Utils.padLeft(finalReferrer.substring(2), 64, '0')}` :
  895. `0x${tokenId}`
  896. return this.triggerContract({
  897. methodName: 'transfer',
  898. abiKey: 'ring',
  899. abiString: ringABI,
  900. contractParams: [this.ABIs['apostleAuction'].address, amount, data],
  901. }, callback)
  902. }
  903. /**
  904. * Receive apostle
  905. * @param tokenId - Apostle Token ID
  906. * @returns {Promise<PromiEvent<any>>}
  907. */
  908. apostleClaim(tokenId, callback = {}) {
  909. return this.triggerContract({
  910. methodName: 'claimApostleAsset',
  911. abiKey: 'apostleAuction',
  912. abiString: apostleAuctionABI,
  913. contractParams: ['0x' + tokenId],
  914. }, callback)
  915. }
  916. /**
  917. * Sell apostle
  918. * @param tokenId - Apostle Token ID
  919. * @param start - auction start price
  920. * @param end - auction end price
  921. * @param duration - duration time
  922. * @returns {Promise<PromiEvent<any>>}
  923. */
  924. async apostleSell(tokenId, start, end, duration, callback = {}) {
  925. const from = await this.getCurrentAccount()
  926. const _from = Utils.padLeft(from.slice(2), 64, '0')
  927. const _start = Utils.toHexAndPadLeft(start).slice(2)
  928. const _end = Utils.toHexAndPadLeft(end).slice(2)
  929. const _duration = Utils.toHexAndPadLeft(duration).slice(2)
  930. const data = `0x${_start}${_end}${_duration}${_from}`
  931. return this.triggerContract({
  932. methodName: 'approveAndCall',
  933. abiKey: 'land',
  934. abiString: landABI,
  935. contractParams: [this.ABIs['apostleAuction'].address, '0x' + tokenId, data],
  936. }, callback)
  937. }
  938. /**
  939. * Cancel the auction by apostle token ID
  940. * @param tokenId - apostle token ID
  941. * @returns {Promise<PromiEvent<any>>}
  942. */
  943. apostleCancelSell(tokenId, callback = {}) {
  944. return this.triggerContract({
  945. methodName: 'cancelAuction',
  946. abiKey: 'apostleAuction',
  947. abiString: apostleAuctionABI,
  948. contractParams: ['0x' + tokenId],
  949. }, callback)
  950. }
  951. /**
  952. *
  953. * @param tokenId
  954. * @param nftData
  955. * @returns {Promise<PromiEvent<any>>}
  956. */
  957. apostleRewardClaim(tokenId, nftData, callback = {}) {
  958. return this.triggerContract({
  959. methodName: 'takeBackNFT',
  960. abiKey: 'apostleTakeBack',
  961. abiString: apostleTakeBackABI,
  962. contractParams: [
  963. nftData.nonce,
  964. '0x' + tokenId,
  965. this.ABIs['land'].address,
  966. nftData.expireTime,
  967. nftData.hash_text,
  968. nftData.v,
  969. nftData.r,
  970. nftData.s
  971. ],
  972. }, callback)
  973. }
  974. /**
  975. * Apostle reproduction in own
  976. * @param tokenId
  977. * @param targetTokenId
  978. * @param amount
  979. * @returns {Promise<PromiEvent<any>>}
  980. */
  981. apostleBreed(tokenId, targetTokenId, amount, callback = {}) {
  982. return this.triggerContract({
  983. methodName: 'transfer',
  984. abiKey: 'ring',
  985. abiString: ringABI,
  986. contractParams: [
  987. this.ABIs["apostleBase"].address,
  988. amount,
  989. `0x${tokenId}${targetTokenId}`
  990. ]
  991. }, callback)
  992. }
  993. /**
  994. * Apostle reproduction
  995. * @param tokenId
  996. * @param targetTokenId
  997. * @param amount
  998. */
  999. apostleBreedBid(tokenId, targetTokenId, amount, callback = {}) {
  1000. return this.triggerContract({
  1001. methodName: 'transfer',
  1002. abiKey: 'ring',
  1003. abiString: ringABI,
  1004. contractParams: [
  1005. this.ABIs["apostleSiringAuction"].address,
  1006. amount,
  1007. `0x${tokenId}${targetTokenId}`
  1008. ]
  1009. }, callback)
  1010. }
  1011. /**
  1012. * Apostle Breed Auction
  1013. * @param tokenId - Apostle tokenId
  1014. * @param start - start price
  1015. * @param end - end price
  1016. * @param duration - auction duration time
  1017. * @returns {Promise<PromiEvent<any>>}
  1018. */
  1019. async apostleBreedAuction(tokenId, start, end, duration, callback = {}) {
  1020. const from = await this.getCurrentAccount()
  1021. const _from = Utils.padLeft(from.slice(2), 64, '0')
  1022. const _start = Utils.toHexAndPadLeft(start).slice(2)
  1023. const _end = Utils.toHexAndPadLeft(end).slice(2)
  1024. const _duration = Utils.toHexAndPadLeft(duration).slice(2)
  1025. const data = `0x${_start}${_end}${_duration}${_from}`
  1026. return this.triggerContract({
  1027. methodName: 'approveAndCall',
  1028. abiKey: 'land',
  1029. abiString: landABI,
  1030. contractParams: [this.ABIs['apostleSiringAuction'].address, '0x' + tokenId, data],
  1031. }, callback)
  1032. }
  1033. /**
  1034. * Cancel apostle breed auction
  1035. * @param tokenId
  1036. * @returns {Promise<PromiEvent<any>>}
  1037. */
  1038. apostleCancelBreedAuction(tokenId, callback = {}) {
  1039. return this.triggerContract({
  1040. methodName: 'cancelAuction',
  1041. abiKey: 'apostleSiringAuction',
  1042. abiString: apostleSiringABI,
  1043. contractParams: [
  1044. '0x' + tokenId
  1045. ]
  1046. }, callback)
  1047. }
  1048. /**
  1049. * Transfer apostle
  1050. * @param toAddress
  1051. * @param tokenId
  1052. * @returns {Promise<PromiEvent<any>>}
  1053. */
  1054. async apostleTransfer(toAddress, tokenId, callback = {}) {
  1055. const from = await this.getCurrentAccount()
  1056. return this.triggerContract({
  1057. methodName: 'transferFrom',
  1058. abiKey: 'land',
  1059. abiString: landABI,
  1060. contractParams: [
  1061. from, toAddress, '0x' + tokenId
  1062. ]
  1063. }, callback)
  1064. }
  1065. /**
  1066. * Let apostle go to work
  1067. * @param tokenId - Apostle tokenId
  1068. * @param landTokenId - Land tokenId
  1069. * @param element - ['gold', 'wood', 'water', 'fire' ,'soil']
  1070. */
  1071. apostleWork(tokenId, landTokenId, element, callback = {}) {
  1072. const elementAddress = this.ABIs[element.toLowerCase() || 'token'].address
  1073. return this.triggerContract({
  1074. methodName: 'startMining',
  1075. abiKey: 'apostleLandResource',
  1076. abiString: landResourceABI,
  1077. contractParams: [
  1078. '0x' + tokenId, '0x' + landTokenId, elementAddress
  1079. ]
  1080. }, callback)
  1081. }
  1082. /**
  1083. * Stop apostle mining
  1084. * @param tokenId - Apostle tokenId
  1085. */
  1086. apostleStopWorking(tokenId, callback = {}) {
  1087. return this.triggerContract({
  1088. methodName: 'stopMining',
  1089. abiKey: 'apostleLandResource',
  1090. abiString: landResourceABI,
  1091. contractParams: [
  1092. '0x' + tokenId
  1093. ]
  1094. }, callback)
  1095. }
  1096. /**
  1097. * Claim an apostle that expires at work
  1098. * @param tokenId - Apostle TokenId
  1099. * @returns {Promise<PromiEvent<any>>}
  1100. */
  1101. apostleHireClaim(tokenId, callback = {}) {
  1102. return this.triggerContract({
  1103. methodName: 'removeTokenUseAndActivity',
  1104. abiKey: 'apostleTokenUse',
  1105. abiString: tokenUseABI,
  1106. contractParams: [
  1107. '0x' + tokenId
  1108. ]
  1109. }, callback)
  1110. }
  1111. /**
  1112. * Renting apostles to work
  1113. * @param tokenId - Apostle TokenId
  1114. * @param duration - Duration in second
  1115. * @param price - Hire Price
  1116. */
  1117. apostleHire(tokenId, duration, price, callback = {}) {
  1118. const address = this.ABIs['apostleLandResource'].address
  1119. const _resourceAddress = Utils.padLeft(address.slice(2), 64, '0')
  1120. const _price = Utils.toHexAndPadLeft(price).slice(2)
  1121. const _duration = Utils.toHexAndPadLeft(duration).slice(2)
  1122. const data = `0x${_duration}${_price}${_resourceAddress}`
  1123. return this.triggerContract({
  1124. methodName: 'approveAndCall',
  1125. abiKey: 'land',
  1126. abiString: landABI,
  1127. contractParams: [
  1128. this.ABIs['apostleTokenUse'].address,
  1129. '0x' + tokenId,
  1130. data
  1131. ]
  1132. }, callback)
  1133. }
  1134. /**
  1135. * Cancel an apostle on Renting
  1136. * @param tokenId - Apostle tokenId
  1137. */
  1138. apostleCancelHire(tokenId, callback = {}) {
  1139. return this.triggerContract({
  1140. methodName: 'cancelTokenUseOffer',
  1141. abiKey: 'apostleTokenUse',
  1142. abiString: tokenUseABI,
  1143. contractParams: [
  1144. '0x' + tokenId
  1145. ]
  1146. }, callback)
  1147. }
  1148. /**
  1149. * Bid apostle on Renting
  1150. * @param tokenId - Apostle tokenId
  1151. * @param price - bid price
  1152. */
  1153. apostleHireBid(tokenId, price, callback = {}) {
  1154. return this.triggerContract({
  1155. methodName: 'transfer',
  1156. abiKey: 'ring',
  1157. abiString: ringABI,
  1158. contractParams: [
  1159. this.ABIs['apostleTokenUse'].address,
  1160. price,
  1161. `0x${tokenId}`
  1162. ]
  1163. }, callback)
  1164. }
  1165. /**
  1166. * Apostle Born without element
  1167. * @param motherTokenId
  1168. */
  1169. apostleBorn(motherTokenId, callback = {}) {
  1170. return this.triggerContract({
  1171. methodName: 'giveBirth',
  1172. abiKey: 'apostleBase',
  1173. abiString: apostleBaseABI,
  1174. contractParams: [
  1175. '0x' + motherTokenId,
  1176. Utils.padLeft(0, 40, '0'),
  1177. 0
  1178. ]
  1179. }, callback)
  1180. }
  1181. /**
  1182. * Apostle Born with element
  1183. * @param motherTokenId
  1184. * @param element
  1185. * @param level
  1186. * @param levelUnitPrice
  1187. */
  1188. apostleBornAndEnhance(
  1189. motherTokenId,
  1190. element,
  1191. level,
  1192. levelUnitPrice,
  1193. callback = {}
  1194. ) {
  1195. return this.triggerContract({
  1196. methodName: 'transfer',
  1197. abiKey: element.toLowerCase(),
  1198. abiString: ringABI,
  1199. contractParams: [
  1200. this.ABIs['apostleBase'].address,
  1201. new BigNumber(level).times(new BigNumber(levelUnitPrice)).toFixed(),
  1202. `0x${motherTokenId}${Utils.toHexAndPadLeft(level).slice(2)}`
  1203. ]
  1204. }, callback)
  1205. }
  1206. /**
  1207. * Bind pet
  1208. * @param originNftAddress
  1209. * @param originTokenId
  1210. * @param apostleTokenId
  1211. * @returns {Promise<PromiEvent<any>>}
  1212. */
  1213. bridgeInAndTie(originNftAddress, originTokenId, apostleTokenId, callback = {}) {
  1214. return this.triggerContract({
  1215. methodName: 'bridgeInAndTie',
  1216. abiKey: 'petBase',
  1217. abiString: petBaseABI,
  1218. contractParams: [originNftAddress, originTokenId, '0x' + apostleTokenId]
  1219. }, callback)
  1220. }
  1221. /**
  1222. * Unbind pet
  1223. * @param petTokenId
  1224. * @returns {Promise<PromiEvent<any>>}
  1225. */
  1226. untiePetToken(petTokenId, callback = {}) {
  1227. return this.triggerContract({
  1228. methodName: 'untiePetToken',
  1229. abiKey: 'petBase',
  1230. abiString: petBaseABI,
  1231. contractParams: ['0x' + petTokenId]
  1232. }, callback)
  1233. }
  1234. /**
  1235. * buy lucky box
  1236. * @param {*} buyer - Receiver
  1237. * @param {*} goldBoxAmount - gold box amount
  1238. * @param {*} silverBoxAmount - silver box amount
  1239. */
  1240. async buyLuckyBox(buyer, goldBoxAmount, silverBoxAmount, callback) {
  1241. const luckyBoxInfo = await this.getLuckyBoxInfo()
  1242. const cost = Utils.toBN(luckyBoxInfo[0]).muln(goldBoxAmount).add(Utils.toBN(luckyBoxInfo[1]).muln(silverBoxAmount))
  1243. return this.triggerContract({
  1244. methodName: 'buyBoxs',
  1245. abiKey: 'luckybag',
  1246. abiString: luckyBoxABI,
  1247. contractParams: [buyer, goldBoxAmount, silverBoxAmount],
  1248. sendParams: {
  1249. value: cost
  1250. }
  1251. }, callback)
  1252. }
  1253. /**
  1254. * lucky box information
  1255. * @returns {Array} - promise -> [goldBoxPrice, silverBoxPrice, goldBoxAmountForSale, silverBoxAmountForSale, goldSaleLimit, silverSaleLimit]
  1256. */
  1257. getLuckyBoxInfo() {
  1258. const _contract = new this._web3js.eth.Contract(luckyBoxABI, this.ABIs['luckybag'].address)
  1259. return Promise.all([
  1260. _contract.methods.goldBoxPrice().call(),
  1261. _contract.methods.silverBoxPrice().call(),
  1262. _contract.methods.goldBoxAmountForSale().call(),
  1263. _contract.methods.silverBoxAmountForSale().call(),
  1264. _contract.methods.goldSaleLimit().call(),
  1265. _contract.methods.silverSaleLimit().call(),
  1266. ])
  1267. }
  1268. /**
  1269. * Number of lucky box already purchased at this address
  1270. * @param {*} address - buyer
  1271. * @returns {Array} - promise -> [goldSalesRecord, silverSalesRecord]
  1272. */
  1273. getLuckyBoxSalesRecord(address) {
  1274. const _contract = new this._web3js.eth.Contract(luckyBoxABI, this.ABIs['luckybag'].address)
  1275. return Promise.all([
  1276. _contract.methods.goldSalesRecord(address).call(),
  1277. _contract.methods.silverSalesRecord(address).call(),
  1278. ])
  1279. }
  1280. /**
  1281. * get furnace treasure price
  1282. * @returns {} - promise -> {0: "1026000000000000000000", 1: "102000000000000000000", priceGoldBox: "1026000000000000000000", priceSilverBox: "102000000000000000000"}
  1283. */
  1284. getFurnaceTreasurePrice() {
  1285. const _contract = new this._web3js.eth.Contract(itemTreasureABI, this.ABIs['itemTreasure'].address)
  1286. return _contract.methods.getPrice().call()
  1287. }
  1288. getFurnaceTakeBackNonce(address) {
  1289. const _contract = new this._web3js.eth.Contract(itemTakeBackABI, this.ABIs['itemTakeBack'].address)
  1290. return _contract.methods.userToNonce(address).call()
  1291. }
  1292. /**
  1293. * buy lucky box
  1294. * @param {*} goldBoxAmount - gold box amount
  1295. * @param {*} silverBoxAmount - silver box amount
  1296. */
  1297. async buyFurnaceTreasure(goldBoxAmount = 0, silverBoxAmount = 0, callback) {
  1298. const treasurePrice = await this.getFurnaceTreasurePrice()
  1299. const cost = Utils.toBN(treasurePrice.priceGoldBox).muln(goldBoxAmount).add(Utils.toBN(treasurePrice.priceSilverBox).muln(silverBoxAmount))
  1300. // Function: transfer(address _to, uint256 _value, bytes _data) ***
  1301. // data
  1302. // 0000000000000000000000000000000000000000000000000000000000000001 gold box amount
  1303. // 0000000000000000000000000000000000000000000000000000000000000002 silver box amount
  1304. const data = Utils.toTwosComplement(goldBoxAmount) + Utils.toTwosComplement(silverBoxAmount).substring(2, 66)
  1305. return this.triggerContract({
  1306. methodName: 'transfer',
  1307. abiKey: 'ring',
  1308. abiString: ringABI,
  1309. contractParams: [this.ABIs['itemTreasure'].address, cost.toString(10), data],
  1310. sendParams: {
  1311. value: 0
  1312. }
  1313. }, callback)
  1314. }
  1315. /**
  1316. * open furnace treasure
  1317. * @returns {Promise<PromiEvent<any>>}
  1318. */
  1319. openFurnaceTreasure({
  1320. boxIds,
  1321. amounts,
  1322. hashmessage,
  1323. v,
  1324. r,
  1325. s
  1326. }, callback = {}) {
  1327. // During the process of opening the treasure chest, there is the logic of randomly gifting rings,
  1328. // which leads to inaccurate gas estimation, so manually set it to avoid out of gas.
  1329. // https://etherscan.io/tx/0xe71f54aee8f7ab1dd15df955d09c79af5060f20e91c0c5ecfcf17f20c9bf02b3
  1330. // https://etherscan.io/tx/0x7b04df9b55f33b6edcc402a5733dbc753a6bbe2f78af7c7bef6f3f4d8dce7491
  1331. // no return ring - gas used - 229,289
  1332. // https://etherscan.io/tx/0x4e1fc1dcec64bb497405126e55ab743368f1cb1cede945936937e0cde1d254e7
  1333. // prize ring - gas used - 254,776
  1334. // https://etherscan.io/tx/0xd2b3f05b19e74627940edfe98daee31eeab84b67e88dcf0e77d595430b3b1afc
  1335. let gasLimit = new BigNumber(amounts[0]).lt('1000000000000000000000') ? new BigNumber(260000) : new BigNumber(300000);
  1336. if(amounts.length > 1) {
  1337. for (let index = 1; index < amounts.length; index++) {
  1338. const amount = amounts[index];
  1339. gasLimit = gasLimit.plus(new BigNumber(amount).lt('1000000000000000000000') ? new BigNumber(260000) : new BigNumber(260000));
  1340. }
  1341. }
  1342. return this.triggerContract({
  1343. methodName: "openBoxes",
  1344. abiString: itemTakeBackABI,
  1345. contractParams: [
  1346. boxIds,
  1347. amounts,
  1348. hashmessage,
  1349. v,
  1350. r,
  1351. s
  1352. ],
  1353. sendParams: {
  1354. value: 0,
  1355. gasLimit: gasLimit.toFixed(0)
  1356. },
  1357. abiKey: "itemTakeBack",
  1358. }, callback);
  1359. }
  1360. checkFurnaceTreasureStatus(id) {
  1361. const _contract = new this._web3js.eth.Contract(itemTakeBackABI, this.ABIs['itemTakeBack'].address)
  1362. return _contract.methods.ids(id).call()
  1363. }
  1364. /**
  1365. * Returns the amount of RING owned by account
  1366. * @param {*} address
  1367. */
  1368. getRingBalance(address) {
  1369. const _contract = new this._web3js.eth.Contract(ringABI, this.ABIs['ring'].address)
  1370. return _contract.methods.balanceOf(address).call()
  1371. }
  1372. /**
  1373. * Returns the amount of KTON owned by account
  1374. * @param {*} address
  1375. */
  1376. getKtonBalance(address) {
  1377. const _contract = new this._web3js.eth.Contract(ktonABI, this.ABIs['kton'].address)
  1378. return _contract.methods.balanceOf(address).call()
  1379. }
  1380. /**
  1381. * Returns the amount of tokens owned by account
  1382. * @param {*} account
  1383. * @param {*} contractAddress
  1384. */
  1385. getTokenBalance(account, contractAddress) {
  1386. const _contract = new this._web3js.eth.Contract(ringABI, contractAddress)
  1387. return _contract.methods.balanceOf(account).call()
  1388. }
  1389. /**
  1390. * Get total supply of erc20 token
  1391. * @param {*} contractAddress Erc20 contract address
  1392. */
  1393. getTokenTotalSupply(contractAddress) {
  1394. const _contract = new this._web3js.eth.Contract(ringABI, contractAddress)
  1395. return _contract.methods.totalSupply().call()
  1396. }
  1397. /**
  1398. * transfer evo land 721 object
  1399. * @param {*} to recevier
  1400. * @param {*} tokenId 721 tokenid
  1401. * @param {*} callback
  1402. */
  1403. async transferFromObjectOwnership(to, tokenId, callback = {}) {
  1404. if (!to) {
  1405. return null
  1406. }
  1407. const from = await this.getCurrentAccount()
  1408. return this.triggerContract({
  1409. methodName: 'transferFrom',
  1410. abiKey: 'land',
  1411. abiString: landABI,
  1412. contractParams: [from, to, '0x' + tokenId],
  1413. }, callback)
  1414. }
  1415. /**
  1416. * Get uniswap Token info by lowercase symbol
  1417. *
  1418. * Token - https://uniswap.org/docs/v2/SDK/token/
  1419. *
  1420. * @param {*} tokenType ring kton gold wood water fire soil
  1421. */
  1422. getUniswapToken(tokenType) {
  1423. switch (tokenType.toLowerCase()) {
  1424. case 'ring':
  1425. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_RING, 18, "RING", "Darwinia Network Native Token");
  1426. case 'kton':
  1427. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_KTON, 18, "KTON", "KTON");
  1428. case 'gold':
  1429. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_ELEMENT_GOLD, 18, "GOLD", "GOLD");
  1430. case 'wood':
  1431. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_ELEMENT_WOOD, 18, "WOOD", "WOOD");
  1432. case 'water':
  1433. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_ELEMENT_WATER, 18, "WATER", "WATER");
  1434. case 'fire':
  1435. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_ELEMENT_FIRE, 18, "FIRE", "FIRE");
  1436. case 'soil':
  1437. return new Token(parseInt(this.env.CONTRACT.NETWORK), this.env.CONTRACT.TOKEN_ELEMENT_SOIL, 18, "SOIL", "SOIL");
  1438. default:
  1439. break;
  1440. }
  1441. }
  1442. /**
  1443. * Get uniswap pair info
  1444. * @param {*} tokenA token address or lowercase symbol (ring kton gold wood water fire soil)
  1445. * @param {*} tokenB token address or lowercase symbol (ring kton gold wood water fire soil)
  1446. * @returns { pair } pair - https://uniswap.org/docs/v2/SDK/pair/
  1447. */
  1448. async getDerivedPairInfo(tokenA, tokenB) {
  1449. if(!tokenA || !tokenB) {
  1450. return;
  1451. }
  1452. const currencyA = this.getUniswapToken(tokenA);
  1453. const currencyB = this.getUniswapToken(tokenB);
  1454. const pair = await Fetcher.fetchPairData(currencyA, currencyB);
  1455. return pair;
  1456. }
  1457. /**
  1458. * Support for addUniswapLiquidity function, and the return router pair instances and elements are returned.
  1459. *
  1460. * Only one account needs to be provided, and the other quantity needs to be provided according to the current pool price
  1461. *
  1462. * tokenType - token address or lowercase symbol (ring kton gold wood water fire soil)
  1463. *
  1464. * amount - amount in WEI
  1465. *
  1466. * @param {*} param0 {token: tokenAType, amount: amountA}
  1467. * @param {*} param1 {token: tokenBType, amount: amountB}
  1468. * @returns {*} {pair, parsedAmounts} pair - https://uniswap.org/docs/v2/SDK/pair/ parsedAmounts - {token0address: amount, token1address: amount}
  1469. */
  1470. async getDerivedMintInfo({token: tokenAType, amount: amountA}, {token: tokenBType, amount: amountB}) {
  1471. const pair = await this.getDerivedPairInfo(tokenAType, tokenBType);
  1472. const totalSupply = new TokenAmount(pair.liquidityToken, await this.getTokenTotalSupply(pair.liquidityToken.address));
  1473. const independentToken = amountA ?
  1474. { token: this.getUniswapToken(tokenAType), amount: amountA} :
  1475. { token: this.getUniswapToken(tokenBType), amount: amountB};
  1476. const parsedAmounts = {
  1477. [pair.liquidityToken.address]: totalSupply,
  1478. [pair.token0.address]: new TokenAmount(pair.token0, independentToken.token.equals(pair.token0) ? JSBI.BigInt(independentToken.amount) : pair.priceOf(independentToken.token).quote(new CurrencyAmount(independentToken.token, JSBI.BigInt(independentToken.amount))).raw),
  1479. [pair.token1.address]: new TokenAmount(pair.token1, independentToken.token.equals(pair.token1) ? JSBI.BigInt(independentToken.amount) : pair.priceOf(independentToken.token).quote(new CurrencyAmount(independentToken.token, JSBI.BigInt(independentToken.amount))).raw),
  1480. }
  1481. return { pair, parsedAmounts }
  1482. }
  1483. /**
  1484. * Support for removeUniswapLiquidity function, assuming removal percentage of liquidity and the return router pair instances and elements are returned.
  1485. *
  1486. * tokenType - token address or lowercase symbol (ring kton gold wood water fire soil)
  1487. *
  1488. * pair - https://uniswap.org/docs/v2/SDK/pair/
  1489. *
  1490. * TokenAmount - https://github.com/Uniswap/uniswap-sdk/blob/v2/src/entities/fractions/tokenAmount.ts
  1491. *
  1492. * parsedAmounts - {
  1493. *
  1494. * LIQUIDITY_PERCENT: percent,
  1495. *
  1496. * liquidityTokenAddress: TokenAmount,
  1497. *
  1498. * token0Address: TokenAmount,
  1499. *
  1500. * token1Address: TokenAmount
  1501. *
  1502. * }
  1503. *
  1504. * @param {*} tokenAType
  1505. * @param {*} tokenBType
  1506. * @param {*} liquidityValue The value of liquidity removed
  1507. * @param {*} to
  1508. * @returns {*} {pair, parsedAmounts}
  1509. */
  1510. async getDerivedBurnInfo(tokenAType, tokenBType, liquidityValue, to) {
  1511. const pair = await this.getDerivedPairInfo(tokenAType, tokenBType);
  1512. if(!to) {
  1513. to = await this.getCurrentAccount();
  1514. }
  1515. const lpBalanceStr = await this.getTokenBalance(to, pair.liquidityToken.address);
  1516. const userLiquidity = new TokenAmount(pair.liquidityToken, JSBI.BigInt(lpBalanceStr));
  1517. const totalSupply = new TokenAmount(pair.liquidityToken, await this.getTokenTotalSupply(pair.liquidityToken.address));
  1518. const liquidityValueA = pair &&
  1519. totalSupply &&
  1520. userLiquidity &&
  1521. pair.token0 && new TokenAmount(pair.token0, pair.getLiquidityValue(pair.token0, totalSupply, userLiquidity, false).raw);
  1522. const liquidityValueB = pair &&
  1523. totalSupply &&
  1524. userLiquidity &&
  1525. pair.token1 && new TokenAmount(pair.token1, pair.getLiquidityValue(pair.token1, totalSupply, userLiquidity, false).raw);
  1526. const percentToRemove = new Percent(JSBI.BigInt(liquidityValue), userLiquidity.raw);
  1527. const parsedAmounts = {
  1528. LIQUIDITY_PERCENT: percentToRemove,
  1529. [pair.liquidityToken.address]: new TokenAmount(userLiquidity.token, percentToRemove.multiply(userLiquidity.raw).quotient),
  1530. [pair.token0.address]: new TokenAmount(pair.token0, percentToRemove.multiply(liquidityValueA.raw).quotient),
  1531. [pair.token1.address]: new TokenAmount(pair.token1, percentToRemove.multiply(liquidityValueB.raw).quotient),
  1532. }
  1533. return { pair, parsedAmounts }
  1534. }
  1535. /**
  1536. * Adds liquidity to an ERC-20⇄ERC-20 pool
  1537. *
  1538. * msg.sender should have already given the router an allowance of at least amount on tokenA/tokenB.
  1539. *
  1540. * Always adds assets at the ideal ratio, according to the price when the transaction is executed.
  1541. *
  1542. * @param {*} param0 {token: tokenAType, amount: amountA}
  1543. * @param {*} param1 {token: tokenBType, amount: amountB}
  1544. * @param {*} to Recipient of the liquidity tokens.
  1545. * @param {*} slippage The amount the price moves in a trading pair between when a transaction is submitted and when it is executed.
  1546. * @param {*} callback
  1547. */
  1548. async addUniswapLiquidity({token: tokenAType, amount: amountA}, {token: tokenBType, amount: amountB}, to, slippage = 100, callback = {}) {
  1549. const { pair, parsedAmounts } = await this.getDerivedMintInfo({token: tokenAType, amount: amountA}, {token: tokenBType, amount: amountB});
  1550. if(!pair || !pair.token0.address || !pair.token1.address) {
  1551. return;
  1552. }
  1553. if(!to) {
  1554. to = await this.getCurrentAccount();
  1555. }
  1556. const amountsMin = {
  1557. [pair.token0.address]: UniswapUtils.calculateSlippageAmount(parsedAmounts[pair.token0.address].raw, slippage)[0],
  1558. [pair.token1.address]: UniswapUtils.calculateSlippageAmount(parsedAmounts[pair.token1.address].raw, slippage)[0]
  1559. }
  1560. const deadline = Math.floor(Date.now() / 1000) + 60 * 120 // 120 minutes from the current Unix time
  1561. // https://uniswap.org/docs/v2/smart-contracts/router02/#addliquidity
  1562. return this.triggerContract({
  1563. methodName: 'addLiquidity',
  1564. abiKey: 'uniswapExchange',
  1565. abiString: uniswapExchangeABI,
  1566. contractParams: [
  1567. pair.token0.address,
  1568. pair.token1.address,
  1569. parsedAmounts[pair.token0.address].raw.toString(),
  1570. parsedAmounts[pair.token1.address].raw.toString(),
  1571. amountsMin[pair.token0.address].toString(),
  1572. amountsMin[pair.token1.address].toString(),
  1573. to,
  1574. deadline
  1575. ],
  1576. sendParams: {
  1577. value: 0
  1578. }
  1579. }, callback)
  1580. }
  1581. /**
  1582. * Removes liquidity from an ERC-20⇄ERC-20 pool.
  1583. *
  1584. * msg.sender should have already given the router an allowance of at least liquidity on the pool.
  1585. *
  1586. * @param {*} tokenAType A pool token.
  1587. * @param {*} tokenBType A pool token.
  1588. * @param {*} liquidityValue The value of liquidity tokens to remove.
  1589. * @param {*} to Recipient of the underlying assets.
  1590. * @param {*} slippage The amount the price moves in a trading pair between when a transaction is submitted and when it is executed.
  1591. * @param {*} callback
  1592. */
  1593. async removeUniswapLiquidity(tokenAType, tokenBType, liquidityValue, to, slippage = 100, callback = {}) {
  1594. if(!to) {
  1595. to = await this.getCurrentAccount();
  1596. }
  1597. const { pair, parsedAmounts } = await this.getDerivedBurnInfo(tokenAType, tokenBType, liquidityValue, to);
  1598. if(!pair || !pair.token0.address || !pair.token1.address) {
  1599. return;
  1600. }
  1601. const amountsMin = {
  1602. [pair.token0.address]: UniswapUtils.calculateSlippageAmount(parsedAmounts[pair.token0.address].raw, slippage)[0],
  1603. [pair.token1.address]: UniswapUtils.calculateSlippageAmount(parsedAmounts[pair.token1.address].raw, slippage)[0]
  1604. }
  1605. const deadline = Math.floor(Date.now() / 1000) + 60 * 120 // 20 minutes from the current Unix time
  1606. // https://uniswap.org/docs/v2/smart-contracts/router02/#removeliquidity
  1607. return this.triggerContract({
  1608. methodName: 'removeLiquidity',
  1609. abiKey: 'uniswapExchange',
  1610. abiString: uniswapExchangeABI,
  1611. contractParams: [
  1612. pair.token0.address,
  1613. pair.token1.address,
  1614. parsedAmounts[pair.liquidityToken.address].raw.toString(),
  1615. amountsMin[pair.token0.address].toString(),
  1616. amountsMin[pair.token1.address].toString(),
  1617. to,
  1618. deadline
  1619. ],
  1620. sendParams: {
  1621. value: 0
  1622. }
  1623. }, callback)
  1624. }
  1625. /**
  1626. * Use nft and elements or LP tokens in the furnace formula to the props.
  1627. * @param {*} formulaIndex Formula for props - https://github.com/evolutionlandorg/furnace/blob/dev/src/Formula.sol
  1628. * @param {*} majorTokenId ERC721 token Id
  1629. * @param {*} minorTokenAddress Elements or LP tokens contract address
  1630. * @param {*} callback callback
  1631. */
  1632. enchantFurnanceProps( formulaIndex, majorTokenId, minorTokenAddress, callback = {}) {
  1633. return this.triggerContract({
  1634. methodName: 'enchant',
  1635. abiKey: 'furnaceItemBase',
  1636. abiString: furnaceItemBaseABI,
  1637. contractParams: [
  1638. formulaIndex,
  1639. majorTokenId,
  1640. minorTokenAddress
  1641. ],
  1642. sendParams: {
  1643. value: 0
  1644. }
  1645. }, callback)
  1646. }
  1647. /**
  1648. * Disenchant furnace props, and will get elements or LP and nft
  1649. * @param {*} propsTokenId Token Id of the Props
  1650. * @param {*} depth Supports one-time decomposition of high-level props. If a prop is in the second level, it needs to be restored to its original state, and the depth needs to be passed in 2
  1651. * @param {*} callback
  1652. */
  1653. disenchantFurnanceProps( propsTokenId, depth, callback = {}) {
  1654. return this.triggerContract({
  1655. methodName: 'disenchant',
  1656. abiKey: 'furnaceItemBase',
  1657. abiString: furnaceItemBaseABI,
  1658. contractParams: [
  1659. propsTokenId,
  1660. depth
  1661. ],
  1662. sendParams: {
  1663. value: 0
  1664. }
  1665. }, callback)
  1666. }
  1667. /**
  1668. * Transfers the ownership of an NFT from one address to another address
  1669. * @param {*} from The current owner of the NFT
  1670. * @param {*} to The new owner
  1671. * @param {*} tokenId The NFT to transfer
  1672. * @param {*} callback
  1673. */
  1674. safeTransferFromEvoErc721(from, to, tokenId, callback = {}) {
  1675. return this.triggerContract({
  1676. methodName: 'safeTransferFrom',
  1677. abiKey: 'objectOwnership',
  1678. abiString: this.ABIs['erc721'].abi,
  1679. contractParams: [
  1680. from,
  1681. to,
  1682. tokenId
  1683. ]
  1684. }, callback)
  1685. }
  1686. /**
  1687. * Equip function, A NFT can equip to EVO Bar (LandBar or ApostleBar).
  1688. * @param {*} tokenId Land token Id which to be quiped.
  1689. * @param {*} resource Which resouce appply to.
  1690. * @param {*} index Index of the Bar.
  1691. * @param {*} token Props token address which to quip.
  1692. * @param {*} id Props token Id which to quip.
  1693. * @param {*} callabck
  1694. */
  1695. async equipLandResource(tokenId, resource, index, token, id, callback = {}) {
  1696. const resourceAddress = await this.getContractAddress(resource);
  1697. return this.triggerContract({
  1698. methodName: 'equip',
  1699. abiKey: 'apostleLandResource',
  1700. abiString: this.ABIs['apostleLandResource'].abi,
  1701. contractParams: [
  1702. tokenId, resourceAddress, index, token, id
  1703. ]
  1704. }, callback)
  1705. }
  1706. /**
  1707. * Divest the props on the index slot on the tokenid land
  1708. * @param {*} tokenId The tokenId of land
  1709. * @param {*} index The index slot
  1710. * @param {*} callback
  1711. */
  1712. divestLandProps(tokenId, index, callback = {}) {
  1713. return this.triggerContract({
  1714. methodName: 'divest',
  1715. abiKey: 'apostleLandResource',
  1716. abiString: this.ABIs['apostleLandResource'].abi,
  1717. contractParams: [
  1718. tokenId, index
  1719. ]
  1720. }, callback)
  1721. }
  1722. /**
  1723. * claim resource on the Land
  1724. * @param tokenAddress The nft of props contract address
  1725. * @param tokenId Land token Id
  1726. * @returns {Promise<PromiEvent<any>>}
  1727. */
  1728. claimFurnaceItemResource(tokenAddress, tokenId, callback = {}) {
  1729. return this.triggerContract({
  1730. methodName: 'claimItemResource',
  1731. abiKey: 'apostleLandResource',
  1732. abiString: landResourceABI,
  1733. contractParams: [tokenAddress, Utils.pad0x(tokenId)],
  1734. }, callback)
  1735. }
  1736. estimateGas(method, address, gasPrice, value = 0) {
  1737. if (!this._web3js) return;
  1738. return (method || this._web3js.eth).estimateGas({ from: address, gasLimit: 0, gasPrice: gasPrice, value });
  1739. }
  1740. getNetworkId() {
  1741. return this._web3js.eth.net.getId()
  1742. }
  1743. /**
  1744. * check address info
  1745. * @param address - Ethereum address
  1746. */
  1747. checkAddress(address) {
  1748. return this.ClientFetch.$get('/api/verified_wallet', {
  1749. wallet: address
  1750. })
  1751. }
  1752. challengeAddress(address) {
  1753. return this.ClientFetch.$get('/api/challenge', {
  1754. wallet: address
  1755. })
  1756. }
  1757. async _sign({
  1758. data,
  1759. name
  1760. }, from) {
  1761. let signature;
  1762. try {
  1763. signature = await this._web3js.eth.personal.sign(
  1764. name + " " + data,
  1765. from
  1766. );
  1767. } catch (e) {
  1768. }
  1769. return {
  1770. address: from,
  1771. signature
  1772. };
  1773. }
  1774. /**
  1775. * Login Evolution Land
  1776. * @param address - Ethereum address
  1777. * @returns {Promise<*>}
  1778. */
  1779. async login(address) {
  1780. return new Promise((resolve, reject) => {
  1781. this.challengeAddress(address).then((res) => {
  1782. const {
  1783. code,
  1784. data,
  1785. name
  1786. } = res
  1787. if (code === 0) {
  1788. this._sign({
  1789. data,
  1790. name
  1791. }, address)
  1792. .then(info => {
  1793. if (info.signature) {
  1794. this.ClientFetch.$post('/api/login', {
  1795. wallet: address,
  1796. sign: info.signature
  1797. }).then((res) => {
  1798. resolve(res)
  1799. })
  1800. } else {
  1801. reject({
  1802. code,
  1803. data
  1804. })
  1805. }
  1806. })
  1807. .catch(err => reject(err))
  1808. }
  1809. })
  1810. })
  1811. }
  1812. }
  1813. export default EthereumEvolutionLand