diff --git a/.changeset/real-crabs-listen.md b/.changeset/real-crabs-listen.md new file mode 100644 index 00000000000..d570fae20e6 --- /dev/null +++ b/.changeset/real-crabs-listen.md @@ -0,0 +1,4 @@ +--- +--- + +ci: update retry and timeout on Transaction `SqueezedOut` test \ No newline at end of file diff --git a/.changeset/stupid-planets-joke.md b/.changeset/stupid-planets-joke.md new file mode 100644 index 00000000000..9213f7b4aa5 --- /dev/null +++ b/.changeset/stupid-planets-joke.md @@ -0,0 +1,6 @@ +--- +"@fuel-ts/account": patch +"@fuel-ts/errors": patch +--- + +chore: add validation for TX max outputs exceeded diff --git a/.changeset/ten-otters-report.md b/.changeset/ten-otters-report.md new file mode 100644 index 00000000000..249bda45e90 --- /dev/null +++ b/.changeset/ten-otters-report.md @@ -0,0 +1,6 @@ +--- +"@fuel-ts/abi-typegen": patch +"@fuel-ts/utils": patch +--- + +feat: improve typegen bytecode compression diff --git a/apps/docs/src/guide/errors/index.md b/apps/docs/src/guide/errors/index.md index fe61222a90a..71f3ebe6e00 100644 --- a/apps/docs/src/guide/errors/index.md +++ b/apps/docs/src/guide/errors/index.md @@ -301,4 +301,8 @@ If you believe you found a bug, please report the [issue](https://github.com/Fue ### `MAX_INPUTS_EXCEEDED` -When the number of transaction inputs exceeds the maximum limit allowed by the blockchain. \ No newline at end of file +When the number of transaction inputs exceeds the maximum limit allowed by the blockchain. + +### `MAX_OUTPUTS_EXCEEDED` + +When the number of transaction outputs exceeds the maximum limit allowed by the blockchain. diff --git a/packages/abi-typegen/src/templates/contract/factory.hbs b/packages/abi-typegen/src/templates/contract/factory.hbs index 7ac88b6e86c..4810bcbba2e 100644 --- a/packages/abi-typegen/src/templates/contract/factory.hbs +++ b/packages/abi-typegen/src/templates/contract/factory.hbs @@ -1,11 +1,11 @@ {{header}} -import { ContractFactory } from "fuels"; +import { ContractFactory, decompressBytecode } from "fuels"; import type { Provider, Account, DeployContractOptions, DeployContractResult } from "fuels"; import { {{capitalizedName}} } from "./{{capitalizedName}}"; -const bytecode = "{{hexlifiedBinString}}"; +const bytecode = decompressBytecode("{{compressedBytecode}}"); export class {{capitalizedName}}Factory extends ContractFactory { diff --git a/packages/abi-typegen/src/templates/contract/factory.test.ts b/packages/abi-typegen/src/templates/contract/factory.test.ts index 18384a62f71..7983ca9ae6b 100644 --- a/packages/abi-typegen/src/templates/contract/factory.test.ts +++ b/packages/abi-typegen/src/templates/contract/factory.test.ts @@ -1,3 +1,4 @@ +import * as utilsMod from '@fuel-ts/utils'; import { join } from 'path'; import { @@ -24,6 +25,8 @@ describe('templates/factory', () => { const project = getTypegenForcProject(AbiTypegenProjectsEnum.MINIMAL); const rawContents = project.abiContents; + vi.spyOn(utilsMod, 'compressBytecode').mockReturnValueOnce('0x-bytecode-here'); + // executing const abi = new Abi({ filepath: './my-contract-abi.json', diff --git a/packages/abi-typegen/src/templates/contract/factory.ts b/packages/abi-typegen/src/templates/contract/factory.ts index b4611a81c7e..08553d22da0 100644 --- a/packages/abi-typegen/src/templates/contract/factory.ts +++ b/packages/abi-typegen/src/templates/contract/factory.ts @@ -1,3 +1,5 @@ +import { compressBytecode } from '@fuel-ts/utils'; + import type { Abi } from '../../abi/Abi'; import { renderHbsTemplate } from '../renderHbsTemplate'; @@ -22,7 +24,7 @@ export function renderFactoryTemplate(params: { abi: Abi }) { capitalizedName, abiJsonString, storageSlotsJsonString, - hexlifiedBinString, + compressedBytecode: compressBytecode(hexlifiedBinString), }, }); diff --git a/packages/abi-typegen/src/templates/predicate/main.hbs b/packages/abi-typegen/src/templates/predicate/main.hbs index 30886b91ad9..03cbaf76dd6 100644 --- a/packages/abi-typegen/src/templates/predicate/main.hbs +++ b/packages/abi-typegen/src/templates/predicate/main.hbs @@ -59,7 +59,7 @@ export type {{capitalizedName}}Parameters = Omit< const abi = {{abiJsonString}}; -const bytecode = '{{hexlifiedBinString}}'; +const bytecode = decompressBytecode('{{compressedBytecode}}'); export class {{capitalizedName}} extends Predicate< {{capitalizedName}}Inputs, diff --git a/packages/abi-typegen/src/templates/predicate/main.test.ts b/packages/abi-typegen/src/templates/predicate/main.test.ts index 144502ba509..f545c655e58 100644 --- a/packages/abi-typegen/src/templates/predicate/main.test.ts +++ b/packages/abi-typegen/src/templates/predicate/main.test.ts @@ -1,4 +1,5 @@ import { safeExec } from '@fuel-ts/errors/test-utils'; +import * as utilsMod from '@fuel-ts/utils'; import { join } from 'path'; import { @@ -18,7 +19,13 @@ import { renderMainTemplate } from './main'; * @group node */ describe('main.ts', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + test('should render main template', () => { + vi.spyOn(utilsMod, 'compressBytecode').mockReturnValueOnce('0x-bytecode-here'); + const { restore } = mockVersions(); const project = getTypegenForcProject(AbiTypegenProjectsEnum.PREDICATE); @@ -46,6 +53,8 @@ describe('main.ts', () => { }); test('should render main template with configurable', () => { + vi.spyOn(utilsMod, 'compressBytecode').mockReturnValueOnce('0x-bytecode-here'); + const { restore } = mockVersions(); const project = getTypegenForcProject(AbiTypegenProjectsEnum.PREDICATE_WITH_CONFIGURABLE); diff --git a/packages/abi-typegen/src/templates/predicate/main.ts b/packages/abi-typegen/src/templates/predicate/main.ts index bfe4f0bd05d..1861cbab8af 100644 --- a/packages/abi-typegen/src/templates/predicate/main.ts +++ b/packages/abi-typegen/src/templates/predicate/main.ts @@ -1,4 +1,5 @@ import { ErrorCode, FuelError } from '@fuel-ts/errors'; +import { compressBytecode } from '@fuel-ts/utils'; import type { Abi } from '../../abi/Abi'; import { renderHbsTemplate } from '../renderHbsTemplate'; @@ -32,7 +33,7 @@ export function renderMainTemplate(params: { abi: Abi }) { const { structs } = formatStructs({ types }); const { imports } = formatImports({ types, - baseMembers: ['Predicate', 'Provider', 'InputValue', 'PredicateParams'], + baseMembers: ['Predicate', 'Provider', 'InputValue', 'PredicateParams', 'decompressBytecode'], }); const { prefixedInputs: inputs, output } = func.attributes; @@ -45,7 +46,7 @@ export function renderMainTemplate(params: { abi: Abi }) { structs, enums, abiJsonString, - hexlifiedBinString, + compressedBytecode: compressBytecode(hexlifiedBinString), capitalizedName, imports, configurables, diff --git a/packages/abi-typegen/src/templates/script/main.hbs b/packages/abi-typegen/src/templates/script/main.hbs index afcc912bef2..225d540e9ca 100644 --- a/packages/abi-typegen/src/templates/script/main.hbs +++ b/packages/abi-typegen/src/templates/script/main.hbs @@ -53,7 +53,7 @@ export type {{capitalizedName}}Configurables = Partial<{ const abi = {{abiJsonString}}; -const bytecode = '{{hexlifiedBinString}}'; +const bytecode = decompressBytecode('{{compressedBytecode}}'); export class {{capitalizedName}} extends Script<{{capitalizedName}}Inputs, {{capitalizedName}}Output> { diff --git a/packages/abi-typegen/src/templates/script/main.test.ts b/packages/abi-typegen/src/templates/script/main.test.ts index 1f6d0311f69..4ef110104b8 100644 --- a/packages/abi-typegen/src/templates/script/main.test.ts +++ b/packages/abi-typegen/src/templates/script/main.test.ts @@ -1,4 +1,5 @@ import { safeExec } from '@fuel-ts/errors/test-utils'; +import * as utilsMod from '@fuel-ts/utils'; import { join } from 'path'; import { @@ -18,7 +19,13 @@ import { renderMainTemplate } from './main'; * @group node */ describe('main.ts', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + test('should render main template', () => { + vi.spyOn(utilsMod, 'compressBytecode').mockReturnValueOnce('0x-bytecode-here'); + const { restore } = mockVersions(); const project = getTypegenForcProject(AbiTypegenProjectsEnum.SCRIPT); @@ -45,6 +52,8 @@ describe('main.ts', () => { }); test('should render main template with configurables', () => { + vi.spyOn(utilsMod, 'compressBytecode').mockReturnValueOnce('0x-bytecode-here'); + const { restore } = mockVersions(); const project = getTypegenForcProject(AbiTypegenProjectsEnum.SCRIPT_WITH_CONFIGURABLE); diff --git a/packages/abi-typegen/src/templates/script/main.ts b/packages/abi-typegen/src/templates/script/main.ts index b48710b653d..b3ef77de1ee 100644 --- a/packages/abi-typegen/src/templates/script/main.ts +++ b/packages/abi-typegen/src/templates/script/main.ts @@ -1,4 +1,5 @@ import { ErrorCode, FuelError } from '@fuel-ts/errors'; +import { compressBytecode } from '@fuel-ts/utils'; import type { Abi } from '../../abi/Abi'; import { renderHbsTemplate } from '../renderHbsTemplate'; @@ -30,7 +31,10 @@ export function renderMainTemplate(params: { abi: Abi }) { const { enums } = formatEnums({ types }); const { structs } = formatStructs({ types }); - const { imports } = formatImports({ types, baseMembers: ['Script', 'Account'] }); + const { imports } = formatImports({ + types, + baseMembers: ['Script', 'Account', 'decompressBytecode'], + }); const { prefixedInputs: inputs, output } = func.attributes; @@ -42,7 +46,7 @@ export function renderMainTemplate(params: { abi: Abi }) { structs, enums, abiJsonString, - hexlifiedBinString, + compressedBytecode: compressBytecode(hexlifiedBinString), capitalizedName, imports, configurables, diff --git a/packages/abi-typegen/test/fixtures/templates/contract/factory.hbs b/packages/abi-typegen/test/fixtures/templates/contract/factory.hbs index c1c4d0796cf..fb8630c1371 100644 --- a/packages/abi-typegen/test/fixtures/templates/contract/factory.hbs +++ b/packages/abi-typegen/test/fixtures/templates/contract/factory.hbs @@ -10,12 +10,12 @@ Fuel-Core version: 33.33.33 */ -import { ContractFactory } from "fuels"; +import { ContractFactory, decompressBytecode } from "fuels"; import type { Provider, Account, DeployContractOptions, DeployContractResult } from "fuels"; import { MyContract } from "./MyContract"; -const bytecode = "0x-bytecode-here"; +const bytecode = decompressBytecode("0x-bytecode-here"); export class MyContractFactory extends ContractFactory { diff --git a/packages/abi-typegen/test/fixtures/templates/predicate-with-configurable/main.hbs b/packages/abi-typegen/test/fixtures/templates/predicate-with-configurable/main.hbs index 86204f512ae..afd2e10c3c4 100644 --- a/packages/abi-typegen/test/fixtures/templates/predicate-with-configurable/main.hbs +++ b/packages/abi-typegen/test/fixtures/templates/predicate-with-configurable/main.hbs @@ -12,6 +12,7 @@ import { BigNumberish, + decompressBytecode, InputValue, Predicate, PredicateParams, @@ -99,7 +100,7 @@ const abi = { ] }; -const bytecode = '0x000'; +const bytecode = decompressBytecode('0x-bytecode-here'); export class MyPredicate extends Predicate< MyPredicateInputs, diff --git a/packages/abi-typegen/test/fixtures/templates/predicate/main.hbs b/packages/abi-typegen/test/fixtures/templates/predicate/main.hbs index 12c5e476e31..dd6bc168cba 100644 --- a/packages/abi-typegen/test/fixtures/templates/predicate/main.hbs +++ b/packages/abi-typegen/test/fixtures/templates/predicate/main.hbs @@ -13,6 +13,7 @@ import { BigNumberish, BN, + decompressBytecode, InputValue, Predicate, PredicateParams, @@ -297,7 +298,7 @@ const abi = { "configurables": [] }; -const bytecode = '0x000'; +const bytecode = decompressBytecode('0x-bytecode-here'); export class MyPredicate extends Predicate< MyPredicateInputs, diff --git a/packages/abi-typegen/test/fixtures/templates/script-with-configurable/main.hbs b/packages/abi-typegen/test/fixtures/templates/script-with-configurable/main.hbs index 33636339ed2..c9d6be8b7cf 100644 --- a/packages/abi-typegen/test/fixtures/templates/script-with-configurable/main.hbs +++ b/packages/abi-typegen/test/fixtures/templates/script-with-configurable/main.hbs @@ -13,6 +13,7 @@ import { Account, BigNumberish, + decompressBytecode, Script, } from 'fuels'; @@ -92,7 +93,7 @@ const abi = { ] }; -const bytecode = '0x000'; +const bytecode = decompressBytecode('0x-bytecode-here'); export class MyScript extends Script { diff --git a/packages/abi-typegen/test/fixtures/templates/script/main.hbs b/packages/abi-typegen/test/fixtures/templates/script/main.hbs index 239131def05..c99d2319601 100644 --- a/packages/abi-typegen/test/fixtures/templates/script/main.hbs +++ b/packages/abi-typegen/test/fixtures/templates/script/main.hbs @@ -14,6 +14,7 @@ import { Account, BigNumberish, BN, + decompressBytecode, Script, } from 'fuels'; @@ -289,7 +290,7 @@ const abi = { "configurables": [] }; -const bytecode = '0x000'; +const bytecode = decompressBytecode('0x-bytecode-here'); export class MyScript extends Script { diff --git a/packages/account/src/providers/provider.test.ts b/packages/account/src/providers/provider.test.ts index 9f7198a9736..a87c419ed95 100644 --- a/packages/account/src/providers/provider.test.ts +++ b/packages/account/src/providers/provider.test.ts @@ -677,7 +677,53 @@ describe('Provider', () => { () => sender.sendTransaction(request), new FuelError( ErrorCode.MAX_INPUTS_EXCEEDED, - 'The transaction exceeds the maximum allowed number of inputs for funding.' + 'The transaction exceeds the maximum allowed number of inputs.' + ) + ); + }); + + it('should throws if max of ouputs was exceeded', async () => { + const maxOutputs = 2; + using launched = await setupTestProviderAndWallets({ + nodeOptions: { + snapshotConfig: { + chainConfig: { + consensus_parameters: { + V1: { + tx_params: { + V1: { + max_outputs: maxOutputs, + }, + }, + }, + }, + }, + }, + }, + walletsConfig: { + count: 3, + }, + }); + + const { + wallets: [sender, receiver1, receiver2], + provider, + } = launched; + + const baseAssetId = provider.getBaseAssetId(); + + const request = new ScriptTransactionRequest(); + const resources = await sender.getResourcesToSpend([[1000, baseAssetId]]); + request.addCoinOutput(receiver1.address, 1, baseAssetId); + request.addCoinOutput(receiver2.address, 1, baseAssetId); + + request.addResources(resources); + + await expectToThrowFuelError( + () => sender.sendTransaction(request), + new FuelError( + ErrorCode.MAX_OUTPUTS_EXCEEDED, + 'The transaction exceeds the maximum allowed number of outputs.' ) ); }); diff --git a/packages/account/src/providers/provider.ts b/packages/account/src/providers/provider.ts index 9b3f0da9dc7..b699cbfae38 100644 --- a/packages/account/src/providers/provider.ts +++ b/packages/account/src/providers/provider.ts @@ -704,10 +704,18 @@ Supported fuel-core version: ${supportedVersion}.` } private validateTransaction(tx: TransactionRequest, consensusParameters: ConsensusParameters) { - if (bn(tx.inputs.length).gt(consensusParameters.txParameters.maxInputs)) { + const { maxOutputs, maxInputs } = consensusParameters.txParameters; + if (bn(tx.inputs.length).gt(maxInputs)) { throw new FuelError( ErrorCode.MAX_INPUTS_EXCEEDED, - 'The transaction exceeds the maximum allowed number of inputs for funding.' + 'The transaction exceeds the maximum allowed number of inputs.' + ); + } + + if (bn(tx.outputs.length).gt(maxOutputs)) { + throw new FuelError( + ErrorCode.MAX_OUTPUTS_EXCEEDED, + 'The transaction exceeds the maximum allowed number of outputs.' ); } } diff --git a/packages/errors/src/error-codes.ts b/packages/errors/src/error-codes.ts index a8a7d51305c..b543b6b8dc5 100644 --- a/packages/errors/src/error-codes.ts +++ b/packages/errors/src/error-codes.ts @@ -78,6 +78,7 @@ export enum ErrorCode { TRANSACTION_SQUEEZED_OUT = 'transaction-squeezed-out', CONTRACT_SIZE_EXCEEDS_LIMIT = 'contract-size-exceeds-limit', MAX_INPUTS_EXCEEDED = 'max-inputs-exceeded', + MAX_OUTPUTS_EXCEEDED = 'max-outputs-exceeded', // receipt INVALID_RECEIPT_TYPE = 'invalid-receipt-type', diff --git a/packages/fuel-gauge/src/transaction-response.test.ts b/packages/fuel-gauge/src/transaction-response.test.ts index 6c22107e0bf..8e2c72acd47 100644 --- a/packages/fuel-gauge/src/transaction-response.test.ts +++ b/packages/fuel-gauge/src/transaction-response.test.ts @@ -204,7 +204,7 @@ describe('TransactionResponse', () => { it( 'should throw error for a SqueezedOut status update [waitForResult]', - { timeout: 10_000 }, + { timeout: 10_000, retry: 10 }, async () => { /** * a larger --tx-pool-ttl 1s is necessary to ensure that the transaction doesn't get squeezed out diff --git a/packages/utils/package.json b/packages/utils/package.json index a800a0a1495..d6247a6a4dd 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -50,6 +50,7 @@ "@fuel-ts/errors": "workspace:*", "@fuel-ts/interfaces": "workspace:*", "@fuel-ts/math": "workspace:*", - "@fuel-ts/versions": "workspace:*" + "@fuel-ts/versions": "workspace:*", + "fflate": "^0.8.2" } } diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index ba483c283e7..deba8f20bc2 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -13,3 +13,4 @@ export * from './utils/base58'; export * from './utils/dataSlice'; export * from './utils/toUtf8Bytes'; export * from './utils/toUtf8String'; +export * from './utils/bytecode'; diff --git a/packages/utils/src/utils/bytecode.test.ts b/packages/utils/src/utils/bytecode.test.ts new file mode 100644 index 00000000000..cbd25098034 --- /dev/null +++ b/packages/utils/src/utils/bytecode.test.ts @@ -0,0 +1,28 @@ +import { arrayify } from './arrayify'; +import { compressBytecode, decompressBytecode } from './bytecode'; + +/** + * We are using a base64 encoded bytecode here to avoid having to + * read the file from disk. This is because we cannot read files + * from the filesystem in a browser testing environment. + */ +const bytecodeBase64 = + 'GvAwAHQAAAIAAAAAAAAEgF3/wAEQ//8AdAAAABrsUACRAAIYXVPwAhBRQMAaQGAAckQCUBBBBEAa6QAAIPgzAFj74AJQ++AEdAAAyRpD0ABQR7AQX+0AAlBDsbBySAAIKEEUgBpAYAByRAJIEEEEQBrpAAAg+DMAWPvgAlD74AR0AAC7GkPQAFBHsFBf7QAKUEOx2HJIAAgoQRSAUEOx2F1HsDtdRRAAXUuwO3JMAAgQSSTAX+0gO1BLsChyTAAIKEkEwF/tEAZQQ7IIckwAEChBJMBdQ7A7EEEEQF/tADtQQ7IIUEux+HJMABAoSQTAUEOx+FBLsUByTAAQKEkEwBrpIAAg+DMAWPvgAlD74AR0AACiGkPQAFBLsBhf7QADX+0QBFBDsbhyRAAQKEEkQFBDsbhf7UAAckQADV/tEAFQR7CYckgAEChHtIBQS7FgckwAEChJBMAa6SAAIPgzAFj74AJQ++AEdAAAnBpL0ABQT7FwclAAEChNFQAa6TAAIPgzAFj74AJQ++AEdAAAkxpP0AATSSTAE0kgABpMAAB2SAAcUEuxkHJMABAoSQTAGukgACD4MwBY++ACUPvgBHQAAJYaS9AAUE+xoHJQABAoTRUAGukwACD4MwBY++ACUPvgBHQAAI0aR9AAUE+xgHJQABAoTQUAGukwACD4MwBY++ACUPvgBHQAAHQaQ9AAKU0kUHZMAAF0AABTIPgzAFj74AJQ++AEdAAAjBpL0AByQAQAJkAAABpAcABQR7BwX+0ADnJABABf7QAPX+wAEFBDsKhyTAAYKEEUwFBHsQByTAAYKEUEwFBDsDhyTAAYKEEUwF1DsAddU7AIXU+wCRBFMEAVRRUAdkQAAXQAAAVyRAACG1FEQCZQAAAoHQTAGkBwABBFBMBeRSAAEEUwQFBLsMBf7QAYX+1AGV/tEBpQQ7DockQAGChBJEBQR7HgckgAGChFBIBQQ7HgUEexGHJIABgoRQSAUEOwWHJIABgoQRSAXUewC1BBABBQS7DYX+0QG1BFIAhyTAAIKEUEwFBDschyRAAQKEEkQFBDschQR7FQckgAEChFBIAa6RAAIPgzAFj74AJQ++AEdAAAFxpD0ABQR7HIUEuxMHJMABAoSRTAUEewiHJMABAoRSTAXUewEiVBEAByQAB7NkAAAJUAAAOWCAAAGuxQABpDoAAaR+AAXUEAABr1AAAa+RAAmAgAAJcAAANK+AAAlQAAB5YIAAAa7FAAkQAAEBpDoAAaR+AAckgAECjtBIAaQ7AAXUEAABr1AACSAAAQGvkQAJgIAACXAAAHSvgAAJUAAAeWCAAAGuxQAJEAABAaQ6AAGkfgAHJIABAo7QSAGkOwAF1BAAEa9QAAkgAAEBr5EACYCAAAlwAAB0r4AACVAAAHlggAABrsUACRAAAQGkOgABpH4ABySAAQKO0EgBpDsABdQQAAGvUAAJIAABAa+RAAmAgAAJcAAAdK+AAAlQAAAZYIAAAa7FAAGkPgABr0EAAa+QAAmAgAAJcAAAFK+AAAdGVzdF9mdW5jdGlvbgAAAAAAAAAAAARY'; +const bytecodeBinary = Uint8Array.from(atob(bytecodeBase64), (c) => c.charCodeAt(0)); + +/** + * @group node + * @group browser + */ +describe('bytecode utils', () => { + test('should compress bytecode', () => { + const compressedBytecode = compressBytecode(bytecodeBinary); + expect(compressedBytecode.length).toBeLessThan(bytecodeBinary.length); + }); + + test('should decompress bytecode', () => { + const compressedBytecode = compressBytecode(bytecodeBinary); + const decompressedBytecode = decompressBytecode(compressedBytecode); + expect(decompressedBytecode).toEqual(arrayify(bytecodeBinary)); + }); +}); diff --git a/packages/utils/src/utils/bytecode.ts b/packages/utils/src/utils/bytecode.ts new file mode 100644 index 00000000000..940d31305d0 --- /dev/null +++ b/packages/utils/src/utils/bytecode.ts @@ -0,0 +1,24 @@ +import type { BytesLike } from '@fuel-ts/interfaces'; +import { gzipSync, gunzipSync } from 'fflate'; + +import { arrayify } from './arrayify'; + +export const compressBytecode = (bytecode?: BytesLike) => { + if (!bytecode) { + return ''; + } + + const bytecodeBytes = arrayify(bytecode); + const bytecodeGzipped = gzipSync(bytecodeBytes); + const bytecodeEncoded = Buffer.from(bytecodeGzipped).toString('base64'); + + return bytecodeEncoded; +}; + +export const decompressBytecode = (bytecode: string) => { + const bytecodeDecoded = Buffer.from(bytecode, 'base64').toString('binary'); + const bytecodeGzipped = Buffer.from(bytecodeDecoded, 'binary'); + const bytecodeBytes = gunzipSync(bytecodeGzipped); + + return bytecodeBytes; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acfa16737d4..1795d6372f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1164,6 +1164,9 @@ importers: '@fuel-ts/versions': specifier: workspace:* version: link:../versions + fflate: + specifier: ^0.8.2 + version: 0.8.2 packages/versions: dependencies: @@ -3772,6 +3775,9 @@ packages: '@lit-labs/ssr-dom-shim@1.2.0': resolution: {integrity: sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==} + '@lit-labs/ssr-dom-shim@1.2.1': + resolution: {integrity: sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==} + '@lit/reactive-element@1.6.3': resolution: {integrity: sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==} @@ -6303,8 +6309,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - babel-plugin-polyfill-corejs3@0.10.4: - resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -8200,6 +8206,9 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -9992,6 +10001,10 @@ packages: resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} engines: {node: 14 || >=16.14} + lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -16478,7 +16491,7 @@ snapshots: '@babel/helper-module-imports': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) semver: 6.3.1 transitivePeerDependencies: @@ -16940,7 +16953,7 @@ snapshots: '@babel/traverse@7.24.1': dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.24.6 '@babel/generator': 7.24.4 '@babel/helper-environment-visitor': 7.24.6 '@babel/helper-function-name': 7.24.6 @@ -17015,7 +17028,7 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.6.3 + semver: 7.5.4 '@changesets/assemble-release-plan@6.0.3': dependencies: @@ -17025,7 +17038,7 @@ snapshots: '@changesets/should-skip-package': 0.1.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - semver: 7.6.3 + semver: 7.5.4 '@changesets/changelog-git@0.2.0': dependencies: @@ -17086,7 +17099,7 @@ snapshots: '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 7.6.3 + semver: 7.5.4 '@changesets/get-github-info@0.6.0': dependencies: @@ -18485,9 +18498,11 @@ snapshots: '@lit-labs/ssr-dom-shim@1.2.0': {} + '@lit-labs/ssr-dom-shim@1.2.1': {} + '@lit/reactive-element@1.6.3': dependencies: - '@lit-labs/ssr-dom-shim': 1.2.0 + '@lit-labs/ssr-dom-shim': 1.2.1 '@lit/reactive-element@2.0.4': dependencies: @@ -20393,7 +20408,7 @@ snapshots: grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 - semver: 7.6.3 + semver: 7.3.8 tsutils: 3.21.0(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 @@ -20550,7 +20565,7 @@ snapshots: '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.4.5) eslint: 8.57.0 eslint-scope: 5.1.1 - semver: 7.6.3 + semver: 7.3.8 transitivePeerDependencies: - supports-color - typescript @@ -20579,7 +20594,7 @@ snapshots: '@typescript-eslint/types': 6.9.1 '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.4.5) eslint: 8.57.0 - semver: 7.6.3 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript @@ -21945,7 +21960,7 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.25.2): + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.2): dependencies: '@babel/core': 7.25.2 '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) @@ -22936,7 +22951,7 @@ snapshots: postcss-modules-scope: 3.0.0(postcss@8.4.40) postcss-modules-values: 4.0.0(postcss@8.4.40) postcss-value-parser: 4.2.0 - semver: 7.6.3 + semver: 7.3.8 webpack: 5.88.0(esbuild@0.17.19) css-minimizer-webpack-plugin@3.4.1(esbuild@0.17.19)(webpack@5.88.0(esbuild@0.17.19)): @@ -24455,6 +24470,8 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.2.1 + fflate@0.8.2: {} + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -24602,7 +24619,7 @@ snapshots: memfs: 3.5.3 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.6.3 + semver: 7.3.8 tapable: 1.1.3 typescript: 5.4.5 webpack: 5.88.0(esbuild@0.17.19) @@ -25942,7 +25959,7 @@ snapshots: jest-message-util@27.5.1: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.24.6 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -25954,7 +25971,7 @@ snapshots: jest-message-util@28.1.3: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.24.6 '@jest/types': 28.1.3 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -26531,7 +26548,7 @@ snapshots: lit-element@3.3.3: dependencies: - '@lit-labs/ssr-dom-shim': 1.2.0 + '@lit-labs/ssr-dom-shim': 1.2.1 '@lit/reactive-element': 1.6.3 lit-html: 2.8.0 @@ -26701,6 +26718,8 @@ snapshots: lru-cache@10.0.0: {} + lru-cache@10.2.0: {} + lru-cache@10.4.3: {} lru-cache@4.1.5: @@ -27890,7 +27909,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.24.6 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -27940,7 +27959,7 @@ snapshots: path-scurry@1.11.1: dependencies: - lru-cache: 10.4.3 + lru-cache: 10.2.0 minipass: 7.0.4 path-to-glob-pattern@1.0.2: {} @@ -28255,7 +28274,7 @@ snapshots: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.4.40 - semver: 7.6.3 + semver: 7.3.8 webpack: 5.88.0(esbuild@0.17.19) postcss-logical@5.0.4(postcss@8.4.40): @@ -29386,7 +29405,7 @@ snapshots: rollup-plugin-terser@7.0.2(rollup@2.79.1): dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.24.6 jest-worker: 26.6.2 rollup: 2.79.1 serialize-javascript: 4.0.0 @@ -29701,7 +29720,7 @@ snapshots: simple-update-notifier@2.0.0: dependencies: - semver: 7.6.3 + semver: 7.5.4 sirv@2.0.4: dependencies: