LedgerHQ/ledger-live-common

code reuse of "device validation" step

gre opened this issue · 2 comments

gre commented

For more code reuse and less questions / topic to synchronize between mobile and desktop, we should have every coin family to export a config of what the device display will look like for a given Transaction.

For instance, sometimes we have amount and fees, sometimes we have tron votes, etc.. etc...

on the UI side, we would just have to map this and switch to different component that implement the UI. By convention, they would correspond to transaction fields but it's up to UI to integrate how to render a field.

This solve two main things:

  • what fields the UI should displayed on device validation
  • what ordering of these fields

and it's best that it's the Coin Integration implementer (live-common) that define it based on exactly what happens on device.

BTW reminder that SEND is the only exception where we don't want to display addresses. basically because when you send to someone, you have picked from another place the address.

Spec proposal:

Each src/families/*/config.js would export a getDeviceTransactionConfig

that would be of

type DeviceTransactionField = {
  type: string,
  label: string,
}

export function getDeviceTransactionConfig({
  account: AccountLike,
  parentAccount: ?Account,
  transaction: Transaction,
  status: TransactionStatus,
}): Array<DeviceTransactionField>

[WIP] FOR DISCUSSION:

A more complex way would be to make DeviceTransactionField a enum type that is the union type of all families and having a clear field discriminator that is unique (id ?). that way we can include MORE data into this, not only having the id, label but also have all the data needed and prepared for the rendering side (like the value to display,..)

We might not want to do this first but let's discuss the pro and cons of such approach. having the type above and only that could be a first milestone good enough to at least solve the ordering + label duplication problem.

Example

// bitcoin will probably be as easy as
export function getDeviceTransactionConfig() {
  return [
    { type: "amount", label: "Amount" },
    { type: "fees", "label": "Network fees" }
  ]
}

but more advanced logic might do different things based on the transaction that is done. for instance switch on the transaction.mode.

gre commented

it’s not too hard to do:

getDeviceTransactionConfig(...).map(field => {
  switch (field.id) {
    case "amount": return 
    <Field label={field.label}>
      <Amount amount={tx.amount} />
    </field>
  }  
})

on ui side.
more generically we can have a map of { id=>ValueComponent } that we enrich from each family.
each ValueComponent is welcomed to picked into the transaction that would be passed in

so like

StellarMemo = ({ transaction }) => <Text ..>{transaction.extra.memo}</Text>
gre commented

work in progress and tracked internally.