# Content Scripts

In the context of web extension development, content scripts are JavaScript files that are injected and executed in the context of web pages. They are a crucial component of browser extensions, allowing the extension to interact with and manipulate the content of a webpage, as well as communicate with other parts of the extension, such as background scripts and popup scripts.

Content scripts have some important properties:

  1. Isolation: Content scripts run in an isolated scope, separate from the webpage's JavaScript context. This means that variables, functions, and objects defined in a content script won't be accessible to the webpage's scripts, and vice versa. However, content scripts can still access and manipulate the DOM of the webpage.

  2. Communication: Content scripts can communicate with other parts of the extension, such as background scripts or popup scripts, using the browser's messaging API. This allows for coordination between different components of an extension.

  3. Permissions: Content scripts execute with the permissions granted to the extension by the user. This allows them to perform actions like making network requests or accessing certain browser APIs, but within the limits of the extension's declared permissions.

In a web extension manifest file, content scripts are defined using the "content_scripts" property, which is an array of objects specifying the properties of each content script, such as the JavaScript file to be injected, the CSS file (if any), and the web pages where the content script should run (using match patterns).

Here's an example of defining a content script in a manifest file:

{
  "manifest_version": 2,
  "name": "My Web Extension",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["*://*.example.com/*"],
      "js": ["content_script.js"],
      "css": ["content_style.css"]
    }
  ]
}

In this example, the content_script.js and content_style.css files will be injected into any page on the example.com domain.

# UTXO Content Scripts

Now, having understood the previous explanation about what Content Scripts are and how they work, let's learn about UTXO Content Scripts, with some examples and an exploration of all its specific features.

# Flow

For better understanding, it's important to know all the steps included in the injection script flow. To facilitate this, the simple flowchart below was created to help developers who want to integrate Pali into the UTXO workflow (note that this same flow can be used to understand EVM Content Scripts as the process is really similar):

png

In this flowchart, we have some steps between user interaction and the final result in the dApp. Initially, when a user accesses a dApp page, the UTXO Content Scripts are automatically injected, and all methods available in window.pali become available for the current application. Thus, with these methods available, the user is free to interact and perform any actions in the dApp.

# Methods

The method available for browser window.pali has some internal methods that are wrapped by the class PaliInpageProviderSys. This class extends another class called BaseProvider, which is a base class for UTXO (window.pali) and EVM (window.ethereum) providers, with common methods between them. These classes, with respective methods, will be explained next.

# Base Provider methods

This class have some generic methods that will be used by PaliInpageProviderSys and PaliInpageProviderEth classes. Here is an explanation about each method (including private methods):

  1. constructor: This is the constructor method that gets called when a new instance of the class is created. It takes three parameters chainType, maxEventListeners, and wallet. The chainType is a string specifying the type of blockchain, maxEventListeners is the maximum number of event listeners that can be attached to this provider instance, and wallet is a string indicating the type of wallet being used.

  2. request: This method is used to make an RPC (Remote Procedure Call) request. It takes an object with method and params properties. It validates the input and then creates a new promise that sends the RPC request and resolves with the result or rejects on error.

  3. enable: This method is deprecated and it will be discontinued in the future. It's newer version is window.ethereum.request({ method:'eth_requestAccounts', params: []}) or window.pali.request({ method:'sys_requestAccounts', params: []}) methods. It sends a request to the extension that prompts the user with a popUp to approve or not the connection of a given address with the dApp (differently from other wallet extensions, Pali only enables one account be connected to the dApp per time. It can have multiple different accounts to different dApps, but for a given dApp there always will be one active account). If it's the first time this method is called, it will also print a deprecation warning in console.

  4. disable: This is another deprecated method. It sends a request to disable the account and returns a promise that resolves to an array of addresses. Similar to enable, it also prints a deprecation warning in console if it's the first time this method is called.

  5. _warnOfDeprecation: This is a private method used to print a deprecation warning for a given event name if it hasn't already been warned about.

  6. _rpcRequest: This is another private method used to make an RPC request. It takes a payload and a callback. The payload can be either a single request or an array of requests. It sends the request and calls the callback with either the result or an error.

  7. proxy: This is another private method that is used to send a message to the window from the extension. It takes a type and data, creates a unique event listener on the window for the message response, posts the message to the window, and returns a promise that resolves with the response or rejects with an error.

