From ec6415966f9c98a5804f6a41cbb2dda195e35993 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:11:47 -0400 Subject: [PATCH 01/10] Update pinned CLI version for e2e tests (#982) Using `rc.1` instead of `preview.1` --- .cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index ef7bdfedb..6b275527a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,7 +1,7 @@ # paths = ["/path/to/override"] # path dependency overrides [alias] # command aliases -install_soroban = "install --version 21.0.0-preview.1 --root ./target soroban-cli --debug" +install_soroban = "install --version 21.0.0-rc.1 --root ./target soroban-cli --debug" # b = "build --target wasm32-unknown-unknown --release" # c = "check" # t = "test" From e5e49dcde5b4333d4b0082abffb5d4cb1ff5cc1d Mon Sep 17 00:00:00 2001 From: Blaine Heffron Date: Wed, 5 Jun 2024 14:12:23 -0400 Subject: [PATCH 02/10] Convert ava tests to mocha (#975) Signed-off-by: blaineheffron Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com> --- package.json | 19 +- .../src/test-contract-client-constructor.js | 75 ++- test/e2e/src/test-custom-types.js | 424 +++++++-------- test/e2e/src/test-hello-world.js | 55 +- test/e2e/src/test-methods-as-args.js | 12 +- test/e2e/src/test-swap.js | 293 +++++----- yarn.lock | 508 ++---------------- 7 files changed, 447 insertions(+), 939 deletions(-) diff --git a/package.json b/package.json index 91e876e72..c0e1d331c 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/ test/e2e/.soroban", "docs": "yarn build:docs && jsdoc -c ./config/.jsdoc.json --verbose", "test": "yarn build:test && yarn test:node && yarn test:integration && yarn test:browser", - "test:e2e": "./test/e2e/initialize.sh && ava", + "test:e2e": "./test/e2e/initialize.sh && yarn _nyc mocha --recursive 'test/e2e/src/test-*.js'", "test:node": "yarn _nyc mocha --recursive 'test/unit/**/*.js'", "test:integration": "yarn _nyc mocha --recursive 'test/integration/**/*.js'", "test:browser": "karma start config/karma.conf.js", @@ -75,14 +75,15 @@ "reporter": "spec", "require": [ "@babel/register", - "test/test-nodejs.js" + "test/test-nodejs.js", + "dotenv/config" ], "exclude": [ "test/test-browser.js" ], "sort": true, "recursive": true, - "timeout": 30000 + "timeout": 120000 }, "nyc": { "instrument": false, @@ -111,8 +112,7 @@ "@types/randombytes": "^2.0.1", "@types/sinon": "^17.0.2", "@types/urijs": "^1.19.20", - "@typescript-eslint/parser": "^7.11.0", - "ava": "^5.3.1", + "@typescript-eslint/parser": "^7.7.1", "axios-mock-adapter": "^1.22.0", "babel-loader": "^9.1.3", "babel-plugin-istanbul": "^6.1.1", @@ -169,14 +169,5 @@ "randombytes": "^2.1.0", "toml": "^3.0.0", "urijs": "^1.19.1" - }, - "ava": { - "files": [ - "./test/e2e/src/test-*" - ], - "require": [ - "dotenv/config" - ], - "timeout": "2m" } } diff --git a/test/e2e/src/test-contract-client-constructor.js b/test/e2e/src/test-contract-client-constructor.js index 60e0069bd..da40738a7 100644 --- a/test/e2e/src/test-contract-client-constructor.js +++ b/test/e2e/src/test-contract-client-constructor.js @@ -1,28 +1,13 @@ -const test = require("ava"); +const { expect } = require("chai"); const { spawnSync } = require("node:child_process"); const { contracts, networkPassphrase, rpcUrl, - friendbotUrl, + generateFundedKeypair, } = require("./util"); -const { Address, contract, Keypair } = require("../../.."); +const { Address, contract } = require("../../.."); -async function generateFundedKeypair() { - const keypair = Keypair.random(); - await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`); - return keypair; -} - -/** - * Generates a Client for the contract with the given name. - * Also generates a new account to use as as the keypair of this contract. This - * account is funded by friendbot. You can pass in an account to re-use the - * same account with multiple contract clients. - * - * By default, will re-deploy the contract every time. Pass in the same - * `contractId` again if you want to re-use the a contract instance. - */ async function clientFromConstructor( name, { keypair = generateFundedKeypair(), contractId } = {}, @@ -104,33 +89,35 @@ async function clientForFromTest(contractId, publicKey, keypair) { return contract.Client.from(options); } -test.before(async (t) => { - const { client, keypair, contractId } = - await clientFromConstructor("customTypes"); - const publicKey = keypair.publicKey(); - const addr = Address.fromString(publicKey); - t.context = { client, publicKey, addr, contractId, keypair }; // eslint-disable-line no-param-reassign -}); +describe('Client', function() { -test("hello from constructor", async (t) => { - const { result } = await t.context.client.hello({ hello: "tests" }); - t.is(result, "tests"); -}); + before(async function() { + const { client, keypair, contractId } = + await clientFromConstructor("customTypes"); + const publicKey = keypair.publicKey(); + const addr = Address.fromString(publicKey); + this.context = { client, publicKey, addr, contractId, keypair }; + }); -test("from", async (t) => { - // objects with different constructors will not pass deepEqual check - function constructorWorkaround(object) { - return JSON.parse(JSON.stringify(object)); - } + it("can be constructed with `new Client`", async function() { + const { result } = await this.context.client.hello({ hello: "tests" }); + expect(result).to.equal("tests"); + }); - const clientFromFrom = await clientForFromTest( - t.context.contractId, - t.context.publicKey, - t.context.keypair, - ); - t.deepEqual( - constructorWorkaround(clientFromFrom), - constructorWorkaround(t.context.client), - ); - t.deepEqual(t.context.client.spec.entries, clientFromFrom.spec.entries); + it("can be constructed with `from`", async function() { + // objects with different constructors will not pass deepEqual check + function constructorWorkaround(object) { + return JSON.parse(JSON.stringify(object)); + } + + const clientFromFrom = await clientForFromTest( + this.context.contractId, + this.context.publicKey, + this.context.keypair, + ); + expect(constructorWorkaround(clientFromFrom)).to.deep.equal( + constructorWorkaround(this.context.client), + ); + expect(this.context.client.spec.entries).to.deep.equal(clientFromFrom.spec.entries); + }); }); diff --git a/test/e2e/src/test-custom-types.js b/test/e2e/src/test-custom-types.js index 6fa1d7045..778a4eeb0 100644 --- a/test/e2e/src/test-custom-types.js +++ b/test/e2e/src/test-custom-types.js @@ -1,226 +1,206 @@ -const test = require("ava"); +const { expect } = require('chai'); const { Address, contract } = require("../../.."); const { clientFor } = require("./util"); -test.before(async (t) => { - const { client, keypair, contractId } = await clientFor("customTypes"); - const publicKey = keypair.publicKey(); - const addr = Address.fromString(publicKey); - t.context = { client, publicKey, addr, contractId, keypair }; // eslint-disable-line no-param-reassign -}); - -test("hello", async (t) => { - const { result } = await t.context.client.hello({ hello: "tests" }); - t.is(result, "tests"); -}); -test("view method with empty keypair", async (t) => { - const { client: client2 } = await clientFor("customTypes", { - keypair: undefined, - contractId: t.context.contractId, - }); - t.is((await client2.hello({ hello: "anonymous" })).result, "anonymous"); -}); - -test("woid", async (t) => { - t.is((await t.context.client.woid()).result, null); -}); - -test("u32_fail_on_even", async (t) => { - t.deepEqual( - (await t.context.client.u32_fail_on_even({ u32_: 1 })).result, - new contract.Ok(1), - ); - t.deepEqual( - (await t.context.client.u32_fail_on_even({ u32_: 2 })).result, - new contract.Err({ message: "Please provide an odd number" }), - ); -}); - -test("u32", async (t) => { - t.is((await t.context.client.u32_({ u32_: 1 })).result, 1); // eslint-disable-line no-underscore-dangle -}); - -test("i32", async (t) => { - t.is((await t.context.client.i32_({ i32_: 1 })).result, 1); // eslint-disable-line no-underscore-dangle -}); - -test("i64", async (t) => { - t.is((await t.context.client.i64_({ i64_: 1n })).result, 1n); // eslint-disable-line no-underscore-dangle -}); - -test("strukt_hel", async (t) => { - const strukt = { a: 0, b: true, c: "world" }; - t.deepEqual((await t.context.client.strukt_hel({ strukt })).result, [ - "Hello", - "world", - ]); -}); - -test("strukt", async (t) => { - const strukt = { a: 0, b: true, c: "hello" }; - t.deepEqual((await t.context.client.strukt({ strukt })).result, strukt); -}); - -test("simple first", async (t) => { - const simple = { tag: "First", values: undefined }; - const ret = { tag: "First" }; - t.deepEqual((await t.context.client.simple({ simple })).result, ret); -}); - -test("simple second", async (t) => { - const simple = { tag: "Second", values: undefined }; - const ret = { tag: "Second" }; - t.deepEqual((await t.context.client.simple({ simple })).result, ret); -}); - -test("simple third", async (t) => { - const simple = { tag: "Third", values: undefined }; - const ret = { tag: "Third" }; - t.deepEqual((await t.context.client.simple({ simple })).result, ret); -}); - -test("complex with struct", async (t) => { - const arg = { tag: "Struct", values: [{ a: 0, b: true, c: "hello" }] }; - t.deepEqual((await t.context.client.complex({ complex: arg })).result, arg); -}); - -test("complex with tuple", async (t) => { - const arg = { - tag: "Tuple", - values: [ - [ - { a: 0, b: true, c: "hello" }, - { tag: "First", values: undefined }, + +describe("Custom Types Tests", function() { + before(async function() { + const { client, keypair, contractId } = await clientFor("customTypes"); + const publicKey = keypair.publicKey(); + const addr = Address.fromString(publicKey); + this.context = { client, publicKey, addr, contractId, keypair }; + }); + + it("hello", async function() { + expect((await this.context.client.hello({ hello: "tests" })).result).to.equal("tests"); + }); + + it("view method with empty keypair", async function() { + const { client: client2 } = await clientFor("customTypes", { + keypair: undefined, + contractId: this.context.contractId, + }); + expect((await client2.hello({ hello: "anonymous" })).result).to.equal("anonymous"); + }); + + it("woid", async function() { + expect((await this.context.client.woid()).result).to.be.null; + }); + + it("u32_fail_on_even", async function() { + let response = await this.context.client.u32_fail_on_even({ u32_: 1 }); + expect(response.result).to.deep.equal(new contract.Ok(1)); + + response = await this.context.client.u32_fail_on_even({ u32_: 2 }); + expect(response.result).to.deep.equal(new contract.Err({ message: "Please provide an odd number" })); + }); + + it("u32", async function() { + expect((await this.context.client.u32_({ u32_: 1 })).result).to.equal(1); + }); + + it("i32", async function() { + expect((await this.context.client.i32_({ i32_: 1 })).result).to.equal(1); + }); + + it("i64", async function() { + expect((await this.context.client.i64_({ i64_: 1n })).result).to.equal(1n); + }); + + it("strukt_hel", async function() { + const strukt = { a: 0, b: true, c: "world" }; + expect((await this.context.client.strukt_hel({ strukt })).result).to.deep.equal(["Hello", "world"]); + }); + + it("strukt", async function() { + const strukt = { a: 0, b: true, c: "hello" }; + expect((await this.context.client.strukt({ strukt })).result).to.deep.equal(strukt); + }); + + it("simple first", async function() { + const simple = { tag: "First", values: undefined }; + expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "First" }); + }); + + it("simple second", async function() { + const simple = { tag: "Second", values: undefined }; + expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "Second" }); + }); + + it("simple third", async function() { + const simple = { tag: "Third", values: undefined }; + expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "Third" }); + }); + + it("complex with struct", async function() { + const arg = { tag: "Struct", values: [{ a: 0, b: true, c: "hello" }] }; + expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(arg); + }); + + it("complex with tuple", async function() { + const arg = { + tag: "Tuple", + values: [ + [ + { a: 0, b: true, c: "hello" }, + { tag: "First", values: undefined }, + ], ], - ], - }; - const ret = { - tag: "Tuple", - values: [[{ a: 0, b: true, c: "hello" }, { tag: "First" }]], - }; - t.deepEqual((await t.context.client.complex({ complex: arg })).result, ret); -}); - -test("complex with enum", async (t) => { - const arg = { tag: "Enum", values: [{ tag: "First", values: undefined }] }; - const ret = { tag: "Enum", values: [{ tag: "First" }] }; - t.deepEqual((await t.context.client.complex({ complex: arg })).result, ret); -}); - -test("complex with asset", async (t) => { - const arg = { tag: "Asset", values: [t.context.publicKey, 1n] }; - t.deepEqual((await t.context.client.complex({ complex: arg })).result, arg); -}); - -test("complex with void", async (t) => { - const complex = { tag: "Void", values: undefined }; - const ret = { tag: "Void" }; - t.deepEqual((await t.context.client.complex({ complex })).result, ret); -}); - -test("addresse", async (t) => { - t.deepEqual( - (await t.context.client.addresse({ addresse: t.context.publicKey })).result, - t.context.addr.toString(), - ); -}); - -test("bytes", async (t) => { - const bytes = Buffer.from("hello"); - t.deepEqual((await t.context.client.bytes({ bytes })).result, bytes); -}); - -test("bytesN", async (t) => { - const bytesN = Buffer.from("123456789"); // what's the correct way to construct bytesN? - t.deepEqual( - (await t.context.client.bytes_n({ bytes_n: bytesN })).result, - bytesN, - ); -}); - -test("card", async (t) => { - const card = 11; - t.is((await t.context.client.card({ card })).result, card); -}); - -test("boolean", async (t) => { - t.is((await t.context.client.boolean({ boolean: true })).result, true); -}); - -test("not", async (t) => { - t.is((await t.context.client.not({ boolean: true })).result, false); -}); - -test("i128", async (t) => { - t.is((await t.context.client.i128({ i128: -1n })).result, -1n); -}); - -test("u128", async (t) => { - t.is((await t.context.client.u128({ u128: 1n })).result, 1n); -}); - -test("multi_args", async (t) => { - t.is((await t.context.client.multi_args({ a: 1, b: true })).result, 1); - t.is((await t.context.client.multi_args({ a: 1, b: false })).result, 0); -}); - -test("map", async (t) => { - const map = new Map(); - map.set(1, true); - map.set(2, false); - // map.set(3, 'hahaha') // should throw an error - t.deepEqual( - (await t.context.client.map({ map })).result, - Array.from(map.entries()), - ); -}); - -test("vec", async (t) => { - const vec = [1, 2, 3]; - t.deepEqual((await t.context.client.vec({ vec })).result, vec); -}); - -test("tuple", async (t) => { - const tuple = ["hello", 1]; - t.deepEqual((await t.context.client.tuple({ tuple })).result, tuple); -}); - -test("option", async (t) => { - // this makes sense - t.deepEqual((await t.context.client.option({ option: 1 })).result, 1); - - // this passes but shouldn't - t.deepEqual( - (await t.context.client.option({ option: undefined })).result, - undefined, - ); - - // this is the behavior we probably want, but fails - // t.deepEqual(await t.context.client.option(), undefined) // typing and implementation require the object - // t.deepEqual((await t.context.client.option({})).result, undefined) // typing requires argument; implementation would be fine with this - // t.deepEqual((await t.context.client.option({ option: undefined })).result, undefined) -}); - -test("u256", async (t) => { - t.is((await t.context.client.u256({ u256: 1n })).result, 1n); -}); - -test("i256", async (t) => { - t.is((await t.context.client.i256({ i256: -1n })).result, -1n); -}); - -test("string", async (t) => { - t.is((await t.context.client.string({ string: "hello" })).result, "hello"); -}); - -test("tuple_strukt", async (t) => { - const arg = [ - { a: 0, b: true, c: "hello" }, - { tag: "First", values: undefined }, - ]; - const res = [{ a: 0, b: true, c: "hello" }, { tag: "First" }]; - t.deepEqual( - (await t.context.client.tuple_strukt({ tuple_strukt: arg })).result, - res, - ); -}); + }; + const ret = { + tag: "Tuple", + values: [[{ a: 0, b: true, c: "hello" }, { tag: "First" }]], + }; + expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(ret); + }); + + it("complex with enum", async function() { + const arg = { tag: "Enum", values: [{ tag: "First", values: undefined }] }; + const ret = { tag: "Enum", values: [{ tag: "First" }] }; + expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(ret); + }); + + it("complex with asset", async function() { + const arg = { tag: "Asset", values: [this.context.publicKey, 1n] }; + expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(arg); + }); + + it("complex with void", async function() { + const complex = { tag: "Void", values: undefined }; + const ret = { tag: "Void" }; + expect((await this.context.client.complex({ complex })).result).to.deep.equal(ret); + }); + + it("addresse", async function() { + expect((await this.context.client.addresse({ addresse: this.context.publicKey })).result).to.equal(this.context.addr.toString()); + }); + + it("bytes", async function() { + const bytes = Buffer.from("hello"); + expect((await this.context.client.bytes({ bytes })).result).to.deep.equal(bytes); + }); + + it("bytesN", async function() { + const bytesN = Buffer.from("123456789"); // what's the correct way to construct bytesN? + expect((await this.context.client.bytes_n({ bytes_n: bytesN })).result).to.deep.equal(bytesN); + }); + + it("card", async function() { + const card = 11; + expect((await this.context.client.card({ card })).result).to.equal(card); + }); + + it("boolean", async function() { + expect((await this.context.client.boolean({ boolean: true })).result).to.equal(true); + }); + + it("not", async function() { + expect((await this.context.client.not({ boolean: true })).result).to.equal(false); + }); + + it("i128", async function() { + expect((await this.context.client.i128({ i128: -1n })).result).to.equal(-1n); + }); + + it("u128", async function() { + expect((await this.context.client.u128({ u128: 1n })).result).to.equal(1n); + }); + + it("multi_args", async function() { + let response = await this.context.client.multi_args({ a: 1, b: true }); + expect(response.result).to.equal(1); + + response = await this.context.client.multi_args({ a: 1, b: false }); + expect(response.result).to.equal(0); + }); + + it("map", async function() { + const map = new Map(); + map.set(1, true); + map.set(2, false); + expect((await this.context.client.map({ map })).result).to.deep.equal(Array.from(map.entries())); + }); + + it("vec", async function() { + const vec = [1, 2, 3]; + expect((await this.context.client.vec({ vec })).result).to.deep.equal(vec); + }); + + it("tuple", async function() { + const tuple = ["hello", 1]; + expect((await this.context.client.tuple({ tuple })).result).to.deep.equal(tuple); + }); + + it("option", async function() { + let response = await this.context.client.option({ option: 1 }); + expect(response.result).to.equal(1); + + response = await this.context.client.option({ option: undefined }); + expect(response.result).to.equal(undefined); + // this is the behavior we probably want, but fails + // t.deepEqual(await t.context.client.option(), undefined) // typing and implementation require the object + // t.deepEqual((await t.context.client.option({})).result, undefined) // typing requires argument; implementation would be fine with this + // t.deepEqual((await t.context.client.option({ option: undefined })).result, undefined) + }); + + it("u256", async function() { + expect((await this.context.client.u256({ u256: 1n })).result).to.equal(1n); + }); + + it("i256", async function() { + expect((await this.context.client.i256({ i256: -1n })).result).to.equal(-1n); + }); + + it("string", async function() { + expect((await this.context.client.string({ string: "hello" })).result).to.equal("hello"); + }); + + it("tuple strukt", async function() { + const arg = [ + { a: 0, b: true, c: "hello" }, + { tag: "First", values: undefined }, + ]; + const res = [{ a: 0, b: true, c: "hello" }, { tag: "First" }]; + expect((await this.context.client.tuple_strukt({ tuple_strukt: arg })).result).to.deep.equal(res); + }); +}); \ No newline at end of file diff --git a/test/e2e/src/test-hello-world.js b/test/e2e/src/test-hello-world.js index 7ce24ec9a..50b50f4f7 100644 --- a/test/e2e/src/test-hello-world.js +++ b/test/e2e/src/test-hello-world.js @@ -1,33 +1,34 @@ -const test = require("ava"); +const { expect } = require("chai"); const { clientFor } = require("./util"); -test("hello", async (t) => { - const { client } = await clientFor("helloWorld"); - t.deepEqual((await client.hello({ world: "tests" })).result, [ - "Hello", - "tests", - ]); -}); +describe("helloWorld client", function() { + it("should return properly formed hello response", async function() { + const { client } = await clientFor("helloWorld"); + const response = await client.hello({ world: "tests" }); + expect(response.result).to.deep.equal(["Hello", "tests"]); + }); -test("auth", async (t) => { - const { client, keypair } = await clientFor("helloWorld"); - const publicKey = keypair.publicKey(); - const { result } = await client.auth({ addr: publicKey, world: "lol" }); - t.deepEqual(result, publicKey); -}); + it("should authenticate the user correctly", async function() { + const { client, keypair } = await clientFor("helloWorld"); + const publicKey = keypair.publicKey(); + const { result } = await client.auth({ addr: publicKey, world: "lol" }); + expect(result).to.equal(publicKey); + }); -test("inc", async (t) => { - const { client } = await clientFor("helloWorld"); - const { result: startingBalance } = await client.get_count(); - const inc = await client.inc(); - t.is((await inc.signAndSend()).result, startingBalance + 1); - t.is(startingBalance, 0); - t.is((await client.get_count()).result, startingBalance + 1); -}); + it("should increment the counter correctly", async function() { + const { client } = await clientFor("helloWorld"); + const { result: startingBalance } = await client.get_count(); + const inc = await client.inc(); + const incrementResponse = await inc.signAndSend(); + expect(incrementResponse.result).to.equal(startingBalance + 1); + expect(startingBalance).to.equal(0); // Assuming the counter starts at 0 + const { result: newBalance } = await client.get_count(); + expect(newBalance).to.equal(startingBalance + 1); + }); -test("options for methods with no arguments", async (t) => { - const { client } = await clientFor("helloWorld"); - // check that options object is FIRST, no need to pass `undefined` for the first argument - const inc = await client.inc({ simulate: false }); - t.falsy(inc.simulation); + it("should accept only options object for methods with no arguments", async function() { + const { client } = await clientFor("helloWorld"); + const inc = await client.inc({ simulate: false }); + expect(inc.simulation).to.be.undefined; + }); }); diff --git a/test/e2e/src/test-methods-as-args.js b/test/e2e/src/test-methods-as-args.js index 1009deb53..1f4b5b5ef 100644 --- a/test/e2e/src/test-methods-as-args.js +++ b/test/e2e/src/test-methods-as-args.js @@ -1,4 +1,4 @@ -const test = require("ava"); +const { expect } = require("chai"); const { clientFor } = require("./util"); // this test checks that apps can pass methods as arguments to other methods and have them still work @@ -6,8 +6,10 @@ function callMethod(method, args) { return method(args); } -test("methods-as-args", async (t) => { - const { client } = await clientFor("helloWorld"); - const { result } = await callMethod(client.hello, { world: "tests" }); - t.deepEqual(result, ["Hello", "tests"]); +describe("methods-as-args", function() { + it("should pass methods as arguments and have them still work", async function() { + const { client } = await clientFor("helloWorld"); + const { result } = await callMethod(client.hello, { world: "tests" }); + expect(result).to.deep.equal(["Hello", "tests"]); + }); }); diff --git a/test/e2e/src/test-swap.js b/test/e2e/src/test-swap.js index f1f651f31..129c181be 100644 --- a/test/e2e/src/test-swap.js +++ b/test/e2e/src/test-swap.js @@ -1,183 +1,146 @@ -const test = require("ava"); +const { expect } = require('chai'); +const { describe, it, before } = require('mocha'); const { contract, rpc } = require("../../.."); const { clientFor, generateFundedKeypair } = require("./util"); const amountAToSwap = 2n; const amountBToSwap = 1n; -test.before(async (t) => { - const alice = await generateFundedKeypair(); - const bob = await generateFundedKeypair(); - - const { - client: tokenA, - contractId: tokenAId, - keypair: root, - } = await clientFor("token"); - const { client: tokenB, contractId: tokenBId } = await clientFor("token", { - keypair: root, - }); - const { client: swapContractAsRoot, contractId: swapId } = await clientFor( - "swap", - { keypair: root }, - ); - await ( - await tokenA.initialize({ - admin: root.publicKey(), - decimal: 0, - name: "Token A", - symbol: "A", - }) - ).signAndSend(); - await ( - await tokenA.mint({ amount: amountAToSwap, to: alice.publicKey() }) - ).signAndSend(); - - await ( +describe("Swap Contract Tests", function () { + + before(async function () { + const alice = await generateFundedKeypair(); + const bob = await generateFundedKeypair(); + + const { + client: tokenA, + contractId: tokenAId, + keypair: root, + } = await clientFor("token"); + const { client: tokenB, contractId: tokenBId } = await clientFor("token", { + keypair: root, + }); + const { client: swapContractAsRoot, contractId: swapId } = await clientFor( + "swap", + { keypair: root }, + ); + await ( + await tokenA.initialize({ + admin: root.publicKey(), + decimal: 0, + name: "Token A", + symbol: "A", + }) + ).signAndSend(); + await ( + await tokenA.mint({ amount: amountAToSwap, to: alice.publicKey() }) + ).signAndSend(); + await tokenB.initialize({ admin: root.publicKey(), decimal: 0, name: "Token B", symbol: "B", - }) - ).signAndSend(); - await ( - await tokenB.mint({ amount: amountBToSwap, to: bob.publicKey() }) - ).signAndSend(); - - t.context = { - // eslint-disable-line no-param-reassign - root, - alice, - bob, - swapContractAsRoot, - swapId, - tokenA, - tokenAId, - tokenB, - tokenBId, - }; -}); + }).then(t => t.signAndSend()); + await ( + await tokenB.mint({ amount: amountBToSwap, to: bob.publicKey() }) + ).signAndSend(); -test("calling `signAndSend()` too soon throws descriptive error", async (t) => { - const tx = await t.context.swapContractAsRoot.swap({ - a: t.context.alice.publicKey(), - b: t.context.bob.publicKey(), - token_a: t.context.tokenAId, - token_b: t.context.tokenBId, - amount_a: amountAToSwap, - min_a_for_b: amountAToSwap, - amount_b: amountBToSwap, - min_b_for_a: amountBToSwap, + this.context = { + root, + alice, + bob, + swapContractAsRoot, + swapId, + tokenA, + tokenAId, + tokenB, + tokenBId, + }; }); - const error = await t.throwsAsync(tx.signAndSend()); - t.true( - error instanceof contract.AssembledTransaction.Errors.NeedsMoreSignatures, - `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`, - ); - if (error) t.regex(error.message, /needsNonInvokerSigningBy/); -}); -test("alice swaps bob 10 A for 1 B", async (t) => { - const tx = await t.context.swapContractAsRoot.swap({ - a: t.context.alice.publicKey(), - b: t.context.bob.publicKey(), - token_a: t.context.tokenAId, - token_b: t.context.tokenBId, - amount_a: amountAToSwap, - min_a_for_b: amountAToSwap, - amount_b: amountBToSwap, - min_b_for_a: amountBToSwap, + it("calling `signAndSend()` too soon throws descriptive error", async function() { + const tx = await this.context.swapContractAsRoot.swap({ + a: this.context.alice.publicKey(), + b: this.context.bob.publicKey(), + token_a: this.context.tokenAId, + token_b: this.context.tokenBId, + amount_a: amountAToSwap, + min_a_for_b: amountAToSwap, + amount_b: amountBToSwap, + min_b_for_a: amountBToSwap, + }); + await expect(tx.signAndSend()).to.be.rejectedWith(contract.AssembledTransaction.Errors.NeedsMoreSignatures).then((error) => { + // Further assertions on the error object + expect(error).to.be.instanceOf(contract.AssembledTransaction.Errors.NeedsMoreSignatures, + `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`); + + if (error) { + // Using regex to check the error message + expect(error.message).to.match(/needsNonInvokerSigningBy/); + } + }); }); - const needsNonInvokerSigningBy = await tx.needsNonInvokerSigningBy(); - t.is(needsNonInvokerSigningBy.length, 2); - t.is( - needsNonInvokerSigningBy.indexOf(t.context.alice.publicKey()), - 0, - "needsNonInvokerSigningBy does not have alice's public key!", - ); - t.is( - needsNonInvokerSigningBy.indexOf(t.context.bob.publicKey()), - 1, - "needsNonInvokerSigningBy does not have bob's public key!", - ); - - // root serializes & sends to alice - const jsonFromRoot = tx.toJSON(); - const { client: clientAlice } = await clientFor("swap", { - keypair: t.context.alice, - contractId: t.context.swapId, - }); - const txAlice = clientAlice.txFromJSON(jsonFromRoot); - await txAlice.signAuthEntries(); - - // alice serializes & sends to bob - const jsonFromAlice = txAlice.toJSON(); - const { client: clientBob } = await clientFor("swap", { - keypair: t.context.bob, - contractId: t.context.swapId, - }); - const txBob = clientBob.txFromJSON(jsonFromAlice); - await txBob.signAuthEntries(); - - // bob serializes & sends back to root - const jsonFromBob = txBob.toJSON(); - const { client: clientRoot } = await clientFor("swap", { - keypair: t.context.root, - contractId: t.context.swapId, + it("alice swaps bob 10 A for 1 B", async function() { + const tx = await this.context.swapContractAsRoot.swap({ + a: this.context.alice.publicKey(), + b: this.context.bob.publicKey(), + token_a: this.context.tokenAId, + token_b: this.context.tokenBId, + amount_a: amountAToSwap, + min_a_for_b: amountAToSwap, + amount_b: amountBToSwap, + min_b_for_a: amountBToSwap, + }); + + const needsNonInvokerSigningBy = await tx.needsNonInvokerSigningBy(); + expect(needsNonInvokerSigningBy).to.have.lengthOf(2); + expect(needsNonInvokerSigningBy.indexOf(this.context.alice.publicKey())).to.equal(0, "needsNonInvokerSigningBy does not have alice's public key!"); + expect(needsNonInvokerSigningBy.indexOf(this.context.bob.publicKey())).to.equal(1, "needsNonInvokerSigningBy does not have bob's public key!"); + + // root serializes & sends to alice + const jsonFromRoot = tx.toJSON(); + const { client: clientAlice } = await clientFor("swap", { + keypair: this.context.alice, + contractId: this.context.swapId, + }); + const txAlice = clientAlice.txFromJSON(jsonFromRoot); + await txAlice.signAuthEntries(); + + // alice serializes & sends to bob + const jsonFromAlice = txAlice.toJSON(); + const { client: clientBob } = await clientFor("swap", { + keypair: this.context.bob, + contractId: this.context.swapId, + }); + const txBob = clientBob.txFromJSON(jsonFromAlice); + await txBob.signAuthEntries(); + + // bob serializes & sends back to root + const jsonFromBob = txBob.toJSON(); + const { client: clientRoot } = await clientFor("swap", { + keypair: this.context.root, + contractId: this.context.swapId, + }); + const txRoot = clientRoot.txFromJSON(jsonFromBob); + + const result = await txRoot.signAndSend(); + + expect(result).to.have.property('sendTransactionResponse'); + expect(result.sendTransactionResponse).to.have.property('status', 'PENDING'); + expect(result).to.have.property('getTransactionResponseAll').that.is.an('array').that.is.not.empty; + expect(result.getTransactionResponse).to.have.property('status').that.is.not.equal('FAILED'); + expect(result.getTransactionResponse).to.have.property('status', rpc.Api.GetTransactionStatus.SUCCESS); + + const aliceTokenABalance = await this.context.tokenA.balance({ id: this.context.alice.publicKey() }); + const aliceTokenBBalance = await this.context.tokenB.balance({ id: this.context.alice.publicKey() }); + const bobTokenABalance = await this.context.tokenA.balance({ id: this.context.bob.publicKey() }); + const bobTokenBBalance = await this.context.tokenB.balance({ id: this.context.bob.publicKey() }); + + expect(aliceTokenABalance.result).to.equal(0n); + expect(aliceTokenBBalance.result).to.equal(amountBToSwap); + expect(bobTokenABalance.result).to.equal(amountAToSwap); + expect(bobTokenBBalance.result).to.equal(0n); }); - const txRoot = clientRoot.txFromJSON(jsonFromBob); - - const result = await txRoot.signAndSend(); - - t.truthy( - result.sendTransactionResponse, - `tx failed: ${JSON.stringify(result, null, 2)}`, - ); - t.is( - result.sendTransactionResponse.status, - "PENDING", - `tx failed: ${JSON.stringify(result, null, 2)}`, - ); - t.truthy( - result.getTransactionResponseAll?.length, - `tx failed: ${JSON.stringify(result.getTransactionResponseAll, null, 2)}`, - ); - t.not( - result.getTransactionResponse.status, - "FAILED", - `tx failed: ${JSON.stringify( - result.getTransactionResponse.resultXdr - .result() - .value() - .map((op) => op.value()?.value().switch()), - null, - 2, - )}`, - ); - t.is( - result.getTransactionResponse.status, - rpc.Api.GetTransactionStatus.SUCCESS, - `tx failed: ${JSON.stringify(result.getTransactionResponse, null, 2)}`, - ); - - t.is( - (await t.context.tokenA.balance({ id: t.context.alice.publicKey() })) - .result, - 0n, - ); - t.is( - (await t.context.tokenB.balance({ id: t.context.alice.publicKey() })) - .result, - amountBToSwap, - ); - t.is( - (await t.context.tokenA.balance({ id: t.context.bob.publicKey() })).result, - amountAToSwap, - ); - t.is( - (await t.context.tokenB.balance({ id: t.context.bob.publicKey() })).result, - 0n, - ); }); diff --git a/yarn.lock b/yarn.lock index 2076ea947..4a4471495 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1634,15 +1634,15 @@ "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" -"@typescript-eslint/parser@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.11.0.tgz#525ad8bee54a8f015f134edd241d91b84ab64839" - integrity sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg== - dependencies: - "@typescript-eslint/scope-manager" "7.11.0" - "@typescript-eslint/types" "7.11.0" - "@typescript-eslint/typescript-estree" "7.11.0" - "@typescript-eslint/visitor-keys" "7.11.0" +"@typescript-eslint/parser@^7.7.1": + version "7.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.12.0.tgz#8761df3345528b35049353db80010b385719b1c3" + integrity sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ== + dependencies: + "@typescript-eslint/scope-manager" "7.12.0" + "@typescript-eslint/types" "7.12.0" + "@typescript-eslint/typescript-estree" "7.12.0" + "@typescript-eslint/visitor-keys" "7.12.0" debug "^4.3.4" "@typescript-eslint/scope-manager@6.21.0": @@ -1653,13 +1653,13 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/scope-manager@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz#cf5619b01de62a226a59add15a02bde457335d1d" - integrity sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw== +"@typescript-eslint/scope-manager@7.12.0": + version "7.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz#259c014362de72dd34f995efe6bd8dda486adf58" + integrity sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg== dependencies: - "@typescript-eslint/types" "7.11.0" - "@typescript-eslint/visitor-keys" "7.11.0" + "@typescript-eslint/types" "7.12.0" + "@typescript-eslint/visitor-keys" "7.12.0" "@typescript-eslint/type-utils@6.21.0": version "6.21.0" @@ -1676,7 +1676,12 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/types@7.11.0", "@typescript-eslint/types@^7.2.0": +"@typescript-eslint/types@7.12.0": + version "7.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.12.0.tgz#bf208f971a8da1e7524a5d9ae2b5f15192a37981" + integrity sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg== + +"@typescript-eslint/types@^7.2.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.11.0.tgz#5e9702a5e8b424b7fc690e338d359939257d6722" integrity sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w== @@ -1695,13 +1700,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz#7cbc569bc7336c3a494ceaf8204fdee5d5dbb7fa" - integrity sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ== +"@typescript-eslint/typescript-estree@7.12.0": + version "7.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz#e6c1074f248b3db6573ab6a7c47a39c4cd498ff9" + integrity sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ== dependencies: - "@typescript-eslint/types" "7.11.0" - "@typescript-eslint/visitor-keys" "7.11.0" + "@typescript-eslint/types" "7.12.0" + "@typescript-eslint/visitor-keys" "7.12.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1730,12 +1735,12 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz#2c50cd292e67645eec05ac0830757071b4a4d597" - integrity sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ== +"@typescript-eslint/visitor-keys@7.12.0": + version "7.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz#c053b55a996679528beeedd8e565710ce1ae1ad3" + integrity sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ== dependencies: - "@typescript-eslint/types" "7.11.0" + "@typescript-eslint/types" "7.12.0" eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": @@ -1914,7 +1919,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^8.1.1, acorn-walk@^8.2.0: +acorn-walk@^8.1.1: version "8.3.2" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== @@ -1932,14 +1937,6 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -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" - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2091,11 +2088,6 @@ array-buffer-byte-length@^1.0.1: call-bind "^1.0.5" is-array-buffer "^3.0.4" -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== - array-includes@^3.1.7: version "3.1.8" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" @@ -2159,16 +2151,6 @@ arraybuffer.prototype.slice@^1.0.3: is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" -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== - asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -2216,55 +2198,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -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" - available-typed-arrays@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" @@ -2394,11 +2327,6 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -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== - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -2600,11 +2528,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -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== - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -2632,13 +2555,6 @@ catharsis@^0.9.0: dependencies: lodash "^4.17.15" -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" - chai-as-promised@^7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.2.tgz#70cd73b74afd519754161386421fb71832c6d041" @@ -2690,7 +2606,7 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.2.0, chalk@^5.3.0, chalk@~5.3.0: +chalk@^5.3.0, chalk@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== @@ -2734,7 +2650,7 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" -chokidar@^3.4.0, chokidar@^3.5.1, chokidar@^3.5.3: +chokidar@^3.4.0, chokidar@^3.5.1: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -2759,21 +2675,11 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== -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.2.0, ci-info@^3.8.0: +ci-info@^3.2.0: version "3.9.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -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== - cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -2787,18 +2693,6 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -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-cursor@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" @@ -2827,14 +2721,6 @@ cli-table3@^0.6.3: optionalDependencies: "@colors/colors" "1.5.0" -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" - cli-truncate@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" @@ -2861,15 +2747,6 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.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" - clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -2879,13 +2756,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.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" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -2999,20 +2869,6 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" -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" - confusing-browser-globals@^1.0.10: version "1.0.11" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" @@ -3058,11 +2914,6 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -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== - cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" @@ -3167,13 +3018,6 @@ crypto-browserify@^3.12.0: randombytes "^2.0.0" randomfill "^1.0.3" -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" - custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" @@ -3218,13 +3062,6 @@ date-format@^4.0.14: resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== -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@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -3399,11 +3236,6 @@ dotenv@^16.4.5: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== -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== - ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -3435,11 +3267,6 @@ elliptic@^6.5.3, elliptic@^6.5.5: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emittery@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-1.0.3.tgz#c9d2a9c689870f15251bb13b31c67715c26d69ac" - integrity sha512-tJdCJitoy2lrC2ldJcqN4vkqJ00lT+tOWNT1hBJjO/3FDMJa5TTIiYGCKGkn/WfCyOzUMObeohbVTj00fhiLiA== - emoji-regex@^10.3.0: version "10.3.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23" @@ -3450,11 +3277,6 @@ emoji-regex@^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== - emojilib@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e" @@ -3630,11 +3452,6 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -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@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -3884,7 +3701,7 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -esutils@^2.0.2, esutils@^2.0.3: +esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== @@ -3957,7 +3774,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.1.2, fast-diff@^1.2.0: +fast-diff@^1.1.2: version "1.3.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== @@ -3967,7 +3784,7 @@ fast-fifo@^1.1.0, fast-fifo@^1.2.0: resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== -fast-glob@^3.2.9, fast-glob@^3.3.0: +fast-glob@^3.2.9: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4010,14 +3827,6 @@ fflate@^0.8.2: resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== -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" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4094,7 +3903,7 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^6.0.0, find-up@^6.3.0: +find-up@^6.3.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== @@ -4400,17 +4209,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -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" - gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -4622,11 +4420,6 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -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.1.1, ignore@^5.2.0, ignore@^5.2.4: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" @@ -4658,11 +4451,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -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== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4695,11 +4483,6 @@ ip-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== -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-arguments@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -4774,11 +4557,6 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -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" @@ -4871,16 +4649,6 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -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-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -4937,11 +4705,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -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== - is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -5098,11 +4861,6 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -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-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5115,7 +4873,7 @@ js-yaml@4.1.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -js-yaml@^3.12.1, js-yaml@^3.13.1, js-yaml@^3.14.1: +js-yaml@^3.12.1, js-yaml@^3.13.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== @@ -5412,11 +5170,6 @@ listr2@~8.2.1: rfdc "^1.3.1" wrap-ansi "^9.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== - loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -5576,13 +5329,6 @@ manage-path@2.0.0: resolved "https://registry.yarnpkg.com/manage-path/-/manage-path-2.0.0.tgz#f4cf8457b926eeee2a83b173501414bc76eb9597" integrity sha512-NJhyB+PJYTpxhxZJ3lecIGgh4kwIY2RAh44XvAz9UlqthlQwtPBf62uBVR8XaD8CRuSjQ6TnZH2lNJkbLPZM2A== -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" - markdown-it-anchor@^8.6.7: version "8.6.7" resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz#ee6926daf3ad1ed5e4e3968b1740eef1c6399634" @@ -5622,20 +5368,6 @@ marked@^9.1.2: resolved "https://registry.yarnpkg.com/marked/-/marked-9.1.6.tgz#5d2a3f8180abfbc5d62e3258a38a1c19c0381695" integrity sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q== -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" - md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -5655,14 +5387,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -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" @@ -5844,7 +5568,7 @@ ms@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, ms@^2.1.1, ms@^2.1.3: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5941,11 +5665,6 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -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-package-data@~1.0.1 || ^2.0.0 || ^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" @@ -6169,18 +5888,6 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== -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@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6237,18 +5944,6 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.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== - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -6288,11 +5983,6 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.7: pbkdf2 "^3.1.2" safe-buffer "^5.2.1" -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== - parse5-htmlparser2-tree-adapter@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -6411,14 +6101,6 @@ pirates@^4.0.6: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -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" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -6440,13 +6122,6 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.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" - possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -6469,13 +6144,6 @@ prettier@^3.2.5: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== -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" - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -6888,7 +6556,7 @@ schema-utils@^4.0.0, schema-utils@^4.2.0: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -"semver@2 >=2.2.1 || 3.x || 4 || 5 || 7", semver@^7.3.2, semver@^7.3.4, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2: +"semver@2 >=2.2.1 || 3.x || 4 || 5 || 7", semver@^7.3.4, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== @@ -6903,13 +6571,6 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -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" - serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -7003,7 +6664,7 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: 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, signal-exit@^4.1.0: +signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== @@ -7042,11 +6703,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -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" @@ -7200,13 +6856,6 @@ ssri@^8.0.0: dependencies: minipass "^3.1.1" -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" - statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" @@ -7268,7 +6917,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0: 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== @@ -7277,15 +6926,6 @@ string-width@^1.0.1: 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" - string-width@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.1.0.tgz#d994252935224729ea3719c49f7206dc9c46550a" @@ -7351,7 +6991,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1, strip-ansi@^7.1.0: +strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -7394,16 +7034,6 @@ superagent@^8.0.9: qs "^6.11.0" semver "^7.3.8" -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" - supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -7477,11 +7107,6 @@ tar@^6.2.1: mkdirp "^1.0.3" yallist "^4.0.0" -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== - terser-webpack-plugin@^5.3.10: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" @@ -7531,11 +7156,6 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -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== - timers-browserify@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" @@ -7656,11 +7276,6 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -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== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -8049,11 +7664,6 @@ webpack@^5.91.0: watchpack "^2.4.1" webpack-sources "^3.2.3" -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-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -8173,14 +7783,6 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -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" - ws@~8.11.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" @@ -8239,11 +7841,6 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -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-unparser@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" @@ -8284,19 +7881,6 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" -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" - yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" From 7f674692d3e53798dcf8e7270642b3ab8605b803 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 11 Jun 2024 17:29:42 -0400 Subject: [PATCH 03/10] Export `DEFAULT_TIMEOUT` for the contract client (#984) --- src/contract/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/contract/index.ts b/src/contract/index.ts index 8b9e1dc5e..657bde8cf 100644 --- a/src/contract/index.ts +++ b/src/contract/index.ts @@ -5,3 +5,4 @@ export * from "./rust_result"; export * from "./sent_transaction"; export * from "./spec"; export * from "./types"; +export { DEFAULT_TIMEOUT } from "./utils"; From 840f57da0d2fe3cc52d37670becd76ecd8b2cdca Mon Sep 17 00:00:00 2001 From: Blaine Heffron Date: Tue, 11 Jun 2024 17:31:14 -0400 Subject: [PATCH 04/10] Adds `AssembledTransaction.toXDR|fromXDR` and `Client.txFromXDR` methods Adds a toXDR and fromXDR for AssembledTransaction class. Also adds a txFromXDR to the Client class. Changes the swap test to use this flow. Limitations: If you use the XDR multi-auth flow, you must re-simulate before the final `signAndSend` call. This is due to the fact that we can't serialize the XDR of the transaction envelope with the results of the simulation. If we want to do this, we would need to add an `AssembledTransaction` type to XDR in `stellar-base`. --------- Co-authored-by: George --- CHANGELOG.md | 12 ++++++ src/contract/assembled_transaction.ts | 58 +++++++++++++++++++++++---- src/contract/client.ts | 3 ++ test/e2e/src/test-swap.js | 13 +++--- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3508b009..151a3761f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ A breaking change will get clearly marked in this log. ## Unreleased +### Added +- `contract.AssembledTransaction` now has a `toXDR` and `fromXDR` method for serializing the +transaction to and from XDR. Additionally, `contract.Client` now has a `txFromXDR`. These methods +should be used in place of `AssembledTransaction.toJSON`, `AssembledTransaction.fromJSON`, and +`Client.txFromJSON` for multi-auth signing. The JSON methods are now deprecated. **Note you must now +call `simulate` on the transaction before the final `signAndSend` call after all required signatures +are gathered when using the XDR methods. + +### Deprecated +- In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and +`fromXDR`. Similarly, in `contract.Client`, `txFromJSON` should be replaced with `txFromXDR`. + ## [v12.0.1](https://github.com/stellar/js-stellar-sdk/compare/v11.3.0...v12.0.1) diff --git a/src/contract/assembled_transaction.ts b/src/contract/assembled_transaction.ts index 1f46824b9..de584fb81 100644 --- a/src/contract/assembled_transaction.ts +++ b/src/contract/assembled_transaction.ts @@ -28,6 +28,7 @@ import { implementsToString, } from "./utils"; import { SentTransaction } from "./sent_transaction"; +import { Spec } from "./spec"; export const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; @@ -364,6 +365,47 @@ export class AssembledTransaction { return txn; } + /** + * Serialize the AssembledTransaction to a base64-encoded XDR string. + */ + toXDR(): string { + if(!this.built) throw new Error( + "Transaction has not yet been simulated; " + + "call `AssembledTransaction.simulate` first.", + ); + return this.built?.toEnvelope().toXDR('base64'); + } + + /** + * Deserialize the AssembledTransaction from a base64-encoded XDR string. + */ + static fromXDR( + options: Omit, "args" | "method" | "parseResultXdr">, + encodedXDR: string, + spec: Spec + ): AssembledTransaction { + const envelope = xdr.TransactionEnvelope.fromXDR(encodedXDR, "base64"); + const built = TransactionBuilder.fromXDR(envelope, options.networkPassphrase) as Tx; + const operation = built.operations[0] as Operation.InvokeHostFunction; + if (!operation?.func?.value || typeof operation.func.value !== 'function') { + throw new Error("Could not extract the method from the transaction envelope."); + } + const invokeContractArgs = operation.func.value() as xdr.InvokeContractArgs; + if (!invokeContractArgs?.functionName) { + throw new Error("Could not extract the method name from the transaction envelope."); + } + const method = invokeContractArgs.functionName().toString('utf-8'); + const txn = new AssembledTransaction( + { ...options, + method, + parseResultXdr: (result: xdr.ScVal) => + spec.funcResToNative(method, result), + } + ); + txn.built = built; + return txn; + } + private constructor(public options: AssembledTransactionOptions) { this.options.simulate = this.options.simulate ?? true; this.server = new Server(this.options.rpcUrl, { @@ -412,14 +454,16 @@ export class AssembledTransaction { } simulate = async (): Promise => { - if (!this.raw) { - throw new Error( - "Transaction has not yet been assembled; " + - "call `AssembledTransaction.build` first.", - ); - } + if (!this.built) { + if (!this.raw) { + throw new Error( + "Transaction has not yet been assembled; " + + "call `AssembledTransaction.build` first.", + ); + } - this.built = this.raw.build(); + this.built = this.raw.build(); + } this.simulation = await this.server.simulateTransaction(this.built); if (Api.isSimulationSuccess(this.simulation)) { diff --git a/src/contract/client.ts b/src/contract/client.ts index e0c298b4a..f576762a6 100644 --- a/src/contract/client.ts +++ b/src/contract/client.ts @@ -124,5 +124,8 @@ export class Client { tx, ); }; + + txFromXDR = (xdrBase64: string): AssembledTransaction => AssembledTransaction.fromXDR(this.options, xdrBase64, this.spec); + } diff --git a/test/e2e/src/test-swap.js b/test/e2e/src/test-swap.js index 129c181be..71e0e0ab4 100644 --- a/test/e2e/src/test-swap.js +++ b/test/e2e/src/test-swap.js @@ -100,31 +100,32 @@ describe("Swap Contract Tests", function () { expect(needsNonInvokerSigningBy.indexOf(this.context.bob.publicKey())).to.equal(1, "needsNonInvokerSigningBy does not have bob's public key!"); // root serializes & sends to alice - const jsonFromRoot = tx.toJSON(); + const xdrFromRoot = tx.toXDR(); const { client: clientAlice } = await clientFor("swap", { keypair: this.context.alice, contractId: this.context.swapId, }); - const txAlice = clientAlice.txFromJSON(jsonFromRoot); + const txAlice = clientAlice.txFromXDR(xdrFromRoot); await txAlice.signAuthEntries(); // alice serializes & sends to bob - const jsonFromAlice = txAlice.toJSON(); + const xdrFromAlice = txAlice.toXDR(); const { client: clientBob } = await clientFor("swap", { keypair: this.context.bob, contractId: this.context.swapId, }); - const txBob = clientBob.txFromJSON(jsonFromAlice); + const txBob = clientBob.txFromXDR(xdrFromAlice); await txBob.signAuthEntries(); // bob serializes & sends back to root - const jsonFromBob = txBob.toJSON(); + const xdrFromBob = txBob.toXDR(); const { client: clientRoot } = await clientFor("swap", { keypair: this.context.root, contractId: this.context.swapId, }); - const txRoot = clientRoot.txFromJSON(jsonFromBob); + const txRoot = clientRoot.txFromXDR(xdrFromBob); + await txRoot.simulate(); const result = await txRoot.signAndSend(); expect(result).to.have.property('sendTransactionResponse'); From 7dc0a8cfee29c0260c260d2a2552bb394d08c929 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:41:51 -0400 Subject: [PATCH 05/10] Update `simulationData` after re-simulation (#985) The new test added here shows that you can edit a transaction with `tx.raw = cloneFrom(tx.build)` and that the `tx.simulationData` will be updated correctly. --- CHANGELOG.md | 3 ++ src/contract/assembled_transaction.ts | 4 ++ test/e2e/src/test-swap.js | 66 +++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 151a3761f..e2642090a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ are gathered when using the XDR methods. - In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and `fromXDR`. Similarly, in `contract.Client`, `txFromJSON` should be replaced with `txFromXDR`. +### Fixed +- Contract Client: if you edit an `AssembledTransaction` with `tx.raw = cloneFrom(tx.build)`, the `tx.simulationData` will now be updated correctly. `simulationData` is effectively a cache, and we now make sure we clear it when you re-simulate. + ## [v12.0.1](https://github.com/stellar/js-stellar-sdk/compare/v11.3.0...v12.0.1) diff --git a/src/contract/assembled_transaction.ts b/src/contract/assembled_transaction.ts index de584fb81..e4d627c0f 100644 --- a/src/contract/assembled_transaction.ts +++ b/src/contract/assembled_transaction.ts @@ -466,6 +466,10 @@ export class AssembledTransaction { } this.simulation = await this.server.simulateTransaction(this.built); + // need to force re-calculation of simulationData for new simulation + delete this.simulationResult; + delete this.simulationTransactionData; + if (Api.isSimulationSuccess(this.simulation)) { this.built = assembleTransaction( this.built, diff --git a/test/e2e/src/test-swap.js b/test/e2e/src/test-swap.js index 71e0e0ab4..a55497071 100644 --- a/test/e2e/src/test-swap.js +++ b/test/e2e/src/test-swap.js @@ -1,7 +1,17 @@ -const { expect } = require('chai'); -const { describe, it, before } = require('mocha'); -const { contract, rpc } = require("../../.."); -const { clientFor, generateFundedKeypair } = require("./util"); +const { expect } = require("chai"); +const { describe, it, before } = require("mocha"); +const { + contract, + rpc, + SorobanDataBuilder, + xdr, + TransactionBuilder, +} = require("../../.."); +const { + clientFor, + generateFundedKeypair, + networkPassphrase, +} = require("./util"); const amountAToSwap = 2n; const amountBToSwap = 1n; @@ -74,7 +84,7 @@ describe("Swap Contract Tests", function () { // Further assertions on the error object expect(error).to.be.instanceOf(contract.AssembledTransaction.Errors.NeedsMoreSignatures, `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`); - + if (error) { // Using regex to check the error message expect(error.message).to.match(/needsNonInvokerSigningBy/); @@ -82,6 +92,52 @@ describe("Swap Contract Tests", function () { }); }); + it("modified & re-simulated transactions show updated data", async function () { + const tx = await this.context.swapContractAsRoot.swap({ + a: this.context.alice.publicKey(), + b: this.context.bob.publicKey(), + token_a: this.context.tokenAId, + token_b: this.context.tokenBId, + amount_a: amountAToSwap, + min_a_for_b: amountAToSwap, + amount_b: amountBToSwap, + min_b_for_a: amountBToSwap, + }); + await tx.signAuthEntries({ + publicKey: this.context.alice.publicKey(), + ...contract.basicNodeSigner(this.context.alice, networkPassphrase), + }); + await tx.signAuthEntries({ + publicKey: this.context.bob.publicKey(), + ...contract.basicNodeSigner(this.context.bob, networkPassphrase), + }); + + const originalResourceFee = Number( + tx.simulationData.transactionData.resourceFee() + ); + const bumpedResourceFee = originalResourceFee + 10000; + + tx.raw = TransactionBuilder.cloneFrom(tx.built, { + fee: tx.built.fee, + sorobanData: new SorobanDataBuilder( + tx.simulationData.transactionData.toXDR() + ) + .setResourceFee( + xdr.Int64.fromString(bumpedResourceFee.toString()).toBigInt() + ) + .build(), + }); + + await tx.simulate(); + + const newSimulatedResourceFee = Number( + tx.simulationData.transactionData.resourceFee() + ); + + expect(originalResourceFee).to.not.equal(newSimulatedResourceFee); + expect(newSimulatedResourceFee).to.be.greaterThan(bumpedResourceFee); + }); + it("alice swaps bob 10 A for 1 B", async function() { const tx = await this.context.swapContractAsRoot.swap({ a: this.context.alice.publicKey(), From 556ffe8349d1a4a3ce103920fb992202fcb3ee72 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:01:43 -0400 Subject: [PATCH 06/10] Add auto restore functionality for contract client (#991) Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Co-authored-by: blaineheffron Co-authored-by: George --- CHANGELOG.md | 9 +- src/contract/assembled_transaction.ts | 160 ++++++++++++++---- src/contract/sent_transaction.ts | 8 +- src/contract/types.ts | 6 + src/contract/utils.ts | 16 +- .../soroban/assembled_transaction_test.js | 120 +++++++++++++ 6 files changed, 276 insertions(+), 43 deletions(-) create mode 100644 test/unit/server/soroban/assembled_transaction_test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index e2642090a..04e0d5df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,9 @@ A breaking change will get clearly marked in this log. ## Unreleased ### Added -- `contract.AssembledTransaction` now has a `toXDR` and `fromXDR` method for serializing the -transaction to and from XDR. Additionally, `contract.Client` now has a `txFromXDR`. These methods -should be used in place of `AssembledTransaction.toJSON`, `AssembledTransaction.fromJSON`, and -`Client.txFromJSON` for multi-auth signing. The JSON methods are now deprecated. **Note you must now -call `simulate` on the transaction before the final `signAndSend` call after all required signatures -are gathered when using the XDR methods. +- `contract.AssembledTransaction` now has: + - `toXDR` and `fromXDR` methods for serializing the transaction to and from XDR. Additionally, `contract.Client` now has a `txFromXDR`. These methods should be used in place of `AssembledTransaction.toJSON`, `AssembledTransaction.fromJSON`, and `Client.txFromJSON` for multi-auth signing. The JSON methods are now deprecated. **Note you must now call `simulate` on the transaction before the final `signAndSend` call after all required signatures are gathered when using the XDR methods. + - a `restoreFootprint` method which accepts the `restorePreamble` returned when a simulation call fails due to some contract state that has expired. When invoking a contract function, one can now set `restore` to `true` in the `MethodOptions`. When enabled, a `restoreFootprint` transaction will be created and await signing when required. ### Deprecated - In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and diff --git a/src/contract/assembled_transaction.ts b/src/contract/assembled_transaction.ts index e4d627c0f..6003de128 100644 --- a/src/contract/assembled_transaction.ts +++ b/src/contract/assembled_transaction.ts @@ -5,6 +5,7 @@ import { BASE_FEE, Contract, Operation, + SorobanDataBuilder, StrKey, TransactionBuilder, authorizeEntry, @@ -26,6 +27,7 @@ import { DEFAULT_TIMEOUT, contractErrorPattern, implementsToString, + getAccount } from "./utils"; import { SentTransaction } from "./sent_transaction"; import { Spec } from "./spec"; @@ -308,6 +310,7 @@ export class AssembledTransaction { */ static Errors = { ExpiredState: class ExpiredStateError extends Error { }, + RestorationFailure: class RestoreFailureError extends Error { }, NeedsMoreSignatures: class NeedsMoreSignaturesError extends Error { }, NoSignatureNeeded: class NoSignatureNeededError extends Error { }, NoUnsignedNonInvokerAuthEntries: class NoUnsignedNonInvokerAuthEntriesError extends Error { }, @@ -437,9 +440,10 @@ export class AssembledTransaction { const tx = new AssembledTransaction(options); const contract = new Contract(options.contractId); - const account = options.publicKey - ? await tx.server.getAccount(options.publicKey) - : new Account(NULL_ACCOUNT, "0"); + const account = await getAccount( + options, + tx.server + ); tx.raw = new TransactionBuilder(account, { fee: options.fee ?? BASE_FEE, @@ -453,27 +457,75 @@ export class AssembledTransaction { return tx; } - simulate = async (): Promise => { - if (!this.built) { - if (!this.raw) { + private static async buildFootprintRestoreTransaction( + options: AssembledTransactionOptions, + sorobanData: SorobanDataBuilder | xdr.SorobanTransactionData, + account: Account, + fee: string + ): Promise> { + const tx = new AssembledTransaction(options); + tx.raw = new TransactionBuilder(account, { + fee, + networkPassphrase: options.networkPassphrase, + }) + .setSorobanData(sorobanData instanceof SorobanDataBuilder ? sorobanData.build() : sorobanData) + .addOperation(Operation.restoreFootprint({})) + .setTimeout(options.timeoutInSeconds ?? DEFAULT_TIMEOUT); + await tx.simulate({ restore: false }); + return tx; + } + + simulate = async ({ restore }: {restore?: boolean} = {}): Promise => { + if (!this.built){ + if(!this.raw) { throw new Error( "Transaction has not yet been assembled; " + - "call `AssembledTransaction.build` first.", + "call `AssembledTransaction.build` first." ); } - this.built = this.raw.build(); } - this.simulation = await this.server.simulateTransaction(this.built); + restore = restore ?? this.options.restore; // need to force re-calculation of simulationData for new simulation delete this.simulationResult; delete this.simulationTransactionData; + this.simulation = await this.server.simulateTransaction(this.built); + + if (restore && Api.isSimulationRestore(this.simulation)) { + const account = await getAccount(this.options, this.server); + const result = await this.restoreFootprint( + this.simulation.restorePreamble, + account + ); + if (result.status === Api.GetTransactionStatus.SUCCESS) { + // need to rebuild the transaction with bumped account sequence number + const contract = new Contract(this.options.contractId); + this.raw = new TransactionBuilder(account, { + fee: this.options.fee ?? BASE_FEE, + networkPassphrase: this.options.networkPassphrase, + }) + .addOperation( + contract.call( + this.options.method, + ...(this.options.args ?? []) + ) + ) + .setTimeout( + this.options.timeoutInSeconds ?? DEFAULT_TIMEOUT + ); + await this.simulate(); + return this; + } + throw new AssembledTransaction.Errors.RestorationFailure( + `Automatic restore failed! You set 'restore: true' but the attempted restore did not work. Result:\n${JSON.stringify(result)}` + ); + } if (Api.isSimulationSuccess(this.simulation)) { this.built = assembleTransaction( this.built, - this.simulation, + this.simulation ).build(); } @@ -502,26 +554,14 @@ export class AssembledTransaction { if (Api.isSimulationRestore(simulation)) { throw new AssembledTransaction.Errors.ExpiredState( - `You need to restore some contract state before you can invoke this method. ${JSON.stringify( - simulation, - null, - 2, - )}`, - ); - } - - if (!simulation.result) { - throw new Error( - `Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify( - simulation, - null, - 2, - )}`, + `You need to restore some contract state before you can invoke this method.\n` + + 'You can set `restore` to true in the method options in order to ' + + 'automatically restore the contract state when needed.' ); } // add to object for serialization & deserialization - this.simulationResult = simulation.result; + this.simulationResult = simulation.result ?? { auth: [], retval: xdr.ScVal.scvVoid() }; this.simulationTransactionData = simulation.transactionData.build(); return { @@ -532,6 +572,9 @@ export class AssembledTransaction { get result(): T { try { + if (!this.simulationData.result) { + throw new Error("No simulation result!"); + } return this.options.parseResultXdr(this.simulationData.result.retval); } catch (e) { if (!implementsToString(e)) throw e; @@ -578,26 +621,29 @@ export class AssembledTransaction { if (!force && this.isReadCall) { throw new AssembledTransaction.Errors.NoSignatureNeeded( "This is a read call. It requires no signature or sending. " + - "Use `force: true` to sign and send anyway.", + "Use `force: true` to sign and send anyway." ); } if (!signTransaction) { throw new AssembledTransaction.Errors.NoSigner( "You must provide a signTransaction function, either when calling " + - "`signAndSend` or when initializing your Client", + "`signAndSend` or when initializing your Client" ); } if (this.needsNonInvokerSigningBy().length) { throw new AssembledTransaction.Errors.NeedsMoreSignatures( "Transaction requires more signatures. " + - "See `needsNonInvokerSigningBy` for details.", + "See `needsNonInvokerSigningBy` for details." ); } const typeChecked: AssembledTransaction = this; - const sent = await SentTransaction.init(signTransaction, typeChecked); + const sent = await SentTransaction.init( + signTransaction, + typeChecked, + ); return sent; }; @@ -789,4 +835,58 @@ export class AssembledTransaction { .readWrite().length; return authsCount === 0 && writeLength === 0; } + + /** + * Restores the footprint (resource ledger entries that can be read or written) + * of an expired transaction. + * + * The method will: + * 1. Build a new transaction aimed at restoring the necessary resources. + * 2. Sign this new transaction if a `signTransaction` handler is provided. + * 3. Send the signed transaction to the network. + * 4. Await and return the response from the network. + * + * Preconditions: + * - A `signTransaction` function must be provided during the Client initialization. + * - The provided `restorePreamble` should include a minimum resource fee and valid + * transaction data. + * + * @throws {Error} - Throws an error if no `signTransaction` function is provided during + * Client initialization. + * @throws {AssembledTransaction.Errors.RestoreFailure} - Throws a custom error if the + * restore transaction fails, providing the details of the failure. + */ + async restoreFootprint( + /** + * The preamble object containing data required to + * build the restore transaction. + */ + restorePreamble: { + minResourceFee: string; + transactionData: SorobanDataBuilder; + }, + /** The account that is executing the footprint restore operation. If omitted, will use the account from the AssembledTransaction. */ + account?: Account + ): Promise { + if (!this.options.signTransaction) { + throw new Error("For automatic restore to work you must provide a signTransaction function when initializing your Client"); + } + account = account ?? await getAccount(this.options, this.server); + // first try restoring the contract + const restoreTx = await AssembledTransaction.buildFootprintRestoreTransaction( + { ...this.options }, + restorePreamble.transactionData, + account, + restorePreamble.minResourceFee + ); + const sentTransaction = await restoreTx.signAndSend(); + if (!sentTransaction.getTransactionResponse) { + throw new AssembledTransaction.Errors.RestorationFailure( + `The attempt at automatic restore failed. \n${JSON.stringify(sentTransaction)}` + ); + } + return sentTransaction.getTransactionResponse; + } + + } diff --git a/src/contract/sent_transaction.ts b/src/contract/sent_transaction.ts index d6f275d78..8d033e648 100644 --- a/src/contract/sent_transaction.ts +++ b/src/contract/sent_transaction.ts @@ -1,6 +1,6 @@ /* disable max-classes rule, because extending error shouldn't count! */ /* eslint max-classes-per-file: 0 */ -import { SorobanDataBuilder, TransactionBuilder } from "@stellar/stellar-base"; +import { TransactionBuilder } from "@stellar/stellar-base"; import type { ClientOptions, MethodOptions, Tx } from "./types"; import { Server } from "../rpc/server" import { Api } from "../rpc/api" @@ -87,10 +87,8 @@ export class SentTransaction { this.assembled.options.timeoutInSeconds ?? DEFAULT_TIMEOUT; this.assembled.built = TransactionBuilder.cloneFrom(this.assembled.built!, { fee: this.assembled.built!.fee, - timebounds: undefined, - sorobanData: new SorobanDataBuilder( - this.assembled.simulationData.transactionData.toXDR(), - ).build(), + timebounds: undefined, // intentionally don't clone timebounds + sorobanData: this.assembled.simulationData.transactionData }) .setTimeout(timeoutInSeconds) .build(); diff --git a/src/contract/types.ts b/src/contract/types.ts index 8b92276c2..d329bd0da 100644 --- a/src/contract/types.ts +++ b/src/contract/types.ts @@ -109,6 +109,12 @@ export type MethodOptions = { * AssembledTransaction. Default: true */ simulate?: boolean; + + /** + * If true, will automatically attempt to restore the transaction if there + * are archived entries that need renewal. @default false + */ + restore?: boolean; }; export type AssembledTransactionOptions = MethodOptions & diff --git a/src/contract/utils.ts b/src/contract/utils.ts index 44e7b8b02..db99d7cbb 100644 --- a/src/contract/utils.ts +++ b/src/contract/utils.ts @@ -1,5 +1,8 @@ -import { xdr, cereal } from "@stellar/stellar-base"; -import type { AssembledTransaction } from "./assembled_transaction"; +import { xdr, cereal, Account } from "@stellar/stellar-base"; +import { Server } from "../rpc/server"; +import { NULL_ACCOUNT, type AssembledTransaction } from "./assembled_transaction"; +import { AssembledTransactionOptions } from "./types"; + /** * The default timeout for waiting for a transaction to be included in a block. @@ -107,3 +110,12 @@ export function processSpecEntryStream(buffer: Buffer) { } return res; } + +export async function getAccount( + options: AssembledTransactionOptions, + server: Server +): Promise { + return options.publicKey + ? await server.getAccount(options.publicKey) + : new Account(NULL_ACCOUNT, "0"); +} diff --git a/test/unit/server/soroban/assembled_transaction_test.js b/test/unit/server/soroban/assembled_transaction_test.js new file mode 100644 index 000000000..6b433fae6 --- /dev/null +++ b/test/unit/server/soroban/assembled_transaction_test.js @@ -0,0 +1,120 @@ +const { + Account, + Keypair, + Networks, + rpc, + SorobanDataBuilder, + xdr, + contract, +} = StellarSdk; +const { Server, AxiosClient, parseRawSimulation } = StellarSdk.rpc; + +const restoreTxnData = StellarSdk.SorobanDataBuilder.fromXDR("AAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQ=="); + +describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { + const keypair = Keypair.random(); + const contractId = "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"; + const networkPassphrase = "Standalone Network ; February 2017"; + const wallet = contract.basicNodeSigner(keypair, networkPassphrase); + const options = { + networkPassphrase, + contractId, + rpcUrl: serverUrl, + allowHttp: true, + publicKey: keypair.publicKey(), + ...wallet, + } + + beforeEach(function () { + this.server = new Server(serverUrl); + this.axiosMock = sinon.mock(AxiosClient); + }); + + afterEach(function () { + this.axiosMock.verify(); + this.axiosMock.restore(); + }); + + + + it("makes expected RPC calls", function (done) { + const simulateTransactionResponse = { + transactionData: restoreTxnData, + minResourceFee: "52641", + cost: { cpuInsns: "0", memBytes: "0" }, + latestLedger: 17027, + }; + + const sendTransactionResponse = { + "status": "PENDING", + "hash": "05870e35fc94e5424f72d125959760b5f60631d91452bde2d11126fb5044e35d", + "latestLedger": 17034, + "latestLedgerCloseTime": "1716483573" + }; + const getTransactionResponse = { + status: "SUCCESS", + latestLedger: 17037, + latestLedgerCloseTime: "1716483576", + oldestLedger: 15598, + oldestLedgerCloseTime: "1716482133", + applicationOrder: 1, + envelopeXdr: "AAAAAgAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQABm0IAAAvWAAAAAwAAAAEAAAAAAAAAAAAAAABmT3cbAAAAAAAAAAEAAAAAAAAAGgAAAAAAAAABAAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQAAAAG+w3upAAAAQGBfsx+gyi/2Dh6i+7Vbb6Ongw3HDcFDZ48eoadkUUvkq97zdPe3wYGFswZgT5/GXPqGDBi+iqHuZiYx5eSy3Qk=", + resultXdr: "AAAAAAAAiRkAAAAAAAAAAQAAAAAAAAAaAAAAAAAAAAA=", + resultMetaXdr: "AAAAAwAAAAAAAAACAAAAAwAAQowAAAAAAAAAABHCklg6riUqP9F21Lt2zdyIZIx9lSn7t3jGCD2+w3upAAAAF0h1Pp0AAAvWAAAAAgAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAAAMMQAAAABmTz9yAAAAAAAAAAEAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAAAACAAAAAMAAAwrAAAACc4pIDe7y0sRFHAghrdpB7ypfj4BVuZStvX4u0BC1S/YAAANVgAAAAAAAAABAABCjAAAAAnOKSA3u8tLERRwIIa3aQe8qX4+AVbmUrb1+LtAQtUv2AAAQ7cAAAAAAAAAAwAADCsAAAAJikpmJa7Pr3lTb+dhRP2N4TOYCqK4tL4tQhDYnNEijtgAAA1WAAAAAAAAAAEAAEKMAAAACYpKZiWuz695U2/nYUT9jeEzmAqiuLS+LUIQ2JzRIo7YAABDtwAAAAAAAAADAAAMMQAAAAlT7LdEin/CaQA3iscHqkwnEFlSh8jfTPTIhSQ5J8Ao0wAADVwAAAAAAAAAAQAAQowAAAAJU+y3RIp/wmkAN4rHB6pMJxBZUofI30z0yIUkOSfAKNMAAEO3AAAAAAAAAAMAAAwxAAAACQycyCYjh7j9CHnTm9OKCYXhgmXw6jdtoMsGHyPk8Aa+AAANXAAAAAAAAAABAABCjAAAAAkMnMgmI4e4/Qh505vTigmF4YJl8Oo3baDLBh8j5PAGvgAAQ7cAAAAAAAAAAgAAAAMAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAABCjAAAAAAAAAAAEcKSWDquJSo/0XbUu3bN3IhkjH2VKfu3eMYIPb7De6kAAAAXSHWDiQAAC9YAAAADAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAEKMAAAAAGZPdfcAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA", + ledger: 17036, + createdAt: "1716483575", + }; + this.axiosMock + .expects("post") + .withArgs( + serverUrl, + sinon.match({ + jsonrpc: "2.0", + id: 1, + method: "simulateTransaction", + }) + ) + .returns(Promise.resolve({ data: { result: simulateTransactionResponse } })); + this.axiosMock + .expects("post") + .withArgs(serverUrl, + sinon.match({ + jsonrpc: "2.0", + id: 1, + method: "getTransaction", + }) + ) + .returns(Promise.resolve({ data: { result: getTransactionResponse } })); + + this.axiosMock + .expects("post") + .withArgs(serverUrl, + sinon.match({ + jsonrpc: "2.0", + id: 1, + method: "sendTransaction", + }) + ) + .returns(Promise.resolve({ data: { result: sendTransactionResponse } })); + + contract.AssembledTransaction.buildFootprintRestoreTransaction( + options, + restoreTxnData, + new StellarSdk.Account( + "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI", + "1", + ), + 52641, + ) + .then((txn) => txn.signAndSend({ ...wallet })) + .then((result) => { + expect(result.getTransactionResponse.status).to.equal(rpc.Api.GetTransactionStatus.SUCCESS); + done(); + }) + .catch((error) => { + // handle any errors that occurred during the promise chain + done(error); + }); + + }) +}); From 863d83a2afd814edd878bf82ed1d8e01d75769e9 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:58:09 -0400 Subject: [PATCH 07/10] Add separate `sign` and `send` methods to `contract.AssembledTransaction` (#992) * add auto restore functionality for contract client * extract getAccount to utils * add changelog entry for auto restore functionality Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Co-authored-by: blaineheffron --- CHANGELOG.md | 1 + src/contract/assembled_transaction.ts | 78 ++++++++++++++++++++++----- src/contract/sent_transaction.ts | 52 ++++-------------- 3 files changed, 78 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04e0d5df0..ba30bfcb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ A breaking change will get clearly marked in this log. - `contract.AssembledTransaction` now has: - `toXDR` and `fromXDR` methods for serializing the transaction to and from XDR. Additionally, `contract.Client` now has a `txFromXDR`. These methods should be used in place of `AssembledTransaction.toJSON`, `AssembledTransaction.fromJSON`, and `Client.txFromJSON` for multi-auth signing. The JSON methods are now deprecated. **Note you must now call `simulate` on the transaction before the final `signAndSend` call after all required signatures are gathered when using the XDR methods. - a `restoreFootprint` method which accepts the `restorePreamble` returned when a simulation call fails due to some contract state that has expired. When invoking a contract function, one can now set `restore` to `true` in the `MethodOptions`. When enabled, a `restoreFootprint` transaction will be created and await signing when required. + - separate `sign` and `send` methods so that you can sign a transaction without sending it. You can continue to use `signAndSend` if you prefer. ### Deprecated - In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and diff --git a/src/contract/assembled_transaction.ts b/src/contract/assembled_transaction.ts index 6003de128..e87de33b7 100644 --- a/src/contract/assembled_transaction.ts +++ b/src/contract/assembled_transaction.ts @@ -303,6 +303,11 @@ export class AssembledTransaction { */ private server: Server; + /** + * The signed transaction. + */ + public signed?: Tx; + /** * A list of the most important errors that various AssembledTransaction * methods can throw. Feel free to catch specific errors in your application @@ -595,13 +600,10 @@ export class AssembledTransaction { } /** - * Sign the transaction with the `wallet`, included previously. If you did - * not previously include one, you need to include one now that at least - * includes the `signTransaction` method. After signing, this method will - * send the transaction to the network and return a `SentTransaction` that - * keeps track of all the attempts to fetch the transaction. + * Sign the transaction with the signTransaction function included previously. + * If you did not previously include one, you need to include one now. */ - signAndSend = async ({ + sign = async ({ force = false, signTransaction = this.options.signTransaction, }: { @@ -613,7 +615,7 @@ export class AssembledTransaction { * You must provide this here if you did not provide one before */ signTransaction?: ClientOptions["signTransaction"]; - } = {}): Promise> => { + } = {}): Promise => { if (!this.built) { throw new Error("Transaction has not yet been simulated"); } @@ -635,16 +637,68 @@ export class AssembledTransaction { if (this.needsNonInvokerSigningBy().length) { throw new AssembledTransaction.Errors.NeedsMoreSignatures( "Transaction requires more signatures. " + - "See `needsNonInvokerSigningBy` for details." + "See `needsNonInvokerSigningBy` for details.", ); } - const typeChecked: AssembledTransaction = this; - const sent = await SentTransaction.init( - signTransaction, - typeChecked, + const timeoutInSeconds = + this.options.timeoutInSeconds ?? DEFAULT_TIMEOUT; + this.built = TransactionBuilder.cloneFrom(this.built!, { + fee: this.built!.fee, + timebounds: undefined, + sorobanData: this.simulationData.transactionData, + }) + .setTimeout(timeoutInSeconds) + .build(); + + const signature = await signTransaction( + this.built.toXDR(), + { + networkPassphrase: this.options.networkPassphrase, + }, ); + + this.signed = TransactionBuilder.fromXDR( + signature, + this.options.networkPassphrase, + ) as Tx; + }; + + /** + * Sends the transaction to the network to return a `SentTransaction` that + * keeps track of all the attempts to fetch the transaction. + */ + async send(){ + if(!this.signed){ + throw new Error("The transaction has not yet been signed. Run `sign` first, or use `signAndSend` instead."); + } + const sent = await SentTransaction.init(undefined, this); return sent; + } + + /** + * Sign the transaction with the `signTransaction` function included previously. + * If you did not previously include one, you need to include one now. + * After signing, this method will send the transaction to the network and + * return a `SentTransaction` that keeps track * of all the attempts to fetch the transaction. + */ + signAndSend = async ({ + force = false, + signTransaction = this.options.signTransaction, + }: { + /** + * If `true`, sign and send the transaction even if it is a read call + */ + force?: boolean; + /** + * You must provide this here if you did not provide one before + */ + signTransaction?: ClientOptions["signTransaction"]; + } = {}): Promise> => { + if(!this.signed){ + await this.sign({ force, signTransaction }); + } + return this.send(); }; private getStorageExpiration = async () => { diff --git a/src/contract/sent_transaction.ts b/src/contract/sent_transaction.ts index 8d033e648..0a449ab3e 100644 --- a/src/contract/sent_transaction.ts +++ b/src/contract/sent_transaction.ts @@ -1,7 +1,6 @@ /* disable max-classes rule, because extending error shouldn't count! */ /* eslint max-classes-per-file: 0 */ -import { TransactionBuilder } from "@stellar/stellar-base"; -import type { ClientOptions, MethodOptions, Tx } from "./types"; +import type { MethodOptions } from "./types"; import { Server } from "../rpc/server" import { Api } from "../rpc/api" import { DEFAULT_TIMEOUT, withExponentialBackoff } from "./utils"; @@ -24,8 +23,6 @@ import type { AssembledTransaction } from "./assembled_transaction"; export class SentTransaction { public server: Server; - public signed?: Tx; - /** * The result of calling `sendTransaction` to broadcast the transaction to the * network. @@ -53,61 +50,32 @@ export class SentTransaction { }; constructor( - public signTransaction: ClientOptions["signTransaction"], + _: any, // deprecated: used to take sentTransaction, need to wait for major release for breaking change public assembled: AssembledTransaction, ) { - if (!signTransaction) { - throw new Error( - "You must provide a `signTransaction` function to send a transaction", - ); - } this.server = new Server(this.assembled.options.rpcUrl, { allowHttp: this.assembled.options.allowHttp ?? false, }); } /** - * Initialize a `SentTransaction` from an existing `AssembledTransaction` and - * a `signTransaction` function. This will also send the transaction to the - * network. + * Initialize a `SentTransaction` from `options` and a `signed` + * AssembledTransaction. This will also send the transaction to the network. */ static init = async ( - /** More info in {@link MethodOptions} */ - signTransaction: ClientOptions["signTransaction"], + /** @deprecated variable is ignored. Now handled by AssembledTransaction. */ + _: any, // eslint-disable-line @typescript-eslint/no-unused-vars /** {@link AssembledTransaction} from which this SentTransaction was initialized */ assembled: AssembledTransaction, ): Promise> => { - const tx = new SentTransaction(signTransaction, assembled); + const tx = new SentTransaction(undefined, assembled); const sent = await tx.send(); return sent; }; private send = async (): Promise => { - const timeoutInSeconds = - this.assembled.options.timeoutInSeconds ?? DEFAULT_TIMEOUT; - this.assembled.built = TransactionBuilder.cloneFrom(this.assembled.built!, { - fee: this.assembled.built!.fee, - timebounds: undefined, // intentionally don't clone timebounds - sorobanData: this.assembled.simulationData.transactionData - }) - .setTimeout(timeoutInSeconds) - .build(); - - const signature = await this.signTransaction!( - // `signAndSend` checks for `this.built` before calling `SentTransaction.init` - this.assembled.built!.toXDR(), - { - networkPassphrase: this.assembled.options.networkPassphrase, - }, - ); - - this.signed = TransactionBuilder.fromXDR( - signature, - this.assembled.options.networkPassphrase, - ) as Tx; - this.sendTransactionResponse = await this.server.sendTransaction( - this.signed, + this.assembled.signed!, ); if (this.sendTransactionResponse.status !== "PENDING") { @@ -122,6 +90,8 @@ export class SentTransaction { const { hash } = this.sendTransactionResponse; + const timeoutInSeconds = + this.assembled.options.timeoutInSeconds ?? DEFAULT_TIMEOUT; this.getTransactionResponseAll = await withExponentialBackoff( () => this.server.getTransaction(hash), (resp) => resp.status === Api.GetTransactionStatus.NOT_FOUND, @@ -183,7 +153,7 @@ export class SentTransaction { // 3. finally, if neither of those are present, throw an error throw new Error( - `Sending transaction failed: ${JSON.stringify(this.assembled)}`, + `Sending transaction failed: ${JSON.stringify(this.assembled.signed)}`, ); } } From 10e5edce7abe82c04c87f86346482d7b9fbe9476 Mon Sep 17 00:00:00 2001 From: George Date: Fri, 14 Jun 2024 10:29:07 -0700 Subject: [PATCH 08/10] Release v12.1.0 (#993) * Upgrade dev dependencies * Upgrade stellar-base to latest version --- CHANGELOG.md | 17 +- package.json | 28 +- yarn.lock | 1564 +++++++++++++++++++++++++------------------------- 3 files changed, 817 insertions(+), 792 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba30bfcb4..1880928d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,18 +6,23 @@ A breaking change will get clearly marked in this log. ## Unreleased + +## [v12.1.0](https://github.com/stellar/js-stellar-sdk/compare/v12.0.1...v12.1.0) + ### Added +- `contract` now exports the `DEFAULT_TIMEOUT` ([#984](https://github.com/stellar/js-stellar-sdk/pull/984)). - `contract.AssembledTransaction` now has: - - `toXDR` and `fromXDR` methods for serializing the transaction to and from XDR. Additionally, `contract.Client` now has a `txFromXDR`. These methods should be used in place of `AssembledTransaction.toJSON`, `AssembledTransaction.fromJSON`, and `Client.txFromJSON` for multi-auth signing. The JSON methods are now deprecated. **Note you must now call `simulate` on the transaction before the final `signAndSend` call after all required signatures are gathered when using the XDR methods. - - a `restoreFootprint` method which accepts the `restorePreamble` returned when a simulation call fails due to some contract state that has expired. When invoking a contract function, one can now set `restore` to `true` in the `MethodOptions`. When enabled, a `restoreFootprint` transaction will be created and await signing when required. - - separate `sign` and `send` methods so that you can sign a transaction without sending it. You can continue to use `signAndSend` if you prefer. + - `toXDR` and `fromXDR` methods for serializing the transaction to and from XDR. These methods should be used in place of `AssembledTransaction.toJSON` and `AssembledTransaction.fromJSON`for multi-auth signing. The JSON methods are now deprecated. **Note:** you must now call `simulate` on the transaction before the final `signAndSend` call after all required signatures are gathered when using the XDR methods ([#977](https://github.com/stellar/js-stellar-sdk/pull/977)). + - a `restoreFootprint` method which accepts the `restorePreamble` returned when a simulation call fails due to some contract state that has expired. When invoking a contract function, one can now set `restore` to `true` in the `MethodOptions`. When enabled, a `restoreFootprint` transaction will be created and await signing when required ([#991](https://github.com/stellar/js-stellar-sdk/pull/991)). + - separate `sign` and `send` methods so that you can sign a transaction without sending it (`signAndSend` still works as before; [#922](https://github.com/stellar/js-stellar-sdk/pull/992)). +- `contract.Client` now has a `txFromXDR` method which should be used in place of `txFromJSON` for multi-auth signing ([#977](https://github.com/stellar/js-stellar-sdk/pull/977)). ### Deprecated -- In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and -`fromXDR`. Similarly, in `contract.Client`, `txFromJSON` should be replaced with `txFromXDR`. +- In `contract.AssembledTransaction`, `toJSON` and `fromJSON` should be replaced with `toXDR` and `fromXDR`. +- In `contract.Client`, `txFromJSON` should be replaced with `txFromXDR`. ### Fixed -- Contract Client: if you edit an `AssembledTransaction` with `tx.raw = cloneFrom(tx.build)`, the `tx.simulationData` will now be updated correctly. `simulationData` is effectively a cache, and we now make sure we clear it when you re-simulate. +- If you edit an `AssembledTransaction` with `tx.raw = cloneFrom(tx.build)`, the `tx.simulationData` will now be updated correctly ([#985](https://github.com/stellar/js-stellar-sdk/pull/985)). ## [v12.0.1](https://github.com/stellar/js-stellar-sdk/compare/v11.3.0...v12.0.1) diff --git a/package.json b/package.json index c0e1d331c..3d1cc2e23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@stellar/stellar-sdk", - "version": "12.0.1", + "version": "12.1.0", "description": "A library for working with the Stellar network, including communication with the Horizon and Soroban RPC servers.", "keywords": [ "stellar" @@ -93,11 +93,11 @@ ] }, "devDependencies": { - "@babel/cli": "^7.24.6", - "@babel/core": "^7.24.6", - "@babel/eslint-plugin": "^7.24.6", - "@babel/preset-env": "^7.24.6", - "@babel/preset-typescript": "^7.24.6", + "@babel/cli": "^7.24.7", + "@babel/core": "^7.24.7", + "@babel/eslint-plugin": "^7.24.7", + "@babel/preset-env": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@babel/register": "^7.24.6", "@definitelytyped/dtslint": "^0.2.20", "@istanbuljs/nyc-config-babel": "3.0.0", @@ -106,13 +106,13 @@ "@types/detect-node": "^2.0.0", "@types/eventsource": "^1.1.12", "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.4", + "@types/lodash": "^4.17.5", "@types/mocha": "^10.0.2", - "@types/node": "^20.12.13", + "@types/node": "^20.14.2", "@types/randombytes": "^2.0.1", "@types/sinon": "^17.0.2", "@types/urijs": "^1.19.20", - "@typescript-eslint/parser": "^7.7.1", + "@typescript-eslint/parser": "^7.13.0", "axios-mock-adapter": "^1.22.0", "babel-loader": "^9.1.3", "babel-plugin-istanbul": "^6.1.1", @@ -127,7 +127,7 @@ "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsdoc": "^48.2.7", + "eslint-plugin-jsdoc": "^48.2.12", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prefer-import": "^0.0.1", "eslint-plugin-prettier": "^5.1.2", @@ -144,13 +144,13 @@ "karma-mocha": "^2.0.0", "karma-sinon-chai": "^2.0.2", "karma-webpack": "^5.0.1", - "lint-staged": "^15.2.5", + "lint-staged": "^15.2.7", "lodash": "^4.17.21", "minami": "^1.1.1", "mocha": "^10.3.0", "node-polyfill-webpack-plugin": "^3.0.0", "nyc": "^15.1.0", - "prettier": "^3.2.5", + "prettier": "^3.3.2", "randombytes": "^2.1.0", "sinon": "^17.0.1", "sinon-chai": "^3.7.0", @@ -158,11 +158,11 @@ "terser-webpack-plugin": "^5.3.10", "ts-node": "^10.9.2", "typescript": "^5.4.3", - "webpack": "^5.91.0", + "webpack": "^5.92.0", "webpack-cli": "^5.0.1" }, "dependencies": { - "@stellar/stellar-base": "^12.0.0", + "@stellar/stellar-base": "^12.0.1", "axios": "^1.7.2", "bignumber.js": "^9.1.2", "eventsource": "^2.0.2", diff --git a/yarn.lock b/yarn.lock index 4a4471495..58e74bbb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,10 +40,10 @@ typescript "5.3.3" validate-npm-package-name "^5.0.0" -"@babel/cli@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.24.6.tgz#fac1fb099dff635efa1110882063c44a211cf18c" - integrity sha512-Sm/YhG/0REw9SKByFHDf4hkk7PYsjcsOyZgHGz1nvab4tUTQ9N4XVv+ykK0Y+VCJ3OshA/7EDyxnwCd8NEP/mQ== +"@babel/cli@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.24.7.tgz#eb2868c1fa384b17ea88d60107577d3e6fd05c4e" + integrity sha512-8dfPprJgV4O14WTx+AQyEA+opgUKPrsIXX/MdL50J1n06EQJ6m1T+CdsJe0qEC0B/Xl85i+Un5KVAxd/PACX9A== dependencies: "@jridgewell/trace-mapping" "^0.3.25" commander "^6.2.0" @@ -56,103 +56,104 @@ "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.3" chokidar "^3.4.0" -"@babel/code-frame@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.6.tgz#ab88da19344445c3d8889af2216606d3329f3ef2" - integrity sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA== +"@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== dependencies: - "@babel/highlight" "^7.24.6" + "@babel/highlight" "^7.24.7" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.6.tgz#b3600217688cabb26e25f8e467019e66d71b7ae2" - integrity sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ== +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.7.tgz#d23bbea508c3883ba8251fb4164982c36ea577ed" + integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== -"@babel/core@^7.12.3", "@babel/core@^7.24.6", "@babel/core@^7.7.5": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.6.tgz#8650e0e4b03589ebe886c4e4a60398db0a7ec787" - integrity sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ== +"@babel/core@^7.12.3", "@babel/core@^7.24.7", "@babel/core@^7.7.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.7.tgz#b676450141e0b52a3d43bc91da86aa608f950ac4" + integrity sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.6" - "@babel/generator" "^7.24.6" - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helpers" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/template" "^7.24.6" - "@babel/traverse" "^7.24.6" - "@babel/types" "^7.24.6" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helpers" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/template" "^7.24.7" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-plugin@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.24.6.tgz#6e9e59653b7fec1047cae3ab82223c50aa810df8" - integrity sha512-sUDNpeOID2Am4cBXEmyhRaSvwwXIHVaG7trk7HO1Ri5VrEIBPYXg4ulTvZm2Lo0Y7u7Tw8QLe6JygchdOOto6w== +"@babel/eslint-plugin@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.24.7.tgz#ebdab31638cdcc720f0c788813066e9b5c0b3e29" + integrity sha512-lODNPJnM+OfcxxBvdmI2YmUeC0fBK3k9yET5O+1Eukr8d5VpO19c6ARtNheE2t2i/8XNYTzp3HeGEAAGZH3nnQ== dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.6.tgz#dfac82a228582a9d30c959fe50ad28951d4737a7" - integrity sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg== +"@babel/generator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" + integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== dependencies: - "@babel/types" "^7.24.6" + "@babel/types" "^7.24.7" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz#517af93abc77924f9b2514c407bbef527fb8938d" - integrity sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg== +"@babel/helper-annotate-as-pure@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== dependencies: - "@babel/types" "^7.24.6" + "@babel/types" "^7.24.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz#19e9089ee87b0d0928012c83961a8deef4b0223f" - integrity sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" + integrity sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA== dependencies: - "@babel/types" "^7.24.6" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz#4a51d681f7680043d38e212715e2a7b1ad29cb51" - integrity sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg== +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz#4eb6c4a80d6ffeac25ab8cd9a21b5dfa48d503a9" + integrity sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg== dependencies: - "@babel/compat-data" "^7.24.6" - "@babel/helper-validator-option" "^7.24.6" + "@babel/compat-data" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" browserslist "^4.22.2" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz#c50b86fa1c4ca9b7a890dc21884f097b6c4b5286" - integrity sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-function-name" "^7.24.6" - "@babel/helper-member-expression-to-functions" "^7.24.6" - "@babel/helper-optimise-call-expression" "^7.24.6" - "@babel/helper-replace-supers" "^7.24.6" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" +"@babel/helper-create-class-features-plugin@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz#2eaed36b3a1c11c53bdf80d53838b293c52f5b3b" + integrity sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz#47d382dec0d49e74ca1b6f7f3b81f5968022a3c8" - integrity sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz#be4f435a80dc2b053c76eeb4b7d16dd22cfc89da" + integrity sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" + "@babel/helper-annotate-as-pure" "^7.24.7" regexpu-core "^5.3.1" semver "^6.3.1" @@ -167,180 +168,187 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz#ac7ad5517821641550f6698dd5468f8cef78620d" - integrity sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g== - -"@babel/helper-function-name@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz#cebdd063386fdb95d511d84b117e51fc68fec0c8" - integrity sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w== - dependencies: - "@babel/template" "^7.24.6" - "@babel/types" "^7.24.6" - -"@babel/helper-hoist-variables@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz#8a7ece8c26756826b6ffcdd0e3cf65de275af7f9" - integrity sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA== +"@babel/helper-environment-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== dependencies: - "@babel/types" "^7.24.6" + "@babel/types" "^7.24.7" -"@babel/helper-member-expression-to-functions@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz#86084f3e0e4e2169a134754df3870bc7784db71e" - integrity sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg== +"@babel/helper-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== dependencies: - "@babel/types" "^7.24.6" + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-hoist-variables@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== + dependencies: + "@babel/types" "^7.24.7" -"@babel/helper-module-imports@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz#65e54ffceed6a268dc4ce11f0433b82cfff57852" - integrity sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-module-transforms@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz#22346ed9df44ce84dee850d7433c5b73fab1fe4e" - integrity sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA== - dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-module-imports" "^7.24.6" - "@babel/helper-simple-access" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" - "@babel/helper-validator-identifier" "^7.24.6" - -"@babel/helper-optimise-call-expression@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz#f7836e3ccca3dfa02f15d2bc8b794efe75a5256e" - integrity sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz#fa02a32410a15a6e8f8185bcbf608f10528d2a24" - integrity sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg== - -"@babel/helper-remap-async-to-generator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz#c96ceb9846e877d806ce82a1521230ea7e0fc354" - integrity sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-wrap-function" "^7.24.6" - -"@babel/helper-replace-supers@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz#3ea87405a2986a49ab052d10e540fe036d747c71" - integrity sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ== - dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-member-expression-to-functions" "^7.24.6" - "@babel/helper-optimise-call-expression" "^7.24.6" - -"@babel/helper-simple-access@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz#1d6e04d468bba4fc963b4906f6dac6286cfedff1" - integrity sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-skip-transparent-expression-wrappers@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz#c47e9b33b7ea50d1073e125ebc26661717cb7040" - integrity sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-split-export-declaration@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz#e830068f7ba8861c53b7421c284da30ae656d7a3" - integrity sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-string-parser@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz#28583c28b15f2a3339cfafafeaad42f9a0e828df" - integrity sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q== - -"@babel/helper-validator-identifier@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz#08bb6612b11bdec78f3feed3db196da682454a5e" - integrity sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw== - -"@babel/helper-validator-option@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz#59d8e81c40b7d9109ab7e74457393442177f460a" - integrity sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ== - -"@babel/helper-wrap-function@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz#c27af1006e310683fdc76b668a0a1f6003e36217" - integrity sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ== - dependencies: - "@babel/helper-function-name" "^7.24.6" - "@babel/template" "^7.24.6" - "@babel/types" "^7.24.6" - -"@babel/helpers@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.6.tgz#cd124245299e494bd4e00edda0e4ea3545c2c176" - integrity sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA== - dependencies: - "@babel/template" "^7.24.6" - "@babel/types" "^7.24.6" - -"@babel/highlight@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.6.tgz#6d610c1ebd2c6e061cade0153bf69b0590b7b3df" - integrity sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ== - dependencies: - "@babel/helper-validator-identifier" "^7.24.6" +"@babel/helper-member-expression-to-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz#67613d068615a70e4ed5101099affc7a41c5225f" + integrity sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-transforms@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz#31b6c9a2930679498db65b685b1698bfd6c7daf8" + integrity sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + +"@babel/helper-optimise-call-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" + integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0" + integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== + +"@babel/helper-remap-async-to-generator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz#b3f0f203628522713849d49403f1a414468be4c7" + integrity sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-wrap-function" "^7.24.7" + +"@babel/helper-replace-supers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz#f933b7eed81a1c0265740edc91491ce51250f765" + integrity sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" + integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-split-export-declaration@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" + integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-option@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6" + integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw== + +"@babel/helper-wrap-function@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz#52d893af7e42edca7c6d2c6764549826336aae1f" + integrity sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw== + dependencies: + "@babel/helper-function-name" "^7.24.7" + "@babel/template" "^7.24.7" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helpers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.7.tgz#aa2ccda29f62185acb5d42fb4a3a1b1082107416" + integrity sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg== + dependencies: + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" chalk "^2.4.2" js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.6.tgz#5e030f440c3c6c78d195528c3b688b101a365328" - integrity sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q== +"@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" + integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.6.tgz#283a74ef365b1e954cda6b2724c678a978215e88" - integrity sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz#fd059fd27b184ea2b4c7e646868a9a381bbc3055" + integrity sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ== dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.6.tgz#f9f5ae4d6fb72f5950262cb6f0b2482c3bc684ef" - integrity sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz#468096ca44bbcbe8fcc570574e12eb1950e18107" + integrity sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.6.tgz#ab9be6edfffa127bd5ec4317c76c5af0f8fc7e6c" - integrity sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz#e4eabdd5109acc399b38d7999b2ef66fc2022f89" + integrity sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.6" - "@babel/plugin-transform-optional-chaining" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.7" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.6.tgz#0faf879249ec622d7f1c42eaebf7d11197401b2c" - integrity sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz#71b21bb0286d5810e63a1538aa901c58e87375ec" + integrity sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg== dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" @@ -382,19 +390,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz#52521c1c1698fc2dd9cf88f7a4dd86d4d041b9e1" - integrity sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg== +"@babel/plugin-syntax-import-assertions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz#2a0b406b5871a20a841240586b1300ce2088a778" + integrity sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-syntax-import-attributes@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz#12aba325534129584672920274fefa4dc2d5f68e" - integrity sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ== +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz#b4f9ea95a79e6912480c4b626739f86a076624ca" + integrity sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" @@ -410,12 +418,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz#bcca2964150437f88f65e3679e3d68762287b9c8" - integrity sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw== +"@babel/plugin-syntax-jsx@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" + integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" @@ -473,12 +481,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.6.tgz#769daf2982d60308bc83d8936eaecb7582463c87" - integrity sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A== +"@babel/plugin-syntax-typescript@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz#58d458271b4d3b6bb27ee6ac9525acbb259bad1c" + integrity sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -488,424 +496,424 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz#93607d1ef5b81c70af174aff3532d57216367492" - integrity sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ== +"@babel/plugin-transform-arrow-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz#4f6886c11e423bd69f3ce51dbf42424a5f275514" + integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-async-generator-functions@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.6.tgz#fa4a9e5c3a7f60f697ba36587b6c41b04f507d84" - integrity sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA== +"@babel/plugin-transform-async-generator-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz#7330a5c50e05181ca52351b8fd01642000c96cfd" + integrity sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g== dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-remap-async-to-generator" "^7.24.6" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-remap-async-to-generator" "^7.24.7" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-async-to-generator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.6.tgz#eb11434b11d73d8c0cf9f71a6f4f1e6ba441df35" - integrity sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g== +"@babel/plugin-transform-async-to-generator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz#72a3af6c451d575842a7e9b5a02863414355bdcc" + integrity sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA== dependencies: - "@babel/helper-module-imports" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-remap-async-to-generator" "^7.24.6" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-remap-async-to-generator" "^7.24.7" -"@babel/plugin-transform-block-scoped-functions@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz#975555b5bfa9870b1218da536d1528735f1f8c56" - integrity sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw== +"@babel/plugin-transform-block-scoped-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz#a4251d98ea0c0f399dafe1a35801eaba455bbf1f" + integrity sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-block-scoping@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz#a03ec8a4591c2b43cf7798bc633e698293fda179" - integrity sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w== +"@babel/plugin-transform-block-scoping@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz#42063e4deb850c7bd7c55e626bf4e7ab48e6ce02" + integrity sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-class-properties@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz#d9f394e97e88ef905d5a1e5e7a16238621b7982e" - integrity sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A== +"@babel/plugin-transform-class-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz#256879467b57b0b68c7ddfc5b76584f398cd6834" + integrity sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-class-static-block@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz#f43f29286f6f0dca33d18fd5033b817d6c3fa816" - integrity sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA== +"@babel/plugin-transform-class-static-block@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz#c82027ebb7010bc33c116d4b5044fbbf8c05484d" + integrity sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz#0cc198c02720d4eeb091004843477659c6b37977" - integrity sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-function-name" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-replace-supers" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" +"@babel/plugin-transform-classes@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz#4ae6ef43a12492134138c1e45913f7c46c41b4bf" + integrity sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz#7a1765c01cdfe59c320d2d0f37a4dc4aecd14df1" - integrity sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg== +"@babel/plugin-transform-computed-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz#4cab3214e80bc71fae3853238d13d097b004c707" + integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/template" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/template" "^7.24.7" -"@babel/plugin-transform-destructuring@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz#bdd1a6c90ffb2bfd13b6007b13316eeafc97cb53" - integrity sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ== +"@babel/plugin-transform-destructuring@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz#a097f25292defb6e6cc16d6333a4cfc1e3c72d9e" + integrity sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-dotall-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz#5a6b3148ec5f4f274ff48cebea90565087cad126" - integrity sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA== +"@babel/plugin-transform-dotall-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz#5f8bf8a680f2116a7207e16288a5f974ad47a7a0" + integrity sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-duplicate-keys@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz#2716301227cf7cd4fdadcbe4353ce191f8b3dc8a" - integrity sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA== +"@babel/plugin-transform-duplicate-keys@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz#dd20102897c9a2324e5adfffb67ff3610359a8ee" + integrity sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-dynamic-import@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz#b477177761d56b15a4ba42a83be31cf72d757acf" - integrity sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w== +"@babel/plugin-transform-dynamic-import@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz#4d8b95e3bae2b037673091aa09cd33fecd6419f4" + integrity sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz#011e9e1a429f91b024af572530873ca571f9ef06" - integrity sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA== +"@babel/plugin-transform-exponentiation-operator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz#b629ee22645f412024297d5245bce425c31f9b0d" + integrity sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-export-namespace-from@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz#b64ded74d9afb3db5d47d93996c4df69f15ac97c" - integrity sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA== +"@babel/plugin-transform-export-namespace-from@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz#176d52d8d8ed516aeae7013ee9556d540c53f197" + integrity sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-for-of@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz#7f31780bd0c582b546372c0c0da9d9d56731e0a2" - integrity sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg== +"@babel/plugin-transform-for-of@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" + integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" -"@babel/plugin-transform-function-name@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz#60d1de3f6fd816a3e3bf9538578a64527e1b9c97" - integrity sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q== +"@babel/plugin-transform-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz#6d8601fbffe665c894440ab4470bc721dd9131d6" + integrity sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w== dependencies: - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-function-name" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-json-strings@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz#a84639180ea1f9001bb5e6dc01921235ab05ad8b" - integrity sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w== +"@babel/plugin-transform-json-strings@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz#f3e9c37c0a373fee86e36880d45b3664cedaf73a" + integrity sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-literals@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz#7f44f2871d7a4456030b0540858046f0b7bc6b18" - integrity sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw== +"@babel/plugin-transform-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz#36b505c1e655151a9d7607799a9988fc5467d06c" + integrity sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-logical-assignment-operators@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz#9cc7baa5629866566562c159dc1eae7569810f33" - integrity sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA== +"@babel/plugin-transform-logical-assignment-operators@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" + integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz#5d3681ca201ac6909419cc51ac082a6ba4c5c756" - integrity sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ== +"@babel/plugin-transform-member-expression-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz#3b4454fb0e302e18ba4945ba3246acb1248315df" + integrity sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-modules-amd@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz#09aeac7acb7913496aaaafdc64f40683e0db7e41" - integrity sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ== +"@babel/plugin-transform-modules-amd@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz#65090ed493c4a834976a3ca1cde776e6ccff32d7" + integrity sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg== dependencies: - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-modules-commonjs@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz#1b8269902f25bd91ca6427230d4735ddd1e1283e" - integrity sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw== +"@babel/plugin-transform-modules-commonjs@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz#9fd5f7fdadee9085886b183f1ad13d1ab260f4ab" + integrity sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ== dependencies: - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-simple-access" "^7.24.6" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" -"@babel/plugin-transform-modules-systemjs@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz#c54eb53fe16f9b82d320abd76762d0320e3f9393" - integrity sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w== +"@babel/plugin-transform-modules-systemjs@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz#f8012316c5098f6e8dee6ecd58e2bc6f003d0ce7" + integrity sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw== dependencies: - "@babel/helper-hoist-variables" "^7.24.6" - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-validator-identifier" "^7.24.6" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" -"@babel/plugin-transform-modules-umd@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz#c4ef8b6d4da230b8dc87e81cd66986728952f89b" - integrity sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg== +"@babel/plugin-transform-modules-umd@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz#edd9f43ec549099620df7df24e7ba13b5c76efc8" + integrity sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A== dependencies: - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz#352ee2861ab8705320029f80238cf26a92ba65d5" - integrity sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q== +"@babel/plugin-transform-named-capturing-groups-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz#9042e9b856bc6b3688c0c2e4060e9e10b1460923" + integrity sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-new-target@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz#fc024294714705113720d5e3dc0f9ad7abdbc289" - integrity sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA== +"@babel/plugin-transform-new-target@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz#31ff54c4e0555cc549d5816e4ab39241dfb6ab00" + integrity sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-nullish-coalescing-operator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz#12b83b3cdfd1cd2066350e36e4fb912ab194545e" - integrity sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A== +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" + integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz#d9115669cc85aa91fbfb15f88f2226332cf4946a" - integrity sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q== +"@babel/plugin-transform-numeric-separator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" + integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz#68d763f69955f9e599c405c6c876f5be46b47d8a" - integrity sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg== +"@babel/plugin-transform-object-rest-spread@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" + integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== dependencies: - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.24.6" + "@babel/plugin-transform-parameters" "^7.24.7" -"@babel/plugin-transform-object-super@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz#9cbe6f995bed343a7ab8daf0416dac057a9c3e27" - integrity sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg== +"@babel/plugin-transform-object-super@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz#66eeaff7830bba945dd8989b632a40c04ed625be" + integrity sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-replace-supers" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" -"@babel/plugin-transform-optional-catch-binding@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz#c81e90a971aad898e56f2b75a358e6c4855aeba3" - integrity sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w== +"@babel/plugin-transform-optional-catch-binding@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" + integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz#3d636b3ed8b5a506f93e4d4675fc95754d7594f5" - integrity sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ== +"@babel/plugin-transform-optional-chaining@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz#b8f6848a80cf2da98a8a204429bec04756c6d454" + integrity sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz#7aee86dfedd2fc0136fecbe6f7649fc02d86ab22" - integrity sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA== +"@babel/plugin-transform-parameters@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" + integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-private-methods@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz#258e1f859a52ff7b30ad556598224c192defcda7" - integrity sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw== +"@babel/plugin-transform-private-methods@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz#e6318746b2ae70a59d023d5cc1344a2ba7a75f5e" + integrity sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-private-property-in-object@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz#59ff09a099f62213112cf348e96b6b11957d1f28" - integrity sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ== +"@babel/plugin-transform-private-property-in-object@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz#4eec6bc701288c1fab5f72e6a4bbc9d67faca061" + integrity sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" - "@babel/helper-create-class-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz#243c4faabe811c405e9443059a58e834bf95dfd1" - integrity sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw== +"@babel/plugin-transform-property-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz#f0d2ed8380dfbed949c42d4d790266525d63bbdc" + integrity sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-regenerator@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz#ed10cf0c13619365e15459f88d1b915ac57ffc24" - integrity sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg== +"@babel/plugin-transform-regenerator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" + integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz#9eb16cbf339fcea0a46677716c775afb5ef14245" - integrity sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A== +"@babel/plugin-transform-reserved-words@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz#80037fe4fbf031fc1125022178ff3938bb3743a4" + integrity sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-shorthand-properties@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz#ef734ebccc428d2174c7bb36015d0800faf5381e" - integrity sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw== +"@babel/plugin-transform-shorthand-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz#85448c6b996e122fa9e289746140aaa99da64e73" + integrity sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-spread@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz#a56cecbd8617675531d1b79f5b755b7613aa0822" - integrity sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA== +"@babel/plugin-transform-spread@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz#e8a38c0fde7882e0fb8f160378f74bd885cc7bb3" + integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" -"@babel/plugin-transform-sticky-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz#1a78127731fea87d954bed193840986a38f04327" - integrity sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw== +"@babel/plugin-transform-sticky-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz#96ae80d7a7e5251f657b5cf18f1ea6bf926f5feb" + integrity sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-template-literals@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz#aaf2ae157acd0e5c9265dba8ac0a439f8d2a6303" - integrity sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg== +"@babel/plugin-transform-template-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz#a05debb4a9072ae8f985bcf77f3f215434c8f8c8" + integrity sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-typeof-symbol@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz#3d02da23ebcc8f1982ddcd1f2581cf3ee4e58762" - integrity sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig== +"@babel/plugin-transform-typeof-symbol@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz#f074be466580d47d6e6b27473a840c9f9ca08fb0" + integrity sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-typescript@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.6.tgz#339c6127a783c32e28a5b591e6c666f899b57db0" - integrity sha512-H0i+hDLmaYYSt6KU9cZE0gb3Cbssa/oxWis7PX4ofQzbvsfix9Lbh8SRk7LCPDlLWJHUiFeHU0qRRpF/4Zv7mQ== +"@babel/plugin-transform-typescript@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz#b006b3e0094bf0813d505e0c5485679eeaf4a881" + integrity sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.6" - "@babel/helper-create-class-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/plugin-syntax-typescript" "^7.24.6" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-typescript" "^7.24.7" -"@babel/plugin-transform-unicode-escapes@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz#c8ddca8fd5bacece837a4e27bd3b7ed64580d1a8" - integrity sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw== +"@babel/plugin-transform-unicode-escapes@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz#2023a82ced1fb4971630a2e079764502c4148e0e" + integrity sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-unicode-property-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz#e66297d5d452db0b0be56515e3d0e10b7d33fb32" - integrity sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA== +"@babel/plugin-transform-unicode-property-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz#9073a4cd13b86ea71c3264659590ac086605bbcd" + integrity sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-unicode-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz#2001e7d87ed709eea145e0b65fb5f93c3c0e225b" - integrity sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA== +"@babel/plugin-transform-unicode-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz#dfc3d4a51127108099b19817c0963be6a2adf19f" + integrity sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-unicode-sets-regex@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz#f18b7292222aee85c155258ceb345a146a070a46" - integrity sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw== +"@babel/plugin-transform-unicode-sets-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz#d40705d67523803a576e29c63cef6e516b858ed9" + integrity sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/preset-env@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.6.tgz#a5a55bc70e5ff1ed7f872067e2a9d65ff917ad6f" - integrity sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg== - dependencies: - "@babel/compat-data" "^7.24.6" - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-validator-option" "^7.24.6" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.6" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.6" +"@babel/preset-env@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.7.tgz#ff067b4e30ba4a72f225f12f123173e77b987f37" + integrity sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ== + dependencies: + "@babel/compat-data" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.7" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.24.6" - "@babel/plugin-syntax-import-attributes" "^7.24.6" + "@babel/plugin-syntax-import-assertions" "^7.24.7" + "@babel/plugin-syntax-import-attributes" "^7.24.7" "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" @@ -917,54 +925,54 @@ "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.24.6" - "@babel/plugin-transform-async-generator-functions" "^7.24.6" - "@babel/plugin-transform-async-to-generator" "^7.24.6" - "@babel/plugin-transform-block-scoped-functions" "^7.24.6" - "@babel/plugin-transform-block-scoping" "^7.24.6" - "@babel/plugin-transform-class-properties" "^7.24.6" - "@babel/plugin-transform-class-static-block" "^7.24.6" - "@babel/plugin-transform-classes" "^7.24.6" - "@babel/plugin-transform-computed-properties" "^7.24.6" - "@babel/plugin-transform-destructuring" "^7.24.6" - "@babel/plugin-transform-dotall-regex" "^7.24.6" - "@babel/plugin-transform-duplicate-keys" "^7.24.6" - "@babel/plugin-transform-dynamic-import" "^7.24.6" - "@babel/plugin-transform-exponentiation-operator" "^7.24.6" - "@babel/plugin-transform-export-namespace-from" "^7.24.6" - "@babel/plugin-transform-for-of" "^7.24.6" - "@babel/plugin-transform-function-name" "^7.24.6" - "@babel/plugin-transform-json-strings" "^7.24.6" - "@babel/plugin-transform-literals" "^7.24.6" - "@babel/plugin-transform-logical-assignment-operators" "^7.24.6" - "@babel/plugin-transform-member-expression-literals" "^7.24.6" - "@babel/plugin-transform-modules-amd" "^7.24.6" - "@babel/plugin-transform-modules-commonjs" "^7.24.6" - "@babel/plugin-transform-modules-systemjs" "^7.24.6" - "@babel/plugin-transform-modules-umd" "^7.24.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.6" - "@babel/plugin-transform-new-target" "^7.24.6" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.6" - "@babel/plugin-transform-numeric-separator" "^7.24.6" - "@babel/plugin-transform-object-rest-spread" "^7.24.6" - "@babel/plugin-transform-object-super" "^7.24.6" - "@babel/plugin-transform-optional-catch-binding" "^7.24.6" - "@babel/plugin-transform-optional-chaining" "^7.24.6" - "@babel/plugin-transform-parameters" "^7.24.6" - "@babel/plugin-transform-private-methods" "^7.24.6" - "@babel/plugin-transform-private-property-in-object" "^7.24.6" - "@babel/plugin-transform-property-literals" "^7.24.6" - "@babel/plugin-transform-regenerator" "^7.24.6" - "@babel/plugin-transform-reserved-words" "^7.24.6" - "@babel/plugin-transform-shorthand-properties" "^7.24.6" - "@babel/plugin-transform-spread" "^7.24.6" - "@babel/plugin-transform-sticky-regex" "^7.24.6" - "@babel/plugin-transform-template-literals" "^7.24.6" - "@babel/plugin-transform-typeof-symbol" "^7.24.6" - "@babel/plugin-transform-unicode-escapes" "^7.24.6" - "@babel/plugin-transform-unicode-property-regex" "^7.24.6" - "@babel/plugin-transform-unicode-regex" "^7.24.6" - "@babel/plugin-transform-unicode-sets-regex" "^7.24.6" + "@babel/plugin-transform-arrow-functions" "^7.24.7" + "@babel/plugin-transform-async-generator-functions" "^7.24.7" + "@babel/plugin-transform-async-to-generator" "^7.24.7" + "@babel/plugin-transform-block-scoped-functions" "^7.24.7" + "@babel/plugin-transform-block-scoping" "^7.24.7" + "@babel/plugin-transform-class-properties" "^7.24.7" + "@babel/plugin-transform-class-static-block" "^7.24.7" + "@babel/plugin-transform-classes" "^7.24.7" + "@babel/plugin-transform-computed-properties" "^7.24.7" + "@babel/plugin-transform-destructuring" "^7.24.7" + "@babel/plugin-transform-dotall-regex" "^7.24.7" + "@babel/plugin-transform-duplicate-keys" "^7.24.7" + "@babel/plugin-transform-dynamic-import" "^7.24.7" + "@babel/plugin-transform-exponentiation-operator" "^7.24.7" + "@babel/plugin-transform-export-namespace-from" "^7.24.7" + "@babel/plugin-transform-for-of" "^7.24.7" + "@babel/plugin-transform-function-name" "^7.24.7" + "@babel/plugin-transform-json-strings" "^7.24.7" + "@babel/plugin-transform-literals" "^7.24.7" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" + "@babel/plugin-transform-member-expression-literals" "^7.24.7" + "@babel/plugin-transform-modules-amd" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.7" + "@babel/plugin-transform-modules-systemjs" "^7.24.7" + "@babel/plugin-transform-modules-umd" "^7.24.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" + "@babel/plugin-transform-new-target" "^7.24.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" + "@babel/plugin-transform-numeric-separator" "^7.24.7" + "@babel/plugin-transform-object-rest-spread" "^7.24.7" + "@babel/plugin-transform-object-super" "^7.24.7" + "@babel/plugin-transform-optional-catch-binding" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.7" + "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/plugin-transform-private-methods" "^7.24.7" + "@babel/plugin-transform-private-property-in-object" "^7.24.7" + "@babel/plugin-transform-property-literals" "^7.24.7" + "@babel/plugin-transform-regenerator" "^7.24.7" + "@babel/plugin-transform-reserved-words" "^7.24.7" + "@babel/plugin-transform-shorthand-properties" "^7.24.7" + "@babel/plugin-transform-spread" "^7.24.7" + "@babel/plugin-transform-sticky-regex" "^7.24.7" + "@babel/plugin-transform-template-literals" "^7.24.7" + "@babel/plugin-transform-typeof-symbol" "^7.24.7" + "@babel/plugin-transform-unicode-escapes" "^7.24.7" + "@babel/plugin-transform-unicode-property-regex" "^7.24.7" + "@babel/plugin-transform-unicode-regex" "^7.24.7" + "@babel/plugin-transform-unicode-sets-regex" "^7.24.7" "@babel/preset-modules" "0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2 "^0.4.10" babel-plugin-polyfill-corejs3 "^0.10.4" @@ -981,16 +989,16 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.6.tgz#27057470fb981c31338bdb897fc3d9aa0cb7dab2" - integrity sha512-U10aHPDnokCFRXgyT/MaIRTivUu2K/mu0vJlwRS9LxJmJet+PFQNKpggPyFCUtC6zWSBPjvxjnpNkAn3Uw2m5w== +"@babel/preset-typescript@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz#66cd86ea8f8c014855671d5ea9a737139cbbfef1" + integrity sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" - "@babel/helper-validator-option" "^7.24.6" - "@babel/plugin-syntax-jsx" "^7.24.6" - "@babel/plugin-transform-modules-commonjs" "^7.24.6" - "@babel/plugin-transform-typescript" "^7.24.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" + "@babel/plugin-syntax-jsx" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.7" + "@babel/plugin-transform-typescript" "^7.24.7" "@babel/register@^7.24.6": version "7.24.6" @@ -1009,44 +1017,44 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.8.4": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e" - integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" + integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.6.tgz#048c347b2787a6072b24c723664c8d02b67a44f9" - integrity sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw== - dependencies: - "@babel/code-frame" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/types" "^7.24.6" - -"@babel/traverse@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.6.tgz#0941ec50cdeaeacad0911eb67ae227a4f8424edc" - integrity sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw== - dependencies: - "@babel/code-frame" "^7.24.6" - "@babel/generator" "^7.24.6" - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-function-name" "^7.24.6" - "@babel/helper-hoist-variables" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/types" "^7.24.6" +"@babel/template@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" + integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/traverse@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" + integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.24.6", "@babel/types@^7.4.4": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.6.tgz#ba4e1f59870c10dc2fa95a274ac4feec23b21912" - integrity sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ== +"@babel/types@^7.24.7", "@babel/types@^7.4.4": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" + integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== dependencies: - "@babel/helper-string-parser" "^7.24.6" - "@babel/helper-validator-identifier" "^7.24.6" + "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" "@colors/colors@1.5.0": @@ -1151,9 +1159,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + version "4.10.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.1.tgz#361461e5cb3845d874e61731c11cfedd664d83a0" + integrity sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1394,10 +1402,10 @@ resolved "https://registry.yarnpkg.com/@stellar/js-xdr/-/js-xdr-3.1.1.tgz#be0ff90c8a861d6e1101bca130fa20e74d5599bb" integrity sha512-3gnPjAz78htgqsNEDkEsKHKosV2BF2iZkoHCNxpmZwUxiPsw+2VaXMed8RRMe0rGk3d5GZe7RrSba8zV80J3Ag== -"@stellar/stellar-base@^12.0.0": - version "12.0.0" - resolved "https://registry.yarnpkg.com/@stellar/stellar-base/-/stellar-base-12.0.0.tgz#d46e2a45b756c3e5b4b8f82f224fcc467dac3ade" - integrity sha512-uGpahDFFXbE39myOmBnEZSjVys4yUkQ/ASNuYENGyS8MNdfA0TS7DPWkiO6t17P+rW+FRV1zmumJtjRHwxxMdw== +"@stellar/stellar-base@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@stellar/stellar-base/-/stellar-base-12.0.1.tgz#3fae34e8f787eb47cc7f58a0dea014e7b70724a7" + integrity sha512-g6c27MNsDgEdUmoNQJn7zCWoCY50WHt0OIIOq3PhWaJRtUaT++qs1Jpb8+1bny2GmhtfRGOfPUFSyQBuHT9Mvg== dependencies: "@stellar/js-xdr" "^3.1.1" base32.js "^0.1.0" @@ -1520,10 +1528,10 @@ resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== -"@types/lodash@^4.17.4": - version "4.17.4" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.4.tgz#0303b64958ee070059e3a7184048a55159fe20b7" - integrity sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ== +"@types/lodash@^4.17.5": + version "4.17.5" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.5.tgz#e6c29b58e66995d57cd170ce3e2a61926d55ee04" + integrity sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw== "@types/markdown-it@^14.1.1": version "14.1.1" @@ -1543,17 +1551,17 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== -"@types/node@*", "@types/node@>=10.0.0", "@types/node@^20.12.13": - version "20.12.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.13.tgz#90ed3b8a4e52dd3c5dc5a42dde5b85b74ad8ed88" - integrity sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA== +"@types/node@*", "@types/node@>=10.0.0", "@types/node@^20.14.2": + version "20.14.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" + integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== dependencies: undici-types "~5.26.4" "@types/node@^18.19.7": - version "18.19.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.33.tgz#98cd286a1b8a5e11aa06623210240bcc28e95c48" - integrity sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A== + version "18.19.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.34.tgz#c3fae2bbbdb94b4a52fe2d229d0dccce02ef3d27" + integrity sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g== dependencies: undici-types "~5.26.4" @@ -1634,15 +1642,15 @@ "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" -"@typescript-eslint/parser@^7.7.1": - version "7.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.12.0.tgz#8761df3345528b35049353db80010b385719b1c3" - integrity sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ== +"@typescript-eslint/parser@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.13.0.tgz#9489098d68d57ad392f507495f2b82ce8b8f0a6b" + integrity sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA== dependencies: - "@typescript-eslint/scope-manager" "7.12.0" - "@typescript-eslint/types" "7.12.0" - "@typescript-eslint/typescript-estree" "7.12.0" - "@typescript-eslint/visitor-keys" "7.12.0" + "@typescript-eslint/scope-manager" "7.13.0" + "@typescript-eslint/types" "7.13.0" + "@typescript-eslint/typescript-estree" "7.13.0" + "@typescript-eslint/visitor-keys" "7.13.0" debug "^4.3.4" "@typescript-eslint/scope-manager@6.21.0": @@ -1653,13 +1661,13 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/scope-manager@7.12.0": - version "7.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz#259c014362de72dd34f995efe6bd8dda486adf58" - integrity sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg== +"@typescript-eslint/scope-manager@7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz#6927d6451537ce648c6af67a2327378d4cc18462" + integrity sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng== dependencies: - "@typescript-eslint/types" "7.12.0" - "@typescript-eslint/visitor-keys" "7.12.0" + "@typescript-eslint/types" "7.13.0" + "@typescript-eslint/visitor-keys" "7.13.0" "@typescript-eslint/type-utils@6.21.0": version "6.21.0" @@ -1676,15 +1684,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/types@7.12.0": - version "7.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.12.0.tgz#bf208f971a8da1e7524a5d9ae2b5f15192a37981" - integrity sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg== - -"@typescript-eslint/types@^7.2.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.11.0.tgz#5e9702a5e8b424b7fc690e338d359939257d6722" - integrity sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w== +"@typescript-eslint/types@7.13.0", "@typescript-eslint/types@^7.2.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.13.0.tgz#0cca95edf1f1fdb0cfe1bb875e121b49617477c5" + integrity sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA== "@typescript-eslint/typescript-estree@6.21.0", "@typescript-eslint/typescript-estree@^6.19.0": version "6.21.0" @@ -1700,13 +1703,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.12.0": - version "7.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz#e6c1074f248b3db6573ab6a7c47a39c4cd498ff9" - integrity sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ== +"@typescript-eslint/typescript-estree@7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz#4cc24fc155088ebf3b3adbad62c7e60f72c6de1c" + integrity sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw== dependencies: - "@typescript-eslint/types" "7.12.0" - "@typescript-eslint/visitor-keys" "7.12.0" + "@typescript-eslint/types" "7.13.0" + "@typescript-eslint/visitor-keys" "7.13.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1735,12 +1738,12 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@7.12.0": - version "7.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz#c053b55a996679528beeedd8e565710ce1ae1ad3" - integrity sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ== +"@typescript-eslint/visitor-keys@7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz#2eb7ce8eb38c2b0d4a494d1fe1908e7071a1a353" + integrity sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw== dependencies: - "@typescript-eslint/types" "7.12.0" + "@typescript-eslint/types" "7.13.0" eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": @@ -1909,10 +1912,10 @@ accepts@~1.3.4: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn-jsx@^5.3.2: version "5.3.2" @@ -1920,14 +1923,16 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" - integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + version "8.3.3" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.3.tgz#9caeac29eefaa0c41e3d4c65137de4d6f34df43e" + integrity sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw== + dependencies: + acorn "^8.11.0" -acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.11.0, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.0.tgz#1627bfa2e058148036133b8d9b51a700663c294c" + integrity sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw== aggregate-error@^3.0.0: version "3.1.0" @@ -1967,9 +1972,9 @@ ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: uri-js "^4.2.2" ajv@^8.0.0, ajv@^8.9.0: - version "8.14.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.14.0.tgz#f514ddfd4756abb200e1704414963620a625ebbb" - integrity sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA== + version "8.16.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.16.0.tgz#22e2a92b94f005f7e0f9c9d39652ef0b8f6f0cb4" + integrity sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw== dependencies: fast-deep-equal "^3.1.3" json-schema-traverse "^1.0.0" @@ -2286,9 +2291,9 @@ balanced-match@^1.0.0: integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== bare-events@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.3.1.tgz#5af2ee0be9578f81e3c1aa9bc3a6a2bcf22307ce" - integrity sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA== + version "2.4.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.4.2.tgz#3140cca7a0e11d49b3edc5041ab560659fd8e1f8" + integrity sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q== base32.js@^0.1.0: version "0.1.0" @@ -2450,14 +2455,14 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + version "4.23.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.1.tgz#ce4af0534b3d37db5c1a4ca98b9080f985041e96" + integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw== dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" + caniuse-lite "^1.0.30001629" + electron-to-chromium "^1.4.796" node-releases "^2.0.14" - update-browserslist-db "^1.0.13" + update-browserslist-db "^1.0.16" buffer-from@^1.0.0: version "1.1.2" @@ -2538,10 +2543,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001587: - version "1.0.30001625" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz#ead1b155ea691d6a87938754d3cb119c24465b03" - integrity sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w== +caniuse-lite@^1.0.30001629: + version "1.0.30001634" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz#aa563c8e7aeaf552f7ead60371bc8d803425deaa" + integrity sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA== caseless@~0.12.0: version "0.12.0" @@ -3069,7 +3074,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: +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== @@ -3083,6 +3088,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: + version "4.3.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3094,9 +3106,9 @@ decamelize@^4.0.0: integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-eql@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + version "4.1.4" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== dependencies: type-detect "^4.0.0" @@ -3249,10 +3261,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.668: - version "1.4.787" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.787.tgz#3eedd0a3b8be2b9e96e21675d399786ad90b99ed" - integrity sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ== +electron-to-chromium@^1.4.796: + version "1.4.802" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz#49b397eadc95a49b1ac33eebee146b8e5a93773f" + integrity sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA== elliptic@^6.5.3, elliptic@^6.5.5: version "6.5.5" @@ -3308,10 +3320,10 @@ engine.io@~6.5.2: engine.io-parser "~5.2.1" ws "~8.11.0" -enhanced-resolve@^5.16.0: - version "5.16.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz#e8bc63d51b826d6f1cbc0a150ecb5a8b0c62e567" - integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== +enhanced-resolve@^5.17.0: + version "5.17.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz#d037603789dd9555b89aaec7eb78845c49089bc5" + integrity sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3531,10 +3543,10 @@ eslint-plugin-import@^2.29.1: semver "^6.3.1" tsconfig-paths "^3.15.0" -eslint-plugin-jsdoc@^48.2.7: - version "48.2.7" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.7.tgz#2610b6fa1a9ba45c8296c2f335e0360bbd238772" - integrity sha512-fYj3roTnkFL9OFFTB129rico8lerC5G8Vp2ZW9SjO9RNWG0exVvI+i/Y8Bpm1ufjR0uvT38xtoab/U0Hp8Ybog== +eslint-plugin-jsdoc@^48.2.12: + version "48.2.12" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.12.tgz#e8411c87e55db3f21a288e04bf7e1fb5fa62dfa9" + integrity sha512-sO9sKkJx5ovWoRk9hV0YiNzXQ4Z6j27CqE/po2E3wddZVuy9wvKPSTiIhpxMTrP/qURvKayJIDB2+o9kyCW1Fw== dependencies: "@es-joy/jsdoccomment" "~0.43.1" are-docs-informative "^0.0.2" @@ -3779,7 +3791,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-fifo@^1.1.0, fast-fifo@^1.2.0: +fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== @@ -5131,9 +5143,9 @@ levn@^0.4.1: type-check "~0.4.0" lilconfig@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.1.tgz#9d8a246fa753106cfc205fd2d77042faca56e5e3" - integrity sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== linkify-it@^5.0.0: version "5.0.0" @@ -5142,10 +5154,10 @@ linkify-it@^5.0.0: dependencies: uc.micro "^2.0.0" -lint-staged@^15.2.5: - version "15.2.5" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.5.tgz#8c342f211bdb34ffd3efd1311248fa6b50b43b50" - integrity sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA== +lint-staged@^15.2.7: + version "15.2.7" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.7.tgz#97867e29ed632820c0fb90be06cd9ed384025649" + integrity sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw== dependencies: chalk "~5.3.0" commander "~12.1.0" @@ -6139,10 +6151,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^3.2.5: - version "3.2.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" - integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== +prettier@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.2.tgz#03ff86dc7c835f2d2559ee76876a3914cec4a90a" + integrity sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA== process-nextick-args@~2.0.0: version "2.0.1" @@ -6477,9 +6489,9 @@ reusify@^1.0.4: integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rfdc@^1.3.0, rfdc@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" - integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" @@ -6894,12 +6906,13 @@ streamroller@^3.1.5: fs-extra "^8.1.0" streamx@^2.15.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.17.0.tgz#c6332e55a79202a5abee274059d15e714af1342b" - integrity sha512-mzRXEeafEA0skX5XLiDht/zdIqEVs4kgayUTFHDoMjiaZ2kC7DoFsQDJVXRILI2Qme/kWXxLpuU6P0B+xcXpFA== + version "2.18.0" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.18.0.tgz#5bc1a51eb412a667ebfdcd4e6cf6a6fc65721ac7" + integrity sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ== dependencies: - fast-fifo "^1.1.0" + fast-fifo "^1.3.2" queue-tick "^1.0.1" + text-decoder "^1.1.0" optionalDependencies: bare-events "^2.2.0" @@ -7119,9 +7132,9 @@ terser-webpack-plugin@^5.3.10: terser "^5.26.0" terser@^5.26.0: - version "5.31.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.0.tgz#06eef86f17007dbad4593f11a574c7f5eb02c6a1" - integrity sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg== + version "5.31.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.1.tgz#735de3c987dd671e95190e6b98cfe2f07f3cf0d4" + integrity sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -7137,6 +7150,13 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-decoder@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.1.0.tgz#3379e728fcf4d3893ec1aea35e8c2cac215ef190" + integrity sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw== + dependencies: + b4a "^1.6.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7238,9 +7258,9 @@ tsconfig-paths@^3.15.0: strip-bom "^3.0.0" tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== tty-browserify@^0.0.1: version "0.0.1" @@ -7287,9 +7307,9 @@ type-fest@^0.8.0: integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== type-fest@^4.4.0: - version "4.18.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.18.3.tgz#5249f96e7c2c3f0f1561625f54050e343f1c8f68" - integrity sha512-Q08/0IrpvM+NMY9PA2rti9Jb+JejTddwmwmVQGskAlhtcrw1wsRzoR6ode6mR+OAabNa75w/dxedSUY2mlphaQ== + version "4.20.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.20.0.tgz#019becf5a97cd58eee93f592f0961859a74482a7" + integrity sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw== type-is@~1.6.18: version "1.6.18" @@ -7396,9 +7416,9 @@ typedarray@^0.0.6: integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== "typescript-5.5@npm:typescript@~5.5.0-0": - version "5.5.0-dev.20240530" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.0-dev.20240530.tgz#90a13ecaabb535086e036e910b8d0fa703bd579b" - integrity sha512-r/4r/a9tbtPRHfif0An0GLycB70C3ci3m9fhpgiv6Ekyl7mxYc4w8aX/R+vQ4OJlmPosJJUCjUbljH11g6C56g== + version "5.5.0-dev.20240603" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.0-dev.20240603.tgz#a1b7311df5039a8abbaaa2213c21cac6ec547490" + integrity sha512-gdm3Sh1A+Pjj9ZlfBEJY3o2rs3tvpcSbu3vYqcCijMe09BePQBtZlsuShuPn+zCnP+qBLxdKjFiw5v1tkna3tA== typescript@5.3.3: version "5.3.3" @@ -7478,7 +7498,7 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.0.13: +update-browserslist-db@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz#f6d489ed90fb2f07d67784eb3f53d7891f736356" integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ== @@ -7634,10 +7654,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.91.0: - version "5.91.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.91.0.tgz#ffa92c1c618d18c878f06892bbdc3373c71a01d9" - integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw== +webpack@^5.92.0: + version "5.92.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.92.0.tgz#cc114c71e6851d220b1feaae90159ed52c876bdf" + integrity sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.5" @@ -7645,10 +7665,10 @@ webpack@^5.91.0: "@webassemblyjs/wasm-edit" "^1.12.1" "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.9.0" + acorn-import-attributes "^1.9.5" browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.16.0" + enhanced-resolve "^5.17.0" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" @@ -7819,9 +7839,9 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@~2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362" - integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== + version "2.4.5" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.5.tgz#60630b206dd6d84df97003d33fc1ddf6296cca5e" + integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== yargs-parser@20.2.4: version "20.2.4" From f1f81f7870affb444c1d2a289c1a272f01410346 Mon Sep 17 00:00:00 2001 From: celestialkylin Date: Tue, 18 Jun 2024 08:06:13 +0800 Subject: [PATCH 09/10] Respect custom headers when using `Server`s (#988) --- src/horizon/server.ts | 4 ++++ src/rpc/server.ts | 2 +- test/integration/client_headers_test.js | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/horizon/server.ts b/src/horizon/server.ts index 48c92106d..e039994b3 100644 --- a/src/horizon/server.ts +++ b/src/horizon/server.ts @@ -92,6 +92,9 @@ export class Server { if (opts.authToken) { customHeaders["X-Auth-Token"] = opts.authToken; } + if (opts.headers) { + Object.assign(customHeaders, opts.headers); + } if (Object.keys(customHeaders).length > 0) { AxiosClient.interceptors.request.use((config) => { // merge the custom headers with an existing headers, where customs @@ -822,6 +825,7 @@ export namespace Server { appName?: string; appVersion?: string; authToken?: string; + headers?: Record; } export interface Timebounds { diff --git a/src/rpc/server.ts b/src/rpc/server.ts index e3c518efb..a0d09f2ba 100644 --- a/src/rpc/server.ts +++ b/src/rpc/server.ts @@ -75,7 +75,7 @@ export class Server { constructor(serverURL: string, opts: Server.Options = {}) { this.serverURL = URI(serverURL); - if (opts.headers && Object.keys(opts.headers).length === 0) { + if (opts.headers && Object.keys(opts.headers).length !== 0) { AxiosClient.interceptors.request.use((config: any) => { // merge the custom headers into any existing headers config.headers = Object.assign(config.headers, opts.headers); diff --git a/test/integration/client_headers_test.js b/test/integration/client_headers_test.js index e070d7e0c..bd564c1be 100644 --- a/test/integration/client_headers_test.js +++ b/test/integration/client_headers_test.js @@ -72,4 +72,26 @@ describe("integration tests: client headers", function (done) { .stream({ onerror: (err) => done(err) }); }); }); + + it("sends client via custom headers", function (done) { + let server; + + const requestHandler = (request, response) => { + expect(request.headers["authorization"]).to.be.equal("123456789"); + response.end(); + server.close(() => done()); + }; + + server = http.createServer(requestHandler); + server.listen(port, (err) => { + if (err) { + done(err); + return; + } + + new Horizon.Server(`http://localhost:${port}`, { headers: { "authorization": "123456789" }, allowHttp: true }) + .operations() + .call(); + }); + }); }); From b8430dd79392d5b08ee3d92daa0a90e4ac2d55e8 Mon Sep 17 00:00:00 2001 From: Blaine Heffron Date: Tue, 25 Jun 2024 16:46:22 -0400 Subject: [PATCH 10/10] Running an absolute clinic on appeasing the ES linter (#990) --- .eslintrc.js | 43 + src/.eslintrc.js | 41 - src/browser.ts | 5 +- src/config.ts | 4 +- src/contract/assembled_transaction.ts | 7 +- src/contract/index.ts | 3 +- src/contract/sent_transaction.ts | 3 +- src/contract/spec.ts | 1629 +++++++++-------- src/contract/types.ts | 7 +- src/contract/utils.ts | 13 +- src/errors.ts | 5 + src/federation/server.ts | 5 +- src/horizon/account_call_builder.ts | 4 +- src/horizon/account_response.ts | 3 +- src/horizon/assets_call_builder.ts | 4 +- src/horizon/call_builder.ts | 36 +- .../claimable_balances_call_builder.ts | 6 +- src/horizon/effect_call_builder.ts | 4 +- src/horizon/horizon_axios_client.ts | 15 +- src/horizon/ledger_call_builder.ts | 4 +- src/horizon/liquidity_pool_call_builder.ts | 5 +- src/horizon/offer_call_builder.ts | 4 +- src/horizon/operation_call_builder.ts | 6 +- src/horizon/path_call_builder.ts | 2 +- src/horizon/payment_call_builder.ts | 4 +- src/horizon/server.ts | 50 +- src/horizon/server_api.ts | 1 + .../strict_receive_path_call_builder.ts | 2 +- src/horizon/strict_send_path_call_builder.ts | 2 +- src/horizon/trade_aggregation_call_builder.ts | 25 +- src/horizon/trades_call_builder.ts | 4 +- src/horizon/transaction_call_builder.ts | 6 +- src/horizon/types/assets.ts | 2 +- src/horizon/types/effects.ts | 2 +- src/horizon/types/offer.ts | 2 +- src/rpc/api.ts | 11 +- src/rpc/axios.ts | 4 +- src/rpc/browser.ts | 6 +- src/rpc/jsonrpc.ts | 21 +- src/rpc/parsers.ts | 104 +- src/rpc/server.ts | 104 +- src/rpc/transaction.ts | 80 +- src/rpc/utils.ts | 1 + src/stellartoml/index.ts | 1 + src/webauth/errors.ts | 2 +- .../src/test-contract-client-constructor.js | 13 +- test/e2e/src/test-custom-types.js | 174 +- test/e2e/src/test-hello-world.js | 10 +- test/e2e/src/test-methods-as-args.js | 4 +- test/e2e/src/test-swap.js | 139 +- .../soroban/assembled_transaction_test.js | 102 +- .../soroban/simulate_transaction_test.js | 119 +- 52 files changed, 1514 insertions(+), 1339 deletions(-) delete mode 100644 src/.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index 16fdb5cab..4fcd5f068 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,11 +4,54 @@ module.exports = { }, extends: [ "airbnb-base", + "airbnb-typescript/base", "prettier", "plugin:jsdoc/recommended", ], + parserOptions: { + parser: "@typescript-eslint/parser", + project: "./config/tsconfig.json", + }, plugins: ["@babel", "prettier", "prefer-import"], rules: { + // OFF "node/no-unpublished-require": 0, + "import/prefer-default-export": 0, + "node/no-unsupported-features/es-syntax": 0, + "node/no-unsupported-features/es-builtins": 0, + camelcase: 0, + "class-methods-use-this": 0, + "linebreak-style": 0, + "jsdoc/require-returns": 0, + "jsdoc/require-param": 0, + "jsdoc/require-param-type": 0, + "jsdoc/require-returns-type": 0, + "jsdoc/no-blank-blocks": 0, + "jsdoc/no-multi-asterisks": 0, + "jsdoc/tag-lines": "off", + "jsdoc/require-jsdoc": "off", + "jsdoc/no-defaults": "off", + "valid-jsdoc": "off", + "import/extensions": 0, + "new-cap": 0, + "no-param-reassign": 0, + "no-underscore-dangle": 0, + "no-use-before-define": 0, + "prefer-destructuring": 0, + "lines-between-class-members": 0, + "@typescript-eslint/lines-between-class-members": "off", + "spaced-comment": 0, + + // WARN + "arrow-body-style": 1, + "no-console": ["warn", { allow: ["assert"] }], + "no-debugger": 1, + "object-shorthand": 1, + "prefer-const": 1, + "prefer-import/prefer-import-over-require": [1], + "require-await": 1, + + // ERROR + "no-unused-expressions": [2, { allowTaggedTemplates: true }], }, }; diff --git a/src/.eslintrc.js b/src/.eslintrc.js deleted file mode 100644 index 97b3cc934..000000000 --- a/src/.eslintrc.js +++ /dev/null @@ -1,41 +0,0 @@ -module.exports = { - extends: [ - "airbnb-base", - "airbnb-typescript/base", - "prettier", - "plugin:jsdoc/recommended", - ], - parserOptions: { - parser: "@typescript-eslint/parser", - project: "./config/tsconfig.json", - }, - rules: { - // OFF - "import/prefer-default-export": 0, - "node/no-unsupported-features/es-syntax": 0, - "node/no-unsupported-features/es-builtins": 0, - camelcase: 0, - "class-methods-use-this": 0, - "linebreak-style": 0, - "jsdoc/require-returns": 0, - "jsdoc/require-param": 0, - "new-cap": 0, - "no-param-reassign": 0, - "no-underscore-dangle": 0, - "no-use-before-define": 0, - "prefer-destructuring": 0, - "lines-between-class-members": 0, - - // WARN - "arrow-body-style": 1, - "no-console": ["warn", { allow: ["assert"] }], - "no-debugger": 1, - "object-shorthand": 1, - "prefer-const": 1, - "prefer-import/prefer-import-over-require": [1], - "require-await": 1, - - // ERROR - "no-unused-expressions": [2, { allowTaggedTemplates: true }], - }, -}; diff --git a/src/browser.ts b/src/browser.ts index 6befec18d..2f6034b93 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -1,9 +1,10 @@ /* tslint:disable:no-var-requires */ +/* eslint import/no-import-module-exports: 0 */ + +import axios from "axios"; // idk why axios is weird export * from "./index"; export * as StellarBase from "@stellar/stellar-base"; - -import axios from "axios"; // idk why axios is weird export { axios }; export default module.exports; diff --git a/src/config.ts b/src/config.ts index 946c793d8..4528a0a8a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -18,7 +18,7 @@ const defaultConfig: Configuration = { timeout: 0, }; -let config = Object.assign({}, defaultConfig); +let config = { ...defaultConfig}; /** * Global config class. @@ -82,7 +82,7 @@ class Config { * @returns {void} */ public static setDefault(): void { - config = Object.assign({}, defaultConfig); + config = { ...defaultConfig}; } } diff --git a/src/contract/assembled_transaction.ts b/src/contract/assembled_transaction.ts index e87de33b7..d038051aa 100644 --- a/src/contract/assembled_transaction.ts +++ b/src/contract/assembled_transaction.ts @@ -24,17 +24,14 @@ import { assembleTransaction } from "../rpc/transaction"; import type { Client } from "./client"; import { Err } from "./rust_result"; import { - DEFAULT_TIMEOUT, contractErrorPattern, implementsToString, getAccount } from "./utils"; +import { DEFAULT_TIMEOUT } from "./types"; import { SentTransaction } from "./sent_transaction"; import { Spec } from "./spec"; -export const NULL_ACCOUNT = - "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; - /** * The main workhorse of {@link Client}. This class is used to wrap a * transaction-under-construction and provide high-level interfaces to the most @@ -909,7 +906,7 @@ export class AssembledTransaction { * Client initialization. * @throws {AssembledTransaction.Errors.RestoreFailure} - Throws a custom error if the * restore transaction fails, providing the details of the failure. - */ + */ async restoreFootprint( /** * The preamble object containing data required to diff --git a/src/contract/index.ts b/src/contract/index.ts index 657bde8cf..4675aacd5 100644 --- a/src/contract/index.ts +++ b/src/contract/index.ts @@ -4,5 +4,4 @@ export * from "./client"; export * from "./rust_result"; export * from "./sent_transaction"; export * from "./spec"; -export * from "./types"; -export { DEFAULT_TIMEOUT } from "./utils"; +export * from "./types"; \ No newline at end of file diff --git a/src/contract/sent_transaction.ts b/src/contract/sent_transaction.ts index 0a449ab3e..0014fa393 100644 --- a/src/contract/sent_transaction.ts +++ b/src/contract/sent_transaction.ts @@ -3,7 +3,8 @@ import type { MethodOptions } from "./types"; import { Server } from "../rpc/server" import { Api } from "../rpc/api" -import { DEFAULT_TIMEOUT, withExponentialBackoff } from "./utils"; +import { withExponentialBackoff } from "./utils"; +import { DEFAULT_TIMEOUT } from "./types"; import type { AssembledTransaction } from "./assembled_transaction"; /** diff --git a/src/contract/spec.ts b/src/contract/spec.ts index 937875fbb..863fbac1d 100644 --- a/src/contract/spec.ts +++ b/src/contract/spec.ts @@ -14,245 +14,659 @@ export interface Union { values?: T; } +function enumToJsonSchema(udt: xdr.ScSpecUdtEnumV0): any { + const description = udt.doc().toString(); + const cases = udt.cases(); + const oneOf: any[] = []; + cases.forEach((aCase) => { + const title = aCase.name().toString(); + const desc = aCase.doc().toString(); + oneOf.push({ + description: desc, + title, + enum: [aCase.value()], + type: "number", + }); + }); + const res: any = { oneOf }; + if (description.length > 0) { + res.description = description; + } + return res; +} + +function isNumeric(field: xdr.ScSpecUdtStructFieldV0) { + return /^\d+$/.test(field.name().toString()); +} + function readObj(args: object, input: xdr.ScSpecFunctionInputV0): any { - let inputName = input.name().toString(); - let entry = Object.entries(args).find(([name, _]) => name === inputName); + const inputName = input.name().toString(); + const entry = Object.entries(args).find(([name]) => name === inputName); if (!entry) { throw new Error(`Missing field ${inputName}`); } return entry[1]; } -/** - * Provides a ContractSpec class which can contains the XDR types defined by the contract. - * This allows the class to be used to convert between native and raw `xdr.ScVal`s. - * - * @example - * ```js - * const specEntries = [...]; // XDR spec entries of a smart contract - * const contractSpec = new ContractSpec(specEntries); - * - * // Convert native value to ScVal - * const args = { - * arg1: 'value1', - * arg2: 1234 - * }; - * const scArgs = contractSpec.funcArgsToScVals('funcName', args); - * - * // Call contract - * const resultScv = await callContract(contractId, 'funcName', scArgs); - * - * // Convert result ScVal back to native value - * const result = contractSpec.funcResToNative('funcName', resultScv); - * - * console.log(result); // {success: true} - * ``` - */ -export class Spec { - public entries: xdr.ScSpecEntry[] = []; - - /** - * Constructs a new ContractSpec from an array of XDR spec entries. - * - * @param {xdr.ScSpecEntry[] | string[]} entries the XDR spec entries - * - * @throws {Error} if entries is invalid - */ - constructor(entries: xdr.ScSpecEntry[] | string[]) { - if (entries.length == 0) { - throw new Error("Contract spec must have at least one entry"); - } - let entry = entries[0]; - if (typeof entry === "string") { - this.entries = (entries as string[]).map((s) => - xdr.ScSpecEntry.fromXDR(s, "base64"), - ); - } else { - this.entries = entries as xdr.ScSpecEntry[]; +function findCase(name: string) { + return function matches(entry: xdr.ScSpecUdtUnionCaseV0) { + switch (entry.switch().value) { + case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value: { + const tuple = entry.tupleCase(); + return tuple.name().toString() === name; + } + case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0().value: { + const voidCase = entry.voidCase(); + return voidCase.name().toString() === name; + } + default: + return false; } - } + }; +} - /** - * Gets the XDR functions from the spec. - * - * @returns {xdr.ScSpecFunctionV0[]} all contract functions - * - */ - funcs(): xdr.ScSpecFunctionV0[] { - return this.entries - .filter( - (entry) => - entry.switch().value === - xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value, - ) - .map((entry) => entry.functionV0()); - } - /** - * Gets the XDR function spec for the given function name. - * - * @param {string} name the name of the function - * @returns {xdr.ScSpecFunctionV0} the function spec - * - * @throws {Error} if no function with the given name exists - */ - getFunc(name: string): xdr.ScSpecFunctionV0 { - let entry = this.findEntry(name); - if ( - entry.switch().value !== xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value - ) { - throw new Error(`${name} is not a function`); +function stringToScVal(str: string, ty: xdr.ScSpecType): xdr.ScVal { + switch (ty.value) { + case xdr.ScSpecType.scSpecTypeString().value: + return xdr.ScVal.scvString(str); + case xdr.ScSpecType.scSpecTypeSymbol().value: + return xdr.ScVal.scvSymbol(str); + case xdr.ScSpecType.scSpecTypeAddress().value: { + const addr = Address.fromString(str as string); + return xdr.ScVal.scvAddress(addr.toScAddress()); } - return entry.functionV0(); - } + case xdr.ScSpecType.scSpecTypeU64().value: + return new XdrLargeInt("u64", str).toScVal(); + case xdr.ScSpecType.scSpecTypeI64().value: + return new XdrLargeInt("i64", str).toScVal(); + case xdr.ScSpecType.scSpecTypeU128().value: + return new XdrLargeInt("u128", str).toScVal(); + case xdr.ScSpecType.scSpecTypeI128().value: + return new XdrLargeInt("i128", str).toScVal(); + case xdr.ScSpecType.scSpecTypeU256().value: + return new XdrLargeInt("u256", str).toScVal(); + case xdr.ScSpecType.scSpecTypeI256().value: + return new XdrLargeInt("i256", str).toScVal(); + case xdr.ScSpecType.scSpecTypeBytes().value: + case xdr.ScSpecType.scSpecTypeBytesN().value: + return xdr.ScVal.scvBytes(Buffer.from(str, "base64")); - /** - * Converts native JS arguments to ScVals for calling a contract function. - * - * @param {string} name the name of the function - * @param {Object} args the arguments object - * @returns {xdr.ScVal[]} the converted arguments - * - * @throws {Error} if argument is missing or incorrect type - * - * @example - * ```js - * const args = { - * arg1: 'value1', - * arg2: 1234 - * }; - * const scArgs = contractSpec.funcArgsToScVals('funcName', args); - * ``` - */ - funcArgsToScVals(name: string, args: object): xdr.ScVal[] { - let fn = this.getFunc(name); - return fn - .inputs() - .map((input) => this.nativeToScVal(readObj(args, input), input.type())); + default: + throw new TypeError(`invalid type ${ty.name} specified for string value`); } +} - /** - * Converts the result ScVal of a function call to a native JS value. - * - * @param {string} name the name of the function - * @param {xdr.ScVal | string} val_or_base64 the result ScVal or base64 encoded string - * @returns {any} the converted native value - * - * @throws {Error} if return type mismatch or invalid input - * - * @example - * ```js - * const resultScv = 'AAA=='; // Base64 encoded ScVal - * const result = contractSpec.funcResToNative('funcName', resultScv); - * ``` - */ - funcResToNative(name: string, val_or_base64: xdr.ScVal | string): any { - let val = - typeof val_or_base64 === "string" - ? xdr.ScVal.fromXDR(val_or_base64, "base64") - : val_or_base64; - let func = this.getFunc(name); - let outputs = func.outputs(); - if (outputs.length === 0) { - let type = val.switch(); - if (type.value !== xdr.ScValType.scvVoid().value) { - throw new Error(`Expected void, got ${type.name}`); - } - return null; +const PRIMITIVE_DEFINITONS: { [key: string]: JSONSchema7Definition } = { + U32: { + type: "integer", + minimum: 0, + maximum: 4294967295, + }, + I32: { + type: "integer", + minimum: -2147483648, + maximum: 2147483647, + }, + U64: { + type: "string", + pattern: "^([1-9][0-9]*|0)$", + minLength: 1, + maxLength: 20, // 64-bit max value has 20 digits + }, + I64: { + type: "string", + pattern: "^(-?[1-9][0-9]*|0)$", + minLength: 1, + maxLength: 21, // Includes additional digit for the potential '-' + }, + U128: { + type: "string", + pattern: "^([1-9][0-9]*|0)$", + minLength: 1, + maxLength: 39, // 128-bit max value has 39 digits + }, + I128: { + type: "string", + pattern: "^(-?[1-9][0-9]*|0)$", + minLength: 1, + maxLength: 40, // Includes additional digit for the potential '-' + }, + U256: { + type: "string", + pattern: "^([1-9][0-9]*|0)$", + minLength: 1, + maxLength: 78, // 256-bit max value has 78 digits + }, + I256: { + type: "string", + pattern: "^(-?[1-9][0-9]*|0)$", + minLength: 1, + maxLength: 79, // Includes additional digit for the potential '-' + }, + Address: { + type: "string", + format: "address", + description: "Address can be a public key or contract id", + }, + ScString: { + type: "string", + description: "ScString is a string", + }, + ScSymbol: { + type: "string", + description: "ScString is a string", + }, + DataUrl: { + type: "string", + pattern: + "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=)?$", + }, +}; + +/* eslint-disable default-case */ +/** + * @param typeDef type to convert to json schema reference + * @returns {JSONSchema7} a schema describing the type + */ +function typeRef(typeDef: xdr.ScSpecTypeDef): JSONSchema7 { + const t = typeDef.switch(); + const value = t.value; + let ref; + switch (value) { + case xdr.ScSpecType.scSpecTypeVal().value: { + ref = "Val"; + break; } - if (outputs.length > 1) { - throw new Error(`Multiple outputs not supported`); + case xdr.ScSpecType.scSpecTypeBool().value: { + return { type: "boolean" }; } - let output = outputs[0]; - if (output.switch().value === xdr.ScSpecType.scSpecTypeResult().value) { - return new Ok(this.scValToNative(val, output.result().okType())); + case xdr.ScSpecType.scSpecTypeVoid().value: { + return { type: "null" }; + } + case xdr.ScSpecType.scSpecTypeError().value: { + ref = "Error"; + break; + } + case xdr.ScSpecType.scSpecTypeU32().value: { + ref = "U32"; + break; + } + case xdr.ScSpecType.scSpecTypeI32().value: { + ref = "I32"; + break; + } + case xdr.ScSpecType.scSpecTypeU64().value: { + ref = "U64"; + break; + } + case xdr.ScSpecType.scSpecTypeI64().value: { + ref = "I64"; + break; + } + case xdr.ScSpecType.scSpecTypeTimepoint().value: { + throw new Error("Timepoint type not supported"); + ref = "Timepoint"; + break; + } + case xdr.ScSpecType.scSpecTypeDuration().value: { + throw new Error("Duration not supported"); + ref = "Duration"; + break; + } + case xdr.ScSpecType.scSpecTypeU128().value: { + ref = "U128"; + break; + } + case xdr.ScSpecType.scSpecTypeI128().value: { + ref = "I128"; + break; + } + case xdr.ScSpecType.scSpecTypeU256().value: { + ref = "U256"; + break; + } + case xdr.ScSpecType.scSpecTypeI256().value: { + ref = "I256"; + break; + } + case xdr.ScSpecType.scSpecTypeBytes().value: { + ref = "DataUrl"; + break; + } + case xdr.ScSpecType.scSpecTypeString().value: { + ref = "ScString"; + break; + } + case xdr.ScSpecType.scSpecTypeSymbol().value: { + ref = "ScSymbol"; + break; + } + case xdr.ScSpecType.scSpecTypeAddress().value: { + ref = "Address"; + break; + } + case xdr.ScSpecType.scSpecTypeOption().value: { + const opt = typeDef.option(); + return typeRef(opt.valueType()); + } + case xdr.ScSpecType.scSpecTypeResult().value: { + // throw new Error('Result type not supported'); + break; + } + case xdr.ScSpecType.scSpecTypeVec().value: { + const arr = typeDef.vec(); + const reference = typeRef(arr.elementType()); + return { + type: "array", + items: reference, + }; + } + case xdr.ScSpecType.scSpecTypeMap().value: { + const map = typeDef.map(); + const items = [typeRef(map.keyType()), typeRef(map.valueType())]; + return { + type: "array", + items: { + type: "array", + items, + minItems: 2, + maxItems: 2, + }, + }; + } + case xdr.ScSpecType.scSpecTypeTuple().value: { + const tuple = typeDef.tuple(); + const minItems = tuple.valueTypes().length; + const maxItems = minItems; + const items = tuple.valueTypes().map(typeRef); + return { type: "array", items, minItems, maxItems }; + } + case xdr.ScSpecType.scSpecTypeBytesN().value: { + const arr = typeDef.bytesN(); + return { + $ref: "#/definitions/DataUrl", + maxLength: arr.n(), + }; + } + case xdr.ScSpecType.scSpecTypeUdt().value: { + const udt = typeDef.udt(); + ref = udt.name().toString(); + break; } - return this.scValToNative(val, output); } + return { $ref: `#/definitions/${ref}` }; +} +/* eslint-enable default-case */ - /** - * Finds the XDR spec entry for the given name. - * - * @param {string} name the name to find - * @returns {xdr.ScSpecEntry} the entry - * - * @throws {Error} if no entry with the given name exists - */ - findEntry(name: string): xdr.ScSpecEntry { - let entry = this.entries.find( - (entry) => entry.value().name().toString() === name, - ); - if (!entry) { - throw new Error(`no such entry: ${name}`); +type Func = { input: JSONSchema7; output: JSONSchema7 }; + +function isRequired(typeDef: xdr.ScSpecTypeDef): boolean { + return typeDef.switch().value !== xdr.ScSpecType.scSpecTypeOption().value; +} + +function argsAndRequired( + input: { type: () => xdr.ScSpecTypeDef; name: () => string | Buffer }[], +): { properties: object; required?: string[] } { + const properties: any = {}; + const required: string[] = []; + input.forEach((arg) => { + const aType = arg.type(); + const name = arg.name().toString(); + properties[name] = typeRef(aType); + if (isRequired(aType)) { + required.push(name); } - return entry; + }); + const res: { properties: object; required?: string[] } = { properties }; + if (required.length > 0) { + res.required = required; } + return res; +} - /** - * Converts a native JS value to an ScVal based on the given type. - * - * @param {any} val the native JS value - * @param {xdr.ScSpecTypeDef} [ty] the expected type - * @returns {xdr.ScVal} the converted ScVal - * - * @throws {Error} if value cannot be converted to the given type - */ - nativeToScVal(val: any, ty: xdr.ScSpecTypeDef): xdr.ScVal { - let t: xdr.ScSpecType = ty.switch(); - let value = t.value; - if (t.value === xdr.ScSpecType.scSpecTypeUdt().value) { - let udt = ty.udt(); - return this.nativeToUdt(val, udt.name().toString()); +function structToJsonSchema(udt: xdr.ScSpecUdtStructV0): object { + const fields = udt.fields(); + if (fields.some(isNumeric)) { + if (!fields.every(isNumeric)) { + throw new Error( + "mixed numeric and non-numeric field names are not allowed", + ); } - if (value === xdr.ScSpecType.scSpecTypeOption().value) { - let opt = ty.option(); - if (val === undefined) { - return xdr.ScVal.scvVoid(); + const items = fields.map((_, i) => typeRef(fields[i].type())); + return { + type: "array", + items, + minItems: fields.length, + maxItems: fields.length, + }; + } + const description = udt.doc().toString(); + const { properties, required }: any = argsAndRequired(fields); + properties.additionalProperties = false; + return { + description, + properties, + required, + type: "object", + }; +} + +function functionToJsonSchema(func: xdr.ScSpecFunctionV0): Func { + const { properties, required }: any = argsAndRequired(func.inputs()); + const args: any = { + additionalProperties: false, + properties, + type: "object", + }; + if (required?.length > 0) { + args.required = required; + } + const input: Partial = { + properties: { + args, + }, + }; + const outputs = func.outputs(); + const output: Partial = + outputs.length > 0 + ? typeRef(outputs[0]) + : typeRef(xdr.ScSpecTypeDef.scSpecTypeVoid()); + const description = func.doc().toString(); + if (description.length > 0) { + input.description = description; + } + input.additionalProperties = false; + output.additionalProperties = false; + return { + input, + output, + }; +} + +/* eslint-disable default-case */ +function unionToJsonSchema(udt: xdr.ScSpecUdtUnionV0): any { + const description = udt.doc().toString(); + const cases = udt.cases(); + const oneOf: any[] = []; + cases.forEach((aCase) => { + switch (aCase.switch().value) { + case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0().value: { + const c = aCase.voidCase(); + const title = c.name().toString(); + oneOf.push({ + type: "object", + title, + properties: { + tag: title, + }, + additionalProperties: false, + required: ["tag"], + }); + break; + } + case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value: { + const c = aCase.tupleCase(); + const title = c.name().toString(); + oneOf.push({ + type: "object", + title, + properties: { + tag: title, + values: { + type: "array", + items: c.type().map(typeRef), + }, + }, + required: ["tag", "values"], + additionalProperties: false, + }); } - return this.nativeToScVal(val, opt.valueType()); } - switch (typeof val) { - case "object": { - if (val === null) { - switch (value) { - case xdr.ScSpecType.scSpecTypeVoid().value: - return xdr.ScVal.scvVoid(); - default: - throw new TypeError( - `Type ${ty} was not void, but value was null`, - ); - } - } + }); - if (val instanceof xdr.ScVal) { - return val; // should we copy? - } + const res: any = { + oneOf, + }; + if (description.length > 0) { + res.description = description; + } + return res; +} +/* eslint-enable default-case */ - if (val instanceof Address) { - if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) { - throw new TypeError( - `Type ${ty} was not address, but value was Address`, - ); - } - return val.toScVal(); - } - if (val instanceof Contract) { - if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) { - throw new TypeError( - `Type ${ty} was not address, but value was Address`, - ); - } - return val.address().toScVal(); - } +/** + * Provides a ContractSpec class which can contains the XDR types defined by the contract. + * This allows the class to be used to convert between native and raw `xdr.ScVal`s. + * + * @example + * ```js + * const specEntries = [...]; // XDR spec entries of a smart contract + * const contractSpec = new ContractSpec(specEntries); + * + * // Convert native value to ScVal + * const args = { + * arg1: 'value1', + * arg2: 1234 + * }; + * const scArgs = contractSpec.funcArgsToScVals('funcName', args); + * + * // Call contract + * const resultScv = await callContract(contractId, 'funcName', scArgs); + * + * // Convert result ScVal back to native value + * const result = contractSpec.funcResToNative('funcName', resultScv); + * + * console.log(result); // {success: true} + * ``` + */ +export class Spec { + public entries: xdr.ScSpecEntry[] = []; + + /** + * Constructs a new ContractSpec from an array of XDR spec entries. + * + * @param {xdr.ScSpecEntry[] | string[]} entries the XDR spec entries + * + * @throws {Error} if entries is invalid + */ + constructor(entries: xdr.ScSpecEntry[] | string[]) { + if (entries.length === 0) { + throw new Error("Contract spec must have at least one entry"); + } + const entry = entries[0]; + if (typeof entry === "string") { + this.entries = (entries as string[]).map((s) => + xdr.ScSpecEntry.fromXDR(s, "base64"), + ); + } else { + this.entries = entries as xdr.ScSpecEntry[]; + } + } + + /** + * Gets the XDR functions from the spec. + * + * @returns {xdr.ScSpecFunctionV0[]} all contract functions + * + */ + funcs(): xdr.ScSpecFunctionV0[] { + return this.entries + .filter( + (entry) => + entry.switch().value === + xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value, + ) + .map((entry) => entry.functionV0()); + } + + /** + * Gets the XDR function spec for the given function name. + * + * @param {string} name the name of the function + * @returns {xdr.ScSpecFunctionV0} the function spec + * + * @throws {Error} if no function with the given name exists + */ + getFunc(name: string): xdr.ScSpecFunctionV0 { + const entry = this.findEntry(name); + if ( + entry.switch().value !== xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value + ) { + throw new Error(`${name} is not a function`); + } + return entry.functionV0(); + } + + /** + * Converts native JS arguments to ScVals for calling a contract function. + * + * @param {string} name the name of the function + * @param {object} args the arguments object + * @returns {xdr.ScVal[]} the converted arguments + * + * @throws {Error} if argument is missing or incorrect type + * + * @example + * ```js + * const args = { + * arg1: 'value1', + * arg2: 1234 + * }; + * const scArgs = contractSpec.funcArgsToScVals('funcName', args); + * ``` + */ + funcArgsToScVals(name: string, args: object): xdr.ScVal[] { + const fn = this.getFunc(name); + return fn + .inputs() + .map((input) => this.nativeToScVal(readObj(args, input), input.type())); + } + + /** + * Converts the result ScVal of a function call to a native JS value. + * + * @param {string} name the name of the function + * @param {xdr.ScVal | string} val_or_base64 the result ScVal or base64 encoded string + * @returns {any} the converted native value + * + * @throws {Error} if return type mismatch or invalid input + * + * @example + * ```js + * const resultScv = 'AAA=='; // Base64 encoded ScVal + * const result = contractSpec.funcResToNative('funcName', resultScv); + * ``` + */ + funcResToNative(name: string, val_or_base64: xdr.ScVal | string): any { + const val = + typeof val_or_base64 === "string" + ? xdr.ScVal.fromXDR(val_or_base64, "base64") + : val_or_base64; + const func = this.getFunc(name); + const outputs = func.outputs(); + if (outputs.length === 0) { + const type = val.switch(); + if (type.value !== xdr.ScValType.scvVoid().value) { + throw new Error(`Expected void, got ${type.name}`); + } + return null; + } + if (outputs.length > 1) { + throw new Error(`Multiple outputs not supported`); + } + const output = outputs[0]; + if (output.switch().value === xdr.ScSpecType.scSpecTypeResult().value) { + return new Ok(this.scValToNative(val, output.result().okType())); + } + return this.scValToNative(val, output); + } + + /** + * Finds the XDR spec entry for the given name. + * + * @param {string} name the name to find + * @returns {xdr.ScSpecEntry} the entry + * + * @throws {Error} if no entry with the given name exists + */ + findEntry(name: string): xdr.ScSpecEntry { + const entry = this.entries.find( + (e) => e.value().name().toString() === name, + ); + if (!entry) { + throw new Error(`no such entry: ${name}`); + } + return entry; + } + + + /** + * Converts a native JS value to an ScVal based on the given type. + * + * @param {any} val the native JS value + * @param {xdr.ScSpecTypeDef} [ty] the expected type + * @returns {xdr.ScVal} the converted ScVal + * + * @throws {Error} if value cannot be converted to the given type + */ + nativeToScVal(val: any, ty: xdr.ScSpecTypeDef): xdr.ScVal { + const t: xdr.ScSpecType = ty.switch(); + const value = t.value; + if (t.value === xdr.ScSpecType.scSpecTypeUdt().value) { + const udt = ty.udt(); + return this.nativeToUdt(val, udt.name().toString()); + } + if (value === xdr.ScSpecType.scSpecTypeOption().value) { + const opt = ty.option(); + if (val === undefined) { + return xdr.ScVal.scvVoid(); + } + return this.nativeToScVal(val, opt.valueType()); + } + switch (typeof val) { + case "object": { + if (val === null) { + switch (value) { + case xdr.ScSpecType.scSpecTypeVoid().value: + return xdr.ScVal.scvVoid(); + default: + throw new TypeError( + `Type ${ty} was not void, but value was null`, + ); + } + } + + if (val instanceof xdr.ScVal) { + return val; // should we copy? + } + + if (val instanceof Address) { + if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) { + throw new TypeError( + `Type ${ty} was not address, but value was Address`, + ); + } + return val.toScVal(); + } + + if (val instanceof Contract) { + if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) { + throw new TypeError( + `Type ${ty} was not address, but value was Address`, + ); + } + return val.address().toScVal(); + } if (val instanceof Uint8Array || Buffer.isBuffer(val)) { const copy = Uint8Array.from(val); switch (value) { case xdr.ScSpecType.scSpecTypeBytesN().value: { - let bytes_n = ty.bytesN(); - if (copy.length !== bytes_n.n()) { + const bytesN = ty.bytesN(); + if (copy.length !== bytesN.n()) { throw new TypeError( - `expected ${bytes_n.n()} bytes, but got ${copy.length}`, + `expected ${bytesN.n()} bytes, but got ${copy.length}`, ); } //@ts-ignore @@ -270,15 +684,15 @@ export class Spec { if (Array.isArray(val)) { switch (value) { case xdr.ScSpecType.scSpecTypeVec().value: { - let vec = ty.vec(); - let elementType = vec.elementType(); + const vec = ty.vec(); + const elementType = vec.elementType(); return xdr.ScVal.scvVec( val.map((v) => this.nativeToScVal(v, elementType)), ); } case xdr.ScSpecType.scSpecTypeTuple().value: { - let tup = ty.tuple(); - let valTypes = tup.valueTypes(); + const tup = ty.tuple(); + const valTypes = tup.valueTypes(); if (val.length !== valTypes.length) { throw new TypeError( `Tuple expects ${valTypes.length} values, but ${val.length} were provided`, @@ -289,14 +703,14 @@ export class Spec { ); } case xdr.ScSpecType.scSpecTypeMap().value: { - let map = ty.map(); - let keyType = map.keyType(); - let valueType = map.valueType(); + const map = ty.map(); + const keyType = map.keyType(); + const valueType = map.valueType(); return xdr.ScVal.scvMap( val.map((entry) => { - let key = this.nativeToScVal(entry[0], keyType); - let val = this.nativeToScVal(entry[1], valueType); - return new xdr.ScMapEntry({ key, val }); + const key = this.nativeToScVal(entry[0], keyType); + const mapVal = this.nativeToScVal(entry[1], valueType); + return new xdr.ScMapEntry({ key, val: mapVal }); }), ); } @@ -311,16 +725,16 @@ export class Spec { if (value !== xdr.ScSpecType.scSpecTypeMap().value) { throw new TypeError(`Type ${ty} was not map, but value was Map`); } - let scMap = ty.map(); - let map = val as Map; - let entries: xdr.ScMapEntry[] = []; - let values = map.entries(); + const scMap = ty.map(); + const map = val as Map; + const entries: xdr.ScMapEntry[] = []; + const values = map.entries(); let res = values.next(); while (!res.done) { - let [k, v] = res.value; - let key = this.nativeToScVal(k, scMap.keyType()); - let val = this.nativeToScVal(v, scMap.valueType()); - entries.push(new xdr.ScMapEntry({ key, val })); + const [k, v] = res.value; + const key = this.nativeToScVal(k, scMap.keyType()); + const mapval = this.nativeToScVal(v, scMap.valueType()); + entries.push(new xdr.ScMapEntry({ key, val: mapval })); res = values.next(); } return xdr.ScVal.scvMap(entries); @@ -391,7 +805,7 @@ export class Spec { } private nativeToUdt(val: any, name: string): xdr.ScVal { - let entry = this.findEntry(name); + const entry = this.findEntry(name); switch (entry.switch()) { case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0(): if (typeof val !== "number") { @@ -413,34 +827,34 @@ export class Spec { val: Union, union_: xdr.ScSpecUdtUnionV0, ): xdr.ScVal { - let entry_name = val.tag; - let case_ = union_.cases().find((entry) => { - let case_ = entry.value().name().toString(); - return case_ === entry_name; + const entryName = val.tag; + const caseFound = union_.cases().find((entry) => { + const caseN = entry.value().name().toString(); + return caseN === entryName; }); - if (!case_) { - throw new TypeError(`no such enum entry: ${entry_name} in ${union_}`); + if (!caseFound) { + throw new TypeError(`no such enum entry: ${entryName} in ${union_}`); } - let key = xdr.ScVal.scvSymbol(entry_name); - switch (case_.switch()) { + const key = xdr.ScVal.scvSymbol(entryName); + switch (caseFound.switch()) { case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0(): { return xdr.ScVal.scvVec([key]); } case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0(): { - let types = case_.tupleCase().type(); + const types = caseFound.tupleCase().type(); if (Array.isArray(val.values)) { - if (val.values.length != types.length) { + if (val.values.length !== types.length) { throw new TypeError( `union ${union_} expects ${types.length} values, but got ${val.values.length}`, ); } - let scvals = val.values.map((v, i) => + const scvals = val.values.map((v, i) => this.nativeToScVal(v, types[i]), ); scvals.unshift(key); return xdr.ScVal.scvVec(scvals); } - throw new Error(`failed to parse union case ${case_} with ${val}`); + throw new Error(`failed to parse union case ${caseFound} with ${val}`); } default: throw new Error(`failed to parse union ${union_} with ${val}`); @@ -448,7 +862,7 @@ export class Spec { } private nativeToStruct(val: any, struct: xdr.ScSpecUdtStructV0): xdr.ScVal { - let fields = struct.fields(); + const fields = struct.fields(); if (fields.some(isNumeric)) { if (!fields.every(isNumeric)) { throw new Error( @@ -461,7 +875,7 @@ export class Spec { } return xdr.ScVal.scvMap( fields.map((field) => { - let name = field.name().toString(); + const name = field.name().toString(); return new xdr.ScMapEntry({ key: this.nativeToScVal(name, xdr.ScSpecTypeDef.scSpecTypeSymbol()), val: this.nativeToScVal(val[name], field.type()), @@ -500,17 +914,18 @@ export class Spec { * @throws {Error} if ScVal cannot be converted to the given type */ scValToNative(scv: xdr.ScVal, typeDef: xdr.ScSpecTypeDef): T { - let t = typeDef.switch(); - let value = t.value; + const t = typeDef.switch(); + const value = t.value; if (value === xdr.ScSpecType.scSpecTypeUdt().value) { return this.scValUdtToNative(scv, typeDef.udt()); } + /* eslint-disable no-fallthrough*/ // we use the verbose xdr.ScValType..value form here because it's faster // than string comparisons and the underlying constants never need to be // updated switch (scv.switch().value) { case xdr.ScValType.scvVoid().value: - return void 0 as T; + return undefined as T; // these can be converted to bigints directly case xdr.ScValType.scvU64().value: @@ -525,14 +940,14 @@ export class Spec { return scValToBigInt(scv) as T; case xdr.ScValType.scvVec().value: { - if (value == xdr.ScSpecType.scSpecTypeVec().value) { - let vec = typeDef.vec(); + if (value === xdr.ScSpecType.scSpecTypeVec().value) { + const vec = typeDef.vec(); return (scv.vec() ?? []).map((elm) => this.scValToNative(elm, vec.elementType()), ) as T; - } else if (value == xdr.ScSpecType.scSpecTypeTuple().value) { - let tuple = typeDef.tuple(); - let valTypes = tuple.valueTypes(); + } if (value === xdr.ScSpecType.scSpecTypeTuple().value) { + const tuple = typeDef.tuple(); + const valTypes = tuple.valueTypes(); return (scv.vec() ?? []).map((elm, i) => this.scValToNative(elm, valTypes[i]), ) as T; @@ -544,12 +959,12 @@ export class Spec { return Address.fromScVal(scv).toString() as T; case xdr.ScValType.scvMap().value: { - let map = scv.map() ?? []; - if (value == xdr.ScSpecType.scSpecTypeMap().value) { - let type_ = typeDef.map(); - let keyType = type_.keyType(); - let valueType = type_.valueType(); - let res = map.map((entry) => [ + const map = scv.map() ?? []; + if (value === xdr.ScSpecType.scSpecTypeMap().value) { + const typed = typeDef.map(); + const keyType = typed.keyType(); + const valueType = typed.valueType(); + const res = map.map((entry) => [ this.scValToNative(entry.key(), keyType), this.scValToNative(entry.val(), valueType), ]) as T; @@ -575,580 +990,178 @@ export class Spec { case xdr.ScValType.scvSymbol().value: { if ( value !== xdr.ScSpecType.scSpecTypeString().value && - value !== xdr.ScSpecType.scSpecTypeSymbol().value - ) { - throw new Error( - `ScSpecType ${t.name - } was not string or symbol, but ${JSON.stringify(scv, null, 2)} is`, - ); - } - return scv.value()?.toString() as T; - } - - // these can be converted to bigint - case xdr.ScValType.scvTimepoint().value: - case xdr.ScValType.scvDuration().value: - return scValToBigInt(xdr.ScVal.scvU64(scv.u64())) as T; - - // in the fallthrough case, just return the underlying value directly - default: - throw new TypeError( - `failed to convert ${JSON.stringify( - scv, - null, - 2, - )} to native type from type ${t.name}`, - ); - } - } - - private scValUdtToNative(scv: xdr.ScVal, udt: xdr.ScSpecTypeUdt): any { - let entry = this.findEntry(udt.name().toString()); - switch (entry.switch()) { - case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0(): - return this.enumToNative(scv); - case xdr.ScSpecEntryKind.scSpecEntryUdtStructV0(): - return this.structToNative(scv, entry.udtStructV0()); - case xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0(): - return this.unionToNative(scv, entry.udtUnionV0()); - default: - throw new Error( - `failed to parse udt ${udt.name().toString()}: ${entry}`, - ); - } - } - - private unionToNative(val: xdr.ScVal, udt: xdr.ScSpecUdtUnionV0): any { - let vec = val.vec(); - if (!vec) { - throw new Error(`${JSON.stringify(val, null, 2)} is not a vec`); - } - if (vec.length === 0 && udt.cases.length !== 0) { - throw new Error( - `${val} has length 0, but the there are at least one case in the union`, - ); - } - let name = vec[0].sym().toString(); - if (vec[0].switch().value != xdr.ScValType.scvSymbol().value) { - throw new Error(`{vec[0]} is not a symbol`); - } - let entry = udt.cases().find(findCase(name)); - if (!entry) { - throw new Error( - `failed to find entry ${name} in union {udt.name().toString()}`, - ); - } - let res: Union = { tag: name }; - if ( - entry.switch().value === - xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value - ) { - let tuple = entry.tupleCase(); - let ty = tuple.type(); - let values = ty.map((entry, i) => this.scValToNative(vec![i + 1], entry)); - res.values = values; - } - return res; - } - private structToNative(val: xdr.ScVal, udt: xdr.ScSpecUdtStructV0): any { - let res: any = {}; - let fields = udt.fields(); - if (fields.some(isNumeric)) { - let r = val - .vec() - ?.map((entry, i) => this.scValToNative(entry, fields[i].type())); - return r; - } - val.map()?.forEach((entry, i) => { - let field = fields[i]; - res[field.name().toString()] = this.scValToNative( - entry.val(), - field.type(), - ); - }); - return res; - } - - private enumToNative(scv: xdr.ScVal): number { - if (scv.switch().value !== xdr.ScValType.scvU32().value) { - throw new Error(`Enum must have a u32 value`); - } - let num = scv.u32(); - return num; - } - - /** - * Gets the XDR error cases from the spec. - * - * @returns {xdr.ScSpecFunctionV0[]} all contract functions - * - */ - errorCases(): xdr.ScSpecUdtErrorEnumCaseV0[] { - return this.entries - .filter( - (entry) => - entry.switch().value === - xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value, - ) - .flatMap((entry) => (entry.value() as xdr.ScSpecUdtErrorEnumV0).cases()); - } - - /** - * Converts the contract spec to a JSON schema. - * - * If `funcName` is provided, the schema will be a reference to the function schema. - * - * @param {string} [funcName] the name of the function to convert - * @returns {JSONSchema7} the converted JSON schema - * - * @throws {Error} if the contract spec is invalid - */ - jsonSchema(funcName?: string): JSONSchema7 { - let definitions: { [key: string]: JSONSchema7Definition } = {}; - for (let entry of this.entries) { - switch (entry.switch().value) { - case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0().value: { - let udt = entry.udtEnumV0(); - definitions[udt.name().toString()] = enumToJsonSchema(udt); - break; - } - case xdr.ScSpecEntryKind.scSpecEntryUdtStructV0().value: { - let udt = entry.udtStructV0(); - definitions[udt.name().toString()] = structToJsonSchema(udt); - break; - } - case xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0().value: - let udt = entry.udtUnionV0(); - definitions[udt.name().toString()] = unionToJsonSchema(udt); - break; - case xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value: { - let fn = entry.functionV0(); - let fnName = fn.name().toString(); - let { input } = functionToJsonSchema(fn); - // @ts-ignore - definitions[fnName] = input; - break; - } - case xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value: { - // console.debug("Error enums not supported yet"); - } - } - } - let res: JSONSchema7 = { - $schema: "http://json-schema.org/draft-07/schema#", - definitions: { ...PRIMITIVE_DEFINITONS, ...definitions }, - }; - if (funcName) { - res["$ref"] = `#/definitions/${funcName}`; - } - return res; - } -} - -function stringToScVal(str: string, ty: xdr.ScSpecType): xdr.ScVal { - switch (ty.value) { - case xdr.ScSpecType.scSpecTypeString().value: - return xdr.ScVal.scvString(str); - case xdr.ScSpecType.scSpecTypeSymbol().value: - return xdr.ScVal.scvSymbol(str); - case xdr.ScSpecType.scSpecTypeAddress().value: { - let addr = Address.fromString(str as string); - return xdr.ScVal.scvAddress(addr.toScAddress()); - } - case xdr.ScSpecType.scSpecTypeU64().value: - return new XdrLargeInt("u64", str).toScVal(); - case xdr.ScSpecType.scSpecTypeI64().value: - return new XdrLargeInt("i64", str).toScVal(); - case xdr.ScSpecType.scSpecTypeU128().value: - return new XdrLargeInt("u128", str).toScVal(); - case xdr.ScSpecType.scSpecTypeI128().value: - return new XdrLargeInt("i128", str).toScVal(); - case xdr.ScSpecType.scSpecTypeU256().value: - return new XdrLargeInt("u256", str).toScVal(); - case xdr.ScSpecType.scSpecTypeI256().value: - return new XdrLargeInt("i256", str).toScVal(); - case xdr.ScSpecType.scSpecTypeBytes().value: - case xdr.ScSpecType.scSpecTypeBytesN().value: - return xdr.ScVal.scvBytes(Buffer.from(str, "base64")); - - default: - throw new TypeError(`invalid type ${ty.name} specified for string value`); - } -} - -function isNumeric(field: xdr.ScSpecUdtStructFieldV0) { - return /^\d+$/.test(field.name().toString()); -} - -function findCase(name: string) { - return function matches(entry: xdr.ScSpecUdtUnionCaseV0) { - switch (entry.switch().value) { - case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value: { - let tuple = entry.tupleCase(); - return tuple.name().toString() === name; - } - case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0().value: { - let void_case = entry.voidCase(); - return void_case.name().toString() === name; - } - default: - return false; - } - }; -} - -const PRIMITIVE_DEFINITONS: { [key: string]: JSONSchema7Definition } = { - U32: { - type: "integer", - minimum: 0, - maximum: 4294967295, - }, - I32: { - type: "integer", - minimum: -2147483648, - maximum: 2147483647, - }, - U64: { - type: "string", - pattern: "^([1-9][0-9]*|0)$", - minLength: 1, - maxLength: 20, // 64-bit max value has 20 digits - }, - I64: { - type: "string", - pattern: "^(-?[1-9][0-9]*|0)$", - minLength: 1, - maxLength: 21, // Includes additional digit for the potential '-' - }, - U128: { - type: "string", - pattern: "^([1-9][0-9]*|0)$", - minLength: 1, - maxLength: 39, // 128-bit max value has 39 digits - }, - I128: { - type: "string", - pattern: "^(-?[1-9][0-9]*|0)$", - minLength: 1, - maxLength: 40, // Includes additional digit for the potential '-' - }, - U256: { - type: "string", - pattern: "^([1-9][0-9]*|0)$", - minLength: 1, - maxLength: 78, // 256-bit max value has 78 digits - }, - I256: { - type: "string", - pattern: "^(-?[1-9][0-9]*|0)$", - minLength: 1, - maxLength: 79, // Includes additional digit for the potential '-' - }, - Address: { - type: "string", - format: "address", - description: "Address can be a public key or contract id", - }, - ScString: { - type: "string", - description: "ScString is a string", - }, - ScSymbol: { - type: "string", - description: "ScString is a string", - }, - DataUrl: { - type: "string", - pattern: - "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=)?$", - }, -}; - -/** - * @param typeDef type to convert to json schema reference - * @returns {JSONSchema7} a schema describing the type - */ -function typeRef(typeDef: xdr.ScSpecTypeDef): JSONSchema7 { - let t = typeDef.switch(); - let value = t.value; - let ref; - switch (value) { - case xdr.ScSpecType.scSpecTypeVal().value: { - ref = "Val"; - break; - } - case xdr.ScSpecType.scSpecTypeBool().value: { - return { type: "boolean" }; - } - case xdr.ScSpecType.scSpecTypeVoid().value: { - return { type: "null" }; - } - case xdr.ScSpecType.scSpecTypeError().value: { - ref = "Error"; - break; - } - case xdr.ScSpecType.scSpecTypeU32().value: { - ref = "U32"; - break; - } - case xdr.ScSpecType.scSpecTypeI32().value: { - ref = "I32"; - break; - } - case xdr.ScSpecType.scSpecTypeU64().value: { - ref = "U64"; - break; - } - case xdr.ScSpecType.scSpecTypeI64().value: { - ref = "I64"; - break; - } - case xdr.ScSpecType.scSpecTypeTimepoint().value: { - throw new Error("Timepoint type not supported"); - ref = "Timepoint"; - break; - } - case xdr.ScSpecType.scSpecTypeDuration().value: { - throw new Error("Duration not supported"); - ref = "Duration"; - break; - } - case xdr.ScSpecType.scSpecTypeU128().value: { - ref = "U128"; - break; - } - case xdr.ScSpecType.scSpecTypeI128().value: { - ref = "I128"; - break; - } - case xdr.ScSpecType.scSpecTypeU256().value: { - ref = "U256"; - break; - } - case xdr.ScSpecType.scSpecTypeI256().value: { - ref = "I256"; - break; - } - case xdr.ScSpecType.scSpecTypeBytes().value: { - ref = "DataUrl"; - break; - } - case xdr.ScSpecType.scSpecTypeString().value: { - ref = "ScString"; - break; - } - case xdr.ScSpecType.scSpecTypeSymbol().value: { - ref = "ScSymbol"; - break; - } - case xdr.ScSpecType.scSpecTypeAddress().value: { - ref = "Address"; - break; - } - case xdr.ScSpecType.scSpecTypeOption().value: { - let opt = typeDef.option(); - return typeRef(opt.valueType()); + value !== xdr.ScSpecType.scSpecTypeSymbol().value + ) { + throw new Error( + `ScSpecType ${t.name + } was not string or symbol, but ${JSON.stringify(scv, null, 2)} is`, + ); + } + return scv.value()?.toString() as T; + } + + // these can be converted to bigint + case xdr.ScValType.scvTimepoint().value: + case xdr.ScValType.scvDuration().value: + return scValToBigInt(xdr.ScVal.scvU64(scv.u64())) as T; + + // in the fallthrough case, just return the underlying value directly + default: + throw new TypeError( + `failed to convert ${JSON.stringify( + scv, + null, + 2, + )} to native type from type ${t.name}`, + ); } - case xdr.ScSpecType.scSpecTypeResult().value: { - // throw new Error('Result type not supported'); - break; + /* eslint-enable no-fallthrough*/ + } + + private scValUdtToNative(scv: xdr.ScVal, udt: xdr.ScSpecTypeUdt): any { + const entry = this.findEntry(udt.name().toString()); + switch (entry.switch()) { + case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0(): + return this.enumToNative(scv); + case xdr.ScSpecEntryKind.scSpecEntryUdtStructV0(): + return this.structToNative(scv, entry.udtStructV0()); + case xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0(): + return this.unionToNative(scv, entry.udtUnionV0()); + default: + throw new Error( + `failed to parse udt ${udt.name().toString()}: ${entry}`, + ); } - case xdr.ScSpecType.scSpecTypeVec().value: { - let arr = typeDef.vec(); - let ref = typeRef(arr.elementType()); - return { - type: "array", - items: ref, - }; + } + + private unionToNative(val: xdr.ScVal, udt: xdr.ScSpecUdtUnionV0): any { + const vec = val.vec(); + if (!vec) { + throw new Error(`${JSON.stringify(val, null, 2)} is not a vec`); } - case xdr.ScSpecType.scSpecTypeMap().value: { - let map = typeDef.map(); - let items = [typeRef(map.keyType()), typeRef(map.valueType())]; - return { - type: "array", - items: { - type: "array", - items, - minItems: 2, - maxItems: 2, - }, - }; + if (vec.length === 0 && udt.cases.length !== 0) { + throw new Error( + `${val} has length 0, but the there are at least one case in the union`, + ); } - case xdr.ScSpecType.scSpecTypeTuple().value: { - let tuple = typeDef.tuple(); - let minItems = tuple.valueTypes().length; - let maxItems = minItems; - let items = tuple.valueTypes().map(typeRef); - return { type: "array", items, minItems, maxItems }; + const name = vec[0].sym().toString(); + if (vec[0].switch().value !== xdr.ScValType.scvSymbol().value) { + throw new Error(`{vec[0]} is not a symbol`); } - case xdr.ScSpecType.scSpecTypeBytesN().value: { - let arr = typeDef.bytesN(); - return { - $ref: "#/definitions/DataUrl", - maxLength: arr.n(), - }; + const entry = udt.cases().find(findCase(name)); + if (!entry) { + throw new Error( + `failed to find entry ${name} in union {udt.name().toString()}`, + ); } - case xdr.ScSpecType.scSpecTypeUdt().value: { - let udt = typeDef.udt(); - ref = udt.name().toString(); - break; + const res: Union = { tag: name }; + if ( + entry.switch().value === + xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value + ) { + const tuple = entry.tupleCase(); + const ty = tuple.type(); + const values = ty.map((e, i) => this.scValToNative(vec![i + 1], e)); + res.values = values; } + return res; } - return { $ref: `#/definitions/${ref}` }; -} - -type Func = { input: JSONSchema7; output: JSONSchema7 }; - -function isRequired(typeDef: xdr.ScSpecTypeDef): boolean { - return typeDef.switch().value != xdr.ScSpecType.scSpecTypeOption().value; -} -function structToJsonSchema(udt: xdr.ScSpecUdtStructV0): object { - let fields = udt.fields(); - if (fields.some(isNumeric)) { - if (!fields.every(isNumeric)) { - throw new Error( - "mixed numeric and non-numeric field names are not allowed", - ); + private structToNative(val: xdr.ScVal, udt: xdr.ScSpecUdtStructV0): any { + const res: any = {}; + const fields = udt.fields(); + if (fields.some(isNumeric)) { + const r = val + .vec() + ?.map((entry, i) => this.scValToNative(entry, fields[i].type())); + return r; } - let items = fields.map((_, i) => typeRef(fields[i].type())); - return { - type: "array", - items, - minItems: fields.length, - maxItems: fields.length, - }; + val.map()?.forEach((entry, i) => { + const field = fields[i]; + res[field.name().toString()] = this.scValToNative( + entry.val(), + field.type(), + ); + }); + return res; } - let description = udt.doc().toString(); - let { properties, required }: any = args_and_required(fields); - properties["additionalProperties"] = false; - return { - description, - properties, - required, - type: "object", - }; -} -function args_and_required( - input: { type: () => xdr.ScSpecTypeDef; name: () => string | Buffer }[], -): { properties: object; required?: string[] } { - let properties: any = {}; - let required: string[] = []; - for (let arg of input) { - let type_ = arg.type(); - let name = arg.name().toString(); - properties[name] = typeRef(type_); - if (isRequired(type_)) { - required.push(name); + private enumToNative(scv: xdr.ScVal): number { + if (scv.switch().value !== xdr.ScValType.scvU32().value) { + throw new Error(`Enum must have a u32 value`); } + const num = scv.u32(); + return num; } - let res: { properties: object; required?: string[] } = { properties }; - if (required.length > 0) { - res.required = required; - } - return res; -} -function functionToJsonSchema(func: xdr.ScSpecFunctionV0): Func { - let { properties, required }: any = args_and_required(func.inputs()); - let args: any = { - additionalProperties: false, - properties, - type: "object", - }; - if (required?.length > 0) { - args.required = required; - } - let input: Partial = { - properties: { - args, - }, - }; - let outputs = func.outputs(); - let output: Partial = - outputs.length > 0 - ? typeRef(outputs[0]) - : typeRef(xdr.ScSpecTypeDef.scSpecTypeVoid()); - let description = func.doc().toString(); - if (description.length > 0) { - input.description = description; + /** + * Gets the XDR error cases from the spec. + * + * @returns {xdr.ScSpecFunctionV0[]} all contract functions + * + */ + errorCases(): xdr.ScSpecUdtErrorEnumCaseV0[] { + return this.entries + .filter( + (entry) => + entry.switch().value === + xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value, + ) + .flatMap((entry) => (entry.value() as xdr.ScSpecUdtErrorEnumV0).cases()); } - input.additionalProperties = false; - output.additionalProperties = false; - return { - input, - output, - }; -} -function unionToJsonSchema(udt: xdr.ScSpecUdtUnionV0): any { - let description = udt.doc().toString(); - let cases = udt.cases(); - let oneOf: any[] = []; - for (let case_ of cases) { - switch (case_.switch().value) { - case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0().value: { - let c = case_.voidCase(); - let title = c.name().toString(); - oneOf.push({ - type: "object", - title, - properties: { - tag: title, - }, - additionalProperties: false, - required: ["tag"], - }); - break; - } - case xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value: { - let c = case_.tupleCase(); - let title = c.name().toString(); - oneOf.push({ - type: "object", - title, - properties: { - tag: title, - values: { - type: "array", - items: c.type().map(typeRef), - }, - }, - required: ["tag", "values"], - additionalProperties: false, - }); + /** + * Converts the contract spec to a JSON schema. + * + * If `funcName` is provided, the schema will be a reference to the function schema. + * + * @param {string} [funcName] the name of the function to convert + * @returns {JSONSchema7} the converted JSON schema + * + * @throws {Error} if the contract spec is invalid + */ + jsonSchema(funcName?: string): JSONSchema7 { + const definitions: { [key: string]: JSONSchema7Definition } = {}; + /* eslint-disable default-case */ + this.entries.forEach(entry => { + switch (entry.switch().value) { + case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0().value: { + const udt = entry.udtEnumV0(); + definitions[udt.name().toString()] = enumToJsonSchema(udt); + break; + } + case xdr.ScSpecEntryKind.scSpecEntryUdtStructV0().value: { + const udt = entry.udtStructV0(); + definitions[udt.name().toString()] = structToJsonSchema(udt); + break; + } + case xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0().value: { + const udt = entry.udtUnionV0(); + definitions[udt.name().toString()] = unionToJsonSchema(udt); + break; + } + case xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value: { + const fn = entry.functionV0(); + const fnName = fn.name().toString(); + const { input } = functionToJsonSchema(fn); + // @ts-ignore + definitions[fnName] = input; + break; + } + case xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value: { + // console.debug("Error enums not supported yet"); + } } + }); + /* eslint-enable default-case */ + const res: JSONSchema7 = { + $schema: "http://json-schema.org/draft-07/schema#", + definitions: { ...PRIMITIVE_DEFINITONS, ...definitions }, + }; + if (funcName) { + res.$ref = `#/definitions/${funcName}`; } + return res; } - - let res: any = { - oneOf, - }; - if (description.length > 0) { - res.description = description; - } - return res; } -function enumToJsonSchema(udt: xdr.ScSpecUdtEnumV0): any { - let description = udt.doc().toString(); - let cases = udt.cases(); - let oneOf: any[] = []; - for (let case_ of cases) { - let title = case_.name().toString(); - let description = case_.doc().toString(); - oneOf.push({ - description, - title, - enum: [case_.value()], - type: "number", - }); - } - - let res: any = { oneOf }; - if (description.length > 0) { - res.description = description; - } - return res; -} diff --git a/src/contract/types.ts b/src/contract/types.ts index d329bd0da..b97231b55 100644 --- a/src/contract/types.ts +++ b/src/contract/types.ts @@ -3,7 +3,6 @@ import { BASE_FEE, Memo, MemoType, Operation, Transaction, xdr } from "@stellar/stellar-base"; import type { Client } from "./client"; import type { AssembledTransaction } from "./assembled_transaction"; -import { DEFAULT_TIMEOUT } from "./utils"; export type XDR_BASE64 = string; export type u32 = number; @@ -123,3 +122,9 @@ export type AssembledTransactionOptions = MethodOptions & args?: any[]; parseResultXdr: (xdr: xdr.ScVal) => T; }; + +/** + * The default timeout for waiting for a transaction to be included in a block. + */ +export const DEFAULT_TIMEOUT = 5 * 60; +export const NULL_ACCOUNT = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"; diff --git a/src/contract/utils.ts b/src/contract/utils.ts index db99d7cbb..b3a131cb7 100644 --- a/src/contract/utils.ts +++ b/src/contract/utils.ts @@ -1,13 +1,7 @@ import { xdr, cereal, Account } from "@stellar/stellar-base"; import { Server } from "../rpc/server"; -import { NULL_ACCOUNT, type AssembledTransaction } from "./assembled_transaction"; -import { AssembledTransactionOptions } from "./types"; - - -/** - * The default timeout for waiting for a transaction to be included in a block. - */ -export const DEFAULT_TIMEOUT = 5 * 60; +import { type AssembledTransaction } from "./assembled_transaction"; +import { NULL_ACCOUNT , AssembledTransactionOptions } from "./types"; /** * Keep calling a `fn` for `timeoutInSeconds` seconds, if `keepWaitingIf` is @@ -111,11 +105,12 @@ export function processSpecEntryStream(buffer: Buffer) { return res; } +//eslint-disable-next-line require-await export async function getAccount( options: AssembledTransactionOptions, server: Server ): Promise { return options.publicKey - ? await server.getAccount(options.publicKey) + ? server.getAccount(options.publicKey) : new Account(NULL_ACCOUNT, "0"); } diff --git a/src/errors.ts b/src/errors.ts index b84f72162..21f877aff 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,7 +1,9 @@ +/* eslint-disable max-classes-per-file */ import { HorizonApi } from "./horizon/horizon_api"; // For ES5 compatibility (https://stackoverflow.com/a/55066280). /* tslint:disable:variable-name max-classes-per-file */ +/* eslint-disable no-proto */ export class NetworkError extends Error { public response: { @@ -10,6 +12,7 @@ export class NetworkError extends Error { statusText?: string; url?: string; }; + public __proto__: NetworkError; constructor(message: string, response: any) { @@ -72,10 +75,12 @@ export class BadResponseError extends NetworkError { */ export class AccountRequiresMemoError extends Error { public __proto__: AccountRequiresMemoError; + /** * accountId account which requires a memo. */ public accountId: string; + /** * operationIndex operation where accountId is the destination. */ diff --git a/src/federation/server.ts b/src/federation/server.ts index 06d88fc87..5f032c18e 100644 --- a/src/federation/server.ts +++ b/src/federation/server.ts @@ -1,3 +1,4 @@ +/* eslint-disable require-await */ import axios from "axios"; import { StrKey } from "@stellar/stellar-base"; import URI from "urijs"; @@ -15,7 +16,7 @@ export const FEDERATION_RESPONSE_MAX_SIZE = 100 * 1024; * FederationServer handles a network connection to a * [federation server](https://developers.stellar.org/docs/glossary/federation/) * instance and exposes an interface for requests to that instance. - * @constructor + * @class * @param {string} serverURL The federation server URL (ex. `https://acme.com/federation`). * @param {string} domain Domain this server represents * @param {object} [opts] options object @@ -30,6 +31,7 @@ export class FederationServer { * @memberof FederationServer */ private readonly serverURL: URI; // TODO: public or private? readonly? + /** * Domain this server represents. * @@ -37,6 +39,7 @@ export class FederationServer { * @memberof FederationServer */ private readonly domain: string; // TODO: public or private? readonly? + /** * Allow a timeout, default: 0. Allows user to avoid nasty lag due to TOML resolve issue. * diff --git a/src/horizon/account_call_builder.ts b/src/horizon/account_call_builder.ts index 06997053a..58b876c1a 100644 --- a/src/horizon/account_call_builder.ts +++ b/src/horizon/account_call_builder.ts @@ -8,8 +8,8 @@ import { ServerApi } from "./server_api"; * * @see [All Accounts](https://developers.stellar.org/api/resources/accounts/) * @class AccountCallBuilder - * @extends CallBuilder - * @constructor + * @augments CallBuilder + * @class * @param {string} serverUrl Horizon server URL. */ export class AccountCallBuilder extends CallBuilder< diff --git a/src/horizon/account_response.ts b/src/horizon/account_response.ts index 376e9a197..def7ecccb 100644 --- a/src/horizon/account_response.ts +++ b/src/horizon/account_response.ts @@ -1,6 +1,7 @@ /* tslint:disable:variable-name */ import { Account as BaseAccount } from "@stellar/stellar-base"; +import type { TransactionBuilder } from "@stellar/stellar-base"; import { HorizonApi } from "./horizon_api"; import { ServerApi } from "./server_api"; @@ -9,7 +10,7 @@ import { ServerApi } from "./server_api"; * * Returns information and links relating to a single account. * The balances section in the returned JSON will also list all the trust lines this account has set up. - * It also contains {@link Account} object and exposes it's methods so can be used in {@link TransactionBuilder}. + * It also contains {@link BaseAccount} object and exposes it's methods so can be used in {@link TransactionBuilder}. * * @see [Account Details](https://developers.stellar.org/api/resources/accounts/object/) * @param {string} response Response from horizon account endpoint. diff --git a/src/horizon/assets_call_builder.ts b/src/horizon/assets_call_builder.ts index 29d63200a..591bf7a37 100644 --- a/src/horizon/assets_call_builder.ts +++ b/src/horizon/assets_call_builder.ts @@ -6,8 +6,8 @@ import { ServerApi } from "./server_api"; * * Do not create this object directly, use {@link Server#assets}. * @class AssetsCallBuilder - * @constructor - * @extends CallBuilder + * @class + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class AssetsCallBuilder extends CallBuilder< diff --git a/src/horizon/call_builder.ts b/src/horizon/call_builder.ts index d8c6f8ec4..4006fbf46 100644 --- a/src/horizon/call_builder.ts +++ b/src/horizon/call_builder.ts @@ -6,6 +6,7 @@ import { BadRequestError, NetworkError, NotFoundError } from "../errors"; import { HorizonApi } from "./horizon_api"; import { AxiosClient, version } from "./horizon_axios_client"; import { ServerApi } from "./server_api"; +import type { Server } from "../federation"; // Resources which can be included in the Horizon response via the `join` // query-param. @@ -20,7 +21,9 @@ export interface EventSourceOptions { const anyGlobal = global as any; type Constructable = new (e: string) => T; // require("eventsource") for Node and React Native environment -let EventSource: Constructable = anyGlobal.EventSource ?? +/* eslint-disable global-require */ +/* eslint-disable prefer-import/prefer-import-over-require */ +const EventSource: Constructable = anyGlobal.EventSource ?? anyGlobal.window?.EventSource ?? require("eventsource"); @@ -38,8 +41,11 @@ export class CallBuilder< | ServerApi.CollectionPage > { protected url: URI; + public filter: string[][]; + protected originalSegments: string[]; + protected neighborRoot: string; constructor(serverUrl: URI, neighborRoot: string = "") { @@ -82,10 +88,10 @@ export class CallBuilder< * @see [Horizon Response Format](https://developers.stellar.org/api/introduction/response-format/) * @see [MDN EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) * @param {object} [options] EventSource options. - * @param {function} [options.onmessage] Callback function to handle incoming messages. - * @param {function} [options.onerror] Callback function to handle errors. + * @param {Function} [options.onmessage] Callback function to handle incoming messages. + * @param {Function} [options.onerror] Callback function to handle errors. * @param {number} [options.reconnectTimeout] Custom stream connection timeout in ms, default is 15 seconds. - * @returns {function} Close function. Run to close the connection and stop listening for new events. + * @returns {Function} Close function. Run to close the connection and stop listening for new events. */ public stream(options: EventSourceOptions = {}): () => void { this.checkFilter(); @@ -104,11 +110,12 @@ export class CallBuilder< const createTimeout = () => { timeout = setTimeout(() => { es?.close(); + // eslint-disable-next-line @typescript-eslint/no-use-before-define es = createEventSource(); }, options.reconnectTimeout || 15 * 1000); }; - let createEventSource = (): EventSource => { + const createEventSource = (): EventSource => { try { es = new EventSource(this.url.toString()); } catch (err) { @@ -174,6 +181,8 @@ export class CallBuilder< return es; }; + + createEventSource(); return () => { clearTimeout(timeout); @@ -195,7 +204,7 @@ export class CallBuilder< /** * Sets `limit` parameter for the current call. Returns the CallBuilder object on which this method has been called. * @see [Paging](https://developers.stellar.org/api/introduction/pagination/) - * @param {number} number Number of records the server should return. + * @param {number} recordsNumber Number of records the server should return. * @returns {object} current CallBuilder instance */ public limit(recordsNumber: number): this { @@ -221,7 +230,7 @@ export class CallBuilder< * will include a `transaction` field for each operation in the * response. * - * @param {"transactions"} join Records to be included in the response. + * @param "include" join Records to be included in the response. * @returns {object} current CallBuilder instance. */ public join(include: "transactions"): this { @@ -272,9 +281,9 @@ export class CallBuilder< * Convert a link object to a function that fetches that link. * @private * @param {object} link A link object - * @param {bool} link.href the URI of the link - * @param {bool} [link.templated] Whether the link is templated - * @returns {function} A function that requests the link + * @param {boolean} link.href the URI of the link + * @param {boolean} [link.templated] Whether the link is templated + * @returns {Function} A function that requests the link */ private _requestFnForLink(link: HorizonApi.ResponseLink): (opts?: any) => any { return async (opts: any = {}) => { @@ -303,7 +312,7 @@ export class CallBuilder< if (!json._links) { return json; } - for (const key of Object.keys(json._links)) { + Object.keys(json._links).forEach((key) => { const n = json._links[key]; let included = false; // If the key with the link name already exists, create a copy @@ -323,14 +332,16 @@ export class CallBuilder< const record = this._parseRecord(json[key]); // Maintain a promise based API so the behavior is the same whether you // are loading from the server or in-memory (via join). + // eslint-disable-next-line require-await json[key] = async () => record; } else { json[key] = this._requestFnForLink(n as HorizonApi.ResponseLink); } - } + }); return json; } + // eslint-disable-next-line require-await private async _sendNormalRequest(initialUrl: URI) { let url = initialUrl; @@ -386,6 +397,7 @@ export class CallBuilder< * @param {object} error Network error object * @returns {Promise} Promise that rejects with a human-readable error */ + // eslint-disable-next-line require-await private async _handleNetworkError(error: NetworkError): Promise { if (error.response && error.response.status && error.response.statusText) { switch (error.response.status) { diff --git a/src/horizon/claimable_balances_call_builder.ts b/src/horizon/claimable_balances_call_builder.ts index bf515702a..3d94fd390 100644 --- a/src/horizon/claimable_balances_call_builder.ts +++ b/src/horizon/claimable_balances_call_builder.ts @@ -8,8 +8,8 @@ import { ServerApi } from "./server_api"; * * @see [Claimable Balances](https://developers.stellar.org/api/resources/claimablebalances/) * @class ClaimableBalanceCallBuilder - * @constructor - * @extends CallBuilder + * @class + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class ClaimableBalanceCallBuilder extends CallBuilder< @@ -65,7 +65,7 @@ export class ClaimableBalanceCallBuilder extends CallBuilder< * Returns all claimable balances which provide a balance for the given asset. * * @see [Claimable Balances](https://developers.stellar.org/api/resources/claimablebalances/list/) - * @param {Asset} The Asset held by the claimable balance + * @param {Asset} asset The Asset held by the claimable balance * @returns {ClaimableBalanceCallBuilder} current ClaimableBalanceCallBuilder instance */ public asset(asset: Asset): this { diff --git a/src/horizon/effect_call_builder.ts b/src/horizon/effect_call_builder.ts index d6db8cc28..01ebaad71 100644 --- a/src/horizon/effect_call_builder.ts +++ b/src/horizon/effect_call_builder.ts @@ -6,9 +6,9 @@ import { ServerApi } from "./server_api"; * Do not create this object directly, use {@link Server#effects}. * * @class EffectCallBuilder - * @extends CallBuilder + * @augments CallBuilder * @see [All Effects](https://developers.stellar.org/api/resources/effects/) - * @constructor + * @class * @param {string} serverUrl Horizon server URL. */ export class EffectCallBuilder extends CallBuilder< diff --git a/src/horizon/horizon_axios_client.ts b/src/horizon/horizon_axios_client.ts index a76da401f..7643b1db5 100644 --- a/src/horizon/horizon_axios_client.ts +++ b/src/horizon/horizon_axios_client.ts @@ -1,7 +1,8 @@ +/* eslint-disable global-require */ import axios, { AxiosResponse } from "axios"; import URI from "urijs"; -/* tslint:disable-next-line:no-var-requires */ +// eslint-disable-next-line prefer-import/prefer-import-over-require export const version = require("../../package.json").version; export interface ServerTime { @@ -30,17 +31,17 @@ export const AxiosClient = axios.create({ }, }); -function _toSeconds(ms: number): number { +function toSeconds(ms: number): number { return Math.floor(ms / 1000); } AxiosClient.interceptors.response.use( - function interceptorHorizonResponse(response: AxiosResponse) { + (response: AxiosResponse) => { const hostname = URI(response.config.url!).hostname(); - const serverTime = _toSeconds(Date.parse(response.headers.date)); - const localTimeRecorded = _toSeconds(new Date().getTime()); + const serverTime = toSeconds(Date.parse(response.headers.date)); + const localTimeRecorded = toSeconds(new Date().getTime()); - if (!isNaN(serverTime)) { + if (!Number.isNaN(serverTime)) { SERVER_TIME_MAP[hostname] = { serverTime, localTimeRecorded, @@ -70,7 +71,7 @@ export function getCurrentServerTime(hostname: string): number | null { } const { serverTime, localTimeRecorded } = entry; - const currentTime = _toSeconds(new Date().getTime()); + const currentTime = toSeconds(new Date().getTime()); // if it's been more than 5 minutes from the last time, then null it out if (currentTime - localTimeRecorded > 60 * 5) { diff --git a/src/horizon/ledger_call_builder.ts b/src/horizon/ledger_call_builder.ts index 5e74a85b5..43ef4aa53 100644 --- a/src/horizon/ledger_call_builder.ts +++ b/src/horizon/ledger_call_builder.ts @@ -6,9 +6,9 @@ import { ServerApi } from "./server_api"; * Do not create this object directly, use {@link Server#ledgers}. * * @see [All Ledgers](https://developers.stellar.org/api/resources/ledgers/list/) - * @constructor + * @class * @class LedgerCallBuilder - * @extends CallBuilder + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class LedgerCallBuilder extends CallBuilder< diff --git a/src/horizon/liquidity_pool_call_builder.ts b/src/horizon/liquidity_pool_call_builder.ts index f6c24b1f5..25798988e 100644 --- a/src/horizon/liquidity_pool_call_builder.ts +++ b/src/horizon/liquidity_pool_call_builder.ts @@ -8,8 +8,8 @@ import { ServerApi } from "./server_api"; * Do not create this object directly, use {@link Server#liquidityPools}. * * @class LiquidityPoolCallBuilder - * @extends CallBuilder - * @constructor + * @augments CallBuilder + * @class * @param {string} serverUrl Horizon server URL. */ export class LiquidityPoolCallBuilder extends CallBuilder< @@ -24,7 +24,6 @@ export class LiquidityPoolCallBuilder extends CallBuilder< * Filters out pools whose reserves don't exactly match these assets. * * @see Asset - * @param {Asset[]} assets * @returns {LiquidityPoolCallBuilder} current LiquidityPoolCallBuilder instance */ public forAssets(...assets: Asset[]): this { diff --git a/src/horizon/offer_call_builder.ts b/src/horizon/offer_call_builder.ts index 4d40b1a4b..beeb5520f 100644 --- a/src/horizon/offer_call_builder.ts +++ b/src/horizon/offer_call_builder.ts @@ -8,8 +8,8 @@ import { ServerApi } from "./server_api"; * * @see [Offers](https://developers.stellar.org/api/resources/offers/) * @class OfferCallBuilder - * @constructor - * @extends CallBuilder + * @class + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class OfferCallBuilder extends CallBuilder< diff --git a/src/horizon/operation_call_builder.ts b/src/horizon/operation_call_builder.ts index e7573e7ba..04da7127f 100644 --- a/src/horizon/operation_call_builder.ts +++ b/src/horizon/operation_call_builder.ts @@ -7,8 +7,8 @@ import { ServerApi } from "./server_api"; * * @see [All Operations](https://developers.stellar.org/api/resources/operations/) * @class OperationCallBuilder - * @constructor - * @extends CallBuilder + * @class + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class OperationCallBuilder extends CallBuilder< @@ -91,7 +91,7 @@ export class OperationCallBuilder extends CallBuilder< * Adds a parameter defining whether to include failed transactions. * By default, only operations of successful transactions are returned. * - * @param {bool} value Set to `true` to include operations of failed transactions. + * @param {boolean} value Set to `true` to include operations of failed transactions. * @returns {OperationCallBuilder} this OperationCallBuilder instance */ public includeFailed(value: boolean): this { diff --git a/src/horizon/path_call_builder.ts b/src/horizon/path_call_builder.ts index 4999e07d8..7b2d40b59 100644 --- a/src/horizon/path_call_builder.ts +++ b/src/horizon/path_call_builder.ts @@ -19,7 +19,7 @@ import { ServerApi } from "./server_api"; * * Do not create this object directly, use {@link Server#paths}. * @see [Find Payment Paths](https://developers.stellar.org/api/aggregations/paths/) - * @extends CallBuilder + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. * @param {string} source The sender's account ID. Any returned path must use a source that the sender can hold. * @param {string} destination The destination account ID that any returned path should use. diff --git a/src/horizon/payment_call_builder.ts b/src/horizon/payment_call_builder.ts index 82e103fb1..1e5c8cb6b 100644 --- a/src/horizon/payment_call_builder.ts +++ b/src/horizon/payment_call_builder.ts @@ -6,8 +6,8 @@ import { ServerApi } from "./server_api"; * * Do not create this object directly, use {@link Server#payments}. * @see [All Payments](https://developers.stellar.org/api/horizon/resources/list-all-payments/) - * @constructor - * @extends CallBuilder + * @class + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. */ export class PaymentCallBuilder extends CallBuilder< diff --git a/src/horizon/server.ts b/src/horizon/server.ts index e039994b3..5e937cd7e 100644 --- a/src/horizon/server.ts +++ b/src/horizon/server.ts @@ -10,6 +10,7 @@ import { } from "@stellar/stellar-base"; import URI from "urijs"; +import type { TransactionBuilder } from "@stellar/stellar-base"; import { CallBuilder } from "./call_builder"; import { Config } from "../config"; import { @@ -37,7 +38,7 @@ import { StrictSendPathCallBuilder } from "./strict_send_path_call_builder"; import { TradeAggregationCallBuilder } from "./trade_aggregation_call_builder"; import { TradesCallBuilder } from "./trades_call_builder"; import { TransactionCallBuilder } from "./transaction_call_builder"; - +// eslint-disable-next-line import/no-named-as-default import AxiosClient, { getCurrentServerTime, } from "./horizon_axios_client"; @@ -50,14 +51,14 @@ const STROOPS_IN_LUMEN = 10000000; // SEP 29 uses this value to define transaction memo requirements for incoming payments. const ACCOUNT_REQUIRES_MEMO = "MQ=="; -function _getAmountInLumens(amt: BigNumber) { +function getAmountInLumens(amt: BigNumber) { return new BigNumber(amt).div(STROOPS_IN_LUMEN).toString(); } /** * Server handles the network connection to a [Horizon](https://developers.stellar.org/api/introduction/) * instance and exposes an interface for requests to that instance. - * @constructor + * @class * @param {string} serverURL Horizon Server URL (ex. `https://horizon-testnet.stellar.org`). * @param {object} [opts] Options object * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! You can also use {@link Config} class to set this globally. @@ -134,10 +135,10 @@ export class Server { * // earlier does the trick! * .build(); * ``` - * @argument {number} seconds Number of seconds past the current time to wait. - * @argument {bool} [_isRetry=false] True if this is a retry. Only set this internally! + * @param {number} seconds Number of seconds past the current time to wait. + * @param {boolean} [_isRetry] True if this is a retry. Only set this internally! * This is to avoid a scenario where Horizon is horking up the wrong date. - * @returns {Promise} Promise that resolves a `timebounds` object + * @returns {Promise} Promise that resolves a `timebounds` object * (with the shape `{ minTime: 0, maxTime: N }`) that you can set the `timebounds` option to. */ public async fetchTimebounds( @@ -165,7 +166,7 @@ export class Server { // otherwise, retry (by calling the root endpoint) // toString automatically adds the trailing slash await AxiosClient.get(URI(this.serverURL as any).toString()); - return await this.fetchTimebounds(seconds, true); + return this.fetchTimebounds(seconds, true); } /** @@ -185,6 +186,7 @@ export class Server { * @see [Fee Stats](https://developers.stellar.org/api/aggregations/fee-stats/) * @returns {Promise} Promise that resolves to the fee stats returned by Horizon. */ + // eslint-disable-next-line require-await public async feeStats(): Promise { const cb = new CallBuilder( URI(this.serverURL as any), @@ -287,8 +289,7 @@ export class Server { * * If `wasPartiallyFilled` is true, you can tell the user that * `amountBought` or `amountSold` have already been transferred. * - * @see [Post - * Transaction](https://developers.stellar.org/api/resources/transactions/post/) + * @see [PostTransaction](https://developers.stellar.org/api/resources/transactions/post/) * @param {Transaction|FeeBumpTransaction} transaction - The transaction to submit. * @param {object} [opts] Options object * @param {boolean} [opts.skipMemoRequiredCheck] - Allow skipping memo @@ -380,8 +381,8 @@ export class Server { // However, you can never be too careful. default: throw new Error( - "Invalid offer result type: " + - offerClaimedAtom.switch(), + `Invalid offer result type: ${ + offerClaimedAtom.switch()}`, ); } @@ -423,9 +424,9 @@ export class Server { sellerId, offerId: offerClaimed.offerId().toString(), assetSold, - amountSold: _getAmountInLumens(claimedOfferAmountSold), + amountSold: getAmountInLumens(claimedOfferAmountSold), assetBought, - amountBought: _getAmountInLumens(claimedOfferAmountBought), + amountBought: getAmountInLumens(claimedOfferAmountBought), }; }); @@ -443,7 +444,7 @@ export class Server { offerId: offerXDR.offerId().toString(), selling: {}, buying: {}, - amount: _getAmountInLumens(offerXDR.amount().toString()), + amount: getAmountInLumens(offerXDR.amount().toString()), price: { n: offerXDR.price().n(), d: offerXDR.price().d(), @@ -474,8 +475,8 @@ export class Server { currentOffer, // this value is in stroops so divide it out - amountBought: _getAmountInLumens(amountBought), - amountSold: _getAmountInLumens(amountSold), + amountBought: getAmountInLumens(amountBought), + amountSold: getAmountInLumens(amountSold), isFullyOpen: !offersClaimed.length && effect !== "manageOfferDeleted", @@ -491,9 +492,7 @@ export class Server { .filter((result: any) => !!result); } - return Object.assign({}, response.data, { - offerResults: hasManageOffer ? offerResults : undefined, - }); + return { ...response.data, offerResults: hasManageOffer ? offerResults : undefined,}; }) .catch((response) => { if (response instanceof Error) { @@ -713,10 +712,10 @@ export class Server { * * @param {Asset} base base asset * @param {Asset} counter counter asset - * @param {long} start_time lower time boundary represented as millis since epoch - * @param {long} end_time upper time boundary represented as millis since epoch - * @param {long} resolution segment duration as millis since epoch. *Supported values are 5 minutes (300000), 15 minutes (900000), 1 hour (3600000), 1 day (86400000) and 1 week (604800000). - * @param {long} offset segments can be offset using this parameter. Expressed in milliseconds. *Can only be used if the resolution is greater than 1 hour. Value must be in whole hours, less than the provided resolution, and less than 24 hours. + * @param {number} start_time lower time boundary represented as millis since epoch + * @param {number} end_time upper time boundary represented as millis since epoch + * @param {number} resolution segment duration as millis since epoch. *Supported values are 5 minutes (300000), 15 minutes (900000), 1 hour (3600000), 1 day (86400000) and 1 week (604800000). + * @param {number} offset segments can be offset using this parameter. Expressed in milliseconds. *Can only be used if the resolution is greater than 1 hour. Value must be in whole hours, less than the provided resolution, and less than 24 hours. * Returns new {@link TradeAggregationCallBuilder} object configured with the current Horizon server configuration. * @returns {TradeAggregationCallBuilder} New TradeAggregationCallBuilder instance */ @@ -769,7 +768,8 @@ export class Server { const destinations = new Set(); - for (let i = 0; i < transaction.operations.length; i++) { + /* eslint-disable no-continue */ + for (let i = 0; i < transaction.operations.length; i+=1) { const operation = transaction.operations[i]; switch (operation.type) { @@ -793,6 +793,7 @@ export class Server { } try { + // eslint-disable-next-line no-await-in-loop const account = await this.loadAccount(destination); if ( account.data_attr["config.memo_required"] === ACCOUNT_REQUIRES_MEMO @@ -816,6 +817,7 @@ export class Server { continue; } } + /* eslint-enable no-continue */ } } diff --git a/src/horizon/server_api.ts b/src/horizon/server_api.ts index 049f98b04..b567498e7 100644 --- a/src/horizon/server_api.ts +++ b/src/horizon/server_api.ts @@ -182,6 +182,7 @@ export namespace ServerApi { import OperationResponseType = HorizonApi.OperationResponseType; import OperationResponseTypeI = HorizonApi.OperationResponseTypeI; + export interface BaseOperationRecord< T extends OperationResponseType = OperationResponseType, TI extends OperationResponseTypeI = OperationResponseTypeI diff --git a/src/horizon/strict_receive_path_call_builder.ts b/src/horizon/strict_receive_path_call_builder.ts index b44876780..a809c8296 100644 --- a/src/horizon/strict_receive_path_call_builder.ts +++ b/src/horizon/strict_receive_path_call_builder.ts @@ -23,7 +23,7 @@ import { ServerApi } from "./server_api"; * * Do not create this object directly, use {@link Server#strictReceivePaths}. * @see [Find Payment Paths](https://developers.stellar.org/api/aggregations/paths/) - * @extends CallBuilder + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. * @param {string|Asset[]} source The sender's account ID or a list of Assets. Any returned path must use a source that the sender can hold. * @param {Asset} destinationAsset The destination asset. diff --git a/src/horizon/strict_send_path_call_builder.ts b/src/horizon/strict_send_path_call_builder.ts index da840374b..523e700de 100644 --- a/src/horizon/strict_send_path_call_builder.ts +++ b/src/horizon/strict_send_path_call_builder.ts @@ -22,7 +22,7 @@ import { ServerApi } from "./server_api"; * * Do not create this object directly, use {@link Server#strictSendPaths}. * @see [Find Payment Paths](https://developers.stellar.org/api/aggregations/paths/) - * @extends CallBuilder + * @augments CallBuilder * @param {string} serverUrl Horizon server URL. * @param {Asset} sourceAsset The asset to be sent. * @param {string} sourceAmount The amount, denominated in the source asset, that any returned path should be able to satisfy. diff --git a/src/horizon/trade_aggregation_call_builder.ts b/src/horizon/trade_aggregation_call_builder.ts index 8dfff4f69..f20d0a34a 100644 --- a/src/horizon/trade_aggregation_call_builder.ts +++ b/src/horizon/trade_aggregation_call_builder.ts @@ -19,15 +19,15 @@ const allowedResolutions = [ * Do not create this object directly, use {@link Server#tradeAggregation}. * * @class TradeAggregationCallBuilder - * @extends CallBuilder - * @constructor + * @augments CallBuilder + * @class * @param {string} serverUrl serverUrl Horizon server URL. * @param {Asset} base base asset * @param {Asset} counter counter asset - * @param {long} start_time lower time boundary represented as millis since epoch - * @param {long} end_time upper time boundary represented as millis since epoch - * @param {long} resolution segment duration as millis since epoch. *Supported values are 1 minute (60000), 5 minutes (300000), 15 minutes (900000), 1 hour (3600000), 1 day (86400000) and 1 week (604800000). - * @param {long} offset segments can be offset using this parameter. Expressed in milliseconds. *Can only be used if the resolution is greater than 1 hour. Value must be in whole hours, less than the provided resolution, and less than 24 hours. + * @param {number} start_time lower time boundary represented as millis since epoch + * @param {number} end_time upper time boundary represented as millis since epoch + * @param {number} resolution segment duration as millis since epoch. *Supported values are 1 minute (60000), 5 minutes (300000), 15 minutes (900000), 1 hour (3600000), 1 day (86400000) and 1 week (604800000). + * @param {number} offset segments can be offset using this parameter. Expressed in milliseconds. *Can only be used if the resolution is greater than 1 hour. Value must be in whole hours, less than the provided resolution, and less than 24 hours. */ export class TradeAggregationCallBuilder extends CallBuilder< ServerApi.CollectionPage @@ -78,22 +78,17 @@ export class TradeAggregationCallBuilder extends CallBuilder< /** * @private - * @param {long} resolution Trade data resolution in milliseconds + * @param {number} resolution Trade data resolution in milliseconds * @returns {boolean} true if the resolution is allowed */ private isValidResolution(resolution: number): boolean { - for (const allowed of allowedResolutions) { - if (allowed === resolution) { - return true; - } - } - return false; + return allowedResolutions.some((allowed) => allowed === resolution); } /** * @private - * @param {long} offset Time offset in milliseconds - * @param {long} resolution Trade data resolution in milliseconds + * @param {number} offset Time offset in milliseconds + * @param {number} resolution Trade data resolution in milliseconds * @returns {boolean} true if the offset is valid */ private isValidOffset(offset: number, resolution: number): boolean { diff --git a/src/horizon/trades_call_builder.ts b/src/horizon/trades_call_builder.ts index 8c601454d..afddd372c 100644 --- a/src/horizon/trades_call_builder.ts +++ b/src/horizon/trades_call_builder.ts @@ -7,8 +7,8 @@ import { ServerApi } from "./server_api"; * Do not create this object directly, use {@link Server#trades}. * * @class TradesCallBuilder - * @extends CallBuilder - * @constructor + * @augments CallBuilder + * @class * @see [Trades](https://developers.stellar.org/api/resources/trades/) * @param {string} serverUrl serverUrl Horizon server URL. */ diff --git a/src/horizon/transaction_call_builder.ts b/src/horizon/transaction_call_builder.ts index 831c4ee6f..5dd24a3eb 100644 --- a/src/horizon/transaction_call_builder.ts +++ b/src/horizon/transaction_call_builder.ts @@ -6,9 +6,9 @@ import { ServerApi } from "./server_api"; * Do not create this object directly, use {@link Server#transactions}. * * @class TransactionCallBuilder - * @extends CallBuilder + * @augments CallBuilder * @see [All Transactions](https://developers.stellar.org/api/resources/transactions/) - * @constructor + * @class * @param {string} serverUrl Horizon server URL. */ export class TransactionCallBuilder extends CallBuilder< @@ -78,7 +78,7 @@ export class TransactionCallBuilder extends CallBuilder< /** * Adds a parameter defining whether to include failed transactions. By default only successful transactions are * returned. - * @param {bool} value Set to `true` to include failed transactions. + * @param {boolean} value Set to `true` to include failed transactions. * @returns {TransactionCallBuilder} current TransactionCallBuilder instance */ public includeFailed(value: boolean): this { diff --git a/src/horizon/types/assets.ts b/src/horizon/types/assets.ts index 76708718c..844e76d63 100644 --- a/src/horizon/types/assets.ts +++ b/src/horizon/types/assets.ts @@ -1,5 +1,5 @@ import { AssetType } from "@stellar/stellar-base"; -import { HorizonApi } from "./../horizon_api"; +import { HorizonApi } from "../horizon_api"; export interface AssetRecord extends HorizonApi.BaseResponse { asset_type: AssetType.credit4 | AssetType.credit12; diff --git a/src/horizon/types/effects.ts b/src/horizon/types/effects.ts index 7742295d8..f7d0c8af7 100644 --- a/src/horizon/types/effects.ts +++ b/src/horizon/types/effects.ts @@ -1,4 +1,4 @@ -import { HorizonApi } from "./../horizon_api"; +import { HorizonApi } from "../horizon_api"; import { OfferAsset } from "./offer"; // Reference: GO SDK https://github.com/stellar/go/blob/ec5600bd6b2b6900d26988ff670b9ca7992313b8/services/horizon/internal/resourceadapter/effects.go diff --git a/src/horizon/types/offer.ts b/src/horizon/types/offer.ts index 9a0de5000..7331664bb 100644 --- a/src/horizon/types/offer.ts +++ b/src/horizon/types/offer.ts @@ -1,5 +1,5 @@ import { AssetType } from "@stellar/stellar-base"; -import { HorizonApi } from "./../horizon_api"; +import { HorizonApi } from "../horizon_api"; export interface OfferAsset { asset_type: AssetType; diff --git a/src/rpc/api.ts b/src/rpc/api.ts index 25591b379..42c97348b 100644 --- a/src/rpc/api.ts +++ b/src/rpc/api.ts @@ -26,13 +26,14 @@ export namespace Api { key: string; /** a base-64 encoded {@link xdr.LedgerEntryData} instance */ xdr: string; - /** optional, a future ledger number upon which this entry will expire + /** + * optional, a future ledger number upon which this entry will expire * based on https://github.com/stellar/soroban-tools/issues/1010 */ liveUntilLedgerSeq?: number; } - /** An XDR-parsed version of {@link RawLedgerEntryResult} */ + /** An XDR-parsed version of {@link this.RawLedgerEntryResult} */ export interface GetLedgerEntriesResponse { entries: LedgerEntryResult[]; latestLedger: number; @@ -226,7 +227,7 @@ export namespace Api { } /** - * Simplifies {@link RawSimulateTransactionResponse} into separate interfaces + * Simplifies {@link Api.RawSimulateTransactionResponse} into separate interfaces * based on status: * - on success, this includes all fields, though `result` is only present * if an invocation was simulated (since otherwise there's nothing to @@ -253,7 +254,6 @@ export namespace Api { * The field is always present, but may be empty in cases where: * - you didn't simulate an invocation or * - there were no events - * @see {@link humanizeEvents} */ events: xdr.DiagnosticEvent[]; @@ -347,7 +347,8 @@ export namespace Api { /** These are xdr.DiagnosticEvents in base64 */ events?: string[]; minResourceFee?: string; - /** This will only contain a single element if present, because only a single + /** + * This will only contain a single element if present, because only a single * invokeHostFunctionOperation is supported per transaction. * */ results?: RawSimulateHostFunctionResult[]; diff --git a/src/rpc/axios.ts b/src/rpc/axios.ts index bf19ff7d9..e33911202 100644 --- a/src/rpc/axios.ts +++ b/src/rpc/axios.ts @@ -1,7 +1,9 @@ import axios from 'axios'; +/* eslint-disable global-require */ -/* tslint:disable-next-line:no-var-requires */ +// eslint-disable-next-line prefer-import/prefer-import-over-require export const version = require('../../package.json').version; + export const AxiosClient = axios.create({ headers: { 'X-Client-Name': 'js-soroban-client', diff --git a/src/rpc/browser.ts b/src/rpc/browser.ts index a5ce47b04..d382124f1 100644 --- a/src/rpc/browser.ts +++ b/src/rpc/browser.ts @@ -1,9 +1,9 @@ /* tslint:disable:no-var-requires */ +/* eslint-disable import/no-import-module-exports */ +import axios from 'axios'; // idk why axios is weird export * from './index'; -export * as StellarBase from '@stellar/stellar-base'; - -import axios from 'axios'; // idk why axios is weird +export * as StellarBase from '@stellar/stellar-base'; export { axios }; export default module.exports; diff --git a/src/rpc/jsonrpc.ts b/src/rpc/jsonrpc.ts index bd93ebbef..dc29a82c5 100644 --- a/src/rpc/jsonrpc.ts +++ b/src/rpc/jsonrpc.ts @@ -26,6 +26,16 @@ export interface Error { data?: E; } +// Check if the given object X has a field Y, and make that available to +// typescript typing. +function hasOwnProperty( + obj: X, + prop: Y, +): obj is X & Record { + // eslint-disable-next-line no-prototype-builtins + return obj.hasOwnProperty(prop); +} + /** Sends the jsonrpc 'params' as a single 'param' object (no array support). */ export async function postObject( url: string, @@ -44,13 +54,4 @@ export async function postObject( } else { return response.data?.result; } -} - -// Check if the given object X has a field Y, and make that available to -// typescript typing. -function hasOwnProperty( - obj: X, - prop: Y, -): obj is X & Record { - return obj.hasOwnProperty(prop); -} +} \ No newline at end of file diff --git a/src/rpc/parsers.ts b/src/rpc/parsers.ts index a54a83434..076e89e5a 100644 --- a/src/rpc/parsers.ts +++ b/src/rpc/parsers.ts @@ -8,7 +8,7 @@ export function parseRawSendTransaction( delete r.errorResultXdr; delete r.diagnosticEventsXdr; - if (!!errorResultXdr) { + if (errorResultXdr) { return { ...r, ...( @@ -70,49 +70,6 @@ export function parseRawLedgerEntries( }; } -/** - * Converts a raw response schema into one with parsed XDR fields and a - * simplified interface. - * - * @param raw the raw response schema (parsed ones are allowed, best-effort - * detected, and returned untouched) - * - * @returns the original parameter (if already parsed), parsed otherwise - * - * @warning This API is only exported for testing purposes and should not be - * relied on or considered "stable". - */ -export function parseRawSimulation( - sim: - | Api.SimulateTransactionResponse - | Api.RawSimulateTransactionResponse -): Api.SimulateTransactionResponse { - const looksRaw = Api.isSimulationRaw(sim); - if (!looksRaw) { - // Gordon Ramsey in shambles - return sim; - } - - // shared across all responses - let base: Api.BaseSimulateTransactionResponse = { - _parsed: true, - id: sim.id, - latestLedger: sim.latestLedger, - events: - sim.events?.map((evt) => xdr.DiagnosticEvent.fromXDR(evt, 'base64')) ?? [] - }; - - // error type: just has error string - if (typeof sim.error === 'string') { - return { - ...base, - error: sim.error - }; - } - - return parseSuccessful(sim, base); -} - function parseSuccessful( sim: Api.RawSimulateTransactionResponse, partial: Api.BaseSimulateTransactionResponse @@ -127,29 +84,27 @@ function parseSuccessful( cost: sim.cost!, ...// coalesce 0-or-1-element results[] list into a single result struct // with decoded fields if present + // eslint-disable-next-line no-self-compare ((sim.results?.length ?? 0 > 0) && { - result: sim.results!.map((row) => { - return { + result: sim.results!.map((row) => ({ auth: (row.auth ?? []).map((entry) => xdr.SorobanAuthorizationEntry.fromXDR(entry, 'base64') ), // if return value is missing ("falsy") we coalesce to void - retval: !!row.xdr + retval: row.xdr ? xdr.ScVal.fromXDR(row.xdr, 'base64') : xdr.ScVal.scvVoid() - }; - })[0] + }))[0] }), + // eslint-disable-next-line no-self-compare ...(sim.stateChanges?.length ?? 0 > 0) && { - stateChanges: sim.stateChanges?.map((entryChange) => { - return { + stateChanges: sim.stateChanges?.map((entryChange) => ({ type: entryChange.type, key: xdr.LedgerKey.fromXDR(entryChange.key, 'base64'), before: entryChange.before ? xdr.LedgerEntry.fromXDR(entryChange.before, 'base64') : null, after: entryChange.after ? xdr.LedgerEntry.fromXDR(entryChange.after, 'base64') : null, - }; - }) + })) } }; @@ -169,3 +124,46 @@ function parseSuccessful( } }; } + +/** + * Converts a raw response schema into one with parsed XDR fields and a + * simplified interface. + * Warning: This API is only exported for testing purposes and should not be + * relied on or considered "stable". + * + * @param {Api.SimulateTransactionResponse|Api.RawSimulateTransactionResponse} sim the raw response schema (parsed ones are allowed, best-effort + * detected, and returned untouched) + * + * @returns the original parameter (if already parsed), parsed otherwise + * + */ +export function parseRawSimulation( + sim: + | Api.SimulateTransactionResponse + | Api.RawSimulateTransactionResponse +): Api.SimulateTransactionResponse { + const looksRaw = Api.isSimulationRaw(sim); + if (!looksRaw) { + // Gordon Ramsey in shambles + return sim; + } + + // shared across all responses + const base: Api.BaseSimulateTransactionResponse = { + _parsed: true, + id: sim.id, + latestLedger: sim.latestLedger, + events: + sim.events?.map((evt) => xdr.DiagnosticEvent.fromXDR(evt, 'base64')) ?? [] + }; + + // error type: just has error string + if (typeof sim.error === 'string') { + return { + ...base, + error: sim.error + }; + } + + return parseSuccessful(sim, base); +} diff --git a/src/rpc/server.ts b/src/rpc/server.ts index a0d09f2ba..1ec1a9804 100644 --- a/src/rpc/server.ts +++ b/src/rpc/server.ts @@ -11,6 +11,8 @@ import { xdr } from '@stellar/stellar-base'; +import type { TransactionBuilder } from '@stellar/stellar-base'; +// eslint-disable-next-line import/no-named-as-default import AxiosClient from './axios'; import { Api as FriendbotApi } from '../friendbot'; import * as jsonrpc from './jsonrpc'; @@ -52,11 +54,44 @@ export namespace Server { } } +function findCreatedAccountSequenceInTransactionMeta( + meta: xdr.TransactionMeta +): string { + let operations: xdr.OperationMeta[] = []; + switch (meta.switch()) { + case 0: + operations = meta.operations(); + break; + case 1: + case 2: + case 3: // all three have the same interface + operations = (meta.value() as xdr.TransactionMetaV3).operations(); + break; + default: + throw new Error('Unexpected transaction meta switch value'); + } + const sequenceNumber = operations + .flatMap(op => op.changes()) + .find(c => c.switch() === xdr.LedgerEntryChangeType.ledgerEntryCreated() && + c.created().data().switch() === xdr.LedgerEntryType.account()) + ?.created() + ?.data() + ?.account() + ?.seqNum() + ?.toString(); + + if (sequenceNumber) { + return sequenceNumber; + } + throw new Error('No account created in transaction'); +} + +/* eslint-disable jsdoc/no-undefined-types */ /** * Handles the network connection to a Soroban RPC instance, exposing an * interface for requests to that instance. * - * @constructor + * @class * * @param {string} serverURL Soroban-RPC Server URL (ex. * `http://localhost:8000/soroban/rpc`). @@ -117,6 +152,7 @@ export class Server { const resp = await this.getLedgerEntries(ledgerKey); if (resp.entries.length === 0) { + // eslint-disable-next-line prefer-promise-reject-errors return Promise.reject({ code: 404, message: `Account not found: ${address}` @@ -140,6 +176,7 @@ export class Server { * console.log("status:", health.status); * }); */ + // eslint-disable-next-line require-await public async getHealth(): Promise { return jsonrpc.postObject( this.serverURL.toString(), @@ -153,6 +190,8 @@ export class Server { * Allows you to directly inspect the current state of a contract. This is a * backup way to access your contract data which may not be available via * events or {@link Server.simulateTransaction}. + * Warning: If the data entry in question is a 'temporary' entry, it's + * entirely possible that it has expired out of existence. * * @param {string|Address|Contract} contract the contract ID containing the * data to load as a strkey (`C...` form), a {@link Contract}, or an @@ -164,9 +203,6 @@ export class Server { * * @returns {Promise} the current data value * - * @warning If the data entry in question is a 'temporary' entry, it's - * entirely possible that it has expired out of existence. - * * @see https://soroban.stellar.org/api/methods/getLedgerEntries * @example * const contractId = "CCJZ5DGASBWQXR5MPFCJXMBI333XE5U3FSJTNQU7RIKE3P5GN2K2WYD5"; @@ -178,6 +214,7 @@ export class Server { * console.log("latestLedger:", data.latestLedger); * }); */ + // eslint-disable-next-line require-await public async getContractData( contract: string | Address | Contract, key: xdr.ScVal, @@ -209,7 +246,7 @@ export class Server { throw new TypeError(`invalid durability: ${durability}`); } - let contractKey = xdr.LedgerKey.contractData( + const contractKey = xdr.LedgerKey.contractData( new xdr.LedgerKeyContractData({ key, contract: scAddress, @@ -220,6 +257,7 @@ export class Server { return this.getLedgerEntries(contractKey).then( (r: Api.GetLedgerEntriesResponse) => { if (r.entries.length === 0) { + // eslint-disable-next-line prefer-promise-reject-errors return Promise.reject({ code: 404, message: `Contract data not found. Contract: ${Address.fromScAddress( @@ -265,6 +303,7 @@ export class Server { const contractLedgerKey = new Contract(contractId).getFootprint(); const response = await this.getLedgerEntries(contractLedgerKey); if (!response.entries.length || !response.entries[0]?.val) { + // eslint-disable-next-line prefer-promise-reject-errors return Promise.reject({code: 404, message: `Could not obtain contract hash from server`}); } @@ -315,6 +354,7 @@ export class Server { const responseWasm = await this.getLedgerEntries(ledgerKeyWasmHash); if (!responseWasm.entries.length || !responseWasm.entries[0]?.val) { + // eslint-disable-next-line prefer-promise-reject-errors return Promise.reject({ code: 404, message: "Could not obtain contract wasm from server" }); } const wasmBuffer = responseWasm.entries[0].val.contractCode().code(); @@ -355,12 +395,14 @@ export class Server { * console.log("latestLedger:", response.latestLedger); * }); */ + // eslint-disable-next-line require-await public async getLedgerEntries( ...keys: xdr.LedgerKey[] ): Promise { return this._getLedgerEntries(...keys).then(parseRawLedgerEntries); } + // eslint-disable-next-line require-await public async _getLedgerEntries(...keys: xdr.LedgerKey[]) { return jsonrpc .postObject( @@ -392,6 +434,7 @@ export class Server { * console.log("resultXdr:", tx.resultXdr); * }); */ + // eslint-disable-next-line require-await public async getTransaction( hash: string ): Promise { @@ -435,6 +478,7 @@ export class Server { }); } + // eslint-disable-next-line require-await public async _getTransaction( hash: string ): Promise { @@ -479,12 +523,14 @@ export class Server { * limit: 10, * }); */ + // eslint-disable-next-line require-await public async getEvents( request: Server.GetEventsRequest ): Promise { return this._getEvents(request).then(parseRawEvents); } + // eslint-disable-next-line require-await public async _getEvents( request: Server.GetEventsRequest ): Promise { @@ -514,8 +560,9 @@ export class Server { * console.log("protocolVersion:", network.protocolVersion); * }); */ + // eslint-disable-next-line require-await public async getNetwork(): Promise { - return await jsonrpc.postObject(this.serverURL.toString(), 'getNetwork'); + return jsonrpc.postObject(this.serverURL.toString(), 'getNetwork'); } /** @@ -533,6 +580,7 @@ export class Server { * console.log("protocolVersion:", response.protocolVersion); * }); */ + // eslint-disable-next-line require-await public async getLatestLedger(): Promise { return jsonrpc.postObject(this.serverURL.toString(), 'getLatestLedger'); } @@ -541,7 +589,7 @@ export class Server { * Submit a trial contract invocation to get back return values, expected * ledger footprint, expected authorizations, and expected costs. * - * @param {Transaction | FeeBumpTransaction} transaction the transaction to + * @param {Transaction | FeeBumpTransaction} tx the transaction to * simulate, which should include exactly one operation (one of * {@link xdr.InvokeHostFunctionOp}, {@link xdr.ExtendFootprintTTLOp}, or * {@link xdr.RestoreFootprintOp}). Any provided footprint or auth @@ -579,6 +627,7 @@ export class Server { * console.log("latestLedger:", sim.latestLedger); * }); */ + // eslint-disable-next-line require-await public async simulateTransaction( tx: Transaction | FeeBumpTransaction, addlResources?: Server.ResourceLeeway @@ -587,6 +636,7 @@ export class Server { .then(parseRawSimulation); } + // eslint-disable-next-line require-await public async _simulateTransaction( transaction: Transaction | FeeBumpTransaction, addlResources?: Server.ResourceLeeway @@ -622,7 +672,7 @@ export class Server { * if you want to inspect estimated fees for a given transaction in detail * first, then re-assemble it manually or via {@link assembleTransaction}. * - * @param {Transaction | FeeBumpTransaction} transaction the transaction to + * @param {Transaction | FeeBumpTransaction} tx the transaction to * prepare. It should include exactly one operation, which must be one of * {@link xdr.InvokeHostFunctionOp}, {@link xdr.ExtendFootprintTTLOp}, * or {@link xdr.RestoreFootprintOp}. @@ -677,7 +727,7 @@ export class Server { public async prepareTransaction(tx: Transaction | FeeBumpTransaction) { const simResponse = await this.simulateTransaction(tx); if (Api.isSimulationError(simResponse)) { - throw simResponse.error; + throw new Error(simResponse.error); } return assembleTransaction(tx, simResponse).build(); @@ -726,12 +776,14 @@ export class Server { * console.log("errorResultXdr:", result.errorResultXdr); * }); */ + // eslint-disable-next-line require-await public async sendTransaction( transaction: Transaction | FeeBumpTransaction ): Promise { return this._sendTransaction(transaction).then(parseRawSendTransaction); } + // eslint-disable-next-line require-await public async _sendTransaction( transaction: Transaction | FeeBumpTransaction ): Promise { @@ -803,37 +855,3 @@ export class Server { } } } - -function findCreatedAccountSequenceInTransactionMeta( - meta: xdr.TransactionMeta -): string { - let operations: xdr.OperationMeta[] = []; - switch (meta.switch()) { - case 0: - operations = meta.operations(); - break; - case 1: - case 2: - case 3: // all three have the same interface - operations = (meta.value() as xdr.TransactionMetaV3).operations(); - break; - default: - throw new Error('Unexpected transaction meta switch value'); - } - - for (const op of operations) { - for (const c of op.changes()) { - if (c.switch() !== xdr.LedgerEntryChangeType.ledgerEntryCreated()) { - continue; - } - const data = c.created().data(); - if (data.switch() !== xdr.LedgerEntryType.account()) { - continue; - } - - return data.account().seqNum().toString(); - } - } - - throw new Error('No account created in transaction'); -} diff --git a/src/rpc/transaction.ts b/src/rpc/transaction.ts index c75f333b4..8ec79d252 100644 --- a/src/rpc/transaction.ts +++ b/src/rpc/transaction.ts @@ -7,9 +7,30 @@ import { import { Api } from './api'; import { parseRawSimulation } from './parsers'; +import type { Server } from './server'; + +function isSorobanTransaction(tx: Transaction): boolean { + if (tx.operations.length !== 1) { + return false; + } + + switch (tx.operations[0].type) { + case 'invokeHostFunction': + case 'extendFootprintTtl': + case 'restoreFootprint': + return true; + + default: + return false; + } +} + /** * Combines the given raw transaction alongside the simulation results. + * If the given transaction already has authorization entries in a host + * function invocation (see {@link Operation.invokeHostFunction}), **the + * simulation entries are ignored**. * * @param raw the initial transaction, w/o simulation applied * @param simulation the Soroban RPC simulation result (see @@ -18,10 +39,6 @@ import { parseRawSimulation } from './parsers'; * @returns a new, cloned transaction with the proper auth and resource (fee, * footprint) simulation data applied * - * @note if the given transaction already has authorization entries in a host - * function invocation (see {@link Operation.invokeHostFunction}), **the - * simulation entries are ignored**. - * * @see {Server.simulateTransaction} * @see {Server.prepareTransaction} */ @@ -47,11 +64,12 @@ export function assembleTransaction( ); } - let success = parseRawSimulation(simulation); + const success = parseRawSimulation(simulation); if (!Api.isSimulationSuccess(success)) { throw new Error(`simulation incorrect: ${JSON.stringify(success)}`); } + /* eslint-disable radix */ const classicFeeNum = parseInt(raw.fee) || 0; const minResourceFeeNum = parseInt(success.minResourceFee) || 0; const txnBuilder = TransactionBuilder.cloneFrom(raw, { @@ -69,43 +87,25 @@ export function assembleTransaction( networkPassphrase: raw.networkPassphrase }); - switch (raw.operations[0].type) { - case 'invokeHostFunction': - // In this case, we don't want to clone the operation, so we drop it. - txnBuilder.clearOperations(); + if (raw.operations[0].type === 'invokeHostFunction') { + // In this case, we don't want to clone the operation, so we drop it. + txnBuilder.clearOperations(); - const invokeOp: Operation.InvokeHostFunction = raw.operations[0]; - const existingAuth = invokeOp.auth ?? []; - txnBuilder.addOperation( - Operation.invokeHostFunction({ - source: invokeOp.source, - func: invokeOp.func, - // if auth entries are already present, we consider this "advanced - // usage" and disregard ALL auth entries from the simulation - // - // the intuition is "if auth exists, this tx has probably been - // simulated before" - auth: existingAuth.length > 0 ? existingAuth : success.result!.auth - }) - ); - break; + const invokeOp: Operation.InvokeHostFunction = raw.operations[0]; + const existingAuth = invokeOp.auth ?? []; + txnBuilder.addOperation( + Operation.invokeHostFunction({ + source: invokeOp.source, + func: invokeOp.func, + // if auth entries are already present, we consider this "advanced + // usage" and disregard ALL auth entries from the simulation + // + // the intuition is "if auth exists, this tx has probably been + // simulated before" + auth: existingAuth.length > 0 ? existingAuth : success.result!.auth + }) + ); } return txnBuilder; } - -function isSorobanTransaction(tx: Transaction): boolean { - if (tx.operations.length !== 1) { - return false; - } - - switch (tx.operations[0].type) { - case 'invokeHostFunction': - case 'extendFootprintTtl': - case 'restoreFootprint': - return true; - - default: - return false; - } -} diff --git a/src/rpc/utils.ts b/src/rpc/utils.ts index af4bb76a2..7691f4e7f 100644 --- a/src/rpc/utils.ts +++ b/src/rpc/utils.ts @@ -4,5 +4,6 @@ export function hasOwnProperty( obj: X, prop: Y, ): obj is X & Record { + // eslint-disable-next-line no-prototype-builtins return obj.hasOwnProperty(prop); } diff --git a/src/stellartoml/index.ts b/src/stellartoml/index.ts index ba0c965bf..96d4bb755 100644 --- a/src/stellartoml/index.ts +++ b/src/stellartoml/index.ts @@ -31,6 +31,7 @@ export class Resolver { * @param {number} [opts.timeout] - Allow a timeout, default: 0. Allows user to avoid nasty lag due to TOML resolve issue. * @returns {Promise} A `Promise` that resolves to the parsed stellar.toml object */ + // eslint-disable-next-line require-await public static async resolve( domain: string, opts: Api.StellarTomlResolveOptions = {}, diff --git a/src/webauth/errors.ts b/src/webauth/errors.ts index 5ba7bca43..4126ea6e0 100644 --- a/src/webauth/errors.ts +++ b/src/webauth/errors.ts @@ -1,4 +1,4 @@ - +/* eslint-disable no-proto */ export class InvalidChallengeError extends Error { public __proto__: InvalidChallengeError; diff --git a/test/e2e/src/test-contract-client-constructor.js b/test/e2e/src/test-contract-client-constructor.js index da40738a7..c0eb015c8 100644 --- a/test/e2e/src/test-contract-client-constructor.js +++ b/test/e2e/src/test-contract-client-constructor.js @@ -89,9 +89,8 @@ async function clientForFromTest(contractId, publicKey, keypair) { return contract.Client.from(options); } -describe('Client', function() { - - before(async function() { +describe("Client", function () { + before(async function () { const { client, keypair, contractId } = await clientFromConstructor("customTypes"); const publicKey = keypair.publicKey(); @@ -99,12 +98,12 @@ describe('Client', function() { this.context = { client, publicKey, addr, contractId, keypair }; }); - it("can be constructed with `new Client`", async function() { + it("can be constructed with `new Client`", async function () { const { result } = await this.context.client.hello({ hello: "tests" }); expect(result).to.equal("tests"); }); - it("can be constructed with `from`", async function() { + it("can be constructed with `from`", async function () { // objects with different constructors will not pass deepEqual check function constructorWorkaround(object) { return JSON.parse(JSON.stringify(object)); @@ -118,6 +117,8 @@ describe('Client', function() { expect(constructorWorkaround(clientFromFrom)).to.deep.equal( constructorWorkaround(this.context.client), ); - expect(this.context.client.spec.entries).to.deep.equal(clientFromFrom.spec.entries); + expect(this.context.client.spec.entries).to.deep.equal( + clientFromFrom.spec.entries, + ); }); }); diff --git a/test/e2e/src/test-custom-types.js b/test/e2e/src/test-custom-types.js index 778a4eeb0..b5c253653 100644 --- a/test/e2e/src/test-custom-types.js +++ b/test/e2e/src/test-custom-types.js @@ -1,83 +1,100 @@ -const { expect } = require('chai'); +const { expect } = require("chai"); const { Address, contract } = require("../../.."); const { clientFor } = require("./util"); - -describe("Custom Types Tests", function() { - before(async function() { +describe("Custom Types Tests", function () { + before(async function () { const { client, keypair, contractId } = await clientFor("customTypes"); const publicKey = keypair.publicKey(); const addr = Address.fromString(publicKey); this.context = { client, publicKey, addr, contractId, keypair }; }); - it("hello", async function() { - expect((await this.context.client.hello({ hello: "tests" })).result).to.equal("tests"); + it("hello", async function () { + expect( + (await this.context.client.hello({ hello: "tests" })).result, + ).to.equal("tests"); }); - it("view method with empty keypair", async function() { + it("view method with empty keypair", async function () { const { client: client2 } = await clientFor("customTypes", { keypair: undefined, contractId: this.context.contractId, }); - expect((await client2.hello({ hello: "anonymous" })).result).to.equal("anonymous"); + expect((await client2.hello({ hello: "anonymous" })).result).to.equal( + "anonymous", + ); }); - it("woid", async function() { + it("woid", async function () { expect((await this.context.client.woid()).result).to.be.null; }); - it("u32_fail_on_even", async function() { + it("u32_fail_on_even", async function () { let response = await this.context.client.u32_fail_on_even({ u32_: 1 }); expect(response.result).to.deep.equal(new contract.Ok(1)); response = await this.context.client.u32_fail_on_even({ u32_: 2 }); - expect(response.result).to.deep.equal(new contract.Err({ message: "Please provide an odd number" })); + expect(response.result).to.deep.equal( + new contract.Err({ message: "Please provide an odd number" }), + ); }); - it("u32", async function() { + it("u32", async function () { expect((await this.context.client.u32_({ u32_: 1 })).result).to.equal(1); }); - it("i32", async function() { + it("i32", async function () { expect((await this.context.client.i32_({ i32_: 1 })).result).to.equal(1); }); - it("i64", async function() { + it("i64", async function () { expect((await this.context.client.i64_({ i64_: 1n })).result).to.equal(1n); }); - it("strukt_hel", async function() { + it("strukt_hel", async function () { const strukt = { a: 0, b: true, c: "world" }; - expect((await this.context.client.strukt_hel({ strukt })).result).to.deep.equal(["Hello", "world"]); + expect( + (await this.context.client.strukt_hel({ strukt })).result, + ).to.deep.equal(["Hello", "world"]); }); - it("strukt", async function() { + it("strukt", async function () { const strukt = { a: 0, b: true, c: "hello" }; - expect((await this.context.client.strukt({ strukt })).result).to.deep.equal(strukt); + expect((await this.context.client.strukt({ strukt })).result).to.deep.equal( + strukt, + ); }); - it("simple first", async function() { + it("simple first", async function () { const simple = { tag: "First", values: undefined }; - expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "First" }); + expect((await this.context.client.simple({ simple })).result).to.deep.equal( + { tag: "First" }, + ); }); - it("simple second", async function() { + it("simple second", async function () { const simple = { tag: "Second", values: undefined }; - expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "Second" }); + expect((await this.context.client.simple({ simple })).result).to.deep.equal( + { tag: "Second" }, + ); }); - it("simple third", async function() { + it("simple third", async function () { const simple = { tag: "Third", values: undefined }; - expect((await this.context.client.simple({ simple })).result).to.deep.equal({ tag: "Third" }); + expect((await this.context.client.simple({ simple })).result).to.deep.equal( + { tag: "Third" }, + ); }); - it("complex with struct", async function() { + it("complex with struct", async function () { const arg = { tag: "Struct", values: [{ a: 0, b: true, c: "hello" }] }; - expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(arg); + expect( + (await this.context.client.complex({ complex: arg })).result, + ).to.deep.equal(arg); }); - it("complex with tuple", async function() { + it("complex with tuple", async function () { const arg = { tag: "Tuple", values: [ @@ -91,62 +108,83 @@ describe("Custom Types Tests", function() { tag: "Tuple", values: [[{ a: 0, b: true, c: "hello" }, { tag: "First" }]], }; - expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(ret); + expect( + (await this.context.client.complex({ complex: arg })).result, + ).to.deep.equal(ret); }); - it("complex with enum", async function() { + it("complex with enum", async function () { const arg = { tag: "Enum", values: [{ tag: "First", values: undefined }] }; const ret = { tag: "Enum", values: [{ tag: "First" }] }; - expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(ret); + expect( + (await this.context.client.complex({ complex: arg })).result, + ).to.deep.equal(ret); }); - it("complex with asset", async function() { + it("complex with asset", async function () { const arg = { tag: "Asset", values: [this.context.publicKey, 1n] }; - expect((await this.context.client.complex({ complex: arg })).result).to.deep.equal(arg); + expect( + (await this.context.client.complex({ complex: arg })).result, + ).to.deep.equal(arg); }); - it("complex with void", async function() { + it("complex with void", async function () { const complex = { tag: "Void", values: undefined }; const ret = { tag: "Void" }; - expect((await this.context.client.complex({ complex })).result).to.deep.equal(ret); + expect( + (await this.context.client.complex({ complex })).result, + ).to.deep.equal(ret); }); - it("addresse", async function() { - expect((await this.context.client.addresse({ addresse: this.context.publicKey })).result).to.equal(this.context.addr.toString()); + it("addresse", async function () { + expect( + (await this.context.client.addresse({ addresse: this.context.publicKey })) + .result, + ).to.equal(this.context.addr.toString()); }); - it("bytes", async function() { + it("bytes", async function () { const bytes = Buffer.from("hello"); - expect((await this.context.client.bytes({ bytes })).result).to.deep.equal(bytes); + expect((await this.context.client.bytes({ bytes })).result).to.deep.equal( + bytes, + ); }); - it("bytesN", async function() { + it("bytesN", async function () { const bytesN = Buffer.from("123456789"); // what's the correct way to construct bytesN? - expect((await this.context.client.bytes_n({ bytes_n: bytesN })).result).to.deep.equal(bytesN); + expect( + (await this.context.client.bytes_n({ bytes_n: bytesN })).result, + ).to.deep.equal(bytesN); }); - it("card", async function() { + it("card", async function () { const card = 11; expect((await this.context.client.card({ card })).result).to.equal(card); }); - it("boolean", async function() { - expect((await this.context.client.boolean({ boolean: true })).result).to.equal(true); + it("boolean", async function () { + expect( + (await this.context.client.boolean({ boolean: true })).result, + ).to.equal(true); }); - it("not", async function() { - expect((await this.context.client.not({ boolean: true })).result).to.equal(false); + it("not", async function () { + expect((await this.context.client.not({ boolean: true })).result).to.equal( + false, + ); }); - it("i128", async function() { - expect((await this.context.client.i128({ i128: -1n })).result).to.equal(-1n); + it("i128", async function () { + expect((await this.context.client.i128({ i128: -1n })).result).to.equal( + -1n, + ); }); - it("u128", async function() { + it("u128", async function () { expect((await this.context.client.u128({ u128: 1n })).result).to.equal(1n); }); - it("multi_args", async function() { + it("multi_args", async function () { let response = await this.context.client.multi_args({ a: 1, b: true }); expect(response.result).to.equal(1); @@ -154,24 +192,28 @@ describe("Custom Types Tests", function() { expect(response.result).to.equal(0); }); - it("map", async function() { + it("map", async function () { const map = new Map(); map.set(1, true); map.set(2, false); - expect((await this.context.client.map({ map })).result).to.deep.equal(Array.from(map.entries())); + expect((await this.context.client.map({ map })).result).to.deep.equal( + Array.from(map.entries()), + ); }); - it("vec", async function() { + it("vec", async function () { const vec = [1, 2, 3]; expect((await this.context.client.vec({ vec })).result).to.deep.equal(vec); }); - it("tuple", async function() { + it("tuple", async function () { const tuple = ["hello", 1]; - expect((await this.context.client.tuple({ tuple })).result).to.deep.equal(tuple); + expect((await this.context.client.tuple({ tuple })).result).to.deep.equal( + tuple, + ); }); - it("option", async function() { + it("option", async function () { let response = await this.context.client.option({ option: 1 }); expect(response.result).to.equal(1); @@ -183,24 +225,30 @@ describe("Custom Types Tests", function() { // t.deepEqual((await t.context.client.option({ option: undefined })).result, undefined) }); - it("u256", async function() { + it("u256", async function () { expect((await this.context.client.u256({ u256: 1n })).result).to.equal(1n); }); - it("i256", async function() { - expect((await this.context.client.i256({ i256: -1n })).result).to.equal(-1n); + it("i256", async function () { + expect((await this.context.client.i256({ i256: -1n })).result).to.equal( + -1n, + ); }); - it("string", async function() { - expect((await this.context.client.string({ string: "hello" })).result).to.equal("hello"); + it("string", async function () { + expect( + (await this.context.client.string({ string: "hello" })).result, + ).to.equal("hello"); }); - it("tuple strukt", async function() { + it("tuple strukt", async function () { const arg = [ { a: 0, b: true, c: "hello" }, { tag: "First", values: undefined }, ]; const res = [{ a: 0, b: true, c: "hello" }, { tag: "First" }]; - expect((await this.context.client.tuple_strukt({ tuple_strukt: arg })).result).to.deep.equal(res); + expect( + (await this.context.client.tuple_strukt({ tuple_strukt: arg })).result, + ).to.deep.equal(res); }); -}); \ No newline at end of file +}); diff --git a/test/e2e/src/test-hello-world.js b/test/e2e/src/test-hello-world.js index 50b50f4f7..ac74a4629 100644 --- a/test/e2e/src/test-hello-world.js +++ b/test/e2e/src/test-hello-world.js @@ -1,21 +1,21 @@ const { expect } = require("chai"); const { clientFor } = require("./util"); -describe("helloWorld client", function() { - it("should return properly formed hello response", async function() { +describe("helloWorld client", function () { + it("should return properly formed hello response", async function () { const { client } = await clientFor("helloWorld"); const response = await client.hello({ world: "tests" }); expect(response.result).to.deep.equal(["Hello", "tests"]); }); - it("should authenticate the user correctly", async function() { + it("should authenticate the user correctly", async function () { const { client, keypair } = await clientFor("helloWorld"); const publicKey = keypair.publicKey(); const { result } = await client.auth({ addr: publicKey, world: "lol" }); expect(result).to.equal(publicKey); }); - it("should increment the counter correctly", async function() { + it("should increment the counter correctly", async function () { const { client } = await clientFor("helloWorld"); const { result: startingBalance } = await client.get_count(); const inc = await client.inc(); @@ -26,7 +26,7 @@ describe("helloWorld client", function() { expect(newBalance).to.equal(startingBalance + 1); }); - it("should accept only options object for methods with no arguments", async function() { + it("should accept only options object for methods with no arguments", async function () { const { client } = await clientFor("helloWorld"); const inc = await client.inc({ simulate: false }); expect(inc.simulation).to.be.undefined; diff --git a/test/e2e/src/test-methods-as-args.js b/test/e2e/src/test-methods-as-args.js index 1f4b5b5ef..3308e907d 100644 --- a/test/e2e/src/test-methods-as-args.js +++ b/test/e2e/src/test-methods-as-args.js @@ -6,8 +6,8 @@ function callMethod(method, args) { return method(args); } -describe("methods-as-args", function() { - it("should pass methods as arguments and have them still work", async function() { +describe("methods-as-args", function () { + it("should pass methods as arguments and have them still work", async function () { const { client } = await clientFor("helloWorld"); const { result } = await callMethod(client.hello, { world: "tests" }); expect(result).to.deep.equal(["Hello", "tests"]); diff --git a/test/e2e/src/test-swap.js b/test/e2e/src/test-swap.js index a55497071..b46a4eec0 100644 --- a/test/e2e/src/test-swap.js +++ b/test/e2e/src/test-swap.js @@ -17,7 +17,6 @@ const amountAToSwap = 2n; const amountBToSwap = 1n; describe("Swap Contract Tests", function () { - before(async function () { const alice = await generateFundedKeypair(); const bob = await generateFundedKeypair(); @@ -46,12 +45,14 @@ describe("Swap Contract Tests", function () { await tokenA.mint({ amount: amountAToSwap, to: alice.publicKey() }) ).signAndSend(); - await tokenB.initialize({ - admin: root.publicKey(), - decimal: 0, - name: "Token B", - symbol: "B", - }).then(t => t.signAndSend()); + await tokenB + .initialize({ + admin: root.publicKey(), + decimal: 0, + name: "Token B", + symbol: "B", + }) + .then((t) => t.signAndSend()); await ( await tokenB.mint({ amount: amountBToSwap, to: bob.publicKey() }) ).signAndSend(); @@ -69,7 +70,36 @@ describe("Swap Contract Tests", function () { }; }); - it("calling `signAndSend()` too soon throws descriptive error", async function() { + it("calling `signAndSend()` too soon throws descriptive error", async function () { + const tx = await this.context.swapContractAsRoot.swap({ + a: this.context.alice.publicKey(), + b: this.context.bob.publicKey(), + token_a: this.context.tokenAId, + token_b: this.context.tokenBId, + amount_a: amountAToSwap, + min_a_for_b: amountAToSwap, + amount_b: amountBToSwap, + min_b_for_a: amountBToSwap, + }); + await expect(tx.signAndSend()) + .to.be.rejectedWith( + contract.AssembledTransaction.Errors.NeedsMoreSignatures, + ) + .then((error) => { + // Further assertions on the error object + expect(error).to.be.instanceOf( + contract.AssembledTransaction.Errors.NeedsMoreSignatures, + `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`, + ); + + if (error) { + // Using regex to check the error message + expect(error.message).to.match(/needsNonInvokerSigningBy/); + } + }); + }); + + it("modified & re-simulated transactions show updated data", async function () { const tx = await this.context.swapContractAsRoot.swap({ a: this.context.alice.publicKey(), b: this.context.bob.publicKey(), @@ -80,16 +110,39 @@ describe("Swap Contract Tests", function () { amount_b: amountBToSwap, min_b_for_a: amountBToSwap, }); - await expect(tx.signAndSend()).to.be.rejectedWith(contract.AssembledTransaction.Errors.NeedsMoreSignatures).then((error) => { - // Further assertions on the error object - expect(error).to.be.instanceOf(contract.AssembledTransaction.Errors.NeedsMoreSignatures, - `error is not of type 'NeedsMoreSignaturesError'; instead it is of type '${error?.constructor.name}'`); + await tx.signAuthEntries({ + publicKey: this.context.alice.publicKey(), + ...contract.basicNodeSigner(this.context.alice, networkPassphrase), + }); + await tx.signAuthEntries({ + publicKey: this.context.bob.publicKey(), + ...contract.basicNodeSigner(this.context.bob, networkPassphrase), + }); - if (error) { - // Using regex to check the error message - expect(error.message).to.match(/needsNonInvokerSigningBy/); - } + const originalResourceFee = Number( + tx.simulationData.transactionData.resourceFee(), + ); + const bumpedResourceFee = originalResourceFee + 10000; + + tx.raw = TransactionBuilder.cloneFrom(tx.built, { + fee: tx.built.fee, + sorobanData: new SorobanDataBuilder( + tx.simulationData.transactionData.toXDR(), + ) + .setResourceFee( + xdr.Int64.fromString(bumpedResourceFee.toString()).toBigInt(), + ) + .build(), }); + + await tx.simulate(); + + const newSimulatedResourceFee = Number( + tx.simulationData.transactionData.resourceFee(), + ); + + expect(originalResourceFee).to.not.equal(newSimulatedResourceFee); + expect(newSimulatedResourceFee).to.be.greaterThan(bumpedResourceFee); }); it("modified & re-simulated transactions show updated data", async function () { @@ -113,17 +166,17 @@ describe("Swap Contract Tests", function () { }); const originalResourceFee = Number( - tx.simulationData.transactionData.resourceFee() + tx.simulationData.transactionData.resourceFee(), ); const bumpedResourceFee = originalResourceFee + 10000; tx.raw = TransactionBuilder.cloneFrom(tx.built, { fee: tx.built.fee, sorobanData: new SorobanDataBuilder( - tx.simulationData.transactionData.toXDR() + tx.simulationData.transactionData.toXDR(), ) .setResourceFee( - xdr.Int64.fromString(bumpedResourceFee.toString()).toBigInt() + xdr.Int64.fromString(bumpedResourceFee.toString()).toBigInt(), ) .build(), }); @@ -131,14 +184,14 @@ describe("Swap Contract Tests", function () { await tx.simulate(); const newSimulatedResourceFee = Number( - tx.simulationData.transactionData.resourceFee() + tx.simulationData.transactionData.resourceFee(), ); expect(originalResourceFee).to.not.equal(newSimulatedResourceFee); expect(newSimulatedResourceFee).to.be.greaterThan(bumpedResourceFee); }); - it("alice swaps bob 10 A for 1 B", async function() { + it("alice swaps bob 10 A for 1 B", async function () { const tx = await this.context.swapContractAsRoot.swap({ a: this.context.alice.publicKey(), b: this.context.bob.publicKey(), @@ -152,8 +205,12 @@ describe("Swap Contract Tests", function () { const needsNonInvokerSigningBy = await tx.needsNonInvokerSigningBy(); expect(needsNonInvokerSigningBy).to.have.lengthOf(2); - expect(needsNonInvokerSigningBy.indexOf(this.context.alice.publicKey())).to.equal(0, "needsNonInvokerSigningBy does not have alice's public key!"); - expect(needsNonInvokerSigningBy.indexOf(this.context.bob.publicKey())).to.equal(1, "needsNonInvokerSigningBy does not have bob's public key!"); + expect( + needsNonInvokerSigningBy.indexOf(this.context.alice.publicKey()), + ).to.equal(0, "needsNonInvokerSigningBy does not have alice's public key!"); + expect( + needsNonInvokerSigningBy.indexOf(this.context.bob.publicKey()), + ).to.equal(1, "needsNonInvokerSigningBy does not have bob's public key!"); // root serializes & sends to alice const xdrFromRoot = tx.toXDR(); @@ -184,16 +241,34 @@ describe("Swap Contract Tests", function () { await txRoot.simulate(); const result = await txRoot.signAndSend(); - expect(result).to.have.property('sendTransactionResponse'); - expect(result.sendTransactionResponse).to.have.property('status', 'PENDING'); - expect(result).to.have.property('getTransactionResponseAll').that.is.an('array').that.is.not.empty; - expect(result.getTransactionResponse).to.have.property('status').that.is.not.equal('FAILED'); - expect(result.getTransactionResponse).to.have.property('status', rpc.Api.GetTransactionStatus.SUCCESS); + expect(result).to.have.property("sendTransactionResponse"); + expect(result.sendTransactionResponse).to.have.property( + "status", + "PENDING", + ); + expect(result) + .to.have.property("getTransactionResponseAll") + .that.is.an("array").that.is.not.empty; + expect(result.getTransactionResponse) + .to.have.property("status") + .that.is.not.equal("FAILED"); + expect(result.getTransactionResponse).to.have.property( + "status", + rpc.Api.GetTransactionStatus.SUCCESS, + ); - const aliceTokenABalance = await this.context.tokenA.balance({ id: this.context.alice.publicKey() }); - const aliceTokenBBalance = await this.context.tokenB.balance({ id: this.context.alice.publicKey() }); - const bobTokenABalance = await this.context.tokenA.balance({ id: this.context.bob.publicKey() }); - const bobTokenBBalance = await this.context.tokenB.balance({ id: this.context.bob.publicKey() }); + const aliceTokenABalance = await this.context.tokenA.balance({ + id: this.context.alice.publicKey(), + }); + const aliceTokenBBalance = await this.context.tokenB.balance({ + id: this.context.alice.publicKey(), + }); + const bobTokenABalance = await this.context.tokenA.balance({ + id: this.context.bob.publicKey(), + }); + const bobTokenBBalance = await this.context.tokenB.balance({ + id: this.context.bob.publicKey(), + }); expect(aliceTokenABalance.result).to.equal(0n); expect(aliceTokenBBalance.result).to.equal(amountBToSwap); diff --git a/test/unit/server/soroban/assembled_transaction_test.js b/test/unit/server/soroban/assembled_transaction_test.js index 6b433fae6..35e966fb5 100644 --- a/test/unit/server/soroban/assembled_transaction_test.js +++ b/test/unit/server/soroban/assembled_transaction_test.js @@ -1,15 +1,10 @@ -const { - Account, - Keypair, - Networks, - rpc, - SorobanDataBuilder, - xdr, - contract, -} = StellarSdk; +const { Account, Keypair, Networks, rpc, SorobanDataBuilder, xdr, contract } = + StellarSdk; const { Server, AxiosClient, parseRawSimulation } = StellarSdk.rpc; -const restoreTxnData = StellarSdk.SorobanDataBuilder.fromXDR("AAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQ=="); +const restoreTxnData = StellarSdk.SorobanDataBuilder.fromXDR( + "AAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQ==", +); describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { const keypair = Keypair.random(); @@ -17,13 +12,13 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { const networkPassphrase = "Standalone Network ; February 2017"; const wallet = contract.basicNodeSigner(keypair, networkPassphrase); const options = { - networkPassphrase, - contractId, - rpcUrl: serverUrl, - allowHttp: true, - publicKey: keypair.publicKey(), - ...wallet, - } + networkPassphrase, + contractId, + rpcUrl: serverUrl, + allowHttp: true, + publicKey: keypair.publicKey(), + ...wallet, + }; beforeEach(function () { this.server = new Server(serverUrl); @@ -35,8 +30,6 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { this.axiosMock.restore(); }); - - it("makes expected RPC calls", function (done) { const simulateTransactionResponse = { transactionData: restoreTxnData, @@ -46,10 +39,10 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { }; const sendTransactionResponse = { - "status": "PENDING", - "hash": "05870e35fc94e5424f72d125959760b5f60631d91452bde2d11126fb5044e35d", - "latestLedger": 17034, - "latestLedgerCloseTime": "1716483573" + status: "PENDING", + hash: "05870e35fc94e5424f72d125959760b5f60631d91452bde2d11126fb5044e35d", + latestLedger: 17034, + latestLedgerCloseTime: "1716483573", }; const getTransactionResponse = { status: "SUCCESS", @@ -58,9 +51,11 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { oldestLedger: 15598, oldestLedgerCloseTime: "1716482133", applicationOrder: 1, - envelopeXdr: "AAAAAgAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQABm0IAAAvWAAAAAwAAAAEAAAAAAAAAAAAAAABmT3cbAAAAAAAAAAEAAAAAAAAAGgAAAAAAAAABAAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQAAAAG+w3upAAAAQGBfsx+gyi/2Dh6i+7Vbb6Ongw3HDcFDZ48eoadkUUvkq97zdPe3wYGFswZgT5/GXPqGDBi+iqHuZiYx5eSy3Qk=", + envelopeXdr: + "AAAAAgAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQABm0IAAAvWAAAAAwAAAAEAAAAAAAAAAAAAAABmT3cbAAAAAAAAAAEAAAAAAAAAGgAAAAAAAAABAAAAAAAAAAAAAAAEAAAABgAAAAHZ4Y4l0GNoS97QH0fa5Jbbm61Ou3t9McQ09l7wREKJYwAAAA8AAAAJUEVSU19DTlQxAAAAAAAAAQAAAAYAAAAB2eGOJdBjaEve0B9H2uSW25utTrt7fTHENPZe8ERCiWMAAAAPAAAACVBFUlNfQ05UMgAAAAAAAAEAAAAGAAAAAdnhjiXQY2hL3tAfR9rkltubrU67e30xxDT2XvBEQoljAAAAFAAAAAEAAAAH+BoQswzzGTKRzrdC6axxKaM4qnyDP8wgQv8Id3S4pbsAAAAAAAAGNAAABjQAAAAAAADNoQAAAAG+w3upAAAAQGBfsx+gyi/2Dh6i+7Vbb6Ongw3HDcFDZ48eoadkUUvkq97zdPe3wYGFswZgT5/GXPqGDBi+iqHuZiYx5eSy3Qk=", resultXdr: "AAAAAAAAiRkAAAAAAAAAAQAAAAAAAAAaAAAAAAAAAAA=", - resultMetaXdr: "AAAAAwAAAAAAAAACAAAAAwAAQowAAAAAAAAAABHCklg6riUqP9F21Lt2zdyIZIx9lSn7t3jGCD2+w3upAAAAF0h1Pp0AAAvWAAAAAgAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAAAMMQAAAABmTz9yAAAAAAAAAAEAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAAAACAAAAAMAAAwrAAAACc4pIDe7y0sRFHAghrdpB7ypfj4BVuZStvX4u0BC1S/YAAANVgAAAAAAAAABAABCjAAAAAnOKSA3u8tLERRwIIa3aQe8qX4+AVbmUrb1+LtAQtUv2AAAQ7cAAAAAAAAAAwAADCsAAAAJikpmJa7Pr3lTb+dhRP2N4TOYCqK4tL4tQhDYnNEijtgAAA1WAAAAAAAAAAEAAEKMAAAACYpKZiWuz695U2/nYUT9jeEzmAqiuLS+LUIQ2JzRIo7YAABDtwAAAAAAAAADAAAMMQAAAAlT7LdEin/CaQA3iscHqkwnEFlSh8jfTPTIhSQ5J8Ao0wAADVwAAAAAAAAAAQAAQowAAAAJU+y3RIp/wmkAN4rHB6pMJxBZUofI30z0yIUkOSfAKNMAAEO3AAAAAAAAAAMAAAwxAAAACQycyCYjh7j9CHnTm9OKCYXhgmXw6jdtoMsGHyPk8Aa+AAANXAAAAAAAAAABAABCjAAAAAkMnMgmI4e4/Qh505vTigmF4YJl8Oo3baDLBh8j5PAGvgAAQ7cAAAAAAAAAAgAAAAMAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAABCjAAAAAAAAAAAEcKSWDquJSo/0XbUu3bN3IhkjH2VKfu3eMYIPb7De6kAAAAXSHWDiQAAC9YAAAADAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAEKMAAAAAGZPdfcAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA", + resultMetaXdr: + "AAAAAwAAAAAAAAACAAAAAwAAQowAAAAAAAAAABHCklg6riUqP9F21Lt2zdyIZIx9lSn7t3jGCD2+w3upAAAAF0h1Pp0AAAvWAAAAAgAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAAAMMQAAAABmTz9yAAAAAAAAAAEAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAAAACAAAAAMAAAwrAAAACc4pIDe7y0sRFHAghrdpB7ypfj4BVuZStvX4u0BC1S/YAAANVgAAAAAAAAABAABCjAAAAAnOKSA3u8tLERRwIIa3aQe8qX4+AVbmUrb1+LtAQtUv2AAAQ7cAAAAAAAAAAwAADCsAAAAJikpmJa7Pr3lTb+dhRP2N4TOYCqK4tL4tQhDYnNEijtgAAA1WAAAAAAAAAAEAAEKMAAAACYpKZiWuz695U2/nYUT9jeEzmAqiuLS+LUIQ2JzRIo7YAABDtwAAAAAAAAADAAAMMQAAAAlT7LdEin/CaQA3iscHqkwnEFlSh8jfTPTIhSQ5J8Ao0wAADVwAAAAAAAAAAQAAQowAAAAJU+y3RIp/wmkAN4rHB6pMJxBZUofI30z0yIUkOSfAKNMAAEO3AAAAAAAAAAMAAAwxAAAACQycyCYjh7j9CHnTm9OKCYXhgmXw6jdtoMsGHyPk8Aa+AAANXAAAAAAAAAABAABCjAAAAAkMnMgmI4e4/Qh505vTigmF4YJl8Oo3baDLBh8j5PAGvgAAQ7cAAAAAAAAAAgAAAAMAAEKMAAAAAAAAAAARwpJYOq4lKj/RdtS7ds3ciGSMfZUp+7d4xgg9vsN7qQAAABdIdT6dAAAL1gAAAAMAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAAQowAAAAAZk919wAAAAAAAAABAABCjAAAAAAAAAAAEcKSWDquJSo/0XbUu3bN3IhkjH2VKfu3eMYIPb7De6kAAAAXSHWDiQAAC9YAAAADAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAEKMAAAAAGZPdfcAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA", ledger: 17036, createdAt: "1716483575", }; @@ -72,49 +67,54 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => { jsonrpc: "2.0", id: 1, method: "simulateTransaction", - }) + }), ) - .returns(Promise.resolve({ data: { result: simulateTransactionResponse } })); + .returns( + Promise.resolve({ data: { result: simulateTransactionResponse } }), + ); this.axiosMock .expects("post") - .withArgs(serverUrl, + .withArgs( + serverUrl, sinon.match({ jsonrpc: "2.0", id: 1, method: "getTransaction", - }) + }), ) .returns(Promise.resolve({ data: { result: getTransactionResponse } })); this.axiosMock .expects("post") - .withArgs(serverUrl, + .withArgs( + serverUrl, sinon.match({ jsonrpc: "2.0", id: 1, method: "sendTransaction", - }) + }), ) .returns(Promise.resolve({ data: { result: sendTransactionResponse } })); - contract.AssembledTransaction.buildFootprintRestoreTransaction( - options, - restoreTxnData, - new StellarSdk.Account( - "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI", - "1", - ), - 52641, - ) - .then((txn) => txn.signAndSend({ ...wallet })) - .then((result) => { - expect(result.getTransactionResponse.status).to.equal(rpc.Api.GetTransactionStatus.SUCCESS); - done(); - }) - .catch((error) => { - // handle any errors that occurred during the promise chain - done(error); - }); - - }) + contract.AssembledTransaction.buildFootprintRestoreTransaction( + options, + restoreTxnData, + new StellarSdk.Account( + "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI", + "1", + ), + 52641, + ) + .then((txn) => txn.signAndSend({ ...wallet })) + .then((result) => { + expect(result.getTransactionResponse.status).to.equal( + rpc.Api.GetTransactionStatus.SUCCESS, + ); + done(); + }) + .catch((error) => { + // handle any errors that occurred during the promise chain + done(error); + }); + }); }); diff --git a/test/unit/server/soroban/simulate_transaction_test.js b/test/unit/server/soroban/simulate_transaction_test.js index 863ad6b13..a48817877 100644 --- a/test/unit/server/soroban/simulate_transaction_test.js +++ b/test/unit/server/soroban/simulate_transaction_test.js @@ -18,12 +18,11 @@ describe("Server#simulateTransaction", async function (done) { let contract = new StellarSdk.Contract(contractId); let address = contract.address().toScAddress(); - const accountId = - "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI"; + const accountId = "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI"; const accountKey = xdr.LedgerKey.account( - new xdr.LedgerKeyAccount({ - accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), - }), + new xdr.LedgerKeyAccount({ + accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), + }), ); const simulationResponse = await invokeSimulationResponse(address); @@ -192,48 +191,48 @@ describe("Server#simulateTransaction", async function (done) { it("works with state changes", async function () { return invokeSimulationResponseWithStateChanges(address).then( - (simResponse) => { - const expected = cloneSimulation(parsedSimulationResponse); - expected.stateChanges = [ - { - type: 2, - key: accountKey, - before: new xdr.LedgerEntry({ - lastModifiedLedgerSeq: 0, - data: new xdr.LedgerEntryData(), - ext: new xdr.LedgerEntryExt(), - }), - after: new xdr.LedgerEntry({ - lastModifiedLedgerSeq: 0, - data: new xdr.LedgerEntryData(), - ext: new xdr.LedgerEntryExt(), - }), - }, - { - type: 1, - key: accountKey, - before: null, - after: new xdr.LedgerEntry({ - lastModifiedLedgerSeq: 0, - data: new xdr.LedgerEntryData(), - ext: new xdr.LedgerEntryExt(), - }), - }, - { - type: 3, - key: accountKey, - before: new xdr.LedgerEntry({ - lastModifiedLedgerSeq: 0, - data: new xdr.LedgerEntryData(), - ext: new xdr.LedgerEntryExt(), - }), - after: null, - }, - ] + (simResponse) => { + const expected = cloneSimulation(parsedSimulationResponse); + expected.stateChanges = [ + { + type: 2, + key: accountKey, + before: new xdr.LedgerEntry({ + lastModifiedLedgerSeq: 0, + data: new xdr.LedgerEntryData(), + ext: new xdr.LedgerEntryExt(), + }), + after: new xdr.LedgerEntry({ + lastModifiedLedgerSeq: 0, + data: new xdr.LedgerEntryData(), + ext: new xdr.LedgerEntryExt(), + }), + }, + { + type: 1, + key: accountKey, + before: null, + after: new xdr.LedgerEntry({ + lastModifiedLedgerSeq: 0, + data: new xdr.LedgerEntryData(), + ext: new xdr.LedgerEntryExt(), + }), + }, + { + type: 3, + key: accountKey, + before: new xdr.LedgerEntry({ + lastModifiedLedgerSeq: 0, + data: new xdr.LedgerEntryData(), + ext: new xdr.LedgerEntryExt(), + }), + after: null, + }, + ]; - const parsed = parseRawSimulation(simResponse); - expect(parsed).to.be.deep.equal(expected); - }, + const parsed = parseRawSimulation(simResponse); + expect(parsed).to.be.deep.equal(expected); + }, ); }); @@ -341,9 +340,9 @@ function baseSimulationResponse(results) { { type: 2, key: xdr.LedgerKey.account( - new xdr.LedgerKeyAccount({ - accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), - }), + new xdr.LedgerKeyAccount({ + accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), + }), ).toXDR("base64"), before: new xdr.LedgerEntry({ lastModifiedLedgerSeq: 0, @@ -355,7 +354,7 @@ function baseSimulationResponse(results) { data: new xdr.LedgerEntryData(), ext: new xdr.LedgerEntryExt(), }).toXDR("base64"), - } + }, ], }; } @@ -374,15 +373,14 @@ async function invokeSimulationResponseWithStateChanges(address) { const accountId = "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI"; return { - ...(await invokeSimulationResponse(address)), stateChanges: [ { type: 2, key: xdr.LedgerKey.account( - new xdr.LedgerKeyAccount({ - accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), - }), + new xdr.LedgerKeyAccount({ + accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), + }), ).toXDR("base64"), before: new xdr.LedgerEntry({ lastModifiedLedgerSeq: 0, @@ -398,9 +396,9 @@ async function invokeSimulationResponseWithStateChanges(address) { { type: 1, key: xdr.LedgerKey.account( - new xdr.LedgerKeyAccount({ - accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), - }), + new xdr.LedgerKeyAccount({ + accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), + }), ).toXDR("base64"), before: null, after: new xdr.LedgerEntry({ @@ -412,9 +410,9 @@ async function invokeSimulationResponseWithStateChanges(address) { { type: 3, key: xdr.LedgerKey.account( - new xdr.LedgerKeyAccount({ - accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), - }), + new xdr.LedgerKeyAccount({ + accountId: Keypair.fromPublicKey(accountId).xdrPublicKey(), + }), ).toXDR("base64"), before: new xdr.LedgerEntry({ lastModifiedLedgerSeq: 0, @@ -427,7 +425,6 @@ async function invokeSimulationResponseWithStateChanges(address) { }; } - describe("works with real responses", function () { const schema = { transactionData: