{"action":"closed","issue":{"url":"https://api.github.com/repos/witnet/sheikah/issues/391","repository_url":"https://api.github.com/repos/witnet/sheikah","labels_url":"https://api.github.com/repos/witnet/sheikah/issues/391/labels{/name}","comments_url":"https://api.github.com/repos/witnet/sheikah/issues/391/comments","events_url":"https://api.github.com/repos/witnet/sheikah/issues/391/events","html_url":"https://github.com/witnet/sheikah/issues/391","id":352068687,"node_id":"MDU6SXNzdWUzNTIwNjg2ODc=","number":391,"title":"Implement `generateAddress` API handler","user":{"login":"aesedepece","id":1316439,"node_id":"MDQ6VXNlcjEzMTY0Mzk=","avatar_url":"https://avatars0.githubusercontent.com/u/1316439?v=4","gravatar_id":"","url":"https://api.github.com/users/aesedepece","html_url":"https://github.com/aesedepece","followers_url":"https://api.github.com/users/aesedepece/followers","following_url":"https://api.github.com/users/aesedepece/following{/other_user}","gists_url":"https://api.github.com/users/aesedepece/gists{/gist_id}","starred_url":"https://api.github.com/users/aesedepece/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aesedepece/subscriptions","organizations_url":"https://api.github.com/users/aesedepece/orgs","repos_url":"https://api.github.com/users/aesedepece/repos","events_url":"https://api.github.com/users/aesedepece/events{/privacy}","received_events_url":"https://api.github.com/users/aesedepece/received_events","type":"User","site_admin":false},"labels":[{"id":925513086,"node_id":"MDU6TGFiZWw5MjU1MTMwODY=","url":"https://api.github.com/repos/witnet/sheikah/labels/backend","name":"backend","color":"b7ff11","default":false},{"id":826724018,"node_id":"MDU6TGFiZWw4MjY3MjQwMTg=","url":"https://api.github.com/repos/witnet/sheikah/labels/enhancement%20%F0%9F%93%88","name":"enhancement 📈","color":"a2eeef","default":false}],"state":"closed","locked":false,"assignee":{"login":"anler","id":83847,"node_id":"MDQ6VXNlcjgzODQ3","avatar_url":"https://avatars0.githubusercontent.com/u/83847?v=4","gravatar_id":"","url":"https://api.github.com/users/anler","html_url":"https://github.com/anler","followers_url":"https://api.github.com/users/anler/followers","following_url":"https://api.github.com/users/anler/following{/other_user}","gists_url":"https://api.github.com/users/anler/gists{/gist_id}","starred_url":"https://api.github.com/users/anler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/anler/subscriptions","organizations_url":"https://api.github.com/users/anler/orgs","repos_url":"https://api.github.com/users/anler/repos","events_url":"https://api.github.com/users/anler/events{/privacy}","received_events_url":"https://api.github.com/users/anler/received_events","type":"User","site_admin":false},"assignees":[{"login":"anler","id":83847,"node_id":"MDQ6VXNlcjgzODQ3","avatar_url":"https://avatars0.githubusercontent.com/u/83847?v=4","gravatar_id":"","url":"https://api.github.com/users/anler","html_url":"https://github.com/anler","followers_url":"https://api.github.com/users/anler/followers","following_url":"https://api.github.com/users/anler/following{/other_user}","gists_url":"https://api.github.com/users/anler/gists{/gist_id}","starred_url":"https://api.github.com/users/anler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/anler/subscriptions","organizations_url":"https://api.github.com/users/anler/orgs","repos_url":"https://api.github.com/users/anler/repos","events_url":"https://api.github.com/users/anler/events{/privacy}","received_events_url":"https://api.github.com/users/anler/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/witnet/sheikah/milestones/12","html_url":"https://github.com/witnet/sheikah/milestone/12","labels_url":"https://api.github.com/repos/witnet/sheikah/milestones/12/labels","id":3549165,"node_id":"MDk6TWlsZXN0b25lMzU0OTE2NQ==","number":12,"title":"Sheikah Sprint #11","description":"The scope of Sprint no. 11 is to:\r\n- Complete the transaction listing\r\n- Complete the address generation and listing screen\r\n- Start the Attestations screen\r\n- Give the main screen a final polish","creator":{"login":"aesedepece","id":1316439,"node_id":"MDQ6VXNlcjEzMTY0Mzk=","avatar_url":"https://avatars0.githubusercontent.com/u/1316439?v=4","gravatar_id":"","url":"https://api.github.com/users/aesedepece","html_url":"https://github.com/aesedepece","followers_url":"https://api.github.com/users/aesedepece/followers","following_url":"https://api.github.com/users/aesedepece/following{/other_user}","gists_url":"https://api.github.com/users/aesedepece/gists{/gist_id}","starred_url":"https://api.github.com/users/aesedepece/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aesedepece/subscriptions","organizations_url":"https://api.github.com/users/aesedepece/orgs","repos_url":"https://api.github.com/users/aesedepece/repos","events_url":"https://api.github.com/users/aesedepece/events{/privacy}","received_events_url":"https://api.github.com/users/aesedepece/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":4,"state":"open","created_at":"2018-08-06T13:53:24Z","updated_at":"2018-08-30T15:26:03Z","due_on":"2018-08-31T07:00:00Z","closed_at":null},"comments":3,"created_at":"2018-08-20T10:09:47Z","updated_at":"2018-08-30T15:26:03Z","closed_at":"2018-08-30T15:26:03Z","author_association":"MEMBER","body":"#### Motivation\r\nAs mentioned in #314, generation of new P2PKH addresses requires implementing a new `generateAddress` API handler.\r\n\r\nThis method will consume @kronolynx crypto library to generate new \"final keys\", calculate their addresses and return those to the client along the used key path.\r\n\r\nThis method does not allow choosing the entire key path but only the account index. It will check instead what's the index of the last final key and create the next one.\r\n\r\n#### Tasks\r\n_Someone tackling this issue shall:_\r\n1. Read and understand our documentation on [key derivation][hdwallets], [address formatting][addresses] and [slip32].\r\n2. Implement the `generateAddress` API handler. This will:\r\n2.1. Parse `params` as `GenerateAddressParams`. Throw `WRONG_PARAMS` otherwise.\r\n2.2. Check if there's an unlocked wallet. Throw `NO_UNLOCKED_WALLET` otherwise.\r\n2.3. Check if the account index does exist. Throw `WRONG_ACCOUNT` otherwise.\r\n2.4. Get the maximum final key index as `k` (`0` by default).\r\n2.5. If `label` is not set or length is `0`, set it to `Payment request #${k+1}`.\r\n2.6. Check that `amount`, if set, is a positive number (`>= 0`). Throw `NEGATIVE_AMOUNT` otherwise. _In the future, we'll also check for enough balance_.\r\n2.7. Check that `expires`, if set, falls in the range `[Date.now(), Date.now() + 31_536_000_000]`. Throw `PAST_EXPIRATION_DATE` or `TOO_FAR_EXPIRATION_DATE` accordingly.\r\n2.8. Create a new final key using keypath `m/3'/4919'/i'/0/k`, where `i` is the account index and `k` is the final key index.\r\n2.9. Store the final key in app state. Throw `WALLET_UPDATE_FAILURE` otherwise.\r\n2.10. Persist app state (write a copy of the wallet into wallet storage). Throw `WALLET_STORE_FAILURE` otherwise.\r\n2.11. Compute final key hash, trim to 20 bytes and encode using [slip32]. Throw `ADDRESS_ENCODING_FAILURE` otherwise.\r\n2.12. Return a `GenerateAddressSuccess` with the used KeyPath, address and creation date.\r\n3. Add a backend route for the `generateAddress` method in [routes.ts].\r\n4. Create pertinent tests for the handler.\r\n\r\n#### Deliverables\r\n_A potential PR closing this issue shall provide:_\r\n- A `generateAddress` handler that takes `GenerateAddressParams` as parameter and returns a `GenerateAddressSuccess` object.\r\n- A route for the `generateAddress` method in [routes.ts].\r\n- A test battery for the `generateAddress` handler.\r\n\r\n#### Type definitions\r\n```ts\r\ntype GenerateAddressParams = {\r\n  account: number // we can optionally refine this type to be a inside range [0, 4294967295],\r\n  label?: string,\r\n  amount?: number,\r\n  expirationDate?: number\r\n}\r\n\r\ntype GenerateAddressSuccess = {\r\n  kind: \"SUCCESS\",\r\n  keyPath: KeyPath,\r\n  address: string,\r\n  creationDate: number\r\n}\r\n```\r\n\r\n[routes.ts]: https://github.com/witnet/sheikah/blob/master/app/main/api/routes.ts\r\n[hdwallets]: https://github.com/aesedepece/WIPs/blob/wip-adansdpc-hdwallets/wip-adansdpc-hdwallets.md\r\n[addresses]: https://github.com/aesedepece/WIPs/blob/wip-adansdpc-addresses/wip-adansdpc-addresses.md\r\n[slip32]: https://github.com/witnet/ts-slip32"}}
{"actor":{"display_login":"mariocao"}}