Skip to content

Commit

Permalink
#11 Refactor TradingWalletFacade
Browse files Browse the repository at this point in the history
  • Loading branch information
ceres3idoo committed Feb 22, 2019
1 parent b4ce6ce commit 4c54c39
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 50 deletions.
91 changes: 56 additions & 35 deletions src/facades/TradingWalletFacade.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const log = require('../logger')
const { QuantityNotAllowedError, TransactionNotMinedError } = require('../utils').errors
const { QuantityNotEnoughError } = require('../utils').errors
const { TransactionLibBuilder } = require('../factories')

/**
Expand Down Expand Up @@ -33,60 +33,74 @@ class TradingWalletFacade {
}

async depositTokenAsync(personalWalletAddress, tradingWalletAddress, quantity, tokenAddress, privateKey) {
const approveTransactionHash = await this.erc20TokenService.approveTrasferAsync(
personalWalletAddress,
tradingWalletAddress,
quantity,
privateKey,
)
const isApproveMined = await this.transactionLib.isTransactionMined(approveTransactionHash, tradingWalletAddress)
let approveToZeroTransactionHash = null
let approveTransactionHash = null

if (!isApproveMined) {
const errMsg = 'Approve transaction not mined.'
this.log.error({
fn: 'depositTokenAsync',
isApproveMined,
const assetBalance = this.erc20TokenService.getBalanceOfAsync(personalWalletAddress)

if (assetBalance < quantity) {
const errorMessage = 'The asset balance is < than the quantity to depoist!'
this.log.info({
personalWalletAddress,
tradingWalletAddress,
quantity,
}, errMsg)
throw new TransactionNotMinedError(errMsg)
tokenAddress,
assetBalance,
fn: 'depositTokenAsync',
},
errorMessage)
throw new QuantityNotEnoughError(errorMessage)
}

const allowedQuantity = await this.erc20TokenService.getAllowanceAsync(personalWalletAddress, tradingWalletAddress)
const allowance = await this.erc20TokenService.getAllowanceAsync(personalWalletAddress, tradingWalletAddress)

if (quantity <= allowedQuantity) {
const errorMessage = 'The quantity to deposit is not allowed!'
this.log.error({
if (quantity > allowance && allowance > 0) {
this.log.info({
personalWalletAddress,
tradingWalletAddress,
quantity,
tokenAddress,
allowedQuantity,
allowance,
fn: 'depositTokenAsync',
},
errorMessage)
throw new QuantityNotAllowedError(errorMessage)
'The quantity to deposit is not completely allowed!')

const zeroQuantity = 0
approveToZeroTransactionHash = await this.erc20TokenService.approveTrasferAsync(
personalWalletAddress,
tradingWalletAddress,
zeroQuantity,
privateKey,
)

this.log.info({
approveToZeroTransactionHash,
fn: 'depositTokenAsync',
},
'Approve to zero quantity done successfully.')
}

if (allowance === 0 || (quantity > allowance && allowance > 0)) {
approveTransactionHash = await this.erc20TokenService.approveTrasferAsync(
personalWalletAddress,
tradingWalletAddress,
quantity,
privateKey,
)
this.log.info({
approveTransactionHash,
fn: 'depositTokenAsync',
},
'Approve quantity done successfully.')
}

const depositTransactionHash = await this.tradingWalletService.depositTokenAsync(
personalWalletAddress,
tradingWalletAddress,
quantity,
tokenAddress,
privateKey,
)
const isDepositMined = await this.transactionLib.isTransactionMined(depositTransactionHash, tradingWalletAddress)

if (!isDepositMined) {
const errMsg = 'Deposit transaction not mined.'
this.log.error({
fn: 'depositTokenAsync',
isDepositMined,
personalWalletAddress,
tradingWalletAddress,
quantity,
}, errMsg)
throw new TransactionNotMinedError(errMsg)
}

this.log.info({
fn: 'depositTokenAsync',
Expand All @@ -95,8 +109,15 @@ class TradingWalletFacade {
quantity,
tokenAddress,
privateKey,
depositTransactionHash,
},
'Deposit token completed successfully.')

return {
approveToZeroTransactionHash,
approveTransactionHash,
depositTransactionHash,
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/utils/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ class TransactionCallError extends BaseError {}
class TradingWalletNotFoundError extends BaseError {}

/**
* This error will be raised if the transaction is not mined.
* This error will be raised if the asset balance is less then the quantity to deposit.
*/
class TransactionNotMinedError extends BaseError {}
class QuantityNotEnoughError extends BaseError {}

/**
* This error will be raised if the allowed quantity is lower than approved quantity
Expand Down Expand Up @@ -89,5 +89,5 @@ module.exports = {
TradingWalletNotFoundError,
TransactionCallError,
TransactionExecutionError,
TransactionNotMinedError,
QuantityNotEnoughError,
}
87 changes: 75 additions & 12 deletions tests/unit/facades/TradingWalletFacade.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global describe, expect, test */
const sandbox = require('sinon').createSandbox()

