Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
01a0afe
advanced-logic and payment-detection
yomarion Mar 19, 2023
0dfe034
fix import
yomarion Mar 19, 2023
c671f5d
chore: replaced rinkeby with matic for TheGraph codegen
yomarion Mar 19, 2023
8af51c7
added payment-detection test for balance
yomarion Mar 19, 2023
5288331
fix: thegraph codegen issues with superfluid
yomarion Mar 19, 2023
f8a60fd
Merge remote-tracking branch 'origin/master' into feat/erc20-fee-prox…
yomarion Mar 19, 2023
c22485c
fix: chain utils
yomarion Mar 19, 2023
b77d304
fix deleted file
yomarion Mar 19, 2023
7fe103b
fix artifact and tenderly related types
yomarion Mar 20, 2023
957e3c6
fix: Utils.isSameNetwork and test
yomarion Mar 20, 2023
cd5baa1
fix: payment-detection near versionMap
yomarion Mar 20, 2023
7092478
dirty-wip before inheriting the abstract class
yomarion Mar 21, 2023
411dd1e
working tests with ERC20NearFeeProxy detector
yomarion Mar 21, 2023
37c0e47
tests running with standard retriever design
yomarion Mar 21, 2023
9d78781
standard info retriever for native token detections
yomarion Mar 22, 2023
dc3fcca
minor type fix
yomarion Mar 22, 2023
e3ebcde
got rid of ERC20NearFeeProxy
yomarion Mar 22, 2023
aeb51d3
fix prettier
yomarion Mar 22, 2023
5454cd4
fix prettier
yomarion Mar 22, 2023
1a30b10
prettier nycrc files
yomarion Mar 22, 2023
4a54df9
fix: mock types
yomarion Mar 22, 2023
6e2b501
fix: wrong mocked advanced-logic types
yomarion Mar 22, 2023
83531e0
minor test fix
yomarion Mar 22, 2023
d1fd986
chore: reduce irrelevant strong typing in tests
yomarion Mar 23, 2023
e89e7de
chore: improve type details in payment detector
yomarion Mar 23, 2023
5a6b0ba
Merge branch 'master' into feat/erc20-fee-proxy-on-near
yomarion Mar 24, 2023
b6b39e9
Merge remote-tracking branch 'origin/master' into feat/erc20-fee-prox…
yomarion Mar 24, 2023
2e45994
fix: merge details
yomarion Mar 26, 2023
ebfe888
Strongly typing NearChainName 1/n
yomarion Mar 26, 2023
d4add72
Strongly typing NearChainName 2/n
yomarion Mar 26, 2023
db7f5a8
fix: test unit test not unit-testable
yomarion Mar 27, 2023
66fd5ae
Enforce TGetSubGraphClient usage
yomarion Mar 27, 2023
3dd4d96
tiny type fix
yomarion Mar 27, 2023
b2c542e
Merge remote-tracking branch 'origin/master' into feat/erc20-fee-prox…
yomarion Mar 29, 2023
c71835e
fixes Alex' feedback
yomarion Mar 30, 2023
87a1207
reset yarn.lock
yomarion Mar 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
standard info retriever for native token detections
  • Loading branch information
yomarion committed Mar 22, 2023
commit 9d78781ef9d5ed9e35d31d2ebc99e4c67bf9a5bf
45 changes: 36 additions & 9 deletions packages/payment-detection/src/erc20/fee-proxy-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
PaymentTypes,
RequestLogicTypes,
} from '@requestnetwork/types';
import { CurrencyDefinition, EvmChains, ICurrencyManager } from '@requestnetwork/currency';
import {
CurrencyDefinition,
EvmChains,
ICurrencyManager,
NearChains,
} from '@requestnetwork/currency';
import ProxyInfoRetriever from './proxy-info-retriever';

import { loadCurrencyFromContract } from './currency';
Expand Down Expand Up @@ -71,22 +76,33 @@ export abstract class ERC20FeeProxyPaymentDetectorBase<
);
}

export type GetSubGraphClient = (
network: CurrencyTypes.ChainName,
) => TheGraphClient | TheGraphClient<'near'>;

