From bb00731cfa65cf5a2dc3650c14d86e47694ba1ff Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:15:02 -0500 Subject: [PATCH] feat(ts-bindings): Client.deploy with constructor args - allow omiting `--contract-id` flag to `stellar contract bindings typescript` command, passing only `--wasm` instead - if no `--contract-id` is included, then the contract will not be fetched from a network, so no network information is logged in this case - this means it's possible to create TS Bindings libraries for contracts that have not yet been deployed, which makes it useful to add types for `Client.deploy` to the generated TS Bindings --- .github/workflows/bindings-ts.yml | 3 + FULL_HELP_DOCS.md | 10 +- .../fixtures/test_custom_types/README.md | 4 +- .../test_custom_types/dist/index.d.ts | 628 ------------------ .../fixtures/test_custom_types/dist/index.js | 97 --- .../test_custom_types/package-lock.json | 355 ---------- .../fixtures/test_custom_types/src/index.ts | 24 +- .../src/boilerplate.rs | 47 +- cmd/crates/soroban-spec-typescript/src/lib.rs | 36 +- .../src/project_template/src/index.ts | 1 + .../ts-tests/initialize.sh | 15 +- .../ts-tests/package-lock.json | 6 +- .../ts-tests/src/test-constructor-args.ts | 29 + .../commands/contract/bindings/typescript.rs | 84 ++- 14 files changed, 186 insertions(+), 1153 deletions(-) delete mode 100644 cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.d.ts delete mode 100644 cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.js delete mode 100644 cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json create mode 100644 cmd/crates/soroban-spec-typescript/ts-tests/src/test-constructor-args.ts diff --git a/.github/workflows/bindings-ts.yml b/.github/workflows/bindings-ts.yml index 957661c4c..9b5f767ac 100644 --- a/.github/workflows/bindings-ts.yml +++ b/.github/workflows/bindings-ts.yml @@ -24,6 +24,9 @@ jobs: --health-timeout 5s --health-retries 50 steps: + - uses: actions/setup-node@v4 + with: + node-version: '22.x' - uses: actions/checkout@v4 - uses: actions/cache@v4 with: diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index f007d0bf4..5f48b353a 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -289,20 +289,20 @@ Generate Rust bindings Generate a TypeScript / JavaScript package -**Usage:** `stellar contract bindings typescript [OPTIONS] --output-dir --contract-id ` +**Usage:** `stellar contract bindings typescript [OPTIONS] --output-dir ` ###### **Options:** -* `--wasm ` — Path to optional wasm binary +* `--wasm ` — Path to wasm file on local filesystem. You must either include this OR `--contract-id` +* `--contract-id ` — A contract ID/address on a network (if no network settings provided, Testnet will be assumed). You must either include this OR `--wasm` * `--output-dir ` — Where to place generated project * `--overwrite` — Whether to overwrite output directory if it already exists -* `--contract-id ` — The contract ID/address on the network -* `--global` — Use global config -* `--config-dir ` — Location of config directory, default is "." * `--rpc-url ` — RPC server endpoint * `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `--network ` — Name of network to use from config +* `--global` — Use global config +* `--config-dir ` — Location of config directory, default is "." diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md index 03f87f30b..efd62a6f7 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/README.md @@ -8,7 +8,7 @@ This library was automatically generated by Soroban CLI using a command similar soroban contract bindings ts \ --rpc-url https://rpc-futurenet.stellar.org:443 \ --network-passphrase "Test SDF Future Network ; October 2022" \ - --contract-id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK \ + --contract-id INSERT_CONTRACT_ID_HERE \ --output-dir ./path/to/test_custom_types ``` @@ -30,7 +30,7 @@ However, we've actually encountered [frustration](https://github.com/stellar/sor ```json "scripts": { - "postinstall": "soroban contract bindings ts --rpc-url https://rpc-futurenet.stellar.org:443 --network-passphrase \"Test SDF Future Network ; October 2022\" --id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK --name test_custom_types" + "postinstall": "soroban contract bindings ts --rpc-url https://rpc-futurenet.stellar.org:443 --network-passphrase \"Test SDF Future Network ; October 2022\" --id INSERT_CONTRACT_ID_HERE --name test_custom_types" } ``` diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.d.ts deleted file mode 100644 index cd888cc04..000000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.d.ts +++ /dev/null @@ -1,628 +0,0 @@ -import { Buffer } from "buffer"; -import { AssembledTransaction, Client as ContractClient, ClientOptions as ContractClientOptions, Result } from '@stellar/stellar-sdk/contract'; -import type { u32, i32, i64, u128, i128, u256, i256, Option } from '@stellar/stellar-sdk/contract'; -export * from '@stellar/stellar-sdk'; -export * as contract from '@stellar/stellar-sdk/contract'; -export * as rpc from '@stellar/stellar-sdk/rpc'; -export declare const networks: { - readonly futurenet: { - readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; - }; -}; -/** - * This is from the rust doc above the struct Test - */ -export interface Test { - a: u32; - b: boolean; - c: string; -} -export type SimpleEnum = { - tag: "First"; - values: void; -} | { - tag: "Second"; - values: void; -} | { - tag: "Third"; - values: void; -}; -export declare enum RoyalCard { - Jack = 11, - Queen = 12, - King = 13 -} -export type TupleStruct = readonly [Test, SimpleEnum]; -export type ComplexEnum = { - tag: "Struct"; - values: readonly [Test]; -} | { - tag: "Tuple"; - values: readonly [TupleStruct]; -} | { - tag: "Enum"; - values: readonly [SimpleEnum]; -} | { - tag: "Asset"; - values: readonly [string, i128]; -} | { - tag: "Void"; - values: void; -}; -export declare const Errors: { - /** - * Please provide an odd number - */ - 1: { - message: string; - }; -}; -export interface Client { - /** - * Construct and simulate a hello transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - hello: ({ hello }: { - hello: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a woid transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - woid: (options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a val transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - val: (options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a u32_fail_on_even transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u32_fail_on_even: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>>; - /** - * Construct and simulate a u32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u32_: ({ u32_ }: { - u32_: u32; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a i32_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i32_: ({ i32_ }: { - i32_: i32; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a i64_ transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i64_: ({ i64_ }: { - i64_: i64; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a strukt_hel transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - * Example contract method which takes a struct - */ - strukt_hel: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>>; - /** - * Construct and simulate a strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - strukt: ({ strukt }: { - strukt: Test; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a simple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - simple: ({ simple }: { - simple: SimpleEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a complex transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - complex: ({ complex }: { - complex: ComplexEnum; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a addresse transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - addresse: ({ addresse }: { - addresse: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a bytes transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - bytes: ({ bytes }: { - bytes: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a bytes_n transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - bytes_n: ({ bytes_n }: { - bytes_n: Buffer; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a card transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - card: ({ card }: { - card: RoyalCard; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a boolean transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - boolean: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a not transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - * Negates a boolean value - */ - not: ({ boolean }: { - boolean: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a i128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i128: ({ i128 }: { - i128: i128; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a u128 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u128: ({ u128 }: { - u128: u128; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a multi_args transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - multi_args: ({ a, b }: { - a: u32; - b: boolean; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a map transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - map: ({ map }: { - map: Map; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>>; - /** - * Construct and simulate a vec transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - vec: ({ vec }: { - vec: Array; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>>; - /** - * Construct and simulate a tuple transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - tuple: ({ tuple }: { - tuple: readonly [string, u32]; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a option transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - * Example of an optional argument - */ - option: ({ option }: { - option: Option; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>>; - /** - * Construct and simulate a u256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - u256: ({ u256 }: { - u256: u256; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a i256 transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - i256: ({ i256 }: { - i256: i256; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a string transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - string: ({ string }: { - string: string; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; - /** - * Construct and simulate a tuple_strukt transaction. Returns an `AssembledTransaction` object which will have a `result` field containing the result of the simulation. If this transaction changes contract state, you will need to call `signAndSend()` on the returned object. - */ - tuple_strukt: ({ tuple_strukt }: { - tuple_strukt: TupleStruct; - }, options?: { - /** - * The fee to pay for the transaction. Default: BASE_FEE - */ - fee?: number; - /** - * The maximum amount of time to wait for the transaction to complete. Default: DEFAULT_TIMEOUT - */ - timeoutInSeconds?: number; - /** - * Whether to automatically simulate the transaction when constructing the AssembledTransaction. Default: true - */ - simulate?: boolean; - }) => Promise>; -} -export declare class Client extends ContractClient { - readonly options: ContractClientOptions; - constructor(options: ContractClientOptions); - readonly fromJSON: { - hello: (json: string) => AssembledTransaction; - woid: (json: string) => AssembledTransaction; - val: (json: string) => AssembledTransaction; - u32_fail_on_even: (json: string) => AssembledTransaction>; - u32_: (json: string) => AssembledTransaction; - i32_: (json: string) => AssembledTransaction; - i64_: (json: string) => AssembledTransaction; - strukt_hel: (json: string) => AssembledTransaction; - strukt: (json: string) => AssembledTransaction; - simple: (json: string) => AssembledTransaction; - complex: (json: string) => AssembledTransaction; - addresse: (json: string) => AssembledTransaction; - bytes: (json: string) => AssembledTransaction; - bytes_n: (json: string) => AssembledTransaction; - card: (json: string) => AssembledTransaction; - boolean: (json: string) => AssembledTransaction; - not: (json: string) => AssembledTransaction; - i128: (json: string) => AssembledTransaction; - u128: (json: string) => AssembledTransaction; - multi_args: (json: string) => AssembledTransaction; - map: (json: string) => AssembledTransaction>; - vec: (json: string) => AssembledTransaction; - tuple: (json: string) => AssembledTransaction; - option: (json: string) => AssembledTransaction>; - u256: (json: string) => AssembledTransaction; - i256: (json: string) => AssembledTransaction; - string: (json: string) => AssembledTransaction; - tuple_strukt: (json: string) => AssembledTransaction; - }; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.js deleted file mode 100644 index 4286b2a68..000000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/index.js +++ /dev/null @@ -1,97 +0,0 @@ -import { Buffer } from "buffer"; -import { Client as ContractClient, Spec as ContractSpec, } from '@stellar/stellar-sdk/contract'; -export * from '@stellar/stellar-sdk'; -export * as contract from '@stellar/stellar-sdk/contract'; -export * as rpc from '@stellar/stellar-sdk/rpc'; -if (typeof window !== 'undefined') { - //@ts-ignore Buffer exists - window.Buffer = window.Buffer || Buffer; -} -export const networks = { - futurenet: { - networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", - } -}; -export var RoyalCard; -(function (RoyalCard) { - RoyalCard[RoyalCard["Jack"] = 11] = "Jack"; - RoyalCard[RoyalCard["Queen"] = 12] = "Queen"; - RoyalCard[RoyalCard["King"] = 13] = "King"; -})(RoyalCard || (RoyalCard = {})); -export const Errors = { - /** - * Please provide an odd number - */ - 1: { message: "NumberMustBeOdd" } -}; -export class Client extends ContractClient { - options; - constructor(options) { - super(new ContractSpec(["AAAAAQAAAC9UaGlzIGlzIGZyb20gdGhlIHJ1c3QgZG9jIGFib3ZlIHRoZSBzdHJ1Y3QgVGVzdAAAAAAAAAAABFRlc3QAAAADAAAAAAAAAAFhAAAAAAAABAAAAAAAAAABYgAAAAAAAAEAAAAAAAAAAWMAAAAAAAAR", - "AAAAAgAAAAAAAAAAAAAAClNpbXBsZUVudW0AAAAAAAMAAAAAAAAAAAAAAAVGaXJzdAAAAAAAAAAAAAAAAAAABlNlY29uZAAAAAAAAAAAAAAAAAAFVGhpcmQAAAA=", - "AAAAAwAAAAAAAAAAAAAACVJveWFsQ2FyZAAAAAAAAAMAAAAAAAAABEphY2sAAAALAAAAAAAAAAVRdWVlbgAAAAAAAAwAAAAAAAAABEtpbmcAAAAN", - "AAAAAQAAAAAAAAAAAAAAC1R1cGxlU3RydWN0AAAAAAIAAAAAAAAAATAAAAAAAAfQAAAABFRlc3QAAAAAAAAAATEAAAAAAAfQAAAAClNpbXBsZUVudW0AAA==", - "AAAAAgAAAAAAAAAAAAAAC0NvbXBsZXhFbnVtAAAAAAUAAAABAAAAAAAAAAZTdHJ1Y3QAAAAAAAEAAAfQAAAABFRlc3QAAAABAAAAAAAAAAVUdXBsZQAAAAAAAAEAAAfQAAAAC1R1cGxlU3RydWN0AAAAAAEAAAAAAAAABEVudW0AAAABAAAH0AAAAApTaW1wbGVFbnVtAAAAAAABAAAAAAAAAAVBc3NldAAAAAAAAAIAAAATAAAACwAAAAAAAAAAAAAABFZvaWQ=", - "AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAAAQAAABxQbGVhc2UgcHJvdmlkZSBhbiBvZGQgbnVtYmVyAAAAD051bWJlck11c3RCZU9kZAAAAAAB", - "AAAAAAAAAAAAAAAFaGVsbG8AAAAAAAABAAAAAAAAAAVoZWxsbwAAAAAAABEAAAABAAAAEQ==", - "AAAAAAAAAAAAAAAEd29pZAAAAAAAAAAA", - "AAAAAAAAAAAAAAADdmFsAAAAAAAAAAABAAAAAA==", - "AAAAAAAAAAAAAAAQdTMyX2ZhaWxfb25fZXZlbgAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAA+kAAAAEAAAAAw==", - "AAAAAAAAAAAAAAAEdTMyXwAAAAEAAAAAAAAABHUzMl8AAAAEAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAAEaTMyXwAAAAEAAAAAAAAABGkzMl8AAAAFAAAAAQAAAAU=", - "AAAAAAAAAAAAAAAEaTY0XwAAAAEAAAAAAAAABGk2NF8AAAAHAAAAAQAAAAc=", - "AAAAAAAAACxFeGFtcGxlIGNvbnRyYWN0IG1ldGhvZCB3aGljaCB0YWtlcyBhIHN0cnVjdAAAAApzdHJ1a3RfaGVsAAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAPqAAAAEQ==", - "AAAAAAAAAAAAAAAGc3RydWt0AAAAAAABAAAAAAAAAAZzdHJ1a3QAAAAAB9AAAAAEVGVzdAAAAAEAAAfQAAAABFRlc3Q=", - "AAAAAAAAAAAAAAAGc2ltcGxlAAAAAAABAAAAAAAAAAZzaW1wbGUAAAAAB9AAAAAKU2ltcGxlRW51bQAAAAAAAQAAB9AAAAAKU2ltcGxlRW51bQAA", - "AAAAAAAAAAAAAAAHY29tcGxleAAAAAABAAAAAAAAAAdjb21wbGV4AAAAB9AAAAALQ29tcGxleEVudW0AAAAAAQAAB9AAAAALQ29tcGxleEVudW0A", - "AAAAAAAAAAAAAAAIYWRkcmVzc2UAAAABAAAAAAAAAAhhZGRyZXNzZQAAABMAAAABAAAAEw==", - "AAAAAAAAAAAAAAAFYnl0ZXMAAAAAAAABAAAAAAAAAAVieXRlcwAAAAAAAA4AAAABAAAADg==", - "AAAAAAAAAAAAAAAHYnl0ZXNfbgAAAAABAAAAAAAAAAdieXRlc19uAAAAA+4AAAAJAAAAAQAAA+4AAAAJ", - "AAAAAAAAAAAAAAAEY2FyZAAAAAEAAAAAAAAABGNhcmQAAAfQAAAACVJveWFsQ2FyZAAAAAAAAAEAAAfQAAAACVJveWFsQ2FyZAAAAA==", - "AAAAAAAAAAAAAAAHYm9vbGVhbgAAAAABAAAAAAAAAAdib29sZWFuAAAAAAEAAAABAAAAAQ==", - "AAAAAAAAABdOZWdhdGVzIGEgYm9vbGVhbiB2YWx1ZQAAAAADbm90AAAAAAEAAAAAAAAAB2Jvb2xlYW4AAAAAAQAAAAEAAAAB", - "AAAAAAAAAAAAAAAEaTEyOAAAAAEAAAAAAAAABGkxMjgAAAALAAAAAQAAAAs=", - "AAAAAAAAAAAAAAAEdTEyOAAAAAEAAAAAAAAABHUxMjgAAAAKAAAAAQAAAAo=", - "AAAAAAAAAAAAAAAKbXVsdGlfYXJncwAAAAAAAgAAAAAAAAABYQAAAAAAAAQAAAAAAAAAAWIAAAAAAAABAAAAAQAAAAQ=", - "AAAAAAAAAAAAAAADbWFwAAAAAAEAAAAAAAAAA21hcAAAAAPsAAAABAAAAAEAAAABAAAD7AAAAAQAAAAB", - "AAAAAAAAAAAAAAADdmVjAAAAAAEAAAAAAAAAA3ZlYwAAAAPqAAAABAAAAAEAAAPqAAAABA==", - "AAAAAAAAAAAAAAAFdHVwbGUAAAAAAAABAAAAAAAAAAV0dXBsZQAAAAAAA+0AAAACAAAAEQAAAAQAAAABAAAD7QAAAAIAAAARAAAABA==", - "AAAAAAAAAB9FeGFtcGxlIG9mIGFuIG9wdGlvbmFsIGFyZ3VtZW50AAAAAAZvcHRpb24AAAAAAAEAAAAAAAAABm9wdGlvbgAAAAAD6AAAAAQAAAABAAAD6AAAAAQ=", - "AAAAAAAAAAAAAAAEdTI1NgAAAAEAAAAAAAAABHUyNTYAAAAMAAAAAQAAAAw=", - "AAAAAAAAAAAAAAAEaTI1NgAAAAEAAAAAAAAABGkyNTYAAAANAAAAAQAAAA0=", - "AAAAAAAAAAAAAAAGc3RyaW5nAAAAAAABAAAAAAAAAAZzdHJpbmcAAAAAABAAAAABAAAAEA==", - "AAAAAAAAAAAAAAAMdHVwbGVfc3RydWt0AAAAAQAAAAAAAAAMdHVwbGVfc3RydWt0AAAH0AAAAAtUdXBsZVN0cnVjdAAAAAABAAAH0AAAAAtUdXBsZVN0cnVjdAA="]), options); - this.options = options; - } - fromJSON = { - hello: (this.txFromJSON), - woid: (this.txFromJSON), - val: (this.txFromJSON), - u32_fail_on_even: (this.txFromJSON), - u32_: (this.txFromJSON), - i32_: (this.txFromJSON), - i64_: (this.txFromJSON), - strukt_hel: (this.txFromJSON), - strukt: (this.txFromJSON), - simple: (this.txFromJSON), - complex: (this.txFromJSON), - addresse: (this.txFromJSON), - bytes: (this.txFromJSON), - bytes_n: (this.txFromJSON), - card: (this.txFromJSON), - boolean: (this.txFromJSON), - not: (this.txFromJSON), - i128: (this.txFromJSON), - u128: (this.txFromJSON), - multi_args: (this.txFromJSON), - map: (this.txFromJSON), - vec: (this.txFromJSON), - tuple: (this.txFromJSON), - option: (this.txFromJSON), - u256: (this.txFromJSON), - i256: (this.txFromJSON), - string: (this.txFromJSON), - tuple_strukt: (this.txFromJSON) - }; -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json deleted file mode 100644 index a4e3759e2..000000000 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package-lock.json +++ /dev/null @@ -1,355 +0,0 @@ -{ - "name": "test_custom_types", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "test_custom_types", - "version": "0.0.0", - "dependencies": { - "@stellar/stellar-sdk": "13.0.0", - "buffer": "6.0.3" - }, - "devDependencies": { - "typescript": "^5.6.2" - } - }, - "node_modules/@stellar/js-xdr": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.1.2.tgz", - "integrity": "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==", - "license": "Apache-2.0" - }, - "node_modules/@stellar/stellar-base": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-13.0.1.tgz", - "integrity": "sha512-Xbd12mc9Oj/130Tv0URmm3wXG77XMshZtZ2yNCjqX5ZbMD5IYpbBs3DVCteLU/4SLj/Fnmhh1dzhrQXnk4r+pQ==", - "license": "Apache-2.0", - "dependencies": { - "@stellar/js-xdr": "^3.1.2", - "base32.js": "^0.1.0", - "bignumber.js": "^9.1.2", - "buffer": "^6.0.3", - "sha.js": "^2.3.6", - "tweetnacl": "^1.0.3" - }, - "optionalDependencies": { - "sodium-native": "^4.3.0" - } - }, - "node_modules/@stellar/stellar-sdk": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-13.0.0.tgz", - "integrity": "sha512-+wvmKi+XWwu27nLYTM17EgBdpbKohEkOfCIK4XKfsI4WpMXAqvnqSm98i9h5dAblNB+w8BJqzGs1JY0PtTGm4A==", - "license": "Apache-2.0", - "dependencies": { - "@stellar/stellar-base": "^13.0.1", - "axios": "^1.7.7", - "bignumber.js": "^9.1.2", - "eventsource": "^2.0.2", - "feaxios": "^0.0.20", - "randombytes": "^2.1.0", - "toml": "^3.0.0", - "urijs": "^1.19.1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/base32.js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", - "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eventsource": { - "version": "2.0.2", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/feaxios": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/feaxios/-/feaxios-0.0.20.tgz", - "integrity": "sha512-g3hm2YDNffNxA3Re3Hd8ahbpmDee9Fv1Pb1C/NoWsjY7mtD8nyNeJytUzn+DK0Hyl9o6HppeWOrtnqgmhOYfWA==", - "license": "MIT", - "dependencies": { - "is-retry-allowed": "^3.0.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/is-retry-allowed": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-3.0.0.tgz", - "integrity": "sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz", - "integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==", - "license": "MIT", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sodium-native": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.1.tgz", - "integrity": "sha512-YdP64gAdpIKHfL4ttuX4aIfjeunh9f+hNeQJpE9C8UMndB3zkgZ7YmmGT4J2+v6Ibyp6Wem8D1TcSrtdW0bqtg==", - "license": "MIT", - "optional": true, - "dependencies": { - "node-gyp-build": "^4.8.0" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "license": "MIT" - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "license": "Unlicense" - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/urijs": { - "version": "1.19.11", - "license": "MIT" - } - } -} diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts index 7f2d5b000..514008096 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/index.ts @@ -4,6 +4,7 @@ import { AssembledTransaction, Client as ContractClient, ClientOptions as ContractClientOptions, + MethodOptions, Result, Spec as ContractSpec, } from '@stellar/stellar-sdk/contract'; @@ -30,12 +31,7 @@ if (typeof window !== 'undefined') { } -export const networks = { - futurenet: { - networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", - } -} as const + /** @@ -631,6 +627,22 @@ export interface Client { } export class Client extends ContractClient { + static async deploy( + /** Constructor/Initialization Args for the contract's `__constructor` method */ + args: null, + /** Options for initalizing a Client as well as for calling a method, with extras specific to deploying. */ + options: MethodOptions & + Omit & { + /** The hash of the Wasm blob, which must already be installed on-chain. */ + wasmHash: Buffer | string; + /** Salt used to generate the contract's ID. Passed through to {@link Operation.createCustomContract}. Default: random. */ + salt?: Buffer | Uint8Array; + /** The format used to decode `wasmHash`, if it's provided as a string. */ + format?: "hex" | "base64"; + } + ): Promise> { + return ContractClient.deploy(args, options) + } constructor(public readonly options: ContractClientOptions) { super( new ContractSpec([ "AAAAAQAAAC9UaGlzIGlzIGZyb20gdGhlIHJ1c3QgZG9jIGFib3ZlIHRoZSBzdHJ1Y3QgVGVzdAAAAAAAAAAABFRlc3QAAAADAAAAAAAAAAFhAAAAAAAABAAAAAAAAAABYgAAAAAAAAEAAAAAAAAAAWMAAAAAAAAR", diff --git a/cmd/crates/soroban-spec-typescript/src/boilerplate.rs b/cmd/crates/soroban-spec-typescript/src/boilerplate.rs index 501d51434..bf5631eda 100644 --- a/cmd/crates/soroban-spec-typescript/src/boilerplate.rs +++ b/cmd/crates/soroban-spec-typescript/src/boilerplate.rs @@ -47,9 +47,9 @@ impl Project { pub fn init( &self, contract_name: &str, - contract_id: &str, - rpc_url: &str, - network_passphrase: &str, + contract_id: Option<&str>, + rpc_url: Option<&str>, + network_passphrase: Option<&str>, spec: &[ScSpecEntry], ) -> std::io::Result<()> { self.replace_placeholder_patterns(contract_name, contract_id, rpc_url, network_passphrase)?; @@ -59,9 +59,9 @@ impl Project { fn replace_placeholder_patterns( &self, contract_name: &str, - contract_id: &str, - rpc_url: &str, - network_passphrase: &str, + contract_id: Option<&str>, + rpc_url: Option<&str>, + network_passphrase: Option<&str>, ) -> std::io::Result<()> { let replacement_strings = &[ ("INSERT_CONTRACT_NAME_HERE", contract_name), @@ -73,9 +73,18 @@ impl Project { "INSERT_CAMEL_CASE_CONTRACT_NAME_HERE", &contract_name.to_lower_camel_case(), ), - ("INSERT_CONTRACT_ID_HERE", contract_id), - ("INSERT_NETWORK_PASSPHRASE_HERE", network_passphrase), - ("INSERT_RPC_URL_HERE", rpc_url), + ( + "INSERT_CONTRACT_ID_HERE", + contract_id.unwrap_or("INSERT_CONTRACT_ID_HERE"), + ), + ( + "INSERT_RPC_URL_HERE", + rpc_url.unwrap_or("INSERT_RPC_URL_HERE"), + ), + ( + "INSERT_NETWORK_PASSPHRASE_HERE", + network_passphrase.unwrap_or("INSERT_NETWORK_PASSPHRASE_HERE"), + ), ]; let root: &Path = self.as_ref(); ["package.json", "README.md", "src/index.ts"] @@ -93,8 +102,8 @@ impl Project { fn append_index_ts( &self, spec: &[ScSpecEntry], - contract_id: &str, - network_passphrase: &str, + contract_id: Option<&str>, + network_passphrase: Option<&str>, ) -> std::io::Result<()> { let networks = Project::format_networks_object(contract_id, network_passphrase); let types_and_fns = generate(spec); @@ -104,7 +113,15 @@ impl Project { .write_all(format!("\n\n{networks}\n\n{types_and_fns}").as_bytes()) } - fn format_networks_object(contract_id: &str, network_passphrase: &str) -> String { + fn format_networks_object( + contract_id: Option<&str>, + network_passphrase: Option<&str>, + ) -> String { + if contract_id.is_none() || network_passphrase.is_none() { + return String::new(); + } + let contract_id = contract_id.unwrap(); + let network_passphrase = network_passphrase.unwrap(); let network = match network_passphrase { NETWORK_PASSPHRASE_TESTNET => "testnet", NETWORK_PASSPHRASE_FUTURENET => "futurenet", @@ -138,9 +155,9 @@ mod test { let p: Project = root.as_ref().to_path_buf().try_into()?; p.init( "test_custom_types", - "CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE", - "https://rpc-futurenet.stellar.org:443", - "Test SDF Future Network ; October 2022", + Some("CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE"), + Some("https://rpc-futurenet.stellar.org:443"), + Some("Test SDF Future Network ; October 2022"), &spec, ) .unwrap(); diff --git a/cmd/crates/soroban-spec-typescript/src/lib.rs b/cmd/crates/soroban-spec-typescript/src/lib.rs index 94b5bb192..697e9a1da 100644 --- a/cmd/crates/soroban-spec-typescript/src/lib.rs +++ b/cmd/crates/soroban-spec-typescript/src/lib.rs @@ -59,7 +59,16 @@ pub fn generate_from_wasm(wasm: &[u8]) -> Result { Ok(json) } -fn generate_class(fns: &[Entry], spec: &[ScSpecEntry]) -> String { +fn generate_class( + fns: &[Entry], + constructor_args: Option>, + spec: &[ScSpecEntry], +) -> String { + let constructor_args = if let Some(inputs) = constructor_args { + format!("{{{}}}", inputs.iter().map(func_input_to_ts).join(", ")) + } else { + "null".to_string() + }; let method_types = fns.iter().map(entry_to_method_type).join(""); let from_jsons = fns .iter() @@ -74,6 +83,22 @@ fn generate_class(fns: &[Entry], spec: &[ScSpecEntry]) -> String { r#"export interface Client {{{method_types} }} export class Client extends ContractClient {{ + static async deploy( + /** Constructor/Initialization Args for the contract's `__constructor` method */ + args: {constructor_args}, + /** Options for initalizing a Client as well as for calling a method, with extras specific to deploying. */ + options: MethodOptions & + Omit & {{ + /** The hash of the Wasm blob, which must already be installed on-chain. */ + wasmHash: Buffer | string; + /** Salt used to generate the contract's ID. Passed through to {{@link Operation.createCustomContract}}. Default: random. */ + salt?: Buffer | Uint8Array; + /** The format used to decode `wasmHash`, if it's provided as a string. */ + format?: "hex" | "base64"; + }} + ): Promise> {{ + return ContractClient.deploy(args, options) + }} constructor(public readonly options: ContractClientOptions) {{ super( new ContractSpec([ {spec} ]), @@ -96,13 +121,20 @@ pub fn generate(spec: &[ScSpecEntry]) -> String { cases: vec![], }); } + let mut constructor_args: Option> = None; // Filter out function entries with names that start with "__" and partition the results + collected.iter().for_each(|entry| match entry { + Entry::Function { name, inputs, .. } if name == "__constructor" => { + constructor_args = Some(inputs.clone()); + } + _ => {} + }); let (fns, other): (Vec<_>, Vec<_>) = collected .into_iter() .filter(|entry| !matches!(entry, Entry::Function { name, .. } if name.starts_with("__"))) .partition(|entry| matches!(entry, Entry::Function { .. })); let top = other.iter().map(entry_to_method_type).join("\n"); - let bottom = generate_class(&fns, spec); + let bottom = generate_class(&fns, constructor_args, spec); format!("{top}\n\n{bottom}") } diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts b/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts index 057d4ef72..b344a1c60 100644 --- a/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts +++ b/cmd/crates/soroban-spec-typescript/src/project_template/src/index.ts @@ -4,6 +4,7 @@ import { AssembledTransaction, Client as ContractClient, ClientOptions as ContractClientOptions, + MethodOptions, Result, Spec as ContractSpec, } from '@stellar/stellar-sdk/contract'; diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh b/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh index 031061cca..e872923c6 100755 --- a/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh +++ b/cmd/crates/soroban-spec-typescript/ts-tests/initialize.sh @@ -29,18 +29,21 @@ function fund_all() { exe eval "./soroban keys generate root" exe eval "./soroban keys fund root" } -function deploy() { - exe eval "(./soroban contract deploy --quiet --source root --wasm $1 --ignore-checks) > $2" +function upload() { + exe eval "(./soroban contract $1 --quiet --source root --wasm $2 --ignore-checks) > $3" } function deploy_all() { - deploy ../../../../target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm contract-id-custom-types.txt + upload deploy ../../../../target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm contract-id-custom-types.txt + # TODO: support `--wasm-hash` with `contract bindings` + upload install ../../../../target/wasm32-unknown-unknown/test-wasms/test_constructor.wasm contract-wasm-hash-constructor.txt } function bind() { - exe eval "./soroban contract bindings typescript --contract-id $(cat $1) --output-dir ./node_modules/$2 --overwrite" - exe eval "sh -c \"cd ./node_modules/$2 && npm install && npm run build\"" + exe eval "./soroban contract bindings typescript $1 $2 --output-dir ./node_modules/$3 --overwrite" + exe eval "sh -c \"cd ./node_modules/$3 && npm install && npm run build\"" } function bind_all() { - bind contract-id-custom-types.txt test-custom-types + bind --contract-id $(cat contract-id-custom-types.txt) test-custom-types + bind --wasm ../../../../target/wasm32-unknown-unknown/test-wasms/test_constructor.wasm test-constructor } fund_all diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json b/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json index 45cc97a67..786edd8ee 100644 --- a/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json +++ b/cmd/crates/soroban-spec-typescript/ts-tests/package-lock.json @@ -2340,9 +2340,9 @@ "dev": true }, "node_modules/node-gyp-build": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz", - "integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "license": "MIT", "optional": true, diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test-constructor-args.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-constructor-args.ts new file mode 100644 index 000000000..a4f8bbfc4 --- /dev/null +++ b/cmd/crates/soroban-spec-typescript/ts-tests/src/test-constructor-args.ts @@ -0,0 +1,29 @@ +import { readFileSync } from "node:fs" +import { join } from "node:path" +import test from "ava" +import { networkPassphrase, rpcUrl, root, signer } from "./util.js" +import { Client } from "test-constructor" + +const wasmHash = readFileSync( + join(import.meta.dirname, "..", "contract-wasm-hash-constructor.txt"), + { encoding: "utf8" } +); + +const INIT_VALUE = 42; + +test("has correctly-typed result", async (t) => { + const deploy = await Client.deploy( + { counter: INIT_VALUE }, + { + networkPassphrase, + rpcUrl, + allowHttp: true, + wasmHash, + publicKey: root.keypair.publicKey(), + ...signer, + }, + ); + const { result: client } = await deploy.signAndSend(); + const { result } = await client.counter(); + t.is(result, INIT_VALUE); +}); diff --git a/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs b/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs index 679e757f4..ea1f63eed 100644 --- a/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs +++ b/cmd/soroban-cli/src/commands/contract/bindings/typescript.rs @@ -17,22 +17,22 @@ use crate::{ #[derive(Parser, Debug, Clone)] #[group(skip)] pub struct Cmd { - /// Path to optional wasm binary + /// Path to wasm file on local filesystem. You must either include this OR `--contract-id`. #[arg(long)] pub wasm: Option, + /// A contract ID/address on a network (if no network settings provided, Testnet will be assumed). You must either include this OR `--wasm`. + #[arg(long, visible_alias = "id")] + pub contract_id: Option, /// Where to place generated project #[arg(long)] pub output_dir: PathBuf, /// Whether to overwrite output directory if it already exists #[arg(long)] pub overwrite: bool, - /// The contract ID/address on the network - #[arg(long, visible_alias = "id")] - pub contract_id: String, - #[command(flatten)] - pub locator: locator::Args, #[command(flatten)] pub network: network::Args, + #[command(flatten)] + pub locator: locator::Args, } #[derive(thiserror::Error, Debug)] @@ -51,6 +51,9 @@ pub enum Error { #[error("--output-dir filepath not representable as utf-8: {0:?}")] NotUtf8(OsString), + #[error("must include either --wasm or --contract-id")] + MissingWasmOrContractId, + #[error(transparent)] Network(#[from] network::Error), @@ -84,34 +87,46 @@ impl NetworkRunnable for Cmd { ) -> Result<(), Error> { let print = Print::new(global_args.is_some_and(|a| a.quiet)); - let network = self.network.get(&self.locator).ok().unwrap_or_else(|| { - network::DEFAULTS - .get("testnet") - .expect("no network specified and testnet network not found") - .into() - }); - - let contract_id = self - .locator - .resolve_contract_id(&self.contract_id, &network.network_passphrase)? - .0; - let contract_address = ScAddress::Contract(Hash(contract_id)); - - let spec = if let Some(wasm) = &self.wasm { + let (spec, contract_address, rpc_url, network_passphrase) = if let Some(wasm) = &self.wasm { print.infoln("Loading contract spec from file..."); let wasm: wasm::Args = wasm.into(); - wasm.parse()?.spec + (wasm.parse()?.spec, None, None, None) } else { + let contract_id = self + .contract_id + .as_ref() + .ok_or(Error::MissingWasmOrContractId)?; + + let network = self.network.get(&self.locator).ok().unwrap_or_else(|| { + network::DEFAULTS + .get("testnet") + .expect("no network specified and testnet network not found") + .into() + }); + print.infoln(format!("Network: {}", network.network_passphrase)); + + let contract_id = self + .locator + .resolve_contract_id(contract_id, &network.network_passphrase)? + .0; + + let contract_address = ScAddress::Contract(Hash(contract_id)).to_string(); print.globeln(format!("Downloading contract spec: {contract_address}")); - get_remote_contract_spec( - &contract_id, - &self.locator, - &self.network, - global_args, - config, + + ( + get_remote_contract_spec( + &contract_id, + &self.locator, + &self.network, + global_args, + config, + ) + .await + .map_err(Error::from)?, + Some(contract_address), + Some(network.rpc_url), + Some(network.network_passphrase), ) - .await - .map_err(Error::from)? }; if self.output_dir.is_file() { return Err(Error::IsFile(self.output_dir.clone())); @@ -125,7 +140,6 @@ impl NetworkRunnable for Cmd { } std::fs::create_dir_all(&self.output_dir)?; let p: Project = self.output_dir.clone().try_into()?; - print.infoln(format!("Network: {}", network.network_passphrase)); let absolute_path = self.output_dir.canonicalize()?; let file_name = absolute_path .file_name() @@ -133,12 +147,14 @@ impl NetworkRunnable for Cmd { let contract_name = &file_name .to_str() .ok_or_else(|| Error::NotUtf8(file_name.to_os_string()))?; - print.infoln(format!("Embedding contract address: {contract_address}")); + if let Some(contract_address) = contract_address.clone() { + print.infoln(format!("Embedding contract address: {contract_address}")); + } p.init( contract_name, - &contract_address.to_string(), - &network.rpc_url, - &network.network_passphrase, + contract_address.as_deref(), + rpc_url.as_deref(), + network_passphrase.as_deref(), &spec, )?; print.checkln("Generated!");