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

@dimitar.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

@nduchak.chain any input here? I see this had been hanging for some time now.

I tested the local node with this command nc -zv $(curl -s https://api.ipify.org) 3015 and it showed that -->
nc: connect to xxx.xxx.xxx.xxx (my ip) port 3015 (tcp) failed: Connection timed out

I used this docs https://github.com/aeternity/aeternity/blob/master/docs/configuration.md maybe is a node config, I installed the node from the binaries, and I doesn’t work. I used the docs.

I set the testnet in the local node fork_management:
network_id: ae_uat

I fixed in the code of the example networkdId: NETWORK_ID, for networkId: NETWORK_ID,

I cheked the config file ./aeternity check_config …/data/aeternity_config_schema.json
Configuration error ({badarg,
[{aeu_env,try_decode,4,
[{file,
“/home/builder/aeternity/apps/aeutils/src/aeu_env.erl”},
{line,496}]},
{aeu_env,read_json,3,
[{file,
“/home/builder/aeternity/apps/aeutils/src/aeu_env.erl”},
{line,470}]},
{aeu_env,do_read_config,4,
[{file,
“/home/builder/aeternity/apps/aeutils/src/aeu_env.erl”},
{line,339}]},
{check_config,check_config,2,
[{file,
“/home/builder/aeternity/apps/check_config/src/check_config.erl”},
{line,19}]},
{escript,run,2,[{file,“escript.erl”},{line,759}]},
{escript,start,1,[{file,“escript.erl”},{line,277}]},
{init,start_em,1,[]},
{init,do_boot,3,[]}]})

it is strange but the node is started. This is the config by default, I have changed the networid_id only.

netstat -putan -->
tcp 0 0 0.0.0.0:3013 0.0.0.0:* ESCUCHAR 25713/aeternity
tcp 0 0 127.0.0.1:3014 0.0.0.0:* ESCUCHAR 25713/aeternity
tcp 0 0 0.0.0.0:3015 0.0.0.0:* ESCUCHAR 25713/aeternity
tcp 0 0 127.0.0.1:3113 0.0.0.0:* ESCUCHAR 25713/aeternity

I installed the docker node also:

sudo docker run -p 0.0.0.0:3013:3013 -p 0.0.0.0:3015:3015 -p 0.0.0.0:3113:3113 -p 0.0.0.0:3014:3014 -v ~/.aeternity/testdb:/home/aeternity/node/data/mnesia aeternity/aeternity bin/aeternity console -noinput -network_id ae_uat

it shows me this --> :10.627 [info] Synced blocks 15314 - 15364
17:42:10.845 [info] Synced blocks 15365 - 15376
17:42:11.322 [info] Peer connections outbound: 8/10, inbound: 0/100
17:42:16.323 [info] Peer connections outbound: 8/10, inbound: 0/100
17:42:19.686 [info] Synced blocks 15377 - 15406
17:42:20.504 [info] Synced blocks 15407 - 15454
17:42:20.855 [info] Synced blocks 15455 - 15474
17:42:20.890 [info] Synced blocks 15475 - 15476
17:42:21.324 [info] Peer connections outbound: 8/10, inbound: 0/100
17:42:26.326 [info] Peer connections outbound: 8/10, inbound: 0/100
17:42:26.414 [info] Synced blocks 15477 - 15480
17:42:27.155 [info] Synced blocks 15481 - 15487

look --> Connection handshake failed - timeout was from <<“144.76.137.121”>>

inbound is 0, is this bad?

I am cheking with websocket in the local node, this error appears:

wscat --connect ‘localhost:3014/channel?channel_reserve=2&initiator_amount=70000000000000&initiator_id=ak_5M4QLCrTvdqSwa3xEXXft3kNYC9ZVDzhnTQUKdJKbiSYGqdeq&lock_period=10&port=12340&protocol=json-rpc&push_amount=1&responder_amount=40000000000000&responder_id=ak_vLdxPmfbTMvaepMRa54YY1cUtDDLBBM2L2AV4f8LtmagCVx1n&role=responder’
Connected (press CTRL+C to quit)
< {“channel_id”:null,“error”:{“code”:3,“data”:[{“code”:1011,“message”:“Participant not found”}],“message”:“Rejected”,“request”:{}},“id”:null,“jsonrpc”:“2.0”,“version”:1}
Disconnected (code: 1000, reason: “”)

both have balance, 15 AE and 10AE.

when I test directly in the sdk-testnet wscat --connect ‘https://sdk-testnet.aepps.com/channel?channel_reserve=2&initiator_amount=70000000000000&initiator_id=ak_5M4QLCrTvdqSwa3xEXXft3kNYC9ZVDzhnTQUKdJKbiSYGqdeq&lock_period=10&port=12340&protocol=json-rpc&push_amount=1&responder_amount=40000000000000&responder_id=ak_vLdxPmfbTMvaepMRa54YY1cUtDDLBBM2L2AV4f8LtmagCVx1n&role=responder
Connected (press CTRL+C to quit)
< {“jsonrpc”:“2.0”,“method”:“channels.info”,“params”:{“channel_id”:null,“data”:{“event”:“fsm_up”,“fsm_id”:“ba_ALvxEGgEtVZpgqvWL5ft+iOZukEqTwHNvczbTqchYDYpj4a7”}},“version”:1}

is this good?
I think is something related with my local test node config but I can not find the answer, maybe is a bad config.

Hey @nduchak.chain please take a look here.

1 Like

Your local node is probably out of sync, you should compare the outputs of:

curl localhost:3013/v2/status and curl https://testnet.aeternity.io/v2/status

Hey @yamiloro,
Currently it’s not reproducible in my side, i suggest you to install SDK from this branch (https://github.com/aeternity/aepp-sdk-js/tree/feat/channel-debug)
Then add debug: true options to your Channel initialization and try to run it again
The debug option will log all WebSocket message to console, then we have a full view what is going on before error appear

Also here you need provide sign function as it’s used for signing request’s from your participant

Ok I could configure the yaml, the status is:

difficulty 138747026
genesis_key_block_hash “kh_wUCideEB8aDtUaiHCtKcfywU6oHZW6gnyci8Mw6S1RSTCnCRu”
listening true
network_id “ae_uat”
node_revision “7d37fd7d37f7f79dbf4fe784faa7588a73939f9b”
node_version “5.5.2”
peer_connections
inbound 0
outbound 9
peer_count 158
peer_pubkey “pp_PA1THwxT4xgYpatzVw9TCX6tyfE1nWm4LYSRSkDjfVd7RqT3n”
pending_transactions_count 96
protocols
0
effective_at_height 154300
version 4
1
effective_at_height 82900
version 3
2
effective_at_height 40900
version 2
3
effective_at_height 0
version 1
solutions 0
sync_progress 1.79322
syncing true
top_block_height 4403
top_key_block_hash “kh_xfusmVxtjs8yAoNrFQvWJaTUZ5X3mLdUXBx3XNF7htEZUV7wT”

should I wait until it reach a sync_progress of 100%?