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?
-
This is the base currency if you have not otherwise added other assets. Have you added a pallet? Or created another instance of one outside balances?– NukeCommented Jul 14, 2022 at 12:56
-
so say i've created a new fungible asset(BAT token) using pallet_assets, i want to be able to pay the transactions fees for this node using the created BAT token if user has the balance– rusty loakiCommented Jul 14, 2022 at 12:59
-
also there is pallet_asset_tx_payment (github.com/paritytech/substrate/tree/polkadot-v0.9.19/frame/…). Should i be using this to solve this? ... If so, is there any examples that we can look at?– rusty loakiCommented Jul 14, 2022 at 13:10
-
@rustyloaki are you able to change your tx_fee from native to asset(BAT token)?– Amit Kumar YadavCommented Apr 14, 2023 at 7:55
2 Answers
In order to do this you will need in your runtime the
pallet_asset_tx_payment
pallet. Here's an example of the configuration.
(the pallet would need to be added into theconstruct_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
UncheckedExtrinsic
type.Then on the client side when you construct the signed transaction the SignedExtra needs to be encoded too (eg. subxt).
-
1On the polkadot-js front there's an issue raised to allow this to be specified on the front end: github.com/polkadot-js/apps/issues/7812– SquirrelCommented Jul 14, 2022 at 13:59
-
Have you ever done this ?? It also requires to edit
UncheckedExtrinsic
type inside thecommand_helper.rs
file under node. There we have to call thefrom
function with two arguments, balance andOption<AssetId>
which you have skipped. Please provide some examples of thecommand_helper.rs
file as well. Also can you tell how to encodeSignedExtra
on client side? Commented Jul 20, 2022 at 11:40 -
@Squirrel is it possible to contruct the
SignedExtra
which is needed by pallet_asset_tx_payment ? Commented Nov 30, 2022 at 7:04 -
This post may be helpful: substrate.stackexchange.com/questions/8063/…– Bruno ♦Commented Apr 13, 2023 at 10:09
-
error[E0277]: the trait bound
pallet_assets::Pallet<Runtime>: hidden_include::traits::fungible::Unbalanced<AccountId32>` is not satisfied. Getting this error, can someone face this error while configuring
pallet_asset_tx_payment`– go11liCommented Apr 27, 2023 at 9:44
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:
Runtime
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.
Client
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 AssetId
there.
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.
Polkadot-js/apps sidenote
The 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 Some<AssetId>
.
-
how can i add to substrate client in which file should i make changes? Commented Apr 13, 2023 at 7:02
-