3

For now I have custom SignedExtension in my substrate node:

#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct CheckAccount<T> {
    timestamp: u64,
    _marker: PhantomData<T>,
}

In my polkadot-js-api I define this like so:

let signedExtensions = {
    CheckAccount: {
      extrinsic: {
        timestamp: "u64",
      },
      payload: {},
    },
  };
const api = await ApiPromise.create({
    ...
    SignedExtensions,
  });

And to perform transaction I have specify extension value manually

api.tx.balances
    .transfer(bob, 1000)
    .signAndSend(alice, { timestamp: Date.now() })

The questing is how can I get behaviour for my custom SignedExtension, for example like CheckNonce have, when it automatically initialised with api and don't have to specify it manually?

Update

I want to get something like this:

api.setGetterForSignedExtension("CheckAccount", Date.now);

And then I just simply can call

api.tx.balances
    .transfer(bob, 1000)
    .signAndSend(Alice);

P.S.

And if this possible can custom SignedExtension be integrated with polkadot/apps to allow submit extrinsic throw polkadot ui. Now when I try do it got this error

1002: Verification Error: Runtime error: Execution failed: Runtime panicked: Bad input data provided to validate_transaction: Could not decode `RuntimeCall`, variant doesn't exist: RuntimeApi, Execution failed: Runtime panicked: Bad input data provided to validate_transaction: Could not decode `RuntimeCall`, variant doesn't exist

1 Answer 1

1

Something like following can be tried out:

const { ApiPromise, Keyring } = require('@polkadot/api');

// Create a custom type registry  

const types = {
  CheckAccount: {
    timestamp: 'u64',
  },
};

// Create the api instance with the custom type registry  

const api = await ApiPromise.create({
  provider: wsProvider,
  types,
});

// Create a wrapper function for the transfer transaction  

const transferWithTimestamp = async (from, to, amount) => {
  const transaction = api.tx.balances.transfer(to, amount);

  // Get the current timestamp  
  const timestamp = Date.now();

  // Set the timestamp in the transaction payload  
  const payload = {
    CheckAccount: {
      timestamp,
    },
  };

  // Sign and send the transaction with the payload  
  await transaction.signAndSend(from, { payload });
};

// Use the wrapper function to perform the transfer with the timestamp
transferWithTimestamp(alice, bob, 1000);

here timestamp = Date.now() is evaluated every time and passed in without need to enter manually

1
  • Thanks for you answer! Yes this is the way, but in this case I need to wrap any kind of transaction and adding new transactions on node will require add more wrappers. May 31 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.