@exodus/web3-ethereum 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export * from './simulation/index.js';
1
+ export { EthereumProvider } from './provider/index.js';
2
+ export { simulateTransaction } from './simulation/index.js';
3
+ export { ExodusEthereumWallet } from './wallet-standard/index.js';
package/lib/index.js CHANGED
@@ -1 +1,3 @@
1
- export * from './simulation/index.js';
1
+ export { EthereumProvider } from './provider/index.js';
2
+ export { simulateTransaction } from './simulation/index.js';
3
+ export { ExodusEthereumWallet } from './wallet-standard/index.js';
@@ -0,0 +1,2 @@
1
+ export { EthereumProvider } from './provider.js';
2
+ export * from './types.js';
@@ -0,0 +1,2 @@
1
+ export { EthereumProvider } from './provider.js';
2
+ export * from './types.js';
@@ -0,0 +1,22 @@
1
+ import { BaseProvider } from '@exodus/web3-provider';
2
+ import type { ChainId, Deps, JsonRpcCallback, JsonRpcRequest, JsonRpcResult, ProviderConnectInfo, RequestArguments } from './types.js';
3
+ interface EthereumProviderEvents {
4
+ accountsChanged(accounts: string[]): void;
5
+ chainChanged(chainId: ChainId): void;
6
+ connect(providerConnectInfo: ProviderConnectInfo): void;
7
+ disconnect(): void;
8
+ message(): void;
9
+ }
10
+ export declare class EthereumProvider extends BaseProvider<EthereumProviderEvents> {
11
+ #private;
12
+ constructor({ accountsObservable, storage, supportedChainIds, transport, getDefaultChainId, }: Deps);
13
+ protected _callRpcMethod<Params, Response>(method: string, params: Params): Promise<Response>;
14
+ isConnected(): boolean;
15
+ request(args: RequestArguments): Promise<unknown>;
16
+ get chainId(): ChainId | null;
17
+ get selectedAddress(): string | null;
18
+ enable(): Promise<string[]>;
19
+ send(methodOrPayload: string | JsonRpcRequest, paramsOrCallback: unknown[] | JsonRpcCallback): Promise<void | JsonRpcResult>;
20
+ sendAsync(payload: JsonRpcRequest, callback: JsonRpcCallback): void;
21
+ }
22
+ export {};
@@ -0,0 +1,236 @@
1
+ import { BaseProvider } from '@exodus/web3-provider';
2
+ import { ethErrors } from 'eth-rpc-errors';
3
+ import { createStorageWrapper } from './storage.js';
4
+ export class EthereumProvider extends BaseProvider {
5
+ #storage;
6
+ #supportedChainIds = [];
7
+ #getDefaultChainId;
8
+ #initializePromise = null;
9
+ #initialized = false;
10
+ #isConnected = false;
11
+ #chainId = null;
12
+ #accounts = [];
13
+ #selectedAddress = null;
14
+ constructor({ accountsObservable, storage, supportedChainIds, transport, getDefaultChainId, }) {
15
+ if (!supportedChainIds?.length) {
16
+ throw new Error('At least one supported chain must be provided');
17
+ }
18
+ super({ transport });
19
+ this.#storage = createStorageWrapper(storage);
20
+ this.#supportedChainIds = supportedChainIds.map((chainId) => chainId.toLowerCase());
21
+ // Observe account changes.
22
+ this.on('connect', () => {
23
+ const unobserve = accountsObservable.observe((accounts) => {
24
+ this.#handleAccountsChanged(accounts);
25
+ });
26
+ this.on('disconnect', unobserve);
27
+ });
28
+ this.on('connect', () => {
29
+ this.#isConnected = true;
30
+ });
31
+ this.#initializePromise = this.#initialize();
32
+ this.#getDefaultChainId =
33
+ typeof getDefaultChainId === 'function'
34
+ ? getDefaultChainId
35
+ : async () => null;
36
+ }
37
+ _callRpcMethod(method, params) {
38
+ const prefix = this.#chainId;
39
+ return super._callRpcMethod(`${prefix}_${method}`, params);
40
+ }
41
+ #assertConnected() {
42
+ if (!this.isConnected()) {
43
+ throw ethErrors.provider.disconnected({
44
+ message: 'The Provider is disconnected from all chains.',
45
+ });
46
+ }
47
+ }
48
+ #assertChainSupported(chainId) {
49
+ if (!this.#supportedChainIds.includes(chainId)) {
50
+ throw ethErrors.provider.custom({
51
+ message: 'The Provider does not support the requested chain.',
52
+ code: 4902,
53
+ });
54
+ }
55
+ }
56
+ async #getChainId() {
57
+ const storedChainId = await this.#storage.getChainId();
58
+ const defaultChainId = this.#supportedChainIds[0];
59
+ return storedChainId ?? defaultChainId;
60
+ }
61
+ async #getAccounts() {
62
+ return this._callRpcMethod('eth_accounts', []);
63
+ }
64
+ async #initialize() {
65
+ const chainId = await this.#getChainId();
66
+ this.#handleConnect(chainId);
67
+ this.#handleChainChanged(chainId);
68
+ const accounts = await this.#getAccounts();
69
+ this.#handleAccountsChanged(accounts);
70
+ this.#initialized = true;
71
+ this.#initializePromise = null;
72
+ }
73
+ async #awaitInitialized() {
74
+ if (this.#initializePromise) {
75
+ await this.#initializePromise;
76
+ }
77
+ }
78
+ #handleConnect(chainId) {
79
+ if (!this.#isConnected) {
80
+ this.#isConnected = true;
81
+ this.emit('connect', { chainId });
82
+ }
83
+ }
84
+ #handleChainChanged(chainId) {
85
+ if (!chainId || typeof chainId !== 'string' || !chainId.startsWith('0x')) {
86
+ return;
87
+ }
88
+ if (chainId !== this.#chainId) {
89
+ this.#chainId = chainId;
90
+ if (this.#initialized) {
91
+ this.emit('chainChanged', chainId);
92
+ }
93
+ }
94
+ }
95
+ #handleAccountsChanged(accounts) {
96
+ // `accounts` is always going to have a single account (or none) for the time being.
97
+ if (this.#accounts[0] !== accounts[0]) {
98
+ this.#accounts = accounts;
99
+ this.#selectedAddress = accounts[0] ?? null;
100
+ if (this.#initialized) {
101
+ this.emit('accountsChanged', accounts);
102
+ }
103
+ }
104
+ }
105
+ async #requestAccounts() {
106
+ const permissions = { eth_accounts: {} };
107
+ await this._callRpcMethod('wallet_requestPermissions', [permissions]);
108
+ const accounts = await this._callRpcMethod('eth_accounts', []);
109
+ this.#handleAccountsChanged(accounts);
110
+ if (!(await this.#storage.getChainId())) {
111
+ // Get default chain Id from remote config
112
+ const defaultChainId = await this.#getDefaultChainId();
113
+ if (defaultChainId) {
114
+ this.#handleChainChanged(defaultChainId);
115
+ }
116
+ }
117
+ return accounts;
118
+ }
119
+ async #addChain(chainId) {
120
+ // Exodus does not support the addition of custom chains.
121
+ // If the requested chain is supported, the provider will switch to that chain.
122
+ // This matches MetaMask's behavior.
123
+ // See: https://github.com/MetaMask/metamask-extension/blob/d92936475a942fed060bb36f810ee6bfd901f4f4/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js#L167-L183.
124
+ return this.#switchChain(chainId);
125
+ }
126
+ async #switchChain(chainId) {
127
+ const lowerCaseChainId = chainId.toLowerCase();
128
+ this.#assertChainSupported(lowerCaseChainId);
129
+ this.#handleChainChanged(lowerCaseChainId);
130
+ await this.#storage.setChainId(lowerCaseChainId);
131
+ return null;
132
+ }
133
+ isConnected() {
134
+ return this.#isConnected;
135
+ }
136
+ async request(args) {
137
+ await this.#awaitInitialized();
138
+ this.#assertConnected();
139
+ const { method, params = [] } = args;
140
+ if (typeof method !== 'string' || method.length === 0) {
141
+ throw ethErrors.rpc.invalidRequest({
142
+ message: "'args.method' must be a non-empty string.",
143
+ data: args,
144
+ });
145
+ }
146
+ if (!Array.isArray(params) &&
147
+ (typeof params !== 'object' || params === null)) {
148
+ throw ethErrors.rpc.invalidRequest({
149
+ message: "'args.params' must be an object or array if provided.",
150
+ data: args,
151
+ });
152
+ }
153
+ /**
154
+ * Intercepted requests.
155
+ */
156
+ // EIP-695
157
+ // See: https://eips.ethereum.org/EIPS/eip-695.
158
+ if (method === 'eth_chainId') {
159
+ return this.#chainId;
160
+ }
161
+ // EIP-2255.
162
+ // See: https://eips.ethereum.org/EIPS/eip-2255.
163
+ if (method === 'eth_requestAccounts') {
164
+ return this.#requestAccounts();
165
+ }
166
+ // EIP-3085
167
+ // See: https://eips.ethereum.org/EIPS/eip-3085.
168
+ if (method === 'wallet_addEthereumChain') {
169
+ const { chainId } = params[0];
170
+ return this.#addChain(chainId);
171
+ }
172
+ // EIP-3326.
173
+ // See: https://eips.ethereum.org/EIPS/eip-3326.
174
+ if (method === 'wallet_switchEthereumChain') {
175
+ const { chainId } = params[0];
176
+ return this.#switchChain(chainId);
177
+ }
178
+ /**
179
+ * Request.
180
+ */
181
+ let revisedParams = params;
182
+ if (method === 'personal_sign') {
183
+ // Omit `password` parameter if passed.
184
+ // See: https://github.com/ethereum/go-ethereum/pull/2940.
185
+ revisedParams = params.slice(0, 2);
186
+ }
187
+ return this._callRpcMethod(method, revisedParams);
188
+ }
189
+ /*
190
+ * Legacy API.
191
+ */
192
+ get chainId() {
193
+ console.warn('Exodus: "ethereum.chainId" is deprecated and may be removed in the future. Please use "ethereum.request({ method: \'eth_chainId\' })" instead.');
194
+ return this.#chainId;
195
+ }
196
+ get selectedAddress() {
197
+ console.warn('Exodus: "ethereum.selectedAddress" is deprecated and may be removed in the future. Please use "ethereum.request({ method: \'eth_accounts\' })" instead.');
198
+ return this.#selectedAddress;
199
+ }
200
+ async enable() {
201
+ console.warn('Exodus: "ethereum.enable()" is deprecated and may be removed in the future. Please use "ethereum.request({ method: \'eth_requestAccounts\' })" instead.\nFor more information, see: https://eips.ethereum.org/EIPS/eip-1102.');
202
+ this.#assertConnected();
203
+ return this.#requestAccounts();
204
+ }
205
+ async send(methodOrPayload, paramsOrCallback) {
206
+ console.warn('Exodus: "ethereum.send()" is deprecated and may be removed in the future. Please use "ethereum.request()" instead.');
207
+ const hasMethod = typeof methodOrPayload === 'string';
208
+ const hasParams = Array.isArray(paramsOrCallback);
209
+ if (hasMethod && (!paramsOrCallback || hasParams)) {
210
+ const method = methodOrPayload;
211
+ const params = paramsOrCallback;
212
+ return new Promise((resolve, reject) => this.request({ method, params })
213
+ .then((result) => resolve({ id: '1', jsonrpc: '2.0', result }))
214
+ .catch((err) => reject({ id: '1', jsonrpc: '2.0', error: err })));
215
+ }
216
+ const payload = methodOrPayload;
217
+ const callback = paramsOrCallback;
218
+ this.sendAsync(payload, callback);
219
+ }
220
+ sendAsync(payload, callback) {
221
+ console.warn('Exodus: "ethereum.sendAsync()" is deprecated and may be removed in the future. Please use "ethereum.request()" instead.');
222
+ const { id, jsonrpc, method, params } = payload;
223
+ const hasCallback = callback && typeof callback === 'function';
224
+ this.request({ method, params })
225
+ .then((result) => {
226
+ if (hasCallback) {
227
+ callback(null, { id, jsonrpc, result });
228
+ }
229
+ })
230
+ .catch((err) => {
231
+ if (hasCallback) {
232
+ callback(err, { id, jsonrpc, error: err });
233
+ }
234
+ });
235
+ }
236
+ }
@@ -0,0 +1,3 @@
1
+ import type { Storage } from '@exodus/web3-types';
2
+ import type { ProviderStorage } from './types.js';
3
+ export declare function createStorageWrapper(storage: Storage): ProviderStorage;
@@ -0,0 +1,28 @@
1
+ const chainIdKey = 'exodus:ethereum:chainId';
2
+ export function createStorageWrapper(storage) {
3
+ async function getChainId() {
4
+ try {
5
+ return await storage.getItem(chainIdKey);
6
+ }
7
+ catch (err) {
8
+ return null;
9
+ }
10
+ }
11
+ async function setChainId(chainId) {
12
+ try {
13
+ await storage.setItem(chainIdKey, chainId);
14
+ }
15
+ catch (err) {
16
+ // Ignore error.
17
+ }
18
+ }
19
+ async function clearChainId() {
20
+ try {
21
+ await storage.removeItem(chainIdKey);
22
+ }
23
+ catch (err) {
24
+ // Ignore error.
25
+ }
26
+ }
27
+ return { getChainId, setChainId, clearChainId };
28
+ }
@@ -0,0 +1,44 @@
1
+ import type { Deps as BaseProviderDeps } from '@exodus/web3-provider';
2
+ import type { Observable, Storage } from '@exodus/web3-types';
3
+ export declare type ChainId = string;
4
+ export interface ProviderConnectInfo {
5
+ chainId: ChainId;
6
+ }
7
+ export interface ChainParameter {
8
+ chainId: ChainId;
9
+ }
10
+ export interface RequestArguments {
11
+ method: string;
12
+ params?: unknown[] | Record<string, unknown>;
13
+ }
14
+ declare type JsonRpcId = string | undefined;
15
+ export interface JsonRpcRequest {
16
+ id: JsonRpcId;
17
+ jsonrpc: '2.0';
18
+ method: string;
19
+ params?: unknown[];
20
+ }
21
+ declare type JsonRpcSuccess = {
22
+ id: JsonRpcId;
23
+ jsonrpc: '2.0';
24
+ result: unknown;
25
+ };
26
+ declare type JsonRpcFailure = {
27
+ id: JsonRpcId;
28
+ jsonrpc: '2.0';
29
+ error: Error;
30
+ };
31
+ export declare type JsonRpcResult = JsonRpcSuccess | JsonRpcFailure;
32
+ export declare type JsonRpcCallback = (error: Error | null, result?: JsonRpcResult) => unknown;
33
+ export declare type Deps = BaseProviderDeps & {
34
+ accountsObservable: Observable;
35
+ storage: Storage;
36
+ supportedChainIds: string[];
37
+ getDefaultChainId?: () => Promise<string | null>;
38
+ };
39
+ export interface ProviderStorage {
40
+ getChainId: () => Promise<ChainId | null>;
41
+ setChainId: (chainId: ChainId) => Promise<void>;
42
+ clearChainId: () => Promise<void>;
43
+ }
44
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1 @@
1
- import type { EVMConstants } from './types.js';
2
- export declare const CHAIN_IDS: {
3
- [key: string]: number;
4
- };
5
- export declare const ENABLED_EVMS: EVMConstants[];
1
+ export declare const SIMULATION_SUPPORTED_ASSET_NAMES: string[];
@@ -1,32 +1 @@
1
- export const CHAIN_IDS = {
2
- avalanchec: 43114,
3
- bsc: 56,
4
- ethereum: 1,
5
- ethereumclassic: 61,
6
- ethereumgoerli: 5,
7
- fantommainnet: 250,
8
- harmonymainnet: 1666600000,
9
- matic: 137,
10
- };
11
- export const ENABLED_EVMS = [
12
- {
13
- assetName: 'ethereum',
14
- shouldSimulate: true,
15
- },
16
- {
17
- assetName: 'matic',
18
- shouldSimulate: false,
19
- },
20
- {
21
- assetName: 'bsc',
22
- shouldSimulate: false,
23
- },
24
- {
25
- assetName: 'avalanchec',
26
- shouldSimulate: false,
27
- },
28
- {
29
- assetName: 'fantommainnet',
30
- shouldSimulate: false,
31
- },
32
- ];
1
+ export const SIMULATION_SUPPORTED_ASSET_NAMES = ['ethereum']; // just ethereum for now
@@ -1,16 +1 @@
1
- import type { EthTransaction } from '@exodus/web3-ethereum-utils';
2
- import type { Asset, EthBalanceChanges } from './types.js';
3
- export declare const simulateTransaction: (assets: Record<string, Asset>, transaction: EthTransaction, network: string) => Promise<{
4
- assetName: string;
5
- advancedDetails: never[];
6
- balanceChanges: EthBalanceChanges;
7
- displayInfo: {
8
- title: string;
9
- };
10
- txFee: unknown;
11
- txFeeDetails: {
12
- gasLimit: number;
13
- maxFeePerGas: number | undefined;
14
- gasPrice: number;
15
- };
16
- }>;
1
+ export { simulateTransaction } from './simulation.js';
@@ -1,70 +1 @@
1
- import { retrieveSideEffects } from '@exodus/ethereum-api';
2
- import { createCurrency, formatAccounts, getEthereumDisplayInfo, supportedNetworkEvms, hexToBN, isEthTransferTx, } from './utils.js';
3
- const computeBalanceChanges = async (asset, shouldSimulate, transaction) => {
4
- const assetName = asset.name;
5
- let balanceChanges = {
6
- willReceive: [],
7
- willSend: [],
8
- willApprove: [],
9
- };
10
- if (isEthTransferTx(transaction)) {
11
- const txValue = hexToBN(transaction.value).toString();
12
- balanceChanges.willSend.push({
13
- balance: createCurrency({
14
- amount: txValue,
15
- denominator: asset.currency.defaultUnit.power,
16
- symbol: asset.displayTicker,
17
- }),
18
- });
19
- }
20
- else {
21
- try {
22
- const sideEffect = await retrieveSideEffects({
23
- assetName,
24
- shouldSimulate,
25
- transaction,
26
- });
27
- if (sideEffect) {
28
- balanceChanges = formatAccounts(sideEffect);
29
- }
30
- }
31
- catch (error) {
32
- console.error('Ethereum transaction simulation failed.', error);
33
- }
34
- }
35
- return balanceChanges;
36
- };
37
- const getTxFeeDetails = (asset, transaction) => {
38
- const maxFeePerGasBn = transaction.maxFeePerGas
39
- ? hexToBN(transaction.maxFeePerGas)
40
- : undefined;
41
- const gasPriceBn = hexToBN(transaction.gasPrice);
42
- const gasBn = hexToBN(transaction.gas);
43
- return {
44
- txFee: asset.currency.baseUnit(gasBn.mul(maxFeePerGasBn || gasPriceBn).toString()),
45
- txFeeDetails: {
46
- gasLimit: gasBn.toNumber(),
47
- maxFeePerGas: maxFeePerGasBn?.toNumber(),
48
- gasPrice: gasPriceBn.toNumber(),
49
- },
50
- };
51
- };
52
- export const simulateTransaction = async (assets, transaction, network) => {
53
- const evm = supportedNetworkEvms.get(network);
54
- if (!evm) {
55
- throw new Error(`unsupported network, ${network}`);
56
- }
57
- const { assetName, shouldSimulate } = evm;
58
- const asset = assets[assetName];
59
- const balanceChanges = await computeBalanceChanges(asset, shouldSimulate, transaction);
60
- const { txFee, txFeeDetails } = getTxFeeDetails(asset, transaction);
61
- const displayInfo = getEthereumDisplayInfo(balanceChanges);
62
- return {
63
- assetName,
64
- advancedDetails: [],
65
- balanceChanges,
66
- displayInfo,
67
- txFee,
68
- txFeeDetails,
69
- };
70
- };
1
+ export { simulateTransaction } from './simulation.js';
@@ -0,0 +1,16 @@
1
+ import type { EthTransaction } from '@exodus/web3-ethereum-utils';
2
+ import type { Asset, EthBalanceChanges } from './types.js';
3
+ export declare const simulateTransaction: (asset: Asset, transaction: EthTransaction) => Promise<{
4
+ assetName: string;
5
+ advancedDetails: never[];
6
+ balanceChanges: EthBalanceChanges;
7
+ displayInfo: {
8
+ title: string;
9
+ };
10
+ txFee: unknown;
11
+ txFeeDetails: {
12
+ gasLimit: number;
13
+ maxFeePerGas: number | undefined;
14
+ gasPrice: number;
15
+ };
16
+ }>;
@@ -0,0 +1,67 @@
1
+ import { retrieveSideEffects } from '@exodus/ethereum-api';
2
+ import { SIMULATION_SUPPORTED_ASSET_NAMES } from './constant.js';
3
+ import { createCurrency, formatAccounts, getEthereumDisplayInfo, hexToBN, isEthTransferTx, } from './utils.js';
4
+ const computeBalanceChanges = async (asset, shouldSimulate, transaction) => {
5
+ const assetName = asset.name;
6
+ let balanceChanges = {
7
+ willReceive: [],
8
+ willSend: [],
9
+ willApprove: [],
10
+ };
11
+ if (isEthTransferTx(transaction)) {
12
+ const txValue = hexToBN(transaction.value).toString();
13
+ balanceChanges.willSend.push({
14
+ balance: createCurrency({
15
+ amount: txValue,
16
+ denominator: asset.currency.defaultUnit.power,
17
+ symbol: asset.displayTicker,
18
+ }),
19
+ });
20
+ }
21
+ else {
22
+ try {
23
+ const sideEffect = await retrieveSideEffects({
24
+ assetName,
25
+ shouldSimulate,
26
+ transaction,
27
+ });
28
+ if (sideEffect) {
29
+ balanceChanges = formatAccounts(sideEffect);
30
+ }
31
+ }
32
+ catch (error) {
33
+ console.error('Ethereum transaction simulation failed.', error);
34
+ }
35
+ }
36
+ return balanceChanges;
37
+ };
38
+ const getTxFeeDetails = (asset, transaction) => {
39
+ const maxFeePerGasBn = transaction.maxFeePerGas
40
+ ? hexToBN(transaction.maxFeePerGas)
41
+ : undefined;
42
+ const gasPriceBn = hexToBN(transaction.gasPrice);
43
+ const gasBn = hexToBN(transaction.gas);
44
+ return {
45
+ txFee: asset.currency.baseUnit(gasBn.mul(maxFeePerGasBn || gasPriceBn).toString()),
46
+ txFeeDetails: {
47
+ gasLimit: gasBn.toNumber(),
48
+ maxFeePerGas: maxFeePerGasBn?.toNumber(),
49
+ gasPrice: gasPriceBn.toNumber(),
50
+ },
51
+ };
52
+ };
53
+ export const simulateTransaction = async (asset, transaction) => {
54
+ const assetName = asset.name;
55
+ const shouldSimulate = SIMULATION_SUPPORTED_ASSET_NAMES.includes(assetName);
56
+ const balanceChanges = await computeBalanceChanges(asset, shouldSimulate, transaction);
57
+ const { txFee, txFeeDetails } = getTxFeeDetails(asset, transaction);
58
+ const displayInfo = getEthereumDisplayInfo(balanceChanges);
59
+ return {
60
+ assetName,
61
+ advancedDetails: [],
62
+ balanceChanges,
63
+ displayInfo,
64
+ txFee,
65
+ txFeeDetails,
66
+ };
67
+ };
@@ -1,7 +1,3 @@
1
- export interface EVMConstants {
2
- assetName: string;
3
- shouldSimulate: boolean;
4
- }
5
1
  export interface CurrencyParams {
6
2
  amount: string;
7
3
  symbol: string;
@@ -2,12 +2,6 @@ import BN from 'bn.js';
2
2
  import type { CurrencyParams, EthBalanceChange, EthBalanceChanges } from './types.js';
3
3
  import type { EthTransaction } from '@exodus/web3-ethereum-utils';
4
4
  export declare const hexToBN: (hexValue?: string) => BN;
5
- export declare const supportedNetworkEvms: Map<string, {
6
- chainId: string;
7
- network: string;
8
- assetName: string;
9
- shouldSimulate: boolean;
10
- }>;
11
5
  export declare const isEthTransferTx: (transaction: EthTransaction) => boolean;
12
6
  export declare function getEthereumDisplayInfo(balanceChanges: EthBalanceChanges): {
13
7
  title: string;
@@ -1,13 +1,6 @@
1
1
  import { UnitType } from '@exodus/currency';
2
2
  import BN from 'bn.js';
3
- import { CHAIN_IDS, ENABLED_EVMS } from './constant.js';
4
3
  export const hexToBN = (hexValue) => new BN((hexValue || '').slice(2), 'hex');
5
- const getEvmNetwork = (chainId) => `evm:${chainId}`;
6
- export const supportedNetworkEvms = new Map(ENABLED_EVMS.map((constant) => {
7
- const chainId = '0x' + CHAIN_IDS[constant.assetName].toString(16);
8
- const network = getEvmNetwork(chainId);
9
- return [network, { ...constant, chainId, network }];
10
- }));
11
4
  export const isEthTransferTx = (transaction) => {
12
5
  return (['0x', null, undefined].includes(transaction.data) &&
13
6
  [undefined, '0x5208'].includes(transaction.gas));
@@ -0,0 +1,2 @@
1
+ import type { WalletIcon } from '@wallet-standard/base';
2
+ export declare const icon: WalletIcon;
@@ -0,0 +1,2 @@
1
+ import { EXODUS_ICON } from '@exodus/web3-constants';
2
+ export const icon = EXODUS_ICON;
@@ -0,0 +1 @@
1
+ export { ExodusEthereumWallet } from './wallet.js';
@@ -0,0 +1 @@
1
+ export { ExodusEthereumWallet } from './wallet.js';
@@ -0,0 +1,17 @@
1
+ import type { Wallet } from '@wallet-standard/base';
2
+ import type { EthereumProvider } from '../provider/provider.js';
3
+ export declare type EthereumProviderFeature = {
4
+ 'ethereum:provider': {
5
+ provider: EthereumProvider;
6
+ };
7
+ };
8
+ export declare class ExodusEthereumWallet implements Wallet {
9
+ #private;
10
+ get version(): "1.0.0";
11
+ get name(): "Exodus";
12
+ get icon(): `data:image/svg+xml;base64,${string}` | `data:image/webp;base64,${string}` | `data:image/png;base64,${string}` | `data:image/gif;base64,${string}`;
13
+ get chains(): never[];
14
+ get features(): EthereumProviderFeature;
15
+ get accounts(): never[];
16
+ constructor(ethereumProvider: EthereumProvider);
17
+ }
@@ -0,0 +1,35 @@
1
+ import { icon } from './icon.js';
2
+ export class ExodusEthereumWallet {
3
+ #version = '1.0.0';
4
+ #name = 'Exodus';
5
+ #icon = icon;
6
+ #provider = null;
7
+ get version() {
8
+ return this.#version;
9
+ }
10
+ get name() {
11
+ return this.#name;
12
+ }
13
+ get icon() {
14
+ return this.#icon;
15
+ }
16
+ get chains() {
17
+ return [];
18
+ }
19
+ get features() {
20
+ return {
21
+ 'ethereum:provider': {
22
+ provider: this.#provider,
23
+ },
24
+ };
25
+ }
26
+ get accounts() {
27
+ return [];
28
+ }
29
+ constructor(ethereumProvider) {
30
+ if (!ethereumProvider) {
31
+ throw new Error('Ethereum Provider is required!');
32
+ }
33
+ this.#provider = ethereumProvider;
34
+ }
35
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exodus/web3-ethereum",
3
3
  "description": "Apps connectivity library for EVM-compatible chains.",
4
- "version": "0.1.0",
4
+ "version": "1.1.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "module": "lib/index.js",
@@ -11,7 +11,8 @@
11
11
  "./package.json": "./package.json",
12
12
  "./provider": "./lib/provider/index.js",
13
13
  "./rpc": "./lib/rpc-handlers/index.js",
14
- "./utils": "./lib/rpc-handlers/index.js"
14
+ "./simulation": "./lib/simulation/index.js",
15
+ "./wallet-standard": "./lib/wallet-standard/index.js"
15
16
  },
16
17
  "react-native": "./lib/index.js",
17
18
  "files": [
@@ -31,15 +32,19 @@
31
32
  "dependencies": {
32
33
  "@exodus/currency": "^2.1.2",
33
34
  "@exodus/ethereum-api": "3.2.4",
34
- "@exodus/web3-ethereum-utils": "1.7.0"
35
+ "@exodus/web3-constants": "^1.13.1",
36
+ "@exodus/web3-ethereum-utils": "1.7.0",
37
+ "@exodus/web3-provider": "^2.9.0",
38
+ "eth-rpc-errors": "^4.0.3"
35
39
  },
36
40
  "devDependencies": {
37
41
  "@exodus/assets": "^8.0.72",
38
42
  "@exodus/schemasafe": "^1.0.0-rc.7",
39
- "@exodus/web3-types": "^1.6.0"
43
+ "@exodus/web3-types": "^1.6.0",
44
+ "@wallet-standard/base": "^1.0.1"
40
45
  },
41
46
  "peerDependencies": {
42
47
  "@exodus/assets": "^8.0.72"
43
48
  },
44
- "gitHead": "9c988db57f3b4a18feb2038480e3466b93f2d06e"
49
+ "gitHead": "75254d697e3ffd2d95759e30425c30c7fb7fa654"
45
50
  }