GitHub Logo HIP-213: Application Signs for End User

Author Justin Atwell, Greg Scullard
Status Active
Needs Council Approval No
Review period ends Tue, 21 Dec 2021 07:00:00 +0000
Type Informational
Created 2021-11-13
Updated 2021-12-07


Describes the concept of how transactions can be issued by one account, but paid for by another account.


Oftentimes it is appropriate for the application to pay fees associated with a transation rather than the end user.



User stories

As an end user that does not want to incur transaction fees on the network, I still want the ability to hold tokens on the Hedera network



private AccountId getAccountId() throws TimeoutException, PrecheckStatusException, ReceiptStatusException {
// Retrieve the Operator Id
AccountId OPERATOR_ID = AccountId.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_ID")));

// need a placeholder key to satisfy the client.setOperator;
PrivateKey dummyKey = PrivateKey.generate();

//Create a testnet Client
Client client = Client.forTestnet();

// Set the operator (and default signer) to the new private key
client.setOperator(OPERATOR_ID, dummyKey);

// We need the public key of the operator id for the signWith operation below
PublicKey OPERATOR_PUBLIC_KEY = PrivateKey.fromString(Dotenv.load().get("OPERATOR_KEY")).getPublicKey();

// Creates a function that is invoked during the signWith method
Function<byte[], byte[]> transactionSigner = generateSignatureFunction();

// Create a TransferTransaction that transfers 1 tinyBar from the operator to account 0.0.3
TransactionResponse response = new TransferTransaction()
        .addHbarTransfer(OPERATOR_ID, Hbar.fromTinybars(1).negated())
        .addHbarTransfer(AccountId.fromString("0.0.3"), Hbar.fromTinybars(1))
        .signWith(OPERATOR_PUBLIC_KEY, transactionSigner)
TransactionReceipt receipt = response.getReceipt(client);

return receipt.accountId;

private Function<byte[],byte[]> generateSignatureFunction() {
// Retrieve the Private Key from the .env file
PrivateKey OPERATOR_KEY = PrivateKey.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_KEY")));

// return a function that will sign the byte array transaction during the signWith method
return (
        t -> OPERATOR_KEY.sign(t)


This document is licensed under the Apache License, Version 2.0 – see LICENSE or (


Please cite this document as: