# Fee Delegation Example

## Table of Contents <a href="#table-of-contents" id="table-of-contents"></a>

* [1. Introduction](#1-introduction)
* [2. How fee delegation works](#2-how-fee-delegation-works)
  * 2.1 Transaction signing by the sender
  * 2.2 Transaction signing by the fee payer
* [3. Simple server and client for fee delegation](#3-simple-server-and-client-for-fee-delegation)
  * 3.1 Sender's client
  * 3.2 Fee payer's server
* [4. Run example](#4-run-example)
  * 4.1 Run `feepayer_server.js`
  * 4.2 Run `sender_client.js`
  * 4.3 Check `feepayer_server.js`
  * 4.4 Klaytn scope

## 1. Introduction <a href="#id-1-introduction" id="id-1-introduction"></a>

This tutorial helps you to write a simple server-client example using caver-js SDK to illustrate how fee delegated value transfer transaction works in Klaytn. This tutorial and the example code is using the Baobab testnet.

## 2. How fee delegation works <a href="#id-2-how-fee-delegation-works" id="id-2-how-fee-delegation-works"></a>

Let's skim through how fee delegation works.

### 2.1 Transaction signing by the sender <a href="#id-2-1-transaction-signing-by-the-sender" id="id-2-1-transaction-signing-by-the-sender"></a>

`Sender` always should sign the transaction before sending a transaction.

To sign a transaction, use [signTransaction](/content/dapp/sdk/caver-js/v1.4.1/api-references/caver.klay.accounts.md#signtransaction) which signs a transaction with given private key.

```
// using the event emitter
const senderAddress = "SENDER_ADDRESS";
const senderPrivateKey = "SENDER_PRIVATEKEY";
const toAddress = "TO_ADDRESS";

const { rawTransaction: senderRawTransaction } = await caver.klay.accounts.signTransaction({
  type: 'FEE_DELEGATED_VALUE_TRANSFER',
  from: senderAddress,
  to: toAddress,
  gas: '300000',
  value: caver.utils.toPeb('1', 'KLAY'),
}, senderPrivateKey)
```

If there are no errors, then `senderRawTransaction` will have a signed transaction which is signed by the `senderPrivateKey`.

Now, you need to send the `senderRawTransaction` to the fee payer. There will be various ways to implement this. In this tutorial, we will provide you a simple server-client code as an example of sending a `senderRawTransaction` to the fee payer.

### 2.2 Transaction signing by the fee payer <a href="#id-2-2-transaction-signing-by-the-fee-payer" id="id-2-2-transaction-signing-by-the-fee-payer"></a>

When `fee payer` receives the `senderRawTransaction`, `fee payer` signs the `senderRawTransaction` again with their private key and sends the transaction to Klaytn. The below code snippet illustrates the process. `klay.sendTransaction` method signs the transaction with the given account's private key before sending the transaction. Before running the code, please replace `"FEEPAYER_ADDRESS"` and `"PRIVATE_KEY"` with the actual values.

Note that when the `fee payer` submits the transaction to Klaytn on behalf of the `sender`, the `senderRawTransaction` type must be a `FEE_DELEATED` type of transaction. In the below example, [sendTransaction(FEE\_DELEGATED\_VALUE\_TRANSFER)](/content/dapp/sdk/caver-js/v1.4.1/api-references/caver.klay/transaction/sendtx_value_transfer.md#sendtransaction-fee_delegated_value_transfer) method is invoked, because the original `senderRawTransaction` generated by the sender was [TxTypeFeeDelegatedValueTransfer](/content/klaytn/design/transactions/fee-delegation.md#txtypefeedelegatedvaluetransfer).

```
const feePayerAddress = "FEEPAYER_ADDRESS";
const feePayerPrivateKey = "PRIVATE_KEY"

caver.klay.accounts.wallet.add(feePayerPrivateKey, feePayerAddress);

caver.klay.sendTransaction({
  senderRawTransaction: senderRawTransaction,
  feePayer: feePayerAddress,
})
.on('transactionHash', function(hash){
    ...
})
.on('receipt', function(receipt){
    ...
})
.on('error', console.error); // If an out-of-gas error, the second parameter is the receipt.
```

## 3. Simple server and client for fee delegation <a href="#id-3-simple-server-and-client-for-fee-delegation" id="id-3-simple-server-and-client-for-fee-delegation"></a>

Let's write a simple server and client using above fee delegation code.

### 3.1 Environment setup <a href="#id-3-1-environment-setup" id="id-3-1-environment-setup"></a>

We will use `npm` and [caver-js](/content/dapp/sdk/caver-js/v1.4.1/getting-started_1.4.1.md) to setup environment for this example as below.

```
$ mkdir example
$ cd example
$ npm init
$ npm install caver-js@latest
```

### 3.1 Sender's client <a href="#id-3-1-sender-s-client" id="id-3-1-sender-s-client"></a>

First, we are going to write a `sender_client.js` as below.

In the example, please replace `"SENDER_ADDRESS"`, `"SENDER_PRIVATEKEY"` and `"TO_ADDRESS"` with the actual values.

```javascript
var net = require('net');
var client = new net.Socket();

const Caver = require('caver-js');
const caver = new Caver('https://public-en-baobab.klaytn.net');
const senderAddress = "SENDER_ADDRESS";
const senderPrivateKey = "SENDER_PRIVATEKEY";
const toAddress = "TO_ADDRESS";

sendFeeDelegateTx = async() => {
    // sign transaction with private key of sender
    const { rawTransaction: senderRawTransaction } = await caver.klay.accounts.signTransaction({
      type: 'FEE_DELEGATED_VALUE_TRANSFER',
      from: senderAddress,
      to: toAddress,
      gas: '300000',
      value: caver.utils.toPeb('0.00001', 'KLAY'),
    }, senderPrivateKey)

    // send signed raw transaction to fee payer's server
    client.connect(1337, '127.0.0.1', function() {
            console.log('Connected to fee delegated service');
    });
    client.write(senderRawTransaction);

    client.on('data', function(data) {
            console.log('Received data from server: ' + data);
    });

    client.on('close', function() {
            console.log('Connection closed');
    });
}

sendFeeDelegateTx();
```

The above code signs a fee delegated value transfer transaction with `senderPrivateKey` and sends the signed `senderRawTransaction` to the fee payer's server which is running on port `1337` on `127.0.0.1`, i.e. localhost.

### 3.2 Fee payer's server <a href="#id-3-2-fee-payer-s-server" id="id-3-2-fee-payer-s-server"></a>

Now let's write the fee payer's server, `feepayer_server.js`, which signs received `senderRawTransaction` with `feePayerPrivateKey` and sends it to Baobab testnet.

In the below example, please replace `"FEEPAYER_ADDRESS"` and `"FEEPAYER_PRIVATEKEY"` with actual values.

```javascript
const Caver = require('caver-js');
const caver = new Caver('https://public-en-baobab.klaytn.net');
const feePayerAddress = "FEEPAYER_ADDRESS";
const feePayerPrivateKey = "FEEPAYER_PRIVATEKEY";

// add fee payer account
caver.klay.accounts.wallet.add(feePayerPrivateKey, feePayerAddress);

var net = require('net');


feePayerSign = (senderRawTransaction, socket) => {
    // fee payer
    caver.klay.sendTransaction({
      senderRawTransaction: senderRawTransaction,
      feePayer: feePayerAddress,
    })
    .on('transactionHash', function(hash){
        console.log('transactionHash', hash);
    })
    .on('receipt', function(receipt){
        console.log('receipt', receipt);
        socket.write('Tx hash is '+ receipt.transactionHash);
        socket.write('Sender Tx hash is '+ receipt.senderTxHash);
    })
    .on('error', console.error); // If an out-of-gas error, the second parameter is the receipt.
}

var server = net.createServer(function(socket) {
       console.log('Client is connected ...');
    socket.write('This is fee delegating service');
    socket.write('Fee payer is ' + feePayerAddress);
        socket.on('data', function(data) {
            console.log('Received data from client:', data.toString());
            feePayerSign(data.toString(), socket);
        });
});

server.listen(1337, '127.0.0.1');
console.log('Fee delegate service started ...');
```

The server listens on port `1337`.

When there is incoming `data`, it signs the `data` with `feePayerPrivateKey` and sends it to the Klaytn blockchain. It assumes that the `data` is `senderRawTransaction` from the `sender_client.js`.

## 4. Run example <a href="#id-4-run-example" id="id-4-run-example"></a>

Prepare two terminals, one for `sender_client.js` and another for `feepayer_server.js`.

### 4.1 Run `feepayer_server.js` <a href="#id-4-1-run-feepayer_server-js" id="id-4-1-run-feepayer_server-js"></a>

Below the command will start the fee payer's server.

```
$ node feepayer_server.js
Fee delegate service started ...
```

The server starts and is now listening on port 1337.

### 4.2 Run `sender_client.js` <a href="#id-4-2-run-sender_client-js" id="id-4-2-run-sender_client-js"></a>

Let's run `sender_client.js` to send a fee delegated transaction.

```
$ node sender_client.js
Signed a fee delegated value transfer transaction.
Sending a signed transaction to fee delegated service.
Connected to fee delegated service
Received data from server: This is fee delegating service
Received data from server: Fee payer is 0x2645BA5Be42FfEe907ca8e9d88f6Ee6dAd8c1410
Received data from server: Tx hash is 0xd99086aa8188255d4ee885d9f1933b6cc062085c1196731ba599b2fb8f2dbbd7
Received data from server: Sender Tx hash is 0xe1f630547f287177a0e92198b1c67212b24fc1ad5a1f0b1f94fd6f980281fdba
```

It will sign a transaction with the `sender` private key and send the signed transaction to the fee delegated service (i.e., fee payer's server). Then it will receive the response from the fee delegate service including the `Fee payer` address, `Tx hash`, and `Sender Tx hash`. `Tx hash` is hash of a transaction submitted to the Klaytn network, while `Sender Tx hash` is hash of a transaction without the fee payer's address and signature. For more details, please take a look at [SenderTxHash](/content/klaytn/design/transactions.md#sendertxhash).

### 4.3 Check `feepayer_server.js` <a href="#id-4-3-check-feepayer_server-js" id="id-4-3-check-feepayer_server-js"></a>

On the server's console, you will see below outputs. It prints the transaction receipt from the Klaytn.

```
$ node feepayer_server.js
Fee delegate service started ...
Client is connected ...
Received data from client: 0x09f88b3a8505d21dba00830493e094fc83add44939ef818ce62dacea23697fa17257838609184e72a000940ecc24157e38b1997aace56f32ccb381b16e1710f847f8458207f5a0e636e67d01acc1f368db5e60290721e9059b13b0bf74af6d46391cc48bd31a81a0135118878be87f808e064f64fa4f13d6dc5bd9888b154ecd17f02980063b9e4280c4c3018080
transactionHash { messageHash:
   '0xa4cd7d479d19251a1981086431eff5514c5edf61731a6e5271b2a137a156f7e7',
  v: '0x07f6',
  r:
   '0xdb9c3a5b75c20f15cba9bc28eebcaff58701f57d4a226e7e3cb2bc4544b3c96c',
  s:
   '0x7646e929aa6467fa1c849f3abf37054df4cb08e6ee160f6375517ae2609f4b11',
  rawTransaction:
   '0x09f8e33a8505d21dba00830493e094fc83add44939ef818ce62dacea23697fa17257838609184e72a000940ecc24157e38b1997aace56f32ccb381b16e1710f847f8458207f5a0e636e67d01acc1f368db5e60290721e9059b13b0bf74af6d46391cc48bd31a81a0135118878be87f808e064f64fa4f13d6dc5bd9888b154ecd17f02980063b9e42942645ba5be42ffee907ca8e9d88f6ee6dad8c1410f847f8458207f6a0db9c3a5b75c20f15cba9bc28eebcaff58701f57d4a226e7e3cb2bc4544b3c96ca07646e929aa6467fa1c849f3abf37054df4cb08e6ee160f6375517ae2609f4b11',
  txHash:
   '0xd99086aa8188255d4ee885d9f1933b6cc062085c1196731ba599b2fb8f2dbbd7' }
transactionHash 0xd99086aa8188255d4ee885d9f1933b6cc062085c1196731ba599b2fb8f2dbbd7
receipt { blockHash:
   '0x1c61f03d2f0eba86c0f58ee7d1be8e8e425f47e9c46433474bd11c5a3f0528b2',
  blockNumber: 3175653,
  contractAddress: null,
  feePayer: '0x2645ba5be42ffee907ca8e9d88f6ee6dad8c1410',
  feePayerSignatures:
   [ { V: '0x7f6',
       R:
        '0xdb9c3a5b75c20f15cba9bc28eebcaff58701f57d4a226e7e3cb2bc4544b3c96c',
       S:
        '0x7646e929aa6467fa1c849f3abf37054df4cb08e6ee160f6375517ae2609f4b11' } ],
  from: '0x0ecc24157e38b1997aace56f32ccb381b16e1710',
  gas: '0x493e0',
  gasPrice: '0x5d21dba00',
  gasUsed: 31000,
  logs: [],
  logsBloom:
   '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  nonce: '0x3a',
  senderTxHash:
   '0xe1f630547f287177a0e92198b1c67212b24fc1ad5a1f0b1f94fd6f980281fdba',
  signatures:
   [ { V: '0x7f5',
       R:
        '0xe636e67d01acc1f368db5e60290721e9059b13b0bf74af6d46391cc48bd31a81',
       S:
        '0x135118878be87f808e064f64fa4f13d6dc5bd9888b154ecd17f02980063b9e42' } ],
  status: true,
  to: '0xfc83add44939ef818ce62dacea23697fa1725783',
  transactionHash:
   '0xd99086aa8188255d4ee885d9f1933b6cc062085c1196731ba599b2fb8f2dbbd7',
  transactionIndex: 0,
  type: 'TxTypeFeeDelegatedValueTransfer',
  typeInt: 9,
  value: '0x9184e72a000' }
```

### 4.4 Klaytn scope <a href="#id-4-4-klaytn-scope" id="id-4-4-klaytn-scope"></a>

You can also find the above transaction on the [Klaytn scope](https://baobab.scope.klaytn.com).

It shows that the transaction is `TxTypeFeeDelegatedValueTransfer` and `Fee payer` is `0x2645ba5be42ffee907ca8e9d88f6ee6dad8c1410` or `feepayerAddress` that you entered, while `From` is a different address which should be the `senderAddress` in above example.

![Fee delegated Tx](/files/OlGinS2lpdxN56OcPCMg)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://archive-docs.klaytn.foundation/content/dapp/tutorials/fee-delegation-example.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
