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: adopt fee token selection dialog in RPC starkNet_executeTxn #419

Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
6bfdbfc
chore: add jsx support in snap
khanti42 Nov 6, 2024
76ae1eb
chore: add jsx support in snap
khanti42 Nov 6, 2024
065bf13
Merge branch 'feat/sf-705-add-jsx-support' into feat/sf-715-jsx-suppo…
khanti42 Nov 6, 2024
6cd5cd2
feat: jsx support management
khanti42 Nov 6, 2024
64e7d08
feat: common jsx components and fragments
khanti42 Nov 6, 2024
db7eafb
chore: fix test and lint
khanti42 Nov 6, 2024
f1976b8
Merge branch 'feat/sf-715-jsx-support-detection' into feat/sf-706-add…
khanti42 Nov 7, 2024
9db1d65
Merge branch 'main' into feat/sf-706-add-common-jsx-component
khanti42 Nov 10, 2024
a0de84b
feat: add interactive-ui for execute txn
khanti42 Nov 11, 2024
ce79daa
fix: add mutex in jsx support detection mechanism
khanti42 Nov 11, 2024
313eeac
Merge branch 'feat/sf-715-jsx-support-detection' into feat/sf-712-int…
khanti42 Nov 11, 2024
a37c70b
chore: fixture request addapted
khanti42 Nov 11, 2024
550bdb5
chore: ensure test pass
khanti42 Nov 11, 2024
069bfaa
Merge branch 'feat/sf-715-jsx-support-detection' into feat/sf-712-int…
khanti42 Nov 11, 2024
184d775
chore: lint
khanti42 Nov 11, 2024
62f1b43
feat: add interactive-ui in execute txn
khanti42 Nov 11, 2024
05e56c5
chore: remove console.log
khanti42 Nov 11, 2024
41a9469
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 11, 2024
70799fc
chore: missing helper in tests
khanti42 Nov 11, 2024
0bf7e56
chore: lint
khanti42 Nov 11, 2024
5b41514
chore: rollback jsx support detection not here
khanti42 Nov 14, 2024
38ab576
Merge branch 'feat/sf-706-add-common-jsx-component' into feat/sf-712-…
khanti42 Nov 14, 2024
dee34b9
chore: rollback index.tsx
khanti42 Nov 14, 2024
a37ba1b
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 14, 2024
eb772f4
Merge branch 'main' into feat/sf-705-add-jsx-support
khanti42 Nov 18, 2024
98deefe
chore: fix comment
khanti42 Nov 18, 2024
4057e3d
Merge branch 'feat/sf-705-add-jsx-support' into feat/sf-706-add-commo…
khanti42 Nov 18, 2024
30d061d
chore: fix comments
khanti42 Nov 18, 2024
73eaef9
chore: fix comments
khanti42 Nov 18, 2024
6016268
Merge branch 'feat/sf-706-add-common-jsx-component' into feat/sf-712-…
khanti42 Nov 18, 2024
b6760b7
chore: update yarn.lock
khanti42 Nov 18, 2024
fa2ae20
Merge branch 'feat/sf-705-add-jsx-support' into feat/sf-706-add-commo…
khanti42 Nov 18, 2024
7f3e73b
chore: update yarn.lock
khanti42 Nov 18, 2024
3ae1dee
Merge branch 'feat/sf-706-add-common-jsx-component' into feat/sf-712-…
khanti42 Nov 18, 2024
6e74bfb
feat: update wallet-ui message
khanti42 Nov 18, 2024
f71eb18
Merge branch 'feat/snap-fee-token-selection' into feat/sf-712-interac…
khanti42 Nov 18, 2024
f1bde36
chore: update yarn.lock
khanti42 Nov 18, 2024
da25436
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
67c3ee3
Merge branch 'feat/wallet-ui-update-unsupported-version-message' into…
khanti42 Nov 18, 2024
ab257a4
chore: rebase wallet-ui changes happening elsewhere
khanti42 Nov 18, 2024
0f2a283
chore: rebase wallet-ui changes happening elsewhere
khanti42 Nov 18, 2024
5987efc
chore: fix comments
khanti42 Nov 18, 2024
940ca47
chore: fix comments
khanti42 Nov 18, 2024
23ccced
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
1e589dd
fix: formatter-utils
khanti42 Nov 18, 2024
e956cc9
chore: fix comments
khanti42 Nov 18, 2024
aa43464
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
f9c95c0
chore: fix comments
khanti42 Nov 18, 2024
e0f6468
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
092d8f4
chore: lint
khanti42 Nov 18, 2024
3e0b92a
chore: lint
khanti42 Nov 18, 2024
000e933
chore: fix comments
khanti42 Nov 18, 2024
b2a16f1
chore: fix comments
khanti42 Nov 18, 2024
053d479
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
f4c75ea
chore: fix comments
khanti42 Nov 18, 2024
7e0db91
chore: fix comments
khanti42 Nov 18, 2024
f338c54
chore: removed utils
khanti42 Nov 18, 2024
3cf9077
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 18, 2024
02e9551
fix: implement comments
khanti42 Nov 19, 2024
c3f2059
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
b8073fd
fix: implement comments
khanti42 Nov 19, 2024
0120f8f
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
80a8fdb
chore: fix comments
khanti42 Nov 19, 2024
ea934df
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
8f7d915
chore: fix comments
khanti42 Nov 19, 2024
8c1b05b
Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx
khanti42 Nov 19, 2024
3d5bea2
Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx
khanti42 Nov 19, 2024
570ee93
Update packages/starknet-snap/src/ui/utils.test.tsx
khanti42 Nov 19, 2024
b53a281
Update packages/starknet-snap/src/types/snapState.ts
khanti42 Nov 19, 2024
2926565
Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx
khanti42 Nov 19, 2024
e1c288b
Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx
khanti42 Nov 19, 2024
086bc1e
Update packages/starknet-snap/src/ui/utils.test.tsx
khanti42 Nov 19, 2024
e1a888b
Update packages/starknet-snap/src/ui/utils.test.tsx
khanti42 Nov 19, 2024
a43fdfe
chore: fix comments
khanti42 Nov 19, 2024
ccf7e7a
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
9a27786
chore: fix comments
khanti42 Nov 19, 2024
59f592b
chore: fix comments
khanti42 Nov 19, 2024
54d94ef
chore: fix comments
khanti42 Nov 19, 2024
3fa6797
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
d47144f
chore: fix comments
khanti42 Nov 19, 2024
b6858f6
chore: lint
khanti42 Nov 19, 2024
0996a34
Merge branch 'feat/sf-712-interactive-ui-for-execute-txn' into feat/s…
khanti42 Nov 19, 2024
283985c
chore: lint
khanti42 Nov 19, 2024
8b5b388
Merge branch 'feat/snap-fee-token-selection' into feat/sf-713-interac…
khanti42 Nov 19, 2024
8bfd9ce
chore: fix comments
khanti42 Nov 19, 2024
2ded1cf
chore: fix comments
khanti42 Nov 19, 2024
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
4 changes: 3 additions & 1 deletion packages/starknet-snap/src/__tests__/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ export function generateTransactionRequests({
type: TransactionType.INVOKE,
signer: address,
maxFee: '100',
feeToken:
selectedFeeToken:
feeTokens[Math.floor(generateRandomValue() * feeTokens.length)].symbol,
calls: [
{
Expand All @@ -337,8 +337,10 @@ export function generateTransactionRequests({
amount: '1',
}),
entrypoint: 'transfer',
isTransfer: true,
},
],
includeDeploy: false,
});
}

