At the moment the transaction fee is payed as the native token in the substrate node template. When I create a new asset_id(say BAT) a fungible asset using pallet_assets, How can I now pay the transaction fees using this BAT token?
In order to do this you will need in your runtime the
pallet_asset_tx_paymentpallet. Here's an example of the configuration.
(the pallet would need to be added into the
construct_runtime!etc. See statemint as an example).
Now that that type is available it needs to be added into the tuple that is the SignedExtra type like this. As you can see that then becomes part of the
Then on the client side when you construct the signed transaction the SignedExtra needs to be encoded too (eg. subxt).
We do this at Encointer, the full code including a client that can pay in the custom asset can be found at https://github.com/encointer/encointer-node. I highlight the most important things here:
You need to include the pallet-asset-tx-payment: https://github.com/encointer/encointer-node/blob/6b5f32350874a099178115de09b163e2b2237e61/runtime/src/lib.rs#L467. We have defined our own
OnChargeTransaction because we don't use the pallet-assets. You can just use the one that pallet-assets exposes.
You need to add it to the signed extension: https://github.com/encointer/encointer-node/blob/6b5f32350874a099178115de09b163e2b2237e61/runtime/src/lib.rs#L523.
This will add an
Option<AssetId> to the signed extension. If it is
Some in the extrinsic, it will use the defined asset as fee-payment token; otherwise it falls back to the native token.
In our encointer-client cli we use the substrate-api-client (subxt-alternative) library to connect to it: https://github.com/scs/substrate-api-client.
Here, we define the signed extension type in extrinsic format: https://github.com/encointer/encointer-node/blob/6b5f32350874a099178115de09b163e2b2237e61/client/encointer-api-client-extension/src/extrinsic_params.rs#L17. It says
CommunityIdentifier here because we don't use the pallet-assets. You will put
At this point we define that we want to pay with the custom asset: https://github.com/encointer/encointer-node/blob/6b5f32350874a099178115de09b163e2b2237e61/client/src/main.rs#L331.
SignedExtension is not exposed in the metadata, hence you need to hardcode it. You need to manually add it to the polkadot-js/api type registry, see https://github.com/polkadot-js/apps/blob/c484456c12dbeeaccc701ec89d891e5e3f53a4cc/packages/apps-config/src/api/spec/encointer-para.ts#L247.
This polkadot-js/apps fix is needed because otherwise polkadot-js/apps is not able to correctly interpret blocks that contain an extrinsic paid in the non-native asset, i.e., where the asset-tx-payment signed extension was