Skip to content

Implement wallet service

Responses

1. Token transactions table

(USD transactions will likely be similar in structure but still need final UX mockup to be sure)

It's fine to calculate running total on client side. If that's how we're going to do it, then tx diffs should have 18 decimals.

Response structure I want (WIP!!!)

token_transactions: {
    filters: [
      {
        id: 'transaction_types',
        label: 'Transaction Types',
        options: [
          {
            id: 'all',
            label: 'All',
            selected: true,
          },
          {
            id: 'offchain_wire',
            label: 'Off-Chain Wire',
            selected: false,
          },
          {
            id: 'onchain_wire',
            label: 'On-Chain Wire',
            selected: false,
          },
          {
            id: 'rewards',
            label: 'Rewards',
            selected: false,
          },
          {
            id: 'purchases',
            label: 'Purchases',
            selected: false,
          },
          {
            id: 'boost',
            label: 'Boost',
            selected: false,
          },
          {
            id: 'onchain_transfer',
            label: 'On-Chain Transfer',
            selected: false,
          },
        ],
      },
    ],
// Never mind I can just get pending elsewhere    
// pending: {
      // total_points: 7,
      // contributions: [
        // { id: 'checkins', label: 'Check-ins', occurrences: 1, points: 2 },
        // { id: 'comments', label: 'Comments', occurrences: 2, points: 4 },
        // { id: 'votes', label: 'Votes', occurrences: 1, points: 1 },
      // ],
    // },
    days: [
      {
        ts_ms: 1567296000000, // today's date
        transactions: [
          {
            ts_ms: 1567296000090, // time of tx
            type_id: 'boosts',
            type_label: 'Boosts',
            diff: -5.000000000000000000, // if we calc running total on client side then the diffs should not be rounded to 3 decimals
            running_total: 25.0,
          },
          {
            ts_ms: 1567296000080,
            type_id: 'rewards',
            type_label: 'Rewards',
            diff: 0.400000000000000000,
            running_total: 30.0,
            details: {
              total_points: 10,
              contributions: [
                {
                  id: 'checkins',
                  label: 'Check-ins',
                  occurrences: 4,
                  points: 8,
                },
                { id: 'comments', label: 'Comments', occurrences: 1, points: 2 },
              ],
            },
          },
          {
            ts_ms: 1567296000070,
            type_id: 'wires',
            type_label: 'Wires', // make sure we have the label field bc this eventually needs to change to 'Pay'
            diff: -1.5,
            running_total: 29.6,
            subtype_id: 'offchain_wires_outbound',
            entity: {
              user_guid: 123,
              username: 'my_wire_recipient',
              //...etc...
            },
          },
          {
            ts_ms: 1567296000060,
            type_id: 'wires',
            type_label: 'Wires',
            diff: 2.0,
            running_total: 30.1,
            subtype_id: 'offchain_wires_inbound',
            entity: {
              user_guid: 456,
              username: 'whoever_wired_me',
              //...etc...
            },
          },
        ],
      },
      {
        ts_ms: 1567295000000, // yesterday's date
        transactions: [
          {
            ts_ms: 1567295000090,
            type_id: 'purchases',
            type_label: 'Purchases',
            diff: -10.0,
            running_total: 28.1,
            subtype_id: 'minds_pro_membership',
          },
          {
            ts_ms: 1567295000080,
            type_id: 'rewards',
            type_label: 'Rewards',
            diff: 0.9,
            running_total: 38.1,
            details: {
              total_points: 50,
              contributions: [
                {
                  id: 'jury_duty',
                  label: 'Jury Duty',
                  occurrences: 2,
                  points: 50,
                },
              ],
            },
          },
        ],
      },
      // days go on...
    ],
    load_next: '',
    status: 'success',
  }

Transaction types

(need to see final UX mockup to be sure about this list)

  • Minds rewards
  • Boosts
  • Wires
  • Purchases
  • On-chain transfers
  • Subscriptions (?)

Minds rewards

  • Found in <m-wallet-token--contributions>
  • Api call looks like:
      let response: any = await this.client.get(
        `api/v2/blockchain/contributions`,
        {
          from: Math.floor(+startDate / 1000),
          to: Math.floor(+endDate / 1000),
        }
      );
  • Example response structure:
contributions: {
  0:  {
    amount:  2,
    metrics:  {
      checkins:  {
        amount:  "1",
        metric:  "checkins",
        score:  2,
        timestamp:  1573776000000,
        user:  "930229554033729554"
      },
      votes:  {
        amount:  "1",
        metric:  "votes",
        score:  1,
        timestamp:  1573776000000,
        user:  "930229554033729554"
      }
    },
    score:  3,
    share:  0.0025391236637861718,
    timestamp:  1573776000000
  },
  1: {
     ... etc...
  }, 
  2: {
     ...etc...
  },
  load-next:  "",
  status:  "success"
}

2. Tokens overview chart

Let's say the user has chosen the 30 day report:

selected_timespan: {
  id: '30d',
  label: '30D',
  interval: 'day',
  from_ts_ms: 1567296000000,
  from_ts_iso: '2019-09-01T00:00:00+00:00',
}

To draw the graph we need these buckets:

buckets: [
{
  key: 1567296000000,
  date: '2019-09-01T00:00:00+00:00',
  value: 11.123,
},
{
  key: 1567382400000,
  date: '2019-09-02T00:00:00+00:00',
  value: 12.456,
},
{
  key: 1567468800000,
  date: '2019-09-03T00:00:00+00:00',
  value: 13.789,
},
etc... ]
  • key: GMT unix timestamp in ms
  • date: GMT date in ISO8601 format
  • value: token value rounded to 3 decimal places

The selected interval shapes the buckets like so:

  • The key of the first bucket should equal selected_timespan.from_ts_ms
  • Interval between each bucket thereafter is determined by timespan.interval (currently we're only using only day & month but this might change)
  • Must consider how best to handle the 'Max' timespan (a.k.a. beginning of time - present)
Edited by Mark Harding