Here are the return types of all public methods:

- request: Promise<Maybe<T>>
- enable: Promise<string[]>
- disable: Promise<string[]>
- proxy: Promise<null|undefined|unknown>

# PaliInpageProviderSys methods

This class is injected in browser method window.pali and it provide all methods inside PaliInpageProviderSys class. Here is an explanation about all these methods:

  1. constructor - This is the method called when a new instance of PaliInpageProviderSys is created. It initializes the Syscoin provider state and sets up event listeners for various wallet notifications. It also calls the wallet_getSysProviderState method and initializes the state.

  2. activeExplorer - This method returns the active block explorer URL, after ensuring that the provider has been initialized.

  3. _initializeState - This method is used to initialize the provider state. It takes an optional initial state parameter and updates the provider state. It also marks the provider as initialized and emits a _sysInitialized event.

  4. isUnlocked - This method returns a boolean indicating whether the Pali is unlocked, after ensuring that the provider has been initialized.

  5. isTestnet - This method returns a boolean indicating whether the provider is connected to a testnet, after ensuring that the provider has been initialized.

  6. request - This method overrides the request method from the BaseProvider. It first checks if the method is not wallet_getSysProviderState, and if so, checks if the connected chain is Syscoin. If not, it throws an error. Otherwise, it calls the request method from the BaseProvider.

  7. _handleUnlockStateChanged - This method is used to handle changes in the unlock state. It updates the provider state and handles the connection of the xpub if the unlock state has changed.

  8. _handleConnectedXpub - This method is used to handle the connection of the xpub. It simply updates the provider state with the new xpub.

  9. _handleActiveBlockExplorer - This method is used to handle changes in the active block explorer. It updates the provider state with the new block explorer URL.

  10. _handleIsTestnet - This method is used to handle changes in the testnet state. It updates the provider state with the new testnet state.

  11. _isSyscoinChain - This method checks if the connected chain is Syscoin by checking the coin of the connected block explorer.

  12. _handleDisconnect - This method handles the disconnection of the provider. It updates the internal state and emits required events.

  13. _sys_ - This is a readOnly method, internally initializated through the _getSysAPI, returns a Proxy object with custom methods to interact with some specific features of the Syscoin UTXO chain. The methods include isNFT, getUserMintedTokens, getHoldingsData, getConnectedAccountXpub, getChangeAddress, and getDataAsset.

The _getSysAPI class is accessible through window.pali._sys which holds the Syscoin API Proxy object, and version which is set to 2. There are also two private fields: _sysState which holds the current state of the Syscoin provider, and _defaultState which is a static field holding the default state.

# Talking about _sys

window.pali._sys: {
    isNFT: (guid: number) => boolean;
    getUserMintedTokens: () => Promise<{
        symbol: string;
        assetGuid: string;
        contract: string;
        decimals: number;
        maxSupply: string;
        pubData: any;
        totalSupply: string;
        updateCapabilityFlags: number;
    }[]>;
    getHoldingsData: () => Promise<any[]>;
    getConnectedAccountXpub: () => string;
    getChangeAddress: () => Promise<string>;
    getDataAsset: (assetGuid: string) => Promise<{
      assetGuid: string;
      contract: string;
      decimals: number;
      maxSupply: string;
      pubData: any;
      symbol: string;
      totalSupply: string;
      updateCapabilityFlags: number;
    }>;
}

This public field in PaliInpageProviderSys class is a wrap of method _getSysAPI. The _getSysAPI method in the PaliInpageProviderSys class is creating a proxy object to handle several utility methods related to the Syscoin UTXO provider.

