-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
184 changed files
with
3,538 additions
and
1,920 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ module.exports = { | |
jest: { | ||
setupTimeout: 120000, | ||
}, | ||
retries: 2, | ||
}, | ||
|
||
configurations: { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Welcome to MetaMask! | ||
|
||
If you're submitting code to MetaMask, there are some simple things we'd appreciate you doing to help us stay organized! | ||
|
||
### Finding the right project | ||
|
||
Before taking the time to code and implement something, feel free to open an issue and discuss it! There may even be an issue already open, and together we may come up with a specific strategy before you take your precious time to write code. | ||
|
||
There are also plenty of open issues we'd love help with. Search the [`good first issue`](https://github.com/MetaMask/metamask-mobile/contribute) label, or head to Gitcoin and earn ETH for completing projects we've posted bounties on. | ||
|
||
If you're picking up a bounty or an existing issue, feel free to ask clarifying questions on the issue as you go about your work. | ||
|
||
### Submitting a pull request | ||
When you're done with your project / bugfix / feature and ready to submit a PR, there are a couple guidelines we ask you to follow: | ||
|
||
- [ ] **Make sure you followed our [`coding guidelines`](https://github.com/MetaMask/metamask-mobile/blob/main/.github/coding_guidelines/CODING_GUIDELINES.md)**: These guidelines aim to maintain consistency and readability across the codebase. They help ensure that the code is easy to understand, maintain, and modify, which is particularly important when working with multiple contributors. | ||
- [ ] **Test it**: For any new programmatic functionality, we like unit tests when possible, so if you can keep your code cleanly isolated, please do add a test file to the `tests` folder. | ||
- [ ] **Add to the CHANGELOG**: Help us keep track of all the moving pieces by adding an entry to the [`CHANGELOG.md`](https://github.com/MetaMask/metamask-mobile/blob/main/CHANGELOG.md) with a link to your PR. | ||
- [ ] **Meet the spec**: Make sure the PR adds functionality that matches the issue you're closing. This is especially important for bounties: sometimes design or implementation details are included in the conversation, so read carefully! | ||
- [ ] **Close the issue**: If this PR closes an open issue, add the line `fixes #$ISSUE_NUMBER`. Ex. For closing issue 418, include the line `fixes #418`. If it doesn't close the issue but addresses it partially, just include a reference to the issue number, like `#418`. | ||
- [ ] **Keep it simple**: Try not to include multiple features in a single PR, and don't make extraneous changes outside the scope of your contribution. All those touched files make things harder to review ;) | ||
- [ ] **PR against `main`**: Submit your PR against the `main` branch. This is where we merge new features to be included in forthcoming releases. When we initiate a new release, we create a branch named `release/x.y.z`, serving as a snapshot of the `main` branch. This particular branch is utilized to construct the builds, which are then tested during the release regression testing phase before they are submitted to the stores for production. In the event your PR is a hot-fix for a bug identified on the `release/x.y.z` branch, you should still submit your PR against the `main` branch. This PR will subsequently be cherry-picked into the `release/x.y.z` branch by our release engineers. | ||
- [ ] **Get the PR reviewed by code owners**: At least two code owner approvals are mandatory before merging any PR. | ||
|
||
And that's it! Thanks for helping out. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# MetaMask Mobile Coding Guidelines | ||
|
||
### 1. New Code Should be Typescript | ||
- New components and utilities should be written in Typescript and enforce typing. | ||
- Existing code should be refactored into Typescript where time allows. If you are replacing a component use Typescript. | ||
|
||
### 2. Using Functional Components and Hooks Instead of Classes | ||
- Use functional components and hooks as they result in more concise and readable code compared to classes. | ||
|
||
### 3. Organize Files Related to the Same Component in One Folder | ||
- An example of a component file structure: | ||
|
||
```.tsx | ||
AvatarAccount | ||
├── AvatarAccount.constants.ts | ||
├── AvatarAccount.stories.tsx | ||
├── AvatarAccount.styles.ts | ||
├── AvatarAccount.test.tsx | ||
├── AvatarAccount.tsx | ||
├── AvatarAccount.types.ts | ||
├── README.md | ||
├── __snapshots__ | ||
│ └── AvatarAccount.test.tsx.snap | ||
└── index.ts | ||
``` | ||
|
||
### 4. Follow Naming Conventions | ||
- You should always use PascalCase when naming components to differentiate them from other non-component TSX files. For example: *TextField*, *NavMenu*, and *SuccessButton*. | ||
- Use camelCase for functions declared inside components like *handleInput()* or *showElement()*. | ||
- When creating hooks use *withHookName()*. | ||
|
||
### 5. Avoid Repetitive Code | ||
- If you notice you are writing duplicated code or components, convert it into a component, utility functions or hooks that can be reused. Do this with [scalable intention](https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction). | ||
|
||
### 6. Component Optimization | ||
- For functional components, instead of having large return statements, break the component down into smaller sub-components. | ||
- Use memoizing techniques where possible. Utilize the useMemo hook for values and useCallback for functions. Follow recommended React Native guidance. | ||
|
||
### 7. Use Object Destructuring For Props | ||
- Instead of passing the props object, use object destructuring to pass the prop name. This discards the need to refer to the props object each time you need to use it. | ||
|
||
```tsx | ||
import React from 'react'; | ||
import { View } from 'react-native'; | ||
|
||
const MyComponent = ({id}) => { | ||
return <View id={id} />; | ||
}; | ||
|
||
const MyComponent = (props, context) => { | ||
const { id } = props; | ||
return <View id={id} />; | ||
}; | ||
|
||
const Foo = class extends React.PureComponent { | ||
render() { | ||
const { title } = this.context; | ||
return <View>{title}</View> | ||
} | ||
}; | ||
|
||
``` | ||
|
||
### 8. Document Each Component/Utility | ||
- New utility functions should be documented [TSDoc](https://tsdoc.org) commenting format. | ||
- Referencing our component docs. | ||
- If applicable add URL to online resources if they are meaningful for the component/method. | ||
|
||
### 9. Write Tests for Each Component/Utility | ||
- Write tests for the components you create as it reduces the possibilities of errors. Testing ensures that the components are behaving as you would expect. In this project Jest is used, and it provides an environment where you can execute your tests. | ||
|
||
### 10. External packages should be well maintained | ||
- New packages should only be integrated if the application doesn’t have the existing functionality and it cannot be added by implementing a small utility function. Use the https://snyk.io/advisor/ to assess the popularity, maintainability and security analysis. The package must be in good standing to be added to the project. | ||
- Update existing dependencies when you notice they are out of date. | ||
|
||
[Source](https://www.makeuseof.com/must-follow-react-practices/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
app/components/Approvals/AddChainApproval/AddChainApproval.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import AddChainApproval from './AddChainApproval'; | ||
import useApprovalRequest from '../../hooks/useApprovalRequest'; | ||
import { shallow } from 'enzyme'; | ||
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware'; | ||
import { ApprovalRequest } from '@metamask/approval-controller'; | ||
|
||
jest.mock('../../hooks/useApprovalRequest'); | ||
|
||
const mockApprovalRequest = (approvalRequest?: ApprovalRequest<any>) => { | ||
( | ||
useApprovalRequest as jest.MockedFn<typeof useApprovalRequest> | ||
).mockReturnValue({ | ||
approvalRequest, | ||
} as any); | ||
}; | ||
|
||
describe('AddChainApproval', () => { | ||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it('renders', () => { | ||
mockApprovalRequest({ | ||
type: ApprovalTypes.ADD_ETHEREUM_CHAIN, | ||
} as any); | ||
|
||
const wrapper = shallow(<AddChainApproval />); | ||
|
||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('returns null if no approval request', () => { | ||
mockApprovalRequest(undefined); | ||
|
||
const wrapper = shallow(<AddChainApproval />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('returns null if incorrect approval request type', () => { | ||
mockApprovalRequest({ type: ApprovalTypes.CONNECT_ACCOUNTS } as any); | ||
|
||
const wrapper = shallow(<AddChainApproval />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); |
25 changes: 25 additions & 0 deletions
25
app/components/Approvals/AddChainApproval/AddChainApproval.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from 'react'; | ||
import useApprovalRequest from '../../hooks/useApprovalRequest'; | ||
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware'; | ||
import ApprovalModal from '../ApprovalModal'; | ||
import AddCustomNetwork from '../../UI/AddCustomNetwork'; | ||
|
||
const AddChainApproval = () => { | ||
const { approvalRequest, pageMeta, onConfirm, onReject } = | ||
useApprovalRequest(); | ||
|
||
if (approvalRequest?.type !== ApprovalTypes.ADD_ETHEREUM_CHAIN) return null; | ||
|
||
return ( | ||
<ApprovalModal isVisible onCancel={onReject}> | ||
<AddCustomNetwork | ||
onCancel={onReject} | ||
onConfirm={onConfirm} | ||
currentPageInformation={pageMeta} | ||
customNetworkInformation={approvalRequest?.requestData} | ||
/> | ||
</ApprovalModal> | ||
); | ||
}; | ||
|
||
export default AddChainApproval; |
13 changes: 13 additions & 0 deletions
13
app/components/Approvals/AddChainApproval/__snapshots__/AddChainApproval.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`AddChainApproval renders 1`] = ` | ||
<ApprovalModal | ||
isVisible={true} | ||
> | ||
<AddCustomNetwork /> | ||
</ApprovalModal> | ||
`; | ||
|
||
exports[`AddChainApproval returns null if incorrect approval request type 1`] = `""`; | ||
|
||
exports[`AddChainApproval returns null if no approval request 1`] = `""`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './AddChainApproval'; |
18 changes: 18 additions & 0 deletions
18
app/components/Approvals/ApprovalModal/ApprovalModal.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import ApprovalModal from './ApprovalModal'; | ||
|
||
describe('ApprovalModal', () => { | ||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it('renders', () => { | ||
const wrapper = shallow( | ||
<ApprovalModal isVisible onCancel={() => undefined}> | ||
<div>test</div> | ||
</ApprovalModal>, | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import { StyleSheet } from 'react-native'; | ||
import Modal from 'react-native-modal'; | ||
import { useTheme } from '../../../util/theme'; | ||
|
||
export interface ApprovalModalProps { | ||
isVisible: boolean; | ||
onCancel: () => void; | ||
children: React.ReactNode; | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
bottomModal: { | ||
justifyContent: 'flex-end', | ||
margin: 0, | ||
}, | ||
}); | ||
|
||
const ApprovalModal = (props: ApprovalModalProps) => { | ||
const { colors } = useTheme(); | ||
|
||
return ( | ||
<Modal | ||
isVisible={props.isVisible} | ||
animationIn="slideInUp" | ||
animationOut="slideOutDown" | ||
style={styles.bottomModal} | ||
backdropColor={colors.overlay.default} | ||
backdropOpacity={1} | ||
animationInTiming={600} | ||
animationOutTiming={600} | ||
onBackdropPress={props.onCancel} | ||
onSwipeComplete={props.onCancel} | ||
swipeDirection={'down'} | ||
propagateSwipe | ||
> | ||
{props.children} | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default ApprovalModal; |
55 changes: 55 additions & 0 deletions
55
app/components/Approvals/ApprovalModal/__snapshots__/ApprovalModal.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`ApprovalModal renders 1`] = ` | ||
<ReactNativeModal | ||
animationIn="slideInUp" | ||
animationInTiming={600} | ||
animationOut="slideOutDown" | ||
animationOutTiming={600} | ||
avoidKeyboard={false} | ||
backdropColor="#00000099" | ||
backdropOpacity={1} | ||
backdropTransitionInTiming={300} | ||
backdropTransitionOutTiming={300} | ||
coverScreen={true} | ||
customBackdrop={null} | ||
deviceHeight={null} | ||
deviceWidth={null} | ||
hasBackdrop={true} | ||
hideModalContentWhileAnimating={false} | ||
isVisible={true} | ||
onBackButtonPress={[Function]} | ||
onBackdropPress={[Function]} | ||
onModalHide={[Function]} | ||
onModalShow={[Function]} | ||
onModalWillHide={[Function]} | ||
onModalWillShow={[Function]} | ||
onSwipeComplete={[Function]} | ||
panResponderThreshold={4} | ||
propagateSwipe={true} | ||
scrollHorizontal={false} | ||
scrollOffset={0} | ||
scrollOffsetMax={0} | ||
scrollTo={null} | ||
statusBarTranslucent={false} | ||
style={ | ||
Object { | ||
"justifyContent": "flex-end", | ||
"margin": 0, | ||
} | ||
} | ||
supportedOrientations={ | ||
Array [ | ||
"portrait", | ||
"landscape", | ||
] | ||
} | ||
swipeDirection="down" | ||
swipeThreshold={100} | ||
useNativeDriver={false} | ||
> | ||
<div> | ||
test | ||
</div> | ||
</ReactNativeModal> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './ApprovalModal'; |
Oops, something went wrong.