Skip to content

Commit

Permalink
feat: declare v2 from account
Browse files Browse the repository at this point in the history
  • Loading branch information
tabaktoni committed Mar 22, 2023
1 parent b6669b5 commit bc861b7
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 45 deletions.
63 changes: 27 additions & 36 deletions src/account/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
DeployAccountContractTransaction,
DeployContractResponse,
DeployContractUDCResponse,
Details,
EstimateFee,
EstimateFeeAction,
EstimateFeeDetails,
Expand All @@ -31,11 +32,11 @@ import {
UniversalDeployerContractPayload,
} from '../types';
import { EstimateFeeBulk, TransactionSimulation } from '../types/account';
import { extractContractHashes } from '../utils/contract';
import { starkCurve } from '../utils/ec';
import { parseUDCEvent } from '../utils/events';
import {
calculateContractAddressFromHash,
computeContractClassHash,
feeTransactionVersion,
transactionVersion,
} from '../utils/hash';
Expand Down Expand Up @@ -108,20 +109,20 @@ export class Account extends Provider implements AccountInterface {
}

public async estimateDeclareFee(
{ contract, classHash: providedClassHash }: DeclareContractPayload,
{ contract, classHash: providedClassHash, casm, compiledClassHash }: DeclareContractPayload,
{ blockIdentifier, nonce: providedNonce }: EstimateFeeDetails = {}
): Promise<EstimateFee> {
const nonce = toBigInt(providedNonce ?? (await this.getNonce()));
const version = toBigInt(feeTransactionVersion);
const chainId = await this.getChainId();

const payload = await this.buildDeclarePayload(
{ classHash: providedClassHash, contract },
const declareContractTransaction = await this.buildDeclarePayload(
{ classHash: providedClassHash, contract, casm, compiledClassHash },
{ nonce, chainId, version, walletAddress: this.address, maxFee: ZERO }
);

const response = await super.getDeclareEstimateFee(
{ ...payload },
declareContractTransaction,
{ version, nonce },
blockIdentifier
);
Expand Down Expand Up @@ -302,44 +303,31 @@ export class Account extends Provider implements AccountInterface {
}

public async declare(
{ contract, classHash: providedClassHash }: DeclareContractPayload, // TODO: compiledClassHash i casm
payload: DeclareContractPayload,
transactionsDetail: InvocationsDetails = {}
): Promise<DeclareContractResponse> {
const nonce = toBigInt(transactionsDetail.nonce ?? (await this.getNonce()));

const classHash = providedClassHash ?? computeContractClassHash(contract);

if (!classHash) throw new Error('declare classHash is undefined');
const declareContractPayload = extractContractHashes(payload);
const details = {} as Details;

const maxFee =
details.nonce = toBigInt(transactionsDetail.nonce ?? (await this.getNonce()));
details.maxFee =
transactionsDetail.maxFee ??
(await this.getSuggestedMaxFee(
{ type: TransactionType.DECLARE, payload: { classHash, contract } }, // Provide the classHash to avoid re-computing it
{
type: TransactionType.DECLARE,
payload: declareContractPayload,
},
transactionsDetail
));
details.version = toBigInt(transactionVersion);
details.chainId = await this.getChainId();

const version = toBigInt(transactionVersion);
const chainId = await this.getChainId();

const signature = await this.signer.signDeclareTransaction({
classHash,
senderAddress: this.address,
chainId,
maxFee,
version,
nonce,
const declareContractTransaction = await this.buildDeclarePayload(declareContractPayload, {
...details,
walletAddress: this.address,
});

const contractDefinition = parseContract(contract);

return this.declareContract(
{ contractDefinition, senderAddress: this.address, signature },
{
nonce,
maxFee,
version,
}
);
return this.declareContract(declareContractTransaction, details);
}

public async deploy(
Expand Down Expand Up @@ -523,15 +511,18 @@ export class Account extends Provider implements AccountInterface {
return feeEstimate.suggestedMaxFee.toString();
}

/**
* @deprecated will be renamed to buildDeclareContractTransaction
*/
public async buildDeclarePayload(
{ classHash: providedClassHash, contract }: DeclareContractPayload,
payload: DeclareContractPayload,
{ nonce, chainId, version, walletAddress, maxFee }: InvocationsSignerDetails
): Promise<DeclareContractTransaction> {
const { classHash, contract, compiledClassHash } = extractContractHashes(payload);
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,
compiledClassHash,
senderAddress: walletAddress,
chainId,
maxFee,
Expand Down
9 changes: 5 additions & 4 deletions src/provider/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
TransactionType,
waitForTransactionOptions,
} from '../types';
import { isSiera } from '../utils/contract';
import fetch from '../utils/fetchPonyfill';
import { getSelector, getSelectorFromName } from '../utils/hash';
import { parse, parseAlwaysAsBig, stringify } from '../utils/json';
Expand Down Expand Up @@ -388,7 +389,7 @@ export class SequencerProvider implements ProviderInterface {
{ senderAddress, contractDefinition, signature }: DeclareContractTransaction,
details: InvocationsDetailsWithNonce
): Promise<DeclareContractResponse> {
if ('program' in contractDefinition) {
if (!isSiera(contractDefinition)) {
return this.fetchEndpoint('add_transaction', undefined, {
type: TransactionType.DECLARE,
contract_class: contractDefinition,
Expand Down Expand Up @@ -429,7 +430,7 @@ export class SequencerProvider implements ProviderInterface {
): Promise<EstimateFeeResponse> {
return this.fetchEndpoint(
'estimate_fee',
{ blockIdentifier, skip_validate: skipValidate },
{ blockIdentifier, skipValidate },
{
type: TransactionType.INVOKE,
sender_address: invocation.contractAddress,
Expand All @@ -449,7 +450,7 @@ export class SequencerProvider implements ProviderInterface {
): Promise<EstimateFeeResponse> {
return this.fetchEndpoint(
'estimate_fee',
{ blockIdentifier, skip_validate: skipValidate },
{ blockIdentifier, skipValidate },
{
type: TransactionType.DECLARE,
sender_address: senderAddress,
Expand All @@ -469,7 +470,7 @@ export class SequencerProvider implements ProviderInterface {
): Promise<EstimateFeeResponse> {
return this.fetchEndpoint(
'estimate_fee',
{ blockIdentifier, skip_validate: skipValidate },
{ blockIdentifier, skipValidate },
{
type: TransactionType.DEPLOY_ACCOUNT,
class_hash: toHex(classHash),
Expand Down
2 changes: 1 addition & 1 deletion src/types/api/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ export namespace Sequencer {
estimate_fee: {
QUERY: {
blockIdentifier: BlockIdentifier;
skip_validate: boolean;
skipValidate: boolean;
};
REQUEST: EstimateFeeRequest;
RESPONSE: EstimateFeeResponse;
Expand Down
1 change: 1 addition & 0 deletions src/types/lib/contract/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CompiledSiera, SieraContractClass } from './siera';
// Final types
export type ContractClass = LegacyContractClass | SieraContractClass;
export type CompiledContract = LegacyCompiledContract | CompiledSiera;
export type CairoContract = ContractClass | CompiledContract;

// Basic elements
export enum EntryPointType {
Expand Down
22 changes: 21 additions & 1 deletion src/types/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { StarknetChainId } from '../../constants';
import { weierstrass } from '../../utils/ec';
import type { BigNumberish } from '../../utils/num';
import { CompiledContract, ContractClass } from './contract';
import { CompiledContract, CompiledSieraCasm, ContractClass } from './contract';

// Common Signature Type which needs to be imported from weierstrass
// and imported at many places
Expand Down Expand Up @@ -48,6 +49,15 @@ export type DeployAccountContractTransaction = Omit<
export type DeclareContractPayload = {
contract: CompiledContract | string;
classHash?: string;
casm?: CompiledSieraCasm;
compiledClassHash?: string;
};

export type CompleteDeclareContractPayload = {
contract: CompiledContract | string;
classHash: string;
casm?: CompiledSieraCasm;
compiledClassHash?: string;
};

export type DeclareAndDeployContractPayload = Omit<UniversalDeployerContractPayload, 'classHash'> &
Expand All @@ -74,6 +84,16 @@ export type InvocationsDetails = {
version?: BigNumberish;
};

/**
* Contain all additional details params
*/
export type Details = {
nonce: BigNumberish;
maxFee: BigNumberish;
version: BigNumberish;
chainId: StarknetChainId;
};

export type InvocationsDetailsWithNonce = InvocationsDetails & {
nonce: BigNumberish;
compiledClassHash?: string;
Expand Down
5 changes: 2 additions & 3 deletions src/utils/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { poseidonHashMany } from 'micro-starknet';
import { API_VERSION, MASK_250, StarknetChainId, TransactionHashPrefix } from '../constants';
import {
Builtins,
CompiledContract,
CompiledSiera,
CompiledSieraCasm,
ContractEntryPointFields,
Expand Down Expand Up @@ -381,9 +382,7 @@ export function computeSieraContractClassHash(siera: CompiledSiera) {
* @param contract CompiledContract | CompiledSiera | string
* @returns HexString ClassHash
*/
export function computeContractClassHash(
contract: LegacyCompiledContract | CompiledSiera | string
) {
export function computeContractClassHash(contract: CompiledContract | string) {
const compiledContract = typeof contract === 'string' ? parse(contract) : contract;

if ('sierra_program' in compiledContract) {
Expand Down

0 comments on commit bc861b7

Please sign in to comment.