diff --git a/Makefile b/Makefile index 1172a0155b..000b2aef57 100644 --- a/Makefile +++ b/Makefile @@ -103,7 +103,7 @@ lint: typescript-bindings-fixtures: build-test-wasms cargo run -- contract bindings typescript \ --wasm ./target/wasm32-unknown-unknown/test-wasms/test_custom_types.wasm \ - --contract-id CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4 \ + --contract-id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK \ --network futurenet \ --output-dir ./cmd/crates/soroban-spec-typescript/fixtures/test_custom_types \ --overwrite 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 d3b60edc8c..03f87f30b4 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 CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4 \ + --contract-id CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK \ --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 CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4 --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 CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK --name test_custom_types" } ``` diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts index 5fcbe41a47..96512dce63 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.d.ts @@ -1,4 +1,5 @@ import * as SorobanClient from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; import type { ResponseTypes, ClassOptions } from './method-options.js'; export * from './invoke.js'; @@ -11,31 +12,31 @@ export type u128 = bigint; export type i128 = bigint; export type u256 = bigint; export type i256 = bigint; -export type Address = string; export type Option = T | undefined; export type Typepoint = bigint; export type Duration = bigint; +export { Address }; export interface Error_ { message: string; } -export interface Result { +export interface Result { unwrap(): T; unwrapErr(): E; isOk(): boolean; isErr(): boolean; } -export declare class Ok implements Result { +export declare class Ok implements Result { readonly value: T; constructor(value: T); - unwrapErr(): Error_; + unwrapErr(): E; unwrap(): T; isOk(): boolean; isErr(): boolean; } -export declare class Err implements Result { - readonly error: Error_; - constructor(error: Error_); - unwrapErr(): Error_; +export declare class Err implements Result { + readonly error: E; + constructor(error: E); + unwrapErr(): E; unwrap(): never; isOk(): boolean; isErr(): boolean; @@ -43,7 +44,7 @@ export declare class Err implements Result { export declare const networks: { readonly futurenet: { readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4"; + readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; }; }; /** @@ -88,6 +89,7 @@ export type ComplexEnum = { }; export declare class Contract { readonly options: ClassOptions; + spec: ContractSpec; constructor(options: ClassOptions); hello({ hello }: { hello: string; @@ -164,7 +166,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; + }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; u32({ u32_ }: { u32_: u32; }, options?: { @@ -327,7 +329,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise; + }): Promise; bytes({ bytes }: { bytes: Buffer; }, options?: { diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js index 9345bceb24..bd2b1e4efa 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/index.js @@ -14,10 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Contract = exports.RoyalCard = exports.networks = exports.Err = exports.Ok = void 0; +exports.Contract = exports.RoyalCard = exports.networks = exports.Err = exports.Ok = exports.Address = void 0; const soroban_client_1 = require("soroban-client"); +Object.defineProperty(exports, "Address", { enumerable: true, get: function () { return soroban_client_1.Address; } }); const buffer_1 = require("buffer"); -const convert_js_1 = require("./convert.js"); const invoke_js_1 = require("./invoke.js"); __exportStar(require("./invoke.js"), exports); __exportStar(require("./method-options.js"), exports); @@ -84,141 +84,75 @@ function parseError(message) { exports.networks = { futurenet: { networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4", + contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", } }; -function TestToXdr(test) { - if (!test) { - return soroban_client_1.xdr.ScVal.scvVoid(); - } - let arr = [ - new soroban_client_1.xdr.ScMapEntry({ key: ((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("a"), val: ((i) => soroban_client_1.xdr.ScVal.scvU32(i))(test["a"]) }), - new soroban_client_1.xdr.ScMapEntry({ key: ((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("b"), val: ((i) => soroban_client_1.xdr.ScVal.scvBool(i))(test["b"]) }), - new soroban_client_1.xdr.ScMapEntry({ key: ((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("c"), val: ((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))(test["c"]) }) - ]; - return soroban_client_1.xdr.ScVal.scvMap(arr); -} -function TestFromXdr(base64Xdr) { - let scVal = (0, convert_js_1.strToScVal)(base64Xdr); - let obj = scVal.map().map(e => [e.key().str(), e.val()]); - let map = new Map(obj); - if (!obj) { - throw new Error('Invalid XDR'); - } - return { - a: (0, convert_js_1.scValToJs)(map.get("a")), - b: (0, convert_js_1.scValToJs)(map.get("b")), - c: (0, convert_js_1.scValToJs)(map.get("c")) - }; -} -function SimpleEnumToXdr(simpleEnum) { - if (!simpleEnum) { - return soroban_client_1.xdr.ScVal.scvVoid(); - } - let res = []; - switch (simpleEnum.tag) { - case "First": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("First")); - break; - case "Second": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Second")); - break; - case "Third": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Third")); - break; - } - return soroban_client_1.xdr.ScVal.scvVec(res); -} -function SimpleEnumFromXdr(base64Xdr) { - let [tag, values] = (0, convert_js_1.strToScVal)(base64Xdr).vec().map(convert_js_1.scValToJs); - if (!tag) { - throw new Error('Missing enum tag when decoding SimpleEnum from XDR'); - } - return { tag, values }; -} var RoyalCard; (function (RoyalCard) { RoyalCard[RoyalCard["Jack"] = 11] = "Jack"; RoyalCard[RoyalCard["Queen"] = 12] = "Queen"; RoyalCard[RoyalCard["King"] = 13] = "King"; })(RoyalCard || (exports.RoyalCard = RoyalCard = {})); -function RoyalCardFromXdr(base64Xdr) { - return (0, convert_js_1.scValStrToJs)(base64Xdr); -} -function RoyalCardToXdr(val) { - return soroban_client_1.xdr.ScVal.scvI32(val); -} -function TupleStructToXdr(tupleStruct) { - if (!tupleStruct) { - return soroban_client_1.xdr.ScVal.scvVoid(); - } - let arr = [ - (i => TestToXdr(i))(tupleStruct[0]), - (i => SimpleEnumToXdr(i))(tupleStruct[1]) - ]; - return soroban_client_1.xdr.ScVal.scvVec(arr); -} -function TupleStructFromXdr(base64Xdr) { - return (0, convert_js_1.scValStrToJs)(base64Xdr); -} -function ComplexEnumToXdr(complexEnum) { - if (!complexEnum) { - return soroban_client_1.xdr.ScVal.scvVoid(); - } - let res = []; - switch (complexEnum.tag) { - case "Struct": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Struct")); - res.push(((i) => TestToXdr(i))(complexEnum.values[0])); - break; - case "Tuple": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Tuple")); - res.push(((i) => TupleStructToXdr(i))(complexEnum.values[0])); - break; - case "Enum": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Enum")); - res.push(((i) => SimpleEnumToXdr(i))(complexEnum.values[0])); - break; - case "Asset": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Asset")); - res.push(((i) => (0, convert_js_1.addressToScVal)(i))(complexEnum.values[0])); - res.push(((i) => (0, convert_js_1.i128ToScVal)(i))(complexEnum.values[1])); - break; - case "Void": - res.push(((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))("Void")); - break; - } - return soroban_client_1.xdr.ScVal.scvVec(res); -} -function ComplexEnumFromXdr(base64Xdr) { - let [tag, values] = (0, convert_js_1.strToScVal)(base64Xdr).vec().map(convert_js_1.scValToJs); - if (!tag) { - throw new Error('Missing enum tag when decoding ComplexEnum from XDR'); - } - return { tag, values }; -} const Errors = { 1: { message: "Please provide an odd number" } }; class Contract { options; + spec; constructor(options) { this.options = options; + this.spec = new soroban_client_1.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=" + ]); } async hello({ hello }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'hello', - args: [((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))(hello)], + args: this.spec.funcArgsToScVals("hello", { hello }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("hello", xdr); }, }); } async woid(options = {}) { return await (0, invoke_js_1.invoke)({ method: 'woid', + args: this.spec.funcArgsToScVals("woid", {}), ...options, ...this.options, parseResultXdr: () => { }, @@ -227,10 +161,11 @@ class Contract { async val(options = {}) { return await (0, invoke_js_1.invoke)({ method: 'val', + args: this.spec.funcArgsToScVals("val", {}), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("val", xdr); }, }); } @@ -238,15 +173,16 @@ class Contract { try { return await (0, invoke_js_1.invoke)({ method: 'u32_fail_on_even', - args: [((i) => soroban_client_1.xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_fail_on_even", { u32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return new Ok((0, convert_js_1.scValStrToJs)(xdr)); + return new Ok(this.spec.funcResToNative("u32_fail_on_even", xdr)); }, }); } catch (e) { + console.log(e); if (typeof e === 'string') { let err = parseError(e); if (err) @@ -258,33 +194,33 @@ class Contract { async u32({ u32_ }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'u32_', - args: [((i) => soroban_client_1.xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_", { u32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("u32_", xdr); }, }); } async i32({ i32_ }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'i32_', - args: [((i) => soroban_client_1.xdr.ScVal.scvI32(i))(i32_)], + args: this.spec.funcArgsToScVals("i32_", { i32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("i32_", xdr); }, }); } async i64({ i64_ }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'i64_', - args: [((i) => soroban_client_1.xdr.ScVal.scvI64(soroban_client_1.xdr.Int64.fromString(i.toString())))(i64_)], + args: this.spec.funcArgsToScVals("i64_", { i64_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("i64_", xdr); }, }); } @@ -294,99 +230,99 @@ class Contract { async struktHel({ strukt }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'strukt_hel', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt_hel", { strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("strukt_hel", xdr); }, }); } async strukt({ strukt }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'strukt', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt", { strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return TestFromXdr(xdr); + return this.spec.funcResToNative("strukt", xdr); }, }); } async simple({ simple }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'simple', - args: [((i) => SimpleEnumToXdr(i))(simple)], + args: this.spec.funcArgsToScVals("simple", { simple }), ...options, ...this.options, parseResultXdr: (xdr) => { - return SimpleEnumFromXdr(xdr); + return this.spec.funcResToNative("simple", xdr); }, }); } async complex({ complex }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'complex', - args: [((i) => ComplexEnumToXdr(i))(complex)], + args: this.spec.funcArgsToScVals("complex", { complex }), ...options, ...this.options, parseResultXdr: (xdr) => { - return ComplexEnumFromXdr(xdr); + return this.spec.funcResToNative("complex", xdr); }, }); } async addresse({ addresse }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'addresse', - args: [((i) => (0, convert_js_1.addressToScVal)(i))(addresse)], + args: this.spec.funcArgsToScVals("addresse", { addresse }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("addresse", xdr); }, }); } async bytes({ bytes }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'bytes', - args: [((i) => soroban_client_1.xdr.ScVal.scvBytes(i))(bytes)], + args: this.spec.funcArgsToScVals("bytes", { bytes }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("bytes", xdr); }, }); } async bytesN({ bytes_n }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'bytes_n', - args: [((i) => soroban_client_1.xdr.ScVal.scvBytes(i))(bytes_n)], + args: this.spec.funcArgsToScVals("bytes_n", { bytes_n }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("bytes_n", xdr); }, }); } async card({ card }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'card', - args: [((i) => RoyalCardToXdr(i))(card)], + args: this.spec.funcArgsToScVals("card", { card }), ...options, ...this.options, parseResultXdr: (xdr) => { - return RoyalCardFromXdr(xdr); + return this.spec.funcResToNative("card", xdr); }, }); } async boolean({ boolean }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'boolean', - args: [((i) => soroban_client_1.xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("boolean", { boolean }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("boolean", xdr); }, }); } @@ -396,84 +332,77 @@ class Contract { async not({ boolean }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'not', - args: [((i) => soroban_client_1.xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("not", { boolean }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("not", xdr); }, }); } async i128({ i128 }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'i128', - args: [((i) => (0, convert_js_1.i128ToScVal)(i))(i128)], + args: this.spec.funcArgsToScVals("i128", { i128 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("i128", xdr); }, }); } async u128({ u128 }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'u128', - args: [((i) => (0, convert_js_1.u128ToScVal)(i))(u128)], + args: this.spec.funcArgsToScVals("u128", { u128 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("u128", xdr); }, }); } async multiArgs({ a, b }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'multi_args', - args: [((i) => soroban_client_1.xdr.ScVal.scvU32(i))(a), - ((i) => soroban_client_1.xdr.ScVal.scvBool(i))(b)], + args: this.spec.funcArgsToScVals("multi_args", { a, b }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("multi_args", xdr); }, }); } async map({ map }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'map', - args: [((i) => soroban_client_1.xdr.ScVal.scvMap(Array.from(i.entries()).map(([key, value]) => { - return new soroban_client_1.xdr.ScMapEntry({ - key: ((i) => soroban_client_1.xdr.ScVal.scvU32(i))(key), - val: ((i) => soroban_client_1.xdr.ScVal.scvBool(i))(value) - }); - })))(map)], + args: this.spec.funcArgsToScVals("map", { map }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("map", xdr); }, }); } async vec({ vec }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'vec', - args: [((i) => soroban_client_1.xdr.ScVal.scvVec(i.map((i) => soroban_client_1.xdr.ScVal.scvU32(i))))(vec)], + args: this.spec.funcArgsToScVals("vec", { vec }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("vec", xdr); }, }); } async tuple({ tuple }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'tuple', - args: [((i) => soroban_client_1.xdr.ScVal.scvVec([((i) => soroban_client_1.xdr.ScVal.scvSymbol(i))(i[0]), - ((i) => soroban_client_1.xdr.ScVal.scvU32(i))(i[1])]))(tuple)], + args: this.spec.funcArgsToScVals("tuple", { tuple }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("tuple", xdr); }, }); } @@ -483,55 +412,55 @@ class Contract { async option({ option }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'option', - args: [((i) => (!i) ? soroban_client_1.xdr.ScVal.scvVoid() : soroban_client_1.xdr.ScVal.scvU32(i))(option)], + args: this.spec.funcArgsToScVals("option", { option }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("option", xdr); }, }); } async u256({ u256 }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'u256', - args: [((i) => i)(u256)], + args: this.spec.funcArgsToScVals("u256", { u256 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("u256", xdr); }, }); } async i256({ i256 }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'i256', - args: [((i) => i)(i256)], + args: this.spec.funcArgsToScVals("i256", { i256 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("i256", xdr); }, }); } async string({ string }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'string', - args: [((i) => soroban_client_1.xdr.ScVal.scvString(i))(string)], + args: this.spec.funcArgsToScVals("string", { string }), ...options, ...this.options, parseResultXdr: (xdr) => { - return (0, convert_js_1.scValStrToJs)(xdr); + return this.spec.funcResToNative("string", xdr); }, }); } async tupleStrukt({ tuple_strukt }, options = {}) { return await (0, invoke_js_1.invoke)({ method: 'tuple_strukt', - args: [((i) => TupleStructToXdr(i))(tuple_strukt)], + args: this.spec.funcArgsToScVals("tuple_strukt", { tuple_strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return TupleStructFromXdr(xdr); + return this.spec.funcResToNative("tuple_strukt", xdr); }, }); } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.d.ts index 033c645924..4e8e953948 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.d.ts @@ -1,6 +1,6 @@ -import * as SorobanClient from 'soroban-client'; -import type { Memo, MemoType, Operation, Transaction } from 'soroban-client'; -import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from './method-options.js'; +import * as SorobanClient from "soroban-client"; +import type { Memo, MemoType, Operation, Transaction, xdr } from "soroban-client"; +import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from "./method-options.js"; export type Tx = Transaction, Operation[]>; export declare class NotImplementedError extends Error { } @@ -12,7 +12,7 @@ type SomeRpcResponse = typeof someRpcResponse; type InvokeArgs = MethodOptions & ClassOptions & { method: string; args?: any[]; - parseResultXdr?: (xdr: string) => T; + parseResultXdr: (xdr: string | xdr.ScVal) => T; }; /** * Invoke a method on the test_custom_types contract. diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.js index 6912acebfe..f7de5eedef 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.js +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/cjs/invoke.js @@ -7,7 +7,7 @@ const SorobanClient = require("soroban-client"); * selected in Freighter. If not connected to Freighter, return null. */ async function getAccount(wallet, server) { - if (!await wallet.isConnected() || !await wallet.isAllowed()) { + if (!(await wallet.isConnected()) || !(await wallet.isAllowed())) { return null; } const { publicKey } = await wallet.getUserInfo(); @@ -22,11 +22,15 @@ exports.NotImplementedError = NotImplementedError; // defined this way so typeahead shows full union, not named alias let someRpcResponse; async function invoke({ method, args = [], fee = 100, responseType, parseResultXdr, secondsToWait = 10, rpcUrl, networkPassphrase, contractId, wallet, }) { - wallet = wallet ?? await Promise.resolve().then(() => require('@stellar/freighter-api')); - const server = new SorobanClient.Server(rpcUrl, { allowHttp: rpcUrl.startsWith('http://') }); + wallet = wallet ?? (await Promise.resolve().then(() => require("@stellar/freighter-api"))); + let parse = parseResultXdr; + const server = new SorobanClient.Server(rpcUrl, { + allowHttp: rpcUrl.startsWith("http://"), + }); const walletAccount = await getAccount(wallet, server); // use a placeholder null account if not yet connected to Freighter so that view calls can still work - const account = walletAccount ?? new SorobanClient.Account('GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF', '0'); + const account = walletAccount ?? + new SorobanClient.Account("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", "0"); const contract = new SorobanClient.Contract(contractId); let tx = new SorobanClient.TransactionBuilder(account, { fee: fee.toString(10), @@ -35,28 +39,32 @@ async function invoke({ method, args = [], fee = 100, responseType, parseResultX .addOperation(contract.call(method, ...args)) .setTimeout(SorobanClient.TimeoutInfinite) .build(); + console.log(method, args); const simulated = await server.simulateTransaction(tx); + console.log("---\n", simulated.result.retval, "\n----"); if (simulated.error) throw simulated.error; - if (responseType === 'simulated') + if (responseType === "simulated") return simulated; // is it possible for `auths` to be present but empty? Probably not, but let's be safe. - const auths = simulated.results?.[0]?.auth; - let authsCount = auths?.length ?? 0; - const writeLength = SorobanClient.xdr.SorobanTransactionData.fromXDR(simulated.transactionData, 'base64').resources().footprint().readWrite().length; - const parse = parseResultXdr ?? (xdr => xdr); + let authsCount = simulated.result.auth?.length ?? 0; + const writeLength = simulated.transactionData + .build() + .resources() + .footprint() + .readWrite().length; const isViewCall = authsCount === 0 && writeLength === 0; if (isViewCall) { - if (responseType === 'full') + if (responseType === "full") return simulated; - const { results } = simulated; - if (!results || results[0] === undefined) { + const retval = simulated.result?.retval; + if (!retval) { if (simulated.error) { throw new Error(simulated.error); } throw new Error(`Invalid response from simulateTransaction:\n{simulated}`); } - return parse(results[0].xdr); + return parseResultXdr(retval); } if (authsCount > 1) { throw new NotImplementedError("Multiple auths not yet supported"); @@ -72,18 +80,18 @@ async function invoke({ method, args = [], fee = 100, responseType, parseResultX // } } if (!walletAccount) { - throw new Error('Not connected to Freighter'); + throw new Error("Not connected to Freighter"); } - tx = await signTx(wallet, SorobanClient.assembleTransaction(tx, networkPassphrase, simulated), networkPassphrase); + tx = await signTx(wallet, SorobanClient.assembleTransaction(tx, networkPassphrase, simulated).build(), networkPassphrase); const raw = await sendTx(tx, secondsToWait, server); - if (responseType === 'full') + if (responseType === "full") return raw; // if `sendTx` awaited the inclusion of the tx in the ledger, it used // `getTransaction`, which has a `resultXdr` field - if ('resultXdr' in raw) - return parse(raw.resultXdr); + if ("resultXdr" in raw) + return parse(raw.resultXdr.result().toXDR("base64")); // otherwise, it returned the result of `sendTransaction` - if ('errorResultXdr' in raw) + if ("errorResultXdr" in raw) return parse(raw.errorResultXdr); // if neither of these are present, something went wrong console.error("Don't know how to parse result! Returning full RPC response."); @@ -121,19 +129,20 @@ async function sendTx(tx, secondsToWait, server) { return sendTransactionResponse; } let getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); - const waitUntil = new Date((Date.now() + secondsToWait * 1000)).valueOf(); + const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); let waitTime = 1000; let exponentialFactor = 1.5; - while ((Date.now() < waitUntil) && getTransactionResponse.status === "NOT_FOUND") { + while (Date.now() < waitUntil && + getTransactionResponse.status === "NOT_FOUND") { // Wait a beat - await new Promise(resolve => setTimeout(resolve, waitTime)); + await new Promise((resolve) => setTimeout(resolve, waitTime)); /// Exponential backoff waitTime = waitTime * exponentialFactor; // See if the transaction is complete getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); } if (getTransactionResponse.status === "NOT_FOUND") { - console.log(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}`); + console.error(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}`); } return getTransactionResponse; } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts index 5fcbe41a47..96512dce63 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.d.ts @@ -1,4 +1,5 @@ import * as SorobanClient from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; import type { ResponseTypes, ClassOptions } from './method-options.js'; export * from './invoke.js'; @@ -11,31 +12,31 @@ export type u128 = bigint; export type i128 = bigint; export type u256 = bigint; export type i256 = bigint; -export type Address = string; export type Option = T | undefined; export type Typepoint = bigint; export type Duration = bigint; +export { Address }; export interface Error_ { message: string; } -export interface Result { +export interface Result { unwrap(): T; unwrapErr(): E; isOk(): boolean; isErr(): boolean; } -export declare class Ok implements Result { +export declare class Ok implements Result { readonly value: T; constructor(value: T); - unwrapErr(): Error_; + unwrapErr(): E; unwrap(): T; isOk(): boolean; isErr(): boolean; } -export declare class Err implements Result { - readonly error: Error_; - constructor(error: Error_); - unwrapErr(): Error_; +export declare class Err implements Result { + readonly error: E; + constructor(error: E); + unwrapErr(): E; unwrap(): never; isOk(): boolean; isErr(): boolean; @@ -43,7 +44,7 @@ export declare class Err implements Result { export declare const networks: { readonly futurenet: { readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4"; + readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; }; }; /** @@ -88,6 +89,7 @@ export type ComplexEnum = { }; export declare class Contract { readonly options: ClassOptions; + spec: ContractSpec; constructor(options: ClassOptions); hello({ hello }: { hello: string; @@ -164,7 +166,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; + }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; u32({ u32_ }: { u32_: u32; }, options?: { @@ -327,7 +329,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise; + }): Promise; bytes({ bytes }: { bytes: Buffer; }, options?: { diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js index e9a5932bce..9552e6182e 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/index.js @@ -1,9 +1,9 @@ -import { xdr } from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; -import { scValStrToJs, scValToJs, addressToScVal, u128ToScVal, i128ToScVal, strToScVal } from './convert.js'; import { invoke } from './invoke.js'; export * from './invoke.js'; export * from './method-options.js'; +export { Address }; ; ; export class Ok { @@ -65,141 +65,75 @@ function parseError(message) { export const networks = { futurenet: { networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4", + contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", } }; -function TestToXdr(test) { - if (!test) { - return xdr.ScVal.scvVoid(); - } - let arr = [ - new xdr.ScMapEntry({ key: ((i) => xdr.ScVal.scvSymbol(i))("a"), val: ((i) => xdr.ScVal.scvU32(i))(test["a"]) }), - new xdr.ScMapEntry({ key: ((i) => xdr.ScVal.scvSymbol(i))("b"), val: ((i) => xdr.ScVal.scvBool(i))(test["b"]) }), - new xdr.ScMapEntry({ key: ((i) => xdr.ScVal.scvSymbol(i))("c"), val: ((i) => xdr.ScVal.scvSymbol(i))(test["c"]) }) - ]; - return xdr.ScVal.scvMap(arr); -} -function TestFromXdr(base64Xdr) { - let scVal = strToScVal(base64Xdr); - let obj = scVal.map().map(e => [e.key().str(), e.val()]); - let map = new Map(obj); - if (!obj) { - throw new Error('Invalid XDR'); - } - return { - a: scValToJs(map.get("a")), - b: scValToJs(map.get("b")), - c: scValToJs(map.get("c")) - }; -} -function SimpleEnumToXdr(simpleEnum) { - if (!simpleEnum) { - return xdr.ScVal.scvVoid(); - } - let res = []; - switch (simpleEnum.tag) { - case "First": - res.push(((i) => xdr.ScVal.scvSymbol(i))("First")); - break; - case "Second": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Second")); - break; - case "Third": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Third")); - break; - } - return xdr.ScVal.scvVec(res); -} -function SimpleEnumFromXdr(base64Xdr) { - let [tag, values] = strToScVal(base64Xdr).vec().map(scValToJs); - if (!tag) { - throw new Error('Missing enum tag when decoding SimpleEnum from XDR'); - } - return { tag, values }; -} export var RoyalCard; (function (RoyalCard) { RoyalCard[RoyalCard["Jack"] = 11] = "Jack"; RoyalCard[RoyalCard["Queen"] = 12] = "Queen"; RoyalCard[RoyalCard["King"] = 13] = "King"; })(RoyalCard || (RoyalCard = {})); -function RoyalCardFromXdr(base64Xdr) { - return scValStrToJs(base64Xdr); -} -function RoyalCardToXdr(val) { - return xdr.ScVal.scvI32(val); -} -function TupleStructToXdr(tupleStruct) { - if (!tupleStruct) { - return xdr.ScVal.scvVoid(); - } - let arr = [ - (i => TestToXdr(i))(tupleStruct[0]), - (i => SimpleEnumToXdr(i))(tupleStruct[1]) - ]; - return xdr.ScVal.scvVec(arr); -} -function TupleStructFromXdr(base64Xdr) { - return scValStrToJs(base64Xdr); -} -function ComplexEnumToXdr(complexEnum) { - if (!complexEnum) { - return xdr.ScVal.scvVoid(); - } - let res = []; - switch (complexEnum.tag) { - case "Struct": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Struct")); - res.push(((i) => TestToXdr(i))(complexEnum.values[0])); - break; - case "Tuple": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Tuple")); - res.push(((i) => TupleStructToXdr(i))(complexEnum.values[0])); - break; - case "Enum": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Enum")); - res.push(((i) => SimpleEnumToXdr(i))(complexEnum.values[0])); - break; - case "Asset": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Asset")); - res.push(((i) => addressToScVal(i))(complexEnum.values[0])); - res.push(((i) => i128ToScVal(i))(complexEnum.values[1])); - break; - case "Void": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Void")); - break; - } - return xdr.ScVal.scvVec(res); -} -function ComplexEnumFromXdr(base64Xdr) { - let [tag, values] = strToScVal(base64Xdr).vec().map(scValToJs); - if (!tag) { - throw new Error('Missing enum tag when decoding ComplexEnum from XDR'); - } - return { tag, values }; -} const Errors = { 1: { message: "Please provide an odd number" } }; export class Contract { options; + spec; constructor(options) { this.options = options; + this.spec = 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=" + ]); } async hello({ hello }, options = {}) { return await invoke({ method: 'hello', - args: [((i) => xdr.ScVal.scvSymbol(i))(hello)], + args: this.spec.funcArgsToScVals("hello", { hello }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("hello", xdr); }, }); } async woid(options = {}) { return await invoke({ method: 'woid', + args: this.spec.funcArgsToScVals("woid", {}), ...options, ...this.options, parseResultXdr: () => { }, @@ -208,10 +142,11 @@ export class Contract { async val(options = {}) { return await invoke({ method: 'val', + args: this.spec.funcArgsToScVals("val", {}), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("val", xdr); }, }); } @@ -219,15 +154,16 @@ export class Contract { try { return await invoke({ method: 'u32_fail_on_even', - args: [((i) => xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_fail_on_even", { u32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return new Ok(scValStrToJs(xdr)); + return new Ok(this.spec.funcResToNative("u32_fail_on_even", xdr)); }, }); } catch (e) { + console.log(e); if (typeof e === 'string') { let err = parseError(e); if (err) @@ -239,33 +175,33 @@ export class Contract { async u32({ u32_ }, options = {}) { return await invoke({ method: 'u32_', - args: [((i) => xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_", { u32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u32_", xdr); }, }); } async i32({ i32_ }, options = {}) { return await invoke({ method: 'i32_', - args: [((i) => xdr.ScVal.scvI32(i))(i32_)], + args: this.spec.funcArgsToScVals("i32_", { i32_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i32_", xdr); }, }); } async i64({ i64_ }, options = {}) { return await invoke({ method: 'i64_', - args: [((i) => xdr.ScVal.scvI64(xdr.Int64.fromString(i.toString())))(i64_)], + args: this.spec.funcArgsToScVals("i64_", { i64_ }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i64_", xdr); }, }); } @@ -275,99 +211,99 @@ export class Contract { async struktHel({ strukt }, options = {}) { return await invoke({ method: 'strukt_hel', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt_hel", { strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("strukt_hel", xdr); }, }); } async strukt({ strukt }, options = {}) { return await invoke({ method: 'strukt', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt", { strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return TestFromXdr(xdr); + return this.spec.funcResToNative("strukt", xdr); }, }); } async simple({ simple }, options = {}) { return await invoke({ method: 'simple', - args: [((i) => SimpleEnumToXdr(i))(simple)], + args: this.spec.funcArgsToScVals("simple", { simple }), ...options, ...this.options, parseResultXdr: (xdr) => { - return SimpleEnumFromXdr(xdr); + return this.spec.funcResToNative("simple", xdr); }, }); } async complex({ complex }, options = {}) { return await invoke({ method: 'complex', - args: [((i) => ComplexEnumToXdr(i))(complex)], + args: this.spec.funcArgsToScVals("complex", { complex }), ...options, ...this.options, parseResultXdr: (xdr) => { - return ComplexEnumFromXdr(xdr); + return this.spec.funcResToNative("complex", xdr); }, }); } async addresse({ addresse }, options = {}) { return await invoke({ method: 'addresse', - args: [((i) => addressToScVal(i))(addresse)], + args: this.spec.funcArgsToScVals("addresse", { addresse }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("addresse", xdr); }, }); } async bytes({ bytes }, options = {}) { return await invoke({ method: 'bytes', - args: [((i) => xdr.ScVal.scvBytes(i))(bytes)], + args: this.spec.funcArgsToScVals("bytes", { bytes }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("bytes", xdr); }, }); } async bytesN({ bytes_n }, options = {}) { return await invoke({ method: 'bytes_n', - args: [((i) => xdr.ScVal.scvBytes(i))(bytes_n)], + args: this.spec.funcArgsToScVals("bytes_n", { bytes_n }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("bytes_n", xdr); }, }); } async card({ card }, options = {}) { return await invoke({ method: 'card', - args: [((i) => RoyalCardToXdr(i))(card)], + args: this.spec.funcArgsToScVals("card", { card }), ...options, ...this.options, parseResultXdr: (xdr) => { - return RoyalCardFromXdr(xdr); + return this.spec.funcResToNative("card", xdr); }, }); } async boolean({ boolean }, options = {}) { return await invoke({ method: 'boolean', - args: [((i) => xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("boolean", { boolean }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("boolean", xdr); }, }); } @@ -377,84 +313,77 @@ export class Contract { async not({ boolean }, options = {}) { return await invoke({ method: 'not', - args: [((i) => xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("not", { boolean }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("not", xdr); }, }); } async i128({ i128 }, options = {}) { return await invoke({ method: 'i128', - args: [((i) => i128ToScVal(i))(i128)], + args: this.spec.funcArgsToScVals("i128", { i128 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i128", xdr); }, }); } async u128({ u128 }, options = {}) { return await invoke({ method: 'u128', - args: [((i) => u128ToScVal(i))(u128)], + args: this.spec.funcArgsToScVals("u128", { u128 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u128", xdr); }, }); } async multiArgs({ a, b }, options = {}) { return await invoke({ method: 'multi_args', - args: [((i) => xdr.ScVal.scvU32(i))(a), - ((i) => xdr.ScVal.scvBool(i))(b)], + args: this.spec.funcArgsToScVals("multi_args", { a, b }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("multi_args", xdr); }, }); } async map({ map }, options = {}) { return await invoke({ method: 'map', - args: [((i) => xdr.ScVal.scvMap(Array.from(i.entries()).map(([key, value]) => { - return new xdr.ScMapEntry({ - key: ((i) => xdr.ScVal.scvU32(i))(key), - val: ((i) => xdr.ScVal.scvBool(i))(value) - }); - })))(map)], + args: this.spec.funcArgsToScVals("map", { map }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("map", xdr); }, }); } async vec({ vec }, options = {}) { return await invoke({ method: 'vec', - args: [((i) => xdr.ScVal.scvVec(i.map((i) => xdr.ScVal.scvU32(i))))(vec)], + args: this.spec.funcArgsToScVals("vec", { vec }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("vec", xdr); }, }); } async tuple({ tuple }, options = {}) { return await invoke({ method: 'tuple', - args: [((i) => xdr.ScVal.scvVec([((i) => xdr.ScVal.scvSymbol(i))(i[0]), - ((i) => xdr.ScVal.scvU32(i))(i[1])]))(tuple)], + args: this.spec.funcArgsToScVals("tuple", { tuple }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("tuple", xdr); }, }); } @@ -464,55 +393,55 @@ export class Contract { async option({ option }, options = {}) { return await invoke({ method: 'option', - args: [((i) => (!i) ? xdr.ScVal.scvVoid() : xdr.ScVal.scvU32(i))(option)], + args: this.spec.funcArgsToScVals("option", { option }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("option", xdr); }, }); } async u256({ u256 }, options = {}) { return await invoke({ method: 'u256', - args: [((i) => i)(u256)], + args: this.spec.funcArgsToScVals("u256", { u256 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u256", xdr); }, }); } async i256({ i256 }, options = {}) { return await invoke({ method: 'i256', - args: [((i) => i)(i256)], + args: this.spec.funcArgsToScVals("i256", { i256 }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i256", xdr); }, }); } async string({ string }, options = {}) { return await invoke({ method: 'string', - args: [((i) => xdr.ScVal.scvString(i))(string)], + args: this.spec.funcArgsToScVals("string", { string }), ...options, ...this.options, parseResultXdr: (xdr) => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("string", xdr); }, }); } async tupleStrukt({ tuple_strukt }, options = {}) { return await invoke({ method: 'tuple_strukt', - args: [((i) => TupleStructToXdr(i))(tuple_strukt)], + args: this.spec.funcArgsToScVals("tuple_strukt", { tuple_strukt }), ...options, ...this.options, parseResultXdr: (xdr) => { - return TupleStructFromXdr(xdr); + return this.spec.funcResToNative("tuple_strukt", xdr); }, }); } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.d.ts index 033c645924..4e8e953948 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.d.ts @@ -1,6 +1,6 @@ -import * as SorobanClient from 'soroban-client'; -import type { Memo, MemoType, Operation, Transaction } from 'soroban-client'; -import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from './method-options.js'; +import * as SorobanClient from "soroban-client"; +import type { Memo, MemoType, Operation, Transaction, xdr } from "soroban-client"; +import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from "./method-options.js"; export type Tx = Transaction, Operation[]>; export declare class NotImplementedError extends Error { } @@ -12,7 +12,7 @@ type SomeRpcResponse = typeof someRpcResponse; type InvokeArgs = MethodOptions & ClassOptions & { method: string; args?: any[]; - parseResultXdr?: (xdr: string) => T; + parseResultXdr: (xdr: string | xdr.ScVal) => T; }; /** * Invoke a method on the test_custom_types contract. diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.js b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.js index 76fe86595c..0ea2d1a4c8 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.js +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/esm/invoke.js @@ -1,10 +1,10 @@ -import * as SorobanClient from 'soroban-client'; +import * as SorobanClient from "soroban-client"; /** * Get account details from the Soroban network for the publicKey currently * selected in Freighter. If not connected to Freighter, return null. */ async function getAccount(wallet, server) { - if (!await wallet.isConnected() || !await wallet.isAllowed()) { + if (!(await wallet.isConnected()) || !(await wallet.isAllowed())) { return null; } const { publicKey } = await wallet.getUserInfo(); @@ -18,11 +18,15 @@ export class NotImplementedError extends Error { // defined this way so typeahead shows full union, not named alias let someRpcResponse; export async function invoke({ method, args = [], fee = 100, responseType, parseResultXdr, secondsToWait = 10, rpcUrl, networkPassphrase, contractId, wallet, }) { - wallet = wallet ?? await import('@stellar/freighter-api'); - const server = new SorobanClient.Server(rpcUrl, { allowHttp: rpcUrl.startsWith('http://') }); + wallet = wallet ?? (await import("@stellar/freighter-api")); + let parse = parseResultXdr; + const server = new SorobanClient.Server(rpcUrl, { + allowHttp: rpcUrl.startsWith("http://"), + }); const walletAccount = await getAccount(wallet, server); // use a placeholder null account if not yet connected to Freighter so that view calls can still work - const account = walletAccount ?? new SorobanClient.Account('GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF', '0'); + const account = walletAccount ?? + new SorobanClient.Account("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", "0"); const contract = new SorobanClient.Contract(contractId); let tx = new SorobanClient.TransactionBuilder(account, { fee: fee.toString(10), @@ -31,28 +35,32 @@ export async function invoke({ method, args = [], fee = 100, responseType, parse .addOperation(contract.call(method, ...args)) .setTimeout(SorobanClient.TimeoutInfinite) .build(); + console.log(method, args); const simulated = await server.simulateTransaction(tx); + console.log("---\n", simulated.result.retval, "\n----"); if (simulated.error) throw simulated.error; - if (responseType === 'simulated') + if (responseType === "simulated") return simulated; // is it possible for `auths` to be present but empty? Probably not, but let's be safe. - const auths = simulated.results?.[0]?.auth; - let authsCount = auths?.length ?? 0; - const writeLength = SorobanClient.xdr.SorobanTransactionData.fromXDR(simulated.transactionData, 'base64').resources().footprint().readWrite().length; - const parse = parseResultXdr ?? (xdr => xdr); + let authsCount = simulated.result.auth?.length ?? 0; + const writeLength = simulated.transactionData + .build() + .resources() + .footprint() + .readWrite().length; const isViewCall = authsCount === 0 && writeLength === 0; if (isViewCall) { - if (responseType === 'full') + if (responseType === "full") return simulated; - const { results } = simulated; - if (!results || results[0] === undefined) { + const retval = simulated.result?.retval; + if (!retval) { if (simulated.error) { throw new Error(simulated.error); } throw new Error(`Invalid response from simulateTransaction:\n{simulated}`); } - return parse(results[0].xdr); + return parseResultXdr(retval); } if (authsCount > 1) { throw new NotImplementedError("Multiple auths not yet supported"); @@ -68,18 +76,18 @@ export async function invoke({ method, args = [], fee = 100, responseType, parse // } } if (!walletAccount) { - throw new Error('Not connected to Freighter'); + throw new Error("Not connected to Freighter"); } - tx = await signTx(wallet, SorobanClient.assembleTransaction(tx, networkPassphrase, simulated), networkPassphrase); + tx = await signTx(wallet, SorobanClient.assembleTransaction(tx, networkPassphrase, simulated).build(), networkPassphrase); const raw = await sendTx(tx, secondsToWait, server); - if (responseType === 'full') + if (responseType === "full") return raw; // if `sendTx` awaited the inclusion of the tx in the ledger, it used // `getTransaction`, which has a `resultXdr` field - if ('resultXdr' in raw) - return parse(raw.resultXdr); + if ("resultXdr" in raw) + return parse(raw.resultXdr.result().toXDR("base64")); // otherwise, it returned the result of `sendTransaction` - if ('errorResultXdr' in raw) + if ("errorResultXdr" in raw) return parse(raw.errorResultXdr); // if neither of these are present, something went wrong console.error("Don't know how to parse result! Returning full RPC response."); @@ -115,19 +123,20 @@ export async function sendTx(tx, secondsToWait, server) { return sendTransactionResponse; } let getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); - const waitUntil = new Date((Date.now() + secondsToWait * 1000)).valueOf(); + const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); let waitTime = 1000; let exponentialFactor = 1.5; - while ((Date.now() < waitUntil) && getTransactionResponse.status === "NOT_FOUND") { + while (Date.now() < waitUntil && + getTransactionResponse.status === "NOT_FOUND") { // Wait a beat - await new Promise(resolve => setTimeout(resolve, waitTime)); + await new Promise((resolve) => setTimeout(resolve, waitTime)); /// Exponential backoff waitTime = waitTime * exponentialFactor; // See if the transaction is complete getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); } if (getTransactionResponse.status === "NOT_FOUND") { - console.log(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}`); + console.error(`Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}`); } return getTransactionResponse; } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts index 5fcbe41a47..96512dce63 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/index.d.ts @@ -1,4 +1,5 @@ import * as SorobanClient from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; import type { ResponseTypes, ClassOptions } from './method-options.js'; export * from './invoke.js'; @@ -11,31 +12,31 @@ export type u128 = bigint; export type i128 = bigint; export type u256 = bigint; export type i256 = bigint; -export type Address = string; export type Option = T | undefined; export type Typepoint = bigint; export type Duration = bigint; +export { Address }; export interface Error_ { message: string; } -export interface Result { +export interface Result { unwrap(): T; unwrapErr(): E; isOk(): boolean; isErr(): boolean; } -export declare class Ok implements Result { +export declare class Ok implements Result { readonly value: T; constructor(value: T); - unwrapErr(): Error_; + unwrapErr(): E; unwrap(): T; isOk(): boolean; isErr(): boolean; } -export declare class Err implements Result { - readonly error: Error_; - constructor(error: Error_); - unwrapErr(): Error_; +export declare class Err implements Result { + readonly error: E; + constructor(error: E); + unwrapErr(): E; unwrap(): never; isOk(): boolean; isErr(): boolean; @@ -43,7 +44,7 @@ export declare class Err implements Result { export declare const networks: { readonly futurenet: { readonly networkPassphrase: "Test SDF Future Network ; October 2022"; - readonly contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4"; + readonly contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK"; }; }; /** @@ -88,6 +89,7 @@ export type ComplexEnum = { }; export declare class Contract { readonly options: ClassOptions; + spec: ContractSpec; constructor(options: ClassOptions); hello({ hello }: { hello: string; @@ -164,7 +166,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; + }): Promise | (R extends undefined ? Err | Ok : R extends "simulated" ? SorobanClient.SorobanRpc.SimulateTransactionResponse : R extends "full" ? SorobanClient.SorobanRpc.SimulateTransactionResponse | SorobanClient.SorobanRpc.SendTransactionResponse | SorobanClient.SorobanRpc.GetTransactionResponse : Err | Ok)>; u32({ u32_ }: { u32_: u32; }, options?: { @@ -327,7 +329,7 @@ export declare class Contract { * If the simulation shows that this invocation requires auth/signing, `invoke` will wait `secondsToWait` seconds for the transaction to complete before giving up and returning the incomplete {@link SorobanClient.SorobanRpc.GetTransactionResponse} results (or attempting to parse their probably-missing XDR with `parseResultXdr`, depending on `responseType`). Set this to `0` to skip waiting altogether, which will return you {@link SorobanClient.SorobanRpc.SendTransactionResponse} more quickly, before the transaction has time to be included in the ledger. Default: 10. */ secondsToWait?: number; - }): Promise; + }): Promise; bytes({ bytes }: { bytes: Buffer; }, options?: { diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/invoke.d.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/invoke.d.ts index 033c645924..4e8e953948 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/invoke.d.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/dist/types/invoke.d.ts @@ -1,6 +1,6 @@ -import * as SorobanClient from 'soroban-client'; -import type { Memo, MemoType, Operation, Transaction } from 'soroban-client'; -import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from './method-options.js'; +import * as SorobanClient from "soroban-client"; +import type { Memo, MemoType, Operation, Transaction, xdr } from "soroban-client"; +import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from "./method-options.js"; export type Tx = Transaction, Operation[]>; export declare class NotImplementedError extends Error { } @@ -12,7 +12,7 @@ type SomeRpcResponse = typeof someRpcResponse; type InvokeArgs = MethodOptions & ClassOptions & { method: string; args?: any[]; - parseResultXdr?: (xdr: string) => T; + parseResultXdr: (xdr: string | xdr.ScVal) => T; }; /** * Invoke a method on the test_custom_types contract. 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 index f5f63980c0..d2c672a811 100644 --- 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 @@ -10,7 +10,7 @@ "dependencies": { "@stellar/freighter-api": "1.5.1", "buffer": "6.0.3", - "soroban-client": "0.9.2" + "soroban-client": "0.11.0" }, "devDependencies": { "typescript": "5.1.6" @@ -21,22 +21,6 @@ "resolved": "https://registry.npmjs.org/@stellar/freighter-api/-/freighter-api-1.5.1.tgz", "integrity": "sha512-WEnKEqd+xVLnOq6bJv+fLXod8JQyPjzpOKTpH4g7tG9MM1fmXzD3y2SXJlpCIw8kVqtiC4ynWOlSWX+TKO7KiQ==" }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -87,75 +71,6 @@ "node": "*" } }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -179,20 +94,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -204,82 +105,6 @@ "node": ">= 0.8" } }, - "node_modules/crc": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz", - "integrity": "sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==", - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "buffer": ">=6.0.3" - }, - "peerDependenciesMeta": { - "buffer": { - "optional": true - } - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -288,76 +113,6 @@ "node": ">=0.4.0" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/eventsource": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", - "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -390,38 +145,6 @@ "node": ">= 6" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -451,38 +174,6 @@ "resolved": "https://registry.npmjs.org/js-xdr/-/js-xdr-3.0.0.tgz", "integrity": "sha512-tSt6UKJ2L7t+yaQURGkHo9kop9qnVbChTlCu62zNiDbDZQoZb/YjUj2iFJ3lgelhfg9p5bhO2o/QX+g36TPsSQ==" }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -502,16 +193,6 @@ "node": ">= 0.6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -523,95 +204,11 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "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==" }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -631,11 +228,6 @@ } ] }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -659,33 +251,25 @@ } }, "node_modules/soroban-client": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/soroban-client/-/soroban-client-0.9.2.tgz", - "integrity": "sha512-PPQLvAQTF/y56ev9V9wdMze/K49u1Cj6F9rkiUlRy++wCpSAVjiRYG+duolYvjkzUFPon56xlgAc7tuP4EolWA==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/soroban-client/-/soroban-client-0.11.0.tgz", + "integrity": "sha512-I7861W31Lruy57JaRsK9Hn78zX+VSVf9ocNoVQZBQTfYQ3fJF1tNqyeDXkmIwmBl2aljtgFOChqIl2cufh/8EA==", "dependencies": { "axios": "^1.4.0", "bignumber.js": "^9.1.1", "buffer": "^6.0.3", - "detect-node": "^2.0.4", - "es6-promise": "^4.2.4", - "eventsource": "^2.0.2", - "lodash": "^4.17.21", - "randombytes": "^2.1.0", - "stellar-base": "10.0.0-soroban.4", - "toml": "^3.0.0", + "stellar-base": "10.0.0-soroban.7", "urijs": "^1.19.1" } }, "node_modules/stellar-base": { - "version": "10.0.0-soroban.4", - "resolved": "https://registry.npmjs.org/stellar-base/-/stellar-base-10.0.0-soroban.4.tgz", - "integrity": "sha512-Afl2Mlh+aXokIHhy2x67Df5ofbss83oAOHV7pHLI0fsPlxAgs7YtbClzkNxvpnXyxQI77PMIWFJbT17Y3dR/+A==", + "version": "10.0.0-soroban.7", + "resolved": "https://registry.npmjs.org/stellar-base/-/stellar-base-10.0.0-soroban.7.tgz", + "integrity": "sha512-5+qqGsFXagtbG0L/oIiTDEIUsnerE7Vwvv/Hp2ugG0sKulcnfxgYjNqeon3Zv13uoJ4dtjslQpVOzLxPlklViQ==", "dependencies": { "base32.js": "^0.1.0", "bignumber.js": "^9.1.1", "buffer": "^6.0.3", - "crc": "^4.3.2", - "crypto-browserify": "^3.12.0", "js-xdr": "^3.0.0", "sha.js": "^2.3.6", "tweetnacl": "^1.0.3" @@ -694,19 +278,6 @@ "sodium-native": "^4.0.1" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" - }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -729,11 +300,6 @@ "version": "1.19.11", "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" } } } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json index 498a748d42..01c2224353 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/package.json @@ -4,7 +4,7 @@ "dependencies": { "@stellar/freighter-api": "1.5.1", "buffer": "6.0.3", - "soroban-client": "0.9.2" + "soroban-client": "0.11.0" }, "scripts": { "build": "node ./scripts/build.mjs" 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 634738e586..07186bd451 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 @@ -1,7 +1,6 @@ import * as SorobanClient from 'soroban-client'; -import { xdr } from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; -import { scValStrToJs, scValToJs, addressToScVal, u128ToScVal, i128ToScVal, strToScVal } from './convert.js'; import { invoke } from './invoke.js'; import type { ResponseTypes, Wallet, ClassOptions } from './method-options.js' @@ -16,24 +15,24 @@ export type u128 = bigint; export type i128 = bigint; export type u256 = bigint; export type i256 = bigint; -export type Address = string; export type Option = T | undefined; export type Typepoint = bigint; export type Duration = bigint; +export {Address}; /// Error interface containing the error message export interface Error_ { message: string }; -export interface Result { +export interface Result { unwrap(): T, unwrapErr(): E, isOk(): boolean, isErr(): boolean, }; -export class Ok implements Result { +export class Ok implements Result { constructor(readonly value: T) { } - unwrapErr(): Error_ { + unwrapErr(): E { throw new Error('No error'); } unwrap(): T { @@ -49,9 +48,9 @@ export class Ok implements Result { } } -export class Err implements Result { - constructor(readonly error: Error_) { } - unwrapErr(): Error_ { +export class Err implements Result { + constructor(readonly error: E) { } + unwrapErr(): E { return this.error; } unwrap(): never { @@ -74,7 +73,7 @@ if (typeof window !== 'undefined') { const regex = /Error\(Contract, #(\d+)\)/; -function parseError(message: string): Err | undefined { +function parseError(message: string): Err | undefined { const match = message.match(regex); if (!match) { return undefined; @@ -93,7 +92,7 @@ function parseError(message: string): Err | undefined { export const networks = { futurenet: { networkPassphrase: "Test SDF Future Network ; October 2022", - contractId: "CB5T6MLZNWJBUBKEQAUVIG5JJWKYSYVVE2OVN25GMX3VX7CZ7OBAPAU4", + contractId: "CBYMYMSDF6FBDNCFJCRC7KMO4REYFPOH2U4N7FXI3GJO6YXNCQ43CDSK", } } as const @@ -106,145 +105,61 @@ export interface Test { c: string; } -function TestToXdr(test?: Test): xdr.ScVal { - if (!test) { - return xdr.ScVal.scvVoid(); - } - let arr = [ - new xdr.ScMapEntry({key: ((i)=>xdr.ScVal.scvSymbol(i))("a"), val: ((i)=>xdr.ScVal.scvU32(i))(test["a"])}), - new xdr.ScMapEntry({key: ((i)=>xdr.ScVal.scvSymbol(i))("b"), val: ((i)=>xdr.ScVal.scvBool(i))(test["b"])}), - new xdr.ScMapEntry({key: ((i)=>xdr.ScVal.scvSymbol(i))("c"), val: ((i)=>xdr.ScVal.scvSymbol(i))(test["c"])}) - ]; - return xdr.ScVal.scvMap(arr); -} - - -function TestFromXdr(base64Xdr: string): Test { - let scVal = strToScVal(base64Xdr); - let obj: [string, any][] = scVal.map()!.map(e => [e.key().str() as string, e.val()]); - let map = new Map(obj); - if (!obj) { - throw new Error('Invalid XDR'); - } - return { - a: scValToJs(map.get("a")) as unknown as u32, - b: scValToJs(map.get("b")) as unknown as boolean, - c: scValToJs(map.get("c")) as unknown as string - }; -} - export type SimpleEnum = {tag: "First", values: void} | {tag: "Second", values: void} | {tag: "Third", values: void}; -function SimpleEnumToXdr(simpleEnum?: SimpleEnum): xdr.ScVal { - if (!simpleEnum) { - return xdr.ScVal.scvVoid(); - } - let res: xdr.ScVal[] = []; - switch (simpleEnum.tag) { - case "First": - res.push(((i) => xdr.ScVal.scvSymbol(i))("First")); - break; - case "Second": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Second")); - break; - case "Third": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Third")); - break; - } - return xdr.ScVal.scvVec(res); -} - -function SimpleEnumFromXdr(base64Xdr: string): SimpleEnum { - type Tag = SimpleEnum["tag"]; - type Value = SimpleEnum["values"]; - let [tag, values] = strToScVal(base64Xdr).vec()!.map(scValToJs) as [Tag, Value]; - if (!tag) { - throw new Error('Missing enum tag when decoding SimpleEnum from XDR'); - } - return { tag, values } as SimpleEnum; -} - export enum RoyalCard { Jack = 11, Queen = 12, King = 13, } -function RoyalCardFromXdr(base64Xdr: string): RoyalCard { - return scValStrToJs(base64Xdr) as RoyalCard; -} - - -function RoyalCardToXdr(val: RoyalCard): xdr.ScVal { - return xdr.ScVal.scvI32(val); -} - export type TupleStruct = readonly [Test, SimpleEnum]; - -function TupleStructToXdr(tupleStruct?: TupleStruct): xdr.ScVal { - if (!tupleStruct) { - return xdr.ScVal.scvVoid(); - } - let arr = [ - (i => TestToXdr(i))(tupleStruct[0]), - (i => SimpleEnumToXdr(i))(tupleStruct[1]) - ]; - return xdr.ScVal.scvVec(arr); -} - - -function TupleStructFromXdr(base64Xdr: string): TupleStruct { - return scValStrToJs(base64Xdr) as TupleStruct; -} - export type ComplexEnum = {tag: "Struct", values: readonly [Test]} | {tag: "Tuple", values: readonly [TupleStruct]} | {tag: "Enum", values: readonly [SimpleEnum]} | {tag: "Asset", values: readonly [Address, i128]} | {tag: "Void", values: void}; -function ComplexEnumToXdr(complexEnum?: ComplexEnum): xdr.ScVal { - if (!complexEnum) { - return xdr.ScVal.scvVoid(); - } - let res: xdr.ScVal[] = []; - switch (complexEnum.tag) { - case "Struct": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Struct")); - res.push(((i)=>TestToXdr(i))(complexEnum.values[0])); - break; - case "Tuple": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Tuple")); - res.push(((i)=>TupleStructToXdr(i))(complexEnum.values[0])); - break; - case "Enum": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Enum")); - res.push(((i)=>SimpleEnumToXdr(i))(complexEnum.values[0])); - break; - case "Asset": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Asset")); - res.push(((i)=>addressToScVal(i))(complexEnum.values[0])); - res.push(((i)=>i128ToScVal(i))(complexEnum.values[1])); - break; - case "Void": - res.push(((i) => xdr.ScVal.scvSymbol(i))("Void")); - break; - } - return xdr.ScVal.scvVec(res); -} - -function ComplexEnumFromXdr(base64Xdr: string): ComplexEnum { - type Tag = ComplexEnum["tag"]; - type Value = ComplexEnum["values"]; - let [tag, values] = strToScVal(base64Xdr).vec()!.map(scValToJs) as [Tag, Value]; - if (!tag) { - throw new Error('Missing enum tag when decoding ComplexEnum from XDR'); - } - return { tag, values } as ComplexEnum; -} - const Errors = { 1: {message:"Please provide an odd number"} } export class Contract { - constructor(public readonly options: ClassOptions) {} + spec: ContractSpec; + constructor(public readonly options: ClassOptions) { + this.spec = 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=" + ]); + } async hello({hello}: {hello: string}, options: { /** * The fee to pay for the transaction. Default: 100. @@ -265,11 +180,11 @@ export class Contract { } = {}) { return await invoke({ method: 'hello', - args: [((i) => xdr.ScVal.scvSymbol(i))(hello)], + args: this.spec.funcArgsToScVals("hello", {hello}), ...options, ...this.options, parseResultXdr: (xdr): string => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("hello", xdr); }, }); } @@ -295,6 +210,7 @@ export class Contract { } = {}) { return await invoke({ method: 'woid', + args: this.spec.funcArgsToScVals("woid", {}), ...options, ...this.options, parseResultXdr: () => {}, @@ -322,10 +238,11 @@ export class Contract { } = {}) { return await invoke({ method: 'val', + args: this.spec.funcArgsToScVals("val", {}), ...options, ...this.options, parseResultXdr: (xdr): any => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("val", xdr); }, }); } @@ -352,14 +269,15 @@ export class Contract { try { return await invoke({ method: 'u32_fail_on_even', - args: [((i) => xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_fail_on_even", {u32_}), ...options, ...this.options, parseResultXdr: (xdr): Ok | Err | undefined => { - return new Ok(scValStrToJs(xdr)); + return new Ok(this.spec.funcResToNative("u32_fail_on_even", xdr)); }, }); } catch (e) { + console.log(e) if (typeof e === 'string') { let err = parseError(e); if (err) return err; @@ -389,11 +307,11 @@ export class Contract { } = {}) { return await invoke({ method: 'u32_', - args: [((i) => xdr.ScVal.scvU32(i))(u32_)], + args: this.spec.funcArgsToScVals("u32_", {u32_}), ...options, ...this.options, parseResultXdr: (xdr): u32 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u32_", xdr); }, }); } @@ -419,11 +337,11 @@ export class Contract { } = {}) { return await invoke({ method: 'i32_', - args: [((i) => xdr.ScVal.scvI32(i))(i32_)], + args: this.spec.funcArgsToScVals("i32_", {i32_}), ...options, ...this.options, parseResultXdr: (xdr): i32 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i32_", xdr); }, }); } @@ -449,11 +367,11 @@ export class Contract { } = {}) { return await invoke({ method: 'i64_', - args: [((i) => xdr.ScVal.scvI64(xdr.Int64.fromString(i.toString())))(i64_)], + args: this.spec.funcArgsToScVals("i64_", {i64_}), ...options, ...this.options, parseResultXdr: (xdr): i64 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i64_", xdr); }, }); } @@ -482,11 +400,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'strukt_hel', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt_hel", {strukt}), ...options, ...this.options, parseResultXdr: (xdr): Array => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("strukt_hel", xdr); }, }); } @@ -512,11 +430,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'strukt', - args: [((i) => TestToXdr(i))(strukt)], + args: this.spec.funcArgsToScVals("strukt", {strukt}), ...options, ...this.options, parseResultXdr: (xdr): Test => { - return TestFromXdr(xdr); + return this.spec.funcResToNative("strukt", xdr); }, }); } @@ -542,11 +460,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'simple', - args: [((i) => SimpleEnumToXdr(i))(simple)], + args: this.spec.funcArgsToScVals("simple", {simple}), ...options, ...this.options, parseResultXdr: (xdr): SimpleEnum => { - return SimpleEnumFromXdr(xdr); + return this.spec.funcResToNative("simple", xdr); }, }); } @@ -572,11 +490,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'complex', - args: [((i) => ComplexEnumToXdr(i))(complex)], + args: this.spec.funcArgsToScVals("complex", {complex}), ...options, ...this.options, parseResultXdr: (xdr): ComplexEnum => { - return ComplexEnumFromXdr(xdr); + return this.spec.funcResToNative("complex", xdr); }, }); } @@ -602,11 +520,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'addresse', - args: [((i) => addressToScVal(i))(addresse)], + args: this.spec.funcArgsToScVals("addresse", {addresse}), ...options, ...this.options, parseResultXdr: (xdr): Address => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("addresse", xdr); }, }); } @@ -632,11 +550,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'bytes', - args: [((i) => xdr.ScVal.scvBytes(i))(bytes)], + args: this.spec.funcArgsToScVals("bytes", {bytes}), ...options, ...this.options, parseResultXdr: (xdr): Buffer => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("bytes", xdr); }, }); } @@ -662,11 +580,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'bytes_n', - args: [((i) => xdr.ScVal.scvBytes(i))(bytes_n)], + args: this.spec.funcArgsToScVals("bytes_n", {bytes_n}), ...options, ...this.options, parseResultXdr: (xdr): Buffer => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("bytes_n", xdr); }, }); } @@ -692,11 +610,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'card', - args: [((i) => RoyalCardToXdr(i))(card)], + args: this.spec.funcArgsToScVals("card", {card}), ...options, ...this.options, parseResultXdr: (xdr): RoyalCard => { - return RoyalCardFromXdr(xdr); + return this.spec.funcResToNative("card", xdr); }, }); } @@ -722,11 +640,11 @@ async struktHel({strukt}: {strukt: Test}, o } = {}) { return await invoke({ method: 'boolean', - args: [((i) => xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("boolean", {boolean}), ...options, ...this.options, parseResultXdr: (xdr): boolean => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("boolean", xdr); }, }); } @@ -755,11 +673,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'not', - args: [((i) => xdr.ScVal.scvBool(i))(boolean)], + args: this.spec.funcArgsToScVals("not", {boolean}), ...options, ...this.options, parseResultXdr: (xdr): boolean => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("not", xdr); }, }); } @@ -785,11 +703,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'i128', - args: [((i) => i128ToScVal(i))(i128)], + args: this.spec.funcArgsToScVals("i128", {i128}), ...options, ...this.options, parseResultXdr: (xdr): i128 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i128", xdr); }, }); } @@ -815,11 +733,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'u128', - args: [((i) => u128ToScVal(i))(u128)], + args: this.spec.funcArgsToScVals("u128", {u128}), ...options, ...this.options, parseResultXdr: (xdr): u128 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u128", xdr); }, }); } @@ -845,12 +763,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'multi_args', - args: [((i) => xdr.ScVal.scvU32(i))(a), - ((i) => xdr.ScVal.scvBool(i))(b)], + args: this.spec.funcArgsToScVals("multi_args", {a, b}), ...options, ...this.options, parseResultXdr: (xdr): u32 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("multi_args", xdr); }, }); } @@ -876,15 +793,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'map', - args: [((i) => xdr.ScVal.scvMap(Array.from(i.entries()).map(([key, value]) => { - return new xdr.ScMapEntry({ - key: ((i)=>xdr.ScVal.scvU32(i))(key), - val: ((i)=>xdr.ScVal.scvBool(i))(value)}) - })))(map)], + args: this.spec.funcArgsToScVals("map", {map}), ...options, ...this.options, parseResultXdr: (xdr): Map => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("map", xdr); }, }); } @@ -910,11 +823,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'vec', - args: [((i) => xdr.ScVal.scvVec(i.map((i)=>xdr.ScVal.scvU32(i))))(vec)], + args: this.spec.funcArgsToScVals("vec", {vec}), ...options, ...this.options, parseResultXdr: (xdr): Array => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("vec", xdr); }, }); } @@ -940,12 +853,11 @@ async not({boolean}: {boolean: boolean}, op } = {}) { return await invoke({ method: 'tuple', - args: [((i) => xdr.ScVal.scvVec([((i) => xdr.ScVal.scvSymbol(i))(i[0]), - ((i) => xdr.ScVal.scvU32(i))(i[1])]))(tuple)], + args: this.spec.funcArgsToScVals("tuple", {tuple}), ...options, ...this.options, parseResultXdr: (xdr): readonly [string, u32] => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("tuple", xdr); }, }); } @@ -974,11 +886,11 @@ async option({option}: {option: Option } = {}) { return await invoke({ method: 'option', - args: [((i) => (!i) ? xdr.ScVal.scvVoid() : xdr.ScVal.scvU32(i))(option)], + args: this.spec.funcArgsToScVals("option", {option}), ...options, ...this.options, parseResultXdr: (xdr): Option => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("option", xdr); }, }); } @@ -1004,11 +916,11 @@ async option({option}: {option: Option } = {}) { return await invoke({ method: 'u256', - args: [((i) => i)(u256)], + args: this.spec.funcArgsToScVals("u256", {u256}), ...options, ...this.options, parseResultXdr: (xdr): u256 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("u256", xdr); }, }); } @@ -1034,11 +946,11 @@ async option({option}: {option: Option } = {}) { return await invoke({ method: 'i256', - args: [((i) => i)(i256)], + args: this.spec.funcArgsToScVals("i256", {i256}), ...options, ...this.options, parseResultXdr: (xdr): i256 => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("i256", xdr); }, }); } @@ -1064,11 +976,11 @@ async option({option}: {option: Option } = {}) { return await invoke({ method: 'string', - args: [((i) => xdr.ScVal.scvString(i))(string)], + args: this.spec.funcArgsToScVals("string", {string}), ...options, ...this.options, parseResultXdr: (xdr): string => { - return scValStrToJs(xdr); + return this.spec.funcResToNative("string", xdr); }, }); } @@ -1094,11 +1006,11 @@ async option({option}: {option: Option } = {}) { return await invoke({ method: 'tuple_strukt', - args: [((i) => TupleStructToXdr(i))(tuple_strukt)], + args: this.spec.funcArgsToScVals("tuple_strukt", {tuple_strukt}), ...options, ...this.options, parseResultXdr: (xdr): TupleStruct => { - return TupleStructFromXdr(xdr); + return this.spec.funcResToNative("tuple_strukt", xdr); }, }); } diff --git a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/invoke.ts b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/invoke.ts index d671af54f5..41c300144f 100644 --- a/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/invoke.ts +++ b/cmd/crates/soroban-spec-typescript/fixtures/test_custom_types/src/invoke.ts @@ -1,39 +1,55 @@ -import * as SorobanClient from 'soroban-client' -import type { Account, Memo, MemoType, Operation, Transaction } from 'soroban-client'; -import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from './method-options.js' - -export type Tx = Transaction, Operation[]> +import * as SorobanClient from "soroban-client"; +import type { + Account, + Memo, + MemoType, + Operation, + Transaction, + xdr, +} from "soroban-client"; +import type { + ClassOptions, + MethodOptions, + ResponseTypes, + Wallet, +} from "./method-options.js"; + +export type Tx = Transaction, Operation[]>; /** * Get account details from the Soroban network for the publicKey currently * selected in Freighter. If not connected to Freighter, return null. */ -async function getAccount(wallet: Wallet, server: SorobanClient.Server): Promise { - if (!await wallet.isConnected() || !await wallet.isAllowed()) { - return null +async function getAccount( + wallet: Wallet, + server: SorobanClient.Server +): Promise { + if (!(await wallet.isConnected()) || !(await wallet.isAllowed())) { + return null; } - const { publicKey } = await wallet.getUserInfo() + const { publicKey } = await wallet.getUserInfo(); if (!publicKey) { - return null + return null; } - return await server.getAccount(publicKey) + return await server.getAccount(publicKey); } -export class NotImplementedError extends Error { } +export class NotImplementedError extends Error {} -type Simulation = SorobanClient.SorobanRpc.SimulateTransactionResponse -type SendTx = SorobanClient.SorobanRpc.SendTransactionResponse -type GetTx = SorobanClient.SorobanRpc.GetTransactionResponse +type Simulation = SorobanClient.SorobanRpc.SimulateTransactionResponse; +type SendTx = SorobanClient.SorobanRpc.SendTransactionResponse; +type GetTx = SorobanClient.SorobanRpc.GetTransactionResponse; // defined this way so typeahead shows full union, not named alias -let someRpcResponse: Simulation | SendTx | GetTx -type SomeRpcResponse = typeof someRpcResponse +let someRpcResponse: Simulation | SendTx | GetTx; +type SomeRpcResponse = typeof someRpcResponse; -type InvokeArgs = MethodOptions & ClassOptions & { - method: string, - args?: any[], - parseResultXdr?: (xdr: string) => T, -} +type InvokeArgs = MethodOptions & + ClassOptions & { + method: string; + args?: any[]; + parseResultXdr: (xdr: string | xdr.ScVal) => T; + }; /** * Invoke a method on the test_custom_types contract. @@ -42,7 +58,17 @@ type InvokeArgs = MethodOptions & ClassO * * @returns {T}, by default, the parsed XDR from either the simulation or the full transaction. If `simulateOnly` or `fullRpcResponse` are true, returns either the full simulation or the result of sending/getting the transaction to/from the ledger. */ -export async function invoke(args: InvokeArgs): Promise; +export async function invoke( + args: InvokeArgs +): Promise< + R extends undefined + ? T + : R extends "simulated" + ? Simulation + : R extends "full" + ? SomeRpcResponse + : T +>; export async function invoke({ method, args = [], @@ -55,14 +81,22 @@ export async function invoke({ contractId, wallet, }: InvokeArgs): Promise { - wallet = wallet ?? await import('@stellar/freighter-api') - const server = new SorobanClient.Server(rpcUrl, { allowHttp: rpcUrl.startsWith('http://') }); - const walletAccount = await getAccount(wallet, server) + wallet = wallet ?? (await import("@stellar/freighter-api")); + let parse = parseResultXdr; + const server = new SorobanClient.Server(rpcUrl, { + allowHttp: rpcUrl.startsWith("http://"), + }); + const walletAccount = await getAccount(wallet, server); // use a placeholder null account if not yet connected to Freighter so that view calls can still work - const account = walletAccount ?? new SorobanClient.Account('GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF', '0') + const account = + walletAccount ?? + new SorobanClient.Account( + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "0" + ); - const contract = new SorobanClient.Contract(contractId) + const contract = new SorobanClient.Contract(contractId); let tx = new SorobanClient.TransactionBuilder(account, { fee: fee.toString(10), @@ -70,38 +104,40 @@ export async function invoke({ }) .addOperation(contract.call(method, ...args)) .setTimeout(SorobanClient.TimeoutInfinite) - .build() + .build(); + const simulated = await server.simulateTransaction(tx); - const simulated = await server.simulateTransaction(tx) - - if (simulated.error) throw simulated.error - if (responseType === 'simulated') return simulated + if (simulated.error) throw simulated.error; + if (responseType === "simulated") return simulated; // is it possible for `auths` to be present but empty? Probably not, but let's be safe. - const auths = simulated.results?.[0]?.auth - let authsCount = auths?.length ?? 0; - - const writeLength = SorobanClient.xdr.SorobanTransactionData.fromXDR(simulated.transactionData, 'base64').resources().footprint().readWrite().length + let authsCount = simulated.result.auth?.length ?? 0; - const parse = parseResultXdr ?? (xdr => xdr) + const writeLength = simulated.transactionData + .build() + .resources() + .footprint() + .readWrite().length; - const isViewCall = authsCount === 0 && writeLength === 0 + const isViewCall = authsCount === 0 && writeLength === 0; if (isViewCall) { - if (responseType === 'full') return simulated + if (responseType === "full") return simulated; - const { results } = simulated - if (!results || results[0] === undefined) { + const retval = simulated.result?.retval; + if (!retval) { if (simulated.error) { - throw new Error(simulated.error as unknown as string) + throw new Error(simulated.error as unknown as string); } - throw new Error(`Invalid response from simulateTransaction:\n{simulated}`) + throw new Error( + `Invalid response from simulateTransaction:\n{simulated}` + ); } - return parse(results[0].xdr) + return parseResultXdr(retval); } if (authsCount > 1) { - throw new NotImplementedError("Multiple auths not yet supported") + throw new NotImplementedError("Multiple auths not yet supported"); } if (authsCount === 1) { // TODO: figure out how to fix with new SorobanClient @@ -115,29 +151,29 @@ export async function invoke({ } if (!walletAccount) { - throw new Error('Not connected to Freighter') + throw new Error("Not connected to Freighter"); } tx = await signTx( wallet, - SorobanClient.assembleTransaction(tx, networkPassphrase, simulated) as Tx, - networkPassphrase, + SorobanClient.assembleTransaction(tx, networkPassphrase, simulated).build(), + networkPassphrase ); const raw = await sendTx(tx, secondsToWait, server); - if (responseType === 'full') return raw + if (responseType === "full") return raw; // if `sendTx` awaited the inclusion of the tx in the ledger, it used // `getTransaction`, which has a `resultXdr` field - if ('resultXdr' in raw) return parse(raw.resultXdr) + if ("resultXdr" in raw) return parse(raw.resultXdr.result().toXDR("base64")); // otherwise, it returned the result of `sendTransaction` - if ('errorResultXdr' in raw) return parse(raw.errorResultXdr) + if ("errorResultXdr" in raw) return parse(raw.errorResultXdr); // if neither of these are present, something went wrong - console.error("Don't know how to parse result! Returning full RPC response.") - return raw + console.error("Don't know how to parse result! Returning full RPC response."); + return raw; } /** @@ -148,15 +184,19 @@ export async function invoke({ * or one of the exported contract methods, you may want to use this function * to sign the transaction with Freighter. */ -export async function signTx(wallet: Wallet, tx: Tx, networkPassphrase: string): Promise { +export async function signTx( + wallet: Wallet, + tx: Tx, + networkPassphrase: string +): Promise { const signed = await wallet.signTransaction(tx.toXDR(), { networkPassphrase, - }) + }); return SorobanClient.TransactionBuilder.fromXDR( signed, - networkPassphrase, - ) as Tx + networkPassphrase + ) as Tx; } /** @@ -169,34 +209,49 @@ export async function signTx(wallet: Wallet, tx: Tx, networkPassphrase: string): * function for its timeout/`secondsToWait` logic, rather than implementing * your own. */ -export async function sendTx(tx: Tx, secondsToWait: number, server: SorobanClient.Server): Promise { +export async function sendTx( + tx: Tx, + secondsToWait: number, + server: SorobanClient.Server +): Promise { const sendTransactionResponse = await server.sendTransaction(tx); if (sendTransactionResponse.status !== "PENDING" || secondsToWait === 0) { return sendTransactionResponse; } - let getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); + let getTransactionResponse = await server.getTransaction( + sendTransactionResponse.hash + ); - const waitUntil = new Date((Date.now() + secondsToWait * 1000)).valueOf() + const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); let waitTime = 1000; - let exponentialFactor = 1.5 + let exponentialFactor = 1.5; - while ((Date.now() < waitUntil) && getTransactionResponse.status === "NOT_FOUND") { + while ( + Date.now() < waitUntil && + getTransactionResponse.status === "NOT_FOUND" + ) { // Wait a beat - await new Promise(resolve => setTimeout(resolve, waitTime)) + await new Promise((resolve) => setTimeout(resolve, waitTime)); /// Exponential backoff waitTime = waitTime * exponentialFactor; // See if the transaction is complete - getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash) + getTransactionResponse = await server.getTransaction( + sendTransactionResponse.hash + ); } if (getTransactionResponse.status === "NOT_FOUND") { - console.log( - `Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}` - ) + console.error( + `Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify( + sendTransactionResponse, + null, + 2 + )}` + ); } - return getTransactionResponse + return getTransactionResponse; } diff --git a/cmd/crates/soroban-spec-typescript/src/lib.rs b/cmd/crates/soroban-spec-typescript/src/lib.rs index 2e4a948280..466003517a 100644 --- a/cmd/crates/soroban-spec-typescript/src/lib.rs +++ b/cmd/crates/soroban-spec-typescript/src/lib.rs @@ -6,15 +6,14 @@ use std::{fs, io}; -use crate::types::{StructField, Type, UnionCase}; +use crate::types::Type; use heck::ToLowerCamelCase; use itertools::Itertools; use sha2::{Digest, Sha256}; -use stellar_xdr::ScSpecEntry; +use stellar_xdr::{ScSpecEntry, WriteXdr}; use types::Entry; -use crate::wrapper::type_to_js_xdr; use soroban_spec::read::{from_wasm, FromWasmError}; pub mod boilerplate; @@ -61,11 +60,20 @@ pub fn generate_from_wasm(wasm: &[u8]) -> Result { Ok(json) } -fn generate_class(fns: &[Entry]) -> String { +fn generate_class(fns: &[Entry], spec: &[ScSpecEntry]) -> String { let methods = fns.iter().map(entry_to_ts).join("\n\n "); + let spec = spec + .iter() + .map(|s| format!("\"{}\"", s.to_xdr_base64().unwrap())) + .join(",\n "); format!( r#"export class Contract {{ - constructor(public readonly options: ClassOptions) {{}} + spec: ContractSpec; + constructor(public readonly options: ClassOptions) {{ + this.spec = new ContractSpec([ + {spec} + ]); + }} {methods} }}"#, ) @@ -84,7 +92,7 @@ pub fn generate(spec: &[ScSpecEntry]) -> String { .into_iter() .partition(|entry| matches!(entry, Entry::Function { .. })); let top = other.iter().map(entry_to_ts).join("\n"); - let bottom = generate_class(&fns); + let bottom = generate_class(&fns, spec); format!("{top}\n\n{bottom}") } @@ -142,15 +150,11 @@ pub fn entry_to_ts(entry: &Entry) -> String { inputs, outputs, } => { - let args = inputs - .iter() - .map(|i| format!("((i) => {})({})", type_to_js_xdr(&i.value), i.name)) - .join(",\n "); + let input_vals = inputs.iter().map(func_input_to_arg_name).join(", "); let input = (!inputs.is_empty()) .then(|| { format!( - "{{{}}}: {{{}}}, ", - inputs.iter().map(func_input_to_arg_name).join(", "), + "{{{input_vals}}}: {{{}}}, ", inputs.iter().map(func_input_to_ts).join(", ") ) }) @@ -179,13 +183,7 @@ pub fn entry_to_ts(entry: &Entry) -> String { let mut output = outputs .get(0) - .map(|type_| { - if let Type::Custom { name } = type_ { - format!("{name}FromXdr(xdr)") - } else { - "scValStrToJs(xdr)".to_owned() - } - }) + .map(|_| format!("this.spec.funcResToNative(\"{name}\", xdr)")) .unwrap_or_default(); if is_result { output = format!("new Ok({output})"); @@ -204,13 +202,12 @@ pub fn entry_to_ts(entry: &Entry) -> String { }; let js_name = jsify_name(name); let options = method_options(&return_type); - let args = (!inputs.is_empty()) - .then(|| format!("args: [{args}],\n ")) - .unwrap_or_default(); + let args = format!("args: this.spec.funcArgsToScVals(\"{name}\", {{{input_vals}}}),"); let mut body = format!( r#"return await invoke({{ method: '{name}', - {args}...options, + {args} + ...options, ...this.options, {parse_result_xdr}, }});"# @@ -237,103 +234,27 @@ pub fn entry_to_ts(entry: &Entry) -> String { } Entry::Struct { doc, name, fields } => { let docs = doc_to_ts_doc(doc); - let arg_name = name.to_lower_camel_case(); - let encoded_fields = js_to_xdr_fields(&arg_name, fields); - let decoded_fields = js_from_xdr_fields(fields); let fields = fields.iter().map(field_to_ts).join("\n "); - let void = type_to_js_xdr(&Type::Void); format!( r#"{docs}export interface {name} {{ {fields} }} - -function {name}ToXdr({arg_name}?: {name}): xdr.ScVal {{ - if (!{arg_name}) {{ - return {void}; - }} - let arr = [ - {encoded_fields} - ]; - return xdr.ScVal.scvMap(arr); -}} - - -function {name}FromXdr(base64Xdr: string): {name} {{ - let scVal = strToScVal(base64Xdr); - let obj: [string, any][] = scVal.map()!.map(e => [e.key().str() as string, e.val()]); - let map = new Map(obj); - if (!obj) {{ - throw new Error('Invalid XDR'); - }} - return {{ - {decoded_fields} - }}; -}} "# ) } Entry::TupleStruct { doc, name, fields } => { let docs = doc_to_ts_doc(doc); - let arg_name = name.to_lower_camel_case(); - let encoded_fields = fields - .iter() - .enumerate() - .map(|(i, t)| format!("(i => {})({arg_name}[{i}])", type_to_js_xdr(t),)) - .join(",\n "); let fields = fields.iter().map(type_to_ts).join(", "); - let void = type_to_js_xdr(&Type::Void); - format!( - r#"{docs}export type {name} = readonly [{fields}]; - -function {name}ToXdr({arg_name}?: {name}): xdr.ScVal {{ - if (!{arg_name}) {{ - return {void}; - }} - let arr = [ - {encoded_fields} - ]; - return xdr.ScVal.scvVec(arr); -}} - - -function {name}FromXdr(base64Xdr: string): {name} {{ - return scValStrToJs(base64Xdr) as {name}; -}} -"# - ) + format!("{docs}export type {name} = readonly [{fields}];") } Entry::Union { name, doc, cases } => { let doc = doc_to_ts_doc(doc); - let arg_name = name.to_lower_camel_case(); - let encoded_cases = js_to_xdr_union_cases(&arg_name, cases); let cases = cases.iter().map(case_to_ts).join(" | "); - let void = type_to_js_xdr(&Type::Void); format!( r#"{doc}export type {name} = {cases}; - -function {name}ToXdr({arg_name}?: {name}): xdr.ScVal {{ - if (!{arg_name}) {{ - return {void}; - }} - let res: xdr.ScVal[] = []; - switch ({arg_name}.tag) {{ - {encoded_cases} - }} - return xdr.ScVal.scvVec(res); -}} - -function {name}FromXdr(base64Xdr: string): {name} {{ - type Tag = {name}["tag"]; - type Value = {name}["values"]; - let [tag, values] = strToScVal(base64Xdr).vec()!.map(scValToJs) as [Tag, Value]; - if (!tag) {{ - throw new Error('Missing enum tag when decoding {name} from XDR'); - }} - return {{ tag, values }} as {name}; -}} "# ) } @@ -347,15 +268,6 @@ function {name}FromXdr(base64Xdr: string): {name} {{ r#"{doc}export enum {name} {{ {cases} }} - -function {name}FromXdr(base64Xdr: string): {name} {{ - return scValStrToJs(base64Xdr) as {name}; -}} - - -function {name}ToXdr(val: {name}): xdr.ScVal {{ - return xdr.ScVal.scvI32(val); -}} "#, ) } @@ -374,38 +286,6 @@ function {name}ToXdr(val: {name}): xdr.ScVal {{ } } -fn js_to_xdr_fields(struct_name: &str, f: &[StructField]) -> String { - f.iter() - .map(|StructField { name, value , .. }| { - format!( - r#"new xdr.ScMapEntry({{key: ((i)=>{})("{name}"), val: ((i)=>{})({struct_name}["{name}"])}})"#, - type_to_js_xdr(&Type::Symbol), - type_to_js_xdr(value), - ) - }) - .join(",\n ") -} - -fn js_to_xdr_union_cases(arg_name: &str, f: &[UnionCase]) -> String { - f.iter() - .map(|UnionCase { name, values, .. }| { - let mut rhs = format!( - "res.push(((i) => {})(\"{name}\"))", - type_to_js_xdr(&Type::Symbol) - ); - if !values.is_empty() { - for (i, value) in values.iter().enumerate() { - rhs = format!( - "{rhs};\n res.push(((i)=>{})({arg_name}.values[{i}]))", - type_to_js_xdr(value) - ); - } - }; - format!("case \"{name}\":\n {rhs};\n break;") - }) - .join("\n ") -} - fn enum_case_to_ts(case: &types::EnumCase) -> String { let types::EnumCase { name, value, .. } = case; format!("{name} = {value},") @@ -479,14 +359,3 @@ pub fn type_to_ts(value: &types::Type) -> String { types::Type::Duration => "Duration".to_string(), } } - -fn js_from_xdr_fields(f: &[StructField]) -> String { - f.iter() - .map(|StructField { name, value, .. }| { - format!( - r#"{name}: scValToJs(map.get("{name}")) as unknown as {}"#, - type_to_ts(value) - ) - }) - .join(",\n ") -} diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/package.json b/cmd/crates/soroban-spec-typescript/src/project_template/package.json index 1c74a0fc16..50f019a652 100644 --- a/cmd/crates/soroban-spec-typescript/src/project_template/package.json +++ b/cmd/crates/soroban-spec-typescript/src/project_template/package.json @@ -4,7 +4,7 @@ "dependencies": { "@stellar/freighter-api": "1.5.1", "buffer": "6.0.3", - "soroban-client": "0.9.2" + "soroban-client": "0.11.0" }, "scripts": { "build": "node ./scripts/build.mjs" 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 45a7e73cee..2b7c15d242 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 @@ -1,7 +1,6 @@ import * as SorobanClient from 'soroban-client'; -import { xdr } from 'soroban-client'; +import { ContractSpec, Address } from 'soroban-client'; import { Buffer } from "buffer"; -import { scValStrToJs, scValToJs, addressToScVal, u128ToScVal, i128ToScVal, strToScVal } from './convert.js'; import { invoke } from './invoke.js'; import type { ResponseTypes, Wallet, ClassOptions } from './method-options.js' @@ -16,24 +15,24 @@ export type u128 = bigint; export type i128 = bigint; export type u256 = bigint; export type i256 = bigint; -export type Address = string; export type Option = T | undefined; export type Typepoint = bigint; export type Duration = bigint; +export {Address}; /// Error interface containing the error message export interface Error_ { message: string }; -export interface Result { +export interface Result { unwrap(): T, unwrapErr(): E, isOk(): boolean, isErr(): boolean, }; -export class Ok implements Result { +export class Ok implements Result { constructor(readonly value: T) { } - unwrapErr(): Error_ { + unwrapErr(): E { throw new Error('No error'); } unwrap(): T { @@ -49,9 +48,9 @@ export class Ok implements Result { } } -export class Err implements Result { - constructor(readonly error: Error_) { } - unwrapErr(): Error_ { +export class Err implements Result { + constructor(readonly error: E) { } + unwrapErr(): E { return this.error; } unwrap(): never { @@ -74,7 +73,7 @@ if (typeof window !== 'undefined') { const regex = /Error\(Contract, #(\d+)\)/; -function parseError(message: string): Err | undefined { +function parseError(message: string): Err | undefined { const match = message.match(regex); if (!match) { return undefined; diff --git a/cmd/crates/soroban-spec-typescript/src/project_template/src/invoke.ts b/cmd/crates/soroban-spec-typescript/src/project_template/src/invoke.ts index 20c5af90d8..41c300144f 100644 --- a/cmd/crates/soroban-spec-typescript/src/project_template/src/invoke.ts +++ b/cmd/crates/soroban-spec-typescript/src/project_template/src/invoke.ts @@ -1,48 +1,74 @@ -import * as SorobanClient from 'soroban-client' -import type { Account, Memo, MemoType, Operation, Transaction } from 'soroban-client'; -import type { ClassOptions, MethodOptions, ResponseTypes, Wallet } from './method-options.js' - -export type Tx = Transaction, Operation[]> +import * as SorobanClient from "soroban-client"; +import type { + Account, + Memo, + MemoType, + Operation, + Transaction, + xdr, +} from "soroban-client"; +import type { + ClassOptions, + MethodOptions, + ResponseTypes, + Wallet, +} from "./method-options.js"; + +export type Tx = Transaction, Operation[]>; /** * Get account details from the Soroban network for the publicKey currently * selected in Freighter. If not connected to Freighter, return null. */ -async function getAccount(wallet: Wallet, server: SorobanClient.Server): Promise { - if (!await wallet.isConnected() || !await wallet.isAllowed()) { - return null +async function getAccount( + wallet: Wallet, + server: SorobanClient.Server +): Promise { + if (!(await wallet.isConnected()) || !(await wallet.isAllowed())) { + return null; } - const { publicKey } = await wallet.getUserInfo() + const { publicKey } = await wallet.getUserInfo(); if (!publicKey) { - return null + return null; } - return await server.getAccount(publicKey) + return await server.getAccount(publicKey); } -export class NotImplementedError extends Error { } +export class NotImplementedError extends Error {} -type Simulation = SorobanClient.SorobanRpc.SimulateTransactionResponse -type SendTx = SorobanClient.SorobanRpc.SendTransactionResponse -type GetTx = SorobanClient.SorobanRpc.GetTransactionResponse +type Simulation = SorobanClient.SorobanRpc.SimulateTransactionResponse; +type SendTx = SorobanClient.SorobanRpc.SendTransactionResponse; +type GetTx = SorobanClient.SorobanRpc.GetTransactionResponse; // defined this way so typeahead shows full union, not named alias -let someRpcResponse: Simulation | SendTx | GetTx -type SomeRpcResponse = typeof someRpcResponse +let someRpcResponse: Simulation | SendTx | GetTx; +type SomeRpcResponse = typeof someRpcResponse; -type InvokeArgs = MethodOptions & ClassOptions & { - method: string, - args?: any[], - parseResultXdr?: (xdr: string) => T, -} +type InvokeArgs = MethodOptions & + ClassOptions & { + method: string; + args?: any[]; + parseResultXdr: (xdr: string | xdr.ScVal) => T; + }; /** - * Invoke a method on the INSERT_CONTRACT_NAME_HERE contract. + * Invoke a method on the test_custom_types contract. * * Uses Freighter to determine the current user and if necessary sign the transaction. * * @returns {T}, by default, the parsed XDR from either the simulation or the full transaction. If `simulateOnly` or `fullRpcResponse` are true, returns either the full simulation or the result of sending/getting the transaction to/from the ledger. */ -export async function invoke(args: InvokeArgs): Promise; +export async function invoke( + args: InvokeArgs +): Promise< + R extends undefined + ? T + : R extends "simulated" + ? Simulation + : R extends "full" + ? SomeRpcResponse + : T +>; export async function invoke({ method, args = [], @@ -55,14 +81,22 @@ export async function invoke({ contractId, wallet, }: InvokeArgs): Promise { - wallet = wallet ?? await import('@stellar/freighter-api') - const server = new SorobanClient.Server(rpcUrl, { allowHttp: rpcUrl.startsWith('http://') }); - const walletAccount = await getAccount(wallet, server) + wallet = wallet ?? (await import("@stellar/freighter-api")); + let parse = parseResultXdr; + const server = new SorobanClient.Server(rpcUrl, { + allowHttp: rpcUrl.startsWith("http://"), + }); + const walletAccount = await getAccount(wallet, server); // use a placeholder null account if not yet connected to Freighter so that view calls can still work - const account = walletAccount ?? new SorobanClient.Account('GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF', '0') + const account = + walletAccount ?? + new SorobanClient.Account( + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "0" + ); - const contract = new SorobanClient.Contract(contractId) + const contract = new SorobanClient.Contract(contractId); let tx = new SorobanClient.TransactionBuilder(account, { fee: fee.toString(10), @@ -70,38 +104,40 @@ export async function invoke({ }) .addOperation(contract.call(method, ...args)) .setTimeout(SorobanClient.TimeoutInfinite) - .build() + .build(); + const simulated = await server.simulateTransaction(tx); - const simulated = await server.simulateTransaction(tx) - - if (simulated.error) throw simulated.error - if (responseType === 'simulated') return simulated + if (simulated.error) throw simulated.error; + if (responseType === "simulated") return simulated; // is it possible for `auths` to be present but empty? Probably not, but let's be safe. - const auths = simulated.results?.[0]?.auth - let authsCount = auths?.length ?? 0; - - const writeLength = SorobanClient.xdr.SorobanTransactionData.fromXDR(simulated.transactionData, 'base64').resources().footprint().readWrite().length + let authsCount = simulated.result.auth?.length ?? 0; - const parse = parseResultXdr ?? (xdr => xdr) + const writeLength = simulated.transactionData + .build() + .resources() + .footprint() + .readWrite().length; - const isViewCall = authsCount === 0 && writeLength === 0 + const isViewCall = authsCount === 0 && writeLength === 0; if (isViewCall) { - if (responseType === 'full') return simulated + if (responseType === "full") return simulated; - const { results } = simulated - if (!results || results[0] === undefined) { + const retval = simulated.result?.retval; + if (!retval) { if (simulated.error) { - throw new Error(simulated.error as unknown as string) + throw new Error(simulated.error as unknown as string); } - throw new Error(`Invalid response from simulateTransaction:\n{simulated}`) + throw new Error( + `Invalid response from simulateTransaction:\n{simulated}` + ); } - return parse(results[0].xdr) + return parseResultXdr(retval); } if (authsCount > 1) { - throw new NotImplementedError("Multiple auths not yet supported") + throw new NotImplementedError("Multiple auths not yet supported"); } if (authsCount === 1) { // TODO: figure out how to fix with new SorobanClient @@ -115,29 +151,29 @@ export async function invoke({ } if (!walletAccount) { - throw new Error('Not connected to Freighter') + throw new Error("Not connected to Freighter"); } tx = await signTx( wallet, - SorobanClient.assembleTransaction(tx, networkPassphrase, simulated) as Tx, - networkPassphrase, + SorobanClient.assembleTransaction(tx, networkPassphrase, simulated).build(), + networkPassphrase ); const raw = await sendTx(tx, secondsToWait, server); - if (responseType === 'full') return raw + if (responseType === "full") return raw; // if `sendTx` awaited the inclusion of the tx in the ledger, it used // `getTransaction`, which has a `resultXdr` field - if ('resultXdr' in raw) return parse(raw.resultXdr) + if ("resultXdr" in raw) return parse(raw.resultXdr.result().toXDR("base64")); // otherwise, it returned the result of `sendTransaction` - if ('errorResultXdr' in raw) return parse(raw.errorResultXdr) + if ("errorResultXdr" in raw) return parse(raw.errorResultXdr); // if neither of these are present, something went wrong - console.error("Don't know how to parse result! Returning full RPC response.") - return raw + console.error("Don't know how to parse result! Returning full RPC response."); + return raw; } /** @@ -148,15 +184,19 @@ export async function invoke({ * or one of the exported contract methods, you may want to use this function * to sign the transaction with Freighter. */ -export async function signTx(wallet: Wallet, tx: Tx, networkPassphrase: string): Promise { +export async function signTx( + wallet: Wallet, + tx: Tx, + networkPassphrase: string +): Promise { const signed = await wallet.signTransaction(tx.toXDR(), { networkPassphrase, - }) + }); return SorobanClient.TransactionBuilder.fromXDR( signed, - networkPassphrase, - ) as Tx + networkPassphrase + ) as Tx; } /** @@ -169,34 +209,49 @@ export async function signTx(wallet: Wallet, tx: Tx, networkPassphrase: string): * function for its timeout/`secondsToWait` logic, rather than implementing * your own. */ -export async function sendTx(tx: Tx, secondsToWait: number, server: SorobanClient.Server): Promise { +export async function sendTx( + tx: Tx, + secondsToWait: number, + server: SorobanClient.Server +): Promise { const sendTransactionResponse = await server.sendTransaction(tx); if (sendTransactionResponse.status !== "PENDING" || secondsToWait === 0) { return sendTransactionResponse; } - let getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash); + let getTransactionResponse = await server.getTransaction( + sendTransactionResponse.hash + ); - const waitUntil = new Date((Date.now() + secondsToWait * 1000)).valueOf() + const waitUntil = new Date(Date.now() + secondsToWait * 1000).valueOf(); let waitTime = 1000; - let exponentialFactor = 1.5 + let exponentialFactor = 1.5; - while ((Date.now() < waitUntil) && getTransactionResponse.status === "NOT_FOUND") { + while ( + Date.now() < waitUntil && + getTransactionResponse.status === "NOT_FOUND" + ) { // Wait a beat - await new Promise(resolve => setTimeout(resolve, waitTime)) + await new Promise((resolve) => setTimeout(resolve, waitTime)); /// Exponential backoff waitTime = waitTime * exponentialFactor; // See if the transaction is complete - getTransactionResponse = await server.getTransaction(sendTransactionResponse.hash) + getTransactionResponse = await server.getTransaction( + sendTransactionResponse.hash + ); } if (getTransactionResponse.status === "NOT_FOUND") { - console.log( - `Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify(sendTransactionResponse, null, 2)}` - ) + console.error( + `Waited ${secondsToWait} seconds for transaction to complete, but it did not. Returning anyway. Check the transaction status manually. Info: ${JSON.stringify( + sendTransactionResponse, + null, + 2 + )}` + ); } - return getTransactionResponse + return getTransactionResponse; } diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/src/test.ts b/cmd/crates/soroban-spec-typescript/ts-tests/src/test.ts index 32e92bacb6..589f62b78e 100644 --- a/cmd/crates/soroban-spec-typescript/ts-tests/src/test.ts +++ b/cmd/crates/soroban-spec-typescript/ts-tests/src/test.ts @@ -1,8 +1,9 @@ import test from 'ava' -import { Contract, Ok, Err, networks } from '../../fixtures/test_custom_types/dist/esm/index.js' +import { Contract, Ok, Err, networks, Address } from '../../fixtures/test_custom_types/dist/esm/index.js' const rpcUrl = 'https://rpc-futurenet.stellar.org' const publicKey = 'GCBVOLOM32I7OD5TWZQCIXCXML3TK56MDY7ZMTAILIBQHHKPCVU42XYW' +const addr = Address.fromString(publicKey) const contract = new Contract({ ...networks.futurenet, @@ -49,7 +50,7 @@ test("strukt_hel", async (t) => { t.deepEqual(await contract.struktHel({ strukt: test }), ["Hello", "world"]) }) -test.failing("strukt", async (t) => { +test("strukt", async (t) => { let test = { a: 0, b: true, c: "hello" } t.deepEqual(await contract.strukt({ strukt: test }), test) }) @@ -71,25 +72,25 @@ test('simple third', async t => { test('complex with struct', async t => { const arg = { tag: 'Struct', values: [{ a: 0, b: true, c: 'hello' }] } as const - const ret = { tag: 'Struct', values: { a: 0, b: true, c: 'hello' } } + const ret = { tag: 'Struct', values: [{ a: 0, b: true, c: 'hello' }] } t.deepEqual(await contract.complex({ complex: arg }), ret) }) test('complex with tuple', async t => { const arg = { tag: 'Tuple', values: [[{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }]] } as const - const ret = { tag: 'Tuple', values: [{ a: 0, b: true, c: 'hello' }, ['First']] } + const ret = { tag: 'Tuple', values: [[{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }]] } t.deepEqual(await contract.complex({ complex: arg }), ret) }) test('complex with enum', async t => { const arg = { tag: 'Enum', values: [{ tag: 'First', values: undefined }] } as const - const ret = { tag: 'Enum', values: ['First'] } + const ret = { tag: 'Enum', values: [{ tag: 'First', values: undefined }] } t.deepEqual(await contract.complex({ complex: arg }), ret) }) test('complex with asset', async t => { - const arg = { tag: 'Asset', values: [publicKey, 1n] } as const - const ret = { tag: 'Asset', values: publicKey } + const arg = { tag: 'Asset', values: [addr, 1n] } as const + const ret = { tag: 'Asset', values: [addr, 1n] } t.deepEqual(await contract.complex({ complex: arg }), ret) }) @@ -99,7 +100,7 @@ test('complex with void', async t => { }) test('addresse', async t => { - t.is(await contract.addresse({ addresse: publicKey }), publicKey) + t.deepEqual(await contract.addresse({ addresse: addr }), addr) }) test('bytes', async t => { @@ -107,12 +108,12 @@ test('bytes', async t => { t.deepEqual(await contract.bytes({ bytes }), bytes) }) -test.failing('bytes_n', async t => { - const bytes_n = Buffer.from('1') // what's the correct way to construct bytes_n? +test('bytes_n', async t => { + const bytes_n = Buffer.from('123456789') // what's the correct way to construct bytes_n? t.deepEqual(await contract.bytesN({ bytes_n }), bytes_n) }) -test.failing('card', async t => { +test('card', async t => { const card = 11 t.is(await contract.card({ card }), card) }) @@ -143,7 +144,7 @@ test('map', async t => { map.set(1, true) map.set(2, false) // map.set(3, 'hahaha') // should throw an error - t.deepEqual(await contract.map({ map }), Object.fromEntries(map.entries())) + t.deepEqual(await contract.map({ map }), map) }) test('vec', async t => { @@ -156,24 +157,24 @@ test('tuple', async t => { t.deepEqual(await contract.tuple({ tuple }), tuple) }) -test.failing('option', async t => { +test('option', async t => { // this makes sense t.deepEqual(await contract.option({ option: 1 }), 1) // this passes but shouldn't - t.deepEqual(await contract.option({ option: undefined }), 0) + t.deepEqual(await contract.option({ option: undefined }), undefined) // this is the behavior we probably want, but fails // t.deepEqual(await contract.option(), undefined) // typing and implementation require the object // t.deepEqual(await contract.option({}), undefined) // typing requires argument; implementation would be fine with this - t.deepEqual(await contract.option({ option: undefined }), undefined) + // t.deepEqual(await contract.option({ option: undefined }), undefined) }) -test.failing('u256', async t => { +test('u256', async t => { t.is(await contract.u256({ u256: 1n }), 1n) }) -test.failing('i256', async t => { +test('i256', async t => { t.is(await contract.i256({ i256: -1n }), -1n) }) @@ -183,6 +184,6 @@ test('string', async t => { test('tuple_strukt', async t => { const arg = [{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }] as const - const res = [{ a: 0, b: true, c: 'hello' }, ['First']] + const res = [{ a: 0, b: true, c: 'hello' }, { tag: 'First', values: undefined }] t.deepEqual(await contract.tupleStrukt({ tuple_strukt: arg }), res) }) \ No newline at end of file diff --git a/cmd/crates/soroban-spec-typescript/ts-tests/yarn.lock b/cmd/crates/soroban-spec-typescript/ts-tests/yarn.lock new file mode 100644 index 0000000000..4c2f56d584 --- /dev/null +++ b/cmd/crates/soroban-spec-typescript/ts-tests/yarn.lock @@ -0,0 +1,1013 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ava/typescript@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ava/typescript/-/typescript-4.1.0.tgz#0dde7b3bbcfe59c1424fb20eb289b4a2b3694418" + integrity sha512-1iWZQ/nr9iflhLK9VN8H+1oDZqe93qxNnyYUz+jTzkYPAHc5fdZXBrqmNIgIfFhWYXK5OaQ5YtC7OmLeTNhVEg== + dependencies: + escape-string-regexp "^5.0.0" + execa "^7.1.1" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/node@^20.4.9": + version "20.5.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" + integrity sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q== + +acorn-walk@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +aggregate-error@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-4.0.1.tgz#25091fe1573b9e0be892aeda15c7c66a545f758e" + integrity sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w== + dependencies: + clean-stack "^4.0.0" + indent-string "^5.0.0" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.0.0, ansi-styles@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== + +arrgv@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arrgv/-/arrgv-1.0.2.tgz#025ed55a6a433cad9b604f8112fc4292715a6ec0" + integrity sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw== + +arrify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-3.0.0.tgz#ccdefb8eaf2a1d2ab0da1ca2ce53118759fd46bc" + integrity sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw== + +ava@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ava/-/ava-5.3.1.tgz#335737dd963b7941b90214836cea2e8de1f4d5f4" + integrity sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg== + dependencies: + acorn "^8.8.2" + acorn-walk "^8.2.0" + ansi-styles "^6.2.1" + arrgv "^1.0.2" + arrify "^3.0.0" + callsites "^4.0.0" + cbor "^8.1.0" + chalk "^5.2.0" + chokidar "^3.5.3" + chunkd "^2.0.1" + ci-info "^3.8.0" + ci-parallel-vars "^1.0.1" + clean-yaml-object "^0.1.0" + cli-truncate "^3.1.0" + code-excerpt "^4.0.0" + common-path-prefix "^3.0.0" + concordance "^5.0.4" + currently-unhandled "^0.4.1" + debug "^4.3.4" + emittery "^1.0.1" + figures "^5.0.0" + globby "^13.1.4" + ignore-by-default "^2.1.0" + indent-string "^5.0.0" + is-error "^2.2.2" + is-plain-object "^5.0.0" + is-promise "^4.0.0" + matcher "^5.0.0" + mem "^9.0.2" + ms "^2.1.3" + p-event "^5.0.1" + p-map "^5.5.0" + picomatch "^2.3.1" + pkg-conf "^4.0.0" + plur "^5.1.0" + pretty-ms "^8.0.0" + resolve-cwd "^3.0.0" + stack-utils "^2.0.6" + strip-ansi "^7.0.1" + supertap "^3.0.1" + temp-dir "^3.0.0" + write-file-atomic "^5.0.1" + yargs "^17.7.2" + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +blueimp-md5@^2.10.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" + integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w== + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +callsites@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-4.1.0.tgz#de72b98612eed4e1e2564c952498677faa9d86c2" + integrity sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw== + +cbor@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +chalk@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chunkd@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/chunkd/-/chunkd-2.0.1.tgz#49cd1d7b06992dc4f7fccd962fe2a101ee7da920" + integrity sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ== + +ci-info@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +ci-parallel-vars@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz#e87ff0625ccf9d286985b29b4ada8485ca9ffbc2" + integrity sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg== + +clean-stack@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-4.2.0.tgz#c464e4cde4ac789f4e0735c5d75beb49d7b30b31" + integrity sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg== + dependencies: + escape-string-regexp "5.0.0" + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + integrity sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw== + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +code-excerpt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-4.0.0.tgz#2de7d46e98514385cb01f7b3b741320115f4c95e" + integrity sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA== + dependencies: + convert-to-spaces "^2.0.1" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + +concordance@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/concordance/-/concordance-5.0.4.tgz#9896073261adced72f88d60e4d56f8efc4bbbbd2" + integrity sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw== + dependencies: + date-time "^3.1.0" + esutils "^2.0.3" + fast-diff "^1.2.0" + js-string-escape "^1.0.1" + lodash "^4.17.15" + md5-hex "^3.0.1" + semver "^7.3.2" + well-known-symbols "^2.0.0" + +convert-to-spaces@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz#61a6c98f8aa626c16b296b862a91412a33bceb6b" + integrity sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== + dependencies: + array-find-index "^1.0.1" + +date-time@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-3.1.0.tgz#0d1e934d170579f481ed8df1e2b8ff70ee845e1e" + integrity sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg== + dependencies: + time-zone "^1.0.0" + +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +emittery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-1.0.1.tgz#e0cf36e2d7eef94dbd025969f642d57ae50a56cd" + integrity sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@5.0.0, escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esutils@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +fast-diff@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +figures@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-5.0.0.tgz#126cd055052dea699f8a54e8c9450e6ecfc44d5f" + integrity sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg== + dependencies: + escape-string-regexp "^5.0.0" + is-unicode-supported "^1.2.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +globby@^13.1.4: + version "13.2.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" + integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.3.0" + ignore "^5.2.4" + merge2 "^1.4.1" + slash "^4.0.0" + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +ignore-by-default@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-2.1.0.tgz#c0e0de1a99b6065bdc93315a6f728867981464db" + integrity sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw== + +ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" + integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== + +irregular-plurals@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-3.5.0.tgz#0835e6639aa8425bdc8b0d33d0dc4e89d9c01d2b" + integrity sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-error@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.2.tgz#c10ade187b3c93510c5470a5567833ee25649843" + integrity sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-unicode-supported@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== + +js-yaml@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +load-json-file@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-7.0.1.tgz#a3c9fde6beffb6bedb5acf104fad6bb1604e1b00" + integrity sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ== + +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + +lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +map-age-cleaner@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +matcher@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-5.0.0.tgz#cd82f1c7ae7ee472a9eeaf8ec7cac45e0fe0da62" + integrity sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw== + dependencies: + escape-string-regexp "^5.0.0" + +md5-hex@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-3.0.1.tgz#be3741b510591434b2784d79e556eefc2c9a8e5c" + integrity sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw== + dependencies: + blueimp-md5 "^2.10.0" + +mem@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/mem/-/mem-9.0.2.tgz#bbc2d40be045afe30749681e8f5d554cee0c0354" + integrity sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A== + dependencies: + map-age-cleaner "^0.1.3" + mimic-fn "^4.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== + +p-event@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-5.0.1.tgz#614624ec02ae7f4f13d09a721c90586184af5b0c" + integrity sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ== + dependencies: + p-timeout "^5.0.2" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + +p-map@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-5.5.0.tgz#054ca8ca778dfa4cf3f8db6638ccb5b937266715" + integrity sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg== + dependencies: + aggregate-error "^4.0.0" + +p-timeout@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-5.1.0.tgz#b3c691cf4415138ce2d9cfe071dba11f0fee085b" + integrity sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew== + +parse-ms@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-3.0.0.tgz#3ea24a934913345fcc3656deda72df921da3a70e" + integrity sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw== + +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-conf@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-4.0.0.tgz#63ace00cbacfa94c2226aee133800802d3e3b80c" + integrity sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w== + dependencies: + find-up "^6.0.0" + load-json-file "^7.0.0" + +plur@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-5.1.0.tgz#bff58c9f557b9061d60d8ebf93959cf4b08594ae" + integrity sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg== + dependencies: + irregular-plurals "^3.3.0" + +pretty-ms@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-8.0.0.tgz#a35563b2a02df01e595538f86d7de54ca23194a3" + integrity sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q== + dependencies: + parse-ms "^3.0.0" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +semver@^7.3.2: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +serialize-error@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" + integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== + dependencies: + type-fest "^0.13.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +supertap@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/supertap/-/supertap-3.0.1.tgz#aa89e4522104402c6e8fe470a7d2db6dc4037c6a" + integrity sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw== + dependencies: + indent-string "^5.0.0" + js-yaml "^3.14.1" + serialize-error "^7.0.1" + strip-ansi "^7.0.1" + +temp-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-3.0.0.tgz#7f147b42ee41234cc6ba3138cd8e8aa2302acffa" + integrity sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw== + +time-zone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" + integrity sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +type-fest@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" + integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== + +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +well-known-symbols@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-2.0.0.tgz#e9c7c07dbd132b7b84212c8174391ec1f9871ba5" + integrity sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +write-file-atomic@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^4.0.1" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==