Skip to content

Commit

Permalink
Firmware version 2.0.0
Browse files Browse the repository at this point in the history
Major rewrite with support for all transaction types, all common fields, and multi-sign.
  • Loading branch information
Patrik Sletmo authored and TamtamHero committed Apr 29, 2020
1 parent 5d4038d commit 7e02026
Show file tree
Hide file tree
Showing 70 changed files with 4,233 additions and 2,248 deletions.
33 changes: 8 additions & 25 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,21 @@ include $(BOLOS_SDK)/Makefile.defines
APPNAME = XRP
APP_LOAD_PARAMS=--appFlags 0x240 --path "44'/144'" --curve secp256k1 --curve ed25519 $(COMMON_LOAD_PARAMS)

APPVERSION_M=1
APPVERSION_N=1
APPVERSION_P=1
APPVERSION_M=2
APPVERSION_N=0
APPVERSION_P=0
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
DEFINES += UNUSED\(x\)=\(void\)x
DEFINES += APPVERSION=\"$(APPVERSION)\"

COIN = xrp

#prepare hsm generation
ifeq ($(TARGET_NAME),TARGET_BLUE)
ICONNAME=blue_app_$(COIN).gif
else
ifeq ($(TARGET_NAME),TARGET_NANOX)
ifeq ($(TARGET_NAME),TARGET_NANOX)
ICONNAME=nanox_app_$(COIN).gif
else
else
ICONNAME=nanos_app_$(COIN).gif
endif
endif
endif


################
Expand All @@ -54,7 +50,7 @@ all: default
############

DEFINES += OS_IO_SEPROXYHAL
DEFINES += HAVE_BAGL HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U
DEFINES += HAVE_BAGL HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U HAVE_UX_FLOW

DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P)
Expand All @@ -80,7 +76,6 @@ DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
DEFINES += HAVE_UX_FLOW
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
endif
Expand Down Expand Up @@ -131,22 +126,10 @@ include $(BOLOS_SDK)/Makefile.glyphs

### computed variables
APP_SOURCE_PATH += src
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f lib_ux

ifeq ($(TARGET_NAME),TARGET_NANOX)
SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
SDK_SOURCE_PATH += lib_ux
endif

# If the SDK supports Flow for Nano S, build for it

ifeq ($(TARGET_NAME),TARGET_NANOS)

ifneq "$(wildcard $(BOLOS_SDK)/lib_ux/src/ux_flow_engine.c)" ""
SDK_SOURCE_PATH += lib_ux
DEFINES += HAVE_UX_FLOW
endif

endif

load: all
Expand Down
259 changes: 257 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,257 @@
# blue-app-xrp
XRP wallet application for Ledger Blue and Nano S
# XRP Wallet App for Ledger Nano S and Ledger Nano X

## Introduction
This repository contains the source code for the XRP wallet app that makes it possible to store XRP-based asset and securely sign any transaction for the XRP Ledger using Ledger Nano S and Ledger Nano X devices.

