Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.11.2/redeclare ts #660

Merged
merged 4 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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