feat: update prices
This commit is contained in:
parent
5f2cd8831f
commit
f594c2d1a7
175
src/abi/OffchainOracle.json
Normal file
175
src/abi/OffchainOracle.json
Normal file
@ -0,0 +1,175 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract MultiWrapper", "name": "_multiWrapper", "type": "address" },
|
||||
{ "internalType": "contract IOracle[]", "name": "existingOracles", "type": "address[]" },
|
||||
{ "internalType": "enum OffchainOracle.OracleType[]", "name": "oracleTypes", "type": "uint8[]" },
|
||||
{ "internalType": "contract IERC20[]", "name": "existingConnectors", "type": "address[]" },
|
||||
{ "internalType": "contract IERC20", "name": "wBase", "type": "address" }
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
||||
"name": "ConnectorAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
||||
"name": "ConnectorRemoved",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [{ "indexed": false, "internalType": "contract MultiWrapper", "name": "multiWrapper", "type": "address" }],
|
||||
"name": "MultiWrapperUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "enum OffchainOracle.OracleType",
|
||||
"name": "oracleType",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "OracleAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": false, "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "enum OffchainOracle.OracleType",
|
||||
"name": "oracleType",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "OracleRemoved",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" },
|
||||
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
||||
"name": "addConnector",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
||||
{ "internalType": "enum OffchainOracle.OracleType", "name": "oracleKind", "type": "uint8" }
|
||||
],
|
||||
"name": "addOracle",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "connectors",
|
||||
"outputs": [{ "internalType": "contract IERC20[]", "name": "allConnectors", "type": "address[]" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract IERC20", "name": "srcToken", "type": "address" },
|
||||
{ "internalType": "contract IERC20", "name": "dstToken", "type": "address" },
|
||||
{ "internalType": "bool", "name": "useWrappers", "type": "bool" }
|
||||
],
|
||||
"name": "getRate",
|
||||
"outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract IERC20", "name": "srcToken", "type": "address" },
|
||||
{ "internalType": "bool", "name": "useSrcWrappers", "type": "bool" }
|
||||
],
|
||||
"name": "getRateToEth",
|
||||
"outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "multiWrapper",
|
||||
"outputs": [{ "internalType": "contract MultiWrapper", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "oracles",
|
||||
"outputs": [
|
||||
{ "internalType": "contract IOracle[]", "name": "allOracles", "type": "address[]" },
|
||||
{ "internalType": "enum OffchainOracle.OracleType[]", "name": "oracleTypes", "type": "uint8[]" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
||||
"name": "removeConnector",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
||||
{ "internalType": "enum OffchainOracle.OracleType", "name": "oracleKind", "type": "uint8" }
|
||||
],
|
||||
"name": "removeOracle",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "contract MultiWrapper", "name": "_multiWrapper", "type": "address" }],
|
||||
"name": "setMultiWrapper",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
523
src/artifacts/OffchainOracle.d.ts
vendored
Normal file
523
src/artifacts/OffchainOracle.d.ts
vendored
Normal file
@ -0,0 +1,523 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import {
|
||||
ethers,
|
||||
EventFilter,
|
||||
Signer,
|
||||
BigNumber,
|
||||
BigNumberish,
|
||||
PopulatedTransaction,
|
||||
BaseContract,
|
||||
ContractTransaction,
|
||||
Overrides,
|
||||
CallOverrides,
|
||||
} from "ethers";
|
||||
import { BytesLike } from "@ethersproject/bytes";
|
||||
import { Listener, Provider } from "@ethersproject/providers";
|
||||
import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi";
|
||||
import { TypedEventFilter, TypedEvent, TypedListener } from "./commons";
|
||||
|
||||
interface OffchainOracleInterface extends ethers.utils.Interface {
|
||||
functions: {
|
||||
"addConnector(address)": FunctionFragment;
|
||||
"addOracle(address,uint8)": FunctionFragment;
|
||||
"connectors()": FunctionFragment;
|
||||
"getRate(address,address,bool)": FunctionFragment;
|
||||
"getRateToEth(address,bool)": FunctionFragment;
|
||||
"multiWrapper()": FunctionFragment;
|
||||
"oracles()": FunctionFragment;
|
||||
"owner()": FunctionFragment;
|
||||
"removeConnector(address)": FunctionFragment;
|
||||
"removeOracle(address,uint8)": FunctionFragment;
|
||||
"renounceOwnership()": FunctionFragment;
|
||||
"setMultiWrapper(address)": FunctionFragment;
|
||||
"transferOwnership(address)": FunctionFragment;
|
||||
};
|
||||
|
||||
encodeFunctionData(
|
||||
functionFragment: "addConnector",
|
||||
values: [string]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "addOracle",
|
||||
values: [string, BigNumberish]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "connectors",
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "getRate",
|
||||
values: [string, string, boolean]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "getRateToEth",
|
||||
values: [string, boolean]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "multiWrapper",
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(functionFragment: "oracles", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "owner", values?: undefined): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "removeConnector",
|
||||
values: [string]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "removeOracle",
|
||||
values: [string, BigNumberish]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "renounceOwnership",
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "setMultiWrapper",
|
||||
values: [string]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "transferOwnership",
|
||||
values: [string]
|
||||
): string;
|
||||
|
||||
decodeFunctionResult(
|
||||
functionFragment: "addConnector",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(functionFragment: "addOracle", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "connectors", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "getRate", data: BytesLike): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "getRateToEth",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "multiWrapper",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(functionFragment: "oracles", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "removeConnector",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "removeOracle",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "renounceOwnership",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "setMultiWrapper",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "transferOwnership",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
|
||||
events: {
|
||||
"ConnectorAdded(address)": EventFragment;
|
||||
"ConnectorRemoved(address)": EventFragment;
|
||||
"MultiWrapperUpdated(address)": EventFragment;
|
||||
"OracleAdded(address,uint8)": EventFragment;
|
||||
"OracleRemoved(address,uint8)": EventFragment;
|
||||
"OwnershipTransferred(address,address)": EventFragment;
|
||||
};
|
||||
|
||||
getEvent(nameOrSignatureOrTopic: "ConnectorAdded"): EventFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "ConnectorRemoved"): EventFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "MultiWrapperUpdated"): EventFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "OracleAdded"): EventFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "OracleRemoved"): EventFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "OwnershipTransferred"): EventFragment;
|
||||
}
|
||||
|
||||
export class OffchainOracle extends BaseContract {
|
||||
connect(signerOrProvider: Signer | Provider | string): this;
|
||||
attach(addressOrName: string): this;
|
||||
deployed(): Promise<this>;
|
||||
|
||||
listeners<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter?: TypedEventFilter<EventArgsArray, EventArgsObject>
|
||||
): Array<TypedListener<EventArgsArray, EventArgsObject>>;
|
||||
off<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>,
|
||||
listener: TypedListener<EventArgsArray, EventArgsObject>
|
||||
): this;
|
||||
on<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>,
|
||||
listener: TypedListener<EventArgsArray, EventArgsObject>
|
||||
): this;
|
||||
once<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>,
|
||||
listener: TypedListener<EventArgsArray, EventArgsObject>
|
||||
): this;
|
||||
removeListener<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>,
|
||||
listener: TypedListener<EventArgsArray, EventArgsObject>
|
||||
): this;
|
||||
removeAllListeners<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>
|
||||
): this;
|
||||
|
||||
listeners(eventName?: string): Array<Listener>;
|
||||
off(eventName: string, listener: Listener): this;
|
||||
on(eventName: string, listener: Listener): this;
|
||||
once(eventName: string, listener: Listener): this;
|
||||
removeListener(eventName: string, listener: Listener): this;
|
||||
removeAllListeners(eventName?: string): this;
|
||||
|
||||
queryFilter<EventArgsArray extends Array<any>, EventArgsObject>(
|
||||
event: TypedEventFilter<EventArgsArray, EventArgsObject>,
|
||||
fromBlockOrBlockhash?: string | number | undefined,
|
||||
toBlock?: string | number | undefined
|
||||
): Promise<Array<TypedEvent<EventArgsArray & EventArgsObject>>>;
|
||||
|
||||
interface: OffchainOracleInterface;
|
||||
|
||||
functions: {
|
||||
addConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
addOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
connectors(
|
||||
overrides?: CallOverrides
|
||||
): Promise<[string[]] & { allConnectors: string[] }>;
|
||||
|
||||
getRate(
|
||||
srcToken: string,
|
||||
dstToken: string,
|
||||
useWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<[BigNumber] & { weightedRate: BigNumber }>;
|
||||
|
||||
getRateToEth(
|
||||
srcToken: string,
|
||||
useSrcWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<[BigNumber] & { weightedRate: BigNumber }>;
|
||||
|
||||
multiWrapper(overrides?: CallOverrides): Promise<[string]>;
|
||||
|
||||
oracles(
|
||||
overrides?: CallOverrides
|
||||
): Promise<
|
||||
[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }
|
||||
>;
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<[string]>;
|
||||
|
||||
removeConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
removeOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
renounceOwnership(
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
setMultiWrapper(
|
||||
_multiWrapper: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferOwnership(
|
||||
newOwner: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
};
|
||||
|
||||
addConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
addOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
connectors(overrides?: CallOverrides): Promise<string[]>;
|
||||
|
||||
getRate(
|
||||
srcToken: string,
|
||||
dstToken: string,
|
||||
useWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
getRateToEth(
|
||||
srcToken: string,
|
||||
useSrcWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
multiWrapper(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
oracles(
|
||||
overrides?: CallOverrides
|
||||
): Promise<
|
||||
[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }
|
||||
>;
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
removeConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
removeOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
renounceOwnership(
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
setMultiWrapper(
|
||||
_multiWrapper: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferOwnership(
|
||||
newOwner: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
callStatic: {
|
||||
addConnector(connector: string, overrides?: CallOverrides): Promise<void>;
|
||||
|
||||
addOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
connectors(overrides?: CallOverrides): Promise<string[]>;
|
||||
|
||||
getRate(
|
||||
srcToken: string,
|
||||
dstToken: string,
|
||||
useWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
getRateToEth(
|
||||
srcToken: string,
|
||||
useSrcWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
multiWrapper(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
oracles(
|
||||
overrides?: CallOverrides
|
||||
): Promise<
|
||||
[string[], number[]] & { allOracles: string[]; oracleTypes: number[] }
|
||||
>;
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
removeConnector(
|
||||
connector: string,
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
removeOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
renounceOwnership(overrides?: CallOverrides): Promise<void>;
|
||||
|
||||
setMultiWrapper(
|
||||
_multiWrapper: string,
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
transferOwnership(
|
||||
newOwner: string,
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
};
|
||||
|
||||
filters: {
|
||||
ConnectorAdded(
|
||||
connector?: null
|
||||
): TypedEventFilter<[string], { connector: string }>;
|
||||
|
||||
ConnectorRemoved(
|
||||
connector?: null
|
||||
): TypedEventFilter<[string], { connector: string }>;
|
||||
|
||||
MultiWrapperUpdated(
|
||||
multiWrapper?: null
|
||||
): TypedEventFilter<[string], { multiWrapper: string }>;
|
||||
|
||||
OracleAdded(
|
||||
oracle?: null,
|
||||
oracleType?: null
|
||||
): TypedEventFilter<
|
||||
[string, number],
|
||||
{ oracle: string; oracleType: number }
|
||||
>;
|
||||
|
||||
OracleRemoved(
|
||||
oracle?: null,
|
||||
oracleType?: null
|
||||
): TypedEventFilter<
|
||||
[string, number],
|
||||
{ oracle: string; oracleType: number }
|
||||
>;
|
||||
|
||||
OwnershipTransferred(
|
||||
previousOwner?: string | null,
|
||||
newOwner?: string | null
|
||||
): TypedEventFilter<
|
||||
[string, string],
|
||||
{ previousOwner: string; newOwner: string }
|
||||
>;
|
||||
};
|
||||
|
||||
estimateGas: {
|
||||
addConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
addOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
connectors(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
getRate(
|
||||
srcToken: string,
|
||||
dstToken: string,
|
||||
useWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
getRateToEth(
|
||||
srcToken: string,
|
||||
useSrcWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
multiWrapper(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
oracles(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
removeConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
removeOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
renounceOwnership(
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
setMultiWrapper(
|
||||
_multiWrapper: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
transferOwnership(
|
||||
newOwner: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<BigNumber>;
|
||||
};
|
||||
|
||||
populateTransaction: {
|
||||
addConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
addOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
connectors(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
getRate(
|
||||
srcToken: string,
|
||||
dstToken: string,
|
||||
useWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
getRateToEth(
|
||||
srcToken: string,
|
||||
useSrcWrappers: boolean,
|
||||
overrides?: CallOverrides
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
multiWrapper(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
oracles(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
removeConnector(
|
||||
connector: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
removeOracle(
|
||||
oracle: string,
|
||||
oracleKind: BigNumberish,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
renounceOwnership(
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
setMultiWrapper(
|
||||
_multiWrapper: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
transferOwnership(
|
||||
newOwner: string,
|
||||
overrides?: Overrides & { from?: string | Promise<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
};
|
||||
}
|
358
src/artifacts/factories/OffchainOracle__factory.ts
Normal file
358
src/artifacts/factories/OffchainOracle__factory.ts
Normal file
@ -0,0 +1,358 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import { Contract, Signer, utils } from "ethers";
|
||||
import { Provider } from "@ethersproject/providers";
|
||||
import type {
|
||||
OffchainOracle,
|
||||
OffchainOracleInterface,
|
||||
} from "../OffchainOracle";
|
||||
|
||||
const _abi = [
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract MultiWrapper",
|
||||
name: "_multiWrapper",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "contract IOracle[]",
|
||||
name: "existingOracles",
|
||||
type: "address[]",
|
||||
},
|
||||
{
|
||||
internalType: "enum OffchainOracle.OracleType[]",
|
||||
name: "oracleTypes",
|
||||
type: "uint8[]",
|
||||
},
|
||||
{
|
||||
internalType: "contract IERC20[]",
|
||||
name: "existingConnectors",
|
||||
type: "address[]",
|
||||
},
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "wBase",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "constructor",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "contract IERC20",
|
||||
name: "connector",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "ConnectorAdded",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "contract IERC20",
|
||||
name: "connector",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "ConnectorRemoved",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "contract MultiWrapper",
|
||||
name: "multiWrapper",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "MultiWrapperUpdated",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "contract IOracle",
|
||||
name: "oracle",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "enum OffchainOracle.OracleType",
|
||||
name: "oracleType",
|
||||
type: "uint8",
|
||||
},
|
||||
],
|
||||
name: "OracleAdded",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "contract IOracle",
|
||||
name: "oracle",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "enum OffchainOracle.OracleType",
|
||||
name: "oracleType",
|
||||
type: "uint8",
|
||||
},
|
||||
],
|
||||
name: "OracleRemoved",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "previousOwner",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "newOwner",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "OwnershipTransferred",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "connector",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "addConnector",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IOracle",
|
||||
name: "oracle",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "enum OffchainOracle.OracleType",
|
||||
name: "oracleKind",
|
||||
type: "uint8",
|
||||
},
|
||||
],
|
||||
name: "addOracle",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "connectors",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "contract IERC20[]",
|
||||
name: "allConnectors",
|
||||
type: "address[]",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "srcToken",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "dstToken",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "useWrappers",
|
||||
type: "bool",
|
||||
},
|
||||
],
|
||||
name: "getRate",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "weightedRate",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "srcToken",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "useSrcWrappers",
|
||||
type: "bool",
|
||||
},
|
||||
],
|
||||
name: "getRateToEth",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "weightedRate",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "multiWrapper",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "contract MultiWrapper",
|
||||
name: "",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "oracles",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "contract IOracle[]",
|
||||
name: "allOracles",
|
||||
type: "address[]",
|
||||
},
|
||||
{
|
||||
internalType: "enum OffchainOracle.OracleType[]",
|
||||
name: "oracleTypes",
|
||||
type: "uint8[]",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "owner",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IERC20",
|
||||
name: "connector",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "removeConnector",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract IOracle",
|
||||
name: "oracle",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "enum OffchainOracle.OracleType",
|
||||
name: "oracleKind",
|
||||
type: "uint8",
|
||||
},
|
||||
],
|
||||
name: "removeOracle",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "renounceOwnership",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract MultiWrapper",
|
||||
name: "_multiWrapper",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "setMultiWrapper",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "newOwner",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
name: "transferOwnership",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function",
|
||||
},
|
||||
];
|
||||
|
||||
export class OffchainOracle__factory {
|
||||
static readonly abi = _abi;
|
||||
static createInterface(): OffchainOracleInterface {
|
||||
return new utils.Interface(_abi) as OffchainOracleInterface;
|
||||
}
|
||||
static connect(
|
||||
address: string,
|
||||
signerOrProvider: Signer | Provider
|
||||
): OffchainOracle {
|
||||
return new Contract(address, _abi, signerOrProvider) as OffchainOracle;
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
/* Autogenerated file. Do not edit manually. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type { OffchainOracle } from "./OffchainOracle";
|
||||
export type { TornadoPool } from "./TornadoPool";
|
||||
|
||||
export { OffchainOracle__factory } from "./factories/OffchainOracle__factory";
|
||||
export { TornadoPool__factory } from "./factories/TornadoPool__factory";
|
||||
|
@ -4,12 +4,14 @@ export const CONTRACT_NETWORKS: { [chainId in ChainId]: string } = {
|
||||
// [ChainId.MAINNET]: '0x8Bfac9EF3d73cE08C7CEC339C0fE3B2e57814c1E',
|
||||
[ChainId.GOERLI]: '0xE2D9aF526edeB16a02FBC3B68B0eB9B534f9c114',
|
||||
[ChainId.OPTIMISM]: '0xcd7318c299A82E887f5180EF865a4c350dFC9fe5',
|
||||
[ChainId.XDAI]: '0xf7Ca3B0522A4Db061eEeaE4A086a79E48F2aCD25',
|
||||
[ChainId.XDAI]: '0x4d701A6EE8c13D3AB0d2CE4dfA773c04fa4C5933',
|
||||
};
|
||||
|
||||
export const RPC_LIST: { [chainId in ChainId]: string } = {
|
||||
// [ChainId.MAINNET]: 'https://mainnet.infura.io/v3/eb6a84e726614079948e0b1efce5baa5',
|
||||
[ChainId.MAINNET]: 'https://mainnet.infura.io/v3/eb6a84e726614079948e0b1efce5baa5',
|
||||
[ChainId.GOERLI]: 'https://eth-goerli.alchemyapi.io/v2/hlSj0EqPUuLGyyTExs6UqFKnXDrc_eOh',
|
||||
[ChainId.OPTIMISM]: 'https://optimism-kovan.infura.io/v3/8f786b96d16046b78e0287fa61c6fcf8',
|
||||
[ChainId.XDAI]: 'https://rpc.xdaichain.com',
|
||||
};
|
||||
|
||||
export const OFF_CHAIN_ORACLE = '0x07D91f5fb9Bf7798734C3f606dB065549F6893bb';
|
||||
|
@ -43,8 +43,9 @@ const BG_ZERO = BigNumber.from(numbers.ZERO);
|
||||
const FIELD_SIZE = BigNumber.from('21888242871839275222246405745257275088548364400416034343698204186575808495617');
|
||||
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
const DAI_ADDRESS = '0x6b175474e89094c44da98b954eedeac495271d0f';
|
||||
|
||||
export { numbers, NETWORKS_INFO, FIELD_SIZE, BG_ZERO, ZERO_ADDRESS };
|
||||
export { numbers, NETWORKS_INFO, DAI_ADDRESS, FIELD_SIZE, BG_ZERO, ZERO_ADDRESS };
|
||||
|
||||
export const CONTRACT_ERRORS = [
|
||||
'Invalid merkle root',
|
||||
|
@ -7,6 +7,7 @@ import { ProviderService } from '@/services';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
import { Transaction } from '@/types';
|
||||
|
||||
@Injectable()
|
||||
class ApiService {
|
||||
constructor(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BullModule } from '@nestjs/bull';
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { GasPriceService, ProviderService } from '@/services';
|
||||
import { GasPriceService, ProviderService, OffchainPriceService } from '@/services';
|
||||
|
||||
import { TransactionProcessor } from './transaction.processor';
|
||||
|
||||
@ -9,7 +9,7 @@ import bullConfig from '@/config/bull.config';
|
||||
|
||||
@Module({
|
||||
imports: [BullModule.registerQueue(bullConfig())],
|
||||
providers: [GasPriceService, ProviderService, TransactionProcessor],
|
||||
providers: [GasPriceService, ProviderService, TransactionProcessor, OffchainPriceService],
|
||||
exports: [BullModule],
|
||||
})
|
||||
export class QueueModule {}
|
||||
|
@ -7,9 +7,10 @@ import { ConfigService } from '@nestjs/config';
|
||||
import { InjectQueue, Process, Processor, OnQueueActive, OnQueueCompleted, OnQueueFailed } from '@nestjs/bull';
|
||||
|
||||
import { Transaction } from '@/types';
|
||||
import { getToIntegerMultiplier, toWei } from '@/utilities';
|
||||
import { numbers, CONTRACT_ERRORS, jobStatus } from '@/constants';
|
||||
import { getToIntegerMultiplier } from '@/utilities';
|
||||
import { GasPriceService, ProviderService } from '@/services';
|
||||
import { GasPriceService, ProviderService, OffchainPriceService } from '@/services';
|
||||
|
||||
import txMangerConfig from '@/config/txManager.config';
|
||||
|
||||
import { BaseProcessor } from './base.processor';
|
||||
@ -19,9 +20,10 @@ import { BaseProcessor } from './base.processor';
|
||||
export class TransactionProcessor extends BaseProcessor<Transaction> {
|
||||
constructor(
|
||||
@InjectQueue('transaction') public transactionQueue: Queue,
|
||||
private configService: ConfigService,
|
||||
private gasPriceService: GasPriceService,
|
||||
private providerService: ProviderService,
|
||||
private configService: ConfigService,
|
||||
private offChainPriceService: OffchainPriceService,
|
||||
) {
|
||||
super();
|
||||
this.queueName = 'transaction';
|
||||
@ -132,13 +134,15 @@ export class TransactionProcessor extends BaseProcessor<Transaction> {
|
||||
|
||||
async checkFee({ fee, externalAmount }) {
|
||||
const { gasLimit } = this.configService.get('base');
|
||||
|
||||
const { fast } = await this.gasPriceService.getGasPrice();
|
||||
|
||||
const expense = BigNumber.from(fast).mul(gasLimit);
|
||||
const operationFee = BigNumber.from(fast).mul(gasLimit);
|
||||
|
||||
const feePercent = this.getServiceFee(externalAmount);
|
||||
|
||||
const ethPrice = await this.offChainPriceService.getDaiEthPrice();
|
||||
|
||||
const expense = operationFee.mul(ethPrice).div(toWei('1'));
|
||||
const desiredFee = expense.add(feePercent);
|
||||
|
||||
if (BigNumber.from(fee).lt(desiredFee)) {
|
||||
|
@ -30,8 +30,8 @@ export class GasPriceService {
|
||||
const bnGas = BigNumber.from(toWei(String(fast), 'gwei'));
|
||||
|
||||
return {
|
||||
instant: bnGas.mul(130).div(100).toHexString(),
|
||||
fast: bnGas,
|
||||
instant: bnGas.mul(150).div(100).toHexString(),
|
||||
fast: bnGas.mul(130).div(100).toHexString(),
|
||||
standard: bnGas.mul(85).div(100).toHexString(),
|
||||
low: bnGas.mul(50).div(100).toHexString(),
|
||||
};
|
@ -1,2 +1,4 @@
|
||||
export * from './oracle.service';
|
||||
export * from './provider.service';
|
||||
|
||||
export * from './gas-price.service';
|
||||
export * from './offchain-price.service';
|
||||
|
30
src/services/offchain-price.service.ts
Normal file
30
src/services/offchain-price.service.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
import { BigNumber } from 'ethers';
|
||||
|
||||
import { ChainId } from '@/types';
|
||||
import { DAI_ADDRESS } from '@/constants';
|
||||
import { ProviderService } from '@/services';
|
||||
import { toWei } from '@/utilities';
|
||||
|
||||
@Injectable()
|
||||
export class OffchainPriceService {
|
||||
private readonly chainId: number;
|
||||
|
||||
constructor(private configService: ConfigService, private providerService: ProviderService) {
|
||||
this.chainId = ChainId.MAINNET;
|
||||
}
|
||||
|
||||
async getDaiEthPrice() {
|
||||
const contract = this.providerService.getOffChainOracle();
|
||||
|
||||
const rate = await contract.callStatic.getRateToEth(DAI_ADDRESS, false);
|
||||
|
||||
const numerator = BigNumber.from(toWei('1'));
|
||||
const denominator = BigNumber.from(toWei('1'));
|
||||
|
||||
// price = rate * "token decimals" / "eth decimals" (dai = eth decimals)
|
||||
return BigNumber.from(rate).mul(numerator).div(denominator);
|
||||
}
|
||||
}
|
@ -2,8 +2,9 @@ import { ethers } from 'ethers';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
import { CONTRACT_NETWORKS, RPC_LIST } from '@/constants';
|
||||
import { TornadoPool__factory as TornadoPoolFactory } from '@/artifacts';
|
||||
import { ChainId } from '@/types';
|
||||
import { CONTRACT_NETWORKS, OFF_CHAIN_ORACLE, RPC_LIST } from '@/constants';
|
||||
import { TornadoPool__factory as TornadoPool, OffchainOracle__factory as OffchainOracle } from '@/artifacts';
|
||||
|
||||
@Injectable()
|
||||
export class ProviderService {
|
||||
@ -20,7 +21,12 @@ export class ProviderService {
|
||||
}
|
||||
|
||||
getTornadoPool() {
|
||||
return TornadoPoolFactory.connect(CONTRACT_NETWORKS[this.chainId], this.getProviderWithSigner());
|
||||
return TornadoPool.connect(CONTRACT_NETWORKS[this.chainId], this.getProviderWithSigner());
|
||||
}
|
||||
|
||||
getOffChainOracle() {
|
||||
const provider = ethers.providers.getDefaultProvider(RPC_LIST[ChainId.MAINNET]);
|
||||
return OffchainOracle.connect(OFF_CHAIN_ORACLE, provider);
|
||||
}
|
||||
|
||||
async checkSenderBalance() {
|
||||
|
Loading…
Reference in New Issue
Block a user