Skip to content
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

major: HDKD feature #431

Merged
merged 213 commits into from
Nov 22, 2019
Merged

major: HDKD feature #431

merged 213 commits into from
Nov 22, 2019

Conversation

hanwencheng
Copy link
Contributor

@hanwencheng hanwencheng commented Oct 23, 2019

So I am thinking how to collaborate together with @goldsteinsveta on this issue, we may work and track on this branch and record the progress here.

Design

References to design: https://www.figma.com/file/4odbGhaJ3OTN2ZQb52uvIy/Signer_UI-2.0?node-id=1760%3A148

Data Schemas

The accountId with Ethereum saved into storage is now with Uppercase. But we still recognize QR code with lower case account.

const networks = [
  {
    name: 'kusama',
    genesisHash: "0xb28bd355a4cd1df46bc56a2949bce8feb84eebc864f1c3f1f77668bd3b6559b3",
    prefix: 2,
    decimals: 12,
    pathID: 'kusama',
    title: 'Kusama CC2',
    unit: 'KSM',
    color: '#e6007a',
    protocol: 'substrate'
  },
  {
    color: '#64A2F4',
    ethereumChainId: '1',
    secondaryColor: colors.card_bgSolid,
    title: 'Ethereum Frontier',
    protocol: 'ethereum'
  }
];


const identities = [
  {
    encryptedSeed: '{"cipher":"aes-128-ctr","cipherparams":{"iv":e872394210984322432423,"cipherText":"a352dfg3g4245..."}}',
    derivationPassword: ''
    //NOTICE: meta is a Map Object
    meta: {
      '//kusma//funding/1': {
        name: 'funding account1',
        accountId: "substrate:DwGa4E65nbGafaGirjMH5kXbtT7jHuAcSXHLLkTePnqw95p:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636",
        createdAt: 1571068850409,
        updatedAt: 1571078850509,
      },
      '//kusma//funding/2': {
        accountId: "substrate:EoXsgmP36WXkyCamoC9iHy7Gr2tZpEykz8rmFw3bAS1nArV:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636",
        name: 'funding account2',
        createdAt: 1571068850409,
        updatedAt: 1571078850509,
      },
      '1': {
        name: 'ethereum frontier account',
        accountId: "ethereum:0x06Fc73F6797Ed62f46A4E6A13dD9366C5f2725D7@42",
        createdAt: 1571068850409,
        updatedAt: 1571078850509,
      }
    },
    //NOTICE: accountIds is a Map Object
    accountIds: {
      'substrate:DwGa4E65nbGafaGirjMH5kXbtT7jHuAcSXHLLkTePnqw95p:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636': '//kusama//funding/1',
      'substrate:EoXsgmP36WXkyCamoC9iHy7Gr2tZpEykz8rmFw3bAS1nArV:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636': '//kusama//funding/2',
      'ethereum:0x06Fc73F6797Ed62f46A4E6A13dD9366C5f2725D7@42': '1',
    }
  },
  {
    encryptedSeed: '{"cipher":"aes-128-ctr","cipherparams":{"iv":f872394210984322432423,"cipherText":"sad12343fdcdxa..."}}',
    derivationPassword: ''
    //NOTICE: meta is a Map Object
    meta: {
      '//kusma//funding/1': {
        name: 'funding account1',
        accountId: "substrate:FJBQ3tv6w3qhYkhKWnxfdjPwhvCd879oUeQKt6u8bHyhqzX:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636",
        createdAt: 1571068850409,
        updatedAt: 1571078850509,
      },
    },
    //NOTICE: accountIds is a Map Object
    accountIds: {
      "substrate:FJBQ3tv6w3qhYkhKWnxfdjPwhvCd879oUeQKt6u8bHyhqzX:0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636": '//kusama//funding/1',
    }
  }
];

Seed Unlock Refractor

Also include the refactoring of unlocking logic, the setPin and unLock will become a function to call the Pin input screen like the following:

//create pin or recover pin
<Button
	title="Next"
	onPress={async () => {
		const pin = await setPin(navigation);
		//then navigate to other screen
	}}
/>

//sign with pin
<Button
	title="Sign"
	onPress={async () => {
		const seed = await unLock(navigation, data);
		//use the seed to sign data
	}}
/>

With new pin code input screen, the pin code input mode will be changed.
Also closes #311, closes #324, closes #448, closes #315 , closes #432 , closes #443, closes #404

Tested Cases

Manual

  • Sign extrinsics with Legacy Substrate account
  • Sign transaction with Legacy Ethereum account
  • Sign messages with Legacy Ethereum account
  • Sign extrinsics with New Substrate account
  • Sign transaction with New Ethereum account
  • Sign messages with New Ethereum account
  • Identity Creation
  • Ethereum keypairs creation
  • Path Derivation
  • Path deletion
  • Ethereum keypairs deletion
  • Renaming

Automat

  • E2E Android: yarn e2e:android
  • E2E iOS: yarn e2e:ios
  • Unit Jest: yarn test
  • Unit Rust yarn test-rust

Not 100% Sure Thing

