approve token for deposit
MODIFY
examples/node/deposit-ERC20.js
examples/node/deposit-ERC20.js
-const Matic = require('maticjs').default
-const config = require('./config')
+const bn = require('bn.js')
+const Matic = require('../../dist/index').default
+const config = require('./config')
const token = config.ROPSTEN_TEST_TOKEN // test token address
-const amount = '1000000000000000000' // amount in wei
+// const amount = '1000000000000000000' // amount in wei
+const amount = new bn(100000000) // amount in wei
+
const from = config.FROM_ADDRESS // from address
// Create object of Matic
const matic = new Matic({
maticProvider: config.MATIC_PROVIDER,
parentProvider: config.PARENT_PROVIDER,
- rootChainAddress: config.ROOTCHAIN_ADDRESS,
- syncerUrl: config.SYNCER_URL,
- watcherUrl: config.WATCHER_URL,
+ rootChain: config.ROOTCHAIN_ADDRESS,
+ registry: config.REGISTRY_ADDRESS,
+ depositManager: config.DEPOSITMANAGER_ADDRESS,
+ withdrawManager: config.WITHDRAWMANAGER_ADDRESS,
})
-matic.wallet = config.PRIVATE_KEY // prefix with `0x`
-
+matic.initialize().then(() => {
+ matic.wallet(config.PRIVATE_KEY)
// Approve token
matic
.approveERC20TokensForDeposit(token, amount, {
@@ -35,3 +39,5 @@ matic
},
})
})
+
+})
\ No newline at end of file

