|
1 | 1 | # {{ programName | titleCase }}
|
2 | 2 |
|
3 |
| -TODO |
| 3 | +{# TODO: Uncomment when CI is generated. #} |
| 4 | +{# <a href="https://github.com/{{ organizationName }}/{{ programName }}/actions/workflows/main.yml"><img src="https://img.shields.io/github/actions/workflow/status/{{ organizationName }}/{{ programName }}/main.yml?logo=GitHub" /></a> #} |
| 5 | +<a href="https://explorer.solana.com/address/{{ programAddress }}"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2F{{ organizationName }}%2F{{ programName }}%2Fmain%2Fprogram%2Fidl.json&query=%24.version&label=program%20version&logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iMzEzIiBoZWlnaHQ9IjI4MSIgdmlld0JveD0iMCAwIDMxMyAyODEiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF80NzZfMjQzMCkiPgo8cGF0aCBkPSJNMzExLjMxOCAyMjEuMDU3TDI1OS42NiAyNzYuNTU4QzI1OC41MzcgMjc3Ljc2NCAyNTcuMTc4IDI3OC43MjUgMjU1LjY2OSAyNzkuMzgyQzI1NC4xNTkgMjgwLjAzOSAyNTIuNTMgMjgwLjM3OCAyNTAuODg0IDI4MC4zNzdINS45OTcxOUM0LjgyODcgMjgwLjM3NyAzLjY4NTY4IDI4MC4wMzUgMi43MDg1NSAyNzkuMzkzQzEuNzMxNDMgMjc4Ljc1MSAwLjk2Mjc3MSAyNzcuODM3IDAuNDk3MDIgMjc2Ljc2NEMwLjAzMTI2OTEgMjc1LjY5IC0wLjExMTI4NiAyNzQuNTA0IDAuMDg2ODcxMiAyNzMuMzVDMC4yODUwMjggMjcyLjE5NiAwLjgxNTI2NSAyNzEuMTI2IDEuNjEyNDMgMjcwLjI3TDUzLjMwOTkgMjE0Ljc2OUM1NC40Mjk5IDIxMy41NjYgNTUuNzg0MyAyMTIuNjA3IDU3LjI4OTMgMjExLjk1QzU4Ljc5NDMgMjExLjI5MyA2MC40MTc4IDIxMC45NTMgNjIuMDU5NSAyMTAuOTVIMzA2LjkzM0MzMDguMTAxIDIxMC45NSAzMDkuMjQ0IDIxMS4yOTIgMzEwLjIyMSAyMTEuOTM0QzMxMS4xOTkgMjEyLjU3NiAzMTEuOTY3IDIxMy40OSAzMTIuNDMzIDIxNC41NjRDMzEyLjg5OSAyMTUuNjM3IDMxMy4wNDEgMjE2LjgyNCAzMTIuODQzIDIxNy45NzdDMzEyLjY0NSAyMTkuMTMxIDMxMi4xMTUgMjIwLjIwMSAzMTEuMzE4IDIyMS4wNTdaTTI1OS42NiAxMDkuMjk0QzI1OC41MzcgMTA4LjA4OCAyNTcuMTc4IDEwNy4xMjcgMjU1LjY2OSAxMDYuNDdDMjU0LjE1OSAxMDUuODEzIDI1Mi41MyAxMDUuNDc0IDI1MC44ODQgMTA1LjQ3NUg1Ljk5NzE5QzQuODI4NyAxMDUuNDc1IDMuNjg1NjggMTA1LjgxNyAyLjcwODU1IDEwNi40NTlDMS43MzE0MyAxMDcuMTAxIDAuOTYyNzcxIDEwOC4wMTUgMC40OTcwMiAxMDkuMDg4QzAuMDMxMjY5MSAxMTAuMTYyIC0wLjExMTI4NiAxMTEuMzQ4IDAuMDg2ODcxMiAxMTIuNTAyQzAuMjg1MDI4IDExMy42NTYgMC44MTUyNjUgMTE0LjcyNiAxLjYxMjQzIDExNS41ODJMNTMuMzA5OSAxNzEuMDgzQzU0LjQyOTkgMTcyLjI4NiA1NS43ODQzIDE3My4yNDUgNTcuMjg5MyAxNzMuOTAyQzU4Ljc5NDMgMTc0LjU1OSA2MC40MTc4IDE3NC44OTkgNjIuMDU5NSAxNzQuOTAySDMwNi45MzNDMzA4LjEwMSAxNzQuOTAyIDMwOS4yNDQgMTc0LjU2IDMxMC4yMjEgMTczLjkxOEMzMTEuMTk5IDE3My4yNzYgMzExLjk2NyAxNzIuMzYyIDMxMi40MzMgMTcxLjI4OEMzMTIuODk5IDE3MC4yMTUgMzEzLjA0MSAxNjkuMDI4IDMxMi44NDMgMTY3Ljg3NUMzMTIuNjQ1IDE2Ni43MjEgMzEyLjExNSAxNjUuNjUxIDMxMS4zMTggMTY0Ljc5NUwyNTkuNjYgMTA5LjI5NFpNNS45OTcxOSA2OS40MjY3SDI1MC44ODRDMjUyLjUzIDY5LjQyNzUgMjU0LjE1OSA2OS4wODkgMjU1LjY2OSA2OC40MzJDMjU3LjE3OCA2Ny43NzUxIDI1OC41MzcgNjYuODEzOSAyNTkuNjYgNjUuNjA4MkwzMTEuMzE4IDEwLjEwNjlDMzEyLjExNSA5LjI1MTA3IDMxMi42NDUgOC4xODA1NiAzMTIuODQzIDcuMDI2OTVDMzEzLjA0MSA1Ljg3MzM0IDMxMi44OTkgNC42ODY4NiAzMTIuNDMzIDMuNjEzM0MzMTEuOTY3IDIuNTM5NzQgMzExLjE5OSAxLjYyNTg2IDMxMC4yMjEgMC45ODM5NDFDMzA5LjI0NCAwLjM0MjAyNiAzMDguMTAxIDMuOTUzMTRlLTA1IDMwNi45MzMgMEw2Mi4wNTk1IDBDNjAuNDE3OCAwLjAwMjc5ODY2IDU4Ljc5NDMgMC4zNDMxNCA1Ny4yODkzIDAuOTk5OTUzQzU1Ljc4NDMgMS42NTY3NyA1NC40Mjk5IDIuNjE2MDcgNTMuMzA5OSAzLjgxODQ3TDEuNjI1NzYgNTkuMzE5N0MwLjgyOTM2MSA2MC4xNzQ4IDAuMjk5MzU5IDYxLjI0NCAwLjEwMDc1MiA2Mi4zOTY0Qy0wLjA5Nzg1MzkgNjMuNTQ4OCAwLjA0MzU2OTggNjQuNzM0MiAwLjUwNzY3OSA2NS44MDczQzAuOTcxNzg5IDY2Ljg4MDMgMS43Mzg0MSA2Ny43OTQzIDIuNzEzNTIgNjguNDM3MkMzLjY4ODYzIDY5LjA4MDIgNC44Mjk4NCA2OS40MjQgNS45OTcxOSA2OS40MjY3WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzQ3Nl8yNDMwKSIvPgo8L2c+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNDc2XzI0MzAiIHgxPSIyNi40MTUiIHkxPSIyODcuMDU5IiB4Mj0iMjgzLjczNSIgeTI9Ii0yLjQ5NTc0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIG9mZnNldD0iMC4wOCIgc3RvcC1jb2xvcj0iIzk5NDVGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMyIgc3RvcC1jb2xvcj0iIzg3NTJGMyIvPgo8c3RvcCBvZmZzZXQ9IjAuNSIgc3RvcC1jb2xvcj0iIzU0OTdENSIvPgo8c3RvcCBvZmZzZXQ9IjAuNiIgc3RvcC1jb2xvcj0iIzQzQjRDQSIvPgo8c3RvcCBvZmZzZXQ9IjAuNzIiIHN0b3AtY29sb3I9IiMyOEUwQjkiLz4KPHN0b3Agb2Zmc2V0PSIwLjk3IiBzdG9wLWNvbG9yPSIjMTlGQjlCIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNDc2XzI0MzAiPgo8cmVjdCB3aWR0aD0iMzEyLjkzIiBoZWlnaHQ9IjI4MC4zNzciIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==&color=9945FF" /></a> |
| 6 | +{% if clients.includes('js') %} |
| 7 | +<a href="https://www.npmjs.com/package/@{{ organizationName }}/{{ jsClientPackageName }}"><img src="https://img.shields.io/npm/v/%40{{ organizationName }}%2F{{ jsClientPackageName }}?logo=npm&color=377CC0" /></a> |
| 8 | +{% endif %} |
| 9 | +{% if clients.includes('rust') %} |
| 10 | +<a href="https://crates.io/crates/{{ rustClientCrateName }}"><img src="https://img.shields.io/crates/v/{{ rustClientCrateName }}?logo=rust" /></a> |
| 11 | +{% else %} |
| 12 | +<a href="https://crates.io/crates/{{ programCrateName }}"><img src="https://img.shields.io/crates/v/{{ programCrateName }}?logo=rust" /></a> |
| 13 | +{% endif %} |
| 14 | + |
| 15 | +This template should help get you started developing Solana programs. Let's walk through this generated program repository and see what's included. |
| 16 | + |
| 17 | +## Project setup |
| 18 | + |
| 19 | +The first thing you'll want to do is install NPM dependencies which will allow you to access all the scripts and tools provided by this template. |
| 20 | + |
| 21 | +```sh |
| 22 | +{{ getNpmCommand("install") }} |
| 23 | +``` |
| 24 | + |
| 25 | +## Managing programs |
| 26 | + |
| 27 | +You'll notice a `program` folder in the root of this repository. This is where your generated Solana program is located. |
| 28 | + |
| 29 | +Whilst only one program gets generated, not that you can have as many programs as you like in this repository. |
| 30 | +Whenever you add a new program folder to this repository, remember to add it to the `members` array of your root `Cargo.toml` file. |
| 31 | +That way, your programs will be recognized by the following scripts that allow you to build, test, format and lint your programs respectively. |
4 | 32 |
|
5 | 33 | ```sh
|
6 | 34 | {{ getNpmCommand("programs:build") }}
|
|
9 | 37 | {{ getNpmCommand("programs:lint") }}
|
10 | 38 | ```
|
11 | 39 |
|
12 |
| -TODO |
| 40 | +## Generating IDLs |
| 41 | + |
| 42 | +You may use the following command to generate the IDLs for your programs. |
| 43 | + |
| 44 | +```sh |
| 45 | +{{ getNpmCommand("generate:idls") }} |
| 46 | +``` |
| 47 | + |
| 48 | +Depending on your program's framework, this will either use Shank or Anchor to generate the IDLs. |
| 49 | +Note that, to ensure IDLs are generated using the correct framework version, the specific version used by the program will be downloaded and used locally. |
| 50 | + |
| 51 | +{% if clients.length > 0 %} |
| 52 | +## Generating clients |
| 53 | + |
| 54 | +Once your programs' IDLs have been generated, you can generate clients for them using the following command. |
| 55 | + |
| 56 | +```sh |
| 57 | +{{ getNpmCommand("generate:clients") }} |
| 58 | +``` |
| 59 | + |
| 60 | +Alternatively, you can use the `generate` script to generate both the IDLs and the clients at once. |
| 61 | + |
| 62 | +```sh |
| 63 | +{{ getNpmCommand("generate") }} |
| 64 | +``` |
| 65 | + |
| 66 | +## Managing clients |
| 67 | + |
| 68 | +The following clients are available for your programs. You may use the following links to learn more about each client. |
| 69 | + |
| 70 | +{% for client in clients %} |
| 71 | +{% if ['js'].includes(client) %} |
| 72 | +- [{{ client | upper }} client](./clients/{{ client }}) |
| 73 | +{% else %} |
| 74 | +- [{{ client | titleCase }} client](./clients/{{ client }}) |
| 75 | +{% endif %} |
| 76 | +{% endfor %} |
| 77 | + |
| 78 | +## Starting and stopping the local validator |
| 79 | + |
| 80 | +The following script is available to start your local validator. |
| 81 | + |
| 82 | +```sh |
| 83 | +{{ getNpmCommand("validator") }} |
| 84 | +``` |
| 85 | + |
| 86 | +By default, if a local validator is already running, the script will be skipped. You may use the `--restart` flag to force the validator to restart. |
| 87 | + |
| 88 | +```sh |
| 89 | +{{ getNpmCommand("validator", "--restart") }} |
| 90 | +``` |
| 91 | + |
| 92 | +Finally, you may stop the local validator using the following command. |
| 93 | + |
| 94 | +```sh |
| 95 | +{{ getNpmCommand("validator:stop") }} |
| 96 | +``` |
| 97 | + |
| 98 | +## Using external programs in your validator |
| 99 | + |
| 100 | +If your program requires any external programs to be running, you'll want to in your local validator. |
| 101 | + |
| 102 | +You can do this by adding their program addresses to the `program-dependencies` array in the `Cargo.toml` of your program. |
| 103 | + |
| 104 | +```toml |
| 105 | +program-dependencies = [ |
| 106 | + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", |
| 107 | + "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV", |
| 108 | +] |
| 109 | +``` |
| 110 | + |
| 111 | +Next time you build your program and run your validator, these external programs will automatically be fetched from mainnet and used in your local validator. |
| 112 | + |
| 113 | +```sh |
| 114 | +{{ getNpmCommand("programs:build") }} |
| 115 | +{{ getNpmCommand("validator", "--restart") }} |
| 116 | +``` |
| 117 | +{% endif %} |
0 commit comments