From e9693327fd5ebf6dfe261d65918950689b134a19 Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Wed, 5 Oct 2022 11:32:43 +0200 Subject: [PATCH 1/6] feat: seller meta tx + batch methods --- e2e/tests/core-sdk.test.ts | 52 ++--- e2e/tests/meta-tx.test.ts | 200 ++++++++++++++++- e2e/tests/utils.ts | 30 +++ packages/core-sdk/src/core-sdk.ts | 203 +++++++++++++++--- packages/core-sdk/src/meta-tx/handler.ts | 139 ++++++++++-- packages/core-sdk/src/offers/handler.ts | 35 ++- packages/core-sdk/src/offers/interface.ts | 46 +++- .../components/cta/exchange/CancelButton.tsx | 2 +- .../components/cta/exchange/RedeemButton.tsx | 2 +- .../src/components/cta/offer/CommitButton.tsx | 2 +- 10 files changed, 622 insertions(+), 89 deletions(-) diff --git a/e2e/tests/core-sdk.test.ts b/e2e/tests/core-sdk.test.ts index 68f42edc4..3a50b18af 100644 --- a/e2e/tests/core-sdk.test.ts +++ b/e2e/tests/core-sdk.test.ts @@ -1,6 +1,5 @@ import { DAY_IN_MS, DAY_IN_SEC } from "./../../packages/core-sdk/tests/mocks"; import { CreateSellerArgs } from "./../../packages/common/src/types/accounts"; -import { CreateOfferArgs } from "./../../packages/common/src/types/offers"; import { DisputeState, ExchangeFieldsFragment @@ -26,7 +25,8 @@ import { seedWallet5, seedWallet6, initCoreSDKWithWallet, - drWallet + drWallet, + createOffer } from "./utils"; const seedWallet = seedWallet4; // be sure the seedWallet is not used by another test (to allow concurrent run) @@ -67,8 +67,10 @@ describe("core-sdk", () => { const seller = await createSeller(coreSDK, fundedWallet.address); expect(seller).toBeTruthy(); + await checkDisputeResolver(coreSDK, seller.id, 1); + // Create an offer with validity duration instead of period - const createdOffer = await createOffer(coreSDK, seller.id, { + const createdOffer = await createOffer(coreSDK, { voucherRedeemableUntilDateInMS: 0, voucherValidDurationInMS: 30 * DAY_IN_MS }); @@ -397,11 +399,10 @@ describe("core-sdk", () => { beforeEach(async () => { await waitForGraphNodeIndexing(); - const sellers = await ensureCreatedSeller(sellerWallet); - const [seller] = sellers; + await ensureCreatedSeller(sellerWallet); // before each case, create offer + commit + redeem - const createdOffer = await createOffer(sellerCoreSDK, seller.id); + const createdOffer = await createOffer(sellerCoreSDK); await depositFunds({ coreSDK: sellerCoreSDK, sellerId: createdOffer.seller.id @@ -436,10 +437,9 @@ describe("core-sdk", () => { test("expired dispute", async () => { // create another offer with very small resolutionPeriod + commit + redeem - const sellers = await ensureCreatedSeller(sellerWallet); - const [seller] = sellers; + await ensureCreatedSeller(sellerWallet); - const createdOffer = await createOffer(sellerCoreSDK, seller.id, { + const createdOffer = await createOffer(sellerCoreSDK, { resolutionPeriodDurationInMS: 1000 }); await depositFunds({ @@ -595,43 +595,19 @@ describe("core-sdk", () => { }); }); -async function createOffer( +async function checkDisputeResolver( coreSDK: CoreSDK, - sellerId: string, - offerParams?: Partial + sellerId: BigNumberish, + disputeResolverId: BigNumberish ) { - const metadataHash = await coreSDK.storeMetadata({ - ...metadata, - type: "BASE" - }); - const metadataUri = "ipfs://" + metadataHash; - - const offerArgs = mockCreateOfferArgs({ - metadataHash, - metadataUri, - ...offerParams - }); - // Check the disputeResolver exists and is active - const disputeResolverId = offerArgs.disputeResolverId; - const dr = await coreSDK.getDisputeResolverById(disputeResolverId); expect(dr).toBeTruthy(); expect(dr.active).toBe(true); expect( - dr.sellerAllowList.length == 0 || dr.sellerAllowList.indexOf(sellerId) >= 0 + dr.sellerAllowList.length == 0 || + dr.sellerAllowList.indexOf(sellerId.toString()) >= 0 ).toBe(true); - - const createOfferTxResponse = await coreSDK.createOffer(offerArgs); - const createOfferTxReceipt = await createOfferTxResponse.wait(); - const createdOfferId = coreSDK.getCreatedOfferIdFromLogs( - createOfferTxReceipt.logs - ); - - await waitForGraphNodeIndexing(); - const offer = await coreSDK.getOfferById(createdOfferId as string); - - return offer; } async function createSeller( diff --git a/e2e/tests/meta-tx.test.ts b/e2e/tests/meta-tx.test.ts index 74ba8a153..f89161e2e 100644 --- a/e2e/tests/meta-tx.test.ts +++ b/e2e/tests/meta-tx.test.ts @@ -11,7 +11,9 @@ import { seedWallet7, seedWallet8, waitForGraphNodeIndexing, - metadata + metadata, + defaultConfig, + createOffer } from "./utils"; const sellerWallet = seedWallet7; // be sure the seedWallet is not used by another test (to allow concurrent run) @@ -35,13 +37,197 @@ describe("meta-tx", () => { offer = await sellerCoreSDK.getOfferById(createdOfferId); }); - describe("#signExecuteMetaTxCommitToOffer()", () => { + // TODO: Find a way to make this work. This fails with `processing error: unknown account` because + // the ephemeral account is not a known signer of the hardhat node. + describe.skip("#signMetaTxCreateSeller()", () => { + test("create for random wallet", async () => { + const nonce = Date.now(); + const randomWallet = Wallet.createRandom(); + const randomSellerCoreSDK = initCoreSDKWithWallet(randomWallet); + + // Random seller signs meta tx + const { r, s, v, functionName, functionSignature } = + await randomSellerCoreSDK.signMetaTxCreateSeller({ + createSellerArgs: { + operator: randomWallet.address, + treasury: randomWallet.address, + admin: randomWallet.address, + clerk: randomWallet.address, + // TODO: replace with correct uri + contractUri: "ipfs://seller-contract", + royaltyPercentage: "0", + authTokenId: "0", + authTokenType: 0 + }, + nonce, + chainId: defaultConfig.chainId + }); + + // `Relayer` executes meta tx on behalf of random seller + const metaTx = await randomSellerCoreSDK.relayMetaTransaction({ + functionName, + functionSignature, + nonce, + sigR: r, + sigS: s, + sigV: v + }); + + const metaTxReceipt = await metaTx.wait(); + const metaTxEvent = metaTxReceipt.events?.find( + (event) => event.event === "MetaTransactionExecuted" + ); + + expect(metaTxEvent).toBeTruthy(); + }); + }); + + describe("#signMetaTxCreateOffer()", () => { + test("create an offer", async () => { + const metadataHash = await sellerCoreSDK.storeMetadata({ + ...metadata, + type: "BASE" + }); + const metadataUri = "ipfs://" + metadataHash; + + const createOfferArgs = mockCreateOfferArgs({ + metadataHash, + metadataUri + }); + + const nonce = Date.now(); + + // Seller signs meta tx + const { r, s, v, functionName, functionSignature } = + await sellerCoreSDK.signMetaTxCreateOffer({ + createOfferArgs, + nonce, + chainId: defaultConfig.chainId + }); + + // `Relayer` executes meta tx on behalf of seller + const metaTx = await sellerCoreSDK.relayMetaTransaction({ + functionName, + functionSignature, + nonce, + sigR: r, + sigS: s, + sigV: v + }); + + const metaTxReceipt = await metaTx.wait(); + expect(metaTxReceipt.transactionHash).toBeTruthy(); + expect(BigNumber.from(metaTxReceipt.effectiveGasPrice).gt(0)).toBe(true); + }); + }); + + describe("#signMetaTxCreateOfferBatch()", () => { + test("create batch of offers", async () => { + const metadataHash = await sellerCoreSDK.storeMetadata({ + ...metadata, + type: "BASE" + }); + const metadataUri = "ipfs://" + metadataHash; + + const createOfferArgs = mockCreateOfferArgs({ + metadataHash, + metadataUri + }); + + const nonce = Date.now(); + + // Seller signs meta tx + const { r, s, v, functionName, functionSignature } = + await sellerCoreSDK.signMetaTxCreateOfferBatch({ + createOffersArgs: [createOfferArgs, createOfferArgs], + nonce, + chainId: defaultConfig.chainId + }); + + // `Relayer` executes meta tx on behalf of seller + const metaTx = await sellerCoreSDK.relayMetaTransaction({ + functionName, + functionSignature, + nonce, + sigR: r, + sigS: s, + sigV: v + }); + + const metaTxReceipt = await metaTx.wait(); + expect(metaTxReceipt.transactionHash).toBeTruthy(); + expect(BigNumber.from(metaTxReceipt.effectiveGasPrice).gt(0)).toBe(true); + }); + }); + + describe("#signMetaTxVoidOffer()", () => { + test("void created offer", async () => { + const createdOffer = await createOffer(sellerCoreSDK); + + const nonce = Date.now(); + + // Seller signs meta tx + const { r, s, v, functionName, functionSignature } = + await sellerCoreSDK.signMetaTxVoidOffer({ + offerId: createdOffer.id, + nonce, + chainId: defaultConfig.chainId + }); + + // `Relayer` executes meta tx on behalf of seller + const metaTx = await sellerCoreSDK.relayMetaTransaction({ + functionName, + functionSignature, + nonce, + sigR: r, + sigS: s, + sigV: v + }); + + const metaTxReceipt = await metaTx.wait(); + expect(metaTxReceipt.transactionHash).toBeTruthy(); + expect(BigNumber.from(metaTxReceipt.effectiveGasPrice).gt(0)).toBe(true); + }); + }); + + describe("#signMetaTxVoidOfferBatch()", () => { + test("void created offers", async () => { + const createdOffer1 = await createOffer(sellerCoreSDK); + const createdOffer2 = await createOffer(sellerCoreSDK); + + const nonce = Date.now(); + + // Seller signs meta tx + const { r, s, v, functionName, functionSignature } = + await sellerCoreSDK.signMetaTxVoidOfferBatch({ + offerIds: [createdOffer1.id, createdOffer2.id], + nonce, + chainId: defaultConfig.chainId + }); + + // `Relayer` executes meta tx on behalf of seller + const metaTx = await sellerCoreSDK.relayMetaTransaction({ + functionName, + functionSignature, + nonce, + sigR: r, + sigS: s, + sigV: v + }); + + const metaTxReceipt = await metaTx.wait(); + expect(metaTxReceipt.transactionHash).toBeTruthy(); + expect(BigNumber.from(metaTxReceipt.effectiveGasPrice).gt(0)).toBe(true); + }); + }); + + describe("#signMetaTxCommitToOffer()", () => { test("non-native exchange token offer", async () => { const nonce = Date.now(); // `Buyer` signs meta tx const { r, s, v, functionName, functionSignature } = - await buyerCoreSDK.signExecuteMetaTxCommitToOffer({ + await buyerCoreSDK.signMetaTxCommitToOffer({ offerId: offer.id, nonce }); @@ -61,7 +247,7 @@ describe("meta-tx", () => { }); }); - describe("#signExecuteMetaTxRedeemVoucher()", () => { + describe("#signMetaTxRedeemVoucher()", () => { test("non-native exchange token offer", async () => { const commitTx = await buyerCoreSDK.commitToOffer(offer.id); const commitTxReceipt = await commitTx.wait(); @@ -73,7 +259,7 @@ describe("meta-tx", () => { // `Buyer` signs meta tx const { r, s, v, functionName, functionSignature } = - await buyerCoreSDK.signExecuteMetaTxRedeemVoucher({ + await buyerCoreSDK.signMetaTxRedeemVoucher({ exchangeId: Number(exchangeId), nonce }); @@ -93,7 +279,7 @@ describe("meta-tx", () => { }); }); - describe("#signExecuteMetaTxCancelVoucher()", () => { + describe("#signMetaTxCancelVoucher()", () => { test("non-native exchange token offer", async () => { const commitTx = await buyerCoreSDK.commitToOffer(offer.id); const commitTxReceipt = await commitTx.wait(); @@ -105,7 +291,7 @@ describe("meta-tx", () => { // `Buyer` signs meta tx const { r, s, v, functionName, functionSignature } = - await buyerCoreSDK.signExecuteMetaTxCancelVoucher({ + await buyerCoreSDK.signMetaTxCancelVoucher({ exchangeId: exchangeId as string, nonce }); diff --git a/e2e/tests/utils.ts b/e2e/tests/utils.ts index 19d2e17d6..be9f879c5 100644 --- a/e2e/tests/utils.ts +++ b/e2e/tests/utils.ts @@ -13,6 +13,8 @@ import { } from "../../packages/core-sdk/src"; import { IpfsMetadataStorage } from "../../packages/ipfs-storage/src"; import { EthersAdapter } from "../../packages/ethers-sdk/src"; +import { CreateOfferArgs } from "./../../packages/common/src/types/offers"; +import { mockCreateOfferArgs } from "../../packages/common/tests/mocks"; import { ACCOUNT_1, ACCOUNT_2, @@ -311,3 +313,31 @@ export async function createDisputeResolver( disputeResolverCoreSDK: drCoreSDK }; } + +export async function createOffer( + coreSDK: CoreSDK, + offerParams?: Partial +) { + const metadataHash = await coreSDK.storeMetadata({ + ...metadata, + type: "BASE" + }); + const metadataUri = "ipfs://" + metadataHash; + + const offerArgs = mockCreateOfferArgs({ + metadataHash, + metadataUri, + ...offerParams + }); + + const createOfferTxResponse = await coreSDK.createOffer(offerArgs); + const createOfferTxReceipt = await createOfferTxResponse.wait(); + const createdOfferId = coreSDK.getCreatedOfferIdFromLogs( + createOfferTxReceipt.logs + ); + + await waitForGraphNodeIndexing(); + const offer = await coreSDK.getOfferById(createdOfferId as string); + + return offer; +} diff --git a/packages/core-sdk/src/core-sdk.ts b/packages/core-sdk/src/core-sdk.ts index 59b90d139..a88f0c4db 100644 --- a/packages/core-sdk/src/core-sdk.ts +++ b/packages/core-sdk/src/core-sdk.ts @@ -680,6 +680,28 @@ export class CoreSDK { }); } + /** + * Creates a batch of offers by calling the `OfferHandlerFacet` contract. + * This transaction only succeeds if there is an existing seller account for connected signer. + * @param offersToCreate - Offer arguments. + * @param overrides - Optional overrides. + * @returns Transaction response. + */ + public async createOfferBatch( + offersToCreate: offers.CreateOfferArgs[], + overrides: Partial<{ + contractAddress: string; + }> = {} + ): Promise { + return offers.handler.createOfferBatch({ + offersToCreate, + web3Lib: this._web3Lib, + theGraphStorage: this._theGraphStorage, + metadataStorage: this._metadataStorage, + contractAddress: overrides.contractAddress || this._protocolDiamond + }); + } + /** * Utility method to retrieve the created `offerId` from logs after calling `createOffer` * or `createOfferAndSeller`. @@ -1380,13 +1402,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTx( + public async signMetaTx( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTx({ + return metaTx.handler.signMetaTx({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1394,18 +1416,126 @@ export class CoreSDK { }); } + /** + * Encodes and signs a meta transaction for `createSeller` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxCreateSeller( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxCreateSeller({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `createOffer` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxCreateOffer( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxCreateOffer({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `createOfferBatch` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxCreateOfferBatch( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxCreateOfferBatch({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `voidOffer` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxVoidOffer( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxVoidOffer({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `voidOfferBatch` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxVoidOfferBatch( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxVoidOfferBatch({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `completeExchangeBatch` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxCompleteExchangeBatch( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" + > + ) { + return metaTx.handler.signMetaTxCompleteExchangeBatch({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + ...args + }); + } + /** * Encodes and signs a meta transaction for `commitToOffer` that can be relayed. * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxCommitToOffer( + public async signMetaTxCommitToOffer( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxCommitToOffer({ + return metaTx.handler.signMetaTxCommitToOffer({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1418,13 +1548,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxCancelVoucher( + public async signMetaTxCancelVoucher( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxCancelVoucher({ + return metaTx.handler.signMetaTxCancelVoucher({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1437,13 +1567,32 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxRedeemVoucher( + public async signMetaTxRedeemVoucher( + args: Omit< + Parameters[0], + "web3Lib" | "metaTxHandlerAddress" | "chainId" + > + ) { + return metaTx.handler.signMetaTxRedeemVoucher({ + web3Lib: this._web3Lib, + metaTxHandlerAddress: this._protocolDiamond, + chainId: this._chainId, + ...args + }); + } + + /** + * Encodes and signs a meta transaction for `expireVoucher` that can be relayed. + * @param args - Meta transaction args. + * @returns Signature. + */ + public async signMetaTxExpireVoucher( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxRedeemVoucher({ + return metaTx.handler.signMetaTxExpireVoucher({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1456,13 +1605,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxRetractDispute( + public async signMetaTxRetractDispute( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxRetractDispute({ + return metaTx.handler.signMetaTxRetractDispute({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1475,13 +1624,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxEscalateDispute( + public async signMetaTxEscalateDispute( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxEscalateDispute({ + return metaTx.handler.signMetaTxEscalateDispute({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1494,13 +1643,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxRaiseDispute( + public async signMetaTxRaiseDispute( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxRaiseDispute({ + return metaTx.handler.signMetaTxRaiseDispute({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1513,13 +1662,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxResolveDispute( + public async signMetaTxResolveDispute( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxResolveDispute({ + return metaTx.handler.signMetaTxResolveDispute({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, @@ -1532,13 +1681,13 @@ export class CoreSDK { * @param args - Meta transaction args. * @returns Signature. */ - public async signExecuteMetaTxWithdrawFunds( + public async signMetaTxWithdrawFunds( args: Omit< - Parameters[0], + Parameters[0], "web3Lib" | "metaTxHandlerAddress" | "chainId" > ) { - return metaTx.handler.signExecuteMetaTxWithdrawFunds({ + return metaTx.handler.signMetaTxWithdrawFunds({ web3Lib: this._web3Lib, metaTxHandlerAddress: this._protocolDiamond, chainId: this._chainId, diff --git a/packages/core-sdk/src/meta-tx/handler.ts b/packages/core-sdk/src/meta-tx/handler.ts index 68dfd1807..ede99a52a 100644 --- a/packages/core-sdk/src/meta-tx/handler.ts +++ b/packages/core-sdk/src/meta-tx/handler.ts @@ -1,9 +1,20 @@ -import { MetaTxConfig, Web3LibAdapter } from "@bosonprotocol/common"; +import { + CreateOfferArgs, + CreateSellerArgs, + MetaTxConfig, + Web3LibAdapter +} from "@bosonprotocol/common"; import { BigNumber, BigNumberish } from "@ethersproject/bignumber"; import { BytesLike } from "@ethersproject/bytes"; import { ContractTransaction } from "@ethersproject/contracts"; +import { encodeCreateSeller } from "../accounts/interface"; import { bosonExchangeHandlerIface } from "../exchanges/interface"; +import { + bosonOfferHandlerIface, + encodeCreateOffer, + encodeCreateOfferBatch +} from "../offers/interface"; import { prepareDataSignatureParameters } from "../utils/signature"; import { Biconomy } from "./biconomy"; @@ -14,7 +25,7 @@ type BaseMetaTxArgs = { chainId: number; }; -export async function signExecuteMetaTx( +export async function signMetaTx( args: BaseMetaTxArgs & { functionName: string; functionSignature: string; @@ -42,16 +53,120 @@ export async function signExecuteMetaTx( functionSignature: args.functionSignature }; - return prepareDataSignatureParameters({ + const signature = await prepareDataSignatureParameters({ ...args, verifyingContractAddress: args.metaTxHandlerAddress, customSignatureType, primaryType: "MetaTransaction", message }); + + return { + functionName: args.functionName, + functionSignature: args.functionSignature, + ...signature + }; +} + +export async function signMetaTxCreateSeller( + args: BaseMetaTxArgs & { + createSellerArgs: CreateSellerArgs; + } +) { + return signMetaTx({ + ...args, + functionName: + "createSeller((uint256,address,address,address,address,bool),(uint256,uint8),(string,uint96))", + functionSignature: encodeCreateSeller(args.createSellerArgs) + }); +} + +export async function signMetaTxCreateOffer( + args: BaseMetaTxArgs & { + createOfferArgs: CreateOfferArgs; + } +) { + return signMetaTx({ + ...args, + functionName: + "createOffer((uint256,uint256,uint256,uint256,uint256,uint256,address,string,string,bool),(uint256,uint256,uint256,uint256),(uint256,uint256,uint256),uint256,uint256)", + functionSignature: encodeCreateOffer(args.createOfferArgs) + }); +} + +export async function signMetaTxCreateOfferBatch( + args: BaseMetaTxArgs & { + createOffersArgs: CreateOfferArgs[]; + } +) { + return signMetaTx({ + ...args, + functionName: + "createOfferBatch((uint256,uint256,uint256,uint256,uint256,uint256,address,string,string,bool)[],(uint256,uint256,uint256,uint256)[],(uint256,uint256,uint256)[],uint256[],uint256[])", + functionSignature: encodeCreateOfferBatch(args.createOffersArgs) + }); +} + +export async function signMetaTxVoidOffer( + args: BaseMetaTxArgs & { + offerId: BigNumberish; + } +) { + return signMetaTx({ + ...args, + functionName: "voidOffer(uint256)", + functionSignature: bosonOfferHandlerIface.encodeFunctionData("voidOffer", [ + args.offerId + ]) + }); +} + +export async function signMetaTxVoidOfferBatch( + args: BaseMetaTxArgs & { + offerIds: BigNumberish[]; + } +) { + return signMetaTx({ + ...args, + functionName: "voidOfferBatch(uint256[])", + functionSignature: bosonOfferHandlerIface.encodeFunctionData( + "voidOfferBatch", + [args.offerIds] + ) + }); +} + +export async function signMetaTxCompleteExchangeBatch( + args: BaseMetaTxArgs & { + exchangeIds: BigNumberish[]; + } +) { + return signMetaTx({ + ...args, + functionName: "completeExchangeBatch(uint256[])", + functionSignature: bosonExchangeHandlerIface.encodeFunctionData( + "completeExchangeBatch", + [args.exchangeIds] + ) + }); +} + +export async function signMetaTxExpireVoucher( + args: BaseMetaTxArgs & { + exchangeId: BigNumberish; + } +) { + return signMetaTx({ + ...args, + functionName: "expireVoucher(uint256)", + functionSignature: bosonExchangeHandlerIface.encodeFunctionData( + "expireVoucher", + [args.exchangeId] + ) + }); } -export async function signExecuteMetaTxCommitToOffer( +export async function signMetaTxCommitToOffer( args: BaseMetaTxArgs & { offerId: BigNumberish; } @@ -107,7 +222,7 @@ export async function signExecuteMetaTxCommitToOffer( }; } -export async function signExecuteMetaTxCancelVoucher( +export async function signMetaTxCancelVoucher( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -115,7 +230,7 @@ export async function signExecuteMetaTxCancelVoucher( return makeExchangeMetaTxSigner("cancelVoucher(uint256)")(args); } -export async function signExecuteMetaTxRedeemVoucher( +export async function signMetaTxRedeemVoucher( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -123,7 +238,7 @@ export async function signExecuteMetaTxRedeemVoucher( return makeExchangeMetaTxSigner("redeemVoucher(uint256)")(args); } -export async function signExecuteMetaTxCompleteExchange( +export async function signMetaTxCompleteExchange( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -131,7 +246,7 @@ export async function signExecuteMetaTxCompleteExchange( return makeExchangeMetaTxSigner("completeExchange(uint256)")(args); } -export async function signExecuteMetaTxRetractDispute( +export async function signMetaTxRetractDispute( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -139,7 +254,7 @@ export async function signExecuteMetaTxRetractDispute( return makeExchangeMetaTxSigner("retractDispute(uint256)")(args); } -export async function signExecuteMetaTxEscalateDispute( +export async function signMetaTxEscalateDispute( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -147,7 +262,7 @@ export async function signExecuteMetaTxEscalateDispute( return makeExchangeMetaTxSigner("escalateDispute(uint256)")(args); } -export async function signExecuteMetaTxRaiseDispute( +export async function signMetaTxRaiseDispute( args: BaseMetaTxArgs & { exchangeId: BigNumberish; } @@ -187,7 +302,7 @@ export async function signExecuteMetaTxRaiseDispute( }); } -export async function signExecuteMetaTxResolveDispute( +export async function signMetaTxResolveDispute( args: BaseMetaTxArgs & { exchangeId: BigNumberish; buyerPercent: string; @@ -243,7 +358,7 @@ export async function signExecuteMetaTxResolveDispute( }); } -export async function signExecuteMetaTxWithdrawFunds( +export async function signMetaTxWithdrawFunds( args: BaseMetaTxArgs & { entityId: BigNumberish; tokenList: string[]; diff --git a/packages/core-sdk/src/offers/handler.ts b/packages/core-sdk/src/offers/handler.ts index 18e16fe8d..a007dbb05 100644 --- a/packages/core-sdk/src/offers/handler.ts +++ b/packages/core-sdk/src/offers/handler.ts @@ -5,7 +5,11 @@ import { MetadataStorage, utils } from "@bosonprotocol/common"; -import { bosonOfferHandlerIface, encodeCreateOffer } from "./interface"; +import { + bosonOfferHandlerIface, + encodeCreateOffer, + encodeCreateOfferBatch +} from "./interface"; import { getOfferById, getOffers } from "./subgraph"; import { storeMetadataOnTheGraph } from "./storage"; import { CreateOfferArgs } from "./types"; @@ -34,6 +38,35 @@ export async function createOffer(args: { }); } +export async function createOfferBatch(args: { + offersToCreate: CreateOfferArgs[]; + contractAddress: string; + web3Lib: Web3LibAdapter; + metadataStorage?: MetadataStorage; + theGraphStorage?: MetadataStorage; +}): Promise { + for (const offerToCreate of args.offersToCreate) { + utils.validation.createOfferArgsSchema.validateSync(offerToCreate, { + abortEarly: false + }); + } + + await Promise.all( + args.offersToCreate.map((offerToCreate) => + storeMetadataOnTheGraph({ + metadataUriOrHash: offerToCreate.metadataUri, + metadataStorage: args.metadataStorage, + theGraphStorage: args.theGraphStorage + }) + ) + ); + + return args.web3Lib.sendTransaction({ + to: args.contractAddress, + data: encodeCreateOfferBatch(args.offersToCreate) + }); +} + export async function voidOffer(args: { contractAddress: string; subgraphUrl: string; diff --git a/packages/core-sdk/src/offers/interface.ts b/packages/core-sdk/src/offers/interface.ts index 022c36193..f85d8947f 100644 --- a/packages/core-sdk/src/offers/interface.ts +++ b/packages/core-sdk/src/offers/interface.ts @@ -7,7 +7,7 @@ import { } from "@bosonprotocol/common"; import { Interface } from "@ethersproject/abi"; import { getAddress } from "@ethersproject/address"; -import { BigNumber, BigNumberish } from "@ethersproject/bignumber"; +import { BigNumberish } from "@ethersproject/bignumber"; import { CreateOfferArgs } from "./types"; export const bosonOfferHandlerIface = new Interface(abis.IBosonOfferHandlerABI); @@ -19,6 +19,50 @@ export function encodeCreateOffer(args: CreateOfferArgs) { ); } +export function encodeCreateOfferBatch(argsBatch: CreateOfferArgs[]) { + const argsTuples: [ + Partial, + Partial, + Partial, + BigNumberish, + BigNumberish + ][] = argsBatch.map((args) => [ + argsToOfferStruct(args), + argsToOfferDatesStruct(args), + argsToOfferDurationsStruct(args), + args.disputeResolverId, + args.agentId + ]); + const [offers, offerDates, offerDurations, disputeResolverIds, agentIds]: [ + Partial[], + Partial[], + Partial[], + BigNumberish[], + BigNumberish[] + ] = argsTuples.reduce( + (acc, tuple) => { + const [offer, offerDates, offerDurations, disputeResolverId, agentId] = + tuple; + return [ + [...acc[0], offer], + [...acc[1], offerDates], + [...acc[2], offerDurations], + [...acc[3], disputeResolverId], + [...acc[4], agentId] + ]; + }, + [[], [], [], [], []] + ); + + return bosonOfferHandlerIface.encodeFunctionData("createOfferBatch", [ + offers, + offerDates, + offerDurations, + disputeResolverIds, + agentIds + ]); +} + export function createOfferArgsToStructs( args: CreateOfferArgs ): [ diff --git a/packages/react-kit/src/components/cta/exchange/CancelButton.tsx b/packages/react-kit/src/components/cta/exchange/CancelButton.tsx index 5f90e6cf2..4b97290ea 100644 --- a/packages/react-kit/src/components/cta/exchange/CancelButton.tsx +++ b/packages/react-kit/src/components/cta/exchange/CancelButton.tsx @@ -55,7 +55,7 @@ export const CancelButton = ({ const nonce = Date.now(); const { r, s, v, functionName, functionSignature } = - await coreSdk.signExecuteMetaTxCancelVoucher({ + await coreSdk.signMetaTxCancelVoucher({ exchangeId, nonce }); diff --git a/packages/react-kit/src/components/cta/exchange/RedeemButton.tsx b/packages/react-kit/src/components/cta/exchange/RedeemButton.tsx index 7736ce3c5..9a9f38944 100644 --- a/packages/react-kit/src/components/cta/exchange/RedeemButton.tsx +++ b/packages/react-kit/src/components/cta/exchange/RedeemButton.tsx @@ -55,7 +55,7 @@ export const RedeemButton = ({ const nonce = Date.now(); const { r, s, v, functionName, functionSignature } = - await coreSdk.signExecuteMetaTxRedeemVoucher({ + await coreSdk.signMetaTxRedeemVoucher({ exchangeId, nonce }); diff --git a/packages/react-kit/src/components/cta/offer/CommitButton.tsx b/packages/react-kit/src/components/cta/offer/CommitButton.tsx index 2ea6ee26e..c89ae2789 100644 --- a/packages/react-kit/src/components/cta/offer/CommitButton.tsx +++ b/packages/react-kit/src/components/cta/offer/CommitButton.tsx @@ -53,7 +53,7 @@ export const CommitButton = ({ if (coreSdk.isMetaTxConfigSet && signerAddress) { const nonce = Date.now(); const { r, s, v, functionName, functionSignature } = - await coreSdk.signExecuteMetaTxCommitToOffer({ + await coreSdk.signMetaTxCommitToOffer({ offerId, nonce }); From 69ded3480e0bc52b1d20c5b307831f45a09256ca Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Tue, 11 Oct 2022 11:14:30 +0200 Subject: [PATCH 2/6] refactor: cleaner separation of `getSellers*` methods --- e2e/tests/core-sdk.test.ts | 3 +- e2e/tests/meta-tx.test.ts | 3 +- e2e/tests/utils.ts | 8 +-- packages/core-sdk/src/accounts/handler.ts | 84 ++++++++++++++++++++-- packages/core-sdk/src/accounts/subgraph.ts | 6 ++ packages/core-sdk/src/core-sdk.ts | 71 ++++-------------- packages/core-sdk/tests/core-sdk.test.ts | 8 +-- 7 files changed, 108 insertions(+), 75 deletions(-) diff --git a/e2e/tests/core-sdk.test.ts b/e2e/tests/core-sdk.test.ts index 3a50b18af..bcfed825a 100644 --- a/e2e/tests/core-sdk.test.ts +++ b/e2e/tests/core-sdk.test.ts @@ -587,8 +587,7 @@ describe("core-sdk", () => { const sellerId = seller.id; - const sellers2 = await coreSDK.getSellersByAddress(fundedWallet.address); - const [seller2] = sellers2; + const seller2 = await coreSDK.getSellerByAddress(fundedWallet.address); expect(seller2).toBeTruthy(); expect(seller2.id).toEqual(sellerId); }); diff --git a/e2e/tests/meta-tx.test.ts b/e2e/tests/meta-tx.test.ts index f89161e2e..ffa15caed 100644 --- a/e2e/tests/meta-tx.test.ts +++ b/e2e/tests/meta-tx.test.ts @@ -314,8 +314,7 @@ describe("meta-tx", () => { async function createOfferAndDepositFunds(sellerWallet: Wallet) { const sellerCoreSDK = initCoreSDKWithWallet(sellerWallet); - const sellers = await sellerCoreSDK.getSellersByAddress(sellerAddress); - const [seller] = sellers; + const seller = await sellerCoreSDK.getSellerByAddress(sellerAddress); // Store metadata const metadataHash = await sellerCoreSDK.storeMetadata({ ...metadata, diff --git a/e2e/tests/utils.ts b/e2e/tests/utils.ts index be9f879c5..15df29995 100644 --- a/e2e/tests/utils.ts +++ b/e2e/tests/utils.ts @@ -219,9 +219,9 @@ export async function createFundedWallet( export async function ensureCreatedSeller(sellerWallet: Wallet) { const sellerAddress = sellerWallet.address; const sellerCoreSDK = initCoreSDKWithWallet(sellerWallet); - let sellers = await sellerCoreSDK.getSellersByAddress(sellerAddress); + let seller = await sellerCoreSDK.getSellerByAddress(sellerAddress); - if (!sellers.length) { + if (!seller) { const tx = await sellerCoreSDK.createSeller({ operator: sellerAddress, treasury: sellerAddress, @@ -235,10 +235,10 @@ export async function ensureCreatedSeller(sellerWallet: Wallet) { }); await tx.wait(); await waitForGraphNodeIndexing(); - sellers = await sellerCoreSDK.getSellersByAddress(sellerAddress); + seller = await sellerCoreSDK.getSellerByAddress(sellerAddress); } - return sellers; + return seller; } export async function ensureMintedAndAllowedTokens( diff --git a/packages/core-sdk/src/accounts/handler.ts b/packages/core-sdk/src/accounts/handler.ts index d8c8be772..4b2ff459e 100644 --- a/packages/core-sdk/src/accounts/handler.ts +++ b/packages/core-sdk/src/accounts/handler.ts @@ -1,10 +1,16 @@ import { Web3LibAdapter, TransactionResponse, - utils + utils, + AuthTokenType } from "@bosonprotocol/common"; -import { BigNumberish } from "@ethersproject/bignumber"; -import { DisputeResolverFieldsFragment } from "../subgraph"; +import { BigNumberish, BigNumber } from "@ethersproject/bignumber"; +import { AddressZero } from "@ethersproject/constants"; +import { + DisputeResolverFieldsFragment, + GetSellersQueryQueryVariables, + SellerFieldsFragment +} from "../subgraph"; import { encodeCreateSeller, encodeUpdateSeller, @@ -16,7 +22,8 @@ import { encodeRemoveSellersFromAllowList, encodeUpdateDisputeResolver } from "./interface"; -import { getDisputeResolverById } from "./subgraph"; +import { getDisputeResolverById, getSellerByAddress } from "./subgraph"; +import * as erc721Handler from "../erc721/handler"; import { CreateSellerArgs, UpdateSellerArgs, @@ -25,6 +32,75 @@ import { DisputeResolverUpdates } from "./types"; +export async function getSellersByAddressOrAuthToken(args: { + lensHubContractAddress?: string; + accountAddress: string; + web3Lib: Web3LibAdapter; + queryVars?: GetSellersQueryQueryVariables; + subgraphUrl: string; +}): Promise { + if (args.accountAddress === AddressZero) { + throw new Error(`Unsupported search address '${AddressZero}'`); + } + const seller = await getSellerByAddress( + args.subgraphUrl, + args.accountAddress, + args.queryVars + ); + if (!seller && args.lensHubContractAddress) { + // If seller is not found per address, try to find per authToken + const tokenType = AuthTokenType.LENS; // only LENS for now + const tokenIds = await fetchAuthTokensOfAccount(args); + const promises: Promise[] = []; + for (const tokenId of tokenIds) { + // Just in case the user owns several auth tokens + const sellerPromise = this.getSellerByAuthToken( + tokenId, + tokenType, + args.queryVars + ); + promises.push(sellerPromise); + } + return (await Promise.all(promises)).filter((seller) => !!seller); + } + return [seller].filter((seller) => !!seller); +} + +export async function fetchAuthTokensOfAccount(args: { + lensHubContractAddress?: string; + accountAddress: string; + tokenType: number; + web3Lib: Web3LibAdapter; +}): Promise> { + if (args.tokenType !== AuthTokenType.LENS) { + // only LENS for now + throw new Error(`Unsupported authTokenType '${args.tokenType}'`); + } + + if (!args.lensHubContractAddress) { + throw new Error("LENS contract is not configured in Core-SDK"); + } + + const balance = await erc721Handler.balanceOf({ + contractAddress: args.lensHubContractAddress, + owner: args.accountAddress, + web3Lib: args.web3Lib + }); + + const balanceBN = BigNumber.from(balance); + const tokenIdPromises: Promise[] = []; + for (let index = 0; balanceBN.gt(index); index++) { + const tokenIdPromise = erc721Handler.tokenOfOwnerByIndex({ + contractAddress: args.lensHubContractAddress, + owner: args.accountAddress, + index, + web3Lib: args.web3Lib + }); + tokenIdPromises.push(tokenIdPromise); + } + return Promise.all(tokenIdPromises); +} + export async function createSeller(args: { sellerToCreate: CreateSellerArgs; contractAddress: string; diff --git a/packages/core-sdk/src/accounts/subgraph.ts b/packages/core-sdk/src/accounts/subgraph.ts index a0e05b964..faf44cda3 100644 --- a/packages/core-sdk/src/accounts/subgraph.ts +++ b/packages/core-sdk/src/accounts/subgraph.ts @@ -1,3 +1,4 @@ +import { AuthTokenType } from "@bosonprotocol/common"; import { getSubgraphSdk } from "../utils/graphql"; import { BuyerFieldsFragment, @@ -137,6 +138,11 @@ export async function getSellerByAuthToken( tokenType: number, queryVars: GetSellersQueryQueryVariables = {} ): Promise { + if (tokenType !== AuthTokenType.LENS) { + // only LENS for now + throw new Error(`Unsupported authTokenType '${tokenType}'`); + } + const sellers = await getSellers(subgraphUrl, { sellersFilter: { ...queryVars.sellersFilter, diff --git a/packages/core-sdk/src/core-sdk.ts b/packages/core-sdk/src/core-sdk.ts index a88f0c4db..f64892688 100644 --- a/packages/core-sdk/src/core-sdk.ts +++ b/packages/core-sdk/src/core-sdk.ts @@ -278,73 +278,34 @@ export class CoreSDK { * @param queryVars - Optional query variables to skip, order or filter. * @returns Seller entity from subgraph. */ - public async getSellersByAddress( + public async getSellerByAddress( address: string, queryVars?: subgraph.GetSellersQueryQueryVariables - ): Promise { - if (address === AddressZero) { - throw new Error(`Unsupported search address '${AddressZero}'`); - } - const seller = await accounts.subgraph.getSellerByAddress( + ): Promise { + return accounts.subgraph.getSellerByAddress( this._subgraphUrl, address, queryVars ); - if (!seller && this._lensContracts?.LENS_HUB_CONTRACT) { - // If seller is not found per address, try to find per authToken - const tokenType = AuthTokenType.LENS; // only LENS for now - const tokenIds = await this.fetchUserAuthTokens(address, tokenType); - const promises: Promise[] = []; - for (const tokenId of tokenIds) { - // Just in case the user owns several auth tokens - const sellerPromise = this.getSellerByAuthToken( - tokenId, - tokenType, - queryVars - ); - promises.push(sellerPromise); - } - return (await Promise.all(promises)).filter((seller) => !!seller); - } - return [seller].filter((seller) => !!seller); } /** - * Returns the array of LENS tokenIds owned by a specified address + * Returns all seller entities from subgraph by either matching address or auth token. * @param address - Address of seller entity to query for. * @param queryVars - Optional query variables to skip, order or filter. - * @returns Array of tokenIds + * @returns Seller entity from subgraph. */ - public async fetchUserAuthTokens( + public async getSellersByAddressOrAuthToken( address: string, - tokenType: number - ): Promise> { - if (tokenType !== AuthTokenType.LENS) { - // only LENS for now - throw new Error(`Unsupported authTokenType '${tokenType}'`); - } - if (!this._lensContracts || !this._lensContracts?.LENS_HUB_CONTRACT) { - throw new Error("LENS contract is not configured in Core-SDK"); - } - const balance = await erc721.handler.balanceOf({ - contractAddress: this._lensContracts?.LENS_HUB_CONTRACT, - owner: address, - web3Lib: this._web3Lib + queryVars?: subgraph.GetSellersQueryQueryVariables + ): Promise { + return accounts.handler.getSellersByAddressOrAuthToken({ + lensHubContractAddress: this._lensContracts?.LENS_HUB_CONTRACT, + accountAddress: address, + web3Lib: this._web3Lib, + queryVars: queryVars, + subgraphUrl: this._subgraphUrl }); - - const balanceBN = BigNumber.from(balance); - const promises: Promise[] = []; - for (let index = 0; balanceBN.gt(index); index++) { - const tokenIdPromise = erc721.handler.tokenOfOwnerByIndex({ - contractAddress: this._lensContracts?.LENS_HUB_CONTRACT, - owner: address, - index, - web3Lib: this._web3Lib - }); - promises.push(tokenIdPromise); - } - const ret = await Promise.all(promises); - return ret; } /** @@ -359,10 +320,6 @@ export class CoreSDK { tokenType: number, queryVars?: subgraph.GetSellersQueryQueryVariables ): Promise { - if (tokenType !== AuthTokenType.LENS) { - // only LENS for now - throw new Error(`Unsupported authTokenType '${tokenType}'`); - } return accounts.subgraph.getSellerByAuthToken( this._subgraphUrl, tokenId, diff --git a/packages/core-sdk/tests/core-sdk.test.ts b/packages/core-sdk/tests/core-sdk.test.ts index fa4076c10..a0031bbe3 100644 --- a/packages/core-sdk/tests/core-sdk.test.ts +++ b/packages/core-sdk/tests/core-sdk.test.ts @@ -73,10 +73,6 @@ describe("#renderContractualAgreementForOffer()", () => { }); test("Not existing offer", async () => { - const mockedRawOfferFromSubgraph = mockRawOfferFromSubgraph({ - price: "100" + "0".repeat(18), - metadata: buildProductV1Metadata("{{priceValue}} {{exchangeTokenSymbol}}") - }); interceptSubgraph().reply(200, { data: { offer: null @@ -96,7 +92,7 @@ describe("#renderContractualAgreementForOffer()", () => { }); }); -describe("getSellersByAddress()", () => { +describe("getSellersByAddressOrAuthToken()", () => { test("shall fail if search address is ZERO_ADDRESS", async () => { const mockedRawSellerFromSubgraph = mockRawSellerFromSubgraph({ operator: ADDRESS @@ -115,7 +111,7 @@ describe("getSellersByAddress()", () => { }); expect(coreSDK).toBeInstanceOf(CoreSDK); await expect( - coreSDK.getSellersByAddress(ZERO_ADDRESS) + coreSDK.getSellersByAddressOrAuthToken(ZERO_ADDRESS) ).rejects.toThrowError( /^Unsupported search address '0x0000000000000000000000000000000000000000'/ ); From 9328ffe8fbe818051952e5339cd39cb76e983c6f Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Tue, 11 Oct 2022 11:32:56 +0200 Subject: [PATCH 3/6] fixup --- packages/core-sdk/src/accounts/handler.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core-sdk/src/accounts/handler.ts b/packages/core-sdk/src/accounts/handler.ts index 4b2ff459e..a401cc151 100644 --- a/packages/core-sdk/src/accounts/handler.ts +++ b/packages/core-sdk/src/accounts/handler.ts @@ -50,7 +50,10 @@ export async function getSellersByAddressOrAuthToken(args: { if (!seller && args.lensHubContractAddress) { // If seller is not found per address, try to find per authToken const tokenType = AuthTokenType.LENS; // only LENS for now - const tokenIds = await fetchAuthTokensOfAccount(args); + const tokenIds = await fetchAuthTokensOfAccount({ + ...args, + tokenType + }); const promises: Promise[] = []; for (const tokenId of tokenIds) { // Just in case the user owns several auth tokens From 197864a1363fee0cb19f47e4ff5aa90b5cf2020e Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Tue, 11 Oct 2022 11:33:50 +0200 Subject: [PATCH 4/6] fixup --- packages/react-kit/src/components/searchBar/SearchBar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-kit/src/components/searchBar/SearchBar.tsx b/packages/react-kit/src/components/searchBar/SearchBar.tsx index e5a351275..03fe3d104 100644 --- a/packages/react-kit/src/components/searchBar/SearchBar.tsx +++ b/packages/react-kit/src/components/searchBar/SearchBar.tsx @@ -74,7 +74,8 @@ export const SearchBar = ({ const sellerByIdPromise = coreSdk.getSellerById(value); - const sellerByAddressPromise = coreSdk.getSellersByAddress(value); + const sellerByAddressPromise = + coreSdk.getSellersByAddressOrAuthToken(value); const buyerByAddressPromise = coreSdk.getBuyers({ buyersFilter: { From be05ff4dd2fb4f0ccc06b3a6bcd517813f413e38 Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Tue, 11 Oct 2022 11:52:10 +0200 Subject: [PATCH 5/6] test: fix --- e2e/tests/accounts.test.ts | 10 +++------- e2e/tests/core-sdk.test.ts | 12 ++++-------- e2e/tests/productV1.test.ts | 8 ++------ packages/core-sdk/tests/accounts/subgraph.test.ts | 9 +++++++-- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/e2e/tests/accounts.test.ts b/e2e/tests/accounts.test.ts index 5240139dc..c1f44e01c 100644 --- a/e2e/tests/accounts.test.ts +++ b/e2e/tests/accounts.test.ts @@ -1,6 +1,4 @@ -import { utils, constants, Wallet } from "ethers"; - -import { CoreSDK } from "../../packages/core-sdk/src"; +import { utils, constants } from "ethers"; import { initCoreSDKWithFundedWallet, @@ -225,11 +223,10 @@ describe("CoreSDK - accounts", () => { }); test("add sellers", async () => { - const [sellers, { coreSDK, fundedWallet }] = await Promise.all([ + const [seller, { coreSDK, fundedWallet }] = await Promise.all([ ensureCreatedSeller(sellerWallet), initCoreSDKWithFundedWallet(protocolAdminWallet) ]); - const [seller] = sellers; const disputeResolverAddress = fundedWallet.address.toLowerCase(); const { disputeResolver } = await createDisputeResolver( @@ -265,11 +262,10 @@ describe("CoreSDK - accounts", () => { }); test("remove sellers", async () => { - const [sellers, { coreSDK, fundedWallet }] = await Promise.all([ + const [seller, { coreSDK, fundedWallet }] = await Promise.all([ ensureCreatedSeller(sellerWallet), initCoreSDKWithFundedWallet(protocolAdminWallet) ]); - const [seller] = sellers; const disputeResolverAddress = fundedWallet.address.toLowerCase(); const { disputeResolver: disputeResolverBeforeUpdate } = diff --git a/e2e/tests/core-sdk.test.ts b/e2e/tests/core-sdk.test.ts index bcfed825a..c057ed480 100644 --- a/e2e/tests/core-sdk.test.ts +++ b/e2e/tests/core-sdk.test.ts @@ -92,8 +92,7 @@ describe("core-sdk", () => { const { coreSDK, fundedWallet } = await initCoreSDKWithFundedWallet( seedWallet ); - const sellers = await ensureCreatedSeller(fundedWallet); - const [seller] = sellers; + const seller = await ensureCreatedSeller(fundedWallet); const funds = await depositFunds({ coreSDK, @@ -113,8 +112,7 @@ describe("core-sdk", () => { const { coreSDK, fundedWallet } = await initCoreSDKWithFundedWallet( seedWallet ); - const sellers = await ensureCreatedSeller(fundedWallet); - const [seller] = sellers; + const seller = await ensureCreatedSeller(fundedWallet); await ensureMintedAndAllowedTokens([fundedWallet], sellerFundsDeposit); @@ -312,8 +310,7 @@ describe("core-sdk", () => { const { coreSDK, fundedWallet } = await initCoreSDKWithFundedWallet( seedWallet ); - const sellers = await ensureCreatedSeller(fundedWallet); - const [seller] = sellers; + const seller = await ensureCreatedSeller(fundedWallet); const funds = await depositFunds({ coreSDK, @@ -341,8 +338,7 @@ describe("core-sdk", () => { const { coreSDK, fundedWallet } = await initCoreSDKWithFundedWallet( seedWallet ); - const sellers = await ensureCreatedSeller(fundedWallet); - const [seller] = sellers; + const seller = await ensureCreatedSeller(fundedWallet); const ethFunds = await depositFunds({ coreSDK, diff --git a/e2e/tests/productV1.test.ts b/e2e/tests/productV1.test.ts index 26b0a6cb5..85b87cd4e 100644 --- a/e2e/tests/productV1.test.ts +++ b/e2e/tests/productV1.test.ts @@ -3,10 +3,7 @@ import { BigNumber } from "@ethersproject/bignumber"; import { parseEther } from "@ethersproject/units"; import { MetadataType } from "@bosonprotocol/metadata"; import { CreateOfferArgs } from "@bosonprotocol/common"; -import { - mockAdditionalOfferMetadata, - mockCreateOfferArgs -} from "@bosonprotocol/common/tests/mocks"; +import { mockCreateOfferArgs } from "@bosonprotocol/common/tests/mocks"; import { ProductV1Metadata } from "@bosonprotocol/metadata/dist/cjs/product-v1"; import { Wallet } from "ethers"; import { CoreSDK, subgraph } from "../../packages/core-sdk/src"; @@ -70,8 +67,7 @@ async function createOffer( sellerWallet: Wallet, offerArgs: CreateOfferArgs ) { - const sellers = await ensureCreatedSeller(sellerWallet); - const [seller] = sellers; + const seller = await ensureCreatedSeller(sellerWallet); // Check the disputeResolver exists and is active const disputeResolverId = offerArgs.disputeResolverId; diff --git a/packages/core-sdk/tests/accounts/subgraph.test.ts b/packages/core-sdk/tests/accounts/subgraph.test.ts index 67003074e..694412b0b 100644 --- a/packages/core-sdk/tests/accounts/subgraph.test.ts +++ b/packages/core-sdk/tests/accounts/subgraph.test.ts @@ -8,6 +8,7 @@ import { interceptSubgraph, mockRawSellerFromSubgraph } from "../mocks"; +import { AuthTokenType } from "@bosonprotocol/common"; describe("#getSellerByAddress()", () => { test("return falsy if address no seller", async () => { @@ -145,7 +146,7 @@ describe("#getSellerByAddress()", () => { operator: ADDRESS, treasury: ADDRESS, authTokenId: tokenId, - authTokenType: 1 + authTokenType: AuthTokenType.LENS }); interceptSubgraph() .times(5) @@ -155,7 +156,11 @@ describe("#getSellerByAddress()", () => { } }); - const rawSeller = await getSellerByAuthToken(SUBGRAPH_URL, tokenId, 1); + const rawSeller = await getSellerByAuthToken( + SUBGRAPH_URL, + tokenId, + AuthTokenType.LENS + ); expect(rawSeller).toMatchObject(mockedRawSellerFromSubgraph); }); From bee26954b73587ed779dd2ee864c2d9785c86657 Mon Sep 17 00:00:00 2001 From: Dong-Ha Kim Date: Tue, 11 Oct 2022 12:31:27 +0200 Subject: [PATCH 6/6] fixup --- packages/core-sdk/src/accounts/handler.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/core-sdk/src/accounts/handler.ts b/packages/core-sdk/src/accounts/handler.ts index a401cc151..270015a61 100644 --- a/packages/core-sdk/src/accounts/handler.ts +++ b/packages/core-sdk/src/accounts/handler.ts @@ -22,7 +22,11 @@ import { encodeRemoveSellersFromAllowList, encodeUpdateDisputeResolver } from "./interface"; -import { getDisputeResolverById, getSellerByAddress } from "./subgraph"; +import { + getDisputeResolverById, + getSellerByAddress, + getSellerByAuthToken +} from "./subgraph"; import * as erc721Handler from "../erc721/handler"; import { CreateSellerArgs, @@ -57,7 +61,8 @@ export async function getSellersByAddressOrAuthToken(args: { const promises: Promise[] = []; for (const tokenId of tokenIds) { // Just in case the user owns several auth tokens - const sellerPromise = this.getSellerByAuthToken( + const sellerPromise = getSellerByAuthToken( + args.subgraphUrl, tokenId, tokenType, args.queryVars