diff --git a/packages/common/src/types/web3-lib-adapter.ts b/packages/common/src/types/web3-lib-adapter.ts index b490aaffb..ad51ae57d 100644 --- a/packages/common/src/types/web3-lib-adapter.ts +++ b/packages/common/src/types/web3-lib-adapter.ts @@ -17,6 +17,7 @@ export type TransactionRequest = Partial<{ export type TransactionResponse = { hash: string; + nonce?: number; wait: (confirmations?: number) => Promise; }; diff --git a/packages/core-sdk/src/accounts/handler.ts b/packages/core-sdk/src/accounts/handler.ts index fadd743b0..df4c247ab 100644 --- a/packages/core-sdk/src/accounts/handler.ts +++ b/packages/core-sdk/src/accounts/handler.ts @@ -1,7 +1,8 @@ import { Web3LibAdapter, TransactionResponse, - utils + utils, + TransactionRequest } from "@bosonprotocol/common"; import { BigNumberish } from "@ethersproject/bignumber"; import { DisputeResolverFieldsFragment } from "../subgraph"; @@ -40,23 +41,31 @@ export async function createSeller(args: { }); } -export async function updateSeller(args: { - sellerUpdates: UpdateSellerArgs; - contractAddress: string; - web3Lib: Web3LibAdapter; -}): Promise { +export async function updateSeller( + args: { + sellerUpdates: UpdateSellerArgs; + contractAddress: string; + web3Lib: Web3LibAdapter; + }, + txParams: TransactionRequest = {} +): Promise { return args.web3Lib.sendTransaction({ + ...txParams, to: args.contractAddress, data: encodeUpdateSeller(args.sellerUpdates) }); } -export async function optInToSellerUpdate(args: { - sellerUpdates: OptInToSellerUpdateArgs; - contractAddress: string; - web3Lib: Web3LibAdapter; -}): Promise { +export async function optInToSellerUpdate( + args: { + sellerUpdates: OptInToSellerUpdateArgs; + contractAddress: string; + web3Lib: Web3LibAdapter; + }, + txParams: TransactionRequest = {} +): Promise { return args.web3Lib.sendTransaction({ + ...txParams, to: args.contractAddress, data: encodeOptInToSellerUpdate(args.sellerUpdates) }); diff --git a/packages/core-sdk/src/accounts/mixin.ts b/packages/core-sdk/src/accounts/mixin.ts index 930968d93..2b5001660 100644 --- a/packages/core-sdk/src/accounts/mixin.ts +++ b/packages/core-sdk/src/accounts/mixin.ts @@ -2,7 +2,12 @@ import { BaseCoreSDK } from "./../mixins/base-core-sdk"; import * as accounts from "."; import * as subgraph from "../subgraph"; import * as erc721 from "../erc721"; -import { AuthTokenType, TransactionResponse, Log } from "@bosonprotocol/common"; +import { + AuthTokenType, + TransactionResponse, + Log, + TransactionRequest +} from "@bosonprotocol/common"; import { BigNumberish, BigNumber } from "@ethersproject/bignumber"; import { AddressZero } from "@ethersproject/constants"; import { offers, orchestration } from ".."; @@ -265,13 +270,17 @@ export class AccountsMixin extends BaseCoreSDK { sellerUpdates: accounts.UpdateSellerArgs, overrides: Partial<{ contractAddress: string; + txParams: TransactionRequest; }> = {} ): Promise { - return accounts.handler.updateSeller({ - sellerUpdates, - web3Lib: this._web3Lib, - contractAddress: overrides.contractAddress || this._protocolDiamond - }); + return accounts.handler.updateSeller( + { + sellerUpdates, + web3Lib: this._web3Lib, + contractAddress: overrides.contractAddress || this._protocolDiamond + }, + overrides.txParams + ); } /** @@ -285,13 +294,17 @@ export class AccountsMixin extends BaseCoreSDK { sellerUpdates: accounts.OptInToSellerUpdateArgs, overrides: Partial<{ contractAddress: string; + txParams: TransactionRequest; }> = {} ): Promise { - return accounts.handler.optInToSellerUpdate({ - sellerUpdates, - web3Lib: this._web3Lib, - contractAddress: overrides.contractAddress || this._protocolDiamond - }); + return accounts.handler.optInToSellerUpdate( + { + sellerUpdates, + web3Lib: this._web3Lib, + contractAddress: overrides.contractAddress || this._protocolDiamond + }, + overrides.txParams + ); } /** @@ -306,9 +319,14 @@ export class AccountsMixin extends BaseCoreSDK { sellerUpdates: accounts.UpdateSellerArgs, overrides: Partial<{ contractAddress: string; - }> = {} + txParams: TransactionRequest; + }> = {}, + updateSellerCallback?: (TransactionResponse) => void ): Promise { const updateTx = await this.updateSeller(sellerUpdates, overrides); + if (updateSellerCallback) { + updateSellerCallback(updateTx); + } const txReceipt = await updateTx.wait(); const pendingSellerUpdate = this.getPendingSellerUpdateFromLogs( txReceipt.logs @@ -332,16 +350,19 @@ export class AccountsMixin extends BaseCoreSDK { fieldsToUpdate.admin || fieldsToUpdate.authToken ) { - return this.optInToSellerUpdate({ - id: sellerUpdates.id, - fieldsToUpdate: { - operator: - currentAccount === pendingSellerUpdate.operator.toLowerCase(), - clerk: currentAccount === pendingSellerUpdate.clerk.toLowerCase(), - admin: currentAccount === pendingSellerUpdate.admin.toLowerCase(), - authToken: pendingSellerUpdate.tokenType !== AuthTokenType.NONE - } - }); + return this.optInToSellerUpdate( + { + id: sellerUpdates.id, + fieldsToUpdate: { + operator: + currentAccount === pendingSellerUpdate.operator.toLowerCase(), + clerk: currentAccount === pendingSellerUpdate.clerk.toLowerCase(), + admin: currentAccount === pendingSellerUpdate.admin.toLowerCase(), + authToken: pendingSellerUpdate.tokenType !== AuthTokenType.NONE + } + }, + overrides + ); } // If there is nothing to optIn from the current account, then return the response from updateSeller return updateTx; diff --git a/packages/eth-connect-sdk/src/eth-connect-adapter.ts b/packages/eth-connect-sdk/src/eth-connect-adapter.ts index 881f155a0..bd9b8a517 100644 --- a/packages/eth-connect-sdk/src/eth-connect-adapter.ts +++ b/packages/eth-connect-sdk/src/eth-connect-adapter.ts @@ -75,6 +75,7 @@ export class EthConnectAdapter implements Web3LibAdapter { EthConnectAdapter.receiptData.set(txHash, receiptData); return { hash: txHash, + nonce: transactionRequest.nonce, wait: async (confirmations?: number) => this._wait(txHash, receiptData) }; } diff --git a/scripts/update-seller.ts b/scripts/update-seller.ts index e7ea7c0e6..a92961771 100644 --- a/scripts/update-seller.ts +++ b/scripts/update-seller.ts @@ -1,7 +1,7 @@ import { AddressZero } from "@ethersproject/constants"; import fs from "fs"; import { EnvironmentType } from "@bosonprotocol/common/src/types/configs"; -import { providers, Contract, Wallet } from "ethers"; +import { providers, Contract, Wallet, utils } from "ethers"; import { program } from "commander"; import { getDefaultConfig, UpdateSellerArgs } from "@bosonprotocol/common/src"; import { CoreSDK } from "../packages/core-sdk/src"; @@ -17,6 +17,9 @@ program ) .option("-d, --data ", "JSON file with the Seller parameters") .option("-e, --env ", "Target environment", "testing") + .option("--gasLimit ", "gas limit") + .option("--gasPrice ", "gas price en gwei") + .option("--nonce ", "gas price en gwei") .option("--id ", "SellerId") .option("--admin ", "New admin address") .option("--treasury ", "New treasury address") @@ -40,6 +43,21 @@ async function main() { const web3Provider = new providers.JsonRpcProvider(defaultConfig.jsonRpcUrl); const sellerWallet = new Wallet(sellerPrivateKey); + let txParams; + if (opts.gasPrice || opts.gasLimit || opts.nonce) { + const nonce = opts.nonce ? parseInt(opts.nonce) : undefined; + if (nonce && isNaN(nonce)) { + throw `Invalid number value '${opts.nonce}' for 'nonce'`; + } + txParams = { + gasPrice: opts.gasPrice + ? utils.parseUnits(opts.gasPrice, "gwei") + : undefined, + gasLimit: opts.gasLimit ?? undefined, + nonce: nonce ?? undefined + }; + } + let sellerDataJson = {} as UpdateSellerArgs; if (opts.data) { const rawData = fs.readFileSync(opts.data); @@ -143,8 +161,18 @@ async function main() { }); console.log(`Updating seller on env ${envName} on chain ${chainId}...`); - const txResponse1 = await coreSDK.updateSellerAndOptIn(sellerDataJson); - console.log(`Tx hash: ${txResponse1.hash}`); + const txResponse1 = await coreSDK.updateSellerAndOptIn( + sellerDataJson, + { + txParams + }, + (updateTx) => { + console.log( + `Update seller tx hash: ${updateTx.hash}, nonce: ${updateTx.nonce}` + ); + } + ); + console.log(`Tx hash: ${txResponse1.hash}, nonce: ${txResponse1.nonce}`); const txReceipt1 = await txResponse1.wait(); const pendingSellerUpdate = coreSDK.getPendingSellerUpdateFromLogs( txReceipt1.logs @@ -178,10 +206,15 @@ async function main() { )}` ); txOptIns.push( - await optInSigner.sdk.optInToSellerUpdate({ - id: sellerDataJson.id, - fieldsToUpdate: optInSigner.fields - }) + await optInSigner.sdk.optInToSellerUpdate( + { + id: sellerDataJson.id, + fieldsToUpdate: optInSigner.fields + }, + { + txParams + } + ) ); } }