feat: use ens API
This commit is contained in:
parent
1049b37c49
commit
b507813587
226
status/ens.nim
226
status/ens.nim
|
@ -15,6 +15,8 @@ import ./statusgo_backend/eth as eth
|
||||||
import ./statusgo_backend/wallet
|
import ./statusgo_backend/wallet
|
||||||
import ./statusgo_backend/accounts as status_accounts
|
import ./statusgo_backend/accounts as status_accounts
|
||||||
import ./statusgo_backend/settings as status_settings
|
import ./statusgo_backend/settings as status_settings
|
||||||
|
import ./statusgo_backend_new/ens as status_ens
|
||||||
|
|
||||||
import ./types/[transaction, setting, rpc_response, network_type, network, profile]
|
import ./types/[transaction, setting, rpc_response, network_type, network, profile]
|
||||||
import ./utils
|
import ./utils
|
||||||
import ./transactions
|
import ./transactions
|
||||||
|
@ -49,6 +51,45 @@ proc userNameOrAlias*(contact: Profile, removeSuffix: bool = false): string =
|
||||||
else:
|
else:
|
||||||
result = contact.alias
|
result = contact.alias
|
||||||
|
|
||||||
|
proc resolver*(username: string): string =
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.resolver(chainId, username)
|
||||||
|
return res.result.getStr
|
||||||
|
|
||||||
|
proc owner*(username: string): string =
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.ownerOf(chainId, username)
|
||||||
|
let address = res.result.getStr
|
||||||
|
if address == "0x0000000000000000000000000000000000000000":
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return address
|
||||||
|
|
||||||
|
proc pubkey*(username: string): string =
|
||||||
|
try:
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.publicKeyOf(chainId, addDomain(username))
|
||||||
|
var key = res.result.getStr
|
||||||
|
key.removePrefix("0x")
|
||||||
|
return "0x04" & key
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
proc address*(username: string): string =
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.addressOf(chainId, username)
|
||||||
|
return res.result.getStr
|
||||||
|
|
||||||
|
proc contenthash*(username: string): string =
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.contentHash(chainId, username)
|
||||||
|
return res.result.getStr
|
||||||
|
|
||||||
|
proc getPrice*(): Stuint[256] =
|
||||||
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
|
let res = status_ens.price(chainId)
|
||||||
|
return fromHex(Stuint[256], res.result.getStr)
|
||||||
|
|
||||||
proc label*(username:string): string =
|
proc label*(username:string): string =
|
||||||
var node:array[32, byte] = keccak_256.digest(username.toLower()).data
|
var node:array[32, byte] = keccak_256.digest(username.toLower()).data
|
||||||
result = "0x" & node.toHex()
|
result = "0x" & node.toHex()
|
||||||
|
@ -68,110 +109,6 @@ proc namehash*(ensName:string): string =
|
||||||
|
|
||||||
result = "0x" & node.toHex()
|
result = "0x" & node.toHex()
|
||||||
|
|
||||||
const registry* = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
|
|
||||||
const resolver_signature = "0x0178b8bf"
|
|
||||||
proc resolver*(usernameHash: string): string =
|
|
||||||
let payload = %* [{
|
|
||||||
"to": registry,
|
|
||||||
"from": "0x0000000000000000000000000000000000000000",
|
|
||||||
"data": fmt"{resolver_signature}{userNameHash}"
|
|
||||||
}, "latest"]
|
|
||||||
let response = eth.call(payload)
|
|
||||||
# TODO: error handling
|
|
||||||
var resolverAddr = response.result
|
|
||||||
resolverAddr.removePrefix("0x000000000000000000000000")
|
|
||||||
result = "0x" & resolverAddr
|
|
||||||
|
|
||||||
const owner_signature = "0x02571be3" # owner(bytes32 node)
|
|
||||||
proc owner*(username: string): string =
|
|
||||||
var userNameHash = namehash(addDomain(username))
|
|
||||||
userNameHash.removePrefix("0x")
|
|
||||||
let payload = %* [{
|
|
||||||
"to": registry,
|
|
||||||
"from": "0x0000000000000000000000000000000000000000",
|
|
||||||
"data": fmt"{owner_signature}{userNameHash}"
|
|
||||||
}, "latest"]
|
|
||||||
let response = eth.call(payload)
|
|
||||||
# TODO: error handling
|
|
||||||
let ownerAddr = response.result
|
|
||||||
if ownerAddr == "0x0000000000000000000000000000000000000000000000000000000000000000":
|
|
||||||
return ""
|
|
||||||
result = "0x" & ownerAddr.substr(26)
|
|
||||||
|
|
||||||
const pubkey_signature = "0xc8690233" # pubkey(bytes32 node)
|
|
||||||
proc pubkey*(username: string): string =
|
|
||||||
var userNameHash = namehash(addDomain(username))
|
|
||||||
userNameHash.removePrefix("0x")
|
|
||||||
let ensResolver = resolver(userNameHash)
|
|
||||||
let payload = %* [{
|
|
||||||
"to": ensResolver,
|
|
||||||
"from": "0x0000000000000000000000000000000000000000",
|
|
||||||
"data": fmt"{pubkey_signature}{userNameHash}"
|
|
||||||
}, "latest"]
|
|
||||||
let response = eth.call(payload)
|
|
||||||
# TODO: error handling
|
|
||||||
var pubkey = response.result
|
|
||||||
if pubkey == "0x" or pubkey == "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":
|
|
||||||
result = ""
|
|
||||||
else:
|
|
||||||
pubkey.removePrefix("0x")
|
|
||||||
result = "0x04" & pubkey
|
|
||||||
|
|
||||||
const address_signature = "0x3b3b57de" # addr(bytes32 node)
|
|
||||||
proc address*(username: string): string =
|
|
||||||
var userNameHash = namehash(addDomain(username))
|
|
||||||
userNameHash.removePrefix("0x")
|
|
||||||
let ensResolver = resolver(userNameHash)
|
|
||||||
let payload = %* [{
|
|
||||||
"to": ensResolver,
|
|
||||||
"from": "0x0000000000000000000000000000000000000000",
|
|
||||||
"data": fmt"{address_signature}{userNameHash}"
|
|
||||||
}, "latest"]
|
|
||||||
let response = eth.call(payload)
|
|
||||||
# TODO: error handling
|
|
||||||
let address = response.result
|
|
||||||
if address == "0x0000000000000000000000000000000000000000000000000000000000000000":
|
|
||||||
return ""
|
|
||||||
result = "0x" & address.substr(26)
|
|
||||||
|
|
||||||
const contenthash_signature = "0xbc1c58d1" # contenthash(bytes32)
|
|
||||||
proc contenthash*(ensAddr: string): string =
|
|
||||||
var ensHash = namehash(ensAddr)
|
|
||||||
ensHash.removePrefix("0x")
|
|
||||||
let ensResolver = resolver(ensHash)
|
|
||||||
let payload = %* [{
|
|
||||||
"to": ensResolver,
|
|
||||||
"from": "0x0000000000000000000000000000000000000000",
|
|
||||||
"data": fmt"{contenthash_signature}{ensHash}"
|
|
||||||
}, "latest"]
|
|
||||||
|
|
||||||
let response = eth.call(payload)
|
|
||||||
let bytesResponse = response.result
|
|
||||||
if bytesResponse == "0x":
|
|
||||||
return ""
|
|
||||||
|
|
||||||
let size = fromHex(Stuint[256], bytesResponse[66..129]).truncate(int)
|
|
||||||
result = bytesResponse[130..129+size*2]
|
|
||||||
result = bytesResponse[130..129+size*2]
|
|
||||||
|
|
||||||
|
|
||||||
proc getPrice*(): Stuint[256] =
|
|
||||||
let
|
|
||||||
network = status_settings.getCurrentNetwork().toNetwork()
|
|
||||||
contract = contracts.findContract(network.chainId, "ens-usernames")
|
|
||||||
payload = %* [{
|
|
||||||
"to": $contract.address,
|
|
||||||
"data": contract.methods["getPrice"].encodeAbi()
|
|
||||||
}, "latest"]
|
|
||||||
|
|
||||||
let response = eth.call(payload)
|
|
||||||
if not response.error.isNil:
|
|
||||||
raise newException(RpcException, "Error getting ens username price: " & response.error.message)
|
|
||||||
if response.result == "0x":
|
|
||||||
raise newException(RpcException, "Error getting ens username price: 0x")
|
|
||||||
result = fromHex(Stuint[256], response.result)
|
|
||||||
result = fromHex(Stuint[256], response.result)
|
|
||||||
|
|
||||||
proc releaseEstimateGas*(username: string, address: string, success: var bool): int =
|
proc releaseEstimateGas*(username: string, address: string, success: var bool): int =
|
||||||
let
|
let
|
||||||
label = fromHex(FixedBytes[32], label(username))
|
label = fromHex(FixedBytes[32], label(username))
|
||||||
|
@ -184,8 +121,7 @@ proc releaseEstimateGas*(username: string, address: string, success: var bool):
|
||||||
let response = ensUsernamesContract.methods["release"].estimateGas(tx, release, success)
|
let response = ensUsernamesContract.methods["release"].estimateGas(tx, release, success)
|
||||||
if success:
|
if success:
|
||||||
result = fromHex[int](response)
|
result = fromHex[int](response)
|
||||||
except RpcException as e:
|
except rpc_response.RpcException as e:
|
||||||
error "Could not estimate gas for ens release", err=e.msg
|
|
||||||
error "Could not estimate gas for ens release", err=e.msg
|
error "Could not estimate gas for ens release", err=e.msg
|
||||||
|
|
||||||
proc release*(username: string, address: string, gas, gasPrice, password: string, success: var bool): string =
|
proc release*(username: string, address: string, gas, gasPrice, password: string, success: var bool): string =
|
||||||
|
@ -200,30 +136,13 @@ proc release*(username: string, address: string, gas, gasPrice, password: strin
|
||||||
result = ensUsernamesContract.methods["release"].send(tx, release, password, success)
|
result = ensUsernamesContract.methods["release"].send(tx, release, password, success)
|
||||||
if success:
|
if success:
|
||||||
trackPendingTransaction(result, address, $ensUsernamesContract.address, PendingTransactionType.ReleaseENS, username)
|
trackPendingTransaction(result, address, $ensUsernamesContract.address, PendingTransactionType.ReleaseENS, username)
|
||||||
except RpcException as e:
|
except rpc_response.RpcException as e:
|
||||||
error "Could not estimate gas for ens release", err=e.msg
|
error "Could not estimate gas for ens release", err=e.msg
|
||||||
|
|
||||||
|
|
||||||
proc getExpirationTime*(username: string, success: var bool): int =
|
proc getExpirationTime*(username: string, success: var bool): int =
|
||||||
let
|
let chainId = status_settings.getCurrentNetwork().toChainId()
|
||||||
label = fromHex(FixedBytes[32], label(username))
|
let res = status_ens.expireAt(chainId, username)
|
||||||
expTime = ExpirationTime(label: label)
|
return fromHex[int](res.result.getStr)
|
||||||
network = status_settings.getCurrentNetwork().toNetwork()
|
|
||||||
ensUsernamesContract = contracts.findContract(network.chainId, "ens-usernames")
|
|
||||||
|
|
||||||
var tx = transactions.buildTransaction(parseAddress("0x0000000000000000000000000000000000000000"), 0.u256)
|
|
||||||
tx.to = ensUsernamesContract.address.some
|
|
||||||
tx.data = ensUsernamesContract.methods["getExpirationTime"].encodeAbi(expTime)
|
|
||||||
var response = ""
|
|
||||||
try:
|
|
||||||
response = eth.call(tx).result
|
|
||||||
success = true
|
|
||||||
except RpcException as e:
|
|
||||||
success = false
|
|
||||||
error "Error obtaining expiration time", err=e.msg
|
|
||||||
|
|
||||||
if success:
|
|
||||||
result = fromHex[int](response)
|
|
||||||
|
|
||||||
proc extractCoordinates*(pubkey: string):tuple[x: string, y:string] =
|
proc extractCoordinates*(pubkey: string):tuple[x: string, y:string] =
|
||||||
result = ("0x" & pubkey[4..67], "0x" & pubkey[68..131])
|
result = ("0x" & pubkey[4..67], "0x" & pubkey[68..131])
|
||||||
|
@ -277,7 +196,6 @@ proc setPubKeyEstimateGas*(username: string, address: string, pubKey: string, su
|
||||||
var hash = namehash(username)
|
var hash = namehash(username)
|
||||||
hash.removePrefix("0x")
|
hash.removePrefix("0x")
|
||||||
|
|
||||||
|
|
||||||
let
|
let
|
||||||
label = fromHex(FixedBytes[32], "0x" & hash)
|
label = fromHex(FixedBytes[32], "0x" & hash)
|
||||||
x = fromHex(FixedBytes[32], "0x" & pubkey[4..67])
|
x = fromHex(FixedBytes[32], "0x" & pubkey[4..67])
|
||||||
|
@ -293,7 +211,7 @@ proc setPubKeyEstimateGas*(username: string, address: string, pubKey: string, su
|
||||||
let response = resolverContract.methods["setPubkey"].estimateGas(tx, setPubkey, success)
|
let response = resolverContract.methods["setPubkey"].estimateGas(tx, setPubkey, success)
|
||||||
if success:
|
if success:
|
||||||
result = fromHex[int](response)
|
result = fromHex[int](response)
|
||||||
except RpcException as e:
|
except rpc_response.RpcException as e:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
proc setPubKey*(username, pubKey, address, gas, gasPrice: string, isEIP1559Enabled: bool, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, success: var bool): string =
|
proc setPubKey*(username, pubKey, address, gas, gasPrice: string, isEIP1559Enabled: bool, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, success: var bool): string =
|
||||||
|
@ -315,7 +233,7 @@ proc setPubKey*(username, pubKey, address, gas, gasPrice: string, isEIP1559Enabl
|
||||||
result = resolverContract.methods["setPubkey"].send(tx, setPubkey, password, success)
|
result = resolverContract.methods["setPubkey"].send(tx, setPubkey, password, success)
|
||||||
if success:
|
if success:
|
||||||
trackPendingTransaction(result, $address, resolverAddress, PendingTransactionType.SetPubKey, username)
|
trackPendingTransaction(result, $address, resolverAddress, PendingTransactionType.SetPubKey, username)
|
||||||
except RpcException as e:
|
except rpc_response.RpcException as e:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
proc statusRegistrarAddress*():string =
|
proc statusRegistrarAddress*():string =
|
||||||
|
@ -325,54 +243,6 @@ proc statusRegistrarAddress*():string =
|
||||||
return $contract.address
|
return $contract.address
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
type
|
|
||||||
ENSType* {.pure.} = enum
|
|
||||||
IPFS,
|
|
||||||
SWARM,
|
|
||||||
IPNS,
|
|
||||||
UNKNOWN
|
|
||||||
|
|
||||||
proc decodeENSContentHash*(value: string): tuple[ensType: ENSType, output: string] =
|
|
||||||
if value == "":
|
|
||||||
return (ENSType.UNKNOWN, "")
|
|
||||||
|
|
||||||
if value[0..5] == "e40101":
|
|
||||||
return (ENSType.SWARM, value.split("1b20")[1])
|
|
||||||
|
|
||||||
if value[0..7] == "e3010170":
|
|
||||||
try:
|
|
||||||
let defaultCodec = parseHexInt("70") #dag-pb
|
|
||||||
var codec = defaultCodec # no codec specified
|
|
||||||
var codecStartIdx = 2 # idx of where codec would start if it was specified
|
|
||||||
# handle the case when starts with 0xe30170 instead of 0xe3010170
|
|
||||||
if value[2..5] == "0101":
|
|
||||||
codecStartIdx = 6
|
|
||||||
codec = parseHexInt(value[6..7])
|
|
||||||
elif value[2..3] == "01" and value[4..5] != "12":
|
|
||||||
codecStartIdx = 4
|
|
||||||
codec = parseHexInt(value[4..5])
|
|
||||||
|
|
||||||
# strip the info we no longer need
|
|
||||||
var multiHashStr = value[codecStartIdx + 2..<value.len]
|
|
||||||
|
|
||||||
# The rest of the hash identifies the multihash algo, length, and digest
|
|
||||||
# More info: https://multiformats.io/multihash/
|
|
||||||
# 12 = identifies sha2-256 hash
|
|
||||||
# 20 = multihash length = 32
|
|
||||||
# ...rest = multihash digest
|
|
||||||
let
|
|
||||||
multiHash = MultiHash.init(nimcrypto.fromHex(multiHashStr)).get()
|
|
||||||
decoded = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get()
|
|
||||||
return (ENSType.IPFS, $decoded)
|
|
||||||
except Exception as e:
|
|
||||||
error "Error decoding ENS contenthash", hash=value, exception=e.msg
|
|
||||||
raise
|
|
||||||
|
|
||||||
if value[0..8] == "e50101700":
|
|
||||||
return (ENSType.IPNS, parseHexStr(value[12..value.len-1]))
|
|
||||||
|
|
||||||
return (ENSType.UNKNOWN, "")
|
|
||||||
|
|
||||||
proc validateEnsName*(ens: string, isStatus: bool, usernames: seq[string]): string =
|
proc validateEnsName*(ens: string, isStatus: bool, usernames: seq[string]): string =
|
||||||
var username = ens & (if(isStatus): domain else: "")
|
var username = ens & (if(isStatus): domain else: "")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
import ens, wallet, permissions, utils
|
|
||||||
import ../eventemitter
|
|
||||||
import ./types/[setting, permission]
|
|
||||||
import utils
|
|
||||||
import statusgo_backend/accounts
|
|
||||||
import statusgo_backend/core
|
|
||||||
import statusgo_backend/settings as status_settings
|
|
||||||
import json, json_serialization, sets, strutils
|
|
||||||
import chronicles
|
|
||||||
import stew/byteutils
|
|
||||||
from stew/base32 import nil
|
|
||||||
from stew/base58 import nil
|
|
||||||
|
|
||||||
const HTTPS_SCHEME* = "https"
|
|
||||||
const IPFS_GATEWAY* = ".infura.status.im"
|
|
||||||
const SWARM_GATEWAY* = "swarm-gateways.net"
|
|
||||||
|
|
||||||
logScope:
|
|
||||||
topics = "provider-model"
|
|
||||||
|
|
||||||
type ProviderModel* = ref object
|
|
||||||
events*: EventEmitter
|
|
||||||
permissions*: PermissionsModel
|
|
||||||
wallet*: WalletModel
|
|
||||||
|
|
||||||
proc newProviderModel*(events: EventEmitter, permissions: PermissionsModel, wallet: WalletModel): ProviderModel =
|
|
||||||
result = ProviderModel()
|
|
||||||
result.events = events
|
|
||||||
result.permissions = permissions
|
|
||||||
result.wallet = wallet
|
|
||||||
|
|
||||||
proc ensResourceURL*(self: ProviderModel, ens: string, url: string):
|
|
||||||
(string, string, string, string, bool) =
|
|
||||||
|
|
||||||
let contentHash = contenthash(ens)
|
|
||||||
if contentHash == "": # ENS does not have a content hash
|
|
||||||
return (url, url, HTTPS_SCHEME, "", false)
|
|
||||||
|
|
||||||
let decodedHash = contentHash.decodeENSContentHash()
|
|
||||||
|
|
||||||
case decodedHash[0]:
|
|
||||||
of ENSType.IPFS:
|
|
||||||
let
|
|
||||||
base58bytes = base58.decode(base58.BTCBase58, decodedHash[1])
|
|
||||||
base32Hash = base32.encode(base32.Base32Lower, base58bytes)
|
|
||||||
|
|
||||||
result = (url, base32Hash & IPFS_GATEWAY, HTTPS_SCHEME, "", true)
|
|
||||||
|
|
||||||
of ENSType.SWARM:
|
|
||||||
result = (url, SWARM_GATEWAY, HTTPS_SCHEME,
|
|
||||||
"/bzz:/" & decodedHash[1] & "/", true)
|
|
||||||
|
|
||||||
of ENSType.IPNS:
|
|
||||||
result = (url, decodedHash[1], HTTPS_SCHEME, "", true)
|
|
||||||
|
|
||||||
else:
|
|
||||||
warn "Unknown content for", ens, contentHash
|
|
|
@ -24,7 +24,6 @@ proc callPrivateRPC*(methodName: string, payload = %* []): RpcResponse[JsonNode]
|
||||||
debug "NewBE_callPrivateRPC", rpc_method=methodName
|
debug "NewBE_callPrivateRPC", rpc_method=methodName
|
||||||
let rpcResponseRaw = status_go.callPrivateRPC($inputJSON)
|
let rpcResponseRaw = status_go.callPrivateRPC($inputJSON)
|
||||||
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
|
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
|
||||||
|
|
||||||
if(not result.error.isNil):
|
if(not result.error.isNil):
|
||||||
var err = "\nstatus-go error ["
|
var err = "\nstatus-go error ["
|
||||||
err &= fmt"methodName:{methodName}, "
|
err &= fmt"methodName:{methodName}, "
|
||||||
|
|
|
@ -3,20 +3,40 @@ import ./core, ./response_type
|
||||||
|
|
||||||
export response_type
|
export response_type
|
||||||
|
|
||||||
proc resolver*(username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc resolver*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
# TODO: Use a real chain id
|
let payload = %* [chainId, username]
|
||||||
let payload = %* [1, username]
|
|
||||||
|
|
||||||
return core.callPrivateRPC("ens_resolver", payload)
|
return core.callPrivateRPC("ens_resolver", payload)
|
||||||
|
|
||||||
proc contentHash*(username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc ownerOf*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
# TODO: Use a real chain id
|
let payload = %* [chainId, username]
|
||||||
let payload = %* [1, username]
|
|
||||||
|
return core.callPrivateRPC("ens_ownerOf", payload)
|
||||||
|
|
||||||
|
proc contentHash*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId, username]
|
||||||
|
|
||||||
return core.callPrivateRPC("ens_contentHash", payload)
|
return core.callPrivateRPC("ens_contentHash", payload)
|
||||||
|
|
||||||
proc resourceURL*(username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc publicKeyOf*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
# TODO: Use a real chain id
|
let payload = %* [chainId, username]
|
||||||
let payload = %* [1, username]
|
|
||||||
return core.callPrivateRPC("ens_resourceURL", payload)
|
|
||||||
|
|
||||||
|
return core.callPrivateRPC("ens_publicKeyOf", payload)
|
||||||
|
|
||||||
|
proc addressOf*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId, username]
|
||||||
|
|
||||||
|
return core.callPrivateRPC("ens_addressOf", payload)
|
||||||
|
|
||||||
|
proc expireAt*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId, username]
|
||||||
|
|
||||||
|
return core.callPrivateRPC("ens_expireAt", payload)
|
||||||
|
|
||||||
|
proc price*(chainId: int): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId]
|
||||||
|
return core.callPrivateRPC("ens_price", payload)
|
||||||
|
|
||||||
|
proc resourceURL*(chainId: int, username: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [chainId, username]
|
||||||
|
return core.callPrivateRPC("ens_resourceURL", payload)
|
|
@ -1,9 +1,10 @@
|
||||||
import ens, provider
|
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
from stew/base32 import nil
|
from stew/base32 import nil
|
||||||
from stew/base58 import nil
|
from stew/base58 import nil
|
||||||
|
import ./statusgo_backend_new/ens as status_ens
|
||||||
import chronicles, httpclient, net
|
import chronicles, httpclient, net
|
||||||
import strutils
|
import strutils
|
||||||
|
import json
|
||||||
import semver
|
import semver
|
||||||
import constants
|
import constants
|
||||||
|
|
||||||
|
@ -14,31 +15,12 @@ type
|
||||||
url*: string
|
url*: string
|
||||||
|
|
||||||
proc getLatestVersion*(): VersionInfo =
|
proc getLatestVersion*(): VersionInfo =
|
||||||
let contentHash = contenthash(APP_UPDATES_ENS)
|
let response = status_ens.resourceUrl(chainId=1, username=APP_UPDATES_ENS)
|
||||||
if contentHash == "":
|
let host = response.result{"Host"}.getStr
|
||||||
|
if host == "":
|
||||||
raise newException(ValueError, "ENS does not have a content hash")
|
raise newException(ValueError, "ENS does not have a content hash")
|
||||||
|
|
||||||
var url: string = ""
|
let url = "https://" & host & response.result{"Path"}.getStr
|
||||||
|
|
||||||
let decodedHash = contentHash.decodeENSContentHash()
|
|
||||||
|
|
||||||
case decodedHash[0]:
|
|
||||||
of ENSType.IPFS:
|
|
||||||
let
|
|
||||||
base58bytes = base58.decode(base58.BTCBase58, decodedHash[1])
|
|
||||||
base32Hash = base32.encode(base32.Base32Lower, base58bytes)
|
|
||||||
|
|
||||||
url = "https://" & base32Hash & IPFS_GATEWAY
|
|
||||||
|
|
||||||
of ENSType.SWARM:
|
|
||||||
url = "https://" & SWARM_GATEWAY & "/bzz:/" & decodedHash[1]
|
|
||||||
|
|
||||||
of ENSType.IPNS:
|
|
||||||
url = "https://" & decodedHash[1]
|
|
||||||
|
|
||||||
else:
|
|
||||||
warn "Unknown content for", contentHash
|
|
||||||
raise newException(ValueError, "Unknown content for " & contentHash)
|
|
||||||
|
|
||||||
# Read version from folder
|
# Read version from folder
|
||||||
let secureSSLContext = newContext()
|
let secureSSLContext = newContext()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5c6549360a2eeb1e6232591d9d13fbff99ca6b49
|
Subproject commit 5512e19d83c9693bbb043a8aa6b3386164213c46
|
Loading…
Reference in New Issue