Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace js-subscriptions with dart #1570

Merged
merged 23 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9d27af6
[ew_polkadart] generate storage key methods
clangenb Nov 23, 2023
ad8c2a8
[ew_polkadart] bump polkadart, which should fix storage subscriptions
clangenb Nov 23, 2023
7c6de72
wip subscribe to native balance with dart.
clangenb Nov 23, 2023
700dbf7
remove unused subscribe timestamp method.
clangenb Nov 23, 2023
c634eb6
prevent null error in dart subscription
clangenb Nov 23, 2023
bcc1c28
wip of subscribing to current phase.
clangenb Nov 23, 2023
ce40c21
fix polkadart version to produce correct key hash
clangenb Nov 23, 2023
9405667
remove debug logs as dart ceremony phase subscription is working now.
clangenb Nov 23, 2023
5ed0506
[encointerApi] remove remnants of subscribing current phase from JS.
clangenb Nov 23, 2023
ba747fe
[JS] remove obsolete (encointer) balance subscriptions
clangenb Nov 23, 2023
f572ed3
[encointerApi] fmt
clangenb Nov 23, 2023
4a136dc
[encointerApi] rewrite placeholder for businessRegistry subscription
clangenb Nov 23, 2023
46e3c27
[encointerApi] replace cid subscription with dart counterpart
clangenb Nov 23, 2023
61abdc7
[JS] remove obsolete subscribeBusinessRegistry
clangenb Nov 23, 2023
591e741
[JS] remove unused imports
clangenb Nov 23, 2023
c1e24a2
subscribe to new heads from dart
clangenb Nov 23, 2023
73bde35
[JS] remove tests that use no longer existing method.
clangenb Nov 24, 2023
db023ca
bump ew_polkadart
clangenb Nov 24, 2023
ae2aaa3
[encointerApi] get community identifiers upon subscribing.
clangenb Nov 25, 2023
c296cbb
[encointerApi] get current phase upon subscribing
clangenb Nov 25, 2023
c33d6f2
fmt
clangenb Nov 25, 2023
b07ac63
[ReconnectingWebsocket] concurrent disconnect handling
clangenb Nov 25, 2023
3a201d7
[encointerApi] fix: don't get reputations if the address is empty.
clangenb Nov 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions app/js_service_encointer/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import 'regenerator-runtime/runtime.js';
import account from './service/account.js';
import encointer from './service/encointer.js';
import settings from './service/settings.js';
import chain from './service/chain.js';

