Skip to content

Commit

Permalink
Upgrade Ledger library and allow setting it up so no blind transactio…
Browse files Browse the repository at this point in the history
…n is allowed
  • Loading branch information
earrietadev committed Sep 17, 2024
1 parent 884ae23 commit cca2641
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 21 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
"@datorama/akita-ng-router-store": "^7.0.0",
"@keystonehq/animated-qr-base": "^0.0.1",
"@keystonehq/keystone-sdk": "^0.7.2",
"@ledgerhq/hw-app-str": "^6.27.11",
"@ledgerhq/hw-transport-webusb": "^6.27.11",
"@ledgerhq/hw-app-str": "^7.0.2",
"@ledgerhq/hw-transport-webusb": "^6.29.2",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0",
"@swimlane/ngx-charts": "^20.1.2",
Expand Down
22 changes: 13 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions src/app/core/services/hardware-wallets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { BehaviorSubject, firstValueFrom } from 'rxjs';
// @ts-ignore
import transformTransaction from 'trezor-connect/lib/plugins/stellar/plugin';
import { filter, take } from 'rxjs/operators';
import { FeeBumpTransaction, Transaction } from 'stellar-sdk';
import { FeeBumpTransaction, StrKey, Transaction } from 'stellar-sdk';
import { SettingsQuery } from '~root/state';

