starknet-modular-account

This project is an implementation of a Modular Account for Starknet. It includes a reference account; a set of extensible/reusable components to build your own tool; modules, including a sessionkey validator; a set of SDKs based on starknet.js to use the account in a Dapp or a signer; tests to demonstrate how to use the account and a documentation.

⚠️ ⚠️ ⚠️ this project is very much a work-in-progress and has not been audited yet ⚠️ ⚠️ ⚠️

Why Develop Another Smart Account?

Starknet has been a place of innovation for Smart Accounts since the very start. Thank to actors like Starkware, Openzeppelin, Argent, Ledger, Cartridge, Braavos or Equilibrium, the user experience has no equivalent. However, implementations are not always compatible and it is hard for teams that need specific features to get it from even one provider or to develop it.

Meanwhile, the Smart Account Ecosystem on Ethereum has grown and a number of ideas have shown up that could be implemented on Starknet. starknet-modular-account is an extensible account that allow developers to write modules for specific use cases. You should see it as an experiment or a wish to get:

  • extensibility: we could add features to Starknet that we can already find with Ethereum Smart Account and Multisig like Safe, Kernel or the Alchemy accounts
  • interoperability: we could develop modules with clean interfaces that would be re-used by widespread accounts
  • security: we could audit components not large account code base
  • ease of use: we could reference a module registry that accounts providers would reference and user understand

Doing it as a community project would help everybody to get those feature now if they want...

License

This project is licensed under the MIT License

Concepts

