Skip to content

Commit

Permalink
Merge pull request #637 from notV4l/634-contract-class-types
Browse files Browse the repository at this point in the history
ContractClass types responses
  • Loading branch information
tabaktoni authored Jun 14, 2023
2 parents 724686f + 1ec347a commit 32188fb
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 53 deletions.
23 changes: 14 additions & 9 deletions __tests__/cairo1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ import {
compiledComplexSierra,
compiledHelloSierra,
compiledHelloSierraCasm,
describeIfDevnet,
describeIfDevnetSequencer,
describeIfSequencerTestnet2,
getTestAccount,
getTestProvider,
} from './fixtures';
import { initializeMatcher } from './schema';

describeIfDevnetSequencer('Cairo 1 Devnet Sequencer', () => {
describe('Sequencer API & Contract interactions', () => {
const provider = getTestProvider() as SequencerProvider;
describeIfDevnet('Cairo 1 Devnet', () => {
describe('API & Contract interactions', () => {
const provider = getTestProvider();
const account = getTestAccount(provider);
let dd: DeclareDeployUDCResponse;
let cairo1Contract: Contract;
Expand Down Expand Up @@ -59,11 +60,6 @@ describeIfDevnetSequencer('Cairo 1 Devnet Sequencer', () => {
expect(deploy).toHaveProperty('address');
});

test('getCompiledClassByClassHash', async () => {
const compiledClass = await provider.getCompiledClassByClassHash(dd.deploy.classHash);
expect(compiledClass).toMatchSchemaRef('CompiledClass');
});

test('GetClassByHash', async () => {
const classResponse = await provider.getClassByHash(dd.deploy.classHash);
expect(classResponse).toMatchSchemaRef('SierraContractClass');
Expand Down Expand Up @@ -410,10 +406,19 @@ describeIfDevnetSequencer('Cairo 1 Devnet Sequencer', () => {
expect(callDataFromObject).toStrictEqual(expectedResult);
expect(callDataFromArray).toStrictEqual(expectedResult);
});

describeIfDevnetSequencer('Sequencer only', () => {
test('getCompiledClassByClassHash', async () => {
const compiledClass = await (provider as SequencerProvider).getCompiledClassByClassHash(
dd.deploy.classHash
);
expect(compiledClass).toMatchSchemaRef('CompiledClass');
});
});
});

describe('Cairo1 Account contract', () => {
const provider = getTestProvider() as SequencerProvider;
const provider = getTestProvider();
const account = getTestAccount(provider);
let accountC1: Account;

Expand Down
7 changes: 3 additions & 4 deletions src/provider/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
BlockIdentifier,
Call,
CallContractResponse,
ContractClass,
ContractClassResponse,
DeclareContractResponse,
DeclareContractTransaction,
DeployAccountContractTransaction,
Expand All @@ -21,7 +21,6 @@ import {
InvokeFunctionResponse,
Nonce,
ProviderOptions,
RPC,
RpcProviderOptions,
SequencerProviderOptions,
SimulateTransactionResponse,
Expand Down Expand Up @@ -72,7 +71,7 @@ export class Provider implements ProviderInterface {
public async getClassAt(
contractAddress: string,
blockIdentifier?: BlockIdentifier
): Promise<ContractClass | RPC.ContractClass> {
): Promise<ContractClassResponse> {
return this.provider.getClassAt(contractAddress, blockIdentifier);
}

Expand All @@ -83,7 +82,7 @@ export class Provider implements ProviderInterface {
return this.provider.getClassHashAt(contractAddress, blockIdentifier);
}

public getClassByHash(classHash: string): Promise<ContractClass | RPC.ContractClass> {
public getClassByHash(classHash: string): Promise<ContractClassResponse> {
return this.provider.getClassByHash(classHash);
}

Expand Down
7 changes: 3 additions & 4 deletions src/provider/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {
BlockIdentifier,
Call,
CallContractResponse,
ContractClass,
ContractClassResponse,
DeclareContractResponse,
DeclareContractTransaction,
DeployAccountContractPayload,
Expand All @@ -21,7 +21,6 @@ import type {
InvocationsDetailsWithNonce,
InvokeFunctionResponse,
Nonce,
RPC,
SimulateTransactionResponse,
StateUpdateResponse,
Storage,
Expand Down Expand Up @@ -76,7 +75,7 @@ export abstract class ProviderInterface {
public abstract getClassAt(
contractAddress: string,
blockIdentifier?: BlockIdentifier
): Promise<ContractClass | RPC.ContractClass>;
): Promise<ContractClassResponse>;

/**
* Returns the class hash deployed under the given address.
Expand All @@ -96,7 +95,7 @@ export abstract class ProviderInterface {
* @param classHash - class hash
* @returns Contract class of compiled contract
*/
public abstract getClassByHash(classHash: string): Promise<ContractClass | RPC.ContractClass>;
public abstract getClassByHash(classHash: string): Promise<ContractClassResponse>;

/**
* Gets the nonce of a contract with respect to a specific block
Expand Down
14 changes: 9 additions & 5 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
BlockIdentifier,
Call,
CallContractResponse,
ContractClassResponse,
DeclareContractResponse,
DeclareContractTransaction,
DeployAccountContractTransaction,
Expand Down Expand Up @@ -215,27 +216,30 @@ export class RpcProvider implements ProviderInterface {
return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash });
}

public async getClassByHash(classHash: RPC.Felt): Promise<RPC.ContractClass> {
public async getClassByHash(classHash: RPC.Felt): Promise<ContractClassResponse> {
return this.getClass(classHash);
}

public async getClass(
classHash: RPC.Felt,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<RPC.ContractClass> {
): Promise<ContractClassResponse> {
const block_id = new Block(blockIdentifier).identifier;
return this.fetchEndpoint('starknet_getClass', { class_hash: classHash, block_id });
return this.fetchEndpoint('starknet_getClass', {
class_hash: classHash,
block_id,
}).then(this.responseParser.parseContractClassResponse);
}

public async getClassAt(
contractAddress: string,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<RPC.ContractClass> {
): Promise<ContractClassResponse> {
const block_id = new Block(blockIdentifier).identifier;
return this.fetchEndpoint('starknet_getClassAt', {
block_id,
contract_address: contractAddress,
});
}).then(this.responseParser.parseContractClassResponse);
}

public async getCode(
Expand Down
24 changes: 8 additions & 16 deletions src/provider/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Call,
CallContractResponse,
CallL1Handler,
ContractClass,
ContractClassResponse,
DeclareContractResponse,
DeclareContractTransaction,
DeployAccountContractTransaction,
Expand Down Expand Up @@ -48,7 +48,7 @@ import {
} from '../utils/hash';
import { parse, parseAlwaysAsBig, stringify } from '../utils/json';
import { getDecimalString, getHexString, getHexStringArray, toBigInt, toHex } from '../utils/num';
import { parseContract, wait } from '../utils/provider';
import { wait } from '../utils/provider';
import { SequencerAPIResponseParser } from '../utils/responseParser/sequencer';
import { randomAddress, signatureToDecimalArray } from '../utils/stark';
import { buildUrl } from '../utils/url';
Expand Down Expand Up @@ -314,14 +314,9 @@ export class SequencerProvider implements ProviderInterface {
public async getClassAt(
contractAddress: string,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<ContractClass> {
): Promise<ContractClassResponse> {
return this.fetchEndpoint('get_full_contract', { blockIdentifier, contractAddress }).then(
(res) => {
if (isSierra(res)) {
return this.responseParser.parseSierraContractClassResponse(res);
}
return parseContract(res);
}
this.responseParser.parseContractClassResponse
);
}

Expand All @@ -335,13 +330,10 @@ export class SequencerProvider implements ProviderInterface {
public async getClassByHash(
classHash: string,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<ContractClass> {
return this.fetchEndpoint('get_class_by_hash', { classHash, blockIdentifier }).then((res) => {
if (isSierra(res)) {
return this.responseParser.parseSierraContractClassResponse(res);
}
return parseContract(res);
});
): Promise<ContractClassResponse> {
return this.fetchEndpoint('get_class_by_hash', { classHash, blockIdentifier }).then(
this.responseParser.parseContractClassResponse
);
}

public async getCompiledClassByClassHash(
Expand Down
1 change: 0 additions & 1 deletion src/types/api/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export namespace RPC {
export type Traces = OPENRPC.Traces;
export type BlockHash = OPENRPC.BlockHash;
export type BlockHashAndNumber = OPENRPC.BlockHashAndNumber;
export type GetClassResponse = OPENRPC.ContractClass;
export type EstimateFeeResponse = OPENRPC.EstimatedFee;
export type GetBlockWithTxHashesResponse = OPENRPC.BlockWithTxHashes;
export type GetBlockWithTxs = OPENRPC.BlockWithTxs;
Expand Down
5 changes: 1 addition & 4 deletions src/types/lib/contract/sierra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ export type CompiledSierra = {
* format produced after compressing 'sierra_program', stringifies 'abi' property and omit sierra_program_debug_info
* CompressedCompiledSierra
*/
export type SierraContractClass = Omit<
CompiledSierra,
'sierra_program' | 'abi' | 'sierra_program_debug_info'
> & {
export type SierraContractClass = Omit<CompiledSierra, 'abi' | 'sierra_program_debug_info'> & {
sierra_program: string;
abi: string;
};
Expand Down
4 changes: 4 additions & 0 deletions src/types/provider/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import { RPC } from '../api/rpc';
import { Sequencer } from '../api/sequencer';
import {
Abi,
AllowArray,
ByteCode,
Call,
ContractClass,
DeclareContractPayload,
DeployAccountContractPayload,
RawCalldata,
Expand Down Expand Up @@ -169,3 +171,5 @@ export interface StateUpdateResponse {
deprecated_declared_classes?: RPC.DeprecatedDeclaredClasses; // RPC Only
};
}

export type ContractClassResponse = Omit<ContractClass, 'abi'> & { abi?: Abi };
11 changes: 6 additions & 5 deletions src/utils/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,23 @@ function nullSkipReplacer(key: string, value: any) {
return value === null ? undefined : value;
}

// about 10x to 100x faster using array to build string
export function formatSpaces(json: string) {
let insideQuotes = false;
let newString = '';
const newString = [];
// eslint-disable-next-line no-restricted-syntax
for (const char of json) {
if (char === '"' && newString.endsWith('\\') === false) {
if (char === '"' && (newString.length > 0 && newString.slice(-1)[0] === '\\') === false) {
insideQuotes = !insideQuotes;
}
if (insideQuotes) {
newString += char;
newString.push(char);
} else {
// eslint-disable-next-line no-nested-ternary
newString += char === ':' ? ': ' : char === ',' ? ', ' : char;
newString.push(char === ':' ? ': ' : char === ',' ? ', ' : char);
}
}
return newString;
return newString.join('');
}

export default function computeHintedClassHash(compiledContract: LegacyCompiledContract) {
Expand Down
8 changes: 8 additions & 0 deletions src/utils/responseParser/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import {
CallContractResponse,
ContractClassResponse,
EstimateFeeResponse,
EstimateFeeResponseBulk,
GetBlockResponse,
Expand Down Expand Up @@ -92,4 +93,11 @@ export class RPCResponseParser
};
});
}

public parseContractClassResponse(res: RPC.ContractClass): ContractClassResponse {
return {
...res,
abi: typeof res.abi === 'string' ? JSON.parse(res.abi) : res.abi,
};
}
}
14 changes: 9 additions & 5 deletions src/utils/responseParser/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
* Map Sequencer Response to common interface response
* Intersection (sequencer response ∩ (∪ rpc responses))
*/

import {
CallContractResponse,
CompiledContract,
ContractClassResponse,
DeclareContractResponse,
DeployContractResponse,
EstimateFeeResponse,
Expand All @@ -14,11 +17,12 @@ import {
HexCalldata,
InvokeFunctionResponse,
Sequencer,
SierraContractClass,
SimulateTransactionResponse,
StateUpdateResponse,
} from '../../types';
import { isSierra } from '../contract';
import { toBigInt } from '../num';
import { parseContract } from '../provider';
import { estimatedFeeToMaxFee } from '../stark';
import { ResponseParser } from '.';

Expand Down Expand Up @@ -199,11 +203,11 @@ export class SequencerAPIResponseParser extends ResponseParser {
};
}

// TODO: Define response as new type as it diff from ContractClass
public parseSierraContractClassResponse(res: any): SierraContractClass {
public parseContractClassResponse(res: CompiledContract): ContractClassResponse {
const response = isSierra(res) ? res : parseContract(res);
return {
...res,
abi: JSON.parse(res.abi),
...response,
abi: typeof response.abi === 'string' ? JSON.parse(response.abi) : response.abi,
};
}
}

0 comments on commit 32188fb

Please sign in to comment.