Skip to content

Commit

Permalink
Add Keypair chooser for REPL and other GUI components
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Apr 25, 2024
1 parent 11ecd11 commit 1b1e9f1
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class HotWalletEntry extends AWalletEntry {
private Hash passHash=null;
boolean locked=false;

private HotWalletEntry(AKeyPair kp) {
public HotWalletEntry(AKeyPair kp) {
this.keyPair = kp;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import javax.swing.JPanel;

import convex.api.Convex;
import convex.core.crypto.wallet.AWalletEntry;
import convex.core.crypto.wallet.IWallet;
import convex.core.data.ACell;
import convex.core.data.Address;
import convex.core.data.prim.AInteger;
import convex.core.lang.ops.Special;
import convex.core.text.Text;
import convex.gui.components.account.AddressCombo;
import convex.gui.components.account.KeyPairCombo;
import net.miginfocom.swing.MigLayout;

/**
Expand All @@ -25,6 +27,7 @@ public class AccountChooserPanel extends JPanel {

private JComboBox<String> modeCombo;
public final AddressCombo addressCombo;
public final KeyPairCombo keyCombo;

private JLabel balanceLabel;

Expand All @@ -44,11 +47,10 @@ public AccountChooserPanel(IWallet wallet,Convex convex) {
// Account selection
mp.add(new JLabel("Account:"));

Address address=convex.getAddress();
addressCombo = new AddressCombo();
addressCombo.setSelectedItem(convex.getAddress());
addressCombo.setSelectedItem(address);
addressCombo.setToolTipText("Select Account for use");
mp.add(addressCombo);

addressCombo.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
Expand All @@ -59,6 +61,15 @@ public void focusLost(FocusEvent e) {
// Ignore
}
});
mp.add(addressCombo);

keyCombo=KeyPairCombo.forConvex(convex);
keyCombo.addItemListener(e->{
AWalletEntry we=(AWalletEntry)e.getItem();
convex.setKeyPair(we.getKeyPair());
});
mp.add(keyCombo);


addressCombo.addItemListener(e -> {
updateAddress(addressCombo.getAddress());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,81 @@
import java.awt.Component;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import convex.api.Convex;
import convex.core.crypto.AKeyPair;
import convex.core.crypto.wallet.AWalletEntry;
import convex.core.crypto.wallet.HotWalletEntry;
import convex.core.data.AccountKey;
import convex.core.util.Utils;
import convex.gui.components.CodeLabel;
import convex.gui.components.Identicon;
import convex.gui.keys.KeyRingPanel;
import convex.gui.utils.Toolkit;
import net.miginfocom.swing.MigLayout;

@SuppressWarnings("serial")
public class KeyPairCombo extends JComboBox<AWalletEntry> {

public static class KeyPairModel extends DefaultComboBoxModel<AWalletEntry> {
public static class KeyPairModel implements ComboBoxModel<AWalletEntry> {

private DefaultListModel<AWalletEntry> underlying;
private AWalletEntry selected;

public KeyPairModel(DefaultListModel<AWalletEntry> underlying) {
this.underlying=underlying;
}

public KeyPairModel() {
this(KeyRingPanel.getListModel());
}

@Override
public int getSize() {
return underlying.getSize();
}

@Override
public AWalletEntry getElementAt(int index) {
return underlying.getElementAt(index);
}

@Override
public void addListDataListener(ListDataListener l) {
underlying.addListDataListener(l);
}

@Override
public void removeListDataListener(ListDataListener l) {
underlying.removeListDataListener(l);
}

@Override
public void setSelectedItem(Object anItem) {
this.selected=(AWalletEntry)anItem;
ListDataListener[] listeners = underlying.getListDataListeners();
ListDataEvent e=new ListDataEvent(this,ListDataEvent.CONTENTS_CHANGED,0,0);
for (ListDataListener l: listeners) {
l.contentsChanged(e);
}
}

@Override
public Object getSelectedItem() {
return this.selected;
}

public void addElement(AWalletEntry entry) {
underlying.addElement(entry);
}

}

Expand All @@ -37,7 +92,7 @@ public Component getListCellRendererComponent(JList<? extends AWalletEntry> list
boolean isSelected, boolean cellHasFocus) {
AWalletEntry entry= (AWalletEntry)value;
setText("0x"+entry.getPublicKey().toHexString(12)+"...");
setIcon(Identicon.createIcon(entry.getIdenticonData(),24));
setIcon(Identicon.createIcon(entry.getIdenticonData(),21));
return this;
}
}
Expand All @@ -59,9 +114,7 @@ public static void main (String... args) {
JPanel p=new JPanel();
p.setLayout(new MigLayout("insets 20 20 20 20, wrap 1"));


KeyPairModel model=new KeyPairModel();
model.addElement(PROTOTYPE);
KeyPairCombo kpCombo=new KeyPairCombo(model);
p.add(kpCombo);

Expand All @@ -80,4 +133,17 @@ public AWalletEntry getWalletEntry() {
Object a = getSelectedItem();
return (AWalletEntry)a;
}

public static KeyPairCombo forConvex(Convex convex) {
KeyPairModel model=new KeyPairModel();
AKeyPair kp=convex.getKeyPair();
AccountKey publicKey=(kp==null)?null:kp.getAccountKey();
AWalletEntry we=Toolkit.getKeyRingEntry(publicKey);
if (we==null) {
we=new HotWalletEntry(kp);
}
model.setSelectedItem(we);

return new KeyPairCombo(model);
}
}
22 changes: 22 additions & 0 deletions convex-gui/src/main/java/convex/gui/utils/Toolkit.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Iterator;

import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
Expand All @@ -37,7 +39,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import convex.core.crypto.wallet.AWalletEntry;
import convex.core.data.AccountKey;
import convex.core.util.Utils;
import convex.gui.keys.KeyRingPanel;
import mdlaf.MaterialLookAndFeel;
import mdlaf.themes.AbstractMaterialTheme;
import mdlaf.themes.MaterialOceanicTheme;
Expand Down Expand Up @@ -269,5 +274,22 @@ private void maybeDisplayPopupMenu(MouseEvent e) {
});
}

/**
* Gets an entry for the current keyring
* @param address
* @return Wallet Entry, or null if not found
*/
public static AWalletEntry getKeyRingEntry(AccountKey publicKey) {
DefaultListModel<AWalletEntry> list = KeyRingPanel.getListModel();
Iterator<AWalletEntry> it=list.elements().asIterator();
while (it.hasNext()) {
AWalletEntry we=it.next();
if (Utils.equals(we.getPublicKey(), publicKey)) {
return we;
}
}
return null;
}


}
10 changes: 9 additions & 1 deletion convex-peer/src/main/java/convex/api/Convex.java
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,15 @@ protected CompletableFuture<Result> awaitResult(long id, long timeout) {
}
});
awaiting.put(id, cf);
CompletableFuture<Result> cr=cf.thenApply(m->m.toResult());
CompletableFuture<Result> cr=cf.thenApply(m->{
Result r=m.toResult();

if (r.getErrorCode()!=null) {
// clear sequence if something went wrong. It is probably invalid now....
sequence=null;
}
return r;
});
return cr;
}