/**
* Handle payment networks with ERC20 fee proxy contract extension
*/
export class ERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBase {
private readonly getSubgraphClient: PaymentNetworkOptions['getSubgraphClient'];
protected readonly network: CurrencyTypes.VMChainName | undefined;
private readonly getSubgraphClient: GetSubGraphClient;
constructor({
advancedLogic,
currencyManager,
getSubgraphClient,
}: ReferenceBasedDetectorOptions & Pick<PaymentNetworkOptions, 'getSubgraphClient'>) {
network,
}: ReferenceBasedDetectorOptions & {
network?: CurrencyTypes.VMChainName;
getSubgraphClient: GetSubGraphClient;
}) {
super(
ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT,
advancedLogic.extensions.feeProxyContractErc20,
advancedLogic.getFeeProxyContractErc20ForNetwork(network) ??
advancedLogic.extensions.feeProxyContractErc20,
currencyManager,
);
this.getSubgraphClient = getSubgraphClient;
this.network = network;
}

/**
Expand All @@ -100,7 +116,11 @@ export class ERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBa
paymentChain: CurrencyTypes.VMChainName,
paymentNetwork: ExtensionTypes.IState,
): Promise<PaymentTypes.AllNetworkEvents<PaymentTypes.IERC20FeePaymentEventParameters>> {
EvmChains.assertChainSupported(paymentChain);
if (this.network && paymentChain !== this.network) {
throw new NetworkNotSupported(
`Unsupported network '${paymentChain}' for payment detector instanciated with '${this.network}'`,
);
}
if (!toAddress) {
return Promise.resolve({
paymentEvents: [],
Expand All @@ -112,10 +132,16 @@ export class ERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBa

const subgraphClient = this.getSubgraphClient(paymentChain);
if (subgraphClient) {
const graphInfoRetriever = new TheGraphInfoRetriever(
subgraphClient as TheGraphClient,
this.currencyManager,
);
const graphInfoRetriever = EvmChains.isChainSupported(paymentChain)
? new TheGraphInfoRetriever(subgraphClient as TheGraphClient, this.currencyManager)
: NearChains.isChainSupported(paymentChain) && this.network
? new NearInfoRetriever(subgraphClient as TheGraphClient<'near'>)
: undefined;
if (!graphInfoRetriever) {
throw new Error(
`Could not find graphInfoRetriever for chain ${paymentChain} in payment detector`,
);
}
return graphInfoRetriever.getTransferEvents({
eventName,
paymentReference,
Expand All @@ -125,6 +151,7 @@ export class ERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBa
acceptedTokens: [requestCurrency.value],
});
} else {
EvmChains.assertChainSupported(paymentChain);
const proxyInfoRetriever = new ProxyInfoRetriever(
paymentReference,
proxyContractAddress,
Expand Down
13 changes: 11 additions & 2 deletions packages/payment-detection/src/native-token-detector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExtensionTypes, PaymentTypes } from '@requestnetwork/types';
import { CurrencyTypes, ExtensionTypes, PaymentTypes } from '@requestnetwork/types';

import { ReferenceBasedDetector } from './reference-based-detector';
import { NativeDetectorOptions } from './types';
Expand All @@ -10,7 +10,14 @@ export abstract class NativeTokenPaymentDetector extends ReferenceBasedDetector<
ExtensionTypes.PnReferenceBased.IReferenceBased,
PaymentTypes.IETHPaymentEventParameters
> {
protected constructor({ network, advancedLogic, currencyManager }: NativeDetectorOptions) {
protected readonly network: CurrencyTypes.NearChainName | undefined;
protected readonly getSubgraphClient: NativeDetectorOptions['getSubgraphClient'];
protected constructor({
network,
advancedLogic,
currencyManager,
getSubgraphClient,
}: NativeDetectorOptions) {
const extensionId = ExtensionTypes.PAYMENT_NETWORK_ID.NATIVE_TOKEN;
const extension = advancedLogic.getNativeTokenExtensionForNetwork(
network,
Expand All @@ -19,5 +26,7 @@ export abstract class NativeTokenPaymentDetector extends ReferenceBasedDetector<
throw new Error(`the ${extensionId} extension is not supported for the network ${network}`);
}
super(extensionId, extension, currencyManager);
this.getSubgraphClient = getSubgraphClient;
this.network = network;
}
}
19 changes: 14 additions & 5 deletions packages/payment-detection/src/near/near-detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,23 @@ export class NearNativeTokenPaymentDetector extends NativeTokenPaymentDetector {
paymentEvents: [],
};
}
const infoRetriever = new NearInfoRetriever(
const subgraphClient = this.getSubgraphClient(paymentChain);
if (!subgraphClient) {
throw new Error(
`Could not find graphInfoRetriever for chain ${paymentChain} in payment detector`,
);
}
const infoRetriever = new NearInfoRetriever(subgraphClient);
const { paymentEvents } = await infoRetriever.getTransferEvents({
paymentReference,
address,
NearNativeTokenPaymentDetector.getContractName(paymentChain, paymentNetwork.version),
toAddress: address,
contractAddress: NearNativeTokenPaymentDetector.getContractName(
paymentChain,
paymentNetwork.version,
),
eventName,
paymentChain,
);
const { paymentEvents } = await infoRetriever.getTransferEvents();
});
return {
paymentEvents,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,18 @@ export class NearInfoRetriever implements ITheGraphBaseInfoRetriever<NearPayment
payment: GetNearPaymentsQuery['payments'][0],
params: TransferEventsParams,
): PaymentTypes.IPaymentNetworkEvent<NearPaymentEvent> {
// const block: number = payment.block;
return {
amount: payment.amount,
name: params.eventName,
timestamp: Number(payment.timestamp),
parameters: {
// amount: payment.amount,
// timestamp: payment.timestamp,
feeAmount: payment.feeAmount,
// currency: payment.currency,
receiptId: payment.receiptId,
// block: Number(payment.block) as number,
// gasUsed: payment.gasUsed,
// gasPrice: payment.gasPrice,
// amountInCrypto: payment.amountInCrypto,
// feeAmountInCrypto: payment.feeAmountInCrypto,
block: payment.block,
to: params.toAddress,
from: payment.from,
feeAddress: payment.feeAddress ?? undefined,
tokenAddress: params.acceptedTokens ? params.acceptedTokens[0] : undefined,
// contractAddress: this.proxyContractName,
},
};
}
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion packages/payment-detection/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export type ReferenceBasedDetectorOptions = {
};

export type NativeDetectorOptions = ReferenceBasedDetectorOptions & {
network: CurrencyTypes.ChainName;
network: CurrencyTypes.NearChainName;
/** override the default Subgraph for payment detection (EVM, Near) */
getSubgraphClient: (network: CurrencyTypes.ChainName) => TheGraphClient<'near'> | undefined;
};
101 changes: 50 additions & 51 deletions packages/payment-detection/test/erc20/fee-proxy-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import {
RequestLogicTypes,
} from '@requestnetwork/types';
import { CurrencyManager } from '@requestnetwork/currency';
import { AdvancedLogic } from '@requestnetwork/advanced-logic';
import {
ERC20FeeProxyPaymentDetector,
ERC20NearFeeProxyPaymentDetector,
} from '../../src/erc20/fee-proxy-contract';
import { ERC20FeeProxyPaymentDetector } from '../../src/erc20/fee-proxy-contract';
import { mockAdvancedLogicBase } from '../utils';

