UNPKG

@superfluid-finance/sdk-core

Version:
311 lines 14.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const ethers_1 = require("ethers"); const BatchCall_1 = __importDefault(require("./BatchCall")); const ConstantFlowAgreementV1_1 = __importDefault(require("./ConstantFlowAgreementV1")); const GeneralDistributionAgreementV1_1 = __importDefault(require("./GeneralDistributionAgreementV1")); const Governance_1 = __importDefault(require("./Governance")); const Host_1 = __importDefault(require("./Host")); const InstantDistributionAgreementV1_1 = __importDefault(require("./InstantDistributionAgreementV1")); const Operation_1 = __importDefault(require("./Operation")); const Query_1 = __importDefault(require("./Query")); const SFError_1 = require("./SFError"); const SuperToken_1 = __importDefault(require("./SuperToken")); const constants_1 = require("./constants"); const frameworkHelpers_1 = require("./frameworkHelpers"); const typechain_types_1 = require("./typechain-types"); const utils_1 = require("./utils"); const V1 = "v1"; /** * Superfluid Framework Class * @description The entrypoint for the SDK-core, `create` an instance of this for full functionality. */ class Framework { constructor(options, settings) { /** * Create a signer which can be used to sign transactions. * @param options.web3Provider a Web3Provider object (e.g. client side - metamask, web3modal) * @param options.provider an ethers Provider object (e.g. via Hardhat ethers) * @param options.privateKey a test account private key * @param options.signer a signer object (e.g. ethers.Wallet instance) * @returns `ethers.Signer` object */ this.createSigner = (options) => { if (!options.privateKey && !options.provider && !options.signer && !options.web3Provider) { throw new SFError_1.SFError({ type: "CREATE_SIGNER", message: "You must pass in a private key, provider or signer.", }); } /* istanbul ignore else */ if (options.privateKey) { if (!options.provider) { throw new SFError_1.SFError({ type: "CREATE_SIGNER", message: "You must pass in a provider with your private key.", }); } return new ethers_1.ethers.Wallet(options.privateKey, options.provider); } else if (options.signer) { return options.signer; } // NOTE: tested by sdk-redux already else if (options.web3Provider) { return options.web3Provider.getSigner(); } /* istanbul ignore next */ throw new SFError_1.SFError({ type: "CREATE_SIGNER", message: "Something went wrong, this should never occur.", }); }; /** * Create a `BatchCall` class from the `Framework`. * @param operations the list of operations to execute * @returns `BatchCall` class */ this.batchCall = (operations) => { return new BatchCall_1.default({ operations, hostAddress: this.settings.config.hostAddress, }); }; /** * Create an `Operation` class from the `Framework`. * @param txn the populated transaction to execute * @param type the operation type * @returns `Operation` class */ this.operation = (txn, type) => { return new Operation_1.default(txn, type); }; /** * Loads `NativeAssetSuperToken` class from the `Framework`. Will throw if token is not NativeAssetSuperToken. * @param tokenAddressOrSymbol * @returns `NativeAssetSuperToken` class */ this.loadNativeAssetSuperToken = async (tokenAddressOrSymbol) => { const superToken = await this.loadSuperToken(tokenAddressOrSymbol); // The NativeAssetSuperToken class should have the nativeTokenSymbol property const isNativeAssetSuperToken = !!superToken.nativeTokenSymbol; if (!isNativeAssetSuperToken) { throw new SFError_1.SFError({ type: "SUPERTOKEN_INITIALIZATION", message: "The token is not a native asset supertoken.", }); } return superToken; }; /** * Loads `PureSuperToken` class from the `Framework`. Will throw if token is not PureSuperToken. * @param tokenAddressOrSymbol * @returns `PureSuperToken` class */ this.loadPureSuperToken = async (tokenAddressOrSymbol) => { const superToken = await this.loadSuperToken(tokenAddressOrSymbol); // The PureSuperToken class should not have the downgrade (and upgrade) function // we can just check if downgrade doesn't exist const isPureSuperToken = !!superToken.downgrade === false; if (!isPureSuperToken) { throw new SFError_1.SFError({ type: "SUPERTOKEN_INITIALIZATION", message: "The token is not a pure supertoken.", }); } return superToken; }; /** * Loads `WrapperSuperToken` class from the `Framework`. Will throw if token is not WrapperSuperToken. * @param tokenAddressOrSymbol * @returns `WrapperSuperToken` class */ this.loadWrapperSuperToken = async (tokenAddressOrSymbol) => { const superToken = await this.loadSuperToken(tokenAddressOrSymbol); // The WrapperSuperToken class should have the underlyingToken property const isWrapperSuperToken = !!superToken.underlyingToken; if (!isWrapperSuperToken) { throw new SFError_1.SFError({ type: "SUPERTOKEN_INITIALIZATION", message: "The token is not a wrapper supertoken.", }); } return superToken; }; /** * Loads `SuperToken` class from the `Framework`. Use this when you're unsure of the token type. * @param tokenAddressOrSymbol the `SuperToken` address or symbol (if symbol, it must be on the resolver) * @returns `SuperToken` class */ this.loadSuperToken = async (tokenAddressOrSymbol) => { const address = await this._tryGetTokenAddress(tokenAddressOrSymbol); return await SuperToken_1.default.create({ ...this.settings, address, }); }; /** * Try to get the token address given an address (returns if valid) or the token symbol via the resolver. * @param tokenAddressOrSymbol * @returns token address */ this._tryGetTokenAddress = async (tokenAddressOrSymbol) => { const isInputValidAddress = ethers_1.ethers.utils.isAddress(tokenAddressOrSymbol); if (isInputValidAddress) { return tokenAddressOrSymbol; } else { try { const superTokenKey = "supertokens." + this.settings.protocolReleaseVersion + "." + tokenAddressOrSymbol; const resolver = typechain_types_1.Resolver__factory.connect(this.settings.config.resolverAddress, this.settings.provider); return await resolver.get(superTokenKey); } catch (err) { throw new SFError_1.SFError({ type: "SUPERTOKEN_INITIALIZATION", message: "There was an error with loading the SuperToken with symbol: " + tokenAddressOrSymbol + " with the resolver.", cause: err, }); } } }; this.userInputOptions = options; this.settings = settings; this.cfaV1 = new ConstantFlowAgreementV1_1.default(settings.config.hostAddress, settings.config.cfaV1Address, settings.config.cfaV1ForwarderAddress); this.governance = new Governance_1.default(settings.config.hostAddress, settings.config.governanceAddress); this.host = new Host_1.default(settings.config.hostAddress); this.idaV1 = new InstantDistributionAgreementV1_1.default(settings.config.hostAddress, settings.config.idaV1Address); this.gdaV1 = new GeneralDistributionAgreementV1_1.default(settings.config.hostAddress, settings.config.gdaV1Address, settings.config.gdaV1ForwarderAddress); this.query = new Query_1.default(settings); const resolver = new ethers_1.ethers.Contract(settings.config.resolverAddress, typechain_types_1.Resolver__factory.abi); this.contracts = { cfaV1: this.cfaV1.contract, governance: this.governance.contract, host: this.host.contract, idaV1: this.idaV1.contract, gdaV1: this.gdaV1.contract, resolver, }; } } _a = Framework; /** * Creates the Framework object based on user provided `options`. * @param options.chainId the chainId of your desired network (e.g. 137 = matic) * @param options.customSubgraphQueriesEndpoint your custom subgraph endpoint * @param options.resolverAddress a custom resolver address (advanced use for testing) * @param options.protocolReleaseVersion a custom release version (advanced use for testing) * @param options.provider a provider object (injected web3, injected ethers, ethers provider) necessary for initializing the framework * @returns `Framework` class */ Framework.create = async (options) => { (0, frameworkHelpers_1.validateFrameworkConstructorOptions)({ ...options, protocolReleaseVersion: options.protocolReleaseVersion || V1, }); const networkName = (0, frameworkHelpers_1.getNetworkName)(options); const chainId = options.chainId || constants_1.networkNameToChainIdMap.get(networkName); const releaseVersion = options.protocolReleaseVersion || V1; const customSubgraphQueriesEndpoint = options.customSubgraphQueriesEndpoint || (0, frameworkHelpers_1.getSubgraphQueriesEndpoint)(options); const provider = (0, utils_1.isEthersProvider)(options.provider) ? options.provider : (0, utils_1.isInjectedWeb3)(options.provider) ? // must explicitly cast web3 provider type because // ethers.providers.Web3Provider doesn't like // the type passed. new ethers_1.ethers.providers.Web3Provider(options.provider.currentProvider) : options.provider.provider; const network = await provider.getNetwork(); if (network.chainId !== chainId && chainId != null) { throw new SFError_1.SFError({ type: "NETWORK_MISMATCH", message: "Your provider network chainId is: " + network.chainId + " whereas your desired chainId is: " + chainId, }); } try { const networkData = constants_1.chainIdToResolverDataMap.get(chainId); const resolverAddress = options.resolverAddress ? options.resolverAddress : networkData ? networkData.addresses.resolver : ethers_1.ethers.constants.AddressZero; const resolver = typechain_types_1.Resolver__factory.connect(resolverAddress, provider); const baseSettings = { chainId, customSubgraphQueriesEndpoint, protocolReleaseVersion: options.protocolReleaseVersion || V1, provider, networkName, }; // supported networks scenario if (networkData && baseSettings.protocolReleaseVersion === V1) { const governanceAddress = networkData.addresses.governance ? networkData.addresses.governance : await typechain_types_1.Superfluid__factory.connect(networkData.addresses.host, provider).getGovernance(); const settings = { ...baseSettings, config: { resolverAddress, hostAddress: networkData.addresses.host, cfaV1Address: networkData.addresses.cfaV1, idaV1Address: networkData.addresses.idaV1, gdaV1Address: networkData.addresses.gdaV1 || ethers_1.ethers.constants.AddressZero, gdaV1ForwarderAddress: networkData.addresses.gdaV1Forwarder || ethers_1.ethers.constants.AddressZero, governanceAddress, cfaV1ForwarderAddress: networkData.addresses.cfaV1Forwarder, }, }; return new _a(options, settings); } else { // unsupported networks scenario (e.g. local testing) const superfluidLoaderAddress = await resolver.get("SuperfluidLoader-v1"); const cfaV1ForwarderAddress = await resolver.get("CFAv1Forwarder"); const gdaV1ForwarderAddress = await resolver.get("GDAv1Forwarder"); const superfluidLoader = typechain_types_1.SuperfluidLoader__factory.connect(superfluidLoaderAddress, provider); const framework = await superfluidLoader.loadFramework(releaseVersion); const governanceAddress = await typechain_types_1.Superfluid__factory.connect(framework.superfluid, provider).getGovernance(); const settings = { ...baseSettings, config: { resolverAddress, hostAddress: framework.superfluid, cfaV1Address: framework.agreementCFAv1, idaV1Address: framework.agreementIDAv1, gdaV1Address: framework.agreementGDAv1, governanceAddress, cfaV1ForwarderAddress, gdaV1ForwarderAddress, }, }; return new _a(options, settings); } } catch (err) { throw new SFError_1.SFError({ type: "FRAMEWORK_INITIALIZATION", message: "There was an error initializing the framework", cause: err, }); } }; exports.default = Framework; //# sourceMappingURL=Framework.js.map