Expand Down
8 changes: 6 additions & 2 deletions convex-peer/src/main/java/convex/api/ConvexLocal.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ public CompletableFuture<Result> requestStatus() {

@Override
public CompletableFuture<Result> transact(SignedData<ATransaction> signed) {
CompletableFuture<Result> r= makeMessageFuture(MessageType.TRANSACT,Vectors.of(makeID(),signed));
maybeUpdateSequence(signed);
CompletableFuture<Result> r= makeMessageFuture(MessageType.TRANSACT,Vectors.of(makeID(),signed));
return r;
}

Expand Down Expand Up @@ -103,7 +103,11 @@ private CompletableFuture<Result> makeMessageFuture(MessageType type, ACell payl

private Consumer<Message> makeResultHandler(CompletableFuture<Result> cf) {
return m->{
cf.complete(m.toResult());
Result r=m.toResult();
if (r.getErrorCode()!=null) {
sequence=null;
}
cf.complete(r);
};
}

Expand Down
2 changes: 1 addition & 1 deletion convex-peer/src/main/java/convex/api/ConvexRemote.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ public synchronized CompletableFuture<Result> transact(SignedData<ATransaction>
id = connection.sendTransaction(signed);
if (id>=0) {
// Store future for completion by result message
cf = awaitResult(id,timeout);
maybeUpdateSequence(signed);
cf = awaitResult(id,timeout);
break;
}
}
Expand Down

0 comments on commit 1b1e9f1

Please sign in to comment.