Refactor/libstatus stickers (#24)
* move decodeContentHash from libstatus to utils * refactor stickers; move logic from libstatus back to status-lib; abstract eth_call
This commit is contained in:
parent
b3968bfc67
commit
132df2b5b4
|
@ -1,8 +1,5 @@
|
|||
import
|
||||
json
|
||||
|
||||
import
|
||||
json_serialization, chronicles, web3/ethtypes
|
||||
json, json_serialization, chronicles, web3/ethtypes
|
||||
|
||||
import
|
||||
../libstatus/core, ../types/[rpc_response, transaction], ../libstatus/conversions
|
||||
|
@ -27,4 +24,10 @@ proc call*(tx: TransactionData): RpcResponse =
|
|||
let responseStr = core.callPrivateRPC("eth_call", %*[%tx, "latest"])
|
||||
result = Json.decode(responseStr, RpcResponse)
|
||||
if not result.error.isNil:
|
||||
raise newException(RpcException, "Error calling method: " & result.error.message)
|
||||
raise newException(RpcException, "Error calling method: " & result.error.message)
|
||||
|
||||
proc eth_call*(payload = %* []): RpcResponse =
|
||||
let responseStr = core.callPrivateRPC("eth_call", payload)
|
||||
result = Json.decode(responseStr, RpcResponse)
|
||||
if not result.error.isNil:
|
||||
raise newException(RpcException, "Error calling method: " & result.error.message)
|
||||
|
|
|
@ -5,13 +5,13 @@ import # project deps
|
|||
chronicles, web3/[ethtypes, conversions], stint
|
||||
|
||||
import # local deps
|
||||
utils as status_utils,
|
||||
eth/contracts as status_contracts,
|
||||
libstatus/stickers as status_stickers, transactions,
|
||||
stickers_backend as status_stickers, transactions,
|
||||
libstatus/wallet, ../eventemitter
|
||||
import ./types/[sticker, transaction, rpc_response]
|
||||
from utils as libstatus_utils import eth2Wei, gwei2Wei, toUInt64, parseAddress
|
||||
|
||||
|
||||
logScope:
|
||||
topics = "stickers-model"
|
||||
|
||||
|
@ -143,7 +143,7 @@ proc addStickerToRecent*(self: StickersModel, sticker: Sticker, save: bool = fal
|
|||
status_stickers.saveRecentStickers(self.recentStickers)
|
||||
|
||||
proc decodeContentHash*(value: string): string =
|
||||
result = status_stickers.decodeContentHash(value)
|
||||
result = status_utils.decodeContentHash(value)
|
||||
|
||||
proc getPackIdFromTokenId*(tokenId: Stuint[256]): int =
|
||||
result = status_stickers.getPackIdFromTokenId(tokenId)
|
||||
|
|
|
@ -1,64 +1,20 @@
|
|||
# used to be libstatus, should be merged with stickers
|
||||
|
||||
import # std libs
|
||||
atomics, json, tables, sequtils, httpclient, net
|
||||
atomics, json, tables, sequtils, httpclient, net,
|
||||
json, json_serialization, chronicles, web3/ethtypes,
|
||||
stint, strutils
|
||||
from strutils import parseHexInt, parseInt
|
||||
|
||||
import nbaser
|
||||
|
||||
import # vendor libs
|
||||
json_serialization, chronicles, libp2p/[multihash, multicodec, cid], stint,
|
||||
web3/[ethtypes, conversions]
|
||||
from nimcrypto import fromHex
|
||||
|
||||
import # status-desktop libs
|
||||
./core as status, ../types/[sticker, setting, rpc_response],
|
||||
../eth/contracts, ./settings, ./edn_helpers
|
||||
|
||||
proc decodeContentHash*(value: string): string =
|
||||
if value == "":
|
||||
return ""
|
||||
|
||||
# eg encoded sticker multihash cid:
|
||||
# e30101701220eab9a8ef4eac6c3e5836a3768d8e04935c10c67d9a700436a0e53199e9b64d29
|
||||
# e3017012205c531b83da9dd91529a4cf8ecd01cb62c399139e6f767e397d2f038b820c139f (testnet)
|
||||
# e3011220c04c617170b1f5725070428c01280b4c19ae9083b7e6d71b7a0d2a1b5ae3ce30 (testnet)
|
||||
#
|
||||
# The first 4 bytes (in hex) represent:
|
||||
# e3 = codec identifier "ipfs-ns" for content-hash
|
||||
# 01 = unused - sometimes this is NOT included (ie ropsten)
|
||||
# 01 = CID version (effectively unused, as we will decode with CIDv0 regardless)
|
||||
# 70 = codec identifier "dag-pb"
|
||||
|
||||
# ipfs-ns
|
||||
if value[0..1] != "e3":
|
||||
warn "Could not decode sticker. It may still be valid, but requires a different codec to be used", hash=value
|
||||
return ""
|
||||
|
||||
try:
|
||||
# dag-pb
|
||||
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()
|
||||
let resultTyped = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get()
|
||||
result = $resultTyped
|
||||
trace "Decoded sticker hash", cid=result
|
||||
except Exception as e:
|
||||
error "Error decoding sticker", hash=value, exception=e.msg
|
||||
raise
|
||||
./eth/transactions as transactions, types/[sticker, setting, rpc_response],
|
||||
eth/contracts, ./libstatus/settings, ./libstatus/edn_helpers, utils
|
||||
|
||||
# Retrieves number of sticker packs owned by user
|
||||
# See https://notes.status.im/Q-sQmQbpTOOWCQcYiXtf5g#Read-Sticker-Packs-owned-by-a-user
|
||||
|
@ -74,8 +30,8 @@ proc getBalance*(address: Address): int =
|
|||
"data": contract.methods["balanceOf"].encodeAbi(balanceOf)
|
||||
}, "latest"]
|
||||
|
||||
let responseStr = status.callPrivateRPC("eth_call", payload)
|
||||
let response = Json.decode(responseStr, RpcResponse)
|
||||
let response = transactions.eth_call(payload)
|
||||
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
|
||||
if response.result == "0x":
|
||||
|
@ -92,8 +48,8 @@ proc getPackCount*(): int =
|
|||
"data": contract.methods["packCount"].encodeAbi()
|
||||
}, "latest"]
|
||||
|
||||
let responseStr = status.callPrivateRPC("eth_call", payload)
|
||||
let response = Json.decode(responseStr, RpcResponse)
|
||||
let response = transactions.eth_call(payload)
|
||||
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
|
||||
if response.result == "0x":
|
||||
|
@ -113,8 +69,7 @@ proc getPackData*(id: Stuint[256], running: var Atomic[bool]): StickerPack =
|
|||
"to": $contract.address,
|
||||
"data": contractMethod.encodeAbi(getPackData)
|
||||
}, "latest"]
|
||||
let responseStr = status.callPrivateRPC("eth_call", payload)
|
||||
let response = Json.decode(responseStr, RpcResponse)
|
||||
let response = transactions.eth_call(payload)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, "Error getting sticker pack data: " & response.error.message)
|
||||
|
||||
|
@ -153,8 +108,7 @@ proc tokenOfOwnerByIndex*(address: Address, idx: Stuint[256]): int =
|
|||
"data": contract.methods["tokenOfOwnerByIndex"].encodeAbi(tokenOfOwnerByIndex)
|
||||
}, "latest"]
|
||||
|
||||
let responseStr = status.callPrivateRPC("eth_call", payload)
|
||||
let response = Json.decode(responseStr, RpcResponse)
|
||||
let response = transactions.eth_call(payload)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, "Error getting owned tokens: " & response.error.message)
|
||||
if response.result == "0x":
|
||||
|
@ -170,8 +124,7 @@ proc getPackIdFromTokenId*(tokenId: Stuint[256]): int =
|
|||
"data": contract.methods["tokenPackId"].encodeAbi(tokenPackId)
|
||||
}, "latest"]
|
||||
|
||||
let responseStr = status.callPrivateRPC("eth_call", payload)
|
||||
let response = Json.decode(responseStr, RpcResponse)
|
||||
let response = transactions.eth_call(payload)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, "Error getting pack id from token id: " & response.error.message)
|
||||
if response.result == "0x":
|
|
@ -1,4 +1,8 @@
|
|||
import
|
||||
atomics, json, tables, sequtils, httpclient, net
|
||||
import json, random, strutils, strformat, tables, chronicles, unicode, times
|
||||
import
|
||||
json_serialization, chronicles, libp2p/[multihash, multicodec, cid], stint, nimcrypto
|
||||
from sugar import `=>`, `->`
|
||||
import stint
|
||||
from times import getTime, toUnix, nanosecond
|
||||
|
@ -6,6 +10,55 @@ import signing_phrases
|
|||
from web3 import Address, fromHex
|
||||
import web3/ethhexstrings
|
||||
|
||||
proc decodeContentHash*(value: string): string =
|
||||
if value == "":
|
||||
return ""
|
||||
|
||||
# eg encoded sticker multihash cid:
|
||||
# e30101701220eab9a8ef4eac6c3e5836a3768d8e04935c10c67d9a700436a0e53199e9b64d29
|
||||
# e3017012205c531b83da9dd91529a4cf8ecd01cb62c399139e6f767e397d2f038b820c139f (testnet)
|
||||
# e3011220c04c617170b1f5725070428c01280b4c19ae9083b7e6d71b7a0d2a1b5ae3ce30 (testnet)
|
||||
#
|
||||
# The first 4 bytes (in hex) represent:
|
||||
# e3 = codec identifier "ipfs-ns" for content-hash
|
||||
# 01 = unused - sometimes this is NOT included (ie ropsten)
|
||||
# 01 = CID version (effectively unused, as we will decode with CIDv0 regardless)
|
||||
# 70 = codec identifier "dag-pb"
|
||||
|
||||
# ipfs-ns
|
||||
if value[0..1] != "e3":
|
||||
warn "Could not decode sticker. It may still be valid, but requires a different codec to be used", hash=value
|
||||
return ""
|
||||
|
||||
try:
|
||||
# dag-pb
|
||||
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()
|
||||
let resultTyped = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get()
|
||||
result = $resultTyped
|
||||
trace "Decoded sticker hash", cid=result
|
||||
except Exception as e:
|
||||
error "Error decoding sticker", hash=value, exception=e.msg
|
||||
raise
|
||||
|
||||
proc getTimelineChatId*(pubKey: string = ""): string =
|
||||
if pubKey == "":
|
||||
return "@timeline70bd746ddcc12beb96b2c9d572d0784ab137ffc774f5383e50585a932080b57cca0484b259e61cecbaa33a4c98a300a"
|
||||
|
|
|
@ -8,6 +8,7 @@ import # vendor libs
|
|||
import # status-desktop libs
|
||||
../libstatus/core as status, ../eth/contracts as contracts,
|
||||
../stickers as status_stickers,
|
||||
../utils as status_utils,
|
||||
web3/[conversions, ethtypes], ../utils, account
|
||||
|
||||
const CRYPTOKITTY* = "cryptokitty"
|
||||
|
@ -242,7 +243,7 @@ proc getStickers*(address: Address, running: var Atomic[bool]): string =
|
|||
let sticker = availableStickerPacks[stickerId]
|
||||
stickers.add(Collectible(id: $tokensIds[index],
|
||||
name: sticker.name,
|
||||
image: fmt"https://ipfs.infura.io/ipfs/{status_stickers.decodeContentHash(sticker.preview)}",
|
||||
image: fmt"https://ipfs.infura.io/ipfs/{status_utils.decodeContentHash(sticker.preview)}",
|
||||
collectibleType: STICKER,
|
||||
description: sticker.author,
|
||||
externalUrl: "")
|
||||
|
|
|
@ -8,6 +8,7 @@ import # vendor libs
|
|||
import # status-desktop libs
|
||||
../libstatus/core as status, ../eth/contracts as contracts,
|
||||
../stickers as status_stickers,
|
||||
../utils as status_utils,
|
||||
web3/[conversions, ethtypes], ../utils, account
|
||||
|
||||
const CRYPTOKITTY* = "cryptokitty"
|
||||
|
@ -242,7 +243,7 @@ proc getStickers*(address: Address, running: var Atomic[bool]): string =
|
|||
let sticker = availableStickerPacks[stickerId]
|
||||
stickers.add(Collectible(id: $tokensIds[index],
|
||||
name: sticker.name,
|
||||
image: fmt"https://ipfs.infura.io/ipfs/{status_stickers.decodeContentHash(sticker.preview)}",
|
||||
image: fmt"https://ipfs.infura.io/ipfs/{status_utils.decodeContentHash(sticker.preview)}",
|
||||
collectibleType: STICKER,
|
||||
description: sticker.author,
|
||||
externalUrl: "")
|
||||
|
|
Loading…
Reference in New Issue