Skip to content

Commit

Permalink
feat: goerli payment (#892)
Browse files Browse the repository at this point in the history
  • Loading branch information
rom1trt authored Aug 1, 2022
1 parent 118b6e1 commit 2495d00
Show file tree
Hide file tree
Showing 29 changed files with 245 additions and 281 deletions.
8 changes: 8 additions & 0 deletions packages/currency/src/aggregators/goerli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc": {
"0x775eb53d00dd0acd3ec1696472105d579b9b386b": 1
},
"0x775eb53d00dd0acd3ec1696472105d579b9b386b": {
"0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc": 1
}
}
11 changes: 11 additions & 0 deletions packages/currency/src/erc20/networks/goerli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { TokenMap } from './types';

// List of the supported goerli ERC20 tokens
export const supportedGoerliERC20: TokenMap = {
// Faucet Token on goerli network. Easy to use on tests.
'0xBA62BCfcAaFc6622853cca2BE6Ac7d845BC0f2Dc': {
decimals: 18,
name: 'Faucet Token',
symbol: 'FAU-goerli',
},
};
2 changes: 1 addition & 1 deletion packages/payment-detection/src/erc20/address-based.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BalanceError } from '../balance-error';
import Erc20InfoRetriever from './address-based-info-retriever';

import { PaymentDetectorBase } from '../payment-detector-base';
const supportedNetworks = ['mainnet', 'rinkeby', 'private'];
const supportedNetworks = ['mainnet', 'rinkeby', 'goerli', 'private'];

