Skip to content

Commit

Permalink
Merge branch 'fix/sf-653' into releases/2.8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
khanti42 committed Jul 10, 2024
2 parents a15f6ab + 1836acf commit 5aaff77
Show file tree
Hide file tree
Showing 40 changed files with 998 additions and 194 deletions.
67 changes: 52 additions & 15 deletions packages/starknet-snap/src/createAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ import {
getAccContractAddressAndCallData,
deployAccount,
waitForTransaction,
getAccContractAddressAndCallDataLegacy,
estimateAccountDeployFee,
} from './utils/starknetUtils';
import {
getNetworkFromChainId,
getValidNumber,
upsertAccount,
upsertTransaction,
addDialogTxt,
getSendTxnText,
} from './utils/snapUtils';
import { AccContract, VoyagerTransactionType, Transaction, TransactionStatus } from './types/snapState';
import { ApiParams, CreateAccountRequestParams } from './types/snapApi';
import { heading, panel, text, DialogType } from '@metamask/snaps-sdk';
import { heading, panel, DialogType } from '@metamask/snaps-sdk';
import { logger } from './utils/logger';
import { CAIRO_VERSION, CAIRO_VERSION_LEGACY } from './utils/constants';
import { CairoVersion, EstimateFee, num } from 'starknet';

