Skip to content

Commit

Permalink
feat: added onBeforeSend hook to the connector interface (#3487)
Browse files Browse the repository at this point in the history
* chore: include beforesign workaround

* chore

* chore: changeset

* lint: minor linting fixes

* chore: accept promise as callback

* feat: skip custom fee

* feat: sip custom fee on contract call

* Revert "feat: sip custom fee on contract call"

This reverts commit 760bf3b.

* chore: finalized connector changes

* Disable PR release

* chore: refactored interface

---------

Co-authored-by: LuizAsFight <[email protected]>
Co-authored-by: chad <[email protected]>
Co-authored-by: Nelito Junior <[email protected]>
Co-authored-by: Anderson Arboleya <[email protected]>
  • Loading branch information
5 people authored Jan 10, 2025
1 parent 3707dc6 commit 0f138cd
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 11 deletions.
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 = {}
): 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);
});
});

0 comments on commit 0f138cd

Please sign in to comment.