@Injectable({
providedIn: 'root'
Expand All @@ -17,6 +18,7 @@ export class HardwareWalletsService {

constructor(
private readonly stellarSdkService: StellarSdkService,
private readonly settingsQuery: SettingsQuery,
) {
this.configureTrezorLibrary().then(() => {
console.log('Trezor connected');
Expand Down Expand Up @@ -46,21 +48,20 @@ export class HardwareWalletsService {
const finalTransport = !!transport ? transport : (await TransportWebUSB.create());
const str = new Str(finalTransport);
const result = await str.getPublicKey(path);
return result.publicKey;
return StrKey.encodeEd25519PublicKey(result.rawPublicKey);
}

async signWithLedger(data: {
accountPath: string;
publicKey: string;
transaction: Transaction | FeeBumpTransaction;
transport: TransportWebUSB;
blindTransaction?: boolean;
}): Promise<IHWSigningResult> {
const str = new Str(data.transport);
const appConfiguration = await str.getAppConfiguration();
const blockBlindLedgerTransactions = await firstValueFrom(this.settingsQuery.blockBlindLedgerTransactions$);

// I know that the ledger can get a signatureBase with 1540 length
// But I have received issues even with ~1400 long signatures, so we use a hash method if 1000 is reached
const result = data.transaction.signatureBase().length < 1000 && !data.blindTransaction
const result = (data.transaction.signatureBase().length < (appConfiguration.maxDataSize || 1000)) || blockBlindLedgerTransactions
? await str.signTransaction(data.accountPath, data.transaction.signatureBase())
: await str.signHash(data.accountPath, data.transaction.hash());

Expand Down
5 changes: 1 addition & 4 deletions src/app/core/services/signing/signing.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,7 @@ export class SigningService {
transaction: params.target,
accountPath: params.selectedAccount.path,
publicKey: params.selectedAccount.publicKey,
transport,
blindTransaction: params.target instanceof FeeBumpTransaction
? !!params.target.innerTransaction.operations.find(o => o.type === 'invokeHostFunction')
: !!params.target.operations.find(o => o.type === 'invokeHostFunction'),
transport
});

params.target.addSignature(result.publicKey, result.signature);
Expand Down
4 changes: 4 additions & 0 deletions src/app/core/settings/services/settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export class SettingsService {
this.settingsStore.updateState({ defaultFee: value });
}

setBlockBlindLedgerTransactionsStatus(status: SettingsState['blockBlindLedgerTransactions']): void {
this.settingsStore.updateState({ blockBlindLedgerTransactions: status });
}

getRecommendedFee(): Observable<string> {
this.settingsStore.updateUIState({ gettingRecommendedFee: true });

Expand Down
11 changes: 11 additions & 0 deletions src/app/modules/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@
</div>
</nz-list-item>

<nz-list-item class="px-4">
<div class="w-8/12">
<p class="m-0 text-sm font-bold">
{{ 'SETTINGS.SETTINGS_DASHBOARD.BLIND_LEDGER_TXS' | translate }}
</p>
</div>
<div class="w-auto">
<nz-switch [formControl]="blockBlindLedgerTransactionsControl"></nz-switch>
</div>
</nz-list-item>

<nz-list-item *ngIf="advanceMode$ | async" class="cursor-pointer px-4" routerLink="/settings/active-operations-types">
<div class="w-8/12">
<p class="m-0 text-sm font-bold">
Expand Down
17 changes: 17 additions & 0 deletions src/app/modules/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export class SettingsComponent implements OnInit, OnDestroy {

languageSelectControl: UntypedFormControl = new UntypedFormControl('', [Validators.required]);

blockBlindLedgerTransactionsControl: UntypedFormControl = new UntypedFormControl(false);
blockBlindLedgerTransactions$: Observable<boolean> = this.settingsQuery.blockBlindLedgerTransactions$;

constructor(
private readonly settingsQuery: SettingsQuery,
private readonly settingsService: SettingsService,
Expand Down Expand Up @@ -83,6 +86,20 @@ export class SettingsComponent implements OnInit, OnDestroy {
this.settingsService.setAdvanceModeStatus(value);
});

blockBlindLedgerTransactionsStateSubscription: Subscription = this.blockBlindLedgerTransactions$
.pipe(takeUntil(this.componentDestroyed$))
.subscribe(mode => {
this.blockBlindLedgerTransactionsControl.patchValue(mode, {
emitEvent: false,
});
});

blockBlindLedgerTransactionsUpdateSubscription: Subscription = this.blockBlindLedgerTransactionsControl.valueChanges
.pipe(takeUntil(this.componentDestroyed$))
.subscribe(value => {
this.settingsService.setBlockBlindLedgerTransactionsStatus(value);
});

setLanguageSubscription: Subscription = this.languageSelectControl.valueChanges
.pipe(takeUntil(this.componentDestroyed$))
.subscribe(value => {
Expand Down
2 changes: 2 additions & 0 deletions src/app/state/settings.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export class SettingsQuery extends Query<SettingsState> {

counterAssetId$ = this.select(state => state.counterAssetId);

blockBlindLedgerTransactions$ = this.select(state => state.blockBlindLedgerTransactions);

constructor(protected store: SettingsStore) {
super(store);
}
Expand Down
9 changes: 9 additions & 0 deletions src/app/state/settings.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ export interface SettingsState {
// This is to use an asset as the base price
// Default values are USDC on both testnet and pubnet
counterAssetId: IWalletAssetModel['_id'];

// Hardware wallet global configurations

/**
* Ledger allows blind signing transactions, the oldest model from ledger requires that the XDR string is lower than a certain amount of characters because otherwise it throws an error
* If this is enabled, even those cases where xBull thinks a ledger device could fail it will still try a regular non-blind transaction
*/
blockBlindLedgerTransactions: boolean;
}

export function createInitialState(): SettingsState {
Expand Down Expand Up @@ -90,6 +98,7 @@ export function createInitialState(): SettingsState {
'liquidity_pool_withdraw',
],
counterAssetId: 'native',
blockBlindLedgerTransactions: false,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
"HORIZON_APIS": "Horizon APIs",
"LANGUAGE_TITLE": "Language",
"DEFAULT_FEE_TITLE": "Default fee",
"BLIND_LEDGER_TXS": "Prevent blind Ledger signing",
"ACTIVE_OPERATIONS_TYPES": "Active operation types",
"SITES_CONNECTED": "Sites connected",
"ANTI_SPAM": "Anti SPAM",
Expand Down

0 comments on commit cca2641

Please sign in to comment.