Skip to content

Commit

Permalink
chore: revamp RPC starkNet_getTransactionStatus (#447)
Browse files Browse the repository at this point in the history
* chore: add chain rpc controller

* chore: relocate base rpc controller

* chore: revamp getTransactionStatus API

* chore: update get transaction status code

* chore: remove mocha test

* chore: remove get transactions test
  • Loading branch information
stanleyyconsensys authored Dec 2, 2024
1 parent 464d65c commit 5d569a8
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 384 deletions.
35 changes: 0 additions & 35 deletions packages/starknet-snap/src/getTransactionStatus.ts

This file was deleted.

7 changes: 5 additions & 2 deletions packages/starknet-snap/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { getStoredNetworks } from './getStoredNetworks';
import { getStoredTransactions } from './getStoredTransactions';
import { getStoredUserAccounts } from './getStoredUserAccounts';
import { getTransactions } from './getTransactions';
import { getTransactionStatus } from './getTransactionStatus';
import { getValue } from './getValue';
import { homePageController } from './on-home-page';
import { recoverAccounts } from './recoverAccounts';
Expand All @@ -39,6 +38,7 @@ import type {
GetDeploymentDataParams,
DeclareContractParams,
WatchAssetParams,
GetTransactionStatusParams,
} from './rpcs';
import {
displayPrivateKey,
Expand All @@ -52,6 +52,7 @@ import {
switchNetwork,
getDeploymentData,
watchAsset,
getTransactionStatus,
} from './rpcs';
import { signDeployAccountTransaction } from './signDeployAccountTransaction';
import type {
Expand Down Expand Up @@ -201,7 +202,9 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
return await getErc20TokenBalance(apiParams);

case 'starkNet_getTransactionStatus':
return await getTransactionStatus(apiParams);
return await getTransactionStatus.execute(
apiParams.requestParams as unknown as GetTransactionStatusParams,
);

case 'starkNet_getValue':
return await getValue(apiParams);
Expand Down
74 changes: 74 additions & 0 deletions packages/starknet-snap/src/rpcs/get-transaction-status.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { constants } from 'starknet';
import {
TransactionExecutionStatus,
TransactionFinalityStatus,
} from 'starknet';

import { mockNetworkStateManager } from '../state/__tests__/helper';
import type { Network } from '../types/snapState';
import { STARKNET_SEPOLIA_TESTNET_NETWORK } from '../utils/constants';
import { InvalidRequestParamsError } from '../utils/exceptions';
import * as starknetUtils from '../utils/starknetUtils';
import type { GetTransactionStatusParams } from './get-transaction-status';
import { getTransactionStatus } from './get-transaction-status';

jest.mock('../utils/snap');
jest.mock('../utils/logger');

describe('GetTransactionStatusRpc', () => {
const prepareGetTransactionStatusTest = ({
network,
status,
}: {
network: Network;
status: {
finalityStatus: TransactionFinalityStatus;
executionStatus: TransactionExecutionStatus;
};
}) => {
const { getNetworkSpy } = mockNetworkStateManager(network);

const getTransactionStatusSpy = jest.spyOn(
starknetUtils,
'getTransactionStatus',
);

getTransactionStatusSpy.mockResolvedValue(status);

return {
getTransactionStatusSpy,
getNetworkSpy,
};
};

it('returns transaction status', async () => {
const network = STARKNET_SEPOLIA_TESTNET_NETWORK;
const transactionHash =
'0x06385d46da9fbed4a5798298b17df069ac5f786e4c9f8f6b81c665540aea245a';
const expectedResult = {
finalityStatus: TransactionFinalityStatus.ACCEPTED_ON_L1,
executionStatus: TransactionExecutionStatus.SUCCEEDED,
};
const { getTransactionStatusSpy } = prepareGetTransactionStatusTest({
network,
status: expectedResult,
});

const result = await getTransactionStatus.execute({
chainId: network.chainId as unknown as constants.StarknetChainId,
transactionHash,
});

expect(result).toStrictEqual(expectedResult);
expect(getTransactionStatusSpy).toHaveBeenCalledWith(
transactionHash,
network,
);
});

it('throws `InvalidRequestParamsError` when request parameter is not correct', async () => {
await expect(
getTransactionStatus.execute({} as unknown as GetTransactionStatusParams),
).rejects.toThrow(InvalidRequestParamsError);
});
});
69 changes: 69 additions & 0 deletions packages/starknet-snap/src/rpcs/get-transaction-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { HexStruct } from '@metamask/utils';
import {
TransactionExecutionStatus,
TransactionFinalityStatus,
} from 'starknet';
import type { Infer } from 'superstruct';
import { assign, nonempty, object, enums, optional } from 'superstruct';

import { BaseRequestStruct } from '../utils';
import { getTransactionStatus as getTransactionStatusFn } from '../utils/starknetUtils';
import { ChainRpcController } from './abstract/chain-rpc-controller';

export const GetTransactionStatusRequestStruct = assign(
object({
transactionHash: nonempty(HexStruct),
}),
BaseRequestStruct,
);

export const GetTransactionStatusResponseStruct = object({
executionStatus: optional(enums(Object.values(TransactionExecutionStatus))),
finalityStatus: optional(enums(Object.values(TransactionFinalityStatus))),
});

export type GetTransactionStatusParams = Infer<
typeof GetTransactionStatusRequestStruct
>;

export type GetTransactionStatusResponse = Infer<
typeof GetTransactionStatusResponseStruct
>;

/**
* The RPC handler to get a transaction status by the given transaction hash.
*/
export class GetTransactionStatusRpc extends ChainRpcController<
GetTransactionStatusParams,
GetTransactionStatusResponse
> {
protected requestStruct = GetTransactionStatusRequestStruct;

protected responseStruct = GetTransactionStatusResponseStruct;

/**
* Execute the get transaction request handler.
*
* @param params - The parameters of the request.
* @param params.transactionHash - The transaction hash to enquire the transaction status.
* @param params.chainId - The chain id of the transaction.
* @returns A promise that resolves to a GetTransactionStatusResponse object that contains executionStatus and finalityStatus.
*/
async execute(
params: GetTransactionStatusParams,
): Promise<GetTransactionStatusResponse> {
return super.execute(params);
}

protected async handleRequest(
params: GetTransactionStatusParams,
): Promise<GetTransactionStatusResponse> {
const { transactionHash } = params;

const resp = await getTransactionStatusFn(transactionHash, this.network);

return resp;
}
}

export const getTransactionStatus = new GetTransactionStatusRpc();
1 change: 1 addition & 0 deletions packages/starknet-snap/src/rpcs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './verify-signature';
export * from './switch-network';
export * from './get-deployment-data';
export * from './watch-asset';
export * from './get-transaction-status';
6 changes: 4 additions & 2 deletions packages/starknet-snap/src/types/snapApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type {
EstimateFeeDetails,
DeployAccountSignerDetails,
constants,
TransactionExecutionStatus,
TransactionFinalityStatus,
} from 'starknet';

import type { SnapState, VoyagerTransactionType } from './snapState';
Expand Down Expand Up @@ -152,8 +154,8 @@ export type DeclareContractRequestParams = {
} & BaseRequestParams;

export type RpcV4GetTransactionReceiptResponse = {
execution_status?: string;
finality_status?: string;
execution_status?: TransactionExecutionStatus;
finality_status?: TransactionFinalityStatus;
};

export type Authorizable = {
Expand Down
69 changes: 0 additions & 69 deletions packages/starknet-snap/test/src/getTransactionStatus.test.ts

This file was deleted.

Loading

0 comments on commit 5d569a8

Please sign in to comment.