/**
* Handle payment networks with ERC20 based address extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = {
},
extensions: {
anyToErc20Proxy: {
supportedNetworks: ['mainnet', 'rinkeby', 'private'],
supportedNetworks: ['mainnet', 'rinkeby', 'goerli', 'private'],
createAddPaymentAddressAction,
createAddRefundAddressAction,
createCreationAction,
Expand All @@ -56,35 +56,61 @@ describe('api/any/conversion-fee-proxy-contract', () => {
jest.clearAllMocks();
});

it('can createExtensionsDataForCreation', async () => {
await anyToErc20Proxy.createExtensionsDataForCreation({
paymentAddress: 'ethereum address',
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: 'rinkeby',
maxRateTimespan: 1000,
const testSuite = (network: string) => {
it(`can createExtensionsDataForCreation on ${network}`, async () => {
await anyToErc20Proxy.createExtensionsDataForCreation({
paymentAddress: 'ethereum address',
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: network,
maxRateTimespan: 1000,
});

expect(createCreationAction).toHaveBeenCalledWith({
feeAddress: undefined,
feeAmount: undefined,
paymentAddress: 'ethereum address',
refundAddress: undefined,
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: network,
maxRateTimespan: 1000,
});
});

expect(createCreationAction).toHaveBeenCalledWith({
feeAddress: undefined,
feeAmount: undefined,
paymentAddress: 'ethereum address',
refundAddress: undefined,
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: 'rinkeby',
maxRateTimespan: 1000,
it(`can createExtensionsDataForCreation with fee amount and address ${network}`, async () => {
await anyToErc20Proxy.createExtensionsDataForCreation({
feeAddress: 'fee address',
feeAmount: '2000',
paymentAddress: 'ethereum address',
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: network,
});

expect(createCreationAction).toHaveBeenCalledWith({
feeAddress: 'fee address',
feeAmount: '2000',
paymentAddress: 'ethereum address',
refundAddress: undefined,
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: network,
});
});
});
};

testSuite('rinkeby');
testSuite('goerli');

it('can createExtensionsDataForCreation with fee amount and address', async () => {
it('can createExtensionsDataForCreation with fee amount and address (Goerli)', async () => {
await anyToErc20Proxy.createExtensionsDataForCreation({
feeAddress: 'fee address',
feeAmount: '2000',
paymentAddress: 'ethereum address',
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: 'rinkeby',
network: 'goerli',
});

expect(createCreationAction).toHaveBeenCalledWith({
Expand All @@ -94,7 +120,7 @@ describe('api/any/conversion-fee-proxy-contract', () => {
refundAddress: undefined,
salt: 'ea3bc7caf64110ca',
acceptedTokens: ['ethereum address2'],
network: 'rinkeby',
network: 'goerli',
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe('api/erc20/address-based', () => {
error: {
code: PaymentTypes.BALANCE_ERROR_CODE.NETWORK_NOT_SUPPORTED,
message:
'Payment network wrong not supported by ERC20 payment detection. Supported networks: mainnet, rinkeby, private',
'Payment network wrong not supported by ERC20 payment detection. Supported networks: mainnet, rinkeby, goerli, private',
},
events: [],
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = {
},
extensions: {
feeProxyContractErc20: {
supportedNetworks: ['mainnet', 'private', 'rinkeby'],
supportedNetworks: ['mainnet', 'private', 'rinkeby', 'goerli'],
createAddPaymentAddressAction,
createAddRefundAddressAction,
createCreationAction,
Expand Down Expand Up @@ -283,7 +283,7 @@ describe('api/erc20/fee-proxy-contract', () => {
).toBe('7');
});

it('should have gasFee & gasUsed in the payment eventl', async () => {
it('should have gasFee & gasUsed in the payment event', async () => {
const mockRequest: RequestLogicTypes.IRequest = {
creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' },
currency: {
Expand Down
4 changes: 2 additions & 2 deletions packages/payment-detection/test/erc20/proxy-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = {
},
extensions: {
proxyContractErc20: {
supportedNetworks: ['mainnet', 'rinkeby'],
supportedNetworks: ['mainnet', 'rinkeby', 'goerli'],
createAddPaymentAddressAction,
createAddRefundAddressAction,
createCreationAction,
Expand Down Expand Up @@ -160,7 +160,7 @@ describe('api/erc20/proxy-contract', () => {
error: {
code: PaymentTypes.BALANCE_ERROR_CODE.NETWORK_NOT_SUPPORTED,
message:
'Payment network WRONG not supported by pn-erc20-proxy-contract payment detection. Supported networks: mainnet, rinkeby',
'Payment network WRONG not supported by pn-erc20-proxy-contract payment detection. Supported networks: mainnet, rinkeby, goerli',
},
events: [],
});
Expand Down
2 changes: 1 addition & 1 deletion packages/payment-detection/test/erc777/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const mockFlows = [
},
{
transactionHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be',
blockNumber: '9945543',
blockNumber: 9945543,
timestamp: '1641495767',
sender: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7',
flowRate: '0',
Expand Down
176 changes: 91 additions & 85 deletions packages/payment-detection/test/erc777/superfluid-retriever.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,106 +7,108 @@ import { mockSuperfluidSubgraph } from './mocks';

jest.mock('graphql-request');
const graphql = mocked(GraphQLClient.prototype);
const fDAIxTokenRinkeby = '0x745861aed1eee363b4aaa5f1994be40b1e05ff90';
const fUSDCxTokenRinkeby = '0x0f1d7c55a2b133e000ea10eec03c774e0d6796e8';
const fDAIxTokenGoerli = '0x2bf02814ea0b2b155ed47b7cede18caa752940e6';
const fUSDCxTokenGoerli = '0x2bf02814ea0b2b155ed47b7cede18caa752940e6';

describe('api/erc777/superfluid-info-retriever', () => {
describe('on untagged requests', () => {
it('should get payment events from SuperFluid via subgraph with 1 request', async () => {
const paymentData = {
reference: '0xbeefaccc470c7dbd54de69',
txHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be',
from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7',
to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594',
network: 'rinkeby',
salt: '0ee84db293a752c6',
amount: '92592592592592000',
requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1',
block: 9945543,
token: '0x745861aed1eee363b4aaa5f1994be40b1e05ff90', //fDAIx
};
graphql.request.mockResolvedValue(mockSuperfluidSubgraph[0]);
const testSuiteWithDaix = (network: string, fDAIxToken: string) => {
describe('api/erc777/superfluid-info-retriever', () => {
describe('on untagged requests', () => {
it(`should get payment events from SuperFluid via subgraph with 1 request on ${network}`, async () => {
const paymentData = {
reference: '0xbeefaccc470c7dbd54de69',
txHash: '0xe472ca1b52751b058fbdaeaffebd98c0cc43b45aa31794b3eb06834ede19f7be',
from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7',
to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594',
network: network,
salt: '0ee84db293a752c6',
amount: '92592592592592000',
requestId: '0188791633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f173c7a4e3ce7e1',
block: 9945543,
token: fDAIxToken,
};
graphql.request.mockResolvedValue(mockSuperfluidSubgraph[0]);

const paymentReference = PaymentReferenceCalculator.calculate(
paymentData.requestId,
paymentData.salt,
paymentData.to,
);
const subgraphReference = `0xbeefac${paymentReference}`;
expect(subgraphReference).toEqual(paymentData.reference);
const paymentReference = PaymentReferenceCalculator.calculate(
paymentData.requestId,
paymentData.salt,
paymentData.to,
);
const subgraphReference = `0xbeefac${paymentReference}`;
expect(subgraphReference).toEqual(paymentData.reference);

const graphRetriever = new SuperFluidInfoRetriever(
paymentReference,
paymentData.token,
paymentData.to,
PaymentTypes.EVENTS_NAMES.PAYMENT,
paymentData.network,
);
const transferEvents = await graphRetriever.getTransferEvents();
expect(transferEvents).toHaveLength(5);
expect(transferEvents[0].amount).toEqual(paymentData.amount);
expect(transferEvents[0].name).toEqual('payment');
expect(transferEvents[0].parameters?.to).toEqual(paymentData.to);
expect(transferEvents[1].amount).toEqual('34722222222222000');
expect(transferEvents[2].amount).toEqual('40509259259259000');
expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash);
expect(transferEvents[0].parameters?.block).toEqual(paymentData.block);
const graphRetriever = new SuperFluidInfoRetriever(
paymentReference,
paymentData.token,
paymentData.to,
PaymentTypes.EVENTS_NAMES.PAYMENT,
paymentData.network,
);
const transferEvents = await graphRetriever.getTransferEvents();
expect(transferEvents).toHaveLength(5);
expect(transferEvents[0].amount).toEqual(paymentData.amount);
expect(transferEvents[0].name).toEqual('payment');
expect(transferEvents[0].parameters?.to).toEqual(paymentData.to);
expect(transferEvents[1].amount).toEqual('34722222222222000');
expect(transferEvents[2].amount).toEqual('40509259259259000');
expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash);
expect(transferEvents[0].parameters?.block).toEqual(paymentData.block);
});
});
});

describe('on 2 nested requests', () => {
it('should get payment event from SuperFluid via subgraph with 2 requests', async () => {
const paymentData = {
reference: '0xbeefac9474ad7670909da5',
from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7',
to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594',
network: 'rinkeby',
salt: '0ee84db293a752c6',
amount: '320833333333331260',
// = (1642693617 - 1642692777 = 840 sec) x (385802469135800 - 3858024691358 = 381944444444442 Wei DAIx / sec)
requestId: '0288792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2',
token: '0x745861aed1eee363b4aaa5f1994be40b1e05ff90', //fDAIx
block: 10024811,
txHash: '0x0fefa02d90be46eb51a82f02b7a787084c35a895bd833a7c9f0560e315bb4061',
};
graphql.request.mockResolvedValue(mockSuperfluidSubgraph[1]);
describe('on 2 nested requests', () => {
it(`should get payment event from SuperFluid via subgraph with 2 requests on ${network}`, async () => {
const paymentData = {
reference: '0xbeefac9474ad7670909da5',
from: '0x9c040e2d6fd83a8b35069aa7154b69674961e0f7',
to: '0x52e5bcfa46393894afcfe6cd98a6761fa692c594',
network: network,
salt: '0ee84db293a752c6',
amount: '320833333333331260',
// = (1642693617 - 1642692777 = 840 sec) x (385802469135800 - 3858024691358 = 381944444444442 Wei DAIx / sec)
requestId: '0288792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2',
token: fDAIxToken,
};
graphql.request.mockResolvedValue(mockSuperfluidSubgraph[1]);

const paymentReference = PaymentReferenceCalculator.calculate(
paymentData.requestId,
paymentData.salt,
paymentData.to,
);
const subgraphReference = `0xbeefac${paymentReference}`;
expect(subgraphReference).toEqual(paymentData.reference);
const graphRetriever = new SuperFluidInfoRetriever(
paymentReference,
paymentData.token,
paymentData.to,
PaymentTypes.EVENTS_NAMES.PAYMENT,
paymentData.network,
);
const transferEvents = await graphRetriever.getTransferEvents();
expect(transferEvents).toHaveLength(1);
expect(transferEvents[0].amount).toEqual(paymentData.amount);
expect(transferEvents[0].name).toEqual('payment');
expect(transferEvents[0].parameters?.to).toEqual(paymentData.to);
expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash);
expect(transferEvents[0].parameters?.block).toEqual(paymentData.block);
const paymentReference = PaymentReferenceCalculator.calculate(
paymentData.requestId,
paymentData.salt,
paymentData.to,
);
const subgraphReference = `0xbeefac${paymentReference}`;
expect(subgraphReference).toEqual(paymentData.reference);
const graphRetriever = new SuperFluidInfoRetriever(
paymentReference,
paymentData.token,
paymentData.to,
PaymentTypes.EVENTS_NAMES.PAYMENT,
paymentData.network,
);
const transferEvents = await graphRetriever.getTransferEvents();
expect(transferEvents).toHaveLength(1);
expect(transferEvents[0].amount).toEqual(paymentData.amount);
expect(transferEvents[0].name).toEqual('payment');
expect(transferEvents[0].parameters?.to).toEqual(paymentData.to);
});
});
});
};

const testSuiteWithUSDCx = (network: string, fUSDCxToken: string) => {
describe('on ongoing request', () => {
it('should get payment event from SuperFluid via subgraph with ongoing request', async () => {
it(`should get payment event from SuperFluid via subgraph with ongoing request on ${network}`, async () => {
const paymentData = {
reference: '0xbeefac0e87b43bf1e99c82',
from: '0x165a26628ac843e97f657e648b004226fbb7f7c5',
to: '0xe7e6431f08db273d915b49888f0c67ef61802e05',
network: 'rinkeby',
network: network,
salt: '0ee84db293a752c6',
amount: '1',
requestId: '0688792633ff0ec72a7dbdefb886d2db6cccfa98287320839c2f273c7a4e3ce7e2',
token: '0x0f1d7c55a2b133e000ea10eec03c774e0d6796e8', //fUSDCx
token: fUSDCxToken,
timestamp: 1643041225,
block: 10047970,
txHash: '0xdb44f35aa1490d2ddc8bbe7b82e0e3a370f3bf171a55da7a8a5886996e9c468d',
};
graphql.request.mockResolvedValue(mockSuperfluidSubgraph[2]);

Expand All @@ -131,8 +133,12 @@ describe('api/erc777/superfluid-info-retriever', () => {
expect(transferEvents[0].amount).toEqual(timestamp.toString());
expect(transferEvents[0].name).toEqual('payment');
expect(transferEvents[0].parameters?.to).toEqual(paymentData.to);
expect(transferEvents[0].parameters?.txHash).toEqual(paymentData.txHash);
expect(transferEvents[0].parameters?.block).toEqual(paymentData.block);
});
});
});
};

testSuiteWithDaix('rinkeby', fDAIxTokenRinkeby);
testSuiteWithDaix('goerli', fDAIxTokenGoerli);

testSuiteWithUSDCx('rinkeby', fUSDCxTokenRinkeby);
testSuiteWithUSDCx('goerli', fUSDCxTokenGoerli);
Loading

0 comments on commit 2495d00

Please sign in to comment.