text: // ==================================
  // Part 1 - incoming messages, look for type
  // ==================================
  var ibc = {};
  var chaincode = {};
  var async = require('async');
  
  module.exports.setup = function(sdk, cc){
  	ibc = sdk;
  	chaincode = cc;
  };
  
  module.exports.process_msg = function(ws, data){
  	if(data.v === 1){
  		if(data.type == 'create'){
  			console.log('its a create!');
  			if(data.name && data.color && data.size && data.user){
  				chaincode.invoke.init_marble([data.name, data.color, data.size, data.user], cb_invoked);				//create a new marble
  			}
  		}
  		else if(data.type == 'get'){
  			console.log('get marbles msg');
  			chaincode.query.read(['_marbleindex'], cb_got_index);
  		}
  		else if(data.type == 'transfer'){
  			console.log('transfering msg');
  			if(data.name && data.user){
  				chaincode.invoke.set_user([data.name, data.user]);
  			}
  		}
  		else if(data.type == 'remove'){
  			console.log('removing msg');
  			if(data.name){
  				chaincode.invoke.delete([data.name]);
  			}
  		}
  		else if(data.type == 'chainstats'){
  			console.log('chainstats msg');
  			ibc.chain_stats(cb_chainstats);
  		}
  	}
  
  	//got the marble index, lets get each marble
  	function cb_got_index(e, index){
  		if(e != null) console.log('error:', e);
  		else{
  			try{
  				var json = JSON.parse(index);
  				var keys = Object.keys(json);
  				var concurrency = 1;
  
  				//serialized version
  				async.eachLimit(keys, concurrency, function(key, cb) {
  					console.log('!', json[key]);
  					chaincode.query.read([json[key]], function(e, marble) {
  						if(e != null) console.log('error:', e);
  						else {
  							sendMsg({msg: 'marbles', e: e, marble: JSON.parse(marble)});
  							cb(null);
  						}
  					});
  				}, function() {
  					sendMsg({msg: 'action', e: e, status: 'finished'});
  				});
  			}
  			catch(e){
  				console.log('error:', e);
  			}
  		}
  	}
  	
  	function cb_invoked(e, a){
  		console.log('response: ', e, a);
  	}
  	
  	//call back for getting the blockchain stats, lets get the block height now
  	var chain_stats = {};
  	function cb_chainstats(e, stats){
  		chain_stats = stats;
  		if(stats && stats.height){
  			var list = [];
  			for(var i = stats.height - 1; i >= 1; i--){									//create a list of heights we need
  				list.push(i);
  				if(list.length >= 8) break;
  			}
  			list.reverse();																//flip it so order is correct in UI
  			console.log(list);
  			async.eachLimit(list, 1, function(key, cb) {								//iter through each one, and send it
  				ibc.block_stats(key, function(e, stats){
  					console.log('key', key);
  					if(e == null){
  						stats.height = key;
  						sendMsg({msg: 'chainstats', e: e, chainstats: chain_stats, blockstats: stats});
  					}
  					cb(null);
  				});
  			}, function() {
  			});
  		}
  	}
  	
  	//send a message, socket might be closed...
  	function sendMsg(json){
  		if(ws){
  			try{
  				ws.send(JSON.stringify(json));
  			}
  			catch(e){
  				console.log('error ws', e);
  			}
  		}
  	}
  };