Skip to content

Commit e66112d

Browse files
chadohShapticdependabot[bot]sergiolclemSérgio Luis
authored
Add a ContractClient libraryy for easy contract interaction (#929)
* Add generation of contract clients and an `AssembledTransaction` abstraction (#891) - new e2e tests copied from cli `ts-tests` for the generated bindings, but with TypeScript removed because the ContractClient is generated here dynamically at run time, so we cannot know the types at compile time in the tests. - generate JSON specs from local .wasm files during initiaze.sh instead of generating TS bindings. As explained in the new wasms/specs/README, this is a bummer, but is temporary * Update soroban-cli and sync with upstream `master` (#911) --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: George <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Make simulation optional, simplify wallet/signer interface (#921) * Update examples to use new module and package structure. (#900) * Fixup deprecation to specify exact version * Upgrade references to use latest modules * Bump follow-redirects from 1.15.3 to 1.15.4 (#906) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](follow-redirects/follow-redirects@v1.15.3...v1.15.4) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Export the individual event response instance (#904) * Add support for new `sendTransaction` response field (#905) * Add checks to ensure incorrect fields don't sneak in * Update README to flow better (#907) * Prepare v11.2.0 for release (#908) * Upgrade all dependencies besides chai * Add changelog entries * Eliminating `utility-types` dependency entirely (#912) Eliminated the 'utility-types' package since its functionalities are likely replaced by native TypeScript features. This change includes cleaning up imports and references in the codebase and updating the package.json and yarn.lock accordingly, resulting in a leaner dependency graph and potentially reducing installation times and package size. Co-authored-by: Sérgio Luis <[email protected]> * Release v11.2.1 (#913) * Upgrade dependencies and stellar-base * fix: stop using TimeoutInfinite * optional simulate & wallet, editable TransactionBuilder - Can now pass an `account` OR `wallet` when constructing the ContractClient, or none! If you pass none, you can still make view calls, since they don't need a signer. You will need to pass a `wallet` when calling things that need it, like `signAndSend`. - You can now pass `simulate: false` when first creating your transaction to skip simulation. You can then modify the transaction using the TransactionBuilder at `tx.raw` before manually calling `simulate`. Example: const tx = await myContract.myMethod( { args: 'for', my: 'method', ... }, { simulate: false } ); tx.raw.addMemo(Memo.text('Nice memo, friend!')) await tx.simulate(); - Error types are now collected under `AssembledTransaction.Errors` and `SentTransaction.Errors`. * Ensure that event streaming tests write a valid stream (#917) * Release v11.2.2 (#918) * export ExampleNodeWallet from lib Tyler van der Hoeven thought this would be useful. The current place it's exported from is surpassingly silly. But it functions properly and the tests fail the same way they failed before. * Drop all usage of array-based passing (#924) * feat(e2e-tests): new account & contract per test - New `clientFor` that instantiates a ContractClient for given contract, as well as initializes a new account, funding it with friendbot - Can also use `generateFundedKeypair` directly, as with test-swap - Stop generating anything in initialize.sh. Just check that the network is running and the pinned binary is installed, and fund the `$SOROBAN_ACCOUNT`. Ideally we wouldn't use the binary at all, but for now the tests are still shelling out to the CLI, so it's worth keeping the pinning around * wallet/signer only needs three methods * feat: no more `Wallet` interface Instead, just accept the things that Wallet contained. This avoids the conundrum of what to call the thing. - `Wallet` seems too high-level. Too high-level to be the concern of stellar-sdk, and too high-level for the thing being described here. It's really just two functions: `signTransaction` and `signAuthEntry`. - No need for this thing to defined `getPublicKey`, let alone any of the more complicated wrappers around it that it used to. Just have people pass in a `publicKey`. For convenience' sake, I also allowed this to be a Promise of a string, so that you don't need to instantiate ContractClient asynchronously, instead doing something like: new ContractClient({ publicKey: asyncPublicKeyLookupFromWallet(), ... }) This helps when getting public keys in a browser environment, where public key lookup is async, and adds little complexity to the logic here. * rm getAccount from exposed interface * make simulation public; wrap comments * explicit allowHttp * test(ava): set timeout to 2m * build: move ExampleNodeWallet to own entrypoint No need to pollute the global API or bundle size with this. * build: move ContractClient & AssembledTransaction These are a bit higher-level and experimental, at this point, so let's not clutter the global API or the bundle size unless people really want it. * fix: allow overriding 'publicKey' for 'signAuthEntries' * feat(contract-client): require publicKey * fix: use Networks from stellar-base * doc: explain 'errorTypes' param * build: ContractClient-related things in one dir * typo * move primitive type defs to contractclient * rm ContractClient.generate; do it in constructor * feat: separate rust_types to own import path * feat: don't make people import and use Networks enum I personally find TS enums a little surprising to work with, and my own codebases already have network passphrases littered throughout. I think we can upgrade to use the enum later, after more discussion about the exact interface. Let's not tangle that up in this change. * doc: include rust_types readme info in build the README.md file is not included in the `lib/rust_types` built version, so it's better to include it in a file that people can find by using the go-to-definition function in their editor, such as a `rust_types.ts` file directly, which gets built as `lib/rust_types.d.ts`. * build: make it easier to import rust_types * feat: basicNodeSigner as a plain-object factory Our suggested approach of spreading `signer` into `ContractClient` constructors causes typing issues, since `networkPassphrase` is a private field inside BasicNodeSigner. This means the `signer` needs to be spread in before the inclusion of `networkPassphrase`, otherwise it gets overwritten with `undefined` (or maybe TypeScript just thinks it will get overwritten). --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: George <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sérgio Luis <[email protected]> Co-authored-by: Sérgio Luis <[email protected]> * fix(contract-client): stop jsifying method names This implementation needs to match what is done in the TS Bindings in Rust. Keeping "JSification" logic consistent in both is not worth the slight nicety of allowing people to type camelCaseMethodNames in JS. Additionally, having camelCaseMethodNames in one context when the real method name is probably_snake_case could lead to confusion. If someone types a camelCaseName in their CLI, the CLI will complain, and they might not know what's going on. * docs(contract-client): clean api, write a book Yes, a whole book about AssembledTransaction. It needed documentation; why not make it useful. This also removes an obsolute method, marks a couple as private, adds detail to other comments, fixes the `fee` type, updates SentTransaction docs, and organizes the code a bit. --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: George <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sérgio Luis <[email protected]> Co-authored-by: Sérgio Luis <[email protected]>
1 parent 53ebe3e commit e66112d

34 files changed

+3361
-959
lines changed

.cargo/config.toml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# paths = ["/path/to/override"] # path dependency overrides
2+
3+
[alias] # command aliases
4+
install_soroban = "install --version 20.2.0 --root ./target soroban-cli --debug"
5+
# b = "build --target wasm32-unknown-unknown --release"
6+
# c = "check"
7+
# t = "test"
8+
# r = "run"
9+
# rr = "run --release"
10+
# recursive_example = "rr --example recursions"
11+
# space_example = ["run", "--release", "--", "\"command list\""]
12+
13+
[build]
14+
# jobs = 1 # number of parallel jobs, defaults to # of CPUs
15+
# rustc = "rustc" # the rust compiler tool
16+
# rustc-wrapper = "…" # run this wrapper instead of `rustc`
17+
# rustc-workspace-wrapper = "…" # run this wrapper instead of `rustc` for workspace members
18+
# rustdoc = "rustdoc" # the doc generator tool
19+
# target = "wasm32-unknown-unknown" # build for the target triple (ignored by `cargo install`)
20+
# target-dir = "target" # path of where to place all generated artifacts
21+
# rustdocflags = ["…", "…"] # custom flags to pass to rustdoc
22+
# incremental = true # whether or not to enable incremental compilation
23+
# dep-info-basedir = "…" # path for the base directory for targets in depfiles
24+
25+
# [doc]
26+
# browser = "chromium" # browser to use with `cargo doc --open`,
27+
# # overrides the `BROWSER` environment variable
28+
29+
# [env]
30+
# # Set ENV_VAR_NAME=value for any process run by Cargo
31+
# ENV_VAR_NAME = "value"
32+
# # Set even if already present in environment
33+
# ENV_VAR_NAME_2 = { value = "value", force = true }
34+
# # Value is relative to .cargo directory containing `config.toml`, make absolute
35+
# ENV_VAR_NAME_3 = { value = "relative/path", relative = true }
36+
37+
# [future-incompat-report]
38+
# frequency = 'always' # when to display a notification about a future incompat report
39+
40+
# [cargo-new]
41+
# vcs = "none" # VCS to use ('git', 'hg', 'pijul', 'fossil', 'none')
42+
43+
# [http]
44+
# debug = false # HTTP debugging
45+
# proxy = "host:port" # HTTP proxy in libcurl format
46+
# ssl-version = "tlsv1.3" # TLS version to use
47+
# ssl-version.max = "tlsv1.3" # maximum TLS version
48+
# ssl-version.min = "tlsv1.1" # minimum TLS version
49+
# timeout = 30 # timeout for each HTTP request, in seconds
50+
# low-speed-limit = 10 # network timeout threshold (bytes/sec)
51+
# cainfo = "cert.pem" # path to Certificate Authority (CA) bundle
52+
# check-revoke = true # check for SSL certificate revocation
53+
# multiplexing = true # HTTP/2 multiplexing
54+
# user-agent = "…" # the user-agent header
55+
56+
# [install]
57+
# root = "/some/path" # `cargo install` destination directory
58+
59+
# [net]
60+
# retry = 2 # network retries
61+
# git-fetch-with-cli = true # use the `git` executable for git operations
62+
# offline = true # do not access the network
63+
64+
# [net.ssh]
65+
# known-hosts = ["..."] # known SSH host keys
66+
67+
# [patch.<registry>]
68+
# # Same keys as for [patch] in Cargo.toml
69+
70+
# [profile.<name>] # Modify profile settings via config.
71+
# inherits = "dev" # Inherits settings from [profile.dev].
72+
# opt-level = 0 # Optimization level.
73+
# debug = true # Include debug info.
74+
# split-debuginfo = '...' # Debug info splitting behavior.
75+
# debug-assertions = true # Enables debug assertions.
76+
# overflow-checks = true # Enables runtime integer overflow checks.
77+
# lto = false # Sets link-time optimization.
78+
# panic = 'unwind' # The panic strategy.
79+
# incremental = true # Incremental compilation.
80+
# codegen-units = 16 # Number of code generation units.
81+
# rpath = false # Sets the rpath linking option.
82+
# [profile.<name>.build-override] # Overrides build-script settings.
83+
# # Same keys for a normal profile.
84+
# [profile.<name>.package.<name>] # Override profile for a package.
85+
# # Same keys for a normal profile (minus `panic`, `lto`, and `rpath`).
86+
87+
# [registries.<name>] # registries other than crates.io
88+
# index = "…" # URL of the registry index
89+
# token = "…" # authentication token for the registry
90+
91+
# [registry]
92+
# default = "…" # name of the default registry
93+
# token = "…" # authentication token for crates.io
94+
95+
# [source.<name>] # source definition and replacement
96+
# replace-with = "…" # replace this source with the given named source
97+
# directory = "…" # path to a directory source
98+
# registry = "…" # URL to a registry source
99+
# local-registry = "…" # path to a local registry source
100+
# git = "…" # URL of a git repository source
101+
# branch = "…" # branch name for the git repository
102+
# tag = "…" # tag name for the git repository
103+
# rev = "…" # revision for the git repository
104+
105+
# [target.<triple>]
106+
# linker = "…" # linker to use
107+
# runner = "…" # wrapper to run executables
108+
# rustflags = ["…", "…"] # custom flags for `rustc`
109+
110+
# [target.<cfg>]
111+
# runner = "…" # wrapper to run executables
112+
# rustflags = ["…", "…"] # custom flags for `rustc`
113+
114+
# [target.<triple>.<links>] # `links` build script override
115+
# rustc-link-lib = ["foo"]
116+
# rustc-link-search = ["/path/to/foo"]
117+
# rustc-flags = ["-L", "/some/path"]
118+
# rustc-cfg = ['key="value"']
119+
# rustc-env = {key = "value"}
120+
# rustc-cdylib-link-arg = ["…"]
121+
# metadata_key1 = "value"
122+
# metadata_key2 = "value"
123+
124+
# [term]
125+
# quiet = false # whether cargo output is quiet
126+
# verbose = false # whether cargo provides verbose output
127+
# color = 'auto' # whether cargo colorizes output
128+
# progress.when = 'auto' # whether cargo shows progress bar
129+
# progress.width = 80 # width of progress bar

.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SOROBAN_NETWORK_PASSPHRASE="Standalone Network ; February 2017"
2+
SOROBAN_RPC_URL="http://localhost:8000/soroban/rpc"
3+
SOROBAN_ACCOUNT="me"
4+
FRIENDBOT_URL="http://localhost:8000/friendbot"

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lib

.github/workflows/e2e.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: ContractClient
2+
3+
on:
4+
push:
5+
branches: [master, release/**]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
name: test generated ContractClient
11+
runs-on: ubuntu-22.04
12+
services:
13+
rpc:
14+
image: stellar/quickstart:soroban-dev@sha256:0ad51035cf7caba2fd99c7c1fad0945df6932be7d5c893e1520ccdef7d6a6ffe
15+
ports:
16+
- 8000:8000
17+
env:
18+
ENABLE_LOGS: true
19+
NETWORK: local
20+
ENABLE_SOROBAN_RPC: true
21+
options: >-
22+
--health-cmd "curl --no-progress-meter --fail-with-body -X POST \"http://localhost:8000/soroban/rpc\" -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":8675309,\"method\":\"getNetwork\"}' && curl --no-progress-meter \"http://localhost:8000/friendbot\" | grep '\"invalid_field\": \"addr\"'"
23+
--health-interval 10s
24+
--health-timeout 5s
25+
--health-retries 50
26+
steps:
27+
- uses: actions/checkout@v3
28+
- uses: actions/cache@v3
29+
with:
30+
path: |
31+
target/
32+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
33+
34+
# Workaround for some `yarn` nonsense, see:
35+
# https://github.com/yarnpkg/yarn/issues/6312#issuecomment-429685210
36+
- run: yarn install --network-concurrency 1
37+
- run: yarn build:prod
38+
- run: yarn test:e2e
39+

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ js-stellar-base/
1212

1313
test/unit/out/
1414
.vscode/launch.json
15+
16+
target
17+
.soroban

package.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@
2828
"build:prod": "cross-env NODE_ENV=production yarn _build",
2929
"build:node": "yarn _babel && yarn build:ts",
3030
"build:ts": "tsc -p ./config/tsconfig.json",
31-
"build:test": "tsc -p ./test/tsconfig.json",
31+
"build:test": "tsc -p ./test/unit/tsconfig.json",
3232
"build:browser": "webpack -c config/webpack.config.browser.js",
3333
"build:docs": "cross-env NODE_ENV=docs yarn _babel",
34-
"clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/",
34+
"clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/ test/e2e/.soroban",
3535
"docs": "yarn build:docs && jsdoc -c ./config/.jsdoc.json --verbose",
3636
"test": "yarn build:test && yarn test:node && yarn test:integration && yarn test:browser",
37+
"test:e2e": "./test/e2e/initialize.sh && ava",
3738
"test:node": "yarn _nyc mocha --recursive 'test/unit/**/*.js'",
3839
"test:integration": "yarn _nyc mocha --recursive 'test/integration/**/*.js'",
3940
"test:browser": "karma start config/karma.conf.js",
@@ -97,6 +98,7 @@
9798
"@types/sinon": "^17.0.2",
9899
"@types/urijs": "^1.19.20",
99100
"@typescript-eslint/parser": "^6.20.0",
101+
"ava": "^5.3.1",
100102
"axios-mock-adapter": "^1.22.0",
101103
"babel-loader": "^9.1.3",
102104
"babel-plugin-istanbul": "^6.1.1",
@@ -105,6 +107,7 @@
105107
"chai-as-promised": "^7.1.1",
106108
"chai-http": "^4.3.0",
107109
"cross-env": "^7.0.3",
110+
"dotenv": "^16.3.1",
108111
"eslint": "^8.56.0",
109112
"eslint-config-airbnb-base": "^15.0.0",
110113
"eslint-config-prettier": "^9.0.0",
@@ -150,5 +153,14 @@
150153
"randombytes": "^2.1.0",
151154
"toml": "^3.0.0",
152155
"urijs": "^1.19.1"
156+
},
157+
"ava": {
158+
"files": [
159+
"./test/e2e/src/test-*"
160+
],
161+
"require": [
162+
"dotenv/config"
163+
],
164+
"timeout": "2m"
153165
}
154166
}

0 commit comments

Comments
 (0)