add withdraw
MODIFY
package-lock.json
package-lock.json
},
"finalhandler": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
"dev": true
+ },
+ "query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "dev": true,
+ "requires": {
+ "decode-uri-component": "0.2.0",
+ "object-assign": "4.1.1",
+ "strict-uri-encode": "1.1.0"
+ }
}
}
},
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"query-string": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
- "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.1.0.tgz",
+ "integrity": "sha512-pNB/Gr8SA8ff8KpUFM36o/WFAlthgaThka5bV19AD9PNTH20Pwq5Zxodif2YyHwrctp6SkL4GqlOot0qR/wGaw==",
"requires": {
"decode-uri-component": "0.2.0",
- "object-assign": "4.1.1",
- "strict-uri-encode": "1.1.0"
+ "strict-uri-encode": "2.0.0"
+ },
+ "dependencies": {
+ "strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
+ }
}
},
"querystring": {
"timed-out": "4.0.1",
"url-set-query": "1.0.0",
"xhr": "2.5.0"
+ },
+ "dependencies": {
+ "query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "requires": {
+ "decode-uri-component": "0.2.0",
+ "object-assign": "4.1.1",
+ "strict-uri-encode": "1.1.0"
+ }
+ }
}
},
"xhr-request-promise": {

MODIFY
package.json
package.json
"ethereumjs-util": "^5.2.0",
"ethers": "^4.0.0",
"merkle-patricia-tree": "^2.3.2",
+ "query-string": "^6.1.0",
"web3": "1.0.0-beta.36"
},
"devDependencies": {

MODIFY
src/index.js
src/index.js
import Web3 from "web3"
import utils from "ethereumjs-util"
+import queryString from "query-string"
import {
getTxBytes,
@@ -24,6 +25,9 @@ export default class Matic {
this._web3 = new Web3(options.maticProvider)
this._parentWeb3 = new Web3(options.parentProvider)
+ this._syncerUrl = options.syncerUrl
+ this._watcherUrl = options.watcherUrl
+
// create rootchain contract
this._rootChainContract = new this._parentWeb3.eth.Contract(
RootChainArtifacts.abi,
@@ -107,6 +111,51 @@ export default class Matic {
})
}
+ async withdraw(txId, options = {}) {
+ //trancation proof
+ const { proof: txProof } = await this._apiCall({
+ url: `${this._syncerUrl}/tx/${txId}/proof`
+ })
+
+ //receipt proof
+ const { proof: receiptProof } = await this._apiCall({
+ url: `${this._syncerUrl}/tx/${txId}/receipt/proof`
+ })
+
+ const header = await this._apiCall({
+ url: `${this._watcherUrl}/header/included/${txProof.blockNumber}`
+ })
+
+ const { proof: headerProof } = await this._apiCall({
+ url: `${syncerUrl}/block/${txProof.blockNumber}/proof`,
+ query: {
+ start: +header.start,
+ end: +header.end
+ }
+ })
+
+ return this._rootChainContract.methods
+ .withdraw(
+ header.number.toString(), // header block
+ utils.bufferToHex(
+ Buffer.concat(headerProof.proof.map(p => utils.toBuffer(p)))
+ ), // header proof
+ txProof.blockNumber, // block number
+ txProof.blockTimestamp.toString(), // block timestamp
+ txProof.root, // tx root
+ receiptProof.root, // receipt root
+ utils.bufferToHex(rlp.encode(receiptProof.path)), // key for trie (both tx and receipt)
+ txProof.value, // tx bytes
+ txProof.parentNodes, // tx proof nodes
+ receiptProof.value, // receipt bytes
+ receiptProof.parentNodes // reciept proof nodes
+ )
+ .send({
+ from: this.wallet.address,
+ ...options
+ })
+ }
+
async withdrawLocally(txId, options = {}) {
const withdrawTx = await this._web3.eth.getTransaction(txId)
const withdrawReceipt = await this._web3.eth.getTransactionReceipt(txId)
@@ -189,4 +238,21 @@ export default class Matic {
return _tokenContract
}
+
+ _apiCall(data = {}) {
+ const headers = data.headers || {}
+ const queryParams = data.query && queryString.stringify(data.query || {})
+ const url = `${data.url}?${queryParams || ""}`
+ return fetch(url, {
+ method: data.method || (data.body ? "POST" : "GET"),
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ ...headers
+ },
+ body: data.body ? JSON.stringify(data.body) : null
+ }).then(res => {
+ return res.json()
+ })
+ }
}

add withdraw