Repository navigation
feat: add register_import! for testing import_contract! callers - #77
Conversation
`import_contract!` bakes a real on-chain address into a contract, and nothing lives at that address in a sandboxed test `Env`. Add `stellar_registry::testutils::register_import!` (behind a new `testutils` feature), which resolves a name through the same code as `import_contract!` and registers the imported Wasm, or a native mock, at that address with `Env::register_at`. Stellar Asset Contracts are a compile error for now. The new `hello_caller` fixture imports `hello_v1` and tests itself with `register_import!`. It is excluded from the workspace, since it needs seeded cache files to compile; `just test-register-import` seeds them and runs it offline, and CI runs that recipe. Part of #65 Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The fixture sits outside the workspace, so it does not pick up the workspace's soroban-sdk bump. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
I have been thinking about this for hours and I still haven't finished reading it all but it's time to give you my first wall of thoughts!!! 😂 😖 🙇🏼 🙇🏼 🙇🏼
(Take this as a good thing! You came up with an interesting solution to a problem I hadn't yet really thought through and it spurred some ideas!!)
Also, as always, I'm open to pushback on any of this! We don't have to do it the ways I'm contemplating, or we do not need to do them right now. Maybe it's fine to do an initial fast release with a cleanup update later.
Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
`args = { admin, quorum: 7u32 }` passes constructor arguments by name.
The macro reads the constructor's parameters from the imported Wasm's
spec, orders the values to match, and calls the typed
`Args::__constructor` that `contractimport!` generates, so names and
types are checked at compile time. Leaving out `args` when the
constructor takes parameters is a compile error listing them. The tuple
form still works and is type-checked too.
Co-Authored-By: Claude <noreply@anthropic.com>
Resolve the Cargo.lock conflict from main's dependency bumps. main moved stellar-xdr to 30 while soroban-spec 28 uses stellar-xdr 28, so read only the raw spec section with soroban-spec and parse it with this crate's stellar-xdr. Co-Authored-By: Claude <noreply@anthropic.com>
The new `unverified_caller` fixture imports `unverified`, the root registry's subregistry on testnet, and tests itself with `register_import!` and named constructor args. `just test-register-import-testnet` runs it with `STELLAR_NETWORK=testnet`, so the id and Wasm are really fetched. It needs network access, so CI doesn't run it. Co-Authored-By: Claude <noreply@anthropic.com>
Drop its committed Cargo.lock (it only runs manually, online) and trim its comments. Co-Authored-By: Claude <noreply@anthropic.com>
`unverified` is the subregistry itself; `unverified/my-token` is an ordinary registered contract, and its five-argument constructor exercises named args more fully. Co-Authored-By: Claude <noreply@anthropic.com>
|
Ok, I've resolved all the comments. I added typed args, but the I also added a recipe for testing through a contract build on testnet, alas that adds another fixture so that I can import that specific contract (alternatively, we could deploy hello_v1 or a different fixture to testnet ... but unverified/token is from the oz-wasms and I thought it fit well). The perk of adding the fixture is that it shows the full example within the repo of how you'd use import_contract and then use register_contract, which I think was what you were aiming for. I like the token one too because it does have a handful of args, so it showcases the typed args well. |
Main now derives asset-syntax SAC addresses at runtime, so resolve() returns a new Resolved::Asset carrying the asset XDR instead of a build-time address. register_import! rejects it like any other SAC, and its expansion now tracks the network env so it re-expands alongside import_contract! when the network changes. Co-Authored-By: Claude <noreply@anthropic.com>
I am building for local but I want to pull a contract/Wasm from testnet. |
Co-Authored-By: Claude <noreply@anthropic.com>
Copies a registered contract from another network: look the name up on `--from-network` (refusing flagged contracts unless `--force`), fetch the deployed contract's Wasm, deploy it on the target network with the given constructor args, and register it there under the same name or `--as`. This lets a local network hold a real copy of a contract that `import_contract!` can then resolve. Co-Authored-By: Claude <noreply@anthropic.com>
`STELLAR_REGISTRY_CONTRACT_ID` points at one registry deployment, usually a local one, so applying it to the source network made a testnet-to-local copy look the name up at the local registry's id on testnet. Use the source network's canonical root registry unless source and target are the same network. Co-Authored-By: Claude <noreply@anthropic.com>
`stellar registry deploy --contract-name <name> --from-network testnet -- <args>` copies a contract registered on another network: it fetches the deployed Wasm there, deploys it here from the source account (not through the registry's `deploy`) and registers it as `--contract-name`. `--from-contract-name` names it on the source network when different; `--force` copies a flagged contract. This replaces the separate `clone-contract` command. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
A fresh local network has nothing at the root registry address, so every registry command failed with a bare "contract not found". On local, check the root first and say how to fix it: deploy the registry contract and set STELLAR_REGISTRY_CONTRACT_ID, or use Stellar Scaffold. Co-Authored-By: Claude <noreply@anthropic.com>
|
Macros shouldn't deploy anything, so the contract's own Since this seemed to be a blocker for you, I added it to this PR rather than a follow-on, though it does expand the PR: It copies the contract from testnet to local and registers it under the same name, so One caveat: the local network needs a root registry deployed first, with |
Getting a contract onto a local network is a separate concern from testing with register_import!, so it moves out of this PR. This restores the CLI and stellar-registry-build to how they were before clone-contract, including dropping the missing-local-registry error that went with it. Co-Authored-By: Claude <noreply@anthropic.com>
A fresh local network has nothing at the root registry address, so every registry command failed with a bare "contract not found". On local, check the root first and say how to fix it: deploy the registry contract and set STELLAR_REGISTRY_CONTRACT_ID, or use Stellar Scaffold. Co-Authored-By: Claude <noreply@anthropic.com>
chadoh
left a comment
There was a problem hiding this comment.
allllmost. This is looking really good. I have a few small-i-swear ideas for cleanup before we merge, though as always I'm happy to be convinced that the current shape of it is good enough, in which case I'll update with the ✅
- Move register_import! and its tests into register.rs; contract.rs keeps the shared resolve. - Drop the token_caller fixture and test-register-import-testnet recipe. - README: workspace dependencies in the example, link the justfile. - Docs: trim the args text, say tuple args are allowed with `contract` but named args aren't, and say the name must match the contract's import_contract! call. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Drop the shorthand note from the README, add a missing period, keep type-checked on one line in the macro docs, list the named `args` form in the unknown-option error, and list register_import! in CLAUDE.md. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
chadoh
left a comment
There was a problem hiding this comment.
Thanks for all the exploration here! Looks like a great starting point now.
## 🤖 New release
* `stellar-registry-macro`: 0.1.3 -> 0.1.4
* `stellar-registry`: 0.1.3 -> 0.1.4 (✓ API compatible changes)
* `stellar-registry-build`: 0.2.0 -> 0.3.0 (⚠ API breaking changes)
* `stellar-registry-cli`: 0.3.0 -> 0.3.1 (✓ API compatible changes)
### ⚠ `stellar-registry-build` breaking changes
```text
--- failure enum_variant_added: enum variant added on exhaustive enum ---
Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/enum_variant_added.ron
Failed in:
variant Error:NoLocalRegistry in /tmp/.tmpx1tFqO/cli/crates/stellar-registry-build/src/error.rs:35
variant Error:NoLocalRegistry in /tmp/.tmpx1tFqO/cli/crates/stellar-registry-build/src/error.rs:35
```
<details><summary><i><b>Changelog</b></i></summary><p>
## `stellar-registry-macro`
<blockquote>
##
[0.1.4](stellar-registry-macro-v0.1.3...stellar-registry-macro-v0.1.4)
- 2026-11-09
### Added
- support Stellar Asset Contracts in register_import!
([#82](#82))
- add register_import! for testing import_contract! callers
([#77](#77))
</blockquote>
## `stellar-registry`
<blockquote>
##
[0.1.4](stellar-registry-v0.1.3...stellar-registry-v0.1.4)
- 2026-11-09
### Added
- support Stellar Asset Contracts in register_import!
([#82](#82))
- add register_import! for testing import_contract! callers
([#77](#77))
</blockquote>
## `stellar-registry-build`
<blockquote>
##
[0.3.0](stellar-registry-build-v0.2.0...stellar-registry-build-v0.3.0)
- 2026-11-09
### Added
- add register_import! for testing import_contract! callers
([#77](#77))
</blockquote>
## `stellar-registry-cli`
<blockquote>
##
[0.3.1](stellar-registry-cli-v0.3.0...stellar-registry-cli-v0.3.1)
- 2026-11-09
### Added
- add register_import! for testing import_contract! callers
([#77](#77))
### Fixed
- read-only commands don't require a source account
([#112](#112))
### Other
- *(deps)* bump shlex from 1.3.0 to 2.0.1
([#105](#105))
</blockquote>
</p></details>
---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Co-authored-by: aha-release-plz[bot] <211513279+aha-release-plz[bot]@users.noreply.github.com>
Part of #65 On `STELLAR_NETWORK=local`, when `import_contract!` or `import_contract_client!` can't find a name in the local registry, the "Things to try" list now also suggests Stellar Scaffold for predictable local builds. Other networks are unchanged, and a missing local registry already has its own error from #77. Before (building a contract that imports `hello_v1`, against a local registry without it): ``` error: Could not resolve a contract id for `hello_v1` on local. Things to try: - Run `stellar registry fetch-contract-id hello_v1` yourself and make sure the name and network match your expectations. - Set STELLAR_NO_REGISTRY=1 to prevent network calls. You will need to create …/target/stellar/local/deployed/hello_v1.id and …/target/stellar/local/deployed/hello_v1.wasm yourself, perhaps using `stellar registry fetch-contract-id` for the id and `stellar contract fetch` for the wasm. stderr from `stellar registry fetch-contract-id`: error: transaction simulation failed: HostError: Error(Contract, #4) … ``` After: ``` error: Could not resolve a contract id for `hello_v1` on local. Things to try: - Run `stellar registry fetch-contract-id hello_v1` yourself and make sure the name and network match your expectations. - Set STELLAR_NO_REGISTRY=1 to prevent network calls. You will need to create …/target/stellar/local/deployed/hello_v1.id and …/target/stellar/local/deployed/hello_v1.wasm yourself, perhaps using `stellar registry fetch-contract-id` for the id and `stellar contract fetch` for the wasm. - Use Stellar Scaffold to achieve predictable local builds: https://stellarscaffold.org stderr from `stellar registry fetch-contract-id`: error: transaction simulation failed: HostError: Error(Contract, #4) … ``` --------- Co-authored-by: Claude <noreply@anthropic.com>
Part of #65
import_contract!bakes the imported contract's on-chain address in at build time, so a unit test'sEnvhas nothing there. This addsregister_import!, behind a newtestutilsfeature onstellar-registry, which resolves the name the same way and registers the imported Wasm, or a native mock, at that address. Constructor args are passed by name and type-checked against the contract's constructor:register_import!(&env, our_dao, args = { admin, quorum: 7u32 }).Tests run with
STELLAR_NETWORK=testnet cargo test, which caches the id and Wasm so later runs can go offline withSTELLAR_NO_REGISTRY=1. Thehello_callerfixture is excluded from the workspace because it needs seeded cache files, andjust test-register-importruns it offline in CI.This also changes one CLI error. On a local network with no registry deployed, every
stellar registrycommand (and soimport_contract!'s lookup) failed with a bare "not found"; the CLI now checks for the root registry on local first and says what to do. Other networks skip the check.Before:
After: