- Your frontend can instantiate a
contract.Clientinstance using thefromWasmHashfunction of the JavaScript SDK. This can generate bindings on-the-fly as your users browse your application. - Your deploy process might include a step that builds/deploys/binds a contract package at deploy-time.
- You could even generate and publish a bindings package all by itself. Then
pnpm install <bindings_package_name>can be done in any dapp that you (or somebody else) might need to interact with that contract.
The manual method
Before you skip ahead! Take a look at this (brief) section. It’s really useful to have a full understanding of what steps we’re going through in the automated section. This will help you adapt and/or troubleshoot this tutorial for your specific purposes.Install the compiled contract
The smart contract code needs to be installed to the network first. This uploads the compiled, binary Wasm file to the blockchain to be instantiated into a contract later on. From inside your project directory:Deploy a contract instance
This will return a hexadecimal hash corresponding to the uploaded Wasm executable (it’s just the Sha256 hash of the executable file, fyi). This hash can then be used in the deploy command to create a new contract instance. Our__constructor function takes an admin address, and the title and text of the first guestbook message, so we supply those arguments after the -- separator:
Generate bindings for the deployed contract
Now we can (again) use the Stellar CLI to generate bindings from the contract we’ve just deployed. You can also generate these bindings from your local Wasm file using the--wasm-hash parameter. The --overwrite parameter is used to tell the CLI that it should output the generated bindings package, even if it finds the directory is not empty (i.e., we’re re-binding a contract because we’ve modified the code and redeployed it).
packages/* is already claimed by the workspace glob and our freshly generated package is picked up automatically:
pnpm-workspace.yaml
pnpm-lock.yaml, which you don’t want inside a workspace (the root lockfile is the only one that matters). And the generated package.json only defines a build script, so we’ll add a prepare script, which gets the bindings compiled on a clean pnpm install. That last one is nicer than it sounds: it means the built dist/ directory never has to be committed.
Import the bindings package as a project dependency
With our bindings generated, we can add it to our frontend project. Because it’s a workspace package, we don’t point at a file path. We let pnpm resolve it from the workspace instead, running this from the root of the project:"ye_olde_guestbook": "workspace:*" in your root package.json, and pnpm links the package out of packages/ rather than copying it. So when you re-generate the bindings after changing your contract, your frontend picks up the new version with no re-install.
This is also the moment the bindings actually get compiled. Adding the dependency runs an install, the install runs the prepare script we just added, and prepare runs tsc. You’ll see pnpm report it as it goes.
Import the bindings client into the SvelteKit project
We’re straying just a bit into the Svelte-ish side of things here. The main goal of this step is to get the contract client (which is the “bindings package” we’ve just generated) into our frontend in a way that makes it usable anywhere we need it. In SvelteKit, we’re putting it into
src/lib/contracts because that means we can easily access the client by importing from #lib/contracts/ye_olde_guestbook.js whenever and wherever we need it.src/lib/contracts/ye_olde_guestbook.ts
The automated way
That was a lot of steps and a lot of work wasn’t it!? The good news is that our starter template (remember that?) comes with aninitialize.js script that will perform all of those actions for you! This script will go through all the following steps for you:
- Create and fund a keypair in the CLI
- Compile, install, and deploy all contracts in the
/contractsdirectory - Generate bindings from the deployed contracts, and settle each package into the workspace: add the
preparescript, gitignore the compileddist/directory, and delete the standalone lockfile the CLI writes - Create a
src/lib/contracts/<contract_alias>.tsfile for easy import into your frontend code
soroban-template-astro repository, as well.
Run the initialization script like so:
For a more comprehensive overview of the process of creating, customizing, and using initialization scripts like this, check out the frontend template guide.
package.json scripts, so you can run this initialize script simply by running (from your project’s root directory):