mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
ADD: hodlhodl trading platform integration alpha
This commit is contained in:
parent
604e958008
commit
1b2bf0d590
@ -22,6 +22,7 @@ import WalletDetails from './screen/wallets/details';
|
||||
import WalletExport from './screen/wallets/export';
|
||||
import WalletXpub from './screen/wallets/xpub';
|
||||
import BuyBitcoin from './screen/wallets/buyBitcoin';
|
||||
import HodlHodl from './screen/wallets/hodlHodl';
|
||||
import Marketplace from './screen/wallets/marketplace';
|
||||
import ReorderWallets from './screen/wallets/reorderWallets';
|
||||
import SelectWallet from './screen/wallets/selectWallet';
|
||||
@ -76,6 +77,9 @@ const WalletsStackNavigator = createStackNavigator(
|
||||
WalletDetails: {
|
||||
screen: WalletDetails,
|
||||
},
|
||||
HodlHodl: {
|
||||
screen: HodlHodl,
|
||||
},
|
||||
CPFP: {
|
||||
screen: cpfp,
|
||||
},
|
||||
|
@ -77,7 +77,7 @@ import com.android.build.OutputFile
|
||||
|
||||
project.ext.react = [
|
||||
entryFile: "index.js",
|
||||
enableHermes: true, // clean and rebuild if changing
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
|
@ -104,6 +104,10 @@ export class AbstractWallet {
|
||||
return false;
|
||||
}
|
||||
|
||||
allowHodlHodlTrading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
weOwnAddress(address) {
|
||||
throw Error('not implemented');
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ export class HDSegwitBech32Wallet extends AbstractHDElectrumWallet {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowHodlHodlTrading() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowRBF() {
|
||||
return true;
|
||||
}
|
||||
|
132
class/hodl-hodl-api.js
Normal file
132
class/hodl-hodl-api.js
Normal file
@ -0,0 +1,132 @@
|
||||
import Frisbee from 'frisbee';
|
||||
|
||||
export class HodlHodlApi {
|
||||
static PAGINATION_LIMIT = 'limit'; // int
|
||||
static PAGINATION_OFFSET = 'offset'; // int
|
||||
|
||||
static FILTERS_ASSET_CODE = 'asset_code';
|
||||
static FILTERS_ASSET_CODE_VALUE_BTC = 'BTC';
|
||||
static FILTERS_ASSET_CODE_VALUE_BTCLN = 'BTCLN';
|
||||
|
||||
static FILTERS_SIDE = 'side';
|
||||
static FILTERS_SIDE_VALUE_BUY = 'buy';
|
||||
static FILTERS_SIDE_VALUE_SELL = 'sell';
|
||||
|
||||
static FILTERS_INCLUDE_GLOBAL = 'include_global'; // bool
|
||||
static FILTERS_ONLY_WORKING_NOW = 'only_working_now'; // bool
|
||||
static FILTERS_COUNTRY = 'country'; // code or name (or "Global")
|
||||
static FILTERS_COUNTRY_VALUE_GLOBAL = 'Global'; // code or name
|
||||
static FILTERS_CURRENCY_CODE = 'currency_code';
|
||||
static FILTERS_PAYMENT_METHOD_ID = 'payment_method_id';
|
||||
static FILTERS_PAYMENT_METHOD_TYPE = 'payment_method_type';
|
||||
static FILTERS_PAYMENT_METHOD_NAME = 'payment_method_name';
|
||||
static FILTERS_VOLUME = 'volume';
|
||||
static FILTERS_PAYMENT_WINDOW_MINUTES_MAX = 'payment_window_minutes_max'; // in minutes
|
||||
static FILTERS_USER_AVERAGE_PAYMENT_TIME_MINUTES_MAX = 'user_average_payment_time_minutes_max'; // in minutes
|
||||
static FILTERS_USER_AVERAGE_RELEASE_TIME_MINUTES_MAX = 'user_average_release_time_minutes_max'; // in minutes
|
||||
|
||||
static SORT_DIRECTION = 'direction';
|
||||
static SORT_DIRECTION_VALUE_ASC = 'asc';
|
||||
static SORT_DIRECTION_VALUE_DESC = 'desc';
|
||||
|
||||
static SORT_BY = 'by';
|
||||
static SORT_BY_VALUE_PRICE = 'price';
|
||||
static SORT_BY_VALUE_PAYMENT_WINDOW_MINUTES = 'payment_window_minutes';
|
||||
static SORT_BY_VALUE_USER_AVERAGE_PAYMENT_TIME_MINUTES = 'user_average_payment_time_minutes';
|
||||
static SORT_BY_VALUE_USER_AVERAGE_RELEASE_TIME_MINUTES = 'user_average_release_time_minutes';
|
||||
static SORT_BY_VALUE_RATING = 'rating';
|
||||
|
||||
constructor(apiKey = false) {
|
||||
this.baseURI = 'https://hodlhodl.com/';
|
||||
this.apiKey = apiKey || 'cmO8iLFgx9wrxCe9R7zFtbWpqVqpGuDfXR3FJB0PSGCd7EAh3xgG51vBKgNTAF8fEEpS0loqZ9P1fDZt';
|
||||
this._api = new Frisbee({ baseURI: this.baseURI });
|
||||
}
|
||||
|
||||
_getHeaders() {
|
||||
return {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer ' + this.apiKey,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getCountries() {
|
||||
let response = await this._api.get('/api/v1/countries', this._getHeaders());
|
||||
|
||||
let json = response.body;
|
||||
if (!json || !json.countries || json.status === 'error') {
|
||||
throw new Error('API failure: ' + JSON.stringify(response));
|
||||
}
|
||||
|
||||
return (this._countries = json.countries);
|
||||
}
|
||||
|
||||
async getMyCountryCode() {
|
||||
let _api = new Frisbee({ baseURI: 'https://ifconfig.co/' });
|
||||
let response;
|
||||
|
||||
let allowedTries = 6;
|
||||
while (allowedTries > 0) {
|
||||
// this API fails a lot, so lets retry several times
|
||||
response = await _api.get('/country-iso', {
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
});
|
||||
|
||||
let body = response.body;
|
||||
if (typeof body === 'string') body = body.replace('\n', '');
|
||||
if (!body || body.length !== 2) {
|
||||
allowedTries--;
|
||||
await (async () => new Promise(resolve => setTimeout(resolve, 3000)))(); // sleep
|
||||
} else {
|
||||
return (this._myCountryCode = body);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('API failure after several tries: ' + JSON.stringify(response));
|
||||
}
|
||||
|
||||
async getPaymentMethods(country) {
|
||||
let response = await this._api.get('/api/v1/payment_methods?filters[country]=' + country, this._getHeaders());
|
||||
|
||||
let json = response.body;
|
||||
if (!json || !json.payment_methods || json.status === 'error') {
|
||||
throw new Error('API failure: ' + JSON.stringify(response));
|
||||
}
|
||||
|
||||
return (this._payment_methods = json.payment_methods.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)));
|
||||
}
|
||||
|
||||
async getCurrencies() {
|
||||
let response = await this._api.get('/api/v1/currencies', this._getHeaders());
|
||||
|
||||
let json = response.body;
|
||||
if (!json || !json.currencies || json.status === 'error') {
|
||||
throw new Error('API failure: ' + JSON.stringify(response));
|
||||
}
|
||||
|
||||
return (this._currencies = json.currencies.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)));
|
||||
}
|
||||
|
||||
async getOffers(pagination = {}, filters = {}, sort = {}) {
|
||||
let uri = [];
|
||||
for (let key in sort) {
|
||||
uri.push('sort[' + key + ']=' + sort[key]);
|
||||
}
|
||||
for (let key in filters) {
|
||||
uri.push('filters[' + key + ']=' + filters[key]);
|
||||
}
|
||||
for (let key in pagination) {
|
||||
uri.push('pagination[' + key + ']=' + pagination[key]);
|
||||
}
|
||||
let response = await this._api.get('/api/v1/offers?' + uri.join('&'), this._getHeaders());
|
||||
|
||||
let json = response.body;
|
||||
if (!json || !json.offers || json.status === 'error') {
|
||||
throw new Error('API failure: ' + JSON.stringify(response));
|
||||
}
|
||||
|
||||
return (this._offers = json.offers);
|
||||
}
|
||||
}
|
@ -292,6 +292,26 @@ export class LegacyWallet extends AbstractWallet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts script pub key to legacy address if it can. Returns FALSE if it cant.
|
||||
*
|
||||
* @param scriptPubKey
|
||||
* @returns {boolean|string} Either p2pkh address or false
|
||||
*/
|
||||
static scriptPubKeyToAddress(scriptPubKey) {
|
||||
const scriptPubKey2 = Buffer.from(scriptPubKey, 'hex');
|
||||
let ret;
|
||||
try {
|
||||
ret = bitcoin.payments.p2pkh({
|
||||
output: scriptPubKey2,
|
||||
network: bitcoin.networks.bitcoin,
|
||||
}).address;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
weOwnAddress(address) {
|
||||
return this.getAddress() === address || this._address === address;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ PODS:
|
||||
- React
|
||||
- RemobileReactNativeQrcodeLocalImage (1.0.4):
|
||||
- React
|
||||
- RNCAsyncStorage (1.7.1):
|
||||
- RNCAsyncStorage (1.6.2):
|
||||
- React
|
||||
- RNDefaultPreference (1.4.1):
|
||||
- React
|
||||
@ -265,13 +265,13 @@ PODS:
|
||||
- React
|
||||
- RNQuickAction (0.3.13):
|
||||
- React
|
||||
- RNRate (1.1.10):
|
||||
- RNRate (1.0.1):
|
||||
- React
|
||||
- RNReactNativeHapticFeedback (1.9.0):
|
||||
- React
|
||||
- RNSecureKeyStore (1.0.0):
|
||||
- React
|
||||
- RNSentry (1.3.1):
|
||||
- RNSentry (1.2.1):
|
||||
- React
|
||||
- Sentry (~> 4.4.0)
|
||||
- RNShare (2.0.0):
|
||||
@ -340,7 +340,7 @@ DEPENDENCIES:
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNHandoff (from `../node_modules/react-native-handoff`)
|
||||
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
||||
- RNRate (from `../node_modules/react-native-rate`)
|
||||
- RNRate (from `../node_modules/react-native-rate/ios`)
|
||||
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
|
||||
- RNSecureKeyStore (from `../node_modules/react-native-secure-key-store/ios`)
|
||||
- "RNSentry (from `../node_modules/@sentry/react-native`)"
|
||||
@ -448,7 +448,7 @@ EXTERNAL SOURCES:
|
||||
RNQuickAction:
|
||||
:path: "../node_modules/react-native-quick-actions"
|
||||
RNRate:
|
||||
:path: "../node_modules/react-native-rate"
|
||||
:path: "../node_modules/react-native-rate/ios"
|
||||
RNReactNativeHapticFeedback:
|
||||
:path: "../node_modules/react-native-haptic-feedback"
|
||||
RNSecureKeyStore:
|
||||
@ -510,17 +510,17 @@ SPEC CHECKSUMS:
|
||||
ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
|
||||
ReactNativePrivacySnapshot: cc295e45dc22810e9ff2c93380d643de20a77015
|
||||
RemobileReactNativeQrcodeLocalImage: 57aadc12896b148fb5e04bc7c6805f3565f5c3fa
|
||||
RNCAsyncStorage: 8539fc80a0075fcc9c8e2dff84cd22dc5bf1dacf
|
||||
RNCAsyncStorage: 5ae4d57458804e99f73d427214442a6b10a53856
|
||||
RNDefaultPreference: 12d246dd2222e66dadcd76cc1250560663befc3a
|
||||
RNDeviceInfo: 12faae605ba42a1a5041c3c41a77834bc23f049d
|
||||
RNFS: 90d1a32d3bc8f75cc7fc3dd2f67506049664346b
|
||||
RNGestureHandler: 911d3b110a7a233a34c4f800e7188a84b75319c6
|
||||
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||
RNRate: d44a8bca6ee08f5d890ecccddaec2810955ffbb3
|
||||
RNRate: 29be49c24b314c4e8ec09d848c3965f61cb0be47
|
||||
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
||||
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
|
||||
RNSentry: 6458ba85aa3f8ae291abed4f72abbd7080839c71
|
||||
RNSentry: 9b1d983b2d5d1c215ba6490348fd2a4cc23a8a9d
|
||||
RNShare: 8b171d4b43c1d886917fdd303bf7a4b87167b05c
|
||||
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
|
||||
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
|
||||
|
@ -27,7 +27,7 @@ export default class BuyBitcoin extends Component {
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
console.log('buyBitcoin/details - componentDidMount');
|
||||
console.log('buyBitcoin - componentDidMount');
|
||||
|
||||
/** @type {AbstractWallet} */
|
||||
let wallet;
|
||||
|
890
screen/wallets/hodlHodl.js
Normal file
890
screen/wallets/hodlHodl.js
Normal file
File diff suppressed because one or more lines are too long
@ -222,6 +222,7 @@ export default class WalletTransactions extends Component {
|
||||
*/}
|
||||
{this.renderMarketplaceButton()}
|
||||
{this.state.wallet.type === LightningCustodianWallet.type && Platform.OS === 'ios' && this.renderLappBrowserButton()}
|
||||
{this.state.wallet.allowHodlHodlTrading() && this.renderHodlHodlButton()}
|
||||
</View>
|
||||
<Text
|
||||
style={{
|
||||
@ -375,6 +376,29 @@ export default class WalletTransactions extends Component {
|
||||
);
|
||||
};
|
||||
|
||||
renderHodlHodlButton = () => {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
this.props.navigation.navigate('HodlHodl', { fromWallet: this.state.wallet });
|
||||
}}
|
||||
style={{
|
||||
marginLeft: 5,
|
||||
backgroundColor: '#f2f2f2',
|
||||
borderRadius: 9,
|
||||
minHeight: 49,
|
||||
flex: 1,
|
||||
paddingHorizontal: 8,
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: '#062453', fontSize: 18 }}>local trader</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
onWalletSelect = async wallet => {
|
||||
if (wallet) {
|
||||
NavigationService.navigate('WalletTransactions', {
|
||||
|
@ -1,5 +1,12 @@
|
||||
/* global it, jasmine, afterAll, beforeAll */
|
||||
import { SegwitP2SHWallet, SegwitBech32Wallet, HDSegwitP2SHWallet, HDLegacyBreadwalletWallet, HDLegacyP2PKHWallet } from '../../class';
|
||||
import {
|
||||
SegwitP2SHWallet,
|
||||
SegwitBech32Wallet,
|
||||
HDSegwitP2SHWallet,
|
||||
HDLegacyBreadwalletWallet,
|
||||
HDLegacyP2PKHWallet,
|
||||
LegacyWallet,
|
||||
} from '../../class';
|
||||
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment
|
||||
@ -37,6 +44,9 @@ it('can convert witness to address', () => {
|
||||
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress('00144d757460da5fcaf84cc22f3847faaa1078e84f6a');
|
||||
assert.strictEqual(address, 'bc1qf46hgcx6tl90snxz9uuy0742zpuwsnm27ysdh7');
|
||||
|
||||
address = LegacyWallet.scriptPubKeyToAddress('76a914d0b77eb1502c81c4093da9aa6eccfdf560cdd6b288ac');
|
||||
assert.strictEqual(address, '1L2bNMGRQQLT2AVUek4K9L7sn3SSMioMgE');
|
||||
});
|
||||
|
||||
it('can create a Segwit HD (BIP49)', async function() {
|
||||
|
135
tests/integration/HodlHodl.test.js
Normal file
135
tests/integration/HodlHodl.test.js
Normal file
@ -0,0 +1,135 @@
|
||||
/* global it, jasmine, describe */
|
||||
import { LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet } from '../../class';
|
||||
import { HodlHodlApi } from '../../class/hodl-hodl-api';
|
||||
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const assert = require('assert');
|
||||
|
||||
it('can create escrow address', () => {
|
||||
const keyPairServer = bitcoin.ECPair.fromPrivateKey(
|
||||
Buffer.from('9a8cfd0e33a37c90a46d358c84ca3d8dd089ed35409a6eb1973148c0df492288', 'hex'),
|
||||
);
|
||||
const keyPairSeller = bitcoin.ECPair.fromPrivateKey(
|
||||
Buffer.from('ab4163f517bfac01d7acd3a1e398bfb28b53ebd162cb1dd767cc63ae8069ef37', 'hex'),
|
||||
);
|
||||
const keyPairBuyer = bitcoin.ECPair.fromPrivateKey(
|
||||
Buffer.from('b4ab9ed098b6d4b308deaefce5079f4203c43cfb51b699dd35dcc0f1ae5906fd', 'hex'),
|
||||
);
|
||||
|
||||
const pubkeys = [
|
||||
keyPairServer.publicKey, // '03141024b18929bfec5b567c12b1693d4ae02783873e2e3aa444f0d6950cb97dee', // server
|
||||
keyPairSeller.publicKey, // '0208137b6cb23cef02c0529948a2ed12fbeed0813cce555de073319f56e215ee1b', // seller
|
||||
keyPairBuyer.publicKey, // '035ed5825258d4f1685df804f21296b9957cd319cf5949ace92fa5767eb7a946f2', // buyer
|
||||
].map(hex => Buffer.from(hex, 'hex'));
|
||||
|
||||
const p2shP2wshP2ms = bitcoin.payments.p2sh({
|
||||
redeem: bitcoin.payments.p2wsh({
|
||||
redeem: bitcoin.payments.p2ms({ m: 2, pubkeys }),
|
||||
}),
|
||||
});
|
||||
const address = p2shP2wshP2ms.address;
|
||||
// console.warn(p2sh_p2wsh_p2ms);
|
||||
|
||||
assert.strictEqual(address, '391ygT71qeF7vbYjxsUZPzH6oDc7Rv4vTs');
|
||||
|
||||
let signedByServerReleaseTransaction =
|
||||
'01000000000101356493a6b93bf17e66d7ec12f1a54e279da17f669f41bf11405a6f2617e1022501000000232200208ec72df31adaa132e40a5f5033589c0e18b67a64cdc65e9c75027fe1efd10f4cffffffff02227e010000000000160014b1c61a73a529c315a1f2b87df12c7948d86ba10c26020000000000001976a914d0b77eb1502c81c4093da9aa6eccfdf560cdd6b288ac040047304402205a447563db8e74177a1fbcdcfe7b7b22556c39d68c17ffe0a4a02609d78c83130220772fbf3261b6031a915eca7e441092df3fe6e4c7d4f389c4921c1f18661c20f401460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069522103141024b18929bfec5b567c12b1693d4ae02783873e2e3aa444f0d6950cb97dee210208137b6cb23cef02c0529948a2ed12fbeed0813cce555de073319f56e215ee1b21035ed5825258d4f1685df804f21296b9957cd319cf5949ace92fa5767eb7a946f253ae00000000';
|
||||
|
||||
let txDecoded = bitcoin.Transaction.fromHex(signedByServerReleaseTransaction);
|
||||
// console.warn(txDecoded.ins[0].witness);
|
||||
|
||||
// we always expect only one input:
|
||||
const psbt = new bitcoin.Psbt().addInput({
|
||||
hash: txDecoded.ins[0].hash,
|
||||
index: txDecoded.ins[0].index,
|
||||
witnessUtxo: {
|
||||
script: p2shP2wshP2ms.redeem.output,
|
||||
value: 100000,
|
||||
},
|
||||
// redeemScript,
|
||||
witnessScript: p2shP2wshP2ms.redeem.redeem.output,
|
||||
});
|
||||
|
||||
for (let out of txDecoded.outs) {
|
||||
let scripthex = out.script.toString('hex');
|
||||
let address =
|
||||
LegacyWallet.scriptPubKeyToAddress(scripthex) ||
|
||||
SegwitP2SHWallet.scriptPubKeyToAddress(scripthex) ||
|
||||
SegwitBech32Wallet.scriptPubKeyToAddress(scripthex);
|
||||
psbt.addOutput({
|
||||
address,
|
||||
value: out.value,
|
||||
});
|
||||
}
|
||||
|
||||
// psbt.signInput(0, keyPairServer);
|
||||
psbt.signInput(0, keyPairSeller);
|
||||
|
||||
// console.warn('signature = ', psbt.data.inputs[0].partialSig[0].signature.toString('hex'));
|
||||
|
||||
// let tx = psbt.finalizeAllInputs().extractTransaction();
|
||||
// console.log(tx.toHex());
|
||||
});
|
||||
|
||||
describe('HodlHodl API', function() {
|
||||
it('can fetch countries & and own country code', async () => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200 * 1000;
|
||||
let Hodl = new HodlHodlApi();
|
||||
const countries = await Hodl.getCountries();
|
||||
assert.ok(countries[0]);
|
||||
assert.ok(countries[0].code);
|
||||
assert.ok(countries[0].name);
|
||||
assert.ok(countries[0].native_name);
|
||||
assert.ok(countries[0].currency_code);
|
||||
assert.ok(countries[0].currency_name);
|
||||
|
||||
let countryCode = await Hodl.getMyCountryCode();
|
||||
assert.strictEqual(countryCode.length, 2);
|
||||
});
|
||||
|
||||
it('can get offers', async () => {
|
||||
let Hodl = new HodlHodlApi();
|
||||
const offers = await Hodl.getOffers(
|
||||
{
|
||||
[HodlHodlApi.PAGINATION_LIMIT]: 10,
|
||||
},
|
||||
{
|
||||
[HodlHodlApi.FILTERS_COUNTRY]: HodlHodlApi.FILTERS_COUNTRY_VALUE_GLOBAL,
|
||||
[HodlHodlApi.FILTERS_SIDE]: HodlHodlApi.FILTERS_SIDE_VALUE_SELL,
|
||||
[HodlHodlApi.FILTERS_ASSET_CODE]: HodlHodlApi.FILTERS_ASSET_CODE_VALUE_BTC,
|
||||
[HodlHodlApi.FILTERS_INCLUDE_GLOBAL]: true,
|
||||
},
|
||||
{
|
||||
[HodlHodlApi.SORT_BY]: HodlHodlApi.SORT_BY_VALUE_PRICE,
|
||||
[HodlHodlApi.SORT_DIRECTION]: HodlHodlApi.SORT_DIRECTION_VALUE_ASC,
|
||||
},
|
||||
);
|
||||
|
||||
assert.ok(offers[0]);
|
||||
assert.ok(offers[0].asset_code === 'BTC');
|
||||
assert.ok(offers[0].country_code);
|
||||
assert.ok(offers[0].side === HodlHodlApi.FILTERS_SIDE_VALUE_SELL);
|
||||
assert.ok(offers[0].title || offers[0].description);
|
||||
assert.ok(offers[0].price);
|
||||
assert.ok(offers[0].payment_method_instructions);
|
||||
assert.ok(offers[0].trader);
|
||||
});
|
||||
|
||||
it('can get payment methods', async () => {
|
||||
let Hodl = new HodlHodlApi();
|
||||
const methods = await Hodl.getPaymentMethods(HodlHodlApi.FILTERS_COUNTRY_VALUE_GLOBAL);
|
||||
assert.ok(methods[0]);
|
||||
assert.ok(methods[0].id);
|
||||
assert.ok(methods[0].type);
|
||||
assert.ok(methods[0].name);
|
||||
});
|
||||
|
||||
it('cat get currencies', async () => {
|
||||
let Hodl = new HodlHodlApi();
|
||||
const currencies = await Hodl.getCurrencies();
|
||||
assert.ok(currencies[0]);
|
||||
assert.ok(currencies[0].code);
|
||||
assert.ok(currencies[0].name);
|
||||
assert.ok(currencies[0].type);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user