Here are the methods that are being wrapped inside this proxy:

  1. isNFT: This method accepts a guid (Globally Unique Identifier) as an argument and returns a boolean value indicating whether the specified asset is a Non-Fungible Token (NFT) on the Syscoin UTXO chain. It does this by calling the _isNFT function from the imported @pollum-io/sysweb3-utils (opens new window) module with the provided guid as its argument.

  2. getUserMintedTokens: This method fetches minted tokens of the currently connected account from the Syscoin UTXO chain. It first makes a request to fetch the account data, filters out transactions of type 'SPTAssetActivate', and collects all tokens related to these transactions. For each token, it makes a request to get asset information, formats this information, and if the formatted asset info includes assetGuid, it is returned. The final output is an array of such token assets.

  3. getHoldingsData: This method gets the tokens held by the current connected account on the Syscoin UTXO chain. It makes a request to get tokens associated with the wallet and if the response has Syscoin tokens, they are returned.

  4. getConnectedAccountXpub: This method returns the extended public key (xpub) of the currently connected account. This key is stored in the _sysState property of the PaliInpageProviderSys instance.

  5. getChangeAddress: This method makes a request to fetch the change address of the currently connected account.

  6. getDataAsset: This method accepts an assetGuid as its argument and returns data about the asset with this identifier from the Syscoin UTXO chain. It waits until the provider is initialized (by checking _sysState and using event _sysInitialized) and then uses getAsset function from the imported @pollum-io/sysweb3-utils (opens new window) module to fetch the asset data.

Additionally, the PaliInpageProviderSys class exposes several public methods. These methods draw functionality from the EVM EIP1193 concept, adapted to better suit UTXO chain operations:

- activeExplorer: Promise<string>
- isUnlocked: Promise<boolean>
- isTestnet: Promise<boolean>
- isBitcoinBased: boolean
- request<T>: Promise<Maybe<T>> (Promise that resolves with the result of the RPC method, or rejects if an error is encountered.)

Those methods are accessible straight through: window.pali.method_name().

# How to use it?

With this explanation, you will be able to use it easily. First, in your preferred dApp project, it will be necessary to define the current provider to use, as in the following example (you could as well use directly window.pali, this suppose a react env with useState):

const [currentUTXOProvider, setCurrentUTXOProvider] = useState(null);

useEffect(() => {
  if (window.pali) {
    // now, all available methods inside window.pali can be used in your dApp project!
    setCurrentUTXOProvider(window.pali);
  }
}, []);

const getPaliCurrentState = () => currentUTXOProvider._sysState;

console.log(getPaliCurrentState());

and it will print correctly the Pali state in console:

{
  "blockExplorerURL": null,
  "xpub": null,
  "isUnlocked": false,
  "initialized": true,
  "isPermanentlyDisconnected": false,
  "isTestnet": false
}

Easy, right? Only these steps are necessary to build a universe of possibilities.

Just note that differently from V1, we now return null for xpub and blockExplorerURL if user isn't connected to the dApp. That might be because the connection isn't yet made or the wallet is locked, in which case the isUnlocked variable will be returning false.

Feel free to use it and have fun!

# EVM Content Scripts

Now, we will discuss EVM Content Scripts. Everything explained in the UTXO Content Scripts can be applied here, but there are some differences to highlight. The first and main difference is regarding the method name available in the browser. For EVM dApp interactions, we will use the window.ethereum method. Within this method, all methods from the PaliInpageProviderEth class are available and we will explain each one in the following section.

TIP

It is crucial to highlight that for the sake of compatibility, our window.ethereum closely mirrors the functionality of the market leader, Metamask. This means that all custom methods of Metamask are enabled by default, including window.ethereum.isMetamask, which is set to true. This decision was made to ensure that Pali users could seamlessly use decentralized applications (dApps) such as Uniswap, 1inch, and OpenSea from the outset.

Looking ahead, we plan to further develop Pali in subsequent releases and facilitate custom integrations. Our goal is for the majority of dApps to be able to distinguish Pali from Metamask in the future. This will pave the way for a unique recognition of Pali, setting it apart from Metamask, and enhancing the user experience.

# PaliInpageProviderEth methods

