Merge pull request #6926 from BlueWallet/frisb

DEL: Remove Frisbee
This commit is contained in:
GLaDOS 2024-08-16 16:30:49 +00:00 committed by GitHub
commit 8f6f173e83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 185 additions and 342 deletions

View File

@ -1,6 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import PushNotificationIOS from '@react-native-community/push-notification-ios';
import Frisbee from 'frisbee';
import { findNodeHandle, Platform } from 'react-native';
import { getApplicationName, getSystemName, getSystemVersion, getVersion, hasGmsSync, hasHmsSync } from 'react-native-device-info';
import { requestNotifications } from 'react-native-permissions';
@ -33,6 +32,7 @@ function Notifications(props) {
};
Notifications.isNotificationsCapable = hasGmsSync() || hasHmsSync() || Platform.OS !== 'android';
/**
* Calls `configure`, which tries to obtain push token, save it, and registers all associated with
* notifications callbacks
@ -173,10 +173,8 @@ function Notifications(props) {
function _getHeaders() {
return {
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
};
}
@ -199,20 +197,19 @@ function Notifications(props) {
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI });
return await api.post(
'/majorTomToGroundControl',
Object.assign({}, _getHeaders(), {
body: {
addresses,
hashes,
txids,
token: pushToken.token,
os: pushToken.os,
},
const response = await fetch(`${baseURI}/majorTomToGroundControl`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
addresses,
hashes,
txids,
token: pushToken.token,
os: pushToken.os,
}),
);
});
return response.json();
};
/**
@ -229,28 +226,26 @@ function Notifications(props) {
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI });
const postCall = await api.post(
'/unsubscribe',
Object.assign({}, _getHeaders(), {
body: {
addresses,
hashes,
txids,
token: pushToken.token,
os: pushToken.os,
},
const response = await fetch(`${baseURI}/unsubscribe`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
addresses,
hashes,
txids,
token: pushToken.token,
os: pushToken.os,
}),
);
});
console.log('Abandoning notifications Permissions...');
PushNotification.abandonPermissions();
console.log('Abandoned notifications Permissions...');
return postCall;
return response.json();
};
Notifications.isNotificationsEnabled = async function () {
const levels = await getLevels();
return !!(await Notifications.getPushToken()) && !!levels.level_all;
};
@ -267,21 +262,22 @@ function Notifications(props) {
return AsyncStorage.getItem(GROUNDCONTROL_BASE_URI);
};
/**
* Validates whether the provided GroundControl URI is valid by pinging it.
*
* @param uri {string}
* @returns {Promise<boolean>} TRUE if valid, FALSE otherwise
*/
Notifications.isGroundControlUriValid = async uri => {
const apiCall = new Frisbee({
baseURI: uri,
});
let response;
try {
response = await Promise.race([apiCall.get('/ping', _getHeaders()), _sleep(2000)]);
response = await Promise.race([fetch(`${uri}/ping`, { headers: _getHeaders() }), _sleep(2000)]);
} catch (_) {}
if (!response || !response.body) return false; // either sleep expired or apiCall threw an exception
if (!response) return false;
const json = response.body;
if (json.description) return true;
return false;
const json = await response.json();
return !!json.description;
};
/**
@ -310,19 +306,16 @@ function Notifications(props) {
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI });
try {
await api.post(
'/setTokenConfiguration',
Object.assign({}, _getHeaders(), {
body: {
level_all: !!levelAll,
token: pushToken.token,
os: pushToken.os,
},
await fetch(`${baseURI}/setTokenConfiguration`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
level_all: !!levelAll,
token: pushToken.token,
os: pushToken.os,
}),
);
});
console.log('Abandoning notifications Permissions...');
PushNotification.abandonPermissions();
console.log('Abandoned notifications Permissions...');
@ -338,19 +331,24 @@ function Notifications(props) {
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI });
let response;
try {
response = await Promise.race([
api.post('/getTokenConfiguration', Object.assign({}, _getHeaders(), { body: { token: pushToken.token, os: pushToken.os } })),
fetch(`${baseURI}/getTokenConfiguration`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
token: pushToken.token,
os: pushToken.os,
}),
}),
_sleep(3000),
]);
} catch (_) {}
if (!response || !response.body) return {}; // either sleep expired or apiCall threw an exception
if (!response) return {};
return response.body;
return await response.json();
};
Notifications.getStoredNotifications = async function () {
@ -380,23 +378,20 @@ function Notifications(props) {
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI });
try {
const lang = (await AsyncStorage.getItem('lang')) || 'en';
const appVersion = getSystemName() + ' ' + getSystemVersion() + ';' + getApplicationName() + ' ' + getVersion();
await api.post(
'/setTokenConfiguration',
Object.assign({}, _getHeaders(), {
body: {
token: pushToken.token,
os: pushToken.os,
lang,
app_version: appVersion,
},
await fetch(`${baseURI}/setTokenConfiguration`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
token: pushToken.token,
os: pushToken.os,
lang,
app_version: appVersion,
}),
);
});
} catch (_) {}
};

View File

@ -1,4 +1,3 @@
import Frisbee from 'frisbee';
import URL from 'url';
export default class Azteco {
@ -10,15 +9,15 @@ export default class Azteco {
*
* @returns {Promise<boolean>} Successfully redeemed or not. This method does not throw exceptions
*/
static async redeem(voucher: string, address: string): Promise<boolean> {
const api = new Frisbee({
baseURI: 'https://azte.co/',
});
const url = `/blue_despatch.php?CODE_1=${voucher[0]}&CODE_2=${voucher[1]}&CODE_3=${voucher[2]}&CODE_4=${voucher[3]}&ADDRESS=${address}`;
static async redeem(voucher: string[], address: string): Promise<boolean> {
const baseURI = 'https://azte.co/';
const url = `${baseURI}blue_despatch.php?CODE_1=${voucher[0]}&CODE_2=${voucher[1]}&CODE_3=${voucher[2]}&CODE_4=${voucher[3]}&ADDRESS=${address}`;
try {
const response = await api.get(url);
return response && response.originalResponse && +response.originalResponse.status === 200;
const response = await fetch(url, {
method: 'GET',
});
return response && response.status === 200;
} catch (_) {
return false;
}

View File

@ -1,6 +1,4 @@
import bolt11 from 'bolt11';
import Frisbee from 'frisbee';
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import { LegacyWallet } from './legacy-wallet';
@ -24,7 +22,6 @@ export class LightningCustodianWallet extends LegacyWallet {
info_raw = false;
preferredBalanceUnit = BitcoinUnit.SATS;
chain = Chain.OFFCHAIN;
private _api?: Frisbee;
last_paid_invoice_result?: any;
decoded_invoice_raw?: any;
@ -81,10 +78,6 @@ export class LightningCustodianWallet extends LegacyWallet {
// un-cache refill onchain addresses on cold start. should help for cases when certain lndhub
// is turned off permanently, so users cant pull refill address from cache and send money to a black hole
this.refill_addressess = [];
this._api = new Frisbee({
baseURI: this.baseURI,
});
}
accessTokenExpired() {
@ -101,14 +94,14 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async createAccount(isTest: boolean = false) {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.post('/create', {
body: { partnerid: 'bluewallet', accounttype: (isTest && 'test') || 'common' },
const response = await fetch(this.baseURI + '/create', {
method: 'POST',
body: JSON.stringify({ partnerid: 'bluewallet', accounttype: (isTest && 'test') || 'common' }),
headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' },
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -116,16 +109,16 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.login || !json.password) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
this.secret = 'lndhub://' + json.login + ':' + json.password;
}
async payInvoice(invoice: string, freeAmount: number = 0) {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.post('/payinvoice', {
body: { invoice, amount: freeAmount },
const response = await fetch(this.baseURI + '/payinvoice', {
method: 'POST',
body: JSON.stringify({ invoice, amount: freeAmount }),
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -133,19 +126,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
if (response.originalResponse && typeof response.originalResponse === 'string') {
try {
response.originalResponse = JSON.parse(response.originalResponse);
} catch (_) {}
}
if (response.originalResponse && response.originalResponse.status && response.originalResponse.status === 503) {
throw new Error('Payment is in transit');
}
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.originalResponse));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -161,19 +144,19 @@ export class LightningCustodianWallet extends LegacyWallet {
* @return {Promise.<Array>}
*/
async getUserInvoices(limit: number | false = false) {
if (!this._api) throw new Error('Internal error: _api is not initialized');
let limitString = '';
if (limit) limitString = '?limit=' + parseInt(limit as unknown as string, 10);
const response = await this._api.get('/getuserinvoices' + limitString, {
const response = await fetch(this.baseURI + '/getuserinvoices' + limitString, {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
Authorization: 'Bearer' + ' ' + this.access_token,
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.originalResponse));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -225,18 +208,18 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async addInvoice(amt: number, memo: string) {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.post('/addinvoice', {
body: { amt: amt + '', memo },
const response = await fetch(this.baseURI + '/addinvoice', {
method: 'POST',
body: JSON.stringify({ amt: amt + '', memo }),
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
Authorization: 'Bearer' + ' ' + this.access_token,
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.originalResponse));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -244,7 +227,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.r_hash || !json.pay_req) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
return json.pay_req;
@ -257,7 +240,6 @@ export class LightningCustodianWallet extends LegacyWallet {
* @return {Promise.<void>}
*/
async authorize() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
let login, password;
if (this.secret.indexOf('blitzhub://') !== -1) {
login = this.secret.replace('blitzhub://', '').split(':')[0];
@ -266,14 +248,15 @@ export class LightningCustodianWallet extends LegacyWallet {
login = this.secret.replace('lndhub://', '').split(':')[0];
password = this.secret.replace('lndhub://', '').split(':')[1];
}
const response = await this._api.post('/auth?type=auth', {
body: { login, password },
const response = await fetch(this.baseURI + '/auth?type=auth', {
method: 'POST',
body: JSON.stringify({ login, password }),
headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' },
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -281,7 +264,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.access_token || !json.refresh_token) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
this.refresh_token = json.refresh_token;
@ -313,15 +296,15 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async refreshAcessToken() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.post('/auth?type=refresh_token', {
body: { refresh_token: this.refresh_token },
const response = await fetch(this.baseURI + '/auth?type=refresh_token', {
method: 'POST',
body: JSON.stringify({ refresh_token: this.refresh_token }),
headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' },
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -329,7 +312,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.access_token || !json.refresh_token) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
this.refresh_token = json.refresh_token;
@ -339,8 +322,8 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async fetchBtcAddress() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.get('/getbtc', {
const response = await fetch(this.baseURI + '/getbtc', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -348,9 +331,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -421,8 +404,8 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async fetchPendingTransactions() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.get('/getpending', {
const response = await fetch(this.baseURI + '/getpending', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -430,9 +413,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -443,7 +426,6 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async fetchTransactions() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
// TODO: iterate over all available pages
const limit = 10;
let queryRes = '';
@ -451,7 +433,8 @@ export class LightningCustodianWallet extends LegacyWallet {
queryRes += '?limit=' + limit;
queryRes += '&offset=' + offset;
const response = await this._api.get('/gettxs' + queryRes, {
const response = await fetch(this.baseURI + '/gettxs' + queryRes, {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -459,9 +442,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -469,7 +452,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!Array.isArray(json)) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
this._lastTxFetch = +new Date();
@ -481,10 +464,10 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async fetchBalance(noRetry?: boolean): Promise<void> {
if (!this._api) throw new Error('Internal error: _api is not initialized');
await this.checkLogin();
const response = await this._api.get('/balance', {
const response = await fetch(this.baseURI + '/balance', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -492,9 +475,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -506,7 +489,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.BTC || typeof json.BTC.AvailableBalance === 'undefined') {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
this.balance = json.BTC.AvailableBalance;
@ -572,8 +555,8 @@ export class LightningCustodianWallet extends LegacyWallet {
}
async fetchInfo() {
if (!this._api) throw new Error('Internal error: _api is not initialized');
const response = await this._api.get('/getinfo', {
const response = await fetch(this.baseURI + '/getinfo', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -581,9 +564,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -591,23 +574,21 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.identity_pubkey) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
}
static async isValidNodeAddress(address: string) {
const apiCall = new Frisbee({
baseURI: address,
});
const response = await apiCall.get('/getinfo', {
const response = await fetch(address + '/getinfo', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.code && json.code !== 1) {
@ -641,10 +622,10 @@ export class LightningCustodianWallet extends LegacyWallet {
* @return {Promise.<Object>}
*/
async decodeInvoiceRemote(invoice: string) {
if (!this._api) throw new Error('Internal error: _api is not initialized');
await this.checkLogin();
const response = await this._api.get('/decodeinvoice?invoice=' + invoice, {
const response = await fetch(this.baseURI + '/decodeinvoice?invoice=' + invoice, {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
@ -652,9 +633,9 @@ export class LightningCustodianWallet extends LegacyWallet {
},
});
const json = response.body;
const json = await response.json();
if (!json) {
throw new Error('API failure: ' + response.err + ' ' + JSON.stringify(response.body));
throw new Error('API failure: ' + response.statusText);
}
if (json.error) {
@ -662,7 +643,7 @@ export class LightningCustodianWallet extends LegacyWallet {
}
if (!json.payment_hash) {
throw new Error('API unexpected response: ' + JSON.stringify(response.body));
throw new Error('API unexpected response: ' + JSON.stringify(json));
}
return (this.decoded_invoice_raw = json);

View File

@ -1002,7 +1002,7 @@ PODS:
- React
- react-native-randombytes (3.6.1):
- React-Core
- react-native-safe-area-context (4.10.8):
- react-native-safe-area-context (4.10.9):
- React-Core
- react-native-secure-key-store (2.0.10):
- React-Core
@ -1240,7 +1240,7 @@ PODS:
- React-utils (= 0.74.5)
- ReactNativeCameraKit (13.0.0):
- React-Core
- RealmJS (12.12.1):
- RealmJS (12.13.0):
- React
- RNCAsyncStorage (1.24.0):
- React-Core
@ -1789,7 +1789,7 @@ SPEC CHECKSUMS:
react-native-menu: d32728a357dfb360cf01cd5979cf7713c5acbb95
react-native-qrcode-local-image: 35ccb306e4265bc5545f813e54cc830b5d75bcfc
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
react-native-safe-area-context: ab8f4a3d8180913bd78ae75dd599c94cce3d5e9a
react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898
react-native-tcp-socket: 8c3e8bef909ab06c557eeb95363fe029391ff09d
React-nativeconfig: ba9a2e54e2f0882cf7882698825052793ed4c851
@ -1816,7 +1816,7 @@ SPEC CHECKSUMS:
React-utils: f242eb7e7889419d979ca0e1c02ccc0ea6e43b29
ReactCommon: f7da14a8827b72704169a48c929bcde802698361
ReactNativeCameraKit: 9d46a5d7dd544ca64aa9c03c150d2348faf437eb
RealmJS: f4f6d27b325b1c1b402eb0aa5ee79e9d5f603293
RealmJS: a8c77aa700951e22403015390b33135f7ad4ace9
RNCAsyncStorage: ec53e44dc3e75b44aa2a9f37618a49c3bc080a7a
RNCClipboard: 0a720adef5ec193aa0e3de24c3977222c7e52a37
RNCPushNotificationIOS: 64218f3c776c03d7408284a819b2abfda1834bc8

108
package-lock.json generated
View File

@ -53,7 +53,6 @@
"electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc",
"electrum-mnemonic": "2.0.0",
"events": "3.3.0",
"frisbee": "3.1.4",
"junderw-crc32c": "1.2.0",
"lottie-react-native": "6.7.2",
"path-browserify": "1.0.1",
@ -4878,10 +4877,6 @@
"node": ">=6.5"
}
},
"node_modules/abortcontroller-polyfill": {
"version": "1.7.5",
"license": "MIT"
},
"node_modules/accepts": {
"version": "1.3.8",
"license": "MIT",
@ -5687,10 +5682,6 @@
"version": "1.0.0",
"license": "ISC"
},
"node_modules/boolean": {
"version": "3.2.0",
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"license": "MIT",
@ -6136,10 +6127,6 @@
],
"license": "CC-BY-4.0"
},
"node_modules/caseless": {
"version": "0.12.0",
"license": "Apache-2.0"
},
"node_modules/cbor-sync": {
"version": "1.0.4",
"license": "MIT"
@ -6472,13 +6459,6 @@
"node": "^12.20.0 || >=14"
}
},
"node_modules/common-tags": {
"version": "1.8.2",
"license": "MIT",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/commondir": {
"version": "1.0.1",
"license": "MIT"
@ -6756,31 +6736,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/cross-fetch": {
"version": "3.1.8",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.12"
}
},
"node_modules/cross-fetch/node_modules/node-fetch": {
"version": "2.7.0",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"license": "MIT",
@ -8836,49 +8791,6 @@
"node": ">= 0.6"
}
},
"node_modules/frisbee": {
"version": "3.1.4",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.10.2",
"abortcontroller-polyfill": "^1.4.0",
"boolean": "^3.0.1",
"caseless": "^0.12.0",
"common-tags": "^1.8.0",
"cross-fetch": "^3.0.4",
"debug": "^4.1.1",
"qs": "6.9.4",
"url-join": "^4.0.1",
"url-parse": "^1.4.7"
},
"engines": {
"node": ">=8.9.4"
}
},
"node_modules/frisbee/node_modules/@babel/runtime": {
"version": "7.25.0",
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/frisbee/node_modules/qs": {
"version": "6.9.4",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/frisbee/node_modules/regenerator-runtime": {
"version": "0.14.1",
"license": "MIT"
},
"node_modules/fs-constants": {
"version": "1.0.0",
"license": "MIT"
@ -12827,10 +12739,6 @@
"node": ">=0.4.x"
}
},
"node_modules/querystringify": {
"version": "2.2.0",
"license": "MIT"
},
"node_modules/queue": {
"version": "6.0.2",
"license": "MIT",
@ -13806,10 +13714,6 @@
"version": "2.0.0",
"license": "ISC"
},
"node_modules/requires-port": {
"version": "1.0.0",
"license": "MIT"
},
"node_modules/resolve": {
"version": "1.22.8",
"license": "MIT",
@ -15339,18 +15243,6 @@
"node": ">= 0.4"
}
},
"node_modules/url-join": {
"version": "4.0.1",
"license": "MIT"
},
"node_modules/url-parse": {
"version": "1.5.10",
"license": "MIT",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/url/node_modules/punycode": {
"version": "1.4.1",
"license": "MIT"

View File

@ -80,16 +80,16 @@
"@keystonehq/bc-ur-registry": "0.7.0",
"@lodev09/react-native-true-sheet": "github:BlueWallet/react-native-true-sheet#730a84b0261ef2dd2e7e9adadba7f260c7f76726",
"@ngraveio/bc-ur": "1.1.13",
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
"@noble/secp256k1": "1.6.3",
"@react-native-async-storage/async-storage": "1.24.0",
"@react-native-clipboard/clipboard": "1.14.1",
"@react-native-community/push-notification-ios": "1.11.0",
"@react-native/gradle-plugin": "^0.74.85",
"@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#958fac3d40811f38b53042ada9168175e321b99f",
"@react-native/gradle-plugin": "^0.74.85",
"@react-navigation/drawer": "6.7.2",
"@react-navigation/native": "6.1.18",
"@react-navigation/native-stack": "6.11.0",
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
"@rneui/base": "4.0.0-rc.8",
"@rneui/themed": "4.0.0-rc.8",
"@spsina/bip47": "github:BlueWallet/bip47#f4b8047",
@ -116,16 +116,15 @@
"electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc",
"electrum-mnemonic": "2.0.0",
"events": "3.3.0",
"frisbee": "3.1.4",
"junderw-crc32c": "1.2.0",
"lottie-react-native": "6.7.2",
"path-browserify": "1.0.1",
"payjoin-client": "1.0.1",
"process": "0.11.10",
"prop-types": "15.8.1",
"react-native": "0.74.5",
"react": "18.3.1",
"react-localization": "github:BlueWallet/react-localization#ae7969a",
"react-native": "0.74.5",
"react-native-biometrics": "3.0.1",
"react-native-blue-crypto": "github:BlueWallet/react-native-blue-crypto#3cb5442",
"react-native-camera-kit": "13.0.0",
@ -146,8 +145,8 @@
"react-native-localize": "3.2.1",
"react-native-obscure": "github:BlueWallet/react-native-obscure#f4b83b4a261e39b1f5ed4a45ac5bcabc8a59eadb",
"react-native-permissions": "4.1.5",
"react-native-prompt-android": "github:BlueWallet/react-native-prompt-android#ed168d66fed556bc2ed07cf498770f058b78a376",
"react-native-privacy-snapshot": "github:BlueWallet/react-native-privacy-snapshot#529e4627d93f67752a27e82a040ff7b64dca0783",
"react-native-prompt-android": "github:BlueWallet/react-native-prompt-android#ed168d66fed556bc2ed07cf498770f058b78a376",
"react-native-push-notification": "8.1.1",
"react-native-qrcode-svg": "6.3.2",
"react-native-quick-actions": "0.3.13",

View File

@ -1,5 +1,4 @@
import assert from 'assert';
import Frisbee from 'frisbee';
import { LightningCustodianWallet } from '../../class';
@ -164,22 +163,25 @@ describe.skip('LightningCustodianWallet', () => {
console.error('process.env.OPENNODE not set, skipped');
return;
}
const api = new Frisbee({
baseURI: 'https://api.opennode.co',
});
const res = await api.post('/v1/charges', {
const response = await fetch('https://api.opennode.co/v1/charges', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: process.env.OPENNODE,
},
body: '{"amount": "0.01", "currency": "USD"}',
body: JSON.stringify({
amount: '0.01',
currency: 'USD',
}),
});
if (!res.body || !res.body.data || !res.body.data.lightning_invoice || !res.body.data.lightning_invoice.payreq) {
const res = await response.json();
if (!res.data || !res.data.lightning_invoice || !res.data.lightning_invoice.payreq) {
throw new Error('Opennode problem');
}
const invoice = res.body.data.lightning_invoice.payreq;
const invoice = res.data.lightning_invoice.payreq;
const l2 = new LightningCustodianWallet();
l2.setSecret(process.env.BLITZHUB);
@ -216,25 +218,22 @@ describe.skip('LightningCustodianWallet', () => {
return;
}
const api = new Frisbee({
baseURI: 'https://api.strike.acinq.co',
headers: {},
});
api.auth(process.env.STRIKE + ':');
const res = await api.post('/api/v1/charges', {
const response = await fetch('https://api.strike.acinq.co/api/v1/charges', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${btoa(process.env.STRIKE + ':')}`,
},
body: 'amount=1&currency=btc&description=acceptance+test',
});
if (!res.body || !res.body.payment_request) {
const res = await response.json();
if (!res.payment_request) {
throw new Error('Strike problem: ' + JSON.stringify(res));
}
const invoice = res.body.payment_request;
const invoice = res.payment_request;
const l2 = new LightningCustodianWallet();
l2.setSecret(process.env.BLITZHUB);
@ -290,18 +289,20 @@ describe.skip('LightningCustodianWallet', () => {
return;
}
const api = new Frisbee({
baseURI: 'https://api-bitrefill.com',
headers: {},
const response = await fetch(`https://api-bitrefill.com/v1/lnurl_pay/${process.env.BITREFILL}/callback?amount=1000`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
const res = await api.get('/v1/lnurl_pay/' + process.env.BITREFILL + '/callback?amount=1000');
const res = await response.json();
if (!res.body || !res.body.pr) {
if (!res.pr) {
throw new Error('Bitrefill problem: ' + JSON.stringify(res));
}
const invoice = res.body.pr;
const invoice = res.pr;
const l2 = new LightningCustodianWallet();
l2.setSecret(process.env.BLITZHUB);
@ -427,16 +428,16 @@ describe.skip('LightningCustodianWallet', () => {
// now, paying same internal invoice. should fail:
let coughtError = false;
let caughtError = false;
await lOld.fetchTransactions();
txLen = lOld.transactions_raw.length;
const invLen = (await lNew.getUserInvoices()).length;
try {
await lOld.payInvoice(invoice);
} catch (Err) {
coughtError = true;
caughtError = true;
}
assert.ok(coughtError);
assert.ok(caughtError);
await lOld.fetchTransactions();
assert.strictEqual(txLen, lOld.transactions_raw.length, 'tx count should not be changed');
@ -457,12 +458,10 @@ describe.skip('LightningCustodianWallet', () => {
return;
}
// fetchig invoice from tippin.me :
// fetching invoice from tippin.me :
const api = new Frisbee({
baseURI: 'https://tippin.me',
});
const res = await api.post('/lndreq/newinvoice.php', {
const response = await fetch('https://tippin.me/lndreq/newinvoice.php', {
method: 'POST',
headers: {
Origin: 'https://tippin.me',
'Accept-Encoding': 'gzip, deflate, br',
@ -473,13 +472,11 @@ describe.skip('LightningCustodianWallet', () => {
body: 'userid=1188&username=overtorment&istaco=0&customAmnt=0&customMemo=',
});
let json;
let invoice;
if (res && res.body && (json = JSON.parse(res.body)) && json.message) {
invoice = json.message;
} else {
const res = await response.json();
if (!res || !res.message) {
throw new Error('tippin.me problem: ' + JSON.stringify(res));
}
const invoice = res.message;
// --> use to pay specific invoice
// invoice =
@ -527,7 +524,7 @@ describe.skip('LightningCustodianWallet', () => {
assert.ok(oldBalance - l2.balance < 10); // sanity check
});
it('cant create zemo amt invoices yet', async () => {
it('cant create zero amt invoices yet', async () => {
const l = new LightningCustodianWallet();
l.setBaseURI(baseUri);
l.init();
@ -569,12 +566,10 @@ describe.skip('LightningCustodianWallet', () => {
return;
}
// fetchig invoice from tippin.me :
// fetching invoice from tippin.me :
const api = new Frisbee({
baseURI: 'https://tippin.me',
});
const res = await api.post('/lndreq/newinvoice.php', {
const response = await fetch('https://tippin.me/lndreq/newinvoice.php', {
method: 'POST',
headers: {
Origin: 'https://tippin.me',
'Accept-Encoding': 'gzip, deflate, br',
@ -585,14 +580,11 @@ describe.skip('LightningCustodianWallet', () => {
body: 'userid=1188&username=overtorment&istaco=0&customAmnt=0&customMemo=',
});
let json;
let invoice;
if (res && res.body && (json = JSON.parse(res.body)) && json.message) {
invoice = json.message;
} else {
const res = await response.json();
if (!res || !res.message) {
throw new Error('tippin.me problem: ' + JSON.stringify(res));
}
const invoice = res.message;
const l2 = new LightningCustodianWallet();
l2.setSecret(process.env.BLITZHUB);
l2.setBaseURI(baseUri);

15
typings/frisbee.d.ts vendored
View File

@ -1,15 +0,0 @@
declare module 'frisbee' {
// TODO: improve with more specific types
type RequestOptions = Record<string, any>;
type Response = any;
declare class Frisbee {
constructor(options: { baseURI?: string; headers?: Record<string, string> });
get(path: string, options?: RequestOptions): Promise<Response>;
post(path: string, options?: RequestOptions): Promise<Response>;
// TODO: add missing methods
}
export default Frisbee;
}