Skip to content

Commit

Permalink
test payment processor
Browse files Browse the repository at this point in the history
  • Loading branch information
vrolland committed Sep 25, 2021
1 parent aa78665 commit 24e9851
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 17 deletions.
28 changes: 12 additions & 16 deletions packages/payment-processor/src/payment/any-to-eth-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import { constants, ContractTransaction, Signer, providers, BigNumberish } from
import { CurrencyManager, getConversionPath, ICurrencyManager } from '@requestnetwork/currency';
import { ethConversionArtifact } from '@requestnetwork/smart-contracts';
import { EthConversionProxy__factory } from '@requestnetwork/smart-contracts/types';
import { ClientTypes, RequestLogicTypes } from '@requestnetwork/types';
import { ClientTypes } from '@requestnetwork/types';

import { ITransactionOverrides } from './transaction-overrides';
import {
getAmountToPay,
getPaymentNetworkExtension,
getProvider,
getRequestPaymentValues,
getSigner,
Expand All @@ -20,7 +19,6 @@ import { IPreparedTransaction } from './prepared-transaction';
/**
* Details required to pay a request with on-chain conversion:
* - currency: should be a valid currency type and accepted token value
* - maxToSpend: maximum number of tokens to be spent when the conversion is made
*/
export interface IPaymentSettings {
maxToSpend: BigNumberish;
Expand Down Expand Up @@ -87,11 +85,7 @@ export function encodePayAnyToEthProxyRequest(
network,
} = getRequestPaymentValues(request);

const paymentCurrency = currencyManager.fromStorageCurrency({
type: RequestLogicTypes.CURRENCY.ETH,
value: RequestLogicTypes.CURRENCY.ETH,
network,
});
const paymentCurrency = currencyManager.from('ETH', network);
if (!paymentCurrency) {
throw new Error(
`Could not find currency for network: ${network}. Did you forget to specify the currencyManager?`,
Expand Down Expand Up @@ -120,7 +114,6 @@ export function encodePayAnyToEthProxyRequest(
`0x${paymentReference}`,
feeToPay,
feeAddress || constants.AddressZero,
paymentSettings.maxToSpend,
maxRateTimespan || 0,
]);
}
Expand All @@ -131,19 +124,22 @@ export function prepareAnyToEthProxyPaymentTransaction(
amount?: BigNumberish,
feeAmount?: BigNumberish,
): IPreparedTransaction {
if (!paymentSettings.currency.network) {
const { network, version } = getRequestPaymentValues(request);

if (!network) {
throw new Error('Cannot pay with a currency missing a network');
}
const encodedTx = encodePayAnyToEthProxyRequest(request, paymentSettings, amount, feeAmount);
const pn = getPaymentNetworkExtension(request);

const proxyAddress = ethConversionArtifact.getAddress(
paymentSettings.currency.network,
pn?.version,
);
const proxyAddress = ethConversionArtifact.getAddress(network, version);

if (!paymentSettings.maxToSpend) {
throw Error('paymentSettings.maxToSpend is required');
}

return {
data: encodedTx,
to: proxyAddress,
value: 0,
value: paymentSettings.maxToSpend,
};
}
124 changes: 124 additions & 0 deletions packages/payment-processor/test/payment/any-to-eth-proxy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { Wallet, providers, BigNumber } from 'ethers';

import {
ClientTypes,
ExtensionTypes,
IdentityTypes,
PaymentTypes,
RequestLogicTypes,
} from '@requestnetwork/types';

// import Utils from '@requestnetwork/utils';

// import { approveEthForProxyConversionIfNeeded } from '../../src/payment/conversion-eth';
import { IPaymentSettings, payAnyToEthProxyRequest } from '../../src/payment/any-to-eth-proxy';
import { currencyManager } from './shared';

const alphaPaymentSettings: IPaymentSettings = {
currencyManager,
maxToSpend: BigNumber.from('10000000000000000000')
};

const mnemonic = 'candy maple cake sugar pudding cream honey rich smooth crumble sweet treat';
const paymentAddress = '0xf17f52151EbEF6C7334FAD080c5704D77216b732';
const feeAddress = '0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef';
const provider = new providers.JsonRpcProvider('http://localhost:8545');
const wallet = Wallet.fromMnemonic(mnemonic).connect(provider);

const validEuroRequest: ClientTypes.IRequestData = {
balance: {
balance: '0',
events: [],
},
contentData: {},
creator: {
type: IdentityTypes.TYPE.ETHEREUM_ADDRESS,
value: wallet.address,
},
currency: 'EUR',
currencyInfo: {
type: RequestLogicTypes.CURRENCY.ISO4217,
value: 'EUR',
},

events: [],
expectedAmount: '100',
extensions: {
[PaymentTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY]: {
events: [],
id: ExtensionTypes.ID.PAYMENT_NETWORK_ANY_TO_ETH_PROXY,
type: ExtensionTypes.TYPE.PAYMENT_NETWORK,
values: {
feeAddress,
feeAmount: '2',
paymentAddress,
salt: 'salt',
network: 'private',
},
version: '0.1.0',
},
},
extensionsData: [],
meta: {
transactionManagerMeta: {},
},
pending: null,
requestId: 'abcd',
state: RequestLogicTypes.STATE.CREATED,
timestamp: 0,
version: '1.0',
};

describe.only('any-to-eth-proxy', () => {
describe('payment', () => {
it('should convert and pay a request in EUR with ETH', async () => {
// get the balances to compare after payment
const fromOldBalance = await provider.getBalance(wallet.address);
const toOldBalance = await provider.getBalance(paymentAddress);
const feeOldBalance = await provider.getBalance(feeAddress);

// convert and pay
const tx = await payAnyToEthProxyRequest(
validEuroRequest,
wallet,
alphaPaymentSettings
);

const confirmedTx = await tx.wait(1);

expect(confirmedTx.status).toEqual(1);
expect(tx.hash).toBeDefined();

// Get the new balances
const fromNewBalance = await provider.getBalance(wallet.address);
const toNewBalance = await provider.getBalance(paymentAddress);
const feeNewBalance = await provider.getBalance(feeAddress);
const gasPrice = (await provider.getFeeData()).gasPrice || 0;

// Check each balance
expect(
fromOldBalance.sub(fromNewBalance).sub(confirmedTx.gasUsed.mul(gasPrice)).toString()
// expectedAmount: 1.00
// feeAmount: + .02
// = 1.02
// AggEurUsd.sol x 1.20
// AggETHUsd.sol / 500
// = 0.002448 (over 18 decimals for this ETH)
).toEqual('2448000000000000');
expect(
toNewBalance.sub(toOldBalance).toString()
// expectedAmount: 1.00
// AggEurUsd.sol x 1.20
// AggETHUsd.sol / 500
// = 0.0024 (over 18 decimals for this ETH)
).toEqual('2400000000000000');
expect(
feeNewBalance.sub(feeOldBalance).toString()
// feeAmount: .02
// AggEurUsd.sol x 1.20
// AggETHUsd.sol / 500
// = 0.000048 (over 18 decimals for this ETH)
).toEqual('48000000000000');
});
});
});
6 changes: 6 additions & 0 deletions packages/payment-processor/test/payment/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { RequestLogicTypes } from '@requestnetwork/types';

export const currencyManager = new CurrencyManager([
...CurrencyManager.getDefaultList(),
...[{
network: 'private',
symbol: 'ETH',
decimals: 18,
type: RequestLogicTypes.CURRENCY.ETH as any,
}],
...[
'0x9FBDa871d559710256a2502A2517b794B482Db40',
'0x38cF23C52Bb4B13F051Aec09580a2dE845a7FA35',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { chainlinkConversionPath } from '../../src/lib';

use(solidity);

describe.only('contract: EthConversionProxy', () => {
describe('contract: EthConversionProxy', () => {
let from: string;
let to: string;
let feeAddress: string;
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/payment-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export enum PAYMENT_NETWORK_ID {
NATIVE_TOKEN = Extension.ID.PAYMENT_NETWORK_NATIVE_TOKEN,
DECLARATIVE = Extension.ID.PAYMENT_NETWORK_ANY_DECLARATIVE,
ANY_TO_ERC20_PROXY = Extension.ID.PAYMENT_NETWORK_ANY_TO_ERC20_PROXY,
ANY_TO_ETH_PROXY = Extension.ID.PAYMENT_NETWORK_ANY_TO_ETH_PROXY,
}

/** Generic info retriever interface */
Expand Down

0 comments on commit 24e9851

Please sign in to comment.