diff --git a/CHANGELOG.md b/CHANGELOG.md index d481053a3..6167053b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,18 +35,13 @@ import { +} from '@stellar/stellar-sdk/contract' ``` -- The `ContractSpec` class is now nested under the `contract` module, and has been renamed to `Spec`. +- The `ContractSpec` class is now nested under the `contract` module, and has been **renamed** to `Spec` ([#962](https://github.com/stellar/js-stellar-sdk/pull/962)). Alternatively, you can import this from the `contract` entrypoint, if your version of Node [and TypeScript](https://stackoverflow.com/a/70020984/249801) support [the `exports` declaration](https://nodejs.org/api/packages.html#exports): ```diff -import { ContractSpec } from '@stellar/stellar-sdk' +import { contract } from '@stellar/stellar-sdk' +const { Spec } = contract -``` - - Alternatively, you can import this from the `contract` entrypoint, if your version of Node [and TypeScript](https://stackoverflow.com/a/70020984/249801) support [the `exports` declaration](https://nodejs.org/api/packages.html#exports). - -```diff --import { ContractSpec } from '@stellar/stellar-sdk' +// OR +import { Spec } from '@stellar/stellar-sdk/contract' ``` @@ -54,7 +49,7 @@ import { ### Deprecated -- `SorobanRpc` module is now also exported as `rpc`. You can import it with either name for now, but `SorobanRpc` will be removed in a future release: +- `SorobanRpc` module is now also exported as `rpc` ([#962](https://github.com/stellar/js-stellar-sdk/pull/962)). You can import it with either name for now, but `SorobanRpc` will be removed in a future release: ```diff -import { SorobanRpc } from '@stellar/stellar-sdk' @@ -70,12 +65,15 @@ import { ``` ### Added -* New methods on `ContractClient` ([#960](https://github.com/stellar/js-stellar-sdk/pull/960)): - - `from(opts: ContractClientOptions)` instantiates the `ContractClient` by fetching the `contractId`'s WASM from the network to fill out the client's `ContractSpec`. - - `fromWasm` and `fromWasmHash` methods to instantiate a `ContractClient` when you already have the WASM bytes or hash alongside the `ContractClientOptions`. -* New methods on `SorobanRpc.Server` ([#960](https://github.com/stellar/js-stellar-sdk/pull/960)): +* New methods on `contract.Client` ([#960](https://github.com/stellar/js-stellar-sdk/pull/960)): + - `from(opts: ContractClientOptions)` instantiates `contract.Client` by fetching the `contractId`'s WASM from the network to fill out the client's `ContractSpec`. + - `fromWasm` and `fromWasmHash` methods to instantiate a `contract.Client` when you already have the WASM bytes or hash alongside the `contract.ClientOptions`. +* New methods on `rpc.Server` ([#960](https://github.com/stellar/js-stellar-sdk/pull/960)): - `getContractWasmByContractId` and `getContractWasmByHash` to retrieve a contract's WASM bytecode via its `contractId` or `wasmHash`, respectively. +### Fixed +* The breaking changes above (strictly speaking, they are not breaking changes because importing from the inner guts of the SDK is not supported) enable the `contract` module to be used in non-Node environments. + ## [v12.0.0-rc.2](https://github.com/stellar/js-stellar-sdk/compare/v11.3.0...v12.0.0-rc.2) diff --git a/package.json b/package.json index 67ff77a00..48a117ebc 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "test:integration": "yarn _nyc mocha --recursive 'test/integration/**/*.js'", "test:browser": "karma start config/karma.conf.js", "fmt": "yarn eslint -c .eslintrc.js src/ --fix && yarn _prettier", - "preversion": "yarn clean && yarn fmt && yarn build:prod && yarn test", + "preversion": "yarn clean && yarn _prettier && yarn build:prod && yarn test", "prepare": "yarn build:prod", "_build": "yarn build:node && yarn build:test && yarn build:browser", "_babel": "babel --extensions '.ts' --out-dir lib/ src/", diff --git a/test/e2e/src/test-contract-client-constructor.js b/test/e2e/src/test-contract-client-constructor.js index 83211941c..60e0069bd 100644 --- a/test/e2e/src/test-contract-client-constructor.js +++ b/test/e2e/src/test-contract-client-constructor.js @@ -1,13 +1,18 @@ -const test = require('ava') -const { spawnSync } = require('node:child_process') -const { contracts, networkPassphrase, rpcUrl, friendbotUrl } = require('./util') -const { Address, contract, Keypair } = require('../../..') +const test = require("ava"); +const { spawnSync } = require("node:child_process"); +const { + contracts, + networkPassphrase, + rpcUrl, + friendbotUrl, +} = require("./util"); +const { Address, contract, Keypair } = require("../../.."); async function generateFundedKeypair() { - const keypair = Keypair.random() - await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`) - return keypair -}; + const keypair = Keypair.random(); + await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`); + return keypair; +} /** * Generates a Client for the contract with the given name. @@ -18,34 +23,54 @@ async function generateFundedKeypair() { * 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 } = {}) { +async function clientFromConstructor( + name, + { keypair = generateFundedKeypair(), contractId } = {}, +) { if (!contracts[name]) { throw new Error( `Contract ${name} not found. ` + - `Pick one of: ${Object.keys(contracts).join(", ")}` - ) + `Pick one of: ${Object.keys(contracts).join(", ")}`, + ); } - keypair = await keypair // eslint-disable-line no-param-reassign - const wallet = contract.basicNodeSigner(keypair, networkPassphrase) + keypair = await keypair; // eslint-disable-line no-param-reassign + const wallet = contract.basicNodeSigner(keypair, networkPassphrase); - const {path} = contracts[name]; - const xdr = JSON.parse(spawnSync("./target/bin/soroban", ["contract", "inspect", "--wasm", path, "--output", "xdr-base64-array"], { shell: true, encoding: "utf8" }).stdout.trim()) + const { path } = contracts[name]; + const xdr = JSON.parse( + spawnSync( + "./target/bin/soroban", + ["contract", "inspect", "--wasm", path, "--output", "xdr-base64-array"], + { shell: true, encoding: "utf8" }, + ).stdout.trim(), + ); const spec = new contract.Spec(xdr); let wasmHash = contracts[name].hash; if (!wasmHash) { - wasmHash = spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", path], { shell: true, encoding: "utf8" }).stdout.trim() + wasmHash = spawnSync( + "./target/bin/soroban", + ["contract", "install", "--wasm", path], + { shell: true, encoding: "utf8" }, + ).stdout.trim(); } // TODO: do this with js-stellar-sdk, instead of shelling out to the CLI - contractId = contractId ?? spawnSync("./target/bin/soroban", [ // eslint-disable-line no-param-reassign - "contract", - "deploy", - "--source", - keypair.secret(), - "--wasm-hash", - wasmHash, - ], { shell: true, encoding: "utf8" }).stdout.trim(); + contractId = + contractId ?? + spawnSync( + "./target/bin/soroban", + [ + // eslint-disable-line no-param-reassign + "contract", + "deploy", + "--source", + keypair.secret(), + "--wasm-hash", + wasmHash, + ], + { shell: true, encoding: "utf8" }, + ).stdout.trim(); const client = new contract.Client(spec, { networkPassphrase, @@ -59,7 +84,7 @@ async function clientFromConstructor(name, { keypair = generateFundedKeypair(), keypair, client, contractId, - } + }; } /** @@ -79,25 +104,33 @@ 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 +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 }); -test('hello from constructor', async t => { - const { result } = await t.context.client.hello({ hello: 'tests' }) - t.is(result, 'tests') -}) +test("hello from constructor", async (t) => { + const { result } = await t.context.client.hello({ hello: "tests" }); + t.is(result, "tests"); +}); -test('from', async (t) => { +test("from", async (t) => { // objects with different constructors will not pass deepEqual check function constructorWorkaround(object) { return JSON.parse(JSON.stringify(object)); } - const clientFromFrom = await clientForFromTest(t.context.contractId, t.context.publicKey, t.context.keypair); - t.deepEqual(constructorWorkaround(clientFromFrom), constructorWorkaround(t.context.client)); + 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); }); diff --git a/test/e2e/src/test-custom-types.js b/test/e2e/src/test-custom-types.js index 63094187b..6fa1d7045 100644 --- a/test/e2e/src/test-custom-types.js +++ b/test/e2e/src/test-custom-types.js @@ -1,199 +1,226 @@ -const test = require('ava') -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 +const test = require("ava"); +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("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', { + const { client: client2 } = await clientFor("customTypes", { keypair: undefined, - contractId: t.context.contractId + 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("woid", async (t) => { + t.is((await t.context.client.woid()).result, null); +}); -test('u32_fail_on_even', async t => { +test("u32_fail_on_even", async (t) => { t.deepEqual( (await t.context.client.u32_fail_on_even({ u32_: 1 })).result, - new contract.Ok(1) - ) + 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" }) - ) -}) + 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("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("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("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"]) -}) + 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 }]] } - 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? + 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 }, + ], + ], + }; + 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.bytes_n({ bytes_n: bytesN })).result, - bytesN - ) -}) + (await t.context.client.addresse({ addresse: t.context.publicKey })).result, + t.context.addr.toString(), + ); +}); -test('card', async t => { - const card = 11 - t.is((await t.context.client.card({ card })).result, card) -}) +test("bytes", async (t) => { + const bytes = Buffer.from("hello"); + t.deepEqual((await t.context.client.bytes({ bytes })).result, bytes); +}); -test('boolean', async t => { - t.is((await t.context.client.boolean({ boolean: true })).result, true) -}) +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('not', async t => { - t.is((await t.context.client.not({ boolean: true })).result, false) -}) +test("card", async (t) => { + const card = 11; + t.is((await t.context.client.card({ card })).result, card); +}); -test('i128', async t => { - t.is((await t.context.client.i128({ i128: -1n })).result, -1n) -}) +test("boolean", async (t) => { + t.is((await t.context.client.boolean({ boolean: true })).result, true); +}); -test('u128', async t => { - t.is((await t.context.client.u128({ u128: 1n })).result, 1n) -}) +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("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) +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())) -}) + 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("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("tuple", async (t) => { + const tuple = ["hello", 1]; + t.deepEqual((await t.context.client.tuple({ tuple })).result, tuple); +}); -test('option', async t => { +test("option", async (t) => { // this makes sense - t.deepEqual((await t.context.client.option({ option: 1 })).result, 1) + 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) + 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("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("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("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) -}) +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, + ); +}); diff --git a/test/e2e/src/test-hello-world.js b/test/e2e/src/test-hello-world.js index fbd927be3..7ce24ec9a 100644 --- a/test/e2e/src/test-hello-world.js +++ b/test/e2e/src/test-hello-world.js @@ -1,30 +1,33 @@ -const test = require('ava') -const { clientFor } = require('./util') +const test = require("ava"); +const { clientFor } = require("./util"); test("hello", async (t) => { - const { client } = await clientFor('helloWorld') - t.deepEqual((await client.hello({ world: "tests" })).result, ["Hello", "tests"]); + const { client } = await clientFor("helloWorld"); + t.deepEqual((await client.hello({ world: "tests" })).result, [ + "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) + const { client, keypair } = await clientFor("helloWorld"); + const publicKey = keypair.publicKey(); + const { result } = await client.auth({ addr: publicKey, world: "lol" }); + t.deepEqual(result, 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) + 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); }); test("options for methods with no arguments", async (t) => { - const { client } = await clientFor('helloWorld') + 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) + const inc = await client.inc({ simulate: false }); + t.falsy(inc.simulation); }); diff --git a/test/e2e/src/test-methods-as-args.js b/test/e2e/src/test-methods-as-args.js index f6f068657..1009deb53 100644 --- a/test/e2e/src/test-methods-as-args.js +++ b/test/e2e/src/test-methods-as-args.js @@ -1,13 +1,13 @@ -const test = require('ava') -const { clientFor } = require('./util') +const test = require("ava"); +const { clientFor } = require("./util"); // this test checks that apps can pass methods as arguments to other methods and have them still work function callMethod(method, args) { - return method(args) + return method(args); } test("methods-as-args", async (t) => { - const { client } = await clientFor('helloWorld') - const { result } = await callMethod(client.hello, { world: "tests" }) + const { client } = await clientFor("helloWorld"); + const { result } = await callMethod(client.hello, { world: "tests" }); t.deepEqual(result, ["Hello", "tests"]); }); diff --git a/test/e2e/src/test-swap.js b/test/e2e/src/test-swap.js index 885debda9..f1f651f31 100644 --- a/test/e2e/src/test-swap.js +++ b/test/e2e/src/test-swap.js @@ -1,32 +1,52 @@ -const test = require('ava') -const { contract, rpc } = require('../../..') -const { clientFor, generateFundedKeypair } = require('./util') +const test = require("ava"); +const { contract, rpc } = require("../../.."); +const { clientFor, generateFundedKeypair } = require("./util"); -const amountAToSwap = 2n -const amountBToSwap = 1n +const amountAToSwap = 2n; +const amountBToSwap = 1n; -test.before(async t => { - const alice = await generateFundedKeypair() - const bob = await generateFundedKeypair() +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 }) + 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 tokenA.initialize({ + admin: root.publicKey(), + decimal: 0, + name: "Token A", + symbol: "A", + }) + ).signAndSend(); await ( await tokenA.mint({ amount: amountAToSwap, to: alice.publicKey() }) - ).signAndSend() + ).signAndSend(); await ( - await tokenB.initialize({ admin: root.publicKey(), decimal: 0, name: 'Token B', symbol: 'B' }) - ).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() + ).signAndSend(); - t.context = { // eslint-disable-line no-param-reassign + t.context = { + // eslint-disable-line no-param-reassign root, alice, bob, @@ -36,10 +56,10 @@ test.before(async t => { tokenAId, tokenB, tokenBId, - } -}) + }; +}); -test('calling `signAndSend()` too soon throws descriptive error', async t => { +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(), @@ -49,13 +69,16 @@ test('calling `signAndSend()` too soon throws descriptive error', async t => { min_a_for_b: amountAToSwap, amount_b: amountBToSwap, min_b_for_a: amountBToSwap, - }) - 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/) -}) + }); + 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 => { +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(), @@ -65,69 +88,96 @@ test('alice swaps bob 10 A for 1 B', async t => { min_a_for_b: amountAToSwap, amount_b: amountBToSwap, min_b_for_a: amountBToSwap, - }) + }); - 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!') + 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', { + 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() + }); + const txAlice = clientAlice.txFromJSON(jsonFromRoot); + await txAlice.signAuthEntries(); // alice serializes & sends to bob - const jsonFromAlice = txAlice.toJSON() - const { client: clientBob } = await clientFor('swap', { + 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() + }); + const txBob = clientBob.txFromJSON(jsonFromAlice); + await txBob.signAuthEntries(); // bob serializes & sends back to root - const jsonFromBob = txBob.toJSON() - const { client: clientRoot } = await clientFor('swap', { + const jsonFromBob = txBob.toJSON(); + const { client: clientRoot } = await clientFor("swap", { keypair: t.context.root, contractId: t.context.swapId, - }) - const txRoot = clientRoot.txFromJSON(jsonFromBob) + }); + const txRoot = clientRoot.txFromJSON(jsonFromBob); - const result = await txRoot.signAndSend() + 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.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)}` - ) + `tx failed: ${JSON.stringify(result.getTransactionResponse, null, 2)}`, + ); t.is( - (await t.context.tokenA.balance({ id: t.context.alice.publicKey() })).result, - 0n - ) + (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 - ) + (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 - ) + amountAToSwap, + ); t.is( (await t.context.tokenB.balance({ id: t.context.bob.publicKey() })).result, - 0n - ) -}) + 0n, + ); +}); diff --git a/test/e2e/src/util.js b/test/e2e/src/util.js index c70995de2..6d760c976 100644 --- a/test/e2e/src/util.js +++ b/test/e2e/src/util.js @@ -1,39 +1,74 @@ -const { spawnSync } = require('node:child_process') -const { contract, Keypair } = require('../../..') +const { spawnSync } = require("node:child_process"); +const { contract, Keypair } = require("../../.."); const contracts = { customTypes: { - hash: spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", `${__dirname}/../wasms/test_custom_types.wasm`], { shell: true, encoding: "utf8" }).stdout.trim(), + hash: spawnSync( + "./target/bin/soroban", + [ + "contract", + "install", + "--wasm", + `${__dirname}/../wasms/test_custom_types.wasm`, + ], + { shell: true, encoding: "utf8" }, + ).stdout.trim(), path: `${__dirname}/../wasms/test_custom_types.wasm`, }, helloWorld: { - hash: spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", `${__dirname}/../wasms/test_hello_world.wasm`], { shell: true, encoding: "utf8" }).stdout.trim(), - path: `${__dirname}/../wasms/test_hello_world.wasm` + hash: spawnSync( + "./target/bin/soroban", + [ + "contract", + "install", + "--wasm", + `${__dirname}/../wasms/test_hello_world.wasm`, + ], + { shell: true, encoding: "utf8" }, + ).stdout.trim(), + path: `${__dirname}/../wasms/test_hello_world.wasm`, }, swap: { - hash: spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", `${__dirname}/../wasms/test_swap.wasm`], { shell: true, encoding: "utf8" }).stdout.trim(), - path: `${__dirname}/../wasms/test_swap.wasm` + hash: spawnSync( + "./target/bin/soroban", + ["contract", "install", "--wasm", `${__dirname}/../wasms/test_swap.wasm`], + { shell: true, encoding: "utf8" }, + ).stdout.trim(), + path: `${__dirname}/../wasms/test_swap.wasm`, }, token: { - hash: spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", `${__dirname}/../wasms/test_token.wasm`], { shell: true, encoding: "utf8" }).stdout.trim(), - path: `${__dirname}/../wasms/test_token.wasm` + hash: spawnSync( + "./target/bin/soroban", + [ + "contract", + "install", + "--wasm", + `${__dirname}/../wasms/test_token.wasm`, + ], + { shell: true, encoding: "utf8" }, + ).stdout.trim(), + path: `${__dirname}/../wasms/test_token.wasm`, }, }; -module.exports.contracts = contracts +module.exports.contracts = contracts; -const rpcUrl = process.env.SOROBAN_RPC_URL ?? "http://localhost:8000/soroban/rpc"; -module.exports.rpcUrl = rpcUrl -const networkPassphrase = process.env.SOROBAN_NETWORK_PASSPHRASE ?? "Standalone Network ; February 2017"; -module.exports.networkPassphrase = networkPassphrase -const friendbotUrl = process.env.SOROBAN_FRIENDBOT_URL ?? "http://localhost:8000/friendbot"; -module.exports.friendbotUrl = friendbotUrl +const rpcUrl = + process.env.SOROBAN_RPC_URL ?? "http://localhost:8000/soroban/rpc"; +module.exports.rpcUrl = rpcUrl; +const networkPassphrase = + process.env.SOROBAN_NETWORK_PASSPHRASE ?? + "Standalone Network ; February 2017"; +module.exports.networkPassphrase = networkPassphrase; +const friendbotUrl = + process.env.SOROBAN_FRIENDBOT_URL ?? "http://localhost:8000/friendbot"; +module.exports.friendbotUrl = friendbotUrl; async function generateFundedKeypair() { - const keypair = Keypair.random() - await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`) - return keypair -}; -module.exports.generateFundedKeypair = generateFundedKeypair + const keypair = Keypair.random(); + await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`); + return keypair; +} +module.exports.generateFundedKeypair = generateFundedKeypair; /** * Generates a Client for the contract with the given name. @@ -44,44 +79,62 @@ module.exports.generateFundedKeypair = generateFundedKeypair * 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 clientFor(name, { keypair = generateFundedKeypair(), contractId } = {}) { +async function clientFor( + name, + { keypair = generateFundedKeypair(), contractId } = {}, +) { if (!contracts[name]) { throw new Error( `Contract ${name} not found. ` + - `Pick one of: ${Object.keys(contracts).join(", ")}` - ) + `Pick one of: ${Object.keys(contracts).join(", ")}`, + ); } - keypair = await keypair // eslint-disable-line no-param-reassign - const wallet = contract.basicNodeSigner(keypair, networkPassphrase) + keypair = await keypair; // eslint-disable-line no-param-reassign + const wallet = contract.basicNodeSigner(keypair, networkPassphrase); let wasmHash = contracts[name].hash; if (!wasmHash) { - wasmHash = spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", contracts[name].path], { shell: true, encoding: "utf8" }).stdout.trim() + wasmHash = spawnSync( + "./target/bin/soroban", + ["contract", "install", "--wasm", contracts[name].path], + { shell: true, encoding: "utf8" }, + ).stdout.trim(); } // TODO: do this with js-stellar-sdk, instead of shelling out to the CLI - contractId = contractId ?? spawnSync("./target/bin/soroban", [ // eslint-disable-line no-param-reassign - "contract", - "deploy", - "--source", - keypair.secret(), - "--wasm-hash", - wasmHash, - ], { shell: true, encoding: "utf8" }).stdout.trim(); + contractId = + contractId ?? + spawnSync( + "./target/bin/soroban", + [ + // eslint-disable-line no-param-reassign + "contract", + "deploy", + "--source", + keypair.secret(), + "--wasm-hash", + wasmHash, + ], + { shell: true, encoding: "utf8" }, + ).stdout.trim(); - const client = await contract.Client.fromWasmHash(wasmHash, { - networkPassphrase, - contractId, - rpcUrl, - allowHttp: true, - publicKey: keypair.publicKey(), - ...wallet, - }, "hex"); + const client = await contract.Client.fromWasmHash( + wasmHash, + { + networkPassphrase, + contractId, + rpcUrl, + allowHttp: true, + publicKey: keypair.publicKey(), + ...wallet, + }, + "hex", + ); return { keypair, client, contractId, - } + }; } -module.exports.clientFor = clientFor +module.exports.clientFor = clientFor; diff --git a/test/unit/server/soroban/get_account_test.js b/test/unit/server/soroban/get_account_test.js index 4372a39c9..a722246b7 100644 --- a/test/unit/server/soroban/get_account_test.js +++ b/test/unit/server/soroban/get_account_test.js @@ -25,7 +25,7 @@ describe("Server#getAccount", function () { jsonrpc: "2.0", id: 1, method: "getLedgerEntries", - params: { keys: [ key.toXDR("base64") ] }, + params: { keys: [key.toXDR("base64")] }, }) .returns( Promise.resolve({ @@ -62,7 +62,7 @@ describe("Server#getAccount", function () { jsonrpc: "2.0", id: 1, method: "getLedgerEntries", - params: { keys: [ key.toXDR("base64") ] }, + params: { keys: [key.toXDR("base64")] }, }) .returns( Promise.resolve({ diff --git a/test/unit/server/soroban/get_contract_wasm_test.js b/test/unit/server/soroban/get_contract_wasm_test.js index 83bb436c1..6e8957739 100644 --- a/test/unit/server/soroban/get_contract_wasm_test.js +++ b/test/unit/server/soroban/get_contract_wasm_test.js @@ -13,10 +13,17 @@ describe("Server#getContractWasm", () => { }); const contractId = "CCN57TGC6EXFCYIQJ4UCD2UDZ4C3AQCHVMK74DGZ3JYCA5HD4BY7FNPC"; - const wasmHash = Buffer.from("kh1dFBiUKv/lXkcD+XnVTsbzi+Lps96lfWEk3rFWNnI=", "base64"); - const wasmBuffer = Buffer.from("0061730120c0800010ab818080000b20002035503082000336232636439000", "hex"); + const wasmHash = Buffer.from( + "kh1dFBiUKv/lXkcD+XnVTsbzi+Lps96lfWEk3rFWNnI=", + "base64", + ); + const wasmBuffer = Buffer.from( + "0061730120c0800010ab818080000b20002035503082000336232636439000", + "hex", + ); const contractCodeEntryExtension = xdr.ContractCodeEntryExt.fromXDR( - "AAAAAQAAAAAAAAAAAAAVqAAAAJwAAAADAAAAAwAAABgAAAABAAAAAQAAABEAAAAgAAABpA==", "base64" + "AAAAAQAAAAAAAAAAAAAVqAAAAJwAAAADAAAAAwAAABgAAAABAAAAAQAAABEAAAAgAAABpA==", + "base64", ); const contract = new Contract(contractId); @@ -29,7 +36,12 @@ describe("Server#getContractWasm", () => { contract: address.toScAddress(), durability: xdr.ContractDataDurability.persistent(), key: xdr.ScVal.scvLedgerKeyContractInstance(), - val: xdr.ScVal.scvContractInstance(new xdr.ScContractInstance({executable: xdr.ContractExecutable.contractExecutableWasm(wasmHash), storage: null})) + val: xdr.ScVal.scvContractInstance( + new xdr.ScContractInstance({ + executable: xdr.ContractExecutable.contractExecutableWasm(wasmHash), + storage: null, + }), + ), }), ); const ledgerKeyWasmHash = xdr.LedgerKey.contractData( @@ -53,18 +65,17 @@ describe("Server#getContractWasm", () => { liveUntilLedgerSeq: 1000, }; - const wasmLedgerKey = xdr.LedgerKey.contractCode( new xdr.LedgerKeyContractCode({ - hash: wasmHash - }) + hash: wasmHash, + }), ); const wasmLedgerCode = xdr.LedgerEntryData.contractCode( new xdr.ContractCodeEntry({ ext: contractCodeEntryExtension, hash: wasmHash, code: wasmBuffer, - }) + }), ); const wasmLedgerTtlEntry = xdr.LedgerEntryData.ttl( @@ -82,8 +93,6 @@ describe("Server#getContractWasm", () => { }; it("retrieves WASM bytecode for a contract", function (done) { - - this.axiosMock .expects("post") .withArgs(serverUrl, { @@ -99,7 +108,9 @@ describe("Server#getContractWasm", () => { latestLedger: 18039, entries: [ { - liveUntilLedgerSeq: ledgerTtlEntryWasmHash.ttl().liveUntilLedgerSeq(), + liveUntilLedgerSeq: ledgerTtlEntryWasmHash + .ttl() + .liveUntilLedgerSeq(), lastModifiedLedgerSeq: wasmHashResult.lastModifiedLedgerSeq, xdr: ledgerEntryWasmHash.toXDR("base64"), key: contractLedgerKey.toXDR("base64"), @@ -107,7 +118,7 @@ describe("Server#getContractWasm", () => { ], }, }, - }) + }), ); this.axiosMock @@ -125,7 +136,9 @@ describe("Server#getContractWasm", () => { latestLedger: 18039, entries: [ { - liveUntilLedgerSeq: wasmLedgerTtlEntry.ttl().liveUntilLedgerSeq(), + liveUntilLedgerSeq: wasmLedgerTtlEntry + .ttl() + .liveUntilLedgerSeq(), lastModifiedLedgerSeq: wasmResult.lastModifiedLedgerSeq, key: wasmLedgerKey.toXDR("base64"), xdr: wasmLedgerCode.toXDR("base64"), @@ -133,7 +146,7 @@ describe("Server#getContractWasm", () => { ], }, }, - }) + }), ); this.server @@ -186,7 +199,9 @@ describe("Server#getContractWasm", () => { latestLedger: 18039, entries: [ { - liveUntilLedgerSeq: ledgerTtlEntryWasmHash.ttl().liveUntilLedgerSeq(), + liveUntilLedgerSeq: ledgerTtlEntryWasmHash + .ttl() + .liveUntilLedgerSeq(), lastModifiedLedgerSeq: wasmHashResult.lastModifiedLedgerSeq, xdr: ledgerEntryWasmHash.toXDR("base64"), key: contractLedgerKey.toXDR("base64"), @@ -194,7 +209,7 @@ describe("Server#getContractWasm", () => { ], }, }, - }) + }), ); this.axiosMock @@ -220,6 +235,4 @@ describe("Server#getContractWasm", () => { ); }); }); - - -}); \ No newline at end of file +}); diff --git a/test/unit/server/soroban/get_events_test.js b/test/unit/server/soroban/get_events_test.js index 6861f887a..c4d759859 100644 --- a/test/unit/server/soroban/get_events_test.js +++ b/test/unit/server/soroban/get_events_test.js @@ -246,7 +246,7 @@ let getEventsResponseFixture = [ inSuccessfulContractCall: true, topic: topicVals.slice(0, 2), value: eventVal, - txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c" + txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c", }, { type: "contract", @@ -258,7 +258,7 @@ let getEventsResponseFixture = [ inSuccessfulContractCall: true, topic: topicVals.slice(0, 2), value: eventVal, - txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c" + txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c", }, { type: "diagnostic", @@ -270,7 +270,7 @@ let getEventsResponseFixture = [ inSuccessfulContractCall: true, topic: [topicVals[0]], value: eventVal, - txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c" + txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c", }, { type: "contract", @@ -282,6 +282,6 @@ let getEventsResponseFixture = [ inSuccessfulContractCall: true, topic: topicVals, value: eventVal, - txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c" + txHash: "d7d09af2ca4f2929ee701cf86d05e4ca5f849a726d0db344785a8f9894e79e6c", }, ]; diff --git a/test/unit/server/soroban/get_ledger_entries_test.js b/test/unit/server/soroban/get_ledger_entries_test.js index a550d62f9..304612586 100644 --- a/test/unit/server/soroban/get_ledger_entries_test.js +++ b/test/unit/server/soroban/get_ledger_entries_test.js @@ -44,7 +44,7 @@ describe("Server#getLedgerEntries", function () { jsonrpc: "2.0", id: 1, method: "getLedgerEntries", - params: {keys: requests}, + params: { keys: requests }, }) .returns( Promise.resolve({ diff --git a/test/unit/transaction_test.js b/test/unit/transaction_test.js index 4ee16f7f2..99ede6fe6 100644 --- a/test/unit/transaction_test.js +++ b/test/unit/transaction_test.js @@ -80,10 +80,7 @@ describe("assembleTransaction", () => { it("simulate updates the tx data from simulation response", () => { const txn = singleContractFnTransaction(); - const result = rpc.assembleTransaction( - txn, - simulationResponse, - ).build(); + const result = rpc.assembleTransaction(txn, simulationResponse).build(); // validate it auto updated the tx fees from sim response fees // since it was greater than tx.fee @@ -97,10 +94,7 @@ describe("assembleTransaction", () => { it("simulate adds the auth to the host function in tx operation", () => { const txn = singleContractFnTransaction(); - const result = rpc.assembleTransaction( - txn, - simulationResponse, - ).build(); + const result = rpc.assembleTransaction(txn, simulationResponse).build(); expect( result @@ -170,13 +164,15 @@ describe("assembleTransaction", () => { .build(); expect(() => { - rpc.assembleTransaction(txn, { - transactionData: {}, - events: [], - minResourceFee: "0", - results: [], - latestLedger: 3, - }).build(); + rpc + .assembleTransaction(txn, { + transactionData: {}, + events: [], + minResourceFee: "0", + results: [], + latestLedger: 3, + }) + .build(); expect.fail(); }).to.throw(/unsupported transaction/i); }); @@ -198,20 +194,14 @@ describe("assembleTransaction", () => { .addOperation(op) .build(); - const tx = rpc.assembleTransaction( - txn, - simulationResponse, - ).build(); + const tx = rpc.assembleTransaction(txn, simulationResponse).build(); expect(tx.operations[0].type).to.equal(op.body().switch().name); }); }); it("doesn't overwrite auth if it's present", function () { const txn = singleContractFnTransaction([fnAuth, fnAuth, fnAuth]); - const tx = rpc.assembleTransaction( - txn, - simulationResponse, - ).build(); + const tx = rpc.assembleTransaction(txn, simulationResponse).build(); expect(tx.operations[0].auth.length).to.equal( 3,