Skip to content

Commit

Permalink
feat: use web socket provider (#1469)
Browse files Browse the repository at this point in the history
  • Loading branch information
iccicci authored Oct 21, 2024
1 parent 8c22ff5 commit c12e34b
Show file tree
Hide file tree
Showing 19 changed files with 391 additions and 177 deletions.
20 changes: 20 additions & 0 deletions .github/shared/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ inputs:
description: 'Url for sanchonet env'
required: false
default: 'https://dev-sanchonet.lw.iog.io'
CARDANO_WS_SERVER_URL_MAINNET:
description: 'WS url for mainnet env'
required: false
default: 'wss://dev-mainnet.lw.iog.io'
CARDANO_WS_SERVER_URL_PREPROD:
description: 'WS url for preprod env'
required: false
default: 'wss://dev-preprod.lw.iog.io'
CARDANO_WS_SERVER_URL_PREVIEW:
description: 'WS url for preview env'
required: false
default: 'wss://dev-preview.lw.iog.io'
CARDANO_WS_SERVER_URL_SANCHONET:
description: 'WS url for sanchonet env'
required: false
default: 'wss://dev-sanchonet.lw.iog.io'
runs:
using: 'composite'
steps:
Expand Down Expand Up @@ -95,4 +111,8 @@ runs:
CARDANO_SERVICES_URL_PREPROD: ${{ inputs.CARDANO_SERVICES_URL_PREPROD }}
CARDANO_SERVICES_URL_PREVIEW: ${{ inputs.CARDANO_SERVICES_URL_PREVIEW }}
CARDANO_SERVICES_URL_SANCHONET: ${{ inputs.CARDANO_SERVICES_URL_SANCHONET }}
CARDANO_WS_SERVER_URL_MAINNET: ${{ inputs.CARDANO_WS_SERVER_URL_MAINNET }}
CARDANO_WS_SERVER_URL_PREPROD: ${{ inputs.CARDANO_WS_SERVER_URL_PREPROD }}
CARDANO_WS_SERVER_URL_PREVIEW: ${{ inputs.CARDANO_WS_SERVER_URL_PREVIEW }}
CARDANO_WS_SERVER_URL_SANCHONET: ${{ inputs.CARDANO_WS_SERVER_URL_SANCHONET }}
run: yarn browser build
3 changes: 3 additions & 0 deletions .github/workflows/e2e-tests-linux-split.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ jobs:
CARDANO_SERVICES_URL_MAINNET: 'https://${{ env.CARDANO_MAINNET_URL }}'
CARDANO_SERVICES_URL_PREPROD: 'https://${{ env.CARDANO_PREPROD_URL }}'
CARDANO_SERVICES_URL_PREVIEW: 'https://${{ env.CARDANO_PREVIEW_URL }}'
CARDANO_WS_SERVER_URL_MAINNET: 'wss://${{ env.CARDANO_MAINNET_URL }}'
CARDANO_WS_SERVER_URL_PREPROD: 'wss://${{ env.CARDANO_PREPROD_URL }}'
CARDANO_WS_SERVER_URL_PREVIEW: 'wss://${{ env.CARDANO_PREVIEW_URL }}'
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
LACE_EXTENSION_KEY: ${{ secrets.MANIFEST_PUBLIC_KEY }}

Expand Down
6 changes: 6 additions & 0 deletions apps/browser-extension-wallet/.env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ CARDANO_SERVICES_URL_PREPROD=https://dev-preprod.lw.iog.io
CARDANO_SERVICES_URL_PREVIEW=https://dev-preview.lw.iog.io
CARDANO_SERVICES_URL_SANCHONET=https://dev-sanchonet.lw.iog.io

# Cardano WS Services
CARDANO_WS_SERVER_URL_MAINNET=wss://dev-mainnet.lw.iog.io
CARDANO_WS_SERVER_URL_PREPROD=wss://dev-preprod.lw.iog.io
CARDANO_WS_SERVER_URL_PREVIEW=wss://dev-preview.lw.iog.io
CARDANO_WS_SERVER_URL_SANCHONET=wss://dev-sanchonet.lw.iog.io

# Explorer URLs
CEXPLORER_URL_MAINNET=https://cexplorer.io
CEXPLORER_URL_PREVIEW=https://preview.cexplorer.io
Expand Down
6 changes: 6 additions & 0 deletions apps/browser-extension-wallet/.env.developerpreview
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ CARDANO_SERVICES_URL_PREPROD=https://dev-preprod.lw.iog.io
CARDANO_SERVICES_URL_PREVIEW=https://dev-preview.lw.iog.io
CARDANO_SERVICES_URL_SANCHONET=https://dev-sanchonet.lw.iog.io

# Cardano WS Services
CARDANO_WS_SERVER_URL_MAINNET=wss://dev-mainnet.lw.iog.io
CARDANO_WS_SERVER_URL_PREPROD=wss://dev-preprod.lw.iog.io
CARDANO_WS_SERVER_URL_PREVIEW=wss://dev-preview.lw.iog.io
CARDANO_WS_SERVER_URL_SANCHONET=wss://dev-sanchonet.lw.iog.io

# Explorer URLs
CEXPLORER_URL_MAINNET=https://cexplorer.io
CEXPLORER_URL_PREVIEW=https://preview.cexplorer.io
Expand Down
6 changes: 6 additions & 0 deletions apps/browser-extension-wallet/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ CARDANO_SERVICES_URL_PREPROD=https://backend.live-preprod.eks.lw.iog.io
CARDANO_SERVICES_URL_PREVIEW=https://backend.live-preview.eks.lw.iog.io
CARDANO_SERVICES_URL_SANCHONET=https://dev-sanchonet.lw.iog.io

# Cardano WS Services
CARDANO_WS_SERVER_URL_MAINNET=wss://dev-mainnet.lw.iog.io
CARDANO_WS_SERVER_URL_PREPROD=wss://dev-preprod.lw.iog.io
CARDANO_WS_SERVER_URL_PREVIEW=wss://dev-preview.lw.iog.io
CARDANO_WS_SERVER_URL_SANCHONET=wss://dev-sanchonet.lw.iog.io

# Explorer URLs
CEXPLORER_URL_MAINNET=https://cexplorer.io
CEXPLORER_URL_PREVIEW=https://preview.cexplorer.io
Expand Down
2 changes: 1 addition & 1 deletion apps/browser-extension-wallet/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"permissions": ["webRequest", "storage", "tabs", "unlimitedStorage"],
"host_permissions": ["<all_urls>"],
"content_security_policy": {
"extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval' $LOCALHOST_SCRIPT_SRC; font-src 'self' https://use.typekit.net; object-src 'self'; connect-src $CARDANO_SERVICES_URLS https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net data:; style-src * 'unsafe-inline'; img-src * data:;"
"extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval' $LOCALHOST_SCRIPT_SRC; font-src 'self' https://use.typekit.net; object-src 'self'; connect-src $CARDANO_SERVICES_URLS $CARDANO_WS_SERVER_URLS https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net data:; style-src * 'unsafe-inline'; img-src * data:;"
},
"content_scripts": [
{
Expand Down
18 changes: 9 additions & 9 deletions apps/browser-extension-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
},
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@cardano-sdk/cardano-services-client": "0.20.8",
"@cardano-sdk/core": "0.39.3",
"@cardano-sdk/dapp-connector": "0.12.36",
"@cardano-sdk/input-selection": "0.13.19",
"@cardano-sdk/tx-construction": "0.21.4",
"@cardano-sdk/cardano-services-client": "0.21.4",
"@cardano-sdk/core": "0.41.1",
"@cardano-sdk/dapp-connector": "0.12.41",
"@cardano-sdk/input-selection": "0.13.24",
"@cardano-sdk/tx-construction": "0.21.9",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/util-rxjs": "0.7.32",
"@cardano-sdk/wallet": "0.44.3",
"@cardano-sdk/web-extension": "0.34.2",
"@cardano-sdk/util-rxjs": "0.7.37",
"@cardano-sdk/wallet": "0.44.11",
"@cardano-sdk/web-extension": "0.34.10",
"@emurgo/cip14-js": "~3.0.1",
"@input-output-hk/lace-ui-toolkit": "1.21.0",
"@lace/cardano": "0.1.0",
Expand Down Expand Up @@ -97,7 +97,7 @@
"zustand": "3.5.14"
},
"devDependencies": {
"@cardano-sdk/hardware-ledger": "0.12.3",
"@cardano-sdk/hardware-ledger": "0.12.9",
"@emurgo/cardano-message-signing-asmjs": "1.0.1",
"@openpgp/web-stream-tools": "0.0.11-patch-0",
"@pdfme/common": "^4.0.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import axiosFetchAdapter from '@shiroyasha9/axios-fetch-adapter';
import { Wallet } from '@lace/cardano';
import { RemoteApiProperties, RemoteApiPropertyType } from '@cardano-sdk/web-extension';
import { getBaseUrlForChain } from '@src/utils/chain';
import { getBaseUrlForChain, getMagicForChain } from '@src/utils/chain';
import { BackgroundService, UserIdService as UserIdServiceInterface } from '../types';
import { getBackgroundStorage } from '@lib/scripts/background/storage';
import { ExperimentName } from '@providers/ExperimentsProvider/types';
import { logger } from '@lace/common';

export const backgroundServiceProperties: RemoteApiProperties<BackgroundService> = {
requestMessage$: RemoteApiPropertyType.HotObservable,
Expand All @@ -26,12 +28,16 @@ export const backgroundServiceProperties: RemoteApiProperties<BackgroundService>

export const getProviders = async (chainName: Wallet.ChainName): Promise<Wallet.WalletProvidersDependencies> => {
const baseCardanoServicesUrl = getBaseUrlForChain(chainName);
const { customSubmitTxUrl } = await getBackgroundStorage();
const magic = getMagicForChain(chainName);
const { customSubmitTxUrl, featureFlags } = await getBackgroundStorage();
const useWebSocket = !!(featureFlags?.[magic]?.[ExperimentName.WEBSOCKET_API] ?? false);

return Wallet.createProviders({
axiosAdapter: axiosFetchAdapter,
baseUrl: baseCardanoServicesUrl,
customSubmitTxUrl
customSubmitTxUrl,
logger,
useWebSocket
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export const getDefaultFeatureFlags = (): FallbackConfiguration => ({
[ExperimentName.CREATE_PAPER_WALLET]: false,
[ExperimentName.RESTORE_PAPER_WALLET]: false,
[ExperimentName.USE_SWITCH_TO_NAMI_MODE]: false,
[ExperimentName.SHARED_WALLETS]: false
[ExperimentName.SHARED_WALLETS]: false,
[ExperimentName.WEBSOCKET_API]: false
});

export const experiments: ExperimentsConfig = {
Expand All @@ -23,5 +24,9 @@ export const experiments: ExperimentsConfig = {
[ExperimentName.SHARED_WALLETS]: {
value: false,
default: false
},
[ExperimentName.WEBSOCKET_API]: {
value: false,
default: false
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export enum ExperimentName {
CREATE_PAPER_WALLET = 'create-paper-wallet',
RESTORE_PAPER_WALLET = 'restore-paper-wallet',
USE_SWITCH_TO_NAMI_MODE = 'use-switch-to-nami-mode',
SHARED_WALLETS = 'shared-wallets'
SHARED_WALLETS = 'shared-wallets',
WEBSOCKET_API = 'websocket-api'
}

interface FeatureFlag {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import { ExperimentName } from '@providers/ExperimentsProvider/types';
import { BehaviorSubject, distinctUntilChanged, Observable, Subscription } from 'rxjs';
import { PostHogAction, PostHogProperties } from '@lace/common';

type FeatureFlag = 'create-paper-wallet' | 'restore-paper-wallet' | 'shared-wallets' | 'use-switch-to-nami-mode';
type FeatureFlag =
| 'create-paper-wallet'
| 'restore-paper-wallet'
| 'shared-wallets'
| 'use-switch-to-nami-mode'
| 'websocket-api';

type FeatureFlags = {
[key in FeatureFlag]: boolean;
Expand Down
25 changes: 25 additions & 0 deletions apps/browser-extension-wallet/src/utils/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,28 @@ export const getBaseUrlForChain = (chainName: Wallet.ChainName): string => {
if (!AVAILABLE_CHAINS.includes(chainName)) throw new Error('Chain not supported');
return url;
};

export const getMagicForChain = (chainName: Wallet.ChainName): number => {
const { AVAILABLE_CHAINS } = config();
let magic = 0;
switch (chainName) {
case 'Mainnet':
magic = Wallet.Cardano.NetworkMagics.Mainnet;
break;
case 'Preprod':
magic = Wallet.Cardano.NetworkMagics.Preprod;
break;
case 'Preview':
magic = Wallet.Cardano.NetworkMagics.Preview;
break;
case 'Sanchonet':
magic = Wallet.Cardano.NetworkMagics.Sanchonet;
break;
default:
throw new Error('Incorrect chain supplied');
}

if (!AVAILABLE_CHAINS.includes(chainName)) throw new Error('Chain not supported');

return magic;
};
4 changes: 4 additions & 0 deletions apps/browser-extension-wallet/webpack-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const transformManifest = (content, mode) => {
manifest.version = `${manifest.version}.${date.getMonth()}${date.getDate()}`;
}
manifest.content_security_policy.extension_pages = manifest.content_security_policy.extension_pages
.replace(
'$CARDANO_WS_SERVER_URLS',
`${process.env.CARDANO_WS_SERVER_URL_MAINNET} ${process.env.CARDANO_WS_SERVER_URL_PREPROD} ${process.env.CARDANO_WS_SERVER_URL_PREVIEW} ${process.env.CARDANO_WS_SERVER_URL_SANCHONET}`
)
.replace(
'$CARDANO_SERVICES_URLS',
`${process.env.CARDANO_SERVICES_URL_MAINNET} ${process.env.CARDANO_SERVICES_URL_PREPROD} ${process.env.CARDANO_SERVICES_URL_PREVIEW} ${process.env.CARDANO_SERVICES_URL_SANCHONET}`
Expand Down
19 changes: 10 additions & 9 deletions packages/cardano/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@
"watch": "yarn build --watch"
},
"dependencies": {
"@cardano-sdk/cardano-services-client": "0.20.8",
"@cardano-sdk/core": "0.39.3",
"@cardano-sdk/cardano-services-client": "0.21.4",
"@cardano-sdk/core": "0.41.1",
"@cardano-sdk/crypto": "0.1.30",
"@cardano-sdk/hardware-ledger": "0.12.3",
"@cardano-sdk/hardware-trezor": "0.6.3",
"@cardano-sdk/key-management": "0.24.2",
"@cardano-sdk/tx-construction": "0.21.4",
"@cardano-sdk/hardware-ledger": "0.12.9",
"@cardano-sdk/hardware-trezor": "0.6.8",
"@cardano-sdk/key-management": "0.24.7",
"@cardano-sdk/tx-construction": "0.21.9",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/wallet": "0.44.3",
"@cardano-sdk/web-extension": "0.34.2",
"@cardano-sdk/wallet": "0.44.11",
"@cardano-sdk/web-extension": "0.34.10",
"@lace/common": "0.1.0",
"@ledgerhq/devices": "^8.2.1",
"@stablelib/chacha20poly1305": "1.0.1",
Expand All @@ -71,11 +71,12 @@
"webextension-polyfill": "0.10.0"
},
"devDependencies": {
"@cardano-sdk/util-dev": "0.22.10",
"@cardano-sdk/util-dev": "0.23.6",
"@emurgo/cardano-message-signing-browser": "1.0.1",
"@types/webextension-polyfill": "0.10.0",
"axios": "^1.7.4",
"rollup-plugin-polyfill-node": "^0.8.0",
"ts-log": "^2.2.7",
"typescript": "^4.9.5"
},
"peerDependencies": {
Expand Down
61 changes: 50 additions & 11 deletions packages/cardano/src/wallet/lib/providers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-new */
import { WalletProvidersDependencies } from '@src/wallet';
import { AxiosAdapter } from 'axios';
import { Logger } from 'ts-log';
import {
AssetProvider,
ChainHistoryProvider,
Expand All @@ -13,6 +14,7 @@ import {
} from '@cardano-sdk/core';

import {
CardanoWsClient,
CreateHttpProviderConfig,
assetInfoHttpProvider,
chainHistoryHttpProvider,
Expand Down Expand Up @@ -56,26 +58,63 @@ export interface ProvidersConfig {
axiosAdapter?: AxiosAdapter;
baseUrl: string;
customSubmitTxUrl?: string;
logger?: Logger;
useWebSocket?: boolean;
}

/**
* Only one instance must be alive.
*
* If a new one needs to be created (ex. on network change) the previous instance needs to be closed. */
let wsProvider: CardanoWsClient;

export const createProviders = ({
axiosAdapter,
baseUrl,
customSubmitTxUrl
customSubmitTxUrl,
logger,
useWebSocket
}: ProvidersConfig): WalletProvidersDependencies => {
const httpProviderConfig: CreateHttpProviderConfig<Provider> = {
baseUrl,
logger: console,
adapter: axiosAdapter
};
if (!logger) logger = console;

const httpProviderConfig: CreateHttpProviderConfig<Provider> = { baseUrl, logger, adapter: axiosAdapter };

const assetProvider = assetInfoHttpProvider(httpProviderConfig);
const chainHistoryProvider = chainHistoryHttpProvider(httpProviderConfig);
const rewardsProvider = rewardsHttpProvider(httpProviderConfig);
const stakePoolProvider = stakePoolHttpProvider(httpProviderConfig);
const txSubmitProvider = createTxSubmitProvider(httpProviderConfig, customSubmitTxUrl);

if (useWebSocket) {
const url = new URL(baseUrl);

url.pathname = '/ws';
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';

// On network change this logs an error line as follows but it is expected as long as this function is called twice
// 'Async error from WebSocket client' 'not-connected'
if (wsProvider) wsProvider.close().catch((error) => console.error(error, 'While closing wsProvider'));

wsProvider = new CardanoWsClient({ chainHistoryProvider, logger }, { url });

return {
assetProvider,
networkInfoProvider: wsProvider.networkInfoProvider,
txSubmitProvider,
stakePoolProvider,
utxoProvider: wsProvider.utxoProvider,
chainHistoryProvider: wsProvider.chainHistoryProvider,
rewardsProvider
};
}

return {
assetProvider: assetInfoHttpProvider(httpProviderConfig),
assetProvider,
networkInfoProvider: networkInfoHttpProvider(httpProviderConfig),
txSubmitProvider: createTxSubmitProvider(httpProviderConfig, customSubmitTxUrl),
stakePoolProvider: stakePoolHttpProvider(httpProviderConfig),
txSubmitProvider,
stakePoolProvider,
utxoProvider: utxoHttpProvider(httpProviderConfig),
chainHistoryProvider: chainHistoryHttpProvider(httpProviderConfig),
rewardsProvider: rewardsHttpProvider(httpProviderConfig)
chainHistoryProvider,
rewardsProvider
};
};
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
},
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@cardano-sdk/wallet": "0.44.3",
"@cardano-sdk/web-extension": "0.34.2",
"@cardano-sdk/wallet": "0.44.11",
"@cardano-sdk/web-extension": "0.34.10",
"@input-output-hk/lace-ui-toolkit": "1.19.0",
"@lace/cardano": "0.1.0",
"@lace/common": "0.1.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/nami/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@
},
"dependencies": {
"@cardano-foundation/ledgerjs-hw-app-cardano": "^6.0.0",
"@cardano-sdk/core": "0.39.3",
"@cardano-sdk/core": "0.41.1",
"@cardano-sdk/crypto": "0.1.30",
"@cardano-sdk/tx-construction": "0.21.4",
"@cardano-sdk/web-extension": "0.34.2",
"@cardano-sdk/tx-construction": "0.21.9",
"@cardano-sdk/web-extension": "0.34.10",
"@chakra-ui/css-reset": "1.0.0",
"@chakra-ui/icons": "1.0.13",
"@chakra-ui/react": "1.6.4",
Expand Down
Loading

0 comments on commit c12e34b

Please sign in to comment.