To add Ledger Nano S and Ledger Nano X support in your application, please see the
NPM package [hw-app-xrp](https://www.npmjs.com/package/@ledgerhq/hw-app-xrp)
and the examples below.

## Features
The XRP wallet app comes with the following features:

- Support for all transaction types:
- AccountSet
- AccountDelete
- CheckCancel
- CheckCash
- CheckCreate
- DepositPreauth
- EscrowCancel
- EscrowCreate
- EscrowFinish
- OfferCancel
- OfferCreate
- Payment
- PaymentChannelClaim
- PaymentChannelCreate
- PaymentChannelFund
- SetRegularKey
- SignerListSet
- TrustSet
- Support for all transaction common fields such as memos
- Support for issued assets such as SOLO, stocks and ETFs
- Support for signing on behalf of others
- Support for multi-signing
- Unified UI across Ledger Nano S and Ledger Nano X

## User Interface
The user interface primarily consists of the idle menu, the transaction
review menu and the approval menu.

### Idle Menu
Upon starting the app on your device you are immediately greeted by
the idle menu. This menu, as the name implies, is used when the device is in
its idle state. At this point, an external application may initiate a
transaction, which opens up the review menu.

![Idle menu](img/idle-menu.png)

### Review Menu
When reviewing a transaction the entire UI is dedicated to displaying the
transaction details. You can page through all the details by using the left
and right buttons on your device, as indicated by arrows on the screen.

![Review menu](img/review-menu.png)

Fields in arrays are suffixed with their array index in square brackets. See example below.

![Array field in review menu](img/review-array.png)

PathSet fields have their index information shown in square brackets on the
form `[Pi: Sj]`, where `i` is the path index and `j` is the step index within
that path. See example below.

![Path field in review menu](img/review-path.png)

In order to take action on the transaction, simply press the two buttons
simultaneously to open the approval menu. Note that you cannot open the
approval menu if the field you are currently viewing has more content
on subsequent pages. This is due to a limitation in Flow UI.

### Approval Menu
With the approval menu open you decide what to do with the transaction. There
are three available options:
- Approve and sign the transaction
- Review the transaction content again, reopening the review menu
- Reject the transaction and abort the signing process

![Approval menu](img/approval-menu.png)

Page through the alternatives with your left and right buttons, then press them
both simultaneously to confirm.

## Usage
In order to initiate transactions from NodeJS or a browser client, the library
[hw-app-xrp](https://www.npmjs.com/package/@ledgerhq/hw-app-xrp) can be used.

An example of a basic payment transaction using this library is shown below:
```javascript
import Transport from "@ledgerhq/hw-transport-node-hid";
// import Transport from "@ledgerhq/hw-transport-u2f"; // for browser
import Xrp from "@ledgerhq/hw-app-xrp";
import { encode } from 'ripple-binary-codec';

function establishConnection() {
return Transport.create()
.then(transport => new Xrp(transport));
}

function fetchAddress(xrp) {
return xrp.getAddress("44'/144'/0'/0/0").then(deviceData => {
return {
xrp,
address: deviceData.address,
publicKey: deviceData.publicKey.toUpperCase()
}
});
}

function signTransaction(context, transaction) {
const preparedTransaction = {
Account: context.address,
SigningPubKey: context.publicKey,
...transaction
};

const transactionBlob = encode(preparedTransaction);

console.log('Sending transaction to device for approval...');
return context.xrp.signTransaction("44'/144'/0'/0/0", transactionBlob);
}

const transactionJSON = {
TransactionType: "Payment",
Destination: "rTooLkitCksh5mQa67eaa2JaWHDBnHkpy",
Amount: "1000000",
Fee: "15",
Flags: 2147483648,
Sequence: 57,
};

establishConnection()
.then(xrp => fetchAddress(xrp))
.then(context => signTransaction(context, transactionJSON))
.then(signature => console.log(`Signature: ${signature}`))
.catch(e => console.log(`An error occurred (${e.message})`));
```

### Advanced Usage
#### Multi-signing a Transaction
It is also possible to perform parallel multi-signing using the XRP wallet
app. This is done by sourcing a list of signatures for the transaction
and appending them to the `Signers` field of the transaction before submitting
it for processing. An example of combining a couple of externally sourced signatures
with a signature of the Ledger device is shown below (uses imports and functions declared in previous example).

```javascript
const transactionJSON = {
Account: "r4PCuDkjuV2e23xVP8ChkVxo1aG2Ufpkjb",
TransactionType: "Payment",
Destination: "rTooLkitCksh5mQa67eaa2JaWHDBnHkpy",
Amount: "1000000",
Fee: "15",
Flags: 2147483648,
Sequence: 47,
SigningPubKey: "" // Must be blank
};

// Sourced externally from other signing parties, replace "..." with actual values.
const otherSigners = [
{
Signer: {
Account: "...",
SigningPubKey: "...",
TxnSignature: "..."
}
},
{
Signer: {
Account: "...",
SigningPubKey: "...",
TxnSignature: "..."
}
}
];

function retrieveSignerData(transaction) {
return establishConnection()
.then(xrp => fetchAddress(xrp))
.then(context => {
return signTransaction(context, transaction)
.then(signature => {
return {
Signer: {
Account: context.account,
SigningPubKey: context.publicKey,
TxnSignature: signature.toUpperCase()
}
}
});
})
.catch(e => console.log(`An error occurred (${e.message})`));
}

retrieveSignerData(transactionJSON)
.then(signer => {
return {
...transactionJSON,
Signers: [
...otherSigners,
signer
]
}
})
.then(transaction => console.log(transaction))
.catch(e => console.log(`An error occurred (${e.message})`));
```

### Additional Notes
From version 2.0.0 of the XRP wallet app it is possible to sign larger
transactions than in previous versions. In order to enable support for larger transactions
there have been slight modifications to the transport protocol, which is used to
communicate between the client and the device.

The protocol changes are fully backwards-compatible with previous versions of
[hw-app-xrp](https://www.npmjs.com/package/@ledgerhq/hw-app-xrp), but in order
to sign larger transactions you must use version 6.0.0 or above of [hw-app-xrp](https://www.npmjs.com/package/@ledgerhq/hw-app-xrp).

### Limitations
Because of resource constraints the following limits apply for the respective
hardware devices:

#### Ledger Nano S
- Maximum fields per transaction: 24 fields
- Maximum displayed field value length: 128 characters
- Maximum transaction size: 800 bytes
- Maximum number of elements per array field: 8 elements
- Multi-sign support: Parallel only
- Address display: Truncated

#### Ledger Nano X
- Maximum fields per transaction: 60 fields
- Maximum displayed field value length: 1024 characters
- Maximum transaction size: 10 000 bytes
- Maximum number of elements per array field: 8 elements
- Multi-sign support: Parallel only
- Address display: Full

## Building
Make sure that you have configured a development environment as outlined in [the development
documentation](https://ledger.readthedocs.io/en/latest/userspace/getting_started.html)
for Ledger devices. Then run make from the repository root to build the app:
```sh
make
```

## Installing
To upload the app to your device, run the following command:
```sh
make load
```

## Testing
Manual testing can be conducted with the help of the testing utility
`ledger-xrp-tests`. Make sure that your device is running the latest
firmware and then follow the instructions in the `ledger-xrp-tests`
repository.
Binary file removed blue_app_xrp.gif
Binary file not shown.
Loading

0 comments on commit 7e02026

Please sign in to comment.