let erc20FeeProxyContract: ERC20FeeProxyPaymentDetector;
Expand All @@ -22,24 +18,25 @@ const createAddFeeAction = jest.fn();
const createAddPaymentInstructionAction = jest.fn();
const createAddRefundInstructionAction = jest.fn();

const feeProxyContractErc20 = {
createAddPaymentAddressAction,
createAddRefundAddressAction,
createCreationAction,
createAddFeeAction,
// inherited from declarative
createAddPaymentInstructionAction,
createAddRefundInstructionAction,
} as any as ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased;

const mockAdvancedLogic: AdvancedLogicTypes.IAdvancedLogic = {
...mockAdvancedLogicBase,
extensions: {
feeProxyContractErc20: {
createAddPaymentAddressAction,
createAddRefundAddressAction,
createCreationAction,
createAddFeeAction,
// inherited from declarative
createAddPaymentInstructionAction,
createAddRefundInstructionAction,
},
feeProxyContractErc20,
} as any as AdvancedLogicTypes.IAdvancedLogicExtensions,
getFeeProxyContractErc20ForNetwork: (_network) => feeProxyContractErc20,
};

const currencyManager = CurrencyManager.getDefault();
const advancedLogic = new AdvancedLogic(currencyManager);

/* eslint-disable @typescript-eslint/no-unused-expressions */
describe('api/erc20/fee-proxy-contract', () => {
beforeEach(() => {
Expand Down Expand Up @@ -551,12 +548,47 @@ describe('api/erc20/fee-proxy-contract', () => {
});

describe('on Near', () => {
beforeEach(() => {
// Same Detector, but instanciated with a Near network and a mocked Near graph client
erc20FeeProxyContract = new ERC20FeeProxyPaymentDetector({
advancedLogic: mockAdvancedLogic,
currencyManager,
network: 'aurora-testnet',
getSubgraphClient: (_network) => ({
GetFungibleTokenPayments: jest.fn().mockImplementation(() => ({
payments: [
{
contractAddress: 'pay.reqnetwork.testnet',
tokenAddress: 'fau.reqnetwork.testnet',
to: 'issuer.reqnetwork.testnet',
from: 'payer.reqnetwork.testnet',
amount: '168040800000000000000000',
feeAmount: '13386000000000000000',
reference: 'f59c9445040531b1',
block: 15767215,
gasUsed: '73152',
gasPrice: '12709127644',
timestamp: 1666002347,
amountInCrypto: null,
feeAddress: 'builder.reqnetwork.testnet',
feeAmountInCrypto: null,
maxRateTimespan: null,
},
],
})),
GetPaymentsAndEscrowState: jest.fn(),
GetNearConversionPayments: jest.fn(),
GetNearPayments: jest.fn(),
GetLastSyncedBlock: jest.fn(),
GetSyncedBlock: jest.fn(),
}),
});
});
it('can createExtensionsDataForCreation', async () => {
await erc20FeeProxyContract.createExtensionsDataForCreation({
paymentAddress: 'issuer.reqnetwork.testnet',
salt: 'ea3bc7caf64110ca',
});

expect(createCreationAction).toHaveBeenCalledWith({
feeAddress: undefined,
feeAmount: undefined,
Expand All @@ -567,7 +599,6 @@ describe('api/erc20/fee-proxy-contract', () => {
});

it('can retrieve payment using thegraph info retriever', async () => {
// graphql.request.mockResolvedValue();
const mockRequest: RequestLogicTypes.IRequest = {
creator: { type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: '0x2' },
currency: {
Expand Down Expand Up @@ -608,40 +639,8 @@ describe('api/erc20/fee-proxy-contract', () => {
timestamp: 0,
version: '0.2',
};
const nearErc20FeeProxyContract = new ERC20NearFeeProxyPaymentDetector({
advancedLogic,
currencyManager,
network: 'aurora-testnet',
getSubgraphClient: () => ({
GetFungibleTokenPayments: jest.fn().mockImplementation(() => ({
payments: [
{
contractAddress: 'pay.reqnetwork.testnet',
tokenAddress: 'fau.reqnetwork.testnet',
to: 'issuer.reqnetwork.testnet',
from: 'payer.reqnetwork.testnet',
amount: '168040800000000000000000',
feeAmount: '13386000000000000000',
reference: 'f59c9445040531b1',
block: 15767215,
gasUsed: '73152',
gasPrice: '12709127644',
timestamp: 1666002347,
amountInCrypto: null,
feeAddress: 'builder.reqnetwork.testnet',
feeAmountInCrypto: null,
maxRateTimespan: null,
},
],
})),
GetNearConversionPayments: jest.fn(),
GetNearPayments: jest.fn(),
GetLastSyncedBlock: jest.fn(),
GetSyncedBlock: jest.fn(),
}),
});

const { balance, error, events } = await nearErc20FeeProxyContract.getBalance(mockRequest);
const { balance, error, events } = await erc20FeeProxyContract.getBalance(mockRequest);
expect;
expect(error).toBeUndefined();
expect(balance).toBe('168040800000000000000000');
Expand Down
Loading