+ class="{{item-status contribution}}{{if (eq contribution.id @selectedContributionId) " selected"}}">
({{contribution.kind}})
diff --git a/app/components/reimbursement-list/component.js b/app/components/reimbursement-list/component.js
new file mode 100644
index 0000000..75a5770
--- /dev/null
+++ b/app/components/reimbursement-list/component.js
@@ -0,0 +1,7 @@
+import Component from '@glimmer/component';
+import { sort } from '@ember/object/computed';
+
+export default class ReimbursementListComponent extends Component {
+ itemSorting = Object.freeze(['pendingStatus:asc', 'id:desc']);
+ @sort('args.items', 'itemSorting') itemsSorted;
+}
diff --git a/app/components/reimbursement-list/template.hbs b/app/components/reimbursement-list/template.hbs
new file mode 100644
index 0000000..37c8181
--- /dev/null
+++ b/app/components/reimbursement-list/template.hbs
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/app/components/topbar-account-panel/component.js b/app/components/topbar-account-panel/component.js
index d7ae8a4..ed1bcfb 100644
--- a/app/components/topbar-account-panel/component.js
+++ b/app/components/topbar-account-panel/component.js
@@ -34,7 +34,6 @@ export default Component.extend({
this.set('setupInProgress', true);
await this.kredits.setup();
this.set('setupInProgress', false);
- this.router.transitionTo('dashboard');
} catch (error) {
this.set('setupInProgress', false);
console.log('Opening Ethereum wallet failed:', error);
diff --git a/app/controllers/budget.js b/app/controllers/budget.js
new file mode 100644
index 0000000..f932b83
--- /dev/null
+++ b/app/controllers/budget.js
@@ -0,0 +1,10 @@
+import Controller from '@ember/controller';
+import { inject as service } from '@ember/service';
+import { alias } from '@ember/object/computed';
+
+export default class BudgetController extends Controller {
+ @service kredits;
+
+ @alias('kredits.reimbursementsUnconfirmed') reimbursementsUnconfirmed;
+ @alias('kredits.reimbursementsConfirmed') reimbursementsConfirmed;
+}
diff --git a/app/helpers/contribution-status.js b/app/helpers/contribution-status.js
deleted file mode 100644
index 959aa72..0000000
--- a/app/helpers/contribution-status.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import Helper from '@ember/component/helper';
-import { inject as service } from '@ember/service';
-import { alias } from '@ember/object/computed';
-import { once } from '@ember/runloop';
-
-export default Helper.extend({
-
- kredits: service(),
- currentBlock: alias('kredits.currentBlock'),
-
- compute([contribution]) {
- this.setupRecompute(contribution);
-
- let status = [];
-
- if (contribution.vetoed) {
- status.push('vetoed');
- } else if (contribution.confirmedAt > this.currentBlock) {
- status.push('unconfirmed');
- } else {
- status.push('confirmed');
- }
-
- if (contribution.hasPendingChanges) {
- status.push('pending');
- }
-
- return status.join(' ');
- },
-
- destroy () {
- if (this.teardown) this.teardown();
- this._super(...arguments);
- },
-
- setupRecompute (contribution) {
- if (this.teardown) this.teardown();
-
- contribution.addObserver('vetoed' , this, this.triggerRecompute);
- contribution.addObserver('confirmedAt' , this, this.triggerRecompute);
- contribution.addObserver('currentBlock' , this, this.triggerRecompute);
- contribution.addObserver('hasPendingChanges' , this, this.triggerRecompute);
-
- this.teardown = () => {
- contribution.removeObserver('vetoed', this, this.triggerRecompute);
- contribution.removeObserver('confirmedAt', this, this.triggerRecompute);
- contribution.removeObserver('currentBlock', this, this.triggerRecompute);
- contribution.removeObserver('hasPendingChanges', this, this.triggerRecompute);
- };
- },
-
- triggerRecompute () {
- once(this, this.recompute);
- }
-
-});
diff --git a/app/helpers/fmt-crypto-currency.js b/app/helpers/fmt-crypto-currency.js
new file mode 100644
index 0000000..76e47c4
--- /dev/null
+++ b/app/helpers/fmt-crypto-currency.js
@@ -0,0 +1,18 @@
+import { helper } from '@ember/component/helper';
+
+export default helper(function fmtCryptoCurrency(params/*, hash*/) {
+ let fmtAmount;
+ const amount = params[0];
+ const code = params[1];
+
+ switch(code) {
+ case 'ETH':
+ fmtAmount = amount / 1000000000000000000;
+ break;
+ case 'WBTC':
+ fmtAmount = amount / 100000000;
+ break;
+ }
+
+ return fmtAmount;
+});
diff --git a/app/helpers/fmt-fiat-currency.js b/app/helpers/fmt-fiat-currency.js
new file mode 100644
index 0000000..61f75dd
--- /dev/null
+++ b/app/helpers/fmt-fiat-currency.js
@@ -0,0 +1,11 @@
+import { helper } from '@ember/component/helper';
+
+export default helper(function fmtFiatCurrency(params) {
+ const lang = navigator.language || navigator.userLanguage;
+ const formatter = new Intl.NumberFormat(lang, {
+ style: 'currency',
+ currency: params[1] || 'EUR',
+ currencyDisplay: 'code'
+ })
+ return formatter.format(params[0]);
+});
diff --git a/app/helpers/item-status.js b/app/helpers/item-status.js
new file mode 100644
index 0000000..e86ee3f
--- /dev/null
+++ b/app/helpers/item-status.js
@@ -0,0 +1,56 @@
+import Helper from '@ember/component/helper';
+import { inject as service } from '@ember/service';
+import { alias } from '@ember/object/computed';
+import { once } from '@ember/runloop';
+
+export default Helper.extend({
+
+ kredits: service(),
+ currentBlock: alias('kredits.currentBlock'),
+
+ compute([item]) {
+ this.setupRecompute(item);
+
+ let status = [];
+
+ if (item.vetoed) {
+ status.push('vetoed');
+ } else if (item.confirmedAt > this.currentBlock) {
+ status.push('unconfirmed');
+ } else {
+ status.push('confirmed');
+ }
+
+ if (item.hasPendingChanges) {
+ status.push('pending');
+ }
+
+ return status.join(' ');
+ },
+
+ destroy () {
+ if (this.teardown) this.teardown();
+ this._super(...arguments);
+ },
+
+ setupRecompute (item) {
+ if (this.teardown) this.teardown();
+
+ item.addObserver('vetoed' , this, this.triggerRecompute);
+ item.addObserver('confirmedAt' , this, this.triggerRecompute);
+ item.addObserver('currentBlock' , this, this.triggerRecompute);
+ item.addObserver('hasPendingChanges' , this, this.triggerRecompute);
+
+ this.teardown = () => {
+ item.removeObserver('vetoed', this, this.triggerRecompute);
+ item.removeObserver('confirmedAt', this, this.triggerRecompute);
+ item.removeObserver('currentBlock', this, this.triggerRecompute);
+ item.removeObserver('hasPendingChanges', this, this.triggerRecompute);
+ };
+ },
+
+ triggerRecompute () {
+ once(this, this.recompute);
+ }
+
+});
diff --git a/app/helpers/sats-to-btc.js b/app/helpers/sats-to-btc.js
new file mode 100644
index 0000000..319004e
--- /dev/null
+++ b/app/helpers/sats-to-btc.js
@@ -0,0 +1,5 @@
+import { helper } from '@ember/component/helper';
+
+export default helper(function satsToBtc(amount/*, hash*/) {
+ return amount / 100000000;
+});
diff --git a/app/models/reimbursement.js b/app/models/reimbursement.js
new file mode 100644
index 0000000..ef56068
--- /dev/null
+++ b/app/models/reimbursement.js
@@ -0,0 +1,47 @@
+import EmberObject, { computed } from '@ember/object';
+import moment from 'moment';
+import { isPresent } from '@ember/utils';
+
+export default EmberObject.extend({
+
+ // Contract
+ id: null,
+ recipientId: null,
+ token: null,
+ amount: null,
+ confirmedAt: null,
+ vetoed: null,
+ ipfsHash: null,
+
+ // contributor model instance
+ recipient: null,
+
+ // TODO contributor who submitted the reimbursement
+ // recordedBy: null,
+
+ // IPFS
+ expenses: null, // Array of expense objects
+
+ pendingTx: null,
+
+ iso8601Date: computed('date', 'time', function() {
+ return this.time ? `${this.date}T${this.time}` : this.date;
+ }),
+
+ jsDate: computed('iso8601Date', function() {
+ return moment(this.iso8601Date).toDate();
+ }),
+
+ hasPendingChanges: computed('pendingTx', function() {
+ return isPresent(this.pendingTx);
+ }),
+
+ pendingStatus: computed('pendingTx', function() {
+ return isPresent(this.pendingTx) ? 'isPending' : 'notPending';
+ }),
+
+ serialize () {
+ return JSON.stringify(this);
+ }
+
+});
diff --git a/app/router.js b/app/router.js
index 578bb62..b0941de 100644
--- a/app/router.js
+++ b/app/router.js
@@ -29,4 +29,13 @@ Router.map(function() {
this.route('eth-account');
this.route('complete');
});
+ this.route('budget', function() {
+ this.route('expenses');
+
+ this.route('reimbursements', function() {});
+ });
+
+ this.route('reimbursements', function() {
+ this.route('new');
+ });
});
diff --git a/app/routes/application.js b/app/routes/application.js
index 92f0e9d..a7470a0 100644
--- a/app/routes/application.js
+++ b/app/routes/application.js
@@ -1,39 +1,37 @@
-import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
import { schedule } from '@ember/runloop';
-export default Route.extend({
- kredits: service(),
+export default class ApplicationRoute extends Route {
+ @service kredits;
+ @service communityFunds;
beforeModel(/* transition */) {
const kredits = this.kredits;
return kredits.setup().then(() => {
- kredits.get('kredits').preflightChecks().catch((error) => {
+ kredits.kredits.preflightChecks().catch((error) => {
console.error('Kredits preflight check failed!');
console.error(error);
});
}).catch((error) => {
console.log('Error initializing Kredits', error);
});
- },
+ }
+
+ model() {
+ return this.kredits.loadInitialData().then(() => {
+ this.kredits.addContractEventHandlers()
+ });
+ }
afterModel() {
- return this.kredits.loadInitialData()
- .then(() => {
- this.kredits.addContractEventHandlers();
- })
- .then(() => {
- if (this.kredits.contributorsNeedSync) {
- schedule('afterRender', this.kredits.syncContributors,
- this.kredits.syncContributors.perform);
- }
- if (this.kredits.contributionsNeedSync) {
- schedule('afterRender', this.kredits.syncContributions,
- this.kredits.syncContributions.perform);
- }
- schedule('afterRender', this.kredits.fetchMissingContributions,
- this.kredits.fetchMissingContributions.perform);
- });
+ if (this.kredits.contributorsNeedSync) {
+ schedule('afterRender', this.kredits.syncContributors,
+ this.kredits.syncContributors.perform);
+ }
+
+ schedule('afterRender', this.communityFunds.fetchBalances,
+ this.communityFunds.fetchBalances.perform);
}
-});
+}
diff --git a/app/routes/budget.js b/app/routes/budget.js
new file mode 100644
index 0000000..c3d2f39
--- /dev/null
+++ b/app/routes/budget.js
@@ -0,0 +1,34 @@
+import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
+import { isEmpty, isPresent } from '@ember/utils';
+import { schedule } from '@ember/runloop';
+
+export default class BudgetRoute extends Route {
+ @service browserCache;
+ @service kredits;
+
+ async model () {
+ if (isPresent(this.kredits.reimbursements) &&
+ isEmpty(this.kredits.reimbursementsPending)) {
+ console.debug('[route:budget] Reimbursements loaded before, no need to sync or load');
+ return;
+ } else {
+ const numCachedReimbursements = await this.browserCache.reimbursements.length();
+ if (numCachedReimbursements > 0) {
+ await this.kredits.loadObjectsFromCache('Reimbursement');
+ this.kredits.set('reimbursementsNeedSync', true);
+ } else {
+ await this.kredits.fetchObjects('Reimbursement', { page: { size: 10 } });
+ }
+ }
+ }
+
+ afterModel() {
+ if (this.kredits.reimbursementsNeedSync) {
+ schedule('afterRender', this.kredits.syncReimbursements,
+ this.kredits.syncReimbursements.perform);
+ }
+ schedule('afterRender', this.kredits.fetchMissingReimbursements,
+ this.kredits.fetchMissingReimbursements.perform);
+ }
+}
diff --git a/app/routes/budget/expenses.js b/app/routes/budget/expenses.js
new file mode 100644
index 0000000..7eb9882
--- /dev/null
+++ b/app/routes/budget/expenses.js
@@ -0,0 +1,4 @@
+import Route from '@ember/routing/route';
+
+export default class BudgetExpensesRoute extends Route {
+}
diff --git a/app/routes/contributions/new.js b/app/routes/contributions/new.js
index 7d760ab..a3eb6a3 100644
--- a/app/routes/contributions/new.js
+++ b/app/routes/contributions/new.js
@@ -1,9 +1,9 @@
import Route from '@ember/routing/route';
-export default Route.extend({
+export default class ContributionsNewRoute extends Route {
model (params) {
return { params };
}
-});
+}
diff --git a/app/routes/dashboard.js b/app/routes/dashboard.js
new file mode 100644
index 0000000..a6b1d4e
--- /dev/null
+++ b/app/routes/dashboard.js
@@ -0,0 +1,18 @@
+import Route from '@ember/routing/route';
+import { schedule } from '@ember/runloop';
+import { inject as service } from '@ember/service';
+
+export default class DashboardRoute extends Route {
+
+ @service kredits;
+
+ afterModel() {
+ if (this.kredits.contributionsNeedSync) {
+ schedule('afterRender', this.kredits.syncContributions,
+ this.kredits.syncContributions.perform);
+ }
+ schedule('afterRender', this.kredits.fetchMissingContributions,
+ this.kredits.fetchMissingContributions.perform);
+ }
+
+}
diff --git a/app/routes/reimbursements/new.js b/app/routes/reimbursements/new.js
new file mode 100644
index 0000000..0e3509d
--- /dev/null
+++ b/app/routes/reimbursements/new.js
@@ -0,0 +1,9 @@
+import Route from '@ember/routing/route';
+
+export default class ReimbursementsNewRoute extends Route {
+
+ model (params) {
+ return { params };
+ }
+
+}
diff --git a/app/services/browser-cache.js b/app/services/browser-cache.js
index 29232dd..f6dc63a 100644
--- a/app/services/browser-cache.js
+++ b/app/services/browser-cache.js
@@ -13,7 +13,8 @@ export default class BrowserCacheService extends Service {
super(...arguments);
this.stores = {
contributors: createStore('contributors'),
- contributions: createStore('contributions')
+ contributions: createStore('contributions'),
+ reimbursements: createStore('reimbursements')
}
}
@@ -24,4 +25,8 @@ export default class BrowserCacheService extends Service {
get contributions() {
return this.stores.contributions;
}
+
+ get reimbursements() {
+ return this.stores.reimbursements;
+ }
}
diff --git a/app/services/community-funds.js b/app/services/community-funds.js
new file mode 100644
index 0000000..2d9f0f3
--- /dev/null
+++ b/app/services/community-funds.js
@@ -0,0 +1,45 @@
+import Service from '@ember/service';
+import { tracked } from '@glimmer/tracking';
+import { A } from '@ember/array';
+import { task } from 'ember-concurrency-decorators';
+import config from 'kredits-web/config/environment';
+
+const txServiceBaseUrl = `${config.gnosisSafe.txServiceHost}/api/v1/safes/${config.gnosisSafe.address}`;
+
+export default class CommunityFundsService extends Service {
+ @tracked balancesLoaded = false;
+ @tracked balances = A([]);
+
+ @task
+ *fetchBalances () {
+ const uri = `${txServiceBaseUrl}/balances/usd/`;
+
+ yield fetch(uri).then(res => res.json())
+ .then(res => this.processBalances(res))
+ .catch(err => {
+ console.log(`[community-funds] Fetching balances failed:`);
+ console.error(err);
+ });
+ }
+
+ processBalances (res) {
+ for (const balance of res) {
+ // Format and round the approximate USD value
+ const lang = navigator.language || navigator.userLanguage;
+ balance.balanceUsd = Math.round(balance.balanceUsd).toLocaleString(lang);
+
+ if (balance.token) {
+ // ERC20 token, has all meta data
+ this.balances.pushObject(balance);
+ } else {
+ // ETH, missing meta data
+ this.balances.pushObject({
+ ...balance,
+ ...{ token: { name: 'Ether', symbol: 'ETH'} }
+ });
+ }
+ }
+
+ this.balancesLoaded = true;
+ }
+}
diff --git a/app/services/exchange-rates.js b/app/services/exchange-rates.js
new file mode 100644
index 0000000..82dbd46
--- /dev/null
+++ b/app/services/exchange-rates.js
@@ -0,0 +1,29 @@
+import Service from '@ember/service';
+import { tracked } from '@glimmer/tracking';
+import config from 'kredits-web/config/environment';
+
+// Need to go through proxy for CORS headers
+const bitstampBaseUrl = `${config.corsProxy}https://www.bitstamp.net/api/v2`;
+
+async function fetchFromBitstamp(currencyPair) {
+ try {
+ const res = await fetch(`${bitstampBaseUrl}/ticker/${currencyPair}/`).then(r => r.json());
+ return res.vwap; // Last 24 hours volume weighted average price
+ } catch(e) {
+ console.error('Could not fetch exchange rate from Bitstamp:', e);
+ return 0;
+ }
+}
+
+export default class ExchangeRatesService extends Service {
+ @tracked btceur = 0;
+ @tracked btcusd = 0;
+
+ async fetchRates (source='bitstamp') {
+ switch(source) {
+ case 'bitstamp':
+ this.btceur = await fetchFromBitstamp('btceur');
+ this.btcusd = await fetchFromBitstamp('btcusd');
+ }
+ }
+}
diff --git a/app/services/kredits.js b/app/services/kredits.js
index e892f56..2721da0 100644
--- a/app/services/kredits.js
+++ b/app/services/kredits.js
@@ -4,7 +4,7 @@ import Kredits from 'kredits-contracts';
import Service from '@ember/service';
import EmberObject from '@ember/object';
import { computed } from '@ember/object';
-import { alias, notEmpty } from '@ember/object/computed';
+import { alias, filterBy, notEmpty, sort } from '@ember/object/computed';
import { isEmpty, isPresent } from '@ember/utils';
import { inject as service } from '@ember/service';
@@ -13,11 +13,15 @@ import { task, taskGroup } from 'ember-concurrency';
import groupBy from 'kredits-web/utils/group-by';
import processContributorData from 'kredits-web/utils/process-contributor-data';
import processContributionData from 'kredits-web/utils/process-contribution-data';
+import processReimbursementData from 'kredits-web/utils/process-reimbursement-data';
import formatKredits from 'kredits-web/utils/format-kredits';
import config from 'kredits-web/config/environment';
-import Contributor from 'kredits-web/models/contributor'
-import Contribution from 'kredits-web/models/contribution'
+import Contributor from 'kredits-web/models/contributor';
+import Contribution from 'kredits-web/models/contribution';
+import Reimbursement from 'kredits-web/models/reimbursement';
+// Lets us access the model classes dynamically
+const models = { Contributor, Contribution, Reimbursement };
export default Service.extend({
@@ -28,64 +32,27 @@ export default Service.extend({
currentUser: null,
contributors: null,
contributions: null,
+ reimbursements: null,
githubAccessToken: null,
currentUserIsContributor: notEmpty('currentUser'),
currentUserIsCore: alias('currentUser.isCore'),
hasAccounts: notEmpty('currentUserAccounts'),
+ contributorsMined: filterBy('contributors', 'id'),
+ contributorsSorting: Object.freeze(['name:asc']),
+ contributorsSorted: sort('contributorsMined', 'contributorsSorting'),
+
// When data was loaded from cache, we need to fetch updates from the network
contributorsNeedSync: false,
contributionsNeedSync: false,
-
- contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
- return this.contributions.filter(contribution => {
- return contribution.confirmedAt > this.currentBlock;
- });
- }),
-
- contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
- return this.contributions
- .filterBy('vetoed', false)
- .filter(contribution => {
- return contribution.confirmedAt <= this.currentBlock;
- });
- }),
-
- kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
- const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
- const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
- const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
- const contributorsWithOnlyConfirmed = this.contributors.reject(c => contributorsWithUnconfirmed.includes(c.id))
-
- const kreditsByContributor = contributionsGrouped.map(c => {
- const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
- const contributor = this.contributors.findBy('id', c.value.toString());
-
- return EmberObject.create({
- contributor: contributor,
- amountUnconfirmed: amountUnconfirmed,
- amountConfirmed: contributor.totalKreditsEarned,
- amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
- })
- });
-
- contributorsWithOnlyConfirmed.forEach(c => {
- kreditsByContributor.push(EmberObject.create({
- contributor: c,
- amountUnconfirmed: 0,
- amountConfirmed: c.totalKreditsEarned,
- amountTotal: c.totalKreditsEarned
- }));
- })
-
- return kreditsByContributor;
- }),
+ reimbursementsNeedSync: false,
init () {
this._super(...arguments);
this.set('contributors', []);
this.set('contributions', []);
+ this.set('reimbursements', []);
},
// This is called in the application route's beforeModel(). So it is
@@ -168,6 +135,22 @@ export default Service.extend({
});
},
+ getCurrentUser: computed('kredits.provider', 'currentUserAccounts.[]', function() {
+ if (isEmpty(this.currentUserAccounts)) {
+ return Promise.resolve();
+ }
+ return this.kredits.Contributor
+ .functions.getContributorIdByAddress(this.currentUserAccounts.firstObject)
+ .then((id) => {
+ // check if the user is a contributor or not
+ if (id === 0) {
+ return Promise.resolve();
+ } else {
+ return this.kredits.Contributor.getById(id);
+ }
+ });
+ }),
+
totalSupply: computed(function() {
return this.kredits.Token.functions.totalSupply().then(total => {
return formatKredits(total);
@@ -179,10 +162,66 @@ export default Service.extend({
.then(total => total.toNumber());
}),
+ kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
+ const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
+ const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
+ const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
+ const contributorsWithOnlyConfirmed = this.contributors.reject(c => contributorsWithUnconfirmed.includes(c.id))
+
+ const kreditsByContributor = contributionsGrouped.map(c => {
+ const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
+ const contributor = this.contributors.findBy('id', c.value.toString());
+
+ return EmberObject.create({
+ contributor: contributor,
+ amountUnconfirmed: amountUnconfirmed,
+ amountConfirmed: contributor.totalKreditsEarned,
+ amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
+ })
+ });
+
+ contributorsWithOnlyConfirmed.forEach(c => {
+ kreditsByContributor.push(EmberObject.create({
+ contributor: c,
+ amountUnconfirmed: 0,
+ amountConfirmed: c.totalKreditsEarned,
+ amountTotal: c.totalKreditsEarned
+ }));
+ })
+
+ return kreditsByContributor;
+ }),
+
+ contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
+ return this.contributions
+ .filter(c => c.confirmedAt > this.currentBlock);
+ }),
+
+ contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
+ return this.contributions
+ .filterBy('vetoed', false)
+ .filter(c => c.confirmedAt <= this.currentBlock);
+ }),
+
+ reimbursementsUnconfirmed: computed('reimbursements.[]', 'currentBlock', function() {
+ return this.reimbursements
+ .filter(r => r.confirmedAt > this.currentBlock);
+ }),
+
+ reimbursementsConfirmed: computed('reimbursements.[]', 'currentBlock', function() {
+ return this.reimbursements
+ .filterBy('vetoed', false)
+ .filter(r => r.confirmedAt <= this.currentBlock);
+ }),
+
+ reimbursementsPending: computed('reimbursements.[]', 'pendingTx', function() {
+ return this.reimbursements.filter(r => !r.id);
+ }),
+
async loadInitialData () {
const numCachedContributors = await this.browserCache.contributors.length();
if (numCachedContributors > 0) {
- await this.loadContributorsFromCache();
+ await this.loadObjectsFromCache('Contributor');
this.set('contributorsNeedSync', true);
} else {
await this.fetchContributors();
@@ -190,7 +229,7 @@ export default Service.extend({
const numCachedContributions = await this.browserCache.contributions.length();
if (numCachedContributions > 0) {
- await this.loadContributionsFromCache();
+ await this.loadObjectsFromCache('Contribution');
this.set('contributionsNeedSync', true);
} else {
await this.fetchContributions({ page: { size: 30 } });
@@ -267,6 +306,7 @@ export default Service.extend({
syncContributors: task(function * () {
yield this.fetchContributors();
+ this.set('contributorsNeedSync', false);
}),
addContribution (attributes) {
@@ -278,7 +318,7 @@ export default Service.extend({
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
const contribution = Contribution.create(attributes);
contribution.set('pendingTx', data);
- contribution.set('confirmedAtBlock', data.blockNumber + 40320);
+ contribution.set('confirmedAtBlock', this.currentBlock + 40320);
this.contributions.pushObject(contribution);
return contribution;
});
@@ -333,6 +373,7 @@ export default Service.extend({
syncContributions: task(function * () {
yield this.fetchNewContributions.perform();
yield this.syncUnconfirmedContributions.perform();
+ this.set('contributionsNeedSync', false);
}).group('contributionTasks'),
fetchNewContributions: task(function * () {
@@ -406,23 +447,185 @@ export default Service.extend({
});
},
- getCurrentUser: computed('kredits.provider', 'currentUserAccounts.[]', function() {
- if (isEmpty(this.currentUserAccounts)) {
- return Promise.resolve();
- }
- return this.kredits.Contributor
- .functions.getContributorIdByAddress(this.currentUserAccounts.firstObject)
- .then((id) => {
- // check if the user is a contributor or not
- if (id === 0) {
- return Promise.resolve();
- } else {
- return this.kredits.Contributor.getById(id);
- }
+ //
+ // Generic data handling (for objects that can be vetoed)
+ //
+
+ fetchObjects(objectClass, options = { page: { size: 200 } }) {
+ const objectClassLowerCase = objectClass.toLowerCase();
+ console.debug(`[kredits] Fetching ${objectClassLowerCase}s from the network`);
+ return this.kredits[objectClass].all(options)
+ .then(objects => {
+ return objects.map(data => {
+ const classInstance = this[`load${objectClass}FromData`](data);
+ return classInstance;
+ });
+ })
+ .then(objects => {
+ const cacheWrites = objects.map(o => {
+ return this.browserCache[objectClassLowerCase+'s']
+ .setItem(o.id.toString(), o.serialize());
+ });
+ return Promise.all(cacheWrites).then(() => {
+ console.debug(`[kredits] Cached ${objects.length} ${objectClassLowerCase+'s'} in browser storage`);
+ });
});
+ },
+
+ removeObjectFromCollectionIfLoaded (collection, objectId) {
+ const loadedObj = this[collection].findBy('id', objectId);
+ if (loadedObj) { this[collection].removeObject(loadedObj); }
+ },
+
+ async cacheLoadedObjects (collection) {
+ for (const o of this[collection]) {
+ await this.browserCache[collection].setItem(o.id, o.serialize());
+ }
+ console.debug(`[kredits] Cached ${this[collection].length} ${collection} in browser storage`);
+ },
+
+ async loadObjectsFromCache (objectClass) {
+ const collection = objectClass.toLowerCase()+'s';
+ return this.browserCache[collection].iterate((value/*, key , iterationNumber */) => {
+ const obj = models[objectClass].create(JSON.parse(value));
+ this.removeObjectFromCollectionIfLoaded(collection, obj.id)
+ this[collection].pushObject(obj);
+ }).then((/* result */) => {
+ console.debug(`[kredits] Loaded ${this[collection].length} ${collection} from cache`);
+ });
+ },
+
+ syncTaskGroup: taskGroup().enqueue(),
+
+ fetchNewObjects: task(function * (objectClass) {
+ const collection = objectClass.toLowerCase()+'s';
+ const count = yield this.kredits[objectClass].functions[`${collection}Count`]();
+ const lastKnownObjectId = Math.max.apply(null, this[collection].mapBy('id'));
+ const toFetch = count - lastKnownObjectId;
+
+ if (toFetch > 0) {
+ console.debug(`[kredits] Fetching ${toFetch} new ${collection}`);
+ for (let id = lastKnownObjectId; id <= count; id++) {
+ const data = yield this.kredits[objectClass].getById(id);
+ const o = this[`load${objectClass}FromData`](data);
+ yield this.browserCache[collection].setItem(o.id.toString(), o.serialize());
+ }
+ } else {
+ console.debug(`[kredits] No new ${collection} to fetch`);
+ }
}),
+ fetchMissingObjects: task(function * (objectClass) {
+ const collection = objectClass.toLowerCase()+'s';
+ const count = yield this.kredits[objectClass].functions[`${collection}Count`]();
+ const allIds = [...Array(count+1).keys()];
+ allIds.shift(); // remove first item, which is 0
+ const loadedObjects = new Set(this[collection].mapBy('id'));
+ const toFetch = allIds.filter(id => !loadedObjects.has(id));
+ if (toFetch.length === 0) {
+ console.debug(`[kredits] No ${collection} left to fetch`);
+ return;
+ }
+ console.debug(`[kredits] Fetching ${toFetch.length} past ${collection}`);
+ let countFetched = 0;
+
+ for (let id = count; id > 0; id--) {
+ if (loadedObjects.has(id)) {
+ continue;
+ } else {
+ const data = yield this.kredits[objectClass].getById(id);
+ const o = this[`load${objectClass}FromData`](data);
+ yield this.browserCache[collection].setItem(o.id.toString(), o.serialize());
+ countFetched++;
+ if (countFetched % 20 === 0) {
+ console.debug(`[kredits] Fetched ${countFetched} more ${collection}`);
+ }
+ }
+ }
+ console.debug(`[kredits] Cached ${countFetched} past ${collection}`);
+ }),
+
+ syncUnconfirmedObjects: task(function * (objectClass) {
+ const collection = objectClass.toLowerCase()+'s';
+ if (this.get(`${collection}Unconfirmed`).length > 0) {
+ console.debug(`[kredits] Syncing unconfirmed ${collection}`);
+ for (const o of this[`${collection}Unconfirmed`]) {
+ if (isEmpty(o.id)) return;
+ const data = yield this.kredits[objectClass].getById(o.id);
+ const object = this[`load${objectClass}FromData`](data);
+ yield this.browserCache[collection]
+ .setItem(o.id.toString(), object.serialize());
+ }
+ } else {
+ console.debug(`[kredits] No unconfirmed ${collection} to sync`);
+ }
+ }),
+
+ vetoAgainstObject (objectClass, objectId) {
+ console.debug(`[kredits] veto against ${objectClass.toLowerCase()}`, objectId);
+ const collection = objectClass.toLowerCase()+'s';
+ const object = this[collection].findBy('id', objectId);
+
+ return this.kredits[objectClass].functions.veto(objectId, { gasLimit: 300000 })
+ .then(data => {
+ console.debug('[kredits] veto response', data);
+ object.set('pendingTx', data);
+ return data;
+ });
+ },
+
+ //
+ // Reimbursements
+ //
+
+ loadReimbursementFromData(data) {
+ const obj = Reimbursement.create(processReimbursementData(data));
+ obj.set('contributor', this.contributors.findBy('id', data.contributorId.toString()));
+ this.removeObjectFromCollectionIfLoaded('reimbursements', obj.id);
+ this.reimbursements.pushObject(obj);
+ return obj;
+ },
+
+ addReimbursement (attributes) {
+ console.debug('[kredits] add reimbursement', attributes);
+
+ return this.kredits.Reimbursement.add(attributes, { gasLimit: 300000 })
+ .then(data => {
+ console.debug('[kredits] add reimbursement response', data);
+ const reimbursement = Reimbursement.create(attributes);
+ reimbursement.setProperties({
+ contributor: this.contributors.findBy('id', attributes.contributorId.toString()),
+ pendingTx: data,
+ confirmedAt: this.currentBlock + 40320
+ });
+ this.reimbursements.pushObject(reimbursement);
+
+ // Listen to tx mining/execution status
+ data.wait()
+ .then(d => console.debug('[kredits] tx successful', d))
+ .catch(e => {
+ window.alert('The transaction failed to execute. Please check the browser console.');
+ console.log('[kredits] tx error', e);
+ });
+
+ return reimbursement;
+ });
+ },
+
+ syncReimbursements: task(function * () {
+ yield this.fetchNewObjects.perform('Reimbursement');
+ yield this.syncUnconfirmedObjects.perform('Reimbursement');
+ this.set('reimbursementsNeedSync', false);
+ }).group('syncTaskGroup'),
+
+ fetchMissingReimbursements: task(function * () {
+ yield this.fetchMissingObjects.perform('Reimbursement');
+ }).group('syncTaskGroup'),
+
+ //
// Contract events
+ //
+
addContractEventHandlers () {
this.kredits.Contributor
.on('ContributorProfileUpdated', this.handleContributorChange.bind(this))
@@ -433,6 +636,10 @@ export default Service.extend({
.on('ContributionAdded', this.handleContributionAdded.bind(this))
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
+ this.kredits.Reimbursement
+ .on('ReimbursementAdded', this.handleReimbursementAdded.bind(this))
+ .on('ReimbursementVetoed', this.handleReimbursementVetoed.bind(this))
+
this.kredits.Token
.on('Transfer', this.handleTransfer.bind(this));
},
@@ -482,6 +689,39 @@ export default Service.extend({
}
},
+ //
+ // TODO test when reimbursement txs are successful
+ //
+ async handleReimbursementAdded (id, addedByAccount, amount) {
+ console.debug('[kredits] ReimbursementAdded event received', { id, addedByAccount, amount });
+
+ const pendingReimbursement = this.reimbursementsPending.find(r => {
+ return r.amount.toString() === amount.toString();
+ });
+
+ if (pendingReimbursement) {
+ console.debug('[kredits] Found a pending reimbursement matching the event. Replacing it with the final record...');
+ this.reimbursements.removeObject(pendingReimbursement);
+ }
+
+ const data = await this.kredits.Reimbursement.getById(id);
+ this.loadReimbursementFromData(data);
+ },
+
+ //
+ // TODO test when reimbursement txs are successful and veto is implemented
+ //
+ handleReimbursementVetoed (id) {
+ console.debug('[kredits] ReimbursementVetoed received for ', id);
+ const reimbursement = this.reimbursements.findBy('id', id);
+ console.debug('[kredits] reimbursement', this.reimbursement);
+
+ if (reimbursement) {
+ reimbursement.set('vetoed', true);
+ reimbursement.set('pendingTx', null);
+ }
+ },
+
handleTransfer (from, to, value) {
value = value.toNumber();
diff --git a/app/styles/_buttons.scss b/app/styles/_buttons.scss
index 6ab5574..eb0c2ff 100644
--- a/app/styles/_buttons.scss
+++ b/app/styles/_buttons.scss
@@ -20,7 +20,7 @@ button, input[type=submit], .button {
background-color: rgba(22, 21, 40, 0.8);
}
- &:active, &.active {
+ &:focus, &:active, &.active {
border-color: $primary-color;
}
@@ -41,7 +41,7 @@ button, input[type=submit], .button {
&:hover {
background-color: rgba(40, 21, 21, 0.8);
}
- &:active, &.active {
+ &:focus, &:active, &.active {
border-color: $red;
}
}
@@ -54,7 +54,7 @@ button, input[type=submit], .button {
&:hover {
background-color: rgba(21, 40, 21, 0.8);
}
- &:active, &.active {
+ &:focus, &:active, &.active {
border-color: $green;
}
}
diff --git a/app/styles/_colors.scss b/app/styles/_colors.scss
index 4898458..35bbc34 100644
--- a/app/styles/_colors.scss
+++ b/app/styles/_colors.scss
@@ -8,3 +8,7 @@ $red: #fb6868;
$primary-color: $blue;
$body-text-color: #fff;
+
+$item-background-color: rgba(255,255,255,0.1);
+$item-highlighted-background-color: rgba(255,255,255,0.2);
+$item-border-color: rgba(255,255,255,0.2);
diff --git a/app/styles/_forms.scss b/app/styles/_forms.scss
index 5153b02..fd861d8 100644
--- a/app/styles/_forms.scss
+++ b/app/styles/_forms.scss
@@ -1,21 +1,31 @@
section#add-contributor,
section#add-contribution,
+section#add-contribution,
+section#add-item, // TODO use for all forms for adding data
section#signup {
-
form {
+ h3 {
+ font-size: 1.5rem;
+ font-weight: normal;
+ margin-top: 2em;
+ margin-bottom: 1em;
+ }
p {
- margin-bottom: 1.5rem;
+ font-size: 1.2rem;
&.mg-bottom-md {
margin-bottom: 2rem;
}
&.label {
+ margin-bottom: 1.5rem;
+ font-size: 1rem;
margin-bottom: .5rem;
}
&.actions {
+ margin-bottom: 1.5rem;
padding-top: 1.5rem;
text-align: center;
a {
@@ -29,9 +39,34 @@ section#signup {
display: block;
margin-bottom: 0.5rem;
opacity: 0.7;
+
+ > p {
+ margin-bottom: 1.5rem;
+ }
}
- input[type=text], select {
+ fieldset {
+ border: none;
+
+ &.horizontal {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-gap: 2rem;
+
+ &.thirds {
+ grid-template-columns: 1fr 1fr 1fr;
+ }
+
+ &.total-amounts {
+ grid-template-columns: 2fr 1fr 1fr;
+ }
+
+ label {
+ }
+ }
+ }
+
+ input[type=text], input[type=url], select {
width: 100%;
padding: 1rem;
border: none;
@@ -39,17 +74,24 @@ section#signup {
background-color: rgba(22, 21, 40, 0.3);
color: #fff;
font-size: 1.2rem;
+ font-weight: normal;
transition: border-color 0.1s linear;
&:focus, &.valid {
background-color: rgba(22, 21, 40, 0.6);
}
- &:focus {
+ &:focus :not(:invalid) {
border-color: $blue;
}
&::placeholder {
color: rgba(238, 238, 238, 0.5);
}
+ &.invalid {
+ border-color: $red;
+ }
+ &:disabled {
+ color: rgba(255, 255, 255, 0.6);
+ }
}
select {
@@ -109,7 +151,5 @@ section#signup {
color: #fff;
}
}
-
}
-
}
diff --git a/app/styles/_item-list.scss b/app/styles/_item-list.scss
new file mode 100644
index 0000000..548bf3c
--- /dev/null
+++ b/app/styles/_item-list.scss
@@ -0,0 +1,35 @@
+ul.item-list {
+ list-style: none;
+
+ > li {
+ padding: 0.8rem 1.2rem;
+ font-size: 1.2rem;
+ background-color: $item-background-color;
+ border-bottom: 1px solid $item-border-color;
+
+ &:first-of-type {
+ border-top: 1px solid $item-border-color;
+ }
+
+ &.selected {
+ background-color: $item-highlighted-background-color;
+ }
+ }
+
+ &.loading {
+ @include loading-border-top;
+
+ > li {
+ &:first-of-type {
+ border-top: none;
+ }
+ }
+ }
+
+ &.spaced {
+ > li {
+ border-top: 1px solid $item-border-color;
+ margin-bottom: 2rem;
+ }
+ }
+}
diff --git a/app/styles/_layout.scss b/app/styles/_layout.scss
index 23be5fa..d313121 100644
--- a/app/styles/_layout.scss
+++ b/app/styles/_layout.scss
@@ -14,6 +14,15 @@ main {
"contributions";
}
+ budget {
+ width: 100%;
+ display: grid;
+ grid-row-gap: 2rem;
+ grid-template-areas:
+ "aside"
+ "content";
+ }
+
&.center-column {
display: flex;
flex-direction: column;
@@ -29,6 +38,16 @@ main {
}
}
+ div#content {
+ section {
+ &:first-of-type {
+ @include media-max(small) {
+ margin-top: 0;
+ }
+ }
+ }
+ }
+
section {
.content {
a {
@@ -68,7 +87,7 @@ main {
@include media-max(small) {
padding: 2rem 1rem;
- font-size: 1.4rem;
+ font-size: 1.5rem;
}
h2 {
@@ -111,6 +130,13 @@ main {
"stats contributions details";
}
}
+
+ budget {
+ grid-column-gap: 3rem;
+ grid-template-columns: 2fr 4fr 2fr;
+ grid-template-areas:
+ "aside content empty";
+ }
}
}
diff --git a/app/styles/app.scss b/app/styles/app.scss
index 97112ac..7ab0be3 100644
--- a/app/styles/app.scss
+++ b/app/styles/app.scss
@@ -47,7 +47,7 @@ a {
section {
h2 {
- font-size: 1.4rem;
+ font-size: 1.5rem;
color: $primary-color;
}
@@ -89,13 +89,17 @@ section {
@import "buttons";
@import "forms";
@import "sugar";
+@import "item-list";
-@import "components/contribution-list";
+@import "components/budget-balances";
@import "components/contribution-details";
+@import "components/contribution-list";
@import "components/contributor-list";
@import "components/contributor-profile";
+@import "components/expense-list";
@import "components/external-account-link";
@import "components/loading-spinner";
+@import "components/reimbursement-list";
@import "components/topbar";
@import "components/topbar-account-panel";
@import "components/user-avatar";
diff --git a/app/styles/components/_budget-balances.scss b/app/styles/components/_budget-balances.scss
new file mode 100644
index 0000000..e6923b9
--- /dev/null
+++ b/app/styles/components/_budget-balances.scss
@@ -0,0 +1,41 @@
+section#funds {
+ @include media-max(small) {
+ margin-bottom: 2rem;
+ }
+
+ table.token-balances {
+ opacity: 1;
+ transition: opacity 0.3s linear;
+
+ &.loading {
+ opacity: 0;
+ }
+
+ thead {
+ display: none;
+ }
+
+ th, td {
+ font-size: 1.2rem;
+ vertical-align: text-bottom;
+ }
+
+ th {
+ text-align: left;
+ padding-right: 1.2rem;
+ }
+
+ td {
+ text-align: right;
+
+ &.amount {
+ font-size: 1.5rem;
+ padding-right: 1.2rem;
+ }
+
+ &.fiat-amount {
+ color: rgba(255,255,255,0.8);
+ }
+ }
+ }
+}
diff --git a/app/styles/components/_contribution-details.scss b/app/styles/components/_contribution-details.scss
index 5cdc1e9..a2071a0 100644
--- a/app/styles/components/_contribution-details.scss
+++ b/app/styles/components/_contribution-details.scss
@@ -16,9 +16,9 @@ section#contribution-details {
margin: 0 0 1.5rem;
padding: 2rem 2rem;
- border-top: 1px solid rgba(255,255,255,0.2);
- border-bottom: 1px solid rgba(255,255,255,0.2);
- background-color: rgba(255,255,255,0.1);
+ border-top: 1px solid $item-border-color;
+ border-bottom: 1px solid $item-border-color;
+ background-color: $item-background-color;
h3 {
font-size: 1.5rem;
@@ -67,7 +67,7 @@ section#contribution-details {
overflow: auto;
margin-top: 2rem;
padding-top: 2rem;
- border-top: 1px solid rgba(255,255,255,0.2);
+ border-top: 1px solid $item-border-color;
font-size: 1.2rem;
.icon {
diff --git a/app/styles/components/_contribution-list.scss b/app/styles/components/_contribution-list.scss
index bb560e6..2c6034d 100644
--- a/app/styles/components/_contribution-list.scss
+++ b/app/styles/components/_contribution-list.scss
@@ -24,22 +24,13 @@ main section {
ul.contribution-list {
clear: both;
width: 100%;
- list-style: none;
li {
display: grid;
grid-template-columns: auto 5rem 5rem;
grid-row-gap: 0.5rem;
- padding: 0.8rem 1.2rem;
- background-color: rgba(255,255,255,0.1);
- font-size: 1.2rem;
- border-bottom: 1px solid rgba(255,255,255,0.2);
cursor: pointer;
- &:first-of-type {
- border-top: 1px solid rgba(255,255,255,0.2);
- }
-
&.confirmed {
grid-template-columns: auto 5rem;
}
@@ -50,10 +41,6 @@ ul.contribution-list {
opacity: 0.6;
}
- &.selected {
- background-color: rgba(255,255,255,0.2);
- }
-
p {
align-self: center;
margin: 0;
@@ -113,14 +100,4 @@ ul.contribution-list {
margin-right: 0.5rem;
}
}
-
- &.loading {
- @include loading-border-top;
-
- li {
- &:first-of-type {
- border-top: none;
- }
- }
- }
}
diff --git a/app/styles/components/_contributor-list.scss b/app/styles/components/_contributor-list.scss
index 2d56780..e2deff7 100644
--- a/app/styles/components/_contributor-list.scss
+++ b/app/styles/components/_contributor-list.scss
@@ -5,16 +5,16 @@ table.contributor-list {
margin-bottom: 1.5rem;
tr {
- background-color: rgba(255,255,255,0.1);
- border-bottom: 1px solid rgba(255,255,255,0.2);
+ background-color: $item-background-color;
+ border-bottom: 1px solid $item-border-color;
cursor: pointer;
&:first-of-type {
- border-top: 1px solid rgba(255,255,255,0.2);
+ border-top: 1px solid $item-border-color;
}
&.selected {
- background-color: rgba(255,255,255,0.2);
+ background-color: $item-highlighted-background-color;
}
&.current-user {
diff --git a/app/styles/components/_contributor-profile.scss b/app/styles/components/_contributor-profile.scss
index 73ed08d..392c634 100644
--- a/app/styles/components/_contributor-profile.scss
+++ b/app/styles/components/_contributor-profile.scss
@@ -8,7 +8,7 @@ section#contributor-profile {
img {
margin: 0 auto;
- border: 3px solid rgba(255,255,255,0.2);
+ border: 3px solid $item-border-color;
}
}
@@ -18,9 +18,9 @@ section#contributor-profile {
margin: -7.2rem 0 1.5rem;
padding: 6rem 1.2rem 2rem;
- border-top: 1px solid rgba(255,255,255,0.2);
- border-bottom: 1px solid rgba(255,255,255,0.2);
- background-color: rgba(255,255,255,0.1);
+ border-top: 1px solid $item-border-color;
+ border-bottom: 1px solid $item-border-color;
+ background-color: $item-background-color;
h2 {
text-align: center;
diff --git a/app/styles/components/_expense-list.scss b/app/styles/components/_expense-list.scss
new file mode 100644
index 0000000..b369f5f
--- /dev/null
+++ b/app/styles/components/_expense-list.scss
@@ -0,0 +1,48 @@
+ul.expense-list {
+ grid-column-start: span 2;
+ width: 100%;
+ margin-top: 0.8rem;
+ border-collapse: collapse;
+
+ li {
+ display: grid;
+ grid-template-columns: auto 10rem;
+ grid-row-gap: 0.5rem;
+ padding-top: 1.2rem;
+ border-top: 1px solid $item-border-color;
+ font-size: 1.2rem;
+
+ &:not(:last-child) {
+ padding-bottom: 1.2rem;
+ }
+ }
+
+ .description {
+ grid-row-start: 1;
+ grid-row-end: 3;
+ }
+
+ .amount {
+ justify-self: end;
+ // font-weight: normal;
+ }
+
+ .actions {
+ justify-self: end;
+ }
+
+ h4 {
+ font-size: 1.2rem;
+ font-weight: normal;
+ line-height: 2rem;
+ }
+
+ p {
+ line-height: 2rem;
+
+ &.description {
+ font-size: 1rem;
+ opacity: 0.7;
+ }
+ }
+}
diff --git a/app/styles/components/_loading-spinner.scss b/app/styles/components/_loading-spinner.scss
index 6db85c4..40e8212 100644
--- a/app/styles/components/_loading-spinner.scss
+++ b/app/styles/components/_loading-spinner.scss
@@ -10,7 +10,7 @@
.loading-spinner {
margin-top: 12rem;
text-align: center;
- font-size: 1.4rem;
+ font-size: 1.5rem;
color: $primary-color;
@include media-max(small) {
diff --git a/app/styles/components/_reimbursement-list.scss b/app/styles/components/_reimbursement-list.scss
new file mode 100644
index 0000000..3c22894
--- /dev/null
+++ b/app/styles/components/_reimbursement-list.scss
@@ -0,0 +1,29 @@
+ul.reimbursement-list {
+ width: 100%;
+
+ > li {
+ display: grid;
+ grid-template-columns: auto 12rem;
+ grid-row-gap: 0.5rem;
+ padding-top: 1.6rem;
+
+ .token-amount {
+ text-align: right;
+
+ img {
+ height: 1em;
+ vertical-align: middle;
+ margin-top: -2px;
+ }
+
+ .amount {
+ font-size: 1.5rem;
+ }
+
+ .symbol {
+ font-size: 1rem;
+ padding-left: 0.2rem;
+ }
+ }
+ }
+}
diff --git a/app/templates/budget.hbs b/app/templates/budget.hbs
new file mode 100644
index 0000000..36aa961
--- /dev/null
+++ b/app/templates/budget.hbs
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{#if this.reimbursementsUnconfirmed}}
+
+
+ Proposed Reimbursements
+
+ add
+
+
+
+
+
+
+ {{/if}}
+
+ {{#if this.reimbursementsConfirmed}}
+
+
+ Confirmed Expenses
+
+ add
+
+
+
+
+
+
+ {{/if}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/templates/budget/expenses.hbs b/app/templates/budget/expenses.hbs
new file mode 100644
index 0000000..e2147ca
--- /dev/null
+++ b/app/templates/budget/expenses.hbs
@@ -0,0 +1 @@
+{{outlet}}
\ No newline at end of file
diff --git a/app/templates/contributions/new.hbs b/app/templates/contributions/new.hbs
index e0ecce3..984343f 100644
--- a/app/templates/contributions/new.hbs
+++ b/app/templates/contributions/new.hbs
@@ -6,8 +6,7 @@
diff --git a/app/templates/dashboard/contributions/show.hbs b/app/templates/dashboard/contributions/show.hbs
index a447c1e..52d6b3d 100644
--- a/app/templates/dashboard/contributions/show.hbs
+++ b/app/templates/dashboard/contributions/show.hbs
@@ -19,7 +19,7 @@
{{this.model.description}}
Kind: {{this.model.kind}}
- Status: {{contribution-status this.model}}
+ Status: {{item-status this.model}}
{{#if this.model.url}}
diff --git a/app/templates/reimbursements/new.hbs b/app/templates/reimbursements/new.hbs
new file mode 100644
index 0000000..154c3d7
--- /dev/null
+++ b/app/templates/reimbursements/new.hbs
@@ -0,0 +1,13 @@
+
+
+
+
+ Submit a Reimbursement
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/utils/is-valid-amount.js b/app/utils/is-valid-amount.js
new file mode 100644
index 0000000..408afc8
--- /dev/null
+++ b/app/utils/is-valid-amount.js
@@ -0,0 +1,8 @@
+export default function isValidAmount(inputAmount) {
+ const amount = parseFloat(inputAmount);
+ if (Number.isNaN(amount)) {
+ return false;
+ } else {
+ return amount > 0;
+ }
+}
diff --git a/app/utils/process-reimbursement-data.js b/app/utils/process-reimbursement-data.js
new file mode 100644
index 0000000..a66287c
--- /dev/null
+++ b/app/utils/process-reimbursement-data.js
@@ -0,0 +1,22 @@
+export default function processReimbursementData(data) {
+ const processed = {
+ amount: data.amount.toNumber()
+ }
+
+ if (data.confirmedAtBlock && (typeof data.confirmedAtBlock.toNumber === 'function')) {
+ processed.confirmedAt = data.confirmedAtBlock.toNumber();
+ } else if (data.confirmedAt !== 'undefined') {
+ processed.confirmedAt = data.confirmedAt;
+ }
+
+ const otherProperties = [
+ 'id', 'contributorId', 'token', 'vetoed', 'ipfsHash',
+ 'expenses', 'pendingTx'
+ ];
+
+ otherProperties.forEach(prop => {
+ processed[prop] = data[prop];
+ });
+
+ return processed;
+}
diff --git a/config/environment.js b/config/environment.js
index 3554ed2..eb48ae2 100644
--- a/config/environment.js
+++ b/config/environment.js
@@ -46,7 +46,18 @@ module.exports = function(environment) {
port: '5444',
protocol: 'https',
gatewayUrl: 'https://ipfs.kosmos.org/ipfs'
- }
+ },
+
+ tokens: {
+ 'WBTC': '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599'
+ },
+
+ gnosisSafe: {
+ txServiceHost: 'https://safe-transaction.mainnet.gnosis.io',
+ address: '0x9CC29b8373FF92B01C1f09F31B5DD862350c167E'
+ },
+
+ corsProxy: 'https://cors.5apps.com/?uri='
};
if (environment === 'development') {
@@ -66,6 +77,8 @@ module.exports = function(environment) {
protocol: 'http',
gatewayUrl: 'http://localhost:8080/ipfs'
};
+
+ ENV.corsProxy = 'https://cors-anywhere.herokuapp.com/';
}
if (environment === 'test') {
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..504cd64
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,5 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ }
+}
diff --git a/package-lock.json b/package-lock.json
index 2477289..0af0729 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2582,6 +2582,15 @@
"integrity": "sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ==",
"dev": true
},
+ "@ember-decorators/utils": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@ember-decorators/utils/-/utils-6.1.1.tgz",
+ "integrity": "sha512-0KqnoeoLKb6AyoSU65TRF5T85wmS4uDn06oARddwNPxxf/lt5jQlh41uX3W7V/fWL9tPu8x1L1Vvpc80MN1+YA==",
+ "dev": true,
+ "requires": {
+ "ember-cli-babel": "^7.1.3"
+ }
+ },
"@ember/edition-utils": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ember/edition-utils/-/edition-utils-1.2.0.tgz",
@@ -2938,9 +2947,9 @@
"dev": true
},
"@kosmos/schemas": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-2.2.1.tgz",
- "integrity": "sha512-zYUctQ91sYhzoJ0ujO73odBSsnwvdLlS6ENA/U/4/IzRKVZBj9cS4RpgFh1xOQXNN+HB4pUu8u7Su/Xtked+vg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.0.0.tgz",
+ "integrity": "sha512-7hnirq0ShsDjENBPjNnu6izwzVjkDzEZ4SKvPzQJJfkeJ/NRVHKvfdn9rkE7CRXTi2hMzsZVFOnlF6D/eYXTCA==",
"dev": true,
"requires": {
"brfs-babel": "^1.0.0"
@@ -3340,6 +3349,15 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
+ "abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "dev": true,
+ "requires": {
+ "event-target-shim": "^5.0.0"
+ }
+ },
"abortcontroller-polyfill": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.4.0.tgz",
@@ -3738,6 +3756,16 @@
"dev": true,
"optional": true
},
+ "async-iterator-to-pull-stream": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/async-iterator-to-pull-stream/-/async-iterator-to-pull-stream-1.3.0.tgz",
+ "integrity": "sha512-NjyhAEz/sx32olqgKIk/2xbWEM6o8qef1yetIgb0U/R3oBgndP1kE/0CslowH3jvnA94BO4I6OXpOkTKH7Z1AA==",
+ "dev": true,
+ "requires": {
+ "get-iterator": "^1.0.2",
+ "pull-stream-to-async-iterator": "^1.0.1"
+ }
+ },
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
@@ -4367,9 +4395,9 @@
}
},
"babel-plugin-static-fs": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-static-fs/-/babel-plugin-static-fs-1.2.0.tgz",
- "integrity": "sha512-7zsDPvDzCBwfbU53WKym5LxTe1PxQHE/dGo+EfIELlBcn08TpU7SlPJILcc6YVAyTrpVUNioQfWiUyMWk1DJVg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-static-fs/-/babel-plugin-static-fs-1.2.1.tgz",
+ "integrity": "sha512-dZasA7svnKAsMEB7/6fKhJO+nIZsC2fvJyj3fbuk/xUOwslZOdl+9umXQsB+oqHwOEubZ5WHJ/Zy9dvnVnRvFg==",
"dev": true,
"requires": {
"babel-template": "^6.3.13",
@@ -4925,9 +4953,9 @@
}
},
"base-x": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.7.tgz",
- "integrity": "sha512-zAKJGuQPihXW22fkrfOclUUZXM2g92z5GzlSMHxhO6r6Qj+Nm0ccaGNBzDZojzwOMkpjAv4J0fOv1U4go+a4iw==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
+ "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
"dev": true,
"requires": {
"safe-buffer": "^5.0.1"
@@ -4985,9 +5013,9 @@
"dev": true
},
"bignumber.js": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz",
- "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+ "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
"dev": true
},
"binary-extensions": {
@@ -5022,18 +5050,36 @@
}
},
"bl": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
- "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
+ "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
"dev": true,
"requires": {
- "readable-stream": "^3.0.1"
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
},
"dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
"readable-stream": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
@@ -5042,9 +5088,9 @@
}
},
"safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"string_decoder": {
@@ -5164,23 +5210,55 @@
}
},
"borc": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.1.tgz",
- "integrity": "sha512-vPLLC2/gS0QN4O3cnPh+8jLshkMMD4qIfs+B1TPGPh30WrtcfItaO6j4k9alsqu/hIgKi8dVdmMvTcbq4tIF7A==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz",
+ "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==",
"dev": true,
"requires": {
"bignumber.js": "^9.0.0",
+ "buffer": "^5.5.0",
"commander": "^2.15.0",
- "ieee754": "^1.1.8",
- "iso-url": "~0.4.4",
- "json-text-sequence": "~0.1.0"
+ "ieee754": "^1.1.13",
+ "iso-url": "~0.4.7",
+ "json-text-sequence": "~0.1.0",
+ "readable-stream": "^3.6.0"
},
"dependencies": {
- "bignumber.js": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
- "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
}
}
},
@@ -6466,6 +6544,12 @@
"json-stable-stringify": "^1.0.1"
}
},
+ "callbackify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/callbackify/-/callbackify-1.1.0.tgz",
+ "integrity": "sha1-0qNphtKKppcUUmwREgm+65l50x4=",
+ "dev": true
+ },
"callsite": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
@@ -6685,13 +6769,6 @@
"to-regex-range": "^5.0.1"
}
},
- "fsevents": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
- "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
- "dev": true,
- "optional": true
- },
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
@@ -6773,15 +6850,28 @@
"dev": true
},
"cids": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/cids/-/cids-0.5.8.tgz",
- "integrity": "sha512-Ye8TZP3YQfy0j+i5k+LPHdTY3JOvTwN1pxds44p6BRUv8PTMOAF/Vt4Bc+oiIQ0Sktn0iftkUHgqKNHIMwhshA==",
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz",
+ "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==",
"dev": true,
"requires": {
+ "buffer": "^5.5.0",
"class-is": "^1.1.0",
"multibase": "~0.6.0",
- "multicodec": "~0.5.0",
- "multihashes": "~0.4.14"
+ "multicodec": "^1.0.0",
+ "multihashes": "~0.4.15"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ }
}
},
"cipher-base": {
@@ -7788,12 +7878,6 @@
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true
},
- "detect-node": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
- "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
- "dev": true
- },
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -10809,6 +10893,39 @@
"ms": "^2.1.1"
}
},
+ "ember-get-config": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/ember-get-config/-/ember-get-config-0.2.4.tgz",
+ "integrity": "sha1-EYSSoqA9c+RgBO13eSiUICH+Hs0=",
+ "dev": true,
+ "requires": {
+ "broccoli-file-creator": "^1.1.1",
+ "ember-cli-babel": "^6.3.0"
+ },
+ "dependencies": {
+ "ember-cli-babel": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz",
+ "integrity": "sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA==",
+ "dev": true,
+ "requires": {
+ "amd-name-resolver": "1.2.0",
+ "babel-plugin-debug-macros": "^0.2.0-beta.6",
+ "babel-plugin-ember-modules-api-polyfill": "^2.6.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.0",
+ "babel-polyfill": "^6.26.0",
+ "babel-preset-env": "^1.7.0",
+ "broccoli-babel-transpiler": "^6.5.0",
+ "broccoli-debug": "^0.6.4",
+ "broccoli-funnel": "^2.0.0",
+ "broccoli-source": "^1.1.0",
+ "clone": "^2.0.0",
+ "ember-cli-version-checker": "^2.1.2",
+ "semver": "^5.5.0"
+ }
+ }
+ }
+ },
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
@@ -11176,6 +11293,263 @@
"ember-maybe-import-regenerator": "^0.1.6"
}
},
+ "ember-concurrency-decorators": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ember-concurrency-decorators/-/ember-concurrency-decorators-2.0.1.tgz",
+ "integrity": "sha512-KJ8mCZxmvgalawh/zytURsc5ParNr9avPeCDR/mE7VQxWvITHtyAuYS2s1PPFQAQggTXTZYcGnfgzjn/cDHNMQ==",
+ "dev": true,
+ "requires": {
+ "@ember-decorators/utils": "^6.1.0",
+ "ember-cli-babel": "^7.19.0",
+ "ember-cli-htmlbars": "^4.3.1",
+ "ember-cli-typescript": "^3.1.4"
+ },
+ "dependencies": {
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+ "dev": true
+ },
+ "@babel/plugin-transform-typescript": {
+ "version": "7.8.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.7.tgz",
+ "integrity": "sha512-7O0UsPQVNKqpHeHLpfvOG4uXmlw+MOxYvUv6Otc9uH5SYMIxvF6eBdjkWvC3f9G+VXe0RsNExyAQBeTRug/wqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.8.3",
+ "@babel/helper-plugin-utils": "^7.8.3",
+ "@babel/plugin-syntax-typescript": "^7.8.3"
+ }
+ },
+ "babel-plugin-htmlbars-inline-precompile": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-3.2.0.tgz",
+ "integrity": "sha512-IUeZmgs9tMUGXYu1vfke5I18yYJFldFGdNFQOWslXTnDWXzpwPih7QFduUqvT+awDpDuNtXpdt5JAf43Q1Hhzg==",
+ "dev": true
+ },
+ "broccoli-persistent-filter": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-2.3.1.tgz",
+ "integrity": "sha512-hVsmIgCDrl2NFM+3Gs4Cr2TA6UPaIZip99hN8mtkaUPgM8UeVnCbxelCvBjUBHo0oaaqP5jzqqnRVvb568Yu5g==",
+ "dev": true,
+ "requires": {
+ "async-disk-cache": "^1.2.1",
+ "async-promise-queue": "^1.0.3",
+ "broccoli-plugin": "^1.0.0",
+ "fs-tree-diff": "^2.0.0",
+ "hash-for-dep": "^1.5.0",
+ "heimdalljs": "^0.2.1",
+ "heimdalljs-logger": "^0.1.7",
+ "mkdirp": "^0.5.1",
+ "promise-map-series": "^0.2.1",
+ "rimraf": "^2.6.1",
+ "rsvp": "^4.7.0",
+ "symlink-or-copy": "^1.0.1",
+ "sync-disk-cache": "^1.3.3",
+ "walk-sync": "^1.0.0"
+ },
+ "dependencies": {
+ "broccoli-plugin": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-1.3.1.tgz",
+ "integrity": "sha512-DW8XASZkmorp+q7J4EeDEZz+LoyKLAd2XZULXyD9l4m9/hAKV3vjHmB1kiUshcWAYMgTP1m2i4NnqCE/23h6AQ==",
+ "dev": true,
+ "requires": {
+ "promise-map-series": "^0.2.1",
+ "quick-temp": "^0.1.3",
+ "rimraf": "^2.3.4",
+ "symlink-or-copy": "^1.1.8"
+ }
+ },
+ "walk-sync": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-1.1.4.tgz",
+ "integrity": "sha512-nowc9thB/Jg0KW4TgxoRjLLYRPvl3DB/98S89r4ZcJqq2B0alNcKDh6pzLkBSkPMzRSMsJghJHQi79qw0YWEkA==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "ensure-posix-path": "^1.1.0",
+ "matcher-collection": "^1.1.1"
+ }
+ }
+ }
+ },
+ "broccoli-plugin": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz",
+ "integrity": "sha512-7w7FP8WJYjLvb0eaw27LO678TGGaom++49O1VYIuzjhXjK5kn2+AMlDm7CaUFw4F7CLGoVQeZ84d8gICMJa4lA==",
+ "dev": true,
+ "requires": {
+ "broccoli-node-api": "^1.6.0",
+ "broccoli-output-wrapper": "^2.0.0",
+ "fs-merger": "^3.0.1",
+ "promise-map-series": "^0.2.1",
+ "quick-temp": "^0.1.3",
+ "rimraf": "^2.3.4",
+ "symlink-or-copy": "^1.1.8"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ember-cli-htmlbars": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-4.4.0.tgz",
+ "integrity": "sha512-ohgctqk7dXIZR4TgN0xRoUYltWhghFJgqmtuswQTpZ7p74RxI9PKx+E8WV/95mGcPzraesvMNBg5utQNvcqgNg==",
+ "dev": true,
+ "requires": {
+ "@ember/edition-utils": "^1.2.0",
+ "babel-plugin-htmlbars-inline-precompile": "^3.2.0",
+ "broccoli-debug": "^0.6.5",
+ "broccoli-persistent-filter": "^2.3.1",
+ "broccoli-plugin": "^3.1.0",
+ "common-tags": "^1.8.0",
+ "ember-cli-babel-plugin-helpers": "^1.1.0",
+ "fs-tree-diff": "^2.0.1",
+ "hash-for-dep": "^1.5.1",
+ "heimdalljs-logger": "^0.1.10",
+ "json-stable-stringify": "^1.0.1",
+ "semver": "^6.3.0",
+ "strip-bom": "^4.0.0",
+ "walk-sync": "^2.0.2"
+ }
+ },
+ "ember-cli-typescript": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-3.1.4.tgz",
+ "integrity": "sha512-HJ73kL45OGRmIkPhBNFt31I1SGUvdZND+LCH21+qpq3pPlFpJG8GORyXpP+2ze8PbnITNLzwe5AwUrpyuRswdQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
+ "@babel/plugin-proposal-optional-chaining": "^7.6.0",
+ "@babel/plugin-transform-typescript": "~7.8.0",
+ "ansi-to-html": "^0.6.6",
+ "broccoli-stew": "^3.0.0",
+ "debug": "^4.0.0",
+ "ember-cli-babel-plugin-helpers": "^1.0.0",
+ "execa": "^3.0.0",
+ "fs-extra": "^8.0.0",
+ "resolve": "^1.5.0",
+ "rsvp": "^4.8.1",
+ "semver": "^6.3.0",
+ "stagehand": "^1.0.0",
+ "walk-sync": "^2.0.0"
+ }
+ },
+ "execa": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+ "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "p-finally": "^2.0.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "fs-tree-diff": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz",
+ "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==",
+ "dev": true,
+ "requires": {
+ "@types/symlink-or-copy": "^1.2.0",
+ "heimdalljs-logger": "^0.1.7",
+ "object-assign": "^4.1.0",
+ "path-posix": "^1.0.0",
+ "symlink-or-copy": "^1.1.8"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "rsvp": {
+ "version": "4.8.5",
+ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "walk-sync": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",
+ "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "ensure-posix-path": "^1.1.0",
+ "matcher-collection": "^2.0.0",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "matcher-collection": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz",
+ "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "minimatch": "^3.0.2"
+ }
+ }
+ }
+ }
+ }
+ },
"ember-diff-attrs": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz",
@@ -11749,39 +12123,6 @@
}
}
},
- "ember-get-config": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/ember-get-config/-/ember-get-config-0.2.4.tgz",
- "integrity": "sha1-EYSSoqA9c+RgBO13eSiUICH+Hs0=",
- "dev": true,
- "requires": {
- "broccoli-file-creator": "^1.1.1",
- "ember-cli-babel": "^6.3.0"
- },
- "dependencies": {
- "ember-cli-babel": {
- "version": "6.18.0",
- "resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz",
- "integrity": "sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA==",
- "dev": true,
- "requires": {
- "amd-name-resolver": "1.2.0",
- "babel-plugin-debug-macros": "^0.2.0-beta.6",
- "babel-plugin-ember-modules-api-polyfill": "^2.6.0",
- "babel-plugin-transform-es2015-modules-amd": "^6.24.0",
- "babel-polyfill": "^6.26.0",
- "babel-preset-env": "^1.7.0",
- "broccoli-babel-transpiler": "^6.5.0",
- "broccoli-debug": "^0.6.4",
- "broccoli-funnel": "^2.0.0",
- "broccoli-source": "^1.1.0",
- "clone": "^2.0.0",
- "ember-cli-version-checker": "^2.1.2",
- "semver": "^5.5.0"
- }
- }
- }
- },
"ember-getowner-polyfill": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz",
@@ -14597,9 +14938,9 @@
"dev": true
},
"err-code": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
- "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"dev": true
},
"errno": {
@@ -15252,6 +15593,12 @@
"es5-ext": "~0.10.14"
}
},
+ "event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "dev": true
+ },
"eventemitter3": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
@@ -15367,6 +15714,12 @@
"homedir-polyfill": "^1.0.1"
}
},
+ "explain-error": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/explain-error/-/explain-error-1.0.4.tgz",
+ "integrity": "sha1-p5PTrAytTGq1cemWj7urbLJTKSk=",
+ "dev": true
+ },
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@@ -15539,6 +15892,12 @@
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
+ "fast-fifo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.0.0.tgz",
+ "integrity": "sha512-4VEXmjxLj7sbs8J//cn2qhRap50dGzF5n8fjay8mau+Jn4hxSeR3xPFwxMaQq/pDaq7+KQk0PAbC2+nWDkJrmQ==",
+ "dev": true
+ },
"fast-glob": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz",
@@ -15832,6 +16191,63 @@
"bser": "2.1.1"
}
},
+ "fetch-mock": {
+ "version": "9.10.7",
+ "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.10.7.tgz",
+ "integrity": "sha512-YkiMHSL8CQ0vlWYpqGvlaZjViFk0Kar9jonPjSvaWoztkeHH6DENqUzBIsffzjVKhwchPI74SZRLRpIsEyNcZQ==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "core-js": "^3.0.0",
+ "debug": "^4.1.1",
+ "glob-to-regexp": "^0.4.0",
+ "is-subset": "^0.1.1",
+ "lodash.isequal": "^4.5.0",
+ "path-to-regexp": "^2.2.1",
+ "querystring": "^0.2.0",
+ "whatwg-url": "^6.5.0"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
+ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ }
+ }
+ },
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@@ -16171,12 +16587,6 @@
"write": "1.0.3"
}
},
- "flatmap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/flatmap/-/flatmap-0.0.3.tgz",
- "integrity": "sha1-Hxik2TgVLUlZZfnJWNkjqy3WabQ=",
- "dev": true
- },
"flatpickr": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.3.tgz",
@@ -16279,12 +16689,6 @@
"readable-stream": "^2.0.0"
}
},
- "fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true
- },
"fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
@@ -16407,15 +16811,11 @@
"dev": true
},
"fsevents": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
- "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"dev": true,
- "optional": true,
- "requires": {
- "bindings": "^1.5.0",
- "nan": "^2.12.1"
- }
+ "optional": true
},
"function-bind": {
"version": "1.1.1",
@@ -16485,6 +16885,12 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
+ "get-iterator": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz",
+ "integrity": "sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==",
+ "dev": true
+ },
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
@@ -16581,6 +16987,12 @@
}
}
},
+ "glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
"global": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
@@ -17317,9 +17729,9 @@
"dev": true
},
"ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz",
+ "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==",
"dev": true
},
"ipaddr.js": {
@@ -17336,89 +17748,68 @@
"requires": {
"cids": "~0.7.0",
"class-is": "^1.1.0"
- },
- "dependencies": {
- "cids": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.1.tgz",
- "integrity": "sha512-qEM4j2GKE/BiT6WdUi6cfW8dairhSLTUE8tIdxJG6SvY33Mp/UPjw+xcO0n1zsllgo72BupzKF/44v+Bg8YPPg==",
- "dev": true,
- "requires": {
- "class-is": "^1.1.0",
- "multibase": "~0.6.0",
- "multicodec": "~0.5.1",
- "multihashes": "~0.4.14"
- }
- }
}
},
"ipfs-http-client": {
- "version": "30.1.4",
- "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-30.1.4.tgz",
- "integrity": "sha512-ordvoPT3lAFL5qsvdYBeDGRP03gtbL6Jl+qJ9dztyhE7NJf2yhtnU3ZNqN1JMCcUK0qpGsDzX89t8dKQvI80Pw==",
+ "version": "41.0.1",
+ "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-41.0.1.tgz",
+ "integrity": "sha512-oyH0hXoB+jfz4NqM+SZSpk6c9wR+9uvUO+/0eQFT6B9Ludz4zR8T5MHo7bnQoVerj9Qlv0x0wO1ckSoekaSPpw==",
"dev": true,
"requires": {
- "async": "^2.6.1",
- "bignumber.js": "^8.0.2",
- "bl": "^3.0.0",
+ "abort-controller": "^3.0.0",
+ "async-iterator-to-pull-stream": "^1.3.0",
+ "bignumber.js": "^9.0.0",
+ "bl": "^4.0.0",
"bs58": "^4.0.1",
- "buffer": "^5.2.1",
- "cids": "~0.5.5",
- "concat-stream": "github:hugomrdias/concat-stream#feat/smaller",
+ "buffer": "^5.4.2",
+ "callbackify": "^1.1.0",
+ "cids": "~0.7.1",
"debug": "^4.1.0",
- "detect-node": "^2.0.4",
- "end-of-stream": "^1.4.1",
- "err-code": "^1.1.2",
- "flatmap": "0.0.3",
- "glob": "^7.1.3",
- "ipfs-block": "~0.8.0",
- "ipld-dag-cbor": "~0.13.1",
- "ipld-dag-pb": "~0.15.3",
- "is-ipfs": "~0.6.0",
- "is-pull-stream": "0.0.0",
- "is-stream": "^1.1.0",
- "iso-stream-http": "~0.1.2",
- "iso-url": "~0.4.6",
- "just-kebab-case": "^1.1.0",
- "just-map-keys": "^1.1.0",
- "lru-cache": "^5.1.1",
+ "err-code": "^2.0.0",
+ "explain-error": "^1.0.4",
+ "form-data": "^3.0.0",
+ "ipfs-block": "~0.8.1",
+ "ipfs-utils": "^0.4.2",
+ "ipld-dag-cbor": "~0.15.0",
+ "ipld-dag-pb": "^0.18.1",
+ "ipld-raw": "^4.0.0",
+ "is-ipfs": "~0.6.1",
+ "it-all": "^1.0.1",
+ "it-glob": "0.0.7",
+ "it-tar": "^1.1.1",
+ "it-to-stream": "^0.1.1",
+ "iterable-ndjson": "^1.1.0",
+ "ky": "^0.15.0",
+ "ky-universal": "^0.3.0",
+ "merge-options": "^2.0.0",
"multiaddr": "^6.0.6",
+ "multiaddr-to-uri": "^5.0.0",
"multibase": "~0.6.0",
- "multicodec": "~0.5.0",
+ "multicodec": "^1.0.0",
"multihashes": "~0.4.14",
- "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3",
- "once": "^1.4.0",
- "peer-id": "~0.12.2",
+ "parse-duration": "^0.1.1",
+ "peer-id": "~0.12.3",
"peer-info": "~0.15.1",
- "promisify-es6": "^1.0.3",
- "pull-defer": "~0.2.3",
- "pull-stream": "^3.6.9",
- "pull-to-stream": "~0.1.1",
- "pump": "^3.0.0",
- "qs": "^6.5.2",
- "readable-stream": "^3.1.1",
- "stream-to-pull-stream": "^1.7.2",
- "tar-stream": "^2.0.1",
- "through2": "^3.0.1"
+ "promise-nodeify": "^3.0.1"
},
"dependencies": {
"buffer": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
- "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
- "concat-stream": {
- "version": "github:hugomrdias/concat-stream#057bc7b5d6d8df26c8cf00a3f151b6721a0a8034",
- "from": "github:hugomrdias/concat-stream#feat/smaller",
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
- "inherits": "^2.0.3",
- "readable-stream": "^3.0.2"
+ "delayed-stream": "~1.0.0"
}
},
"debug": {
@@ -17430,42 +17821,87 @@
"ms": "^2.1.1"
}
},
- "lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "form-data": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
+ "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
"dev": true,
"requires": {
- "yallist": "^3.0.2"
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
}
},
- "minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
- "dev": true
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
- },
- "ndjson": {
- "version": "github:hugomrdias/ndjson#4db16da6b42e5b39bf300c3a7cde62abb3fa3a11",
- "from": "github:hugomrdias/ndjson#feat/readable-stream3",
+ }
+ }
+ },
+ "ipfs-utils": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-0.4.2.tgz",
+ "integrity": "sha512-k/uNOniniqg7uCnHvmujis8ASNefn0url8GS7HaNLAhL3RV3dHBiibtQFp8JZ/zfN+80FrYJt7cPEzRbGbmJUA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.2.1",
+ "err-code": "^2.0.0",
+ "fs-extra": "^8.1.0",
+ "is-buffer": "^2.0.3",
+ "is-electron": "^2.2.0",
+ "is-pull-stream": "0.0.0",
+ "is-stream": "^2.0.0",
+ "it-glob": "0.0.7",
+ "kind-of": "^6.0.2",
+ "pull-stream-to-async-iterator": "^1.0.2",
+ "readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"requires": {
- "json-stringify-safe": "^5.0.1",
- "minimist": "^1.2.0",
- "split2": "^3.1.0",
- "through2": "^3.0.0"
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
}
},
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
"readable-stream": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
@@ -17474,9 +17910,9 @@
}
},
"safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"string_decoder": {
@@ -17487,49 +17923,139 @@
"requires": {
"safe-buffer": "~5.2.0"
}
- },
- "through2": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
- "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
- "dev": true,
- "requires": {
- "readable-stream": "2 || 3"
- }
}
}
},
"ipld-dag-cbor": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/ipld-dag-cbor/-/ipld-dag-cbor-0.13.1.tgz",
- "integrity": "sha512-96KKh5XUq9LrWE/TQ/BOJ5FcQx7UZ892N76ufDdovq+fIwZ4/YpPRTAVssLUuN3crATHoGu80TVZMgevsuTCdQ==",
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/ipld-dag-cbor/-/ipld-dag-cbor-0.15.3.tgz",
+ "integrity": "sha512-m23nG7ZyoVFnkK55/bLAErc7EfiMgaEQlqHWDTGzPI+O5r6bPfp+qbL5zTVSIT8tpbHmu174dwerVtLoVgeVyA==",
"dev": true,
"requires": {
- "borc": "^2.1.0",
- "bs58": "^4.0.1",
- "cids": "~0.5.5",
+ "borc": "^2.1.2",
+ "buffer": "^5.5.0",
+ "cids": "~0.8.0",
"is-circular": "^1.0.2",
- "multihashes": "~0.4.14",
- "multihashing-async": "~0.5.1",
- "traverse": "~0.6.6"
+ "multicodec": "^1.0.0",
+ "multihashing-async": "~0.8.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "cids": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz",
+ "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "class-is": "^1.1.0",
+ "multibase": "^1.0.0",
+ "multicodec": "^1.0.1",
+ "multihashes": "^1.0.1"
+ }
+ },
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ }
+ }
}
},
"ipld-dag-pb": {
- "version": "0.15.3",
- "resolved": "https://registry.npmjs.org/ipld-dag-pb/-/ipld-dag-pb-0.15.3.tgz",
- "integrity": "sha512-J1RJzSVCaOpxPmSzXbwVNsAZPHctjY4OjqG1dMIG86Z37CKvuy1QwCFkDhNccUTcQpF3sXfj5e0ZUyMM035vzg==",
+ "version": "0.18.5",
+ "resolved": "https://registry.npmjs.org/ipld-dag-pb/-/ipld-dag-pb-0.18.5.tgz",
+ "integrity": "sha512-8IAPZrkRjgTpkxV9JOwXSBe0GXNxd4B2lubPgbifTGL92rZOEKWutpijsWsWvjXOltDFHKMQIIIhkgLC5RPqbA==",
"dev": true,
"requires": {
- "async": "^2.6.1",
- "bs58": "^4.0.1",
- "cids": "~0.5.4",
+ "buffer": "^5.6.0",
+ "cids": "~0.8.0",
"class-is": "^1.1.0",
- "is-ipfs": "~0.6.0",
- "multihashing-async": "~0.5.1",
- "protons": "^1.0.1",
- "pull-stream": "^3.6.9",
- "pull-traverse": "^1.0.3",
- "stable": "~0.1.8"
+ "multicodec": "^1.0.1",
+ "multihashing-async": "~0.8.1",
+ "protons": "^1.0.2",
+ "stable": "^0.1.8"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "cids": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz",
+ "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "class-is": "^1.1.0",
+ "multibase": "^1.0.0",
+ "multicodec": "^1.0.1",
+ "multihashes": "^1.0.1"
+ }
+ },
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ }
+ }
+ }
+ },
+ "ipld-raw": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/ipld-raw/-/ipld-raw-4.0.1.tgz",
+ "integrity": "sha512-WjIdtZ06jJEar8zh+BHB84tE6ZdbS/XNa7+XCArOYfmeJ/c01T9VQpeMwdJQYn5c3s5UvvCu7y4VIi3vk2g1bA==",
+ "dev": true,
+ "requires": {
+ "cids": "~0.7.0",
+ "multicodec": "^1.0.0",
+ "multihashing-async": "~0.8.0"
}
},
"is-accessor-descriptor": {
@@ -17625,6 +18151,12 @@
}
}
},
+ "is-electron": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.0.tgz",
+ "integrity": "sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q==",
+ "dev": true
+ },
"is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -17687,38 +18219,110 @@
"dev": true
},
"is-ip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz",
- "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz",
+ "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==",
"dev": true,
"requires": {
- "ip-regex": "^2.0.0"
+ "ip-regex": "^4.0.0"
}
},
"is-ipfs": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/is-ipfs/-/is-ipfs-0.6.1.tgz",
- "integrity": "sha512-WhqQylam6pODS2RyqT/u0PR5KWtBZNCgPjgargFOVQjzw/3+6d0midXenzU65klM4LH13IUiCC6ObhDUdXZ7Nw==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/is-ipfs/-/is-ipfs-0.6.3.tgz",
+ "integrity": "sha512-HyRot1dvLcxImtDqPxAaY1miO6WsiP/z7Yxpg2qpaLWv5UdhAPtLvHJ4kMLM0w8GSl8AFsVF23PHe1LzuWrUlQ==",
"dev": true,
"requires": {
"bs58": "^4.0.1",
"cids": "~0.7.0",
- "mafmt": "^6.0.7",
- "multiaddr": "^6.0.4",
+ "mafmt": "^7.0.0",
+ "multiaddr": "^7.2.1",
"multibase": "~0.6.0",
"multihashes": "~0.4.13"
},
"dependencies": {
- "cids": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.1.tgz",
- "integrity": "sha512-qEM4j2GKE/BiT6WdUi6cfW8dairhSLTUE8tIdxJG6SvY33Mp/UPjw+xcO0n1zsllgo72BupzKF/44v+Bg8YPPg==",
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "multiaddr": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-7.5.0.tgz",
+ "integrity": "sha512-GvhHsIGDULh06jyb6ev+VfREH9evJCFIRnh3jUt9iEZ6XDbyoisZRFEI9bMvK/AiR6y66y6P+eoBw9mBYMhMvw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "cids": "~0.8.0",
"class-is": "^1.1.0",
- "multibase": "~0.6.0",
- "multicodec": "~0.5.1",
- "multihashes": "~0.4.14"
+ "is-ip": "^3.1.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "cids": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz",
+ "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "class-is": "^1.1.0",
+ "multibase": "^1.0.0",
+ "multicodec": "^1.0.1",
+ "multihashes": "^1.0.1"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ },
+ "multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ }
}
}
}
@@ -17770,6 +18374,12 @@
"isobject": "^3.0.1"
}
},
+ "is-promise": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz",
+ "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=",
+ "dev": true
+ },
"is-pull-stream": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/is-pull-stream/-/is-pull-stream-0.0.0.tgz",
@@ -17805,6 +18415,12 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
+ "is-subset": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
+ "dev": true
+ },
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
@@ -17865,27 +18481,36 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
- "iso-random-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/iso-random-stream/-/iso-random-stream-1.1.0.tgz",
- "integrity": "sha512-ywSWt0KrWcsaK0jVoVJIR30rLyjg9Rw3k2Sm/qp+3tdtSV0SNH7L7KilKnENcENOSoJxDFvpt2idvuMMQohdCQ==",
+ "iso-constants": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/iso-constants/-/iso-constants-0.1.2.tgz",
+ "integrity": "sha512-OTCM5ZCQsHBCI4Wdu4tSxvDIkmDHd5EwJDps5mKqnQnWJSKlnwMs3EDZ4n3Fh1tmkWkDlyd2vCDbEYuPbyrUNQ==",
"dev": true
},
- "iso-stream-http": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/iso-stream-http/-/iso-stream-http-0.1.2.tgz",
- "integrity": "sha512-oHEDNOysIMTNypbg2f1SlydqRBvjl4ZbSE9+0awVxnkx3K2stGTFwB/kpVqnB6UEfF8QD36kAjDwZvqyXBLMnQ==",
+ "iso-random-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/iso-random-stream/-/iso-random-stream-1.1.1.tgz",
+ "integrity": "sha512-YEt/7xOwTdu4KXIgtdgGFkiLUsBaddbnkmHyaFdjJYIcD7V4gpQHPvYC5tyh3kA0PQ01y9lWm1ruVdf8Mqzovg==",
"dev": true,
"requires": {
- "builtin-status-codes": "^3.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^3.1.1"
+ "buffer": "^5.4.3",
+ "readable-stream": "^3.4.0"
},
"dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
"readable-stream": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
@@ -17894,9 +18519,9 @@
}
},
"safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"string_decoder": {
@@ -17911,9 +18536,9 @@
}
},
"iso-url": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.6.tgz",
- "integrity": "sha512-YQO7+aIe6l1aSJUKOx+Vrv08DlhZeLFIVfehG2L29KLSEb9RszqPXilxJRVpp57px36BddKR5ZsebacO5qG0tg==",
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz",
+ "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==",
"dev": true
},
"isobject": {
@@ -17949,6 +18574,163 @@
"is-object": "^1.0.1"
}
},
+ "it-all": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.2.tgz",
+ "integrity": "sha512-3hrCLLcuHS1/VUn1qETPuh9rFTw31SBCUUijjs41VJ+oQGx3H+3Lpxo1bFD3q3570w3o99a+sfRGic5PBBt3Vg==",
+ "dev": true
+ },
+ "it-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/it-concat/-/it-concat-1.0.0.tgz",
+ "integrity": "sha512-mLhiCB3tW4NTYTg7bMlyYX2c782KsAacthHMR3y5kjJn9JhNFb02NcH70KZuNrSXFSTq8k6m8MiYaQWRjrDxAA==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.0.0"
+ }
+ },
+ "it-glob": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/it-glob/-/it-glob-0.0.7.tgz",
+ "integrity": "sha512-XfbziJs4fi0MfdEGTLkZXeqo2EorF2baFXxFn1E2dGbgYMhFTZlZ2Yn/mx5CkpuLWVJvO1DwtTOVW2mzRyVK8w==",
+ "dev": true,
+ "requires": {
+ "fs-extra": "^8.1.0",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ }
+ }
+ },
+ "it-reader": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/it-reader/-/it-reader-2.1.0.tgz",
+ "integrity": "sha512-hSysqWTO9Tlwc5EGjVf8JYZzw0D2FsxD/g+eNNWrez9zODxWt6QlN6JAMmycK72Mv4jHEKEXoyzUN4FYGmJaZw==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.0.0"
+ }
+ },
+ "it-tar": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/it-tar/-/it-tar-1.2.2.tgz",
+ "integrity": "sha512-M8V4a9I+x/vwXTjqvixcEZbQZHjwDIb8iUQ+D4M2QbhAdNs3WKVSl+45u5/F2XFx6jYMFOGzMVlKNK/uONgNIA==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.0.0",
+ "buffer": "^5.4.3",
+ "iso-constants": "^0.1.2",
+ "it-concat": "^1.0.0",
+ "it-reader": "^2.0.0",
+ "p-defer": "^3.0.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ }
+ }
+ },
+ "it-to-stream": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/it-to-stream/-/it-to-stream-0.1.1.tgz",
+ "integrity": "sha512-QQx/58JBvT189imr6fD234F8aVf8EdyQHJR0MxXAOShEWK1NWyahPYIQt/tQG7PId0ZG/6/3tUiVCfw2cq+e1w==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.2.1",
+ "fast-fifo": "^1.0.0",
+ "get-iterator": "^1.0.2",
+ "p-defer": "^3.0.0",
+ "p-fifo": "^1.0.0",
+ "readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
+ "iterable-ndjson": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/iterable-ndjson/-/iterable-ndjson-1.1.0.tgz",
+ "integrity": "sha512-OOp1Lb0o3k5MkXHx1YaIY5Z0ELosZfTnBaas9f8opJVcZGBIONA2zY/6CYE+LKkqrSDooIneZbrBGgOZnHPkrg==",
+ "dev": true,
+ "requires": {
+ "string_decoder": "^1.2.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
"jquery": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
@@ -18127,18 +18909,6 @@
"verror": "1.10.0"
}
},
- "just-kebab-case": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/just-kebab-case/-/just-kebab-case-1.1.0.tgz",
- "integrity": "sha512-QkuwuBMQ9BQHMUEkAtIA4INLrkmnnveqlFB1oFi09gbU0wBdZo6tTnyxNWMR84zHxBuwK7GLAwqN8nrvVxOLTA==",
- "dev": true
- },
- "just-map-keys": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/just-map-keys/-/just-map-keys-1.1.0.tgz",
- "integrity": "sha512-oNKi+4y7fr8lXnhKYpBbCkiwHRVkAnx0VDkCeTDtKKMzGr1Lz1Yym+RSieKUTKim68emC5Yxrb4YmiF9STDO+g==",
- "dev": true
- },
"keypair": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/keypair/-/keypair-1.0.1.tgz",
@@ -18161,79 +18931,31 @@
"dev": true
},
"kredits-contracts": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/kredits-contracts/-/kredits-contracts-5.5.0.tgz",
- "integrity": "sha512-kiiKySe7plOeywiJv+0E2MfUxQ56yTUamrQzVqLjyTssHWtjv7Nv+/EoYnVXgWHBcGouh02QzmxrYJYpAAS6Ig==",
+ "version": "github:67P/kredits-contracts#c63fcc002b05c5907d3f1ebd9487ee074e80d6e9",
+ "from": "github:67P/kredits-contracts#feature/expenses",
"dev": true,
"requires": {
- "ethers": "^4.0.29",
- "ipfs-http-client": "^30.1.3",
- "kosmos-schemas": "^2.1.0",
+ "@kosmos/schemas": "^3.0.0",
+ "ethers": "^4.0.47",
+ "ipfs-http-client": "^41.0.1",
"node-fetch": "^2.6.0",
"tv4": "^1.3.0"
- },
- "dependencies": {
- "@types/node": {
- "version": "10.14.18",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.18.tgz",
- "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ==",
- "dev": true
- },
- "elliptic": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz",
- "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=",
- "dev": true,
- "requires": {
- "bn.js": "^4.4.0",
- "brorand": "^1.0.1",
- "hash.js": "^1.0.0",
- "inherits": "^2.0.1"
- }
- },
- "ethers": {
- "version": "4.0.37",
- "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.37.tgz",
- "integrity": "sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw==",
- "dev": true,
- "requires": {
- "@types/node": "^10.3.2",
- "aes-js": "3.0.0",
- "bn.js": "^4.4.0",
- "elliptic": "6.3.3",
- "hash.js": "1.1.3",
- "js-sha3": "0.5.7",
- "scrypt-js": "2.0.4",
- "setimmediate": "1.0.4",
- "uuid": "2.0.1",
- "xmlhttprequest": "1.8.0"
- }
- },
- "hash.js": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
- "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "minimalistic-assert": "^1.0.0"
- }
- },
- "kosmos-schemas": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/kosmos-schemas/-/kosmos-schemas-2.1.0.tgz",
- "integrity": "sha512-RT90o0ujAKoCUpcYHi5ijDxg9F9enY5aOIZXujidjkCQ/hgjJ2tyNi+x8rszutsAP/mx64yj307oWJWhNZTyTg==",
- "dev": true,
- "requires": {
- "brfs-babel": "^1.0.0"
- }
- },
- "uuid": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
- "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=",
- "dev": true
- }
+ }
+ },
+ "ky": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/ky/-/ky-0.15.0.tgz",
+ "integrity": "sha512-6IlJRPFHq4ZKRRa9lyh6YqHqlmddAkfyXI9CYvZpLQtg7fQvwncPHyHrmtXAHKCqHOilINPMT88eW6FTA3HwkA==",
+ "dev": true
+ },
+ "ky-universal": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.3.0.tgz",
+ "integrity": "sha512-CM4Bgb2zZZpsprcjI6DNYTaH3oGHXL2u7BU4DK+lfCuC4snkt9/WRpMYeKbBbXscvKkeqBwzzjFX2WwmKY5K/A==",
+ "dev": true,
+ "requires": {
+ "abort-controller": "^3.0.0",
+ "node-fetch": "^2.6.0"
}
},
"leek": {
@@ -18273,9 +18995,9 @@
}
},
"libp2p-crypto": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.16.1.tgz",
- "integrity": "sha512-+fxqy+cDjwOKK4KTj44WQmjPE5ep2eR5uAIQWHl/+RKvRSor3+RAY53VWkAecgAEvjX2AswxBsoCIJK1Qk5aIQ==",
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.16.3.tgz",
+ "integrity": "sha512-ro7/5Tu+f8p2+qDS1JrROnO++nNaAaBFs+VVXVHLuTMnbnMASu1eUtSlWPk1uOwikAlBFTvfqe5J1bK6Bpq6Pg==",
"dev": true,
"requires": {
"asmcrypto.js": "^2.3.2",
@@ -18288,29 +19010,49 @@
"keypair": "^1.0.1",
"libp2p-crypto-secp256k1": "~0.3.0",
"multihashing-async": "~0.5.1",
- "node-forge": "~0.7.6",
+ "node-forge": "~0.9.1",
"pem-jwk": "^2.0.0",
"protons": "^1.0.1",
"rsa-pem-to-jwk": "^1.1.3",
"tweetnacl": "^1.0.0",
- "ursa-optional": "~0.9.10"
+ "ursa-optional": "~0.10.0"
},
"dependencies": {
"asn1.js": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz",
- "integrity": "sha512-Q7hnYGGNYbcmGrCPulXfkEw7oW7qjWeM4ZTALmgpuIcZLxyqqKYWxCZg2UBm8bklrnB4m2mGyJPWfoktdORD8A==",
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
"dev": true,
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+ "dev": true
+ },
+ "multihashing-async": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-0.5.2.tgz",
+ "integrity": "sha512-mmyG6M/FKxrpBh9xQDUvuJ7BbqT93ZeEeH5X6LeMYKoYshYLr9BDdCsvDtZvn+Egf+/Xi+aOznrWL4vp3s+p0Q==",
+ "dev": true,
+ "requires": {
+ "blakejs": "^1.1.0",
+ "js-sha3": "~0.8.0",
+ "multihashes": "~0.4.13",
+ "murmurhash3js": "^3.0.1",
+ "nodeify": "^1.0.1"
}
},
"tweetnacl": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz",
- "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
"dev": true
}
}
@@ -18822,6 +19564,12 @@
"integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
"dev": true
},
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+ "dev": true
+ },
"lodash.isfunction": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz",
@@ -18991,12 +19739,6 @@
}
}
},
- "looper": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
- "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=",
- "dev": true
- },
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -19039,12 +19781,96 @@
}
},
"mafmt": {
- "version": "6.0.10",
- "resolved": "https://registry.npmjs.org/mafmt/-/mafmt-6.0.10.tgz",
- "integrity": "sha512-FjHDnew6dW9lUu3eYwP0FvvJl9uvNbqfoJM+c1WJcSyutNEIlyu6v3f/rlPnD1cnmue38IjuHlhBdIh3btAiyw==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/mafmt/-/mafmt-7.1.0.tgz",
+ "integrity": "sha512-vpeo9S+hepT3k2h5iFxzEHvvR0GPBx9uKaErmnRzYNcaKb03DgOArjEMlgG4a9LcuZZ89a3I8xbeto487n26eA==",
"dev": true,
"requires": {
- "multiaddr": "^6.1.0"
+ "multiaddr": "^7.3.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "cids": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz",
+ "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "class-is": "^1.1.0",
+ "multibase": "^1.0.0",
+ "multicodec": "^1.0.1",
+ "multihashes": "^1.0.1"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ },
+ "multiaddr": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-7.5.0.tgz",
+ "integrity": "sha512-GvhHsIGDULh06jyb6ev+VfREH9evJCFIRnh3jUt9iEZ6XDbyoisZRFEI9bMvK/AiR6y66y6P+eoBw9mBYMhMvw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "cids": "~0.8.0",
+ "class-is": "^1.1.0",
+ "is-ip": "^3.1.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ }
}
},
"magic-string": {
@@ -19238,6 +20064,23 @@
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
"dev": true
},
+ "merge-options": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz",
+ "integrity": "sha512-S7xYIeWHl2ZUKF7SDeBhGg6rfv5bKxVBdk95s/I7wVF8d+hjLSztJ/B271cnUiF6CAFduEQ5Zn3HYwAjT16DlQ==",
+ "dev": true,
+ "requires": {
+ "is-plain-obj": "^2.0.0"
+ },
+ "dependencies": {
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true
+ }
+ }
+ },
"merge-source-map": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
@@ -19525,65 +20368,245 @@
"ip": "^1.1.5",
"is-ip": "^2.0.0",
"varint": "^5.0.0"
+ },
+ "dependencies": {
+ "ip-regex": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+ "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "dev": true
+ },
+ "is-ip": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz",
+ "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=",
+ "dev": true,
+ "requires": {
+ "ip-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "multiaddr-to-uri": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/multiaddr-to-uri/-/multiaddr-to-uri-5.1.0.tgz",
+ "integrity": "sha512-rIlMLkw3yk3RJmf2hxYYzeqPXz4Vx7C4M/hg7BVWhmksDW0rDVNMEyoVb0H1A+sh3deHOh5EAFK87XcW+mFimA==",
+ "dev": true,
+ "requires": {
+ "multiaddr": "^7.2.1"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "cids": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz",
+ "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "class-is": "^1.1.0",
+ "multibase": "^1.0.0",
+ "multicodec": "^1.0.1",
+ "multihashes": "^1.0.1"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ },
+ "multiaddr": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-7.5.0.tgz",
+ "integrity": "sha512-GvhHsIGDULh06jyb6ev+VfREH9evJCFIRnh3jUt9iEZ6XDbyoisZRFEI9bMvK/AiR6y66y6P+eoBw9mBYMhMvw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "cids": "~0.8.0",
+ "class-is": "^1.1.0",
+ "is-ip": "^3.1.0",
+ "multibase": "^0.7.0",
+ "varint": "^5.0.0"
+ }
+ },
+ "multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ },
+ "dependencies": {
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
+ }
+ }
}
},
"multibase": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.0.tgz",
- "integrity": "sha512-R9bNLQhbD7MsitPm1NeY7w9sDgu6d7cuj25snAWH7k5PSNPSwIQQBpcpj8jx1W96dLbdigZqmUWOdQRMnAmgjA==",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz",
+ "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==",
"dev": true,
"requires": {
- "base-x": "3.0.4"
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
},
"dependencies": {
- "base-x": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz",
- "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==",
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"requires": {
- "safe-buffer": "^5.0.1"
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
}
}
}
},
"multicodec": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.5.tgz",
- "integrity": "sha512-1kOifvwAqp9IdiiTKmpK2tS+LY6GHZdKpk3S2EvW4T32vlwDyA3hJoZtGauzqdedUPVNGChnTksEotVOCVlC+Q==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.3.tgz",
+ "integrity": "sha512-8G4JKbHWSe/39Xx2uiI+/b/S6mGgimzwEN4TOCokFUIfofg1T8eHny88ht9eWImD2dng+EEQRsApXxA5ubhU4g==",
"dev": true,
"requires": {
+ "buffer": "^5.6.0",
"varint": "^5.0.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ }
}
},
"multihashes": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.15.tgz",
- "integrity": "sha512-G/Smj1GWqw1RQP3dRuRRPe3oyLqvPqUaEDIaoi7JF7Loxl4WAWvhJNk84oyDEodSucv0MmSW/ZT0RKUrsIFD3g==",
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz",
+ "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==",
"dev": true,
"requires": {
- "bs58": "^4.0.1",
+ "buffer": "^5.5.0",
+ "multibase": "^0.7.0",
"varint": "^5.0.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "multibase": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz",
+ "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ }
}
},
"multihashing-async": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-0.5.2.tgz",
- "integrity": "sha512-mmyG6M/FKxrpBh9xQDUvuJ7BbqT93ZeEeH5X6LeMYKoYshYLr9BDdCsvDtZvn+Egf+/Xi+aOznrWL4vp3s+p0Q==",
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-0.8.2.tgz",
+ "integrity": "sha512-2lKa1autuCy8x7KIEj9aVNbAb3aIMRFYIwN7mq/zD4pxgNIVgGlm+f6GKY4880EOF2Y3GktHYssRy7TAJQ2DyQ==",
"dev": true,
"requires": {
"blakejs": "^1.1.0",
- "js-sha3": "~0.8.0",
- "multihashes": "~0.4.13",
- "murmurhash3js": "^3.0.1",
- "nodeify": "^1.0.1"
+ "buffer": "^5.4.3",
+ "err-code": "^2.0.0",
+ "js-sha3": "^0.8.0",
+ "multihashes": "^1.0.1",
+ "murmurhash3js-revisited": "^3.0.0"
},
"dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
"js-sha3": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
"dev": true
+ },
+ "multibase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz",
+ "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.8",
+ "buffer": "^5.5.0"
+ }
+ },
+ "multihashes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz",
+ "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.6.0",
+ "multibase": "^1.0.1",
+ "varint": "^5.0.0"
+ }
}
}
},
@@ -19593,6 +20616,12 @@
"integrity": "sha1-Ppg+W0fCoG9DpxMXTn5DXKBEuZg=",
"dev": true
},
+ "murmurhash3js-revisited": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz",
+ "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==",
+ "dev": true
+ },
"mustache": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz",
@@ -19605,12 +20634,6 @@
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true
},
- "nan": {
- "version": "2.13.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
- "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
- "dev": true
- },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -19707,9 +20730,9 @@
"dev": true
},
"node-forge": {
- "version": "0.7.6",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz",
- "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==",
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz",
+ "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==",
"dev": true
},
"node-int64": {
@@ -19825,14 +20848,6 @@
"requires": {
"is-promise": "~1.0.0",
"promise": "~1.3.0"
- },
- "dependencies": {
- "is-promise": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz",
- "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=",
- "dev": true
- }
}
},
"nopt": {
@@ -20244,6 +21259,15 @@
"mimic-fn": "^2.1.0"
}
},
+ "optimist": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+ "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
+ "dev": true,
+ "requires": {
+ "wordwrap": "~0.0.2"
+ }
+ },
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
@@ -20400,6 +21424,16 @@
"integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==",
"dev": true
},
+ "p-fifo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-fifo/-/p-fifo-1.0.0.tgz",
+ "integrity": "sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==",
+ "dev": true,
+ "requires": {
+ "fast-fifo": "^1.0.0",
+ "p-defer": "^3.0.0"
+ }
+ },
"p-finally": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
@@ -20493,6 +21527,12 @@
"safe-buffer": "^5.1.1"
}
},
+ "parse-duration": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.3.tgz",
+ "integrity": "sha512-hMOZHfUmjxO5hMKn7Eft+ckP2M4nV4yzauLXiw3PndpkASnx5r8pDAMcOAiqxoemqWjMWmz4fOHQM6n6WwETXw==",
+ "dev": true
+ },
"parse-headers": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz",
@@ -20641,9 +21681,9 @@
}
},
"peer-id": {
- "version": "0.12.4",
- "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.12.4.tgz",
- "integrity": "sha512-AIAwL/6CmVc/VKbUhpA1rY3A/VJ3Z9ELvtvDQfl5cIi0A74L7lvsJ6LxQn5JSJVHM5Us2Ng9zMO523dO3FFnnw==",
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/peer-id/-/peer-id-0.12.5.tgz",
+ "integrity": "sha512-3xVWrtIvNm9/OPzaQBgXDrfWNx63AftgFQkvqO6YSZy7sP3Fuadwwbn54F/VO9AnpyW/26i0WRQz9FScivXrmw==",
"dev": true,
"requires": {
"async": "^2.6.3",
@@ -20673,6 +21713,17 @@
"multiaddr": "^6.0.3",
"peer-id": "~0.12.2",
"unique-by": "^1.0.0"
+ },
+ "dependencies": {
+ "mafmt": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/mafmt/-/mafmt-6.0.10.tgz",
+ "integrity": "sha512-FjHDnew6dW9lUu3eYwP0FvvJl9uvNbqfoJM+c1WJcSyutNEIlyu6v3f/rlPnD1cnmue38IjuHlhBdIh3btAiyw==",
+ "dev": true,
+ "requires": {
+ "multiaddr": "^6.1.0"
+ }
+ }
}
},
"pem-jwk": {
@@ -20685,14 +21736,15 @@
},
"dependencies": {
"asn1.js": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz",
- "integrity": "sha512-Q7hnYGGNYbcmGrCPulXfkEw7oW7qjWeM4ZTALmgpuIcZLxyqqKYWxCZg2UBm8bklrnB4m2mGyJPWfoktdORD8A==",
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
"dev": true,
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
}
}
}
@@ -20923,14 +21975,6 @@
"dev": true,
"requires": {
"is-promise": "~1"
- },
- "dependencies": {
- "is-promise": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz",
- "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=",
- "dev": true
- }
}
},
"promise-inflight": {
@@ -20948,34 +21992,46 @@
"rsvp": "^3.0.14"
}
},
+ "promise-nodeify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/promise-nodeify/-/promise-nodeify-3.0.1.tgz",
+ "integrity": "sha512-ghsSuzZXJX8iO7WVec2z7GI+Xk/EyiD+JZK7AZKhUqYfpLa/Zs4ylUD+CwwnKlG6G3HnkUPMAi6PO7zeqGKssg==",
+ "dev": true
+ },
"promise.hash.helper": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/promise.hash.helper/-/promise.hash.helper-1.0.7.tgz",
"integrity": "sha512-0qhWYyCV9TYDMSooYw1fShIb7R6hsWYja7JLqbeb1MvHqDTvP/uy/R1RsyVqDi6GCiHOI4G5p2Hpr3IA+/l/+Q==",
"dev": true
},
- "promisify-es6": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/promisify-es6/-/promisify-es6-1.0.3.tgz",
- "integrity": "sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA==",
- "dev": true
- },
"protocol-buffers-schema": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz",
- "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.4.0.tgz",
+ "integrity": "sha512-G/2kcamPF2S49W5yaMGdIpkG6+5wZF0fzBteLKgEHjbNzqjZQ85aAs1iJGto31EJaSTkNvHs5IXuHSaTLWBAiA==",
"dev": true
},
"protons": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/protons/-/protons-1.0.1.tgz",
- "integrity": "sha512-+0ZKnfVs+4c43tbAQ5j0Mck8wPcLnlxUYzKQoB4iDW4ocdXGnN4P+0dDbgX1FTpoY9+7P2Tn2scJyHHqj+S/lQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/protons/-/protons-1.2.1.tgz",
+ "integrity": "sha512-2oqDyc/SN+tNcJf8XxrXhYL7sQn2/OMl8mSdD7NVGsWjMEmAbks4eDVnCyf0vAoRbBWyWTEXWk4D8XfuKVl3zg==",
"dev": true,
"requires": {
+ "buffer": "^5.5.0",
"protocol-buffers-schema": "^3.3.1",
- "safe-buffer": "^5.1.1",
"signed-varint": "^2.0.1",
"varint": "^5.0.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ }
}
},
"proxy-addr": {
@@ -21014,61 +22070,21 @@
"safe-buffer": "^5.1.2"
}
},
- "pull-defer": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz",
- "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==",
- "dev": true
- },
"pull-stream": {
"version": "3.6.14",
"resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz",
"integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==",
"dev": true
},
- "pull-to-stream": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pull-to-stream/-/pull-to-stream-0.1.1.tgz",
- "integrity": "sha512-thZkMv6F9PILt9zdvpI2gxs19mkDrlixYKX6cOBxAW16i1NZH+yLAmF4r8QfJ69zuQh27e01JZP9y27tsH021w==",
+ "pull-stream-to-async-iterator": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pull-stream-to-async-iterator/-/pull-stream-to-async-iterator-1.0.2.tgz",
+ "integrity": "sha512-c3KRs2EneuxP7b6pG9fvQTIjatf33RbIErhbQ75s5r2MI6E8R74NZC1nJgXc8kcmqiQxmr+TWY+WwK2mWaUnlA==",
"dev": true,
"requires": {
- "readable-stream": "^3.1.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.2.0"
- }
- }
+ "pull-stream": "^3.6.9"
}
},
- "pull-traverse": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pull-traverse/-/pull-traverse-1.0.3.tgz",
- "integrity": "sha1-dPtde+f6a9enjpeTPhmbeUWGaTg=",
- "dev": true
- },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -21885,17 +22901,6 @@
"dev": true,
"requires": {
"optimist": "~0.3.5"
- },
- "dependencies": {
- "optimist": {
- "version": "0.3.7",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
- "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
- "dev": true,
- "requires": {
- "wordwrap": "~0.0.2"
- }
- }
}
},
"rsvp": {
@@ -22111,9 +23116,9 @@
"dev": true
},
"secp256k1": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz",
- "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz",
+ "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==",
"dev": true,
"requires": {
"bindings": "^1.5.0",
@@ -22121,15 +23126,30 @@
"bn.js": "^4.11.8",
"create-hash": "^1.2.0",
"drbg.js": "^1.0.1",
- "elliptic": "^6.4.1",
+ "elliptic": "^6.5.2",
"nan": "^2.14.0",
"safe-buffer": "^5.1.2"
},
"dependencies": {
+ "elliptic": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+ "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
"nan": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
- "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
"dev": true
}
}
@@ -23098,16 +24118,6 @@
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
"dev": true
},
- "stream-to-pull-stream": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz",
- "integrity": "sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==",
- "dev": true,
- "requires": {
- "looper": "^3.0.0",
- "pull-stream": "^3.2.3"
- }
- },
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -23658,47 +24668,6 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
"dev": true
},
- "tar-stream": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
- "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
- "dev": true,
- "requires": {
- "bl": "^3.0.0",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.2.0"
- }
- }
- }
- },
"temp": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz",
@@ -24121,12 +25090,6 @@
"loader-utils": "^1.0.2"
}
},
- "traverse": {
- "version": "0.6.6",
- "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
- "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
- "dev": true
- },
"tree-sync": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/tree-sync/-/tree-sync-1.4.0.tgz",
@@ -24505,13 +25468,21 @@
"dev": true
},
"ursa-optional": {
- "version": "0.9.10",
- "resolved": "https://registry.npmjs.org/ursa-optional/-/ursa-optional-0.9.10.tgz",
- "integrity": "sha512-RvEbhnxlggX4MXon7KQulTFiJQtLJZpSb9ZSa7ZTkOW0AzqiVTaLjI4vxaSzJBDH9dwZ3ltZadFiBaZslp6haA==",
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/ursa-optional/-/ursa-optional-0.10.1.tgz",
+ "integrity": "sha512-/pgpBXVJut57dHNrdGF+1/qXi+5B7JrlmZDWPSyoivEcbwFWRZJBJGkWb6ivknMBA3bnFA7lqsb6iHiFfp79QQ==",
"dev": true,
"requires": {
- "bindings": "^1.3.0",
- "nan": "^2.11.1"
+ "bindings": "^1.5.0",
+ "nan": "^2.14.0"
+ },
+ "dependencies": {
+ "nan": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
+ "dev": true
+ }
}
},
"use": {
@@ -24790,6 +25761,16 @@
"upath": "^1.1.1"
}
},
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0"
+ }
+ },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
diff --git a/package.json b/package.json
index 8f62fc8..c755e29 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"@ember/optional-features": "^1.3.0",
"@glimmer/component": "^1.0.0",
"@glimmer/tracking": "^1.0.0",
- "@kosmos/schemas": "^2.2.1",
+ "@kosmos/schemas": "^3.0.0",
"babel-eslint": "^10.1.0",
"babel-preset-es2015": "^6.22.0",
"babelify": "^7.3.0",
@@ -49,6 +49,7 @@
"ember-cli-sri": "^2.1.1",
"ember-cli-uglify": "^3.0.0",
"ember-concurrency": "^1.1.7",
+ "ember-concurrency-decorators": "^2.0.1",
"ember-export-application-global": "^2.0.1",
"ember-fetch": "^8.0.1",
"ember-flatpickr": "^2.16.2",
@@ -66,7 +67,8 @@
"eslint-plugin-ember": "^8.5.2",
"eslint-plugin-node": "^11.1.0",
"ethers": "^4.0.47",
- "kredits-contracts": "^5.5.0",
+ "fetch-mock": "^9.10.7",
+ "kredits-contracts": "github:67P/kredits-contracts#feature/expenses",
"loader.js": "^4.7.0",
"localforage": "^1.7.3",
"ndjson": "github:hugomrdias/ndjson#feat/readable-stream3",
diff --git a/public/img/bitcoin.svg b/public/img/bitcoin.svg
new file mode 100644
index 0000000..b3fd9e3
--- /dev/null
+++ b/public/img/bitcoin.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/helpers/create-component.js b/tests/helpers/create-component.js
new file mode 100644
index 0000000..8f16dad
--- /dev/null
+++ b/tests/helpers/create-component.js
@@ -0,0 +1,8 @@
+import { getContext } from '@ember/test-helpers';
+
+export default function createComponent(lookupPath, named = {}) {
+ let { owner } = getContext();
+ let componentManager = owner.lookup('component-manager:glimmer');
+ let { class: componentClass } = owner.factoryFor(lookupPath);
+ return componentManager.createComponent(componentClass, { named });
+}
diff --git a/tests/integration/components/add-expense-item/component-test.js b/tests/integration/components/add-expense-item/component-test.js
new file mode 100644
index 0000000..7a5df8d
--- /dev/null
+++ b/tests/integration/components/add-expense-item/component-test.js
@@ -0,0 +1,15 @@
+// import { module, test } from 'qunit';
+// import { setupRenderingTest } from 'ember-qunit';
+// import { render } from '@ember/test-helpers';
+// import { hbs } from 'ember-cli-htmlbars';
+//
+// module('Integration | Component | add-expense-item', function(hooks) {
+// setupRenderingTest(hooks);
+//
+// test('it renders', async function(assert) {
+// Set any properties with this.set('myProperty', 'value');
+// Handle any actions with this.set('myAction', function(val) { ... });
+// await render(hbs` `);
+// assert.equal(this.element.textContent.trim(), '');
+// });
+// });
diff --git a/tests/integration/components/add-reimbursement/component-test.js b/tests/integration/components/add-reimbursement/component-test.js
new file mode 100644
index 0000000..a35da24
--- /dev/null
+++ b/tests/integration/components/add-reimbursement/component-test.js
@@ -0,0 +1,13 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | add-reimbursement', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it works', async function(assert) {
+ await render(hbs` `);
+ assert.ok(true);
+ });
+});
diff --git a/tests/integration/components/budget-balances/component-test.js b/tests/integration/components/budget-balances/component-test.js
new file mode 100644
index 0000000..6e6345b
--- /dev/null
+++ b/tests/integration/components/budget-balances/component-test.js
@@ -0,0 +1,13 @@
+// import { module, test } from 'qunit';
+// import { setupRenderingTest } from 'ember-qunit';
+// import { render } from '@ember/test-helpers';
+// import { hbs } from 'ember-cli-htmlbars';
+//
+// module('Integration | Component | budget-balances', function(hooks) {
+// setupRenderingTest(hooks);
+//
+// test('it renders', async function(assert) {
+// await render(hbs` `);
+// assert.equal(this.element.textContent.trim(), '');
+// });
+// });
diff --git a/tests/integration/components/reimbursement-list/component-test.js b/tests/integration/components/reimbursement-list/component-test.js
new file mode 100644
index 0000000..7c0c2aa
--- /dev/null
+++ b/tests/integration/components/reimbursement-list/component-test.js
@@ -0,0 +1,17 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | reimbursement-list', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function(assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs` `);
+
+ assert.equal(this.element.textContent.trim(), '');
+ });
+});
diff --git a/tests/integration/helpers/fmt-crypto-currency-test.js b/tests/integration/helpers/fmt-crypto-currency-test.js
new file mode 100644
index 0000000..a27bcb9
--- /dev/null
+++ b/tests/integration/helpers/fmt-crypto-currency-test.js
@@ -0,0 +1,20 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Helper | fmt-crypto-currency', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it converts Wei to ETH', async function(assert) {
+ this.set('balanceETH', '500000000000000000');
+ await render(hbs`{{fmt-crypto-currency balanceETH "ETH"}}`);
+ assert.equal(this.element.textContent.trim(), '0.5');
+ });
+
+ test('it converts Satoshis to (W)BTC', async function(assert) {
+ this.set('balanceWBTC', '117214976');
+ await render(hbs`{{fmt-crypto-currency balanceWBTC "WBTC"}}`);
+ assert.equal(this.element.textContent.trim(), '1.17214976');
+ });
+});
diff --git a/tests/integration/helpers/fmt-fiat-currency-test.js b/tests/integration/helpers/fmt-fiat-currency-test.js
new file mode 100644
index 0000000..122760a
--- /dev/null
+++ b/tests/integration/helpers/fmt-fiat-currency-test.js
@@ -0,0 +1,22 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Helper | fmt-fiat-currency', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it returns the number formatted as currency', async function(assert) {
+ this.set('amount', 13.9);
+
+ await render(hbs`{{fmt-fiat-currency this.amount}}`);
+ assert.ok(this.element.textContent.trim().match(/13.90/),
+ 'formats the number with two decimals');
+ assert.ok(this.element.textContent.trim().match(/EUR/),
+ 'using EUR by default');
+
+ await render(hbs`{{fmt-fiat-currency this.amount 'USD'}}`);
+ assert.ok(this.element.textContent.trim().match(/USD/),
+ 'using defined currency when given');
+ });
+});
diff --git a/tests/integration/helpers/sats-to-btc-test.js b/tests/integration/helpers/sats-to-btc-test.js
new file mode 100644
index 0000000..1773874
--- /dev/null
+++ b/tests/integration/helpers/sats-to-btc-test.js
@@ -0,0 +1,16 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Helper | sats-to-btc', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it converts satoshis to full BTC amounts', async function(assert) {
+ this.set('amount', '166800');
+
+ await render(hbs`{{sats-to-btc this.amount}}`);
+
+ assert.equal(this.element.textContent.trim(), '0.001668');
+ });
+});
diff --git a/tests/test-helper.js b/tests/test-helper.js
index 0382a84..808f998 100644
--- a/tests/test-helper.js
+++ b/tests/test-helper.js
@@ -2,6 +2,19 @@ import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
+import fetchMock from 'fetch-mock';
+
+fetchMock.get(`${config.corsProxy}https://www.bitstamp.net/api/v2/ticker/btceur/`, {
+ "high": "9258.43", "last": "9165.14", "timestamp": "1601455909", "bid":
+ "9159.93", "vwap": "9167.57", "volume": "1542.54764854", "low": "9080.20",
+ "ask": "9165.14", "open": "9240.84"
+});
+
+fetchMock.get(`${config.corsProxy}https://www.bitstamp.net/api/v2/ticker/btcusd/`, {
+ "high": "10865.00", "last": "10714.62", "timestamp": "1601455914", "bid":
+ "10711.31", "vwap": "10749.70", "volume": "4460.32091975", "low": "10636.66",
+ "ask": "10715.99", "open": "10840.00"
+});
setApplication(Application.create(config.APP));
diff --git a/tests/unit/components/add-reimbursement-test.js b/tests/unit/components/add-reimbursement-test.js
new file mode 100644
index 0000000..acb4da8
--- /dev/null
+++ b/tests/unit/components/add-reimbursement-test.js
@@ -0,0 +1,50 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+import createComponent from 'kredits-web/tests/helpers/create-component';
+
+const expenses = [
+ {
+ title: "Server rent",
+ description: "Dedicated server: andromeda.kosmos.org, April 2020",
+ currency: "EUR",
+ amount: 39.00,
+ date: "2020-05-06",
+ url: "https://wiki.kosmos.org/Infrastructure#Hetzner",
+ tags: ["infrastructure", "server", "hetzner"]
+ },
+ {
+ title: "Server rent",
+ description: "Dedicated server: centaurus.kosmos.org, April 2020",
+ currency: "EUR",
+ amount: 32.00,
+ date: "2020-05-06",
+ url: "https://wiki.kosmos.org/Infrastructure#Hetzner",
+ tags: ["infrastructure", "server", "hetzner"]
+ },
+ {
+ title: "Domain name kosmos.org",
+ currency: "USD",
+ amount: 59.00,
+ date: "2020-05-07",
+ tags: ["domain"]
+ }
+];
+
+module('Unit | Component | add-reimbursement', function(hooks) {
+ setupTest(hooks);
+
+ test('total sums of expenses in EUR and USD', function(assert) {
+ let component = createComponent('component:add-reimbursement');
+ component.expenses = expenses;
+ assert.equal(component.totalEUR, '71');
+ assert.equal(component.totalUSD, '59');
+ });
+
+ test('#updateTotalAmountFromFiat', async function(assert) {
+ let component = createComponent('component:add-reimbursement');
+ component.expenses = expenses;
+ await component.exchangeRates.fetchRates();
+ component.updateTotalAmountFromFiat();
+ assert.equal(component.total, '0.01323322', 'converts EUR and USD totals to BTC and rounds to 8 decimals');
+ });
+});
diff --git a/tests/unit/controllers/budget-test.js b/tests/unit/controllers/budget-test.js
new file mode 100644
index 0000000..ec61054
--- /dev/null
+++ b/tests/unit/controllers/budget-test.js
@@ -0,0 +1,12 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Controller | budget', function(hooks) {
+ setupTest(hooks);
+
+ // Replace this with your real tests.
+ test('it exists', function(assert) {
+ let controller = this.owner.lookup('controller:budget');
+ assert.ok(controller);
+ });
+});
diff --git a/tests/unit/helpers/contribution-status-test.js b/tests/unit/helpers/item-status-test.js
similarity index 84%
rename from tests/unit/helpers/contribution-status-test.js
rename to tests/unit/helpers/item-status-test.js
index f0b9f91..0496f27 100644
--- a/tests/unit/helpers/contribution-status-test.js
+++ b/tests/unit/helpers/item-status-test.js
@@ -2,11 +2,11 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import Contribution from 'kredits-web/models/contribution';
-module('Unit | Helper | contribution-status', function (hooks) {
+module('Unit | Helper | item-status', function (hooks) {
setupTest(hooks);
test('returns the appropriate status', function (assert) {
- const contributionStatus = this.owner.factoryFor('helper:contribution-status').create();
+ const contributionStatus = this.owner.factoryFor('helper:item-status').create();
const kredits = this.owner.lookup('service:kredits');
kredits.set('currentBlock', 23000);
diff --git a/tests/unit/routes/budget-test.js b/tests/unit/routes/budget-test.js
new file mode 100644
index 0000000..122704e
--- /dev/null
+++ b/tests/unit/routes/budget-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | budget', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:budget');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/routes/budget/expenses-test.js b/tests/unit/routes/budget/expenses-test.js
new file mode 100644
index 0000000..c79b55e
--- /dev/null
+++ b/tests/unit/routes/budget/expenses-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | budget/expenses', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:budget/expenses');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/routes/dashboard-test.js b/tests/unit/routes/dashboard-test.js
new file mode 100644
index 0000000..26accbd
--- /dev/null
+++ b/tests/unit/routes/dashboard-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | dashboard', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:dashboard');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/routes/reimbursements/new-test.js b/tests/unit/routes/reimbursements/new-test.js
new file mode 100644
index 0000000..e98d799
--- /dev/null
+++ b/tests/unit/routes/reimbursements/new-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | reimbursements/new', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:reimbursements/new');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/services/community-funds-test.js b/tests/unit/services/community-funds-test.js
new file mode 100644
index 0000000..8c6fad6
--- /dev/null
+++ b/tests/unit/services/community-funds-test.js
@@ -0,0 +1,12 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Service | community-funds', function(hooks) {
+ setupTest(hooks);
+
+ // Replace this with your real tests.
+ test('it exists', function(assert) {
+ let service = this.owner.lookup('service:community-funds');
+ assert.ok(service);
+ });
+});
diff --git a/tests/unit/services/exchange-rates-test.js b/tests/unit/services/exchange-rates-test.js
new file mode 100644
index 0000000..9c52d8f
--- /dev/null
+++ b/tests/unit/services/exchange-rates-test.js
@@ -0,0 +1,13 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Service | exchange-rates', function(hooks) {
+ setupTest(hooks);
+
+ test('#fetchRates', async function(assert) {
+ let service = this.owner.lookup('service:exchange-rates');
+ await service.fetchRates();
+ assert.equal(service.btceur, 9167.57, 'fetches BTCEUR from Bitstamp');
+ assert.equal(service.btcusd, 10749.70, 'fetches BTCUSD from Bitstamp');
+ });
+});
diff --git a/tests/unit/services/kredits-test.js b/tests/unit/services/kredits-test.js
index f18e067..526a5a4 100644
--- a/tests/unit/services/kredits-test.js
+++ b/tests/unit/services/kredits-test.js
@@ -49,4 +49,12 @@ module('Unit | Service | kredits', function(hooks) {
assert.equal(c3.amountUnconfirmed, 5000, 'correct amount unconfirmed');
assert.equal(c3.amountTotal, 5000, 'correct amount total');
});
+
+ test('#contributorsSorted', function(assert) {
+ let service = this.owner.lookup('service:kredits');
+ service.set('contributors', contributors);
+
+ assert.ok(service.contributorsSorted instanceof Array, 'is an array');
+ assert.equal(service.contributorsSorted[1].name, 'Manuel', 'sorts by name');
+ });
});
diff --git a/tests/unit/utils/is-valid-amount-test.js b/tests/unit/utils/is-valid-amount-test.js
new file mode 100644
index 0000000..6941c71
--- /dev/null
+++ b/tests/unit/utils/is-valid-amount-test.js
@@ -0,0 +1,22 @@
+import isValidAmount from 'kredits-web/utils/is-valid-amount';
+import { module, test } from 'qunit';
+
+module('Unit | Utility | is-valid-amount', function() {
+ test('it returns true for valid amounts', function(assert) {
+ assert.ok(isValidAmount('1'));
+ assert.ok(isValidAmount('1.0'));
+ assert.ok(isValidAmount('0.3'));
+ assert.ok(isValidAmount('0.3333923'));
+ assert.ok(isValidAmount(1));
+ assert.ok(isValidAmount(1.0));
+ assert.ok(isValidAmount(0.3));
+ assert.ok(isValidAmount(0.3333923));
+ });
+
+ test('it returns false for invalid amounts', function(assert) {
+ assert.notOk(isValidAmount('0'));
+ assert.notOk(isValidAmount(0));
+ assert.notOk(isValidAmount(''));
+ assert.notOk(isValidAmount('foo'));
+ });
+});