Bitcoin

Wallet Provider Injection

Since the Bitcoin community does not have a standard specification for Providers, imToken references EIP-1193 from the Ethereum community and implements it by injecting a bitcoin property into the window object. The specific implementation is as follows:

window.bitcoin = new BitcoinProvider({
  requestTransport: ({ method, params }) => window.imToken.callApi(
    'bitcoin.request',
    {
      method,
      params
    }
  )
})

Developers can access the API provided by the Wallet Provider via window.bitcoin:

Schema

type WalletRpcSchema = [
  /**
   * @description Requests that the user provides an address to be identified by.
   * @example
   * provider.request({ method: 'btc_requestAccounts' }] })
   * // => ['tbc1...', 'tbc1...']
   */
  {
    Method: 'btc_requestAccounts'
    Parameters?: undefined
    ReturnType: string[]
  },
  /**
   * @description Returns the current network associated with the wallet.
   * @example
   * provider.request({ method: 'btc_getNetwork' })
   * // => 'signet'
   */
  {
    Method: 'btc_getNetwork'
    Parameters?: undefined
    ReturnType: Network
  },

  /**
   * @description Gets the public key of the connected wallet.
   * @example
   * provider.request({ method: 'btc_getPublicKey' }] })
   * // => 'publicKey...'
   */
  {
    Method: 'btc_getPublicKey'
    Parameters?: undefined
    ReturnType: string
  },

  /**
   * @description Returns the balance of an address in satoshis.
   * @example
   * provider.request({ method: 'btc_getBalance', params: ['tbc1...'] })
   * // => 1000
   */
  {
    Method: 'btc_getBalance'
    Parameters: [address: string]
    ReturnType: number
  },

  /**
   * @description Retrieves the unspent transaction outputs (UTXOs) for a given address and amount.
   * If the amount is provided, it will return UTXOs that cover the specified amount.
   * If the amount is not provided, it will return all available UTXOs for the address.
   * @example
   * provider.request({ method: 'btc_getUnspent', params: ['tbc1...', 100] })
   * // => [{ utxo }]
   */
  {
    Method: 'btc_getUnspent'
    Parameters: [address: string, amount: number]
    ReturnType: UTXO[]
  },

  /**
   * @description Signs the given PSBT in hex format.
   * @example
   * provider.request({ method: 'btc_signPsbt', params: ['0x...', true] })
   * // => '0x...'
   */
  {
    Method: 'btc_signPsbt'
    Parameters: [psbtHex: Hex, autoFinalize?: boolean]
    ReturnType: Hex
  },
  /**
   * @description Signs multiple PSBTs in hex format.
   * @example
   * provider.request({ method: 'btc_signPsbts', params: ['0x...', '0x...'] })
   * // => ['0x...', '0x...']
   */
  {
    Method: 'btc_signPsbts'
    Parameters: [psbtsHexes: Hex[]]
    ReturnType: Hex[]
  },
  /**
   * @description Signs a message using BIP-322.
   * @example
   * provider.request({ method: 'btc_signMessage', params: ['tb1...'] })
   * // => 'base64...'
   */
  {
    Method: 'btc_signMessage'
    Parameters: [
      message: string,
      type: 'bip322-simple' | 'bip322-full' | 'bip322-legacy'
    ]
    ReturnType: string
  },
  /**
   * @description send raw transaction
   * @example
   * provider.request({ method: 'btc_sendRawTransaction', params: ['signature'] })
   * // => 'string'
   */
   {
     Method: 'btc_sendRawTransaction'
     Parameters: [signature: string]
     ReturnType: string
   },

  /**
   * @description Switch the wallet to the given network.
   * @example
   * provider.request({ method: 'btc_switchNetwork', params: ['signet'] })
   * // => null
   */
  {
    Method: 'btc_switchNetwork'
    Parameters: [network: Network]
    ReturnType: null
  }
]

Provider API

Request User Accounts

  • Method: btc_requestAccounts

  • Parameters: None

  • Returns: string[]

  • Example:

