I do have a use case where I need to sign a transaction on an edge device without having connection to the chain (but lets consider chain ID , user and private key are well known on the edge). I am able to sign a transaction on the device with cleos sign to get the 'SIG_K1_' signature. But this transaction of course has empty TAPoS fields. e.g cleos sign output:

  "expiration": "1970-01-01T00:00:00",
  "ref_block_num": 0,
  "ref_block_prefix": 0,
  "max_net_usage_words": 0,
  "max_cpu_usage_ms": 0,
  "delay_sec": 0,
  "context_free_actions": [],
  "actions": [{
      "account": "...a",
      "name": "...b",
      "authorization": [{
          "actor": "...c",
          "permission": "active"
      "data": "...d"
  "transaction_extensions": [],
  "signatures": [
  "context_free_data": []

When I forward this 'SIG_K1_' signature to an eosjs application and try to sign and push a similiar transaction with this signature on to the chain using api.pushSignedTransaction(), I get the error:

UnhandledPromiseRejectionWarning: Error: transaction declares authority '{"actor":"...c","permission":"active"}', but does not have signatures for it under a provided delay of 0 ms, provided permissions [], provided keys [], and a delay max limit of 3888000000 ms

My simple eosjs apllication:

const { api, RpcError } = require('./init');

async function sendTransaction(owner, vehicleId, data) {
    // Signature and action information will be retrieved from device (see above)
    const signatures = [ "SIG_K1_K8TogB8CobJwoES6Qcxj968oe5JuwNLUxLY5N1rpvsidjD9xQ4QXVkUzqy3NRB4AQVm9w7XCi4ibPYpQES1uJN9k45pmjU" ]
    const transaction = {
        actions: [{
          account: '...a',
          name: '...b',
          authorization: [{
            actor: '...c',
            permission: 'active'
          data: '...d'

    const options = { broadcast: false, sign: false, blocksBehind: 3, expireSeconds: 300 }
    const transact = await api.transact(transaction, options)    
    const opt = { signatures: signatures, serializedTransaction: transact.serializedTransaction, serializedContextFreeData: transact.serializedContextFreeData}
    const response = api.pushSignedTransaction(opt, false, true)

    return { response: response, error: null }

module.exports = { sendTransaction }

My Question is if it's theoretically possible to sign transactions on a device without having access to the chain directly and use this signature to push the transaction from an eosjs application which has access to the chain? If yes, how could I achieve this? Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.