/**
* Create an starknet account.
Expand All @@ -24,11 +28,15 @@ import { logger } from './utils/logger';
* @param silentMode - The flag to disable the confirmation dialog from snap.
* @param waitMode - The flag to enable an determination by doing an recursive fetch to check if the deploy account status is on L2 or not. The wait mode is only useful when it compose with other txn together, it can make sure the deploy txn execute complete, avoiding the latter txn failed.
*/
export async function createAccount(params: ApiParams, silentMode = false, waitMode = false) {
export async function createAccount(
params: ApiParams,
silentMode = false,
waitMode = false,
cairoVersion: CairoVersion = CAIRO_VERSION,
) {
try {
const { state, wallet, saveMutex, keyDeriver, requestParams } = params;
const requestParamsObj = requestParams as CreateAccountRequestParams;

const addressIndex = getValidNumber(requestParamsObj.addressIndex, -1, 0);
const network = getNetworkFromChainId(state, requestParamsObj.chainId);
const deploy = !!requestParamsObj.deploy;
Expand All @@ -39,37 +47,64 @@ export async function createAccount(params: ApiParams, silentMode = false, waitM
addressIndex: addressIndexInUsed,
derivationPath,
} = await getKeysFromAddressIndex(keyDeriver, network.chainId, state, addressIndex);
const { address: contractAddress, callData: contractCallData } = getAccContractAddressAndCallData(publicKey);

const { address: contractAddress, callData: contractCallData } =
cairoVersion == CAIRO_VERSION_LEGACY
? getAccContractAddressAndCallDataLegacy(publicKey)
: getAccContractAddressAndCallData(publicKey);
logger.log(
`createAccount:\ncontractAddress = ${contractAddress}\npublicKey = ${publicKey}\naddressIndex = ${addressIndexInUsed}`,
);

if (deploy) {
if (!silentMode) {
const components = [];
addDialogTxt(components, 'Address', contractAddress);
addDialogTxt(components, 'Public Key', publicKey);
addDialogTxt(components, 'Address Index', addressIndex.toString());
logger.log(
`estimateAccountDeployFee:\ncontractAddress = ${contractAddress}\npublicKey = ${publicKey}\naddressIndex = ${addressIndexInUsed}`,
);

const estimateDeployFee: EstimateFee = await estimateAccountDeployFee(
network,
contractAddress,
contractCallData,
publicKey,
privateKey,
cairoVersion,
);
logger.log(`estimateAccountDeployFee:\nestimateDeployFee: ${toJson(estimateDeployFee)}`);
const maxFee = num.toBigInt(estimateDeployFee.suggestedMaxFee.toString(10) ?? '0');
const dialogComponents = getSendTxnText(
state,
contractAddress,
'deploy',
contractCallData,
contractAddress,
maxFee,
network,
);

const response = await wallet.request({
method: 'snap_dialog',
params: {
type: DialogType.Confirmation,
content: panel([
heading('Do you want to sign this deploy account transaction ?'),
text(`It will be signed with address: ${contractAddress}`),
...components,
]),
content: panel([heading('Do you want to sign this deploy transaction ?'), ...dialogComponents]),
},
});

if (!response)
return {
address: contractAddress,
};
}

// Deploy account will auto estimate the fee from the network if not provided
const deployResp = await deployAccount(network, contractAddress, contractCallData, publicKey, privateKey);
const deployResp = await deployAccount(
network,
contractAddress,
contractCallData,
publicKey,
privateKey,
cairoVersion,
);

if (deployResp.contract_address && deployResp.transaction_hash) {
const userAccount: AccContract = {
Expand All @@ -80,6 +115,8 @@ export async function createAccount(params: ApiParams, silentMode = false, waitM
derivationPath,
deployTxnHash: deployResp.transaction_hash,
chainId: network.chainId,
upgradeRequired: cairoVersion === CAIRO_VERSION_LEGACY,
deployRequired: false,
};

await upsertAccount(userAccount, wallet, saveMutex);
Expand Down
18 changes: 12 additions & 6 deletions packages/starknet-snap/src/declareContract.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { toJson } from './utils/serializer';
import { ApiParams, DeclareContractRequestParams } from './types/snapApi';
import { getNetworkFromChainId, getDeclareSnapTxt, showUpgradeRequestModal } from './utils/snapUtils';
import { getKeysFromAddress, declareContract as declareContractUtil, isUpgradeRequired } from './utils/starknetUtils';
import { getNetworkFromChainId, getDeclareSnapTxt, showAccountRequireUpgradeOrDeployModal } from './utils/snapUtils';
import {
getKeysFromAddress,
declareContract as declareContractUtil,
validateAccountRequireUpgradeOrDeploy,
} from './utils/starknetUtils';
import { heading, panel, DialogType } from '@metamask/snaps-sdk';
import { logger } from './utils/logger';

Expand All @@ -14,11 +18,13 @@ export async function declareContract(params: ApiParams) {

const senderAddress = requestParamsObj.senderAddress;
const network = getNetworkFromChainId(state, requestParamsObj.chainId);
const { privateKey } = await getKeysFromAddress(keyDeriver, network, state, senderAddress);
const { privateKey, publicKey } = await getKeysFromAddress(keyDeriver, network, state, senderAddress);

if (await isUpgradeRequired(network, senderAddress)) {
await showUpgradeRequestModal(wallet);
throw new Error('Upgrade required');
try {
await validateAccountRequireUpgradeOrDeploy(network, senderAddress, publicKey);
} catch (e) {
await showAccountRequireUpgradeOrDeployModal(wallet, e);
throw e;
}

const snapComponents = getDeclareSnapTxt(
Expand Down
9 changes: 3 additions & 6 deletions packages/starknet-snap/src/estimateFee.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toJson } from './utils/serializer';
import { Invocations, TransactionType } from 'starknet';
import { validateAndParseAddress } from '../src/utils/starknetUtils';
import { validateAccountRequireUpgradeOrDeploy, validateAndParseAddress } from '../src/utils/starknetUtils';
import { ApiParams, EstimateFeeRequestParams } from './types/snapApi';
import { getNetworkFromChainId } from './utils/snapUtils';
import {
Expand All @@ -11,7 +11,6 @@ import {
estimateFeeBulk,
addFeesFromAllTransactions,
isAccountDeployed,
isUpgradeRequired,
} from './utils/starknetUtils';
import { ACCOUNT_CLASS_HASH } from './utils/constants';
import { logger } from './utils/logger';
Expand Down Expand Up @@ -45,17 +44,15 @@ export async function estimateFee(params: ApiParams) {
throw new Error(`The given sender address is invalid: ${senderAddress}`);
}

if (await isUpgradeRequired(network, senderAddress)) {
throw new Error('Upgrade required');
}

const { privateKey: senderPrivateKey, publicKey } = await getKeysFromAddress(
keyDeriver,
network,
state,
senderAddress,
);

await validateAccountRequireUpgradeOrDeploy(network, senderAddress, publicKey);

const txnInvocation = {
contractAddress,
entrypoint: contractFuncName,
Expand Down
17 changes: 12 additions & 5 deletions packages/starknet-snap/src/executeTxn.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { Invocations, TransactionType } from 'starknet';
import { getNetworkFromChainId, getTxnSnapTxt, addDialogTxt, showUpgradeRequestModal } from './utils/snapUtils';
import {
getNetworkFromChainId,
getTxnSnapTxt,
addDialogTxt,
showAccountRequireUpgradeOrDeployModal,
} from './utils/snapUtils';
import {
getKeysFromAddress,
executeTxn as executeTxnUtil,
isAccountDeployed,
estimateFeeBulk,
getAccContractAddressAndCallData,
addFeesFromAllTransactions,
isUpgradeRequired,
validateAccountRequireUpgradeOrDeploy,
} from './utils/starknetUtils';
import { ApiParams, ExecuteTxnRequestParams } from './types/snapApi';
import { createAccount } from './createAccount';
Expand All @@ -27,9 +32,11 @@ export async function executeTxn(params: ApiParams) {
addressIndex,
} = await getKeysFromAddress(keyDeriver, network, state, senderAddress);

if (await isUpgradeRequired(network, senderAddress)) {
await showUpgradeRequestModal(wallet);
throw new Error('Upgrade required');
try {
await validateAccountRequireUpgradeOrDeploy(network, senderAddress, publicKey);
} catch (e) {
await showAccountRequireUpgradeOrDeployModal(wallet, e);
throw e;
}

const txnInvocationArray = Array.isArray(requestParamsObj.txnInvocation)
Expand Down
11 changes: 4 additions & 7 deletions packages/starknet-snap/src/extractPrivateKey.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { toJson } from './utils/serializer';
import { validateAndParseAddress } from '../src/utils/starknetUtils';
import { validateAccountRequireUpgradeOrDeploy, validateAndParseAddress } from '../src/utils/starknetUtils';
import { ApiParams, ExtractPrivateKeyRequestParams } from './types/snapApi';
import { getNetworkFromChainId } from './utils/snapUtils';
import { getKeysFromAddress, isUpgradeRequired } from './utils/starknetUtils';
import { getKeysFromAddress } from './utils/starknetUtils';
import { copyable, panel, text, DialogType } from '@metamask/snaps-sdk';
import { logger } from './utils/logger';

Expand All @@ -22,9 +22,8 @@ export async function extractPrivateKey(params: ApiParams) {
throw new Error(`The given user address is invalid: ${userAddress}`);
}

if (await isUpgradeRequired(network, userAddress)) {
throw new Error('Upgrade required');
}
const { privateKey: userPrivateKey, publicKey } = await getKeysFromAddress(keyDeriver, network, state, userAddress);
await validateAccountRequireUpgradeOrDeploy(network, userAddress, publicKey);

const response = await wallet.request({
method: 'snap_dialog',
Expand All @@ -35,8 +34,6 @@ export async function extractPrivateKey(params: ApiParams) {
});

if (response === true) {
const { privateKey: userPrivateKey } = await getKeysFromAddress(keyDeriver, network, state, userAddress);

await wallet.request({
method: 'snap_dialog',
params: {
Expand Down
9 changes: 4 additions & 5 deletions packages/starknet-snap/src/extractPublicKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toJson } from './utils/serializer';
import { constants, num } from 'starknet';
import { validateAndParseAddress, isUpgradeRequired } from '../src/utils/starknetUtils';
import { validateAndParseAddress, validateAccountRequireUpgradeOrDeploy } from '../src/utils/starknetUtils';
import { ApiParams, ExtractPublicKeyRequestParams } from './types/snapApi';
import { getAccount, getNetworkFromChainId } from './utils/snapUtils';
import { getKeysFromAddress } from './utils/starknetUtils';
Expand All @@ -26,15 +26,14 @@ export async function extractPublicKey(params: ApiParams) {
throw new Error(`The given user address is invalid: ${requestParamsObj.userAddress}`);
}

if (await isUpgradeRequired(network, userAddress)) {
throw new Error('Upgrade required');
}
// [TODO] logic below is redundant, getKeysFromAddress is doing the same
const { publicKey } = await getKeysFromAddress(keyDeriver, network, state, userAddress);
await validateAccountRequireUpgradeOrDeploy(network, userAddress, publicKey);

let userPublicKey;
const accContract = getAccount(state, userAddress, network.chainId);
if (!accContract?.publicKey || num.toBigInt(accContract.publicKey) === constants.ZERO) {
logger.log(`extractPublicKey: User address cannot be found or the signer public key is 0x0: ${userAddress}`);
const { publicKey } = await getKeysFromAddress(keyDeriver, network, state, userAddress);
userPublicKey = publicKey;
} else {
userPublicKey = accContract.publicKey;
Expand Down
5 changes: 5 additions & 0 deletions packages/starknet-snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { addNetwork } from './addNetwork';
import { switchNetwork } from './switchNetwork';
import { getCurrentNetwork } from './getCurrentNetwork';
import {
CAIRO_VERSION_LEGACY,
PRELOADED_TOKENS,
STARKNET_INTEGRATION_NETWORK,
STARKNET_MAINNET_NETWORK,
Expand Down Expand Up @@ -124,6 +125,10 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ origin, request }) =>
apiParams.keyDeriver = await getAddressKeyDeriver(snap);
return createAccount(apiParams);

case 'starkNet_createAccountLegacy':
apiParams.keyDeriver = await getAddressKeyDeriver(snap);
return createAccount(apiParams, false, true, CAIRO_VERSION_LEGACY);

case 'starkNet_getStoredUserAccounts':
return await getStoredUserAccounts(apiParams);

Expand Down
2 changes: 2 additions & 0 deletions packages/starknet-snap/src/recoverAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export async function recoverAccounts(params: ApiParams) {
address: contractAddress,
signerPubKey: signerPublicKey,
upgradeRequired,
deployRequired,
} = await getCorrectContractAddress(network, publicKey);
logger.log(
`recoverAccounts: index ${i}:\ncontractAddress = ${contractAddress}\npublicKey = ${publicKey}\nisUpgradeRequired = ${upgradeRequired}`,
Expand All @@ -57,6 +58,7 @@ export async function recoverAccounts(params: ApiParams) {
deployTxnHash: '',
chainId: network.chainId,
upgradeRequired: upgradeRequired,
deployRequired: deployRequired,
};

logger.log(`recoverAccounts: index ${i}\nuserAccount: ${toJson(userAccount)}`);
Expand Down
14 changes: 8 additions & 6 deletions packages/starknet-snap/src/signDeclareTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { ApiParams, SignDeclareTransactionRequestParams } from './types/snapApi'
import {
getKeysFromAddress,
signDeclareTransaction as signDeclareTransactionUtil,
isUpgradeRequired,
validateAccountRequireUpgradeOrDeploy,
} from './utils/starknetUtils';
import { getNetworkFromChainId, getSignTxnTxt, showUpgradeRequestModal } from './utils/snapUtils';
import { getNetworkFromChainId, getSignTxnTxt, showAccountRequireUpgradeOrDeployModal } from './utils/snapUtils';
import { heading, panel, DialogType } from '@metamask/snaps-sdk';
import { logger } from './utils/logger';

Expand All @@ -16,11 +16,13 @@ export async function signDeclareTransaction(params: ApiParams): Promise<Signatu
const requestParamsObj = requestParams as SignDeclareTransactionRequestParams;
const signerAddress = requestParamsObj.signerAddress;
const network = getNetworkFromChainId(state, requestParamsObj.chainId);
const { privateKey } = await getKeysFromAddress(keyDeriver, network, state, signerAddress);
const { privateKey, publicKey } = await getKeysFromAddress(keyDeriver, network, state, signerAddress);

if (await isUpgradeRequired(network, signerAddress)) {
await showUpgradeRequestModal(wallet);
throw new Error('Upgrade required');
try {
await validateAccountRequireUpgradeOrDeploy(network, signerAddress, publicKey);
} catch (e) {
await showAccountRequireUpgradeOrDeployModal(wallet, e);
throw e;
}

logger.log(`signDeclareTransaction params: ${toJson(requestParamsObj.transaction, 2)}}`);
Expand Down
14 changes: 8 additions & 6 deletions packages/starknet-snap/src/signDeployAccountTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { ApiParams, SignDeployAccountTransactionRequestParams } from './types/sn
import {
getKeysFromAddress,
signDeployAccountTransaction as signDeployAccountTransactionUtil,
isUpgradeRequired,
validateAccountRequireUpgradeOrDeploy,
} from './utils/starknetUtils';
import { getNetworkFromChainId, getSignTxnTxt, showUpgradeRequestModal } from './utils/snapUtils';
import { getNetworkFromChainId, getSignTxnTxt, showAccountRequireUpgradeOrDeployModal } from './utils/snapUtils';
import { heading, panel, DialogType } from '@metamask/snaps-sdk';
import { logger } from '../src/utils/logger';

Expand All @@ -16,11 +16,13 @@ export async function signDeployAccountTransaction(params: ApiParams): Promise<S
const requestParamsObj = requestParams as SignDeployAccountTransactionRequestParams;
const signerAddress = requestParamsObj.signerAddress;
const network = getNetworkFromChainId(state, requestParamsObj.chainId);
const { privateKey } = await getKeysFromAddress(keyDeriver, network, state, signerAddress);
const { privateKey, publicKey } = await getKeysFromAddress(keyDeriver, network, state, signerAddress);

if (await isUpgradeRequired(network, signerAddress)) {
await showUpgradeRequestModal(wallet);
throw new Error('Upgrade required');
try {
await validateAccountRequireUpgradeOrDeploy(network, signerAddress, publicKey);
} catch (e) {
await showAccountRequireUpgradeOrDeployModal(wallet, e);
throw e;
}

logger.log(`signDeployAccountTransaction params: ${toJson(requestParamsObj.transaction, 2)}}`);
Expand Down
Loading

0 comments on commit 5aaff77

Please sign in to comment.