diff --git a/__mocks__/cairo/helloSierra/hello.cairo b/__mocks__/cairo/helloSierra/hello.cairo index 588e4d0da..2daf7302b 100644 --- a/__mocks__/cairo/helloSierra/hello.cairo +++ b/__mocks__/cairo/helloSierra/hello.cairo @@ -329,12 +329,6 @@ mod HelloStarknet { testbet::read() } - //#[external] - //fn set_user() { - // let newUser = UserData{address: 0xff, is_claimed: true}; - // user::write(newUser); - //} - #[external] fn set_user1(user: UserData) { user1::write(user); diff --git a/__tests__/account.test.ts b/__tests__/account.test.ts index 0765a4f9e..07f163efb 100644 --- a/__tests__/account.test.ts +++ b/__tests__/account.test.ts @@ -13,7 +13,10 @@ import { stark, } from '../src'; import { uint256 } from '../src/utils/calldata/cairo'; -import { extractContractHashes } from '../src/utils/contract'; +import { + contractClassResponseToLegacyCompiledContract, + extractContractHashes, +} from '../src/utils/contract'; import { parseUDCEvent } from '../src/utils/events'; import { calculateContractAddressFromHash, feeTransactionVersion } from '../src/utils/hash'; import { cleanHex, hexToDecimalString, toBigInt, toHex } from '../src/utils/num'; @@ -40,12 +43,13 @@ describe('deploy and test Wallet', () => { let erc20: Contract; let erc20Address: string; let dapp: Contract; + let dd: DeclareDeployUDCResponse; beforeAll(async () => { initializeMatcher(expect); expect(account).toBeInstanceOf(Account); - const declareDeploy = await account.declareAndDeploy({ + dd = await account.declareAndDeploy({ contract: compiledErc20, constructorCalldata: [ encodeShortString('Token'), @@ -54,7 +58,7 @@ describe('deploy and test Wallet', () => { ], }); - erc20Address = declareDeploy.deploy.contract_address; + erc20Address = dd.deploy.contract_address; erc20 = new Contract(compiledErc20.abi, erc20Address, provider); const { balance } = await erc20.balanceOf(account.address); @@ -68,6 +72,19 @@ describe('deploy and test Wallet', () => { dapp = new Contract(compiledTestDapp.abi, dappResponse.deploy.contract_address!, provider); }); + xtest('validate TS for redeclare - skip testing', async () => { + const cc0 = await account.getClassAt(dd.deploy.address); + const cc0_1 = await account.getClassByHash(toHex(dd.declare.class_hash)); + + await account.declare({ + contract: contractClassResponseToLegacyCompiledContract(cc0), + }); + + await account.declare({ + contract: contractClassResponseToLegacyCompiledContract(cc0_1), + }); + }); + test('estimateInvokeFee Cairo 0', async () => { const innerInvokeEstFeeSpy = jest.spyOn(account.signer, 'signTransaction'); const result = await account.estimateInvokeFee({ diff --git a/__tests__/cairo1.test.ts b/__tests__/cairo1.test.ts index 285d7e101..b0d4b2636 100644 --- a/__tests__/cairo1.test.ts +++ b/__tests__/cairo1.test.ts @@ -4,6 +4,7 @@ import { BigNumberish, CallData, Calldata, + CompiledSierra, Contract, DeclareDeployUDCResponse, RawArgsArray, @@ -16,6 +17,7 @@ import { shortString, stark, } from '../src'; +import { toHex } from '../src/utils/num'; import { starknetKeccak } from '../src/utils/selector'; import { compiledC1Account, @@ -54,6 +56,21 @@ describeIfDevnet('Cairo 1 Devnet', () => { expect(cairo1Contract).toBeInstanceOf(Contract); }); + xtest('validate TS for redeclare - skip testing', async () => { + const cc0 = await account.getClassAt(dd.deploy.address); + const cc0_1 = await account.getClassByHash(toHex(dd.declare.class_hash)); + + await account.declare({ + contract: cc0 as CompiledSierra, + casm: compiledHelloSierraCasm, + }); + + await account.declare({ + contract: cc0_1 as CompiledSierra, + casm: compiledHelloSierraCasm, + }); + }); + test('deployContract Cairo1', async () => { const deploy = await account.deployContract({ classHash: dd.deploy.classHash, diff --git a/src/types/lib/contract/index.ts b/src/types/lib/contract/index.ts index dc603e5c7..810d65505 100644 --- a/src/types/lib/contract/index.ts +++ b/src/types/lib/contract/index.ts @@ -7,10 +7,15 @@ import { CompiledSierra, SierraContractClass } from './sierra'; * CompressedCompiledContract */ export type ContractClass = LegacyContractClass | SierraContractClass; + /** * format produced after compile .cairo to .json */ export type CompiledContract = LegacyCompiledContract | CompiledSierra; + +/** + * Compressed or decompressed Cairo0 or Cairo1 Contract + */ export type CairoContract = ContractClass | CompiledContract; // Basic elements diff --git a/src/types/lib/contract/sierra.ts b/src/types/lib/contract/sierra.ts index f44dc3399..2973f9a83 100644 --- a/src/types/lib/contract/sierra.ts +++ b/src/types/lib/contract/sierra.ts @@ -18,7 +18,7 @@ export type CairoAssembly = { */ export type CompiledSierra = { sierra_program: ByteCode; - sierra_program_debug_info: SierraProgramDebugInfo; + sierra_program_debug_info?: SierraProgramDebugInfo; contract_class_version: string; entry_points_by_type: SierraEntryPointsByType; abi: Abi; diff --git a/src/types/provider/response.ts b/src/types/provider/response.ts index d9102d674..f41cb3009 100644 --- a/src/types/provider/response.ts +++ b/src/types/provider/response.ts @@ -6,13 +6,13 @@ import { RPC } from '../api/rpc'; import { Sequencer } from '../api/sequencer'; import { - Abi, AllowArray, ByteCode, Call, - ContractClass, + CompiledSierra, DeclareContractPayload, DeployAccountContractPayload, + LegacyContractClass, RawCalldata, Signature, Status, @@ -172,4 +172,12 @@ export interface StateUpdateResponse { }; } -export type ContractClassResponse = Omit & { abi?: Abi }; +/** + * Standardized type + * Cairo0 program compressed and Cairo1 sierra_program decompressed + * abi Abi + * CompiledSierra without '.sierra_program_debug_info' + */ +export type ContractClassResponse = + | LegacyContractClass + | Omit; diff --git a/src/utils/contract.ts b/src/utils/contract.ts index e2d71763f..cfb4fdb52 100644 --- a/src/utils/contract.ts +++ b/src/utils/contract.ts @@ -1,7 +1,15 @@ -import { CairoContract, CompiledSierra, SierraContractClass } from '../types/lib/contract/index'; +import { ContractClassResponse } from '../types'; +import { + CairoContract, + CompiledSierra, + LegacyCompiledContract, + LegacyContractClass, + SierraContractClass, +} from '../types/lib/contract/index'; import { CompleteDeclareContractPayload, DeclareContractPayload } from '../types/lib/index'; import { computeCompiledClassHash, computeContractClassHash } from './hash'; import { parse } from './json'; +import { decompressProgram } from './stark'; export function isSierra( contract: CairoContract | string @@ -31,3 +39,16 @@ export function extractContractHashes( return response; } + +/** + * Helper to redeclare response Cairo0 contract + * @param ccr ContractClassResponse + * @returns LegacyCompiledContract + */ +export function contractClassResponseToLegacyCompiledContract(ccr: ContractClassResponse) { + if (isSierra(ccr)) { + throw Error('ContractClassResponse need to be LegacyContractClass (cairo0 response class)'); + } + const contract = ccr as LegacyContractClass; + return { ...contract, program: decompressProgram(contract.program) } as LegacyCompiledContract; +} diff --git a/src/utils/provider.ts b/src/utils/provider.ts index b1fc74749..2da5e3f3c 100644 --- a/src/utils/provider.ts +++ b/src/utils/provider.ts @@ -33,7 +33,6 @@ export function parseContract(contract: CompiledContract | string): ContractClas if (!isSierra(contract)) { return { ...parsedContract, - // TODO: Why do we gzip program object? ...('program' in parsedContract && { program: compressProgram(parsedContract.program) }), } as LegacyContractClass; }