Skip to content

Commit

Permalink
feat: Generate TS from XDR (#871)
Browse files Browse the repository at this point in the history
Co-authored-by: Chad Ostrowski <[email protected]>
Co-authored-by: Paul Bellamy <[email protected]>
  • Loading branch information
3 people authored Jun 12, 2023
1 parent 1ad9c0e commit 7d143e4
Show file tree
Hide file tree
Showing 35 changed files with 2,050 additions and 18 deletions.
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Install binaryen (for `wasm-opt`):
brew install binaryen
```

If any changes to typescript bindings. You need to rebuild the snapshot example. `make build-snapshot`

## Command Cheatsheet

See the `Makefile` for all the common commands you might need.
Expand Down Expand Up @@ -64,3 +66,8 @@ Build and test on changes:
```
make watch
```

Build the snapshot for testing project generation:
```
make build-snapshot
```
61 changes: 61 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ doc: fmt
cargo test --doc -p soroban-sdk -p soroban-sdk-macros --features testutils
cargo +nightly doc -p soroban-sdk --no-deps --features docs,testutils $(CARGO_DOC_ARGS)

build-snapshot:
cargo test --package soroban-spec --lib -- gen::typescript::boilerplate::test::build_package --exact --nocapture --ignored

test: fmt build
cargo hack --feature-powerset --ignore-unknown-features --features testutils --exclude-features docs $(CARGO_TEST_SUBCOMMAND)

Expand Down
8 changes: 6 additions & 2 deletions soroban-spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = "1.69"
stellar-xdr = { workspace = true, features = ["next", "std", "serde"] }
base64 = "0.13.0"
thiserror = "1.0.32"
syn = {version="2.0",features=["full"]}
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
proc-macro2 = "1.0"
itertools = "0.10.3"
Expand All @@ -25,6 +25,10 @@ serde = "1.0.82"
serde_derive = "1.0.82"
serde_json = "1.0.82"
prettyplease = "0.2.4"
include_dir = { version = "0.7.3", features = ["glob"] }
heck = "0.4.1"

[dev_dependencies]
[dev-dependencies]
temp-dir = "0.1.11"
pretty_assertions = "1.2.1"
walkdir = "2.3.3"
2 changes: 2 additions & 0 deletions soroban-spec/fixtures/ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
out/
49 changes: 49 additions & 0 deletions soroban-spec/fixtures/ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# contract-data-example JS

JS library for interacting with [Soroban](https://soroban.stellar.org/) smart contract `contract-data-example` via Soroban RPC.

This library was automatically generated by Soroban CLI using a command similar to:

```bash
soroban contract bindings ts \
--rpc-url https://rpc-futurenet.stellar.org:443/soroban/rpc \
--network-passphrase "Test SDF Future Network ; October 2022" \
--id C… \
--name contract-data-example
```

It uses these settings by default, but you can override them with environment variables if you need to:

- **Contract ID**: `C…`

Override with environment variable `SOROBAN_CONTRACT_DATA_EXAMPLE_CONTRACT_ID` or `PUBLIC_SOROBAN_CONTRACT_DATA_EXAMPLE_CONTRACT_ID`

- **RPC endpoint**: `https://rpc-futurenet.stellar.org:443/soroban/rpc`

Override with environment variable `SOROBAN_RPC_URL` or `PUBLIC_SOROBAN_RPC_URL`

- **Network Passphrase**: `Test SDF Future Network ; October 2022`

Override with environment variable `SOROBAN_NETWORK_PASSPHRASE` or `PUBLIC_SOROBAN_NETWORK_PASSPHRASE`

# Use it

You don't need to publish this library to NPM to use it. You can add it to your project's `package.json` using a file path:

```json
{
"dependencies": {
"contract-data-example": "./path/to/this/folder"
}
}
```

Then you can import it into your editor and see inline documentation for all of its exports:

```js
import * as contractDataExample from "contract-data-example"

contractDataExample.|
```

As long as your editor is configured to show JavaScript/TypeScript documentation, you can pause your typing at that `|` to get a list of all exports and inline-documentation for each. It exports a separate [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) function for each method in the smart contract, with documentation for each generated from the comments the contract's author included in the original source code.
21 changes: 21 additions & 0 deletions soroban-spec/fixtures/ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "0.0.0",
"name": "contract-data-example",
"dependencies": {
"@stellar/freighter-api": "1.4.0",
"buffer": "6.0.3",
"soroban-client": "0.8.0",
"bigint-conversion": "2.4.1"
},
"scripts": {
"build": "node ./scripts/build.mjs"
},
"exports": {
"require": "./dist/cjs/index.js",
"import": "./dist/esm/index.js"
},
"typings": "dist/types/index.d.ts",
"devDependencies": {
"typescript": "5.0.4"
}
}
32 changes: 32 additions & 0 deletions soroban-spec/fixtures/ts/scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { spawnSync } from "node:child_process"
import fs from "node:fs"
import path from "node:path"

const buildDir = "./dist"

spawnSync("rm", ["-rf", buildDir], { stdio: "inherit" })
spawnSync("tsc", ["-b", "./scripts/tsconfig.cjs.json", "./scripts/tsconfig.esm.json", "./scripts/tsconfig.types.json"], { stdio: "inherit" })

function createEsmModulePackageJson() {
fs.readdir(buildDir, function (err, dirs) {
if (err) {
throw err
}
dirs.forEach(function (dir) {
if (dir === "esm") {
// 1. add package.json file with "type": "module"
var packageJsonFile = path.join(buildDir, dir, "/package.json")
if (!fs.existsSync(packageJsonFile)) {
fs.writeFileSync(
packageJsonFile,
'{"type": "module"}',
'utf8',
err => { if (err) throw err }
)
}
}
})
})
}

createEsmModulePackageJson()
7 changes: 7 additions & 0 deletions soroban-spec/fixtures/ts/scripts/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../dist/cjs",
"module": "commonjs"
}
}
7 changes: 7 additions & 0 deletions soroban-spec/fixtures/ts/scripts/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../dist/esm",
"module": "esnext"
}
}
8 changes: 8 additions & 0 deletions soroban-spec/fixtures/ts/scripts/tsconfig.types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../dist/types",
"declaration": true,
"emitDeclarationOnly": true
}
}
25 changes: 25 additions & 0 deletions soroban-spec/fixtures/ts/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Contract } from 'soroban-client'

/**
* The Soroban contract ID for the contract-data-example contract.
*/
export const CONTRACT_ID = 'C…'

/**
* The Soroban contract ID for the contract-data-example contract, in hex.
* If {@link CONTRACT_ID} is a new-style `C…` string, you will need this hex
* version when making calls to RPC for now.
*/
export const CONTRACT_ID_HEX = new Contract(CONTRACT_ID).contractId('hex')


/**
* The Soroban network passphrase used to initialize this library.
*/
export const NETWORK_PASSPHRASE = 'Test SDF Future Network ; October 2022'

/**
* The Soroban RPC endpoint used to initialize this library.
*/
export const RPC_URL = 'https://rpc-futurenet.stellar.org:443/soroban/rpc'

Loading

0 comments on commit 7d143e4

Please sign in to comment.