MODIFY
package.json
package.json
{
- "name": "maticjs",
- "version": "1.0.0-beta.16",
+ "name": "@maticnetwork/maticjs",
+ "version": "2.0.0-beta.0",
"description": "Javascript developer library for interacting with Matic Network",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"matic-protocol": "github:atvanguard/contracts#d8cf2444713af700de6030fd4721a430fe36f28d",
"merkle-patricia-tree": "2.3.2",
"query-string": "6.8.1",
- "web3": "1.2.1"
+ "web3": "1.2.1",
+ "web3-providers-ws": "1.2.4"
},
"devDependencies": {
"babel-eslint": "7.2.3",

MODIFY
src/common/ContractsBase.ts
src/common/ContractsBase.ts
import Web3Client from './Web3Client'
import BN from 'bn.js'
-import assert from 'assert';
+import assert from 'assert'
import ChildERC20Artifact from 'matic-protocol/contracts-core/artifacts/ChildERC20.json'
import ChildERC721Artifact from 'matic-protocol/contracts-core/artifacts/ChildERC721.json'
@@ -22,12 +22,47 @@ export default class ContractsBase {
}
}
- public getERC20TokenContract(token: address) {
- return new this.web3Client.web3.eth.Contract(ChildERC20Artifact.abi, token)
+ public getERC20TokenContract(token: address, parent: boolean = false) {
+ const web3 = parent ? this.web3Client.parentWeb3 : this.web3Client.web3
+ return new web3.eth.Contract(ChildERC20Artifact.abi, token)
}
- public getERC721TokenContract(token: address) {
- return new this.web3Client.web3.eth.Contract(ChildERC721Artifact.abi, token)
+ public getERC721TokenContract(token: address, parent: boolean = false) {
+ const web3 = parent ? this.web3Client.parentWeb3 : this.web3Client.web3
+ return new web3.eth.Contract(ChildERC721Artifact.abi, token)
+ }
+
+ async _fillOptions(options, txObject, web3) {
+ delete txObject.chainId
+ const from = options.from
+ if (!from) {
+ throw new Error(
+ '`from` required in options or set wallet using maticObject.wallet = <private key>',
+ )
+ }
+
+ const [gasLimit, gasPrice, nonce, chainId] = await Promise.all([
+ !(options.gasLimit || options.gas)
+ ? txObject.estimateGas({ from, value: options.value })
+ : options.gasLimit || options.gas,
+ // NOTE: Gas Price is set to '0', take care of type of gasPrice on web3^1.0.0-beta.36
+ !options.gasPrice ? web3.eth.getGasPrice() : options.gasPrice,
+ !options.nonce
+ ? web3.eth.getTransactionCount(from, 'pending')
+ : options.nonce,
+ !options.chainId ? web3.eth.net.getId() : options.chainId,
+ ])
+ return {
+ from,
+ gas: gasLimit,
+ gasLimit,
+ gasPrice,
+ nonce,
+ chainId,
+ value: options.value || 0,
+ to: options.to || null,
+ data: options.data,
+ }
}
wrapWeb3Promise(promise, options) {

MODIFY
src/common/Web3Client.ts
src/common/Web3Client.ts
@@ -7,32 +7,55 @@ export default class Web3Client {
public parentDefaultOptions: SendOptions
public maticDefaultOptions: SendOptions
- constructor(parentProvider, maticProvider, parentDefaultOptions, maticDefaultOptions) {
+ constructor(
+ parentProvider,
+ maticProvider,
+ parentDefaultOptions,
+ maticDefaultOptions,
+ ) {
this.parentWeb3 = new Web3(parentProvider)
this.web3 = new Web3(maticProvider)
this.parentDefaultOptions = parentDefaultOptions
this.maticDefaultOptions = maticDefaultOptions
}
+ set wallet(_wallet) {
+ this.parentWeb3.eth.accounts.wallet.add(_wallet)
+ this.web3.eth.accounts.wallet.add(_wallet)
+ }
+
async call(method, options?: SendOptions) {
return method.call(options || this.parentDefaultOptions)
}
- async send(method, options?) {
+ async _fillOptions(options, txObject, web3) {
const _options = options || this.parentDefaultOptions
if (!_options.from) return new Error('from is not specified')
- const gas = await method.estimateGas(JSON.parse(JSON.stringify(_options)))
- _options.gas = _options.gas || gas
- // since we use the delegated proxy patterns, the following should be a good way to provide enough gas
- // apparently even when provided with a buffer of 20k, the call reverts. This shouldn't be happening because the actual gas used is less than what the estimation returns
- // providing higher buffer for now
- // @todo handle hex values of gas
- _options.gas = _options.gas + 1000000
- console.log('sending tx with', _options)
- return this.wrapWeb3Promise(
- method.send(_options),
- _options
- )
+ const from = _options.from
+ delete txObject.chainId
+
+ const [gasLimit, gasPrice, nonce, chainId] = await Promise.all([
+ !(_options.gasLimit || _options.gas)
+ ? txObject.estimateGas({ from, value: _options.value })
+ : _options.gasLimit || _options.gas,
+ !_options.gasPrice ? web3.eth.getGasPrice() : _options.gasPrice,
+ !_options.nonce
+ ? web3.eth.getTransactionCount(from, 'pending')
+ : _options.nonce,
+ !_options.chainId ? web3.eth.net.getId() : _options.chainId,
+ ])
+
+ return {
+ from,
+ gas: gasLimit,
+ gasLimit: gasLimit,
+ gasPrice,
+ nonce,
+ chainId,
+ value: options.value || 0,
+ to: options.to || null,
+ data: options.data,
+ }
}
wrapWeb3Promise(promise, options) {
@@ -51,9 +74,19 @@ export default class Web3Client {
const _options = options || this.maticDefaultOptions
if (!_options.from) return new Error('from is not specified')
console.log('sending tx on matic with', _options)
- const receipt = await method.send(_options)
- console.log('yoyo')
- return receipt
+ return this.wrapWeb3Promise(method.send(_options), _options)
+ }
+
+ async send(txObject, options?) {
+ const _options = options || this.parentDefaultOptions
+ _options.gas = _options.gas + 1000000
+ // since we use the delegated proxy patterns, the following should be a good way to provide enough gas
+ // apparently even when provided with a buffer of 20k, the call reverts. This shouldn't be happening because the actual gas used is less than what the estimation returns
+ // providing higher buffer for now
+ // @todo handle hex values of gas
+ console.log('sending tx on matic with', _options)
+
+ return this.wrapWeb3Promise(txObject.send(_options), _options)
}
getParentWeb3() {

MODIFY
src/index.ts
src/index.ts
@@ -16,27 +16,74 @@ export default class Matic extends ContractsBase {
public registry: Registry
constructor(options: any = {}) {
- const web3Client = new Web3Client(options.parentProvider, options.maticProvider, options.parentDefaultOptions || {}, options.maticDefaultOptions || {})
+ const web3Client = new Web3Client(
+ options.parentProvider,
+ options.maticProvider,
+ options.parentDefaultOptions || {},
+ options.maticDefaultOptions || {},
+ )
super(web3Client)
this.web3Client = web3Client
this.registry = new Registry(options.registry, this.web3Client)
this.rootChain = new RootChain(options.rootChain, this.web3Client)
- this.depositManager = new DepositManager(options.depositManager, this.web3Client)
- this.withdrawManager = new WithdrawManager(options.withdrawManager, this.rootChain, this.web3Client, this.registry)
+ this.depositManager = new DepositManager(
+ options.depositManager,
+ this.web3Client,
+ )
+ this.withdrawManager = new WithdrawManager(
+ options.withdrawManager,
+ this.rootChain,
+ this.web3Client,
+ this.registry,
+ )
}
initialize() {
- return Promise.all([
- this.withdrawManager.initialize()
- ])
+ return Promise.all([this.withdrawManager.initialize()])
}
- transferTokens(token: address, to: address, amount: BN | string, options?: SendOptions) {
+ wallet(_wallet) {
+ this.web3Client.wallet = _wallet
+ }
+
+ transferERC20Tokens(
+ token: address,
+ to: address,
+ amount: BN | string,
+ options?: SendOptions,
+ ) {
+ if (options && (!options.from || !amount || !token || !to)) {
+ throw new Error('options.from, to, token or amount is missing')
+ }
return this.wrapWeb3Promise(
- this.getERC20TokenContract(token).methods
- .transfer(to, this.encode(amount))
+ this.getERC20TokenContract(token)
+ .methods.transfer(to, this.encode(amount))
.send(options),
- options
+ options,
)
}
+
+ async approveERC20TokensForDeposit(
+ token: address,
+ amount: BN | string,
+ options?: SendOptions,
+ ) {
+ if (options && (!options.from || !amount || !token)) {
+ throw new Error('options.from, token or amount is missing')
+ }
+
+ return this.depositManager.approveERC20(token, amount, options)
+ }
+
+ depositERC20ForUser(
+ token: address,
+ user: address,
+ amount: BN | string,
+ options?: SendOptions,
+ ) {
+ if (options && (!options.from || !amount || !token)) {
+ throw new Error('options.from, token or amount is missing')
+ }
+ return this.depositManager.depositERC20ForUser(token, amount, user, options)
+ }
}

MODIFY
src/root/DepositManager.ts
src/root/DepositManager.ts
@@ -11,48 +11,132 @@ export default class DepositManager extends ContractsBase {
constructor(depositManager: address, web3Client: Web3Client) {
super(web3Client)
- this.depositManagerContract = new this.web3Client.parentWeb3.eth.Contract(DepositManagerArtifact.abi, depositManager)
+ this.depositManagerContract = new this.web3Client.parentWeb3.eth.Contract(
+ DepositManagerArtifact.abi,
+ depositManager,
+ )
}
- depositERC20(token: address, amount: BN | string, options?: SendOptions) {
- return this.web3Client.send(
- this.depositManagerContract.methods.depositERC20(token, this.encode(amount)),
- options
+ async approveERC20(
+ token: address,
+ amount: BN | string,
+ options?: SendOptions,
+ ) {
+ const txObject = this.getERC20TokenContract(token, true).methods.approve(
+ this.depositManagerContract.options.address,
+ this.encode(amount),
+ )
+
+ const _options = await this._fillOptions(
+ options,
+ txObject,
+ this.web3Client.getParentWeb3(),
+ )
+
+ if (options.encodeAbi) {
+ _options.data = txObject.encodeABI()
+ _options.to = token
+ return _options
+ }
+
+ return this.web3Client.send(txObject, _options)
+ }
+
+ async depositERC20(
+ token: address,
+ amount: BN | string,
+ options?: SendOptions,
+ ) {
+ const txObject = this.depositManagerContract.methods.depositERC20(
+ token,
+ this.encode(amount),
)
+
+ const _options = await this._fillOptions(
+ options,
+ txObject,
+ this.web3Client.getParentWeb3(),
+ )
+
+ if (options.encodeAbi) {
+ _options.data = txObject.encodeABI()
+ _options.to = token
+ return _options
+ }
+
+ return this.web3Client.send(txObject, _options)
}
depositERC721(token: address, tokenId: string, options?: SendOptions) {
return this.web3Client.send(
this.depositManagerContract.methods.depositERC721(token, tokenId),
- options
+ options,
)
}
- depositBulk(tokens: address[], amountOrTokenIds: string[], user: address, options?: SendOptions) {
+ depositBulk(
+ tokens: address[],
+ amountOrTokenIds: string[],
+ user: address,
+ options?: SendOptions,
+ ) {
return this.web3Client.send(
- this.depositManagerContract.methods.depositBulk(tokens, amountOrTokenIds, user),
- options
+ this.depositManagerContract.methods.depositBulk(
+ tokens,
+ amountOrTokenIds,
+ user,
+ ),
+ options,
)
}
- depositERC20ForUser(token: address, amount: BN | string, user: address, options?: SendOptions) {
- return this.web3Client.send(
- this.depositManagerContract.methods.depositERC20ForUser(token, user, this.encode(amount)),
- options
+ async depositERC20ForUser(
+ token: address,
+ amount: BN | string,
+ user: address,
+ options?: SendOptions,
+ ) {
+ console.log('-->', token, user, this.encode(amount))
+ const txObject = this.depositManagerContract.methods.depositERC20ForUser(
+ token,
+ user,
+ this.encode(amount),
+ )
+ const _options = await this._fillOptions(
+ options,
+ txObject,
+ this.web3Client.getParentWeb3(),
)
+
+ if (options.encodeAbi) {
+ _options.data = txObject.encodeABI()
+ _options.to = token
+ return _options
+ }
+
+ return this.web3Client.send(txObject, _options)
}
- depositERC721ForUser(token: address, tokenId: string, user: address, options?: SendOptions) {
+ depositERC721ForUser(
+ token: address,
+ tokenId: string,
+ user: address,
+ options?: SendOptions,
+ ) {
return this.web3Client.send(
- this.depositManagerContract.methods.depositERC721ForUser(token, user, tokenId),
- options
+ this.depositManagerContract.methods.depositERC721ForUser(
+ token,
+ user,
+ tokenId,
+ ),
+ options,
)
}
depositEther(amount: string, options: SendOptions = {}) {
return this.web3Client.send(
this.depositManagerContract.methods.depositEther(),
- Object.assign(options, { value: amount })
+ Object.assign(options, { value: amount }),
)
}

MODIFY
src/types/Common.ts
src/types/Common.ts
@@ -5,4 +5,5 @@ export declare interface SendOptions {
value?: string | number
gas?: string | number
gasPrice?: string | number
+ encodeAbi?: boolean
}

approve token for deposit