Skip to content

Commit

Permalink
feat: return from wait Transaction,Account deployContract and declare…
Browse files Browse the repository at this point in the history
…Deploy
  • Loading branch information
tabaktoni committed Nov 22, 2022
1 parent 0e00459 commit 724975d
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 33 deletions.
57 changes: 50 additions & 7 deletions __tests__/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
compiledErc20,
compiledTestDapp,
erc20ClassHash,
getERC20DeployPayload,
getTestAccount,
getTestProvider,
} from './fixtures';
Expand All @@ -25,15 +24,38 @@ describe('deploy and test Wallet', () => {
beforeAll(async () => {
expect(account).toBeInstanceOf(Account);

const erc20DeployPayload = getERC20DeployPayload(account.address);

const erc20Response = await provider.deployContract(erc20DeployPayload);
/* // Declare
const declareTx = await account.declare({
contract: compiledErc20,
classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a',
});
expect(declareTx.transaction_hash).toBeDefined();
await provider.waitForTransaction(declareTx.transaction_hash);
// Deploy Contract
const erc20Response = await account.deployContract2({
classHash: declareTx.class_hash,
constructorCalldata: [
encodeShortString('Token'),
encodeShortString('ERC20'),
account.address,
],
});
expect(erc20Response.contract_address).toBeDefined(); */

const declareDeploy = await account.declareDeploy({
contract: compiledErc20,
classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a',
constructorCalldata: [
encodeShortString('Token'),
encodeShortString('ERC20'),
account.address,
],
});

erc20Address = erc20Response.contract_address;
erc20Address = declareDeploy.deploy.contract_address;
erc20 = new Contract(compiledErc20.abi, erc20Address, provider);

await provider.waitForTransaction(erc20Response.transaction_hash);

const x = await erc20.balanceOf(account.address);

expect(number.toBN(x[0].low).toString()).toStrictEqual(number.toBN(1000).toString());
Expand Down Expand Up @@ -176,6 +198,27 @@ describe('deploy and test Wallet', () => {
expect(declareTx.class_hash).toEqual(erc20ClassHash);
});

test('UDC DeployContract', async () => {
const deployResponse = await account.deployContract2({
classHash: erc20ClassHash,
constructorCalldata: [
encodeShortString('Token'),
encodeShortString('ERC20'),
account.address,
],
});

expect(deployResponse.contract_address).toBeDefined();
expect(deployResponse.transaction_hash).toBeDefined();
expect(deployResponse.address).toBeDefined();
expect(deployResponse.deployer).toBeDefined();
expect(deployResponse.unique).toBeDefined();
expect(deployResponse.classHash).toBeDefined();
expect(deployResponse.calldata_len).toBeDefined();
expect(deployResponse.calldata).toBeDefined();
expect(deployResponse.salt).toBeDefined();
});

test('UDC Deploy', async () => {
const salt = randomAddress(); // use random salt

Expand Down
10 changes: 1 addition & 9 deletions __tests__/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import fs from 'fs';

import { Account, ProviderInterface, RpcProvider, SequencerProvider, ec, json } from '../src';
import { CompiledContract, DeployContractPayload } from '../src/types';
import { encodeShortString } from '../src/utils/shortString';
import { CompiledContract } from '../src/types';

const readContract = (name: string): CompiledContract =>
json.parse(fs.readFileSync(`./__mocks__/${name}.json`).toString('ascii'));
Expand Down Expand Up @@ -74,10 +73,3 @@ export const describeIfRpc = describeIf(IS_RPC);
export const describeIfNotDevnet = describeIf(!IS_DEVNET);

export const erc20ClassHash = '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a';

export const getERC20DeployPayload = (recipient: string): DeployContractPayload => {
return {
contract: compiledErc20,
constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), recipient],
};
};
75 changes: 70 additions & 5 deletions src/account/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ import {
DeployAccountContractPayload,
UniversalDeployerContractPayload,
} from '../types/lib';
import { AccountDeployContractResponse, InvokeTransactionReceiptResponse } from '../types/provider';
import {
calculateContractAddressFromHash,
feeTransactionVersion,
transactionVersion,
} from '../utils/hash';
import { BigNumberish, toBN, toCairoBool } from '../utils/number';
import { parseContract } from '../utils/provider';
import { compileCalldata, estimatedFeeToMaxFee } from '../utils/stark';
import { compileCalldata, estimatedFeeToMaxFee, randomAddress } from '../utils/stark';
import { fromCallsToExecuteCalldata } from '../utils/transaction';
import { TypedData, getMessageHash } from '../utils/typedData';
import { AccountInterface } from './interface';
Expand Down Expand Up @@ -169,7 +170,7 @@ export class Account extends Provider implements AccountInterface {
public async estimateDeployFee(
{
classHash,
salt,
salt = '',
unique = true,
constructorCalldata = [],
additionalCalls = [],
Expand Down Expand Up @@ -272,16 +273,16 @@ export class Account extends Provider implements AccountInterface {
public async deploy(
{
classHash,
salt,
salt = '',
unique = true,
constructorCalldata = [],
additionalCalls = [],
}: UniversalDeployerContractPayload,
transactionsDetail: InvocationsDetails = {}
): Promise<InvokeFunctionResponse> {
const compiledConstructorCallData = compileCalldata(constructorCalldata);

const callsArray = Array.isArray(additionalCalls) ? additionalCalls : [additionalCalls];
const randomSalt = salt ?? randomAddress();

return this.execute(
[
Expand All @@ -290,7 +291,7 @@ export class Account extends Provider implements AccountInterface {
entrypoint: UDC.ENTRYPOINT,
calldata: [
classHash,
salt,
randomSalt,
toCairoBool(unique),
compiledConstructorCallData.length,
...compiledConstructorCallData,
Expand All @@ -303,6 +304,70 @@ export class Account extends Provider implements AccountInterface {
);
}

/**
* Simplify deploy simulating old DeployContract with same response + UDC specific response
*
* @param payload UniversalDeployerContractPayload
* @param detials InvocationsDetails
* @returns Promise<AccountDeployContractResponse | Error>
*/
public async deployContract2(
{
classHash,
salt,
unique = true,
constructorCalldata = [],
additionalCalls = [],
}: UniversalDeployerContractPayload,
transactionsDetail: InvocationsDetails = {}
): Promise<AccountDeployContractResponse | Error> {
const deployTx = await this.deploy(
{
classHash,
salt,
unique,
constructorCalldata,
additionalCalls,
},
transactionsDetail
);
const txReceipt = await this.waitForTransaction(deployTx.transaction_hash);

return this.getUDCResponse(txReceipt);
}

/**
* Parse Transaction Receipt Event from UDC invoke transaction and
* create DeployContractResponse compatibile response with adition of UDC Event data
*
* @param txReceipt
* @returns DeployContractResponse | UDC Event Response data
*/
public getUDCResponse(txReceipt: InvokeTransactionReceiptResponse | void) {
if (txReceipt && txReceipt.events) {
const event = txReceipt.events.find((it) => it.from_address === UDC.ADDRESS) || { data: [] };
return {
transaction_hash: txReceipt.transaction_hash,
contract_address: event.data[0],
address: event.data[0],
deployer: event.data[1],
unique: event.data[2],
classHash: event.data[3],
calldata_len: event.data[4],
calldata: event.data.slice(5, 5 + parseInt(event.data[4], 16)),
salt: event.data[event.data.length - 1],
};
}
return new Error("UDC didn't emmit event");
}

public async declareDeploy({ classHash, contract, constructorCalldata }: any) {
const { transaction_hash } = await this.declare({ contract, classHash });
const declare = await this.waitForTransaction(transaction_hash);
const deploy = await this.deployContract2({ classHash, constructorCalldata });
return { declare: { ...declare, class_hash: classHash }, deploy };
}

public async deployAccount(
{
classHash,
Expand Down
21 changes: 14 additions & 7 deletions src/provider/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,20 @@ export class Provider implements ProviderInterface {
private provider!: ProviderInterface;

constructor(providerOrOptions?: ProviderOptions | ProviderInterface) {
if (providerOrOptions && 'chainId' in providerOrOptions) {
this.provider = providerOrOptions;
} else if (providerOrOptions?.rpc) {
this.provider = new RpcProvider(providerOrOptions.rpc);
} else if (providerOrOptions?.sequencer) {
this.provider = new SequencerProvider(providerOrOptions.sequencer);
if (
providerOrOptions instanceof RpcProvider ||
providerOrOptions instanceof SequencerProvider
) {
// providerOrOptions is provider
this.provider = <ProviderInterface>providerOrOptions;
} else if (providerOrOptions && 'rpc' in providerOrOptions) {
// providerOrOptions is rpc option
this.provider = new RpcProvider(<RpcProviderOptions>providerOrOptions.rpc);
} else if (providerOrOptions && 'sequencer' in providerOrOptions) {
// providerOrOptions is sequencer option
this.provider = new SequencerProvider(<SequencerProviderOptions>providerOrOptions.sequencer);
} else {
// providerOrOptions is none, create SequencerProvider as default
this.provider = new SequencerProvider();
}
}
Expand Down Expand Up @@ -180,7 +187,7 @@ export class Provider implements ProviderInterface {
return this.provider.getCode(contractAddress, blockIdentifier);
}

public async waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<void> {
public async waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<any> {
return this.provider.waitForTransaction(txHash, retryInterval);
}
}
2 changes: 1 addition & 1 deletion src/provider/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,5 @@ export abstract class ProviderInterface {
* @param txHash - transaction hash
* @param retryInterval - retry interval
*/
public abstract waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<void>;
public abstract waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<any>;
}
4 changes: 3 additions & 1 deletion src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ export class RpcProvider implements ProviderInterface {
public async waitForTransaction(txHash: string, retryInterval: number = 8000) {
let { retries } = this;
let onchain = false;
let res;

while (!onchain) {
const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING'];
Expand All @@ -416,7 +417,7 @@ export class RpcProvider implements ProviderInterface {
await wait(retryInterval);
try {
// eslint-disable-next-line no-await-in-loop
const res = await this.getTransactionReceipt(txHash);
res = await this.getTransactionReceipt(txHash);

if (!('status' in res)) {
const error = new Error('pending transaction');
Expand Down Expand Up @@ -445,6 +446,7 @@ export class RpcProvider implements ProviderInterface {
}

await wait(retryInterval);
return res;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/provider/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,13 @@ export class SequencerProvider implements ProviderInterface {

public async waitForTransaction(txHash: BigNumberish, retryInterval: number = 8000) {
let onchain = false;
let res;

while (!onchain) {
// eslint-disable-next-line no-await-in-loop
await wait(retryInterval);
// eslint-disable-next-line no-await-in-loop
const res = await this.getTransactionStatus(txHash);
res = await this.getTransactionStatus(txHash);

const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING'];
const errorStates = ['REJECTED', 'NOT_RECEIVED'];
Expand All @@ -471,6 +472,7 @@ export class SequencerProvider implements ProviderInterface {
throw error;
}
}
return res;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/types/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export interface ContractClass {

export type UniversalDeployerContractPayload = {
classHash: BigNumberish;
salt: string;
unique: boolean;
salt?: string;
unique?: boolean;
constructorCalldata?: RawArgs;
additionalCalls?: AllowArray<Call>; // support multicall
};
Expand Down
10 changes: 10 additions & 0 deletions src/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ export interface DeployContractResponse {
transaction_hash: string;
}

export interface AccountDeployContractResponse extends DeployContractResponse {
address: string;
deployer: string;
unique: string;
classHash: string;
calldata_len: string;
calldata: Array<string>;
salt: string;
}

export interface DeclareContractResponse {
transaction_hash: string;
class_hash: string;
Expand Down

0 comments on commit 724975d

Please sign in to comment.