const { QuantityNotAllowedError, TransactionNotMinedError } = require('../../../index').utils.errors
const { QuantityNotEnoughError } = require('../../../index').utils.errors

const { Erc20TokenServiceBuilder, TradingWalletServiceBuilder } = require('../../../index').factories
const { TradingWalletFacade } = require('../../../index').facades
Expand All @@ -23,9 +23,9 @@ afterEach(() => {
})

describe('DepositTokenAsync', () => {
const approvedTxHash = '0xApprovedTxHash'
test('should raise TransactionNotMinedError if the approved transaction was not mined.', async () => {
sandbox.stub(tradingWalletFacade.erc20TokenService, 'approveTrasferAsync').returns(approvedTxHash)
test('should raise QuantityNotEnoughError if the asset balance is not enought.', async () => {
const balanceOfQuantity = '10000000000000000'
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getBalanceOfAsync').returns(balanceOfQuantity)
const isApprovedMinedMock = sandbox.stub(tradingWalletFacade.transactionLib, 'isTransactionMined')
isApprovedMinedMock.onFirstCall().returns(false)

Expand All @@ -35,21 +35,84 @@ describe('DepositTokenAsync', () => {
quantityToDeposit,
tokenAddress,
privateKey,
)).rejects.toBeInstanceOf(TransactionNotMinedError)
)).rejects.toBeInstanceOf(QuantityNotEnoughError)
})

test('should raise TransactionNotMinedError if deposit transaction was not mined.', async () => {
sandbox.stub(tradingWalletFacade.erc20TokenService, 'approveTrasferAsync').returns(approvedTxHash)
const isApprovedMinedMock = sandbox.stub(tradingWalletFacade.transactionLib, 'isTransactionMined')
isApprovedMinedMock.onFirstCall().returns(true)
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getAllowanceAsync').returns(quantityToDeposit + 10000)
test('should call directly depositToken becuase the quantity its already approved', async () => {
const balanceOfQuantity = '500000000000000000'
const depositTxHash = '0xDepositTxHash'
const expecetedResult = {
approveToZeroTransactionHash: null,
approveTransactionHash: null,
depositTransactionHash: depositTxHash,
}
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getBalanceOfAsync').returns(balanceOfQuantity)
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getAllowanceAsync').returns(quantityToDeposit)
sandbox.stub(tradingWalletFacade.tradingWalletService, 'depositTokenAsync').returns(depositTxHash)

return expect(tradingWalletFacade.depositTokenAsync(
const result = await tradingWalletFacade.depositTokenAsync(
personalWalletAddress,
tradingWalletAddress,
quantityToDeposit,
tokenAddress,
privateKey,
)

expect(result).toMatchObject(expecetedResult)
})

test('should call approve becuase the allowance is zero', async () => {
const balanceOfQuantity = '500000000000000000'
const allowance = 0
const depositTxHash = '0xDepositTxHash'
const approveTxHash = '0xApproveTxHash'
const expecetedResult = {
approveToZeroTransactionHash: null,
approveTransactionHash: approveTxHash,
depositTransactionHash: depositTxHash,
}
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getBalanceOfAsync').returns(balanceOfQuantity)
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getAllowanceAsync').returns(allowance)
sandbox.stub(tradingWalletFacade.erc20TokenService, 'approveTrasferAsync').returns(approveTxHash)
sandbox.stub(tradingWalletFacade.tradingWalletService, 'depositTokenAsync').returns(depositTxHash)

const result = await tradingWalletFacade.depositTokenAsync(
personalWalletAddress,
tradingWalletAddress,
quantityToDeposit,
tokenAddress,
privateKey,
)).rejects.toBeInstanceOf(QuantityNotAllowedError)
)

expect(result).toMatchObject(expecetedResult)
})

test('should call directly approve ', async () => {
const balanceOfQuantity = '500000000000000000'
const allowance = balanceOfQuantity - 1000
const depositTxHash = '0xDepositTxHash'
const approveZeroTxHash = '0xApproveZeroTxHash'
const approveTxHash = '0xApproveTxHash'
const expecetedResult = {
approveToZeroTransactionHash: approveZeroTxHash,
approveTransactionHash: approveTxHash,
depositTransactionHash: depositTxHash,
}
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getBalanceOfAsync').returns(balanceOfQuantity)
sandbox.stub(tradingWalletFacade.erc20TokenService, 'getAllowanceAsync').returns(allowance)
const approveTrasferMock = sandbox.stub(tradingWalletFacade.erc20TokenService, 'approveTrasferAsync')
approveTrasferMock.onFirstCall().returns(approveZeroTxHash)
approveTrasferMock.onSecondCall().returns(approveTxHash)
sandbox.stub(tradingWalletFacade.tradingWalletService, 'depositTokenAsync').returns(depositTxHash)

const result = await tradingWalletFacade.depositTokenAsync(
personalWalletAddress,
tradingWalletAddress,
quantityToDeposit,
tokenAddress,
privateKey,
)

expect(result).toMatchObject(expecetedResult)
})
})

0 comments on commit 4c54c39

Please sign in to comment.