const accounts = await window.bitcoin.request({
    method: 'btc_requestAccounts'
})

// Returns: ['tbc1...', 'tbc1...']

Get Current Network

  • Method: btc_getNetwork

  • Parameters: None

  • Returns: Network

  • Example:

const network = await window.bitcoin.request({
    method: 'btc_getNetwork'
})

// Returns: 'signet'

Get Public Key

  • Method: btc_getPublicKey

  • Parameters: None

  • Returns: string

  • Example:

const publicKey = await window.bitcoin.request({
    method: 'btc_getPublicKey'
})

// Returns: 'publicKey...'

Get Balance

  • Method: btc_getBalance

  • Parameters: [address: string]

  • Returns: number (unit is satoshi)

  • Example:

const balance = await window.bitcoin.request({
    method: 'btc_getBalance',
    params: ['tbc1...']
})

// Returns: 1000

Get Unspent Transaction Outputs (UTXO)

  • Method: btc_getUnspent

  • Parameters: [address: string, amount: number]

  • Returns: UTXO[]

  • Example:

const utxos = await window.bitcoin.request({
    method: 'btc_getUnspent',
    params: ['tbc1...', 100]
})
// Returns: [{ utxo }]

Sign PSBT

  • Method: btc_signPsbt

  • Parameters: [psbtHex: Hex, autoFinalize?: boolean]

  • Returns: Hex

  • Example:

const signedPsbt = await window.bitcoin.request({
    method: 'btc_signPsbt',
    params: ['0x...', true ]
})
// Returns: '0x...'

Batch Sign PSBT

Not yet supported

  • Method: btc_signPsbts

  • Parameters: [psbtsHexes: Hex[]]

  • Returns: Hex[]

  • Example:

const signedPsbts = await window.bitcoin.request({
    method: 'btc_signPsbts',
    params: ['0x...', '0x...']
})
// Returns: ['0x...', '0x...']

Sign Message

Only bip322-simple is supported.

  • Method: btc_signMessage

  • Parameters: [message: string, type: 'bip322-simple' | 'bip322-full' | 'bip322-legacy']

  • Returns: string (Base64 encoded)

  • Example:

const signature = await window.bitcoin.request({
    method: 'btc_signMessage',
    params: ['Hello, World!', 'bip322-simple']
})
// Returns: 'base64...'

Send Raw Transaction

  • Method: btc_sendRawTransaction

  • Parameters: [signature: string]

  • Returns: string

  • Example:

const txid = await window.bitcoin.request({ // Changed 'signature' to 'txid' for clarity, as 'signature' is the param
    method: 'btc_sendRawTransaction',
    params: ['signature'] // 'signature' here refers to the signed raw transaction hex
})
// Returns: '...' // This would be the transaction ID

Switch Network

Not yet supported

  • Method: btc_switchNetwork

  • Parameters: [network: Network]

  • Returns: null

  • Example:

await window.bitcoin.request({
    method: 'btc_switchNetwork',
    params: ['signet']
})
// Returns: null

Other Methods

Get Wallet Name and Icon

const walletName = window.bitcoin.getName(); // => imToken
const walletIcon = window.bitcoin.getIcon(); // => base64 icon

Event Listening

The Provider inherits from EventEmitter and can use standard event listening methods.

type ProviderEventMap = {
  accountsChanged(accounts: string[]): void
  networkChanged(network: Network): void
  connect(connectInfo: ProviderConnectInfo): void
  disconnect(error: ProviderRpcError): void
  message(message: ProviderMessage): void
}

type ProviderEvents = {
  on<TEvent extends keyof ProviderEventMap>(
    event: TEvent,
    listener: ProviderEventMap[TEvent]
  ): void
  removeListener<TEvent extends keyof ProviderEventMap>(
    event: TEvent,
    listener: ProviderEventMap[TEvent]
  ): void
}

Version Compatibility

imToken started injecting the bitcoin provider from version 2.15.4.

Last updated

Was this helpful?