Skip to content

Commit

Permalink
feat: get_compiled_class_by_class_hash, get_class_by_hash, ContractCl…
Browse files Browse the repository at this point in the history
…ass, rpc hotfix
  • Loading branch information
tabaktoni committed Feb 23, 2023
1 parent 96312dc commit fc33d19
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 62 deletions.
4 changes: 2 additions & 2 deletions __tests__/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import fs from 'fs';
import path from 'path';

import { Account, ProviderInterface, RpcProvider, SequencerProvider, json } from '../src';
import { CompiledContract, waitForTransactionOptions } from '../src/types';
import { LegacyCompiledContract, waitForTransactionOptions } from '../src/types';
import { toHex } from '../src/utils/number';

const readContract = (name: string): CompiledContract =>
const readContract = (name: string): LegacyCompiledContract =>
json.parse(
fs.readFileSync(path.resolve(__dirname, `../__mocks__/${name}.json`)).toString('ascii')
);
Expand Down
3 changes: 3 additions & 0 deletions src/account/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ export class Account extends Provider implements AccountInterface {

const classHash = providedClassHash ?? computeContractClassHash(contract);

if (!classHash) throw new Error('declare classHash is undefined');

const maxFee =
transactionsDetail.maxFee ??
(await this.getSuggestedMaxFee(
Expand Down Expand Up @@ -527,6 +529,7 @@ export class Account extends Provider implements AccountInterface {
): Promise<DeclareContractTransaction> {
const contractDefinition = parseContract(contract);
const classHash = providedClassHash ?? computeContractClassHash(contract);
if (!classHash) throw new Error('buildDeclarePayload classHash is undefined');
const signature = await this.signer.signDeclareTransaction({
classHash,
senderAddress: walletAddress,
Expand Down
5 changes: 3 additions & 2 deletions src/provider/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
InvocationBulk,
InvocationsDetailsWithNonce,
InvokeFunctionResponse,
RPC,
StateUpdateResponse,
TransactionSimulationResponse,
waitForTransactionOptions,
Expand Down Expand Up @@ -69,7 +70,7 @@ export class Provider implements ProviderInterface {
public async getClassAt(
contractAddress: string,
blockIdentifier?: BlockIdentifier
): Promise<ContractClass> {
): Promise<ContractClass | RPC.ContractClass> {
return this.provider.getClassAt(contractAddress, blockIdentifier);
}

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

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

Expand Down
5 changes: 3 additions & 2 deletions src/provider/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
InvocationBulk,
InvocationsDetailsWithNonce,
InvokeFunctionResponse,
RPC,
StateUpdateResponse,
TransactionSimulationResponse,
waitForTransactionOptions,
Expand Down Expand Up @@ -71,7 +72,7 @@ export abstract class ProviderInterface {
public abstract getClassAt(
contractAddress: string,
blockIdentifier?: BlockIdentifier
): Promise<ContractClass>;
): Promise<ContractClass | RPC.ContractClass>;

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

/**
* Gets the nonce of a contract with respect to a specific block
Expand Down
66 changes: 37 additions & 29 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,22 +268,26 @@ export class RpcProvider implements ProviderInterface {
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<EstimateFeeResponse> {
const block_id = new Block(blockIdentifier).identifier;
return this.fetchEndpoint('starknet_estimateFee', {
request: {
type: RPC.TransactionType.DECLARE,
contract_class: {
program: contractDefinition.program,
entry_points_by_type: contractDefinition.entry_points_by_type,
abi: contractDefinition.abi, // rpc 2.0
if ('program' in contractDefinition) {
return this.fetchEndpoint('starknet_estimateFee', {
request: {
type: RPC.TransactionType.DECLARE,
contract_class: {
program: contractDefinition.program,
entry_points_by_type: contractDefinition.entry_points_by_type,
abi: contractDefinition.abi, // rpc 2.0
},
sender_address: senderAddress,
signature: signatureToHexArray(signature),
version: toHex(details?.version || 0),
nonce: toHex(details.nonce),
max_fee: toHex(details?.maxFee || 0),
},
sender_address: senderAddress,
signature: signatureToHexArray(signature),
version: toHex(details?.version || 0),
nonce: toHex(details.nonce),
max_fee: toHex(details?.maxFee || 0),
},
block_id,
}).then(this.responseParser.parseFeeEstimateResponse);
block_id,
}).then(this.responseParser.parseFeeEstimateResponse);
}
// TODO: When RPC Update implement Siera
throw new Error('RPC do not support Siera Contracts yet');
}

public async getDeployAccountEstimateFee(
Expand Down Expand Up @@ -319,21 +323,25 @@ export class RpcProvider implements ProviderInterface {
{ contractDefinition, signature, senderAddress }: DeclareContractTransaction,
details: InvocationsDetailsWithNonce
): Promise<DeclareContractResponse> {
return this.fetchEndpoint('starknet_addDeclareTransaction', {
declare_transaction: {
contract_class: {
program: contractDefinition.program,
entry_points_by_type: contractDefinition.entry_points_by_type,
abi: contractDefinition.abi, // rpc 2.0
if ('program' in contractDefinition) {
return this.fetchEndpoint('starknet_addDeclareTransaction', {
declare_transaction: {
contract_class: {
program: contractDefinition.program,
entry_points_by_type: contractDefinition.entry_points_by_type,
abi: contractDefinition.abi, // rpc 2.0
},
type: RPC.TransactionType.DECLARE,
version: toHex(details.version || 0),
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
nonce: toHex(details.nonce),
},
type: RPC.TransactionType.DECLARE,
version: toHex(details.version || 0),
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
nonce: toHex(details.nonce),
},
});
});
}
// TODO: When RPC Update implement Siera
throw new Error('RPC do not support Siera Contracts yet');
}

public async deployAccountContract(
Expand Down
17 changes: 15 additions & 2 deletions src/provider/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import urljoin from 'url-join';

import { BaseUrl, NetworkName, StarknetChainId } from '../constants';
import {
CairoAssembly,
Call,
CallContractResponse,
CallL1Handler,
Expand Down Expand Up @@ -336,8 +337,20 @@ export class SequencerProvider implements ProviderInterface {
return this.fetchEndpoint('get_class_hash_at', { blockIdentifier, contractAddress });
}

public async getClassByHash(classHash: string): Promise<ContractClass> {
return this.fetchEndpoint('get_class_by_hash', { classHash }).then(parseContract);
public async getClassByHash(
classHash: string,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<ContractClass> {
return this.fetchEndpoint('get_class_by_hash', { classHash, blockIdentifier }).then(
parseContract
);
}

public async getCompiledClassByClassHash(
classHash: string,
blockIdentifier: BlockIdentifier = this.blockIdentifier
): Promise<CairoAssembly> {
return this.fetchEndpoint('get_compiled_class_by_class_hash', { classHash, blockIdentifier });
}

public async invokeFunction(
Expand Down
18 changes: 15 additions & 3 deletions src/types/api/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {
Abi,
AllowArray,
BlockNumber,
ByteCode,
CairoAssembly,
CompiledContract,
ContractClass,
EntryPointType,
RawCalldata,
Expand Down Expand Up @@ -144,7 +147,7 @@ export namespace Sequencer {
};

export type GetCodeResponse = {
bytecode: string[];
bytecode: ByteCode;
abi: Abi;
};

Expand Down Expand Up @@ -385,9 +388,10 @@ export namespace Sequencer {
get_class_by_hash: {
QUERY: {
classHash: string;
blockIdentifier?: BlockIdentifier;
};
REQUEST: never;
RESPONSE: any;
RESPONSE: CompiledContract;
};
get_class_hash_at: {
QUERY: {
Expand All @@ -411,7 +415,7 @@ export namespace Sequencer {
blockIdentifier?: BlockIdentifier;
};
REQUEST: never;
RESPONSE: any;
RESPONSE: CompiledContract;
};
estimate_message_fee: {
QUERY: any;
Expand Down Expand Up @@ -440,5 +444,13 @@ export namespace Sequencer {
REQUEST: never;
RESPONSE: BlockTransactionTracesResponse;
};
get_compiled_class_by_class_hash: {
QUERY: {
classHash: string;
blockIdentifier?: BlockIdentifier;
};
REQUEST: any;
RESPONSE: CairoAssembly;
};
};
}
49 changes: 37 additions & 12 deletions src/types/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { weierstrass } from '../utils/ec';
import type { BigNumberish } from '../utils/number';
import { RPC } from './api/rpc';

// Common Signature Type which needs to be imported from weierstrass
// and imported at many places
Expand All @@ -18,11 +17,30 @@ export type RawArgs =
}
| BigNumberish[];

export interface ContractClass {
// Cairo Contract Class
export type ContractClass = LegacyContractClass | SieraContractClass;

// TODO: Clean this mess with types

export type SieraContractClass = {
sierra_program: ByteCode;
sierra_program_debug_info: SieraProgramDebugInfo;
contract_class_version: string;
entry_points_by_type: EntryPointsByType;
abi: Abi;
};

export type SieraProgramDebugInfo = {
type_names: [number, string][];
libfunc_names: [number, string][];
user_func_names: [number, string][];
};

export type LegacyContractClass = {
program: CompressedProgram;
entry_points_by_type: RPC.ContractClass['entry_points_by_type'];
abi?: Abi;
}
entry_points_by_type: EntryPointsByType;
abi: Abi;
};

export type UniversalDeployerContractPayload = {
classHash: BigNumberish;
Expand Down Expand Up @@ -170,18 +188,15 @@ export type EntryPointsByType = {
export interface Program extends Record<string, any> {
builtins: string[];
data: string[];
// TODO: Add missing properties
}
export type BlockTag = 'pending' | 'latest';
export type BlockNumber = BlockTag | null | number;

export type CompiledContract = {
abi: Abi;
entry_points_by_type: EntryPointsByType;
program: Program;
};
export type CompiledContract = LegacyCompiledContract | SieraContractClass;

export type CompressedCompiledContract = Omit<CompiledContract, 'program'> & {
program: CompressedProgram;
export type LegacyCompiledContract = Omit<LegacyContractClass, 'program'> & {
program: Program;
};

export type Struct = {
Expand All @@ -199,3 +214,13 @@ export type waitForTransactionOptions = {
retryInterval?: number;
successStates?: Array<TransactionStatus>;
};

export type CairoAssembly = {
prime: string;
compiler_version: string;
bytecode: ByteCode;
hints: any[];
entry_points_by_type: EntryPointsByType;
};

export type ByteCode = string[];
3 changes: 2 additions & 1 deletion src/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from './api/sequencer';
import {
AllowArray,
ByteCode,
Call,
DeclareContractPayload,
DeployAccountContractPayload,
Expand All @@ -36,7 +37,7 @@ export interface GetBlockResponse {
}

export interface GetCodeResponse {
bytecode: string[];
bytecode: ByteCode;
// abi: string; // is not consistent between rpc and sequencer (is it?), therefore not included in the provider interface
}

Expand Down
Loading

0 comments on commit fc33d19

Please sign in to comment.