-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: switch from soroban-react to generated libs #117
Conversation
c689821 to
a32b966
Compare
.cargo/config.toml
Outdated
| # paths = ["/path/to/override"] # path dependency overrides | ||
|
|
||
| [alias] # command aliases | ||
| install_soroban = "install --git https://github.com/ahalabs/soroban-tools --rev c00eca975046a3298bdb5b8d5d4dc8ebdcf4a128 --root ./target soroban-cli --debug" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can switch to stellar repo once stellar/stellar-cli#708 gets merged to main
|
|
||
| env: | ||
| RUSTFLAGS: -Dwarnings -Dclippy::all -Dclippy::pedantic | ||
| RUSTFLAGS: -Wclippy::all -Wclippy::pedantic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR copied in the token example from https://github.com/stellar/soroban-examples. But the examples repo does not have the pedantic clippy linting, so this more rigid check failed. This makes the clippy check only warn (-W) rather than deny (-D).
d439956 to
1fd66ad
Compare
|
I ran this with |
Shaptic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buncha small comments but otherwise lgtm 👍
package.json
Outdated
| "start": "next start", | ||
| "lint": "next lint" | ||
| "lint": "next lint", | ||
| "postinstall": "./target/bin/soroban contract bindings typescript --wasm ./target/wasm32-unknown-unknown/release/soroban_crowdfund_contract.wasm --id $(cat ./.soroban-example-dapp/crowdfund_id) --root-dir ./node_modules/crowdfund-contract --network futurenet --contract-name crowdfund-contract && ./target/bin/soroban contract bindings typescript --wasm ./target/wasm32-unknown-unknown/release/abundance_token.wasm --id $(cat ./.soroban-example-dapp/abundance_token_id) --root-dir ./node_modules/abundance-token --network futurenet --contract-name abundance-token" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a for loop on *.wasm could make this a little easier to grok but then you'd need to figure out the IDs somehow so maybe it'll actually be even more confusing hah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also considered putting it in the initialize.sh script. I like the postinstall because it guarantees that it runs after install, and install actually removes "incorrect" folders, which is essentially what these are, so you need to re-add them right away or you start getting errors.
I didn't want to use postinstall 😞
Other things we tried:
- Generating them to
target/js-clients/*, then adding them as dependencies with, for example,"crowdfund-contract": "file:./target/js-clients/crowdfund-contract". This worked most of the time, but failed on CI at thenpm cistep. It seemed like maybenpm ciwould cause NPM to fail to correctly resolve dependencies within thetarget/js-clients/*folders, but only in CI, not locally? You can see the failure here; it was very baffling. - Switching to
yarninstead ofnpm. This required changing"file:./target/js-clients/*"to just"./target/js-clients/*", but at least it worked withyarn install --frozen-lockfileon CI.
We tried multiple variations of these, but we fretted that we would be inundated with support requests for whatever just-right permutation we landed on, since it all seemed so brittle.
Ultimately, we shook our heads at the messy state of local dependencies in the JS ecosystem, and we settled on the postinstall script. It's weird that this means dependencies aren't listed in dependencies, but if everything works then... ¯\_(ツ)_/¯ ???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the breakdown of the history behind this decision, heh, the knowledge-share should help with the "well why didn't you try x" I'm sure we'll see later after this is forgotten hah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✋ I was here and asked this question
| const n = undivided.valueOf() < BigInt(Number.MAX_SAFE_INTEGER) | ||
| ? Number(undivided) / (10 ** decimals) | ||
| : (undivided.valueOf() / (10n ** BigInt(decimals))); | ||
| return String(n); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could do a scale-up by 1e7 then a shift of the decimal point 🤔
also shouldn't this check the result is under MAX_SAFE_INT rather than the value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the value is over MAX_SAFE_INT then you need to perform BigInt division. You can't mix BigInt and Number types during the division operation.
scale-up by
1e7then a shift of the decimal point
Like, using string manipulation? Maybe. Feels a little dirty, but then again, so does what I've written here.
I don't think I nailed this logic, but it's been working well enough for the current app. I think maybe we merge as-is and then someone (you?) can send follow-up PRs with improvements. And maybe tests!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clarifying! That makes sense. Yeah, I did mean using string manips, see this: stellar/js-stellar-base#607 (comment) 🧠 agreed that we can just improve this later; ideally this sorta stuff would have helpers in stellar-base aka soroban-client, anyway
| ); | ||
|
|
||
| return xdr.ScVal.scvI128(new xdr.Int128Parts({lo, hi})); | ||
| export function scValToJs<T>(val: xdr.ScVal): T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gonna use this as a trampoline for stellar/js-stellar-base#628, thanks!!
|
Seems like there are a ton of clippy errors in the abundance token, so running |
|
This also doesn't work in standalone mode anymore (because the RPC_URL is hardcoded to futurenet). We should either fix that (which I'd prefer) or remove standalone mode (as a stopgap). |
| interface GeneratedLibrary { | ||
| Server: SorobanClient.Server | ||
| CONTRACT_ID_HEX: string | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat
paulbellamy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there. A couple failing build and standalone issues
| case xdr.ScValType.scvAddress(): { | ||
| return Address.fromScVal(val).toString() as unknown as T; | ||
| } | ||
| case xdr.ScValType.scvString(): { | ||
| return val.str().toString() as unknown as T; | ||
| } | ||
| case xdr.ScValType.scvSymbol(): { | ||
| return val.sym().toString() as unknown as T; | ||
| } | ||
| case xdr.ScValType.scvBytes(): { | ||
| return val.bytes() as unknown as T; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
realizing on a second look after doing some work to incorporate this into stellar-base@soroban, you can leverage .value() on the XDR structure if the effect is the same, e.g.:
case xdr.ScValType.scvBool():
case xdr.ScValType.scvU32():
case xdr.ScValType.scvI32():
case xdr.ScValType.scvString():
case xdr.ScValType.scvBytes():
return val.value() as unknown as T;because if e.g. val.switch() == scvBytes, then val.value() == val.bytes()
- don't use `soroban lab token` to generate/deploy token - instead, copy example token from examples repo - remove `../examples` reference in `generate` script - add `target/bin/soroban` with pinned version of `soroban` to be used throughout initialize.sh
This copies ideas from the contract in https://github.com/AhaLabs/soroban-abundance-token, allowing anyone to mint themselves tokens. Now this can be used from the frontend directly, so we no longer need to embed the admin's secret key in the JS. Hooray! Upon closer inspection, we didn't need any of those constants anymore, since the contract IDs are embedded in the token libraries.
The whole page no longer reloads after a pledge. Instead, FormPledge now takes an `onPledge` param, which it calls after the pledge succeeds. The now-somewhat-awkward `resultSubmit` has also been filled back out to match what the modal expects, so the modal looks correct.
The CI script needs the values there before it can generate the libraries, of course. And the `token_admin*` stuff isn't needed anymore.
Replace `run-script` with the much more common alias `run` to match the rest of the workflow file
and add .cargo/config.toml to match CI settings
This gets the subscriptions working, and finally breaks all dependence on the @soroban-react packages. The logic is a little confusing, but it works!
This is a hook that can be copy/pasted into other React projects that need such functionality, to work alongside their generated libraries until these generated libraries expose subscription logic natively.
Uses the version with updated freighter-api stellar/stellar-cli#708
Since d771b3f, the default settings are now set in `.cargo/config.toml`
Everything looks correct, but when running the app it fails with:
Error: Cannot connect to insecure soroban-rpc server
406f67f to
0a214fa
Compare
kalepail
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. If there's no reason not to I vote we go ahead and merge this. I love it!
The Idea
Rather than use the
@soroban-reactsuite of packages, this switches to packages generated by the newsoroban contract bindings typescriptcommand.Get it Running
You should be able to run
npm run installandnpm run resetto get everything set up! Check out the new scripts inpackage.jsonto see the magic. Yes, it works with apostinstallscript and generates the libraries directly into thenode_modulesfolder. This smells bad but worked better than anything else we tried!You'll also see that there's a
cargo install_sorobanstep. This uses theinstall_sorobanalias that's defined in the newly-added.cargo/config.tomlfile, and saves it to./target/bin/soroban. If you want to work with your own local branch of soroban-cli, you can remove the built./target/bin/sorobanand add a symlink there instead pointing at your local CLI build'stargetfolder.