{"id":25429955,"url":"https://github.com/davidyslu/portto-wallet","last_synced_at":"2026-05-16T13:05:07.591Z","repository":{"id":93934394,"uuid":"508573264","full_name":"davidyslu/Portto-Wallet","owner":"davidyslu","description":"Simple crypto collectable wallet on OpenSea ✈️","archived":false,"fork":false,"pushed_at":"2022-07-08T09:52:57.000Z","size":1921,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-29T12:39:47.425Z","etag":null,"topics":["ant-design","axios","react","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidyslu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-29T06:30:06.000Z","updated_at":"2022-07-08T09:59:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"bd428eb3-9c08-40f7-b104-359cdd1b7a15","html_url":"https://github.com/davidyslu/Portto-Wallet","commit_stats":null,"previous_names":["davidyslu/portto-wallet","yungshenglu/portto-wallet"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/davidyslu/Portto-Wallet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidyslu%2FPortto-Wallet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidyslu%2FPortto-Wallet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidyslu%2FPortto-Wallet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidyslu%2FPortto-Wallet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidyslu","download_url":"https://codeload.github.com/davidyslu/Portto-Wallet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidyslu%2FPortto-Wallet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33103971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ant-design","axios","react","typescript"],"created_at":"2025-02-17T02:32:48.148Z","updated_at":"2026-05-16T13:05:07.572Z","avatar_url":"https://github.com/davidyslu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Portto Wallet\n\n![](assets/img/Demo.png)\n\nThis repository is my first practice to implement a crypto collectable wallet of ERC-721 on [OpenSea](https://opensea.io/assets/ethereum/0x4164692f986daea213ba582cfed9ec1155462107/0) using React and TypeScript. ✈️\n\n\u003e HINT: If you have any questions, please feel free to ask me.\n\n---\n\n## Description\n\n### Execution\n\n1. To run our production, you need to clone our project first\n   ```bash\n   $ git clone https://github.com/yungshenglu/Portto-Wallet/\n   ```\n2. After cloning, change the your current directory into the repository and setup the project\n   ```bash\n   $ cd Portto-Wallet/ \u0026 yarn install\n   ```\n   - The command `yarn install` will install some necessary packages for this project\n   - It will take few second for running above command\n3. Compiles and hot-reloads for development\n   ```bash\n   $ yarn start\n   ```\n   - It will take few second for running above command\n   - This command will also start a proxy server on port `9527` to fetch the data from OpenSea\n   - You won't get any error messages if running successful\n4. Congratulation! you can open your browser to `http://localhost:9528` and see our Portto-Wallet\n\n---\n\n## Implementation\n\n### CORS (Cross-Origin Resource Sharing)\n\n\u003e HINT: [CORS on Wiki](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)\n\n- Implementing a simple **proxy server** to solve the CORS policy\n   - Set the proxy server running on port `9527` via [Express](https://expressjs.com/)\n   - You can see the detail of the implementation [here](./app.js)\n- The default of the request mode in Express server is `mode: no-cors`\n   - Use [CORS](https://www.npmjs.com/package/cors), a Node package for providing a Connect/Express middleware that can be used to enable CORS with various options\n   - You can see the detail of the implementation [here](./app.js)\n- In this repository, we only implement the following two APIs in our server: (The detail is in the following **APIs** section)\n   - `/api/assets`: Fetch the list of the assets\n   - `/api/assets\u0026token=:token`: Fetch the content of the asset via the token\n\n### Customize Hooks\n\n\u003e HINT: You can see the detail [here](./src/hooks)\n\n- `useFetchAssetsList`: Fetch the list of the assets\n   - There are two cases when triggering this API:\n      - Case 1: Entering the page **first time**\n      - Case 2: Loading more assets when **scrolling to the bottom** of the page\n   - When entering the page **first time**, the parameter of `before` will be 0. After getting the response, do the followings:\n      - Set the return data into `postList`\n      - Set the status of loading into `false`\n      - Set the status of having more assets into `true` as default\n   - When **scrolling to the bottom** of the page, the parameter of `before` will NOT be 0. After getting the response, do the followings:\n      - Append the new return data after existed `postList`\n      - Set the status of loading into `false`\n      - Set the status of having more assets into `true` as default\n- `useFetchAssets`: Fetch the content the specific asset\n   - Encapsulate the hook `useAxios` in [`axios-hooks`](https://www.npmjs.com/package/axios-hooks)\n   - The only parameters is `postId` (Number) which is to get the content you want.\n   - Set `manual: true` to avoid triggering the API when rendering\n   - The only condition of triggering the API is clicking the asset on the list\n\n### Infinite Scrolling\n\n- Using **Intersection Observer API** to implement \"Lazy Loading\"\n   - You can see the detail of the implementation [here](./src/views/Home/Home.tsx)\n- The main concept is that we need to *observe the last item in the list whether is intersect with viewport*\n   - When the last item is intersect with view port, we fetch new asset's list after it\n   - Register the DOM of the last asset with **Intersection Observer** each time after fetching the list\n   - Use `useCallback` to setup the callback function when the target DOM intersects with the viewport and start observing the target\n\n---\n## APIs\n\n- GET: `/api/assets\u0026offset=:offset`\n   - Usage: Fetch the list of assets on OpenSea\n   - Params:\n      - `offset` (Number):\n         - Return the assets after this offset\n         - If `offset` is 0, it will seems to be the first fetching\n   - URL:\n      - `https://testnets-api.opensea.io/api/v1/assets`\n- GET: `/api/assets\u0026token=:token`\n   - Usage: Fetch the content of the asset via this token on OpenSea\n   - Params:\n      - `token` (Number):\n         - Return the content of the asset via this token\n   - URL:\n      - `https://testnets-api.opensea.io/api/v1/asset/${contactAddress}/${token}`\n\n---\n\n## Contributor\n\n\u003e NOTICE: You can follow the contributing process [CONTRIBUTING.md](CONTRIBUTING.md) to join me. I am very welcome for any issue!\n\n- [David Lu](https://github.com/yungshenglu)\n\n---\n\n## License\n\n[WTFPL](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidyslu%2Fportto-wallet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidyslu%2Fportto-wallet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidyslu%2Fportto-wallet/lists"}