Skip to content

Commit

Permalink
feat(get-starknet): Integrate get-starknet v4 (#400)
Browse files Browse the repository at this point in the history
* feat(get-starknet): add skeleton to support get-starknet v4 (#365)

* feat: implement skeleton

* chore: update skeletion

* chore: update test

* Update packages/get-starknet/src/rpcs/switch-network.ts

Co-authored-by: khanti42 <[email protected]>

---------

Co-authored-by: khanti42 <[email protected]>

* chore: get-starknet linter relax (#371)

* feat: implement skeleton

* chore: update skeletion

* chore: update test

* Update packages/get-starknet/src/rpcs/switch-network.ts

Co-authored-by: khanti42 <[email protected]>

* chore: remove js from linter

* Update packages/get-starknet/.eslintrc.js

Co-authored-by: stanleyyuen <[email protected]>

* feat(get-starknet): add wallet_supportedSpecs rpc method (#370)

* feat: implement skeleton

* chore: update skeletion

* chore: update test

* Update packages/get-starknet/src/rpcs/switch-network.ts

Co-authored-by: khanti42 <[email protected]>

* feat: add wallet_supportedSpecs handling

* Update packages/get-starknet/src/constants.ts

Co-authored-by: Stanley Yuen <[email protected]>

---------

Co-authored-by: stanleyyuen <[email protected]>

* refactor(get-starknet): add get-starknet error handling (#375)

* chore: add error handling

* chore: update error name

* chore: change wallet rpc and error handle

* chore: update get-starknet switch network rpc

* chore: change wallet rpc and error handle (#377)

* feat(get-starknet): add `wallet_requestChainId` rpc method (#379)

* chore: change wallet rpc and error handle

* feat(get-starknet): add wallet_requestChainId rpc method

* feat(get-starknet): add `wallet_requestAccounts` rpc method (#380)

* feat: add wallet_requestAccounts rpc to get-starknet

* chore: rename rpc file name

---------

Co-authored-by: khanti42 <[email protected]>

* feat(get-starknet): add wallet_supportedWalletApi rpc method  (#372)

* feat: add wallet_supportedWalletApi handling

* chore: lint

* fix: remove type duplicate

* feat(get-starknet): add `wallet_deploymentData` rpc method (#382)

* chore: add get-starknet deployment data rpc

* feat(get-starknet): add `wallet_deploymentData` rpc method

* feat(get-starknet): add `wallet_signTypedData` rpc method (#386)

* feat(get-starknet): add `wallet_signTypedData` rpc method

* chore: update get-starknet wallet instance

* feat(get-starknet): add `wallet_watchAsset` rpc method (#387)

* feat(get-starknet): add rpc `wallet_watchAsset`

* chore: fix comment

* chore: update error message (#389)

* feat(get-starknet): add `wallet_addInvokeTransaction` rpc method (#385)

* feat: add suport for add-invoke rpcs in get-starknet

* fix: test

* feat: format calls to starknet.js format before calling snap

* chore: address comments review

* Update packages/get-starknet/src/rpcs/add-invoke.test.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/get-starknet/src/rpcs/add-invoke.test.ts

Co-authored-by: Stanley Yuen <[email protected]>

---------

Co-authored-by: Stanley Yuen <[email protected]>

* feat: add rpc wallet_getPermissions (#390)

* feat(get-starknet): add `WalletAddDeclareTransaction` rpc method  (#392)

* feat: handle add-declare rpc and request formatting

* chore: enable rpc method add declare

* Update packages/get-starknet/src/utils/formatter.ts

Co-authored-by: Stanley Yuen <[email protected]>

* chore: address comments review

* Update packages/get-starknet/src/utils/formatter.ts

Co-authored-by: Stanley Yuen <[email protected]>

* Update packages/get-starknet/src/utils/formatter.test.ts

Co-authored-by: Stanley Yuen <[email protected]>

---------

Co-authored-by: Stanley Yuen <[email protected]>

* chore: refactor get-starknet rpc that doesnt need to connect with snap (#393)

* fix: incorrect params on get-starknet rpc sign data (#394)

* refactor(get-starknet): change get starknet snap params structure (#395)

* fix: incorrect params on get-starknet rpc sign data

* chore: refactor get-starknet

* chore: update get-starknet snap util

* chore: update get-starknet account obj

* chore: fix comment

* chore: remove get-starknet-core-v3"

---------

Co-authored-by: khanti42 <[email protected]>
  • Loading branch information
stanleyyconsensys and khanti42 authored Oct 22, 2024
1 parent 5617ccf commit 8bf8463
Show file tree
Hide file tree
Showing 43 changed files with 1,633 additions and 182 deletions.
35 changes: 35 additions & 0 deletions packages/__tests__/fixture/typedDataExample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"types": {
"StarkNetDomain": [
{ "name": "name", "type": "felt" },
{ "name": "version", "type": "felt" },
{ "name": "chainId", "type": "felt" }
],
"Person": [
{ "name": "name", "type": "felt" },
{ "name": "wallet", "type": "felt" }
],
"Mail": [
{ "name": "from", "type": "Person" },
{ "name": "to", "type": "Person" },
{ "name": "contents", "type": "felt" }
]
},
"primaryType": "Mail",
"domain": {
"name": "Starknet Mail",
"version": "1",
"chainId": 1
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
}
}
2 changes: 1 addition & 1 deletion packages/get-starknet/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ module.exports = {
},
],

ignorePatterns: ['!.eslintrc.js', 'dist/', '**/test', '.nyc_output/', 'coverage/'],
ignorePatterns: ['!.eslintrc.js', 'dist/', '**/test', '.nyc_output/', 'coverage/', 'webpack.*.js'],
};
31 changes: 31 additions & 0 deletions packages/get-starknet/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = {
transform: {
'^.+\\.(t|j)sx?$': 'ts-jest',
},
restoreMocks: true,
resetMocks: true,
verbose: true,
testPathIgnorePatterns: ['/node_modules/', '/__mocks__/'],
testMatch: ['<rootDir>/src/**/?(*.)+(spec|test).[tj]s?(x)'],
// Switch off the collectCoverage until jest replace mocha
collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
collectCoverageFrom: [
'./src/**/*.ts',
'!./src/**/*.d.ts',
'!./src/**/index.ts',
'!./src/**/__mocks__/**',
'!./src/config/*.ts',
'!./src/**/type?(s).ts',
'!./src/**/exception?(s).ts',
'!./src/**/constant?(s).ts',
'!./test/**',
'./src/index.ts',
],
// The directory where Jest should output its coverage files
coverageDirectory: 'coverage',
// Indicates which provider should be used to instrument code for coverage
coverageProvider: 'babel',
// A list of reporter names that Jest uses when writing coverage reports
coverageReporters: ['html', 'json-summary', 'text'],
};
7 changes: 5 additions & 2 deletions packages/get-starknet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"prettier": "prettier --write \"src/**/*.ts\"",
"lint": "eslint 'src/*.{js,ts,tsx}' --max-warnings 0 -f json -o eslint-report.json",
"lint:fix": "eslint '**/*.{js,ts,tsx}' --fix",
"test:unit": ""
"test": "jest --passWithNoTests"
},
"keywords": [],
"author": "Consensys",
Expand All @@ -38,10 +38,12 @@
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"get-starknet-core": "^3.2.0",
"get-starknet-core": "^4.0.0",
"jest": "^29.5.0",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"serve": "14.2.1",
"ts-jest": "^29.1.0",
"ts-loader": "^9.5.1",
"typescript": "^4.6.3",
"webpack": "^5.91.0",
Expand All @@ -53,6 +55,7 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"async-mutex": "^0.3.2",
"starknet": "6.11.0"
}
}
31 changes: 31 additions & 0 deletions packages/get-starknet/src/__mocks__/snap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export class MetaMaskSnap {
getPubKey = jest.fn();

signTransaction = jest.fn();

signDeployAccountTransaction = jest.fn();

signDeclareTransaction = jest.fn();

execute = jest.fn();

signMessage = jest.fn();

declare = jest.fn();

getNetwork = jest.fn();

recoverDefaultAccount = jest.fn();

recoverAccounts = jest.fn();

switchNetwork = jest.fn();

addStarknetChain = jest.fn();

watchAsset = jest.fn();

getCurrentNetwork = jest.fn();

installIfNot = jest.fn();
}
117 changes: 117 additions & 0 deletions packages/get-starknet/src/__tests__/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { constants } from 'starknet';

import { MetaMaskSnap } from '../snap';
import type { MetaMaskProvider, Network } from '../type';
import { MetaMaskSnapWallet } from '../wallet';

export const SepoliaNetwork: Network = {
name: 'Sepolia Testnet',
baseUrl: 'https://alpha-sepolia.starknet.io',
chainId: constants.StarknetChainId.SN_SEPOLIA,
nodeUrl: 'https://nodeUrl.com',
voyagerUrl: '',
accountClassHash: '', // from argent-x repo
};

export const MainnetNetwork: Network = {
name: 'Mainnet',
baseUrl: 'https://mainnet.starknet.io',
chainId: constants.StarknetChainId.SN_MAIN,
nodeUrl: 'https://nodeUrl.com',
voyagerUrl: '',
accountClassHash: '', // from argent-x repo
};

export const EthAsset = {
address: '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
name: 'Ether',
symbol: 'ETH',
decimals: 18,
};

/**
* Generate an account object.
*
* @param params
* @param params.addressSalt - The salt of the address.
* @param params.publicKey - The public key of the account.
* @param params.address - The address of the account.
* @param params.addressIndex - The index of the address.
* @param params.derivationPath - The derivation path of the address.
* @param params.deployTxnHash - The transaction hash of the deploy transaction.
* @param params.chainId - The chain id of the account.
* @returns The account object.
*/
export function generateAccount({
addressSalt = 'addressSalt',
publicKey = 'publicKey',
address = '0x04882a372da3dfe1c53170ad75893832469bf87b62b13e84662565c4a88f25cd',
addressIndex = 0,
derivationPath = "m/44'/60'/0'/0/0",
deployTxnHash = '',
chainId = SepoliaNetwork.chainId,
}: {
addressSalt?: string;
publicKey?: string;
address?: string;
addressIndex?: number;
derivationPath?: string;
deployTxnHash?: string;
chainId?: string;
}) {
return {
addressSalt,
publicKey,
address,
addressIndex,
derivationPath,
deployTxnHash,
chainId,
};
}

export class MockProvider implements MetaMaskProvider {
request = jest.fn();
}

/**
* Create a wallet instance.
*/
export function createWallet() {
return new MetaMaskSnapWallet(new MockProvider());
}

/**
* Mock the wallet init method.
*
* @param params
* @param params.install - The return value of the installIfNot method.
* @param params.currentNetwork - The return value of the getCurrentNetwork method.
* @param params.address - The address of the account.
* @returns The spy objects.
*/
export function mockWalletInit({
install = true,
currentNetwork = SepoliaNetwork,
address = '0x04882a372da3dfe1c53170ad75893832469bf87b62b13e84662565c4a88f25cd',
}: {
install?: boolean;
currentNetwork?: Network;
address?: string;
}) {
const installSpy = jest.spyOn(MetaMaskSnap.prototype, 'installIfNot');
const getCurrentNetworkSpy = jest.spyOn(MetaMaskSnap.prototype, 'getCurrentNetwork');
const recoverDefaultAccountSpy = jest.spyOn(MetaMaskSnap.prototype, 'recoverDefaultAccount');
const initSpy = jest.spyOn(MetaMaskSnapWallet.prototype, 'init');

installSpy.mockResolvedValue(install);
getCurrentNetworkSpy.mockResolvedValue(currentNetwork);
recoverDefaultAccountSpy.mockResolvedValue(generateAccount({ address }));

return {
initSpy,
installSpy,
getCurrentNetworkSpy,
recoverDefaultAccountSpy,
};
}
36 changes: 28 additions & 8 deletions packages/get-starknet/src/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,43 @@ export class MetaMaskAccount extends Account {

async execute(
calls: AllowArray<Call>,
// ABIs is deprecated and will be removed in the future
abisOrTransactionsDetail?: Abi[] | InvocationsDetails,
transactionsDetail?: InvocationsDetails,
details?: InvocationsDetails,
): Promise<InvokeFunctionResponse> {
if (!transactionsDetail) {
return this.#snap.execute(this.#address, calls, undefined, abisOrTransactionsDetail as InvocationsDetails);
// if abisOrTransactionsDetail is an array, we assume it's an array of ABIs
// otherwise, we assume it's an InvocationsDetails object
if (Array.isArray(abisOrTransactionsDetail)) {
return this.#snap.execute({
address: this.#address,
calls,
details,
abis: abisOrTransactionsDetail,
});
}
return this.#snap.execute(this.#address, calls, abisOrTransactionsDetail as Abi[], transactionsDetail);
return this.#snap.execute({
address: this.#address,
calls,
details: abisOrTransactionsDetail as unknown as InvocationsDetails,
});
}

async signMessage(typedData: TypedData): Promise<Signature> {
return this.#snap.signMessage(typedData, true, this.#address);
async signMessage(typedDataMessage: TypedData): Promise<Signature> {
return this.#snap.signMessage({
typedDataMessage,
address: this.#address,
enableAuthorize: true,
});
}

async declare(
contractPayload: DeclareContractPayload,
transactionsDetails?: InvocationsDetails,
invocationsDetails?: InvocationsDetails,
): Promise<DeclareContractResponse> {
return this.#snap.declare(this.#address, contractPayload, transactionsDetails);
return this.#snap.declare({
senderAddress: this.#address,
contractPayload,
invocationsDetails,
});
}
}
22 changes: 22 additions & 0 deletions packages/get-starknet/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export enum RpcMethod {
WalletSwitchStarknetChain = 'wallet_switchStarknetChain',
WalletSupportedSpecs = 'wallet_supportedSpecs',
WalletDeploymentData = 'wallet_deploymentData',
WalletSupportedWalletApi = 'wallet_supportedWalletApi',
WalletRequestAccounts = 'wallet_requestAccounts',
WalletRequestChainId = 'wallet_requestChainId',
WalletAddInvokeTransaction = 'wallet_addInvokeTransaction',
WalletAddDeclareTransaction = 'wallet_addDeclareTransaction',
WalletWatchAsset = 'wallet_watchAsset',
WalletSignTypedData = 'wallet_signTypedData',
WalletGetPermissions = 'wallet_getPermissions',
}

export const WalletIconMetaData = `data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMTIiIGhlaWdodD0iMTg5IiB2aWV3Qm94PSIwIDAgMjEyIDE4OSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cG9seWdvbiBmaWxsPSIjQ0RCREIyIiBwb2ludHM9IjYwLjc1IDE3My4yNSA4OC4zMTMgMTgwLjU2MyA4OC4zMTMgMTcxIDkwLjU2MyAxNjguNzUgMTA2LjMxMyAxNjguNzUgMTA2LjMxMyAxODAgMTA2LjMxMyAxODcuODc1IDg5LjQzOCAxODcuODc1IDY4LjYyNSAxNzguODc1Ii8+PHBvbHlnb24gZmlsbD0iI0NEQkRCMiIgcG9pbnRzPSIxMDUuNzUgMTczLjI1IDEzMi43NSAxODAuNTYzIDEzMi43NSAxNzEgMTM1IDE2OC43NSAxNTAuNzUgMTY4Ljc1IDE1MC43NSAxODAgMTUwLjc1IDE4Ny44NzUgMTMzLjg3NSAxODcuODc1IDExMy4wNjMgMTc4Ljg3NSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMjU2LjUgMCkiLz48cG9seWdvbiBmaWxsPSIjMzkzOTM5IiBwb2ludHM9IjkwLjU2MyAxNTIuNDM4IDg4LjMxMyAxNzEgOTEuMTI1IDE2OC43NSAxMjAuMzc1IDE2OC43NSAxMjMuNzUgMTcxIDEyMS41IDE1Mi40MzggMTE3IDE0OS42MjUgOTQuNSAxNTAuMTg4Ii8+PHBvbHlnb24gZmlsbD0iI0Y4OUMzNSIgcG9pbnRzPSI3NS4zNzUgMjcgODguODc1IDU4LjUgOTUuMDYzIDE1MC4xODggMTE3IDE1MC4xODggMTIzLjc1IDU4LjUgMTM2LjEyNSAyNyIvPjxwb2x5Z29uIGZpbGw9IiNGODlEMzUiIHBvaW50cz0iMTYuMzEzIDk2LjE4OCAuNTYzIDE0MS43NSAzOS45MzggMTM5LjUgNjUuMjUgMTM5LjUgNjUuMjUgMTE5LjgxMyA2NC4xMjUgNzkuMzEzIDU4LjUgODMuODEzIi8+PHBvbHlnb24gZmlsbD0iI0Q4N0MzMCIgcG9pbnRzPSI0Ni4xMjUgMTAxLjI1IDkyLjI1IDEwMi4zNzUgODcuMTg4IDEyNiA2NS4yNSAxMjAuMzc1Ii8+PHBvbHlnb24gZmlsbD0iI0VBOEQzQSIgcG9pbnRzPSI0Ni4xMjUgMTAxLjgxMyA2NS4yNSAxMTkuODEzIDY1LjI1IDEzNy44MTMiLz48cG9seWdvbiBmaWxsPSIjRjg5RDM1IiBwb2ludHM9IjY1LjI1IDEyMC4zNzUgODcuNzUgMTI2IDk1LjA2MyAxNTAuMTg4IDkwIDE1MyA2NS4yNSAxMzguMzc1Ii8+PHBvbHlnb24gZmlsbD0iI0VCOEYzNSIgcG9pbnRzPSI2NS4yNSAxMzguMzc1IDYwLjc1IDE3My4yNSA5MC41NjMgMTUyLjQzOCIvPjxwb2x5Z29uIGZpbGw9IiNFQThFM0EiIHBvaW50cz0iOTIuMjUgMTAyLjM3NSA5NS4wNjMgMTUwLjE4OCA4Ni42MjUgMTI1LjcxOSIvPjxwb2x5Z29uIGZpbGw9IiNEODdDMzAiIHBvaW50cz0iMzkuMzc1IDEzOC45MzggNjUuMjUgMTM4LjM3NSA2MC43NSAxNzMuMjUiLz48cG9seWdvbiBmaWxsPSIjRUI4RjM1IiBwb2ludHM9IjEyLjkzOCAxODguNDM4IDYwLjc1IDE3My4yNSAzOS4zNzUgMTM4LjkzOCAuNTYzIDE0MS43NSIvPjxwb2x5Z29uIGZpbGw9IiNFODgyMUUiIHBvaW50cz0iODguODc1IDU4LjUgNjQuNjg4IDc4Ljc1IDQ2LjEyNSAxMDEuMjUgOTIuMjUgMTAyLjkzOCIvPjxwb2x5Z29uIGZpbGw9IiNERkNFQzMiIHBvaW50cz0iNjAuNzUgMTczLjI1IDkwLjU2MyAxNTIuNDM4IDg4LjMxMyAxNzAuNDM4IDg4LjMxMyAxODAuNTYzIDY4LjA2MyAxNzYuNjI1Ii8+PHBvbHlnb24gZmlsbD0iI0RGQ0VDMyIgcG9pbnRzPSIxMjEuNSAxNzMuMjUgMTUwLjc1IDE1Mi40MzggMTQ4LjUgMTcwLjQzOCAxNDguNSAxODAuNTYzIDEyOC4yNSAxNzYuNjI1IiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgMSAyNzIuMjUgMCkiLz48cG9seWdvbiBmaWxsPSIjMzkzOTM5IiBwb2ludHM9IjcwLjMxMyAxMTIuNSA2NC4xMjUgMTI1LjQzOCA4Ni4wNjMgMTE5LjgxMyIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMTUwLjE4OCAwKSIvPjxwb2x5Z29uIGZpbGw9IiNFODhGMzUiIHBvaW50cz0iMTIuMzc1IC41NjMgODguODc1IDU4LjUgNzUuOTM4IDI3Ii8+PHBhdGggZmlsbD0iIzhFNUEzMCIgZD0iTTEyLjM3NTAwMDIsMC41NjI1MDAwMDggTDIuMjUwMDAwMDMsMzEuNTAwMDAwNSBMNy44NzUwMDAxMiw2NS4yNTAwMDEgTDMuOTM3NTAwMDYsNjcuNTAwMDAxIEw5LjU2MjUwMDE0LDcyLjU2MjUgTDUuMDYyNTAwMDgsNzYuNTAwMDAxMSBMMTEuMjUsODIuMTI1MDAxMiBMNy4zMTI1MDAxMSw4NS41MDAwMDEzIEwxNi4zMTI1MDAyLDk2Ljc1MDAwMTQgTDU4LjUwMDAwMDksODMuODEyNTAxMiBDNzkuMTI1MDAxMiw2Ny4zMTI1MDA0IDg5LjI1MDAwMTMsNTguODc1MDAwMyA4OC44NzUwMDEzLDU4LjUwMDAwMDkgQzg4LjUwMDAwMTMsNTguMTI1MDAwOSA2My4wMDAwMDA5LDM4LjgxMjUwMDYgMTIuMzc1MDAwMiwwLjU2MjUwMDAwOCBaIi8+PGcgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMjExLjUgMCkiPjxwb2x5Z29uIGZpbGw9IiNGODlEMzUiIHBvaW50cz0iMTYuMzEzIDk2LjE4OCAuNTYzIDE0MS43NSAzOS45MzggMTM5LjUgNjUuMjUgMTM5LjUgNjUuMjUgMTE5LjgxMyA2NC4xMjUgNzkuMzEzIDU4LjUgODMuODEzIi8+PHBvbHlnb24gZmlsbD0iI0Q4N0MzMCIgcG9pbnRzPSI0Ni4xMjUgMTAxLjI1IDkyLjI1IDEwMi4zNzUgODcuMTg4IDEyNiA2NS4yNSAxMjAuMzc1Ii8+PHBvbHlnb24gZmlsbD0iI0VBOEQzQSIgcG9pbnRzPSI0Ni4xMjUgMTAxLjgxMyA2NS4yNSAxMTkuODEzIDY1LjI1IDEzNy44MTMiLz48cG9seWdvbiBmaWxsPSIjRjg5RDM1IiBwb2ludHM9IjY1LjI1IDEyMC4zNzUgODcuNzUgMTI2IDk1LjA2MyAxNTAuMTg4IDkwIDE1MyA2NS4yNSAxMzguMzc1Ii8+PHBvbHlnb24gZmlsbD0iI0VCOEYzNSIgcG9pbnRzPSI2NS4yNSAxMzguMzc1IDYwLjc1IDE3My4yNSA5MCAxNTMiLz48cG9seWdvbiBmaWxsPSIjRUE4RTNBIiBwb2ludHM9IjkyLjI1IDEwMi4zNzUgOTUuMDYzIDE1MC4xODggODYuNjI1IDEyNS43MTkiLz48cG9seWdvbiBmaWxsPSIjRDg3QzMwIiBwb2ludHM9IjM5LjM3NSAxMzguOTM4IDY1LjI1IDEzOC4zNzUgNjAuNzUgMTczLjI1Ii8+PHBvbHlnb24gZmlsbD0iI0VCOEYzNSIgcG9pbnRzPSIxMi45MzggMTg4LjQzOCA2MC43NSAxNzMuMjUgMzkuMzc1IDEzOC45MzggLjU2MyAxNDEuNzUiLz48cG9seWdvbiBmaWxsPSIjRTg4MjFFIiBwb2ludHM9Ijg4Ljg3NSA1OC41IDY0LjY4OCA3OC43NSA0Ni4xMjUgMTAxLjI1IDkyLjI1IDEwMi45MzgiLz48cG9seWdvbiBmaWxsPSIjMzkzOTM5IiBwb2ludHM9IjcwLjMxMyAxMTIuNSA2NC4xMjUgMTI1LjQzOCA4Ni4wNjMgMTE5LjgxMyIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMTUwLjE4OCAwKSIvPjxwb2x5Z29uIGZpbGw9IiNFODhGMzUiIHBvaW50cz0iMTIuMzc1IC41NjMgODguODc1IDU4LjUgNzUuOTM4IDI3Ii8+PHBhdGggZmlsbD0iIzhFNUEzMCIgZD0iTTEyLjM3NTAwMDIsMC41NjI1MDAwMDggTDIuMjUwMDAwMDMsMzEuNTAwMDAwNSBMNy44NzUwMDAxMiw2NS4yNTAwMDEgTDMuOTM3NTAwMDYsNjcuNTAwMDAxIEw5LjU2MjUwMDE0LDcyLjU2MjUgTDUuMDYyNTAwMDgsNzYuNTAwMDAxMSBMMTEuMjUsODIuMTI1MDAxMiBMNy4zMTI1MDAxMSw4NS41MDAwMDEzIEwxNi4zMTI1MDAyLDk2Ljc1MDAwMTQgTDU4LjUwMDAwMDksODMuODEyNTAxMiBDNzkuMTI1MDAxMiw2Ny4zMTI1MDA0IDg5LjI1MDAwMTMsNTguODc1MDAwMyA4OC44NzUwMDEzLDU4LjUwMDAwMDkgQzg4LjUwMDAwMTMsNTguMTI1MDAwOSA2My4wMDAwMDA5LDM4LjgxMjUwMDYgMTIuMzc1MDAwMiwwLjU2MjUwMDAwOCBaIi8+PC9nPjwvZz48L3N2Zz4=`;

// The supported RPC version should be update base on the Provider.
// With Provider `Alchemy`, it is 0.7
export const SupportedStarknetSpecVersion = ['0.7'];

// The wallet API support is 0.7.2 but the RPC specs requests xx.yy. Hence we skip the last digits.
export const SupportedWalletApi = ['0.7'];
48 changes: 48 additions & 0 deletions packages/get-starknet/src/rpcs/add-declare.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { mockWalletInit, createWallet, generateAccount } from '../__tests__/helper';
import { MetaMaskSnap } from '../snap';
import { formatDeclareTransaction } from '../utils/formatter';
import { WalletAddDeclareTransaction } from './add-declare';

/* eslint-disable @typescript-eslint/naming-convention */
describe('WalletAddDeclareTransaction', () => {
it('submits a declare transaction and returns transaction hash', async () => {
const params = {
compiled_class_hash: '0xcompiledClassHash',
class_hash: '0xclassHash',
contract_class: {
sierra_program: ['0x1', '0x2'],
contract_class_version: '1.0.0',
entry_points_by_type: {
CONSTRUCTOR: [{ selector: '0xconstructorSelector', function_idx: 0 }],
EXTERNAL: [{ selector: '0xexternalSelector', function_idx: 1 }],
L1_HANDLER: [{ selector: '0xhandlerSelector', function_idx: 2 }],
},
abi: '[{"type":"function","name":"transfer"}]', // passing as a string (no parsing)
},
};

const formattedParams = formatDeclareTransaction(params);
const expectedResult = {
transaction_hash: '0x12345abcd',
class_hash: '0x000',
};

const wallet = createWallet();
const account = generateAccount({});
mockWalletInit({ address: account.address });

const declareSpy = jest.spyOn(MetaMaskSnap.prototype, 'declare');
declareSpy.mockResolvedValue(expectedResult);

const walletAddDeclareTransaction = new WalletAddDeclareTransaction(wallet);
const result = await walletAddDeclareTransaction.execute(params);

expect(result).toStrictEqual(expectedResult);
expect(declareSpy).toHaveBeenCalledWith({
senderAddress: account.address,
contractPayload: formattedParams,
chainId: wallet.chainId,
});
});
});
/* eslint-enable @typescript-eslint/naming-convention */
18 changes: 18 additions & 0 deletions packages/get-starknet/src/rpcs/add-declare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { RpcTypeToMessageMap } from 'get-starknet-core';

import { formatDeclareTransaction } from '../utils/formatter';
import { StarknetWalletRpc } from '../utils/rpc';

export type WalletAddDeclareTransactionMethod = 'wallet_addDeclareTransaction';
type Params = RpcTypeToMessageMap[WalletAddDeclareTransactionMethod]['params'];
type Result = RpcTypeToMessageMap[WalletAddDeclareTransactionMethod]['result'];

export class WalletAddDeclareTransaction extends StarknetWalletRpc {
async handleRequest(params: Params): Promise<Result> {
return await this.snap.declare({
senderAddress: this.wallet.selectedAddress,
contractPayload: formatDeclareTransaction(params),
chainId: this.wallet.chainId,
});
}
}
Loading

0 comments on commit 8bf8463

Please sign in to comment.