View on GitHub
File Changes
m
+8/-1

                      
### Features

                      
+
- Integrated Cardano V2 API endpoints ([PR 1548](https://github.com/input-output-hk/daedalus/pull/1548), [PR 1551](https://github.com/input-output-hk/daedalus/pull/1551), [PR 1552](https://github.com/input-output-hk/daedalus/pull/1552), [PR 1553](https://github.com/input-output-hk/daedalus/pull/1553), [PR 1555](https://github.com/input-output-hk/daedalus/pull/1555), [PR 1556](https://github.com/input-output-hk/daedalus/pull/1556), [PR 1557](https://github.com/input-output-hk/daedalus/pull/1557), [PR 1558](https://github.com/input-output-hk/daedalus/pull/1558), [PR 1559](https://github.com/input-output-hk/daedalus/pull/1559))
+
- Removed select dropdown arrow ([PR 1550](https://github.com/input-output-hk/daedalus/pull/1550))
- Implemented automated and manual update flows unification ([PR 1491](https://github.com/input-output-hk/daedalus/pull/1491))
- Updated behavior of system dialogs ([PR 1494](https://github.com/input-output-hk/daedalus/pull/1494))
- Implemented the new "Wallet Creation" process ([PR 1499](https://github.com/input-output-hk/daedalus/pull/1499), [PR 1515](https://github.com/input-output-hk/daedalus/pull/1515), [PR 1530](https://github.com/input-output-hk/daedalus/issues/1530))

                      
### Fixes

                      
+
- Fixed UI issues across different app themes ([PR 1547](https://github.com/input-output-hk/daedalus/pull/1547))
- Fixed minor UI issues on the "Delegation center" screen and "Delegation setup" wizard ([PR 1545](https://github.com/input-output-hk/daedalus/pull/1545))
- Fixed "White" theme styles ([PR 1532](https://github.com/input-output-hk/daedalus/pull/1532))
- Removed tooltip on Diagnostics Screen connection error message ([PR 1535](https://github.com/input-output-hk/daedalus/pull/1535))

                      
### Chores

                      
+
<<<<<<< HEAD
- Integration of the V2 API ([PR 1557](https://github.com/input-output-hk/daedalus/pull/1557), [PR 1558](https://github.com/input-output-hk/daedalus/pull/1558), [PR 1559](https://github.com/input-output-hk/daedalus/pull/1559), [PR 1560](https://github.com/input-output-hk/daedalus/pull/1560))
+
=======
+
- Use improved `NumericInput` component of `React-Polymorph` v0.9.0 ([1511](https://github.com/input-output-hk/daedalus/pull/1511))
+
>>>>>>> chore/ddw-876-get-wallet-utxo-statistics-v2-api-integration
- Added minimum heights of main app window for different environments (Windows, Linux, MacOS) ([1485](https://github.com/input-output-hk/daedalus/pull/1485))
- Removed "Ada Redemption" feature ([PR 1510](https://github.com/input-output-hk/daedalus/pull/1510))
- Changed `themes:check` to `themes:check:createTheme` and added a 4 part "Theme Management in Daedalus" tutorial series to a README document in the themes directory ([PR 1525](https://github.com/input-output-hk/daedalus/pull/1525))
### Chore

                      
- Updated to react-router v4
-
- Testing setup with cucumber & spectron
\ No newline at end of file
+
- Testing setup with cucumber & spectron
      | title          | amount         |
      | my transaction | <WRONG_AMOUNT> |
    Then I should see the following error messages on the wallet send form:
-
      | message                               |
-
      | wallet.send.form.errors.invalidAmount |
+
      | message |
+
      | <ERROR> |

                      
    Examples:
-
      | WRONG_AMOUNT |
-
      | 45000000001  |
-
      | 0            |
+
      | WRONG_AMOUNT | ERROR                                        |
+
      | 99999999     | api.errors.NotEnoughFundsForTransactionError |
+
      | 0            | wallet.send.form.errors.invalidAmount        |

                      
When(/^I select Japanese language$/, function() {
  return this.waitAndClick(
-
    '//*[@class="SimpleOptions_label"][contains(text(), "Japanese")]'
+
    '//*[@class="SimpleOptions_option"]//*[contains(text(), "Japanese")]'
  );
});

                      

                      
When(/^I select "Strict" assurance level$/, function() {
  return this.waitAndClick(
-
    '//*[@class="SimpleOptions_label"][contains(text(), "Strict")]'
+
    '//*[@class="SimpleOptions_option"]//*[contains(text(), "Strict")]'
  );
});

                      
m
+1/-1
    "react-lottie": "1.2.3",
    "react-markdown": "3.1.0",
    "react-number-format": "3.0.3",
-
    "react-polymorph": "0.8.7",
+
    "react-polymorph": "0.9.0-rc.15",
    "react-router": "3.2.1",
    "react-svg-inline": "2.1.0",
    "react-virtualized": "9.21.0",
  closeCertificateGeneration: Action<any> = new Action();
  setCertificateTemplate: Action<{ selectedTemplate: string }> = new Action();
  finishCertificate: Action<any> = new Action();
+
  getWallet: Action<{ walletId: string }> = new Action();
}
import { restoreWallet } from './wallets/requests/restoreWallet';
import { updateWallet } from './wallets/requests/updateWallet';
import { getWalletUtxos } from './wallets/requests/getWalletUtxos';
+
import { getWallet } from './wallets/requests/getWallet';

                      
// utility functions
import {
  ImportWalletFromFileRequest,
  UpdateWalletRequest,
  GetWalletUtxosRequest,
+
  GetWalletRequest,
} from './wallets/types';

                      
// Common errors
    }
  };

                      
+
  getWallet = async (request: GetWalletRequest): Promise<Wallet> => {
+
    Logger.debug('AdaApi::getWallet called', {
+
      parameters: filterLogData(request),
+
    });
+
    try {
+
      const { walletId } = request;
+
      const wallet: AdaWallet = await getWallet(this.config, { walletId });
+
      Logger.debug('AdaApi::getWallet success', { wallet });
+
      return _createWalletFromServerData(wallet);
+
    } catch (error) {
+
      Logger.error('AdaApi::getWallet error', { error });
+
      throw new GenericApiError();
+
    }
+
  };
+

                      
  getAddresses = async (
    request: GetAddressesRequest
  ): Promise<GetAddressesResponse> => {

                      
      Logger.debug('AdaApi::getAddresses success', { addresses: response });
      const addresses = response.map(_createAddressFromServerData);
-

                      
      return new Promise(resolve => resolve({ accountIndex: 0, addresses }));
    } catch (error) {
      Logger.error('AdaApi::getAddresses error', { error });
  },
};

                      
+
const ALLOWED_ERROR_EXCEPTION_PATHS = [
+
  '/api/internal/next-update', // when nextAdaUpdate receives a 404, it isn't an error
+
];
+

                      
function typedRequest<Response>(
  httpOptions: RequestOptions,
  queryParams?: {},
  rawBodyParams?: any
  // requestOptions?: { returnMeta: boolean }
): Promise<Response> {
  return new Promise((resolve, reject) => {
-
    const allowedErrorExceptionPaths = [
-
      '/api/internal/next-update', // when nextAdaUpdate receives a 404, it isn't an error
-
    ];
    const options: RequestOptions = Object.assign({}, httpOptions);
    // const { returnMeta } = Object.assign({}, requestOptions);
    let hasRequestBody = false;
    }

                      
    // @API TODO:  Delete once HTTPS is supported by the new API
-
    const httpOnlyOptions = {
-
      ...options,
-
      hostname: options.hostname,
-
      method: options.method,
-
      path: options.path,
-
      port: options.port,
-
    };
+
    const httpOnlyOptions = omit(options, ['ca', 'cert', 'key']);

                      
    // @API TODO: Uncomment / switch once HTTPS is supported by the new API
    // const httpsRequest = global.https.request(options);
      response.on('end', () => {
        try {
          const { statusCode, statusMessage } = response;
-
          const successResponse =
+
          const isSuccessResponse =
            (statusCode >= 200 && statusCode <= 206) ||
            (statusCode === 404 &&
-
              includes(allowedErrorExceptionPaths, options.path));
+
              includes(ALLOWED_ERROR_EXCEPTION_PATHS, options.path));

                      
-
          if (successResponse) {
+
          if (isSuccessResponse) {
            const data =
              statusCode === 404
                ? 'null'
            }
            resolve(JSON.parse(body));
          } else if (body) {
+
            // Error response with a body
            const parsedBody = JSON.parse(body);
            if (parsedBody.code && parsedBody.message) {
              reject(parsedBody);
            } else {
-
              // TODO: find a way to record this case and report to the backend team
-
              reject(new Error('Unknown response from backend.'));
+
              reject(new Error('Unknown API response'));
            }
          } else {
-
            // TODO: find a way to record this case and report to the backend team
-
            reject(new Error('Unknown response from backend.'));
+
            // Error response without a body
+
            reject(new Error('Unknown API response'));
          }
        } catch (error) {
          // Handle internal server errors (e.g. HTTP 500 - 'Something went wrong')
+
// @flow
+
import type { RequestConfig } from '../../common/types';
+
import type { GetWalletRequest, AdaWallet } from '../types';
+
import { request } from '../../utils/request';
+

                      
+
export const getWallet = (
+
  config: RequestConfig,
+
  { walletId }: GetWalletRequest
+
): Promise<AdaWallet> =>
+
  request({
+
    method: 'GET',
+
    path: `/v2/wallets/${walletId}`,
+
    ...config,
+
  });
  request(
    {
      method: 'PUT',
-
      path: `/api/v1/wallets/${walletId}`,
+
      path: `/v2/wallets/${walletId}`,
      ...config,
    },
    {},
  passphrase: string,
  scrambledInput: string,
};
+

                      
+
export type GetWalletRequest = {
+
  walletId: string,
+
};

                      
  a {
    @include link(--theme-system-error-overlay-support-link-icon-color);
-
    border-bottom: 2px solid var(--theme-system-error-overlay-text-color);
+
    border-bottom: 1px solid var(--theme-system-error-overlay-text-color);
    color: var(--theme-system-error-overlay-text-color);
  }

                      
import classnames from 'classnames';
import { observer } from 'mobx-react';
import SVGInline from 'react-svg-inline';
-
import humanizeDuration from 'humanize-duration';
import { defineMessages, intlShape } from 'react-intl';
import spinnerIcon from '../../assets/images/spinner-dark.inline.svg';
import styles from './RestoreNotification.scss';
});

                      
type Props = {
-
  currentLocale: string,
  restoreProgress: number,
-
  restoreETA: number,
};

                      
@observer

                      
  render() {
    const { intl } = this.context;
-
    const { currentLocale, restoreProgress, restoreETA } = this.props;
+
    const { restoreProgress } = this.props;

                      
    const restoreNotificationClasses = classnames([
      styles.component,
      'ActiveRestoreNotification',
    ]);

                      
-
    let humanizedDurationLanguage;
-
    switch (currentLocale) {
-
      case 'ja-JP':
-
        humanizedDurationLanguage = 'ja';
-
        break;
-
      case 'zh-CN':
-
        humanizedDurationLanguage = 'zh_CN';
-
        break;
-
      case 'ko-KR':
-
        humanizedDurationLanguage = 'ko';
-
        break;
-
      case 'de-DE':
-
        humanizedDurationLanguage = 'de';
-
        break;
-
      default:
-
        humanizedDurationLanguage = 'en';
-
    }
-

                      
-
    const estimatedCompletionTime = humanizeDuration(restoreETA, {
-
      round: true, // round seconds to prevent e.g. 1 day 3 hours *11,56 seconds*
-
      language: humanizedDurationLanguage,
-
    });
-

                      
    return (
      <div className={restoreNotificationClasses}>
        <span className={styles.text}>
          {intl.formatMessage(messages.activeRestoreMessage)}: {restoreProgress}
-
          % ({estimatedCompletionTime})
+
          %
        </span>
        <SVGInline svg={spinnerIcon} className={styles.icon} />
      </div>
}

                      
.submitButton {
-
  background: none !important;
+
  background-color: var(--theme-data-migration-layer-button-background-color);
  border: solid 1px var(--theme-data-migration-button-border-color) !important;
  color: var(--theme-data-migration-button-label-color) !important;
  line-height: 1.36 !important;
    background: var(
      --theme-data-migration-layer-button-background-color-hover
    ) !important;
-
    color: var(--theme-data-migration-layer-background-color) !important;
+
    color: var(--theme-data-migration-layer-text-color-hover) !important;
  }
}

                      

                      
  .description {
    @extend %regularText;
+
    color: var(--theme-staking-font-color-light);
    margin-bottom: 24px;
  }

                      
        opacity: 0.5;
      }
    }
+

                      
+
    :global {
+
      .SimpleOptions_option {
+
        padding: 8px 20px;
+
      }
+
    }
  }
}
      font-size: 16px;
      font-weight: 500;
      line-height: 1.38;
-
      margin-bottom: 20px;
+
      margin-bottom: 0;
      .feesLabel {
        color: var(--theme-delegation-steps-confirmation-fees-label-color);
        margin-bottom: 6px;
        word-break: break-all;

                      
        .stakePoolReference {
-
          color: var(--theme-staking-table-body-highlighted-text-color);
+
          color: var(--theme-staking-font-color-regular);
          font-family: var(--font-medium);
        }
      }

                      
.description {
  @extend %regularText;
+
  color: var(--theme-staking-font-color-light);
  margin-bottom: 24px;
}

                      
      font-family: var(--font-medium);
      font-size: 14px;
      &:hover {
-
        color: var(--theme-staking-font-color);
+
        color: var(--theme-staking-font-color-light);
      }
    }
  }
Diff too large – View on GitHub