dcd7477 : Reset preHash in cleanup() function in ScannerStore.

Problem Tracking

component/screen Name type creation styling data-binding
LegacyAccountList Screen
LegacyAccountBackupScreen Screen
IdenititesSwitch Component
IdentityNew (Include Recover) Screen
IdentityBackup Screen
IdentityPin Screen
IdentityManagement Screen
PathDerivation Screen
PathsList Screen
PathDetails Screen
PathManagement Screen
PathCard Component

@hanwencheng hanwencheng added this to the v4 HDKD milestone Oct 23, 2019
Copy link
Contributor

@Tbaut Tbaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review (will get back at it later today)

This looks awesome and work very very well, I've had a hard time finding bugs 🎉
tested:

  • ✔️ Migration from master to this branch with both ETH and Kusama dev accounts
  • ✔️ Sign and Tx on Eth kovan successful
  • ✔️ Multipart and extrinsics on Kusama dev successful

Found one problem, some nits, and general comments:

  • deleting an account doesn't require the pin
  • (nit) we hard-coded the word "extrinsic" although this doesn't apply to Etherrm: screenshot
  • (nit) Ethereum message signing should probably have some margin with the account card: screenshot

General feedback (not necessarily to be addressed in this PR):

  • Right now the structure is probably super clear in your mind. it'd be great to have a comment exlaining the structure like (this is nonsense, but just to get an idea)
IdentityMap = {
  ['//hard/path']: {
    "meta": {
      "name": "account name"
     }
   ...
  }
}
  • style in components clutter them and make them harder to read. I'd advice in the future to use global style variables.

e2e/e2eUtils.js Outdated Show resolved Hide resolved
e2e/e2eUtils.js Outdated Show resolved Hide resolved
data={identitiesToShow}
renderItem={renderNonSelectedIdentity}
keyExtractor={item => item.encryptedSeed}
style={{ paddingVertical: identities.length > 5 ? 8 : 0 }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and the same check >5 2 lines down) looks sketchy 👀
Why 5 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just talked with Sveta, 8 is the Height of the scroll container.
If there are more than 5 identities, the list will become scrollable.
there will be shadow to indicate that there's more and some other details.

So I think it is decide by the smallest screen, just checked on iPhone SE. Also tried on my big Android screen, there are more margin, but I think it is OK for now. We could programmatically change that as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to discuss it separately, I think that would need discussion multiple possibilities together with Sveta, I will open an issue later this afternoon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMG_0044

src/components/IdentitiesSwitch.js Outdated Show resolved Hide resolved
@hanwencheng
Copy link
Contributor Author

I have add the current data schema in the description, hope that helps!

And I also agree with group styling, for example, there are lots of uniform styling in TxDetails SignedTx MessageDetails SignedMessage. It would be make reading and editing easy if we extract them out into one commonStyles.js file. In project scope that would need a lot of work and I agree to put them into future PR.

Copy link
Contributor

@Tbaut Tbaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested again extensively (ETH and Kusama dev), multi-identity, recovering accounts as well, it just works.

🎉 💯

Copy link
Contributor

@pmespresso pmespresso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍻🍻🍻Many thanks, @goldsteinsveta @hanwencheng!

NetInfo.addEventListener(state => {
setIsConnected(state.isConnected);
});
return subscribe();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems this is missing an unsubscribe() on component unmount?

Copy link
Contributor

@Tbaut Tbaut Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this, but it's "just" a typo imho. It should be named unsubscribed, and this will be called when the component unmounts (because it's what the useEffect returns)

It was named this.unsubscribe previously

Copy link
Contributor Author

@hanwencheng hanwencheng Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is kind of strange because this subscribe directly return an unsubscribe function. Probably name it as unsubscribe.

Here I wrapped it in function so it may be different, I will just extract them out.

sample usage from NetInfo

// Subscribe
const unsubscribe = NetInfo.addEventListener(state => {
  console.log("Connection type", state.type);
  console.log("Is connected?", state.isConnected);
});

// Unsubscribe
unsubscribe();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how I'm used to see subscriptions. Polkadot-js api does the same. So to do things right we can rename it yes, but I think the logic is correct.

Copy link
Contributor

@pmespresso pmespresso Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, let's just refactor to save "future us" unnecessary confusion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now it is even cleaner:

	useEffect(
		() =>
			NetInfo.addEventListener(state => {
				setIsConnected(state.isConnected);
			}),
		[]
	);

src/components/Separator.js Outdated Show resolved Hide resolved
src/screens/AccountEdit.js Outdated Show resolved Hide resolved
src/screens/AccountNetworkChooser.js Outdated Show resolved Hide resolved
@goldsteinsveta goldsteinsveta merged commit 4c86d8c into master Nov 22, 2019
@hanwencheng hanwencheng deleted the sveta-hanwen-hdkd branch November 22, 2019 15:03
@hanwencheng
Copy link
Contributor Author

YJ also approved the PR with today's chat

@pmespresso
Copy link
Contributor

pmespresso commented Nov 22, 2019

indeed 💃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants