mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-28 19:55:53 +03:00
btc: provider/wallet setup flow
This commit is contained in:
parent
d32e78799f
commit
cc7318aaa9
@ -69,6 +69,20 @@
|
||||
++ on-watch
|
||||
|= pax=path
|
||||
^- (quip card _this)
|
||||
:: checking provider permissions before trying to subscribe
|
||||
:: terrible hack until we have cross-ship scries
|
||||
::
|
||||
?: ?=([%permitted @ ~] pax)
|
||||
:_ this
|
||||
=/ jon=json
|
||||
%+ frond:enjs:format
|
||||
%'providerStatus'
|
||||
%- pairs:enjs:format
|
||||
:~ provider+s+(scot %p our.bowl)
|
||||
permitted+b+(is-whitelisted:hc src.bowl)
|
||||
==
|
||||
[%give %fact ~ %json !>(jon)]~
|
||||
::
|
||||
?> ?=([%clients *] pax)
|
||||
?. (is-whitelisted:hc src.bowl)
|
||||
~& >>> "btc-provider: blocked client {<src.bowl>}"
|
||||
|
@ -108,6 +108,17 @@
|
||||
|= pax=path
|
||||
^- (unit (unit cage))
|
||||
?+ pax (on-peek:def pax)
|
||||
[%x %configured ~]
|
||||
=/ provider=json
|
||||
?~ prov ~
|
||||
[%s (scot %p host.u.prov)]
|
||||
=/ result=json
|
||||
%- pairs:enjs:format
|
||||
:~ [%'provider' provider]
|
||||
[%'hasWallet' b+?=(^ walts)]
|
||||
==
|
||||
``json+!>(result)
|
||||
::
|
||||
[%x %scanned ~]
|
||||
``noun+!>(scanned-wallets)
|
||||
::
|
||||
@ -135,11 +146,43 @@
|
||||
::
|
||||
%btc-provider-update
|
||||
(handle-provider-update:hc !<(update:bp q.cage.sign))
|
||||
::
|
||||
%json
|
||||
?> ?=([%permitted @ ~] wire)
|
||||
=/ who (slav %p i.t.wire)
|
||||
:_ state
|
||||
:~ [%give %fact ~[/all] cage.sign]
|
||||
[%pass wire %agent [who %btc-provider] %leave ~]
|
||||
==
|
||||
==
|
||||
[cards this]
|
||||
==
|
||||
::
|
||||
++ on-watch on-watch:def
|
||||
++ on-watch
|
||||
|= =path
|
||||
^- (quip card _this)
|
||||
?> (team:title our.bowl src.bowl)
|
||||
?> ?=([%all ~] path)
|
||||
=/ provider=json
|
||||
?~ prov ~
|
||||
[%s (scot %p host.u.prov)]
|
||||
=/ cb=(unit sats) current-balance:hc
|
||||
=/ wallet=json
|
||||
?~ walts ~
|
||||
%- pairs:enjs:format
|
||||
:~ balance+?~(cb ~ (numb:enjs:format u.cb))
|
||||
==
|
||||
=/ initial=json
|
||||
%+ frond:enjs:format
|
||||
%initial
|
||||
%- pairs:enjs:format
|
||||
:~ [%'provider' provider]
|
||||
[%'hasWallet' b+?=(^ walts)]
|
||||
[%wallet wallet]
|
||||
==
|
||||
:_ this
|
||||
[%give %fact ~ %json !>(initial)]~
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
@ -159,6 +202,11 @@
|
||||
:~ [%pass /set-provider/[(scot %p host.u.prov)] %agent [host.u.prov %btc-provider] %leave ~]
|
||||
sub-card
|
||||
==
|
||||
::
|
||||
%check-provider
|
||||
=/ pax /permitted/(scot %p provider.comm)
|
||||
:_ state
|
||||
[%pass pax %agent [provider.comm %btc-provider] %watch pax]~
|
||||
::
|
||||
%set-current-wallet
|
||||
(set-curr-xpub xpub.comm)
|
||||
@ -493,18 +541,22 @@
|
||||
|= s=status:bp
|
||||
^- (quip card _state)
|
||||
|^
|
||||
?~ prov `state
|
||||
?. =(host.u.prov src.bowl) `state
|
||||
?- -.s
|
||||
%new-block
|
||||
(on-connected u.prov network.s block.s fee.s `blockhash.s `blockfilter.s)
|
||||
::
|
||||
%connected
|
||||
(on-connected u.prov network.s block.s fee.s ~ ~)
|
||||
::
|
||||
%disconnected
|
||||
`state(prov `u.prov(connected %.n))
|
||||
==
|
||||
=^ cards state
|
||||
?~ prov `state
|
||||
?. =(host.u.prov src.bowl) `state
|
||||
?- -.s
|
||||
%new-block
|
||||
(on-connected u.prov network.s block.s fee.s `blockhash.s `blockfilter.s)
|
||||
::
|
||||
%connected
|
||||
(on-connected u.prov network.s block.s fee.s ~ ~)
|
||||
::
|
||||
%disconnected
|
||||
`state(prov `u.prov(connected %.n))
|
||||
==
|
||||
:_ state
|
||||
:_ cards
|
||||
[%give %fact ~[/all] %btc-provider-status !>(s)]
|
||||
::
|
||||
++ on-connected
|
||||
|= $: p=provider
|
||||
@ -854,4 +906,10 @@
|
||||
add
|
||||
`(roll values add)
|
||||
::
|
||||
::
|
||||
++ current-balance
|
||||
^- (unit sats)
|
||||
?~ curr-xpub ~
|
||||
(balance u.curr-xpub)
|
||||
::
|
||||
--
|
||||
|
80
pkg/arvo/lib/bitcoin-json.hoon
Normal file
80
pkg/arvo/lib/bitcoin-json.hoon
Normal file
@ -0,0 +1,80 @@
|
||||
/- btc-wallet, btc-provider, bitcoin
|
||||
|%
|
||||
++ dejs
|
||||
=, dejs:format
|
||||
|%
|
||||
++ command
|
||||
|= jon=json
|
||||
^- command:btc-wallet
|
||||
%. jon
|
||||
%- of
|
||||
:~ set-provider+ship
|
||||
check-provider+ship
|
||||
set-current-wallet+so
|
||||
add-wallet+add-wallet
|
||||
delete-wallet+so
|
||||
init-payment+init-payment
|
||||
broadcast-tx+so
|
||||
==
|
||||
::
|
||||
++ ship (su ;~(pfix sig fed:ag))
|
||||
::
|
||||
++ add-wallet
|
||||
%- ot
|
||||
:~ xpub+so
|
||||
fprint+(at [ni ni ~])
|
||||
scan-to+(mu (at [ni ni ~]))
|
||||
max-gap+(mu ni)
|
||||
confs+(mu ni)
|
||||
==
|
||||
::
|
||||
++ init-payment
|
||||
%- ot
|
||||
:~ payee+ship
|
||||
value+ni
|
||||
feyb+ni
|
||||
==
|
||||
--
|
||||
::
|
||||
++ enjs
|
||||
=, enjs:format
|
||||
|%
|
||||
++ status
|
||||
|= sta=status:btc-provider
|
||||
^- json
|
||||
%+ frond -.sta
|
||||
?- -.sta
|
||||
%connected (connected sta)
|
||||
%new-block (new-block sta)
|
||||
%disconnected ~
|
||||
==
|
||||
::
|
||||
++ connected
|
||||
|= sta=status:btc-provider
|
||||
?> ?=(%connected -.sta)
|
||||
%- pairs
|
||||
:~ network+s+network.sta
|
||||
block+(numb block.sta)
|
||||
fee+?~(fee.sta ~ (numb u.fee.sta))
|
||||
==
|
||||
::
|
||||
++ new-block
|
||||
|= sta=status:btc-provider
|
||||
?> ?=(%new-block -.sta)
|
||||
%- pairs
|
||||
:~ network+s+network.sta
|
||||
block+(numb block.sta)
|
||||
fee+?~(fee.sta ~ (numb u.fee.sta))
|
||||
blockhash+(hexb blockhash.sta)
|
||||
blockfilter+(hexb blockfilter.sta)
|
||||
==
|
||||
::
|
||||
++ hexb
|
||||
|= h=hexb:bitcoin
|
||||
^- json
|
||||
%- pairs
|
||||
:~ wid+(numb:enjs wid.h)
|
||||
dat+s+(scot %ux dat.h)
|
||||
==
|
||||
--
|
||||
--
|
@ -1,9 +1,11 @@
|
||||
/- *btc-provider
|
||||
/+ bitcoin-json
|
||||
|_ sta=status
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun sta
|
||||
++ json (status:enjs:bitcoin-json sta)
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
|
14
pkg/arvo/mar/btc-wallet/command.hoon
Normal file
14
pkg/arvo/mar/btc-wallet/command.hoon
Normal file
@ -0,0 +1,14 @@
|
||||
/- *btc-wallet
|
||||
/+ bitcoin-json
|
||||
|_ com=command
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun com
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
++ noun command
|
||||
++ json command:dejs:bitcoin-json
|
||||
--
|
||||
--
|
@ -13,6 +13,7 @@
|
||||
::
|
||||
+$ command
|
||||
$% [%set-provider provider=ship]
|
||||
[%check-provider provider=ship]
|
||||
[%set-current-wallet =xpub]
|
||||
[%add-wallet =xpub =fprint scan-to=(unit scon) max-gap=(unit @ud) confs=(unit @ud)]
|
||||
[%delete-wallet =xpub]
|
||||
|
113
pkg/btc-wallet/src/js/components/lib/providerModal.js
Normal file
113
pkg/btc-wallet/src/js/components/lib/providerModal.js
Normal file
@ -0,0 +1,113 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Text,
|
||||
Button,
|
||||
StatelessTextInput,
|
||||
Icon,
|
||||
Row,
|
||||
Input,
|
||||
} from '@tlon/indigo-react';
|
||||
|
||||
import { isValidPatp } from 'urbit-ob';
|
||||
|
||||
export default class ProviderModal extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
ready: false,
|
||||
provider: null,
|
||||
}
|
||||
|
||||
this.checkProvider = this.checkProvider.bind(this);
|
||||
this.submitProvider = this.submitProvider.bind(this);
|
||||
}
|
||||
|
||||
checkProvider(e) {
|
||||
// TODO: loading states
|
||||
let provider = e.target.value;
|
||||
let ready = false;
|
||||
|
||||
if (isValidPatp(provider)) {
|
||||
let command = {
|
||||
"check-provider": provider
|
||||
}
|
||||
this.props.api.btcWalletCommand(command);
|
||||
}
|
||||
this.setState({provider, ready});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState){
|
||||
if (!this.state.ready){
|
||||
if (this.props.providerPerms[this.state.provider]) {
|
||||
this.setState({ready: true});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
submitProvider(e){
|
||||
if (this.state.ready){
|
||||
let command = {
|
||||
"set-provider": this.state.provider
|
||||
}
|
||||
this.props.api.btcWalletCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let workingNode = (!this.state.ready) ? null :
|
||||
<Box mt={3}>
|
||||
<Text fontSize="14px" color="green">
|
||||
{this.state.provider} is a working provider node
|
||||
</Text>
|
||||
</Box>
|
||||
return (
|
||||
<Box
|
||||
width="100%"
|
||||
height="100%"
|
||||
padding={3}
|
||||
>
|
||||
<Row>
|
||||
<Icon icon="NullIcon" mr={2}/>
|
||||
<Text fontSize="14px" fontWeight="bold">
|
||||
Step 1 of 2: Set up Bitcoin Provider Node
|
||||
</Text>
|
||||
</Row>
|
||||
<Box mt={3}>
|
||||
<Text fontSize="14px" fontWeight="regular" color="gray">
|
||||
In order to perform Bitcoin transaction in Landscape, you'll need to set a provider node. A provider node is an urbit which maintains a synced Bitcoin ledger. Learn More
|
||||
</Text>
|
||||
</Box>
|
||||
<Box mt={3} mb={2}>
|
||||
<Text fontSize="14px" fontWeight="500">
|
||||
Provider Node
|
||||
</Text>
|
||||
</Box>
|
||||
<StatelessTextInput
|
||||
fontSize="14px"
|
||||
type="text"
|
||||
name="masterTicket"
|
||||
placeholder="e.g. ~zod"
|
||||
autoCapitalize="none"
|
||||
autoCorrect="off"
|
||||
mono
|
||||
backgroundColor={this.state.ready ? "veryLightGreen": null}
|
||||
color={this.state.ready ? "green": null}
|
||||
borderColor={this.state.ready ? "green": null}
|
||||
onChange={this.checkProvider}
|
||||
/>
|
||||
{workingNode}
|
||||
<Button
|
||||
mt={3}
|
||||
primary
|
||||
disabled={!this.state.ready}
|
||||
children="Set Peer Node"
|
||||
fontSize="14px"
|
||||
style={{cursor: this.state.ready ? "pointer" : "default"}}
|
||||
onClick={() => {this.submitProvider(this.state.provider)}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
52
pkg/btc-wallet/src/js/components/lib/startupModal.js
Normal file
52
pkg/btc-wallet/src/js/components/lib/startupModal.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
|
||||
import WalletModal from './walletModal.js'
|
||||
import ProviderModal from './providerModal.js'
|
||||
|
||||
|
||||
export default class StartupModal extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
let modal = null;
|
||||
|
||||
if (this.props.state.hasWallet && this.props.state.provider) {
|
||||
return null;
|
||||
} else if (!this.props.state.provider){
|
||||
modal =
|
||||
<ProviderModal
|
||||
api={this.props.api}
|
||||
providerPerms={this.props.state.providerPerms}
|
||||
/>
|
||||
} else if (!this.props.state.hasWallet){
|
||||
modal = <WalletModal api={this.props.api}/>
|
||||
}
|
||||
return (
|
||||
<Box
|
||||
backgroundColor="scales.black20"
|
||||
left="0px"
|
||||
top="0px"
|
||||
width="100%"
|
||||
height="100%"
|
||||
position="fixed"
|
||||
display="flex"
|
||||
zIndex={10}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Box display="flex"
|
||||
flexDirection="column"
|
||||
width='400px'
|
||||
backgroundColor="white"
|
||||
borderRadius={3}
|
||||
>
|
||||
{modal}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
204
pkg/btc-wallet/src/js/components/lib/walletModal.js
Normal file
204
pkg/btc-wallet/src/js/components/lib/walletModal.js
Normal file
@ -0,0 +1,204 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Text,
|
||||
Button,
|
||||
StatelessTextInput,
|
||||
Icon,
|
||||
Row,
|
||||
Input,
|
||||
} from '@tlon/indigo-react';
|
||||
|
||||
const kg = require('urbit-key-generation');
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const bs58check = require('bs58check')
|
||||
import { Buffer } from 'buffer';
|
||||
|
||||
|
||||
function xpubToZpub(xpub) {
|
||||
var data = bs58check.decode(xpub);
|
||||
data = data.slice(4);
|
||||
data = Buffer.concat([Buffer.from('04b24746', 'hex'), data]);
|
||||
return bs58check.encode(data);
|
||||
}
|
||||
|
||||
const BTC_DERIVATION_PATH = "m/84'/0'/0'"
|
||||
const BTC_DERIVATION_TYPE = 'bitcoin'
|
||||
// const NETWORK = bitcoin.networks.bitcoin
|
||||
const NETWORK = bitcoin.networks.testnet
|
||||
|
||||
export default class WalletModal extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
mode: 'masterTicket',
|
||||
masterTicket: '',
|
||||
xpub: '',
|
||||
ready: false,
|
||||
}
|
||||
this.checkTicket = this.checkTicket.bind(this);
|
||||
this.checkXPub = this.checkXPub.bind(this);
|
||||
this.submitMasterTicket = this.submitMasterTicket.bind(this);
|
||||
this.submitXPub = this.submitXPub.bind(this);
|
||||
}
|
||||
|
||||
checkTicket(e){
|
||||
// TODO: port over bridge ticket validation logic
|
||||
let masterTicket = e.target.value;
|
||||
let ready = (masterTicket.length > 0);
|
||||
this.setState({masterTicket, ready});
|
||||
}
|
||||
|
||||
checkXPub(e){
|
||||
let xpub = e.target.value;
|
||||
let ready = (xpub.length > 0);
|
||||
this.setState({xpub, ready});
|
||||
}
|
||||
|
||||
submitMasterTicket(ticket){
|
||||
console.log("ticket", ticket);
|
||||
|
||||
const node = kg.deriveNode(
|
||||
ticket,
|
||||
BTC_DERIVATION_TYPE,
|
||||
BTC_DERIVATION_PATH
|
||||
);
|
||||
|
||||
const zpub = xpubToZpub(
|
||||
bitcoin.bip32.fromPublicKey(
|
||||
Buffer.from(node.keys.public, 'hex'),
|
||||
Buffer.from(node.keys.chain, 'hex'),
|
||||
NETWORK
|
||||
).toBase58()
|
||||
);
|
||||
|
||||
this.submitXPub(zpub);
|
||||
}
|
||||
|
||||
submitXPub(xpub){
|
||||
console.log("xpub", xpub);
|
||||
const command = {
|
||||
"add-wallet": {
|
||||
"xpub": xpub,
|
||||
"fprint": [0, 0],
|
||||
"scan-to": null,
|
||||
"max-gap": 8,
|
||||
"confs": 1
|
||||
}
|
||||
}
|
||||
api.btcWalletCommand(command);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.mode === 'masterTicket'){
|
||||
return (
|
||||
<Box
|
||||
width="100%"
|
||||
height="100%"
|
||||
padding={3}
|
||||
>
|
||||
<Row>
|
||||
<Icon icon="NullIcon" mr={2}/>
|
||||
<Text fontSize="14px" fontWeight="bold">
|
||||
Step 2 of 2: Import your extended public key
|
||||
</Text>
|
||||
</Row>
|
||||
<Box mt={3}>
|
||||
<Text fontSize="14px" fontWeight="regular" color="gray">
|
||||
To begin, you'll need to derive an XPub Bitcoin address using your
|
||||
master ticket. Learn More
|
||||
</Text>
|
||||
</Box>
|
||||
<Box mt={3} mb={2}>
|
||||
<Text fontSize="14px" fontWeight="500">
|
||||
Master Key
|
||||
</Text>
|
||||
</Box>
|
||||
<StatelessTextInput
|
||||
value={this.state.masterTicket}
|
||||
fontSize="14px"
|
||||
type="password"
|
||||
name="masterTicket"
|
||||
obscure={value => value.replace(/[^~-]+/g, '••••••')}
|
||||
placeholder="••••••-••••••-••••••-••••••"
|
||||
autoCapitalize="none"
|
||||
autoCorrect="off"
|
||||
onChange={this.checkTicket}
|
||||
/>
|
||||
<Box mt={3} mb={3}>
|
||||
<Text fontSize="14px" fontWeight="regular" color="gray"
|
||||
style={{cursor: "pointer"}}
|
||||
onClick={() => { this.setState({mode: 'xpub', xpub: ''})}}
|
||||
>
|
||||
Manually import your extended public key ->
|
||||
</Text>
|
||||
</Box>
|
||||
<Button
|
||||
primary
|
||||
disabled={!this.state.ready}
|
||||
children="Next Step"
|
||||
fontSize="14px"
|
||||
style={{cursor: this.state.ready ? "pointer" : "default"}}
|
||||
onClick={() => {this.submitMasterTicket(this.state.masterTicket)}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
} else if (this.state.mode === 'xpub') {
|
||||
return (
|
||||
<Box
|
||||
width="100%"
|
||||
height="100%"
|
||||
padding={3}
|
||||
>
|
||||
<Row>
|
||||
<Icon icon="NullIcon" mr={2}/>
|
||||
<Text fontSize="14px" fontWeight="bold">
|
||||
Step 2 of 2: Import your extended public key
|
||||
</Text>
|
||||
</Row>
|
||||
<Box mt={3}>
|
||||
<Text fontSize="14px" fontWeight="regular" color="gray">
|
||||
Visit bridge.urbit.org to obtain your key
|
||||
</Text>
|
||||
</Box>
|
||||
<Box mt={3} mb={2}>
|
||||
<Text fontSize="14px" fontWeight="500">
|
||||
Extended Public Key (XPub)
|
||||
</Text>
|
||||
</Box>
|
||||
<StatelessTextInput
|
||||
value={this.state.xpub}
|
||||
fontSize="14px"
|
||||
type="password"
|
||||
name="xpub"
|
||||
autoCapitalize="none"
|
||||
autoCorrect="off"
|
||||
onChange={this.checkXPub}
|
||||
/>
|
||||
<Row mt={3}>
|
||||
<Button
|
||||
primary
|
||||
color="black"
|
||||
backgroundColor="veryLightGray"
|
||||
borderColor="veryLightGray"
|
||||
children="Cancel"
|
||||
fontSize="14px"
|
||||
mr={2}
|
||||
style={{cursor: "pointer"}}
|
||||
onClick={() => {this.setState({mode: 'masterTicket', xpub: ''})}}
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
disabled={!this.state.ready}
|
||||
children="Next Step"
|
||||
fontSize="14px"
|
||||
style={{cursor: this.state.ready ? "pointer" : "default"}}
|
||||
onClick={() => { this.submitXPub(this.state.xpub) }}
|
||||
/>
|
||||
</Row>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import styled, { ThemeProvider, createGlobalStyle } from 'styled-components';
|
||||
import light from './themes/light';
|
||||
import dark from './themes/dark';
|
||||
import { Text, Box } from '@tlon/indigo-react';
|
||||
//import StartupModal from './lib/startupModal.js';
|
||||
import StartupModal from './lib/startupModal.js';
|
||||
//import Header from './lib/header.js'
|
||||
//import Balance from './lib/balance.js'
|
||||
//import Transactions from './lib/transactions.js'
|
||||
@ -31,7 +31,7 @@ export class Root extends Component {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<ThemeProvider theme={light}>
|
||||
{// <StartupModal api={api} state={this.state}/> }
|
||||
<StartupModal api={api} state={this.state}/>
|
||||
<Box display='flex'
|
||||
flexDirection='column'
|
||||
position='absolute'
|
||||
|
@ -6,6 +6,9 @@ export class InitialReducer {
|
||||
let data = _.get(json, 'initial', false);
|
||||
console.log('data', data);
|
||||
if (data) {
|
||||
state.provider = data.provider;
|
||||
state.hasWallet = data.hasWallet;
|
||||
state.wallet = data.wallet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,5 +3,20 @@ import _ from 'lodash';
|
||||
|
||||
export class UpdateReducer {
|
||||
reduce(json, state) {
|
||||
console.log('update', json);
|
||||
if (json.providerStatus) {
|
||||
this.reduceProviderStatus(json.providerStatus, state);
|
||||
}
|
||||
if (json.connected) {
|
||||
this.reduceConnected(json.connected, state);
|
||||
}
|
||||
}
|
||||
|
||||
reduceProviderStatus(json, state) {
|
||||
state.providerPerms[json.provider] = json.permitted;
|
||||
}
|
||||
|
||||
reduceConnected(json, state) {
|
||||
state.provider = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user