Skip to content

Commit

Permalink
feat: enable v3 in executeTxn legacy (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
khanti42 authored Sep 4, 2024
1 parent 83cd403 commit 6f2b099
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 56 deletions.
73 changes: 38 additions & 35 deletions packages/starknet-snap/src/executeTxn.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { Component } from '@metamask/snaps-sdk';
import { heading, panel, divider, DialogType } from '@metamask/snaps-sdk';
import type { Invocations } from 'starknet';
import type { constants, Invocations } from 'starknet';
import { TransactionType } from 'starknet';

import { createAccount } from './createAccount';
import type {
ApiParamsWithKeyDeriver,
ExecuteTxnRequestParams,
Expand All @@ -23,6 +22,7 @@ import {
estimateFeeBulk,
getAccContractAddressAndCallData,
addFeesFromAllTransactions,
createAccount,
} from './utils/starknetUtils';

/**
Expand All @@ -33,15 +33,16 @@ export async function executeTxn(params: ApiParamsWithKeyDeriver) {
try {
const { state, keyDeriver, requestParams, wallet } = params;
const requestParamsObj = requestParams as ExecuteTxnRequestParams;
const { senderAddress } = requestParamsObj;
const { senderAddress: address, invocationsDetails } = requestParamsObj;
const network = getNetworkFromChainId(state, requestParamsObj.chainId);
const {
privateKey: senderPrivateKey,
publicKey,
addressIndex,
} = await getKeysFromAddress(keyDeriver, network, state, senderAddress);
const { privateKey, publicKey, addressIndex } = await getKeysFromAddress(
keyDeriver,
network,
state,
address,
);

await verifyIfAccountNeedUpgradeOrDeploy(network, senderAddress, publicKey);
await verifyIfAccountNeedUpgradeOrDeploy(network, address, publicKey);

const txnInvocationArray = Array.isArray(requestParamsObj.txnInvocation)
? requestParamsObj.txnInvocation
Expand All @@ -50,12 +51,16 @@ export async function executeTxn(params: ApiParamsWithKeyDeriver) {
type: TransactionType.INVOKE,
payload: ele,
}));
const accountDeployed = await isAccountDeployed(network, senderAddress);

const accountDeployed = await isAccountDeployed(network, address);
const version =
invocationsDetails?.version as unknown as constants.TRANSACTION_VERSION;

if (!accountDeployed) {
const { callData } = getAccContractAddressAndCallData(publicKey);
const deployAccountpayload = {
classHash: ACCOUNT_CLASS_HASH,
contractAddress: senderAddress,
contractAddress: address,
constructorCalldata: callData,
addressSalt: publicKey,
};
Expand All @@ -68,12 +73,10 @@ export async function executeTxn(params: ApiParamsWithKeyDeriver) {

const fees = await estimateFeeBulk(
network,
senderAddress,
senderPrivateKey,
address,
privateKey,
bulkTransactions,
requestParamsObj.invocationsDetails
? requestParamsObj.invocationsDetails
: undefined,
invocationsDetails ?? undefined,
);
const estimateFeeResp = addFeesFromAllTransactions(fees);

Expand All @@ -88,33 +91,21 @@ export async function executeTxn(params: ApiParamsWithKeyDeriver) {
logger.log(`MaxFee: ${maxFee}`);

let snapComponents: Component[] = [];
let createAccountApiParams = {} as ApiParamsWithKeyDeriver;
if (!accountDeployed) {
snapComponents.push(heading(`The account will be deployed`));
addDialogTxt(snapComponents, 'Address', senderAddress);
addDialogTxt(snapComponents, 'Address', address);
addDialogTxt(snapComponents, 'Public Key', publicKey);
addDialogTxt(snapComponents, 'Address Index', addressIndex.toString());
snapComponents.push(divider());
createAccountApiParams = {
state,
wallet: params.wallet,
saveMutex: params.saveMutex,
keyDeriver,
requestParams: {
addressIndex,
deploy: true,
chainId: requestParamsObj.chainId,
},
};
}

snapComponents = snapComponents.concat(
getTxnSnapTxt(
senderAddress,
address,
network,
requestParamsObj.txnInvocation,
requestParamsObj.abis,
requestParamsObj.invocationsDetails,
invocationsDetails,
),
);

Expand All @@ -133,17 +124,29 @@ export async function executeTxn(params: ApiParamsWithKeyDeriver) {
}

if (!accountDeployed) {
await createAccount(createAccountApiParams, true, true);
await createAccount({
network,
address,
publicKey,
privateKey,
waitMode: true,
callback: undefined,
version,
});
}
const nonceSendTransaction = accountDeployed ? undefined : 1;

return await executeTxnUtil(
network,
senderAddress,
senderPrivateKey,
address,
privateKey,
requestParamsObj.txnInvocation,
requestParamsObj.abis,
{ maxFee, nonce: nonceSendTransaction },
{
...invocationsDetails,
maxFee,
nonce: nonceSendTransaction,
},
CAIRO_VERSION,
);
} catch (error) {
Expand Down
6 changes: 5 additions & 1 deletion packages/starknet-snap/src/utils/snapUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,13 @@ export function getTxnSnapTxt(
}

if (details?.maxFee) {
const feeToken: FeeToken =
details?.version === constants.TRANSACTION_VERSION.V3
? FeeToken.STRK
: FeeToken.ETH;
addDialogTxt(
components,
`Max Fee(${FeeToken.ETH})`,
`Max Fee(${feeToken})`,
convert(details.maxFee, 'wei', 'ether'),
);
}
Expand Down
42 changes: 22 additions & 20 deletions packages/starknet-snap/test/src/executeTxn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,13 @@ import {
account1,
estimateFeeResp,
} from '../constants.test';
import * as createAccountUtils from '../../src/createAccount';
import * as snapsUtil from '../../src/utils/snapUtils';
import { getAddressKeyDeriver } from '../../src/utils/keyPair';
import { Mutex } from 'async-mutex';
import {
ApiParamsWithKeyDeriver,
ExecuteTxnRequestParams,
} from '../../src/types/snapApi';
import { GetTransactionReceiptResponse } from 'starknet';
import {
DeployRequiredError,
UpgradeRequiredError,
} from '../../src/utils/exceptions';

chai.use(sinonChai);
const sandbox = sinon.createSandbox();
Expand Down Expand Up @@ -96,7 +90,7 @@ describe('Test function: executeTxn', function () {
sandbox.stub(utils, 'validateAccountRequireUpgradeOrDeploy').resolvesThis();
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
const createAccountStub = sandbox
.stub(createAccountUtils, 'createAccount')
.stub(utils, 'createAccount')
.resolvesThis();
const stub = sandbox.stub(utils, 'executeTxn').resolves({
transaction_hash: 'transaction_hash',
Expand All @@ -123,18 +117,22 @@ describe('Test function: executeTxn', function () {
undefined,
{ maxFee: '22702500105945', nonce: 1 },
);
expect(createAccountStub).to.have.been.calledOnceWith(
sinon.match.any,
true,
true,
);
expect(createAccountStub).to.have.been.calledOnceWith({
network: STARKNET_MAINNET_NETWORK,
address: account1.address,
publicKey: account1.publicKey,
privateKey: privateKey,
waitMode: true,
callback: undefined,
version: undefined,
});
});

it('should executeTxn multiple and deploy an account', async function () {
sandbox.stub(utils, 'validateAccountRequireUpgradeOrDeploy').resolvesThis();
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
const createAccountStub = sandbox
.stub(createAccountUtils, 'createAccount')
.stub(utils, 'createAccount')
.resolvesThis();
const stub = sandbox.stub(utils, 'executeTxn').resolves({
transaction_hash: 'transaction_hash',
Expand Down Expand Up @@ -189,15 +187,19 @@ describe('Test function: executeTxn', function () {
undefined,
{ maxFee: '22702500105945', nonce: 1 },
);
expect(createAccountStub).to.have.been.calledOnceWith(
sinon.match.any,
true,
true,
);
expect(createAccountStub).to.have.been.calledOnceWith({
network: STARKNET_MAINNET_NETWORK,
address: account1.address,
publicKey: account1.publicKey,
privateKey: privateKey,
waitMode: true,
callback: undefined,
version: undefined,
});
});

it('should executeTxn and not deploy an account', async function () {
const createAccountStub = sandbox.stub(createAccountUtils, 'createAccount');
const createAccountStub = sandbox.stub(utils, 'createAccount');
sandbox.stub(utils, 'validateAccountRequireUpgradeOrDeploy').resolvesThis();
sandbox.stub(utils, 'isAccountDeployed').resolves(true);
const stub = sandbox.stub(utils, 'executeTxn').resolves({
Expand Down Expand Up @@ -231,7 +233,7 @@ describe('Test function: executeTxn', function () {
});

it('should executeTxn multiple and not deploy an account', async function () {
const createAccountStub = sandbox.stub(createAccountUtils, 'createAccount');
const createAccountStub = sandbox.stub(utils, 'createAccount');
sandbox.stub(utils, 'validateAccountRequireUpgradeOrDeploy').resolvesThis();
sandbox.stub(utils, 'isAccountDeployed').resolves(true);
const stub = sandbox.stub(utils, 'executeTxn').resolves({
Expand Down

0 comments on commit 6f2b099

Please sign in to comment.