Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added onBeforeSend hook to the connector interface #3487

Merged
merged 18 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sharp-islands-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

feat: added `onBeforeSend` hook to the connector interface
13 changes: 9 additions & 4 deletions packages/account/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { BytesLike } from '@fuel-ts/utils';
import { arrayify, hexlify, isDefined } from '@fuel-ts/utils';
import { clone } from 'ramda';

import type { FuelConnector } from './connectors';
import type { FuelConnector, FuelConnectorSendTxParams } from './connectors';
import type {
TransactionRequest,
CoinQuantityLike,
Expand All @@ -23,14 +23,14 @@ import type {
EstimateTransactionParams,
CursorPaginationArgs,
TransactionRequestLike,
ProviderSendTxParams,
CallResult,
GetCoinsResponse,
GetMessagesResponse,
GetBalancesResponse,
Coin,
TransactionCostParams,
TransactionResponse,
ProviderSendTxParams,
} from './providers';
import {
withdrawScript,
Expand Down Expand Up @@ -66,6 +66,8 @@ export type ContractTransferParams = {
assetId: BytesLike;
};

export type AccountSendTxParams = ProviderSendTxParams & FuelConnectorSendTxParams;

export type EstimatedTxParams = Pick<
TransactionCost,
'estimatedPredicates' | 'addedSignatures' | 'requiredQuantities' | 'updateMaxFee' | 'gasPrice'
Expand Down Expand Up @@ -649,11 +651,14 @@ export class Account extends AbstractAccount implements WithAddress {
*/
async sendTransaction(
transactionRequestLike: TransactionRequestLike,
{ estimateTxDependencies = true }: ProviderSendTxParams = {}
{ estimateTxDependencies = true, onBeforeSend, skipCustomFee = false }: AccountSendTxParams = {}
petertonysmith94 marked this conversation as resolved.
Show resolved Hide resolved
): Promise<TransactionResponse> {
if (this._connector) {
return this.provider.getTransactionResponse(
await this._connector.sendTransaction(this.address.toString(), transactionRequestLike)
await this._connector.sendTransaction(this.address.toString(), transactionRequestLike, {
onBeforeSend,
skipCustomFee,
})
);
}
const transactionRequest = transactionRequestify(transactionRequestLike);
Expand Down
15 changes: 12 additions & 3 deletions packages/account/src/connectors/fuel-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {
FuelEventArg,
Version,
SelectNetworkArguments,
FuelConnectorSendTxParams,
} from './types';

interface Connector {
Expand Down Expand Up @@ -42,7 +43,11 @@ interface Connector {
signTransaction(address: string, transaction: TransactionRequestLike): Promise<string>;
// #endregion fuel-connector-method-signTransaction
// #region fuel-connector-method-sendTransaction
sendTransaction(address: string, transaction: TransactionRequestLike): Promise<string>;
sendTransaction(
address: string,
transaction: TransactionRequestLike,
params?: FuelConnectorSendTxParams
): Promise<string>;
// #endregion fuel-connector-method-sendTransaction
// #region fuel-connector-method-currentAccount
currentAccount(): Promise<string | null>;
Expand Down Expand Up @@ -193,10 +198,14 @@ export abstract class FuelConnector extends EventEmitter implements Connector {
*
* @param address - The address to sign the transaction
* @param transaction - The transaction to send
*
* @param params - Optional parameters to send the transaction
* @returns The transaction id
*/
async sendTransaction(_address: string, _transaction: TransactionRequestLike): Promise<string> {
async sendTransaction(
_address: string,
_transaction: TransactionRequestLike,
_params?: FuelConnectorSendTxParams
): Promise<string> {
throw new FuelError(FuelError.CODES.NOT_IMPLEMENTED, 'Method not implemented.');
}

Expand Down
10 changes: 10 additions & 0 deletions packages/account/src/connectors/types/data-type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { JsonAbi } from '@fuel-ts/abi-coder';
import type { RequireAtLeastOne } from 'type-fest';

import type { TransactionRequest } from '../../providers';

/**
* @name Version
*/
Expand Down Expand Up @@ -42,3 +44,11 @@ export type SelectNetworkArguments = RequireAtLeastOne<Network, 'chainId' | 'url
* Read more at: https://docs.fuel.network/docs/specs/abi/json-abi-format/
*/
export type FuelABI = JsonAbi;

/**
* Params for the sendTransaction method (for connectors).
*/
export type FuelConnectorSendTxParams = {
skipCustomFee?: boolean;
onBeforeSend?: (txRequest: TransactionRequest) => Promise<TransactionRequest>;
};
9 changes: 7 additions & 2 deletions packages/account/test/fixtures/mocked-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
ConnectorMetadata,
Network,
SelectNetworkArguments,
AccountSendTxParams,
} from '../../src';
import { FuelConnector } from '../../src/connectors/fuel-connector';
import { FuelConnectorEventTypes } from '../../src/connectors/types';
Expand Down Expand Up @@ -105,12 +106,16 @@ export class MockConnector extends FuelConnector {
return wallet.signMessage(_message);
}

override async sendTransaction(_address: string, _transaction: TransactionRequestLike) {
override async sendTransaction(
_address: string,
_transaction: TransactionRequestLike,
_params: AccountSendTxParams
) {
const wallet = this._wallets.find((w) => w.address.toString() === _address);
if (!wallet) {
throw new Error('Wallet is not found!');
}
const { id } = await wallet.sendTransaction(_transaction);
const { id } = await wallet.sendTransaction(_transaction, _params);
return id;
}

Expand Down
39 changes: 37 additions & 2 deletions packages/account/test/fuel-wallet-connector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import type { BytesLike } from '@fuel-ts/utils';
import { TESTNET_NETWORK_URL } from '@internal/utils';
import { EventEmitter } from 'events';

import type { Network, ProviderOptions, SelectNetworkArguments } from '../src';
import type { AccountSendTxParams, Network, ProviderOptions, SelectNetworkArguments } from '../src';
import { Fuel } from '../src/connectors/fuel';
import { FuelConnectorEventType } from '../src/connectors/types';
import { Provider, TransactionStatus } from '../src/providers';
import { Provider, ScriptTransactionRequest, TransactionStatus } from '../src/providers';
import { setupTestProviderAndWallets, TestMessage } from '../src/test-utils';
import { Wallet } from '../src/wallet';

Expand Down Expand Up @@ -669,4 +669,39 @@ describe('Fuel Connector', () => {
new FuelError(ErrorCode.INVALID_PROVIDER, 'Provider is not valid.')
);
});

it('should ensure sendTransaction works just fine', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider,
wallets: [connectorWallet],
} = launched;
const connector = new MockConnector({
wallets: [connectorWallet],
});
const fuel = await new Fuel({
connectors: [connector],
});

const sendTransactionSpy = vi.spyOn(connectorWallet, 'sendTransaction');

const request = new ScriptTransactionRequest();
const resources = await connectorWallet.getResourcesToSpend([
{ assetId: await provider.getBaseAssetId(), amount: 1000 },
]);
request.addResources(resources);
await request.autoCost(connectorWallet);

const params: AccountSendTxParams = {
onBeforeSend: vi.fn(),
skipCustomFee: true,
};
const response = await fuel.sendTransaction(
connectorWallet.address.toString(),
request,
params
);
expect(response).toBeDefined();
expect(sendTransactionSpy).toHaveBeenCalledWith(request, params);
});
});
Loading