diff --git a/packages/core/package.json b/packages/core/package.json index 639ac44967..3e990ad048 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,6 +39,7 @@ "dependencies": { "@snickerdoodlelabs/common-utils": "workspace:^", "@snickerdoodlelabs/contracts-sdk": "workspace:^", + "@snickerdoodlelabs/erc7529": "workspace:^", "@snickerdoodlelabs/indexers": "workspace:^", "@snickerdoodlelabs/insight-platform-api": "workspace:^", "@snickerdoodlelabs/node-utils": "workspace:^", diff --git a/packages/core/src/implementations/SnickerdoodleCore.module.ts b/packages/core/src/implementations/SnickerdoodleCore.module.ts index c95700281a..8934f958a2 100644 --- a/packages/core/src/implementations/SnickerdoodleCore.module.ts +++ b/packages/core/src/implementations/SnickerdoodleCore.module.ts @@ -12,6 +12,13 @@ import { LogUtils, TimeUtils, } from "@snickerdoodlelabs/common-utils"; +import { + ERC7529Utils, + IERC7529ConfigProvider, + IERC7529ConfigProviderType, + IERC7529Utils, + IERC7529UtilsType, +} from "@snickerdoodlelabs/erc7529"; import { IIndexerConfigProvider, IIndexerConfigProviderType, @@ -54,10 +61,8 @@ import { ICloudStorageManager, ICloudStorageManagerType, ICloudStorage, - GoogleCloudStorage, DropboxCloudStorage, IDropboxCloudStorageType, - IGDriveCloudStorageType, IPersistenceContextProvider, IPersistenceContextProviderType, NullCloudStorage, @@ -120,7 +125,6 @@ import { BrowsingDataRepository, CoinGeckoTokenPriceRepository, ConsentContractRepository, - DNSRepository, DataWalletPersistence, DemographicDataRepository, DiscordRepository, @@ -208,8 +212,6 @@ import { IBrowsingDataRepositoryType, IConsentContractRepository, IConsentContractRepositoryType, - IDNSRepository, - IDNSRepositoryType, IDataWalletPersistence, IDataWalletPersistenceType, IDemographicDataRepository, @@ -344,9 +346,6 @@ export const snickerdoodleCoreModule = new ContainerModule( bind(IMarketplaceRepositoryType).to( MarketplaceRepository, ); - bind(IDNSRepositoryType) - .to(DNSRepository) - .inSingletonScope(); bind(IDomainCredentialRepositoryType) .to(DomainCredentialRepository) .inSingletonScope(); @@ -421,6 +420,9 @@ export const snickerdoodleCoreModule = new ContainerModule( bind(IIndexerConfigProviderType).toConstantValue( configProvider, ); + bind(IERC7529ConfigProviderType).toConstantValue( + configProvider, + ); // Binding cloud storage manager bind( @@ -454,6 +456,8 @@ export const snickerdoodleCoreModule = new ContainerModule( bind(IBigNumberUtilsType) .to(BigNumberUtils) .inSingletonScope(); + bind(ITimeUtilsType).to(TimeUtils).inSingletonScope(); + bind(IERC7529UtilsType).to(ERC7529Utils).inSingletonScope(); // Utilites/factory bind(IContractFactoryType) @@ -507,9 +511,6 @@ export const snickerdoodleCoreModule = new ContainerModule( .to(SDQLQueryWrapperFactory) .inSingletonScope(); - bind(ITimeUtilsType).to(TimeUtils).inSingletonScope(); - - /* Cloud Storage Options - may need to comment out */ bind(INullCloudStorageType) .to(NullCloudStorage) .inSingletonScope(); diff --git a/packages/core/src/implementations/SnickerdoodleCore.ts b/packages/core/src/implementations/SnickerdoodleCore.ts index 3187e0249b..88ed903ec9 100644 --- a/packages/core/src/implementations/SnickerdoodleCore.ts +++ b/packages/core/src/implementations/SnickerdoodleCore.ts @@ -399,15 +399,6 @@ export class SnickerdoodleCore implements ISnickerdoodleCore { return invitationService.getAgreementFlags(consentContractAddress); }, - getAvailableInvitationsCID: ( - sourceDomain: DomainName | undefined = undefined, - ) => { - const invitationService = this.iocContainer.get( - IInvitationServiceType, - ); - - return invitationService.getAvailableInvitationsCID(); - }, getAcceptedInvitationsCID: ( sourceDomain: DomainName | undefined = undefined, ) => { @@ -762,7 +753,12 @@ export class SnickerdoodleCore implements ISnickerdoodleCore { const consentRepo = this.iocContainer.get( IConsentContractRepositoryType, ); - return consentRepo.getInvitationUrls(consentContractAddress); + return consentRepo.getDomains(consentContractAddress).map((domains) => { + // This method only returns domains, not complete urls + return domains.map((domain) => { + return URLString(domain); + }); + }); } public getConsentCapacity( diff --git a/packages/core/src/implementations/api/BlockchainListener.ts b/packages/core/src/implementations/api/BlockchainListener.ts index 6861c37461..3e3b30d9c1 100644 --- a/packages/core/src/implementations/api/BlockchainListener.ts +++ b/packages/core/src/implementations/api/BlockchainListener.ts @@ -4,7 +4,6 @@ import { BlockchainProviderError, BlockNumber, ConsentContractError, - ConsentContractRepositoryError, ConsentError, ConsentFactoryContractError, IPFSError, diff --git a/packages/core/src/implementations/business/InvitationService.ts b/packages/core/src/implementations/business/InvitationService.ts index 0ad03c6cc8..edce9fcd69 100644 --- a/packages/core/src/implementations/business/InvitationService.ts +++ b/packages/core/src/implementations/business/InvitationService.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { ILogUtils, ILogUtilsType } from "@snickerdoodlelabs/common-utils"; +import { IERC7529Utils, IERC7529UtilsType } from "@snickerdoodlelabs/erc7529"; import { IInsightPlatformRepository, IInsightPlatformRepositoryType, @@ -11,7 +12,6 @@ import { BigNumberString, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, ConsentError, ConsentFactoryContractError, DataPermissions, @@ -42,7 +42,6 @@ import { BigNumber, ethers } from "ethers"; import { inject, injectable } from "inversify"; import { errAsync, okAsync, ResultAsync } from "neverthrow"; import { ResultUtils } from "neverthrow-result-utils"; -import { getDomain, parse } from "tldts"; import { IInvitationService } from "@core/interfaces/business/index.js"; import { @@ -52,8 +51,6 @@ import { import { IConsentContractRepository, IConsentContractRepositoryType, - IDNSRepository, - IDNSRepositoryType, IInvitationRepository, IInvitationRepositoryType, ILinkedAccountRepository, @@ -80,7 +77,6 @@ export class InvitationService implements IInvitationService { protected consentRepo: IConsentContractRepository, @inject(IInsightPlatformRepositoryType) protected insightPlatformRepo: IInsightPlatformRepository, - @inject(IDNSRepositoryType) protected dnsRepository: IDNSRepository, @inject(IInvitationRepositoryType) protected invitationRepo: IInvitationRepository, @inject(IMetatransactionForwarderRepositoryType) @@ -92,6 +88,7 @@ export class InvitationService implements IInvitationService { @inject(ILogUtilsType) protected logUtils: ILogUtils, @inject(ILinkedAccountRepositoryType) protected accountRepo: ILinkedAccountRepository, + @inject(IERC7529UtilsType) protected erc7529Utils: IERC7529Utils, ) {} public checkInvitationStatus( @@ -100,7 +97,7 @@ export class InvitationService implements IInvitationService { EInvitationStatus, | PersistenceError | ConsentContractError - | ConsentContractRepositoryError + | ConsentFactoryContractError | UninitializedError | BlockchainProviderError | AjaxError @@ -113,8 +110,10 @@ export class InvitationService implements IInvitationService { // isAddressOptedIn() just checks for a balance- it does not require that the persistence // layer actually know about the token this.consentRepo.isAddressOptedIn(invitation.consentContractAddress), - this.getConsentCapacity(invitation.consentContractAddress), + this.consentRepo.getConsentCapacity(invitation.consentContractAddress), this.consentRepo.isOpenOptInDisabled(invitation.consentContractAddress), + this.consentRepo.getConsentContracts([invitation.consentContractAddress]), + this.configProvider.getConfig(), ]) .andThen( ([ @@ -123,6 +122,8 @@ export class InvitationService implements IInvitationService { optedInOnChain, consentCapacity, openOptInDisabled, + consentContracts, + config, ]) => { const rejected = rejectedConsentContracts.includes( invitation.consentContractAddress, @@ -135,6 +136,17 @@ export class InvitationService implements IInvitationService { ); }); + const consentContract = consentContracts.get( + invitation.consentContractAddress, + ); + if (consentContract == null) { + return errAsync( + new ConsentContractError( + `No consent contract found for ${invitation.consentContractAddress} from getConsentContracts()`, + ), + ); + } + // If we are opted in, that wins if (optedInOnChain) { // Check if know about the opt-in in the persistence @@ -225,40 +237,19 @@ export class InvitationService implements IInvitationService { // If invitation belongs any domain verify URLs if (invitation.domain) { const domain = invitation.domain; - // Not rejected or already in the cohort, we need to verify the invitation - return ResultUtils.combine([ - this.consentRepo.getInvitationUrls( - invitation.consentContractAddress, - ), - this.getConsentContractAddressesFromDNS(domain), - ]).map(([urls, consentContractAddresses]) => { - // Derive a list of domains from a list of URLs - - const domains = urls - .map((url) => { - if (url.includes("https://") || url.includes("http://")) { - return new URL(url).href; - } - return new URL(`http://${url}`).href; - }) - .map((href) => getDomain(href)); - - // We need to remove the subdomain so it would match with the saved domains in the blockchain - const domainStr = getDomain(domain); - // The contract must include the domain - if (!domains.includes(domainStr)) { - return EInvitationStatus.Invalid; - } - if ( - !consentContractAddresses.includes( - invitation.consentContractAddress, - ) - ) { - return EInvitationStatus.Invalid; - } - return EInvitationStatus.New; - }); + return this.erc7529Utils + .verifyContractForDomain( + consentContract, + domain, + config.controlChainId, + ) + .map((verified) => { + if (!verified) { + return EInvitationStatus.Invalid; + } + return EInvitationStatus.New; + }); } return okAsync(EInvitationStatus.New); }, @@ -283,13 +274,17 @@ export class InvitationService implements IInvitationService { | BlockchainProviderError | MinimalForwarderContractError | ConsentError + | ConsentContractError + | ConsentFactoryContractError | BlockchainCommonErrors > { // This will actually create a metatransaction, since the invitation is issued // to the data wallet address - return this.contextProvider - .getContext() - .andThen((context) => { + return ResultUtils.combine([ + this.contextProvider.getContext(), + this.configProvider.getConfig(), + ]) + .andThen(([context, config]) => { if ( context.dataWalletAddress == null || context.dataWalletKey == null @@ -310,20 +305,36 @@ export class InvitationService implements IInvitationService { ); } - let invitationCheck = okAsync(undefined); + let invitationCheck = okAsync< + void, + | ConsentContractError + | UninitializedError + | BlockchainProviderError + | AjaxError + | BlockchainCommonErrors + | ConsentFactoryContractError + | ConsentError + >(undefined); if (invitation.domain != null) { - invitationCheck = this.consentContractHasMatchingTXT( - invitation.consentContractAddress, - ).andThen((matchingTxt) => { - if (!matchingTxt) { - return errAsync( - new ConsentError( - `Invitation for contract ${invitation.consentContractAddress} does not have valid domain information. Check the DNS settings for a proper TXT record!`, - ), + invitationCheck = this.consentRepo + .getConsentContract(invitation.consentContractAddress) + .andThen((consentContract) => { + return this.erc7529Utils.verifyContractForDomain( + consentContract, + invitation.domain!, + config.controlChainId, ); - } - return okAsync(undefined); - }); + }) + .andThen((matchingTxt) => { + if (!matchingTxt) { + return errAsync( + new ConsentError( + `Invitation for contract ${invitation.consentContractAddress} does not have valid domain information. Check the DNS settings for a proper TXT record!`, + ), + ); + } + return okAsync(undefined); + }); } return invitationCheck @@ -467,7 +478,6 @@ export class InvitationService implements IInvitationService { | UninitializedError | PersistenceError | ConsentContractError - | ConsentContractRepositoryError | BlockchainProviderError | AjaxError | ConsentError @@ -628,7 +638,14 @@ export class InvitationService implements IInvitationService { | PersistenceError | BlockchainCommonErrors > { - return this.getConsentContractAddressesFromDNS(domain) + return this.configProvider + .getConfig() + .andThen((config) => { + return this.erc7529Utils.getContractsFromDomain( + domain, + config.controlChainId, + ); + }) .andThen((contractAddresses) => { return ResultUtils.combine( contractAddresses.map((consentContractAddress) => { @@ -721,14 +738,16 @@ export class InvitationService implements IInvitationService { | IPFSError | PersistenceError | BlockchainCommonErrors + | AjaxError > { return ResultUtils.combine([ - this.consentRepo.getInvitationUrls(consentContractAddress), + this.consentRepo.getDomains(consentContractAddress), this.consentRepo.getMetadataCID(consentContractAddress), this.getConsentCapacity(consentContractAddress), + this.configProvider.getConfig(), // @TODO - check later // this.invitationRepo.getRejectedInvitations(), - ]).andThen(([invitationUrls, ipfsCID, consentCapacity]) => { + ]).andThen(([domains, ipfsCID, consentCapacity, config]) => { // If there's no slots, there's no invites if (consentCapacity.availableOptInCount == 0) { return okAsync([]); @@ -755,10 +774,10 @@ export class InvitationService implements IInvitationService { ); } return ResultUtils.combine( - invitationUrls.map((invitationUrl) => { + domains.map((domain) => { return this.cryptoUtils.getTokenId().map((tokenId) => { return new PageInvitation( - invitationUrl, // getDomains() is actually misnamed, it returns URLs now + domain, // getDomains() is actually misnamed, it returns URLs now new Invitation( consentContractAddress, tokenId, @@ -928,53 +947,6 @@ export class InvitationService implements IInvitationService { return this.consentTokenUtils.getAgreementFlags(consentContractAddress); } - public getAvailableInvitationsCID(): ResultAsync< - Map, - | BlockchainProviderError - | UninitializedError - | ConsentFactoryContractError - | ConsentContractError - | PersistenceError - | BlockchainCommonErrors - > { - return this.getAvailableConsentContractAddresses().andThen( - (consentAddresses) => { - return ResultUtils.combine( - consentAddresses.map((consentAddress) => - this.consentContractHasMatchingTXT(consentAddress).map( - (hasMatchingTXT) => ({ - consentAddress, - hasMatchingTXT, - }), - ), - ), - ) - .andThen((results) => { - // since we are checking TXT records here - // we can confirm that all consent addresses are for public invitations - const validConsentContractAddresses = results - .filter((result) => result.hasMatchingTXT) - .map((validResults) => validResults.consentAddress); - return ResultUtils.combine( - validConsentContractAddresses.map((contractAddress) => - this.consentRepo - .getMetadataCID(contractAddress) - .map((ipfsCID) => ({ ipfsCID, contractAddress })), - ), - ); - }) - .map((addressesWithCID) => { - return new Map( - addressesWithCID.map((addressWithCID) => [ - addressWithCID.contractAddress, - addressWithCID.ipfsCID, - ]), - ); - }); - }, - ); - } - public setDefaultReceivingAddress( receivingAddress: AccountAddress | null, ): ResultAsync { @@ -1054,8 +1026,8 @@ export class InvitationService implements IInvitationService { return okAsync(linkedAccount.sourceAccountAddress); } - // This check removes the receiving address from the contract and replaces - // it with the default + // This check removes the receiving address from the contract and replaces + // it with the default return this.accountRepo .setReceivingAddress(contractAddress, null) .andThen(() => { @@ -1101,38 +1073,6 @@ export class InvitationService implements IInvitationService { }); } - protected consentContractHasMatchingTXT( - consentContractAddress: EVMContractAddress, - ): ResultAsync { - return this.consentRepo - .getInvitationUrls(consentContractAddress) - .andThen((urls) => { - return ResultUtils.combine( - urls.map((url) => { - const urlInfo = parse(url); - return this.getConsentContractAddressesFromDNS( - DomainName(`snickerdoodle-protocol.${urlInfo.domain}`), - ).orElse(() => { - return okAsync([] as EVMContractAddress[]); - }); - }), - ); - }) - .map((contractAddressesArr) => { - let match = false; - for (const contractAddresses of contractAddressesArr) { - if (contractAddresses.includes(consentContractAddress)) { - match = true; - break; - } - } - return match; - }) - .orElse((e) => { - return okAsync(false); - }); - } - protected getAvailableConsentContractAddresses(): ResultAsync< EVMContractAddress[], | BlockchainProviderError @@ -1176,26 +1116,6 @@ export class InvitationService implements IInvitationService { }); } - protected getConsentContractAddressesFromDNS( - domain: DomainName, - ): ResultAsync { - return this.dnsRepository.fetchTXTRecords(domain).map((txtRecords) => { - // to avoid TXT records which were not shaped as JSON - try { - return txtRecords - .map((txtRecord) => { - const records = JSON.parse(txtRecord) - .split(",") - .map((r) => r.trim()); - return records.map((record) => EVMContractAddress(record)); - }) - .flat(); - } catch { - return []; - } - }); - } - private getLinkedAccountForReceivingAddress( linkedAccounts: LinkedAccount[], receivingAddress: AccountAddress | null, diff --git a/packages/core/src/implementations/data/BrowsingDataRepository.ts b/packages/core/src/implementations/data/BrowsingDataRepository.ts index 052d7d28ec..fee47a0ba8 100644 --- a/packages/core/src/implementations/data/BrowsingDataRepository.ts +++ b/packages/core/src/implementations/data/BrowsingDataRepository.ts @@ -1,3 +1,4 @@ +import { ITimeUtilsType, ITimeUtils } from "@snickerdoodlelabs/common-utils"; import { SiteVisit, PersistenceError, @@ -9,7 +10,6 @@ import { UnixTimestamp, SiteVisitsMap, SiteVisitsData, - ISO8601DateString, } from "@snickerdoodlelabs/objects"; import { inject, injectable } from "inversify"; import { ResultAsync } from "neverthrow"; @@ -21,7 +21,6 @@ import { IDataWalletPersistence, IDataWalletPersistenceType, } from "@core/interfaces/data/index.js"; -import { ITimeUtilsType, ITimeUtils } from "@snickerdoodlelabs/common-utils"; @injectable() export class BrowsingDataRepository implements IBrowsingDataRepository { @@ -94,9 +93,8 @@ export class BrowsingDataRepository implements IBrowsingDataRepository { this.timeUtils.convertTimestampToISOString(visit.endTime) > siteVisitData.lastReportedTime ) { - siteVisitData.lastReportedTime = this.timeUtils.convertTimestampToISOString( - visit.endTime, - ); + siteVisitData.lastReportedTime = + this.timeUtils.convertTimestampToISOString(visit.endTime); } } else { visitsMap.set( @@ -114,7 +112,6 @@ export class BrowsingDataRepository implements IBrowsingDataRepository { return visitsMap; } - protected calculateAverageScreenTime(visitsMap: SiteVisitsMap): void { for (const [_, siteVisitData] of visitsMap) { siteVisitData.averageScreenTime = diff --git a/packages/core/src/implementations/data/ConsentContractRepository.ts b/packages/core/src/implementations/data/ConsentContractRepository.ts index 1bc5ab9f9a..8b2b179c45 100644 --- a/packages/core/src/implementations/data/ConsentContractRepository.ts +++ b/packages/core/src/implementations/data/ConsentContractRepository.ts @@ -4,7 +4,6 @@ import { AjaxError, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, ConsentFactoryContractError, ConsentToken, DataPermissions, @@ -12,15 +11,14 @@ import { EVMContractAddress, HexString, IpfsCID, - OptInInfo, Signature, TokenId, TokenUri, IConsentCapacity, UninitializedError, - URLString, BlockNumber, BlockchainCommonErrors, + DomainName, } from "@snickerdoodlelabs/objects"; import { inject, injectable } from "inversify"; import { errAsync, okAsync, ResultAsync } from "neverthrow"; @@ -53,24 +51,20 @@ export class ConsentContractRepository implements IConsentContractRepository { BlockNumber | null >(); - public getInvitationUrls( + public getDomains( consentContractAddress: EVMContractAddress, ): ResultAsync< - URLString[], + DomainName[], | BlockchainProviderError | UninitializedError | ConsentContractError | BlockchainCommonErrors > { - return this.getConsentContract(consentContractAddress) - .andThen((contract) => { + return this.getConsentContract(consentContractAddress).andThen( + (contract) => { return contract.getDomains(); - }) - .map((domains) => { - return domains.map((domain) => { - return URLString(domain); - }); - }); + }, + ); } public getConsentCapacity( @@ -153,7 +147,6 @@ export class ConsentContractRepository implements IConsentContractRepository { ): ResultAsync< boolean, | ConsentContractError - | ConsentContractRepositoryError | UninitializedError | BlockchainProviderError | AjaxError @@ -406,7 +399,7 @@ export class ConsentContractRepository implements IConsentContractRepository { }); } - protected getConsentContract( + public getConsentContract( consentContractAddress: EVMContractAddress, ): ResultAsync< IConsentContract, diff --git a/packages/core/src/implementations/data/DNSRepository.ts b/packages/core/src/implementations/data/DNSRepository.ts deleted file mode 100644 index d459a80f04..0000000000 --- a/packages/core/src/implementations/data/DNSRepository.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - IAxiosAjaxUtils, - IAxiosAjaxUtilsType, -} from "@snickerdoodlelabs/common-utils"; -import { AjaxError, DomainName } from "@snickerdoodlelabs/objects"; -import { inject, injectable } from "inversify"; -import { errAsync, okAsync, ResultAsync } from "neverthrow"; -import { urlJoinP } from "url-join-ts"; - -import { IDNSRepository } from "@core/interfaces/data/IDNSRepository.js"; -import { - IConfigProviderType, - IConfigProvider, -} from "@core/interfaces/utilities/index.js"; - -@injectable() -export class DNSRepository implements IDNSRepository { - constructor( - @inject(IAxiosAjaxUtilsType) protected ajaxUtil: IAxiosAjaxUtils, - @inject(IConfigProviderType) protected configProvider: IConfigProvider, - ) {} - - public fetchTXTRecords(domain: DomainName): ResultAsync { - return this.configProvider - .getConfig() - .andThen((config) => { - const url = new URL( - urlJoinP(config.dnsServerAddress, [], { - name: domain, - type: "TXT", - }), - ); - return this.ajaxUtil.get(url, { - headers: { Accept: "application/dns-json" }, - }); - }) - .map((response) => { - return ( - response?.Answer?.map?.((txtRecord) => { - return txtRecord.data; - }) ?? [] - ); - }) - .orElse((error) => { - console.log("error from fetchTXTRecords", error); - return errAsync(error); - }); - } - - // // Not sure about using something like this - // formatTxtRecords( - // txtRecords: ITXTRecords[], - // ): ResultAsync { - // // txtRecords = [{data:'0x999'},{data:'0x999,0x1111'},{data:'0x999'},{data:'01x999'}]; - // // return = ["0x999", "0x999", "0x1111", "0x999"] - // let formatedContractAddresses: string[] = []; - // txtRecords - // .map(function (txt) { - // return txt["data"]; - // }) - // .filter((record) => { - // return record?.startsWith("0x"); - // }) - // .map((contract) => { - // const splittedArray = contract?.split(","); - // formatedContractAddresses = [ - // ...formatedContractAddresses, - // ...splittedArray, - // ]; - // }); - // return okAsync(formatedContractAddresses); - // } -} -interface IGetTxtRecordsResponse { - Answer: ITXTRecords[]; -} -interface ITXTRecords { - name: string; - type: number; - TTL: number; - data: string; -} diff --git a/packages/core/src/implementations/data/index.ts b/packages/core/src/implementations/data/index.ts index 39506eac58..6c6d0cf267 100644 --- a/packages/core/src/implementations/data/index.ts +++ b/packages/core/src/implementations/data/index.ts @@ -4,7 +4,6 @@ export * from "@core/implementations/data/AuthenticatedStorageRepository.js"; export * from "@core/implementations/data/BrowsingDataRepository.js"; export * from "@core/implementations/data/CoinGeckoTokenPriceRepository.js"; export * from "@core/implementations/data/ConsentContractRepository.js"; -export * from "@core/implementations/data/DNSRepository.js"; export * from "@core/implementations/data/DemographicDataRepository.js"; export * from "@core/implementations/data/DiscordRepository.js"; export * from "@core/implementations/data/DomainCredentialRepository.js"; diff --git a/packages/core/src/implementations/utilities/ConfigProvider.ts b/packages/core/src/implementations/utilities/ConfigProvider.ts index d917bb8f30..dc18caf1e3 100644 --- a/packages/core/src/implementations/utilities/ConfigProvider.ts +++ b/packages/core/src/implementations/utilities/ConfigProvider.ts @@ -140,7 +140,7 @@ export class ConfigProvider secondaryInfuraKey: null, // secondaryInfuraKey secondaryRPCProviderURL: null, }, - URLString("https://cloudflare-dns.com/dns-query"), // dnsServerAddress + URLString("https://cloudflare-dns.com/dns-query"), // dnsProviderBaseUrl ECurrencyCode.USD, // quoteCurrency 100, // etherscan tx batch size 4000, // polling interval for consent contracts on control chain @@ -330,8 +330,8 @@ export class ConfigProvider this.config.apiKeys.blockvisionKey = overrides.blockvisionKey ?? this.config.apiKeys.blockvisionKey; - this.config.dnsServerAddress = - overrides.dnsServerAddress ?? this.config.dnsServerAddress; + this.config.dnsProviderBaseUrl = + overrides.dnsProviderBaseUrl ?? this.config.dnsProviderBaseUrl; this.config.dataWalletBackupIntervalMS = overrides.dataWalletBackupIntervalMS ?? this.config.dataWalletBackupIntervalMS; diff --git a/packages/core/src/interfaces/business/IInvitationService.ts b/packages/core/src/interfaces/business/IInvitationService.ts index 36c599d2a8..7520102a4f 100644 --- a/packages/core/src/interfaces/business/IInvitationService.ts +++ b/packages/core/src/interfaces/business/IInvitationService.ts @@ -4,7 +4,6 @@ import { Invitation, DataPermissions, ConsentContractError, - ConsentContractRepositoryError, ConsentError, DomainName, EInvitationStatus, @@ -34,7 +33,7 @@ export interface IInvitationService { EInvitationStatus, | PersistenceError | ConsentContractError - | ConsentContractRepositoryError + | ConsentFactoryContractError | UninitializedError | BlockchainProviderError | AjaxError @@ -52,6 +51,8 @@ export interface IInvitationService { | AjaxError | MinimalForwarderContractError | ConsentError + | ConsentContractError + | ConsentFactoryContractError | BlockchainCommonErrors >; @@ -63,7 +64,6 @@ export interface IInvitationService { | UninitializedError | PersistenceError | ConsentContractError - | ConsentContractRepositoryError | BlockchainProviderError | AjaxError | ConsentError @@ -169,16 +169,6 @@ export interface IInvitationService { | AjaxError | BlockchainCommonErrors >; - - getAvailableInvitationsCID(): ResultAsync< - Map, - | BlockchainProviderError - | UninitializedError - | ConsentFactoryContractError - | ConsentContractError - | PersistenceError - | BlockchainCommonErrors - >; } export const IInvitationServiceType = Symbol.for("IInvitationService"); diff --git a/packages/core/src/interfaces/data/IConsentContractRepository.ts b/packages/core/src/interfaces/data/IConsentContractRepository.ts index 1e01e7bda0..e69a457e97 100644 --- a/packages/core/src/interfaces/data/IConsentContractRepository.ts +++ b/packages/core/src/interfaces/data/IConsentContractRepository.ts @@ -7,30 +7,29 @@ import { EVMAccountAddress, ConsentContractError, AjaxError, - ConsentContractRepositoryError, ConsentFactoryContractError, HexString, TokenId, DataPermissions, - URLString, IpfsCID, Signature, TokenUri, IConsentCapacity, BlockNumber, BlockchainCommonErrors, + DomainName, } from "@snickerdoodlelabs/objects"; import { ResultAsync } from "neverthrow"; export interface IConsentContractRepository { /** - * Returns all the URLs that are configured in the contract. + * Returns all the domains that are configured in the contract. * @param consentContractAddress */ - getInvitationUrls( + getDomains( consentContractAddress: EVMContractAddress, ): ResultAsync< - URLString[], + DomainName[], | BlockchainProviderError | UninitializedError | ConsentContractError @@ -82,7 +81,6 @@ export interface IConsentContractRepository { ): ResultAsync< boolean, | ConsentContractError - | ConsentContractRepositoryError | UninitializedError | BlockchainProviderError | AjaxError @@ -106,6 +104,13 @@ export interface IConsentContractRepository { BlockchainProviderError | UninitializedError | ConsentFactoryContractError >; + getConsentContract( + consentContractAddresses: EVMContractAddress, + ): ResultAsync< + IConsentContract, + BlockchainProviderError | UninitializedError | ConsentFactoryContractError + >; + getDeployedConsentContractAddresses(): ResultAsync< EVMContractAddress[], | BlockchainProviderError diff --git a/packages/core/src/interfaces/data/IDNSRepository.ts b/packages/core/src/interfaces/data/IDNSRepository.ts deleted file mode 100644 index b98ed04f82..0000000000 --- a/packages/core/src/interfaces/data/IDNSRepository.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AjaxError, DomainName } from "@snickerdoodlelabs/objects"; -import { ResultAsync } from "neverthrow"; - -export interface IDNSRepository { - fetchTXTRecords(domain: DomainName): ResultAsync; -} -export const IDNSRepositoryType = Symbol.for("IDNSRepository"); diff --git a/packages/core/src/interfaces/data/index.ts b/packages/core/src/interfaces/data/index.ts index fd1794bc47..41188647f7 100644 --- a/packages/core/src/interfaces/data/index.ts +++ b/packages/core/src/interfaces/data/index.ts @@ -3,7 +3,6 @@ export * from "@core/interfaces/data/IAdDataRepository.js"; export * from "@core/interfaces/data/IAuthenticatedStorageRepository.js"; export * from "@core/interfaces/data/IBrowsingDataRepository.js"; export * from "@core/interfaces/data/IConsentContractRepository.js"; -export * from "@core/interfaces/data/IDNSRepository.js"; export * from "@core/interfaces/data/IDemographicDataRepository.js"; export * from "@core/interfaces/data/IDiscordRepository.js"; export * from "@core/interfaces/data/IDomainCredentialRepository.js"; diff --git a/packages/core/src/interfaces/objects/CoreConfig.ts b/packages/core/src/interfaces/objects/CoreConfig.ts index 6866d89ed9..a8757c3cde 100644 --- a/packages/core/src/interfaces/objects/CoreConfig.ts +++ b/packages/core/src/interfaces/objects/CoreConfig.ts @@ -1,3 +1,4 @@ +import { ERC7529Config } from "@snickerdoodlelabs/erc7529"; import { IIndexerConfig } from "@snickerdoodlelabs/indexers"; import { ControlChainInformation, @@ -14,7 +15,9 @@ import { IPersistenceConfig } from "@snickerdoodlelabs/persistence"; import { MetatransactionGasAmounts } from "@core/interfaces/objects/MetatransactionGasAmounts.js"; -export class CoreConfig implements IIndexerConfig, IPersistenceConfig { +export class CoreConfig + implements IIndexerConfig, IPersistenceConfig, ERC7529Config +{ public constructor( public controlChainId: EChain, public controlChainInformation: ControlChainInformation, @@ -32,7 +35,7 @@ export class CoreConfig implements IIndexerConfig, IPersistenceConfig { public dataWalletBackupIntervalMS: number, public backupChunkSizeTarget: number, public apiKeys: IApiKeys, - public dnsServerAddress: URLString, + public dnsProviderBaseUrl: URLString, public quoteCurrency: ECurrencyCode, public etherscanTransactionsBatchSize: number, public requestForDataCheckingFrequency: number, @@ -49,6 +52,6 @@ export class CoreConfig implements IIndexerConfig, IPersistenceConfig { public devChainProviderURL: ProviderUrl | null, public maxStatsRetentionSeconds: number, public passwordLanguageCode: LanguageCode, - public queryPerformanceMetricsLimit : number + public queryPerformanceMetricsLimit: number, ) {} } diff --git a/packages/core/src/interfaces/utilities/IConfigProvider.ts b/packages/core/src/interfaces/utilities/IConfigProvider.ts index 454c6a21ea..b2a98ce4e8 100644 --- a/packages/core/src/interfaces/utilities/IConfigProvider.ts +++ b/packages/core/src/interfaces/utilities/IConfigProvider.ts @@ -1,9 +1,10 @@ +import { IERC7529ConfigProvider } from "@snickerdoodlelabs/erc7529"; import { IConfigOverrides } from "@snickerdoodlelabs/objects"; import { ResultAsync } from "neverthrow"; import { CoreConfig } from "@core/interfaces/objects/index.js"; -export interface IConfigProvider { +export interface IConfigProvider extends IERC7529ConfigProvider { getConfig(): ResultAsync; setConfigOverrides(overrides: IConfigOverrides): void; } diff --git a/packages/core/test/unit/business/InvitationService.test.ts b/packages/core/test/unit/business/InvitationService.test.ts index 3b071aba8a..ab0ad806c3 100644 --- a/packages/core/test/unit/business/InvitationService.test.ts +++ b/packages/core/test/unit/business/InvitationService.test.ts @@ -1,5 +1,6 @@ import "reflect-metadata"; import { ILogUtils } from "@snickerdoodlelabs/common-utils"; +import { IERC7529Utils } from "@snickerdoodlelabs/erc7529"; import { IInsightPlatformRepository } from "@snickerdoodlelabs/insight-platform-api"; import { ICryptoUtils } from "@snickerdoodlelabs/node-utils"; import { @@ -28,7 +29,6 @@ import { IInvitationService } from "@core/interfaces/business/index.js"; import { IConsentTokenUtils } from "@core/interfaces/business/utilities/index.js"; import { IConsentContractRepository, - IDNSRepository, IInvitationRepository, ILinkedAccountRepository, IMetatransactionForwarderRepository, @@ -40,6 +40,7 @@ import { defaultInsightPlatformBaseUrl, externalAccountAddress1, dataWalletKey, + controlChainId, } from "@core-tests/mock/mocks/commonValues.js"; import { ConfigProviderMock, @@ -56,8 +57,6 @@ const optOutSignature = Signature("OptOutSignature"); const optInPrivateKey = EVMPrivateKey("optInPrivateKey"); const optInAccountAddress = EVMAccountAddress("optInAccountAddress"); const domain = DomainName("phoebe.com"); -const url1 = URLString("phoebe.com/cute"); -const url2 = URLString("phoebe.com/loud"); const ipfsCID = IpfsCID("ipfscid"); const tokenId1 = TokenId(BigInt(13)); const tokenId2 = TokenId(BigInt(69)); @@ -96,7 +95,6 @@ class InvitationServiceMocks { public consentTokenUtils: IConsentTokenUtils; public consentRepo: IConsentContractRepository; public insightPlatformRepo: IInsightPlatformRepository; - public dnsRepository: IDNSRepository; public invitationRepo: IInvitationRepository; public forwarderRepo: IMetatransactionForwarderRepository; public dataWalletUtils: IDataWalletUtils; @@ -105,12 +103,12 @@ class InvitationServiceMocks { public configProvider: ConfigProviderMock; public logUtils: ILogUtils; public accountRepo: ILinkedAccountRepository; + public erc7529Utils: IERC7529Utils; public constructor() { this.consentTokenUtils = td.object(); this.consentRepo = td.object(); this.insightPlatformRepo = td.object(); - this.dnsRepository = td.object(); this.invitationRepo = td.object(); this.forwarderRepo = td.object(); this.contextProvider = new ContextProviderMock(); @@ -119,6 +117,7 @@ class InvitationServiceMocks { this.configProvider = new ConfigProviderMock(); this.logUtils = td.object(); this.accountRepo = td.object(); + this.erc7529Utils = td.object(); td.when( this.insightPlatformRepo.executeMetatransaction( @@ -134,17 +133,17 @@ class InvitationServiceMocks { ), ).thenReturn(okAsync(undefined)); - td.when(this.dnsRepository.fetchTXTRecords(domain)).thenReturn( - okAsync([`"${consentContractAddress1}"`]), - ); + td.when( + this.erc7529Utils.getContractsFromDomain(domain, controlChainId), + ).thenReturn(okAsync([consentContractAddress1])); // ConsentRepo --------------------------------------------------------------- - td.when( - this.consentRepo.getInvitationUrls(consentContractAddress1), - ).thenReturn(okAsync([url1, url2])); td.when( this.consentRepo.getMetadataCID(consentContractAddress1), ).thenReturn(okAsync(ipfsCID)); + td.when(this.consentRepo.getDomains(consentContractAddress1)).thenReturn( + okAsync([domain]), + ); td.when( this.consentRepo.getConsentCapacity(consentContractAddress1), ).thenReturn(okAsync({ availableOptInCount: 10, maxCapacity: 10 })); @@ -239,7 +238,6 @@ class InvitationServiceMocks { this.consentTokenUtils, this.consentRepo, this.insightPlatformRepo, - this.dnsRepository, this.invitationRepo, this.forwarderRepo, this.dataWalletUtils, @@ -248,6 +246,7 @@ class InvitationServiceMocks { this.configProvider, this.logUtils, this.accountRepo, + this.erc7529Utils, ); } } @@ -265,9 +264,9 @@ describe("InvitationService tests", () => { expect(result).toBeDefined(); expect(result.isErr()).toBeFalsy(); const pageInvitations = result._unsafeUnwrap(); - expect(pageInvitations.length).toBe(2); + expect(pageInvitations.length).toBe(1); - expect(pageInvitations[0].url).toBe(url1); + expect(pageInvitations[0].url).toBe(domain); expect(pageInvitations[0].invitationMetadata).toBe(invitationMetadata); expect(pageInvitations[0].invitation.businessSignature).toBeNull(); expect(pageInvitations[0].invitation.consentContractAddress).toBe( @@ -276,14 +275,14 @@ describe("InvitationService tests", () => { expect(pageInvitations[0].invitation.domain).toBe(domain); expect(pageInvitations[0].invitation.tokenId).toBe(tokenId1); - expect(pageInvitations[1].url).toBe(url2); - expect(pageInvitations[1].invitationMetadata).toBe(invitationMetadata); - expect(pageInvitations[1].invitation.businessSignature).toBeNull(); - expect(pageInvitations[1].invitation.consentContractAddress).toBe( - consentContractAddress1, - ); - expect(pageInvitations[1].invitation.domain).toBe(domain); - expect(pageInvitations[1].invitation.tokenId).toBe(tokenId2); + // expect(pageInvitations[1].url).toBe(url2); + // expect(pageInvitations[1].invitationMetadata).toBe(invitationMetadata); + // expect(pageInvitations[1].invitation.businessSignature).toBeNull(); + // expect(pageInvitations[1].invitation.consentContractAddress).toBe( + // consentContractAddress1, + // ); + // expect(pageInvitations[1].invitation.domain).toBe(domain); + // expect(pageInvitations[1].invitation.tokenId).toBe(tokenId2); }); test("getInvitationsByDomain no available slots", async () => { diff --git a/packages/core/test/unit/utilities/DataWalletUtils.test.ts b/packages/core/test/unit/utilities/DataWalletUtils.test.ts index efe79a9fa3..f2e4f321cd 100644 --- a/packages/core/test/unit/utilities/DataWalletUtils.test.ts +++ b/packages/core/test/unit/utilities/DataWalletUtils.test.ts @@ -89,8 +89,8 @@ describe("DataWalletUtils tests", () => { expect(result2.isErr()).toBeFalsy(); const newAccount1 = result1._unsafeUnwrap(); const newAccount2 = result2._unsafeUnwrap(); - expect(newAccount1).toBe("0x417643fBD5D41dB241d29C684Ba9bf46499FA21e"); - expect(newAccount2).toBe("0x67b7a6dD90a0d0eE405646771141a07F451B1256"); + expect(newAccount1).toBe("0x417643fbd5d41db241d29c684ba9bf46499fa21e"); + expect(newAccount2).toBe("0x67b7a6dd90a0d0ee405646771141a07f451b1256"); }); test("deriveEncryptionKeyFromPassword works", async () => { @@ -136,13 +136,13 @@ describe("DataWalletUtils tests", () => { "05312b78360d124ad808575b6f2e96d9c611b19ae58f61eb5b6981319f336eef", ); expect(eoa1.accountAddress).toBe( - "0x8eD53fb062a2285CB9726c4961a6BBDC6aA6FCA9", + "0x8ed53fb062a2285cb9726c4961a6bbdc6aa6fca9", ); expect(eoa2.privateKey).toBe( "f3ae4787d9545528065d0a63c82159581ac8ef073c5aba177a9c82299a586511", ); expect(eoa2.accountAddress).toBe( - "0xb717C7DC8a1576c77C05703885584c23f2d45440", + "0xb717c7dc8a1576c77c05703885584c23f2d45440", ); }); }); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index fc372a943e..697dd7cdaf 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -20,6 +20,9 @@ { "path": "../contracts-sdk" }, + { + "path": "../erc7529" + }, { "path": "../indexers" }, diff --git a/packages/docker/Dockerfile b/packages/docker/Dockerfile index a1ab5bde3d..43958a8aed 100644 --- a/packages/docker/Dockerfile +++ b/packages/docker/Dockerfile @@ -12,6 +12,7 @@ COPY packages/common-utils/package.json /build/packages/common-utils/package.jso COPY packages/contracts/package.json /build/packages/contracts/package.json COPY packages/contracts-sdk/package.json /build/packages/contracts-sdk/package.json COPY packages/core/package.json /build/packages/core/package.json +COPY packages/erc7529/package.json /build/packages/erc7529/package.json COPY packages/extension-onboarding/package.json /build/packages/extension-onboarding/package.json COPY packages/iframe/package.json /build/packages/iframe/package.json COPY packages/indexers/package.json /build/packages/indexers/package.json diff --git a/packages/erc7529/README.md b/packages/erc7529/README.md index 047f073910..f35a373e28 100644 --- a/packages/erc7529/README.md +++ b/packages/erc7529/README.md @@ -1,10 +1,10 @@ ![Snickerdoodle Protocol](https://github.com/SnickerdoodleLabs/Snickerdoodle-Theme-Light/blob/main/snickerdoodle_horizontal_notab.png?raw=true) -# EIP-7529 +# ERC-7529 -The introduction of DNS-over-HTTPS (DoH) in [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) has enabled tamper-resistant client-side queries of DNS records directly from the browser context. [ERC-7529](./eip-7529.md) describes a simple standard leveraging DoH to fetch TXT records which are used for discovering and verifying the association of a smart contract with a common DNS domain. +The introduction of DNS-over-HTTPS (DoH) in [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) has enabled tamper-resistant client-side queries of DNS records directly from the browser context. [ERC-7529](./erc-7529.md) describes a simple standard leveraging DoH to fetch TXT records which are used for discovering and verifying the association of a smart contract with a common DNS domain. -This package is a library for interacting with and verifying EIP-7529 compliant contracts. It manages DoH as well as smart contract manipulation and interaction via the [Ethers](https://github.com/ethers-io/ethers.js) library. It should work on any [EVM-compatible](https://ethereum.org/en/developers/docs/evm) chain. +This package is a library for interacting with and verifying ERC-7529 compliant contracts. It manages DoH as well as smart contract manipulation and interaction via the [Ethers](https://github.com/ethers-io/ethers.js) library. It should work on any [EVM-compatible](https://ethereum.org/en/developers/docs/evm) chain. ## Motivation diff --git a/packages/erc7529/src/ERC7529Utils.ts b/packages/erc7529/src/ERC7529Utils.ts index c3493d2554..a11ca68783 100644 --- a/packages/erc7529/src/ERC7529Utils.ts +++ b/packages/erc7529/src/ERC7529Utils.ts @@ -14,7 +14,7 @@ import { } from "@snickerdoodlelabs/objects"; import { ethers } from "ethers"; import { inject, injectable } from "inversify"; -import { errAsync, okAsync, ResultAsync } from "neverthrow"; +import { ResultAsync } from "neverthrow"; import { ResultUtils } from "neverthrow-result-utils"; import { urlJoinP } from "url-join-ts"; @@ -101,29 +101,59 @@ export class ERC7529Utils implements IERC7529Utils { type: "TXT", }), ); - return this.ajaxUtils.get(url, { - headers: { Accept: "application/dns-json" }, - }); + // TODO: Remove this after we've fully migrated + const snickerdoodleUrl = new URL( + urlJoinP(config.dnsProviderBaseUrl, [], { + name: `snickerdoodle-protocol.${domain}`, + type: "TXT", + }), + ); + return ResultUtils.combine([ + this.ajaxUtils.get(url, { + headers: { Accept: "application/dns-json" }, + }), + this.ajaxUtils.get(snickerdoodleUrl, { + headers: { Accept: "application/dns-json" }, + }), + ]); }) - .map((response) => { - if (response.Answer == null) { - return []; + .map(([response, snickerdoodleResponse]) => { + const records = new Array(); + + if (response.Answer != null) { + response.Answer.reduce((records, txtRecord) => { + // txtRecord.Data comes back as a string- WITH QUOTES, '"string"'. + // We need to remove the quotes + try { + const stringOnly = JSON.parse(txtRecord.data); + records.push(stringOnly); + } catch (err) { + this.logUtils.warning( + `Error parsing TXT record. Value: ${txtRecord.data}`, + err, + ); + } + return records; + }, records); } - return response.Answer.reduce((records, txtRecord) => { - // txtRecord.Data comes back as a string- WITH QUOTES, '"string"'. - // We need to remove the quotes - try { - const stringOnly = JSON.parse(txtRecord.data); - records.push(stringOnly); - } catch (err) { - this.logUtils.warning( - `Error parsing TXT record. Value: ${txtRecord.data}`, - err, - ); - } - return records; - }, new Array()); + if (snickerdoodleResponse.Answer != null) { + snickerdoodleResponse.Answer.reduce((records, txtRecord) => { + // txtRecord.Data comes back as a string- WITH QUOTES, '"string"'. + // We need to remove the quotes + try { + const stringOnly = JSON.parse(txtRecord.data); + records.push(stringOnly); + } catch (err) { + this.logUtils.warning( + `Error parsing TXT record. Value: ${txtRecord.data}`, + err, + ); + } + return records; + }, records); + } + return records; }); } } diff --git a/packages/erc7529/src/IERC7529Utils.ts b/packages/erc7529/src/IERC7529Utils.ts index 3a278f6b15..0ce0718f62 100644 --- a/packages/erc7529/src/IERC7529Utils.ts +++ b/packages/erc7529/src/IERC7529Utils.ts @@ -4,6 +4,7 @@ import { BlockchainCommonErrors, ChainId, DomainName, + EChain, EVMContractAddress, } from "@snickerdoodlelabs/objects"; import { ResultAsync } from "neverthrow"; @@ -12,11 +13,13 @@ export interface IERC7529Utils { verifyContractForDomain( contract: IERC7529Contract, domain: DomainName, - chainId: ChainId, + chainId: ChainId | EChain, ): ResultAsync; getContractsFromDomain( domain: DomainName, - chainId: ChainId, + chainId: ChainId | EChain, ): ResultAsync; } + +export const IERC7529UtilsType = Symbol.for("IERC7529Utils"); diff --git a/packages/iframe/src/implementations/api/CoreListener.ts b/packages/iframe/src/implementations/api/CoreListener.ts index 82132a50f5..39b3ba7ae2 100644 --- a/packages/iframe/src/implementations/api/CoreListener.ts +++ b/packages/iframe/src/implementations/api/CoreListener.ts @@ -55,10 +55,8 @@ import { IStorageUtils, } from "@snickerdoodlelabs/utils"; import { injectable, inject } from "inversify"; -import { ResultAsync, okAsync } from "neverthrow"; -import { ResultUtils } from "neverthrow-result-utils"; +import { okAsync } from "neverthrow"; import Postmate from "postmate"; -import { parse } from "tldts"; import { ICoreListener } from "@core-iframe/interfaces/api/index"; import { @@ -432,18 +430,6 @@ export class CoreListener extends ChildProxy implements ICoreListener { }, data.callId); }, - getAvailableInvitationsCID: ( - data: IIFrameCallData>, - ) => { - this.returnForModel(() => { - return this.coreProvider.getCore().andThen((core) => { - return core.invitation.getAvailableInvitationsCID( - this.sourceDomain, - ); - }); - }, data.callId); - }, - getConsentContractURLs: ( data: IIFrameCallData<{ contractAddress: EVMContractAddress; diff --git a/packages/mobile/src/services/interfaces/business/IInvitationService.ts b/packages/mobile/src/services/interfaces/business/IInvitationService.ts index bdbff2042b..706a0d1c47 100644 --- a/packages/mobile/src/services/interfaces/business/IInvitationService.ts +++ b/packages/mobile/src/services/interfaces/business/IInvitationService.ts @@ -4,7 +4,6 @@ import { Invitation, DataPermissions, ConsentContractError, - ConsentContractRepositoryError, ConsentError, DomainName, EInvitationStatus, @@ -31,7 +30,6 @@ export interface IInvitationService { EInvitationStatus, | PersistenceError | ConsentContractError - | ConsentContractRepositoryError | UninitializedError | BlockchainProviderError | AjaxError @@ -57,7 +55,6 @@ export interface IInvitationService { | UninitializedError | PersistenceError | ConsentContractError - | ConsentContractRepositoryError | BlockchainProviderError | AjaxError | ConsentError @@ -137,15 +134,6 @@ export interface IInvitationService { | PersistenceError | ConsentFactoryContractError >; - - getAvailableInvitationsCID(): ResultAsync< - Map, - | BlockchainProviderError - | UninitializedError - | ConsentFactoryContractError - | ConsentContractError - | PersistenceError - >; } export const IInvitationServiceType = Symbol.for("IInvitationService"); diff --git a/packages/objects/src/businessObjects/PageInvitation.ts b/packages/objects/src/businessObjects/PageInvitation.ts index 029d3a9653..7051063a8e 100644 --- a/packages/objects/src/businessObjects/PageInvitation.ts +++ b/packages/objects/src/businessObjects/PageInvitation.ts @@ -1,11 +1,11 @@ import { Invitation } from "@objects/businessObjects/Invitation.js"; import { IOldUserAgreement } from "@objects/interfaces/IOldUserAgreement.js"; import { IUserAgreement } from "@objects/interfaces/IUserAgreement.js"; -import { URLString } from "@objects/primitives/index.js"; +import { DomainName } from "@objects/primitives/index.js"; export class PageInvitation { public constructor( - public url: URLString, + public url: DomainName, public invitation: Invitation, public invitationMetadata: IOldUserAgreement | IUserAgreement, ) {} diff --git a/packages/objects/src/errors/ConsentContractRepositoryError.ts b/packages/objects/src/errors/ConsentContractRepositoryError.ts deleted file mode 100644 index 4c1a9c1a39..0000000000 --- a/packages/objects/src/errors/ConsentContractRepositoryError.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { BaseError } from "@objects/errors/BaseError.js"; -import errorCodes from "@objects/errors/errorCodes.js"; - -export class ConsentContractRepositoryError extends BaseError { - protected errorCode: string = errorCodes[ConsentContractRepositoryError.name]; - constructor(message: string, public src?: unknown) { - super( - message, - 500, - errorCodes[ConsentContractRepositoryError.name], - src, - false, - ); - } -} diff --git a/packages/objects/src/errors/errorCodes.ts b/packages/objects/src/errors/errorCodes.ts index 50f4462ee8..183fa58637 100644 --- a/packages/objects/src/errors/errorCodes.ts +++ b/packages/objects/src/errors/errorCodes.ts @@ -4,7 +4,6 @@ const errorCodes = { BackupError: "ERR_BACKUP", BlockchainProviderError: "ERR_BLOCKCHAIN_PROVIDER", CloudStorageError: "ERR_CLOUD_STORAGE", - ConsentContractRepositoryError: "CONSENT_CONTRACT_REPOSITORY_ERROR", ConsentContractError: "CONSENT_CONTRACT_ERROR", ConsentError: "ERR_NO_CONSENT_GIVEN", ConsentFactoryContractError: "CONSENT_FACTORY_CONTRACT_ERROR", diff --git a/packages/objects/src/errors/index.ts b/packages/objects/src/errors/index.ts index cfd20f28c7..289c3e9d37 100644 --- a/packages/objects/src/errors/index.ts +++ b/packages/objects/src/errors/index.ts @@ -8,7 +8,6 @@ export * from "@objects/errors/BlockchainErrorMapper.js"; export * from "@objects/errors/BlockchainProviderError.js"; export * from "@objects/errors/CloudStorageError.js"; export * from "@objects/errors/ConsentContractError.js"; -export * from "@objects/errors/ConsentContractRepositoryError.js"; export * from "@objects/errors/ConsentError.js"; export * from "@objects/errors/ConsentFactoryContractError.js"; export * from "@objects/errors/CrumbsContractError.js"; diff --git a/packages/objects/src/interfaces/IConfigOverrides.ts b/packages/objects/src/interfaces/IConfigOverrides.ts index 784e2b0bdb..2372ba7c09 100644 --- a/packages/objects/src/interfaces/IConfigOverrides.ts +++ b/packages/objects/src/interfaces/IConfigOverrides.ts @@ -42,7 +42,7 @@ export interface IConfigOverrides { spaceAndTimeKey?: string | null; blockvisionKey?: string | null; - dnsServerAddress?: URLString; + dnsProviderBaseUrl?: URLString; dataWalletBackupIntervalMS?: number; backupChunkSizeTarget?: number; requestForDataCheckingFrequency?: number; @@ -69,5 +69,5 @@ export interface IConfigOverrides { projectId: string; }; - queryPerformanceMetricsLimit ? : number + queryPerformanceMetricsLimit?: number; } diff --git a/packages/objects/src/interfaces/ISdlDataWallet.ts b/packages/objects/src/interfaces/ISdlDataWallet.ts index 64a7f4a07c..91ecd9db95 100644 --- a/packages/objects/src/interfaces/ISdlDataWallet.ts +++ b/packages/objects/src/interfaces/ISdlDataWallet.ts @@ -245,10 +245,6 @@ export interface ISdlDataWallet { Map, ProxyError >; - getAvailableInvitationsCID(): ResultAsync< - Map, - ProxyError - >; getInvitationMetadataByCID( ipfsCID: IpfsCID, ): ResultAsync; diff --git a/packages/objects/src/interfaces/ISnickerdoodleCore.ts b/packages/objects/src/interfaces/ISnickerdoodleCore.ts index 37ebb0dc10..99026d67ea 100644 --- a/packages/objects/src/interfaces/ISnickerdoodleCore.ts +++ b/packages/objects/src/interfaces/ISnickerdoodleCore.ts @@ -49,7 +49,6 @@ import { AjaxError, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, ConsentError, ConsentFactoryContractError, DiscordError, @@ -491,7 +490,7 @@ export interface IInvitationMethods { | UninitializedError | AjaxError | ConsentContractError - | ConsentContractRepositoryError + | ConsentFactoryContractError | UnauthorizedError | BlockchainCommonErrors >; @@ -515,6 +514,8 @@ export interface IInvitationMethods { | AjaxError | MinimalForwarderContractError | ConsentError + | ConsentContractError + | ConsentFactoryContractError | UnauthorizedError | BlockchainCommonErrors >; @@ -541,7 +542,6 @@ export interface IInvitationMethods { | ConsentError | AjaxError | ConsentContractError - | ConsentContractRepositoryError | UnauthorizedError | BlockchainCommonErrors >; @@ -601,19 +601,6 @@ export interface IInvitationMethods { | BlockchainCommonErrors >; - getAvailableInvitationsCID( - sourceDomain?: DomainName | undefined, - ): ResultAsync< - Map, - | BlockchainProviderError - | UninitializedError - | ConsentFactoryContractError - | ConsentContractError - | PersistenceError - | UnauthorizedError - | BlockchainCommonErrors - >; - getAcceptedInvitationsCID( sourceDomain?: DomainName | undefined, ): ResultAsync< diff --git a/packages/synamint-extension-sdk/src/content/DataWalletProxy.ts b/packages/synamint-extension-sdk/src/content/DataWalletProxy.ts index 9e0b997411..da7ea2f417 100644 --- a/packages/synamint-extension-sdk/src/content/DataWalletProxy.ts +++ b/packages/synamint-extension-sdk/src/content/DataWalletProxy.ts @@ -557,10 +557,6 @@ export class _DataWalletProxy extends EventEmitter implements ISdlDataWallet { return coreGateway.getAcceptedInvitationsCID(); } - public getAvailableInvitationsCID() { - return coreGateway.getAvailableInvitationsCID(); - } - public getInvitationMetadataByCID(ipfsCID: IpfsCID) { return coreGateway.getInvitationMetadataByCID( new GetInvitationMetadataByCIDParams(ipfsCID), diff --git a/packages/synamint-extension-sdk/src/core/implementations/api/RpcCallHandler.ts b/packages/synamint-extension-sdk/src/core/implementations/api/RpcCallHandler.ts index 68337e23fe..a0d047fd39 100644 --- a/packages/synamint-extension-sdk/src/core/implementations/api/RpcCallHandler.ts +++ b/packages/synamint-extension-sdk/src/core/implementations/api/RpcCallHandler.ts @@ -79,7 +79,6 @@ import { GetSiteVisitsParams, GetSiteVisitsMapParams, GetAcceptedInvitationsCIDParams, - GetAvailableInvitationsCIDParams, CloseTabParams, GetStateParams, GetInternalStateParams, @@ -460,16 +459,6 @@ export class RpcCallHandler implements IRpcCallHandler { }); }, ), - new CoreActionHandler( - GetAvailableInvitationsCIDParams.getCoreAction(), - (_params) => { - return this.invitationService - .getAvailableInvitationsCID() - .map((res) => { - return ObjectUtils.serialize(res); - }); - }, - ), new CoreActionHandler( GetAgreementPermissionsParams.getCoreAction(), (params) => { diff --git a/packages/synamint-extension-sdk/src/core/implementations/business/InvitationService.ts b/packages/synamint-extension-sdk/src/core/implementations/business/InvitationService.ts index 223b3775b7..8ccd034c34 100644 --- a/packages/synamint-extension-sdk/src/core/implementations/business/InvitationService.ts +++ b/packages/synamint-extension-sdk/src/core/implementations/business/InvitationService.ts @@ -87,13 +87,6 @@ export class InvitationService implements IInvitationService { }); } - public getAvailableInvitationsCID(): ResultAsync< - Map, - SnickerDoodleCoreError - > { - return this.invitationRepository.getAvailableInvitationsCID(); - } - public getAcceptedInvitationsCID(): ResultAsync< Map, SnickerDoodleCoreError diff --git a/packages/synamint-extension-sdk/src/core/implementations/data/InvitationRepository.ts b/packages/synamint-extension-sdk/src/core/implementations/data/InvitationRepository.ts index 52d8603b98..6604558d73 100644 --- a/packages/synamint-extension-sdk/src/core/implementations/data/InvitationRepository.ts +++ b/packages/synamint-extension-sdk/src/core/implementations/data/InvitationRepository.ts @@ -93,16 +93,6 @@ export class InvitationRepository implements IInvitationRepository { }); } - public getAvailableInvitationsCID(): ResultAsync< - Map, - SnickerDoodleCoreError - > { - return this.core.invitation.getAvailableInvitationsCID().mapErr((error) => { - this.errorUtils.emit(error); - return new SnickerDoodleCoreError((error as Error).message, error); - }); - } - public getAcceptedInvitationsCID(): ResultAsync< Map, SnickerDoodleCoreError diff --git a/packages/synamint-extension-sdk/src/core/interfaces/business/IInvitationService.ts b/packages/synamint-extension-sdk/src/core/interfaces/business/IInvitationService.ts index f8866ade39..508619cb63 100644 --- a/packages/synamint-extension-sdk/src/core/interfaces/business/IInvitationService.ts +++ b/packages/synamint-extension-sdk/src/core/interfaces/business/IInvitationService.ts @@ -73,10 +73,6 @@ export interface IInvitationService { Map>, SnickerDoodleCoreError >; - getAvailableInvitationsCID(): ResultAsync< - Map, - SnickerDoodleCoreError - >; getAgreementPermissions( consentContractAddress: EVMContractAddress, diff --git a/packages/synamint-extension-sdk/src/core/interfaces/data/IInvitationRepository.ts b/packages/synamint-extension-sdk/src/core/interfaces/data/IInvitationRepository.ts index 1e76019b25..8c188d98d6 100644 --- a/packages/synamint-extension-sdk/src/core/interfaces/data/IInvitationRepository.ts +++ b/packages/synamint-extension-sdk/src/core/interfaces/data/IInvitationRepository.ts @@ -10,7 +10,6 @@ import { MarketplaceListing, AccountAddress, IConsentCapacity, - PossibleReward, PagingRequest, MarketplaceTag, PagedResponse, @@ -52,10 +51,6 @@ export interface IInvitationRepository { getConsentCapacity( consentContractAddress: EVMContractAddress, ): ResultAsync; - getAvailableInvitationsCID(): ResultAsync< - Map, - SnickerDoodleCoreError - >; getEarnedRewardsByContractAddress( contractAddresses: EVMContractAddress[], ): ResultAsync< diff --git a/packages/synamint-extension-sdk/src/gateways/ExternalCoreGateway.ts b/packages/synamint-extension-sdk/src/gateways/ExternalCoreGateway.ts index 8108542ca3..d489db3527 100644 --- a/packages/synamint-extension-sdk/src/gateways/ExternalCoreGateway.ts +++ b/packages/synamint-extension-sdk/src/gateways/ExternalCoreGateway.ts @@ -110,7 +110,6 @@ import { GetAccountBalancesParams, GetAccountsParams, GetAcceptedInvitationsCIDParams, - GetAvailableInvitationsCIDParams, GetStateParams, InitializeDiscordUserParams, GetDiscordInstallationUrlParams, @@ -321,17 +320,6 @@ export class ExternalCoreGateway { }); } - public getAvailableInvitationsCID(): ResultAsync< - Map, - ProxyError - > { - return this._handler - .call(new GetAvailableInvitationsCIDParams()) - .map((jsonString) => { - return ObjectUtils.deserialize(jsonString); - }); - } - public acceptInvitation( invitation: Invitation, dataTypes: EWalletDataType[] | null, diff --git a/packages/synamint-extension-sdk/src/shared/interfaces/actions.ts b/packages/synamint-extension-sdk/src/shared/interfaces/actions.ts index b0bb12dc64..f1938dae48 100644 --- a/packages/synamint-extension-sdk/src/shared/interfaces/actions.ts +++ b/packages/synamint-extension-sdk/src/shared/interfaces/actions.ts @@ -564,15 +564,6 @@ export class GetAcceptedInvitationsCIDParams extends CoreActionParams { - public constructor() { - super(GetAvailableInvitationsCIDParams.getCoreAction()); - } - static getCoreAction(): ECoreActions { - return ECoreActions.GET_AVAILABLE_INVITATIONS_CID; - } -} - export class GetStateParams extends CoreActionParams { public constructor() { super(GetStateParams.getCoreAction()); diff --git a/packages/test-harness/src/prompts/OptInCampaign.ts b/packages/test-harness/src/prompts/OptInCampaign.ts index e23c1ef345..699986e4e1 100644 --- a/packages/test-harness/src/prompts/OptInCampaign.ts +++ b/packages/test-harness/src/prompts/OptInCampaign.ts @@ -3,7 +3,6 @@ import { AjaxError, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, EInvitationStatus, PageInvitation, PersistenceError, @@ -33,7 +32,6 @@ export class OptInCampaign extends Prompt { | UninitializedError | ConsentContractError | AjaxError - | ConsentContractRepositoryError > { return this.core.invitation .getInvitationsByDomain(this.mocks.domainName) diff --git a/packages/test-harness/src/prompts/OptOutCampaign.ts b/packages/test-harness/src/prompts/OptOutCampaign.ts index 74a571beaa..f1d042d74f 100644 --- a/packages/test-harness/src/prompts/OptOutCampaign.ts +++ b/packages/test-harness/src/prompts/OptOutCampaign.ts @@ -2,7 +2,6 @@ import { AjaxError, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, Invitation, PersistenceError, UninitializedError, @@ -22,7 +21,6 @@ export class OptOutCampaign extends Prompt { | UninitializedError | ConsentContractError | AjaxError - | ConsentContractRepositoryError > { return this.core.invitation .getAcceptedInvitations() diff --git a/packages/test-harness/src/prompts/UpdateDataPermissions.ts b/packages/test-harness/src/prompts/UpdateDataPermissions.ts index 8e6773e9d3..11074682b8 100644 --- a/packages/test-harness/src/prompts/UpdateDataPermissions.ts +++ b/packages/test-harness/src/prompts/UpdateDataPermissions.ts @@ -2,7 +2,6 @@ import { AjaxError, BlockchainProviderError, ConsentContractError, - ConsentContractRepositoryError, DataPermissions, EVMContractAddress, EWalletDataType, @@ -24,7 +23,6 @@ export class UpdateDataPermissions extends Prompt { | UninitializedError | ConsentContractError | AjaxError - | ConsentContractRepositoryError > { return this.core.invitation .getAcceptedInvitations() diff --git a/packages/test-harness/src/utilities/DataWalletProfile.ts b/packages/test-harness/src/utilities/DataWalletProfile.ts index 602e04ec3d..fcd6d32748 100644 --- a/packages/test-harness/src/utilities/DataWalletProfile.ts +++ b/packages/test-harness/src/utilities/DataWalletProfile.ts @@ -166,7 +166,7 @@ export class DataWalletProfile { const core = new SnickerdoodleCore( { defaultInsightPlatformBaseUrl: "http://localhost:3006", - dnsServerAddress: "http://localhost:3006/dns", + dnsProviderBaseUrl: "http://localhost:3006/dns", devChainProviderURL: "http://127.0.0.1:8545", discordOverrides: discordConfig, heartbeatIntervalMS: 5000, // Set the heartbeat to 5 seconds diff --git a/packages/web-integration/src/implementations/proxy/SnickerdoodleIFrameProxy.ts b/packages/web-integration/src/implementations/proxy/SnickerdoodleIFrameProxy.ts index c4eaec14c2..9f02f9db85 100644 --- a/packages/web-integration/src/implementations/proxy/SnickerdoodleIFrameProxy.ts +++ b/packages/web-integration/src/implementations/proxy/SnickerdoodleIFrameProxy.ts @@ -400,13 +400,6 @@ export class SnickerdoodleIFrameProxy return this._createCall("getAcceptedInvitationsCID", null); } - public getAvailableInvitationsCID(): ResultAsync< - Map, - ProxyError - > { - return this._createCall("getAvailableInvitationsCID", null); - } - public getConsentContractURLs( contractAddress: EVMContractAddress, ): ResultAsync { diff --git a/yarn.lock b/yarn.lock index 3bba7bedf3..536f2a39be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9213,6 +9213,7 @@ __metadata: dependencies: "@snickerdoodlelabs/common-utils": "workspace:^" "@snickerdoodlelabs/contracts-sdk": "workspace:^" + "@snickerdoodlelabs/erc7529": "workspace:^" "@snickerdoodlelabs/indexers": "workspace:^" "@snickerdoodlelabs/insight-platform-api": "workspace:^" "@snickerdoodlelabs/node-utils": "workspace:^" @@ -9234,7 +9235,7 @@ __metadata: languageName: unknown linkType: soft -"@snickerdoodlelabs/erc7529@workspace:packages/erc7529": +"@snickerdoodlelabs/erc7529@workspace:^, @snickerdoodlelabs/erc7529@workspace:packages/erc7529": version: 0.0.0-use.local resolution: "@snickerdoodlelabs/erc7529@workspace:packages/erc7529" dependencies: