Error with state channel example

I have been trying to run the example

TUTORIAL: State Channels Introduction

and this error appears:

(node:12492) UnhandledPromiseRejectionWarning: #<_Event>
(node:12492) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the
node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:12492) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:12492) UnhandledPromiseRejectionWarning: #<_Event>
(node:12492) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the
node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
C:\xampp\htdocs\sistema_encuentros\[email protected]\aepp-sdk\dist\aepp-sdk.js:1
!function(t,e){“object”==typeof exports&&“object”==typeof module?module.exports=e(require(“bignumber.js”),require("@stamp/required"),require("@stamp/it"),require(“tweetnacl”),require(“joi-browser”),require(“axios”),require(“uuid”),require(“rlp”),require("@aeternity/bip39"),require(“bs58check”),require(“ed2curve”),require(“tweetnacl-auth”),require(“blakejs”),require(“aes-js”),require(“sha.js”),require(“websocket”),require(“bip32-path”),require(“libsodium-wrappers-sumo”)):“function”==typeof define&&define.amd?define([,],e):“object”==typeof exports?exports.Ae=e(require(“bignumber.js”),require("@stamp/required"),require("@stamp/it"),require(“tweetnacl”),require(“joi-browser”),require(“axios”),require(“uuid”),require(“rlp”),require("@aeternity/bip39"),require(“bs58check”),require(“ed2curve”),require(“tweetnacl-auth”),require(“blakejs”),require(“aes-js”),require(“sha.js”),require(“websocket”),require("bip32-path

TypeError: Cannot read property ‘send’ of undefined
at $l (C:\xampp\htdocs\sistema_encuentros\node_modules\←[[email protected]←[24m\aepp-sdk\dist\aepp-sdk.js:1:243178)
at a (C:\xampp\htdocs\sistema_encuentros\node_modules\←[[email protected]←[24m\aepp-sdk\dist\aepp-sdk.js:1:268980)
at Timeout._onTimeout (C:\xampp\htdocs\sistema_encuentros\node_modules\←[[email protected]←[24m\aepp-sdk\dist\aepp-sdk.js:1:269171)
←[90m at listOnTimeout (internal/timers.js:549:17)←[39m
←[90m at processTimers (internal/timers.js:492:7)←[39m

Could somebody help me?

Thanks

Hey @yamiloro

@KrumTheFearsome.chain or @uwigeroferlang.chain should be able to help you.

@albena.chain nope, this is a JS SDK question, I guess either @mpowaga or @nduchak.chain

1 Like

Hello @yamiloro,
Can you please provide code snippet for reproducing your issue please,
SDK and NodeJs version also will be helpful

Thank you

@nduchak.chain

const { Channel, Universal, TxBuilder: { unpackTx } } = require(’@aeternity/aepp-sdk’)
const { BigNumber } = require(‘bignumber.js’)

const API_URL = ‘http://localhost:3013
const INTERNAL_API_URL = ‘http://localhost:3113
const STATE_CHANNEL_URL = ‘ws://localhost:3014/channel’
const NETWORK_ID = ‘ae_uat’
const RESPONDER_HOST = ‘localhost’
const RESPONDER_PORT = 3333

const initiatorAddress = ‘ak_2FyHpQaHPMHqWLZT2aZSnBPWZKyzFqBVv2VfSzRdJi8626BA2g’
const responderAddress = ‘ak_trGPuJJCo2g1X6jTUkAooUoUd5G9zHxdvSDrBPso8Nf6ydVrk’

let initiatorAccount
let responderAccount

async function createAccounts () {
initiatorAccount = await Universal({
networkdId: NETWORK_ID,
url: API_URL,
internalUrl: INTERNAL_API_URL,
keypair: {
publicKey: initiatorAddress,
secretKey: ‘77b8b5446e5ada152f2f402d6bacd3f3a906262887d925e2a476fd2625a37109a5b040820f76293431e4676c83c2a6d189c4ffc8b232a247203929ca4afe552c’
}
})
responderAccount = await Universal({
networkdId: NETWORK_ID,
url: API_URL,
internalUrl: INTERNAL_API_URL,
keypair: {
publicKey: responderAddress,
secretKey: ‘0a8a5042846fc8bd32711f7a00953272b77cc6dc588c283a39721d4072048cca75bafc728d726c16f877d7846eb4ee19316438da03a573307584680d6042f2df’
}
})
}

async function initiatorSign (tag, tx) {
if (tag === ‘initiator_sign’) {
return initiatorAccount.signTransaction(tx)
}

// Deserialize binary transaction so we can inspect it
const { txType, tx: txData } = unpackTx(tx)
if (tag === ‘shutdown_sign_ack’) {
// Fee amount is splitted equally per participants
const fee = BigNumber(txData.fee).div(2)
if (
txType === ‘channelCloseMutual’ &&
// To keep things simple we manually check that
// balances are correct (as a result of previous transfer update)
BigNumber(txData.initiatorAmountFinal).plus(fee).eq(BigNumber(DEPOSIT).minus(10)) &&
BigNumber(txData.responderAmountFinal).plus(fee).eq(BigNumber(DEPOSIT).plus(10))
) {
return initiatorAccount.signTransaction(tx)
}
}
}

async function responderSign (tag, tx, { updates } = {}) {
if (tag === ‘responder_sign’) {
return responderAccount.signTransaction(tx)
}

// Deserialize binary transaction so we can inspect it
const { txType, tx: txData } = unpackTx(tx)
// When someone wants to transfer a tokens we will receive
// a sign request with update_ack tag
if (tag === ‘update_ack’) {
// Check if update contains only one offchain transaction
// and sender is initiator
if (
txType === ‘channelOffChain’ &&
updates.length === 1 &&
updates[0].op === ‘OffChainTransfer’ &&
updates[0].from === initiatorAddress
) {
return responderAccount.signTransaction(tx)
}
}
}

async function connectAsInitiator (params) {
return Channel({
…params,
url: STATE_CHANNEL_URL,
role: ‘initiator’,
//sign: initiatorSign
})
}

async function connectAsResponder (params) {
return Channel({
…params,
url: STATE_CHANNEL_URL,
role: ‘responder’,
//sign: responderSign
})
}

const DEPOSIT = 10
const params = {
// Public key of initiator
// (in this case initiatorAddress defined earlier)
initiatorId: initiatorAddress,
// Public key of responder
// (in this case responderAddress defined earlier)
responderId: responderAddress,
// Initial deposit in favour of the responder by the initiator
pushAmount: 0,
// Amount of tokens initiator will deposit into state channel
initiatorAmount: DEPOSIT,
// Amount of tokens responder will deposit into state channel
responderAmount: DEPOSIT,
// Minimum amount both peers need to maintain
channelReserve: 1,
// Minimum block height to include the channel_create_tx
ttl: 1000,
// Amount of blocks for disputing a solo close
lockPeriod: 10,
// Host of the responder’s node
host: RESPONDER_HOST,
// Port of the responders node
port: RESPONDER_PORT,
}

createAccounts().then(() => {
// initiator connects to state channels endpoint
connectAsInitiator(params).then(initiatorChannel => {
console.log(initiatorChannel);
initiatorChannel.on(‘statusChanged’, (status) => {
if (status === ‘open’) {
console.log(‘State channel has been opened!’)
}
})

initiatorChannel.on('onChainTx', (tx) => {
  console.log('channel_create_tx:', tx)
})

initiatorChannel.sendMessage('hello world', responderAddress)

initiatorChannel.update(
  // Sender account
  initiatorAddress,
  // Recipient account
  responderAddress,
  // Amount
  10,
  // This function should verify offchain transaction
  // and sign it with initiator's private key
  async (tx) => initiatorAccount.signTransaction(tx)
).then((result) => {
  if (result.accepted) {
    console.log('Succesfully transfered 10 tokens!')
  } else {
    console.log('Transfer has been rejected')  
  }
})
                                                   
initiatorChannel.on('error', err => console.log(err))

}).catch(err => {
console.log(‘Initiator failed to connect’)
console.log(err)
})

// responder connects to state channels endpoint
connectAsResponder(params).then(responderChannel => {
responderChannel.on(‘message’, (msg) => {
console.log(‘Received message from:’, msg.from)
console.log(msg.info)
})

// close channel after a minute
setTimeout(() => {
  console.log('Closing channel...')
  responderChannel.shutdown(
    // This function should verify shutdown transaction
    // and sign it with responder's secret key 
    async (tx) => responderAccount.signTransaction(tx)
  ).then((tx) => {
    console.log('State channel has been closed')
    console.log('You can track this transaction onchain', tx)
  }).catch(err => console.log(err))
}, 60000)
                                                   
responderChannel.on('error', err => console.log(err))

}).catch(err => {
console.log(‘Responder failed to connect’)
console.log(err)
})
})

Well, I installed a local node and I commented //sign: responderSign and //sign: innitiatiorSign . The error disappeared, but now the log show me this

(node:7864) UnhandledPromiseRejectionWarning: Error: State Channels FSM entered unknown state

Node
v8.10.0

SDK

7.1.1

Netstat -putan shows:

[email protected]:~/Documentos/proyecto_encuentros$ netstat -putan|grep aeternity
(No todos los procesos pueden ser identificados, no hay información de propiedad del proceso
no se mostrarán, necesita ser superusuario para verlos todos.)
tcp 0 0 127.0.0.1:34931 0.0.0.0:* ESCUCHAR 21546/aeternity
tcp 0 0 0.0.0.0:3013 0.0.0.0:* ESCUCHAR 21546/aeternity
tcp 0 0 127.0.0.1:3014 0.0.0.0:* ESCUCHAR 21546/aeternity
tcp 0 0 0.0.0.0:3015 0.0.0.0:* ESCUCHAR 21546/aeternity
tcp 0 0 127.0.0.1:3113 0.0.0.0:* ESCUCHAR 21546/aeternity
tcp 0 0 192.168.0.105:42569 52.26.157.37:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 127.0.0.1:55569 127.0.0.1:4369 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:42933 52.11.110.179:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:38593 52.220.198.72:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:43325 13.228.202.140:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:35687 13.250.144.60:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:35653 18.217.69.24:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:36921 3.17.15.239:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:42177 13.53.78.163:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:39699 52.194.244.101:3015 ESTABLECIDO 21546/aeternity
tcp 0 0 192.168.0.105:36749 147.135.10.88:3015 ESTABLECIDO 21546/aeternity
udp 0 0 0.0.0.0:43023 0.0.0.0:* 21546/aeternity