Skip to content

Commit

Permalink
Merge pull request #660 from 0xs34n/0.11.2/redeclare-ts
Browse files Browse the repository at this point in the history
0.11.2/redeclare ts
  • Loading branch information
tabaktoni committed Jun 26, 2023
2 parents 1a63522 + 00b7bdf commit be8ba99
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 44 deletions.
45 changes: 31 additions & 14 deletions __tests__/account.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Signature } from 'micro-starknet';

import typedDataExample from '../__mocks__/typedDataExample.json';
import {
Account,
Expand All @@ -8,17 +6,16 @@ import {
Provider,
TransactionStatus,
TransactionType,
cairo,
contractClassResponseToLegacyCompiledContract,
ec,
extractContractHashes,
hash,
num,
parseUDCEvent,
shortString,
stark,
} from '../src';
import { uint256 } from '../src/utils/calldata/cairo';
import { 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';
import { encodeShortString } from '../src/utils/shortString';
import { randomAddress } from '../src/utils/stark';
import {
compiledErc20,
compiledHelloSierra,
Expand All @@ -34,18 +31,25 @@ import {
} from './fixtures';
import { initializeMatcher } from './schema';

const { cleanHex, hexToDecimalString, toBigInt, toHex } = num;
const { encodeShortString } = shortString;
const { randomAddress } = stark;
const { uint256 } = cairo;
const { Signature } = ec.starkCurve;

describe('deploy and test Wallet', () => {
const provider = new Provider(getTestProvider());
const account = getTestAccount(provider);
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'),
Expand All @@ -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);
Expand All @@ -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({
Expand All @@ -77,7 +94,7 @@ describe('deploy and test Wallet', () => {
});

expect(result).toMatchSchemaRef('EstimateFee');
expect(innerInvokeEstFeeSpy.mock.calls[0][1].version).toBe(feeTransactionVersion);
expect(innerInvokeEstFeeSpy.mock.calls[0][1].version).toBe(hash.feeTransactionVersion);
innerInvokeEstFeeSpy.mockClear();
});

Expand Down Expand Up @@ -287,7 +304,7 @@ describe('deploy and test Wallet', () => {
await provider.waitForTransaction(declareAccount.transaction_hash);
const privateKey = stark.randomAddress();
const starkKeyPub = ec.starkCurve.getStarkKey(privateKey);
const precalculatedAddress = calculateContractAddressFromHash(
const precalculatedAddress = hash.calculateContractAddressFromHash(
starkKeyPub,
accountClassHash,
{ publicKey: starkKeyPub },
Expand Down Expand Up @@ -595,7 +612,7 @@ describe('deploy and test Wallet', () => {

const privateKey = stark.randomAddress();
starkKeyPub = ec.starkCurve.getStarkKey(privateKey);
precalculatedAddress = calculateContractAddressFromHash(
precalculatedAddress = hash.calculateContractAddressFromHash(
starkKeyPub,
accountClassHash,
{ publicKey: starkKeyPub },
Expand Down
47 changes: 33 additions & 14 deletions __tests__/cairo1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
BigNumberish,
CallData,
Calldata,
CompiledSierra,
Contract,
DeclareDeployUDCResponse,
RawArgsArray,
Expand All @@ -13,11 +14,10 @@ import {
ec,
hash,
num,
selector,
shortString,
stark,
} from '../src';
import { isCairo1Abi } from '../src/utils/calldata/cairo';
import { starknetKeccak } from '../src/utils/selector';
import {
compiledC1Account,
compiledC1AccountCasm,
Expand All @@ -32,6 +32,10 @@ import {
} from './fixtures';
import { initializeMatcher } from './schema';

const { uint256, tuple, isCairo1Abi } = cairo;
const { toHex } = num;
const { starknetKeccak } = selector;

describeIfDevnet('Cairo 1 Devnet', () => {
describe('API & Contract interactions', () => {
const provider = getTestProvider();
Expand All @@ -55,6 +59,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,
Expand Down Expand Up @@ -123,7 +142,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
expect(result).toBe(2n ** 256n - 1n);

// defined as struct
const result1 = await cairo1Contract.test_u256(cairo.uint256(2n ** 256n - 2n));
const result1 = await cairo1Contract.test_u256(uint256(2n ** 256n - 2n));
expect(result1).toBe(2n ** 256n - 1n);
});

Expand Down Expand Up @@ -200,7 +219,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
});

test('Cairo 1 Contract Interaction - echo flat un-named un-nested tuple', async () => {
const status = await cairo1Contract.echo_un_tuple(cairo.tuple(77, 123));
const status = await cairo1Contract.echo_un_tuple(tuple(77, 123));
expect(Object.values(status)).toEqual([77n, 123n]);
});

Expand All @@ -214,10 +233,10 @@ describeIfDevnet('Cairo 1 Devnet', () => {

// uint256 defined as struct
const status11 = await cairo1Contract.echo_array_u256([
cairo.uint256(123),
cairo.uint256(55),
cairo.uint256(77),
cairo.uint256(255),
uint256(123),
uint256(55),
uint256(77),
uint256(255),
]);
expect(status11).toEqual([123n, 55n, 77n, 255n]);

Expand Down Expand Up @@ -305,7 +324,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
1: true,
});

const res1 = await cairo1Contract.tuple_echo(cairo.tuple([1, 2, 3], [4, 5, 6]));
const res1 = await cairo1Contract.tuple_echo(tuple([1, 2, 3], [4, 5, 6]));
expect(res1).toEqual({
0: [1n, 2n, 3n],
1: [4n, 5n, 6n],
Expand All @@ -331,7 +350,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
initial_supply: myFalseUint256,
recipient: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
decimals: 18,
tupoftup: cairo.tuple(cairo.tuple(34, '0x5e'), myFalseUint256),
tupoftup: tuple(tuple(34, '0x5e'), myFalseUint256),
card: myOrder2bis,
longText: 'Bug is back, for ever, here and everywhere',
array1: [100, 101, 102],
Expand All @@ -342,9 +361,9 @@ describeIfDevnet('Cairo 1 Devnet', () => {
],
array3: [myOrder2bis, myOrder2bis],
array4: [myFalseUint256, myFalseUint256],
tuple1: cairo.tuple(40000n, myOrder2bis, [54, 55n, '0xae'], 'texte'),
tuple1: tuple(40000n, myOrder2bis, [54, 55n, '0xae'], 'texte'),
name: 'niceToken',
array5: [cairo.tuple(251, 40000n), cairo.tuple(252, 40001n)],
array5: [tuple(251, 40000n), tuple(252, 40001n)],
};
const myRawArgsArray: RawArgsArray = [
'niceToken',
Expand Down Expand Up @@ -503,7 +522,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
entrypoint: 'transfer',
calldata: {
recipient: toBeAccountAddress,
amount: cairo.uint256(1_000_000_000_000_000),
amount: uint256(1_000_000_000_000_000),
},
});
await account.waitForTransaction(transaction_hash);
Expand Down Expand Up @@ -575,7 +594,7 @@ describeIfSequencerTestnet2('Cairo1 Testnet2', () => {
});

test('Cairo 1 - uint256 struct', async () => {
const myUint256 = cairo.uint256(2n ** 256n - 2n);
const myUint256 = uint256(2n ** 256n - 2n);
const result = await cairo1Contract.test_u256(myUint256);
expect(result).toBe(2n ** 256n - 1n);
});
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ export * as shortString from './utils/shortString';
export * as typedData from './utils/typedData';
export * as ec from './utils/ec';
export * as starknetId from './utils/starknetId';
export * as provider from './utils/provider';
export * as selector from './utils/selector';
export * from './utils/address';
export * from './utils/url';
export * from './utils/calldata';
export * from './utils/contract';
export * from './utils/events';

/**
* Deprecated
Expand Down
16 changes: 7 additions & 9 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,14 +337,13 @@ export class RpcProvider implements ProviderInterface {
details: InvocationsDetailsWithNonce
): Promise<DeclareContractResponse> {
if (!isSierra(contract)) {
const legacyContract = contract as LegacyContractClass;
return this.fetchEndpoint('starknet_addDeclareTransaction', {
declare_transaction: {
type: RPC.TransactionType.DECLARE,
contract_class: {
program: legacyContract.program,
entry_points_by_type: legacyContract.entry_points_by_type,
abi: legacyContract.abi,
program: contract.program,
entry_points_by_type: contract.entry_points_by_type,
abi: contract.abi,
},
version: toHex(transactionVersion),
max_fee: toHex(details.maxFee || 0),
Expand All @@ -354,15 +353,14 @@ export class RpcProvider implements ProviderInterface {
},
});
}
const sierraContract = contract as SierraContractClass;
return this.fetchEndpoint('starknet_addDeclareTransaction', {
declare_transaction: {
type: RPC.TransactionType.DECLARE,
contract_class: {
sierra_program: decompressProgram(sierraContract.sierra_program),
contract_class_version: sierraContract.contract_class_version,
entry_points_by_type: sierraContract.entry_points_by_type,
abi: sierraContract.abi,
sierra_program: decompressProgram(contract.sierra_program),
contract_class_version: contract.contract_class_version,
entry_points_by_type: contract.entry_points_by_type,
abi: contract.abi,
},
compiled_class_hash: compiledClassHash || '',
version: toHex(transactionVersion_2),
Expand Down
5 changes: 5 additions & 0 deletions src/types/lib/contract/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/types/lib/contract/sierra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 11 additions & 3 deletions src/types/provider/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -172,4 +172,12 @@ export interface StateUpdateResponse {
};
}

export type ContractClassResponse = Omit<ContractClass, 'abi'> & { 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<CompiledSierra, 'sierra_program_debug_info'>;
27 changes: 25 additions & 2 deletions src/utils/contract.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { CairoContract } 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) {
export function isSierra(
contract: CairoContract | string
): contract is SierraContractClass | CompiledSierra {
const compiledContract = typeof contract === 'string' ? parse(contract) : contract;
return 'sierra_program' in compiledContract;
}
Expand All @@ -29,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;
}
Loading

0 comments on commit be8ba99

Please sign in to comment.