UNPKG

@gateway.fm/gtw-dvf-client-js

Version:

DVF client js lib with gateway.fm rpc endpoints

263 lines (209 loc) 8.41 kB
const nock = require('nock') const instance = require('./test/helpers/instance') const mockGetConf = require('./test/fixtures/getConf') const sw = require('starkware_crypto') const toQuantizedAmount = require('../lib/dvf/token/toQuantizedAmount') const createKeyPair = require('../lib/stark/createKeyPair') // Mocks the first call to the server used to lookup recipient vaultId and stark key const mockVaultIdAndStarkKeyApiCall = ({ targetEthAddress, token }) => { const vaultIdAndStarkKeyApiResponse = { vaultId: 1559, // For ETH address : 0x5317c63f870e8d2f85f0de3c2666d1414f5a728c starkKey: '0x00334070e2218dac427f3a9cbcc057cb07e8fb161a70bd4f4b83e6cf3ed02529' } const vaultIdAndStarkKeyQueryValidator = jest.fn(query => { expect(query).toMatchObject({ targetEthAddress, token }) return true }) nock(dvf.config.api) .get(/\/v1\/trading\/r\/vaultIdAndStarkKey.*/) .query(vaultIdAndStarkKeyQueryValidator) .reply(200, vaultIdAndStarkKeyApiResponse) return [vaultIdAndStarkKeyQueryValidator, vaultIdAndStarkKeyApiResponse] } let dvf describe('dvf.transfer', () => { beforeAll(async () => { mockGetConf() dvf = await instance() }) afterEach(() => { nock.cleanAll() }) it.skip(`Transfers ERC20 token to user's vault`, async () => { const starkPrivateKey = '100' const senderKeyPair = createKeyPair({ sw }, starkPrivateKey) const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 12 const token = 'USDT' const [ vaultIdAndStarkKeyQueryValidator, vaultIdAndStarkKeyApiResponse ] = mockVaultIdAndStarkKeyApiCall({ targetEthAddress: recipientEthAddress, token }) const transferApiResponse = { _id: 'LCafcGC6tBH', token, amount: toQuantizedAmount(dvf, token, amount), recipient: recipientEthAddress, createAt: (new Date()).toISOString() } const transferPayloadValidator = jest.fn(body => { expect(body.tx.signature.s).toMatch(/[\da-f]/i) expect(body).toMatchObject({ tx: { type: 'TransferRequest', amount: toQuantizedAmount(dvf, token, amount), receiverVaultId: vaultIdAndStarkKeyApiResponse.vaultId, receiverPublicKey: vaultIdAndStarkKeyApiResponse.starkKey, senderPublicKey: '0x' + senderKeyPair.starkPublicKey.x }, starkPublicKey: senderKeyPair.starkPublicKey }) expect(body.tx.token).toMatch(/0x[\da-f]+/i) expect(body.tx.signature.r).toMatch(/[\da-f]/i) expect(body.tx.signature.s).toMatch(/[\da-f]/i) expect(typeof body.tx.nonce).toBe('number') expect(typeof body.tx.expirationTimestamp).toBe('number') return true }) nock(dvf.config.api) .post('/v1/trading/w/transfer', transferPayloadValidator) .reply(200, transferApiResponse) await dvf.transfer({ recipientEthAddress, token, amount }, starkPrivateKey) expect(vaultIdAndStarkKeyQueryValidator).toBeCalled() expect(transferPayloadValidator).toBeCalled() }) it.skip(`Transfers ETH token to user's vault`, async () => { const starkPrivateKey = '100' const senderKeyPair = createKeyPair({ sw }, starkPrivateKey) const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 12 const token = 'ETH' const [ vaultIdAndStarkKeyQueryValidator, vaultIdAndStarkKeyApiResponse ] = mockVaultIdAndStarkKeyApiCall({ targetEthAddress: recipientEthAddress, token }) const transferApiResponse = { _id: 'LCafcGC6tBH', token, amount: toQuantizedAmount(dvf, token, amount), recipient: recipientEthAddress, createAt: (new Date()).toISOString() } const transferPayloadValidator = jest.fn(body => { expect(body.tx.signature.s).toMatch(/[\da-f]/i) expect(body).toMatchObject({ tx: { type: 'TransferRequest', amount: toQuantizedAmount(dvf, token, amount), receiverVaultId: vaultIdAndStarkKeyApiResponse.vaultId, receiverPublicKey: vaultIdAndStarkKeyApiResponse.starkKey, senderPublicKey: '0x' + senderKeyPair.starkPublicKey.x }, starkPublicKey: senderKeyPair.starkPublicKey }) expect(body.tx.token).toMatch(/0x[\da-f]+/i) expect(body.tx.signature.r).toMatch(/[\da-f]/i) expect(body.tx.signature.s).toMatch(/[\da-f]/i) expect(typeof body.tx.nonce).toBe('number') expect(typeof body.tx.expirationTimestamp).toBe('number') return true }) nock(dvf.config.api) .post('/v1/trading/w/transfer', transferPayloadValidator) .reply(200, transferApiResponse) await dvf.transfer({ recipientEthAddress, token, amount }, starkPrivateKey) expect(vaultIdAndStarkKeyQueryValidator).toBeCalled() expect(transferPayloadValidator).toBeCalled() }) it(`Should throw if vaultIdAndStarkKey request returns an error`, async () => { const starkPrivateKey = '100' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 12 const token = 'USDT' const vaultIdAndStarkKeyQueryValidator = jest.fn(query => { return true }) nock(dvf.config.api) .get(/\/v1\/trading\/r\/vaultIdAndStarkKey.*/) .query(vaultIdAndStarkKeyQueryValidator) .reply(404, { message: 'Target user not registered' }) const transferPayloadValidator = jest.fn(body => { return true }) nock(dvf.config.api) .post('/v1/trading/w/transfer', transferPayloadValidator) .reply(200) await expect(dvf.transfer({ recipientEthAddress, token, amount }, starkPrivateKey)) .rejects .toThrow(/Target user not registered/) expect(vaultIdAndStarkKeyQueryValidator).toBeCalled() expect(transferPayloadValidator).not.toBeCalled() }) it('Gives error for transfer with value of 0', async () => { const starkPrivateKey = '100' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 0 const token = 'ZRX' await expect(dvf.transfer({ token, amount, recipientEthAddress }, starkPrivateKey)) .rejects .toThrow('INVALID_METHOD_ARGUMENT') }) it('Gives error if token is missing', async () => { const starkPrivateKey = '100' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 14 const token = '' await expect(dvf.transfer({ token, amount, recipientEthAddress }, starkPrivateKey)) .rejects .toThrow('INVALID_METHOD_ARGUMENT') }) it.skip('Gives error if token is not supported', async () => { const starkPrivateKey = '100' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 14 const token = 'NOT' mockVaultIdAndStarkKeyApiCall({ targetEthAddress: recipientEthAddress, token }) await expect(dvf.transfer({ token, amount, recipientEthAddress }, starkPrivateKey)) .rejects .toThrow('ERR_INVALID_TOKEN') }) it.skip('Gives error if starkPrivateKey is not provided', async () => { const starkPrivateKey = '' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 14 const token = 'ZRX' mockVaultIdAndStarkKeyApiCall({ targetEthAddress: recipientEthAddress, token }) await expect(dvf.transfer({ token, amount, recipientEthAddress }, starkPrivateKey)) .rejects .toThrow('STARK_PRIVATE_KEY_IS_REQUIRED') }) it.skip('Posts to transfer API and gets error response', async () => { const starkPrivateKey = '100' const recipientEthAddress = '0x5317c63f870e8d2f85f0de3c2666d1414f5a728c' const amount = 14 const token = 'ZRX' const apiErrorResponse = { statusCode: 422, error: 'Unprocessable Entity', message: 'Please contact support if you believe there should not be an error here', details: { error: { type: 'DVFError', message: 'MUST_REGISTER' } } } mockVaultIdAndStarkKeyApiCall({ targetEthAddress: recipientEthAddress, token }) nock(dvf.config.api) .post('/v1/trading/w/transfer') .reply(422, apiErrorResponse) await expect(dvf.transfer({ recipientEthAddress, amount, token }, starkPrivateKey)) .rejects .toThrow(/MUST_REGISTER/) }) })