feat: register status ens usernames

This commit is contained in:
Richard Ramos 2020-08-27 12:06:53 -04:00 committed by Iuri Matias
parent 1d0e4fe2cf
commit 8f1f01b6a0
7 changed files with 175 additions and 20 deletions

View File

@ -8,9 +8,10 @@ import ../../../status/threads
import ../../../status/ens as status_ens import ../../../status/ens as status_ens
import ../../../status/libstatus/wallet as status_wallet import ../../../status/libstatus/wallet as status_wallet
import ../../../status/libstatus/settings as status_settings import ../../../status/libstatus/settings as status_settings
import ../../../status/libstatus/utils as utils import ../../../status/libstatus/utils as libstatus_utils
import ../../../status/libstatus/tokens as tokens import ../../../status/libstatus/tokens as tokens
import ../../../status/status import ../../../status/status
from eth/common/utils import parseAddress
type type
EnsRoles {.pure.} = enum EnsRoles {.pure.} = enum
@ -135,10 +136,17 @@ QtObject:
}.toTable }.toTable
proc getPrice(self: EnsManager): string {.slot.} = proc getPrice(self: EnsManager): string {.slot.} =
result = utils.wei2Eth(getPrice()) result = libstatus_utils.wei2Eth(getPrice())
proc getUsernameRegistrar(self: EnsManager): string {.slot.} = proc getUsernameRegistrar(self: EnsManager): string {.slot.} =
result = statusRegistrarAddress() result = statusRegistrarAddress()
proc getENSRegistry(self: EnsManager): string {.slot.} = proc getENSRegistry(self: EnsManager): string {.slot.} =
result = registry result = registry
proc registerENS(self: EnsManager, username: string, password: string) {.slot.} =
let pubKey = status_settings.getSetting[string](Setting.PublicKey, "0x0")
let address = parseAddress(status_wallet.getWalletAccounts()[0].address)
discard registerUsername(username & status_ens.domain, address, pubKey, password)
self.connect(username, true)

View File