This class is injected in browser method window.ethereum, as said previously, and it provide all methods inside PaliInpageProviderEth class. Here is an explanation about all these methods:

  1. constructor: This is the constructor method that's run when a new instance of the PaliInpageProviderEth class is created. It initializes several properties, binds methods, sets up event listeners, and attempts to get the initial provider state.

  2. isConnected: This method returns whether the provider can process RPC (Remote Procedure Call) requests.

  3. sendAsync: This method is used to send an asynchronous request. It's considered deprecated and is maintained for backwards compatibility.

  4. send: This method handles RPC requests. It's overloaded, meaning it has different behaviors depending on the number and types of arguments it's called with. It's considered deprecated and is maintained for backwards compatibility.

  5. _rpcRequest: This is a protected method used internally for handling RPC requests.

  6. _sendSync: This is a private method used for handling synchronous requests.

  7. _handleAccountsChanged: This private method is called whenever the accounts change. It validates the accounts and, if any changes are detected, it updates the internal state and emits an 'accountsChanged' event.

  8. _handleConnect: This private method is invoked when the provider becomes connected. It updates internal state and emits the required 'connect' event.

  9. _handleChainChanged: This private method is triggered whenever the chain is changed. It updates internal state and emits a 'chainChanged' event.

  10. _handleDisconnect: This private method is invoked when the provider becomes disconnected. It updates the internal state and emits the required 'disconnect' event.

  11. _handleUnlockStateChanged: This private method is invoked when the unlocked state changes. It updates the internal state and handles changes in accounts.

  12. _initializeState: This private method sets the initial state of the provider and marks it as initialized.

  13. _getExperimentalApi: This private method returns a Proxy object that contains experimental API methods. In this case, it includes the isUnlocked method which checks if Pali is unlocked by the user.

Overall, this class provides the necessary methods for interacting with the Ethereum network, including sending RPC requests, handling account and chain changes, and managing the state of the provider.

Here are the return types of all public methods:

- send: Promise<undefined|null|unknown>
- sendAsync: void
- isBitcoinBased: boolean
- isConnected: boolean

# Experimental method: isUnlocked

WARNING

This method is experimental. Use it at your own risk.

window.ethereum._metamask.isUnlocked(): Promise<boolean>;

Returns a promise that resolves to a boolean indicating if Pali is unlocked by the user. Pali must be unlocked to perform any operation involving user accounts. Note that this method doesn't indicate if the user has exposed any accounts to the caller.

# Experimental method: requestBatch

We do not yet support the requestBatch method, but we are working on it to provide this support as soon as possible. Thank you for understanding!

# RPC methods: Send Transaction

You can send a transaction in Pali using the eth_sendTransaction (opens new window) RPC method.

For example, the following JavaScript gets the user's accounts and sends a transaction when they select each button, and the following HTML displays the buttons.

# JavaScript

const ethereumButton = document.querySelector(".enableEthereumButton");
const sendEthButton = document.querySelector(".sendEthButton");

let accounts = [];

// Send Ethereum to an address
sendEthButton.addEventListener("click", () => {
  paliEvmProvider
    .request({
      method: "eth_sendTransaction",
      params: [
        {
          from: accounts[0], // The user's active address.
          to: "0x2f318C334780961FB129D2a6c30D0763d9a5C970", // Required except during contract publications.
          value: "0x29a2241af62c0000", // Only required to send ether to the recipient from the initiating external account.
          gasPrice: "0x09184e72a000", // Customizable by the user during Pali confirmation.
          gas: "0x2710", // Customizable by the user during Pali confirmation.
        },
      ],
    })
    .then((txHash) => console.log(txHash))
    .catch((error) => console.error(error));
});

ethereumButton.addEventListener("click", () => {
  getAccount();
});

async function getAccount() {
  accounts = await paliEvmProvider.request({ method: "eth_requestAccounts" });
}

# HTML

<button class="enableEthereumButton btn">Enable Ethereum</button>
<button class="sendEthButton btn">Send ETH</button>

# Transaction parameters

# Nonce

In Ethereum, every transaction has a nonce, so each transaction can only be processed by the blockchain once. To be a valid transaction, either:

  • The nonce must be 0.
  • A transaction with a nonce of the previous number, from the same account, must have been processed.

This means that transactions are always processed in order for a given account.

Nonces are easy to mess up, especially when a user is interacting with multiple applications with pending transactions using the same account, potentially across multiple devices. Because of this, Pali doesn't allow dapp developers to customize nonces.

# Gas price

Gas price is an optional parameter, and best used on private blockchains.

