Skip to content

Commit

Permalink
feat: simplify snap logic
Browse files Browse the repository at this point in the history
  • Loading branch information
stanleyyconsensys committed Nov 17, 2023
1 parent 62f589e commit 2ee8e1b
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 57 deletions.
4 changes: 2 additions & 2 deletions packages/starknet-snap/src/createAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
deployAccount,
getBalance,
estimateAccountDeployFee,
isAccountAddressDeployed,
isAccountDeployed,
} from './utils/starknetUtils';
import {
getEtherErc20Token,
Expand Down Expand Up @@ -72,7 +72,7 @@ export async function createAccount(params: ApiParams, silentMode = false) {
};
}

const signerAssigned = await isAccountAddressDeployed(network, contractAddress);
const signerAssigned = await isAccountDeployed(network, contractAddress);

if (!signerAssigned) {
try {
Expand Down
2 changes: 1 addition & 1 deletion packages/starknet-snap/src/estimateFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export async function estimateFee(params: ApiParams) {
logger.log(`estimateFee:\ntxnInvocation: ${toJson(txnInvocation)}`);

//Estimate deploy account fee if the signer has not been deployed yet
const accountDeployed = await isAccountDeployed(network, publicKey);
const accountDeployed = await isAccountDeployed(network, senderAddress);
let bulkTransactions: Invocations = [
{
type: TransactionType.INVOKE,
Expand Down
13 changes: 7 additions & 6 deletions packages/starknet-snap/src/sendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ export async function sendTransaction(params: ApiParams) {
throw new Error('Upgrade required');
}

const {
privateKey: senderPrivateKey,
publicKey,
addressIndex,
} = await getKeysFromAddress(keyDeriver, network, state, senderAddress);
const { privateKey: senderPrivateKey, addressIndex } = await getKeysFromAddress(
keyDeriver,
network,
state,
senderAddress,
);
let maxFee = requestParamsObj.maxFee ? num.toBigInt(requestParamsObj.maxFee) : constants.ZERO;
if (maxFee === constants.ZERO) {
const { suggestedMaxFee } = await estimateFee(params);
Expand Down Expand Up @@ -88,7 +89,7 @@ export async function sendTransaction(params: ApiParams) {

logger.log(`sendTransaction:\ntxnInvocation: ${toJson(txnInvocation)}\nmaxFee: ${maxFee.toString()}}`);

const accountDeployed = await isAccountDeployed(network, publicKey);
const accountDeployed = await isAccountDeployed(network, senderAddress);
if (!accountDeployed) {
//Deploy account before sending the transaction
logger.log('sendTransaction:\nFirst transaction : send deploy transaction');
Expand Down
1 change: 0 additions & 1 deletion packages/starknet-snap/src/types/snapState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export interface Network {
nodeUrl: string;
voyagerUrl: string;
accountClassHash: string; // in hex
accountClassHashV0?: string; // in hex
useOldAccounts?: boolean;
}

Expand Down
9 changes: 3 additions & 6 deletions packages/starknet-snap/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ export const STARKNET_MAINNET_NETWORK: Network = {
baseUrl: 'https://alpha-mainnet.starknet.io',
nodeUrl: 'https://starknet-mainnet.infura.io/v3/60c7253fb48147658095fe0460ac9ee9',
voyagerUrl: 'https://voyager.online',
accountClassHashV0: '0x033434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2', // from argent-x repo
accountClassHash: '0x1a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003',
accountClassHash: '',
};

export const STARKNET_TESTNET_NETWORK: Network = {
Expand All @@ -32,8 +31,7 @@ export const STARKNET_TESTNET_NETWORK: Network = {
baseUrl: 'https://alpha4.starknet.io',
nodeUrl: 'https://starknet-goerli.infura.io/v3/60c7253fb48147658095fe0460ac9ee9',
voyagerUrl: 'https://goerli.voyager.online',
accountClassHashV0: '0x033434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2', // from argent-x repo
accountClassHash: '0x1a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003',
accountClassHash: '',
};

export const STARKNET_INTEGRATION_NETWORK: Network = {
Expand All @@ -42,8 +40,7 @@ export const STARKNET_INTEGRATION_NETWORK: Network = {
baseUrl: 'https://external.integration.starknet.io',
nodeUrl: '',
voyagerUrl: '',
accountClassHashV0: '0x033434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2', // from argent-x repo
accountClassHash: '0x1a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003',
accountClassHash: '',
};

export const ETHER_MAINNET: Erc20Token = {
Expand Down
72 changes: 47 additions & 25 deletions packages/starknet-snap/src/utils/starknetUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,12 @@ export const getNextAddressIndex = (chainId: string, state: SnapState, derivatio
return uninitializedAccount?.addressIndex ?? accounts.length;
};

/**
* calculate contract address by publicKey, supported for carioVersions [1]
*
* @param publicKey - address's publicKey.
* @returns - address and calldata.
*/
export const getAccContractAddressAndCallData = (publicKey) => {
const callData = CallData.compile({
signer: publicKey,
Expand All @@ -438,6 +444,12 @@ export const getAccContractAddressAndCallData = (publicKey) => {
};
};

/**
* calculate contract address by publicKey, supported for carioVersions [0]
*
* @param publicKey - address's publicKey.
* @returns - address and calldata.
*/
export const getAccContractAddressAndCallDataCairo0 = (publicKey) => {
const callData = CallData.compile({
implementation: ACCOUNT_CLASS_HASH_V0,
Expand Down Expand Up @@ -496,37 +508,23 @@ export const getKeysFromAddressIndex = async (
};
};

export const isAccountDeployedCairo0 = async (network: Network, publicKey: string) => {
const { address } = getAccContractAddressAndCallDataCairo0(publicKey);
return isAccountAddressDeployed(network, address, 0);
};

export const isAccountDeployed = async (network: Network, publicKey: string) => {
const { address } = getAccContractAddressAndCallData(publicKey);
return isAccountAddressDeployed(network, address, 1);
};

export const isAccountAddressDeployed = async (network: Network, address: string, cairoVersion = 1) => {
let accountDeployed = true;
/**
* Check address is deployed by using getVersion, supported for carioVersions [0,1]
*
* @param network - Network.
* @param address - Input address.
* @returns - boolean.
*/
export const isAccountDeployed = async (network: Network, address: string) => {
try {
switch (cairoVersion) {
case 0:
await getSigner(address, network);
break;
case 1:
await getOwner(address, network);
break;
default:
throw new Error(`Not supported cairo version ${cairoVersion}`);
}
await getVersion(address, network);
return true;
} catch (err) {
if (!err.message.includes('Contract not found')) {
throw err;
}
accountDeployed = false;
return false;
}

return accountDeployed;
};

export const addFeesFromAllTransactions = (fees: EstimateFee[]): EstimateFee => {
Expand All @@ -552,6 +550,16 @@ export const validateAndParseAddress = (address: num.BigNumberish, length = 63)
return _validateAndParseAddressFn(address);
};

/**
* Find address index from the keyDeriver, supported for carioVersions [0,1]
*
* @param chainId - Network ChainId.
* @param address - Input address.
* @param keyDeriver - keyDeriver from MetaMask wallet.
* @param state - MetaMask Snap state.
* @param maxScan - Number of scaning in the keyDeriver.
* @returns - address index and cairoVersion.
*/
export const findAddressIndex = async (
chainId: string,
address: string,
Expand All @@ -575,6 +583,13 @@ export const findAddressIndex = async (
throw new Error(`Address not found: ${address}`);
};

/**
* Check address needed upgrade by using getVersion and compare with MIN_ACC_CONTRACT_VERSION, supported for carioVersions [0,1]
*
* @param network - Network.
* @param address - Input address.
* @returns - boolean.
*/
export const isUpgradeRequired = async (network: Network, address: string) => {
try {
logger.log(`isUpgradeRequired: address = ${address}`);
Expand All @@ -590,6 +605,13 @@ export const isUpgradeRequired = async (network: Network, address: string) => {
}
};

/**
* Get user address by public key, return address if the address has deployed, prioritize cario 1 over cario 0, supported for carioVersions [0,1]
*
* @param network - Network.
* @param publicKey - address's public key.
* @returns - address and address's public key.
*/
export const getCorrectContractAddress = async (network: Network, publicKey: string) => {
const { address: contractAddress } = getAccContractAddressAndCallData(publicKey);
const { address: contractAddressCairo0 } = getAccContractAddressAndCallDataCairo0(publicKey);
Expand Down
1 change: 0 additions & 1 deletion packages/starknet-snap/test/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export const invalidNetwork: Network = {
nodeUrl: '',
voyagerUrl: '',
accountClassHash: '',
accountClassHashV0: '',
};

export const account1: AccContract = {
Expand Down
24 changes: 12 additions & 12 deletions packages/starknet-snap/test/src/createAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('Test function: createAccount', function () {
});

it('should only return derived address without sending deploy txn correctly in mainnet if deploy is false', async function () {
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
const requestObject: CreateAccountRequestParams = {
chainId: STARKNET_MAINNET_NETWORK.chainId,
};
Expand All @@ -86,7 +86,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyMainnetResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand Down Expand Up @@ -122,7 +122,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyMainnetResp2;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand Down Expand Up @@ -157,7 +157,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand Down Expand Up @@ -206,7 +206,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(true);
sandbox.stub(utils, 'isAccountDeployed').resolves(true);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand All @@ -227,7 +227,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand All @@ -248,7 +248,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').callsFake(async () => {
return getBalanceResp[0];
});
Expand All @@ -269,7 +269,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'getBalance').throws(new Error());
sandbox.stub(utils, 'estimateAccountDeployFee').callsFake(async () => {
return estimateDeployFeeResp2;
Expand All @@ -288,7 +288,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountFailedProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'callContract').resolves(getBalanceResp);
sandbox.stub(utils, 'getSigner').throws(new Error());
sandbox.stub(utils, 'estimateAccountDeployFee').callsFake(async () => {
Expand All @@ -309,7 +309,7 @@ describe('Test function: createAccount', function () {
sandbox.stub(utils, 'deployAccount').callsFake(async () => {
return createAccountProxyResp;
});
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
sandbox.stub(utils, 'callContract').resolves(getBalanceResp);
sandbox.stub(utils, 'getSigner').throws(new Error());
sandbox.stub(utils, 'estimateAccountDeployFee').callsFake(async () => {
Expand All @@ -328,8 +328,8 @@ describe('Test function: createAccount', function () {
}
});

it('should throw error if isAccountAddressDeployed failed', async function () {
const isAccountAddressDeployedStub = sandbox.stub(utils, 'isAccountAddressDeployed').throws(new Error());
it('should throw error if isAccountDeployed failed', async function () {
const isAccountAddressDeployedStub = sandbox.stub(utils, 'isAccountDeployed').throws(new Error());
const deployAccountStub = sandbox.stub(utils, 'deployAccount');
const estimateAccountDeployFeeStub = sandbox.stub(utils, 'estimateAccountDeployFee');
const getBalanceStub = sandbox.stub(utils, 'getBalance');
Expand Down
6 changes: 3 additions & 3 deletions packages/starknet-snap/test/src/sendTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ describe('Test function: sendTransaction', function () {
});
describe('when account is deployed', function () {
beforeEach(async function () {
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(true);
sandbox.stub(utils, 'isAccountDeployed').resolves(true);
});

it('should send a transaction for transferring 10 tokens correctly', async function () {
Expand Down Expand Up @@ -268,7 +268,7 @@ describe('Test function: sendTransaction', function () {

describe('when account is deployed', function () {
beforeEach(async function () {
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(true);
sandbox.stub(utils, 'isAccountDeployed').resolves(true);
});

it('should send a transaction for transferring 10 tokens correctly', async function () {
Expand Down Expand Up @@ -410,7 +410,7 @@ describe('Test function: sendTransaction', function () {

describe('when account is not deployed', function () {
beforeEach(async function () {
sandbox.stub(utils, 'isAccountAddressDeployed').resolves(false);
sandbox.stub(utils, 'isAccountDeployed').resolves(false);
});

it('should send a transaction for transferring 10 tokens and a transaction for deploy correctly', async function () {
Expand Down

0 comments on commit 2ee8e1b

Please sign in to comment.