-
-
Notifications
You must be signed in to change notification settings - Fork 650
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
Shepherd MVP Integration #1413
Shepherd MVP Integration #1413
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's working great for me, saw some instances of a node failing but the call still went through by re-requesting from another node. Just dropped a few comments in code, but I'm happy to approve if they don't seem worth addressing.
Just a couple of other things I noticed though, were some console logs. Looks like shepherd is doing a lot of logging that it should probably not do unless configured to do so in someway. Likewise, I got some errors about a socket not being able to connect. Is that also related to shepherd?
@@ -343,6 +341,7 @@ class CustomNodeModal extends React.Component<Props, State> { | |||
|
|||
private saveAndAdd = () => { | |||
const node = this.makeCustomNodeConfigFromState(); | |||
shepherd.useProvider('myccustom', node.id, makeProviderConfig({ network: node.network }), node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be happening at the saga layer? This seems like something that could get out of sync with redux, and might not belong in the component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shepherd handles these race conditions internally, useProvider is considered a synchronous method from the caller's view
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I wasn't clear, I wasn't worried about asynchronosity, I just thought this was a little too much logic for a component to implement. If there's ever another different component or process that can add custom nodes (e.g. pulling in a node from the URL) they would have to implement this as well. I figured this might be better off in a saga.
common/libs/nodes/index.ts
Outdated
import { shepherd, redux } from 'myc-shepherd'; | ||
import { INode } from '.'; | ||
import { tokenBalanceHandler } from './tokenBalanceProxy'; | ||
import { IProviderConfig } from 'myc-shepherd/dist/lib/ducks/providerConfigs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to get types from an myc-shepherd/index.d.ts
file instead so that we don't need to specify paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently waiting on this to be resolved so that works: MyCryptoHQ/shepherd#44
export const tokenBalanceHandler: ProxyHandler<any> = { | ||
get(target, propKey) { | ||
const tokenBalanceShim = (address: string, token: Token) => { | ||
const sendCallRequest: (...rpcArgs: any[]) => Promise<string> = Reflect.get( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the value in doing Reflect.get
over just target.sendCallRequest
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing really, just is more specific semantics wise
import { TokenValue } from 'libs/units'; | ||
|
||
export const tokenBalanceHandler: ProxyHandler<any> = { | ||
get(target, propKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be typed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, ill add the type to proxyhandler
.then(result => ({ balance: TokenValue(result), error: null })) | ||
.catch(err => ({ | ||
balance: TokenValue('0'), | ||
error: 'Caught error:' + err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Err could be an object so it may not work with addition like this. Prefer Caught error: ${err}
so that it properly stringifies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied over from our old code, ill change it though
@@ -34,6 +108,13 @@ export function* unsetWeb3NodeOnWalletEvent(action: SetWalletAction): SagaIterat | |||
return; | |||
} | |||
|
|||
const network: NetworkConfig = yield select(getNetworkConfig); | |||
|
|||
if (getShepherdManualMode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any harm in calling shepherd.auto
even if it's not in manual? Seems like it would reduce some amount of boilerplate in checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switching networks is disabled in shepherd if you're in manual mode, since manual mode implies that everything is overridden
common/selectors/config/nodes.ts
Outdated
const isWeb3Node = (nodeId: string, _: StaticNodeConfig | Web3NodeConfig): _ is Web3NodeConfig => | ||
nodeId === 'web3'; | ||
export const getWeb3Node = (state: AppState): StaticNodeConfig | null => { | ||
const isWeb3Node = (nodeId: string, _: StaticNodeConfig) => nodeId === 'web3'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to specify second param if it's not used anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
shared/types/node.d.ts
Outdated
UBQ = 'ubq', | ||
EXP_AUTO = 'exp_auto', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need all of these extra autos, if they only have the one node?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so that when custom nodes get added with the same network, the user will also have the option to balance between them
webpack_config/makeConfig.js
Outdated
new HardSourceWebpackPlugin({ | ||
environmentHash: { | ||
root: process.cwd(), | ||
directories: ['webpack_config'], | ||
files: ['package.json'] | ||
} | ||
}), | ||
}),*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was this removed for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad ill revert this, it was breaking my builds
} else { | ||
shepherd.manual(savedNodeId, false); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might do well to implement something in here that sets users to auto who have previously loaded the beta. I was defaulted to the MyCrypto node, because I had a stored config already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should first implement a versioning spec for local storage so we can properly invalidate data for situations like this. Since this case pops up often enough to warrant it imo
configuredStore.getState(); | ||
|
||
const expectedInitialState = { | ||
eth_mycrypto: { | ||
network: 'ETH', | ||
isCustom: false, | ||
lib: new RPCNode('https://api.mycryptoapi.com/eth'), | ||
lib: {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we refactor to just remove lib
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirming it all works great, including with a custom node.
Depends on #1456 since shepherd package uses new types introduced in TS 2.8.1 for its published types
Closes #1419
Closes #1309
Closes #1293
This current iteration of shepherd MVP is at feature parity with the current mycrypto beta.
Notable codebase changes:
The remaining TODO's do not effect the functionality of the product compared to pre-shepherd.
TODO:
How to monitor the balancer:
Clone the shepherd repo and install dependencies
Run mycrypto app and open page
Run
npm run remotedev
inside repoOpen
remote
mode onredux-dev-tools
Point to
localhost
port8000