In Ethereum, every transaction specifies a price for the gas it consumes. To maximize their profit, block producers pick pending transactions with higher gas prices first when creating the next block. This means that a high gas price usually causes your transaction to be processed faster, at the cost of greater transaction fees.

Some networks, such as Layer 2 networks, might have a constant gas price or no gas price. So while you can ignore this parameter on Pali's default networks, you might include it when your dapp knows more about the target network than Pali does. On the default networks, Pali allows users to choose between slow, medium, and fast options for their gas price.

# Gas limit

Gas limit is an optional parameter, since Pali automatically calculates a reasonable gas price.

# To

The to parameter is a hex-encoded Ethereum address. It's required for transactions with a recipient (all transactions except for contract creation).

Contract creation occurs when there is no to value but there is a data value.

# Value

The value parameter is a hex-encoded value of the network's native currency to send. On Mainnet, this is ether (opens new window), which is denominated in wei.

These numbers are often far higher precision than native JavaScript numbers, and can cause unpredictable behavior if not anticipated. We recommend using BN.js (opens new window) when manipulating values intended for Ethereum.

# Data

The data parameter is required for smart contract creation.

This field is also used for specifying contract methods and their parameters. See the Solidity ABI spec (opens new window) for more information on how the data is encoded.

# Chain ID

The chain ID is derived from the user's current selected network at window.ethereum.networkVersion.

In the future, Pali might allow connecting to multiple networks at the same time, at which point this parameter will become important, so it might be useful to be in the habit of including it now.

# RPC Methods: Sign Data

You can use the following RPC methods to request cryptographic signatures from users:

  • eth_signTypedData_v4 - Use this method to request the most human-readable signatures that are efficient to process on-chain. We recommend this for most use cases.
  • personal_sign - Use this method for the easiest way to request human-readable signatures that don't need to be efficiently processed on-chain.

WARNING

eth_sign is deprecated.

TIP

Pali supports signing transactions using Trezor hardware wallet. These wallets only support signing data using personal_sign. If you can't log in to a dapp when using a Trezor, the dapp might be requesting you to sign data using an unsupported method, in which case we recommend using your standard Pali account.

# Use eth_signTypedData_v4

eth_signTypedData_v4 (opens new window) provides the most human-readable signatures that are efficient to process on-chain. It follows the EIP-712 (opens new window) specification to allow users to sign typed structured data that can be verified on-chain. It renders the structured data as usefully as possible to the user (for example, displaying known account names in place of addresses).

An eth_signTypedData_v4 payload uses a standard format of encoding structs, but has a different format for the top-level struct that is signed, which includes some metadata about the verifying contract to provide replay protection of these signatures between different contract instances.

We recommend using eth-sig-util (opens new window) to generate and validate signatures. You can use eip712-codegen (opens new window) to generate most of the Solidity required to verify these signatures on-chain. It currently doesn't generate the top-level struct verification code, so you must write that part manually. See this example implementation (opens new window).

WARNING

Since the top-level struct type's name and the domain.name are presented to the user prominently in the confirmation, consider your contract name, the top-level struct name, and the struct keys to be a user-facing security interface. Ensure your contract is as readable as possible to the user.

# JavaScript

