Skip to content

Commit

Permalink
feat: add jsx support and interactive fee token selection in StarkNet…
Browse files Browse the repository at this point in the history
… Snap (#429)

* chore: add jsx support in snap (#415)

* chore: add jsx support in snap

* chore: fix comment

* chore: update yarn.lock

* feat: add common jsx component (#417)

* chore: add jsx support in snap

* chore: add jsx support in snap

* feat: jsx support management

* feat: common jsx components and fragments

* chore: fix test and lint

* chore: rollback jsx support detection not here

* chore: fix comment

* chore: fix comments

* chore: fix comments

* chore: update yarn.lock

* chore: update yarn.lock

* chore: add react-dom types

* chore: fix comments

* chore: rebase wallet-ui changes happening elsewhere

* feat: add fee token selection interactive UI (#418)

* chore: add jsx support in snap

* chore: add jsx support in snap

* feat: jsx support management

* feat: common jsx components and fragments

* chore: fix test and lint

* feat: add interactive-ui for execute txn

* fix: add mutex in jsx support detection mechanism

* chore: fixture request addapted

* chore: ensure test pass

* chore: lint

* chore: remove console.log

* chore: rollback jsx support detection not here

* chore: rollback index.tsx

* chore: fix comment

* chore: fix comments

* chore: fix comments

* chore: update yarn.lock

* chore: update yarn.lock

* chore: update yarn.lock

* chore: rebase wallet-ui changes happening elsewhere

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: removed utils

* fix: implement comments

* fix: implement comments

* chore: fix comments

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/types/snapState.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: lint

---------

Co-authored-by: Stanley Yuen <[email protected]>

* feat: adopt fee token selection dialog in RPC `starkNet_executeTxn` (#419)

* chore: add jsx support in snap

* chore: add jsx support in snap

* feat: jsx support management

* feat: common jsx components and fragments

* chore: fix test and lint

* feat: add interactive-ui for execute txn

* fix: add mutex in jsx support detection mechanism

* chore: fixture request addapted

* chore: ensure test pass

* chore: lint

* feat: add interactive-ui in execute txn

* chore: remove console.log

* chore: missing helper in tests

* chore: lint

* chore: rollback jsx support detection not here

* chore: rollback index.tsx

* chore: fix comment

* chore: fix comments

* chore: fix comments

* chore: update yarn.lock

* chore: update yarn.lock

* feat: update wallet-ui message

* chore: update yarn.lock

* chore: rebase wallet-ui changes happening elsewhere

* chore: rebase wallet-ui changes happening elsewhere

* chore: fix comments

* chore: fix comments

* fix: formatter-utils

* chore: fix comments

* chore: fix comments

* chore: lint

* chore: lint

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: removed utils

* fix: implement comments

* fix: implement comments

* chore: fix comments

* chore: fix comments

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/types/snapState.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: lint

* chore: lint

* chore: fix comments

* chore: fix comments

---------

Co-authored-by: Stanley Yuen <[email protected]>

* chore: fix tests

* feat: add jsx support detection (#416)

* chore: add jsx support in snap

* chore: add jsx support in snap

* feat: jsx support management

* chore: fix test and lint

* fix: add mutex in jsx support detection mechanism

* chore: ensure test pass

* feat: new init state manager class to manage state init and support check

* fix: wait for hooks in request handler

* chore: lint

* fix: set jsx support to true before showing dialog

* chore: fix comment

* fix: moved ping pong

* chore: lint

* chore: rollback state

* chore: lint

* chore: fix comments

* fix: test suits

* feat: add event listener for fee token selection (#420)

* chore: add jsx support in snap

* chore: add jsx support in snap

* feat: jsx support management

* feat: common jsx components and fragments

* chore: fix test and lint

* feat: add interactive-ui for execute txn

* fix: add mutex in jsx support detection mechanism

* chore: fixture request addapted

* chore: ensure test pass

* chore: lint

* feat: add interactive-ui in execute txn

* chore: remove console.log

* chore: missing helper in tests

* chore: lint

* feat: event-handler in index.tsx

* feat: event controller

* feat: error handling and tests suits for event controller

* fix: test suits

* fix: signer in fee-token-selector

* chore: rollback jsx support detection not here

* chore: rollback index.tsx

* chore: lint

* chore: fix comment

* chore: fix comments

* chore: fix comments

* chore: update yarn.lock

* chore: update yarn.lock

* feat: update wallet-ui message

* chore: update yarn.lock

* chore: rebase wallet-ui changes happening elsewhere

* chore: rebase wallet-ui changes happening elsewhere

* chore: fix comments

* chore: fix comments

* fix: formatter-utils

* chore: fix comments

* chore: fix comments

* chore: lint

* chore: lint

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: lint

* chore: lint

* chore: removed utils

* feat: add comments in user-input classes

* fix: implement comments

* fix: implement comments

* chore: fix comments

* chore: fix comments

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/types/snapState.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/components/ExecuteTxnUI.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/ui/utils.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: lint

* chore: lint

* chore: fix rebase

* chore: fix comments

* chore: fix comments

* chore: fix comments

* chore: rebase

* fix: removed user-input controller abstract class and derived ones

* chore: rollback execute-txn

* chore: update

* chore: fix comments

* chore: fix comments

* chore: refine the code

* fix: add execution test

* fix: update execute txn test

---------

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/state/state-manager.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/index.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/types/snapState.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/index.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/index.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/starknet-snap/src/index.test.tsx

Co-authored-by: Stanley Yuen <[email protected]>

* chore: lint

---------

Co-authored-by: Stanley Yuen <[email protected]>
  • Loading branch information
khanti42 and stanleyyconsensys authored Nov 21, 2024
1 parent 0c8468a commit abfc0e5
Show file tree
Hide file tree
Showing 35 changed files with 1,810 additions and 273 deletions.
9 changes: 8 additions & 1 deletion packages/starknet-snap/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@ module.exports = {
'jsdoc/require-returns': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/match-description': 'off',
// This allows importing the `Text` JSX component.
'@typescript-eslint/no-shadow': [
'error',
{
allow: ['Text'],
},
],
},
},
{
files: ['*.test.ts'],
files: ['*.test.ts', '*.test.tsx'],
extends: ['@metamask/eslint-config-jest'],
rules: {
'@typescript-eslint/no-shadow': [
Expand Down
8 changes: 5 additions & 3 deletions packages/starknet-snap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
"cover:report": "nyc report --reporter=lcov --reporter=text",
"jest": "jest --passWithNoTests",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:eslint": "eslint . --cache --ext js,ts,tsx",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.ts' '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path .gitignore",
"lint:misc": "prettier '**/*.ts' '**/*.tsx' '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path .gitignore",
"serve": "mm-snap serve",
"start": "mm-snap watch",
"test": "yarn run test:unit && yarn run cover:report && yarn run jest",
Expand All @@ -39,7 +39,7 @@
},
"dependencies": {
"@metamask/key-tree": "9.0.0",
"@metamask/snaps-sdk": "^4.0.0",
"@metamask/snaps-sdk": "^6.1.1",
"@metamask/utils": "^9.1.0",
"async-mutex": "^0.3.2",
"ethereum-unit-converter": "^0.0.17",
Expand All @@ -59,6 +59,8 @@
"@metamask/snaps-jest": "^8.2.0",
"@types/chai": "^4.3.1",
"@types/chai-as-promised": "^7.1.5",
"@types/react": "18.2.4",
"@types/react-dom": "18.2.4",
"@types/sinon": "^10.0.11",
"@types/sinon-chai": "^3.2.8",
"@typescript-eslint/eslint-plugin": "^5.42.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/starknet-snap/snap.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require('dotenv').config();

const config: SnapConfig = {
bundler: 'webpack',
input: resolve(__dirname, 'src/index.ts'),
input: resolve(__dirname, 'src/index.tsx'),
server: {
port: 8081,
},
Expand Down
17 changes: 16 additions & 1 deletion packages/starknet-snap/src/__tests__/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,11 @@ export function generateTransactionRequests({
id: uuidv4(),
interfaceId: uuidv4(),
type: TransactionType.INVOKE,
networkName: 'Sepolia',
signer: address,
addressIndex: 0,
maxFee: '100',
feeToken:
selectedFeeToken:
feeTokens[Math.floor(generateRandomValue() * feeTokens.length)].symbol,
calls: [
{
Expand All @@ -339,6 +341,19 @@ export function generateTransactionRequests({
entrypoint: 'transfer',
},
],
includeDeploy: false,
resourceBounds: [
{
l1_gas: {
max_amount: '0',
max_price_per_unit: '0',
},
l2_gas: {
max_amount: '0',
max_price_per_unit: '0',
},
},
],
});
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import type {
OnHomePageHandler,
OnInstallHandler,
OnUpdateHandler,
OnUserInputHandler,
UserInputEvent,
InterfaceContext,
} from '@metamask/snaps-sdk';
import { panel, text, MethodNotFoundError } from '@metamask/snaps-sdk';
import { MethodNotFoundError } from '@metamask/snaps-sdk';
import { Box, Link, Text } from '@metamask/snaps-sdk/jsx';

import { addNetwork } from './addNetwork';
import { Config } from './config';
Expand Down Expand Up @@ -58,8 +62,15 @@ import type {
ApiRequestParams,
} from './types/snapApi';
import type { SnapState } from './types/snapState';
import { UserInputEventController } from './ui/controllers/user-input-event-controller';
import { upgradeAccContract } from './upgradeAccContract';
import { getDappUrl, isSnapRpcError } from './utils';
import {
ensureJsxSupport,
getDappUrl,
getStateData,
isSnapRpcError,
setStateData,
} from './utils';
import {
CAIRO_VERSION_LEGACY,
PRELOADED_TOKENS,
Expand Down Expand Up @@ -93,12 +104,7 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
}

// TODO: this will causing racing condition, need to be fixed
let state: SnapState = await snap.request({
method: 'snap_manageState',
params: {
operation: 'get',
},
});
let state: SnapState = await getStateData<SnapState>();
if (!state) {
state = {
accContracts: [],
Expand All @@ -107,13 +113,7 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
transactions: [],
};
// initialize state if empty and set default data
await snap.request({
method: 'snap_manageState',
params: {
operation: 'update',
newState: state,
},
});
await setStateData(state);
}

// TODO: this can be remove, after state manager is implemented
Expand Down Expand Up @@ -307,41 +307,52 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
};

export const onInstall: OnInstallHandler = async () => {
const component = panel([
text('Your MetaMask wallet is now compatible with Starknet!'),
text(
`To manage your Starknet account and send and receive funds, visit the [companion dapp for Starknet](${getDappUrl()}).`,
),
]);

await snap.request({
method: 'snap_dialog',
params: {
type: 'alert',
content: component,
},
});
await ensureJsxSupport(
<Box>
<Text>Your MetaMask wallet is now compatible with Starknet!</Text>
<Text>
To manage your Starknet account and send and receive funds, visit the{' '}
<Link href={getDappUrl()}>companion dapp for Starknet</Link>.
</Text>
</Box>,
);
};

export const onUpdate: OnUpdateHandler = async () => {
const component = panel([
text('Features released with this update:'),
text(
'Support STRK token for the gas fee in sending transaction and estimating fee.',
),
text('Default network changed to mainnet.'),
text('Support for multiple consecutive transactions.'),
]);

await snap.request({
method: 'snap_dialog',
params: {
type: 'alert',
content: component,
},
});
await ensureJsxSupport(
<Box>
<Text>Your Starknet Snap is now up-to-date !</Text>
<Text>
As usual, to manage your Starknet account and send and receive funds,
visit the <Link href={getDappUrl()}>companion dapp for Starknet</Link>.
</Text>
</Box>,
);
};

export const onHomePage: OnHomePageHandler = async () => {
return await homePageController.execute();
};

/**
* Handle incoming user events coming from the MetaMask clients open interfaces.
*
* @param params - The event parameters.
* @param params.id - The Snap interface ID where the event was fired.
* @param params.event - The event object containing the event type, name, and
* value.
* @param params.context
* @see https://docs.metamask.io/snaps/reference/exports/#onuserinput
*/
export const onUserInput: OnUserInputHandler = async ({
id,
event,
context,
}: {
id: string;
event: UserInputEvent;
context: InterfaceContext | null;
}): Promise<void> => {
const controller = new UserInputEventController(id, event, context);
await controller.handleEvent();
};
4 changes: 2 additions & 2 deletions packages/starknet-snap/src/on-home-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class HomePageController {

const balance = await this.getBalance(network, address);

return this.buildComponenets(address, network, balance);
return this.buildComponents(address, network, balance);
} catch (error) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
logger.error('Failed to execute onHomePage', toJson(error));
Expand Down Expand Up @@ -97,7 +97,7 @@ export class HomePageController {
);
}

protected buildComponenets(
protected buildComponents(
address: string,
network: Network,
balance: string,
Expand Down
36 changes: 36 additions & 0 deletions packages/starknet-snap/src/rpcs/__tests__/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,34 @@ import type { constants } from 'starknet';

import type { StarknetAccount } from '../../__tests__/helper';
import { generateAccounts, generateRandomValue } from '../../__tests__/helper';
import { TransactionRequestStateManager } from '../../state/request-state-manager';
import type { SnapState } from '../../types/snapState';
import { getExplorerUrl, shortenAddress, toJson } from '../../utils';
import * as snapHelper from '../../utils/snap';
import * as snapUtils from '../../utils/snapUtils';
import * as starknetUtils from '../../utils/starknetUtils';

export const mockTransactionRequestStateManager = () => {
const upsertTransactionRequestSpy = jest.spyOn(
TransactionRequestStateManager.prototype,
'upsertTransactionRequest',
);
const getTransactionRequestSpy = jest.spyOn(
TransactionRequestStateManager.prototype,
'getTransactionRequest',
);
const removeTransactionRequestSpy = jest.spyOn(
TransactionRequestStateManager.prototype,
'removeTransactionRequest',
);

return {
upsertTransactionRequestSpy,
getTransactionRequestSpy,
removeTransactionRequestSpy,
};
};

/**
*
* @param chainId
Expand Down Expand Up @@ -58,6 +80,20 @@ export function prepareConfirmDialog() {
};
}

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

/**
*
*/
Expand Down
Loading

0 comments on commit abfc0e5

Please sign in to comment.