Today, I started my workday by checking the Slack messages in our team-pak
channel. My boss and manager, Touseef Liaqat, asked me, Mudassir Shabir, to run one of our dApps on GitHub Codespaces. I had an early start today, beginning work at 8 AM.
After seeing his message, I decided to explore GitHub Codespaces. Prior to this, I had no idea what it was or what it did. After going through the documentation, I was both stunned and impressed. GitHub Codespaces is amazing.
A GitHub Codespace is a cloud-hosted development environment that can be customized to fit our needs. You get everything you need for app development pre-configured in a remote setting. You can set it up as needed, pre-configure it with necessary tools, and then share it with others. I found this concept particularly useful for scenarios where your computer lacks the processing power needed for a project. A Codespace is a viable solution to this problem.
Using the free tier, I was able to create a Codespace by following the documentation. I cloned the repo I needed, installed all the required dependencies, and started my development server as well a local instance of the blockchain in the Codespace. Everything was working fine until I encountered an issue.
In our dApp, we connect a wallet to our blockchain. On a local machine, we usually run a local instance of the blockchain, with all the RPC and API URLs accessible via localhost. This wasn’t the case here. Our dApp’s frontend had to make API and RPC calls to the blockchain, attempting to connect to localhost:PORT
, which was inaccessible. This happened because Codespace automatically forwards the port it accessible in the browser. You can read about it in detail over here. As a result, you get a URL to view your app in the browser.
Initially, I wasn’t clear about the concept of port forwarding. Accessing the dApp in the browser via a URL provided by Codespace was like a black box to me. Due to my lack of understanding, I tried using Nginx in Codespace to route localhost to the URL given to me by Codespace for the RPC and API endpoints.
I realized this was not the right approach, and my mental model was incorrect after a meeting with my boss, Touseef. During the meeting, he explained the workflow and even drew a diagram to illustrate it.
So, I decided to hardcode the URLs for the API and RPC endpoints in the dApp code. In the code, it was attempting to connect to the wallet and perform chain operations using localhost for ports 1317
and 26657
. I captured the URLs of the RPC and API endpoints associated with the Codespace and hardcoded these URLs into the dApp code. Initially, this seemed to resolve the issue. But, another error happened. Now I encountered a new problem: CORS errors.
The problem arose because my dApp was running on port 5173
, while the RPC and API endpoints were on ports 1317
and 26657
, respectively. This port mismatch caused the CORS errors, preventing the dApp from functioning correctly.
I red a blog suggesting the use of a proxy server to mitigate this CORS error. The idea was to make a request from the dApp to the proxy, which would then forward the request to the API and RPC endpoints. When the proxy received the response, it would add the ACCESS-CONTROL-ALLOW-ORIGIN
header to it. This way, the client-side would correctly interpret the response. I tried creating a Node.js proxy. It worked but it soon felt like overkill. Although, the blog was interesting and you can read it over here.
I went to Jummah Prayer, after the meeting with Touseef and Muddasir. When I returned, I googled CORS issues related to Codespaces. I found that this was a common problem. I discovered a helpful GitHub thread suggesting that making all the ports public could resolve the CORS issue. Following this advice, I made the ports public in VS Code within Codespace, and once I did that, the CORS issue was resolved.
Our next task for Muddasir and me is to find a way to pass the Codespace URLs (the ones we get after port forwarding) into the code as environment variables. Each Codespace generates a unique URL every time it is created, which makes it challenging to hardcode these URLs.
We are working on this for an upcoming workshop on Agoric Smart Contracts. During the workshop, students will be running their own Codespaces, and we want to avoid requiring them to manually copy and paste URLs into the code.
We have been experimenting with various solutions to automate this process. So far, we have come up with a few potential methods, but they are not perfect and still have some flaws.