This commit is contained in:
Isaac Visintainer 2021-04-23 13:18:20 -07:00 committed by ixv
parent 2288858302
commit 24db04bccc
8 changed files with 201 additions and 109 deletions

View File

@ -186,6 +186,7 @@
[%give %fact ~ %json !>(response)]~
::
[%all ~]
~& %watch-all
?> (team:title our.bowl src.bowl)
:_ this
[give-initial:hc]~
@ -643,6 +644,7 @@
btc-state [block fee now.bowl]
==
?: ?|(?!(connected.p) (lth block.btc-state block))
~& >> block
;: weld
(retry-pend-piym network)
(retry-poym network)
@ -652,6 +654,7 @@
retry-ahistorical-txs
==
;: weld
:: (retry-addrs network)
retry-ahistorical-txs
(retry-pend-piym network)
==
@ -760,6 +763,7 @@
++ handle-tx-info
|= ti=info:tx
^- (quip card _state)
~& %handle-tx-info^ti
|^
=/ h (~(get by history) txid.ti)
=. ahistorical-txs (~(del in ahistorical-txs) txid.ti)
@ -769,6 +773,13 @@
%+ turn (weld inputs.ti outputs.ti)
|=(=val:tx address.val)
is-our-address
~& addresses+our-addrs
:: =/ addr-info-cards=(list card)
:: %+ turn ~(tap in our-addrs)
:: |= a=address
:: ^- card
:: (poke-provider [%address-info a])
::
?: =(0 ~(wyt in our-addrs)) `state
=/ =xpub
xpub.w:(need (address-coords:bl (snag 0 ~(tap in our-addrs)) ~(val by walts)))
@ -776,13 +787,16 @@
=/ new-hest=hest (mk-hest xpub our-addrs)
=. history (~(put by history) txid.ti new-hest)
:_ state
:: :_ addr-info-cards
[(give-update %new-tx new-hest)]~
?. included.ti :: tx in history, but not in mempool/blocks
:_ state(history (~(del by history) txid.ti))
:: :_ addr-info-cards
[(give-update %cancel-tx txid.ti)]~
=/ new-hest u.h(confs confs.ti, recvd recvd.ti)
=. history (~(put by history) txid.ti new-hest)
:_ state
:: :_ addr-info-cards
[(give-update %new-tx new-hest)]~
::
++ mk-hest
@ -830,6 +844,7 @@
++ handle-address-info
|= [=address utxos=(set utxo) used=?]
^- (quip card _state)
~& %handle-address-info^address
=/ ac (address-coords:bl address ~(val by walts))
?~ ac
`state
@ -1020,21 +1035,29 @@
::
++ balance
|= =xpub:bc
^- (unit sats)
^- (unit [sats sats])
=/ w (~(get by walts) xpub)
?~ w ~
=/ values=(list sats)
=/ values=(list [confirmed=sats unconfirmed=sats])
%+ turn ~(val by wach.u.w)
|= =addi ^- sats
|= =addi ^- [sats sats]
%+ roll
%+ turn ~(tap by utxos.addi)
|=(=utxo value.utxo)
add
`(roll values add)
|= =utxo
^- [sats sats]
?: (~(spendable sut:bl [u.w eny.bowl block.btc-state ~ 0 ~]) utxo)
[value.utxo 0]
[0 value.utxo]
|= [[a=sats b=sats] out=[p=sats q=sats]]
[(add a p.out) (add b q.out)]
:- ~
%+ roll values
|= [[a=sats b=sats] out=[p=sats q=sats]]
[(add a p.out) (add b q.out)]
::
::
++ current-balance
^- (unit sats)
^- (unit [sats sats])
?~ curr-xpub ~
(balance u.curr-xpub)
::

View File

@ -116,7 +116,7 @@
%- pairs
:~ provider+(provider provider.upd)
wallet+?~(wallet.upd ~ [%s u.wallet.upd])
balance+?~(balance.upd ~ (numb u.balance.upd))
balance+(balance balance.upd)
history+(history history.upd)
btc-state+(btc-state btc-state.upd)
address+?~(address.upd ~ (address u.address.upd))
@ -134,10 +134,19 @@
^- json
%- pairs
:~ wallet+?~(wallet.upd ~ [%s u.wallet.upd])
balance+?~(balance.upd ~ (numb u.balance.upd))
balance+(balance balance.upd)
history+(history history.upd)
==
::
++ balance
|= b=(unit [p=@ q=@])
^- json
?~ b ~
%- pairs
:~ confirmed+(numb p.u.b)
unconfirmed+(numb q.u.b)
==
::
++ btc-state
|= bs=btc-state:btc-wallet
^- json

View File

@ -118,13 +118,13 @@
$% $: %initial
provider=(unit provider)
wallet=(unit xpub)
balance=(unit sats)
balance=(unit [p=sats q=sats])
=history
=btc-state
address=(unit address)
==
[%change-provider provider=(unit provider)]
[%change-wallet wallet=(unit xpub) balance=(unit sats) =history]
[%change-wallet wallet=(unit xpub) balance=(unit [p=sats q=sats]) =history]
[%psbt pb=@t]
[%btc-state =btc-state]
[%new-tx =hest]

View File

@ -67,6 +67,7 @@ export default class Balance extends Component {
denomination={denomination}
sats={sats}
conversion={conversion}
network={this.props.network}
stopSending={() => {
this.setState({sending: false});
store.handleEvent({data: {psbt: ''}});

View File

@ -33,12 +33,38 @@ export default class Send extends Component {
focusCurrency: false,
focusSats: false,
submitting: false,
feeChoices: {
low: [10, 1],
mid: [10, 1],
high: [10, 1],
},
feeValue: "mid",
showModal: false,
};
this.initPayment = this.initPayment.bind(this);
this.checkPayee = this.checkPayee.bind(this);
}
componentDidMount(){
// TODO switch this to bitcoin
if (this.props.network === 'testnet'){
let url = "https://bitcoiner.live/api/fees/estimates/latest";
fetch(url).then(res => res.json()).then(n => {
let estimates = Object.keys(n.estimates);
let mid = Math.floor(estimates.length/2)
let high = estimates.length - 1;
this.setState({
feeChoices: {
low: [30, n.estimates[30]["sat_per_vbyte"]],
mid: [180, n.estimates[180]["sat_per_vbyte"]],
high: [360, n.estimates[360]["sat_per_vbyte"]],
}
});
})
}
}
checkPayee(e){
let payee = e.target.value;
let isPatp = ob.isValidPatp(payee);
@ -154,102 +180,133 @@ export default class Send extends Component {
borderRadius='32px'
mb={5}
p={5}
display="flex"
flexDirection="column"
justifyContent="space-between"
>
<Row
justifyContent='space-between'
alignItems='center'
>
<Text highlight color='blue' fontSize={1}>Send BTC</Text>
<Text highlight color='blue' fontSize={1}>{value}</Text>
<Icon
icon='X'
cursor='pointer'
onClick={() => stopSending()}
/>
</Row>
<Row
alignItems='center'
mt={6}
justifyContent='space-between'>
<Row justifyContent="space-between" width='calc(40% - 30px)' alignItems="center">
<Text gray fontSize={1} fontWeight='600'>To</Text>
{this.state.checkingPatp ?
<LoadingSpinner background="midOrange" foreground="orange"/> : null
}
<Col width="100%">
<Row
justifyContent='space-between'
alignItems='center'
>
<Text highlight color='blue' fontSize={1}>Send BTC</Text>
<Text highlight color='blue' fontSize={1}>{value}</Text>
<Icon
icon='X'
cursor='pointer'
onClick={() => stopSending()}
/>
</Row>
<Input
autoFocus
onFocus={() => {this.setState({focusPayee: true})}}
onBlur={() => {this.setState({focusPayee: false})}}
color={payeeColor}
backgroundColor={payeeBg}
borderColor={payeeBorder}
ml={2}
flexGrow="1"
fontSize='14px'
placeholder='~sampel-palnet or BTC address'
value={payee}
fontFamily="mono"
disabled={signing}
onChange={this.checkPayee}
/>
</Row>
<Row
alignItems='center'
mt={4}
justifyContent='space-between'>
<Text
gray
fontSize={1}
fontWeight='600'
width="40%"
>Amount</Text>
<Input
onFocus={() => {this.setState({focusCurrency: true})}}
onBlur={() => {this.setState({focusCurrency: false})}}
fontSize='14px'
width='100%'
type='number'
borderColor={this.state.focusCurrency ? "lightGray" : "none"}
disabled={signing}
value={denomAmount}
onChange={e => {
this.setState({
denomAmount: e.target.value,
satsAmount: Math.round(parseFloat(e.target.value) / conversion * 100000000)
});
}}
/>
<Text color="lighterGray" fontSize={1} ml={3}>{denomination}</Text>
</Row>
<Row
alignItems='center'
mt={2}
justifyContent='space-between'>
{/* yes this is a hack */}
<Box width='40%'/>
<Input
onFocus={() => {this.setState({focusSats: true})}}
onBlur={() => {this.setState({focusSats: false})}}
fontSize='14px'
width='100%'
type='number'
borderColor={this.state.focusSats ? "lightGray" : "none"}
disabled={signing}
value={satsAmount}
onChange={e => {
this.setState({
denomAmount: parseFloat(e.target.value) * (conversion / 100000000),
satsAmount: e.target.value
});
}}
/>
<Text color="lighterGray" fontSize={1} ml={3}>sats</Text>
</Row>
<Row
alignItems='center'
mt={6}
justifyContent='space-between'>
<Row justifyContent="space-between" width='calc(40% - 30px)' alignItems="center">
<Text gray fontSize={1} fontWeight='600'>To</Text>
{this.state.checkingPatp ?
<LoadingSpinner background="midOrange" foreground="orange"/> : null
}
</Row>
<Input
autoFocus
onFocus={() => {this.setState({focusPayee: true})}}
onBlur={() => {this.setState({focusPayee: false})}}
color={payeeColor}
backgroundColor={payeeBg}
borderColor={payeeBorder}
ml={2}
flexGrow="1"
fontSize='14px'
placeholder='~sampel-palnet or BTC address'
value={payee}
fontFamily="mono"
disabled={signing}
onChange={this.checkPayee}
/>
</Row>
<Row
alignItems='center'
mt={4}
justifyContent='space-between'>
<Text
gray
fontSize={1}
fontWeight='600'
width="40%"
>Amount</Text>
<Input
onFocus={() => {this.setState({focusCurrency: true})}}
onBlur={() => {this.setState({focusCurrency: false})}}
fontSize='14px'
width='100%'
type='number'
borderColor={this.state.focusCurrency ? "lightGray" : "none"}
disabled={signing}
value={denomAmount}
onChange={e => {
this.setState({
denomAmount: e.target.value,
satsAmount: Math.round(parseFloat(e.target.value) / conversion * 100000000)
});
}}
/>
<Text color="lighterGray" fontSize={1} ml={3}>{denomination}</Text>
</Row>
<Row
alignItems='center'
mt={2}
justifyContent='space-between'>
{/* yes this is a hack */}
<Box width='40%'/>
<Input
onFocus={() => {this.setState({focusSats: true})}}
onBlur={() => {this.setState({focusSats: false})}}
fontSize='14px'
width='100%'
type='number'
borderColor={this.state.focusSats ? "lightGray" : "none"}
disabled={signing}
value={satsAmount}
onChange={e => {
this.setState({
denomAmount: parseFloat(e.target.value) * (conversion / 100000000),
satsAmount: e.target.value
});
}}
/>
<Text color="lighterGray" fontSize={1} ml={3}>sats</Text>
</Row>
<Row mt={4} width="100%" justifyContent="space-between">
<Text
gray
fontSize={1}
fontWeight='600'
width="40%"
>Fee</Text>
<Row alignItems="center">
<Text mr={2} color="lightGray" fontSize="14px">
{this.state.feeChoices[this.state.feeValue][1]} sats/vbyte
</Text>
<Icon icon="ChevronSouth"
fontSize="14px"
color="lightGray"
onClick={() => { this.setState({showModal: !this.state.showModal}); }}
cursor="pointer"/>
</Row>
</Row>
<Col alignItems="center">
{!this.state.showModal ? null :
<Box position="fixed" p={4}
border="1px solid green" borderRadius={3}
backgroundColor="white" zIndex={10}>
<Text fontSize={1} color="black">Transaction Speed</Text>
</Box>
}
</Col>
</Col>
<Row
flexDirection='row-reverse'
alignItems="center"
mt={8}
>
<Button
primary

View File

@ -38,9 +38,9 @@ export default class Transaction extends Component {
let counter = _.find(this.props.tx.outputs, (output) => {
return (output.ship !== window.ship);
});
counterShip = counter.ship;
counterAddress = counter.val.address;
value = counter.val.value;
counterShip = _.get(counter, 'ship', null);
counterAddress = _.get(counter, 'val.address', null);
value = _.get(counter, 'val.value', null);
sign = '-'
}
else if (action === "recv") {
@ -52,8 +52,8 @@ export default class Transaction extends Component {
let counter = _.find(this.props.tx.inputs, (input) => {
return (input.ship !== window.ship);
});
counterShip = counter.ship;
counterAddress = counter.val.address;
counterShip = _.get(counter, 'ship', null);
counterAddress = _.get(counter, 'val.address', null);
sign = '';
}

View File

@ -37,7 +37,8 @@ export default class TxCounterparty extends Component {
>
<Icon icon="Bitcoin" color="gray"/>
</Box>
const addressText = this.props.address.slice(0, 6) + '...' +
const addressText = (!this.props.address) ? '' :
this.props.address.slice(0, 6) + '...' +
this.props.address.slice(-6);
const text = (this.props.ship) ?
`~${this.props.ship}` : addressText;

View File

@ -2,11 +2,12 @@ import _ from 'lodash';
export class InitialReducer {
reduce(json, state) {
console.log('data', json);
let data = _.get(json, 'initial', false);
if (data) {
state.provider = data.provider;
state.wallet = data.wallet;
state.balance = data.balance;
state.balance = _.get(data.balance, 'confirmed', null);
state.btcState = data['btc-state'];
state.history = this.reduceHistory(data.history);
state.address = data.address