Skip to content
On this page

Pontem Provider

When a user has Pontem Wallet installed (be it as an extension or a mobile app), a special object called Provider is embedded on each page. Its purpose is to enable dApp developers to interact with our wallet.

This object is located in the global variable window. You can access it using a window.pontem call

Below we'll provide sample code and logic for getting information about a user, including their address / public key, as well as send requests to send transactions and sign your messages.

You can find more examples of the Provider object's methods on the API Reference page.

Detect the Provider

The first step is to check the availability of the pPovider. Since the insertion of the pontem provider into the window does not happen immediately when a page is loaded, you should wait for a bit and subscribe to a special event #pontemWalletInjected, which the Provider generates when it is placed in the window.

js
function detectProvider (timeout = 3000) {
  return new Promise((resolve, reject) => {
    if (typeof window.pontem === 'undefined') {
      const timer = setTimeout(reject, timeout)
      window.addEventListener('#pontemWalletInjected', (e) => {
        clearTimeout(timer)
        resolve(e.detail)
      }, { once: true })
    } else {
      resolve(window.pontem)
    }
  })
}

detectProvider()
  .then(provider => console.log('Pontem Wallet Detected'))
  .catch(() => console.log('Pontem Wallet not found'))

Now you know how to get a Provider in your dApp application.
Let's take a closer look at how to interact with it.

Interacting with Provider

Versioning

You should pay attention to the version of Pontem Wallet that the user has installed.

The Aptos ecosystem is still very young, and wallet features may differ considerably from version to version. In the API guide, you can always see in which version a certain method appeared, as well as changes in the method signature.

INFO

The Pontem team is working to minimize future changes to the wallet API and ensure backward compatibility. You can see all the changes introduced in each version in our changelog.

To get the current version of the installed Provider, you need to use the provider.version property. We version according to the semver standard.

js
detectProvider()
  .then(provider => {
    console.log(provider.version) // 2.6.1
  })

Check connection status

First of all, when a Provider object is found, we need to check the status of the wallet connection to the site. To do this, you can use the provider.isConnected method, which will return a boolean value

js
detectProvider()
  .then(async provider => {
    const status = await provider.isConnected(); // true or false
  })

After that, you can query the current account

js
detectProvider()
  .then(async provider => {
    const status = await provider.isConnected()
    
    if(status) {
      const account = await provider.account(); // will return the address of the current account
    }
  })

If you query an account when the user has not given permission for the site to access the wallet, an error will be returned as an exception in Promise.

js
detectProvider()
  .then(async provider => {
    try {
      const account = await provider.account();
    } catch (e) {
      console.log(e); // { code: 401, message: 'Access denied' }
    }
  })

Request to Connect

When a user first interacts your dApp, they will need to allow access to it in their wallet. To initialize this process, you need to call the provider.connect method, which will open an extension window (or mobile application) with a confirmation request.

TIP

If the connect method has already been called before and the user has already granted access, you will receive the following structure in the response, and a UI confirmation window for a join request will not be displayed.

js
detectProvider()
  .then(async provider => {
    try {
      const account = await provider.connect();
      console.log(account);
      /*
        {
          address: "0x797b0209c...15e63e",
          publicKey: "0xf7498703...1ee4e4"
        }
      */
    } catch (e) {
      console.log(e); // { code: 403, message: 'Rejected by user' }
    }
  })

If the user allows access to the wallet account, you will receive an account structure that contains address and publicKey.

TIP

You can also obtain the account's public key later using the provider.publicKey method.

Subscribe to Account change

It can be useful to subscribe to changes in the account's status of connection to the site. For example, a user can switch the account or manually remove the dApp from the list of allowed sites. To properly handle such events, use the provider.onChangeAccount method.

js
detectProvider()
  .then(async provider => {
    const unsubscribe = provider.onChangeAccount((account) => {
      console.log(account); // undefined or address
    })
  })

If the user switches to an account that hasn't yet been granted access to the site, or disables access manually, you will receive undefined in response.

Subscribe to Network change

The same can be done for network change events. When a user switches to a different network, you will also receive a notification. To properly handle such events, use the provider.onChangeNetwork method.

This method will call callback every time the network is changed. The network object stores information about its name, chainId and api address to the node.

js
detectProvider()
  .then(async provider => {
    const unsubscribe = provider.onChangeNetwork((network) => {
      console.log(network);
      // { name: 'Aptos testnet', api: 'https://fullnode.testnet.aptoslabs.com/v1/', chainId: '2' }
    })
  })

TIP

You can also get the current network later using the provider.network method.

Request to Sign Transaction

Now you can proceed to the most interesting part: signing and sending transactions. To send a transaction, you need to prepare all its data and pass it on to the provider.signAndSubmit method

js
detectProvider()
  .then(async provider => {
    const tx = {
      function: '0x1::coin::transfer',
      type_arguments: ['0x1::aptos_coin::AptosCoin'],
      arguments: [
        '0xeb442855143ce3e26babc6152ad98e9da7db7f0820f08be3d006535b663a6292',
        '100'
      ]
    }
    
    try {
      const result = await provider.signAndSubmit(tx)
    } catch (e) {
      console.log(e);
    }
  })

⚡️ TypedArray support

You can also pass TypedArray objects such as Uint8Array, Int8Array objects as arguments.

js
const typedArgument = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05])
const result = await provider.signAndSubmit({
  function: '0x1::coin::transfer',
  type_arguments: ['0x1::aptos_coin::AptosCoin'],
  arguments: [
    typedArgument,
    '100'
  ]
})

Request to Disconnect

You can disconnect the wallet from your dApp at any time by calling the provider.disconnect method. This will not remove the entry about the site from the user's wallet, as only the user can remove a site from the allowed list through the UI interface. The provider.disconnect method will disconnect the wallet, and you will receive a false response to provider.isConnected requests.

js
detectProvider()
  .then(async provider => {
    await provider.disconnect();
  })

TIP

To connect the wallet back you need to call the provider.connect method. This will not trigger a UI confirmation for the user.