- backend - backend canister processing ICRC1 payments
- frontend - asset canister hosted frontend client to the backend canister
- test - unit and e2e testing
- workbench - prototyping and integration workbench, included as an example of how testing was iterated
- declarations - automatically generated declarations (only backend is used)
- icrc1-token-canister - Dfinity provided rosetta based ICRC1 canister wasm and did used to develop backend's interactions with mainnet ICRC1 token canister
Note the setup script requires the current dfx identity not to require unlocking each time a dfx command is issued.
- Clone a local copy from [insert github link]
- Install local dependencies and start the local replica testnet configured for the project by entering the command:
npm run setup
- Once setup finished, start the backend and frontend dev servers by entering the command:
npm run start
- Open your browser to
localhost:3000
to interact with the web app's dev server, which will already be connected to the backend canister on the local replica. Alternatively the application is directly available athttp://localhost:4943?canisterId=br5f7-7uaaa-aaaaa-qaaca-cai
.
Now any changes to either the backend or frontend code will be visible in either the browser or declarations file.
Working with the backend in a Javascript environment is available in the workbench
subdirectory which a node based project automatically loading the enviromental variables, declarations and utils of the frontend. To run that project index.js
file, open a new integrated terminal (or terminal of your choice) and from this project's root directory, enter the commands:
cd src/workbench
npm run run
You should see that file's console log output in the terminal. Alternatively you can use the Candid UI to interact with the backend canister in the browser, visit the Internet Computer Guide for more information.
Also note in the local testnet, the current dfx identity will receive 100 ICRC1 tokens (normal units) in the ICRC1 account corresponding to the subaccount address created for that identity by the backend payment processing canister.
- After a local copy is cloned, all testing can be done by entering the command:
npm run test
All tests are in the src/test subdirectory and are managed by the same Vitest
instance.
The results of the tests will displayed in the terminal output.
To run tests in watch mode, first cd
into src/tests
and then run npm run test
. Testing is made up of the units tests of the frontend and backend, and the integrated E2E testing which is focused on how the utils of the web worker process the calls and responses of the backend canister's API and how they are become a part ofthe UI via the reducer
(that is also used by CanisterProvider
). For more dedicated projects, using an E2E testing library like Cypress would provide better coverage.
An important note is that different environments are used for testing (jsdom
versus node
), and jsdom
may require additional configuration for it to work with agent-js
out of the box.
This test identity is the ED25519 key pair provided by the dfx nns extension
code base. If the project is started with the testing flag (npm run test
in the project's root directory) this identity will receive 100 CVCMICRC1 to use.
This project uses the bash scripting library zx to issue the commands to start and configure the local replica. When npm run start
or npm run test
is entered, first npm ci
is run in each project's root subdirectories (frontend
, test
, workbench
), and the setup.js
script is run. This script uses zx
along with some utility methods in script-utils.js
to:
- Load the environmental variables from the
.env
file generated bydfx
when building the canisters into the local execution context withdotenv
. - Check the ICRC1 Rosetta based wasm and did exist locally, if not downloading them with the install.sh script.
- Install the canisters in order so their ids remain constant. Note that as
zx
accepts template literals as input, the script-utils.js utility methods often simply return the command line argument as a literal to be used byzx
. In particular, this can make it easier to dynamically deploy the ICRC1 token canister during local development for instance. - Gets the
icrc1_token_canister
canister's id and uses it to call the backend'sset_icrc1_token_canister_id
canister method, updating the backend canister to use that canister to process payments. - Also calls the backend canister to get the ICRC1 account address associated with the current
dfx
identity's principal, to which 100 normal units worth of (mock) ICRC1 tokens are sent. If testing, additionally transfer similar amounts of ICRC1 tokens to the test identities used. - This should all be displayed in the terminal's output.
Also note that this project, as mentioned, includes the integrated local Internet Identity canister.
This is the canister that processes payments.
Note that the ICRC1 token canister is dynamically set, so the set_icrc1_token_canister_id
must be called once before it can process any payments by sending transfers.
Also note that all addresses it uses are its own subaccounts, so for a caller to send a payment through the backend canister, they must first deposit some ICRC1 tokens into their account address to credit it. Currently it maps only one subaccount to each caller, generating the subaccount with the utils method getAccountUserSubaccount.
All the API methods are typed which can be viewed in its Types.mo file.
Mops is used for including for the stable hashmap and SHA2 dependencies.
mo-dev is used for live reloading.
This is a Vite bundled, React and Tailwind based web app that uses a web worker to handle all processing with the backend canister so it occurs off the main thread.
Web workers have a different context and
For more details, check out its README.
This project was orignally based on:
And is adapted as a payment client, with the objectives of being mobile oriented with Tailwind and for the use of the background processing of web workers, from the BNT-3: Sample App - ICRC-1 Compliant Payment Flow.
For additional information and resources also see: