Skip to content

Feature/cip45 hardening #943

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

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions android/app/release/output-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "org.cardanofoundation.idw",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}
12 changes: 9 additions & 3 deletions services/cip45-sample-dapp/src/pages/Demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,20 @@ const Demo: React.FC = () => {
}
}, []);

const disconnectWallet = () => {
const disconnectWallet = async () => {
disconnect();
setPeerConnectWalletInfo(defautlWallet);
setShowAcceptButton(false);
setWalletIsConnected(false);
setError("");

const api =
window.cardano && window.cardano[peerConnectWalletInfo.name];
if (!api) return;
const enabledApi = await api.enable();
await enabledApi.experimental.disable();
}

const handleAcceptWallet = () => {
if (peerConnectWalletInfo) {
onPeerConnectAccept();
Expand All @@ -119,7 +126,6 @@ const Demo: React.FC = () => {

const checkApi = setInterval(async () => {
const api =
// @ts-ignore
window.cardano && window.cardano[peerConnectWalletInfo.name];
if (api || Date.now() - start > timeout) {
clearInterval(checkApi);
Expand Down Expand Up @@ -201,7 +207,7 @@ const Demo: React.FC = () => {
showAcceptButton ? <button className="bg-blue-500 text-white font-bold py-3 px-6 rounded-lg"
onClick={handleAcceptWallet} disabled={!showAcceptButton}>
Accept connection with {peerConnectWalletInfo.name}
</button> : walletIsConnected ? <button className="bg-red-600 text-white font-bold py-3 px-6 rounded-lg"
</button> : peerConnectWalletInfo.name.length && walletIsConnected ? <button className="bg-red-600 text-white font-bold py-3 px-6 rounded-lg"
onClick={disconnectWallet}>
Disconnect Wallet
</button> : null
Expand Down
12 changes: 9 additions & 3 deletions src/core/cardano/walletConnect/identityWalletConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
IWalletInfo,
} from "@fabianbormann/cardano-peer-connect/dist/src/types";
import { CardanoPeerConnect } from "@fabianbormann/cardano-peer-connect";
import { Signer } from "signify-ts";
import { Agent } from "../../agent/agent";
import {
PeerConnectSigningEvent,
Expand All @@ -14,6 +13,7 @@ import {
TxSignError,
} from "./peerConnection.types";
import { CoreEventEmitter } from "../../agent/event";
import {PeerConnection} from "./peerConnection";

class IdentityWalletConnect extends CardanoPeerConnect {
private selectedAid: string;
Expand All @@ -25,7 +25,7 @@ class IdentityWalletConnect extends CardanoPeerConnect {
identifier: string,
payload: string
) => Promise<string | { error: PeerConnectionError }>;

disable: () => void;
constructor(
walletInfo: IWalletInfo,
seed: string | null,
Expand All @@ -38,7 +38,7 @@ class IdentityWalletConnect extends CardanoPeerConnect {
seed: seed,
announce: announce,
discoverySeed: discoverySeed,
logLevel: "info",
logLevel: "debug",
});
this.selectedAid = selectedAid;
this.eventEmitter = eventService;
Expand Down Expand Up @@ -91,6 +91,11 @@ class IdentityWalletConnect extends CardanoPeerConnect {
return { error: TxSignError.UserDeclined };
}
};

this.disable = (): void => {
PeerConnection.peerConnection.disconnectDApp(null, false);
};

}

protected getNetworkId(): Promise<number> {
Expand Down Expand Up @@ -134,6 +139,7 @@ class IdentityWalletConnect extends CardanoPeerConnect {
protected submitTx(tx: string): Promise<string> {
throw new Error("Method not implemented.");
}

}

export { IdentityWalletConnect };
58 changes: 52 additions & 6 deletions src/core/cardano/walletConnect/peerConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {KeyStoreKeys, SecureStorage} from "../../storage";
import { CoreEventEmitter } from "../../agent/event";
import {
ExperimentalAPIFunctions,
PeerConnectSigningEvent,
PeerConnectedEvent,
PeerConnectionBrokenEvent,
PeerConnectionEventTypes,
PeerConnectSigningEvent,
PeerDisconnectedEvent,
} from "./peerConnection.types";
import { Agent } from "../../agent/agent";
Expand All @@ -28,9 +28,13 @@ class PeerConnection {
requestAutoconnect: true,
};

// Trackers repositories
private static trackersFileUrls: string[] = [
"https://raw.githubusercontent.com/cardano-foundation/cf-identity-wallet/refs/heads/main/trackers.txt"
];

private announce = [
"wss://tracker.webtorrent.dev:443/announce",
"wss://dev.btt.cf-identity-wallet.metadata.dev.cf-deployments.org"
"wss://tracker.webtorrent.dev:443/announce"
];

private identityWalletConnect: IdentityWalletConnect | undefined;
Expand Down Expand Up @@ -78,6 +82,8 @@ class PeerConnection {

async start(selectedAid: string) {



const meerkatSeed = await SecureStorage.get(
KeyStoreKeys.MEERKAT_SEED
);
Expand All @@ -88,13 +94,17 @@ class PeerConnection {
) {
this.disconnectDApp(this.connectedDAppAddress);
}

this.announce = await this.getTrackersFromRemoteFiles();

this.identityWalletConnect = new IdentityWalletConnect(
this.walletInfo,
meerkatSeed,
this.announce,
selectedAid,
this.eventEmitter
);

this.identityWalletConnect.setOnConnect(
async (connectMessage: IConnectMessage) => {
if (!connectMessage.error) {
Expand Down Expand Up @@ -146,6 +156,7 @@ class PeerConnection {
new ExperimentalContainer<ExperimentalAPIFunctions>({
getKeriIdentifier: this.identityWalletConnect.getKeriIdentifier,
signKeri: this.identityWalletConnect.signKeri,
disable: this.identityWalletConnect.disable
})
);
}
Expand All @@ -162,7 +173,7 @@ class PeerConnection {
error.message ===
PeerConnectionStorage.PEER_CONNECTION_METADATA_RECORD_MISSING
) {
return undefined;
return Promise.resolve(undefined);
} else {
throw error;
}
Expand All @@ -183,11 +194,11 @@ class PeerConnection {
SecureStorage.set(KeyStoreKeys.MEERKAT_SEED, seed);
}

disconnectDApp(dAppIdentifier: string, isBroken?: boolean) {
disconnectDApp(dAppIdentifier?: string | null, isBroken?: boolean) {
if (this.identityWalletConnect === undefined) {
throw new Error(PeerConnection.PEER_CONNECTION_START_PENDING);
}
this.identityWalletConnect.disconnect(dAppIdentifier);
this.identityWalletConnect.disconnect(dAppIdentifier ? dAppIdentifier : this.connectedDAppAddress);

if (isBroken) {
this.eventEmitter.emit<PeerConnectionBrokenEvent>({
Expand All @@ -207,6 +218,41 @@ class PeerConnection {
}
return this.identityWalletConnect.getKeriIdentifier();
}

private async getTrackersFromRemoteFiles(): Promise<string[]> {
const validUrlRegex = /^(wss|https|udp):\/\/[^/\s?#]+(:\d+)?(\/|$)/;

for (const fileUrl of PeerConnection.trackersFileUrls) {
try {
const response = await fetch(fileUrl);
if (!response.ok) {
// eslint-disable-next-line no-console
console.warn(`Error loading file ${fileUrl}: Status code ${response.status}`);
continue;
}

const text = await response.text();
const trackers = text
.split("\n")
.map(line => line.trim())
.filter(line => line && !line.startsWith("#"))
.filter(line => validUrlRegex.test(line));

if (trackers.length > 0) {
return trackers;
} else {
// eslint-disable-next-line no-console
console.warn(`File ${fileUrl} loaded successfully but contains no valid trackers.`);
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(`Error processing file ${fileUrl}:`, error);
}
}

return this.announce; // Fallback
}

}

export { PeerConnection };
1 change: 1 addition & 0 deletions src/core/cardano/walletConnect/peerConnection.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface ExperimentalAPIFunctions {
identifier: string,
payload: string
) => Promise<string | { error: PeerConnectionError }>;
disable: () => void;
}

enum PeerConnectionEventTypes {
Expand Down
13 changes: 11 additions & 2 deletions src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { StrictMode, useEffect, useState } from "react";
import EventEmitter from "events";
import { Routes } from "../routes";
import { useAppDispatch, useAppSelector } from "../store/hooks";
import {
Expand All @@ -35,6 +36,7 @@ import { SecureStorage } from "../core/storage";
import { compareVersion } from "./utils/version";
import { ANDROID_MIN_VERSION, IOS_MIN_VERSION, WEBVIEW_MIN_VERSION } from "./globals/constants";


setupIonicReact();

const App = () => {
Expand All @@ -49,14 +51,21 @@ const App = () => {
const handleUnknownPromiseError = (event: PromiseRejectionEvent) => {
// prevent log error to console.
event.preventDefault();
event.promise.catch((e) => showError("Unhandled error", e, dispatch));
const reasonMessage = event.reason?.message || JSON.stringify(event.reason);
if (reasonMessage.includes("No torrent with id")) return; // TODO: refactor error

event.promise.catch((e) => {
showError("Unhandled error", e, dispatch)
});
}

window.addEventListener("unhandledrejection", handleUnknownPromiseError);

const handleUnknownError = (event: ErrorEvent) => {
event.preventDefault();
showError("Unhandled error", event.error, dispatch);
/* eslint-disable no-console */
console.error("Unhandled error222", event.error);
// showError("Unhandled error", event.error, dispatch);
}

window.addEventListener("error", handleUnknownError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const ConfirmConnectModal = ({
isConnectModal,
closeModal,
onConfirm,
onReconnect,
connectionData,
onDeleteConnection,
}: ConfirmConnectModalProps) => {
Expand Down Expand Up @@ -77,6 +78,12 @@ const ConfirmConnectModal = ({
onConfirm();
};


const reconnect = () => {
closeModal();
onReconnect && onReconnect();
};

const confirmClass = combineClassNames("confirm-connect-submit", {
"primary-button": isConnectModal,
"secondary-button": !isConnectModal,
Expand Down Expand Up @@ -150,6 +157,14 @@ const ConfirmConnectModal = ({
>
{buttonTitle}
</IonButton>
<IonButton
disabled={isConnecting}
className={confirmClass}
data-testid="confirm-connect-btn"
onClick={reconnect}
>
Reconnect
</IonButton>
</OptionModal>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface ConfirmConnectModalProps {
openModal: boolean;
closeModal: () => void;
onConfirm: () => void;
onReconnect?: () => void;
onDeleteConnection: (data: ConnectionData) => void;
isConnectModal: boolean;
connectionData?: ConnectionData;
Expand Down
6 changes: 6 additions & 0 deletions src/ui/pages/Menu/components/ConnectWallet/ConnectWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,13 @@ const ConnectWallet = forwardRef<ConnectWalletOptionRef, object>(
const disconnectWallet = () => {
if (!connectedWallet) return;
PeerConnection.peerConnection.disconnectDApp(connectedWallet?.id);

};

const reconnect = async () => {
if (!connectedWallet) return;
await PeerConnection.peerConnection.connectWithDApp(connectedWallet?.id);
}
const toggleConnected = () => {
if (defaultIdentifierCache.length === 0) {
setOpenIdentifierMissingAlert(true);
Expand Down Expand Up @@ -337,6 +342,7 @@ const ConnectWallet = forwardRef<ConnectWalletOptionRef, object>(
openModal={openConfirmConnectModal}
closeModal={() => setOpenConfirmConnectModal(false)}
onConfirm={toggleConnected}
onReconnect={reconnect}
connectionData={actionInfo.data}
onDeleteConnection={handleOpenDeleteAlert}
/>
Expand Down
8 changes: 8 additions & 0 deletions trackers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
wss://tracker.webtorrent.dev:443/announce
wss://dev.btt.cf-identity-wallet.metadata.dev.cf-deployments.org

# Trackers lists
# https://raw.githubusercontent.com/ngosang/trackerslist/refs/heads/master/trackers_all_ws.txt
# https://raw.githubusercontent.com/ngosang/trackerslist/refs/heads/master/trackers_all_udp.txt
# https://raw.githubusercontent.com/ngosang/trackerslist/refs/heads/master/trackers_all_https.txt
# https://raw.githubusercontent.com/XIU2/TrackersListCollection/refs/heads/master/best.txt
Loading