vechain.energy
Fee Delegation
Implementation

Implementation

In most situations the implementation of a signing service for a regular dApp is a one-liner configuration. All required work is done within Connex and Sync2.

With Connex & Sync2 as Wallet

Connex has the delegate()-function enable fee delegation during transaction signing. Sync2 will automatically use the given URL for fee delegation:

const tx = await connex.vendor.sign('tx', clauses)
  .delegate('https://sponsor-testnet.vechain.energy/by/#') // <-- add this line
  .comment('This is a Test Transaction')
  .request()

Read more about it in the docs at transaction signing service (opens in a new tab).

Connex and own Wallet Management

Build Transaction and enable Fee Delegation

Build a transaction with reserved defined. Setting features = 1 enables fee delegation.

const transaction = new Transaction({
  chainTag: Number.parseInt(connex.thor.genesis.id.slice(-2), 16),
  blockRef: connex.thor.status.head.id.slice(0, 18),
  expiration: 32,
  clauses: [],
  gas: connex.thor.genesis.gasLimit,
  gasPriceCoef: 128,
  dependsOn: null,
  nonce: +new Date(),
  reserved: {
    features: 1 // this enables the fee delegation feature
  }
})

Submit Transaction to Gas Payer

Afterwards the transaction is encoded into a hex-string:

const raw = `0x${transaction.encode().toString('hex')}`

… and submitted to the delegation service including the user address for confirmation and co-signing:

post('https://sponsor-testnet.vechain.energy/by/#', { raw, origin })

Sign Transaction

The Gas Payers signature combined with the users signature build the final signature for the transaction:

const { signature } = await post('https://sponsor-testnet.vechain.energy/by/#', { raw, origin })
 
// sign transaction with local wallets privateKey
const signingHash = transaction.signingHash()
const originSignature = secp256k1.sign(signingHash, Buffer.from(wallet.privateKey.slice(2), 'hex'))
  
// build combined signature from both parties
const sponsorSignature = Buffer.from(signature.substr(2), 'hex')
transaction.signature = Buffer.concat([originSignature, sponsorSignature])

When fee delegation is enabled in a transaction, the blockchain can verify that both parties (sender and payer) have agreed to the transaction.

Broadcast/Submit Transaction

const signedTransaction = `0x${transaction.encode().toString('hex')}`
const { id } = await post('https://testnet.veblocks.net/transactions', { raw: signedTransaction })

A working example is available at the Client Examples (opens in a new tab).