@exodus/ethereum-api 5.1.0-alpha.0 → 6.0.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/package.json +3 -3
- package/src/eth-like-util.js +5 -14
- package/src/index.js +0 -1
- package/src/simulate-tx/simulate-eth-tx.js +33 -31
- package/src/tx-log/clarity-monitor.js +7 -4
- package/src/tx-log/ethereum-monitor.js +7 -3
- package/src/tx-log/ethereum-no-history-monitor.js +18 -8
- package/src/tx-log/monitor-utils/exclude-unchanged-token-balances.js +13 -0
- package/src/tx-log/monitor-utils/get-log-items-from-server-tx.js +10 -1
- package/src/tx-log/monitor-utils/index.js +2 -0
- package/src/optimism-gas/addresses.js +0 -1
- package/src/optimism-gas/index.js +0 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ethereum-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Ethereum Api",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@exodus/asset-lib": "^3.7.1",
|
|
18
18
|
"@exodus/crypto": "^1.0.0-rc.0",
|
|
19
|
-
"@exodus/ethereum-lib": "^
|
|
19
|
+
"@exodus/ethereum-lib": "^3.0.0",
|
|
20
20
|
"@exodus/ethereumjs-util": "^7.1.0-exodus.6",
|
|
21
21
|
"@exodus/fetch": "^1.2.1",
|
|
22
22
|
"@exodus/simple-retry": "^0.0.6",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@exodus/models": "^8.10.4"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "b299a67ebe7a7c23638d868b074df4d20b3f56d9"
|
|
40
40
|
}
|
package/src/eth-like-util.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
1
2
|
import { normalizeTxId, isEthereumLikeAsset, isEthereumLikeToken, ABI } from '@exodus/ethereum-lib'
|
|
2
|
-
import { getServerByName, getServer } from './exodus-eth-server'
|
|
3
3
|
import { memoizeLruCache } from '@exodus/asset-lib'
|
|
4
|
-
import assets from '@exodus/assets'
|
|
5
4
|
import SolidityContract from '@exodus/solidity-contract'
|
|
5
|
+
import { getServerByName, getServer } from './exodus-eth-server'
|
|
6
6
|
|
|
7
7
|
export async function isContract(baseAssetName, address) {
|
|
8
8
|
return getServerByName(baseAssetName).isContract(address)
|
|
@@ -86,18 +86,9 @@ const ERC20BytesParams = new SolidityContract(ABI.erc20BytesParams)
|
|
|
86
86
|
const DEFAULT_PARAM_NAMES = ['decimals', 'name', 'symbol']
|
|
87
87
|
const erc20ParamsCache = {}
|
|
88
88
|
|
|
89
|
-
export const getERC20Params = async ({
|
|
90
|
-
|
|
91
|
-
address,
|
|
92
|
-
paramNames = DEFAULT_PARAM_NAMES,
|
|
93
|
-
} = {}) => {
|
|
94
|
-
const asset = assets[assetName]
|
|
95
|
-
if (!asset) {
|
|
96
|
-
throw new Error(`${assetName} not found`)
|
|
97
|
-
}
|
|
98
|
-
if (!address) {
|
|
99
|
-
throw new Error(`Token address should be provided, got: ${address}`)
|
|
100
|
-
}
|
|
89
|
+
export const getERC20Params = async ({ asset, address, paramNames = DEFAULT_PARAM_NAMES } = {}) => {
|
|
90
|
+
assert(asset, 'getERC20Params(): asset required')
|
|
91
|
+
assert(address, 'getERC20Params(): address required')
|
|
101
92
|
|
|
102
93
|
const cacheKey = `${address}:${paramNames}`
|
|
103
94
|
if (erc20ParamsCache[cacheKey]) {
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
|
+
import { asset as ethereum } from '@exodus/ethereum-meta'
|
|
2
3
|
import {
|
|
3
4
|
checkIsERC721InputData,
|
|
4
5
|
checkIsNFTInputData,
|
|
@@ -9,14 +10,14 @@ import SolidityContract from '@exodus/solidity-contract'
|
|
|
9
10
|
import { fetchTxPreview } from './fetch-tx-preview'
|
|
10
11
|
import { getERC20Params } from '../eth-like-util'
|
|
11
12
|
|
|
12
|
-
const ethDecimals =
|
|
13
|
+
const ethDecimals = ethereum.units.ETH
|
|
13
14
|
|
|
14
15
|
const ethHexToInt = (hexValue) => parseInt(hexValue, '16')
|
|
15
16
|
|
|
16
|
-
async function getAssetSymbolFromContract(contractAddress) {
|
|
17
|
+
async function getAssetSymbolFromContract(contractAddress, asset) {
|
|
17
18
|
const { symbol: assetSymbol } = await getERC20Params({
|
|
18
19
|
address: contractAddress,
|
|
19
|
-
|
|
20
|
+
asset,
|
|
20
21
|
paramNames: ['symbol'],
|
|
21
22
|
})
|
|
22
23
|
|
|
@@ -53,12 +54,11 @@ async function prepareBalanceChanges(
|
|
|
53
54
|
internalTransactions,
|
|
54
55
|
balanceChanges,
|
|
55
56
|
transactionInput,
|
|
56
|
-
|
|
57
|
+
asset
|
|
57
58
|
) {
|
|
58
59
|
const assetNameToSymbolMap = Object.create(null)
|
|
59
60
|
assetNameToSymbolMap['ethereum'] = 'ETH' // Refactor after blowfish integration
|
|
60
61
|
|
|
61
|
-
const asset = assets[assetName]
|
|
62
62
|
const preparedBalanceChanges = [...balanceChanges]
|
|
63
63
|
|
|
64
64
|
const decimals = Object.create(null)
|
|
@@ -85,7 +85,7 @@ async function prepareBalanceChanges(
|
|
|
85
85
|
if (isERC20) {
|
|
86
86
|
const assetSymbol =
|
|
87
87
|
contractCall.contractAlias ||
|
|
88
|
-
(await getAssetSymbolFromContract(contractCall.contractAddress))
|
|
88
|
+
(await getAssetSymbolFromContract(contractCall.contractAddress, asset))
|
|
89
89
|
|
|
90
90
|
assetSymbols[contractCall.contractAddress] = assetSymbol
|
|
91
91
|
decimals[assetSymbol] = contractCall.contractDecimals
|
|
@@ -98,40 +98,40 @@ async function prepareBalanceChanges(
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
for (const balanceChange of preparedBalanceChanges) {
|
|
101
|
-
const { asset } = balanceChange
|
|
101
|
+
const { asset: assetData } = balanceChange
|
|
102
102
|
|
|
103
|
-
if (!
|
|
104
|
-
|
|
105
|
-
assetSymbols[
|
|
106
|
-
(await getAssetSymbolFromContract(
|
|
103
|
+
if (!assetData.symbol) {
|
|
104
|
+
assetData.symbol =
|
|
105
|
+
assetSymbols[assetData.contractAddress] ||
|
|
106
|
+
(await getAssetSymbolFromContract(assetData.contractAddress, asset))
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
if (isERC721) {
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
assetData.type = 'erc721'
|
|
111
|
+
assetData.title = contractName
|
|
112
112
|
continue
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
if (typeof decimals[
|
|
116
|
-
|
|
115
|
+
if (typeof decimals[assetData.symbol] === 'number') {
|
|
116
|
+
assetData.decimal = decimals[assetData.symbol]
|
|
117
117
|
continue
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
if (isERC20 &&
|
|
120
|
+
if (isERC20 && assetData.contractAddress) {
|
|
121
121
|
const { decimals: assetDecimal } = await getERC20Params({
|
|
122
|
-
address:
|
|
123
|
-
|
|
122
|
+
address: assetData.contractAddress,
|
|
123
|
+
asset,
|
|
124
124
|
paramNames: ['decimals'],
|
|
125
125
|
})
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
assetData.decimal = assetDecimal
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
return maybeRemoveDuplicates(preparedBalanceChanges)
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
async function tryToDecodeApprovalTransaction(transaction) {
|
|
134
|
+
async function tryToDecodeApprovalTransaction(transaction, asset) {
|
|
135
135
|
if (!transaction?.data.startsWith(APPROVE_METHOD_ID)) return null
|
|
136
136
|
|
|
137
137
|
const contract = SolidityContract.erc20(transaction.to)
|
|
@@ -142,7 +142,7 @@ async function tryToDecodeApprovalTransaction(transaction) {
|
|
|
142
142
|
const [grantedTo, balance] = decodedInput.values
|
|
143
143
|
|
|
144
144
|
const symbol =
|
|
145
|
-
(await getAssetSymbolFromContract(transaction.to))?.toUpperCase() || 'Unknown Token'
|
|
145
|
+
(await getAssetSymbolFromContract(transaction.to, asset))?.toUpperCase() || 'Unknown Token'
|
|
146
146
|
|
|
147
147
|
return [{ grantedTo, balance, symbol, decimals: undefined }] // ToDo: Return 'decimals' in the future once we support changing the approval amount.
|
|
148
148
|
} catch (e) {
|
|
@@ -152,11 +152,13 @@ async function tryToDecodeApprovalTransaction(transaction) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
export async function retrieveSideEffects({ transaction,
|
|
155
|
+
export async function retrieveSideEffects({ transaction, asset, shouldSimulate = true }) {
|
|
156
|
+
assert(asset, 'retrieveSideEffects(): asset is required')
|
|
157
|
+
|
|
156
158
|
const willSend = []
|
|
157
159
|
const willReceive = []
|
|
158
160
|
|
|
159
|
-
const approveTransactionData = await tryToDecodeApprovalTransaction(transaction)
|
|
161
|
+
const approveTransactionData = await tryToDecodeApprovalTransaction(transaction, asset)
|
|
160
162
|
if (approveTransactionData) {
|
|
161
163
|
return { willApprove: approveTransactionData }
|
|
162
164
|
}
|
|
@@ -192,25 +194,25 @@ export async function retrieveSideEffects({ transaction, assetName, shouldSimula
|
|
|
192
194
|
internalTransactions,
|
|
193
195
|
sender.balanceChanges,
|
|
194
196
|
transaction.data,
|
|
195
|
-
|
|
197
|
+
asset
|
|
196
198
|
)
|
|
197
199
|
|
|
198
200
|
for (const balanceChange of preparedBalanceChanges) {
|
|
199
|
-
const { delta, asset } = balanceChange
|
|
201
|
+
const { delta, asset: assetData } = balanceChange
|
|
200
202
|
|
|
201
203
|
const account = {
|
|
202
|
-
symbol:
|
|
204
|
+
symbol: assetData.symbol,
|
|
203
205
|
balance: delta,
|
|
204
|
-
assetType:
|
|
205
|
-
decimal:
|
|
206
|
+
assetType: assetData.type,
|
|
207
|
+
decimal: assetData.decimal,
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
if (delta.startsWith('-')) {
|
|
209
211
|
willSend.push(account)
|
|
210
212
|
} else {
|
|
211
|
-
if (
|
|
213
|
+
if (assetData.type === 'erc721') {
|
|
212
214
|
account.nft = {
|
|
213
|
-
title: `${
|
|
215
|
+
title: `${assetData.title || assetData.symbol} #${delta}`,
|
|
214
216
|
}
|
|
215
217
|
}
|
|
216
218
|
willReceive.push(account)
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
getAllLogItemsByAsset,
|
|
9
9
|
checkPendingTransactions,
|
|
10
10
|
getDeriveTransactionsToCheck,
|
|
11
|
+
excludeUnchangedTokenBalances,
|
|
11
12
|
} from './monitor-utils'
|
|
12
13
|
import { getLogItemsFromServerTx, getDeriveDataNeededForTick, filterEffects } from './clarity-utils'
|
|
13
14
|
|
|
@@ -158,6 +159,7 @@ export class ClarityMonitor extends BaseMonitor {
|
|
|
158
159
|
|
|
159
160
|
const accountState = await this.getNewAccountState({
|
|
160
161
|
tokens,
|
|
162
|
+
currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
|
|
161
163
|
ourWalletAddress: derivedData.ourWalletAddress,
|
|
162
164
|
})
|
|
163
165
|
await this.updateAccountState({
|
|
@@ -187,7 +189,7 @@ export class ClarityMonitor extends BaseMonitor {
|
|
|
187
189
|
}
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
async getNewAccountState({ tokens, ourWalletAddress }) {
|
|
192
|
+
async getNewAccountState({ tokens, currentTokenBalances, ourWalletAddress }) {
|
|
191
193
|
const asset = this.asset
|
|
192
194
|
const newAccountState = {}
|
|
193
195
|
const balances = await this.getBalances({ tokens, ourWalletAddress })
|
|
@@ -196,14 +198,15 @@ export class ClarityMonitor extends BaseMonitor {
|
|
|
196
198
|
newAccountState.balance = asset.currency.baseUnit(balance)
|
|
197
199
|
}
|
|
198
200
|
const tokenBalancePairs = Object.entries(balances).filter((entry) => entry[0] !== asset.name)
|
|
199
|
-
const
|
|
201
|
+
const tokenBalanceEntries = tokenBalancePairs
|
|
200
202
|
.map((pair) => {
|
|
201
203
|
const token = tokens.find((token) => token.name === pair[0])
|
|
202
204
|
const value = token.currency.baseUnit(pair[1] || 0)
|
|
203
|
-
return
|
|
205
|
+
return [token.name, value]
|
|
204
206
|
})
|
|
205
207
|
.filter((pair) => pair)
|
|
206
|
-
|
|
208
|
+
|
|
209
|
+
const tokenBalances = excludeUnchangedTokenBalances(currentTokenBalances, tokenBalanceEntries)
|
|
207
210
|
if (!isEmpty(tokenBalances)) newAccountState.tokenBalances = tokenBalances
|
|
208
211
|
return newAccountState
|
|
209
212
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getDeriveDataNeededForTick,
|
|
12
12
|
getDeriveTransactionsToCheck,
|
|
13
13
|
getHistoryFromServer,
|
|
14
|
+
excludeUnchangedTokenBalances,
|
|
14
15
|
} from './monitor-utils'
|
|
15
16
|
|
|
16
17
|
import {
|
|
@@ -185,8 +186,10 @@ export class EthereumMonitor extends BaseMonitor {
|
|
|
185
186
|
|
|
186
187
|
const accountState = await this.getNewAccountState({
|
|
187
188
|
tokens,
|
|
189
|
+
currentTokenBalances: derivedData.currentAccountState?.tokenBalances,
|
|
188
190
|
ourWalletAddress: derivedData.ourWalletAddress,
|
|
189
191
|
})
|
|
192
|
+
|
|
190
193
|
await this.updateAccountState({ newData: { index, ...accountState }, walletAccount })
|
|
191
194
|
|
|
192
195
|
await this.removeFromTxLog(txsToRemove)
|
|
@@ -220,7 +223,7 @@ export class EthereumMonitor extends BaseMonitor {
|
|
|
220
223
|
}
|
|
221
224
|
}
|
|
222
225
|
|
|
223
|
-
async getNewAccountState({ tokens, ourWalletAddress }) {
|
|
226
|
+
async getNewAccountState({ tokens, currentTokenBalances, ourWalletAddress }) {
|
|
224
227
|
const asset = this.asset
|
|
225
228
|
const newAccountState = {}
|
|
226
229
|
const server = this.server
|
|
@@ -236,10 +239,11 @@ export class EthereumMonitor extends BaseMonitor {
|
|
|
236
239
|
.map(async (token) => {
|
|
237
240
|
const { confirmed } = await server.balanceOf(ourWalletAddress, token.contract.address)
|
|
238
241
|
const value = token.currency.baseUnit(confirmed[token.contract.address] || 0)
|
|
239
|
-
return
|
|
242
|
+
return [token.name, value]
|
|
240
243
|
})
|
|
241
244
|
)
|
|
242
|
-
|
|
245
|
+
|
|
246
|
+
const tokenBalances = excludeUnchangedTokenBalances(currentTokenBalances, tokenBalancePairs)
|
|
243
247
|
if (!isEmpty(tokenBalances)) newAccountState.tokenBalances = tokenBalances
|
|
244
248
|
return newAccountState
|
|
245
249
|
}
|
|
@@ -3,7 +3,11 @@ import { getServer } from '@exodus/ethereum-api'
|
|
|
3
3
|
import { DEFAULT_SERVER_URLS } from '@exodus/ethereum-lib'
|
|
4
4
|
import { Tx } from '@exodus/models'
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getDeriveDataNeededForTick,
|
|
8
|
+
getDeriveTransactionsToCheck,
|
|
9
|
+
excludeUnchangedTokenBalances,
|
|
10
|
+
} from './monitor-utils'
|
|
7
11
|
|
|
8
12
|
import { isEmpty, unionBy, zipObject } from 'lodash'
|
|
9
13
|
|
|
@@ -57,21 +61,22 @@ export class EthereumNoHistoryMonitor extends BaseMonitor {
|
|
|
57
61
|
return Object.fromEntries(entries)
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
async getNewAccountState({ tokens, ourWalletAddress }) {
|
|
64
|
+
async getNewAccountState({ tokens, currentTokenBalances, ourWalletAddress }) {
|
|
61
65
|
const asset = this.asset
|
|
62
66
|
const newAccountState = {}
|
|
63
67
|
const balances = await this.getBalances({ tokens, ourWalletAddress })
|
|
64
68
|
const balance = balances[asset.name]
|
|
65
69
|
newAccountState.balance = asset.currency.baseUnit(balance)
|
|
66
70
|
const tokenBalancePairs = Object.entries(balances).filter((entry) => entry[0] !== asset.name)
|
|
67
|
-
const
|
|
71
|
+
const tokenBalanceEntries = tokenBalancePairs
|
|
68
72
|
.map((pair) => {
|
|
69
73
|
const token = tokens.find((token) => token.name === pair[0])
|
|
70
74
|
const value = token.currency.baseUnit(pair[1] || 0)
|
|
71
|
-
return
|
|
75
|
+
return [token.name, value]
|
|
72
76
|
})
|
|
73
77
|
.filter((pair) => pair)
|
|
74
|
-
|
|
78
|
+
|
|
79
|
+
const tokenBalances = excludeUnchangedTokenBalances(currentTokenBalances, tokenBalanceEntries)
|
|
75
80
|
if (!isEmpty(tokenBalances)) newAccountState.tokenBalances = tokenBalances
|
|
76
81
|
return newAccountState
|
|
77
82
|
}
|
|
@@ -79,7 +84,11 @@ export class EthereumNoHistoryMonitor extends BaseMonitor {
|
|
|
79
84
|
async deriveData({ assetSource, tokens }) {
|
|
80
85
|
const { assetName, walletAccount } = assetSource
|
|
81
86
|
|
|
82
|
-
const { ourWalletAddress } = await this.deriveDataNeededForTick({
|
|
87
|
+
const { ourWalletAddress, currentAccountState } = await this.deriveDataNeededForTick({
|
|
88
|
+
assetName,
|
|
89
|
+
walletAccount,
|
|
90
|
+
})
|
|
91
|
+
|
|
83
92
|
const {
|
|
84
93
|
pendingTransactionsGroupedByAddressAndNonce,
|
|
85
94
|
pendingTransactionsToCheck,
|
|
@@ -96,7 +105,7 @@ export class EthereumNoHistoryMonitor extends BaseMonitor {
|
|
|
96
105
|
'tx.txId'
|
|
97
106
|
)
|
|
98
107
|
|
|
99
|
-
return { ourWalletAddress, pendingTransactions }
|
|
108
|
+
return { ourWalletAddress, pendingTransactions, currentAccountState }
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
async getTransactionsFromNode(transactions) {
|
|
@@ -148,7 +157,7 @@ export class EthereumNoHistoryMonitor extends BaseMonitor {
|
|
|
148
157
|
|
|
149
158
|
const assetSource = { assetName: this.asset.name, walletAccount }
|
|
150
159
|
|
|
151
|
-
const { ourWalletAddress, pendingTransactions } = await this.deriveData({
|
|
160
|
+
const { ourWalletAddress, pendingTransactions, currentAccountState } = await this.deriveData({
|
|
152
161
|
assetSource,
|
|
153
162
|
tokens,
|
|
154
163
|
})
|
|
@@ -171,6 +180,7 @@ export class EthereumNoHistoryMonitor extends BaseMonitor {
|
|
|
171
180
|
|
|
172
181
|
const accountState = await this.getNewAccountState({
|
|
173
182
|
tokens,
|
|
183
|
+
currentTokenBalances: currentAccountState?.tokenBalances,
|
|
174
184
|
ourWalletAddress,
|
|
175
185
|
})
|
|
176
186
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function excludeUnchangedTokenBalances(currentTokenBalances, newTokenBalancePairs) {
|
|
2
|
+
const newTokenBalances = Object.fromEntries(newTokenBalancePairs)
|
|
3
|
+
|
|
4
|
+
const tokenBalances = newTokenBalancePairs.reduce((tokenBalancesAcc, [token, balance]) => {
|
|
5
|
+
const currentBalance = currentTokenBalances[token]
|
|
6
|
+
if (!newTokenBalances[token].isZero || (currentBalance && !currentBalance.isZero)) {
|
|
7
|
+
tokenBalancesAcc[token] = balance
|
|
8
|
+
}
|
|
9
|
+
return tokenBalancesAcc
|
|
10
|
+
}, {})
|
|
11
|
+
|
|
12
|
+
return tokenBalances
|
|
13
|
+
}
|
|
@@ -41,8 +41,9 @@ export default function getLogItemsFromServerTx({
|
|
|
41
41
|
{
|
|
42
42
|
const sendingTransferPresent = ethereumTransfers.some(({ from }) => from === ourWalletAddress)
|
|
43
43
|
const receivingTransferPresent = ethereumTransfers.some(({ to }) => to === ourWalletAddress)
|
|
44
|
+
const nftTransferPresent = isNftTransfer({ serverTx, ourWalletAddress })
|
|
44
45
|
|
|
45
|
-
if (sendingTransferPresent || receivingTransferPresent) {
|
|
46
|
+
if (sendingTransferPresent || receivingTransferPresent || nftTransferPresent) {
|
|
46
47
|
const coinAmount = getValueOfTransfers(ourWalletAddress, asset, ethereumTransfers)
|
|
47
48
|
const selfSend = isSelfSendTx({
|
|
48
49
|
coinAmount,
|
|
@@ -140,3 +141,11 @@ function isSelfSendTx({
|
|
|
140
141
|
coinAmount.isZero && sendingTransferPresent && receivingTransferPresent && ourWalletWasSender
|
|
141
142
|
)
|
|
142
143
|
}
|
|
144
|
+
|
|
145
|
+
function isNftTransfer({ serverTx, ourWalletAddress }) {
|
|
146
|
+
if (!Array.isArray(serverTx.erc721) || serverTx.erc721.length < 1) return false
|
|
147
|
+
|
|
148
|
+
return serverTx.erc721.some(
|
|
149
|
+
(transfer) => transfer.to === ourWalletAddress || transfer.from === ourWalletAddress
|
|
150
|
+
)
|
|
151
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { default as getDeriveDataNeededForTick } from './get-derive-data-needed-for-tick'
|
|
2
|
+
|
|
2
3
|
export { default as getAllLogItemsByAsset } from './get-all-log-items-by-asset'
|
|
3
4
|
export { default as getLogItemsFromServerTx } from './get-log-items-from-server-tx'
|
|
4
5
|
export { default as getHistoryFromServer } from './get-history-from-server'
|
|
5
6
|
export { default as checkPendingTransactions } from './check-pending-transactions'
|
|
6
7
|
export { default as getDeriveTransactionsToCheck } from './get-derive-transactions-to-check'
|
|
8
|
+
export * from './exclude-unchanged-token-balances'
|
|
7
9
|
|
|
8
10
|
export type { PendingTransactionsDictionary } from './types'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const GAS_ORACLE_ADDRESS = '0x420000000000000000000000000000000000000F'
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as ethUtil from '@exodus/ethereumjs-util'
|
|
2
|
-
import { convertUnsignedTx, createContract } from '@exodus/ethereum-lib'
|
|
3
|
-
import { getServerByName } from '../exodus-eth-server'
|
|
4
|
-
import { GAS_ORACLE_ADDRESS } from './addresses'
|
|
5
|
-
|
|
6
|
-
const gasContract = createContract(GAS_ORACLE_ADDRESS, 'optimismGasOracle')
|
|
7
|
-
|
|
8
|
-
export async function estimateOptimismL1DataFee({ unsignedTx }) {
|
|
9
|
-
const ethjsTx = convertUnsignedTx(unsignedTx)
|
|
10
|
-
const serialized = ethjsTx.serialize()
|
|
11
|
-
const callData = gasContract.getL1Fee.build(serialized)
|
|
12
|
-
const buffer = Buffer.from(callData)
|
|
13
|
-
const data = ethUtil.bufferToHex(buffer)
|
|
14
|
-
const server = getServerByName('optimism')
|
|
15
|
-
return server.ethCall({ to: GAS_ORACLE_ADDRESS, data }, 'latest')
|
|
16
|
-
}
|