Skip to content

Commit

Permalink
feat: rpc 0.4.0-rc3, no cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tabaktoni committed Jul 31, 2023
1 parent f4e414f commit 54674cb
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 166 deletions.
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export { IS_BROWSER } from './utils/encode';

export const HEX_STR_TRANSACTION_VERSION_1 = '0x1';
export const HEX_STR_TRANSACTION_VERSION_2 = '0x2';

export const ZERO = 0n;
export const MASK_250 = 2n ** 250n - 1n; // 2 ** 250 - 1
export const MASK_251 = 2n ** 251n;
Expand Down
91 changes: 50 additions & 41 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { StarknetChainId } from '../constants';
import {
HEX_STR_TRANSACTION_VERSION_1,
HEX_STR_TRANSACTION_VERSION_2,
StarknetChainId,
} from '../constants';
import {
AccountInvocationItem,
AccountInvocations,
Expand All @@ -19,27 +23,23 @@ import {
Invocation,
InvocationsDetailsWithNonce,
InvokeFunctionResponse,
LegacyContractClass,
RPC,
RpcProviderOptions,
SIMULATION_FLAG,
SierraContractClass,
SimulateTransactionResponse,
TransactionStatus,
TransactionType,
getEstimateFeeBulkOptions,
getSimulateTransactionOptions,
waitForTransactionOptions,
} from '../types';
import {
SimulationFlag,
TransactionExecutionStatus,
TransactionFinalityStatus,
} from '../types/api/rpc';
import { CallData } from '../utils/calldata';
import { isSierra } from '../utils/contract';
import fetch from '../utils/fetchPonyfill';
import {
getSelectorFromName,
getVersionsByType,
transactionVersion,
transactionVersion_2,
} from '../utils/hash';
import { getSelectorFromName, getVersionsByType } from '../utils/hash';
import { stringify } from '../utils/json';
import { toHex, toStorageKey } from '../utils/num';
import { wait } from '../utils/provider';
Expand Down Expand Up @@ -345,7 +345,7 @@ export class RpcProvider implements ProviderInterface {
entry_points_by_type: contract.entry_points_by_type,
abi: contract.abi,
},
version: toHex(transactionVersion),
version: HEX_STR_TRANSACTION_VERSION_1,
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
Expand All @@ -363,7 +363,7 @@ export class RpcProvider implements ProviderInterface {
abi: contract.abi,
},
compiled_class_hash: compiledClassHash || '',
version: toHex(transactionVersion_2),
version: HEX_STR_TRANSACTION_VERSION_2,
max_fee: toHex(details.maxFee || 0),
signature: signatureToHexArray(signature),
sender_address: senderAddress,
Expand Down Expand Up @@ -436,15 +436,15 @@ export class RpcProvider implements ProviderInterface {
public async waitForTransaction(txHash: string, options?: waitForTransactionOptions) {
let { retries } = this;
let onchain = false;
let isErrorState = false;
// eslint-disable-next-line no-undef-init
let txReceipt: any = {};
const retryInterval = options?.retryInterval ?? 5000;
const errorStates: any = options?.errorStates ?? [
TransactionStatus.REJECTED,
TransactionStatus.NOT_RECEIVED,
];
const errorStates: any = options?.errorStates ?? [TransactionExecutionStatus.REVERTED];
const successStates: any = options?.successStates ?? [
TransactionStatus.ACCEPTED_ON_L1,
TransactionStatus.ACCEPTED_ON_L2,
TransactionExecutionStatus.SUCCEEDED,
TransactionFinalityStatus.ACCEPTED_ON_L1,
TransactionFinalityStatus.ACCEPTED_ON_L2,
];

while (!onchain) {
Expand All @@ -453,21 +453,31 @@ export class RpcProvider implements ProviderInterface {
try {
// eslint-disable-next-line no-await-in-loop
txReceipt = await this.getTransactionReceipt(txHash);
if (!('status' in txReceipt)) {

if (!txReceipt.execution_status || !txReceipt.finality_status) {
// Transaction is potentially REJECTED or NOT_RECEIVED but RPC doesn't have dose statuses
// so we will retry '{ retries }' times
const error = new Error('waiting for transaction status');
throw error;
}

if (txReceipt.status && successStates.includes(txReceipt.status)) {
if (
successStates.includes(txReceipt.execution_status) ||
successStates.includes(txReceipt.finality_status)
) {
onchain = true;
} else if (txReceipt.status && errorStates.includes(txReceipt.status)) {
const message = txReceipt.status;
const error = new Error(message) as Error & { response: any };
} else if (
errorStates.includes(txReceipt.execution_status) ||
errorStates.includes(txReceipt.finality_status)
) {
const message = `${txReceipt.execution_status}: ${txReceipt.finality_status}: ${txReceipt.revert_reason}`;
const error = new Error(message) as Error & { response: RPC.TransactionReceipt };
error.response = txReceipt;
isErrorState = true;
throw error;
}
} catch (error: unknown) {
if (error instanceof Error && errorStates.includes(error.message as TransactionStatus)) {
} catch (error) {
if (error instanceof Error && isErrorState) {
throw error;
}

Expand Down Expand Up @@ -532,18 +542,19 @@ export class RpcProvider implements ProviderInterface {
{
blockIdentifier = this.blockIdentifier,
skipValidate = false,
skipExecute = false,
skipExecute = false, // @deprecated
skipFeeCharge = false,
}: getSimulateTransactionOptions
): Promise<SimulateTransactionResponse> {
const block_id = new Block(blockIdentifier).identifier;

const simulationFlags = [];
if (skipValidate) simulationFlags.push(SIMULATION_FLAG.SKIP_VALIDATE);
if (skipExecute) simulationFlags.push(SIMULATION_FLAG.SKIP_EXECUTE);
if (skipValidate) simulationFlags.push(SimulationFlag.SKIP_VALIDATE);
if (skipExecute || skipFeeCharge) simulationFlags.push(SimulationFlag.SKIP_FEE_CHARGE);

return this.fetchEndpoint('starknet_simulateTransaction', {
return this.fetchEndpoint('starknet_simulateTransactions', {
block_id,
transactions: invocations.map((it) => this.buildTransaction(it)), // TODO: Pathfinder 0.5.6 bug, should be transaction
transactions: invocations.map((it) => this.buildTransaction(it)),
simulation_flags: simulationFlags,
}).then(this.responseParser.parseSimulateTransactionResponse);
}
Expand All @@ -559,7 +570,7 @@ export class RpcProvider implements ProviderInterface {
public buildTransaction(
invocation: AccountInvocationItem,
versionType?: 'fee' | 'transaction'
): RPC.BroadcastedTransaction {
): RPC.BaseTransaction {
const defaultVersions = getVersionsByType(versionType);
const details = {
signature: signatureToHexArray(invocation.signature),
Expand All @@ -572,32 +583,30 @@ export class RpcProvider implements ProviderInterface {
type: RPC.TransactionType.INVOKE, // Diff between sequencer and rpc invoke type
sender_address: invocation.contractAddress,
calldata: CallData.toHex(invocation.calldata),
version: toHex(invocation.version || defaultVersions.v1),
version: HEX_STR_TRANSACTION_VERSION_1,
...details,
};
}
if (invocation.type === RPC.TransactionType.DECLARE) {
if (invocation.type === TransactionType.DECLARE) {
if (!isSierra(invocation.contract)) {
const legacyContract = invocation.contract as LegacyContractClass;
return {
type: invocation.type,
contract_class: legacyContract,
contract_class: invocation.contract,
sender_address: invocation.senderAddress,
version: toHex(invocation.version || defaultVersions.v1),
version: HEX_STR_TRANSACTION_VERSION_1,
...details,
};
}
const sierraContract = invocation.contract as SierraContractClass;
return {
// compiled_class_hash
type: invocation.type,
contract_class: {
...sierraContract,
sierra_program: decompressProgram(sierraContract.sierra_program),
...invocation.contract,
sierra_program: decompressProgram(invocation.contract.sierra_program),
},
compiled_class_hash: invocation.compiledClassHash || '',
sender_address: invocation.senderAddress,
version: toHex(invocation.version || defaultVersions.v2),
version: HEX_STR_TRANSACTION_VERSION_2,
...details,
};
}
Expand Down
Loading

0 comments on commit 54674cb

Please sign in to comment.