signTypedDataV4Button.addEventListener("click", async function(event) {
  event.preventDefault();

  // eth_signTypedData_v4 parameters. All of these parameters affect the resulting signature.
  const msgParams = JSON.stringify({
    domain: {
      // This defines the network, in this case, Mainnet.
      chainId: 1,
      // Give a user-friendly name to the specific contract you're signing for.
      name: "Ether Mail",
      // Add a verifying contract to make sure you're establishing contracts with the proper entity.
      verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
      // This identifies the latest version.
      version: "1",
    },

    // This defines the message you're proposing the user to sign, is dapp-specific, and contains
    // anything you want. There are no required fields. Be as explicit as possible when building out
    // the message schema.
    message: {
      contents: "Hello, Bob!",
      attachedMoneyInEth: 4.2,
      from: {
        name: "Cow",
        wallets: [
          "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
          "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
        ],
      },
      to: [
        {
          name: "Bob",
          wallets: [
            "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
            "0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
            "0xB0B0b0b0b0b0B000000000000000000000000000",
          ],
        },
      ],
    },
    // This refers to the keys of the following types object.
    primaryType: "Mail",
    types: {
      // This refers to the domain the contract is hosted on.
      EIP712Domain: [
        { name: "name", type: "string" },
        { name: "version", type: "string" },
        { name: "chainId", type: "uint256" },
        { name: "verifyingContract", type: "address" },
      ],
      // Not an EIP712Domain definition.
      Group: [
        { name: "name", type: "string" },
        { name: "members", type: "Person[]" },
      ],
      // Refer to primaryType.
      Mail: [
        { name: "from", type: "Person" },
        { name: "to", type: "Person[]" },
        { name: "contents", type: "string" },
      ],
      // Not an EIP712Domain definition.
      Person: [
        { name: "name", type: "string" },
        { name: "wallets", type: "address[]" },
      ],
    },
  });

  var from = await web3.eth.getAccounts();

  var params = [from[0], msgParams];
  var method = "eth_signTypedData_v4";

  web3.currentProvider.sendAsync(
    {
      method,
      params,
      from: from[0],
    },
    function(err, result) {
      if (err) return console.dir(err);
      if (result.error) {
        alert(result.error.message);
      }
      if (result.error) return console.error("ERROR", result);
      console.log("TYPED SIGNED:" + JSON.stringify(result.result));

      const recovered = sigUtil.recoverTypedSignature_v4({
        data: JSON.parse(msgParams),
        sig: result.result,
      });

      if (
        ethUtil.toChecksumAddress(recovered) === ethUtil.toChecksumAddress(from)
      ) {
        alert("Successfully recovered signer as " + from);
      } else {
        alert(
          "Failed to verify signer when comparing " + result + " to " + from
        );
      }
    }
  );
});

# HTML

<h3>Sign typed data v4</h3>
<button type="button" id="signTypedDataV4Button">eth_signTypedData_v4</button>

# Use personal_sign

personal_sign (opens new window) is the easiest way to request human-readable signatures that don't need to be efficiently processed on-chain. It's often used for signature challenges that are authenticated on a web server, such as Sign-In with Ethereum (opens new window).

Some other signers implement personal_sign as eth_sign, because the Go Ethereum client changed the behavior of their eth_sign method. Because Pali supports existing applications, Pali implements both personal_sign and eth_sign. You might need to check what method your supported signers use for a given implementation.

WARNING

  • Don't use this method to display binary data, because the user wouldn't be able to understand what they're agreeing to.
  • If using this method for a signature challenge, think about what would prevent a phisher from reusing the same challenge and impersonating your site. Add text referring to your domain, or the current time, so the user can easily verify if this challenge is legitimate.

# JavaScript

personalSignButton.addEventListener("click", async function(event) {
  event.preventDefault();
  const exampleMessage = "Example `personal_sign` message.";
  try {
    const from = accounts[0];
    // For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
    // This uses a Node.js-style buffer shim in the browser.
    const msg = `0x${Buffer.from(exampleMessage, "utf8").toString("hex")}`;
    const sign = await paliEvmProvider.request({
      method: "personal_sign",
      params: [msg, from, "Example password"],
    });
    personalSignResult.innerHTML = sign;
    personalSignVerify.disabled = false;
  } catch (err) {
    console.error(err);
    personalSign.innerHTML = `Error: ${err.message}`;
  }
});

# HTML

<h3>Personal sign</h3>
<button type="button" id="personalSignButton">personal_sign</button>

personal_sign prepends the message with \x19Ethereum Signed Message:\n<length of message> before hashing and signing it.

# Wallet Content Scripts

In the following discussion, we will delve into Wallet Content Scripts. It's important to note that the principles and concepts we've outlined previously also apply here, with one key difference: the prefix used in the method name when invoking window.ethereum or window.pali methods.

This distinction is especially critical as some wallet methods are exclusively applicable to UTXO chains, while others are solely relevant for EVM chains. To provide clarity:

  • For methods specific to UTXO chains, you should use window.pali.
  • Conversely, for methods unique to EVM chains, you will need to use window.ethereum.

In the sections below, we will highlight these differences in more detail, ensuring a clear understanding of when and how to use each approach.

# Wallet Methods