@ -133,19 +133,23 @@ proc getPrice*(): Stuint[256] =
raise newException(RpcException, "Error getting ens username price: 0x") raise newException(RpcException, "Error getting ens username price: 0x")
result = fromHex(Stuint[256], response.result) result = fromHex(Stuint[256], response.result)
proc registerUsername*(username:string, address: EthAddress, pubKey: string, price: Stuint[256], password: string): string = proc extractCoordinates*(pubkey: string):tuple[x: string, y:string] =
let label = fromHex(FixedBytes[32], namehash(addDomain(username))) result = ("0x" & pubkey[4..67], "0x" & pubkey[68..131])
let x = fromHex(FixedBytes[32], "0x" & pubkey[4..67])
let y = fromHex(FixedBytes[32], "0x" & pubkey[68..131]) proc registerUsername*(username:string, address: EthAddress, pubKey: string, password: string): string =
let let
label = fromHex(FixedBytes[32], namehash(addDomain(username)))
coordinates = extractCoordinates(pubkey)
x = fromHex(FixedBytes[32], coordinates.x)
y = fromHex(FixedBytes[32], coordinates.y)
ensUsernamesContract = contracts.getContract("ens-usernames") ensUsernamesContract = contracts.getContract("ens-usernames")
sntContract = contracts.getContract("snt") sntContract = contracts.getContract("snt")
price = getPrice() price = getPrice()
register = Register(label: label, account: address, x: x, y: y)
registerAbiEncoded = ensUsernamesContract.methods["register"].encodeAbi(register)
let let
approveAndCallObj = ApproveAndCall(to: ensUsernamesContract.address, value: price, data: DynamicBytes[136].fromHex(registerAbiEncoded)) register = Register(label: label, account: address, x: x, y: y)
registerAbiEncoded = ensUsernamesContract.methods["register"].encodeAbi(register)
approveAndCallObj = ApproveAndCall(to: ensUsernamesContract.address, value: price, data: DynamicBytes[132].fromHex(registerAbiEncoded))
approveAndCallAbiEncoded = sntContract.methods["approveAndCall"].encodeAbi(approveAndCallObj) approveAndCallAbiEncoded = sntContract.methods["approveAndCall"].encodeAbi(approveAndCallObj)
let payload = %* { let payload = %* {
@ -154,12 +158,11 @@ proc registerUsername*(username:string, address: EthAddress, pubKey: string, pri
# "gas": 200000, # TODO: obtain gas price? # "gas": 200000, # TODO: obtain gas price?
"data": approveAndCallAbiEncoded "data": approveAndCallAbiEncoded
} }
let responseStr = sendTransaction($payload, password) let responseStr = sendTransaction($payload, password)
let response = Json.decode(responseStr, RpcResponse) let response = Json.decode(responseStr, RpcResponse)
if not response.error.isNil: if not response.error.isNil:
raise newException(RpcException, "Error registering ens-username: " & response.error.message) raise newException(RpcException, "Error registering ens-username: " & response.error.message)
result = response.result # should be a tx receipt result = response.result
proc statusRegistrarAddress*():string = proc statusRegistrarAddress*():string =
result = $contracts.getContract("ens-usernames").address result = $contracts.getContract("ens-usernames").address

View File

@ -36,7 +36,7 @@ type
ApproveAndCall* = object ApproveAndCall* = object
to*: EthAddress to*: EthAddress
value*: Stuint[256] value*: Stuint[256]
data*: DynamicBytes[136] data*: DynamicBytes[132]
Transfer* = object Transfer* = object
to*: EthAddress to*: EthAddress

View File

@ -134,7 +134,7 @@ proc buyPack*(packId: Stuint[256], address: EthAddress, price: Stuint[256], pass
buyToken = BuyToken(packId: packId, address: address, price: price) buyToken = BuyToken(packId: packId, address: address, price: price)
buyTxAbiEncoded = stickerMktContract.methods["buyToken"].encodeAbi(buyToken) buyTxAbiEncoded = stickerMktContract.methods["buyToken"].encodeAbi(buyToken)
let let
approveAndCallObj = ApproveAndCall(to: stickerMktContract.address, value: price, data: DynamicBytes[136].fromHex(buyTxAbiEncoded)) approveAndCallObj = ApproveAndCall(to: stickerMktContract.address, value: price, data: DynamicBytes[132].fromHex(buyTxAbiEncoded))
approveAndCallAbiEncoded = sntContract.methods["approveAndCall"].encodeAbi(approveAndCallObj) approveAndCallAbiEncoded = sntContract.methods["approveAndCall"].encodeAbi(approveAndCallObj)
let payload = %* { let payload = %* {
"from": $address, "from": $address,

View File

@ -0,0 +1,92 @@
import QtQuick 2.14
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.14
import "../../../../../imports"
import "../../../../../shared"
Item {
property string ensUsername: ""
signal okBtnClicked()
StyledText {
id: sectionTitle
//% "ENS usernames"
text: qsTrId("ens-usernames")
anchors.left: parent.left
anchors.leftMargin: Style.current.bigPadding
anchors.top: parent.top
anchors.topMargin: Style.current.bigPadding
font.weight: Font.Bold
font.pixelSize: 20
}
Rectangle {
id: circle
anchors.top: sectionTitle.bottom
anchors.topMargin: Style.current.bigPadding
anchors.horizontalCenter: parent.horizontalCenter
width: 60
height: 60
radius: 120
color: Style.current.blue
StyledText {
text: "✓"
opacity: 0.7
font.weight: Font.Bold
font.pixelSize: 18
color: Style.current.white
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
StyledText {
id: title
text: qsTr("Username added")
anchors.top: circle.bottom
anchors.topMargin: Style.current.bigPadding
font.weight: Font.Bold
font.pixelSize: 24
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
StyledText {
id: subtitle
text: qsTr("Nice! You own %1.stateofus.eth once the transaction is complete.").arg(ensUsername)
anchors.top: title.bottom
anchors.topMargin: 24
font.pixelSize: 14
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
StyledText {
id: progress
text: qsTr("You can follow the progress in the Transaction History section of your wallet.")
anchors.top: subtitle.bottom
anchors.topMargin: 24
font.pixelSize: 12
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
color: Style.current.secondaryText
}
StyledButton {
id: startBtn
anchors.top: progress.bottom
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
label: qsTr("Ok, got it")
onClicked: okBtnClicked()
}
}

View File

@ -5,11 +5,10 @@ import "../../../../../imports"
import "../../../../../shared" import "../../../../../shared"
Item { Item {
property var onClick: function(){}
property string username: "" property string username: ""
signal backBtnClicked(); signal backBtnClicked();
signal usernameRegistered(userName: string);
StyledText { StyledText {
id: sectionTitle id: sectionTitle
@ -23,6 +22,35 @@ Item {
font.pixelSize: 20 font.pixelSize: 20
} }
ModalPopup {
id: transactionDialog
title: qsTr("TODO: replace this for the transaction dialog")
Input {
id: passwd
placeholderText: "Password"
anchors.top: parent.textToCopy
anchors.topMargin: 24
anchors.left: parent.left
anchors.leftMargin: 24
}
StyledButton {
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
label: qsTr("Ok")
onClicked: {
profileModel.ens.registerENS(username, passwd.text)
passwd.text = "";
usernameRegistered(username);
transactionDialog.close();
}
}
}
ModalPopup { ModalPopup {
id: popup id: popup
title: qsTr("Terms of name registration") title: qsTr("Terms of name registration")
@ -292,8 +320,8 @@ Item {
anchors.bottomMargin: Style.current.padding anchors.bottomMargin: Style.current.padding
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Style.current.padding anchors.rightMargin: Style.current.padding
label: parseFloat(walletModel.getSNTBalance()) < 10 ? qsTr("Not enough SNT") : qsTr("Ok") label: parseFloat(walletModel.getSNTBalance()) < 10 ? qsTr("Not enough SNT") : qsTr("Register")
disabled: parseFloat(walletModel.getSNTBalance()) < 10 || !termsAndConditionsCheckbox.checked disabled: parseFloat(walletModel.getSNTBalance()) < 10 || !termsAndConditionsCheckbox.checked
onClicked: onClick() onClicked: transactionDialog.open()
} }
} }

View File

@ -17,6 +17,7 @@ Item {
signal next(output: string) signal next(output: string)
signal back() signal back()
signal done(ensUsername: string)
signal connect(ensUsername: string) signal connect(ensUsername: string)
signal goToWelcome(); signal goToWelcome();
@ -149,6 +150,23 @@ Item {
targetState: listState targetState: listState
signal: back signal: back
} }
DSM.SignalTransition {
targetState: listState
signal: back
}
DSM.SignalTransition {
targetState: ensRegisteredState
signal: done
}
}
DSM.State {
id: ensRegisteredState
onEntered:loader.sourceComponent = ensRegistered
DSM.SignalTransition {
targetState: listState
signal: next
}
} }
} }
@ -182,10 +200,8 @@ Item {
id: termsAndConditions id: termsAndConditions
TermsAndConditions { TermsAndConditions {
username: selectedUsername username: selectedUsername
onClick: function(output){
next(output);
}
onBackBtnClicked: back(); onBackBtnClicked: back();
onUsernameRegistered: done(userName);
} }
} }
@ -196,6 +212,14 @@ Item {
} }
} }
Component {
id: ensRegistered
ENSRegistered {
ensUsername: selectedUsername
onOkBtnClicked: next(null)
}
}
Component { Component {
id: list id: list
List { List {