Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Wallet
ExtLibJ
Commits
75dbe7e7
Commit
75dbe7e7
authored
Oct 06, 2021
by
zeroleak
Browse files
Merge branch 'dsk' into develop
# Conflicts: # pom.xml
parents
46da3462
01f49379
Changes
90
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1004 additions
and
84 deletions
+1004
-84
java/BipWallet.java
java/BipWallet.java
+82
-0
java/com/samourai/http/client/JacksonHttpClient.java
java/com/samourai/http/client/JacksonHttpClient.java
+4
-8
java/com/samourai/wallet/SamouraiWalletConst.java
java/com/samourai/wallet/SamouraiWalletConst.java
+4
-0
java/com/samourai/wallet/api/backend/BackendApi.java
java/com/samourai/wallet/api/backend/BackendApi.java
+20
-63
java/com/samourai/wallet/api/backend/BackendOAuthApi.java
java/com/samourai/wallet/api/backend/BackendOAuthApi.java
+59
-0
java/com/samourai/wallet/api/backend/MinerFee.java
java/com/samourai/wallet/api/backend/MinerFee.java
+12
-0
java/com/samourai/wallet/api/backend/WebSocketHandler.java
java/com/samourai/wallet/api/backend/WebSocketHandler.java
+392
-0
java/com/samourai/wallet/api/backend/beans/TxDetail.java
java/com/samourai/wallet/api/backend/beans/TxDetail.java
+45
-0
java/com/samourai/wallet/api/backend/beans/UnspentOutput.java
.../com/samourai/wallet/api/backend/beans/UnspentOutput.java
+55
-7
java/com/samourai/wallet/api/backend/beans/WalletResponse.java
...com/samourai/wallet/api/backend/beans/WalletResponse.java
+3
-3
java/com/samourai/wallet/api/backend/websocket/BackendWsApi.java
...m/samourai/wallet/api/backend/websocket/BackendWsApi.java
+214
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSResponse.java
...mourai/wallet/api/backend/websocket/beans/WSResponse.java
+5
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSResponseBlock.java
...i/wallet/api/backend/websocket/beans/WSResponseBlock.java
+8
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSResponseOperator.java
...allet/api/backend/websocket/beans/WSResponseOperator.java
+28
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSResponseUtxo.java
...ai/wallet/api/backend/websocket/beans/WSResponseUtxo.java
+8
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSSubscribeAddressRequest.java
...pi/backend/websocket/beans/WSSubscribeAddressRequest.java
+12
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSSubscribeBlockRequest.java
.../api/backend/websocket/beans/WSSubscribeBlockRequest.java
+10
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSSubscribeOperator.java
...llet/api/backend/websocket/beans/WSSubscribeOperator.java
+28
-0
java/com/samourai/wallet/api/backend/websocket/beans/WSSubscribeRequest.java
...allet/api/backend/websocket/beans/WSSubscribeRequest.java
+13
-0
java/com/samourai/wallet/bip47/rpc/BIP47Account.java
java/com/samourai/wallet/bip47/rpc/BIP47Account.java
+2
-3
No files found.
java/BipWallet.java
0 → 100644
View file @
75dbe7e7
package
com.samourai.wallet.client
;
import
com.samourai.wallet.api.backend.beans.UnspentOutput
;
import
com.samourai.wallet.client.indexHandler.IIndexHandler
;
import
com.samourai.wallet.hd.*
;
import
com.samourai.whirlpool.client.wallet.beans.WhirlpoolAccount
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
BipWallet
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
BipWallet
.
class
);
private
WhirlpoolAccount
account
;
private
HD_Wallet
bipWallet
;
private
IIndexHandler
indexHandler
;
private
IIndexHandler
indexChangeHandler
;
public
BipWallet
(
HD_Wallet
bip44w
,
WhirlpoolAccount
account
,
IIndexHandler
indexHandler
,
IIndexHandler
indexChangeHandler
,
AddressType
addressType
)
{
this
.
account
=
account
;
this
.
bipWallet
=
new
HD_Wallet
(
addressType
.
getPurpose
(),
bip44w
);
this
.
indexHandler
=
indexHandler
;
this
.
indexChangeHandler
=
indexChangeHandler
;
}
public
String
getPub
(
AddressType
addressType
)
{
HD_Account
hdAccount
=
bipWallet
.
getAccount
(
account
.
getAccountIndex
());
switch
(
addressType
)
{
case
LEGACY:
return
hdAccount
.
xpubstr
();
case
SEGWIT_COMPAT:
return
hdAccount
.
ypubstr
();
case
SEGWIT_NATIVE:
return
hdAccount
.
zpubstr
();
}
log
.
error
(
"Unknown addressType: "
+
addressType
);
return
null
;
}
public
HD_Address
getNextAddress
()
{
return
getNextAddress
(
true
);
}
public
HD_Address
getNextAddress
(
boolean
increment
)
{
int
nextAddressIndex
=
increment
?
indexHandler
.
getAndIncrement
()
:
indexHandler
.
get
();
return
getAddressAt
(
Chain
.
RECEIVE
.
getIndex
(),
nextAddressIndex
);
}
public
HD_Address
getNextChangeAddress
()
{
return
getNextChangeAddress
(
true
);
}
public
HD_Address
getNextChangeAddress
(
boolean
increment
)
{
int
nextAddressIndex
=
increment
?
indexChangeHandler
.
getAndIncrement
()
:
indexChangeHandler
.
get
();
return
getAddressAt
(
Chain
.
CHANGE
.
getIndex
(),
nextAddressIndex
);
}
public
HD_Address
getAddressAt
(
int
chainIndex
,
int
addressIndex
)
{
return
bipWallet
.
getAddressAt
(
account
.
getAccountIndex
(),
chainIndex
,
addressIndex
);
}
public
HD_Address
getAddressAt
(
UnspentOutput
utxo
)
{
return
getAddressAt
(
utxo
.
computePathChainIndex
(),
utxo
.
computePathAddressIndex
());
}
public
WhirlpoolAccount
getAccount
()
{
return
account
;
}
public
IIndexHandler
getIndexHandler
()
{
return
indexHandler
;
}
public
IIndexHandler
getIndexChangeHandler
()
{
return
indexChangeHandler
;
}
}
java/com/samourai/http/client/JacksonHttpClient.java
View file @
75dbe7e7
package
com.samourai.http.client
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.samourai.wallet.api.backend.beans.HttpException
;
import
com.samourai.wallet.util.JSONUtils
;
import
io.reactivex.Observable
;
import
java8.util.Optional
;
import
org.slf4j.Logger
;
...
...
@@ -14,11 +14,7 @@ import java.util.concurrent.Callable;
public
abstract
class
JacksonHttpClient
implements
IHttpClient
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
JacksonHttpClient
.
class
);
private
ObjectMapper
objectMapper
;
public
JacksonHttpClient
()
{
this
.
objectMapper
=
new
ObjectMapper
();
objectMapper
.
disable
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
);
}
protected
abstract
String
requestJsonGet
(
String
urlStr
,
Map
<
String
,
String
>
headers
,
boolean
async
)
...
...
@@ -68,7 +64,7 @@ public abstract class JacksonHttpClient implements IHttpClient {
@Override
public
T
call
()
throws
Exception
{
try
{
String
jsonBody
=
o
bjectMapper
.
writeValueAsString
(
bodyObj
);
String
jsonBody
=
getO
bjectMapper
()
.
writeValueAsString
(
bodyObj
);
String
responseContent
=
requestJsonPost
(
urlStr
,
headers
,
jsonBody
);
T
result
=
parseJson
(
responseContent
,
responseType
);
return
result
;
...
...
@@ -119,7 +115,7 @@ public abstract class JacksonHttpClient implements IHttpClient {
if
(
String
.
class
.
equals
(
responseType
))
{
result
=
(
T
)
responseContent
;
}
else
{
result
=
o
bjectMapper
.
readValue
(
responseContent
,
responseType
);
result
=
getO
bjectMapper
()
.
readValue
(
responseContent
,
responseType
);
}
return
result
;
}
...
...
@@ -142,6 +138,6 @@ public abstract class JacksonHttpClient implements IHttpClient {
}
protected
ObjectMapper
getObjectMapper
()
{
return
o
bjectMapper
;
return
JSONUtils
.
getInstance
().
getO
bjectMapper
()
;
}
}
java/com/samourai/wallet/SamouraiWalletConst.java
View file @
75dbe7e7
...
...
@@ -9,4 +9,8 @@ public class SamouraiWalletConst {
// hard limit for acceptable fees 0.005
public
static
final
long
MAX_ACCEPTABLE_FEES
=
500000
;
public
static
final
BigInteger
RBF_SEQUENCE_VAL_WITH_NLOCKTIME
=
BigInteger
.
valueOf
(
0xffffffff
L
-
1L
);
public
static
final
BigInteger
RBF_SEQUENCE_VAL
=
BigInteger
.
valueOf
(
0xffffffff
L
-
2L
);
public
static
final
BigInteger
NLOCKTIME_SEQUENCE_VAL
=
BigInteger
.
valueOf
(
0xffffffff
L
-
3L
);
}
java/com/samourai/wallet/api/backend/BackendApi.java
View file @
75dbe7e7
package
com.samourai.wallet.api.backend
;
import
com.samourai.wallet.api.backend.beans.*
;
import
com.samourai.wallet.util.oauth.OAuthApi
;
import
com.samourai.wallet.util.oauth.OAuthManager
;
import
java8.util.Optional
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.*
;
public
class
BackendApi
implements
OAuthApi
{
public
class
BackendApi
{
private
Logger
log
=
LoggerFactory
.
getLogger
(
BackendApi
.
class
);
private
static
final
String
URL_UNSPENT
=
"/unspent?active="
;
private
static
final
String
URL_MULTIADDR
=
"/multiaddr?active="
;
private
static
final
String
URL_WALLET
=
"/wallet?active="
;
private
static
final
String
URL_TXS
=
"/txs?active="
;
private
static
final
String
URL_TX
=
"/tx/"
;
private
static
final
String
URL_INIT_BIP84
=
"/xpub"
;
private
static
final
String
URL_MINER_FEES
=
"/fees"
;
private
static
final
String
URL_PUSHTX
=
"/pushtx/"
;
private
static
final
String
URL_GET_AUTH_LOGIN
=
"/auth/login"
;
private
static
final
String
URL_GET_AUTH_REFRESH
=
"/auth/refresh"
;
private
static
final
String
ZPUB_SEPARATOR
=
"%7C"
;
private
IBackendClient
httpClient
;
private
String
urlBackend
;
private
Optional
<
OAuthManager
>
oAuthManager
;
private
OAuthManager
oAuthManager
;
// may be null
public
BackendApi
(
IBackendClient
httpClient
,
String
urlBackend
,
Optional
<
OAuthManager
>
oAuthManager
)
{
public
BackendApi
(
IBackendClient
httpClient
,
String
urlBackend
)
{
this
(
httpClient
,
urlBackend
,
null
);
}
public
BackendApi
(
IBackendClient
httpClient
,
String
urlBackend
,
OAuthManager
oAuthManager
)
{
this
.
httpClient
=
httpClient
;
this
.
urlBackend
=
urlBackend
;
if
(
oAuthManager
==
null
)
{
oAuthManager
=
Optional
.
empty
();
}
this
.
oAuthManager
=
oAuthManager
;
if
(
log
.
isDebugEnabled
())
{
String
oAuthStr
=
oAuthManager
.
isPresent
()
?
"yes"
:
"no"
;
String
oAuthStr
=
oAuthManager
!=
null
?
"yes"
:
"no"
;
log
.
debug
(
"urlBackend="
+
urlBackend
+
", oAuth="
+
oAuthStr
);
}
}
...
...
@@ -47,16 +45,10 @@ public class BackendApi implements OAuthApi {
return
zpubStr
;
}
/**
* @deprecated use fetchWallet()
*/
public
List
<
UnspentOutput
>
fetchUtxos
(
String
zpub
)
throws
Exception
{
return
fetchUtxos
(
new
String
[]{
zpub
});
}
/**
* @deprecated use fetchWallet()
*/
public
List
<
UnspentOutput
>
fetchUtxos
(
String
[]
zpubs
)
throws
Exception
{
String
zpubStr
=
computeZpubStr
(
zpubs
);
String
url
=
computeAuthUrl
(
urlBackend
+
URL_UNSPENT
+
zpubStr
);
...
...
@@ -73,9 +65,6 @@ public class BackendApi implements OAuthApi {
return
unspentOutputs
;
}
/**
* @deprecated use fetchWallet()
*/
public
Map
<
String
,
MultiAddrResponse
.
Address
>
fetchAddresses
(
String
[]
zpubs
)
throws
Exception
{
String
zpubStr
=
computeZpubStr
(
zpubs
);
String
url
=
computeAuthUrl
(
urlBackend
+
URL_MULTIADDR
+
zpubStr
);
...
...
@@ -93,9 +82,6 @@ public class BackendApi implements OAuthApi {
return
addressesByZpub
;
}
/**
* @deprecated use fetchWallet()
*/
public
MultiAddrResponse
.
Address
fetchAddress
(
String
zpub
)
throws
Exception
{
Collection
<
MultiAddrResponse
.
Address
>
addresses
=
fetchAddresses
(
new
String
[]{
zpub
}).
values
();
if
(
addresses
.
size
()
!=
1
)
{
...
...
@@ -115,9 +101,6 @@ public class BackendApi implements OAuthApi {
return
address
;
}
/**
* @deprecated use fetchWallet()
*/
public
TxsResponse
fetchTxs
(
String
[]
zpubs
,
int
page
,
int
count
)
throws
Exception
{
String
zpubStr
=
computeZpubStr
(
zpubs
);
...
...
@@ -129,6 +112,15 @@ public class BackendApi implements OAuthApi {
return
httpClient
.
getJson
(
url
,
TxsResponse
.
class
,
headers
);
}
public
TxDetail
fetchTx
(
String
txid
,
boolean
fees
)
throws
Exception
{
String
url
=
computeAuthUrl
(
urlBackend
+
URL_TX
+
txid
+
(
fees
?
"?fees=1"
:
""
));
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"fetchTx: "
+
txid
);
}
Map
<
String
,
String
>
headers
=
computeHeaders
();
return
httpClient
.
getJson
(
url
,
TxDetail
.
class
,
headers
);
}
public
WalletResponse
fetchWallet
(
String
zpub
)
throws
Exception
{
return
fetchWallet
(
new
String
[]{
zpub
});
}
...
...
@@ -243,9 +235,9 @@ public class BackendApi implements OAuthApi {
protected
Map
<
String
,
String
>
computeHeaders
()
throws
Exception
{
Map
<
String
,
String
>
headers
=
new
HashMap
<
String
,
String
>();
if
(
oAuthManager
.
isPresent
()
)
{
if
(
oAuthManager
!=
null
)
{
// add auth token
headers
.
put
(
"Authorization"
,
"Bearer "
+
oAuthManager
.
get
().
getOAuthAccessToken
(
this
));
headers
.
put
(
"Authorization"
,
"Bearer "
+
oAuthManager
.
getOAuthAccessToken
());
}
return
headers
;
}
...
...
@@ -263,39 +255,4 @@ public class BackendApi implements OAuthApi {
return
urlBackend
;
}
// OAuthAPI
@Override
public
RefreshTokenResponse
.
Authorization
oAuthAuthenticate
(
String
apiKey
)
throws
Exception
{
String
url
=
getUrlBackend
()
+
URL_GET_AUTH_LOGIN
;
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"tokenAuthenticate"
);
}
Map
<
String
,
String
>
postBody
=
new
HashMap
<
String
,
String
>();
postBody
.
put
(
"apikey"
,
apiKey
);
RefreshTokenResponse
response
=
getHttpClient
().
postUrlEncoded
(
url
,
RefreshTokenResponse
.
class
,
null
,
postBody
);
if
(
response
.
authorizations
==
null
||
StringUtils
.
isEmpty
(
response
.
authorizations
.
access_token
))
{
throw
new
Exception
(
"Authorization refused. Invalid apiKey?"
);
}
return
response
.
authorizations
;
}
@Override
public
String
oAuthRefresh
(
String
refreshTokenStr
)
throws
Exception
{
String
url
=
getUrlBackend
()
+
URL_GET_AUTH_REFRESH
;
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"tokenRefresh"
);
}
Map
<
String
,
String
>
postBody
=
new
HashMap
<
String
,
String
>();
postBody
.
put
(
"rt"
,
refreshTokenStr
);
RefreshTokenResponse
response
=
getHttpClient
().
postUrlEncoded
(
url
,
RefreshTokenResponse
.
class
,
null
,
postBody
);
if
(
response
.
authorizations
==
null
||
StringUtils
.
isEmpty
(
response
.
authorizations
.
access_token
))
{
throw
new
Exception
(
"Authorization refused. Invalid apiKey?"
);
}
return
response
.
authorizations
.
access_token
;
}
}
java/com/samourai/wallet/api/backend/BackendOAuthApi.java
0 → 100644
View file @
75dbe7e7
package
com.samourai.wallet.api.backend
;
import
com.samourai.wallet.api.backend.beans.RefreshTokenResponse
;
import
com.samourai.wallet.util.oauth.OAuthApi
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
BackendOAuthApi
implements
OAuthApi
{
private
Logger
log
=
LoggerFactory
.
getLogger
(
BackendApi
.
class
);
private
static
final
String
URL_GET_AUTH_LOGIN
=
"/auth/login"
;
private
static
final
String
URL_GET_AUTH_REFRESH
=
"/auth/refresh"
;
private
IBackendClient
httpClient
;
private
String
urlBackend
;
public
BackendOAuthApi
(
IBackendClient
httpClient
,
String
urlBackend
)
{
this
.
httpClient
=
httpClient
;
this
.
urlBackend
=
urlBackend
;
}
@Override
public
RefreshTokenResponse
.
Authorization
oAuthAuthenticate
(
String
apiKey
)
throws
Exception
{
String
url
=
urlBackend
+
URL_GET_AUTH_LOGIN
;
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"tokenAuthenticate"
);
}
Map
<
String
,
String
>
postBody
=
new
HashMap
<
String
,
String
>();
postBody
.
put
(
"apikey"
,
apiKey
);
RefreshTokenResponse
response
=
httpClient
.
postUrlEncoded
(
url
,
RefreshTokenResponse
.
class
,
null
,
postBody
);
if
(
response
.
authorizations
==
null
||
StringUtils
.
isEmpty
(
response
.
authorizations
.
access_token
))
{
throw
new
Exception
(
"Authorization refused. Invalid apiKey?"
);
}
return
response
.
authorizations
;
}
@Override
public
String
oAuthRefresh
(
String
refreshTokenStr
)
throws
Exception
{
String
url
=
urlBackend
+
URL_GET_AUTH_REFRESH
;
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"tokenRefresh"
);
}
Map
<
String
,
String
>
postBody
=
new
HashMap
<
String
,
String
>();
postBody
.
put
(
"rt"
,
refreshTokenStr
);
RefreshTokenResponse
response
=
httpClient
.
postUrlEncoded
(
url
,
RefreshTokenResponse
.
class
,
null
,
postBody
);
if
(
response
.
authorizations
==
null
||
StringUtils
.
isEmpty
(
response
.
authorizations
.
access_token
))
{
throw
new
Exception
(
"Authorization refused. Invalid apiKey?"
);
}
return
response
.
authorizations
.
access_token
;
}
}
java/com/samourai/wallet/api/backend/MinerFee.java
View file @
75dbe7e7
...
...
@@ -13,4 +13,16 @@ public class MinerFee {
int
fee
=
feesResponse
.
get
(
feeTarget
.
getValue
());
return
fee
;
}
public
Map
<
String
,
Integer
>
_getMap
()
{
return
feesResponse
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
MinerFee
minerFee
=
(
MinerFee
)
o
;
return
feesResponse
.
equals
(
minerFee
.
feesResponse
);
}
}
java/com/samourai/wallet/api/backend/WebSocketHandler.java
0 → 100755
View file @
75dbe7e7
package
com.samourai.wallet.api.backend
;
/*
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Looper;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory;
import com.samourai.wallet.MainActivity2;
import com.samourai.wallet.SamouraiWallet;
import com.samourai.wallet.api.APIFactory;
import com.samourai.wallet.bip47.BIP47Meta;
import com.samourai.wallet.bip47.BIP47Util;
import com.samourai.wallet.bip47.rpc.PaymentCode;
import com.samourai.wallet.tor.TorManager;
import com.samourai.wallet.util.AppUtil;
import com.samourai.wallet.util.MonetaryUtil;
import com.samourai.wallet.util.NotificationsFactory;
import com.samourai.wallet.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import static com.samourai.wallet.util.LogUtil.debug;
import static com.samourai.wallet.util.LogUtil.info;
public class WebSocketHandler {
private WebSocket mConnection = null;
private String[] addrs = null;
private static List<String> seenHashes = new ArrayList<String>();
private static Context context = null;
public WebSocketHandler(Context ctx, String[] addrs) {
this.context = ctx;
this.addrs = addrs;
}
public void send(String message) {
try {
if (mConnection != null && mConnection.isOpen()) {
info("WebSocketHandler", "Websocket subscribe:" + message);
mConnection.sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void subscribe() {
send("{\"op\":\"blocks_sub\"}");
for(int i = 0; i < addrs.length; i++) {
if(addrs[i] != null && addrs[i].length() > 0) {
send("{\"op\":\"addr_sub\", \"addr\":\""+ addrs[i] + "\"}");
// info("WebSocketHandler", "{\"op\":\"addr_sub\",\"addr\":\"" + addrs[i] + "\"}");
}
}
}
public boolean isConnected() {
return mConnection != null && mConnection.isOpen();
}
public void stop() {
if(mConnection != null && mConnection.isOpen()) {
mConnection.disconnect();
}
}
public void start() {
try {
stop();
connect();
}
catch (IOException | com.neovisionaries.ws.client.WebSocketException e) {
e.printStackTrace();
}
}
private void connect() throws IOException, WebSocketException
{
new ConnectionTask().execute();
}
private void updateBalance(final String rbfHash, final String blkHash) {
new Thread() {
public void run() {
Looper.prepare();
// Intent intent = new Intent("com.samourai.wallet.BalanceFragment.REFRESH");
// intent.putExtra("rbf", rbfHash);
// intent.putExtra("notifTx", true);
// intent.putExtra("fetch", true);
// intent.putExtra("hash", blkHash);
// LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Looper.loop();
}
}.start();
}
private void updateReceive(final String address) {
new Thread() {
public void run() {
Looper.prepare();
Intent intent = new Intent("com.samourai.wallet.ReceiveFragment.REFRESH");
intent.putExtra("received_on", address);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Looper.loop();
}
}.start();
}
private class ConnectionTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... args) {
if(AppUtil.getInstance(context).isOfflineMode() || TorManager.INSTANCE.isRequired()) {
return null;
}
try {
mConnection = new WebSocketFactory()
.createSocket(SamouraiWallet.getInstance().isTestNet() ? "wss://api.samourai.io/test/v2/inv" : "wss://api.samourai.io/v2/inv")
.addListener(new WebSocketAdapter() {
public void onTextMessage(WebSocket websocket, String message) {
debug("WebSocket", message);
try {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(message);
} catch (JSONException je) {
// info("WebSocketHandler", "JSONException:" + je.getMessage());
jsonObject = null;
}
if (jsonObject == null) {
// info("WebSocketHandler", "jsonObject is null");
return;
}
// info("WebSocketHandler", jsonObject.toString());
String op = (String) jsonObject.get("op");
if(op.equals("block") && jsonObject.has("x")) {
JSONObject objX = (JSONObject) jsonObject.get("x");
String hash = null;
if (objX.has("hash")) {
hash = objX.getString("hash");
if(seenHashes.contains(hash)){
return;
}
else {
seenHashes.add(hash);
}
}
updateBalance(null, hash);
return;
}
if (op.equals("utx") && jsonObject.has("x")) {
JSONObject objX = (JSONObject) jsonObject.get("x");
long value = 0L;
long total_value = 0L;
long ts = 0L;
String in_addr = null;
String out_addr = null;
String hash = null;
boolean isRBF = false;
if (objX.has("time")) {
ts = objX.getLong("time");
}
if (objX.has("hash")) {
hash = objX.getString("hash");
}