@exodus/solana-plugin 1.2.0 → 1.3.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 +4 -4
- package/src/create-asset.js +167 -0
- package/src/index.js +5 -153
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Exodus internal Solana asset plugin",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@exodus/assets": "^9.0.1",
|
|
23
23
|
"@exodus/bip44-constants": "^195.0.0",
|
|
24
|
-
"@exodus/solana-api": "^
|
|
25
|
-
"@exodus/solana-lib": "^
|
|
24
|
+
"@exodus/solana-api": "^3.0.0",
|
|
25
|
+
"@exodus/solana-lib": "^2.0.0",
|
|
26
26
|
"@exodus/solana-meta": "^1.0.7",
|
|
27
27
|
"minimalistic-assert": "^1.0.1",
|
|
28
28
|
"ms": "^2.1.3"
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@exodus/assets-testing": "^1.0.0"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "01254e502415ab368a8d8c9932f7e30476146e9a"
|
|
34
34
|
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { connectAssetsList } from '@exodus/assets'
|
|
2
|
+
import bip44Constants from '@exodus/bip44-constants/by-ticker'
|
|
3
|
+
import {
|
|
4
|
+
createGetKeyIdentifier,
|
|
5
|
+
getAddressFromPublicKey,
|
|
6
|
+
getEncodedSecretKey,
|
|
7
|
+
isValidAddress,
|
|
8
|
+
parseUnsignedTx,
|
|
9
|
+
signUnsignedTx,
|
|
10
|
+
signHardware,
|
|
11
|
+
createFeeData,
|
|
12
|
+
} from '@exodus/solana-lib'
|
|
13
|
+
import ms from 'ms'
|
|
14
|
+
import {
|
|
15
|
+
isSolanaRewardsActivityTx,
|
|
16
|
+
getBalancesFactory,
|
|
17
|
+
getUnstakingFee,
|
|
18
|
+
SolanaMonitor,
|
|
19
|
+
SolanaFeeMonitor,
|
|
20
|
+
createAccountState,
|
|
21
|
+
createAndBroadcastTXFactory,
|
|
22
|
+
} from '@exodus/solana-api'
|
|
23
|
+
|
|
24
|
+
const DEFAULT_ACCOUNT_RESERVE = 0.01
|
|
25
|
+
const DEFAULT_LOW_BALANCE = 0.01
|
|
26
|
+
const DEFAULT_MIN_STAKING_AMOUNT = 0.01
|
|
27
|
+
|
|
28
|
+
export const createSolanaAssetFactory =
|
|
29
|
+
({ assetList, serverApi }) =>
|
|
30
|
+
({
|
|
31
|
+
config: {
|
|
32
|
+
stakingFeatureAvailable = true,
|
|
33
|
+
includeUnparsed = false,
|
|
34
|
+
monitorInterval = ms('30s'),
|
|
35
|
+
defaultAccountReserve = DEFAULT_ACCOUNT_RESERVE,
|
|
36
|
+
defaultLowBalance = DEFAULT_LOW_BALANCE,
|
|
37
|
+
defaultMinStakingAmount = DEFAULT_MIN_STAKING_AMOUNT,
|
|
38
|
+
ticksBetweenHistoryFetches,
|
|
39
|
+
ticksBetweenStakeFetches,
|
|
40
|
+
txsLimit,
|
|
41
|
+
} = {},
|
|
42
|
+
overrideCallback = ({ asset }) => asset,
|
|
43
|
+
} = {}) => {
|
|
44
|
+
const assets = connectAssetsList(assetList)
|
|
45
|
+
const base = assets.solana
|
|
46
|
+
|
|
47
|
+
const accountReserve = base.currency.defaultUnit(
|
|
48
|
+
defaultAccountReserve ?? DEFAULT_ACCOUNT_RESERVE
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const lowBalance = base.currency.defaultUnit(defaultLowBalance ?? DEFAULT_LOW_BALANCE)
|
|
52
|
+
|
|
53
|
+
const MIN_STAKING_AMOUNT = base.currency.defaultUnit(
|
|
54
|
+
defaultMinStakingAmount ?? DEFAULT_MIN_STAKING_AMOUNT
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
const address = {
|
|
58
|
+
validate: isValidAddress,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const bip44 = bip44Constants[base.ticker]
|
|
62
|
+
|
|
63
|
+
const keys = {
|
|
64
|
+
encodePrivate: getEncodedSecretKey,
|
|
65
|
+
encodePublic: getAddressFromPublicKey,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const getBalances = getBalancesFactory({ stakingFeatureAvailable })
|
|
69
|
+
|
|
70
|
+
const feeData = createFeeData({ asset: base })
|
|
71
|
+
|
|
72
|
+
const sendTx = createAndBroadcastTXFactory(serverApi)
|
|
73
|
+
|
|
74
|
+
const createToken = ({ mintAddress, name, ...tokenDef }) => ({
|
|
75
|
+
...tokenDef,
|
|
76
|
+
address,
|
|
77
|
+
assetId: mintAddress,
|
|
78
|
+
bip44,
|
|
79
|
+
keys,
|
|
80
|
+
mintAddress,
|
|
81
|
+
name,
|
|
82
|
+
api: {
|
|
83
|
+
features: {},
|
|
84
|
+
getBalances,
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const createCustomToken = ({ assetId, assetName, ...rest }) =>
|
|
89
|
+
createToken({ ...rest, name: assetName, mintAddress: assetId })
|
|
90
|
+
|
|
91
|
+
const isSmallValueTx = (tx) =>
|
|
92
|
+
!tx.tokens?.length &&
|
|
93
|
+
!isSolanaRewardsActivityTx(tx) &&
|
|
94
|
+
Math.abs(tx.coinAmount.toDefaultNumber()) <= 0.000_000_001
|
|
95
|
+
|
|
96
|
+
const getActivityTxs = ({ txs }) => txs.filter((tx) => !isSmallValueTx(tx))
|
|
97
|
+
|
|
98
|
+
const features = {
|
|
99
|
+
accountState: true,
|
|
100
|
+
customTokens: true,
|
|
101
|
+
feeMonitor: false,
|
|
102
|
+
feesApi: true,
|
|
103
|
+
nfts: true,
|
|
104
|
+
staking: {},
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const assetStakingApi = {
|
|
108
|
+
isStaking: ({ accountState }) => accountState.mem.isDelegating,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const SolanaAccountState = createAccountState({ assetList })
|
|
112
|
+
|
|
113
|
+
const api = {
|
|
114
|
+
getActivityTxs,
|
|
115
|
+
addressHasHistory: (...args) => serverApi.getAccountInfo(...args).then((acc) => !!acc),
|
|
116
|
+
broadcastTx: (...args) => serverApi.broadcastTransaction(...args),
|
|
117
|
+
createAccountState: () => SolanaAccountState,
|
|
118
|
+
createFeeMonitor: (args) => new SolanaFeeMonitor({ ...args, api: serverApi }),
|
|
119
|
+
createHistoryMonitor: (args) =>
|
|
120
|
+
new SolanaMonitor({
|
|
121
|
+
interval: monitorInterval,
|
|
122
|
+
ticksBetweenHistoryFetches,
|
|
123
|
+
ticksBetweenStakeFetches,
|
|
124
|
+
includeUnparsed,
|
|
125
|
+
api: serverApi,
|
|
126
|
+
txsLimit,
|
|
127
|
+
...args,
|
|
128
|
+
}),
|
|
129
|
+
createToken: (tokenDef) =>
|
|
130
|
+
tokenDef.isBuiltIn ? createToken(tokenDef) : createCustomToken(tokenDef),
|
|
131
|
+
defaultAddressPath: 'm/0/0',
|
|
132
|
+
features,
|
|
133
|
+
getBalances,
|
|
134
|
+
getFee: ({ feeData }) => feeData.fee,
|
|
135
|
+
getFeeAsync: async ({ feeData }) => feeData.fee,
|
|
136
|
+
getFeeData: () => feeData,
|
|
137
|
+
getSupportedPurposes: () => [44],
|
|
138
|
+
getKeyIdentifier: createGetKeyIdentifier({ bip44 }),
|
|
139
|
+
getTokens: () =>
|
|
140
|
+
Object.values(assets)
|
|
141
|
+
.filter((asset) => asset.name !== base.name)
|
|
142
|
+
.map(createToken),
|
|
143
|
+
getUnstakingFee,
|
|
144
|
+
hasFeature: (feature) => !!features[feature], // @deprecated use api.features instead
|
|
145
|
+
parseUnsignedTx: (unsignedTx) => parseUnsignedTx({ asset: base, unsignedTx }),
|
|
146
|
+
parseTx: ({ unsignedTx }) => parseUnsignedTx({ asset: base, unsignedTx }),
|
|
147
|
+
sendTx,
|
|
148
|
+
signTx: ({ unsignedTx, privateKey }) => signUnsignedTx(unsignedTx, privateKey),
|
|
149
|
+
signUnsignedTx,
|
|
150
|
+
signHardware,
|
|
151
|
+
staking: assetStakingApi,
|
|
152
|
+
validateAssetId: isValidAddress,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const fullAsset = {
|
|
156
|
+
...base,
|
|
157
|
+
address,
|
|
158
|
+
keys,
|
|
159
|
+
api,
|
|
160
|
+
bip44,
|
|
161
|
+
accountReserve,
|
|
162
|
+
lowBalance,
|
|
163
|
+
MIN_STAKING_AMOUNT,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return overrideCallback({ asset: fullAsset })
|
|
167
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,160 +1,12 @@
|
|
|
1
|
-
import { connectAssetsList } from '@exodus/assets'
|
|
2
|
-
import bip44Constants from '@exodus/bip44-constants/by-ticker'
|
|
3
|
-
import {
|
|
4
|
-
createGetKeyIdentifier,
|
|
5
|
-
getAddressFromPublicKey,
|
|
6
|
-
getEncodedSecretKey,
|
|
7
|
-
isValidAddress,
|
|
8
|
-
parseUnsignedTx,
|
|
9
|
-
signUnsignedTx,
|
|
10
|
-
signHardware,
|
|
11
|
-
} from '@exodus/solana-lib'
|
|
12
|
-
import { solana as feeData } from '@exodus/solana-lib/src/fee-data'
|
|
13
1
|
import assetList from '@exodus/solana-meta'
|
|
14
|
-
import
|
|
15
|
-
import serverApi, {
|
|
16
|
-
isSolanaRewardsActivityTx,
|
|
17
|
-
getBalancesFactory,
|
|
18
|
-
getUnstakingFee,
|
|
19
|
-
SolanaMonitor,
|
|
20
|
-
SolanaFeeMonitor,
|
|
21
|
-
SolanaAccountState,
|
|
22
|
-
createAndBroadcastTXFactory,
|
|
23
|
-
} from '@exodus/solana-api'
|
|
2
|
+
import serverApi from '@exodus/solana-api'
|
|
24
3
|
|
|
25
|
-
|
|
26
|
-
const DEFAULT_LOW_BALANCE = 0.01
|
|
27
|
-
const DEFAULT_MIN_STAKING_AMOUNT = 0.01
|
|
4
|
+
import { createSolanaAssetFactory } from './create-asset'
|
|
28
5
|
|
|
29
|
-
|
|
30
|
-
config: {
|
|
31
|
-
stakingFeatureAvailable = true,
|
|
32
|
-
includeUnparsed = false,
|
|
33
|
-
monitorInterval = ms('30s'),
|
|
34
|
-
defaultAccountReserve = DEFAULT_ACCOUNT_RESERVE,
|
|
35
|
-
defaultLowBalance = DEFAULT_LOW_BALANCE,
|
|
36
|
-
defaultMinStakingAmount = DEFAULT_MIN_STAKING_AMOUNT,
|
|
37
|
-
ticksBetweenHistoryFetches,
|
|
38
|
-
ticksBetweenStakeFetches,
|
|
39
|
-
txsLimit,
|
|
40
|
-
} = {},
|
|
41
|
-
overrideCallback = ({ asset }) => asset,
|
|
42
|
-
} = {}) => {
|
|
43
|
-
const assets = connectAssetsList(assetList)
|
|
44
|
-
const base = assets.solana
|
|
6
|
+
export * from './create-asset' // for solanatestnet and solanadevnet
|
|
45
7
|
|
|
46
|
-
|
|
47
|
-
const lowBalance = base.currency.SOL(defaultLowBalance ?? DEFAULT_LOW_BALANCE)
|
|
48
|
-
const MIN_STAKING_AMOUNT = base.currency.SOL(
|
|
49
|
-
defaultMinStakingAmount ?? DEFAULT_MIN_STAKING_AMOUNT
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
const address = {
|
|
53
|
-
validate: isValidAddress,
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const bip44 = bip44Constants[base.ticker]
|
|
57
|
-
|
|
58
|
-
const keys = {
|
|
59
|
-
encodePrivate: getEncodedSecretKey,
|
|
60
|
-
encodePublic: getAddressFromPublicKey,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const getBalances = getBalancesFactory({ stakingFeatureAvailable })
|
|
64
|
-
|
|
65
|
-
const sendTx = createAndBroadcastTXFactory(serverApi)
|
|
66
|
-
|
|
67
|
-
const createToken = ({ mintAddress, name, ...tokenDef }) => ({
|
|
68
|
-
...tokenDef,
|
|
69
|
-
address,
|
|
70
|
-
assetId: mintAddress,
|
|
71
|
-
bip44,
|
|
72
|
-
keys,
|
|
73
|
-
mintAddress,
|
|
74
|
-
name,
|
|
75
|
-
api: {
|
|
76
|
-
features: {},
|
|
77
|
-
getBalances,
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const createCustomToken = ({ assetId, assetName, ...rest }) =>
|
|
82
|
-
createToken({ ...rest, name: assetName, mintAddress: assetId })
|
|
83
|
-
|
|
84
|
-
const isSmallValueTx = (tx) =>
|
|
85
|
-
!tx.tokens?.length &&
|
|
86
|
-
!isSolanaRewardsActivityTx(tx) &&
|
|
87
|
-
Math.abs(tx.coinAmount.toDefaultNumber()) <= 0.000_000_001
|
|
88
|
-
|
|
89
|
-
const getActivityTxs = ({ txs }) => txs.filter((tx) => !isSmallValueTx(tx))
|
|
90
|
-
|
|
91
|
-
const features = {
|
|
92
|
-
accountState: true,
|
|
93
|
-
customTokens: true,
|
|
94
|
-
feeMonitor: false,
|
|
95
|
-
feesApi: true,
|
|
96
|
-
nfts: true,
|
|
97
|
-
staking: {},
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const assetStakingApi = {
|
|
101
|
-
isStaking: ({ accountState }) => accountState.mem.isDelegating,
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const api = {
|
|
105
|
-
getActivityTxs,
|
|
106
|
-
addressHasHistory: (...args) => serverApi.getAccountInfo(...args).then((acc) => !!acc),
|
|
107
|
-
broadcastTx: (...args) => serverApi.broadcastTransaction(...args),
|
|
108
|
-
createAccountState: () => SolanaAccountState,
|
|
109
|
-
createFeeMonitor: (args) => new SolanaFeeMonitor({ ...args, api: serverApi }),
|
|
110
|
-
createHistoryMonitor: (args) =>
|
|
111
|
-
new SolanaMonitor({
|
|
112
|
-
interval: monitorInterval,
|
|
113
|
-
ticksBetweenHistoryFetches,
|
|
114
|
-
ticksBetweenStakeFetches,
|
|
115
|
-
includeUnparsed,
|
|
116
|
-
api: serverApi,
|
|
117
|
-
txsLimit,
|
|
118
|
-
...args,
|
|
119
|
-
}),
|
|
120
|
-
createToken: (tokenDef) =>
|
|
121
|
-
tokenDef.isBuiltIn ? createToken(tokenDef) : createCustomToken(tokenDef),
|
|
122
|
-
defaultAddressPath: 'm/0/0',
|
|
123
|
-
features,
|
|
124
|
-
getBalances,
|
|
125
|
-
getFee: ({ feeData }) => feeData.fee,
|
|
126
|
-
getFeeAsync: async ({ feeData }) => feeData.fee,
|
|
127
|
-
getFeeData: () => feeData,
|
|
128
|
-
getKeyIdentifier: createGetKeyIdentifier({ bip44 }),
|
|
129
|
-
getTokens: () =>
|
|
130
|
-
Object.values(assets)
|
|
131
|
-
.filter((asset) => asset.name !== base.name)
|
|
132
|
-
.map(createToken),
|
|
133
|
-
getUnstakingFee,
|
|
134
|
-
hasFeature: (feature) => !!features[feature], // @deprecated use api.features instead
|
|
135
|
-
parseUnsignedTx,
|
|
136
|
-
parseTx: ({ unsignedTx }) => parseUnsignedTx(unsignedTx),
|
|
137
|
-
sendTx,
|
|
138
|
-
signTx: ({ unsignedTx, privateKey }) => signUnsignedTx(unsignedTx, privateKey),
|
|
139
|
-
signUnsignedTx,
|
|
140
|
-
signHardware,
|
|
141
|
-
staking: assetStakingApi,
|
|
142
|
-
validateAssetId: isValidAddress,
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const fullAsset = {
|
|
146
|
-
...base,
|
|
147
|
-
address,
|
|
148
|
-
keys,
|
|
149
|
-
api,
|
|
150
|
-
bip44,
|
|
151
|
-
accountReserve,
|
|
152
|
-
lowBalance,
|
|
153
|
-
MIN_STAKING_AMOUNT,
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return overrideCallback({ asset: fullAsset })
|
|
157
|
-
}
|
|
8
|
+
const createAsset = createSolanaAssetFactory({ assetList, serverApi })
|
|
158
9
|
|
|
159
10
|
const defaultExport = { createAsset }
|
|
11
|
+
|
|
160
12
|
export default defaultExport
|