Skip to content

Commit be8ba99

Browse files
authored
Merge pull request #660 from 0xs34n/0.11.2/redeclare-ts
0.11.2/redeclare ts
2 parents 1a63522 + 00b7bdf commit be8ba99

File tree

9 files changed

+117
-44
lines changed

9 files changed

+117
-44
lines changed

__tests__/account.test.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Signature } from 'micro-starknet';
2-
31
import typedDataExample from '../__mocks__/typedDataExample.json';
42
import {
53
Account,
@@ -8,17 +6,16 @@ import {
86
Provider,
97
TransactionStatus,
108
TransactionType,
9+
cairo,
10+
contractClassResponseToLegacyCompiledContract,
1111
ec,
12+
extractContractHashes,
1213
hash,
14+
num,
15+
parseUDCEvent,
16+
shortString,
1317
stark,
1418
} from '../src';
15-
import { uint256 } from '../src/utils/calldata/cairo';
16-
import { extractContractHashes } from '../src/utils/contract';
17-
import { parseUDCEvent } from '../src/utils/events';
18-
import { calculateContractAddressFromHash, feeTransactionVersion } from '../src/utils/hash';
19-
import { cleanHex, hexToDecimalString, toBigInt, toHex } from '../src/utils/num';
20-
import { encodeShortString } from '../src/utils/shortString';
21-
import { randomAddress } from '../src/utils/stark';
2219
import {
2320
compiledErc20,
2421
compiledHelloSierra,
@@ -34,18 +31,25 @@ import {
3431
} from './fixtures';
3532
import { initializeMatcher } from './schema';
3633

34+
const { cleanHex, hexToDecimalString, toBigInt, toHex } = num;
35+
const { encodeShortString } = shortString;
36+
const { randomAddress } = stark;
37+
const { uint256 } = cairo;
38+
const { Signature } = ec.starkCurve;
39+
3740
describe('deploy and test Wallet', () => {
3841
const provider = new Provider(getTestProvider());
3942
const account = getTestAccount(provider);
4043
let erc20: Contract;
4144
let erc20Address: string;
4245
let dapp: Contract;
46+
let dd: DeclareDeployUDCResponse;
4347

4448
beforeAll(async () => {
4549
initializeMatcher(expect);
4650
expect(account).toBeInstanceOf(Account);
4751

48-
const declareDeploy = await account.declareAndDeploy({
52+
dd = await account.declareAndDeploy({
4953
contract: compiledErc20,
5054
constructorCalldata: [
5155
encodeShortString('Token'),
@@ -54,7 +58,7 @@ describe('deploy and test Wallet', () => {
5458
],
5559
});
5660

57-
erc20Address = declareDeploy.deploy.contract_address;
61+
erc20Address = dd.deploy.contract_address;
5862
erc20 = new Contract(compiledErc20.abi, erc20Address, provider);
5963

6064
const { balance } = await erc20.balanceOf(account.address);
@@ -68,6 +72,19 @@ describe('deploy and test Wallet', () => {
6872
dapp = new Contract(compiledTestDapp.abi, dappResponse.deploy.contract_address!, provider);
6973
});
7074

75+
xtest('validate TS for redeclare - skip testing', async () => {
76+
const cc0 = await account.getClassAt(dd.deploy.address);
77+
const cc0_1 = await account.getClassByHash(toHex(dd.declare.class_hash));
78+
79+
await account.declare({
80+
contract: contractClassResponseToLegacyCompiledContract(cc0),
81+
});
82+
83+
await account.declare({
84+
contract: contractClassResponseToLegacyCompiledContract(cc0_1),
85+
});
86+
});
87+
7188
test('estimateInvokeFee Cairo 0', async () => {
7289
const innerInvokeEstFeeSpy = jest.spyOn(account.signer, 'signTransaction');
7390
const result = await account.estimateInvokeFee({
@@ -77,7 +94,7 @@ describe('deploy and test Wallet', () => {
7794
});
7895

7996
expect(result).toMatchSchemaRef('EstimateFee');
80-
expect(innerInvokeEstFeeSpy.mock.calls[0][1].version).toBe(feeTransactionVersion);
97+
expect(innerInvokeEstFeeSpy.mock.calls[0][1].version).toBe(hash.feeTransactionVersion);
8198
innerInvokeEstFeeSpy.mockClear();
8299
});
83100

@@ -287,7 +304,7 @@ describe('deploy and test Wallet', () => {
287304
await provider.waitForTransaction(declareAccount.transaction_hash);
288305
const privateKey = stark.randomAddress();
289306
const starkKeyPub = ec.starkCurve.getStarkKey(privateKey);
290-
const precalculatedAddress = calculateContractAddressFromHash(
307+
const precalculatedAddress = hash.calculateContractAddressFromHash(
291308
starkKeyPub,
292309
accountClassHash,
293310
{ publicKey: starkKeyPub },
@@ -595,7 +612,7 @@ describe('deploy and test Wallet', () => {
595612

596613
const privateKey = stark.randomAddress();
597614
starkKeyPub = ec.starkCurve.getStarkKey(privateKey);
598-
precalculatedAddress = calculateContractAddressFromHash(
615+
precalculatedAddress = hash.calculateContractAddressFromHash(
599616
starkKeyPub,
600617
accountClassHash,
601618
{ publicKey: starkKeyPub },

__tests__/cairo1.test.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
BigNumberish,
55
CallData,
66
Calldata,
7+
CompiledSierra,
78
Contract,
89
DeclareDeployUDCResponse,
910
RawArgsArray,
@@ -13,11 +14,10 @@ import {
1314
ec,
1415
hash,
1516
num,
17+
selector,
1618
shortString,
1719
stark,
1820
} from '../src';
19-
import { isCairo1Abi } from '../src/utils/calldata/cairo';
20-
import { starknetKeccak } from '../src/utils/selector';
2121
import {
2222
compiledC1Account,
2323
compiledC1AccountCasm,
@@ -32,6 +32,10 @@ import {
3232
} from './fixtures';
3333
import { initializeMatcher } from './schema';
3434

35+
const { uint256, tuple, isCairo1Abi } = cairo;
36+
const { toHex } = num;
37+
const { starknetKeccak } = selector;
38+
3539
describeIfDevnet('Cairo 1 Devnet', () => {
3640
describe('API & Contract interactions', () => {
3741
const provider = getTestProvider();
@@ -55,6 +59,21 @@ describeIfDevnet('Cairo 1 Devnet', () => {
5559
expect(cairo1Contract).toBeInstanceOf(Contract);
5660
});
5761

62+
xtest('validate TS for redeclare - skip testing', async () => {
63+
const cc0 = await account.getClassAt(dd.deploy.address);
64+
const cc0_1 = await account.getClassByHash(toHex(dd.declare.class_hash));
65+
66+
await account.declare({
67+
contract: cc0 as CompiledSierra,
68+
casm: compiledHelloSierraCasm,
69+
});
70+
71+
await account.declare({
72+
contract: cc0_1 as CompiledSierra,
73+
casm: compiledHelloSierraCasm,
74+
});
75+
});
76+
5877
test('deployContract Cairo1', async () => {
5978
const deploy = await account.deployContract({
6079
classHash: dd.deploy.classHash,
@@ -123,7 +142,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
123142
expect(result).toBe(2n ** 256n - 1n);
124143

125144
// defined as struct
126-
const result1 = await cairo1Contract.test_u256(cairo.uint256(2n ** 256n - 2n));
145+
const result1 = await cairo1Contract.test_u256(uint256(2n ** 256n - 2n));
127146
expect(result1).toBe(2n ** 256n - 1n);
128147
});
129148

@@ -200,7 +219,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
200219
});
201220

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

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

215234
// uint256 defined as struct
216235
const status11 = await cairo1Contract.echo_array_u256([
217-
cairo.uint256(123),
218-
cairo.uint256(55),
219-
cairo.uint256(77),
220-
cairo.uint256(255),
236+
uint256(123),
237+
uint256(55),
238+
uint256(77),
239+
uint256(255),
221240
]);
222241
expect(status11).toEqual([123n, 55n, 77n, 255n]);
223242

@@ -305,7 +324,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
305324
1: true,
306325
});
307326

308-
const res1 = await cairo1Contract.tuple_echo(cairo.tuple([1, 2, 3], [4, 5, 6]));
327+
const res1 = await cairo1Contract.tuple_echo(tuple([1, 2, 3], [4, 5, 6]));
309328
expect(res1).toEqual({
310329
0: [1n, 2n, 3n],
311330
1: [4n, 5n, 6n],
@@ -331,7 +350,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
331350
initial_supply: myFalseUint256,
332351
recipient: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
333352
decimals: 18,
334-
tupoftup: cairo.tuple(cairo.tuple(34, '0x5e'), myFalseUint256),
353+
tupoftup: tuple(tuple(34, '0x5e'), myFalseUint256),
335354
card: myOrder2bis,
336355
longText: 'Bug is back, for ever, here and everywhere',
337356
array1: [100, 101, 102],
@@ -342,9 +361,9 @@ describeIfDevnet('Cairo 1 Devnet', () => {
342361
],
343362
array3: [myOrder2bis, myOrder2bis],
344363
array4: [myFalseUint256, myFalseUint256],
345-
tuple1: cairo.tuple(40000n, myOrder2bis, [54, 55n, '0xae'], 'texte'),
364+
tuple1: tuple(40000n, myOrder2bis, [54, 55n, '0xae'], 'texte'),
346365
name: 'niceToken',
347-
array5: [cairo.tuple(251, 40000n), cairo.tuple(252, 40001n)],
366+
array5: [tuple(251, 40000n), tuple(252, 40001n)],
348367
};
349368
const myRawArgsArray: RawArgsArray = [
350369
'niceToken',
@@ -503,7 +522,7 @@ describeIfDevnet('Cairo 1 Devnet', () => {
503522
entrypoint: 'transfer',
504523
calldata: {
505524
recipient: toBeAccountAddress,
506-
amount: cairo.uint256(1_000_000_000_000_000),
525+
amount: uint256(1_000_000_000_000_000),
507526
},
508527
});
509528
await account.waitForTransaction(transaction_hash);
@@ -575,7 +594,7 @@ describeIfSequencerTestnet2('Cairo1 Testnet2', () => {
575594
});
576595

577596
test('Cairo 1 - uint256 struct', async () => {
578-
const myUint256 = cairo.uint256(2n ** 256n - 2n);
597+
const myUint256 = uint256(2n ** 256n - 2n);
579598
const result = await cairo1Contract.test_u256(myUint256);
580599
expect(result).toBe(2n ** 256n - 1n);
581600
});

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ export * as shortString from './utils/shortString';
2626
export * as typedData from './utils/typedData';
2727
export * as ec from './utils/ec';
2828
export * as starknetId from './utils/starknetId';
29+
export * as provider from './utils/provider';
30+
export * as selector from './utils/selector';
2931
export * from './utils/address';
3032
export * from './utils/url';
3133
export * from './utils/calldata';
34+
export * from './utils/contract';
35+
export * from './utils/events';
3236

3337
/**
3438
* Deprecated

src/provider/rpc.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,13 @@ export class RpcProvider implements ProviderInterface {
337337
details: InvocationsDetailsWithNonce
338338
): Promise<DeclareContractResponse> {
339339
if (!isSierra(contract)) {
340-
const legacyContract = contract as LegacyContractClass;
341340
return this.fetchEndpoint('starknet_addDeclareTransaction', {
342341
declare_transaction: {
343342
type: RPC.TransactionType.DECLARE,
344343
contract_class: {
345-
program: legacyContract.program,
346-
entry_points_by_type: legacyContract.entry_points_by_type,
347-
abi: legacyContract.abi,
344+
program: contract.program,
345+
entry_points_by_type: contract.entry_points_by_type,
346+
abi: contract.abi,
348347
},
349348
version: toHex(transactionVersion),
350349
max_fee: toHex(details.maxFee || 0),
@@ -354,15 +353,14 @@ export class RpcProvider implements ProviderInterface {
354353
},
355354
});
356355
}
357-
const sierraContract = contract as SierraContractClass;
358356
return this.fetchEndpoint('starknet_addDeclareTransaction', {
359357
declare_transaction: {
360358
type: RPC.TransactionType.DECLARE,
361359
contract_class: {
362-
sierra_program: decompressProgram(sierraContract.sierra_program),
363-
contract_class_version: sierraContract.contract_class_version,
364-
entry_points_by_type: sierraContract.entry_points_by_type,
365-
abi: sierraContract.abi,
360+
sierra_program: decompressProgram(contract.sierra_program),
361+
contract_class_version: contract.contract_class_version,
362+
entry_points_by_type: contract.entry_points_by_type,
363+
abi: contract.abi,
366364
},
367365
compiled_class_hash: compiledClassHash || '',
368366
version: toHex(transactionVersion_2),

src/types/lib/contract/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import { CompiledSierra, SierraContractClass } from './sierra';
77
* CompressedCompiledContract
88
*/
99
export type ContractClass = LegacyContractClass | SierraContractClass;
10+
1011
/**
1112
* format produced after compile .cairo to .json
1213
*/
1314
export type CompiledContract = LegacyCompiledContract | CompiledSierra;
15+
16+
/**
17+
* Compressed or decompressed Cairo0 or Cairo1 Contract
18+
*/
1419
export type CairoContract = ContractClass | CompiledContract;
1520

1621
// Basic elements

src/types/lib/contract/sierra.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type CairoAssembly = {
1818
*/
1919
export type CompiledSierra = {
2020
sierra_program: ByteCode;
21-
sierra_program_debug_info: SierraProgramDebugInfo;
21+
sierra_program_debug_info?: SierraProgramDebugInfo;
2222
contract_class_version: string;
2323
entry_points_by_type: SierraEntryPointsByType;
2424
abi: Abi;

src/types/provider/response.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
import { RPC } from '../api/rpc';
77
import { Sequencer } from '../api/sequencer';
88
import {
9-
Abi,
109
AllowArray,
1110
ByteCode,
1211
Call,
13-
ContractClass,
12+
CompiledSierra,
1413
DeclareContractPayload,
1514
DeployAccountContractPayload,
15+
LegacyContractClass,
1616
RawCalldata,
1717
Signature,
1818
Status,
@@ -172,4 +172,12 @@ export interface StateUpdateResponse {
172172
};
173173
}
174174

175-
export type ContractClassResponse = Omit<ContractClass, 'abi'> & { abi?: Abi };
175+
/**
176+
* Standardized type
177+
* Cairo0 program compressed and Cairo1 sierra_program decompressed
178+
* abi Abi
179+
* CompiledSierra without '.sierra_program_debug_info'
180+
*/
181+
export type ContractClassResponse =
182+
| LegacyContractClass
183+
| Omit<CompiledSierra, 'sierra_program_debug_info'>;

src/utils/contract.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
import { CairoContract } from '../types/lib/contract/index';
1+
import { ContractClassResponse } from '../types';
2+
import {
3+
CairoContract,
4+
CompiledSierra,
5+
LegacyCompiledContract,
6+
LegacyContractClass,
7+
SierraContractClass,
8+
} from '../types/lib/contract/index';
29
import { CompleteDeclareContractPayload, DeclareContractPayload } from '../types/lib/index';
310
import { computeCompiledClassHash, computeContractClassHash } from './hash';
411
import { parse } from './json';
12+
import { decompressProgram } from './stark';
513

6-
export function isSierra(contract: CairoContract | string) {
14+
export function isSierra(
15+
contract: CairoContract | string
16+
): contract is SierraContractClass | CompiledSierra {
717
const compiledContract = typeof contract === 'string' ? parse(contract) : contract;
818
return 'sierra_program' in compiledContract;
919
}
@@ -29,3 +39,16 @@ export function extractContractHashes(
2939

3040
return response;
3141
}
42+
43+
/**
44+
* Helper to redeclare response Cairo0 contract
45+
* @param ccr ContractClassResponse
46+
* @returns LegacyCompiledContract
47+
*/
48+
export function contractClassResponseToLegacyCompiledContract(ccr: ContractClassResponse) {
49+
if (isSierra(ccr)) {
50+
throw Error('ContractClassResponse need to be LegacyContractClass (cairo0 response class)');
51+
}
52+
const contract = ccr as LegacyContractClass;
53+
return { ...contract, program: decompressProgram(contract.program) } as LegacyCompiledContract;
54+
}

0 commit comments

Comments
 (0)