Table of Contents

  • Accounts and the Modular Account
  • Modules
  • Accounts and the Modular Account

    The starknet modular account is a configurable account that provides standard features and delegates others to some modules of choice. For instance, the account enables users to add and remove modules; it allows to execute a method of a module. On the other hand, the account delegates the validation of transactions to modules. This account/module split simplifies the development of specific features; it provides an account that can easily evolve to match the user requirements and be extended...

    This document presents the different aspects and interfaces of the modular account as well as modules. It introduces how the account works in general and how the modular account is different. This document is useful for developing new modules. It also provides hints about accessing and managing the modular account from an application.

    Account Interface

    Abstract accounts or smart accounts are key components of the Starknet protocol. On most blockchains, the source of a transaction is a public key, i.e. the counterpart of your keys that remain secret. In the case of Starknet, the source of a transaction is always an account address. This leads to an immediate question that is "How do you create an account?". As you can guess, you need to run a transaction create an account. In some cases, you will not even have an account to proceed. If this question is out of the scope of this document, this answer to that question is pretty "smart" and we encourage you to find it.

    So, except for the account creation that relies on a specific syscall, Starknet interacts with the account both before and during the execution of a transaction. How the account behaves is not part of the protocol which leaves a lot of freedom to developers. To work correctly, however, Starknet requires the account to implement the __validate__ and __execute__ entrypoints in an account contract. To say it otherwise, that is the interface that does the account.

    The account interface as described in both SNIP-6 and the comments on this thread. The code below provides the standard definition of a Starknet account! A Starknet account is a Starknet contract that implements the following interface:

    #![allow(unused)]
    fn main() {
    struct Call {
        to: ContractAddress,
        selector: felt252,
        calldata: Array<felt252>
    }
    
    /// @title SRC-6 Standard Account
    trait ISRC6 {
        /// @notice Execute a transaction through the account
        /// @param calls The list of calls to execute
        /// @return The list of each call's serialized return value
        fn __execute__(calls: Array<Call>) -> Array<Span<felt252>>;
    
        /// @notice Assert whether the transaction is valid to be executed
        /// @param calls The list of calls to execute
        /// @return The string 'VALID' represented as felt when is valid
        fn __validate__(calls: Array<Call>) -> felt252;
    
        /// @notice Assert whether a given signature for a given hash is valid
        /// @param hash The hash of the data
        /// @param signature The signature to validate
        /// @return The string 'VALID' represented as felt when the signature is valid
        fn is_valid_signature(hash: Array<felt252>, signature: Array<felt252>) -> felt252;
    }
    }

    It is very simple both to understand and to conform to the account development specification. As a result, an account can be develop that does things that you would not expect from a regular chain like:

    • blindly validate all the transactions that are submitted. This scenario that we call the Yasager or Yeasayer is a very interesting to code; at least to learn more about accounts
    • execute something very different from what the transaction requests. For instance we could store a signature that would allow to execute the requested transaction later on a different call and execute nothing

    The Modular Account

    The starknet modular account is an implementation of an account so that you can develop and register a module that are triggered from inside the __validate__ and/or __execute__ entrypoints. The benefit of this approach is that you can develop some code that change the behavior of the account without rewriting a whole account.

    There are 2 types of modules for the starknet modular account:

    • Validator Modules that are triggered when validating a transaction
    • Executor Modules that are triggered when executing a transaction

    Note: Only Validator Modules are implemented for now. Executor Modules are part of the Modular Account roadmap.

    Validator and Core Validator Modules

    A validator module is a class that implements the following interface and can be used by the account to delegate the transaction validation:

    #![allow(unused)]
    fn main() {
    /// @title Validator Module Interface
    trait IValidator {
        fn validate(calls: Array<Call>) -> felt252;
    }
    }

    As you can guess Validator modules "replace" the __validate__ entrypoint of the account:

    Note: __validate__ is a reserved entrypoint name for the account and the cairo compiler treat them differently. That is why the module entrypoint are named validate and not __validate__ but that should have been the case.

    A Validator is a Core Validator if it also implements the ICoreValidator interface:

    #![allow(unused)]
    fn main() {
    /// @title Core Validator Module Interface
    trait ICoreValidator<TState> {
        fn is_valid_signature(self: @TState, hash: Array<felt252>, signature: Array<felt252>) -> felt252;
        fn initialize(ref self: TState, public_key: Array<felt252>);
    }
    }

    The core validator has some enhanced features, including the ability to check a signature from another validator. This can be leverage to support and verify offchain. This is possible with the is_valid_signature function that can be used, not only to check transactions but also signed messages. The initialize function is used to setup the core module configuration at the installation time.

    When installing the modular account, not only the public key of the signer is required like on most account but the Core validator module class hash(*) is also mandatory. So "the" Core validator module is a module, i.e. a class, that contains all the validation logic for the account, i.e. the __validate__ and the is_valid_signature functions.

    For now, the only core validator module available is the stark module; it:

    • computes the transaction into a a pedersen hash
    • validate the transaction signature with the stark curve

    That is why the modular account constructor is the following:

    #![allow(unused)]
    fn main() {
    #[constructor]
    fn constructor(ref self: ContractState, core_validator: felt252, public_key: Array<felt252>) {
        self.account.initializer(core_validator, public_key);
    }
    }

    (*) the core_validator is a felt252 and not a ClassHash type due to some technical constraints on the validation of the account deployment. However the external representation of a ClassHash is the same as the one from a felt252.

    Note: the public_key is an Array so that it can be used to support private keys that are larger than the felt232. In the case of the Stark Curve, we simply put the public key in an array of one

    Validator Modules and Prefix Call

    So if there is a core validator module that is used by default by the modular account, other validator modules can also be used in addition to it. In order to be triggered, a number of conditions must be met:

    • the validator module class must be declared to the network
    • the validator module class has must be added to the account with the module management API as described in Module Management
    • some metadata in the form of a prefix call(**) must be added to the transaction

    Assuming the module is declared in the network and installed in the modular account, adding a prefix will trigger it. But what is a prefix? Let's say a transaction is a set of calls like this:

    [call1, call2, ..., callN]
    

    A prefixCall with the following structure has to be created:

    const prefixCall: Call = {
      contractAddress: accountAddress,
      // selector!("__module_validate__")
      entrypoint: moduleEntrypointSelector,
      calldata: [
        moduleClassHash,
        ...otherValidatorArgs,
      ]
    }
    

    And the transaction that will be requested will actually be the following:

    [prefixCall, call1, call2, ..., callN]
    

    As a matter of fact the prefixCall does not modify the execution of the transaction that will be made of the other calls from 1 to N. Instead, it modifies the behavior of the account __validate__ entrypoint that will check the validation is compliant with the module requirements. In this call, the following values are used:

    • accountAddress is the account address. If you use another address the call will fail
    • moduleEntrypointSelector is the sn_keccak of __module_validate__ so it is a fixed value
    • moduleClassHash that is passed as the first parameter of the calldata is the module class hash taht is being used
    • otherValidatorArgs is an array of felt252 that can be used to pass some parameters to the module so that it can actually validate the transactions. For instance in the case of a Yasager module, it could be that no other parameters are used.

    (**) As discussed in the roadmap, we are exploring some changes so that the validator module does not need to use a prefix call. However the SDKs are masking the complexity associated with generating that call and there is not guarranty for now that this change that will land in the signature will actually work.

    Executor Modules

    The executor module are implemented for now. They will rely on the same usage of a prefix call with a moduleEntrypointSelector that is the sn_keccak of __module_execute__.

    Additional Account Interfaces

    The modular account provides another set of interfaces to interact with modules. The code below shows the interface definition:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IModule<TState> {
        fn __module_validate__(self: @TState, calldata: Array<felt252>);
        fn __module_execute__(self: @TState, calldata: Array<felt252>);
        fn add_module(ref self: TState, class_hash: ClassHash);
        fn remove_module(ref self: TState, class_hash: ClassHash);
        fn update_core_module(ref self: TState, class_hash: ClassHash);
        fn get_core_module(self: @TState) -> ClassHash;
        fn is_module(self: @TState, class_hash: ClassHash) -> bool;
        fn call_on_module(self: @TState, class_hash: ClassHash, call: Call) -> Array<felt252>;
        fn execute_on_module(ref self: TState, class_hash: ClassHash, call: Call) -> Array<felt252>;
    }
    }

    Module Management

    The account provides 2 sets of interfaces to manage the core module and other modules:

    • get_core_module and update_core_module enables to check the current core module and to change it for another module.
    • add_module, remove_module and is_module enables to add, remove and check the account modules that are not the core validator module

    Note: update_core_module is very risky and probably contains flows right now

    Module Configuration

    Module configuration depends on the module and requires you call the module entrypoint from the account. The account provides 2 helper functions that are used by the SDKs to grant those accesses. The functions are:

    • call_on_module a view function that allows interactions with the view functions of a module
    • execute_on_module that can be used to run transactions on the module from
    • the account (and only from it).

    Prefix functions

    __module_validate__ and __module_execute__ are functions that do nothing. They are part of the account so that when you prefix the calls the transaction does not fail because Starknet nodes checks for the existence of an entrypoint as part of the transaction validation process.

    Upgrade and Backward Compatibility

    The modular account implements the openzeppelin Upgradeable interface that is the following:

    #![allow(unused)]
    fn main() {
    fn upgrade(ref self: ContractState, new_class_hash: ClassHash)
    }

    It enables both to upgrade accounts and to move to another version of the account like the one from openzeppelin, argent or braavo. Be Careful moving to another account requires you update the internal state of the account so that it works correctly and upgrading without updating the state will for sure break it in an IRREVERSIBLE way. The experiments/starknet-bootstrap-account provides some the basic principle that can be used to perform those migrations but it needs to be developed and battle-tested. We do not know if the reverse, i.e. moving from another account to the

    Modules

    The project comes with 2 validator modules:

    • The stark validator that can be used as a core validator for the modular account. This relies on a pedersen-based hash of the transaction and the stark curve signature verification primitives to validate transactions.
    • The sessionkey validator that requires an access to the core validator. The sessionkey validator requires an offchain authorisation to be granted by the account signer and allows a 3rd party to run a limited number of transactions with the account.

    Validator Interfaces

    As mentioned earlier, validators must implement the following interface to work properly. How the implementation is done depends on the requirements...

    #![allow(unused)]
    fn main() {
    /// @title Validator Module Interface
    trait IValidator {
        fn validate(calls: Array<Call>) -> felt252;
    }
    }

    In addition, if the validator is a Core validator, it must also implement the following interface:

    #![allow(unused)]
    fn main() {
    /// @title Core Validator Module Interface
    trait ICoreValidator<TState> {
        fn is_valid_signature(self: @TState, hash: Array<felt252>, signature: Array<felt252>) -> felt252;
        fn initialize(ref self: TState, public_key: Array<felt252>);
    }
    }

    Validator Configuration

    In order to allow calls and execution on the account with the entrypoints from the module, the module must also implement the following interface. The call and the execute functions map the input and output respectively between the call_on_module and execute_on_module on the account and the view functions and the external functions of the module on the other side.

    #![allow(unused)]
    fn main() {
    pub trait IConfigure {
        fn call(self: @TState, call: Call) -> Array<felt252>;
        fn execute(ref self: TState, call: Call) -> Array<felt252>;
    }
    }

    As a result, to provide an access to the configuration of a module, not only use must add the required entrypoint in the module but you must also provide the mapping in one of these 2 functions.

    Validator Entrypoints

    The entrypoints associated with each module are specific to the module. They can be whatever is required by the module. Below are the entrypoints:

    • For the stark validator
    #![allow(unused)]
    fn main() {
    pub trait IPublicKeys{
        fn add_public_key(ref self: ContractState, new_public_key: felt252);
        fn get_public_keys(self: @ContractState) -> Array<felt252>;
        fn get_threshold(self: @ContractState) -> u8;
        fn remove_public_key(ref self: ContractState, old_public_key: felt252);
        fn set_threshold(ref self: ContractState, new_threshold: u8);
    }
    }
    • For the Eth validator
    #![allow(unused)]
    fn main() {
    pub trait IPublicKey<TState> {
        fn set_public_key(ref self: TState, new_public_key: EthPublicKey);
        fn get_public_key(self: @TState) -> EthPublicKey;
    }
    }
    • For the sessionkey validator
    #![allow(unused)]
    fn main() {
    pub trait IDisableSessionKey {
        fn disable_session_key(ref self: ContractState, sessionkey: felt252);
        fn is_disabled_session_key(self: @ContractState, sessionkey: felt252);
    }
    }

    Using SDKs

    starknet-modular-account comes with 2 SDKs that leverage starknet.js.

    • @0xknwn/starknet-modular-account provides the SmartrAccount class that extends starknet.js account to support multiple signers and helps to manage modules. It also provides the AccountModuleInterface that should be used by module SDKs.
    • @0xknwn/starknet-module-sessionkey provides the SessionKeyModule that implements the AccountModuleInterface as well as tools to configure the sessionkey module, including the PolicyManager and the PolicyGrantor classes.
    • @0xknwn/starknet-module provides the EthModule that implements the AccountModuleInterface.

    In addition, the project provides another SDK called @0xknwn/starknet-test-helpers that can be used to create helper classes outside of this repository. It is used to demonstrate the 2 main SDKs.

    This section provides a set of tutorials about how to use the account and modules. If you want to understand how modules are working internally, you should check Modules Internals.

    Installing SDKs

    SDKs are provided as NPM packages for an easy use. If you plan to use them, you should have a Javascript or a Typescript project configured,

    Create a typescript project

    If not already done the script below shows how to create a minimalistic typescript project:

    mkdir documentation-examples && cd documentation-examples
    npm init -y
    git init
    npm install typescript --save-dev
    npx tsc --init
    

    Obviously you might want to adapt the script to your requirements and that is out of the scope of this documentation...

    The rest of the documentation assume typescript is used and the javascript file are generated in the dist directory. To change the default settings edit the tsconfig.json and change the following:

    • set the outDir property to be dist
    • change the target to be es2020 or later. That is because we intensively use bigint in the project and it was not supported with es2016

    This is an example of a working tsconfig.json:

    {
      "compilerOptions": {
        "target": "esnext",
        "module": "commonjs",
        "outDir": "./dist/",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
      }
    }
    

    Then create a simple src directory with a index.ts file in it:

    mkdir -p src
    echo 'console.log("success");' > src/index.ts
    

    To transpile typescript in javascript, run:

    npx tsc --build
    

    To run the output, run:

    node dist/index.js
    

    Install the Modular Account SDK

    The modular account SDK is named @0xknwn/starknet-modular-account. To add it to your project, run the command below:

    npm install --save @0xknwn/starknet-modular-account
    
    npm install --save starknet@6.8.0
    

    Install the SessionKey Module SDK

    If you plan to use the sessionkey module, you will need the @0xknwn/starknet-module-sessionkey SDK but very likely also the @0xknwn/starknet-modular-account SDK. To install the 2 packages, run the command below:

    npm install --save \
      @0xknwn/starknet-modular-account \
      @0xknwn/starknet-module-sessionkey
    
    npm install --save starknet@6.8.0
    

    Deploying the Modular Account

    Declare a the SmartrAccount and StarkValidator classes

    If you are working on a network that does not have the classes already declared, you will need to declare them. The modular account main SDK, aka @0xknwn/starknet-modular-account contains class and a helper function named declareClass to declare the class to the network. To use it, you need to pass:

    • A starknet.js Account as a first parameter
    • The name of the class to declare as the 2nd parameter. They are SmartrAccount for the modular account and StarkValidator for the Stark Core Validator

    Below is an example of a script that declares the 2 classes.

    // file src/01-declare-class.ts
    import { RpcProvider, Account } from "starknet";
    import { declareClass } from "@0xknwn/starknet-modular-account";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ozAccountAddress =
      "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691";
    const ozPrivateKey = "0x71d7bb07b9a64f6f78ac4c816aff4da9";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const account = new Account(provider, ozAccountAddress, ozPrivateKey);
    
      const { classHash: smartrAccountClassHash } = await declareClass(
        account,
        "SmartrAccount"
      );
      console.log("smartrAccount class hash:", smartrAccountClassHash);
    
      const { classHash: starkValidatorClassHash } = await declareClass(
        account,
        "StarkValidator"
      );
      console.log("starkValidator class hash:", starkValidatorClassHash);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Note: To declare the class, the account you use must be loaded with ETH.

    Assuming you have named the script src/01-declare-class.ts, to transpile it and run it, use the script below:

    npx tsc --build
    
    node dist/01-declare-class.js
    

    The output should return the hashes for the 2 classes.

    Verify the SmartrAccount and StarkValidator class hash

    The 2 class hashes do NOT depend on the deployment or the network. So you can find them at any time with the classHash helper that comes with the SDK. The script below shows how to use that function:

    // file src/01-check-class.ts
    import { classHash } from "@0xknwn/starknet-modular-account";
    
    console.log("smartrAccount class hash:", classHash("SmartrAccount"));
    console.log("starkValidator class hash:", classHash("StarkValidator"));
    

    Assuming you have named the script src/01-check-class.ts, you can transpile and run it:

    npx tsc --build
    
    node dist/01-check-class.js
    

    Charge ETH to the SmartrAccount Address to deploy it

    Here again, the SDK provides a helper function called deployAccount to help with the deployment of the modular account. Before you move forward with the account, you must compute the account address with accountAddress and send ETH to it. To proceed, create a file named src/01-load-eth.ts with this content:

    // file src/01-load-eth.ts
    import {
      RpcProvider,
      Account,
      Signer,
      Contract,
      cairo,
      CallData,
    } from "starknet";
    import {
      accountAddress,
      classHash,
      SmartrAccountABI,
    } from "@0xknwn/starknet-modular-account";
    import { ABI as ERC20ABI } from "./abi/ERC20";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ozAccountAddress =
      "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691";
    const ozPrivateKey = "0x71d7bb07b9a64f6f78ac4c816aff4da9";
    const smartrAccountPrivateKey = "0x1";
    const ethAddress =
      "0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const account = new Account(provider, ozAccountAddress, ozPrivateKey);
      const smartrSigner = new Signer(smartrAccountPrivateKey);
      const smartrAccountPublicKey = await smartrSigner.getPubKey();
      const starkValidatorClassHash = classHash("StarkValidator");
      const calldata = new CallData(SmartrAccountABI).compile("constructor", {
        core_validator: starkValidatorClassHash,
        public_key: [smartrAccountPublicKey],
      });
      const smartrAccountAddress = accountAddress(
        "SmartrAccount",
        smartrAccountPublicKey,
        calldata
      );
      const ETH = new Contract(ERC20ABI, ethAddress, account);
      const initial_EthTransfer = cairo.uint256(3n * 10n ** 15n);
      const call = ETH.populate("transfer", {
        recipient: smartrAccountAddress,
        amount: initial_EthTransfer,
      });
      const { transaction_hash } = await account.execute(call);
      const output = await account.waitForTransaction(transaction_hash);
      if (!output.isSuccess()) {
        throw new Error("Could not send ETH to the expected address");
      }
      console.log("accountAddress", smartrAccountAddress);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Note: You must create a file abi/ERC20.ts that contains the ABI of an ERC20 in order to call it from a contract.

    Transpile and run the script:

    npx tsc --build
    
    node dist/01-load-eth.js
    

    Deploy the Modular Account

    Now that the address has some ETH on it, you can deploy the account with the deployAccount helper. Create a file named src/01-deploy-account.ts like below:

    // file src/01-deploy-account.ts
    import { RpcProvider, Account, Signer, CallData } from "starknet";
    import {
      accountAddress,
      classHash,
      deployAccount,
      SmartrAccount,
      SmartrAccountABI,
    } from "@0xknwn/starknet-modular-account";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const smartrAccountPrivateKey = "0x1";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const smartrSigner = new Signer(smartrAccountPrivateKey);
      const smartrAccountPublicKey = await smartrSigner.getPubKey();
      const starkValidatorClassHash = classHash("StarkValidator");
      const calldata = new CallData(SmartrAccountABI).compile("constructor", {
        core_validator: starkValidatorClassHash,
        public_key: [smartrAccountPublicKey],
      });
      const smartrAccountAddress = accountAddress(
        "SmartrAccount",
        smartrAccountPublicKey,
        calldata
      );
      const smartrAccount = new SmartrAccount(
        provider,
        smartrAccountAddress,
        smartrAccountPrivateKey
      );
      const address = await deployAccount(
        smartrAccount,
        "SmartrAccount",
        smartrAccountPublicKey,
        calldata
      );
      if (address !== smartrAccountAddress) {
        throw new Error(
          `The account should have been deployed to ${smartrAccountAddress}, instead ${address}`
        );
      }
      console.log("accountAddress", smartrAccountAddress);
      console.log("public key", smartrAccountPublicKey);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/01-deploy-account.js
    

    Using the modular account from the SDK

    You can use rely on the SmartrAccount class to use the account. The script below shows all the requirements to compute the class hash, the address and instantiate the account:

    // file src/01-using-account.ts
    import { RpcProvider, Signer, CallData } from "starknet";
    import {
      accountAddress,
      classHash,
      SmartrAccount,
      SmartrAccountABI,
    } from "@0xknwn/starknet-modular-account";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const smartrAccountPrivateKey = "0x1";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const smartrSigner = new Signer(smartrAccountPrivateKey);
      const smartrAccountPublicKey = await smartrSigner.getPubKey();
      const starkValidatorClassHash = classHash("StarkValidator");
      const calldata = new CallData(SmartrAccountABI).compile("constructor", {
        core_validator: starkValidatorClassHash,
        public_key: [smartrAccountPublicKey],
      });
      const smartrAccountAddress = accountAddress(
        "SmartrAccount",
        smartrAccountPublicKey,
        calldata
      );
      const smartrAccount = new SmartrAccount(
        provider,
        smartrAccountAddress,
        smartrAccountPrivateKey
      );
      console.log("address", smartrAccount.address);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/01-using-account.js
    

    Using the Stark Validator

    The Stark Validator Module can be used as a Core Validator for the account. It is used by default by the modular account in many configuration. In this section of the documentation, you will see how you can use the Moduler Account with the Stark Validator Module as a Core Module.

    Note: This section assumes the SmartrAccount class has been instantiated in the smartrAccount variable as shown in Using the modular account from the SDK. It also assumes the Counter contract that comes with the project has been deploys to the counterAddress and the CounterABI class is available. The 02-setup.ts script that comes with this project ensure those steps are executed.

    Interacting with a Contract

    The starknet modular account SDK provides the SmartrAccount class that extends the starknet.js Account class. As you can see from the script below, using the SmartrAccount is exactly like using the Account class, you can:

    • instantiate the account with an RpcProvider, an address and a Signer or private key
    • use the account in a Contract to call view functions
    • use the execute function of the account to call an external function of a contract. SmartrAccount provides the same methods as Account
    // file src/02-execute-tx.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./02-init";
    import { RpcProvider, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress, smartrAccountPrivateKey } =
        await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/02-execute-tx.js
    

    Interacting with the Stark Validator

    The SmartrAccount class, however, provides more than just the regular Account class. It can interact with functions that are part of the module and not part of the account. In the case of the Stark Validator, those functions are:

    #![allow(unused)]
    fn main() {
    fn get_public_key(self: @TState) -> felt252;
    fn set_public_key(ref self: TState, new_public_key: felt252);
    }

    To execute a function that is part of the module you need:

    • to figure out the stark validator module class hash
    • to check the module is installed on the account. That is something that is setup at the account deployment time
    • to use one of callOnModule for view functions or executeOnModule for running transactions on the SmartrAccount.

    The sections below dig into the details of these operations.

    Getting the stark validator module class hash

    This is something we have already done previously. You can use classHash("StaekValidator") after your imported the classHash function from @0xknwn/starknet-modular-account like below:

    // file src/02-check-class.ts
    import { classHash } from "@0xknwn/starknet-modular-account";
    
    console.log("starkValidator class hash:", classHash("StarkValidator"));
    

    To execute the script, make sure you have deployed the account in the network and run the following commands:

    npx tsc --build
    
    node dist/02-check-class.js
    

    Check the module is installed on the account

    The SmartrAccount provides a method isModule that can be used to know if a module is installed with the account.

    // file src/02-module-installed.ts
    import { SmartrAccount, classHash } from "@0xknwn/starknet-modular-account";
    import { init } from "./02-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const isInstalled = await account.isModule(classHash("StarkValidator"));
      console.log(
        "module",
        classHash("StarkValidator"),
        "is installed",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/02-module-installed.js
    

    Calling views functions in the module

    To execute a view function on the module, we must build the argumemt list with the CallData class. Thwn we can call the callOnModule function from SmartrAccount with the module class hash, the function name and the calldata like below:

    // file src/02-registered-publickeys.ts
    import {
      StarkValidatorABI,
      SmartrAccount,
      classHash,
    } from "@0xknwn/starknet-modular-account";
    import { init } from "./02-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(StarkValidatorABI);
      const calldata = await moduleCallData.compile("get_public_key", {});
      const publickey = await account.callOnModule(
        classHash("StarkValidator"),
        "get_public_key",
        calldata
      );
      console.log("publickey is", `0x${BigInt(publickey[0]).toString(16)}`);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/02-registered-publickey.js
    

    Executing external functions in the module

    To execute an external function on the module, we must build the argumemt list with the CallData class. Then we can call the executeOnModule function from SmartrAccount with the module class hash, the function name and the calldata like below. Here we will register a second public key for the same account:

    // file src/02-add-publickey.ts
    import {
      StarkValidatorABI,
      SmartrAccount,
      classHash,
    } from "@0xknwn/starknet-modular-account";
    import { init } from "./02-init";
    import { CallData, RpcProvider, Signer } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const newAccountPrivateKey = "0x2";
    
    const main = async () => {
      const signer = new Signer(newAccountPrivateKey);
      const newAccountPublicKey = await signer.getPubKey();
      console.log("second account public key", newAccountPublicKey);
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(StarkValidatorABI);
      const calldata = await moduleCallData.compile("set_public_key", {
        new_public_key: newAccountPublicKey,
      });
      const { transaction_hash } = await account.executeOnModule(
        classHash("StarkValidator"),
        "set_public_key",
        calldata
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/02-update-publickey.js
    

    You can re-run the script from the previous example to check the account has two registered public key:

    node dist/02-registered-publickey.js
    

    Interacting with a Contract with the new registered key

    You now can interact with the SmartrAccount with your new private key like below:

    // file src/02-execute-tx-pk2.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./02-init";
    import { RpcProvider, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const newSmartrAccountPrivateKey = "0x2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        newSmartrAccountPrivateKey
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/02-execute-tx-pk2.js
    

    Interacting with the Contract with the SDK Stark Module

    You can use the StarkValidator as a secondary module, even when installed as a Core module. To run a transaction with such a configuration, all you have to do is to call the StarkModule with the account address when creating the SmartrAccount by adding a 4th parameter to the constructor. The script below shows the change:

    // file src/02-execute-tx-pk2-with-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { StarkModule } from "@0xknwn/starknet-module";
    import { init, CounterABI } from "./02-init";
    import { RpcProvider, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const newSmartrAccountPrivateKey = "0x2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress } = await init();
      const module = new StarkModule(accountAddress);
      const account = new SmartrAccount(
        provider,
        accountAddress,
        newSmartrAccountPrivateKey,
        module
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    If you check the transaction, you can see the call is prefixed by a call to __validate_module__ with the account address and StarkValidator class hash as a first parameter. Transpile and run the script:

    npx tsc --build
    
    node dist/02-execute-tx-pk2-with-module.js
    

    Note: The Starkmodule is part of @0xknwn/starknet-module and this SDK as to be installed if you want to interact with the StarkModule as a secondary module.

    Using the Multisig Validator

    When installed with the Multisig Validator Module, the starknet modular account not only can have multiple signers registered but it can also require N of those signers to agree to sign a transaction. This Multisig feature takes place offchain and the SmartrAccount class provides the framework manage several signers on the same account to sign the a transaction. This is what is shown in this section.

    Note 1: This section assumes the SmartrAccount class has been instantiated in the smartrAccount variable as shown in Using the modular account from the SDK. It also assumes the Counter contract that comes with the project has been deploys to the counterAddress and the CounterABI class are available. The 03-setup.ts script that comes with this project ensure those steps are executed.

    Note 2: This multi-signer model has some limits: the exchange of the transaction between signers is not managed by the SDK and requires some synchronization between the actors. In addition, the fact the transaction is a regular transaction that involves the account Nonce generated by the network prevents from using it at a large scale. The starknet modular account can be used to implement more advanced models to workaround those 2 issues.

    Interacting with the Multisig Validator

    The SmartrAccount class, however, provides more than just the regular Account class. It can interact with functions that are part of the module and not part of the account. In the case of the Multisig Validator, those functions are:

    #![allow(unused)]
    fn main() {
    fn get_public_keys(self: @TState) -> Array<felt252>;
    fn add_public_key(ref self: TState, new_public_key: felt252);
    fn remove_public_key(ref self: TState, old_public_key: felt252);
    fn get_threshold(self: @TState) -> u8;
    fn set_threshold(ref self: TState, new_threshold: u8);
    }

    To execute a function that is part of the module you need:

    • to figure out the Multisig Validator module class hash
    • to check the module is installed on the account. That is something that is setup at the account deployment time
    • to use one of callOnModule for view functions or executeOnModule for running transactions on the SmartrAccount.

    The sections below dig into the details of these operations.

    Getting the stark validator module class hash

    This is something we have already done previously. You can use classHash("MultisigValidator") after your imported the classHash function from @0xknwn/starknet-module like below:

    // file src/03-check-class.ts
    import { classHash } from "@0xknwn/starknet-module";
    
    console.log("MultisigValidator class hash:", classHash("MultisigValidator"));
    

    To execute the script, make sure you have deployed the account in the network and run the following commands:

    npx tsc --build
    
    node dist/03-check-class.js
    

    Check the module is installed on the account

    The SmartrAccount provides a method isModule that can be used to know if a module is installed with the account.

    // file src/03-module-installed.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const isInstalled = await account.isModule(classHash("MultisigValidator"));
      console.log(
        "module",
        classHash("MultisigValidator"),
        "is installed",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-module-installed.js
    

    Calling views functions in the module

    To execute a view function on the module, we must build the argumemt list with the CallData class. Thwn we can call the callOnModule function from SmartrAccount with the module class hash, the function name and the calldata like below:

    // file src/03-registered-publickeys.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(MultisigValidatorABI);
      const calldata = moduleCallData.compile("get_public_keys", {});
      const publickeysList = await account.callOnModule(
        moduleClassHash("MultisigValidator"),
        "get_public_keys",
        calldata
      );
      console.log("number of public keys for module", publickeysList.length);
      publickeysList.forEach((publickey, idx) => {
        console.log("publickey #", idx + 1, `0x${publickey.toString(16)}`);
      });
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-registered-publickeys.js
    

    Executing external functions in the module

    To execute an external function on the module, we must build the argumemt list with the CallData class. Then we can call the executeOnModule function from SmartrAccount with the module class hash, the function name and the calldata like below. Here we will register a second public key for the same account:

    // file src/03-add-publickeys.ts
    import {
      SmartrAccountABI,
      SmartrAccount,
    } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { CallData, RpcProvider, Signer, hash, type Call } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const secondAccountPrivateKey = "0x2";
    const thirdAccountPrivateKey = "0x3";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const module_class_hash = moduleClassHash("MultisigValidator");
      const calls: Call[] = [];
      for (const privateKey of [secondAccountPrivateKey, thirdAccountPrivateKey]) {
        const signer = new Signer(privateKey);
        const publicKey = await signer.getPubKey();
        console.log("new account public key", publicKey);
        const moduleCallData = new CallData(MultisigValidatorABI);
        const moduleCalldata = moduleCallData.compile("add_public_key", {
          new_public_key: publicKey,
        });
        const accountCallData = new CallData(SmartrAccountABI);
        const calldata = accountCallData.compile("execute_on_module", {
          class_hash: module_class_hash,
          call: {
            selector: hash.getSelectorFromName("add_public_key"),
            to: accountAddress,
            calldata: moduleCalldata,
          },
        });
        const call: Call = {
          entrypoint: "execute_on_module",
          contractAddress: accountAddress,
          calldata,
        };
        calls.push(call);
      }
      const { transaction_hash } = await account.execute(calls);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-add-publickeys.js
    

    You can re-run the script from the previous example to check the account has two registered public key:

    node dist/03-registered-publickeys.js
    

    The output should look like that:

    number of public keys for module 3
    publickey # 1 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca
    publickey # 2 0x759ca09377679ecd535a81e83039658bf40959283187c654c5416f439403cf5
    publickey # 3 0x411494b501a98abd8262b0da1351e17899a0c4ef23dd2f96fec5ba847310b20
    

    Interacting with a Contract with the new registered key

    You now can interact with the SmartrAccount with your second private key like below:

    // file src/03-execute-tx.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./03-init";
    import { RpcProvider, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const secondAccountPrivateKey = "0x2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        secondAccountPrivateKey
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-execute-tx-pk2.js
    

    Changing the Account Threshold to 2

    By changing the Multisig Validator Threshold to 2, you force transactions to be signed by 2 of the 3 signers of the account. Run a script like below to change the threshold:

    // file src/03-increase-threshold.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(MultisigValidatorABI);
      const calldata = moduleCallData.compile("set_threshold", {
        new_threshold: 2,
      });
      const { transaction_hash } = await account.executeOnModule(
        moduleClassHash("MultisigValidator"),
        "set_threshold",
        calldata
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-increase-threshold.js
    

    You can check the current threshold on the account with the script below:

    // file src/04-get-threshold.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(MultisigValidatorABI);
      const calldata = await moduleCallData.compile("get_threshold", {});
      const threshold = await account.callOnModule(
        moduleClassHash("MultisigValidator"),
        "get_threshold",
        calldata
      );
      threshold.forEach((threshold) => console.log("threshold", threshold));
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Run the script with the command below:

    npx tsc --build
    
    node dist/03-get-threshold.js
    

    Checking you can NOT run a transaction with a single signer

    The script below executes a transaction with a single signer as it was the case in the previous section:

    // file src/03-execute-tx.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./03-init";
    import { RpcProvider, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress, smartrAccountPrivateKey } =
        await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Make sure you have deployed the account and the counter contract in the network and run the following commands:

    npx tsc --build
    
    node dist/03-execute-tx.js
    

    You are now getting an error saying the signature is invalid like below:

    Execution failed.
    Failure reason: 0x4163636f756e743a20696e76616c6964207369676e6174757265 
    ('Account: invalid signature')
    

    Running a Multiple Signer Transaction

    To run a transaction with multiple signers, you need to instantiate several SmartrAccount, each one with a different signer. Because you have set the threshold, you need to instantiate 2 accounts.

    Once done, proceed in 3 steps:

    • Step 1: generate the transaction details. This requires you create the calls but also you set some details about it, including: the Fees, the Nonce, the Version and the Chain. The SmartrAccount class uses the provider to get the chain id. To get the other details, you should run the prepareMultisig that returns the details associated with the transaction.
    • Step 2: have all the signers generate their part of the signature. The signMultisig takes the list of calls and the details you have generated and provides the signature as an array of string
    • Step 3: Execute the transaction with all the signatures from Step 2. This could be done by anyone, including one of the account you have already created. The executeMultisig function takes the list of calls, the details and an array that contains all the signatures.

    The script below signs the transaction with 2 signers and to run the increment external function of the Counter contract. It shows the value of the counter before and after the call:

    // file src/03-execute-tx-multiple-signers.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./03-init";
    import { RpcProvider, Contract, ArraySignatureType } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const secondSmartrAccountPrivateKey = "0x2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress, smartrAccountPrivateKey } =
        await init();
      const firstAccount = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const secondAccount = new SmartrAccount(
        provider,
        accountAddress,
        secondSmartrAccountPrivateKey
      );
    
      // Before you start check the value of the counter
      const counter = new Contract(CounterABI, counterAddress, provider);
      let currentCounter = await counter.call("get");
      console.log("currentCounter value", currentCounter);
    
      // Step 1: Prepare the transaction and get the details
      const call = counter.populate("increment");
      const calls = [call];
    
      const detail = await firstAccount.prepareMultisig(calls);
      console.log("below are the details assciated with the transaction");
      console.log(detail);
    
      // Step 2: Sign the transaction with 2 signers
      // (because the threshold on the account is currently 2)
      const firstSignature: ArraySignatureType = await firstAccount.signMultisig(
        calls,
        detail
      );
      console.log("first signature is", firstSignature);
      const secondSignature: ArraySignatureType = await secondAccount.signMultisig(
        calls,
        detail
      );
      console.log("second signature is", secondSignature);
    
      // Step 3: Execute the transaction
      const { transaction_hash } = await firstAccount.executeMultisig(
        calls,
        detail,
        [...firstSignature, ...secondSignature]
      );
      const receipt = await firstAccount.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      // Once finished, check the value of the counter again
      currentCounter = await counter.call("get");
      console.log("currentCounter value", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-execute-tx-multiple-signers.js
    

    Reset the threshold to one

    As for any transaction, you need to run a multi-signed transaction to reset the account threshold back to one. The script below build the call to execute_on_module and run it with multiple signer:

    // file src/03-decrease-threshold.ts
    import {
      SmartrAccount,
      SmartrAccountABI,
    } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import {
      CallData,
      RpcProvider,
      hash,
      type Call,
      type ArraySignatureType,
    } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const secondSmartrAccountPrivateKey = "0x2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const firstAccount = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const secondAccount = new SmartrAccount(
        provider,
        accountAddress,
        secondSmartrAccountPrivateKey
      );
    
      // Before you start build the set_threshold call
      const moduleCallData = new CallData(MultisigValidatorABI);
      const moduleCalldata = moduleCallData.compile("set_threshold", {
        new_threshold: 1,
      });
      const accountCallData = new CallData(SmartrAccountABI);
      const calldata = accountCallData.compile("execute_on_module", {
        class_hash: moduleClassHash("MultisigValidator"),
        call: {
          selector: hash.getSelectorFromName("set_threshold"),
          to: accountAddress,
          calldata: moduleCalldata,
        },
      });
      const call: Call = {
        entrypoint: "execute_on_module",
        contractAddress: accountAddress,
        calldata,
      };
      const calls = [call];
    
      // Step 1: Prepare the transaction and get the details
      const detail = await firstAccount.prepareMultisig(calls);
    
      // Step 2: Sign the transaction with 2 signers
      // (because the threshold on the account is currently 2)
      const firstSignature: ArraySignatureType = await firstAccount.signMultisig(
        calls,
        detail
      );
      const secondSignature: ArraySignatureType = await secondAccount.signMultisig(
        calls,
        detail
      );
    
      // Step 3: Execute the transaction
      const { transaction_hash } = await firstAccount.executeMultisig(
        calls,
        detail,
        [...firstSignature, ...secondSignature]
      );
      const receipt = await firstAccount.waitForTransaction(transaction_hash);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Execute the script with the following commands:

    npx tsc --build
    
    node dist/03-decrease-threshold.js
    

    You can check the threshold is back to one:

    node dist/03-get-threshold.js
    

    Remove Registered Keys

    You can now run transaction with a single signer on the account. The script below shows how to remove 2 public keys from a single call:

    // file src/03-remove-publickeys.ts
    import {
      SmartrAccountABI,
      SmartrAccount,
    } from "@0xknwn/starknet-modular-account";
    import {
      MultisigValidatorABI,
      classHash as moduleClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./03-init";
    import { CallData, RpcProvider, Signer, hash, type Call } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const secondAccountPrivateKey = "0x2";
    const thirdAccountPrivateKey = "0x3";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const module_class_hash = moduleClassHash("MultisigValidator");
      const calls: Call[] = [];
      for (const privateKey of [secondAccountPrivateKey, thirdAccountPrivateKey]) {
        const signer = new Signer(privateKey);
        const publicKey = await signer.getPubKey();
        console.log("account public key to remove", publicKey);
        const moduleCallData = new CallData(MultisigValidatorABI);
        const moduleCalldata = moduleCallData.compile("remove_public_key", {
          old_public_key: publicKey,
        });
        const accountCallData = new CallData(SmartrAccountABI);
        const calldata = accountCallData.compile("execute_on_module", {
          class_hash: module_class_hash,
          call: {
            selector: hash.getSelectorFromName("remove_public_key"),
            to: accountAddress,
            calldata: moduleCalldata,
          },
        });
        const call: Call = {
          entrypoint: "execute_on_module",
          contractAddress: accountAddress,
          calldata,
        };
        calls.push(call);
      }
      const { transaction_hash } = await account.execute(calls);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/03-remove-publickeys.js
    

    You can check the 2 of the 3 public keys have been removed:

    node dist/03-registered-publickeys.js
    

    Using the Eth Validator

    The Eth Validator Module can both work as a Secondary or as the Core Validator for the account. It requires a separate SDK. In this section of the documentation, you will see how you can use the Moduler Account to interact with the Eth Validator Module.

    Note: This section assumes the SmartrAccount class has been instantiated in the smartrAccount variable as shown in Using the modular account from the SDK. It also assumes the Counter contract that comes with the project has been deploys to the counterAddress and the CounterABI class is available. The 05-setup.ts script that comes with this project ensure those steps are executed.

    Installing the Eth Validator SDK

    If you plan to use the Eth Validatoi module, you might need the @0xknwn/starknet-module SDK in addition to the @0xknwn/starknet-modular-account SDK. To install it, run:

    npm install --save \
      @0xknwn/starknet-module
    

    Declaring the Eth Validator

    If you are working on a network that does not have the eth validator class already declared, you will need to declare it. The Eth validator module SDK, aka @0xknwn/starknet-module contains a helper function named declareClass to declare the class to the network. To use it, you need to pass:

    • A starknet.js Account as a first parameter
    • The name of the class to declare as the 2nd parameter. For the Eth Validator, the name isEthValidator

    Below is an example of a script that declares the new classes.

    // file src/04-declare-eth-validator.ts
    import { RpcProvider, Account } from "starknet";
    import { declareClass } from "@0xknwn/starknet-module";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ozAccountAddress =
      "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691";
    const ozPrivateKey = "0x71d7bb07b9a64f6f78ac4c816aff4da9";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const account = new Account(provider, ozAccountAddress, ozPrivateKey);
    
      const { classHash: ethValidatorClassHash } = await declareClass(
        account,
        "EthValidator"
      );
      console.log("EthValidator class hash:", ethValidatorClassHash);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Note: To declare the class, the account you use must be loaded with ETH.

    Assuming you have named the script src/04-declare-eth-validator.ts, transpile and run it:

    npx tsc --build
    
    node dist/04-declare-eth-validator.js
    

    The output should return the hash for the class.

    Verify the Eth Validator class hash

    The class hash does NOT depend on the deployment or the network. So you can find them at any time with the classHash helper that comes with the SDK. The script below shows how to use that function:

    // file src/04-check-eth-validator.ts
    import { classHash } from "@0xknwn/starknet-module";
    
    console.log("Computed EthValidator class hash:", classHash("EthValidator"));
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-check-eth-validator.js
    

    Using the Eth Validator as a Secondary Validator

    The simplest way to use the Eth Validator is to add it as a module to an existing account and execute a transaction with the EthModule class from the @0xknwn/starknet-module.

    Register the Eth Validator as a Module

    The modular account SDK comes with the addModule, removeModule and isModule. You can use those 3 functions to manage the module in the account once it has been declared to the network. To register the module in the account, use addModule:

    // file src/04-add-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module";
    import { init } from "./04-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.addModule(
        classHash("EthValidator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("EthValidator"));
      console.log("module", classHash("EthValidator"), "is installed", isInstalled);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-add-module.js
    

    Register the public key associated with your Eth Private Key

    Every module comes with a set of Management API. In the case of the Eth Validator, the associated interfaces are the following:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IPublicKey<TState> {
        fn set_public_key(ref self: TState, new_public_key: EthPublicKey);
        fn get_public_key(self: @TState) -> EthPublicKey;
    }
    }

    Now that you have installed the module, you can create an ETH private key and register the associated public key in the module. For the purpose of the demonstration, we will use an arbitrary (and now unsafe) private/public key pair:

    • private key: 0xb28ebb20fb1015da6e6367d1b5dba9b52862a06dbb3a4022e4749b6987ac1bd2
    • public key:
      • x: 0xd31cf702f5c89d49c567dcfd568bc4869e343506749f69d849eb408802cfa646
      • y: 0x348c7bbf341964c306669365292c0066c23a2fedd131907534677aa3e22db2fc

    Because Starknet types can only manage felt252 that are smaller than uint256 the format used by EthPublicKey is actually an array<felt252> that is made of [x.low, x.high, y.low, y.high]. To register the public key, use the script below:

    // file src/04-register-publickey.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash as ethClassHash } from "@0xknwn/starknet-module";
    import { EthSigner, cairo } from "starknet";
    import { init } from "./04-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ethPrivateKey =
      "0xb28ebb20fb1015da6e6367d1b5dba9b52862a06dbb3a4022e4749b6987ac1bd2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const module_class_hash = ethClassHash("EthValidator");
      const signer = new EthSigner(ethPrivateKey);
      const publicKey = await signer.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      console.log("x:", `0x${x}`);
      console.log("(x.low:", x_felts.low, ", x.high:", x_felts.high, ")");
      console.log("y:", `0x${y}`);
      console.log("(y.low:", y_felts.low, ", y.high:", y_felts.high, ")");
      const { transaction_hash } = await account.executeOnModule(
        module_class_hash,
        "set_public_key",
        [
          x_felts.low.toString(),
          x_felts.high.toString(),
          y_felts.low.toString(),
          y_felts.high.toString(),
        ]
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-register-publickey.js
    

    You can check the public key is correctly registered with the script below:

    // file src/04-get-publickey.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      EthValidatorABI,
      classHash as ethClassHash,
    } from "@0xknwn/starknet-module";
    import { init } from "./04-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(EthValidatorABI);
      const calldata = moduleCallData.compile("get_public_key", {});
      const public_keys = await account.callOnModule(
        ethClassHash("EthValidator"),
        "get_public_key",
        calldata
      );
      public_keys.forEach((public_key, idx) =>
        console.log(`public key (${idx}):`, public_key)
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-get-publickey.js
    

    Run a transaction with the EthModule

    The EthModule is an implementation of a module that can be passed to the SmartrAccount and manages the decoration of the transaction under the hood. To fully instantiate that module, you will need:

    • to instantiate the EthModule module from the SDK
    • to use the EthSigner provided by Starknet.js with the Private Key
    • to instantiate the SmartrAccount with the 2 classes above

    Then you can run a transaction, exactly as you would do with any Starknet.js account. The example below execute the increment entrypoint on the Counter contract:

    // file src/04-execute-tx.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./04-init";
    import { RpcProvider, Contract, EthSigner } from "starknet";
    import { EthModule } from "@0xknwn/starknet-module";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ethPrivateKey =
      "0xb28ebb20fb1015da6e6367d1b5dba9b52862a06dbb3a4022e4749b6987ac1bd2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, counterAddress, smartrAccountPrivateKey } =
        await init();
      const signer = new EthSigner(ethPrivateKey);
      const ethModule = new EthModule(accountAddress);
      const account = new SmartrAccount(
        provider,
        accountAddress,
        signer,
        ethModule
      );
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-execute-tx.js
    

    Remove the Eth Validator Module

    You can use removeModule and isModule to remove the module from the account with the script below:

    // file src/04-remove-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module";
    import { init } from "./04-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.removeModule(
        classHash("EthValidator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("EthValidator"));
      console.log(
        "module",
        classHash("EthValidator"),
        "has been removed",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/04-remove-module.js
    

    Using the Eth Validator as the Core Validator

    You can also use the Eth Validator as a Core Validator for the account. For that purpose you will deploy a new account and use the EthSigner to validate the account deployment without registering the EthModule in the SmartrAccount. In order to proceed you need to:

    • Generate the public key as an Array of felt252
    • Compute the account address
    • Send ETH to the modular account address
    • Deploy the Account

    Compute the Public Key as an Array of felt252

    The EthSigner helps to generate the public key from the private key. Once you have the public key you should slice to get an array of 4 pieces like below:

    const signer = new EthSigner(ethPrivateKey);
    const publicKey = await signer.getPubKey();
    const coords = publicKey.slice(2, publicKey.length);
    const x = coords.slice(0, 64);
    const x_felts = cairo.uint256(`0x${x}`);
    const y = coords.slice(64, 128);
    const y_felts = cairo.uint256(`0x${y}`);
    const publicKeyArray = [
      x_felts.low.toString(),
      x_felts.high.toString(),
      y_felts.low.toString(),
      y_felts.high.toString(),
    ];
    

    Compute the Account Address

    Once you have the public key, you should use the accountAddress function from @0xknwn/starknet-modular-account to compute the address of the account you will install. As a Salt, we will use the hash.computeHashOnElements from the public key like below:

    const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
    const computedAccountAddress = accountAddress(
      "SmartrAccount",
      publicKeyHash,
      [ethClassHash("EthValidator"), "0x4", ...publicKeyArray]
    );
    

    Note: The "0x4" that is inserted in the calldata is here to indicate there are 4 pieces to the publci key:

    Send ETH to the SmartrAccount Address to deploy it

    To deploy the account, you need to have ETH associated with the target account address. Assuming you have access to an account with ETH, this is how you send eth to the computedAccountAddress:

    const account = new SmartrAccount(
      provider,
      ozAccountAddress,
      smartrAccountPrivateKey
    );
    const ETH = new Contract(ERC20ABI, ethAddress, account);
    const initial_EthTransfer = cairo.uint256(5n * 10n ** 15n);
    const call = ETH.populate("transfer", {
      recipient: computedAccountAddress,
      amount: initial_EthTransfer,
    });
    const { transaction_hash } = await account.execute(call);
    const output = await account.waitForTransaction(transaction_hash);
    

    Deploy the Account with the Eth Validator as Core

    To deploy the account, you will need to use the deployAccount helper function from @0xknwn/starknet-modular-account with a SmartrAccount that has been instantiated with a EthSigner like below:

    const ethSmartrSigner = new EthSigner(smartrAccountPrivateKey);
    const ethAccount = new SmartrAccount(
      provider,
      computedAccountAddress,
      ethSmartrSigner
    );
    const address = await deployAccount(
      ethAccount,
      "SmartrAccount",
      publicKeyHash,
      [ethClassHash("EthValidator"), "0x4", ...publicKeyArray]
    );
    

    The Script Code

    You will find below the whole script that does the account deployment:

    // file src/04-deploy-account.ts
    import { RpcProvider, EthSigner, Contract, cairo, hash } from "starknet";
    import {
      accountAddress,
      deployAccount,
      SmartrAccount,
    } from "@0xknwn/starknet-modular-account";
    import { classHash as ethClassHash } from "@0xknwn/starknet-module";
    import { init } from "./04-init";
    import { ABI as ERC20ABI } from "./abi/ERC20";
    const ethAddress =
      "0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ethPrivateKey =
      "0xb28ebb20fb1015da6e6367d1b5dba9b52862a06dbb3a4022e4749b6987ac1bd2";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress: ozAccountAddress, smartrAccountPrivateKey } =
        await init();
    
      // Step 1 - Get the public key from the Eth Signer
      const ethSmartrSigner = new EthSigner(ethPrivateKey);
      const publicKey = await ethSmartrSigner.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      const publicKeyArray = [
        x_felts.low.toString(),
        x_felts.high.toString(),
        y_felts.low.toString(),
        y_felts.high.toString(),
      ];
    
      // Step 2 - Compute the account address
      const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
      const computedAccountAddress = accountAddress(
        "SmartrAccount",
        publicKeyHash,
        [ethClassHash("EthValidator"), "0x4", ...publicKeyArray]
      );
    
      // Step 3 - Send ETH to the computed account address
      const account = new SmartrAccount(
        provider,
        ozAccountAddress,
        smartrAccountPrivateKey
      );
      const ETH = new Contract(ERC20ABI, ethAddress, account);
      const initial_EthTransfer = cairo.uint256(5n * 10n ** 15n);
      const call = ETH.populate("transfer", {
        recipient: computedAccountAddress,
        amount: initial_EthTransfer,
      });
      const { transaction_hash } = await account.execute(call);
      const output = await account.waitForTransaction(transaction_hash);
      if (!output.isSuccess()) {
        throw new Error("Could not send ETH to the expected address");
      }
    
      // Step 4 - Deploy the account with the EthValidator as Core Validator
      const ethAccount = new SmartrAccount(
        provider,
        computedAccountAddress,
        ethSmartrSigner
      );
      const address = await deployAccount(
        ethAccount,
        "SmartrAccount",
        publicKeyHash,
        [ethClassHash("EthValidator"), "0x4", ...publicKeyArray]
      );
      if (address !== computedAccountAddress) {
        throw new Error(
          `The account should have been deployed to ${computedAccountAddress}, instead ${address}`
        );
      }
      console.log("accountAddress", computedAccountAddress);
      console.log("public key", publicKeyArray);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run it:

    npx tsc --build
    
    node dist/04-deploy-account.js
    

    Running a transaction with the Eth Validator as Core

    Running a transaction with the EthValidator as a Core is no more complex than running a transaction on a regular account. All you need to do is

    • get the account address that could have been saved from earlier
    • instantiate the SmartrAccount with the Starknet.js EthSigner
    • execute the transaction

    Below is an example that assumes you have deployed the account with the 04-deploy-account.ts script earlier:

    // file src/04-execute-tx-core.ts
    import {
      SmartrAccount,
      accountAddress,
    } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./04-init";
    import { RpcProvider, Contract, EthSigner, cairo, hash } from "starknet";
    import { classHash as ethClassHash } from "@0xknwn/starknet-module";
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ethPrivateKey =
      "0xb28ebb20fb1015da6e6367d1b5dba9b52862a06dbb3a4022e4749b6987ac1bd2";
    
    const main = async () => {
      // recompute the account address
      const signer = new EthSigner(ethPrivateKey);
      const publicKey = await signer.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      const publicKeyArray = [
        x_felts.low.toString(),
        x_felts.high.toString(),
        y_felts.low.toString(),
        y_felts.high.toString(),
      ];
    
      const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
      const computedAccountAddress = accountAddress(
        "SmartrAccount",
        publicKeyHash,
        [ethClassHash("EthValidator"), "0x4", ...publicKeyArray]
      );
    
      // execute the transaction
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { counterAddress } = await init();
      const account = new SmartrAccount(provider, computedAccountAddress, signer);
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run it:

    npx tsc --build
    
    node dist/04-execute-tx-core.js
    

    As you can see from the script:

    • You do not need the EthModule to interact with the account. That is because the validator is used as a Core Validator and, as such, the transaction does not required to be prefixed
    • Running transactions is the same as running a transaction with the Stark validator. Only the signature changes.

    Using the P256 Validator

    The P256 Validator Module can both work as a Secondary or as the Core Validator for the account. It requires the module SDK. In this section of the documentation, you will see how you can use the Modular Account to interact with the P256 Validator Module.

    Note: This section assumes the SmartrAccount class has been instantiated in the smartrAccount variable as shown in Using the modular account from the SDK. It also assumes the Counter contract that comes with the project has been deploys to the counterAddress and the CounterABI class is available. The 05-setup.ts script that comes with this project ensure those steps are executed.

    Installing the P256 Validator SDK

    If you plan to use the P256 Validatoi module, you might need the @0xknwn/starknet-module SDK in addition to the @0xknwn/starknet-modular-account SDK. To install it, run:

    npm install --save \
      @0xknwn/starknet-module
    

    Declaring the P256 Validator

    If you are working on a network that does not have the P256 validator class already declared, you will need to declare it. The P256 validator module SDK, aka @0xknwn/starknet-module contains a helper function named declareClass to declare the class to the network. To use it, you need to pass:

    • A starknet.js Account as a first parameter
    • The name of the class to declare as the 2nd parameter. For the P256 Validator, the name isP256Validator

    Below is an example of a script that declares the new classes.

    // file src/05-declare-p256-validator.ts
    import { RpcProvider, Account } from "starknet";
    import { declareClass } from "@0xknwn/starknet-module";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const ozAccountAddress =
      "0x3b2d6d0edcbdbdf6548d2b79531263628887454a0a608762c71056172d36240";
    const ozPrivateKey =
      "0x000e8f079f1092042bf9b855935d3ef1bb7078609491fb24e7cb8cbb574e50ca";
    const providerURL = "https://starknet-sepolia.public.blastapi.io";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const account = new Account(provider, ozAccountAddress, ozPrivateKey);
    
      const { classHash: p256ValidatorClassHash } = await declareClass(
        account,
        "P256Validator"
      );
      console.log("P256Validator class hash:", p256ValidatorClassHash);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Note: To declare the class, the account you use must be loaded with P256.

    Assuming you have named the script src/05-declare-p256-validator.ts, transpile and run it:

    npx tsc --build
    
    node dist/05-declare-p256-validator.js
    

    The output should return the hash for the class.

    Verify the P256 Validator class hash

    The class hash does NOT depend on the deployment or the network. So you can find them at any time with the classHash helper that comes with the SDK. The script below shows how to use that function:

    // file src/05-check-p256-validator.ts
    import { classHash } from "@0xknwn/starknet-module";
    
    console.log("Computed P256Validator class hash:", classHash("P256Validator"));
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-check-p256-validator.js
    

    Using the P256 Validator as a Secondary Validator

    The simplest way to use the P256 Validator is to add it as a module to an existing account and execute a transaction with the P256Module class from the @0xknwn/starknet-module.

    Register the P256 Validator as a Module

    The modular account SDK comes with the addModule, removeModule and isModule. You can use those 3 functions to manage the module in the account once it has been declared to the network. To register the module in the account, use addModule:

    // file src/05-add-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module";
    import { init } from "./05-init";
    import { RpcProvider } from "starknet";
    
    const ozAccountAddress =
      "0x3b2d6d0edcbdbdf6548d2b79531263628887454a0a608762c71056172d36240";
    const ozPrivateKey =
      "0x000e8f079f1092042bf9b855935d3ef1bb7078609491fb24e7cb8cbb574e50ca";
    const providerURL = "https://starknet-sepolia.public.blastapi.io";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.addModule(
        classHash("P256Validator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("P256Validator"));
      console.log(
        "module",
        classHash("P256Validator"),
        "is installed:",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-add-module.js
    

    Register the public key associated with your P256 Private Key

    Every module comes with a set of Management API. In the case of the P256 Validator, the associated interfaces are the following:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IPublicKey<TState> {
        fn set_public_key(ref self: TState, new_public_key: P256PublicKey);
        fn get_public_key(self: @TState) -> P256PublicKey;
    }
    }

    Now that you have installed the module, you can create an ETH private key and register the associated public key in the module. For the purpose of the demonstration, we will use an arbitrary (and now unsafe) private/public key pair:

    • private key: 0x1efecf7ee1e25bb87098baf2aaab0406167aae0d5ea9ba0d31404bf01886bd0e
    • public key:
      • x: 0x097420e05fbc83afe4d73b31890187d0cacf2c3653e27f434701a91625f916c2
        • x.low: 269579757328574126121444003492591638210
        • x.high: 12566025211498978771503502663570524112
      • y: 0x98a304ff544db99c864308a9b3432324adc6c792181bae33fe7a4cbd48cf263a
        • y.low: 230988565823064299531546210785320445498
        • y.high: 202889101106158949967186230758848275236

    Because Starknet types can only manage felt252 that are smaller than uint256 the format used by P256PublicKey is actually an array<felt252> that is made of [x.low, x.high, y.low, y.high]. To register the public key, use the script below:

    // file src/05-register-publickey.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      classHash as moduleClassHash,
      P256Signer,
    } from "@0xknwn/starknet-module";
    import { cairo } from "starknet";
    import { init } from "./05-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "https://starknet-sepolia.public.blastapi.io";
    const p256PrivateKey =
      "0x1efecf7ee1e25bb87098baf2aaab0406167aae0d5ea9ba0d31404bf01886bd0e";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const module_class_hash = moduleClassHash("P256Validator");
      const signer = new P256Signer(p256PrivateKey);
      const publicKey = await signer.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      console.log("x:", `0x${x}`);
      console.log("(x.low:", x_felts.low, ", x.high:", x_felts.high, ")");
      console.log("y:", `0x${y}`);
      console.log("(y.low:", y_felts.low, ", y.high:", y_felts.high, ")");
      const { transaction_hash } = await account.executeOnModule(
        module_class_hash,
        "set_public_key",
        [
          x_felts.low.toString(),
          x_felts.high.toString(),
          y_felts.low.toString(),
          y_felts.high.toString(),
        ]
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-register-publickey.js
    

    You can check the public key is correctly registered with the script below:

    // file src/05-get-publickey.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      classHash as moduleClassHash,
      P256ValidatorABI,
    } from "@0xknwn/starknet-module";
    import { init } from "./05-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "https://starknet-sepolia.public.blastapi.io";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const moduleCallData = new CallData(P256ValidatorABI);
      const calldata = moduleCallData.compile("get_public_key", {});
      const public_keys = await account.callOnModule(
        moduleClassHash("P256Validator"),
        "get_public_key",
        calldata
      );
      public_keys.forEach((public_key, idx) =>
        console.log(`public key (${idx}):`, public_key)
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-get-publickey.js
    

    Run a transaction with the P256Module

    The P256Module is an implementation of a module that can be passed to the SmartrAccount and manages the decoration of the transaction under the hood. To fully instantiate that module, you will need:

    • to instantiate the P256Module module from the SDK
    • to use the P256Signer provided by `@0xknwn/starknet-module with the Private Key
    • to instantiate the SmartrAccount with the 2 classes above

    Then you can run a transaction, exactly as you would do with any Starknet.js account. The example below execute the increment entrypoint on the Counter contract:

    // file src/05-execute-tx.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./05-init";
    import { RpcProvider, Contract } from "starknet";
    import { P256Module, P256Signer } from "@0xknwn/starknet-module";
    
    const providerURL = "https://starknet-sepolia.public.blastapi.io";
    const p256PrivateKey =
      "0x1efecf7ee1e25bb87098baf2aaab0406167aae0d5ea9ba0d31404bf01886bd0e";
    const counterAddress =
      "0x31c527e5bfe99c50aaa7573b383d298aa9ca70f96ab3834b448e2ba7ee651c1";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      console.log("accountAddress", accountAddress);
      const signer = new P256Signer(p256PrivateKey);
      const p256Module = new P256Module(accountAddress);
      const account = new SmartrAccount(
        provider,
        accountAddress,
        signer,
        p256Module
      );
      console.log("counterAddress", counterAddress);
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      console.log("transaction_hash", transaction_hash);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-execute-tx.js
    

    Remove the P256 Validator Module

    You can use removeModule and isModule to remove the module from the account with the script below:

    // file src/05-remove-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module";
    import { init } from "./05-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.removeModule(
        classHash("P256Validator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("P256Validator"));
      console.log(
        "module",
        classHash("P256Validator"),
        "is installed:",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/05-remove-module.js
    

    Using the P256 Validator as the Core Validator

    You can also use the P256 Validator as a Core Validator for the account. For that purpose you will deploy a new account and use the P256Signer to validate the account deployment without registering the P256Module in the SmartrAccount. In order to proceed you need to:

    • Generate the public key as an Array of felt252
    • Compute the account address
    • Send ETH to the modular account address
    • Deploy the Account

    Compute the Public Key as an Array of felt252

    The P256Signer helps to generate the public key from the private key. Once you have the public key you should slice to get an array of 4 pieces like below:

    const p236SmartrSigner = new P256Signer(p256PrivateKey);
    const publicKey = await p236SmartrSigner.getPubKey();
    const coords = publicKey.slice(2, publicKey.length);
    const x = coords.slice(0, 64);
    const x_felts = cairo.uint256(`0x${x}`);
    const y = coords.slice(64, 128);
    const y_felts = cairo.uint256(`0x${y}`);
    const publicKeyArray = [
      x_felts.low.toString(),
      x_felts.high.toString(),
      y_felts.low.toString(),
      y_felts.high.toString(),
    ];
    

    Compute the Account Address

    Once you have the public key, you should use the accountAddress function from @0xknwn/starknet-modular-account to compute the address of the account you will install. As a Salt, we will use the hash.computeHashOnElements from the public key like below:

    const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
    const computedAccountAddress = accountAddress(
      "SmartrAccount",
      publicKeyHash,
      [moduleClassHash("P256Validator"), "0x4", ...publicKeyArray]
    );
    

    Note: The "0x4" that is inserted in the calldata is here to indicate there are 4 pieces to the public key:

    Send ETH to the SmartrAccount Address to deploy it

    To deploy the account, you need to have ETH associated with the target account address. Assuming you have access to an account with ETH, this is how you send p256 to the computedAccountAddress:

    const account = new SmartrAccount(
      provider,
      ozAccountAddress,
      smartrAccountPrivateKey
    );
    const ETH = new Contract(ERC20ABI, ethAddress, account);
    const initial_EthTransfer = cairo.uint256(5n * 10n ** 15n);
    const call = ETH.populate("transfer", {
      recipient: computedAccountAddress,
      amount: initial_EthTransfer,
    });
    const { transaction_hash } = await account.execute(call);
    const output = await account.waitForTransaction(transaction_hash);
    

    Deploy the Account with the P256 Validator as Core

    To deploy the account, you will need to use the deployAccount helper function from @0xknwn/starknet-modular-account with a SmartrAccount that has been instantiated with a P256Signer like below:

    const p256Account = new SmartrAccount(
      provider,
      computedAccountAddress,
      p236SmartrSigner
    );
    const address = await deployAccount(
      p256Account,
      "SmartrAccount",
      publicKeyHash,
      [moduleClassHash("P256Validator"), "0x4", ...publicKeyArray]
    );
    

    The Script Code

    You will find below the whole script that does the account deployment:

    // file src/05-deploy-account.ts
    import { RpcProvider, Contract, cairo, hash } from "starknet";
    import {
      accountAddress,
      deployAccount,
      SmartrAccount,
    } from "@0xknwn/starknet-modular-account";
    import {
      classHash as moduleClassHash,
      P256Signer,
    } from "@0xknwn/starknet-module";
    import { init } from "./05-init";
    import { ABI as ERC20ABI } from "./abi/ERC20";
    const ethAddress =
      "0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const p256PrivateKey =
      "0x1efecf7ee1e25bb87098baf2aaab0406167aae0d5ea9ba0d31404bf01886bd0e";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress: ozAccountAddress, smartrAccountPrivateKey } =
        await init();
    
      // Step 1 - Get the public key from the Eth Signer
      const p236SmartrSigner = new P256Signer(p256PrivateKey);
      const publicKey = await p236SmartrSigner.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      const publicKeyArray = [
        x_felts.low.toString(),
        x_felts.high.toString(),
        y_felts.low.toString(),
        y_felts.high.toString(),
      ];
    
      // Step 2 - Compute the account address
      const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
      const computedAccountAddress = accountAddress(
        "SmartrAccount",
        publicKeyHash,
        [moduleClassHash("P256Validator"), "0x4", ...publicKeyArray]
      );
    
      // Step 3 - Send ETH to the computed account address
      const account = new SmartrAccount(
        provider,
        ozAccountAddress,
        smartrAccountPrivateKey
      );
      const ETH = new Contract(ERC20ABI, ethAddress, account);
      const initial_EthTransfer = cairo.uint256(5n * 10n ** 15n);
      const call = ETH.populate("transfer", {
        recipient: computedAccountAddress,
        amount: initial_EthTransfer,
      });
      const { transaction_hash } = await account.execute(call);
      const output = await account.waitForTransaction(transaction_hash);
      if (!output.isSuccess()) {
        throw new Error("Could not send ETH to the expected address");
      }
    
      // Step 4 - Deploy the account with the P256Validator as Core Validator
      const p256Account = new SmartrAccount(
        provider,
        computedAccountAddress,
        p236SmartrSigner
      );
      const address = await deployAccount(
        p256Account,
        "SmartrAccount",
        publicKeyHash,
        [moduleClassHash("P256Validator"), "0x4", ...publicKeyArray]
      );
      if (address !== computedAccountAddress) {
        throw new Error(
          `The account should have been deployed to ${computedAccountAddress}, instead ${address}`
        );
      }
      console.log("accountAddress", computedAccountAddress);
      console.log("public key", publicKeyArray);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run it:

    npx tsc --build
    
    node dist/05-deploy-account.js
    

    Running a transaction with the P256 Validator as Core

    Running a transaction with the P256Validator as a Core is no more complex than running a transaction on a regular account. All you need to do is

    • get the account address that could have been saved from earlier
    • instantiate the SmartrAccount with the Starknet.js P256Signer
    • execute the transaction

    Below is an example that assumes you have deployed the account with the 05-deploy-account.ts script earlier:

    // file src/05-execute-tx-core.ts
    import {
      SmartrAccount,
      accountAddress,
    } from "@0xknwn/starknet-modular-account";
    import { init, CounterABI } from "./05-init";
    import { RpcProvider, Contract, cairo, hash } from "starknet";
    import {
      classHash as moduleClassHash,
      P256Signer,
    } from "@0xknwn/starknet-module";
    const providerURL = "http://127.0.0.1:5050/rpc";
    const p256PrivateKey =
      "0x1efecf7ee1e25bb87098baf2aaab0406167aae0d5ea9ba0d31404bf01886bd0e";
    
    const main = async () => {
      // recompute the account address
      const signer = new P256Signer(p256PrivateKey);
      const publicKey = await signer.getPubKey();
      const coords = publicKey.slice(2, publicKey.length);
      const x = coords.slice(0, 64);
      const x_felts = cairo.uint256(`0x${x}`);
      const y = coords.slice(64, 128);
      const y_felts = cairo.uint256(`0x${y}`);
      const publicKeyArray = [
        x_felts.low.toString(),
        x_felts.high.toString(),
        y_felts.low.toString(),
        y_felts.high.toString(),
      ];
    
      const publicKeyHash = hash.computeHashOnElements(publicKeyArray);
      const computedAccountAddress = accountAddress(
        "SmartrAccount",
        publicKeyHash,
        [moduleClassHash("P256Validator"), "0x4", ...publicKeyArray]
      );
    
      // execute the transaction
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { counterAddress } = await init();
      const account = new SmartrAccount(provider, computedAccountAddress, signer);
      const counter = new Contract(CounterABI, counterAddress, account);
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await account.execute(call);
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run it:

    npx tsc --build
    
    node dist/05-execute-tx-core.js
    

    As you can see from the script:

    • You do not need the P256Module to interact with the account. That is because the validator is used as a Core Validator and, as such, the transaction does not required to be prefixed
    • Running transactions is the same as running a transaction with the Stark validator. Only the signature changes!

    Using the SessionKey Validator

    The starknet modular account comes with the @0xknwn/starknet-module-sessionkey SDK that you can use to work with the sessionkey validator. In this section, you will see, how to install and use the validator, how to request a sessionkey and how to use it.

    Note: This section assumes the SmartrAccount class has been instantiated in the smartrAccount variable as shown in Using the modular account from the SDK. It also assumes the Counter contract that comes with the project has been deploys to the counterAddress and the CounterABI class is available. The 06-setup.ts script that comes with this project ensure those steps are executed.

    Install the SessionKey Validator

    @0xknwn/starknet-module-sessionkey is a SDK that complements @0xknwn/starknet-modular-account and provide the tools to manage the module and interact with it from the SmartrAccount. Start by adding the module to the project with a command like the one below:

    npm install --save @0xknwn/starknet-module-sessionkey
    

    If you are working on a network that does not have the sessionkey module class declared already, like the devnet, you should declare the class. The declareClass function that comes with the SDK allow such an installation. Below is an example of a script that install the module class:

    // file src/06-declare-class.ts
    import { RpcProvider, Account } from "starknet";
    import { declareClass } from "@0xknwn/starknet-module-sessionkey";
    
    // these are the settings for the devnet with --seed=0
    // change them to mee your requirements
    const providerURL = "http://127.0.0.1:5050/rpc";
    const ozAccountAddress =
      "0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691";
    const ozPrivateKey = "0x71d7bb07b9a64f6f78ac4c816aff4da9";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const account = new Account(provider, ozAccountAddress, ozPrivateKey);
    
      const { classHash: sessionkeyValidatorClassHash } = await declareClass(
        account,
        "SessionKeyValidator"
      );
      console.log("SessionKeyValidator class hash:", sessionkeyValidatorClassHash);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Note: To declare the class, the account you use must be loaded with ETH. In order to do it, you can use any account, including the modular account.

    Transpile it and run the script with the commands below:

    npx tsc --build
    
    node dist/06-declare-class.js
    

    Note: only the declareClass function from @0xknwn/starknet-module-sessionkey can declare the Sessionkey Validator class. If you are using the declareClass function from @0xknwn/starknet-modular-account, you will be able to declare the Stark Validator and the Modular Account class but not the SessionKey Validator.

    Register the SessionKey Validator as a Module

    The modular account SDK comes with the addModule, removeModule and isModule. You can use those 3 functions to manage the module in the account once it has been declared to the network. To register the module in the account, use addModule:

    // file src/06-add-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module-sessionkey";
    import { init } from "./06-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.addModule(
        classHash("SessionKeyValidator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("SessionKeyValidator"));
      console.log(
        "module",
        classHash("SessionKeyValidator"),
        "is installed",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/06-add-module.js
    

    Requesting a Session Key

    Once the module is installed in the account, a dapp can request a grant associated with a private key. In order to get that authorization, it must first build a session key request. A request is made of the following elements:

    • the account address. A session key is granted to an account and cannot be used with another one.
    • the sessionkey validator module class hash. Because an account could have several sessionkey module installed, we want to make sure the session key is granted to a very specific module.
    • the core validator class hash. Here we want to make sure the sessionkey grantor is the core validator for the account to prevent checking a signature with another module from the account
    • the dapp public key that is associated with the session key request. Once the session key is authorized, the dapp will only be able to sign transactions with its private key counterpart.
    • an expiration time. Here again, we want the session key to be limited in time and we strongly suggest the signer keep that period short.
    • an array of policies, i.e a list of (1) contract addresses and (2) entrypoints the dapp will be able to call with that session key. Keep in mind that many contracts are upgradeable and that a good practice would be to grant an access only to a contract that is opensource, audited and not upgradeable.
    • the chain id. This is something that might be remove in a later version of the session key because the account address already depends of the chain id. However, this element is mandatory to request a sessionkey grant

    Create and Manage Policies

    Policies are very specific to session keys and as such, the sessionkey SDK, i.e @0xknwn/starknet-module-sessionkey provides a class named PolicyManager that helps to manage them. There are 2 main reasons to use that class:

    • When requesting a sessionkey. That is because you do not use the array of policies but a hash of each one of them and a merkle tree of those hashes. The PolicyManager that comes with the SDK provides you with that Merkle tree root that is what is used to request the sessionkey grant.
    • When signing a transaction with the session key. That is because when you sign a transaction, not only you need to provide a valid signature of the transaction with the private key that has been granted the access but you also need to provide the merkle proofs that the call that are used in the transaction are part of the sessionkey policies.

    So assuming you want to grant an access to the increment and increment_by entrypoints of the Counter class and assuming counterAddress contains counter address, to use the PolicyManager class, you will call its constructor like below:

    const policyManager = new PolicyManager([
      { contractAddress: counterContract.address, selector: "increment" },
      { contractAddress: counterContract.address, selector: "increment_by" },
    ]);
    

    The policyManager.getRoot() function will return the root of the merkle tree associated with the policies.

    Note: The second useful function of PolicyManager is the getProof(policy) function. However, once the session key module registered in SmartrAccount that function is used by the account and you should not use it by yourself.

    Create a SessionKeyModule

    The SessionKeyModule is an implementation of a module that can be passed to the SmartrAccount and manages the decoration of the transaction under the hood. To fully instantiate that module, you will need:

    • all the data above
    • to request/get an authorization from the core validator signer
    • to add the signature provided by the grantor back into the module

    The first step consists in instantiating the SessionKeyModule with all the data associated with the session key:

    const sessionKeyModule = new SessionKeyModule(
      sessionkeyPublicKey,
      accountAddress,
      sessionkeyClassHash,
      chain,
      expires,
      policyManager
    );
    

    Request a Grant by the Account Core Validator Signer

    To request the authorization you should call the request method on the module with the starkValidatorClassHash like below:

    const request = await sessionKeyModule.request(starkValidatorClassHash);
    

    Note: this step is very important because it stores the starkValidatorClassHash in the module.

    Get the Session Key Grant

    Now, you need to use the core validator signer to provide the signature that will be necessary for the module to be activated. The sessionkey SDK provides the SessionKeyGrantor to help you with signing the request. To generate the signature, run the sign method on it:

    const grantor = new SessionKeyGrantor(
      starkValidatorClassHash,
      smartrAccountPrivateKey
    );
    const signature = await grantor.sign(sessionKeyModule);
    

    Register the Core Validator Signature with the SessionKeyModule

    To finish with the module configuration, you just have to add the signature to it like below:

    sessionKeyModule.add_signature(signature);
    

    Create an Account with the SessionKeyModule

    Now you can create an Account with the SmartrAccount class. The class constructor can use a module as a 4th argument of the constructor like below:

    const smartrAccountWithSessionKey = new SmartrAccount(
      provider,
      accountAddress,
      sessionkeyPrivateKey,
      sessionKeyModule
    );
    

    Note: here you are not using the private key from the core validator signer but the private key generated by your dapp.

    Source Code

    The overall sessionkey request/grant process with the execution of a transaction on the counter contract is available as a single script below:

    // file src/06-sessionkey-transaction.ts
    import { SmartrAccount, classHash } from "@0xknwn/starknet-modular-account";
    import {
      classHash as sessionkeyClassHash,
      PolicyManager,
      SessionKeyModule,
      SessionKeyGrantor,
    } from "@0xknwn/starknet-module-sessionkey";
    import { init, CounterABI } from "./06-init";
    import { RpcProvider, Signer, Contract } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const sessionkeyPrivateKey = "0x4";
    
    const main = async () => {
      const { counterAddress, smartrAccountPrivateKey, accountAddress } =
        await init();
      const provider = new RpcProvider({ nodeUrl: providerURL });
    
      // Step 1: Collect all the necessary information to request a sessionkey
      // Authorization to the modular account signers
      const signer = new Signer(sessionkeyPrivateKey);
      const sessionkeyPublicKey = await signer.getPubKey();
    
      const chain = await provider.getChainId();
    
      const expires = BigInt(Math.floor(Date.now() / 1000) + 24 * 60 * 60); // 24 hours from now
    
      const policyManager = new PolicyManager([
        { contractAddress: counterAddress, selector: "increment" },
        { contractAddress: counterAddress, selector: "increment_by" },
      ]);
    
      // Step 2: Create a session key module that can be used to request a session
      // key and to create a SmartrAccount with the signed session key that can
      // execute transactions as any regular Account
      const sessionKeyModule = new SessionKeyModule(
        sessionkeyPublicKey,
        accountAddress,
        sessionkeyClassHash("SessionKeyValidator"),
        chain,
        `0x${expires.toString(16)}`,
        policyManager
      );
    
      // Step 3: Generate the sessionkey grant request
      // that is an important step to request a session key because that is when
      // the core validator class is registered with the session key module
      const request = await sessionKeyModule.request(classHash("StarkValidator"));
      console.log("request", request);
    
      // Step 4: Use the SessionKeyGrantor helper class to sign the request
      const grantor = new SessionKeyGrantor(
        classHash("StarkValidator"),
        smartrAccountPrivateKey
      );
      const signature = await grantor.sign(sessionKeyModule);
    
      // Step 5: Register the signatures to the session key module
      sessionKeyModule.add_signature(signature);
    
      // Step 6: Create the SmartrAccount with the session key module
      const smartrAccountWithSessionKey = new SmartrAccount(
        provider,
        accountAddress,
        sessionkeyPrivateKey,
        sessionKeyModule
      );
    
      // Step 7: Execute transactions with the session key module
      const counter = new Contract(
        CounterABI,
        counterAddress,
        smartrAccountWithSessionKey
      );
      let currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
      const call = counter.populate("increment");
      const { transaction_hash } = await smartrAccountWithSessionKey.execute(call);
      const receipt = await smartrAccountWithSessionKey.waitForTransaction(
        transaction_hash
      );
      console.log("transaction succeeded", receipt.isSuccess());
      currentCounter = await counter.call("get");
      console.log("currentCounter", currentCounter);
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run it:

    npx tsc --build
    
    node dist/06-sessionkey-transaction.js
    

    Execute a Transaction with the Session Key

    As you can see from above, executing a transaction with a session key is exactly the same as executing any transaction with a starknet.js account. All you need to do is to use the SmartrAccount that comes with the @0xknwn/starknet-modular-account SDK with the SessionKeyModule from the @0xknwn/starknet-module-sessionkey SDK.

    Invalidate the Session Key

    If needed, you can block a session key. To proceed, you would need the hash of the session key as shown in the request. That is the hash that is actually signed by the core validator signer and stored in sessionkeyHash in the script. Then, you can use disable_session_key entrypoint on the module with the executeOnModule entrypoint of the account:

    // file src/06-block-sessionkey.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import {
      classHash as sessionkeyClassHash,
      SessionKeyValidatorABI,
    } from "@0xknwn/starknet-module-sessionkey";
    import { init } from "./06-init";
    import { CallData, RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    const sessionkeyHash = "0x7";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
    
      const moduleCallData = new CallData(SessionKeyValidatorABI);
      const calldata = moduleCallData.compile("disable_session_key", {
        sessionkey: sessionkeyHash,
      });
      const { transaction_hash } = await account.executeOnModule(
        sessionkeyClassHash("SessionKeyValidator"),
        "disable_session_key",
        calldata
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script:

    npx tsc --build
    
    node dist/06-block-sessionkey.js
    

    Remove the SessionKey Validator Module from the Account

    To remove the module from the account, use removeModule:

    // file src/06-remove-module.ts
    import { SmartrAccount } from "@0xknwn/starknet-modular-account";
    import { classHash } from "@0xknwn/starknet-module-sessionkey";
    import { init } from "./06-init";
    import { RpcProvider } from "starknet";
    
    const providerURL = "http://127.0.0.1:5050/rpc";
    
    const main = async () => {
      const provider = new RpcProvider({ nodeUrl: providerURL });
      const { accountAddress, smartrAccountPrivateKey } = await init();
      const account = new SmartrAccount(
        provider,
        accountAddress,
        smartrAccountPrivateKey
      );
      const { transaction_hash } = await account.removeModule(
        classHash("SessionKeyValidator")
      );
      const receipt = await account.waitForTransaction(transaction_hash);
      console.log("transaction succeeded", receipt.isSuccess());
    
      const isInstalled = await account.isModule(classHash("SessionKeyValidator"));
      console.log(
        "module",
        classHash("SessionKeyValidator"),
        "has been removed",
        isInstalled
      );
    };
    
    main()
      .then(() => {})
      .catch((e) => {
        console.warn(e);
      });
    

    Transpile and run the script with the commands below:

    npx tsc --build
    
    node dist/06-remove-module.js
    

    Modules

    Starknet Modular Account requires modules to work properly. There are 2 types of modules:

    • Validator Modules, including the Core Validator Module are used to validate transactions
    • Executor Modules are not yet available. They enable to change the account behavior: you can create metadata to track the signer complies to some specific rules; you can add checks that are not related to the signature like the fact that an amount allowed to a signer is not already spent.

    This section details module development and specific implementations. In particular, the folllowing are explained.

    If you just plan to use the Starknet Modular Account with those modules, we suggest you check the SDKs sections of the documentation.

    Developing your Own Validator Module

    A Validator Module can be used to change the way the Modular Account validates transactions and messages. Validators can be used as the Core Validator, i.e. they validate the transaction on the account by default. If not, they require the transaction to be decorated with a prefix call to the __module_validate__ entrypoint.

    This section provides directions about how to develop and test your own module. If you are interested to extend the account with Validators, we suggest you contact the project to get some help.

    Validator Module

    A Validator is a class that implement the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IValidator<TState> {
        fn validate(self: @TState, grantor_class: ClassHash, calls: Array<Call>) -> felt252;
    }
    }

    validate generated the hash for a transaction and validates the transaction for the account. Opposite to is_valid_signature, validate has access to the whole transaction and, as such should always be fully implemented by any validator module.

    Note: the grantor class that is passed by the account is the Core Validator class hash registered with the account. It can be used for some specific use. For instance, in the case of the sessionkey validator, it enables the sessionkey validator module to validate the sessionkey authorization with the is_valid_signature from the Core Validator of the account.

    Core Validator Interface

    In addition to the IValidator interface, Core Validator Modules must implement the ICoreValidator interface. That is because the module has to configure the account public key when the accounted is created the first time

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait ICoreValidator<TState> {
        fn is_valid_signature(self: @TState, hash: Array<felt252>, signature: Array<felt252>) -> felt252;
        fn initialize(ref self: TState, public_key: Array<felt252>);
    }
    }
    • is_valid_signature, given the hash that can be a transaction hash or a message hash should return starknet::VALIDATED is the signature is valid and 0 if not. Depending on the case, it can be that the function cannot be implemented. If that is the case, we suggest you return that the transaction is not valid
    • initialize is used at the installation time of the account to store the first account public key. The reason the public_key is an Array<felt252> is to be able to initialize scheme where the public key requires more than one felt252.

    Management Interface and Mappers

    Each Validator Module can provide some management functions to configure the module. The name and implementation of those functions depend on the module.

    The management interface cannot be call on a class, they must be triggered on a contract. To workaround that issue, the account provides 2 entrypoints execute_on_module and call_on_module that can call the management interface from the account. The execute_on_module provides some additional security making sure that only the account signers can initiate those calls.

    To allow the remove access between the account calls and the management interface the validator requires the call and execute methods to be implemented. Those methods map the input and output arguments of the management function. The associated interface looks like:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IConfigure<TState> {
        fn call(self: @TState, call: Call) -> Array<felt252>;
        fn execute(ref self: TState, call: Call) -> Array<felt252>;
    }
    }

    Note: To work the Call should include the following:

    • selector must be the selector for the management interface, i.e. the sn_keccak of the entrypoint name
    • to should be the account address
    • calldata should be the call data as defined by the ABI of the class

    Version Interface

    It is recommended to implement the IVersion interface in the module and add them to the mappers as describe above. These interface helps the users to identify the validators, even if eventually, the class hash remains the only real identifier:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IVersion<TState> {
        fn get_version(self: @TState) -> felt252;
        fn get_name(self: @TState) -> felt252;
    }
    }

    Other considerations

    In addition to the feature above, we suggest a number of good practices to develop modules

    • Be very careful with Storage variable names as they can be accessed by another module. A good practice is to prefix those names with a prefix that is uniquely derived from the module.
    • Use the account notify_owner_addition and notify_owner_removal functions that are part of the internal implementation of the account to notify users of the addition/removal of public keys
    • Add a Typescript/Javascript module SDK to the Modular Account SDK. That would allow applications to easily use your module and help with tests.
    • Provide a set of tests to make sure the module is behaving correctly and so that people can understand how it is supposed to work
    • Write a documentation both about the module and the SDK.

    The Stark Validator Module

    The Stark Validator Module is an implementation of a Validator Module for the Starknet Modular Account. It must be used as the Core Validator for the Account. This document explains the features, the configuration and some of the Internals of this module.

    Validator Module

    A validator is a contract that implement the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    trait IValidator<TState> {
        fn validate(self: @TState, grantor_class: ClassHash, calls: Array<Call>) -> felt252;
    }
    }

    validate is used to validate a transaction on the account. It

    • gets the hash for the current transaction from the network
    • use is_valid_signature to check the signature is valid

    Note: the grantor class that is passed by the account is the Core Validator class hash registered with the account. In the case of the Stark Validator it is the module class hash. The validator does not use that parameter.

    Core Validator Interface

    In addition to the IValidator interface, The Stark Validator Module implements the ICoreValidator interface. That is because the Stark Validator can be installed as a Core Validator Module, i.e. the default Validator for the account. The interface looks like this:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait ICoreValidator<TState> {
        fn is_valid_signature(self: @TState, hash: Hash<felt252>, signature: Array<felt252>) -> felt252;
        fn initialize(ref self: TState, public_key: Array<felt252>);
    }
    }

    In the case of the Stark Validator the 2 functionsare:

    • is_valid_signature. It checks a hash of a transaction or a hash of a message matches the account public keys of the current configurationm i.e stored in the account storage:
      • It checks the elements of the signature are valid considering the public keys registered in the account
      • It checks the number of valid signature matches the threshold defines in the account.
    • initialize is used at the installation time of the account to store the first account public key. In the case of the Stark Validator, the public key can be managed in a single felt so you can just use an array of one, i.e. array![publicKey] in cairo or [publicKey] in Typescript/Javascript.

    Note: In the case of the Stark Validator the key is simply stored in the Account_public_keys storage. It is also stored in the Account_public_key so that we can downgrade the account back to an OpenZeppelin Account.

    Management Interface

    Each Validator Module can provide some management entrypoint to configure the module. In the case of the Stark Validator, the management methods are:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IPublicKeys<TState> {
        fn add_public_key(ref self: TState, new_public_key: felt252);
        fn get_public_keys(self: @TState) -> Array<felt252>;
        fn get_threshold(self: @TState) -> u8;
        fn remove_public_key(ref self: TState, old_public_key: felt252);
        fn set_threshold(ref self: TState, new_threshold: u8);
    }
    }

    As you can assess by their name:

    • add_public_key adds a public key into the account. Be careful that it does not remove the existing key that must be managed separately.
    • remove_public_key removes a public key from the account.
    • get_public_keys returns the list of current public keys registered with the account
    • set_threshold defines the number of signer that must sign a transaction or message for the signature to be valid
    • get_threshold list the current threshold of the account.

    Version Interface

    The Stark Validator implements the IVersion interface below:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IVersion<TState> {
        fn get_version(self: @TState) -> felt252;
        fn get_name(self: @TState) -> felt252;
    }
    }
    • get_name() returns stark-validator in a shortString
    • get_version() returns the version starting with a v, like v0.1.8 as a short string.

    Module Management Interface Mappers

    The management interface cannot be call on a class, they must be triggered on a contract. To workaround that issue, the account provides 2 entrypoints execute_on_module and call_on_module that can call the management interface from the account. The execute_on_module provides some additional security making sure that only the account signers can initiate those calls.

    To allow the remove access between the account calls and the management interface the validator requires the call and execute method are implemented and does map the input and output arguments correctly. That is the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IConfigure<TState> {
        fn call(self: @TState, call: Call) -> Array<felt252>;
        fn execute(ref self: TState, call: Call) -> Array<felt252>;
    }
    }

    In the case of the Stark Validator:

    • call can takes calls to get_public_keys, get_name, get_version and get_threshold.
    • execute execute calls to add_public_key, remove_public_keys and set_threshold.

    Note: To work the Call should include the following:

    • selector must be the selector for the management interface, i.e. the sn_keccak of the entrypoint name
    • to should be the account address
    • calldata should be the call data as defined by the ABI of the class

    The ETH and P256 Validator Module

    The Eth and P256 Validator Modules are implementations of a Validator Module for the Starknet Modular Account. They can both be used as the Core Validator or as a secondary Validator for the Account. This document explains the features, the configuration and some of the Internals of these modules.

    Validator Module

    A validator is a contract that implement the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    trait IValidator<TState> {
        fn validate(self: @TState, grantor_class: ClassHash, calls: Array<Call>) -> felt252;
    }
    }

    validate is used to validate a transaction on the account. It

    • gets the hash for the current transaction from the network
    • use is_valid_signature to check the signature is valid

    Note: the grantor class that is passed by the account is the Core Validator class hash registered with the account. In the case of the Eth and P256 Validator it is the module class hash. The validator does not use that parameter for now.

    Core Validator Interface

    In addition to the IValidator interface, The Eth and P256 Validator Modules implement the ICoreValidator interface. That is because they can be installed as a Core Validator Modules, i.e. the default Validator for the account. The interface looks like this:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait ICoreValidator<TState> {
        fn is_valid_signature(self: @TState, hash: Hash<felt252>, signature: Array<felt252>) -> felt252;
        fn initialize(ref self: TState, public_key: Array<felt252>);
    }
    }

    In the case of these Validators, the 2 functions are:

    • is_valid_signature. It checks a hash of a transaction or a hash of a message matches the account public keys of the current configurationm i.e stored in the account storage. It checks the elements of the signature are valid considering the public keys registered in the account
    • initialize is used at the installation time of the account to store the first account public key. In the case of the Eth and P256 Validator, the public key is managed by an array of 4 felt.

    Note: The downgrade from the account back to an OpenZeppelin Account as not been tested.

    Management Interface

    Each Validator Module can provide some management entrypoint to configure the module. The management methods for the 2 validators are:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IPublicKeys<TState> {
        fn set_public_key(ref self: TState, new_public_key: Array<felt252>);
        fn get_public_key(self: @TState) -> Array<felt252>;
    }
    }

    As you can assess by their name:

    • set_public_key changes the public key associated with the account. Be careful that it removes the existing key
    • get_public_key returns the elements of current public keys registered with the account

    Version Interface

    The Validator implements the IVersion interface below:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IVersion<TState> {
        fn get_version(self: @TState) -> felt252;
        fn get_name(self: @TState) -> felt252;
    }
    }
    • get_name() returns eth-validator for the ETH validator in a shortString. It returns p256-validator for the ETH validator in a shortString.
    • get_version() returns the version starting with a v, like v0.1.8 as a short string.

    Module Management Interface Mappers

    The management interface cannot be call on a class, they must be triggered on a contract. To workaround that issue, the account provides 2 entrypoints execute_on_module and call_on_module that can call the management interface from the account. The execute_on_module provides some additional security making sure that only the account signers can initiate those calls.

    To allow the remove access between the account calls and the management interface the validator requires the call and execute method are implemented and does map the input and output arguments correctly. That is the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IConfigure<TState> {
        fn call(self: @TState, call: Call) -> Array<felt252>;
        fn execute(ref self: TState, call: Call) -> Array<felt252>;
    }
    }

    In the case of the Eth Validator:

    • call can takes calls to get_public_key, get_name and get_version.
    • execute can execute calls to set_public_key.

    Note: To work the Call should include the following:

    • selector must be the selector for the management interface, i.e. the sn_keccak of the entrypoint name
    • to should be the account address
    • calldata should be the call data as defined by the ABI of the class and in the case of an EthPublicKey, it should be an array of 4 felts.

    The SessionKey Validator Module

    The SessionKey Validator Module is an implementation of a Validator Module for the Starknet Modular Account. It must be used as a secondary Validator for the Account and requires a Core Validator module to authorize the sessionkey. This document explains the features, the configuration and some of the Internals of this module.

    Note: To understand the process of requesting a session key authorization and signing the authorization, you should check the documentation for the Session Key Validator SDK

    Validator Module

    A validator is a contract that implement the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IValidator<TState> {
        fn validate(self: @TState, grantor_class: ClassHash, calls: Array<Call>) -> felt252;
    }
    }

    In the case of the sessionkey Validator the validate function checks the transaction signature is valid by:

    • making sure the session key has not been disabled with the module management interface.
    • extracting the session key data and making sure they are valid, signed by the core validator and still properly configured in the account.
    • check the transaction calls matches the policies associated with the session key by examining the merkle proofs of the signature and recomputing the merkle root with those proofs and the calls
    • check the transaction is signed by the private key that has been granted the access by the session key.

    Note: the grantor class that is passed by the account is the Core Validator class hash registered with the account. In the case of the SessionKey Validator it is used to check the session key authorization is actually valid with the Core Validator Signature.

    Core Validator Interface

    This module cannot be used as a Core Validator. That is because the session key needs to be authorized by the Core Validator Signer to be used. As a result, it does not implement the ICoreValidator interface. In addition, a message cannot be signed by a session key simply because the policy cannot apply to it and there is no way to check a transaction hash is valid without the calls. That is why the is_valid_signature cannot be implemented for that case.

    Management Interface

    Each Validator Module can provide some management entrypoint to configure the module. In the case of the Stark Validator, the management methods are:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IDisableSessionKey<TState> {
        fn disable_session_key(ref self: TState, sessionkey: felt252);
        fn is_disabled_session_key(self: @TState, sessionkey: felt252) -> bool;
    }
    }

    As you can assess by their name:

    • disable_session_key register the hash of the session key in the account to block a future attempt to use it again. Note that disabling is permanent and a session key must be re-emitted if necessary
    • is_disabled_session_key list if a session key has been registered with the disabled session keys

    Module Management Interface Mappers

    The management interface cannot be call on a class, they must be triggered on a contract. To workaround that issue, the account provides 2 entrypoints execute_on_module and call_on_module that can call the management interface from the account. The execute_on_module provides some additional security making sure that only the account signers can initiate those calls.

    To allow the remove access between the account calls and the management interface the validator requires the call and execute method are implemented and does map the input and output arguments correctly. That is the following interface:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IConfigure<TState> {
        fn call(self: @TState, call: Call) -> Array<felt252>;
        fn execute(ref self: TState, call: Call) -> Array<felt252>;
    }
    }

    In the case of the Stark Validator:

    • call takes calls to is_disabled_session_key and match the input/output on the account.
    • execute takes calls to disable_session_key and match the input/output on the account.

    Note: To work the Call should include the following:

    • selector must be the selector for the management interface, i.e. the sn_keccak of the entrypoint name
    • to should be the account address
    • calldata should be the call data as defined by the ABI of the class

    Version Interface

    The Session Key Validator implements the IVersion interface below:

    #![allow(unused)]
    fn main() {
    #[starknet::interface]
    pub trait IVersion<TState> {
        fn get_version(self: @TState) -> felt252;
        fn get_name(self: @TState) -> felt252;
    }
    }
    • get_name() returns sessionkey-validator in a shortString
    • get_version() returns the version starting with a v, like v0.1.8 as a short string.

    Roadmap and Known Issues

    The starknet modular account is a work-in-progress effort to provide features to dapps and provide better experience to Starknet. As such, there is a lot to work on and this section gives some ideas of the direction the project will take the coming weeks and months.

    Roadmap

    Ideas to enhance the account are legions. However, we plan to stay focus on a small set of features:

    1. Develop a Guarded Validator. This would require it to be a core validators. It would provide more value for the modular account because the implementation requires some different signature depending on the calls so it would validate/invalidate the current set of interfaces.
    2. Add an entrypoint to allow execute_from_outside with the signature from the core validator and some limitation. This entrypoint would require to manage a user defined Nonce to prevent replay-scenarios. It would also battle test the model. The benefit from that entrypoint besides is that it allows a 3rd party to pay for your transaction. A consolation prize for the paymaster to not be implemented yet.
    3. Move the Validator Module data from a prefix call to the account signature. This might not be feasible but it makes sense because the validation is supposed to rely on the signature.
    4. Add support for Executor Modules. Some scenario like the ability to delay the execution of a transaction or the ability to track some data like an amount of ERC20 dedicated to a 3rd party requires those modules to work.
    5. Add support for the version 3 of the transaction as described in SNIP-8.
    6. Ensure the compatibility between session key and SNIP-12.
    7. Check what can be done to support upgrades from OpenZeppelin, Argent and Braavo Accounts

    If you need support for another scenario, feel free to open an issue on Github.

    Known Issues

    In addition to the planned changes above, there are a number of smaller issues that have been identified and need to be addressed. Most of them are implementation details bit some of them might impact your usage. Those issues are the following:

    • Version the contracts for both accounts and modules and maintain a compatibility matrix. Actually we should check if we can rely on the boostrap experiment to have a more stable account address stability and introduce a contract that manages versions and allow to initiate some sort of registry.
    • Improve the upgrade management with the help of the bootstrap experiment. Right now the upgrade works because it is actually a downgrade and move back. In reality it will not pass a test of an upgrade with an Argent, Braavos or Openzeppelin Account.
    • Right now, type conversions are done manually with the core::traits::Into package. Improve it so that is it more readable and consistent with how other libraries like openzeppelin does.
    • Reduce, as much as possible the SDKs API surface to make it simpler to use for developers.
    • Associate class versions with class hash in the documentation and version the documentation so that we can keep track of the version history
    • It is possible to get a sessionkey that has all accesses on an account. We need to disable that feature to force dapps to requests what they want and for users to review policies.
    • For a better understanding of the sessionkey flow in the SDK we should sign directly the request and not the SessionKeyModule
    • Check when OpenZeppelin uses Poseidon Hash and see if that impacts the Eth module.
    • Fees are not computed correctly when a large part comes from the signature and as a result, the deploy_account has a fixed maxFee. Improve the computation and remove that fix value.
    • Check existing audits and see if the recommendations apply. If yes, apply them.

    SDK Reference Documentation

    This section provides the generated reference documentation for the Typescript/Javascript SDKs that comes with the project. For a better understanding of those SDKs, check the Using SDKs section.

    The 3 SDKs can be downloaded from npmjs.com.

    • @0xknwn/starknet-modular-account extends the starknet.js Account to support multiple signers and manage modules. It also provides the AccountModuleInterface that should be used by module SDKs. You can check the reference documentation for this SDK here
    • @0xknwn/starknet-module-sessionkey provides the SessionKeyModule that implements the AccountModuleInterface as well as tools to configure the sessionkey module, including the PolicyManager and the PolicyGrantor classes. You can check the reference documentation for this SDK here
    • @0xknwn/starknet-module provides the EthModule that implements the AccountModuleInterface. To sign transaction, you can simply use the Starknet.js EthSigner. You can check the reference documentation for this SDK here

    In addition, the project provides another SDK called @0xknwn/starknet-test-helpers that can be used to create helper classes outside of this repository. That project is used to help building demonstration and/or tests. In particular in includes the tools to 2 contracts named Counter and SwapRouter. You can check the reference documentation for this SDK here.

    @0xknwn/starknet-modular-account / Exports

    @0xknwn/starknet-modular-account

    Table of contents

    Classes

    Interfaces

    Type Aliases

    Variables

    Functions

    Type Aliases

    Authorization

    Ƭ Authorization: Object

    Type declaration

    NameType
    accountAddressstring
    authKeystring
    chainIdstring
    expiresstring
    grantorClass?string
    hash?string
    rootstring
    selectorstring
    signaturestring[]
    validatorClassstring

    Defined in

    sdks/account/src/smartr_account.ts:27

    Variables

    POLICY_TYPE_HASH

    Const POLICY_TYPE_HASH: string

    Defined in

    sdks/account/src/message.ts:5


    SESSION_TYPE_HASH

    Const SESSION_TYPE_HASH: string

    Defined in

    sdks/account/src/message.ts:4


    STARKNET_DOMAIN_TYPE_HASH

    Const STARKNET_DOMAIN_TYPE_HASH: string

    Defined in

    sdks/account/src/message.ts:3


    SmartrAccountABI

    Const SmartrAccountABI: readonly [{ interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; name: "UpgradeableImpl" = "UpgradeableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_class_hash" = "new_class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "upgrade" = "upgrade"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; type: "interface" = "interface" }, { interface_name: "smartr::component::account::ISRC6" = "smartr::component::account::ISRC6"; name: "SRC6Impl" = "SRC6Impl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "__execute__" = "__execute__"; outputs: readonly [{ type: "core::array::Array::<core::array::Span::<core::felt252>>" = "core::array::Array::<core::array::Span::<core::felt252>>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "__validate__" = "__validate__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::account::ISRC6" = "smartr::component::account::ISRC6"; type: "interface" = "interface" }, { interface_name: "smartr::component::account::IDeclarer" = "smartr::component::account::IDeclarer"; name: "DeclarerImpl" = "DeclarerImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::felt252" = "core::felt252" }] ; name: "__validate_declare__" = "__validate_declare__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::account::IDeclarer" = "smartr::component::account::IDeclarer"; type: "interface" = "interface" }, { interface_name: "smartr::component::account::IDeployable" = "smartr::component::account::IDeployable"; name: "DeployableImpl" = "DeployableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::felt252" = "core::felt252" }, { name: "contract_address_salt" = "contract_address_salt"; type: "core::felt252" = "core::felt252" }, { name: "core_validator" = "core_validator"; type: "core::felt252" = "core::felt252" }, { name: "public_key" = "public_key"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "__validate_deploy__" = "__validate_deploy__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::account::IDeployable" = "smartr::component::account::IDeployable"; type: "interface" = "interface" }, { interface_name: "smartr::component::account::IModule" = "smartr::component::account::IModule"; name: "ModuleImpl" = "ModuleImpl"; type: "impl" = "impl" }, { name: "core::bool" = "core::bool"; type: "enum" = "enum"; variants: readonly [{ name: "False" = "False"; type: "()" = "()" }, { name: "True" = "True"; type: "()" = "()" }] }, { items: readonly [{ inputs: readonly [{ name: "calldata" = "calldata"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "__module_validate__" = "__module_validate__"; outputs: readonly [] = []; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "add_module" = "add_module"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "remove_module" = "remove_module"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "forward_validate_module" = "forward_validate_module"; type: "core::bool" = "core::bool" }] ; name: "update_core_module" = "update_core_module"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_core_module" = "get_core_module"; outputs: readonly [{ type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "is_validate_module_forwarded" = "is_validate_module_forwarded"; outputs: readonly [{ type: "core::bool" = "core::bool" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "is_module" = "is_module"; outputs: readonly [{ type: "core::bool" = "core::bool" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call_on_module" = "call_on_module"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute_on_module" = "execute_on_module"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::account::IModule" = "smartr::component::account::IModule"; type: "interface" = "interface" }, { interface_name: "openzeppelin::introspection::interface::ISRC5" = "openzeppelin::introspection::interface::ISRC5"; name: "SRC5Impl" = "SRC5Impl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "interface_id" = "interface_id"; type: "core::felt252" = "core::felt252" }] ; name: "supports_interface" = "supports_interface"; outputs: readonly [{ type: "core::bool" = "core::bool" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "openzeppelin::introspection::interface::ISRC5" = "openzeppelin::introspection::interface::ISRC5"; type: "interface" = "interface" }, { inputs: readonly [{ name: "core_validator" = "core_validator"; type: "core::felt252" = "core::felt252" }, { name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "data" = "data"; name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "Upgraded" = "Upgraded"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" }] }, { kind: "enum" = "enum"; name: "smartr::account::smartraccount::SmartrAccount::Event" = "smartr::account::smartraccount::SmartrAccount::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "UpgradeableEvent" = "UpgradeableEvent"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" }] }]

    Defined in

    sdks/account/src/abi/SmartrAccount.ts:1


    StarkValidatorABI

    Const StarkValidatorABI: readonly [{ interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; name: "CoreValidator" = "CoreValidator"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "initialize" = "initialize"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { interface_name: "smartr::modules::starkvalidator::starkvalidator::IPublicKey" = "smartr::modules::starkvalidator::starkvalidator::IPublicKey"; name: "PublicKey" = "PublicKey"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_public_key" = "new_public_key"; type: "core::felt252" = "core::felt252" }] ; name: "set_public_key" = "set_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_public_key" = "get_public_key"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::modules::starkvalidator::starkvalidator::IPublicKey" = "smartr::modules::starkvalidator::starkvalidator::IPublicKey"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::starkvalidator::starkvalidator::StarkValidator::Event" = "smartr::modules::starkvalidator::starkvalidator::StarkValidator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    sdks/account/src/abi/StarkValidator.ts:1

    Functions

    accountAddress

    accountAddress(accountName, salt, constructorCallData): string

    Calculates the account address for a given account name, public key, and constructor call data.

    Parameters

    NameTypeDescription
    accountName"SmartrAccount"-
    saltstring-
    constructorCallDatastring[]The constructor call data for the account.

    Returns

    string

    The calculated account address.

    Remarks

    This function requires the cairo account to be compiled with the scarb build command at the root of the project.

    Defined in

    sdks/account/src/contract.ts:14


    classHash

    classHash(className?): string

    Computes the hash of the requested class that is part of the 0xknwn/starknet-modular-account project.

    Parameters

    NameTypeDefault valueDescription
    className"StarkValidator" | "SmartrAccount" | "SimpleValidator""SmartrAccount"The name of the contract class.

    Returns

    string

    The hash of the contract class.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project.

    Defined in

    sdks/account/src/class.ts:18


    declareClass

    declareClass(account, className?): Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    If not already declared, declare the requested class from the 0xknwn/starknet-modular-account project to the Starknet network used by the provided account.

    Parameters

    NameTypeDefault valueDescription
    accountAccountundefinedThe starknet.js account used to declare the class.
    className"StarkValidator" | "SmartrAccount" | "SimpleValidator""SmartrAccount"The name of the class to declare. Defaults to "SmartrAccount".

    Returns

    Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    An object containing the declared class hash and the transaction receipt if the class was not already declared.

    Throws

    An error if the class deployment fails.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project. It also requires the account to have enough funds to declare the class to the Starknet network.

    Defined in

    sdks/account/src/class.ts:58


    deployAccount

    deployAccount(deployerAccount, accountName, salt, constructorCalldata): Promise<string>

    Deploys an account on the StarkNet network.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe account used to deploy the new account.
    accountName"SmartrAccount"The name of the account to be deployed.
    saltstring-
    constructorCalldataany[]The constructor calldata required for deploying the account.

    Returns

    Promise<string>

    The address of the deployed account.

    Throws

    Error if the deployment fails.

    Defined in

    sdks/account/src/contract.ts:38


    hash_auth_message

    hash_auth_message(account_address, validator_class, grantor_class, auth_key, expires, root, chain_id): string

    Parameters

    NameType
    account_addressstring
    validator_classstring
    grantor_classstring
    auth_keystring
    expiresstring
    rootstring
    chain_idstring

    Returns

    string

    Defined in

    sdks/account/src/message.ts:7


    signatureToHexArray

    signatureToHexArray(signature): ArraySignatureType

    Generates a signature represented as an array of hexadecimal.

    Parameters

    NameTypeDescription
    signatureSignatureThe signature to handle.

    Returns

    ArraySignatureType

    The signature as an array.

    Defined in

    sdks/account/src/smartr_account.ts:49

    @0xknwn/starknet-modular-account / Exports / SmartrAccount

    Class: SmartrAccount

    Represents a SmartrAccount.

    Hierarchy

    • Account

      SmartrAccount

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new SmartrAccount(providerOrOptions, address, pkOrSigner, module?, cairoVersion?, transactionVersion?): SmartrAccount

    Parameters

    NameTypeDefault value
    providerOrOptionsProviderInterface | ProviderOptionsundefined
    addressstringundefined
    pkOrSignerstring | Uint8Array | SignerInterfaceundefined
    moduleundefined | AccountModuleInterfaceundefined
    cairoVersion?CairoVersionundefined
    transactionVersionanyRPC.ETransactionVersion.V2

    Returns

    SmartrAccount

    Overrides

    Account.constructor

    Defined in

    sdks/account/src/smartr_account.ts:76

    Properties

    address

    address: string

    Inherited from

    Account.address

    Defined in

    node_modules/starknet/dist/index.d.ts:3738


    cairoVersion

    cairoVersion: CairoVersion

    Inherited from

    Account.cairoVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3739


    channel

    channel: RpcChannel | RpcChannel$1

    Inherited from

    Account.channel

    Defined in

    node_modules/starknet/dist/index.d.ts:3196


    deploySelf

    deploySelf: (__namedParameters: DeployAccountContractPayload, details?: UniversalDetails) => Promise<DeployContractResponse>

    Type declaration

    ▸ («destructured», details?): Promise<DeployContractResponse>

    Parameters
    NameType
    «destructured»DeployAccountContractPayload
    details?UniversalDetails
    Returns

    Promise<DeployContractResponse>

    Inherited from

    Account.deploySelf

    Defined in

    node_modules/starknet/dist/index.d.ts:3770


    getStateUpdate

    getStateUpdate: () => Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>(blockIdentifier: "pending") => Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>(blockIdentifier: "latest") => Promise<{ block_hash: string ; new_root: string ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>(blockIdentifier?: BlockIdentifier) => Promise<StateUpdateResponse>

    Type declaration

    ▸ (): Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Returns

    Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    ▸ (blockIdentifier): Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Parameters
    NameType
    blockIdentifier"pending"
    Returns

    Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    ▸ (blockIdentifier): Promise<{ block_hash: string ; new_root: string ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Parameters
    NameType
    blockIdentifier"latest"
    Returns

    Promise<{ block_hash: string ; new_root: string ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    ▸ (blockIdentifier?): Promise<StateUpdateResponse>

    Parameters
    NameType
    blockIdentifier?BlockIdentifier
    Returns

    Promise<StateUpdateResponse>

    Inherited from

    Account.getStateUpdate

    Defined in

    node_modules/starknet/dist/index.d.ts:3233


    module

    module: undefined | AccountModuleInterface

    Defined in

    sdks/account/src/smartr_account.ts:74


    signer

    signer: SignerInterface

    Inherited from

    Account.signer

    Defined in

    node_modules/starknet/dist/index.d.ts:3737


    transactionVersion

    Readonly transactionVersion: V2 | V3

    Inherited from

    Account.transactionVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3740

    Methods

    accountInvocationsFactory

    accountInvocationsFactory(invocations, details): Promise<AccountInvocations>

    Parameters

    NameType
    invocationsInvocations
    detailsAccountInvocationsFactoryDetails

    Returns

    Promise<AccountInvocations>

    Inherited from

    Account.accountInvocationsFactory

    Defined in

    node_modules/starknet/dist/index.d.ts:3793


    addModule

    addModule(class_hash, execute?): Promise<{ transaction_hash: string }>

    Add a module to an account.

    Parameters

    NameTypeDescription
    class_hashstringthe module to add
    execute?trueIf true, the transaction is executed, otherwise it is built and returned so that it can be used in a multicall.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the transaction receipt if executes is true, otherwise it returns the transaction call.

    Defined in

    sdks/account/src/smartr_account.ts:428

    addModule(class_hash, execute): Promise<Call[]>

    Parameters

    NameType
    class_hashstring
    executefalse

    Returns

    Promise<Call[]>

    Defined in

    sdks/account/src/smartr_account.ts:432


    buildAccountDeployPayload

    buildAccountDeployPayload(«destructured», details): Promise<DeployAccountContractTransaction>

    Parameters

    NameType
    «destructured»DeployAccountContractPayload
    detailsInvocationsSignerDetails

    Returns

    Promise<DeployAccountContractTransaction>

    Inherited from

    Account.buildAccountDeployPayload

    Defined in

    node_modules/starknet/dist/index.d.ts:3791


    buildDeclarePayload

    buildDeclarePayload(payload, details): Promise<DeclareContractTransaction>

    Parameters

    NameType
    payloadDeclareContractPayload
    detailsInvocationsSignerDetails

    Returns

    Promise<DeclareContractTransaction>

    Inherited from

    Account.buildDeclarePayload

    Defined in

    node_modules/starknet/dist/index.d.ts:3790


    buildInvocation

    buildInvocation(call, details): Promise<Invocation>

    Parameters

    NameType
    callCall[]
    detailsInvocationsSignerDetails

    Returns

    Promise<Invocation>

    Inherited from

    Account.buildInvocation

    Defined in

    node_modules/starknet/dist/index.d.ts:3789


    buildUDCContractPayload

    buildUDCContractPayload(payload): Call[]

    Parameters

    NameType
    payloadUniversalDeployerContractPayload | UniversalDeployerContractPayload[]

    Returns

    Call[]

    Inherited from

    Account.buildUDCContractPayload

    Defined in

    node_modules/starknet/dist/index.d.ts:3792


    callContract

    callContract(call, blockIdentifier?): Promise<string[]>

    Parameters

    NameType
    callCall
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string[]>

    Inherited from

    Account.callContract

    Defined in

    node_modules/starknet/dist/index.d.ts:3287


    callOnModule

    callOnModule(module_class_hash, module_entrypoint, calldata): Promise<BigNumberish[]>

    Call an entrypoint on the module account.

    Parameters

    NameTypeDescription
    module_class_hashstringThe installed module class_hash.
    module_entrypointstringThe module entrypoint to call.
    calldatastring[]The entrypoint calldata.

    Returns

    Promise<BigNumberish[]>

    A promise that resolves to the call output.

    Defined in

    sdks/account/src/smartr_account.ts:374


    declare

    declare(payload, details?): Promise<{ class_hash: string ; transaction_hash: string }>

    Parameters

    NameType
    payloadDeclareContractPayload
    details?UniversalDetails

    Returns

    Promise<{ class_hash: string ; transaction_hash: string }>

    Inherited from

    Account.declare

    Defined in

    node_modules/starknet/dist/index.d.ts:3766


    declareAndDeploy

    declareAndDeploy(payload, details?): Promise<DeclareDeployUDCResponse>

    Parameters

    NameType
    payloadDeclareAndDeployContractPayload
    details?UniversalDetails

    Returns

    Promise<DeclareDeployUDCResponse>

    Inherited from

    Account.declareAndDeploy

    Defined in

    node_modules/starknet/dist/index.d.ts:3769


    declareContract

    declareContract(transaction, details): Promise<DeclaredTransaction>

    Parameters

    NameType
    transactionDeclareContractTransaction
    detailsInvocationsDetailsWithNonce

    Returns

    Promise<DeclaredTransaction>

    Inherited from

    Account.declareContract

    Defined in

    node_modules/starknet/dist/index.d.ts:3285


    declareIfNot

    declareIfNot(payload, transactionsDetail?): Promise<{ class_hash: string ; transaction_hash: string }>

    First check if contract is already declared, if not declare it If contract already declared returned transaction_hash is ''. Method will pass even if contract is already declared

    Parameters

    NameTypeDescription
    payloadDeclareContractPayload-
    transactionsDetail?UniversalDetails(optional)

    Returns

    Promise<{ class_hash: string ; transaction_hash: string }>

    Inherited from

    Account.declareIfNot

    Defined in

    node_modules/starknet/dist/index.d.ts:3765


    deploy

    deploy(payload, details?): Promise<MultiDeployContractResponse>

    Parameters

    NameType
    payloadUniversalDeployerContractPayload | UniversalDeployerContractPayload[]
    details?UniversalDetails

    Returns

    Promise<MultiDeployContractResponse>

    Inherited from

    Account.deploy

    Defined in

    node_modules/starknet/dist/index.d.ts:3767


    deployAccount

    deployAccount(«destructured», details?): Promise<DeployContractResponse>

    Parameters

    NameType
    «destructured»DeployAccountContractPayload
    details?UniversalDetails

    Returns

    Promise<DeployContractResponse>

    Inherited from

    Account.deployAccount

    Defined in

    node_modules/starknet/dist/index.d.ts:3771


    deployAccountContract

    deployAccountContract(transaction, details): Promise<DeployedAccountTransaction>

    Parameters

    NameType
    transactionDeployAccountContractTransaction
    detailsInvocationsDetailsWithNonce

    Returns

    Promise<DeployedAccountTransaction>

    Inherited from

    Account.deployAccountContract

    Defined in

    node_modules/starknet/dist/index.d.ts:3286


    deployContract

    deployContract(payload, details?): Promise<DeployContractUDCResponse>

    Parameters

    NameType
    payloadUniversalDeployerContractPayload | UniversalDeployerContractPayload[]
    details?UniversalDetails

    Returns

    Promise<DeployContractUDCResponse>

    Inherited from

    Account.deployContract

    Defined in

    node_modules/starknet/dist/index.d.ts:3768


    estimateAccountDeployFee

    estimateAccountDeployFee(«destructured», details?): Promise<EstimateFee>

    Parameters

    NameType
    «destructured»DeployAccountContractPayload
    details?UniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.estimateAccountDeployFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3753


    estimateDeclareFee

    estimateDeclareFee(payload, details?): Promise<EstimateFee>

    Parameters

    NameType
    payloadDeclareContractPayload
    details?UniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.estimateDeclareFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3752


    estimateDeployFee

    estimateDeployFee(payload, details?): Promise<EstimateFee>

    Parameters

    NameType
    payloadUniversalDeployerContractPayload | UniversalDeployerContractPayload[]
    details?UniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.estimateDeployFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3754


    estimateFee

    estimateFee(calls, estimateFeeDetails?): Promise<EstimateFee>

    Parameters

    NameType
    callsAllowArray<Call>
    estimateFeeDetails?UniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.estimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3750


    estimateFeeBulk

    estimateFeeBulk(invocations, details?): Promise<EstimateFeeBulk>

    Parameters

    NameType
    invocationsInvocations
    details?UniversalDetails

    Returns

    Promise<EstimateFeeBulk>

    Inherited from

    Account.estimateFeeBulk

    Defined in

    node_modules/starknet/dist/index.d.ts:3755


    estimateInvokeFee

    estimateInvokeFee(calls, details?): Promise<EstimateFee>

    Parameters

    NameType
    callsAllowArray<Call>
    details?UniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.estimateInvokeFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3751


    estimateMessageFee

    estimateMessageFee(message, blockIdentifier?): Promise<FEE_ESTIMATE>

    NEW: Estimate the fee for a message from L1

    Parameters

    NameTypeDescription
    messageMSG_FROM_L1Message From L1
    blockIdentifier?BlockIdentifier-

    Returns

    Promise<FEE_ESTIMATE>

    Inherited from

    Account.estimateMessageFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3292


    execute

    execute(transactions, transactionsDetail?): Promise<{ transaction_hash: string }>

    Executes a set of transactions on the StarkNet network.

    Parameters

    NameTypeDescription
    transactionsAllowArray<Call>An array of transactions to be executed.
    transactionsDetail?UniversalDetailsOptional object containing additional details for the transactions.

    Returns

    Promise<{ transaction_hash: string }>

    A Promise that resolves to an InvokeFunctionResponse object representing the result of the execution.

    Overrides

    Account.execute

    Defined in

    sdks/account/src/smartr_account.ts:236

    execute(transactions, abis?, transactionsDetail?): Promise<{ transaction_hash: string }>

    Executes a set of transactions on the StarkNet network.

    Parameters

    NameTypeDescription
    transactionsAllowArray<Call>An array of transactions to be executed.
    abis?Abi[]Optional argument that can be an array of ABIs.
    transactionsDetail?UniversalDetailsOptional object containing additional details for the transactions.

    Returns

    Promise<{ transaction_hash: string }>

    A Promise that resolves to an InvokeFunctionResponse object representing the result of the execution.

    Overrides

    Account.execute

    Defined in

    sdks/account/src/smartr_account.ts:249


    executeMultisig

    executeMultisig(transactions, details, signature): Promise<{ transaction_hash: string }>

    Executes a set of transactions, assuming they have been signed by all parties.

    Parameters

    NameTypeDescription
    transactionsCall[]An array of transactions to be executed.
    detailsInvocationsDetailsWithNonceOptional object containing additional details for the transactions.
    signatureArraySignatureTypeThe signature of the transactions.

    Returns

    Promise<{ transaction_hash: string }>

    A Promise that resolves to the transactions invocation response.

    Defined in

    sdks/account/src/smartr_account.ts:195


    executeOnModule

    executeOnModule(module_class_hash, module_entrypoint, calldata, execute?): Promise<{ transaction_hash: string }>

    Execute or build a transaction on the module account.

    Parameters

    NameTypeDescription
    module_class_hashstringThe installed module class_hash.
    module_entrypointstringThe module entrypoint to execute.
    calldatastring[]The entrypoint calldata.
    execute?trueIf true, the transaction is executed, otherwise it is built and returned so that it can be used in a multicall.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the transaction receipt if executes is true, otherwise it returns the transaction call.

    Defined in

    sdks/account/src/smartr_account.ts:329

    executeOnModule(module_class_hash, module_entrypoint, calldata, execute): Promise<Call[]>

    Parameters

    NameType
    module_class_hashstring
    module_entrypointstring
    calldatastring[]
    executefalse

    Returns

    Promise<Call[]>

    Defined in

    sdks/account/src/smartr_account.ts:335


    fetch

    fetch(method, params?, id?): Promise<Response>

    Parameters

    NameType
    methodstring
    params?object
    id?string | number

    Returns

    Promise<Response>

    Inherited from

    Account.fetch

    Defined in

    node_modules/starknet/dist/index.d.ts:3198


    getAddressFromStarkName

    getAddressFromStarkName(name, StarknetIdContract?): Promise<string>

    Parameters

    NameType
    namestring
    StarknetIdContract?string

    Returns

    Promise<string>

    Inherited from

    Account.getAddressFromStarkName

    Defined in

    node_modules/starknet/dist/index.d.ts:3307


    getBlock

    getBlock(): Promise<PendingBlock>

    Returns

    Promise<PendingBlock>

    Inherited from

    Account.getBlock

    Defined in

    node_modules/starknet/dist/index.d.ts:3202

    getBlock(blockIdentifier): Promise<PendingBlock>

    Parameters

    NameType
    blockIdentifier"pending"

    Returns

    Promise<PendingBlock>

    Inherited from

    Account.getBlock

    Defined in

    node_modules/starknet/dist/index.d.ts:3203

    getBlock(blockIdentifier): Promise<Block$1>

    Parameters

    NameType
    blockIdentifier"latest"

    Returns

    Promise<Block$1>

    Inherited from

    Account.getBlock

    Defined in

    node_modules/starknet/dist/index.d.ts:3204

    getBlock(blockIdentifier?): Promise<GetBlockResponse>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<GetBlockResponse>

    Inherited from

    Account.getBlock

    Defined in

    node_modules/starknet/dist/index.d.ts:3205


    getBlockLatestAccepted

    getBlockLatestAccepted(): Promise<BlockHashAndNumber>

    Get the most recent accepted block hash and number

    Returns

    Promise<BlockHashAndNumber>

    Inherited from

    Account.getBlockLatestAccepted

    Defined in

    node_modules/starknet/dist/index.d.ts:3209


    getBlockNumber

    getBlockNumber(): Promise<number>

    Get the most recent accepted block number redundant use getBlockLatestAccepted();

    Returns

    Promise<number>

    Number of the latest block

    Inherited from

    Account.getBlockNumber

    Defined in

    node_modules/starknet/dist/index.d.ts:3215


    getBlockStateUpdate

    getBlockStateUpdate(): Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Returns

    Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Inherited from

    Account.getBlockStateUpdate

    Defined in

    node_modules/starknet/dist/index.d.ts:3239

    getBlockStateUpdate(blockIdentifier): Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Parameters

    NameType
    blockIdentifier"pending"

    Returns

    Promise<{ block_hash: never ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Inherited from

    Account.getBlockStateUpdate

    Defined in

    node_modules/starknet/dist/index.d.ts:3240

    getBlockStateUpdate(blockIdentifier): Promise<{ block_hash: string ; new_root: string ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Parameters

    NameType
    blockIdentifier"latest"

    Returns

    Promise<{ block_hash: string ; new_root: string ; old_root: string ; state_diff: { declared_classes: { class_hash: string ; compiled_class_hash: string }[] ; deployed_contracts: { address: string ; class_hash: string }[] ; deprecated_declared_classes: string[] ; nonces: { contract_address: string ; nonce: string }[] ; replaced_classes: { class_hash: string ; contract_address: string }[] ; storage_diffs: { address: string ; storage_entries: { key: string ; value: string }[] }[] } }>

    Inherited from

    Account.getBlockStateUpdate

    Defined in

    node_modules/starknet/dist/index.d.ts:3241

    getBlockStateUpdate(blockIdentifier?): Promise<StateUpdateResponse>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<StateUpdateResponse>

    Inherited from

    Account.getBlockStateUpdate

    Defined in

    node_modules/starknet/dist/index.d.ts:3242


    getBlockTransactionCount

    getBlockTransactionCount(blockIdentifier?): Promise<number>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<number>

    Inherited from

    Account.getBlockTransactionCount

    Defined in

    node_modules/starknet/dist/index.d.ts:3244


    getBlockTransactionsTraces

    getBlockTransactionsTraces(blockIdentifier?): Promise<BlockTransactionsTraces>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<BlockTransactionsTraces>

    Inherited from

    Account.getBlockTransactionsTraces

    Defined in

    node_modules/starknet/dist/index.d.ts:3243


    getBlockWithReceipts

    getBlockWithReceipts(blockIdentifier?): Promise<BlockWithTxReceipts>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<BlockWithTxReceipts>

    Inherited from

    Account.getBlockWithReceipts

    Defined in

    node_modules/starknet/dist/index.d.ts:3232


    getBlockWithTxHashes

    getBlockWithTxHashes(blockIdentifier?): Promise<BlockWithTxHashes$1>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<BlockWithTxHashes$1>

    Inherited from

    Account.getBlockWithTxHashes

    Defined in

    node_modules/starknet/dist/index.d.ts:3216


    getBlockWithTxs

    getBlockWithTxs(blockIdentifier?): Promise<BlockWithTxs>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<BlockWithTxs>

    Inherited from

    Account.getBlockWithTxs

    Defined in

    node_modules/starknet/dist/index.d.ts:3217


    getCairoVersion

    getCairoVersion(classHash?): Promise<CairoVersion>

    Retrieves the Cairo version from the network and sets cairoVersion if not already set in the constructor.

    Parameters

    NameTypeDescription
    classHash?stringif provided detects Cairo version from classHash, otherwise from the account address

    Returns

    Promise<CairoVersion>

    Inherited from

    Account.getCairoVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3749


    getChainId

    getChainId(): Promise<StarknetChainId>

    Returns

    Promise<StarknetChainId>

    Inherited from

    Account.getChainId

    Defined in

    node_modules/starknet/dist/index.d.ts:3199


    getClass

    getClass(classHash, blockIdentifier?): Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Parameters

    NameType
    classHashBigNumberish
    blockIdentifier?BlockIdentifier

    Returns

    Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Inherited from

    Account.getClass

    Defined in

    node_modules/starknet/dist/index.d.ts:3272


    getClassAt

    getClassAt(contractAddress, blockIdentifier?): Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Parameters

    NameType
    contractAddressBigNumberish
    blockIdentifier?BlockIdentifier

    Returns

    Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Inherited from

    Account.getClassAt

    Defined in

    node_modules/starknet/dist/index.d.ts:3273


    getClassByHash

    getClassByHash(classHash): Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Parameters

    NameType
    classHashBigNumberish

    Returns

    Promise<LegacyContractClass | Omit<CompiledSierra, "sierra_program_debug_info">>

    Inherited from

    Account.getClassByHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3271


    getClassHashAt

    getClassHashAt(contractAddress, blockIdentifier?): Promise<string>

    Parameters

    NameType
    contractAddressBigNumberish
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string>

    Inherited from

    Account.getClassHashAt

    Defined in

    node_modules/starknet/dist/index.d.ts:3270


    getContractVersion

    getContractVersion(contractAddress, classHash?, options?): Promise<ContractVersion>

    Parameters

    NameType
    contractAddressBigNumberish
    classHash?undefined
    options?getContractVersionOptions

    Returns

    Promise<ContractVersion>

    Inherited from

    Account.getContractVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3274

    getContractVersion(contractAddress, classHash, options?): Promise<ContractVersion>

    Parameters

    NameType
    contractAddressundefined
    classHashBigNumberish
    options?getContractVersionOptions

    Returns

    Promise<ContractVersion>

    Inherited from

    Account.getContractVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3275


    getDeclareEstimateFee

    getDeclareEstimateFee(invocation, details, blockIdentifier?, skipValidate?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    invocationDeclareContractTransaction
    detailsInvocationsDetailsWithNonce
    blockIdentifier?BlockIdentifier
    skipValidate?boolean

    Returns

    Promise<EstimateFeeResponse>

    Inherited from

    Account.getDeclareEstimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3281


    getDeployAccountEstimateFee

    getDeployAccountEstimateFee(invocation, details, blockIdentifier?, skipValidate?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    invocationDeployAccountContractTransaction
    detailsInvocationsDetailsWithNonce
    blockIdentifier?BlockIdentifier
    skipValidate?boolean

    Returns

    Promise<EstimateFeeResponse>

    Inherited from

    Account.getDeployAccountEstimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3282


    getEstimateFee

    getEstimateFee(invocation, invocationDetails, blockIdentifier?, skipValidate?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    invocationInvocation
    invocationDetailsInvocationsDetailsWithNonce
    blockIdentifier?BlockIdentifier
    skipValidate?boolean

    Returns

    Promise<EstimateFeeResponse>

    Deprecated

    use gettypeEstimateFee (will be refactored based on type after sequencer deprecation)

    Inherited from

    Account.getEstimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3279


    getEstimateFeeBulk

    getEstimateFeeBulk(invocations, options): Promise<EstimateFeeResponseBulk>

    Parameters

    NameType
    invocationsAccountInvocations
    optionsgetEstimateFeeBulkOptions

    Returns

    Promise<EstimateFeeResponseBulk>

    Inherited from

    Account.getEstimateFeeBulk

    Defined in

    node_modules/starknet/dist/index.d.ts:3283


    getEvents

    getEvents(eventFilter): Promise<EVENTS_CHUNK>

    Returns all events matching the given filter

    Parameters

    NameType
    eventFilterEventFilter

    Returns

    Promise<EVENTS_CHUNK>

    events and the pagination of the events

    Inherited from

    Account.getEvents

    Defined in

    node_modules/starknet/dist/index.d.ts:3302


    getInvokeEstimateFee

    getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier?, skipValidate?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    invocationInvocation
    invocationDetailsInvocationsDetailsWithNonce
    blockIdentifier?BlockIdentifier
    skipValidate?boolean

    Returns

    Promise<EstimateFeeResponse>

    Inherited from

    Account.getInvokeEstimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3280


    getL1GasPrice

    getL1GasPrice(blockIdentifier?): Promise<string>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string>

    Inherited from

    Account.getL1GasPrice

    Defined in

    node_modules/starknet/dist/index.d.ts:3230


    getL1MessageHash

    getL1MessageHash(l2TxHash): Promise<string>

    Parameters

    NameType
    l2TxHashBigNumberish

    Returns

    Promise<string>

    Inherited from

    Account.getL1MessageHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3231


    getNonce

    getNonce(blockIdentifier?): Promise<string>

    Parameters

    NameType
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string>

    Inherited from

    Account.getNonce

    Defined in

    node_modules/starknet/dist/index.d.ts:3743


    getNonceForAddress

    getNonceForAddress(contractAddress, blockIdentifier?): Promise<string>

    Parameters

    NameType
    contractAddressBigNumberish
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string>

    Inherited from

    Account.getNonceForAddress

    Defined in

    node_modules/starknet/dist/index.d.ts:3201


    getNonceSafe

    getNonceSafe(nonce?): Promise<bigint>

    Parameters

    NameType
    nonce?BigNumberish

    Returns

    Promise<bigint>

    Inherited from

    Account.getNonceSafe

    Defined in

    node_modules/starknet/dist/index.d.ts:3744


    getPendingTransactions

    getPendingTransactions(): Promise<TransactionWithHash$1[]>

    Return transactions from pending block

    Returns

    Promise<TransactionWithHash$1[]>

    Deprecated

    Instead use getBlock(BlockTag.pending); (will be removed in next minor version) Utility method, same result can be achieved using getBlockWithTxHashes(BlockTag.pending);

    Inherited from

    Account.getPendingTransactions

    Defined in

    node_modules/starknet/dist/index.d.ts:3250


    getPreferredVersion

    getPreferredVersion(type12, type3): ETransactionVersion

    Parameters

    NameType
    type12ETransactionVersion
    type3ETransactionVersion

    Returns

    ETransactionVersion

    Inherited from

    Account.getPreferredVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3742


    getSimulateTransaction

    getSimulateTransaction(invocations, options?): Promise<SimulateTransactionResponse>

    Parameters

    NameTypeDescription
    invocationsAccountInvocationsAccountInvocations
    options?getSimulateTransactionOptionsblockIdentifier and flags to skip validation and fee charge
    - blockIdentifier
    - skipValidate (default false)
    - skipFeeCharge (default true)

    Returns

    Promise<SimulateTransactionResponse>

    Inherited from

    Account.getSimulateTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3267


    getSpecVersion

    getSpecVersion(): Promise<string>

    Returns

    Promise<string>

    Inherited from

    Account.getSpecVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3200


    getStarkName

    getStarkName(address?, StarknetIdContract?): Promise<string>

    Parameters

    NameType
    address?BigNumberish
    StarknetIdContract?string

    Returns

    Promise<string>

    Inherited from

    Account.getStarkName

    Defined in

    node_modules/starknet/dist/index.d.ts:3794


    getStarkProfile

    getStarkProfile(address, StarknetIdContract?, StarknetIdIdentityContract?, StarknetIdVerifierContract?, StarknetIdPfpContract?, StarknetIdPopContract?, StarknetIdMulticallContract?): Promise<StarkProfile>

    Parameters

    NameType
    addressBigNumberish
    StarknetIdContract?string
    StarknetIdIdentityContract?string
    StarknetIdVerifierContract?string
    StarknetIdPfpContract?string
    StarknetIdPopContract?string
    StarknetIdMulticallContract?string

    Returns

    Promise<StarkProfile>

    Inherited from

    Account.getStarkProfile

    Defined in

    node_modules/starknet/dist/index.d.ts:3308


    getStorageAt

    getStorageAt(contractAddress, key, blockIdentifier?): Promise<string>

    Parameters

    NameType
    contractAddressBigNumberish
    keyBigNumberish
    blockIdentifier?BlockIdentifier

    Returns

    Promise<string>

    Inherited from

    Account.getStorageAt

    Defined in

    node_modules/starknet/dist/index.d.ts:3269


    getSuggestedFee

    getSuggestedFee(«destructured», details): Promise<EstimateFee>

    Parameters

    NameType
    «destructured»EstimateFeeAction
    detailsUniversalDetails

    Returns

    Promise<EstimateFee>

    Inherited from

    Account.getSuggestedFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3788


    getSyncingStats

    getSyncingStats(): Promise<Syncing>

    Returns an object about the sync status, or false if the node is not synching

    Returns

    Promise<Syncing>

    Object with the stats data

    Inherited from

    Account.getSyncingStats

    Defined in

    node_modules/starknet/dist/index.d.ts:3297


    getTransaction

    getTransaction(txHash): Promise<TransactionWithHash$1>

    Parameters

    NameType
    txHashBigNumberish

    Returns

    Promise<TransactionWithHash$1>

    Inherited from

    Account.getTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3251


    getTransactionByBlockIdAndIndex

    getTransactionByBlockIdAndIndex(blockIdentifier, index): Promise<TransactionWithHash$1>

    Parameters

    NameType
    blockIdentifierBlockIdentifier
    indexnumber

    Returns

    Promise<TransactionWithHash$1>

    Inherited from

    Account.getTransactionByBlockIdAndIndex

    Defined in

    node_modules/starknet/dist/index.d.ts:3253


    getTransactionByHash

    getTransactionByHash(txHash): Promise<TransactionWithHash$1>

    Parameters

    NameType
    txHashBigNumberish

    Returns

    Promise<TransactionWithHash$1>

    Inherited from

    Account.getTransactionByHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3252


    getTransactionReceipt

    getTransactionReceipt(txHash): Promise<GetTransactionReceiptResponse>

    Parameters

    NameType
    txHashBigNumberish

    Returns

    Promise<GetTransactionReceiptResponse>

    Inherited from

    Account.getTransactionReceipt

    Defined in

    node_modules/starknet/dist/index.d.ts:3254


    getTransactionStatus

    getTransactionStatus(transactionHash): Promise<TransactionStatus$1>

    Get the status of a transaction

    Parameters

    NameType
    transactionHashBigNumberish

    Returns

    Promise<TransactionStatus$1>

    Inherited from

    Account.getTransactionStatus

    Defined in

    node_modules/starknet/dist/index.d.ts:3259


    getTransactionTrace

    getTransactionTrace(txHash): Promise<TRANSACTION_TRACE>

    Parameters

    NameType
    txHashBigNumberish

    Returns

    Promise<TRANSACTION_TRACE>

    Inherited from

    Account.getTransactionTrace

    Defined in

    node_modules/starknet/dist/index.d.ts:3255


    getUniversalSuggestedFee

    getUniversalSuggestedFee(version, «destructured», details): Promise<{ maxFee: BigNumberish ; resourceBounds: RESOURCE_BOUNDS_MAPPING }>

    Parameters

    NameType
    versionETransactionVersion
    «destructured»EstimateFeeAction
    detailsUniversalDetails

    Returns

    Promise<{ maxFee: BigNumberish ; resourceBounds: RESOURCE_BOUNDS_MAPPING }>

    Inherited from

    Account.getUniversalSuggestedFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3784


    hashMessage

    hashMessage(typedData): Promise<string>

    Parameters

    NameType
    typedDataTypedData

    Returns

    Promise<string>

    Inherited from

    Account.hashMessage

    Defined in

    node_modules/starknet/dist/index.d.ts:3773


    invokeFunction

    invokeFunction(functionInvocation, details): Promise<InvokedTransaction>

    Parameters

    NameType
    functionInvocationInvocation
    detailsInvocationsDetailsWithNonce

    Returns

    Promise<InvokedTransaction>

    Inherited from

    Account.invokeFunction

    Defined in

    node_modules/starknet/dist/index.d.ts:3284


    isModule

    isModule(class_hash): Promise<boolean>

    Call an entrypoint on the module account.

    Parameters

    NameTypeDescription
    class_hashstringthe module to test

    Returns

    Promise<boolean>

    A promise that is true if the module is installed with the account.

    Defined in

    sdks/account/src/smartr_account.ts:413


    prepareMultisig

    prepareMultisig(transactions, transactionsDetail?): Promise<InvocationsDetailsWithNonce>

    generates the details, i.e nonce, version, fee, module prefix, to execute transactions on the StarkNet network.

    Parameters

    NameTypeDescription
    transactionsAllowArray<Call>An array of transactions to be executed.
    transactionsDetail?UniversalDetailsOptional object containing additional details for the transactions.

    Returns

    Promise<InvocationsDetailsWithNonce>

    A Promise that resolves to the transaction details.

    Defined in

    sdks/account/src/smartr_account.ts:105


    removeModule

    removeModule(class_hash, execute?): Promise<{ transaction_hash: string }>

    remove a module from an account.

    Parameters

    NameTypeDescription
    class_hashstringthe module to remove
    execute?trueIf true, the transaction is executed, otherwise it is built and returned so that it can be used in a multicall.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the transaction receipt if executes is true, otherwise it returns the transaction call.

    Defined in

    sdks/account/src/smartr_account.ts:454

    removeModule(class_hash, execute): Promise<Call[]>

    Parameters

    NameType
    class_hashstring
    executefalse

    Returns

    Promise<Call[]>

    Defined in

    sdks/account/src/smartr_account.ts:458


    signMessage

    signMessage(typedData): Promise<Signature>

    Parameters

    NameType
    typedDataTypedData

    Returns

    Promise<Signature>

    Inherited from

    Account.signMessage

    Defined in

    node_modules/starknet/dist/index.d.ts:3772


    signMultisig

    signMultisig(transactions, details): Promise<ArraySignatureType>

    Signs a set of transactions to be executed on the StarkNet network.

    Parameters

    NameTypeDescription
    transactionsCall[]An array of transactions to be executed.
    detailsInvocationsDetailsWithNonceOptional object containing additional details for the transactions.

    Returns

    Promise<ArraySignatureType>

    A Promise that resolves to the signature of the transactions.

    Defined in

    sdks/account/src/smartr_account.ts:151


    simulateTransaction

    simulateTransaction(invocations, details?): Promise<SimulateTransactionResponse>

    Parameters

    NameType
    invocationsInvocations
    details?SimulateTransactionDetails

    Returns

    Promise<SimulateTransactionResponse>

    Inherited from

    Account.simulateTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3756


    upgrade

    upgrade(classHash): Promise<{ transaction_hash: string }>

    Upgrades the SmartrAccount to a new class.

    Parameters

    NameTypeDescription
    classHashstringThe hash of the new class.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the transaction receipt if executes is true, otherwise it returns the transaction call.

    Defined in

    sdks/account/src/smartr_account.ts:398


    verifyMessage

    verifyMessage(typedData, signature, signatureVerificationFunctionName?, signatureVerificationResponse?): Promise<boolean>

    Parameters

    NameType
    typedDataTypedData
    signatureSignature
    signatureVerificationFunctionName?string
    signatureVerificationResponse?Object
    signatureVerificationResponse.errorstring[]
    signatureVerificationResponse.nokResponsestring[]
    signatureVerificationResponse.okResponsestring[]

    Returns

    Promise<boolean>

    Inherited from

    Account.verifyMessage

    Defined in

    node_modules/starknet/dist/index.d.ts:3779


    verifyMessageHash

    verifyMessageHash(hash, signature, signatureVerificationFunctionName?, signatureVerificationResponse?): Promise<boolean>

    Parameters

    NameType
    hashBigNumberish
    signatureSignature
    signatureVerificationFunctionName?string
    signatureVerificationResponse?Object
    signatureVerificationResponse.errorstring[]
    signatureVerificationResponse.nokResponsestring[]
    signatureVerificationResponse.okResponsestring[]

    Returns

    Promise<boolean>

    Inherited from

    Account.verifyMessageHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3774


    waitForBlock

    waitForBlock(blockIdentifier?, retryInterval?): Promise<void>

    Pause the execution of the script until a specified block is created.

    Parameters

    NameTypeDescription
    blockIdentifier?BlockIdentifierbloc number (BigNumberisk) or 'pending' or 'latest'. Use of 'latest" or of a block already created will generate no pause.
    retryInterval?numbernumber of milliseconds between 2 requests to the node

    Returns

    Promise<void>

    Example

    await myProvider.waitForBlock();
    // wait the creation of the pending block
    

    Inherited from

    Account.waitForBlock

    Defined in

    node_modules/starknet/dist/index.d.ts:3229


    waitForTransaction

    waitForTransaction(txHash, options?): Promise<GetTransactionReceiptResponse>

    Parameters

    NameType
    txHashBigNumberish
    options?waitForTransactionOptions

    Returns

    Promise<GetTransactionReceiptResponse>

    Inherited from

    Account.waitForTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3268


    executeStarkName

    executeStarkName(provider, address, contract): Promise<CallContractResponse>

    Parameters

    NameType
    providerProviderInterface
    addressstring
    contractstring

    Returns

    Promise<CallContractResponse>

    Inherited from

    Account.executeStarkName

    Defined in

    node_modules/starknet/dist/index.d.ts:3310


    executeStarkProfile

    executeStarkProfile(provider, contract, functionName, initialCalldata, fallbackCalldata): Promise<CallContractResponse>

    Parameters

    NameType
    providerProviderInterface
    contractstring
    functionNamestring
    initialCalldataRawArgsArray
    fallbackCalldataRawArgsArray

    Returns

    Promise<CallContractResponse>

    Inherited from

    Account.executeStarkProfile

    Defined in

    node_modules/starknet/dist/index.d.ts:3313


    getAddressFromStarkName

    getAddressFromStarkName(provider, name, StarknetIdContract?): Promise<string>

    Parameters

    NameType
    providerProviderInterface
    namestring
    StarknetIdContract?string

    Returns

    Promise<string>

    Inherited from

    Account.getAddressFromStarkName

    Defined in

    node_modules/starknet/dist/index.d.ts:3311


    getStarkName

    getStarkName(provider, address, StarknetIdContract?): Promise<string>

    Parameters

    NameType
    providerProviderInterface
    addressBigNumberish
    StarknetIdContract?string

    Returns

    Promise<string>

    Inherited from

    Account.getStarkName

    Defined in

    node_modules/starknet/dist/index.d.ts:3309


    getStarkProfile

    getStarkProfile(provider, address, StarknetIdContract?, StarknetIdIdentityContract?, StarknetIdVerifierContract?, StarknetIdPfpContract?, StarknetIdPopContract?, StarknetIdMulticallContract?): Promise<StarkProfile>

    Parameters

    NameType
    providerProviderInterface
    addressBigNumberish
    StarknetIdContract?string
    StarknetIdIdentityContract?string
    StarknetIdVerifierContract?string
    StarknetIdPfpContract?string
    StarknetIdPopContract?string
    StarknetIdMulticallContract?string

    Returns

    Promise<StarkProfile>

    Inherited from

    Account.getStarkProfile

    Defined in

    node_modules/starknet/dist/index.d.ts:3312

    @0xknwn/starknet-modular-account / Exports / AccountModuleInterface

    Interface: AccountModuleInterface

    Table of contents

    Methods

    Methods

    prefix

    prefix(calls): Call

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Call

    Defined in

    sdks/account/src/smartr_account.ts:41

    @0xknwn/starknet-module / Exports

    @0xknwn/starknet-module

    Table of contents

    Classes

    Variables

    Functions

    Variables

    EthValidatorABI

    Const EthValidatorABI: readonly [{ interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; name: "CoreValidator" = "CoreValidator"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "initialize" = "initialize"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { interface_name: "smartr::modules::ethvalidator::ethvalidator::IPublicKey" = "smartr::modules::ethvalidator::ethvalidator::IPublicKey"; name: "PublicKey" = "PublicKey"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_public_key" = "new_public_key"; type: "core::starknet::secp256k1::Secp256k1Point" = "core::starknet::secp256k1::Secp256k1Point" }] ; name: "set_public_key" = "set_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_public_key" = "get_public_key"; outputs: readonly [{ type: "core::starknet::secp256k1::Secp256k1Point" = "core::starknet::secp256k1::Secp256k1Point" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::modules::ethvalidator::ethvalidator::IPublicKey" = "smartr::modules::ethvalidator::ethvalidator::IPublicKey"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::ethvalidator::ethvalidator::EthValidator::Event" = "smartr::modules::ethvalidator::ethvalidator::EthValidator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    module/src/abi/EthValidator.ts:1


    GuardedValidatorABI

    Const GuardedValidatorABI: readonly [{ interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::modules::guardedvalidator::guardedvalidator::IGuardedKeys" = "smartr::modules::guardedvalidator::guardedvalidator::IGuardedKeys"; name: "GuardedKeysImpl" = "GuardedKeysImpl"; type: "impl" = "impl" }, { name: "smartr::modules::guardedvalidator::guardedvalidator::EjectionStatus" = "smartr::modules::guardedvalidator::guardedvalidator::EjectionStatus"; type: "enum" = "enum"; variants: readonly [{ name: "None" = "None"; type: "()" = "()" }, { name: "NotReady" = "NotReady"; type: "()" = "()" }, { name: "Ready" = "Ready"; type: "()" = "()" }, { name: "Expired" = "Expired"; type: "()" = "()" }] }, { members: readonly [{ name: "ready_at" = "ready_at"; type: "core::integer::u64" = "core::integer::u64" }, { name: "ejection_type" = "ejection_type"; type: "core::felt252" = "core::felt252" }, { name: "signer" = "signer"; type: "core::felt252" = "core::felt252" }] ; name: "smartr::modules::guardedvalidator::guardedvalidator::Ejection" = "smartr::modules::guardedvalidator::guardedvalidator::Ejection"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [] = []; name: "cancel_ejection" = "cancel_ejection"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "new_guardian" = "new_guardian"; type: "core::felt252" = "core::felt252" }] ; name: "change_backup_gardian" = "change_backup_gardian"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "new_guardian" = "new_guardian"; type: "core::felt252" = "core::felt252" }] ; name: "change_gardian" = "change_gardian"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "new_owner" = "new_owner"; type: "core::felt252" = "core::felt252" }] ; name: "change_owner" = "change_owner"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "finalize_guardian_ejection" = "finalize_guardian_ejection"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "finalize_owner_ejection" = "finalize_owner_ejection"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_ejection_status" = "get_ejection_status"; outputs: readonly [{ type: "smartr::modules::guardedvalidator::guardedvalidator::EjectionStatus" = "smartr::modules::guardedvalidator::guardedvalidator::EjectionStatus" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_ejection" = "get_ejection"; outputs: readonly [{ type: "smartr::modules::guardedvalidator::guardedvalidator::Ejection" = "smartr::modules::guardedvalidator::guardedvalidator::Ejection" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_guardian_backup_key" = "get_guardian_backup_key"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_guardian_ejection_attempts" = "get_guardian_ejection_attempts"; outputs: readonly [{ type: "core::integer::u32" = "core::integer::u32" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_guardian_key" = "get_guardian_key"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_owner_ejection_attempts" = "get_owner_ejection_attempts"; outputs: readonly [{ type: "core::integer::u32" = "core::integer::u32" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_owner_key" = "get_owner_key"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "new_guardian" = "new_guardian"; type: "core::felt252" = "core::felt252" }] ; name: "request_guardian_ejection" = "request_guardian_ejection"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "new_owner" = "new_owner"; type: "core::felt252" = "core::felt252" }] ; name: "request_owner_ejection" = "request_owner_ejection"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::modules::guardedvalidator::guardedvalidator::IGuardedKeys" = "smartr::modules::guardedvalidator::guardedvalidator::IGuardedKeys"; type: "interface" = "interface" }, { interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; name: "CoreValidator" = "CoreValidator"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "initialize" = "initialize"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::guardedvalidator::guardedvalidator::GuardedValidator::Event" = "smartr::modules::guardedvalidator::guardedvalidator::GuardedValidator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    module/src/abi/GuardedValidator.ts:1


    MultisigValidatorABI

    Const MultisigValidatorABI: readonly [{ interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; name: "CoreValidator" = "CoreValidator"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "initialize" = "initialize"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { interface_name: "smartr::modules::multisigvalidator::multisigvalidator::IPublicKeys" = "smartr::modules::multisigvalidator::multisigvalidator::IPublicKeys"; name: "PublicKeys" = "PublicKeys"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_public_key" = "new_public_key"; type: "core::felt252" = "core::felt252" }] ; name: "add_public_key" = "add_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_public_keys" = "get_public_keys"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_threshold" = "get_threshold"; outputs: readonly [{ type: "core::integer::u8" = "core::integer::u8" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "old_public_key" = "old_public_key"; type: "core::felt252" = "core::felt252" }] ; name: "remove_public_key" = "remove_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "new_threshold" = "new_threshold"; type: "core::integer::u8" = "core::integer::u8" }] ; name: "set_threshold" = "set_threshold"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::modules::multisigvalidator::multisigvalidator::IPublicKeys" = "smartr::modules::multisigvalidator::multisigvalidator::IPublicKeys"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::multisigvalidator::multisigvalidator::MultisigValidator::Event" = "smartr::modules::multisigvalidator::multisigvalidator::MultisigValidator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    module/src/abi/MultisigValidator.ts:1


    P256ValidatorABI

    Const P256ValidatorABI: readonly [{ interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; name: "CoreValidator" = "CoreValidator"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "hash" = "hash"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "initialize" = "initialize"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::ICoreValidator" = "smartr::component::validator::ICoreValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { interface_name: "smartr::modules::p256validator::p256validator::IPublicKey" = "smartr::modules::p256validator::p256validator::IPublicKey"; name: "PublicKey" = "PublicKey"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_public_key" = "new_public_key"; type: "core::starknet::secp256r1::Secp256r1Point" = "core::starknet::secp256r1::Secp256r1Point" }] ; name: "set_public_key" = "set_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_public_key" = "get_public_key"; outputs: readonly [{ type: "core::starknet::secp256r1::Secp256r1Point" = "core::starknet::secp256r1::Secp256r1Point" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::modules::p256validator::p256validator::IPublicKey" = "smartr::modules::p256validator::p256validator::IPublicKey"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::p256validator::p256validator::P256Validator::Event" = "smartr::modules::p256validator::p256validator::P256Validator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    module/src/abi/P256Validator.ts:1


    __module_validate__

    Const __module_validate__: "0x119c88dea7ff05dbe71c36247fc6682116f6dafa24089373d49aca7b2657017"

    Defined in

    module/src/class.ts:14

    Functions

    classHash

    classHash(className?): string

    Computes the hash of the requested class that is part of the 0xknwn/starknet-modular-account project.

    Parameters

    NameTypeDefault valueDescription
    className"EthValidator" | "GuardedValidator" | "MultisigValidator" | "P256Validator" | "StarkValidator""EthValidator"The name of the contract class.

    Returns

    string

    The hash of the contract class.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project.

    Defined in

    module/src/class.ts:26


    declareClass

    declareClass(account, className?): Promise<{ classHash: string }>

    If not already declared, declare the requested class from the 0xknwn/starknet-modular-account project to the Starknet network used by the provided account.

    Parameters

    NameTypeDefault valueDescription
    accountAccountundefinedThe starknet.js account used to declare the class.
    className"EthValidator" | "GuardedValidator" | "MultisigValidator" | "P256Validator" | "StarkValidator""EthValidator"The name of the class to declare. Defaults to "SmartrAccount".

    Returns

    Promise<{ classHash: string }>

    An object containing the declared class hash and the transaction receipt if the class was not already declared.

    Throws

    An error if the class deployment fails.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project. It also requires the account to have enough funds to declare the class to the Starknet network.

    Defined in

    module/src/class.ts:74

    @0xknwn/starknet-module / Exports / EthModule

    Class: EthModule

    Implements

    • AccountModuleInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new EthModule(accountAddress): EthModule

    Parameters

    NameType
    accountAddressstring

    Returns

    EthModule

    Defined in

    module/src/eth.ts:8

    Properties

    accountAddress

    Protected accountAddress: string

    Defined in

    module/src/eth.ts:7

    Methods

    prefix

    prefix(calls): Object

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Object

    NameType
    calldatastring[]
    contractAddressstring
    entrypointstring

    Implementation of

    AccountModuleInterface.prefix

    Defined in

    module/src/eth.ts:12

    @0xknwn/starknet-module / Exports / MultisigModule

    Class: MultisigModule

    Implements

    • AccountModuleInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new MultisigModule(accountAddress): MultisigModule

    Parameters

    NameType
    accountAddressstring

    Returns

    MultisigModule

    Defined in

    module/src/multisig.ts:8

    Properties

    accountAddress

    Protected accountAddress: string

    Defined in

    module/src/multisig.ts:7

    Methods

    prefix

    prefix(calls): Object

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Object

    NameType
    calldatastring[]
    contractAddressstring
    entrypointstring

    Implementation of

    AccountModuleInterface.prefix

    Defined in

    module/src/multisig.ts:12

    @0xknwn/starknet-module / Exports / P256Module

    Class: P256Module

    Implements

    • AccountModuleInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new P256Module(accountAddress): P256Module

    Parameters

    NameType
    accountAddressstring

    Returns

    P256Module

    Defined in

    module/src/p256.ts:8

    Properties

    accountAddress

    Protected accountAddress: string

    Defined in

    module/src/p256.ts:7

    Methods

    prefix

    prefix(calls): Object

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Object

    NameType
    calldatastring[]
    contractAddressstring
    entrypointstring

    Implementation of

    AccountModuleInterface.prefix

    Defined in

    module/src/p256.ts:12

    @0xknwn/starknet-module / Exports / P256Signer

    Class: P256Signer

    Signer for accounts using Ethereum signature

    Implements

    • SignerInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new P256Signer(pk): P256Signer

    Parameters

    NameType
    pkstring | Uint8Array

    Returns

    P256Signer

    Defined in

    module/src/p256signer.ts:39

    Properties

    pk

    Protected pk: string

    Defined in

    module/src/p256signer.ts:37

    Methods

    formatP256Signature

    formatP256Signature(p256Signature): ArraySignatureType

    Serialize the signature in conformity with starknet::eth_signature::Signature

    Parameters

    NameType
    p256SignatureRecoveredSignatureType

    Returns

    ArraySignatureType

    an array of felts, representing a Cairo Eth Signature.

    Defined in

    module/src/p256signer.ts:195


    getPubKey

    getPubKey(): Promise<string>

    provides the Ethereum full public key (without parity prefix)

    Returns

    Promise<string>

    an hex string : 64 first characters are Point X coordinate. 64 last characters are Point Y coordinate.

    Implementation of

    SignerInterface.getPubKey

    Defined in

    module/src/p256signer.ts:50


    signDeclareTransaction

    signDeclareTransaction(details): Promise<Signature>

    Parameters

    NameType
    detailsDeclareSignerDetails

    Returns

    Promise<Signature>

    Implementation of

    SignerInterface.signDeclareTransaction

    Defined in

    module/src/p256signer.ts:155


    signDeployAccountTransaction

    signDeployAccountTransaction(details): Promise<Signature>

    Parameters

    NameType
    detailsDeployAccountSignerDetails

    Returns

    Promise<Signature>

    Implementation of

    SignerInterface.signDeployAccountTransaction

    Defined in

    module/src/p256signer.ts:114


    signMessage

    signMessage(typedData, accountAddress): Promise<Signature>

    Parameters

    NameType
    typedDataTypedData
    accountAddressstring

    Returns

    Promise<Signature>

    Implementation of

    SignerInterface.signMessage

    Defined in

    module/src/p256signer.ts:59


    signTransaction

    signTransaction(transactions, details): Promise<Signature>

    Parameters

    NameType
    transactionsCall[]
    detailsInvocationsSignerDetails

    Returns

    Promise<Signature>

    Implementation of

    SignerInterface.signTransaction

    Defined in

    module/src/p256signer.ts:71

    @0xknwn/starknet-module / Exports / StarkModule

    Class: StarkModule

    Implements

    • AccountModuleInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new StarkModule(accountAddress): StarkModule

    Parameters

    NameType
    accountAddressstring

    Returns

    StarkModule

    Defined in

    module/src/stark.ts:10

    Properties

    accountAddress

    Protected accountAddress: string

    Defined in

    module/src/stark.ts:9

    Methods

    prefix

    prefix(calls): Object

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Object

    NameType
    calldatastring[]
    contractAddressstring
    entrypointstring

    Implementation of

    AccountModuleInterface.prefix

    Defined in

    module/src/stark.ts:14

    @0xknwn/starknet-module-sessionkey / Exports

    @0xknwn/starknet-module-sessionkey

    Table of contents

    Classes

    Type Aliases

    Variables

    Functions

    Type Aliases

    Policies

    Ƭ Policies: Policy[]

    Defined in

    sdks/module-sessionkey/src/policies.ts:8


    Policy

    Ƭ Policy: Object

    Type declaration

    NameType
    contractAddressstring
    selectorstring

    Defined in

    sdks/module-sessionkey/src/policies.ts:3

    Variables

    SessionKeyValidatorABI

    Const SessionKeyValidatorABI: readonly [{ interface_name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; name: "VersionImpl" = "VersionImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_version" = "get_version"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get_name" = "get_name"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::version::IVersion" = "smartr::component::version::IVersion"; type: "interface" = "interface" }, { interface_name: "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::IDisableSessionKey" = "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::IDisableSessionKey"; name: "DisableSessionKeyImpl" = "DisableSessionKeyImpl"; type: "impl" = "impl" }, { name: "core::bool" = "core::bool"; type: "enum" = "enum"; variants: readonly [{ name: "False" = "False"; type: "()" = "()" }, { name: "True" = "True"; type: "()" = "()" }] }, { items: readonly [{ inputs: readonly [{ name: "sessionkey" = "sessionkey"; type: "core::felt252" = "core::felt252" }] ; name: "disable_session_key" = "disable_session_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "sessionkey" = "sessionkey"; type: "core::felt252" = "core::felt252" }] ; name: "is_disabled_session_key" = "is_disabled_session_key"; outputs: readonly [{ type: "core::bool" = "core::bool" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::IDisableSessionKey" = "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::IDisableSessionKey"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; name: "ValidatorImpl" = "ValidatorImpl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "grantor_class" = "grantor_class"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }, { name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "validate" = "validate"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::component::validator::IValidator" = "smartr::component::validator::IValidator"; type: "interface" = "interface" }, { interface_name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; name: "ConfigureImpl" = "ConfigureImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "call" = "call"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "call" = "call"; type: "core::starknet::account::Call" = "core::starknet::account::Call" }] ; name: "execute" = "execute"; outputs: readonly [{ type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::component::validator::IConfigure" = "smartr::component::validator::IConfigure"; type: "interface" = "interface" }, { inputs: readonly [] = []; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "enum" = "enum"; name: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "smartr::component::account::AccountComponent::OwnerAdded" = "smartr::component::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "smartr::component::account::AccountComponent::OwnerRemoved" = "smartr::component::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::SessionKeyValidator::Event" = "smartr::modules::sessionkeyvalidator::sessionkeyvalidator::SessionKeyValidator::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "ValidatorEvent" = "ValidatorEvent"; type: "smartr::component::validator::ValidatorComponent::Event" = "smartr::component::validator::ValidatorComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "smartr::component::account::AccountComponent::Event" = "smartr::component::account::AccountComponent::Event" }] }]

    Defined in

    sdks/module-sessionkey/src/abi/SessionKeyValidator.ts:1


    __module_validate__

    Const __module_validate__: "0x119c88dea7ff05dbe71c36247fc6682116f6dafa24089373d49aca7b2657017"

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:11

    Functions

    classHash

    classHash(className?): string

    Computes the hash of the requested class that is part of the 0xknwn/starknet-modular-account project.

    Parameters

    NameTypeDefault valueDescription
    className"SessionKeyValidator""SessionKeyValidator"The name of the contract class.

    Returns

    string

    The hash of the contract class.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project.

    Defined in

    sdks/module-sessionkey/src/class.ts:14


    declareClass

    declareClass(account, className?): Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    If not already declared, declare the requested class from the 0xknwn/starknet-modular-account project to the Starknet network used by the provided account.

    Parameters

    NameTypeDefault valueDescription
    accountAccountundefinedThe starknet.js account used to declare the class.
    className"SessionKeyValidator""SessionKeyValidator"The name of the class to declare. Defaults to "SmartrAccount".

    Returns

    Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    An object containing the declared class hash and the transaction receipt if the class was not already declared.

    Throws

    An error if the class deployment fails.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project. It also requires the account to have enough funds to declare the class to the Starknet network.

    Defined in

    sdks/module-sessionkey/src/class.ts:45

    @0xknwn/starknet-module-sessionkey / Exports / PolicyManager

    Class: PolicyManager

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new PolicyManager(policies): PolicyManager

    Parameters

    NameType
    policiesPolicies

    Returns

    PolicyManager

    Defined in

    sdks/module-sessionkey/src/policies.ts:14

    Properties

    policies

    Private policies: Policies

    Defined in

    sdks/module-sessionkey/src/policies.ts:11


    tree

    Private tree: MerkleTree

    Defined in

    sdks/module-sessionkey/src/policies.ts:12

    Methods

    getProof

    getProof(policy): string[]

    Parameters

    NameType
    policyPolicy

    Returns

    string[]

    Defined in

    sdks/module-sessionkey/src/policies.ts:29


    getRoot

    getRoot(): string

    Returns

    string

    Defined in

    sdks/module-sessionkey/src/policies.ts:25

    @0xknwn/starknet-module-sessionkey / Exports / SessionKeyGrantor

    Class: SessionKeyGrantor

    Hierarchy

    • Signer

      SessionKeyGrantor

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new SessionKeyGrantor(validatorGrantorClass, privateKey): SessionKeyGrantor

    Parameters

    NameType
    validatorGrantorClassstring
    privateKeystring | Uint8Array

    Returns

    SessionKeyGrantor

    Overrides

    Signer.constructor

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:16

    Properties

    pk

    Protected pk: string | Uint8Array

    Inherited from

    Signer.pk

    Defined in

    node_modules/starknet/dist/index.d.ts:3400


    validatorGrantorClass

    validatorGrantorClass: string

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:15

    Methods

    getPubKey

    getPubKey(): Promise<string>

    Returns

    Promise<string>

    Inherited from

    Signer.getPubKey

    Defined in

    node_modules/starknet/dist/index.d.ts:3402


    sign

    sign(module): Promise<ArraySignatureType>

    Parameters

    NameType
    moduleSessionKeyModule

    Returns

    Promise<ArraySignatureType>

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:21


    signDeclareTransaction

    signDeclareTransaction(details): Promise<Signature>

    Parameters

    NameType
    detailsDeclareSignerDetails

    Returns

    Promise<Signature>

    Inherited from

    Signer.signDeclareTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3406


    signDeployAccountTransaction

    signDeployAccountTransaction(details): Promise<Signature>

    Parameters

    NameType
    detailsDeployAccountSignerDetails

    Returns

    Promise<Signature>

    Inherited from

    Signer.signDeployAccountTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3405


    signMessage

    signMessage(typedData, accountAddress): Promise<Signature>

    Parameters

    NameType
    typedDataTypedData
    accountAddressstring

    Returns

    Promise<Signature>

    Inherited from

    Signer.signMessage

    Defined in

    node_modules/starknet/dist/index.d.ts:3403


    signRaw

    signRaw(msgHash): Promise<Signature>

    Parameters

    NameType
    msgHashstring

    Returns

    Promise<Signature>

    Inherited from

    Signer.signRaw

    Defined in

    node_modules/starknet/dist/index.d.ts:3407


    signTransaction

    signTransaction(transactions, details): Promise<Signature>

    Parameters

    NameType
    transactionsCall[]
    detailsInvocationsSignerDetails

    Returns

    Promise<Signature>

    Inherited from

    Signer.signTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3404

    @0xknwn/starknet-module-sessionkey / Exports / SessionKeyModule

    Class: SessionKeyModule

    Implements

    • AccountModuleInterface

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new SessionKeyModule(authKey, accountAddress, validatorClassHash, chainId, expires, policyManager?): SessionKeyModule

    Parameters

    NameType
    authKeystring
    accountAddressstring
    validatorClassHashstring
    chainIdstring
    expiresstring
    policyManager?PolicyManager

    Returns

    SessionKeyModule

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:37

    Properties

    auth

    Protected auth: Authorization

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:34


    policyManager

    Protected Optional policyManager: PolicyManager

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:35

    Methods

    add_signature

    add_signature(signature): Promise<void>

    Parameters

    NameType
    signaturestring[]

    Returns

    Promise<void>

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:98


    get_session_key

    get_session_key(): Promise<string>

    Returns

    Promise<string>

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:83


    prefix

    prefix(calls): Object

    Parameters

    NameType
    callsCall | Call[]

    Returns

    Object

    NameType
    calldatastring[]
    contractAddressstring
    entrypointstring

    Implementation of

    AccountModuleInterface.prefix

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:112


    request

    request(grantorClass): Promise<Authorization>

    Parameters

    NameType
    grantorClassstring

    Returns

    Promise<Authorization>

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:62


    reset

    reset(signature): Promise<void>

    Parameters

    NameType
    signaturestring[]

    Returns

    Promise<void>

    Defined in

    sdks/module-sessionkey/src/sessionkey.ts:105

    @0xknwn/starknet-test-helpers / Exports

    @0xknwn/starknet-test-helpers

    Table of contents

    Classes

    Type Aliases

    Variables

    Functions

    Type Aliases

    AccountConfig

    Ƭ AccountConfig: Object

    Represents the configuration of an account.

    Type declaration

    NameType
    addressstring
    classHash?string
    privateKeystring
    publicKeystring

    Defined in

    sdks/tests/helpers/src/utils.ts:7


    Config

    Ƭ Config: Object

    Represents the configuration for the test helpers.

    Type declaration

    NameType
    accountsAccountConfig[]
    providerURLstring

    Defined in

    sdks/tests/helpers/src/utils.ts:21

    Variables

    CounterABI

    Const CounterABI: readonly [{ interface_name: "smartr::helpers::counter::ICounter" = "smartr::helpers::counter::ICounter"; name: "CounterImpl" = "CounterImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "increment" = "increment"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "args" = "args"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "increment_by_array" = "increment_by_array"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [{ name: "value" = "value"; type: "core::integer::u64" = "core::integer::u64" }] ; name: "increment_by" = "increment_by"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "get" = "get"; outputs: readonly [{ type: "core::integer::u64" = "core::integer::u64" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [] = []; name: "reset" = "reset"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "smartr::helpers::counter::ICounter" = "smartr::helpers::counter::ICounter"; type: "interface" = "interface" }, { interface_name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; name: "UpgradeableImpl" = "UpgradeableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_class_hash" = "new_class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "upgrade" = "upgrade"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; type: "interface" = "interface" }, { interface_name: "openzeppelin::access::ownable::interface::IOwnable" = "openzeppelin::access::ownable::interface::IOwnable"; name: "OwnableImpl" = "OwnableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "owner" = "owner"; outputs: readonly [{ type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "new_owner" = "new_owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }] ; name: "transfer_ownership" = "transfer_ownership"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }, { inputs: readonly [] = []; name: "renounce_ownership" = "renounce_ownership"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "openzeppelin::access::ownable::interface::IOwnable" = "openzeppelin::access::ownable::interface::IOwnable"; type: "interface" = "interface" }, { inputs: readonly [{ name: "owner" = "owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }] ; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "previous_owner" = "previous_owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { kind: "key" = "key"; name: "new_owner" = "new_owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }] ; name: "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred" = "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "previous_owner" = "previous_owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { kind: "key" = "key"; name: "new_owner" = "new_owner"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }] ; name: "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted" = "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "openzeppelin::access::ownable::ownable::OwnableComponent::Event" = "openzeppelin::access::ownable::ownable::OwnableComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnershipTransferred" = "OwnershipTransferred"; type: "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred" = "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred" }, { kind: "nested" = "nested"; name: "OwnershipTransferStarted" = "OwnershipTransferStarted"; type: "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted" = "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted" }] }, { kind: "struct" = "struct"; members: readonly [{ kind: "data" = "data"; name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "Upgraded" = "Upgraded"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" }] }, { kind: "enum" = "enum"; name: "smartr::helpers::counter::Counter::Event" = "smartr::helpers::counter::Counter::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "OwnableEvent" = "OwnableEvent"; type: "openzeppelin::access::ownable::ownable::OwnableComponent::Event" = "openzeppelin::access::ownable::ownable::OwnableComponent::Event" }, { kind: "flat" = "flat"; name: "UpgradeableEvent" = "UpgradeableEvent"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" }] }]

    Defined in

    sdks/tests/helpers/src/abi/Counter.ts:1


    SimpleAccountABI

    Const SimpleAccountABI: readonly [{ interface_name: "smartr::helpers::simple_account::IDeployable" = "smartr::helpers::simple_account::IDeployable"; name: "DeployableImpl" = "DeployableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::felt252" = "core::felt252" }, { name: "contract_address_salt" = "contract_address_salt"; type: "core::felt252" = "core::felt252" }, { name: "public_key" = "public_key"; type: "core::felt252" = "core::felt252" }, { name: "more" = "more"; type: "core::felt252" = "core::felt252" }] ; name: "__validate_deploy__" = "__validate_deploy__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "smartr::helpers::simple_account::IDeployable" = "smartr::helpers::simple_account::IDeployable"; type: "interface" = "interface" }, { interface_name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; name: "UpgradeableImpl" = "UpgradeableImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "new_class_hash" = "new_class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "upgrade" = "upgrade"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "openzeppelin::upgrades::interface::IUpgradeable" = "openzeppelin::upgrades::interface::IUpgradeable"; type: "interface" = "interface" }, { interface_name: "openzeppelin::account::interface::ISRC6" = "openzeppelin::account::interface::ISRC6"; name: "SRC6Impl" = "SRC6Impl"; type: "impl" = "impl" }, { members: readonly [{ name: "snapshot" = "snapshot"; type: "@core::array::Array::<core::felt252>" = "@core::array::Array::<core::felt252>" }] ; name: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>"; type: "struct" = "struct" }, { members: readonly [{ name: "to" = "to"; type: "core::starknet::contract_address::ContractAddress" = "core::starknet::contract_address::ContractAddress" }, { name: "selector" = "selector"; type: "core::felt252" = "core::felt252" }, { name: "calldata" = "calldata"; type: "core::array::Span::<core::felt252>" = "core::array::Span::<core::felt252>" }] ; name: "core::starknet::account::Call" = "core::starknet::account::Call"; type: "struct" = "struct" }, { items: readonly [{ inputs: readonly [{ name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "__execute__" = "__execute__"; outputs: readonly [{ type: "core::array::Array::<core::array::Span::<core::felt252>>" = "core::array::Array::<core::array::Span::<core::felt252>>" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "calls" = "calls"; type: "core::array::Array::<core::starknet::account::Call>" = "core::array::Array::<core::starknet::account::Call>" }] ; name: "__validate__" = "__validate__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "hash" = "hash"; type: "core::felt252" = "core::felt252" }, { name: "signature" = "signature"; type: "core::array::Array::<core::felt252>" = "core::array::Array::<core::felt252>" }] ; name: "is_valid_signature" = "is_valid_signature"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "openzeppelin::account::interface::ISRC6" = "openzeppelin::account::interface::ISRC6"; type: "interface" = "interface" }, { interface_name: "openzeppelin::account::interface::IDeclarer" = "openzeppelin::account::interface::IDeclarer"; name: "DeclarerImpl" = "DeclarerImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [{ name: "class_hash" = "class_hash"; type: "core::felt252" = "core::felt252" }] ; name: "__validate_declare__" = "__validate_declare__"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }] ; name: "openzeppelin::account::interface::IDeclarer" = "openzeppelin::account::interface::IDeclarer"; type: "interface" = "interface" }, { interface_name: "openzeppelin::account::interface::IPublicKey" = "openzeppelin::account::interface::IPublicKey"; name: "PublicKeyImpl" = "PublicKeyImpl"; type: "impl" = "impl" }, { items: readonly [{ inputs: readonly [] = []; name: "get_public_key" = "get_public_key"; outputs: readonly [{ type: "core::felt252" = "core::felt252" }] ; state_mutability: "view" = "view"; type: "function" = "function" }, { inputs: readonly [{ name: "new_public_key" = "new_public_key"; type: "core::felt252" = "core::felt252" }] ; name: "set_public_key" = "set_public_key"; outputs: readonly [] = []; state_mutability: "external" = "external"; type: "function" = "function" }] ; name: "openzeppelin::account::interface::IPublicKey" = "openzeppelin::account::interface::IPublicKey"; type: "interface" = "interface" }, { inputs: readonly [{ name: "public_key" = "public_key"; type: "core::felt252" = "core::felt252" }, { name: "more" = "more"; type: "core::felt252" = "core::felt252" }] ; name: "constructor" = "constructor"; type: "constructor" = "constructor" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "new_owner_guid" = "new_owner_guid"; type: "core::felt252" = "core::felt252" }] ; name: "openzeppelin::account::account::AccountComponent::OwnerAdded" = "openzeppelin::account::account::AccountComponent::OwnerAdded"; type: "event" = "event" }, { kind: "struct" = "struct"; members: readonly [{ kind: "key" = "key"; name: "removed_owner_guid" = "removed_owner_guid"; type: "core::felt252" = "core::felt252" }] ; name: "openzeppelin::account::account::AccountComponent::OwnerRemoved" = "openzeppelin::account::account::AccountComponent::OwnerRemoved"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "openzeppelin::account::account::AccountComponent::Event" = "openzeppelin::account::account::AccountComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "OwnerAdded" = "OwnerAdded"; type: "openzeppelin::account::account::AccountComponent::OwnerAdded" = "openzeppelin::account::account::AccountComponent::OwnerAdded" }, { kind: "nested" = "nested"; name: "OwnerRemoved" = "OwnerRemoved"; type: "openzeppelin::account::account::AccountComponent::OwnerRemoved" = "openzeppelin::account::account::AccountComponent::OwnerRemoved" }] }, { kind: "enum" = "enum"; name: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event"; type: "event" = "event"; variants: readonly [] = [] }, { kind: "struct" = "struct"; members: readonly [{ kind: "data" = "data"; name: "class_hash" = "class_hash"; type: "core::starknet::class_hash::ClassHash" = "core::starknet::class_hash::ClassHash" }] ; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded"; type: "event" = "event" }, { kind: "enum" = "enum"; name: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event"; type: "event" = "event"; variants: readonly [{ kind: "nested" = "nested"; name: "Upgraded" = "Upgraded"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" }] }, { kind: "enum" = "enum"; name: "smartr::helpers::simple_account::SimpleAccount::Event" = "smartr::helpers::simple_account::SimpleAccount::Event"; type: "event" = "event"; variants: readonly [{ kind: "flat" = "flat"; name: "AccountEvent" = "AccountEvent"; type: "openzeppelin::account::account::AccountComponent::Event" = "openzeppelin::account::account::AccountComponent::Event" }, { kind: "flat" = "flat"; name: "SRC5Event" = "SRC5Event"; type: "openzeppelin::introspection::src5::SRC5Component::Event" = "openzeppelin::introspection::src5::SRC5Component::Event" }, { kind: "flat" = "flat"; name: "UpgradeableEvent" = "UpgradeableEvent"; type: "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" = "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" }] }]

    Defined in

    sdks/tests/helpers/src/abi/SimpleAccount.ts:1


    default_timeout

    Const default_timeout: 120000

    Defined in

    sdks/tests/helpers/src/parameters.ts:3


    initial_EthTransfer

    Const initial_EthTransfer: Uint256

    Defined in

    sdks/tests/helpers/src/parameters.ts:4


    udcAddress

    Const udcAddress: bigint

    The address of the UDC (Universal Deployer Contract) in the StarkNet network.

    Defined in

    sdks/tests/helpers/src/natives.ts:13

    Functions

    ETH

    ETH(provider): Contract

    /**

    • Represents an instance of the ETH contract.

    Parameters

    NameType
    providerAccount | RpcProvider

    Returns

    Contract

    Defined in

    sdks/tests/helpers/src/natives.ts:30


    STRK

    STRK(provider): Contract

    Creates an instance of the STARK contract.

    Parameters

    NameTypeDescription
    providerAccount | RpcProviderThe RpcProvider or Account used to interact with the token

    Returns

    Contract

    An instance of the STARK contract.

    Defined in

    sdks/tests/helpers/src/natives.ts:23


    accountAddress

    accountAddress(accountName, publicKey, constructorCallData): string

    Calculates the account address for a given account name, public key, and constructor call data.

    Parameters

    NameTypeDescription
    accountName"SimpleAccount"The name of the account used in this project.
    publicKeystringThe public key associated with the account.
    constructorCallDatastring[]The constructor call data for the account.

    Returns

    string

    The calculated account address.

    Remarks

    This function requires the cairo account to be compiled with the scarb build command at the root of the project.

    Defined in

    sdks/tests/helpers/src/contract.ts:40


    classHash

    classHash(className?): string

    Computes the hash of the requested class that is part of the 0xknwn/starknet-modular-account project.

    Parameters

    NameTypeDefault valueDescription
    className"Counter" | "SimpleAccount" | "SwapRouter" | "TokenA" | "TokenB""Counter"The name of the contract class.

    Returns

    string

    The hash of the contract class.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project.

    Defined in

    sdks/tests/helpers/src/class.ts:22


    config

    config(env?): Config

    Retrieves the configuration based on the specified environment.

    Parameters

    NameTypeDefault valueDescription
    envstring"devnet"The environment for which to retrieve the configuration. Defaults to "devnet".

    Returns

    Config

    The configuration object.

    Defined in

    sdks/tests/helpers/src/utils.ts:33


    counterAddress

    counterAddress(deployerAddress, ownerAddress): Promise<string>

    Retrieves the address of the Counter contract.

    Parameters

    NameTypeDescription
    deployerAddressstringThe address of the deployer.
    ownerAddressstringThe address of the owner.

    Returns

    Promise<string>

    The address of the Counter contract.

    Defined in

    sdks/tests/helpers/src/counter.ts:11


    declareClass

    declareClass(account, className?): Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    If not already declared, declare the requested class from the 0xknwn/starknet-modular-account project to the Starknet network used by the provided account.

    Parameters

    NameTypeDefault valueDescription
    accountAccountundefinedThe starknet.js account used to declare the class.
    className"Counter" | "SimpleAccount" | "SwapRouter" | "TokenA" | "TokenB""Counter"The name of the class to declare. Defaults to "SmartrAccount".

    Returns

    Promise<{ classHash: string = HelperClassHash } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "INVOKE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; block_hash: string ; block_number: number ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: { amount: string ; unit: "WEI" | "FRI" } ; classHash: string = declare.class_hash; events: { data: string[] ; from_address: string ; keys: string[] }[] ; execution_resources: { bitwise_builtin_applications: undefined | number ; data_availability: undefined | { l1_data_gas: number ; l1_gas: number } ; ec_op_builtin_applications: undefined | number ; ecdsa_builtin_applications: undefined | number ; keccak_builtin_applications: undefined | number ; memory_holes: undefined | number ; pedersen_builtin_applications: undefined | number ; poseidon_builtin_applications: undefined | number ; range_check_builtin_applications: undefined | number ; segment_arena_builtin: undefined | number ; steps: number } ; execution_status: "SUCCEEDED" | "REVERTED" ; finality_status: "ACCEPTED_ON_L2" | "ACCEPTED_ON_L1" ; messages_sent: { from_address: string ; payload: string[] ; to_address: string }[] ; revert_reason: undefined | string ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; type: "DECLARE" ; value: TransactionReceiptValue } | { actual_fee: string ; block_hash?: string ; block_number?: BlockNumber ; classHash: string = declare.class_hash; events: any[] ; execution_status: any ; finality_status: any ; messages_sent: MessageToL1[] ; revert_reason?: string ; status?: TransactionStatus ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_hash: string ; transaction_index?: number ; type?: any ; value: TransactionReceiptValue } | { classHash: string = declare.class_hash; status: "REJECTED" ; statusReceipt: keyof TransactionStatusReceiptSets ; transaction_failure_reason: { code: string ; error_message: string } ; value: TransactionReceiptValue }>

    An object containing the declared class hash and the transaction receipt if the class was not already declared.

    Throws

    An error if the class deployment fails.

    Remarks

    This function requires the cairo contract to be compiled with the scarb build command at the root of the project. It also requires the account to have enough funds to declare the class to the Starknet network.

    Defined in

    sdks/tests/helpers/src/class.ts:72


    deployAccount

    deployAccount(deployerAccount, accountName, publicKey, constructorCalldata): Promise<string>

    Deploys an account on the StarkNet network.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe account used to deploy the new account.
    accountName"SimpleAccount"The name of the account to be deployed.
    publicKeystringThe public key associated with the account.
    constructorCalldataany[]The constructor calldata required for deploying the account.

    Returns

    Promise<string>

    The address of the deployed account.

    Throws

    Error if the deployment fails.

    Defined in

    sdks/tests/helpers/src/contract.ts:102


    deployCounter

    deployCounter(deployerAccount, ownerAddress): Promise<Contract>

    Deploys a Counter contract.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe account used to deploy the contract.
    ownerAddressstringThe owner's address.

    Returns

    Promise<Contract>

    A Promise that resolves to the deployed Counter contract.

    Defined in

    sdks/tests/helpers/src/counter.ts:28


    deploySimpleAccount

    deploySimpleAccount(deployerAccount, publicKey, more): Promise<string>

    Deploys a simple account on the StarkNet network.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe account used to deploy the simple account.
    publicKeystringThe public key associated with the simple account.
    morestringAdditional information for the simple account.

    Returns

    Promise<string>

    A promise that resolves to the deployed simple account.

    Defined in

    sdks/tests/helpers/src/simple_account.ts:32


    deploySwapRouter

    deploySwapRouter(deployerAccount, ownerAddress): Promise<Contract>

    Deploys the SwapRouter contract.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe deployer account.
    ownerAddressstringThe owner address.

    Returns

    Promise<Contract>

    A Promise that resolves to the deployed Counter contract.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:30


    deployTokenA

    deployTokenA(deployerAccount, recipientAddress, ownerAddress): Promise<Contract>

    Deploys the TokenA contract.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe deployer account.
    recipientAddressstring-
    ownerAddressstringThe owner address.

    Returns

    Promise<Contract>

    A Promise that resolves to the deployed Counter contract.

    Defined in

    sdks/tests/helpers/src/tokens.ts:29


    deployTokenB

    deployTokenB(deployerAccount, recipientAddress, ownerAddress): Promise<Contract>

    Deploys the TokenB contract.

    Parameters

    NameTypeDescription
    deployerAccountAccountThe deployer account.
    recipientAddressstring-
    ownerAddressstringThe owner address.

    Returns

    Promise<Contract>

    A Promise that resolves to the deployed Counter contract.

    Defined in

    sdks/tests/helpers/src/tokens.ts:63


    simpleAccountAddress

    simpleAccountAddress(publicKey, more): string

    Generates a simple account address based on the provided public key and additional data.

    Parameters

    NameTypeDescription
    publicKeystringThe public key associated with the account.
    morestringAdditional data for the account.

    Returns

    string

    The generated account address.

    Defined in

    sdks/tests/helpers/src/simple_account.ts:13


    swapRouterAddress

    swapRouterAddress(deployerAddress, ownerAddress): Promise<string>

    Retrieves the swap router address from its deployer and owner.

    Parameters

    NameTypeDescription
    deployerAddressstringThe address of the deployer.
    ownerAddressstringThe address of the owner.

    Returns

    Promise<string>

    The address of the swap router contract.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:13


    testAccounts

    testAccounts(config): Account[]

    Retrieves the Accounts from the configuration.

    Parameters

    NameTypeDescription
    configConfigThe configuration object containing the provider URL and account details.

    Returns

    Account[]

    An array of Accounts.

    Defined in

    sdks/tests/helpers/src/utils.ts:54


    tokenAAddress

    tokenAAddress(deployerAddress, recipientAddress, ownerAddress): Promise<string>

    Retrieves the token A address.

    Parameters

    NameTypeDescription
    deployerAddressstringThe address of the deployer.
    recipientAddressstringThe address of the recipient.
    ownerAddressstringThe address of the owner.

    Returns

    Promise<string>

    The token A address.

    Defined in

    sdks/tests/helpers/src/tokens.ts:16


    tokenBAddress

    tokenBAddress(deployerAddress, recipientAddress, ownerAddress): Promise<string>

    Retrieves the token B address.

    Parameters

    NameTypeDescription
    deployerAddressstringThe address of the deployer.
    recipientAddressstringThe address of the recipient.
    ownerAddressstringThe address of the owner.

    Returns

    Promise<string>

    The token B address.

    Defined in

    sdks/tests/helpers/src/tokens.ts:50

    @0xknwn/starknet-test-helpers / Exports / Counter

    Class: Counter

    Represents a Counter contract.

    Hierarchy

    • Contract

      Counter

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new Counter(address, account): Counter

    Creates an instance of the Counter contract.

    Parameters

    NameTypeDescription
    addressstringThe address of the contract.
    accountAccountThe account used to interact with the contract.

    Returns

    Counter

    Overrides

    Contract.constructor

    Defined in

    sdks/tests/helpers/src/counter.ts:50

    Properties

    abi

    abi: Abi

    Inherited from

    Contract.abi

    Defined in

    node_modules/starknet/dist/index.d.ts:3957


    address

    address: string

    Inherited from

    Contract.address

    Defined in

    node_modules/starknet/dist/index.d.ts:3958


    callStatic

    Readonly callStatic: Object

    Index signature

    ▪ [name: string]: AsyncContractFunction

    Inherited from

    Contract.callStatic

    Defined in

    node_modules/starknet/dist/index.d.ts:3968


    deployTransactionHash

    Optional deployTransactionHash: string

    Inherited from

    Contract.deployTransactionHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3960


    estimateFee

    Readonly estimateFee: Object

    Index signature

    ▪ [name: string]: ContractFunction

    Inherited from

    Contract.estimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3974


    events

    Protected Readonly events: AbiEvents

    Inherited from

    Contract.events

    Defined in

    node_modules/starknet/dist/index.d.ts:3964


    functions

    Readonly functions: Object

    Index signature

    ▪ [name: string]: AsyncContractFunction

    Inherited from

    Contract.functions

    Defined in

    node_modules/starknet/dist/index.d.ts:3965


    populateTransaction

    Readonly populateTransaction: Object

    Index signature

    ▪ [name: string]: ContractFunction

    Inherited from

    Contract.populateTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3971


    providerOrAccount

    providerOrAccount: ProviderInterface | AccountInterface

    Inherited from

    Contract.providerOrAccount

    Defined in

    node_modules/starknet/dist/index.d.ts:3959


    structs

    Protected Readonly structs: Object

    Index signature

    ▪ [name: string]: StructAbi

    Inherited from

    Contract.structs

    Defined in

    node_modules/starknet/dist/index.d.ts:3961

    Methods

    attach

    attach(address): void

    Parameters

    NameType
    addressstring

    Returns

    void

    Inherited from

    Contract.attach

    Defined in

    node_modules/starknet/dist/index.d.ts:3987


    call

    call(method, args?, «destructured»?): Promise<Result>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata
    «destructured»CallOptions

    Returns

    Promise<Result>

    Inherited from

    Contract.call

    Defined in

    node_modules/starknet/dist/index.d.ts:3990


    connect

    connect(providerOrAccount): void

    Parameters

    NameType
    providerOrAccountProviderInterface | AccountInterface

    Returns

    void

    Inherited from

    Contract.connect

    Defined in

    node_modules/starknet/dist/index.d.ts:3988


    deployed

    deployed(): Promise<Contract>

    Returns

    Promise<Contract>

    Inherited from

    Contract.deployed

    Defined in

    node_modules/starknet/dist/index.d.ts:3989


    estimate

    estimate(method, args?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata

    Returns

    Promise<EstimateFeeResponse>

    Inherited from

    Contract.estimate

    Defined in

    node_modules/starknet/dist/index.d.ts:3992


    getVersion

    getVersion(): Promise<ContractVersion>

    Returns

    Promise<ContractVersion>

    Inherited from

    Contract.getVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3996


    increment

    increment(): Promise<{ transaction_hash: string }>

    Increments the counter by 1.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the result of the execution.

    Defined in

    sdks/tests/helpers/src/counter.ts:58


    increment_by

    increment_by(value): Promise<{ transaction_hash: string }>

    Increments the counter by the specified value.

    Parameters

    NameTypeDescription
    valuenumberThe value to increment the counter by.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the result of the execution.

    Defined in

    sdks/tests/helpers/src/counter.ts:69


    increment_by_array

    increment_by_array(args): Promise<{ transaction_hash: string }>

    Increments the counter by an array of numbers using increment_by_array.

    Parameters

    NameTypeDescription
    argsnumber[]The array of values to increment the counter by.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the result of the execution.

    Defined in

    sdks/tests/helpers/src/counter.ts:98


    increment_by_multicall

    increment_by_multicall(values): Promise<{ transaction_hash: string }>

    Increments the counter by an array of numbers using a multicall of increment_by.

    Parameters

    NameTypeDescription
    valuesnumber[]The array of values to increment the counter by.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the result of the execution.

    Defined in

    sdks/tests/helpers/src/counter.ts:80


    invoke

    invoke(method, args?, «destructured»?): Promise<{ transaction_hash: string }>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata
    «destructured»InvokeOptions

    Returns

    Promise<{ transaction_hash: string }>

    Inherited from

    Contract.invoke

    Defined in

    node_modules/starknet/dist/index.d.ts:3991


    isCairo1

    isCairo1(): boolean

    Returns

    boolean

    Inherited from

    Contract.isCairo1

    Defined in

    node_modules/starknet/dist/index.d.ts:3995


    parseEvents

    parseEvents(receipt): ParsedEvents

    Parameters

    NameType
    receiptGetTransactionReceiptResponse

    Returns

    ParsedEvents

    Inherited from

    Contract.parseEvents

    Defined in

    node_modules/starknet/dist/index.d.ts:3994


    populate

    populate(method, args?): Call

    Parameters

    NameType
    methodstring
    args?RawArgs

    Returns

    Call

    Inherited from

    Contract.populate

    Defined in

    node_modules/starknet/dist/index.d.ts:3993


    reset

    reset(): Promise<{ transaction_hash: string }>

    Resets the counter.

    Returns

    Promise<{ transaction_hash: string }>

    A promise that resolves to the result of the execution.

    Remarks

    This function requires the Account used by the Counter to be its owner.

    Defined in

    sdks/tests/helpers/src/counter.ts:112


    typedv2

    typedv2<TAbi>(tAbi): TypedContractV2<TAbi>

    Type parameters

    NameType
    TAbiextends readonly (AbiImpl | AbiInterface | AbiConstructor | AbiFunction | AbiStruct | AbiEnum | AbiEvent)[]

    Parameters

    NameType
    tAbiTAbi

    Returns

    TypedContractV2<TAbi>

    Inherited from

    Contract.typedv2

    Defined in

    node_modules/starknet/dist/index.d.ts:3997

    @0xknwn/starknet-test-helpers / Exports / SwapRouter

    Class: SwapRouter

    Represents a Swap contract.

    Hierarchy

    • Contract

      SwapRouter

    Table of contents

    Constructors

    Properties

    Methods

    Constructors

    constructor

    new SwapRouter(address, account): SwapRouter

    Creates an instance of the Counter contract.

    Parameters

    NameTypeDescription
    addressstringThe address of the contract.
    accountAccountThe account used to interact with the contract.

    Returns

    SwapRouter

    Overrides

    Contract.constructor

    Defined in

    sdks/tests/helpers/src/swap_router.ts:55

    Properties

    abi

    abi: Abi

    Inherited from

    Contract.abi

    Defined in

    node_modules/starknet/dist/index.d.ts:3957


    address

    address: string

    Inherited from

    Contract.address

    Defined in

    node_modules/starknet/dist/index.d.ts:3958


    callStatic

    Readonly callStatic: Object

    Index signature

    ▪ [name: string]: AsyncContractFunction

    Inherited from

    Contract.callStatic

    Defined in

    node_modules/starknet/dist/index.d.ts:3968


    deployTransactionHash

    Optional deployTransactionHash: string

    Inherited from

    Contract.deployTransactionHash

    Defined in

    node_modules/starknet/dist/index.d.ts:3960


    estimateFee

    Readonly estimateFee: Object

    Index signature

    ▪ [name: string]: ContractFunction

    Inherited from

    Contract.estimateFee

    Defined in

    node_modules/starknet/dist/index.d.ts:3974


    events

    Protected Readonly events: AbiEvents

    Inherited from

    Contract.events

    Defined in

    node_modules/starknet/dist/index.d.ts:3964


    functions

    Readonly functions: Object

    Index signature

    ▪ [name: string]: AsyncContractFunction

    Inherited from

    Contract.functions

    Defined in

    node_modules/starknet/dist/index.d.ts:3965


    populateTransaction

    Readonly populateTransaction: Object

    Index signature

    ▪ [name: string]: ContractFunction

    Inherited from

    Contract.populateTransaction

    Defined in

    node_modules/starknet/dist/index.d.ts:3971


    providerOrAccount

    providerOrAccount: ProviderInterface | AccountInterface

    Inherited from

    Contract.providerOrAccount

    Defined in

    node_modules/starknet/dist/index.d.ts:3959


    structs

    Protected Readonly structs: Object

    Index signature

    ▪ [name: string]: StructAbi

    Inherited from

    Contract.structs

    Defined in

    node_modules/starknet/dist/index.d.ts:3961

    Methods

    attach

    attach(address): void

    Parameters

    NameType
    addressstring

    Returns

    void

    Inherited from

    Contract.attach

    Defined in

    node_modules/starknet/dist/index.d.ts:3987


    call

    call(method, args?, «destructured»?): Promise<Result>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata
    «destructured»CallOptions

    Returns

    Promise<Result>

    Inherited from

    Contract.call

    Defined in

    node_modules/starknet/dist/index.d.ts:3990


    connect

    connect(providerOrAccount): void

    Parameters

    NameType
    providerOrAccountProviderInterface | AccountInterface

    Returns

    void

    Inherited from

    Contract.connect

    Defined in

    node_modules/starknet/dist/index.d.ts:3988


    deployed

    deployed(): Promise<Contract>

    Returns

    Promise<Contract>

    Inherited from

    Contract.deployed

    Defined in

    node_modules/starknet/dist/index.d.ts:3989


    estimate

    estimate(method, args?): Promise<EstimateFeeResponse>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata

    Returns

    Promise<EstimateFeeResponse>

    Inherited from

    Contract.estimate

    Defined in

    node_modules/starknet/dist/index.d.ts:3992


    faucet

    faucet(amount): Promise<GetTransactionReceiptResponse>

    Sends a request to the faucet to receive a specified amount of Token A.

    Parameters

    NameTypeDescription
    amountUint256The amount of tokens to request from the faucet.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt once the transfer is complete.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:64


    getVersion

    getVersion(): Promise<ContractVersion>

    Returns

    Promise<ContractVersion>

    Inherited from

    Contract.getVersion

    Defined in

    node_modules/starknet/dist/index.d.ts:3996


    get_conversion_rate

    get_conversion_rate(): Promise<bigint>

    Retrieves the conversion rate.

    Returns

    Promise<bigint>

    A promise that resolves to a bigint representing the conversion rate.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:108


    invoke

    invoke(method, args?, «destructured»?): Promise<{ transaction_hash: string }>

    Parameters

    NameType
    methodstring
    args?ArgsOrCalldata
    «destructured»InvokeOptions

    Returns

    Promise<{ transaction_hash: string }>

    Inherited from

    Contract.invoke

    Defined in

    node_modules/starknet/dist/index.d.ts:3991


    isCairo1

    isCairo1(): boolean

    Returns

    boolean

    Inherited from

    Contract.isCairo1

    Defined in

    node_modules/starknet/dist/index.d.ts:3995


    parseEvents

    parseEvents(receipt): ParsedEvents

    Parameters

    NameType
    receiptGetTransactionReceiptResponse

    Returns

    ParsedEvents

    Inherited from

    Contract.parseEvents

    Defined in

    node_modules/starknet/dist/index.d.ts:3994


    populate

    populate(method, args?): Call

    Parameters

    NameType
    methodstring
    args?RawArgs

    Returns

    Call

    Inherited from

    Contract.populate

    Defined in

    node_modules/starknet/dist/index.d.ts:3993


    set_conversion_rate

    set_conversion_rate(rate): Promise<GetTransactionReceiptResponse>

    Sets the conversion rate for the swap router.

    Parameters

    NameTypeDescription
    ratestringThe conversion rate to be set.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt once the conversion rate is set.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:95


    set_tokens

    set_tokens(tokenAAddress, tokenBAddress): Promise<GetTransactionReceiptResponse>

    Sets the token addresses for tokenA and tokenB.

    Parameters

    NameTypeDescription
    tokenAAddressstringThe address of tokenA.
    tokenBAddressstringThe address of tokenB.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt once the transaction is confirmed.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:80


    swap

    swap(tokenAAddress, amount): Promise<GetTransactionReceiptResponse>

    Swaps a specified amount of a token for another token.

    Parameters

    NameTypeDescription
    tokenAAddressstringThe address of the token to be swapped.
    amountUint256The amount of the token to be swapped.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt once the swap is completed.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:118


    swap_maximum_at

    swap_maximum_at(tokenAAddress, rate, amount): Promise<GetTransactionReceiptResponse>

    Swaps the maximum amount of tokens at a given rate.

    Parameters

    NameTypeDescription
    tokenAAddressstringThe address of the token A.
    ratestringThe rate at which to swap the tokens.
    amountUint256The amount of tokens to swap.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt of the swap.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:171


    swap_minimum_at

    swap_minimum_at(tokenAAddress, rate, amount): Promise<GetTransactionReceiptResponse>

    Executes a swap with a minimum rate and amount.

    Parameters

    NameTypeDescription
    tokenAAddressstringThe address of the token A.
    ratestringThe rate of the swap.
    amountUint256The amount to swap.

    Returns

    Promise<GetTransactionReceiptResponse>

    A promise that resolves to the transaction receipt of the swap.

    Defined in

    sdks/tests/helpers/src/swap_router.ts:145


    typedv2

    typedv2<TAbi>(tAbi): TypedContractV2<TAbi>

    Type parameters

    NameType
    TAbiextends readonly (AbiImpl | AbiInterface | AbiConstructor | AbiFunction | AbiStruct | AbiEnum | AbiEvent)[]

    Parameters

    NameType
    tAbiTAbi

    Returns

    TypedContractV2<TAbi>

    Inherited from

    Contract.typedv2

    Defined in

    node_modules/starknet/dist/index.d.ts:3997

    How to Contribute

    We really appreciate and value contributions to the starknet-modular-account. There are different ways to be involved so do not hesitate to do it.

    Development Guidelines

    Before starting development, please create an issue to open the discussion, validate that the PR is wanted and coordinate with the team.

    Please check this document to make sure your contributions are merged as soon as possible.

    Table of Contents

    Pull Requests (PRs)

    As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the repository. See "Fork-a-Repo" for how to work.

    The typical PR includes:

    • a branch associated with the PR should be rebased to the head of develop
    • documentation that complies with the PR template. Make sure every section of it is properly fullfilled

    Code Reviews

    Maintainers will review your code and ask for changes if necessary you code can be merged into the repository. Be mindful and forgiving as we might not be available right on.

    Many of the issues we are facing during the code review are due to a lack of context. Do not hesitate to explain why you are doing what you are doing.

    IMPORTANT Pay attention to the maintainer's feedback and do the changes accordingly.

    Environment

    The project uses a number of tools. Make sure you have installed them in order to develop and test:

    Once you have forked/cloned the repository, you should create a .env.devnet.json file at the root of the project. You can simply copy the content of .env.template.json if you plan to use the devnet on the default port and with the account associated with the seed 0!

    Useful Commands

    • (1) fetch the project cairo dependencies
    scarb fetch
    
    • (2) build the project artifacts
    scarb build
    
    • (3) execute starknet foundry tests
    # you can also use: snforge test
    scarb test
    
    • (4) start starknet-devnet on the default port
    starknet-devnet --seed=0
    
    • (5) create a configuration file to run the project against the devnet
    cp .env.template.json .env.devnet.json
    
    • (6) install node dependencies
    npm install
    
    • (7) execute the npm test scripts with a specific test suite
    npm run test -- simple_account.test.ts
    
    • (8) start mitmproxy with the browser UI on port 8080 and redirect all the requests to the default starknet. You can then change the url in .env.devnet.json so that you run the tests through http://localhost:8080
    mitmweb --mode reverse:http://localhost:5050
    

    Getting ETH on Sepolia

    To get ETH on Starknet Sepolia

    Learning Starknet/Cairo

    If you are not used to Starknet and Cairo yet, a good starting point is to learn is the list of ressources below:

    Do not hesitate to join the Starkware Discord and some Telegram Developer Groups...

    More questions

    If you have any questions, feel free to post them as an issues.

    Thanks for your time and code!

    Starknet Accounts and Network Updates

    There are already numerous implementations of Abstract Accounts, many of which provide awesome features:

    The 2024 Starknet roadmap provides some details about the expected features. In particular, see Mattéo Georges answer in Dec 2023 that suggests the Paymaster is not yet prioritized.

    Proposals, Whitepapers and Docs for Ethereum Accounts

    • Adam Egyed (@adamegyed), Fangting Liu (@trinity-0111), Jay Paik (@jaypaik), Yoav Weiss (@yoavw), Huawei Gu (@huaweigu), Daniel Lim (@dlim-circle), Zhiyu Zhang (@ZhiyuCircle), "ERC-6900: Modular Smart Contract Accounts and Plugins [DRAFT]," Ethereum Improvement Proposals, no. 6900, April 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6900.
    • zeroknots (@zeroknots), Konrad Kopp (@kopy-kat), Taek Lee (@leekt), Fil Makarov (@filmakarov), Elim Poon (@yaonam), Lyu Min (@rockmin216), "ERC-7579: Minimal Modular Smart Accounts [DRAFT]," Ethereum Improvement Proposals, no. 7579, December 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7579.
    • Safe Module system that supports an alpha implementation of the Safe{Core} Protocol
    • The Kernel Smart Contract
    • The RIP 7560 that is a proposal to make ERC 4337 mandatory for rollups.

    Module Registry

    • Konrad Kopp (@kopy-kat), zeroknots (@zeroknots), "ERC-7484: Registry Extension for ERC-7579 [DRAFT]," Ethereum Improvement Proposals, no. 7484, August 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7484.

    Module Use-Cases

    Modules help to address advanced scenarios. They are often classified in 4 groups:

    • Roles: e.g. spending limits, associated token: vTokens, NFT(id) or Oracle, multiple factor for administrative privileges, recurring payments, alternative signatures including faceid or fingerprints, zkproof, Merkle tree for Offchain ACL
    • Recovery: e.g. social recovery, custodial recovery, physical devices, other secrets validation
    • Protection: e.g. allow/deny list, freeze account, external whitelisting, Oracle MEV protection
    • Modifiers: e.g. time-lock, cooldown/grace period, bonds

    To dig deeper into some of the many scenarios associated with Module, you can have a look at existing implementations like:

    Other resources

    You might also want to check:

    Contributor Covenant Code of Conduct

    Our Pledge

    We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

    We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

    Our Standards

    Examples of behavior that contributes to a positive environment for our community include:

    • Demonstrating empathy and kindness toward other people
    • Being respectful of differing opinions, viewpoints, and experiences
    • Giving and gracefully accepting constructive feedback
    • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
    • Focusing on what is best not just for us as individuals, but for the overall community

    Examples of unacceptable behavior include:

    • The use of sexualized language or imagery, and sexual attention or advances of any kind
    • Trolling, insulting or derogatory comments, and personal or political attacks
    • Public or private harassment
    • Publishing others' private information, such as a physical or email address, without their explicit permission
    • Other conduct which could reasonably be considered inappropriate in a professional setting

    Enforcement Responsibilities

    Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

    Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

    Scope

    This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

    Enforcement

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at 0xknwn at gmail dot com. All complaints will be reviewed and investigated promptly and fairly.

    All community leaders are obligated to respect the privacy and security of the reporter of any incident.

    Enforcement Guidelines

    Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

    1. Correction

    Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

    Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

    2. Warning

    Community Impact: A violation through a single incident or series of actions.

    Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

    3. Temporary Ban

    Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

    Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

    4. Permanent Ban

    Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

    Consequence: A permanent ban from any sort of public interaction within the community.

    Attribution

    This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

    Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

    For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

    MIT License

    Copyright (c) 2024 0xknwn

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.