mirror of
https://github.com/DanielPollithy/flashwifi.git
synced 2025-10-16 11:45:32 +00:00
Merge branch 'master' of https://github.com/DanielPollithy/flashwifi
This commit is contained in:
commit
6cb3842798
20
app/src/main/java/com/flashwifi/wifip2p/Constants.java
Normal file
20
app/src/main/java/com/flashwifi/wifip2p/Constants.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
/**
|
||||
* Created by daniel on 23.01.18.
|
||||
*/
|
||||
|
||||
public class Constants {
|
||||
public interface ACTION {
|
||||
public static String MAIN_ACTION = "com.flashwifi.wifip2p.service.main";
|
||||
public static String PREV_ACTION = "com.flashwifi.wifip2p.service.prev";
|
||||
public static String PLAY_ACTION = "com.flashwifi.wifip2p.service.play";
|
||||
public static String NEXT_ACTION = "com.flashwifi.wifip2p.service.next";
|
||||
public static String STARTFOREGROUND_ACTION = "com.flashwifi.wifip2p.start_foreground_service";
|
||||
public static String STOPFOREGROUND_ACTION = "com.flashwifi.wifip2p.sop_foreground_service";
|
||||
}
|
||||
|
||||
public interface NOTIFICATION_ID {
|
||||
public static int FOREGROUND_SERVICE = 101;
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ public class FundWalletFragment extends Fragment {
|
||||
transactionInProgress = false;
|
||||
|
||||
if(returnStatus.equals("noError")){
|
||||
balanceTextView.setText(balance + " i");
|
||||
balanceTextView.setText(balance);
|
||||
addressTextView.setText(depositAddress);
|
||||
createAddressQRCode(depositAddress);
|
||||
makeToastFundWalletFragment("Balance and address updated");
|
||||
|
||||
@ -23,10 +23,8 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Example;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.IotaFlashBridge;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Main;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.pddstudio.preferences.encrypted.EncryptedPreferences;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -102,14 +100,16 @@ public class HomeActivity extends AppCompatActivity {
|
||||
String iotaflash = readFile("iotaflash");
|
||||
String iotaflashhelper = readFile("iotaflashhelper");
|
||||
|
||||
/*try {
|
||||
try {
|
||||
IotaFlashBridge.boot(iotaflash, iotaflashhelper);
|
||||
Main.runExample();
|
||||
Example.setup();
|
||||
Example.transaction(Example.one, Example.two);
|
||||
Example.close(Example.one, Example.two);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -34,8 +34,6 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private int numberConnectedPeers = 0;
|
||||
|
||||
WiFiDirectBroadcastService mService;
|
||||
boolean mBound = false;
|
||||
BroadcastReceiver updateUIReceiver;
|
||||
|
||||
public HotspotFragment() {
|
||||
@ -73,7 +71,7 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private void updateUi(Intent intent) {
|
||||
Log.d(TAG, "updateUi: Got some network data into the hotspot fragment");
|
||||
String numberAvailableDevices = Integer.toString(mService.getArrayList().size());
|
||||
String numberAvailableDevices = Integer.toString(getmService().getArrayList().size());
|
||||
TextView text = (TextView) getActivity().findViewById(R.id.numberPeers);
|
||||
text.setVisibility(View.VISIBLE);
|
||||
text.setText(String.format("%s peers", numberAvailableDevices));
|
||||
@ -81,9 +79,9 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
//if (intent.hasExtra("what") && intent.getExtras().getString("what", "").equals("connectivity_changed")) {
|
||||
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
WifiP2pGroup wifiP2pGroup = mService.getP2p_group();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
WifiP2pGroup wifiP2pGroup = getmService().getP2p_group();
|
||||
|
||||
if (intent.hasExtra("currentDeviceConnected")) {
|
||||
//String macAddress = intent.getExtras().getString("currentDeviceConnected");
|
||||
@ -92,11 +90,11 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
if (p2p_info.isGroupOwner) {
|
||||
Snackbar.make(activity_view, "You are the group owner", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
mService.startNegotiationServer(false, null);
|
||||
getmService().startNegotiationServer(false, null);
|
||||
} else {
|
||||
InetAddress groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
Snackbar.make(activity_view, "You are only a member of the group", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
mService.startNegotiationClient(groupOwnerAddress, false, null);
|
||||
getmService().startNegotiationClient(groupOwnerAddress, false, null);
|
||||
}
|
||||
|
||||
}
|
||||
@ -111,9 +109,7 @@ public class HotspotFragment extends Fragment {
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getActivity().unbindService(mConnection);
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
mBound = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,6 +125,11 @@ public class HotspotFragment extends Fragment {
|
||||
initFragment();
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
MainActivity act = (MainActivity) getActivity();
|
||||
return act.getmService();
|
||||
}
|
||||
|
||||
private void initFragment(){
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("com.flashwifi.wifip2p.update_ui");
|
||||
@ -138,6 +139,10 @@ public class HotspotFragment extends Fragment {
|
||||
updateUIReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getActivity() == null) {
|
||||
Log.d(TAG, "onReceive: getActivity is null");
|
||||
return;
|
||||
}
|
||||
if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) {
|
||||
String mac = intent.getStringExtra("peer_mac_address");
|
||||
ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
@ -157,10 +162,6 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
getActivity().registerReceiver(updateUIReceiver, filter);
|
||||
|
||||
// Bind to Service
|
||||
Intent intent = new Intent(getActivity(), WiFiDirectBroadcastService.class);
|
||||
getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
initUI();
|
||||
|
||||
testInternetConnection();
|
||||
@ -185,29 +186,13 @@ public class HotspotFragment extends Fragment {
|
||||
// ToDo: Move this to a async task
|
||||
//boolean status = (isNetworkConnected() && isInternetAvailable());
|
||||
}
|
||||
|
||||
private boolean isNetworkConnected() {
|
||||
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
return cm.getActiveNetworkInfo() != null;
|
||||
}
|
||||
|
||||
public boolean isInternetAvailable() {
|
||||
try {
|
||||
InetAddress ipAddr = InetAddress.getByName("google.com");
|
||||
return !ipAddr.getHostAddress().equals("");
|
||||
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void startDiscovery() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
if (mBound) {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(true);
|
||||
mService.getPeerList(new WifiP2pManager.ActionListener() {
|
||||
if (getmService() != null) {
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(true);
|
||||
getmService().getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
// show progress wheel
|
||||
@ -228,12 +213,12 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private void stopDiscovery() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
if (mBound) {
|
||||
mService.stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
if (getmService() != null) {
|
||||
getmService().stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(false);
|
||||
Snackbar.make(activity_view, "Stopped Hotspot mode", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
@ -241,8 +226,8 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(false);
|
||||
Snackbar.make(activity_view, "Aaaargh :( Problem stopping discovery", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
@ -255,12 +240,11 @@ public class HotspotFragment extends Fragment {
|
||||
private void initUI() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
final ToggleButton button = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
//button.setChecked(mService.isInRoleHotspot());
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mBound) {
|
||||
if (!mService.isSetup()) {
|
||||
if (getmService() != null) {
|
||||
if (!getmService().isSetup()) {
|
||||
Snackbar.make(activity_view, "Please enable WiFi P2P", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
button.setChecked(false);
|
||||
return;
|
||||
@ -276,23 +260,4 @@ public class HotspotFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
@ -13,6 +14,8 @@ import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
@ -24,14 +27,13 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Switch;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.billing.Accountant;
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletBalanceChecker;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements NavigationView.OnNavigationItemSelectedListener
|
||||
@ -40,6 +42,9 @@ public class MainActivity extends AppCompatActivity
|
||||
private static final String TAG = "MainAct";
|
||||
private String password;
|
||||
private String seed;
|
||||
private static final int PREF_UPDATE = 2;
|
||||
private static final int BALANCE_RETRIEVE_TASK_COMPLETE = 1;
|
||||
private Handler balanceHandler;
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
private ListView mDrawerList;
|
||||
@ -71,15 +76,27 @@ public class MainActivity extends AppCompatActivity
|
||||
intent.getStringExtra("key"));
|
||||
} else if (intent.getAction().equals("com.flashwifi.wifip2p.stop_roaming")) {
|
||||
Log.d(TAG, "onReceive: Reset billing state");
|
||||
mService.resetBillingState();
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
registerReceiver(updateUIReceiver, filter);
|
||||
}
|
||||
|
||||
public boolean isTheServiceRunning() {
|
||||
return isMyServiceRunning(WiFiDirectBroadcastService.class);
|
||||
}
|
||||
|
||||
private boolean isMyServiceRunning(Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
@ -110,7 +127,7 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private void initUi() {
|
||||
final Switch switch_ = (Switch) findViewById(R.id.wifiSwitch);
|
||||
/*final Switch switch_ = (Switch) findViewById(R.id.wifiSwitch);
|
||||
switch_.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (isChecked) {
|
||||
@ -124,7 +141,7 @@ public class MainActivity extends AppCompatActivity
|
||||
mService.disableService();
|
||||
}
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -140,6 +157,9 @@ public class MainActivity extends AppCompatActivity
|
||||
password = intent.getStringExtra("password");
|
||||
seed = intent.getStringExtra("seed");
|
||||
|
||||
setBalanceHandler();
|
||||
updateBalance();
|
||||
|
||||
Accountant.getInstance().setSeed(seed);
|
||||
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
@ -153,10 +173,29 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
|
||||
|
||||
beginForegroundService();
|
||||
|
||||
Intent intent2 = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
bindService(intent2, mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
if (mBound) {
|
||||
return mService;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void beginForegroundService() {
|
||||
if (!isTheServiceRunning()) {
|
||||
Intent startIntent = new Intent(MainActivity.this, WiFiDirectBroadcastService.class);
|
||||
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
|
||||
startService(startIntent);
|
||||
} else {
|
||||
Log.d(TAG, "beginForegroundService: Service is already running");
|
||||
}
|
||||
}
|
||||
|
||||
private void initEverything() {
|
||||
subscribeToBroadcasts();
|
||||
initUi();
|
||||
@ -245,6 +284,11 @@ public class MainActivity extends AppCompatActivity
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateBalance() {
|
||||
WalletBalanceChecker balanceChecker = new WalletBalanceChecker(this,this.getString(R.string.preference_file_key),seed, balanceHandler,PREF_UPDATE,true);
|
||||
balanceChecker.execute();
|
||||
}
|
||||
|
||||
public void startSearchFragment() {
|
||||
if (mBound && mService.isInRoleHotspot()) {
|
||||
Toast.makeText(this, "Can't start search because you are hotspot", Toast.LENGTH_SHORT).show();
|
||||
@ -381,6 +425,7 @@ public class MainActivity extends AppCompatActivity
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
mService.enableService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -388,4 +433,34 @@ public class MainActivity extends AppCompatActivity
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
|
||||
private void setBalanceHandler() {
|
||||
//Handle post-asynctask activities
|
||||
balanceHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message inputMessage) {
|
||||
switch (inputMessage.what) {
|
||||
case BALANCE_RETRIEVE_TASK_COMPLETE:
|
||||
AddressBalanceTransfer addressBalanceTransfer = (AddressBalanceTransfer) inputMessage.obj;
|
||||
String returnStatus = addressBalanceTransfer.getMessage();
|
||||
if (returnStatus.equals("noError")) {
|
||||
makeToastBalance("Balance updated");
|
||||
} else if (returnStatus.equals("hostError")) {
|
||||
makeToastBalance("Unable to reach host (node)");
|
||||
} else if (returnStatus.equals("addressError")) {
|
||||
makeToastBalance("Error getting address");
|
||||
} else if (returnStatus.equals("balanceError")) {
|
||||
makeToastBalance("Error getting balance. May not be able to resolve host/node");
|
||||
} else {
|
||||
makeToastBalance("Unknown error");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void makeToastBalance(String message) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
@ -232,50 +232,7 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void cancelNotification() {
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
mNotificationManager.cancel(1);
|
||||
}
|
||||
|
||||
|
||||
private void showNotification() {
|
||||
// The id of the channel.
|
||||
String CHANNEL_ID = "com.flashwifi.wifip2p.roaming_1";
|
||||
|
||||
String contentText = mService.isInRoleHotspot() ? "You are providing" : "You are consuming";
|
||||
|
||||
// ToDo: make this work on high API version
|
||||
NotificationCompat.Builder mBuilder =
|
||||
new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.icon_tethering_on)
|
||||
.setContentTitle("IOTA HOTSPOT")
|
||||
.setContentText(contentText);
|
||||
// Creates an explicit intent for an Activity in your app
|
||||
Intent resultIntent = new Intent(this, RoamingActivity.class);
|
||||
|
||||
// The stack builder object will contain an artificial back stack for the
|
||||
// started Activity.
|
||||
// This ensures that navigating backward from the Activity leads out of
|
||||
// your app to the Home screen.
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
||||
// Adds the back stack for the Intent (but not the Intent itself)
|
||||
stackBuilder.addParentStack(RoamingActivity.class);
|
||||
// Adds the Intent that starts the Activity to the top of the stack
|
||||
stackBuilder.addNextIntent(resultIntent);
|
||||
PendingIntent resultPendingIntent =
|
||||
stackBuilder.getPendingIntent(
|
||||
0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
);
|
||||
mBuilder.setContentIntent(resultPendingIntent);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
// mNotificationId is a unique integer your app uses to identify the
|
||||
// notification. For example, to cancel the notification, you can pass its ID
|
||||
// number to NotificationManager.cancel().
|
||||
mNotificationManager.notify(1, mBuilder.build());
|
||||
}
|
||||
|
||||
|
||||
@ -326,7 +283,8 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
|
||||
updateBillingCard();
|
||||
|
||||
showNotification();
|
||||
// ToDo: update notification
|
||||
//showNotification();
|
||||
}
|
||||
|
||||
private void endRoaming() {
|
||||
@ -350,6 +308,12 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
mService.disconnectAP();
|
||||
}
|
||||
mService.setRoaming(false);
|
||||
mService.resetBillingState();
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
|
||||
PeerStore.getInstance().clear();
|
||||
|
||||
// hide the spinner and the stop button
|
||||
ProgressBar stopProgressBar = (ProgressBar) findViewById(R.id.stopProgressBar);
|
||||
stopProgressBar.setVisibility(View.GONE);
|
||||
|
||||
@ -33,6 +33,7 @@ import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Main;
|
||||
|
||||
/**
|
||||
* Fragment that appears in the "content_frame", shows a planet
|
||||
@ -41,8 +42,6 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
public final static String TAG = "SearchActivity";
|
||||
|
||||
WiFiDirectBroadcastService mService;
|
||||
boolean mBound = false;
|
||||
BroadcastReceiver updateUIReceiver = null;
|
||||
|
||||
ArrayList<String> arrayList;
|
||||
@ -64,6 +63,14 @@ public class SearchFragment extends Fragment {
|
||||
return rootView;
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
MainActivity act = (MainActivity) getActivity();
|
||||
if (act != null) {
|
||||
return act.getmService();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -112,7 +119,7 @@ public class SearchFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void startNegotiationProtocol(String macAddress){
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
|
||||
if (p2p_info.isGroupOwner) {
|
||||
startNegotiationProtocolServer(macAddress);
|
||||
@ -123,13 +130,13 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
private void startNegotiationProtocolServer(String macAddress) {
|
||||
// starts the server if necessary
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
|
||||
if (network_info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
if (p2p_info.isGroupOwner) {
|
||||
Log.d(TAG, "You are the group owner");
|
||||
mService.startNegotiationServer(true, macAddress);
|
||||
getmService().startNegotiationServer(true, macAddress);
|
||||
Log.d(TAG, "SocketServer started");
|
||||
}
|
||||
}
|
||||
@ -137,8 +144,8 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
private void startNegotiationProtocolClient(String macAddress){
|
||||
// starts the server if necessary
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
|
||||
if (network_info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
if (!p2p_info.isGroupOwner) {
|
||||
@ -146,7 +153,7 @@ public class SearchFragment extends Fragment {
|
||||
// groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
InetAddress groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
Log.d(TAG, "Group owner address: " + p2p_info.groupOwnerAddress.getHostAddress());
|
||||
mService.startNegotiationClient(groupOwnerAddress, true, macAddress);
|
||||
getmService().startNegotiationClient(groupOwnerAddress, true, macAddress);
|
||||
Log.d(TAG, "Client Socket started");
|
||||
}
|
||||
}
|
||||
@ -155,10 +162,6 @@ public class SearchFragment extends Fragment {
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mBound) {
|
||||
getActivity().unbindService(mConnection);
|
||||
mBound = false;
|
||||
}
|
||||
if (updateUIReceiver != null) {
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
updateUIReceiver = null;
|
||||
@ -168,10 +171,6 @@ public class SearchFragment extends Fragment {
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (mBound) {
|
||||
getActivity().unbindService(mConnection);
|
||||
mBound = false;
|
||||
}
|
||||
if (updateUIReceiver != null) {
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
updateUIReceiver = null;
|
||||
@ -200,6 +199,10 @@ public class SearchFragment extends Fragment {
|
||||
updateUIReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getActivity() == null) {
|
||||
Log.d(TAG, "onReceive: getActivity is null");
|
||||
return;
|
||||
}
|
||||
Log.d("", "onReceive: FRAGMENT HAT WAS");
|
||||
if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) {
|
||||
String mac = intent.getStringExtra("peer_mac_address");
|
||||
@ -217,10 +220,6 @@ public class SearchFragment extends Fragment {
|
||||
};
|
||||
getActivity().registerReceiver(updateUIReceiver, filter);
|
||||
|
||||
// Bind to Service
|
||||
Intent intent = new Intent(getActivity(), WiFiDirectBroadcastService.class);
|
||||
getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
view = getActivity().findViewById(R.id.fragment_view);
|
||||
|
||||
initUI();
|
||||
@ -235,26 +234,20 @@ public class SearchFragment extends Fragment {
|
||||
toggle.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
if (mBound) {
|
||||
if (!mService.isSetup()) {
|
||||
Snackbar.make(view, "Please enable WiFi P2P", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
toggle.setChecked(false);
|
||||
return;
|
||||
}
|
||||
if (!getmService().isSetup()) {
|
||||
Snackbar.make(view, "Please enable WiFi P2P", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
toggle.setChecked(false);
|
||||
return;
|
||||
}
|
||||
updateList();
|
||||
if (toggle.isChecked()) {
|
||||
if (mBound) {
|
||||
mService.setInRoleHotspot(false);
|
||||
mService.setInRoleConsumer(true);
|
||||
startSearching();
|
||||
}
|
||||
getmService().setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(true);
|
||||
startSearching();
|
||||
} else {
|
||||
if (mBound) {
|
||||
mService.setInRoleHotspot(false);
|
||||
mService.setInRoleConsumer(false);
|
||||
stopSearching();
|
||||
}
|
||||
getmService().setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
stopSearching();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -298,7 +291,7 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
|
||||
public void startChat(final String address, String name) {
|
||||
mService.connect(address, new WifiP2pManager.ActionListener() {
|
||||
getmService().connect(address, new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Toast.makeText(view.getContext(), "Connected to peer", Toast.LENGTH_SHORT).show();
|
||||
@ -315,53 +308,31 @@ public class SearchFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void stopSearching() {
|
||||
if (mBound) {
|
||||
mService.stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Stopped search", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
getmService().stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Stopped search", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( problem stopping search!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( problem stopping search!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void startSearching() {
|
||||
getmService().getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Successfully searched for peers", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
|
||||
if (mBound) {
|
||||
mService.getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Successfully searched for peers", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( Peering problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( Peering problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -103,13 +103,14 @@ public class SettingsFragment extends PreferenceFragment implements SharedPrefer
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch(key){
|
||||
case "pref_key_security":
|
||||
makeToastSettingsFragment("Security Changed");
|
||||
//makeToastSettingsFragment("Security Changed");
|
||||
break;
|
||||
case "pref_key_network_timeout":
|
||||
makeToastSettingsFragment("Network Timeout Changed");
|
||||
//makeToastSettingsFragment("Network Timeout Changed");
|
||||
break;
|
||||
case "pref_key_units":
|
||||
makeToastSettingsFragment("Units Changed");
|
||||
//makeToastSettingsFragment("Units Changed");
|
||||
break;
|
||||
case "pref_key_switch_testnet":
|
||||
makeToastSettingsFragment("Testnet on/off Changed");
|
||||
|
||||
@ -95,11 +95,11 @@ public class WithdrawWalletFragment extends Fragment {
|
||||
transactionInProgress = false;
|
||||
|
||||
if(returnStatus.equals("noError")){
|
||||
balanceTextView.setText(appWalletBalance + " i");
|
||||
balanceTextView.setText(appWalletBalance);
|
||||
makeToastFundWalletFragment("Balance updated");
|
||||
}
|
||||
else if (returnStatus.equals("noErrorNoUpdateMessage")){
|
||||
balanceTextView.setText(appWalletBalance + " i");
|
||||
balanceTextView.setText(appWalletBalance);
|
||||
clearAllTransferValues();
|
||||
makeFieldsEditable();
|
||||
}
|
||||
|
||||
@ -197,6 +197,7 @@ public class BillingClient {
|
||||
|
||||
if (error_count >= maxErrorCount) {
|
||||
// stop trying to connect
|
||||
Log.d(TAG, "start: error count too high");
|
||||
state = State.ERROR;
|
||||
sendUpdateUIBroadcastWithMessage("Exit");
|
||||
}
|
||||
|
||||
@ -244,13 +244,17 @@ public class BillingServer {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
socketWrapper.close();
|
||||
} catch (IOException e) {
|
||||
if (socketWrapper != null) {
|
||||
socketWrapper.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {
|
||||
if (serverSocket != null) {
|
||||
serverSocket.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
package com.flashwifi.wifip2p.broadcast;
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.DhcpInfo;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.p2p.WifiP2pConfig;
|
||||
@ -20,9 +25,14 @@ import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.Constants;
|
||||
import com.flashwifi.wifip2p.MainActivity;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
import com.flashwifi.wifip2p.accesspoint.AccessPointTask;
|
||||
import com.flashwifi.wifip2p.accesspoint.ConnectTask;
|
||||
import com.flashwifi.wifip2p.accesspoint.StopAccessPointTask;
|
||||
@ -38,10 +48,14 @@ import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -96,6 +110,57 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
ConnectTask connectTask;
|
||||
private boolean negotiatorRunning = false;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
|
||||
Log.i(TAG, "Received Start Foreground Intent ");
|
||||
Intent notificationIntent = new Intent(this, MainActivity.class);
|
||||
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
|
||||
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
||||
notificationIntent, 0);
|
||||
/*
|
||||
Intent previousIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
|
||||
PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
|
||||
previousIntent, 0);
|
||||
|
||||
Intent playIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
|
||||
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
|
||||
playIntent, 0);*/
|
||||
|
||||
Intent stopIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
|
||||
PendingIntent pstopIntent = PendingIntent.getService(this, 0,
|
||||
stopIntent, 0);
|
||||
|
||||
Bitmap icon = BitmapFactory.decodeResource(getResources(),
|
||||
R.drawable.icon_tethering_on);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(this)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setTicker(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.notification_doing_nothing))
|
||||
.setSmallIcon(R.drawable.icon_tethering_on)
|
||||
.setLargeIcon(
|
||||
Bitmap.createScaledBitmap(icon, 128, 128, false))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true)
|
||||
.addAction(R.drawable.icon_tethering_off, "Stop",
|
||||
pstopIntent).build();
|
||||
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
|
||||
notification);
|
||||
} else if (intent.getAction().equals(
|
||||
Constants.ACTION.STOPFOREGROUND_ACTION)) {
|
||||
Log.i(TAG, "Received Stop Foreground Intent");
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
public boolean isSetup() {
|
||||
return setup;
|
||||
}
|
||||
@ -165,9 +230,23 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
@Override
|
||||
public void run() {
|
||||
BillingClient billingClient = new BillingClient(mac, getApplicationContext());
|
||||
// ToDo: get the AP gateway ip address
|
||||
// Gget the AP gateway ip address
|
||||
// https://stackoverflow.com/questions/9035784/how-to-know-ip-address-of-the-router-from-code-in-android
|
||||
billingClient.start("192.168.43.1");
|
||||
final WifiManager manager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
final DhcpInfo dhcp = manager.getDhcpInfo();
|
||||
byte[] myIPAddress = BigInteger.valueOf(dhcp.gateway).toByteArray();
|
||||
ArrayUtils.reverse(myIPAddress);
|
||||
InetAddress myInetIP = null;
|
||||
String routerIP = null;
|
||||
try {
|
||||
myInetIP = InetAddress.getByAddress(myIPAddress);
|
||||
routerIP = myInetIP.getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
routerIP = "192.168.43.1";
|
||||
}
|
||||
Log.d(TAG, "DHCP gateway: " + routerIP);
|
||||
billingClient.start(routerIP);
|
||||
// ToDo: handle billingServer EXIT CODES
|
||||
// -> close the roaming etc.
|
||||
}
|
||||
@ -379,7 +458,7 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
stopAllTasks();
|
||||
thread.start();
|
||||
} else {
|
||||
Log.d(TAG, "startNegotiationClient: BLOCKED due to roaming state");
|
||||
Log.d(TAG, "startNegotiationClient: BLOCKED due to roaming state or negotiator running");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -76,14 +76,13 @@ public class WalletAddressChecker {
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String security = prefManager.getString("pref_key_security","2");
|
||||
int securityInt = Integer.parseInt(security);
|
||||
System.out.println("securityInt: "+securityInt);
|
||||
addressResponse = api.getNewAddress(seed, securityInt, keyIndex, true, 1, false);
|
||||
} catch (ArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return addressList;
|
||||
}
|
||||
|
||||
if(addressResponse != null) {
|
||||
System.out.println("WalletAddressChecker - Address: "+addressResponse.getAddresses().get(0));
|
||||
addressList.add(addressResponse.getAddresses().get(0));
|
||||
|
||||
String[] addressesCheckArray = new String[1];
|
||||
@ -101,7 +100,7 @@ public class WalletAddressChecker {
|
||||
}
|
||||
}
|
||||
|
||||
if(transactionsForAddress.isEmpty() || (transactionsForAddress.size() == 0 || transactionsForAddress.equals(null))){
|
||||
if(transactionsForAddress == null || transactionsForAddress.isEmpty() || (transactionsForAddress.size() == 0)){
|
||||
//Transactions not found, use this address
|
||||
foundAddress = true;
|
||||
}
|
||||
@ -110,11 +109,6 @@ public class WalletAddressChecker {
|
||||
|
||||
String curHash = transactionsForAddress.get(0).getHash();
|
||||
hashStringList.add(curHash);
|
||||
|
||||
System.out.println("WalletAddressChecker value: "+transactionsForAddress.get(0).getValue());
|
||||
System.out.println("WalletAddressChecker time: "+transactionsForAddress.get(0).getAttachmentTimestamp());
|
||||
System.out.println("WalletAddressChecker address: "+transactionsForAddress.get(0).getAddress());
|
||||
|
||||
keyIndex = keyIndex + 1;
|
||||
}
|
||||
}
|
||||
@ -130,34 +124,27 @@ public class WalletAddressChecker {
|
||||
//Check whether pending transactions exist
|
||||
containsPendingTransaction = false;
|
||||
keyIndexChanged = false;
|
||||
GetInclusionStateResponse inclusionResponse;
|
||||
try {
|
||||
GetInclusionStateResponse inclusionResponse = api.getLatestInclusion(hashStringArray);
|
||||
boolean[] states = inclusionResponse.getStates();
|
||||
|
||||
for (boolean state : states) {
|
||||
if(!state){
|
||||
containsPendingTransaction = true;
|
||||
}
|
||||
}
|
||||
} catch (ArgumentException e) {
|
||||
inclusionResponse = api.getLatestInclusion(hashStringArray);
|
||||
} catch (ArgumentException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
return addressList;
|
||||
}
|
||||
|
||||
System.out.println("containsPendingTransaction: "+containsPendingTransaction);
|
||||
boolean[] states = inclusionResponse.getStates();
|
||||
|
||||
for (boolean state : states) {
|
||||
if(!state){
|
||||
containsPendingTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!containsPendingTransaction){
|
||||
//all confirmed transactions, ok to change keyIndex
|
||||
|
||||
if(keyIndex != getKeyIndex()){
|
||||
keyIndexChanged = true;
|
||||
if(keyIndex == 0){
|
||||
//Put the initial address to search. No transactions for the seed yet.
|
||||
putKeyIndex(keyIndex);
|
||||
}
|
||||
else{
|
||||
//Put the second last address to search
|
||||
putKeyIndex(keyIndex-1);
|
||||
}
|
||||
putKeyIndex(keyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,8 @@ import android.preference.PreferenceManager;
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import jota.IotaAPI;
|
||||
@ -24,6 +26,7 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private static final int FUND_WALLET = 0;
|
||||
private static final int WITHDRAW_WALLET = 1;
|
||||
private static final int PREF_UPDATE = 2;
|
||||
|
||||
private static IotaAPI api;
|
||||
private static Context context;
|
||||
@ -76,6 +79,7 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
|
||||
if(context != null){
|
||||
|
||||
WalletAddressChecker addressChecker = new WalletAddressChecker(context,prefFile);
|
||||
@ -83,8 +87,6 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
boolean containsPendingTransactions = addressChecker.getContainsPendingTransaction();
|
||||
boolean keyIndexChanged = addressChecker.getkeyIndexChanged();
|
||||
|
||||
System.out.println("seed: "+seed);
|
||||
|
||||
if(addressList != null && addressList.get(0).equals("Unable to resolve host")){
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"hostError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
@ -126,10 +128,6 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
public String getBalance(List<String> inAddresses, boolean containsPendingTransactions, boolean keyIndexChanged){
|
||||
|
||||
for (String inAddress : inAddresses) {
|
||||
System.out.println("addressGetBalance: "+inAddress);
|
||||
}
|
||||
|
||||
String updatedBalanceString;
|
||||
try {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
@ -140,11 +138,7 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
GetBalancesAndFormatResponse balanceResponse = api.getBalanceAndFormat(inAddresses, 0, 0, stopWatch, securityInt);
|
||||
long total = balanceResponse.getTotalBalance();
|
||||
System.out.println("getTotalBalance: "+total);
|
||||
|
||||
long storedBaseBalance = Long.parseLong(getBaseSharedPrefKeyBalance());
|
||||
System.out.println("getBaseSharedPreKeyBalance: "+storedBaseBalance);
|
||||
|
||||
long updatedBaseBalance = storedBaseBalance + total;
|
||||
updatedBalanceString = Long.toString(updatedBaseBalance);
|
||||
|
||||
@ -163,26 +157,35 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
//No Pending Transactions, new confirmed transactions
|
||||
else if(!containsPendingTransactions && keyIndexChanged){
|
||||
putBaseSharedPrefBalance(updatedBalanceString);
|
||||
|
||||
System.out.println("Store new base balance");
|
||||
System.out.println("updated balance: "+updatedBaseBalance);
|
||||
|
||||
updatedBalanceString = Long.toString(updatedBaseBalance);
|
||||
putSharedPrefBalance(updatedBalanceString);
|
||||
}
|
||||
} catch (ArgumentException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
return getSharedPrefKeyBalance()+"i (cached: "+getSharedPrefKeyBalanceDateUpdate()+")";
|
||||
}
|
||||
return updatedBalanceString;
|
||||
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
|
||||
putSharedPrefBalanceDateUpdate(currentDateTimeString);
|
||||
return updatedBalanceString+"i";
|
||||
}
|
||||
|
||||
private void putSharedPrefBalanceDateUpdate(String currentDateTimeString) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString("balanceDateUpdate", currentDateTimeString);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private String getSharedPrefKeyBalanceDateUpdate() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("balanceDateUpdate",defaultValue);
|
||||
return storedBalance;
|
||||
}
|
||||
|
||||
private String getSharedPrefKeyBalance() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
int keyIndex = sharedPref.getInt("keyIndex",0);
|
||||
|
||||
System.out.println("KeyIndex: "+keyIndex);
|
||||
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("balance",defaultValue);
|
||||
return storedBalance;
|
||||
@ -198,10 +201,6 @@ public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private String getBaseSharedPrefKeyBalance() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
int keyIndex = sharedPref.getInt("keyIndex",0);
|
||||
|
||||
System.out.println("KeyIndex: "+keyIndex);
|
||||
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("baseBalance",defaultValue);
|
||||
return storedBalance;
|
||||
|
||||
@ -148,8 +148,6 @@ public class WalletTestnetTokenGen extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private void transferToWallet(List<String> destAddressses, TokenGenJSONResponse token) {
|
||||
|
||||
System.out.println("2000 seed: "+token.getSeed());
|
||||
|
||||
if(destAddressses != null && destAddressses.get(0).equals("Unable to resolve host")){
|
||||
//Host Error
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE, "hostError");
|
||||
@ -161,9 +159,6 @@ public class WalletTestnetTokenGen extends AsyncTask<Void, Void, Void> {
|
||||
completeMessage.sendToTarget();
|
||||
String destAddress = destAddressses.get(destAddressses.size()-1);
|
||||
|
||||
System.out.println("DestAddress: "+destAddress);
|
||||
System.out.println("TokenAmt: "+token.getAmount().toString());
|
||||
|
||||
WalletTransferRequest transferRequest = new WalletTransferRequest(destAddress,token.getSeed(),token.getAmount().toString(),"","",context,testnetTokenGenHandler);
|
||||
transferRequest.execute();
|
||||
}
|
||||
|
||||
@ -107,7 +107,6 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
try {
|
||||
if(testnet) {
|
||||
//Testnet
|
||||
System.out.println("WalletTransferRequest: Testnet");
|
||||
if(testnetPrivate){
|
||||
sendTransferResponse = api.sendTransfer(appWalletSeed, securityInt, 4, 3, transfers, null, null, false);
|
||||
}
|
||||
@ -155,7 +154,6 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
else{
|
||||
transferResult = "Transfer error: Send Response not received";
|
||||
}
|
||||
System.out.println("WalletTransferRequest - result: "+transferResult);
|
||||
return transferResult;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,198 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Bundle;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.CreateTransactionHelperObject;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Digest;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Multisig;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Signature;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Transfer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by wlad on 24.01.18.
|
||||
*/
|
||||
|
||||
public class Example {
|
||||
public static FlashChannelHelper one;
|
||||
public static FlashChannelHelper two;
|
||||
|
||||
public static void setup() {
|
||||
|
||||
double[] deposits = new double[]{100,100};
|
||||
int depth = 4;
|
||||
|
||||
|
||||
// Example of a user setup.
|
||||
one = FlashChannelHelper.getInstance();
|
||||
one.setupUser(0, "RDNUSLPNOQUGDIZVOINTYRIRRIJMLODOC9ZTQU9KQSCDXPVSBILXUE9AHEOA9MNYZWNSECAVPQ9QSAHCN", 0, 1);
|
||||
one.setupFlash(deposits, depth);
|
||||
|
||||
// Create a second user
|
||||
// Here i needed a second instance so I left the public in the constructor of FlashChannelHelper
|
||||
two = new FlashChannelHelper();
|
||||
two.setupUser(0, "IUQDBHFDXK9EHKC9VUHCUXDLICLRANNDHYRMDYFCGSZMROWCZBLBNRKXWBSWZYDMLLHIHMP9ZPOPIFUSW", 0, 1);
|
||||
two.setupFlash(deposits, depth);
|
||||
|
||||
// The addresses must be exchanged over the network.
|
||||
// When done setup the settlementAddresses.
|
||||
ArrayList<String> settlementAddresses = new ArrayList<>();
|
||||
settlementAddresses.add("EYUSQTMUVAFUGXMJEJYRHVMSCUBDXXKOEPFWPKVJJIY9DDTQJGJRZJTMPZAVBAICZBRGSTBOGCQR9Y9P9");
|
||||
settlementAddresses.add("EYUSQTMUVAFUGXMJEJYRHVMSCUBDXXKOEPFWPKVJJIY9DDTQJGJRZJTMPZAVBAICZBRGSTBOGCQR9Y9P9");
|
||||
|
||||
// Set the addresses
|
||||
one.setupSettlementAddresses(settlementAddresses);
|
||||
two.setupSettlementAddresses(settlementAddresses);
|
||||
|
||||
// Now generate the digests for each user.
|
||||
List<Digest> initialDigestsOne = one.initialChannelDigests();
|
||||
List<Digest> initialDigestsTwo = two.initialChannelDigests();
|
||||
|
||||
// Now the users should exchange the digests over the network
|
||||
// When the both have the digests create a array with them. make sure the order is kept.
|
||||
List<List<Digest>> digestPairs = new ArrayList<>();
|
||||
digestPairs.add(initialDigestsOne);
|
||||
digestPairs.add(initialDigestsTwo);
|
||||
|
||||
// This will create the initial multisig addresses and the root address.
|
||||
one.setupChannelWithDigests(digestPairs);
|
||||
two.setupChannelWithDigests(digestPairs);
|
||||
|
||||
// After this the root must be set. You can check for it using this call.
|
||||
Log.d("[ROOT ADDR]", one.getRootAddressWithChecksum());
|
||||
|
||||
// Now the setup is ready
|
||||
}
|
||||
|
||||
public static void transaction(FlashChannelHelper sender, FlashChannelHelper reciever) {
|
||||
// Check if we need to expand the tree
|
||||
CreateTransactionHelperObject helper = sender.getTransactionHelper();
|
||||
|
||||
// If the generate value is larget 0 we need to generate some new addresses
|
||||
if (helper.getGenerate() > 0) {
|
||||
// Get digests from the sender
|
||||
ArrayList<Digest> senderDigests = Helpers.getNewBranchDigests(sender.getUser(), helper.getGenerate());
|
||||
|
||||
// Send senderDigests to user two and wait for his digests.
|
||||
|
||||
// User two makes digests.
|
||||
ArrayList<Digest> recieverDigests = Helpers.getNewBranchDigests(reciever.getUser(), helper.getGenerate());
|
||||
|
||||
// When you have both you can create a digest array
|
||||
List<List<Digest>> digestPairs = new ArrayList<>();
|
||||
digestPairs.add(senderDigests);
|
||||
digestPairs.add(recieverDigests);
|
||||
|
||||
// Now each party must generate the digests.
|
||||
Multisig updatedAddress = one.updateTreeWithDigests(digestPairs, helper.getAddress());
|
||||
|
||||
// Since the other user does not have the address to use (the object reference). We search for it.
|
||||
Multisig extansionMultisigTwo = two.getMultisigByAddress(helper.getAddress().getAddress());
|
||||
if (extansionMultisigTwo == null) {
|
||||
Log.d("[ERROR]", "Could not find attachment address for tree expansion.");
|
||||
}
|
||||
|
||||
two.updateTreeWithDigests(digestPairs, extansionMultisigTwo);
|
||||
|
||||
// Now the sender just has to update the helper objects multisig address. I will optimize this in the future.
|
||||
helper.setAddress(updatedAddress);
|
||||
}
|
||||
|
||||
// Now you can perform a transaction
|
||||
|
||||
// Create transfers.
|
||||
ArrayList<Transfer> transfers = new ArrayList<>();
|
||||
transfers.add(new Transfer(reciever.getSettlementAddress(), 10));
|
||||
|
||||
// Create a transaction from a transfer.
|
||||
ArrayList<Bundle> senderBundles = Helpers.createTransaction(transfers, helper, sender.getUser());
|
||||
|
||||
// Now send the senderBundles to the receiver and wait for the response signatures.
|
||||
|
||||
// USER2: check if bundle content is okay. Only the first transaction of the last bundle is interesting.
|
||||
// But if we want to be sure we need to check both bundles and all transactions.
|
||||
|
||||
// User two generates signatures if all is okay.
|
||||
ArrayList<Signature> receiverSignatures = two.createSignaturesForBundles(senderBundles);
|
||||
|
||||
// Now both just have to apply the signatures and check if all is good.
|
||||
ArrayList<Bundle> senderSignedBundles = IotaFlashBridge.appliedSignatures(senderBundles, receiverSignatures);
|
||||
ArrayList<Bundle> receiverSignedBundles = IotaFlashBridge.appliedSignatures(senderBundles, receiverSignatures);
|
||||
|
||||
// Now if all is good just apply. In future I will throw a error on invalid signing.
|
||||
one.applyTransfers(senderSignedBundles);
|
||||
two.applyTransfers(receiverSignedBundles);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sender
|
||||
* @param reciever
|
||||
*/
|
||||
public static void close(FlashChannelHelper sender, FlashChannelHelper reciever) {
|
||||
// Close is more or a less just a transaction.
|
||||
// So the start is exactly the same.
|
||||
|
||||
// Check if we need to expand the tree
|
||||
CreateTransactionHelperObject helper = sender.getTransactionHelper();
|
||||
|
||||
// If the generate value is larget 0 we need to generate some new addresses
|
||||
if (helper.getGenerate() > 0) {
|
||||
// Get digests from the sender
|
||||
ArrayList<Digest> senderDigests = Helpers.getNewBranchDigests(sender.getUser(), helper.getGenerate());
|
||||
|
||||
// Send senderDigests to user two and wait for his digests.
|
||||
|
||||
// User two makes digests.
|
||||
ArrayList<Digest> recieverDigests = Helpers.getNewBranchDigests(reciever.getUser(), helper.getGenerate());
|
||||
|
||||
// When you have both you can create a digest array
|
||||
List<List<Digest>> digestPairs = new ArrayList<>();
|
||||
digestPairs.add(senderDigests);
|
||||
digestPairs.add(recieverDigests);
|
||||
|
||||
// Now each party must generate the digests.
|
||||
Multisig updatedAddress = one.updateTreeWithDigests(digestPairs, helper.getAddress());
|
||||
|
||||
// Since the other user does not have the address to use (the object reference). We search for it.
|
||||
Multisig extansionMultisigTwo = two.getMultisigByAddress(helper.getAddress().getAddress());
|
||||
if (extansionMultisigTwo == null) {
|
||||
Log.d("[ERROR]", "Could not find attachment address for tree expansion.");
|
||||
}
|
||||
|
||||
two.updateTreeWithDigests(digestPairs, extansionMultisigTwo);
|
||||
|
||||
// Now the sender just has to update the helper objects multisig address. I will optimize this in the future.
|
||||
helper.setAddress(updatedAddress);
|
||||
}
|
||||
|
||||
// Now we create is closing transaction.
|
||||
ArrayList<Bundle> senderBundles = sender.createCloseTransactions();
|
||||
|
||||
// Here the same game as before with the signatures...
|
||||
|
||||
|
||||
// Now send the senderBundles to the receiver and wait for the response signatures.
|
||||
|
||||
// USER2: check if bundle content is okay. Only the first transaction of the last bundle is interesting.
|
||||
// But if we want to be sure we need to check both bundles and all transactions.
|
||||
|
||||
// User two generates signatures if all is okay.
|
||||
ArrayList<Signature> receiverSignatures = two.createSignaturesForBundles(senderBundles);
|
||||
|
||||
// Now both just have to apply the signatures and check if all is good.
|
||||
ArrayList<Bundle> senderSignedBundles = IotaFlashBridge.appliedSignatures(senderBundles, receiverSignatures);
|
||||
ArrayList<Bundle> receiverSignedBundles = IotaFlashBridge.appliedSignatures(senderBundles, receiverSignatures);
|
||||
|
||||
// Now if all is good just apply. In future I will throw a error on invalid signing.
|
||||
one.applyTransfers(senderSignedBundles);
|
||||
two.applyTransfers(receiverSignedBundles);
|
||||
|
||||
// And here we attach the bundle to the tangle. We can check the response bundles since we may need to rebroadcast them.
|
||||
// As far as I understand only one needs to send them.
|
||||
List<Bundle> attachedBundles = Helpers.POWClosedBundle(senderSignedBundles, 4, 13);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,171 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Bundle;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.CreateTransactionHelperObject;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Digest;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.FlashObject;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Multisig;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.Signature;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.UserObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jota.utils.Checksum;
|
||||
|
||||
/**
|
||||
* Created by wlad on 24.01.18.
|
||||
*/
|
||||
|
||||
public class FlashChannelHelper {
|
||||
public static FlashChannelHelper getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FlashChannelHelper();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
private static FlashChannelHelper instance;
|
||||
|
||||
|
||||
private UserObject user;
|
||||
|
||||
/**
|
||||
* When ready change public to private and only use a singleton.
|
||||
*/
|
||||
public FlashChannelHelper() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userIndex
|
||||
* @param seed
|
||||
* @param seedIndex
|
||||
* @param security
|
||||
*/
|
||||
public void setupUser(int userIndex, String seed, int seedIndex, int security) {
|
||||
this.user = new UserObject(userIndex, seed, seedIndex, security);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param deposits
|
||||
* @param depth
|
||||
*/
|
||||
public void setupFlash(double[] deposits, int depth) {
|
||||
if (user == null) {
|
||||
Log.d("[ERROR]", "setupUser must be called before calling setupFlash");
|
||||
return;
|
||||
}
|
||||
this.user.setFlash(new FlashObject(deposits, depth, user.getSecurity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create digests for the depth of the flash channel. Branches will be added when needed.
|
||||
* @return
|
||||
*/
|
||||
public List<Digest> initialChannelDigests() {
|
||||
return Helpers.getDigestsForUser(this.user, this.user.getFlash().getDepth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets settlement addresses in the flash object, the addresses must be ordered according to the userIndex.
|
||||
* @param addresses
|
||||
*/
|
||||
public void setupSettlementAddresses(ArrayList<String> addresses) {
|
||||
if (addresses.size() != user.getFlash().getSignersCount()) {
|
||||
Log.d("[ERROR]", "Not enough addresses found...");
|
||||
return;
|
||||
}
|
||||
user.getFlash().setSettlementAddresses(addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine all user digests pairs, create multisig addresses and setup tree structure.
|
||||
* @param digestPairs
|
||||
*/
|
||||
public void setupChannelWithDigests(List<List<Digest>> digestPairs) {
|
||||
if (digestPairs.size() != user.getFlash().getSignersCount()) {
|
||||
Log.d("[ERROR]", " Not enough digest pairs found...");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create multisigs.
|
||||
List<Multisig> mulitisigs = Helpers.getMultisigsForUser(digestPairs, user);
|
||||
|
||||
// Set renainder address.
|
||||
Multisig oneRemainderAddr = mulitisigs.remove(0); //shiftCopyArray();
|
||||
user.getFlash().setRemainderAddress(oneRemainderAddr);
|
||||
|
||||
// Build flash trees
|
||||
for (int i = 1; i < mulitisigs.size(); i++) {
|
||||
System.out.println(mulitisigs.get(i - 1).toString() + " -> " + mulitisigs.get(i).toString());
|
||||
mulitisigs.get(i - 1).push(mulitisigs.get(i));
|
||||
}
|
||||
user.getFlash().setRoot(mulitisigs.remove(0));
|
||||
}
|
||||
|
||||
public String getRootAddressWithChecksum() {
|
||||
try {
|
||||
return Checksum.addChecksum(user.getFlash().getRoot().getAddress());
|
||||
} catch (Exception e) {
|
||||
Log.d("[ERROR]", "Failed to get root address");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transfer utils
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create new multisig and insert it into the flash channel tree of the user.
|
||||
* @param digestPairs
|
||||
* @param address address to which the new address will be attached.
|
||||
*/
|
||||
public Multisig updateTreeWithDigests(List<List<Digest>> digestPairs, Multisig address) {
|
||||
Multisig multisig = Helpers.getNewBranch(digestPairs, user, address);
|
||||
|
||||
// Find the multisig with the address and append new address to children
|
||||
return Helpers.updateMultisigChildrenForUser(user, multisig);
|
||||
}
|
||||
|
||||
public Multisig getMultisigByAddress(String address) {
|
||||
return user.getFlash().getRoot().find(address);
|
||||
}
|
||||
|
||||
public ArrayList<Signature> createSignaturesForBundles(ArrayList<Bundle> bundles) {
|
||||
return IotaFlashBridge.sign(user.getFlash().getRoot(), user.getSeed(), bundles);
|
||||
}
|
||||
|
||||
public void applyTransfers(ArrayList<Bundle> signedBundles) {
|
||||
Helpers.applyTransfers(signedBundles, user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closing utils
|
||||
*/
|
||||
|
||||
public ArrayList<Bundle> createCloseTransactions() {
|
||||
return Helpers.closeChannel(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a helper with the address to use and the number of new addresses to generate.
|
||||
* Please create the new addresses before making the transaction.
|
||||
* @return
|
||||
*/
|
||||
public CreateTransactionHelperObject getTransactionHelper() {
|
||||
return Helpers.getTransactionHelper(user.getFlash().getRoot());
|
||||
}
|
||||
|
||||
public UserObject getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getSettlementAddress() {
|
||||
return user.getFlash().getSettlementAddresses().get(user.getUserIndex());
|
||||
}
|
||||
}
|
||||
@ -1,95 +1,467 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper;
|
||||
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.*;
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetBalancesResponse;
|
||||
import jota.model.Transaction;
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Helpers {
|
||||
public static ArrayList<Bundle> createTransaction(UserObject user, ArrayList<Transfer> transfers, boolean shouldClose) {
|
||||
CreateTransactionHelperObject toUse = IotaFlashBridge.updateLeafToRoot(user.getFlash().getRoot());
|
||||
if (toUse.getGenerate() != 0) {
|
||||
// TODO: tell the server to gen new address.
|
||||
System.out.println("No more addresses in channel.");
|
||||
}
|
||||
private static boolean useTestnet = true;
|
||||
private static String seedGeneratorURL = "http://87.118.96.200:3000"; //"https://seeedy.tangle.works";
|
||||
private static String testNetNodeURL = "https://testnet140.tangle.works:443";
|
||||
private static String netNodeURL = "http://node.iotawallet.info:14265"; // "http://87.118.96.200:14700";//
|
||||
private static IotaAPI iotaAPI = null;
|
||||
|
||||
ArrayList<Transfer> newTransfers;
|
||||
/**
|
||||
* Get a transaction object. The object contains the address to use and if required the number of new addresses to generate
|
||||
* @param root multisig address at the top of the tree
|
||||
* @return Transaction object with address and number of addresses to create.
|
||||
*/
|
||||
public static CreateTransactionHelperObject getTransactionHelper(Multisig root) {
|
||||
return IotaFlashBridge.updateLeafToRoot(root);
|
||||
}
|
||||
|
||||
if (shouldClose) {
|
||||
newTransfers = IotaFlashBridge.close(user.getFlash().getSettlementAddresses(), user.getFlash().getDeposits());
|
||||
} else {
|
||||
newTransfers = IotaFlashBridge.prepare(
|
||||
user.getFlash().getSettlementAddresses(),
|
||||
user.getFlash().getDeposits(),
|
||||
user.getUserIndex(),
|
||||
transfers
|
||||
);
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param transfers
|
||||
* @param toUse Transaction helper object
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Bundle> createTransaction(ArrayList<Transfer> transfers, CreateTransactionHelperObject toUse, UserObject user) {
|
||||
// System.out.println("Creating a transaction of" + transfers.getValue() + " to " + transfers.getAddress());
|
||||
System.out.println("[INFO]: using address " + toUse.getAddress().getAddress() + ", with boundle count" + toUse.getAddress().getBundles().size());
|
||||
|
||||
ArrayList<Bundle> bundles = IotaFlashBridge.compose(
|
||||
user.getFlash().getBalance(),
|
||||
user.getFlash().getDeposits(),
|
||||
user.getFlash().getOutputs(),
|
||||
toUse.getAddress(),
|
||||
user.getFlash().getRemainderAddress(),
|
||||
user.getFlash().getTransfers(),
|
||||
newTransfers,
|
||||
shouldClose
|
||||
|
||||
FlashObject flash = user.getFlash();
|
||||
ArrayList<Bundle> bundles;
|
||||
// Prepare a new transaction.
|
||||
ArrayList<Transfer> newTransfers = IotaFlashBridge.prepare(
|
||||
flash.getSettlementAddresses(),
|
||||
flash.getDeposits(),
|
||||
user.getUserIndex(),
|
||||
transfers
|
||||
);
|
||||
return bundles;
|
||||
}
|
||||
|
||||
public static ArrayList<Signature> signTransaction(UserObject user, ArrayList<Bundle> bundles) {
|
||||
return IotaFlashBridge.sign(user.getFlash().getRoot(), user.getSeed(), bundles);
|
||||
}
|
||||
//
|
||||
// public static ArrayList<Bundle> appliedSignatures(ArrayList<Bundle> bundles, ArrayList<Signature> signatures) {
|
||||
// ArrayList<Bundle> clonedBundles = clone(bundles);
|
||||
// bundles.clone();
|
||||
//
|
||||
// for (int i = 0; i < bundles.size(); i++) {
|
||||
// Signature sig = signatures.get(i);
|
||||
// Bundle b = bundles.get(i);
|
||||
// if (sig == null) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// ArrayList<Transaction> transactions = b.getBundles();
|
||||
// String addy = transactions.stream().filter(tx -> tx.getValue() < 0).findFirst().get().getAddress();
|
||||
// List<Transaction> tmp = transactions.stream()
|
||||
// .filter(tx -> tx.getAddress().equals(addy))
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// tmp = tmp.subList(sig.getIndex(), sig.getIndex() + sig.getSignatureFragments().size());
|
||||
//
|
||||
// for (int j = 0; j < tmp.size(); j++) {
|
||||
// tmp.get(j).setSignatureFragments(sig.getSignatureFragments().get(j));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return clonedBundles;
|
||||
// }
|
||||
|
||||
public static void applyTransfers(UserObject user, ArrayList<Bundle> bundles) {
|
||||
FlashObject flash = IotaFlashBridge.applyTransfersToUser(user, bundles);
|
||||
user.setFlash(flash);
|
||||
// IotaFlashBridge.applyTransfers(
|
||||
// user.getFlash().getRoot(),
|
||||
// user.getFlash().getDeposits(),
|
||||
// user.getFlash().getOutputs(),
|
||||
// user.getFlash().getRemainderAddress(),
|
||||
// user.getFlash().getTransfers(),
|
||||
// bundles
|
||||
// );
|
||||
}
|
||||
|
||||
public static ArrayList<Bundle> clone(ArrayList<Bundle> bundles) {
|
||||
ArrayList<Bundle> clonedBundles = new ArrayList<>();
|
||||
for (Bundle b : bundles) {
|
||||
clonedBundles.add(b.clone());
|
||||
if (newTransfers == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return clonedBundles;
|
||||
|
||||
// Compose the transaction. This may also add some management transactions (moving remainder tokens.)
|
||||
bundles = IotaFlashBridge.compose(
|
||||
flash.getBalance(),
|
||||
flash.getDeposits(),
|
||||
flash.getOutputs(),
|
||||
toUse.getAddress(),
|
||||
flash.getRemainderAddress(),
|
||||
flash.getTransfers(),
|
||||
newTransfers,
|
||||
false
|
||||
);
|
||||
|
||||
System.out.println("[SUCCESS] Created signatures for user" + user.getUserIndex());
|
||||
// Apply the signature of the transaction creater to the current transactions bundle.
|
||||
ArrayList<Signature> signatures = IotaFlashBridge.sign(toUse.getAddress(), user.getSeed(), bundles);
|
||||
|
||||
System.out.println("[SUCCESS] Parial applied Signature for user" + user.getUserIndex() + " on transfer bundle");
|
||||
// Sign bundle with your USER ONE'S signatures
|
||||
return IotaFlashBridge.appliedSignatures(bundles, signatures);
|
||||
}
|
||||
|
||||
public static ArrayList<Bundle> closeChannel(UserObject user) {
|
||||
FlashObject flash = user.getFlash();
|
||||
ArrayList<Transfer> closeTransfers = IotaFlashBridge.close(flash.getSettlementAddresses(), flash.getDeposits());
|
||||
// Compose the transaction. This may also add some management transactions (moving remainder tokens.)
|
||||
ArrayList<Bundle> bundles = IotaFlashBridge.compose(
|
||||
flash.getBalance(),
|
||||
flash.getDeposits(),
|
||||
flash.getOutputs(),
|
||||
flash.getRoot(),
|
||||
flash.getRemainderAddress(),
|
||||
flash.getTransfers(),
|
||||
closeTransfers,
|
||||
true
|
||||
);
|
||||
|
||||
System.out.println("[SUCCESS] Created signatures for user" + user.getUserIndex());
|
||||
// Apply the signature of the transaction creater to the current transactions bundle.
|
||||
ArrayList<Signature> signatures = IotaFlashBridge.sign(flash.getRoot(), user.getSeed(), bundles);
|
||||
|
||||
System.out.println("[SUCCESS] Parial applied Signature for user" + user.getUserIndex() + " on transfer bundle");
|
||||
// Sign bundle with your USER ONE'S signatures
|
||||
return IotaFlashBridge.appliedSignatures(bundles, signatures);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Tree management.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param user
|
||||
* @param toGenerate
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Digest> getNewBranchDigests(UserObject user, int toGenerate) {
|
||||
ArrayList<Digest> digests = new ArrayList<>();
|
||||
for (int i = 0; i < toGenerate; i++) {
|
||||
Digest digest = IotaFlashBridge.getDigest(user.getSeed(), user.getSeedIndex(), user.getSecurity());
|
||||
System.out.println("USING index for digest: " + user.getSeedIndex() );
|
||||
user.incrementSeedIndex();
|
||||
digests.add(digest);
|
||||
}
|
||||
return digests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param oneDigests
|
||||
* @param twoDigests
|
||||
* @param user
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
public static Multisig getNewBranch(ArrayList<Digest> oneDigests, ArrayList<Digest> twoDigests, UserObject user, Multisig address) {
|
||||
List<List<Digest>> userDigestList = new ArrayList<>();
|
||||
userDigestList.add(oneDigests);
|
||||
userDigestList.add(twoDigests);
|
||||
return getNewBranch(userDigestList, user, address);
|
||||
}
|
||||
|
||||
public static Multisig getNewBranch(List<List<Digest>> digestPairs, UserObject user, Multisig address) {
|
||||
List<Multisig> multisigs = getMultisigsForUser(digestPairs, user);
|
||||
|
||||
System.out.println("[INFO]: Adding to address " + address.getAddress());
|
||||
|
||||
// Build flash trees
|
||||
for (int i = 1; i < multisigs.size(); i++) {
|
||||
multisigs.get(i - 1).push(multisigs.get(i));
|
||||
}
|
||||
|
||||
// Clone the address to avoid overwriting params.
|
||||
Multisig output = address.clone();
|
||||
|
||||
// Add new multisigs to address.
|
||||
output.push(multisigs.get(0));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Digests and Multisig creation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates initial digests for a user. This will only create digests for a given TREE_DEPTH -> Digests.size == TREE_DEPTH + 1
|
||||
* Other transactions will be generated when required.
|
||||
* @param user user for which the digests should be generated
|
||||
* @param TREE_DEPTH number of initial digests to generate
|
||||
* @return digests for provided user.
|
||||
*/
|
||||
public static ArrayList<Digest> getDigestsForUser(UserObject user, int TREE_DEPTH) {
|
||||
ArrayList<Digest> digests = new ArrayList<>();
|
||||
// Create digests for the start of the channel
|
||||
for (int i = 0; i < TREE_DEPTH + 1; i++) {
|
||||
// Create new digest
|
||||
Digest digest = IotaFlashBridge.getDigest(
|
||||
user.getSeed(),
|
||||
user.getSeedIndex(),
|
||||
user.getSecurity()
|
||||
);
|
||||
user.incrementSeedIndex();
|
||||
System.out.println("Adding digest (" + digest.toString() + ") to user " + user.getUserIndex());
|
||||
// Increment key index
|
||||
|
||||
digests.add(digest);
|
||||
}
|
||||
return digests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param allDigests
|
||||
* @param currentUser
|
||||
* @return
|
||||
*/
|
||||
public static List<Multisig> getMultisigsForUser(List<List<Digest>> allDigests, UserObject currentUser) {
|
||||
|
||||
// Generate the first addresses
|
||||
ArrayList<Multisig> multisigs = new ArrayList<Multisig>();
|
||||
|
||||
// Loop for all digests.
|
||||
for (int index = 0; index < allDigests.get(0).size(); index++) {
|
||||
ArrayList<Digest> alignedDigests = new ArrayList<>();
|
||||
|
||||
int securitySum = 0;
|
||||
|
||||
// Loop for all users.
|
||||
for (int userIndex = 0; userIndex < allDigests.size(); userIndex++) {
|
||||
Digest digest = allDigests.get(userIndex).get(index);
|
||||
// Get array of digests for all users.
|
||||
alignedDigests.add(digest);
|
||||
securitySum += digest.getSecurity();
|
||||
}
|
||||
|
||||
// Create multisgAddr from digests.
|
||||
Multisig multisig = IotaFlashBridge.composeAddress(alignedDigests);
|
||||
|
||||
// Get digests data for current user.
|
||||
Digest digest = allDigests.get(currentUser.getUserIndex()).get(index);
|
||||
|
||||
multisig.setIndex(digest.getIndex());
|
||||
multisig.setSigningIndex(currentUser.getUserIndex() * digest.getSecurity());
|
||||
multisig.setSecuritySum(securitySum);
|
||||
multisig.setSecurity(digest.getSecurity());
|
||||
|
||||
System.out.println("Creating address " + multisig.getAddress() + " index" + multisig.getIndex() + " signingIndex: " + multisig.getSigningIndex());
|
||||
|
||||
multisigs.add(multisig);
|
||||
}
|
||||
|
||||
return multisigs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param user
|
||||
* @param multisig
|
||||
* @return
|
||||
*/
|
||||
public static Multisig updateMultisigChildrenForUser(UserObject user, Multisig multisig) {
|
||||
FlashObject flash = user.getFlash();
|
||||
Multisig originAddress = flash.getRoot().find(multisig.getAddress());
|
||||
if (originAddress != null) {
|
||||
|
||||
System.out.println("[INFO]: found address in user" + user.getUserIndex() + " data");
|
||||
originAddress.setChildren(multisig.getChildren());
|
||||
originAddress.setBundles(multisig.getBundles());
|
||||
originAddress.setSecurity(multisig.getSecurity());
|
||||
return originAddress;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply transfers to a user flash state.
|
||||
* @param signedBundles
|
||||
* @param user
|
||||
*/
|
||||
public static void applyTransfers(ArrayList<Bundle> signedBundles, UserObject user) {
|
||||
// Apply transfers to User ONE
|
||||
FlashObject newFlash = IotaFlashBridge.applyTransfersToUser(user, signedBundles);
|
||||
|
||||
// Set new flash object to user
|
||||
user.setFlash(newFlash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send trytes array to the node specified in the IotaAPI setup.
|
||||
* @param trytes
|
||||
* @param api
|
||||
* @return returns the transactions applied to the node tangle.
|
||||
*/
|
||||
public static List<jota.model.Transaction> sendTrytes(String[] trytes, IotaAPI api, int depth, int minWeightMagnitude) {
|
||||
|
||||
try {
|
||||
System.out.println("[INFO] Sinding close bundle... This can take some time");
|
||||
List<jota.model.Transaction> txs = api.sendTrytes(trytes, depth, minWeightMagnitude);
|
||||
return txs;
|
||||
} catch (IllegalAccessError error) {
|
||||
System.out.println("[ERROR] " + error.getLocalizedMessage());
|
||||
} catch (Exception exception) {
|
||||
System.out.println("[ERROR]: could not send trytes " + exception.getLocalizedMessage());
|
||||
}
|
||||
|
||||
return new ArrayList<jota.model.Transaction>();
|
||||
}
|
||||
|
||||
|
||||
public static List<Bundle> POWClosedBundle(List<Bundle> bundles, int depth, int minWeightMagnitude) {
|
||||
List<Bundle> attachedBundles = new ArrayList<>();
|
||||
for (Bundle b : bundles) {
|
||||
String[] trytes = b.toTrytesArray();
|
||||
List<jota.model.Transaction> txs = sendTrytes(trytes, getIotaAPI(), depth, minWeightMagnitude);
|
||||
if (txs != null && txs.size() > 0) {
|
||||
Bundle bundle = new Bundle(txs);
|
||||
attachedBundles.add(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
return attachedBundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new iota instace with the defined url and mode (testnet or not)
|
||||
* if api instance available the just return it
|
||||
* @return IotaAPI instance with setup url
|
||||
*/
|
||||
public static IotaAPI getIotaAPI() {
|
||||
if (iotaAPI == null) {
|
||||
return getNewIotaAPI();
|
||||
}
|
||||
return iotaAPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of iota api and override the currently set one.
|
||||
* Can be used to change url settings.
|
||||
* @return IotaAPI instance with setup url
|
||||
*/
|
||||
public static IotaAPI getNewIotaAPI() {
|
||||
URL nodeURL;
|
||||
|
||||
try {
|
||||
if (useTestnet) {
|
||||
nodeURL = new URL(testNetNodeURL);
|
||||
} else {
|
||||
nodeURL = new URL(netNodeURL);
|
||||
}
|
||||
iotaAPI = new IotaAPI.Builder()
|
||||
.protocol(nodeURL.getProtocol())
|
||||
.host(nodeURL.getHost())
|
||||
.port(String.valueOf(nodeURL.getPort()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
System.out.println("[ERROR] Failed to create IotaAPI instance." + e.getLocalizedMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return iotaAPI;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* gives a new funded seed from a seedGeneratorURL
|
||||
* @return
|
||||
*/
|
||||
public static GeneratedSeed getNewSeed() {
|
||||
try {
|
||||
String seedData = readUrl(seedGeneratorURL);
|
||||
Gson gson = new Gson();
|
||||
GeneratedSeed genSeed = gson.fromJson(seedData, GeneratedSeed.class);
|
||||
return genSeed;
|
||||
} catch (Exception e) {
|
||||
System.out.println("[ERROR]: Failed to get new testned seed" + e.getLocalizedMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total left in the flash channel.
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public static double getFlashDeposits(UserObject user) {
|
||||
double sum = 0;
|
||||
for (double deposit : user.getFlash().getDeposits()) {
|
||||
sum += deposit;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current output of the flash channel. All transactions and remainder.
|
||||
* @param user UserObject for which to compute amount
|
||||
* @return amount of IOTA
|
||||
*/
|
||||
public static double getBalanceOfUser(UserObject user) {
|
||||
FlashObject flash = user.getFlash();
|
||||
double balance = flash.getDeposits().get(user.getUserIndex());
|
||||
Map<String, Integer> transfers = flash.getOutputs();
|
||||
for (Map.Entry<String, Integer> transfer : transfers.entrySet()) {
|
||||
String userSettlementAddr = flash.getSettlementAddresses().get(user.getUserIndex());
|
||||
if (transfer.getKey().equals(userSettlementAddr)) {
|
||||
balance += transfer.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of iota deposited in a selected address
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
public static long getBalance(String address) {
|
||||
ArrayList<String> addreses = new ArrayList<>();
|
||||
addreses.add(address);
|
||||
IotaAPI api = getIotaAPI();
|
||||
try {
|
||||
GetBalancesResponse resp = api.getBalances(100, addreses);
|
||||
return Long.parseLong(resp.getBalances()[0]);
|
||||
} catch (Exception e) {
|
||||
System.out.println("[ERROR]: could not read balance for account " + address + " with error " + e.getLocalizedMessage());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for reading date from a provided url string.
|
||||
* @param urlString
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String readUrl(String urlString) throws Exception {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
URL url = new URL(urlString);
|
||||
reader = new BufferedReader(new InputStreamReader(url.openStream()));
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int read;
|
||||
char[] chars = new char[1024];
|
||||
while ((read = reader.read(chars)) != -1)
|
||||
buffer.append(chars, 0, read);
|
||||
|
||||
return buffer.toString();
|
||||
} finally {
|
||||
if (reader != null)
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static Transaction cloneTransaction(jota.model.Transaction transaction) {
|
||||
return new Transaction(
|
||||
transaction.getSignatureFragments(),
|
||||
transaction.getCurrentIndex(),
|
||||
transaction.getLastIndex(),
|
||||
transaction.getNonce(),
|
||||
transaction.getHash(),
|
||||
transaction.getObsoleteTag(),
|
||||
transaction.getTimestamp(),
|
||||
transaction.getTrunkTransaction(),
|
||||
transaction.getBranchTransaction(),
|
||||
transaction.getAddress(),
|
||||
transaction.getValue(),
|
||||
transaction.getBundle(),
|
||||
transaction.getTag(),
|
||||
transaction.getAttachmentTimestamp(),
|
||||
transaction.getAttachmentTimestampLowerBound(),
|
||||
transaction.getAttachmentTimestampUpperBound()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,17 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper;
|
||||
import com.eclipsesource.v8.*;
|
||||
import com.eclipsesource.v8.utils.V8ObjectUtils;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.*;
|
||||
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class IotaFlashBridge {
|
||||
private static V8 engine;
|
||||
private static V8Object transfer;
|
||||
@ -45,7 +41,7 @@ public class IotaFlashBridge {
|
||||
* @param digests
|
||||
* @return
|
||||
*/
|
||||
public static MultisigAddress composeAddress(ArrayList<Digest> digests) {
|
||||
public static Multisig composeAddress(ArrayList<Digest> digests) {
|
||||
// Create js object for digest
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Digest digest: digests) {
|
||||
@ -58,17 +54,12 @@ public class IotaFlashBridge {
|
||||
V8Array params = V8ObjectUtils.toV8Array(engine, paramsList);
|
||||
|
||||
V8Object retV8 = multisig.executeObjectFunction("composeAddress", params);
|
||||
|
||||
// Parse return values from JS into Java world.
|
||||
Map<String, ? super Object> resultMap = V8ObjectUtils.toMap(retV8);
|
||||
// Parse result into Java Obj.
|
||||
String addr = (String) resultMap.get("address");
|
||||
int secSum = (Integer) resultMap.get("securitySum");
|
||||
MultisigAddress ret = new MultisigAddress(addr, secSum);
|
||||
// Create multisig.
|
||||
Multisig multisig = V8Converter.multisigAddressFromV8Object(retV8);
|
||||
|
||||
params.release();
|
||||
retV8.release();
|
||||
return ret;
|
||||
return multisig;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +90,7 @@ public class IotaFlashBridge {
|
||||
*
|
||||
* @param root
|
||||
*/
|
||||
public static CreateTransactionHelperObject updateLeafToRoot(MultisigAddress root) {
|
||||
public static CreateTransactionHelperObject updateLeafToRoot(Multisig root) {
|
||||
Map<String, Object> map = root.toMap();
|
||||
// Create param list
|
||||
List<Object> paramsObj = new ArrayList<Object>();
|
||||
@ -109,7 +100,7 @@ public class IotaFlashBridge {
|
||||
V8Object ret = multisig.executeObjectFunction("updateLeafToRoot", params);
|
||||
int generate = ret.getInteger("generate");
|
||||
V8Object multisigObject = (V8Object) ret.getObject("multisig");
|
||||
MultisigAddress multisig = V8Converter.multisigAddressFromV8Object(multisigObject);
|
||||
Multisig multisig = V8Converter.multisigAddressFromV8Object(multisigObject);
|
||||
return new CreateTransactionHelperObject(generate, multisig);
|
||||
}
|
||||
|
||||
@ -122,7 +113,7 @@ public class IotaFlashBridge {
|
||||
* @param transfers array of all transfers (value, address) pairs
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Transfer> prepare(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, int index, ArrayList<Transfer> transfers) {
|
||||
public static ArrayList<Transfer> prepare(List<String> settlementAddresses, List<Double> deposits, int index, List<Transfer> transfers) {
|
||||
|
||||
// Now put all params into JS ready array.
|
||||
List<Object> params = new ArrayList<>();
|
||||
@ -132,8 +123,14 @@ public class IotaFlashBridge {
|
||||
params.add(V8Converter.transferListToV8Array(engine, transfers));
|
||||
|
||||
// Call js function.
|
||||
V8Array ret = transfer.executeArrayFunction("prepare", V8ObjectUtils.toV8Array(engine, params));
|
||||
return V8Converter.transferListFromV8Array(ret);
|
||||
try {
|
||||
V8Array ret = transfer.executeArrayFunction("prepare", V8ObjectUtils.toV8Array(engine, params));
|
||||
return V8Converter.transferListFromV8Array(ret);
|
||||
} catch (V8ScriptExecutionException exception) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -143,7 +140,7 @@ public class IotaFlashBridge {
|
||||
* @param deposits
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Transfer> close(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits) {
|
||||
public static ArrayList<Transfer> close(List<String> settlementAddresses, List<Double> deposits) {
|
||||
V8Array saJS = V8ObjectUtils.toV8Array(engine, settlementAddresses);
|
||||
// Deposits
|
||||
V8Array depositsJS = V8ObjectUtils.toV8Array(engine, deposits);
|
||||
@ -170,27 +167,24 @@ public class IotaFlashBridge {
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Bundle> compose(int balance,
|
||||
List<Integer> deposits,
|
||||
ArrayList<Bundle> outputs,
|
||||
MultisigAddress root,
|
||||
MultisigAddress remainderAddress,
|
||||
ArrayList<Bundle> history,
|
||||
ArrayList<Transfer> transfers,
|
||||
List<Double> deposits,
|
||||
Map<String, Integer> outputs,
|
||||
Multisig root,
|
||||
Multisig remainderAddress,
|
||||
List<Bundle> history,
|
||||
List<Transfer> transfers,
|
||||
boolean close) {
|
||||
|
||||
|
||||
|
||||
// Create params.
|
||||
// Now put all params into JS ready array.
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
params.add(balance);
|
||||
params.add(V8ObjectUtils.toV8Array(engine, deposits));
|
||||
params.add(V8Converter.bundleListToV8Array(engine, outputs));
|
||||
params.add(V8ObjectUtils.toV8Object(engine, outputs));
|
||||
params.add(V8Converter.multisigToV8Object(engine, root));
|
||||
params.add(V8Converter.multisigToV8Object(engine, remainderAddress));
|
||||
params.add(V8Converter.bundleListToV8Array(engine, history));
|
||||
params.add(V8Converter.transferListToV8Array(engine, transfers));
|
||||
|
||||
params.add(close);
|
||||
// Call js function.
|
||||
V8Array ret = transfer.executeArrayFunction("compose", V8ObjectUtils.toV8Array(engine, params));
|
||||
|
||||
@ -204,7 +198,7 @@ public class IotaFlashBridge {
|
||||
* @param bundles
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<Signature> sign(MultisigAddress root, String seed, ArrayList<Bundle> bundles) {
|
||||
public static ArrayList<Signature> sign(Multisig root, String seed, ArrayList<Bundle> bundles) {
|
||||
|
||||
// Create params.
|
||||
// Now put all params into JS ready array.
|
||||
@ -257,10 +251,10 @@ public class IotaFlashBridge {
|
||||
* @param signedBundles
|
||||
* @return
|
||||
*/
|
||||
public static void applyTransfers(MultisigAddress root,
|
||||
public static void applyTransfers(Multisig root,
|
||||
ArrayList<Integer> deposits,
|
||||
ArrayList<Bundle> outputs,
|
||||
MultisigAddress remainderAddress,
|
||||
Multisig remainderAddress,
|
||||
ArrayList<Bundle> transfers,
|
||||
ArrayList<Bundle> signedBundles) {
|
||||
// Construct Java params
|
||||
@ -288,4 +282,25 @@ public class IotaFlashBridge {
|
||||
ret.release();
|
||||
return flash;
|
||||
}
|
||||
|
||||
/// Utils
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
* @param encoding
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static String readFile(String path, Charset encoding)
|
||||
throws IOException
|
||||
{
|
||||
File file = new File(IotaFlashBridge.class.getClassLoader().getResource(path).getFile());
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] data = new byte[(int) file.length()];
|
||||
fis.read(data);
|
||||
fis.close();
|
||||
|
||||
return new String(data, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,245 +0,0 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void runExample() throws Exception {
|
||||
|
||||
// Run a test based on the flash example
|
||||
// Link: https://github.com/iotaledger/iota.flash.js/blob/master/examples/flash.js
|
||||
|
||||
String oneSeed = "USERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSER";
|
||||
String oneSettlement = "USERONE9ADDRESS9USERONE9ADDRESS9USERONE9ADDRESS9USERONE9ADDRESS9USERONE9ADDRESS9U";
|
||||
String twoSeed = "USERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSERTWOUSER";
|
||||
String twoSettlement = "USERTWO9ADDRESS9USERTWO9ADDRESS9USERTWO9ADDRESS9USERTWO9ADDRESS9USERTWO9ADDRESS9U";
|
||||
|
||||
//////////////////////////////////
|
||||
// INITIAL CHANNEL CONDITIONS
|
||||
|
||||
// Security level
|
||||
int SECURITY = 2;
|
||||
// Number of parties taking signing part in the channel
|
||||
int SIGNERS_COUNT = 2;
|
||||
// Flash tree depth
|
||||
int TREE_DEPTH = 4;
|
||||
// Total channel Balance
|
||||
int CHANNEL_BALANCE = 2000;
|
||||
// Users deposits
|
||||
ArrayList<Integer> DEPOSITS = new ArrayList<>();
|
||||
DEPOSITS.add(1000);
|
||||
DEPOSITS.add(1000);
|
||||
// Setup users.
|
||||
FlashObject oneFlashObj = new FlashObject(SIGNERS_COUNT, CHANNEL_BALANCE, DEPOSITS);
|
||||
UserObject oneFlash = new UserObject(0, oneSeed, TREE_DEPTH, oneFlashObj);
|
||||
|
||||
FlashObject twoFlashObj = new FlashObject(SIGNERS_COUNT, CHANNEL_BALANCE, DEPOSITS);
|
||||
UserObject twoFlash = new UserObject(1, twoSeed, TREE_DEPTH, twoFlashObj);
|
||||
|
||||
// USER ONE
|
||||
setupUser(oneFlash, TREE_DEPTH);
|
||||
|
||||
// USER TWO
|
||||
setupUser(twoFlash, TREE_DEPTH);
|
||||
|
||||
//////////////////////////////////
|
||||
// INITAL MULTISIG
|
||||
|
||||
// Make an array of digests
|
||||
ArrayList<UserObject> allUsers = new ArrayList<UserObject>();
|
||||
allUsers.add(oneFlash);
|
||||
allUsers.add(twoFlash);
|
||||
|
||||
// Create partial digests for users.
|
||||
createInitialPartialDigests(allUsers, oneFlash);
|
||||
createInitialPartialDigests(allUsers, twoFlash);
|
||||
|
||||
ArrayList<MultisigAddress> oneMultisigs = oneFlash.getMultisigDigests();
|
||||
ArrayList<MultisigAddress> twoMultisigs = twoFlash.getMultisigDigests();
|
||||
|
||||
// Set renainder address.
|
||||
MultisigAddress oneRemainderAddr = oneMultisigs.remove(0); //shiftCopyArray();
|
||||
oneFlash.getFlash().setRemainderAddress(oneRemainderAddr);
|
||||
|
||||
MultisigAddress twoRemainderAddr = twoMultisigs.remove(0);
|
||||
twoFlash.getFlash().setRemainderAddress(twoRemainderAddr);
|
||||
|
||||
// Build flash trees
|
||||
for (int i = 1; i < oneMultisigs.size(); i++) {
|
||||
System.out.println(oneMultisigs.get(i - 1).toString() + " -> " + oneMultisigs.get(i).toString());
|
||||
oneMultisigs.get(i - 1).push(oneMultisigs.get(i));
|
||||
}
|
||||
|
||||
// Build flash trees
|
||||
for (int i = 1; i < twoMultisigs.size(); i++) {
|
||||
twoMultisigs.get(i - 1).push(twoMultisigs.get(i));
|
||||
}
|
||||
|
||||
oneFlash.getFlash().setRoot(oneMultisigs.remove(0));
|
||||
twoFlash.getFlash().setRoot(twoMultisigs.remove(0));
|
||||
|
||||
ArrayList<String> settlementAddresses = new ArrayList<>();
|
||||
settlementAddresses.add(oneSettlement);
|
||||
settlementAddresses.add(twoSettlement);
|
||||
oneFlash.getFlash().setSettlementAddresses(settlementAddresses);
|
||||
twoFlash.getFlash().setSettlementAddresses(settlementAddresses);
|
||||
|
||||
// Set digest/key index
|
||||
oneFlash.setIndex(oneFlash.getPartialDigests().size());
|
||||
twoFlash.setIndex(twoFlash.getPartialDigests().size());
|
||||
|
||||
System.out.println("Channel Setup!");
|
||||
|
||||
ArrayList<Transfer> transfers = new ArrayList<>();
|
||||
transfers.add(new Transfer(twoSettlement, 1));
|
||||
transfers.add(new Transfer(twoSettlement, 400));
|
||||
|
||||
System.out.println(oneFlash);
|
||||
|
||||
System.out.println("Creating a transaction: 200 to " + twoSettlement);
|
||||
ArrayList<Bundle> bundles = Helpers.createTransaction(oneFlash, transfers, false);
|
||||
|
||||
ArrayList<Bundle> partialSignedBundles = signTransfer(bundles, oneFlash);
|
||||
ArrayList<Bundle> signedBundles = signTransfer(partialSignedBundles, twoFlash);
|
||||
/////////////////////////////////
|
||||
/// APPLY SIGNED BUNDLES
|
||||
|
||||
// Apply transfers to User ONE
|
||||
Helpers.applyTransfers(oneFlash, signedBundles);
|
||||
|
||||
// Save latest channel bundles
|
||||
oneFlash.setBundles(signedBundles);
|
||||
|
||||
// Apply transfers to User TWO
|
||||
Helpers.applyTransfers(twoFlash, signedBundles);
|
||||
// Save latest channel bundles
|
||||
twoFlash.setBundles(signedBundles);
|
||||
System.out.println("[SUCCESS] Apply Transfer to flash channel.");
|
||||
|
||||
|
||||
System.out.println("Transaction Applied!");
|
||||
// System.out.println(
|
||||
// "Transactable tokens: " +
|
||||
// oneFlash.getFlash().getDeposits().stream().mapToInt(v -> v.intValue()).sum()
|
||||
// );
|
||||
|
||||
System.out.println("Closing channel... not yet working...");
|
||||
}
|
||||
|
||||
private static ArrayList<Bundle> signTransfer(ArrayList<Bundle> bundles, UserObject user) {
|
||||
System.out.println("[SUCCESS] Created signatures for users.");
|
||||
ArrayList<Signature> oneSignatures = Helpers.signTransaction(user, bundles);
|
||||
|
||||
System.out.println("[SUCCESS] Parial applied Signature for User one on transfer bundle");
|
||||
// Sign bundle with your USER ONE'S signatures
|
||||
ArrayList<Bundle> signedBundles = IotaFlashBridge.appliedSignatures(bundles, oneSignatures);
|
||||
|
||||
return signedBundles;
|
||||
}
|
||||
|
||||
private static void setupUser(UserObject user, int TREE_DEPTH) {
|
||||
// Create digests for the start of the channel
|
||||
for (int i = 0; i < TREE_DEPTH + 1; i++) {
|
||||
// Create new digest
|
||||
Digest digest = IotaFlashBridge.getDigest(
|
||||
user.getSeed(),
|
||||
user.getIndex(),
|
||||
user.getSecurity()
|
||||
);
|
||||
System.out.println("Adding digest (" + digest.toString() + ") to user " + user.getUserIndex());
|
||||
// Increment key index
|
||||
user.incrementIndex();
|
||||
user.add(digest);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createInitialPartialDigests(ArrayList<UserObject> allUsers, UserObject currentUser) {
|
||||
|
||||
// Generate the first addresses
|
||||
ArrayList<MultisigAddress> oneMultisigs = new ArrayList<MultisigAddress>();
|
||||
|
||||
|
||||
System.out.println("_________________________________________________________________");
|
||||
System.out.println("Creating multisigs on user: " + currentUser.getUserIndex());
|
||||
int index = 0;
|
||||
// Create address
|
||||
for (Digest digest: allUsers.get(index).getPartialDigests()) {
|
||||
int i = index;
|
||||
|
||||
ArrayList<Digest> currentDigests = new ArrayList<>();
|
||||
int securitySum = 0;
|
||||
for (int j = 0; j < allUsers.size(); j++) {
|
||||
Digest currentDigest = allUsers.get(j).getPartialDigests().get(i);
|
||||
currentDigests.add(currentDigest);
|
||||
securitySum += currentDigest.getSecurity();
|
||||
}
|
||||
|
||||
MultisigAddress addy = IotaFlashBridge.composeAddress(currentDigests);
|
||||
|
||||
System.out.println("Multisig: " + addy.toString());
|
||||
|
||||
// Add key index in
|
||||
addy.setIndex(digest.getIndex());
|
||||
// Add the signing index to the object IMPORTANT
|
||||
addy.setSigningIndex(currentUser.getUserIndex() * digest.getSecurity());
|
||||
// Get the sum of all digest security to get address security sum
|
||||
addy.setSecuritySum(securitySum);
|
||||
addy.setSecurity(digest.getSecurity());
|
||||
oneMultisigs.add(addy);
|
||||
index++;
|
||||
}
|
||||
currentUser.setMultisigDigests(oneMultisigs);
|
||||
}
|
||||
|
||||
private static ArrayList<MultisigAddress> shiftCopyArray(ArrayList<MultisigAddress> input) {
|
||||
ArrayList<MultisigAddress> output = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i < input.size(); i++) {
|
||||
output.add(input.get(i));
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private static void test() throws IOException {
|
||||
|
||||
System.out.println("IOTA Flash channel tester");
|
||||
|
||||
String pathToLib = "res/iotaflash.js";
|
||||
|
||||
System.out.println("Loading lib into V8 engine");
|
||||
System.out.println("Lib imported");
|
||||
|
||||
|
||||
System.out.println("Testing getDigest(seed, index, security):");
|
||||
Digest digest1 = IotaFlashBridge.getDigest("USERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSER", 0, 2);
|
||||
Digest digest2 = IotaFlashBridge.getDigest("USERTWOUSERTWOUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSER", 0, 2);
|
||||
System.out.println("Digest1: " + digest1.toString());
|
||||
|
||||
|
||||
System.out.println("Testing composeAddress(digests):");
|
||||
ArrayList<Digest> digests = new ArrayList<Digest>();
|
||||
digests.add(digest1);
|
||||
digests.add(digest2);
|
||||
MultisigAddress composedAddr = IotaFlashBridge.composeAddress(digests);
|
||||
System.out.println("Got multisig addr for digests: " + composedAddr.getAddress() + ", securitySum: " + composedAddr.getSecuritySum());
|
||||
|
||||
testPrepare();
|
||||
}
|
||||
|
||||
private static void testPrepare() {
|
||||
|
||||
System.out.println("Testing prepare()");
|
||||
ArrayList<String> settlementAddr = new ArrayList<String>();
|
||||
settlementAddr.add("RCZHCRDWMGJPHKROKEGVADVJXPGKEKNJRNLZZFPITUVEWNPGIWNUMKTYKMNB9DCNLWGMJZDNKYQDQKDLC");
|
||||
ArrayList<Integer> depositsPrep = new ArrayList<Integer>();
|
||||
ArrayList<Transfer> transfers = new ArrayList<Transfer>();
|
||||
|
||||
IotaFlashBridge.prepare(settlementAddr, depositsPrep, 0, transfers);
|
||||
}
|
||||
}
|
||||
@ -1,50 +1,63 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.V8Converter;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Helpers;
|
||||
import jota.model.Transaction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Bundle extends jota.model.Bundle {
|
||||
|
||||
public class Bundle {
|
||||
private ArrayList<Transaction> bundles;
|
||||
|
||||
public Bundle(ArrayList<Transaction> bundles) {
|
||||
this.bundles = bundles;
|
||||
public Bundle(List<Transaction> transactions) {
|
||||
super(transactions, transactions.size());
|
||||
}
|
||||
|
||||
public Bundle() {
|
||||
this.bundles = new ArrayList<>();
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String out = "";
|
||||
for (Transaction t: bundles) {
|
||||
for (Transaction t: getTransactions()) {
|
||||
out += t.toString();
|
||||
out += "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public String[] toTrytesArray() {
|
||||
String[] bundleTrytes = new String[getTransactions().size()];
|
||||
List<jota.model.Transaction> transactions = getTransactions();
|
||||
for (int i = 0; i < bundleTrytes.length; i++) {
|
||||
bundleTrytes[(bundleTrytes.length - 1) - i] = transactions.get(i).toTrytes();
|
||||
}
|
||||
|
||||
return bundleTrytes;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
List<Object> bundleList = new ArrayList<Object>();
|
||||
for (Transaction b: bundles) {
|
||||
bundleList.add(b.toMap());
|
||||
}
|
||||
map.put("bundles", bundleList);
|
||||
|
||||
map.put("bundles", toArrayList());
|
||||
return map;
|
||||
}
|
||||
|
||||
public ArrayList<Transaction> getBundles() {
|
||||
return bundles;
|
||||
public List<Object> toArrayList() {
|
||||
List<Object> bundleList = new ArrayList<Object>();
|
||||
for (Transaction tx: getTransactions()) {
|
||||
bundleList.add(V8Converter.transactionToMap(tx));
|
||||
}
|
||||
return bundleList;
|
||||
}
|
||||
|
||||
public Bundle clone() {
|
||||
public Bundle clone() {
|
||||
ArrayList<Transaction> clonedTransactions = new ArrayList<>();
|
||||
for (Transaction t: bundles) {
|
||||
clonedTransactions.add(t.clone());
|
||||
for (Transaction tx: getTransactions()) {
|
||||
clonedTransactions.add(Helpers.cloneTransaction(tx));
|
||||
}
|
||||
return new Bundle(clonedTransactions);
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
|
||||
public class CreateTransactionHelperObject {
|
||||
private int generate = 0;
|
||||
private MultisigAddress address;
|
||||
private Multisig address;
|
||||
|
||||
public CreateTransactionHelperObject(int gen, MultisigAddress addr) {
|
||||
public CreateTransactionHelperObject(int gen, Multisig addr) {
|
||||
this.generate = gen;
|
||||
this.address = addr;
|
||||
}
|
||||
@ -14,7 +13,11 @@ public class CreateTransactionHelperObject {
|
||||
return generate;
|
||||
}
|
||||
|
||||
public MultisigAddress getAddress() {
|
||||
public Multisig getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Multisig address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -17,7 +16,6 @@ public class Digest {
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public String getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
public class FlashLibJSException extends Exception {
|
||||
|
||||
public enum FlashLibJSExceptionType {
|
||||
INSUFFICIENT_FUNDS, UNKNOWN
|
||||
}
|
||||
|
||||
|
||||
private FlashLibJSExceptionType type = FlashLibJSExceptionType.UNKNOWN;
|
||||
|
||||
public FlashLibJSException(String string) {
|
||||
if (string.contains(FlashLibJSExceptionType.INSUFFICIENT_FUNDS.name())) {
|
||||
this.type = FlashLibJSExceptionType.INSUFFICIENT_FUNDS;
|
||||
}
|
||||
}
|
||||
|
||||
public FlashLibJSExceptionType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@ -1,28 +1,36 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.*;
|
||||
import com.eclipsesource.v8.utils.V8ObjectUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class FlashObject {
|
||||
int signersCount = 2;
|
||||
int balance;
|
||||
ArrayList<String> settlementAddresses;
|
||||
ArrayList<Integer> deposits; // Clone correctly
|
||||
ArrayList<Bundle> outputs = new ArrayList<Bundle>();
|
||||
ArrayList<Bundle> transfers = new ArrayList<Bundle>();
|
||||
MultisigAddress root;
|
||||
MultisigAddress remainderAddress;
|
||||
private int signersCount = 2;
|
||||
private int balance;
|
||||
private List<String> settlementAddresses;
|
||||
private List<Double> deposits;
|
||||
private Map<String, Integer> outputs = new HashMap<>();
|
||||
private List<Bundle> transfers = new ArrayList<Bundle>();
|
||||
private Multisig root;
|
||||
private Multisig remainderAddress;
|
||||
private int depth;
|
||||
private int security;
|
||||
|
||||
public FlashObject(double[] deposits, int depth, int security) {
|
||||
|
||||
public FlashObject(int signersCount, int balance, ArrayList<Integer> deposits) {
|
||||
this.signersCount = signersCount;
|
||||
this.balance = balance;
|
||||
this.deposits = deposits;
|
||||
this.signersCount = deposits.length;
|
||||
for (double dep : deposits) {
|
||||
this.balance += dep;
|
||||
}
|
||||
this.deposits = new ArrayList<>();
|
||||
for (double deposit : deposits){
|
||||
this.deposits.add(deposit);
|
||||
}
|
||||
this.depth = depth;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
public FlashObject(int signersCount, int balance, ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, ArrayList<Bundle> outputs, ArrayList<Bundle> transfers, MultisigAddress root, MultisigAddress remainderAddress) {
|
||||
public FlashObject(int signersCount, int balance, List<String> settlementAddresses, List<Double> deposits, Map<String, Integer> outputs, List<Bundle> transfers, Multisig root, Multisig remainderAddress, int depth, int security) {
|
||||
this.signersCount = signersCount;
|
||||
this.balance = balance;
|
||||
this.settlementAddresses = settlementAddresses;
|
||||
@ -31,35 +39,8 @@ public class FlashObject {
|
||||
this.transfers = transfers;
|
||||
this.root = root;
|
||||
this.remainderAddress = remainderAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String out = "";
|
||||
out += "signersCount: " + signersCount + "\n";
|
||||
out += "balance: " + balance + "\n";
|
||||
out += "settlementAddresses: " + "\n";
|
||||
for (String b: settlementAddresses) {
|
||||
out += "\t" + b + "\n";
|
||||
}
|
||||
out += "deposits: " + "\n";
|
||||
for (Integer b: deposits) {
|
||||
out += "\t" + b + "\n";
|
||||
}
|
||||
|
||||
out += "outputs: " + "\n";
|
||||
for (Bundle b: outputs) {
|
||||
out += "\t" + b.toString() + "\n";
|
||||
}
|
||||
|
||||
out += "transfers: " + "\n";
|
||||
for (Bundle b: transfers) {
|
||||
out += "\t" + b.toString() + "\n";
|
||||
}
|
||||
out += "remainderAddress: " + remainderAddress.toString() + "\n";
|
||||
out += "root: " + root.toString() + "\n";
|
||||
|
||||
return out;
|
||||
this.depth = depth;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
@ -69,57 +50,62 @@ public class FlashObject {
|
||||
objectMap.put("root", root.toMap());
|
||||
objectMap.put("remainderAddress", remainderAddress.toMap());
|
||||
objectMap.put("settlementAddresses", getSettlementAddresses());
|
||||
|
||||
ArrayList<Object> outputMap = new ArrayList<>();
|
||||
for (Bundle b: outputs) {
|
||||
outputMap.add(b.toMap());
|
||||
}
|
||||
objectMap.put("outputs", outputMap);
|
||||
objectMap.put("depth", getDepth());
|
||||
objectMap.put("security", getSecurity());
|
||||
// Wrap outputs inside an array.
|
||||
objectMap.put("outputs", getOutputs());
|
||||
|
||||
objectMap.put("deposits", getDeposits());
|
||||
|
||||
ArrayList<Object> transfersMap = new ArrayList<>();
|
||||
for (Bundle b: transfers) {
|
||||
outputMap.add(b.toMap());
|
||||
for (Bundle b: getTransfers()) {
|
||||
transfersMap.add(b.toArrayList());
|
||||
}
|
||||
objectMap.put("transfers", transfersMap);
|
||||
return objectMap;
|
||||
|
||||
}
|
||||
|
||||
public int getSignersCount() {
|
||||
return signersCount;
|
||||
}
|
||||
|
||||
public int getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public MultisigAddress getRoot() {
|
||||
public int getSignersCount() {
|
||||
return signersCount;
|
||||
}
|
||||
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public int getSecurity() {
|
||||
return security;
|
||||
}
|
||||
|
||||
public Multisig getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getDeposits() {
|
||||
public List<Double> getDeposits() {
|
||||
return deposits;
|
||||
}
|
||||
|
||||
public ArrayList<Bundle> getOutputs() {
|
||||
public Map<String, Integer> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
public ArrayList<Bundle> getTransfers() {
|
||||
public List<Bundle> getTransfers() {
|
||||
return transfers;
|
||||
}
|
||||
|
||||
public void setRemainderAddress(MultisigAddress remainderAddress) {
|
||||
public void setRemainderAddress(Multisig remainderAddress) {
|
||||
this.remainderAddress = remainderAddress;
|
||||
}
|
||||
|
||||
public MultisigAddress getRemainderAddress() {
|
||||
public Multisig getRemainderAddress() {
|
||||
return remainderAddress;
|
||||
}
|
||||
|
||||
public void setRoot(MultisigAddress root) {
|
||||
public void setRoot(Multisig root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
@ -127,7 +113,7 @@ public class FlashObject {
|
||||
this.settlementAddresses = settlementAddresses;
|
||||
}
|
||||
|
||||
public ArrayList<String> getSettlementAddresses() {
|
||||
public List<String> getSettlementAddresses() {
|
||||
return settlementAddresses;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
public class GeneratedSeed {
|
||||
private String address;
|
||||
private String seed;
|
||||
private long amount;
|
||||
|
||||
public GeneratedSeed(String address, String seed, long amount) {
|
||||
this.address = address;
|
||||
this.seed = seed;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public void setSeed(String seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
@ -9,35 +9,71 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MultisigAddress {
|
||||
|
||||
public class Multisig {
|
||||
private String address;
|
||||
private int securitySum;
|
||||
private int index;
|
||||
private int signingIndex;
|
||||
private int security = 2;
|
||||
private ArrayList<MultisigAddress> children;
|
||||
private ArrayList<Multisig> children;
|
||||
private ArrayList<Bundle> bundles;
|
||||
|
||||
public MultisigAddress(String address, int securitySum) {
|
||||
public Multisig(String address, int securitySum) {
|
||||
this.address = address;
|
||||
this.securitySum = securitySum;
|
||||
this.children = new ArrayList<MultisigAddress>();
|
||||
this.children = new ArrayList<Multisig>();
|
||||
this.bundles = new ArrayList<Bundle>();
|
||||
|
||||
}
|
||||
|
||||
public MultisigAddress(String address, int securitySum, ArrayList<MultisigAddress> children) {
|
||||
public Multisig(String address, int securitySum, ArrayList<Multisig> children) {
|
||||
this.address = address;
|
||||
this.securitySum = securitySum;
|
||||
this.children = children;
|
||||
this.bundles = new ArrayList<Bundle>();
|
||||
}
|
||||
|
||||
public void push(MultisigAddress addr) {
|
||||
public Multisig find(String address) {
|
||||
if (getAddress().equals(address)) {
|
||||
return this;
|
||||
} else {
|
||||
for (Multisig mult: getChildren()) {
|
||||
Multisig result = mult.find(address);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Multisig clone() {
|
||||
Multisig output = new Multisig(this.getAddress(), this.getSecuritySum());
|
||||
|
||||
output.setSecurity(this.getSecurity());
|
||||
output.setIndex(this.getIndex());
|
||||
output.setSigningIndex(this.getSigningIndex());
|
||||
// Copy all bundles
|
||||
ArrayList<Bundle> bundleCopy = new ArrayList<>();
|
||||
for (Bundle b : this.getBundles()) {
|
||||
bundleCopy.add(b.clone());
|
||||
}
|
||||
output.setBundles(bundleCopy);
|
||||
|
||||
// Copy all children
|
||||
ArrayList<Multisig> childrenCopy = new ArrayList<>();
|
||||
for (Multisig child : this.getChildren()) {
|
||||
childrenCopy.add(child.clone());
|
||||
}
|
||||
output.setChildren(childrenCopy);
|
||||
return output;
|
||||
}
|
||||
|
||||
public void push(Multisig addr) {
|
||||
children.add(addr);
|
||||
}
|
||||
|
||||
public ArrayList<MultisigAddress> getChildren() {
|
||||
public ArrayList<Multisig> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@ -52,6 +88,22 @@ public class MultisigAddress {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public void setChildren(ArrayList<Multisig> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public ArrayList<Bundle> getBundles() {
|
||||
return bundles;
|
||||
}
|
||||
|
||||
public void setBundles(ArrayList<Bundle> bundles) {
|
||||
this.bundles = bundles;
|
||||
}
|
||||
|
||||
public int getSigningIndex() {
|
||||
return signingIndex;
|
||||
}
|
||||
@ -84,14 +136,14 @@ public class MultisigAddress {
|
||||
map.put("signingIndex", getSigningIndex());
|
||||
map.put("security", security);
|
||||
List<Object> childrenList = new ArrayList<Object>();
|
||||
for (MultisigAddress ma: children) {
|
||||
for (Multisig ma: children) {
|
||||
childrenList.add(ma.toMap());
|
||||
}
|
||||
map.put("children", childrenList);
|
||||
|
||||
List<Object> bundleList = new ArrayList<Object>();
|
||||
for (Bundle b: bundles) {
|
||||
bundleList.add(b.getBundles());
|
||||
bundleList.add(b.toArrayList());
|
||||
}
|
||||
map.put("bundles", bundleList);
|
||||
|
||||
@ -105,7 +157,7 @@ public class MultisigAddress {
|
||||
@Override
|
||||
public String toString() {
|
||||
String out = "{ \n address':'" + address + "' \n, securitySum:" + securitySum + "\n, signingIndex: " + signingIndex + " \n";
|
||||
for (MultisigAddress addr: children) {
|
||||
for (Multisig addr: children) {
|
||||
out += addr.toString();
|
||||
}
|
||||
return out;
|
||||
@ -8,56 +8,17 @@ import java.util.List;
|
||||
*
|
||||
* @author Adrian
|
||||
**/
|
||||
public class Signature {
|
||||
public class Signature extends jota.model.Signature {
|
||||
private int index;
|
||||
private String bundle;
|
||||
private String address;
|
||||
private List<String> signatureFragments;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the Signature class.
|
||||
*/
|
||||
public Signature() {
|
||||
this.signatureFragments = new ArrayList<>();
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address.
|
||||
*
|
||||
* @return The address.
|
||||
*/
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address.
|
||||
*
|
||||
* @param address The address.
|
||||
*/
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signatureFragments.
|
||||
*
|
||||
* @return The signatureFragments.
|
||||
*/
|
||||
public List<String> getSignatureFragments() {
|
||||
return signatureFragments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the signatureFragments.
|
||||
*
|
||||
* @param signatureFragments The signatureFragments.
|
||||
*/
|
||||
public void setSignatureFragments(List<String> signatureFragments) {
|
||||
this.signatureFragments = signatureFragments;
|
||||
}
|
||||
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
@ -79,10 +40,10 @@ public class Signature {
|
||||
String out = "{ \n" +
|
||||
" \tindex:" + index + ", " +
|
||||
" \n\tbundle: " + bundle + ", " +
|
||||
" \n\taddress:" + address + ",";
|
||||
" \n\taddress:" + getAddress() + ",";
|
||||
|
||||
out += "\n\t[ \n";
|
||||
for (String sf : signatureFragments) {
|
||||
for (String sf : getSignatureFragments()) {
|
||||
out += "\n\t" + sf + ",";
|
||||
}
|
||||
out += " ]";
|
||||
|
||||
@ -1,128 +0,0 @@
|
||||
package com.flashwifi.wifip2p.iotaFlashWrapper.Model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Transaction {
|
||||
private String hash;
|
||||
private String signatureFragments;
|
||||
private String address;
|
||||
private long value;
|
||||
private String obsoleteTag;
|
||||
private long timestamp;
|
||||
private long currentIndex;
|
||||
private long lastIndex;
|
||||
private String bundle;
|
||||
private String trunkTransaction;
|
||||
private String branchTransaction;
|
||||
private String nonce;
|
||||
private Boolean persistence;
|
||||
private long attachmentTimestamp;
|
||||
private String tag;
|
||||
private long attachmentTimestampLowerBound;
|
||||
private long attachmentTimestampUpperBound;
|
||||
|
||||
|
||||
// Unsigned constructor
|
||||
public Transaction(String address, int value, String obsoleteTag, String tag, Integer timestamp) {
|
||||
this.address = address;
|
||||
this.value = value;
|
||||
this.obsoleteTag = obsoleteTag;
|
||||
this.tag = tag;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public Transaction(String signatureFragments, Long currentIndex, Long lastIndex, String nonce,
|
||||
String hash, String obsoleteTag, Long timestamp, String trunkTransaction,
|
||||
String branchTransaction, String address, Long value, String bundle, String tag,
|
||||
Long attachmentTimestamp, Long attachmentTimestampLowerBound, Long attachmentTimestampUpperBound) {
|
||||
|
||||
this.hash = hash;
|
||||
this.obsoleteTag = obsoleteTag;
|
||||
this.signatureFragments = signatureFragments;
|
||||
this.address = address;
|
||||
this.value = value;
|
||||
this.timestamp = timestamp;
|
||||
this.currentIndex = currentIndex;
|
||||
this.lastIndex = lastIndex;
|
||||
this.bundle = bundle;
|
||||
this.trunkTransaction = trunkTransaction;
|
||||
this.branchTransaction = branchTransaction;
|
||||
this.tag = tag;
|
||||
this.attachmentTimestamp = attachmentTimestamp;
|
||||
this.attachmentTimestampLowerBound = attachmentTimestampLowerBound;
|
||||
this.attachmentTimestampUpperBound = attachmentTimestampUpperBound;
|
||||
this.nonce = nonce;
|
||||
}
|
||||
|
||||
|
||||
public String getSignatureFragments() {
|
||||
return signatureFragments;
|
||||
}
|
||||
|
||||
public void setSignatureFragments(String signatureFragments) {
|
||||
this.signatureFragments = signatureFragments;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
if (hash != null && !hash.equals("")) {
|
||||
map.put("hash", hash);
|
||||
}
|
||||
map.put("signatureMessageFragment", signatureFragments);
|
||||
map.put("address", address);
|
||||
map.put("value", value);
|
||||
map.put("obsoleteTag", obsoleteTag);
|
||||
map.put("currentIndex", currentIndex);
|
||||
map.put("timestamp", timestamp);
|
||||
map.put("lastIndex", lastIndex);
|
||||
map.put("bundle", bundle);
|
||||
map.put("trunkTransaction", trunkTransaction);
|
||||
map.put("branchTransaction", branchTransaction);
|
||||
map.put("nonce", nonce);
|
||||
map.put("attachmentTimestamp", String.valueOf(attachmentTimestamp));
|
||||
map.put("tag", tag);
|
||||
map.put("attachmentTimestampLowerBound", String.valueOf(attachmentTimestampLowerBound));
|
||||
map.put("attachmentTimestampUpperBound", String.valueOf(attachmentTimestampUpperBound));
|
||||
return map;
|
||||
}
|
||||
|
||||
public Transaction clone() {
|
||||
return new Transaction(
|
||||
this.signatureFragments,
|
||||
this.currentIndex,
|
||||
this.lastIndex,
|
||||
this.nonce,
|
||||
this.hash,
|
||||
this.obsoleteTag,
|
||||
this.timestamp,
|
||||
this.trunkTransaction,
|
||||
this.branchTransaction,
|
||||
this.address,
|
||||
this.value,
|
||||
this.bundle,
|
||||
this.tag,
|
||||
this.attachmentTimestamp,
|
||||
this.attachmentTimestampLowerBound,
|
||||
this.attachmentTimestampUpperBound
|
||||
);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
Map<String, Object> mapObj = toMap();
|
||||
String value = "{";
|
||||
for (Map.Entry<String, Object> entry: mapObj.entrySet()) {
|
||||
value += "'" + entry.getKey() + "':'" + entry.getValue().toString() + "', \n";
|
||||
}
|
||||
value += "}";
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@ -4,31 +4,24 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class UserObject {
|
||||
private int userIndex = 1;
|
||||
private int userIndex;
|
||||
private String seed;
|
||||
private int index = 0;
|
||||
private int security = 2;
|
||||
private int depth = 4;
|
||||
private ArrayList<Bundle> bundles = new ArrayList<Bundle>();
|
||||
private ArrayList<Digest> partialDigests = new ArrayList<Digest>();
|
||||
private ArrayList<MultisigAddress> multisigDigests = new ArrayList<MultisigAddress>();
|
||||
private int seedIndex;
|
||||
private int security;
|
||||
|
||||
private FlashObject flash;
|
||||
|
||||
public UserObject(int userID, String seed, int depth, FlashObject flash) {
|
||||
public UserObject(int userID, String seed, int seedIndex, int security) {
|
||||
this.userIndex = userID;
|
||||
this.seed = seed;
|
||||
this.depth = depth;
|
||||
this.flash = flash;
|
||||
this.seedIndex = seedIndex;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
public void incrementIndex() {
|
||||
index++;
|
||||
}
|
||||
|
||||
public void add(Digest digest) {
|
||||
partialDigests.add(digest);
|
||||
public int incrementSeedIndex() {
|
||||
this.seedIndex = this.seedIndex + 1;
|
||||
return seedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,21 +29,9 @@ public class UserObject {
|
||||
String out = "";
|
||||
out += "userIndex: " + userIndex + "\n";
|
||||
out += "seed: " + seed + "\n";
|
||||
out += "index: " + index + "\n";
|
||||
out += "seedIndex: " + seedIndex + "\n";
|
||||
out += "security: " + getSecurity() + "\n";
|
||||
out += "depth: " + depth + "\n";
|
||||
out += "bundles: " + "\n";
|
||||
for (Bundle b: bundles) {
|
||||
out += "\t" + b.toString() + "\n";
|
||||
}
|
||||
out += "partialDigests: " + "\n";
|
||||
for (Digest d: partialDigests) {
|
||||
out += "\t" + d.toString() + "\n";
|
||||
}
|
||||
out += "multisigDigests: " + "\n";
|
||||
for (MultisigAddress m: multisigDigests) {
|
||||
out += "\t" + m.toString() + "\n";
|
||||
}
|
||||
out += "Flash: " + "\n";
|
||||
out += flash.toString();
|
||||
|
||||
@ -61,27 +42,8 @@ public class UserObject {
|
||||
Map<String, Object> objectMap = new HashMap<>();
|
||||
objectMap.put("userIndex", getUserIndex());
|
||||
objectMap.put("seed", getSeed());
|
||||
objectMap.put("index", getIndex());
|
||||
objectMap.put("seedIndex", getSeedIndex());
|
||||
objectMap.put("security", getSecurity());
|
||||
objectMap.put("depth", depth);
|
||||
|
||||
ArrayList<Object> bundleMaps = new ArrayList<>();
|
||||
for (Bundle b: bundles) {
|
||||
bundleMaps.add(b.toMap());
|
||||
}
|
||||
objectMap.put("bundles", bundleMaps);
|
||||
|
||||
ArrayList<Object> partialDigestMaps = new ArrayList<>();
|
||||
for (Bundle b: bundles) {
|
||||
partialDigestMaps.add(b.toMap());
|
||||
}
|
||||
objectMap.put("partialDigests", partialDigestMaps);
|
||||
|
||||
ArrayList<Object> multisigDigestsMaps = new ArrayList<>();
|
||||
for (Bundle b: bundles) {
|
||||
partialDigestMaps.add(b.toMap());
|
||||
}
|
||||
objectMap.put("multisigDigests", multisigDigestsMaps);
|
||||
objectMap.put("flash", flash.toMap());
|
||||
return objectMap;
|
||||
}
|
||||
@ -91,24 +53,12 @@ public class UserObject {
|
||||
* Getters and Setters
|
||||
*/
|
||||
|
||||
public void setMultisigDigests(ArrayList<MultisigAddress> multisigDigests) {
|
||||
this.multisigDigests = multisigDigests;
|
||||
}
|
||||
|
||||
public void setFlash(FlashObject flash) {
|
||||
this.flash = flash;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void setBundles(ArrayList<Bundle> bundles) {
|
||||
this.bundles = bundles;
|
||||
}
|
||||
|
||||
public ArrayList<MultisigAddress> getMultisigDigests() {
|
||||
return multisigDigests;
|
||||
public void setSeedIndex(int index) {
|
||||
this.seedIndex = index;
|
||||
}
|
||||
|
||||
public int getSecurity() {
|
||||
@ -119,22 +69,14 @@ public class UserObject {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
public int getSeedIndex() {
|
||||
return seedIndex;
|
||||
}
|
||||
|
||||
public int getUserIndex() {
|
||||
return userIndex;
|
||||
}
|
||||
|
||||
public ArrayList<Bundle> getBundles() {
|
||||
return bundles;
|
||||
}
|
||||
|
||||
public ArrayList<Digest> getPartialDigests() {
|
||||
return partialDigests;
|
||||
}
|
||||
|
||||
public FlashObject getFlash() {
|
||||
return flash;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import com.eclipsesource.v8.V8Array;
|
||||
import com.eclipsesource.v8.V8Object;
|
||||
import com.eclipsesource.v8.utils.V8ObjectUtils;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Model.*;
|
||||
|
||||
import jota.model.Transaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -36,13 +36,14 @@ public class V8Converter {
|
||||
return signatures;
|
||||
}
|
||||
|
||||
public static V8Object multisigToV8Object(V8 engine, MultisigAddress multisig) {
|
||||
public static V8Object multisigToV8Object(V8 engine, Multisig multisig) {
|
||||
Map<String, Object> sigMapg = multisig.toMap();
|
||||
return V8ObjectUtils.toV8Object(engine, sigMapg);
|
||||
}
|
||||
|
||||
public static V8Object flashObjectToV8Object(V8 engine, FlashObject flash) {
|
||||
return V8ObjectUtils.toV8Object(engine, flash.toMap());
|
||||
Map <String, Object> flashMap = flash.toMap();
|
||||
return V8ObjectUtils.toV8Object(engine, flashMap);
|
||||
}
|
||||
|
||||
public static FlashObject flashObjectFromV8Object(V8Object input) {
|
||||
@ -51,22 +52,33 @@ public class V8Converter {
|
||||
Integer singersCount = (Integer) inputMap.get("signersCount");
|
||||
Integer balance = (Integer) inputMap.get("balance");
|
||||
ArrayList<String> settlementAddresses = (ArrayList<String>) inputMap.get("settlementAddresses");
|
||||
MultisigAddress root = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("root"));
|
||||
MultisigAddress remainderAddress = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("remainderAddress"));
|
||||
ArrayList<Integer> deposits = (ArrayList<Integer>) inputMap.get("deposits");
|
||||
Multisig root = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("root"));
|
||||
Multisig remainderAddress = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("remainderAddress"));
|
||||
ArrayList<Double> deposits = new ArrayList<>();
|
||||
if (inputMap.get("deposits") instanceof ArrayList) {
|
||||
Object depositEntry = inputMap.get("deposits");
|
||||
if (((ArrayList<Object>) depositEntry).size() > 0 && ((ArrayList<Object>) depositEntry).get(0) instanceof Integer) {
|
||||
for (int val: (ArrayList<Integer>) depositEntry) {
|
||||
deposits.add(new Double(val));
|
||||
}
|
||||
} else {
|
||||
deposits = (ArrayList<Double>) depositEntry;
|
||||
}
|
||||
}
|
||||
ArrayList<Bundle> transfers = bundleListFromArrayList((ArrayList<Object>) inputMap.get("transfers"));
|
||||
ArrayList<Bundle> outputs = bundleListFromArrayList((ArrayList<Object>) inputMap.get("outputs"));
|
||||
|
||||
return new FlashObject(singersCount, balance, settlementAddresses, deposits, outputs, transfers, root, remainderAddress);
|
||||
Map<String, Integer> outputs = (Map<String, Integer>) inputMap.get("outputs");
|
||||
Integer depth = (Integer) inputMap.get("depth");
|
||||
Integer security = (Integer) inputMap.get("security");
|
||||
return new FlashObject(singersCount, balance, settlementAddresses, deposits, outputs, transfers, root, remainderAddress, depth ,security);
|
||||
}
|
||||
|
||||
public static V8Array bundleListToV8Array(V8 engine, ArrayList<Bundle> bundles) {
|
||||
public static V8Array bundleListToV8Array(V8 engine, List<Bundle> bundles) {
|
||||
|
||||
List<Object> bundleTmp = new ArrayList<Object>();
|
||||
for (Bundle b: bundles) {
|
||||
List<Object> transactions = new ArrayList<Object>();
|
||||
for (Transaction t: b.getBundles()) {
|
||||
transactions.add(t.toMap());
|
||||
for (jota.model.Transaction tx: b.getTransactions()) {
|
||||
transactions.add(transactionToMap((Transaction) tx));
|
||||
}
|
||||
bundleTmp.add(transactions);
|
||||
}
|
||||
@ -85,32 +97,62 @@ public class V8Converter {
|
||||
ArrayList<Bundle> ret = new ArrayList<>();
|
||||
|
||||
for (Object o: input) {
|
||||
ret.add(bundleFromArrayList((ArrayList<Object>) o));
|
||||
if (o instanceof Map) {
|
||||
if (((Map) o).get("bundles") instanceof String) {
|
||||
ArrayList<Object> bundles = (ArrayList<Object>) ((Map<String, Object>) o).get("bundles");
|
||||
ret.add(bundleFromArrayList(bundles));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (o instanceof ArrayList) {
|
||||
ret.add(bundleFromArrayList((ArrayList<Object>) o));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static MultisigAddress multisigAddressFromV8Object(V8Object input) {
|
||||
public static Multisig multisigAddressFromV8Object(V8Object input) {
|
||||
if (input.isUndefined()) {
|
||||
System.out.println("[ERROR]: could not parse object");
|
||||
return null;
|
||||
}
|
||||
Map<String, ? super Object> multiSigMap = V8ObjectUtils.toMap(input);
|
||||
return multisigAddressFromPropertyMap(multiSigMap);
|
||||
}
|
||||
|
||||
public static MultisigAddress multisigAddressFromPropertyMap(Map<String, Object> propMap) {
|
||||
public static Multisig multisigAddressFromPropertyMap(Map<String, Object> propMap) {
|
||||
// Parse result into Java Obj.
|
||||
String addr = (String) propMap.get("address");
|
||||
int secSum = (Integer) propMap.get("securitySum");
|
||||
|
||||
|
||||
ArrayList<MultisigAddress> children = new ArrayList<>();
|
||||
ArrayList<Multisig> children = new ArrayList<>();
|
||||
|
||||
for (Object child: (ArrayList<Object>) propMap.get("children")) {
|
||||
Map<String, ? super Object> childPropMap = (Map<String, ? super Object>) child;
|
||||
children.add(multisigAddressFromPropertyMap(childPropMap));
|
||||
}
|
||||
|
||||
MultisigAddress multisig = new MultisigAddress(addr, secSum, children);
|
||||
Multisig multisig = new Multisig(addr, secSum, children);
|
||||
|
||||
if (propMap.get("bundles") instanceof ArrayList) {
|
||||
ArrayList<Bundle> bundles = new ArrayList<>();
|
||||
for (Object bundle: (ArrayList<Object>) propMap.get("bundles")) {
|
||||
Bundle b = new Bundle();
|
||||
if (!(bundle instanceof ArrayList)) {
|
||||
continue;
|
||||
} else {
|
||||
for (Object transactionMap: (ArrayList<Object>) bundle) {
|
||||
b.getTransactions().add(transactionFromObject(transactionMap));
|
||||
}
|
||||
}
|
||||
bundles.add(b);
|
||||
}
|
||||
|
||||
multisig.setBundles(bundles);
|
||||
}
|
||||
|
||||
if (propMap.get("index") != null) {
|
||||
multisig.setIndex((Integer) propMap.get("index"));
|
||||
@ -119,6 +161,10 @@ public class V8Converter {
|
||||
multisig.setSigningIndex((Integer) propMap.get("signingIndex"));
|
||||
}
|
||||
|
||||
if (propMap.get("security") instanceof Integer) {
|
||||
multisig.setSecurity((Integer) propMap.get("security"));
|
||||
}
|
||||
|
||||
return multisig;
|
||||
}
|
||||
|
||||
@ -127,6 +173,10 @@ public class V8Converter {
|
||||
// Parse return as array of bundles
|
||||
ArrayList<Bundle> returnBundles = new ArrayList<>();
|
||||
for (Object bundleItem: inputList) {
|
||||
if (!(bundleItem instanceof ArrayList)) {
|
||||
System.out.println("[ERROR]: got undefined for bunle");
|
||||
continue;
|
||||
}
|
||||
ArrayList<Object> bundleContent = (ArrayList<Object>) bundleItem;
|
||||
|
||||
ArrayList<Transaction> returnedTransactions = new ArrayList<>();
|
||||
@ -199,7 +249,7 @@ public class V8Converter {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static V8Array transferListToV8Array(V8 engine, ArrayList<Transfer> transfers) {
|
||||
public static V8Array transferListToV8Array(V8 engine, List<Transfer> transfers) {
|
||||
List<Object> transferObj = new ArrayList<Object>();
|
||||
for (Transfer t: transfers) {
|
||||
transferObj.add(t.toMap());
|
||||
@ -209,12 +259,34 @@ public class V8Converter {
|
||||
|
||||
public static V8Array transactionListToV8Array(V8 engine, ArrayList<Transaction> transactions) {
|
||||
List<Object> transfersObj = new ArrayList<Object>();
|
||||
for (Transaction t: transactions) {
|
||||
transfersObj.add(t.toMap());
|
||||
for (Transaction tx: transactions) {
|
||||
transfersObj.add(transactionToMap(tx));
|
||||
}
|
||||
return V8ObjectUtils.toV8Array(engine, transfersObj);
|
||||
}
|
||||
|
||||
public static Map<String, Object> transactionToMap(jota.model.Transaction transaction) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
if (transaction.getHash() != null && !transaction.getHash().equals("")) {
|
||||
map.put("hash", transaction.getHash());
|
||||
}
|
||||
map.put("signatureMessageFragment", transaction.getSignatureFragments());
|
||||
map.put("address", transaction.getAddress());
|
||||
map.put("value", transaction.getValue());
|
||||
map.put("obsoleteTag", transaction.getObsoleteTag());
|
||||
map.put("currentIndex", transaction.getCurrentIndex());
|
||||
map.put("timestamp", transaction.getTimestamp());
|
||||
map.put("lastIndex", transaction.getLastIndex());
|
||||
map.put("bundle", transaction.getBundle());
|
||||
map.put("trunkTransaction", transaction.getTrunkTransaction());
|
||||
map.put("branchTransaction", transaction.getBranchTransaction());
|
||||
map.put("nonce", transaction.getNonce());
|
||||
map.put("attachmentTimestamp", String.valueOf(transaction.getAttachmentTimestamp()));
|
||||
map.put("tag", transaction.getTag());
|
||||
map.put("attachmentTimestampLowerBound", String.valueOf(transaction.getAttachmentTimestampLowerBound()));
|
||||
map.put("attachmentTimestampUpperBound", String.valueOf(transaction.getAttachmentTimestampUpperBound()));
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Transaction transactionFromObject(Object input) {
|
||||
Map<String, Object> bundleData = (Map<String, Object>) input;
|
||||
|
||||
@ -301,11 +301,11 @@ public class Negotiator {
|
||||
if (iotaPerMegabyte < 0) {
|
||||
return error(R.string.err_sell_price_bad_setting, false);
|
||||
}
|
||||
int minMinutes = Integer.valueOf(prefs.getString("edit_text_min_minutes", "-1"));
|
||||
int minMinutes = Integer.valueOf(prefs.getString("edit_text_sell_min_minutes", "-1"));
|
||||
if (minMinutes < 0) {
|
||||
return error(R.string.err_min_minutes_bad_setting, false);
|
||||
}
|
||||
int maxMinutes = Integer.valueOf(prefs.getString("edit_text_max_minutes", "-1"));
|
||||
int maxMinutes = Integer.valueOf(prefs.getString("edit_text_sell_max_minutes", "-1"));
|
||||
if (maxMinutes < 0) {
|
||||
return error(R.string.err_max_minutes_bad_setting, false);
|
||||
}
|
||||
|
||||
@ -102,10 +102,14 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stopText"
|
||||
android:gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/channelClosed"
|
||||
android:visibility="invisible"/>
|
||||
android:visibility="gone"/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.NoActionBar.PopupOverlay">
|
||||
<Switch
|
||||
<!--<Switch
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:layout_gravity="end"
|
||||
@ -27,7 +27,7 @@
|
||||
android:checked="false"
|
||||
android:hint="@string/wifi_p2p_discovery"
|
||||
android:width="120dp"
|
||||
android:id="@+id/wifiSwitch"/>
|
||||
android:id="@+id/wifiSwitch"/>-->
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/startAP" />
|
||||
android:textOn="@string/stopAP"
|
||||
android:textOff="@string/startAPText" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarAP"
|
||||
|
||||
@ -68,6 +68,9 @@
|
||||
<string name="channelClosed">The payment channel was closed.</string>
|
||||
<string name="initRetransfer">Initializing retransfer</string>
|
||||
<string name="welcome">Welcome to the Wifi Iota Hotspot App</string>
|
||||
<string name="notification_doing_nothing">Currently doing nothing</string>
|
||||
<string name="stopAP">Stop Hotspot</string>
|
||||
<string name="startAPText">Start Hotspot</string>
|
||||
|
||||
|
||||
<!-- Welcome Slideshow -->
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:defaultValue="true"
|
||||
android:key="pref_key_switch_testnet"
|
||||
android:title="Testnet" />
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
android:key="pref_key_payment_settings">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="10"
|
||||
android:defaultValue="15"
|
||||
android:key="edit_text_buy_price"
|
||||
android:inputType="number"
|
||||
android:selectAllOnFocus="true"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user