spacylabs-rhino
Version:
99 lines (79 loc) • 3.37 kB
JavaScript
const FP = require('lodash/fp')
const { Joi, toBN } = require('@rhino.fi/dvf-utils')
const post = require('../lib/dvf/post-authenticated')
const validateWithJoi = require('../lib/validators/validateWithJoi')
const DVFError = require('../lib/dvf/DVFError')
const getSafeQuantizedAmountOrThrow = require('../lib/dvf/token/getSafeQuantizedAmountOrThrow')
const getTokenAddressFromTokenInfoOrThrow = require('../lib/dvf/token/getTokenAddressFromTokenInfoOrThrow')
const permitParamsSchema = require('../lib/schemas/permitParamsSchema')
const depositFromSidechainBridge = require('./contract/depositFromSidechainBridge')
const createPromiseAndCallbackFn = require('../lib/util/createPromiseAndCallbackFn')
const schema = Joi.object({
chain: Joi.string(),
token: Joi.string(),
amount: Joi.bigNumber().greaterThan(0), // number or number string
// useProxiedContract: Joi.boolean().optional().default(false),
permitParams: permitParamsSchema.optional(),
web3Options: Joi.object().optional(), // For internal use (custom gas limits, etc)
referralId: Joi.string().optional()
})
const validateArg0 = validateWithJoi(schema)('INVALID_METHOD_ARGUMENT')({
context: 'bridgedDeposit'
})
const endpoint = '/v1/trading/bridgedDeposits'
const validationEndpoint = '/v1/trading/deposits-validate'
module.exports = async (dvf, data, nonce, signature, txHashCb) => {
const { chain, token, amount, web3Options, permitParams, referralId } = validateArg0(data)
const tokenInfo = dvf.token.getTokenInfoOrThrow(token)
// Quantised amount must be from base token config
const quantisedAmount = getSafeQuantizedAmountOrThrow(amount, tokenInfo)
// Base units should be using the execution chain
const tokenChainInfo = dvf.token.getTokenInfoForChainOrThrow(token, chain)
const baseUnitAmount = toBN(amount).shiftedBy(tokenChainInfo.decimals).toString()
// Force the use of header (instead of payload) for authentication.
dvf = FP.set('config.useAuthHeader', true, dvf)
await post(dvf, validationEndpoint, nonce, signature, { token, amount: quantisedAmount })
const bridgeContractAddress = dvf.getBridgeContractAddressOrThrow(chain)
if (!permitParams) {
await dvf.contract.approve(
token,
baseUnitAmount,
bridgeContractAddress,
chain
)
}
const tokenAddress = getTokenAddressFromTokenInfoOrThrow(tokenInfo, chain)
// Sending the deposit transaction to the blockchain first before notifying the server
const tx = {
bridgeContractAddress,
tokenAddress,
baseUnitAmount
}
const [transactionHashPromise, transactionHashCb] = createPromiseAndCallbackFn(txHashCb)
const options = {
transactionHashCb,
chain,
...web3Options
}
const onChainDepositPromise = depositFromSidechainBridge(dvf, tx, options)
const { transactionHash, clearCallback } = await transactionHashPromise
const payload = {
chain,
token,
amount: quantisedAmount,
txHash: transactionHash,
referralId
}
const httpDeposit = await post(dvf, endpoint, nonce, signature, payload)
const onChainDeposit = await onChainDepositPromise
if (typeof clearCallback === 'function') {
clearCallback()
}
if (!onChainDeposit.status) {
throw new DVFError('ERR_ONCHAIN_BRIDGED_DEPOSIT', {
httpDeposit,
onChainDeposit
})
}
return { ...httpDeposit, transactionHash }
}