This methods is also injected in browser methods but you will need the wallet_ prefix at the method name to use it. Here is an explanation about all the methods availables:

  1. isLocked: This method returns if the wallet is Locked. If returns false it means the wallet is Unlocked.

  2. getChangeAddress: This method will validate if you already have a account created, if you have, will be created a new address for your account. Also, this method can't be used at EVM Networks, so remember to be connected into a SYS UTXO Networks first.

  3. getAccount: This method is used to get the infos about your connected account. As the method before, this method is only available into a SYS UTXO networks.

  4. getBalance: This method returns your balance for the current network connected.

  5. getNetwork: This method returns the infos about the current network connected.

  6. getPublicKey: This method returns the current account xpub value.

  7. getAddress: This method returns the current account address value.

  8. getTokens: This methods returns the current account assets/tokens list.

  9. changeAccount: This method is used to change the current account.

  10. requestPermissions: This method is used to request permissions about your account at a dApp. Also, this method is only available at EVM Networks.

  11. getPermissions: This method is used to get permissions about your account and be available to use some Restricted Methods. Also, this method is only available at EVM Networks.

  12. addEthereumChain: This method is used to add a custom network to your wallet. The params that you provided will be evaluated and if everything is fine, the chain will be added. Also this method is only available for EVM Networks.

  13. switchEthereumChain: This method is used to change between EVM Networks. The only parameter that you need to provide is the network ChainID, this value will be evaluated and if exists in the current wallet networks, will be opened a popup to you accept the network change. Also this method is only available for EVM Networks

  14. getProviderState: This method is used to return the basic infos about the current connected section. Will be returned this infos:

{
  "accounts": Current accounts connected.
  "chainID": current network ChainID converted to number.
  "isUnlocked": If wallet is unlocked or not.
  "networkVersion": Current network ChainID as HEX value.
}
  1. getSysProviderState: This method is used to return the basic SYS infos about the current connected section. Will be returned this infos:
{
  "xpub": Current accounts connected.
  "blockExplorerURL": Current blockbook explorer URL.
  "isUnlocked": If wallet is unlocked or not.
}

Here are the return types of all wallet methods:

- isLocked: boolean
- getChangeAddress: Promise<string>
- getAccount: {
  assets: {
  ethereum: any[];
  syscoin: any[];
  };
  transactions: any;
  address: string;
  id: number;
  isTrezorWallet: boolean;
  label: string;
  balances: {
  ethereum: number;
  syscoin: number;
  };
  xpub: string;
  isImported: boolean;
  } 
  - getBalance: number
  - getNetwork: {
    chainId: number;
    url: string;
    default?: boolean;
    label: string;
    key?: string;
    apiUrl?: string;
    currency?: string;
    explorer?: string;
    slip44?: number;
    }
  - getPublicKey: string
  - getAddress: string
  - getTokens: {
    ethereum: any[];
    syscoin: any[];
    }
  - changeAccount: void
  - requestPermissions: void
  - getPermissions: void
  - addEthereumChain: void
  - switchEthereumChain: void
  - getSysProviderState: {
    xpub: string;
    blockExplorerURL: string;
    isUnlocked: boolean;
    isBitcoinBased: boolean;
    }

# How use it ?

As mentioned before you have to use the _wallet prefix the method name, so if you want to use some of it we need to do like this:

window.ethereum
  .request({
    method: "wallet_getBalance",
  })
  .then((balance) => console.log("Current account balance", balance))
  .catch((error) => console.log(error));

Or some method that needs params to be called:

window.ethereum.request({
  method: "wallet_addEthereumChain",
  params: [
    {
      // Valid RPC URL for the network that you are trying to add
      url: "https://www.rpc-url.com",
      // Valid ChainID for the network
      chainId: "0x00",
      // The label that you want for this network
      label: "RPC Label",
      // Valid API URL for this network
      apiUrl: "https://www.rpc-apiurl.com",
      // Remember to never put this as true, you are adding a EVM Network
      isSyscoinRpc: false,
      // Correct Network Symbol
      symbol: "RPC Symbol",
    },
  ],
});

So, one more time, keep in mind that if you gonna use one of those methods you have to use the wallet_ prefix.