Skip to content

Commit

Permalink
feat(hw-app-str): refactor hw-app-str and add `signSorobanAuthoriza…
Browse files Browse the repository at this point in the history
…tion`.
  • Loading branch information
overcat committed Jun 11, 2024
1 parent 68fab96 commit 782d637
Show file tree
Hide file tree
Showing 11 changed files with 720 additions and 465 deletions.
6 changes: 6 additions & 0 deletions .changeset/fair-scissors-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@ledgerhq/hw-app-str": major
"@ledgerhq/live-common": patch
---

Refactor `hw-app-str` and add `signSorobanAuthorization`. Please check the changelog and documentation of "@ledgerhq/hw-app-str" for more information.
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ const dataset: DatasetTest<Transaction> = {
{
name: "stellar seed 1",
apdus: `
=> e002000017038000002c8000009480000000766961206c756d696e61
=> e00200000d038000002c8000009480000000
<= 27c586f8499294c64d57f8d7956eef4431de58ab20e1c88001f6cf131c97d6f39000
=> e002000017038000002c8000009480000001766961206c756d696e61
=> e00200000d038000002c8000009480000001
<= 1174242cc3e722e843ac37db3a745897941396d486456e303001b06b417db1f89000
=> e002000017038000002c8000009480000002766961206c756d696e61
=> e00200000d038000002c8000009480000002
<= 8636fa7a5a5bb9fe4fb2615f04425f54dc74c16fefc1325958c9719ee03ef5379000
=> e002000017038000002c8000009480000003766961206c756d696e61
=> e00200000d038000002c8000009480000003
<= 0f052ff4b74726a6f668380927c3d23e9c16d538cb6c272add871e069336bead9000
=> e002000017038000002c8000009480000004766961206c756d696e61
=> e00200000d038000002c8000009480000004
<= 60c75356c268ff0158eeca556526830761327693a93cf4754020fadbe04d0f2b9000
=> e002000017038000002c8000009480000005766961206c756d696e61
=> e00200000d038000002c8000009480000005
<= 124516f8ffb161c9492486e54b4432a2c11e4817414dea54fb8bde13b5ac49439000
`,
},
Expand Down
8 changes: 5 additions & 3 deletions libs/ledger-live-common/src/families/stellar/hw-getAddress.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import Stellar from "@ledgerhq/hw-app-str";
import type { Resolver } from "../../hw/getAddress/types";
import { StrKey } from "@stellar/stellar-sdk";

const resolver: Resolver = async (transport, { path, verify }) => {
const stellar = new Stellar(transport);
const r = await stellar.getPublicKey(path, false, verify);
const { rawPublicKey } = await stellar.getPublicKey(path, verify);
const publicKey = StrKey.encodeEd25519PublicKey(rawPublicKey);
return {
path,
address: r.publicKey,
publicKey: r.raw.toString("hex"),
address: publicKey,
publicKey: rawPublicKey.toString("hex"),
};
};

Expand Down
15 changes: 15 additions & 0 deletions libs/ledgerjs/packages/hw-app-str/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# @ledgerhq/hw-app-str

## 7.0.0

### Major Changes

- `Str.getPublicKey`'s function signature has changed. Previously, it was `getPublicKey(path: string, boolValidate?: boolean, boolDisplay?: boolean): Promise<{ publicKey: string; raw: Buffer; }>` and now it is `async getPublicKey(path: string, display = false): Promise<{ rawPublicKey: Buffer }>`
- `Str.signTransaction` will no longer automatically fallback to `Str.signHash`. If you want to sign a hash, you have to call `Str.signHash` directly.
- Removed the fixed limit on the maximum length of the transaction in `Str.signTransaction`. Currently, if the transaction is too large for the device to handle, `StellarUserRefusedError` will be thrown.
- Add `Str.signSorobanAuthorization` method to sign Stellar Soroban authorization.
- `Str.getAppConfiguration` now returns `maxDataSize`, it represents the maximum size of the data that the device can processed.
- Add error classes for better error handling, check the documentation for more information:
- `StellarUserRefusedError`
- `StellarHashSigningNotEnabledError`
- `StellarDataTooLargeError`
- `StellarDataParsingFailedError`

## 6.28.6

### Patch Changes
Expand Down
218 changes: 161 additions & 57 deletions libs/ledgerjs/packages/hw-app-str/README.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,174 @@
<img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />

## Ledger Stellar app API
[GitHub](https://github.com/LedgerHQ/ledger-live/),
[Ledger Devs Discord](https://developers.ledger.com/discord-pro),
[Developer Portal](https://developers.ledger.com/)

## Usage
## @ledgerhq/hw-app-str

Ledger Hardware Wallet Stellar JavaScript bindings.

```js
// when using "@ledgerhq/hw-transport-node-hid" library you need to go to
// Settings -> Browser support in ledger stellar app and set this setting to 'No'
import Transport from "@ledgerhq/hw-transport-node-hid";
// import Transport from "@ledgerhq/hw-transport-u2f"; // for browser
import Str from "@ledgerhq/hw-app-str";
import * as StellarSdk from "@stellar/stellar-sdk";

const getStrAppVersion = async () => {
const transport = await Transport.create();
const str = new Str(transport);
const result = await str.getAppConfiguration();
return result.version;
}
getStrAppVersion().then(v => console.log(v));

const getStrPublicKey = async () => {
const transport = await Transport.create();
const str = new Str(transport);
const result = await str.getPublicKey("44'/148'/0'");
return result.publicKey;
};
let publicKey;
getStrPublicKey().then(pk => {
console.log(pk);
publicKey = pk;
});

const signStrTransaction = async (publicKey) => {
const transaction = new StellarSdk.TransactionBuilder({accountId: () => publicKey, sequenceNumber: () => '1234', incrementSequenceNumber: () => null})
.addOperation(StellarSdk.Operation.createAccount({
source: publicKey,
destination: 'GBLYVYCCCRYTZTWTWGOMJYKEGQMTH2U3X4R4NUI7CUGIGEJEKYD5S5OJ', // SATIS5GR33FXKM7HVWZ2UQO33GM66TVORZUEF2HPUQ3J7K634CTOAWQ7
startingBalance: '11.331',
}))
.build();
const transport = await Transport.create();
const str = new Str(transport);
const result = await str.signTransaction("44'/148'/0'", transaction.signatureBase());

// add signature to transaction
const keyPair = StellarSdk.Keypair.fromPublicKey(publicKey);
const hint = keyPair.signatureHint();
const decorated = new StellarSdk.xdr.DecoratedSignature({hint: hint, signature: result.signature});
transaction.signatures.push(decorated);

return transaction;
}
signStrTransaction(publicKey).then(transaction => console.log(transaction.toEnvelope().toXDR().toString('base64')));
```

---
***

## Are you adding Ledger support to your software wallet?

You may be using this package to communicate with the Stellar Nano App.

For a smooth and quick integration:

- See the developers’ documentation on the [Developer Portal](https://developers.ledger.com/docs/transport/overview/) and
- Go on [Discord](https://developers.ledger.com/discord-pro/) to chat with developer support and the developer community.
* See the developers’ documentation on the [Developer Portal](https://developers.ledger.com/docs/transport/overview/) and
* Go on [Discord](https://developers.ledger.com/discord-pro/) to chat with developer support and the developer community.

***

## Errors handling

All functions may throw an error, it's important to handle the errors properly.

We have written corresponding classes for exceptions that developers should actively handle, you can find them in the [API](#api) section.

***

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

#### Table of Contents

* [StellarHashSigningNotEnabledError](#stellarhashsigningnotenablederror)
* [StellarDataParsingFailedError](#stellardataparsingfailederror)
* [StellarUserRefusedError](#stellaruserrefusederror)
* [StellarDataTooLargeError](#stellardatatoolargeerror)
* [Str](#str)
* [Parameters](#parameters)
* [Examples](#examples)
* [getAppConfiguration](#getappconfiguration)
* [Examples](#examples-1)
* [getPublicKey](#getpublickey)
* [Parameters](#parameters-1)
* [Examples](#examples-2)
* [signTransaction](#signtransaction)
* [Parameters](#parameters-2)
* [Examples](#examples-3)
* [signSorobanAuthorization](#signsorobanauthorization)
* [Parameters](#parameters-3)
* [Examples](#examples-4)
* [signHash](#signhash)
* [Parameters](#parameters-4)
* [Examples](#examples-5)

### StellarHashSigningNotEnabledError

Error thrown when hash signing is not enabled on the device.

### StellarDataParsingFailedError

Error thrown when data parsing fails.

For example, when parsing the transaction fails, this error is thrown.

### StellarUserRefusedError

Error thrown when the user refuses the request on the device.

### StellarDataTooLargeError

Error thrown when the data is too large to be processed by the device.

### Str

Stellar API

#### Parameters

* `transport` **Transport** a transport for sending commands to a device
* `scrambleKey` a scramble key (optional, default `"l0v"`)

#### Examples

```javascript
import Str from "@ledgerhq/hw-app-str";
const str = new Str(transport)
```

#### getAppConfiguration

Get Stellar application configuration.

##### Examples

```javascript
str.getAppConfiguration().then(o => o.version)
```

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), hashSigningEnabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), maxDataSize: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?}>** an object with the application configuration, including the version,
whether hash signing is enabled, and the maximum data size in bytes that the device can sign.

#### getPublicKey

Get Stellar raw public key for a given BIP 32 path.

##### Parameters

* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP 32 format
* `display` if true, the device will ask the user to confirm the address on the device, if false, it will return the raw public key directly (optional, default `false`)

##### Examples

```javascript
str.getPublicKey("44'/148'/0'").then(o => o.rawPublicKey)
```

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{rawPublicKey: [Buffer](https://nodejs.org/api/buffer.html)}>** an object with the raw ed25519 public key.
If you want to convert it to string, you can use [StrKey.encodeEd25519PublicKey](https://stellar.github.io/js-stellar-base/StrKey.html#.encodeEd25519PublicKey)

#### signTransaction

Sign a Stellar transaction.

##### Parameters

* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP 32 format
* `transaction` **[Buffer](https://nodejs.org/api/buffer.html)** [signature base](https://stellar.github.io/js-stellar-base/Transaction.html#signatureBase) of the transaction to sign

##### Examples

```javascript
str.signTransaction("44'/148'/0'", signatureBase).then(o => o.signature)
```

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{signature: [Buffer](https://nodejs.org/api/buffer.html)}>** an object with the signature

#### signSorobanAuthorization

Sign a Stellar Soroban authorization.

##### Parameters

* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP 32 format
* `hashIdPreimage` **[Buffer](https://nodejs.org/api/buffer.html)** the [Soroban authorization hashIdPreimage](https://github.com/stellar/stellar-xdr/blob/1a04392432dacc0092caaeae22a600ea1af3c6a5/Stellar-transaction.x#L702-L709) to sign

##### Examples

```javascript
str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage).then(o => o.signature)
```

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{signature: [Buffer](https://nodejs.org/api/buffer.html)}>** an object with the signature

#### signHash

Sign a hash.

##### Parameters

* `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a path in BIP 32 format
* `hash` **[Buffer](https://nodejs.org/api/buffer.html)** the hash to sign

##### Examples

```javascript
str.signHash("44'/148'/0'", hash).then(o => o.signature)
```

---
Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{signature: [Buffer](https://nodejs.org/api/buffer.html)}>** an object with the signature
8 changes: 4 additions & 4 deletions libs/ledgerjs/packages/hw-app-str/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ledgerhq/hw-app-str",
"version": "6.28.6",
"version": "7.0.0",
"description": "Ledger Hardware Wallet Stellar Application API",
"keywords": [
"Ledger",
Expand Down Expand Up @@ -28,9 +28,8 @@
"license": "Apache-2.0",
"dependencies": {
"@ledgerhq/hw-transport": "workspace:^",
"base32.js": "^0.1.0",
"sha.js": "^2.3.6",
"tweetnacl": "^1.0.3"
"@ledgerhq/errors": "workspace:^",
"bip32-path": "^0.4.2"
},
"devDependencies": {
"@ledgerhq/hw-transport-mocker": "workspace:^",
Expand All @@ -48,6 +47,7 @@
"build": "tsc && tsc -m ES6 --outDir lib-es",
"prewatch": "pnpm build",
"watch": "tsc --watch",
"doc": "documentation readme src/** --section=API --pe ts --re ts --re d.ts",
"lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx --cache",
"lint:fix": "pnpm lint --fix",
"test": "jest",
Expand Down
Loading

0 comments on commit 782d637

Please sign in to comment.