This will create a pending withdrawal. Then, the Gateway Oracle will pick the pending withdrawal and, after a small delay, it will sign the pending withdrawal and submit the signature to the DAppChain Gateway. In turn, the DAppChain Gateway emits an event to notify us that the pending withdrawal has been signed. Here's how we can make sure that the event has been emitted:
const timeout = 60 * 1000
const gatewayContract = this.zekndGateway
const receiveSignedWithdrawalEvent = new Promise((resolve, reject) => {
let timer = setTimeout(
() => reject(new Error('Timeout while waiting for withdrawal to be signed')),
timeout
)
const listener = event => {
console.log('receiveSignedWithdrawalEvent resolved')
if (
event.tokenContract.local.toString() === TRON_DAPP_ADDRESS &&
event.tokenOwner.toString() === this.trxAddrObj.toString()
) {
clearTimeout(timer)
timer = null
gatewayContract.removeAllListeners(Contracts.TransferGateway.EVENT_TOKEN_WITHDRAWAL)
console.log('Oracle signed tx ', CryptoUtils.bytesToHexAddr(event.sig))
resolve(event)
}
}
gatewayContract.on(Contracts.TransferGateway.EVENT_TOKEN_WITHDRAWAL, listener)
})
await receiveSignedWithdrawalEvent
Then, we can get the withdrawal receipt and the signature using something like this:
let data = await this.zekndGateway.withdrawalReceiptAsync(this.zekndLocalAddress)
if (!data) return null
let signature = CryptoUtils.bytesToHexAddr(data.oracleSignature)
Lastly, let's withdraw TRX to our TRON account:
let sig = signature
if (sig.length > 132) {
let byteToOmit = sig.length - 132 + 2 // +2 from `0x`
sig = sig.slice(byteToOmit)
sig = '0x' + sig
}
const r = sig.slice(0, 66)
const s = '0x' + sig.slice(66, 130)
let v = '0x' + sig.slice(130, 132)
v = this.zekndWeb3.utils.toDecimal(v)
await this.tronGateway.withdrawTRX(TRX_AMOUNT, r, s, v).send({ from: this.tronAddrBase58 })
#Refreshing Balances
We'll be using a simple function to refresh our balances:
Since TRX is a native token on TRON, there are no events we could listen to. Thus, to make it so that the web UI automatically updates our balance on TRON, we will poll the account balance as follows:
const maxRetries = 10
let retries = 0
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
const initialShastaBalance = await this.tronWeb.trx.getBalance(this.tronAddrBase58)
let currentShastaBalance = initialShastaBalance
while (initialShastaBalance == currentShastaBalance && retries < maxRetries) {
currentShastaBalance = await this.tronWeb.trx.getBalance(this.tronAddrBase58)
await delay(2000)
retries++
}
if (retries == maxRetries) {
console.log('Waiting is over... No change!')
} else {
console.log('Balance updated after ' + retries + ' retries. Refreshing balances')
await this.refreshBalance()
}
#Wrapping it up
We've built a small demo project to showcase this functionality. The source code is available .