window.addEventListener('flutterInAppWebViewPlatformReady', function (event) {

window.send = send;

window.account = account;
window.chain = chain;
window.encointer = encointer;
window.settings = settings;

Expand Down
44 changes: 0 additions & 44 deletions app/js_service_encointer/src/service/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { cryptoWaitReady, mnemonicGenerate } from '@polkadot/util-crypto';
import {
hexToU8a,
u8aToHex,
hexToString,
} from '@polkadot/util';
import BN from 'bn.js';
import { Keyring } from '@polkadot/keyring';
Expand All @@ -11,7 +10,6 @@ import {
encointerBalances,
transfer
} from '../config/consts.js';
import { unsubscribe } from '../utils/unsubscribe.js';
import { extractEvents } from '@encointer/node-api';
import { stringNumberToEncointerBalanceU8a } from '../utils/utils.js';

Expand Down Expand Up @@ -99,46 +97,6 @@ async function addressFromUri(uri) {
return keyring.encodeAddress(pubKey, ss58);
}

/**
* get ERT balance of an address
* @param {String} address
* @returns {String} balance
*/
async function getBalance (address) {
const all = await api.derive.balances.all(address);
const lockedBreakdown = all.lockedBreakdown.map((i) => {
return {
...i,
use: hexToString(i.id.toHex())
};
});
return {
...all,
lockedBreakdown
};
}

/**
* subscribes to ERT balance of an address
* @param msgChannel channel that the message handler uses on the dart side
* @param {String} address
* @returns {String} balance
*/
async function subscribeBalance (msgChannel, address) {
return await api.derive.balances.all(address, (all) => {
const lockedBreakdown = all.lockedBreakdown.map((i) => {
return {
...i,
use: hexToString(i.id.toHex())
};
});
send(msgChannel, {
...all,
lockedBreakdown
});
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

function getBlockTime (blocks) {
return new Promise((resolve) => {
const res = [];
Expand Down Expand Up @@ -335,8 +293,6 @@ export default {
addressFromUri,
gen,
recover,
getBalance,
subscribeBalance,
getBlockTime,
txFeeEstimate,
sendTx,
Expand Down
20 changes: 0 additions & 20 deletions app/js_service_encointer/src/service/chain.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
import { unsubscribe } from '../utils/unsubscribe.js';

/**
* Mainly debug method introduced to test subscriptions. Subscribes to the timestamp of the last block
* @param msgChannel channel that the message handler uses on the dart side
* @returns {Promise<void>}
*/
export async function subscribeTimestamp (msgChannel) {
await api.query.timestamp.now((moment) => {
send(msgChannel, moment);
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

export async function subscribeNewHeads (msgChannel) {
await api.rpc.chain.subscribeNewHeads((lastHeader) => {
send(msgChannel, lastHeader);
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

export async function getFinalizedHeader () {
const hash = await api.rpc.chain.getFinalizedHead();
return api.rpc.chain.getHeader(hash);
}

export default {
subscribeTimestamp,
subscribeNewHeads,
getFinalizedHeader,
};
57 changes: 2 additions & 55 deletions app/js_service_encointer/src/service/encointer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { assert, hexToU8a } from '@polkadot/util';
import { cryptoWaitReady } from '@polkadot/util-crypto';
import { createType } from '@polkadot/types';
import { parseEncointerBalance, stringToDegree } from '@encointer/types';
import { parseEncointerBalance } from '@encointer/types';
import { keyring, sendTxWithPair } from './account.js';
import { pallets, parachainSpecName, solochainSpecName } from '../config/consts.js';
import { unsubscribe } from '../utils/unsubscribe.js';
import { parachainSpecName, solochainSpecName } from '../config/consts.js';
import { communityIdentifierToString } from '@encointer/util';
import {
getMeetupIndex as _getMeetupIndex,
Expand All @@ -20,28 +19,6 @@ import {
hasCommittedFor,
} from './faucet.js';

/**
* Subscribes to the current ceremony phase
* @param msgChannel channel that the message handler uses on the dart side
* @returns {Promise<void>}
*/
export async function subscribeCurrentPhase (msgChannel) {
return await api.query.encointerScheduler.currentPhase((phase) => {
send(msgChannel, phase);
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

/**
* Subscribes to the currencies registry
* @param msgChannel channel that the message handler uses on the dart side
* @returns {Promise<void>}
*/
export async function subscribeCommunityIdentifiers (msgChannel) {
return await api.query[pallets.encointerCommunities.name][pallets.encointerCommunities.calls.communityIdentifiers]((cids) => {
send(msgChannel, cids);
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

export async function getBalance (cid, address) {
const balanceEntry = await api.query.encointerBalances.balance(cid, address);
return {
Expand Down Expand Up @@ -111,32 +88,6 @@ export function encointerTransferAll (fromPair, recipientAddress, cid) {
return sendTxWithPair(fromPair, txInfo, paramList);
}

/**
* Subscribes to the balance of a given cid
* @param msgChannel channel that the message handler uses on the dart side
* @returns {Promise<void>}
*/
export async function subscribeBalance (msgChannel, cid, address) {
return await api.query.encointerBalances.balance(cid, address, (b) => {
const balance = parseEncointerBalance(b.principal.bits);
send(msgChannel, {
principal: balance,
lastUpdate: b.lastUpdate.toNumber()
});
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

/**
* Subscribes to the business registry of a given cid
* @param msgChannel channel that the message handler uses on the dart side
* @returns {Promise<void>}
*/
export async function subscribeBusinessRegistry (msgChannel, cid) {
return await api.query.encointerBazaar.businessRegistry(cid, (businesses) => {
send(msgChannel, businesses);
}).then((unsub) => unsubscribe(unsub, msgChannel));
}

export async function getDemurrage (cid) {
const cidT = api.createType('CommunityIdentifier', cid);

Expand Down Expand Up @@ -292,10 +243,6 @@ export async function sendNextPhaseTx() {
}

export default {
subscribeCurrentPhase,
subscribeBalance,
subscribeCommunityIdentifiers,
subscribeBusinessRegistry,
getProofOfAttendance,
getMeetupIndex,
hasPendingIssuance,
Expand Down
9 changes: 0 additions & 9 deletions app/js_service_encointer/test/gesell.test-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,6 @@ describe('encointer', () => {
});
});

describe('accountgetBalances method', () => {
it('should return balances', async () => {
const address = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
const balances = await account.getBalance(address);
console.log(balances);
expect(balances.availableBalance.gtn(1));
});
});

describe('can transform problematic location', () => {
it('should be defined', async () => {
const loc_js = {
Expand Down
10 changes: 0 additions & 10 deletions app/js_service_encointer/test/service/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ describe('account', () => {
keyring = new Keyring({ type: 'sr25519' });
});

describe('faucet', () => {
it('has enough funds', async () => {
await cryptoWaitReady();
const alice = keyring.addFromUri('//Alice', { name: 'Alice default' });
const balance = await account.getBalance(alice.address);
const faucetTransferValue = 0.0001 * Math.pow(10, 12);
expect(parseInt(balance.freeBalance)).toBeGreaterThan(faucetTransferValue);
});
});

describe('community-payment', () => {
// skipping because it needs to have a community setup
it.skip('community fee payment works for ferdie without native tokens', async () => {
Expand Down
2 changes: 1 addition & 1 deletion app/lib/page/profile/account/faucet_list_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,6 @@ class _FaucetListTileState extends State<FaucetListTile> {

Future<BigInt> getNativeFreeBalance(String address) async {
final balance = await webApi.assets.getBalanceOf(address);
return balance.freeBalance;
return balance.free;
}
}
13 changes: 9 additions & 4 deletions app/lib/service/substrate_api/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class Api {
provider,
dartApi,
AccountApi(store, js, provider),
AssetsApi(store, js),
ChainApi(store, js),
AssetsApi(store, js, EncointerKusama(provider)),
ChainApi(store, provider),
EncointerApi(store, js, dartApi, ewHttp, EncointerKusama(provider)),
isIntegrationTest ? MockIpfsApi(ewHttp) : IpfsApi(ewHttp, gateway: store.settings.ipfsGateway),
jsServiceEncointer,
Expand Down Expand Up @@ -269,14 +269,19 @@ class ReconnectingWsProvider extends Provider {
}

@override
Future disconnect() {
Future disconnect() async {
// We only care if the channel is not equal to null.
// Because we still want the internal cleanup if
// the connection was closed from the other end.
if (provider.channel == null) {
return Future.value();
} else {
return provider.disconnect();
try {
await provider.disconnect();
} catch (e) {
Log.e('Error disconnecting websocket: $e', 'ReconnectingWsProvider');
return Future.value();
}
}
}

Expand Down
55 changes: 28 additions & 27 deletions app/lib/service/substrate_api/assets_api.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import 'dart:async';

import 'package:encointer_wallet/service/log/log_service.dart';
import 'package:encointer_wallet/service/substrate_api/core/js_api.dart';
import 'package:encointer_wallet/store/app.dart';
import 'package:encointer_wallet/store/assets/types/balances_info.dart';
import 'package:ew_keyring/ew_keyring.dart';
import 'package:ew_polkadart/ew_polkadart.dart' show ByteInput, EncointerKusama, StorageChangeSet;
import 'package:ew_polkadart/generated/encointer_kusama/types/pallet_balances/types/account_data.dart';

class AssetsApi {
AssetsApi(this.store, this.jsApi);
AssetsApi(this.store, this.jsApi, this.encointerKusama);

final JSApi jsApi;
final AppStore store;
final EncointerKusama encointerKusama;

final String _balanceSubscribeChannel = 'gas token balance';
StreamSubscription<StorageChangeSet>? _balanceSubscription;

Future<void> startSubscriptions() async {
Log.d('api: starting assets subscriptions', 'AssetsApi');
Expand All @@ -18,47 +23,43 @@ class AssetsApi {

Future<void> stopSubscriptions() async {
Log.d('api: stopping assets subscriptions', 'AssetsApi');
await jsApi.unsubscribeMessage(_balanceSubscribeChannel);
await _balanceSubscription?.cancel();
_balanceSubscription = null;
}

Future<void> fetchBalance() async {
final pubKey = store.account.currentAccountPubKey;
final currentAddress = store.account.currentAddress;
if (pubKey != null && pubKey.isNotEmpty) {
final address = currentAddress;
final res = await jsApi.evalJavascript<Map<String, dynamic>>('account.getBalance("$address")');
await store.assets.setAccountBalances(pubKey, Map.of({store.settings.networkState!.tokenSymbol: res}));
if (currentAddress.isNotEmpty) {
final accountData = await encointerKusama.query.balances.account(AddressUtils.addressToPubKey(currentAddress));
await store.assets.setAccountBalances(pubKey, Map.of({store.settings.networkState!.tokenSymbol!: accountData}));
}
await _fetchMarketPrice();
}

Future<BalancesInfo> getBalance() async {
Future<AccountData> getBalance() async {
return getBalanceOf(store.account.currentAddress);
}

Future<BalancesInfo> getBalanceOf(String address) async {
final res = await jsApi.evalJavascript<Map<String, dynamic>>('account.getBalance("$address")');
return BalancesInfo.fromJson(res);
Future<AccountData> getBalanceOf(String address) async {
return encointerKusama.query.balances.account(AddressUtils.addressToPubKey(address));
}

Future<void> subscribeBalance() async {
await jsApi.unsubscribeMessage(_balanceSubscribeChannel);
await _balanceSubscription?.cancel();

final pubKey = store.account.currentAccountPubKey;
if (pubKey != null && pubKey.isNotEmpty) {
final address = store.account.currentAddress;
final address = store.account.currentAddress;

await jsApi.subscribeMessage(
'account.subscribeBalance("$_balanceSubscribeChannel","$address")',
_balanceSubscribeChannel,
(Map<String, dynamic> data) async {
await store.assets.setAccountBalances(pubKey, Map.of({store.settings.networkState!.tokenSymbol: data}));
},
);
}
}
if (pubKey == null || pubKey.isEmpty || address.isEmpty) return;

final balanceKey = encointerKusama.query.balances.accountKey(AddressUtils.addressToPubKey(address));

Future<void> _fetchMarketPrice() async {
Log.d('Fetch marketprice not implemented for Encointer networks', 'AssetsApi');
_balanceSubscription = await encointerKusama.rpc.state.subscribeStorage([balanceKey], (storageChangeSet) async {
Log.p('Got account data subscription: $storageChangeSet');
if (storageChangeSet.changes[0].value != null) {
final accountData = AccountData.decode(ByteInput(storageChangeSet.changes[0].value!));
await store.assets.setAccountBalances(pubKey, Map.of({store.settings.networkState!.tokenSymbol!: accountData}));
}
});
}
}
Loading
Loading