Expand Down
11 changes: 11 additions & 0 deletions packages/starknet-snap/src/rpcs/__tests__/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ export function prepareConfirmDialog() {
};
}

/**
*
*/
export function prepareConfirmDialogInteractiveUI() {
const confirmDialogSpy = jest.spyOn(snapHelper, 'confirmDialogInteractiveUI');
confirmDialogSpy.mockResolvedValue(true);
return {
confirmDialogSpy,
};
}

/**
*
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/starknet-snap/src/rpcs/execute-txn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { executeTxn as executeTxnUtil } from '../utils/starknetUtils';
import {
generateRandomFee,
mockAccount,
prepareConfirmDialog,
prepareConfirmDialogInteractiveUI,
prepareMockAccount,
} from './__tests__/helper';
import type { ExecuteTxnParams } from './execute-txn';
Expand All @@ -35,7 +35,7 @@ const prepareMockExecuteTxn = async (
networks: [STARKNET_SEPOLIA_TESTNET_NETWORK],
transactions: [],
};
const { confirmDialogSpy } = prepareConfirmDialog();
const { confirmDialogSpy } = prepareConfirmDialogInteractiveUI();

const account = await mockAccount(constants.StarknetChainId.SN_SEPOLIA);
prepareMockAccount(account, state);
Expand Down
172 changes: 39 additions & 133 deletions packages/starknet-snap/src/rpcs/execute-txn.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
import type { Component, Json } from '@metamask/snaps-sdk';
import convert from 'ethereum-unit-converter';
import { type Json } from '@metamask/snaps-sdk';
import type { Call, Calldata } from 'starknet';
import { constants, TransactionStatus, TransactionType } from 'starknet';
import type { Infer } from 'superstruct';
import { object, string, assign, optional, any } from 'superstruct';
import { v4 as uuidv4 } from 'uuid';

import { AccountStateManager } from '../state/account-state-manager';
import { TransactionRequestStateManager } from '../state/request-state-manager';
import { TokenStateManager } from '../state/token-state-manager';
import { TransactionStateManager } from '../state/transaction-state-manager';
import { FeeToken } from '../types/snapApi';
import type { TransactionRequest } from '../types/snapState';
import { VoyagerTransactionType, type Transaction } from '../types/snapState';
import { ExecuteTxnUI } from '../ui/components';
import { generateFlow } from '../ui/utils';
import type { AccountRpcControllerOptions } from '../utils';
import {
AddressStruct,
BaseRequestStruct,
AccountRpcController,
confirmDialog,
UniversalDetailsStruct,
CallsStruct,
mapDeprecatedParams,
addressUI,
signerUI,
networkUI,
jsonDataUI,
dividerUI,
headerUI,
rowUI,
formatCallData,
confirmDialogInteractiveUI,
} from '../utils';
import { UserRejectedOpError } from '../utils/exceptions';
import { logger } from '../utils/logger';
import {
createAccount,
executeTxn as executeTxnUtil,
Expand Down Expand Up @@ -112,6 +109,7 @@ export class ExecuteTxnRpc extends AccountRpcController<
): Promise<ExecuteTxnResponse> {
const { address, calls, abis, details } = params;
const { privateKey, publicKey } = this.account;
const callsArray = Array.isArray(calls) ? calls : [calls];

const { includeDeploy, suggestedMaxFee, estimateResults } =
await getEstimatedFees(
Expand All @@ -132,15 +130,36 @@ export class ExecuteTxnRpc extends AccountRpcController<
const version =
details?.version as unknown as constants.TRANSACTION_VERSION;

if (
!(await this.getExecuteTxnConsensus(
address,
accountDeployed,
calls,
suggestedMaxFee,
version,
))
) {
const formattedCalls = await formatCallData(
callsArray,
this.network.chainId,
address,
this.tokenStateManager,
);

khanti42 marked this conversation as resolved.
Show resolved Hide resolved
const request: TransactionRequest = {
chainId: this.network.chainId,
id: uuidv4(),
interfaceId: '',
type: TransactionType.INVOKE,
signer: address,
maxFee: suggestedMaxFee,
calls: formattedCalls,
selectedFeeToken:
version === constants.TRANSACTION_VERSION.V3
? FeeToken.STRK
: FeeToken.ETH,
includeDeploy,
};

const interfaceId = await generateFlow(ExecuteTxnUI, request);

request.interfaceId = interfaceId;

const stateManager = new TransactionRequestStateManager();
await stateManager.upsertTransactionRequest(request);

khanti42 marked this conversation as resolved.
Show resolved Hide resolved
if (!(await confirmDialogInteractiveUI(interfaceId))) {
throw new UserRejectedOpError() as unknown as Error;
}

Expand Down Expand Up @@ -213,119 +232,6 @@ export class ExecuteTxnRpc extends AccountRpcController<
});
}

protected async getExecuteTxnConsensus(
address: string,
accountDeployed: boolean,
calls: Call[] | Call,
maxFee: string,
version?: constants.TRANSACTION_VERSION,
) {
const { name: chainName, chainId } = this.network;
const callsArray = Array.isArray(calls) ? calls : [calls];

const components: Component[] = [];
const feeToken: FeeToken =
version === constants.TRANSACTION_VERSION.V3
? FeeToken.STRK
: FeeToken.ETH;

components.push(headerUI('Do you want to sign this transaction?'));
components.push(
signerUI({
address,
chainId,
}),
);

// Display a message to indicate the signed transaction will include an account deployment
if (!accountDeployed) {
components.push(headerUI(`The account will be deployed`));
}

components.push(dividerUI());
components.push(
rowUI({
label: `Estimated Gas Fee (${feeToken})`,
value: convert(maxFee, 'wei', 'ether'),
}),
);

components.push(dividerUI());
components.push(
networkUI({
networkName: chainName,
}),
);

// Iterate over each call in the calls array
for (const call of callsArray) {
const { contractAddress, calldata, entrypoint } = call;
components.push(dividerUI());
components.push(
addressUI({
label: 'Contract',
address: contractAddress,
chainId,
}),
);

components.push(
jsonDataUI({
label: 'Call Data',
data: calldata,
}),
);

// If the contract is an ERC20 token and the function is 'transfer', display sender, recipient, and amount
const token = await this.tokenStateManager.getToken({
address: contractAddress,
chainId,
});

if (token && entrypoint === 'transfer' && calldata) {
try {
const senderAddress = address;
const recipientAddress = calldata[0]; // Assuming the first element in calldata is the recipient
let amount = '';

if ([3, 6, 9, 12, 15, 18].includes(token.decimals)) {
amount = convert(calldata[1], -1 * token.decimals, 'ether');
} else {
amount = (
Number(calldata[1]) * Math.pow(10, -1 * token.decimals)
).toFixed(token.decimals);
}
components.push(dividerUI());
components.push(
addressUI({
label: 'Sender Address',
address: senderAddress,
chainId,
}),
dividerUI(),
addressUI({
label: 'Recipient Address',
address: recipientAddress,
chainId,
}),
dividerUI(),
rowUI({
label: `Amount (${token.symbol})`,
value: amount,
}),
);
} catch (error) {
logger.warn(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`error found in amount conversion: ${error}`,
);
}
}
}

return await confirmDialog(components);
}

protected createDeployTxn(
address: string,
transactionHash: string,
Expand Down
2 changes: 1 addition & 1 deletion packages/starknet-snap/src/state/request-state-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class TransactionRequestStateManager extends StateManager<TransactionRequ
): void {
khanti42 marked this conversation as resolved.
Show resolved Hide resolved
// This is the only field that can be updated
dataInState.maxFee = data.maxFee;
dataInState.feeToken = data.feeToken;
dataInState.selectedFeeToken = data.selectedFeeToken;
}

/**
Expand Down
21 changes: 15 additions & 6 deletions packages/starknet-snap/src/types/snapState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,28 @@ export type SnapState = {
transactionRequests?: TransactionRequest[];
};

export type FormattedCallData = {
contractAddress: string;
calldata?: string[];
entrypoint: string;
isTransfer: boolean; // Flag to indicate if this call is a transfer
transferSenderAddress?: string;
transferRecipientAddress?: string;
transferAmount?: string;
transferTokenDecimals?: number;
transferTokenSymbol?: string;
};

export type TransactionRequest = {
id: string;
interfaceId: string;
type: string;
signer: string;
chainId: string;
maxFee: string;
calls: {
contractAddress: string;
calldata: RawCalldata;
entrypoint: string;
}[];
feeToken: string;
calls: FormattedCallData[];
selectedFeeToken: string;
includeDeploy: boolean;
};

export type AccContract = {
Expand Down
40 changes: 0 additions & 40 deletions packages/starknet-snap/src/ui/components/AddressUI.tsx

This file was deleted.

Loading
Loading