This commit is contained in:
Believethehype
2023-04-23 18:09:28 +02:00
28 changed files with 262 additions and 26 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
android:name=".Amethyst"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/amethyst"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:enableOnBackInvokedCallback="true"
android:supportsRtl="true"
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@@ -6,14 +6,16 @@ import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
fun checkForHashtagWithIcon(tag: String): HashtagIcon? {
return when (tag.lowercase()) {
"bitcoin", "btc" -> HashtagIcon(R.drawable.ht_btc, "Bitcoin", Color.Unspecified, Modifier.padding(2.dp, 2.dp, 0.dp, 0.dp))
"nostr", "nostrich", "nostriches", "nostrichs" -> HashtagIcon(R.drawable.ht_nostr, "Nostr", Color.Unspecified, Modifier.padding(1.dp, 2.dp, 0.dp, 0.dp))
"bitcoin", "btc", "timechain" -> HashtagIcon(R.drawable.ht_btc, "Bitcoin", Color.Unspecified, Modifier.padding(2.dp, 2.dp, 0.dp, 0.dp))
"nostr", "nostrich", "nostriches" -> HashtagIcon(R.drawable.ht_nostr, "Nostr", Color.Unspecified, Modifier.padding(1.dp, 2.dp, 0.dp, 0.dp))
"lightning", "lightningnetwork" -> HashtagIcon(R.drawable.ht_lightning, "Lightning", Color.Unspecified, Modifier.padding(1.dp, 3.dp, 0.dp, 0.dp))
"zap", "zaps", "zapper", "zappers", "zapping", "zapped", "zapathon", "zapraiser", "zaplife", "zapchain" -> HashtagIcon(R.drawable.zap, "Zap", Color.Unspecified, Modifier.padding(1.dp, 3.dp, 0.dp, 0.dp))
"amethyst" -> HashtagIcon(R.drawable.amethyst, "Amethyst", Color.Unspecified, Modifier.padding(3.dp, 2.dp, 0.dp, 0.dp))
"plebs", "pleb", "plebchain" -> HashtagIcon(R.drawable.plebs, "Pleb", Color.Unspecified, Modifier.padding(2.dp, 2.dp, 0.dp, 1.dp))
"coffee", "coffeechain" -> HashtagIcon(R.drawable.coffee, "Coffee", Color.Unspecified, Modifier.padding(2.dp, 2.dp, 0.dp, 0.dp))
"coffee", "coffeechain", "cafe" -> HashtagIcon(R.drawable.coffee, "Coffee", Color.Unspecified, Modifier.padding(2.dp, 2.dp, 0.dp, 0.dp))
"skullofsatoshi" -> HashtagIcon(R.drawable.skull, "SkullofSatoshi", Color.Unspecified, Modifier.padding(2.dp, 1.dp, 0.dp, 0.dp))
"grownostr", "#permaculture", "#gardening", "#garden" -> HashtagIcon(R.drawable.grownostr, "GrowNostr", Color.Unspecified, Modifier.padding(0.dp, 1.dp, 0.dp, 1.dp))
"footstr" -> HashtagIcon(R.drawable.footstr, "Footstr", Color.Unspecified, Modifier.padding(1.dp, 1.dp, 0.dp, 0.dp))
else -> null
}
}
@@ -4,6 +4,7 @@ import android.util.Log
import androidx.lifecycle.LiveData
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.vitorpamplona.amethyst.service.NostrAccountDataSource.account
import com.vitorpamplona.amethyst.service.model.*
import com.vitorpamplona.amethyst.service.relays.Relay
import com.vitorpamplona.amethyst.ui.components.BundledInsert
@@ -594,6 +595,16 @@ object LocalCache {
fun consume(event: LnZapEvent) {
val note = getOrCreateNote(event.id)
var decryptedContent = LnZapRequestEvent.checkForPrivateZap(event.zapRequest!!, account.loggedIn.privKey!!)
if (decryptedContent != null) {
Log.e(
"DC",
"Decrypted Content from Anon Tag: Sender: {${decryptedContent.pubKey}}, Message: {${decryptedContent.content}} "
// TODO Update Notification with this Sender and Message
)
}
// Already processed this event.
if (note.event != null) return
@@ -16,7 +16,7 @@ class LnZapEvent(
// This event is also kept in LocalCache (same object)
@Transient val zapRequest: LnZapRequestEvent?
private fun containedPost(): LnZapRequestEvent? = try {
override fun containedPost(): LnZapRequestEvent? = try {
description()?.ifBlank { null }?.let {
fromJson(it, Client.lenient)
} as? LnZapRequestEvent
@@ -53,8 +53,7 @@ class LnZapEvent(
null
}
}
override fun message(): String {
override fun content(): String {
return content
}
@@ -68,7 +67,7 @@ class LnZapEvent(
enum class ZapType() {
PUBLIC,
PRIVATE, // not yet implemented
PRIVATE,
ANONYMOUS,
NONZAP
}
@@ -16,5 +16,5 @@ interface LnZapEventInterface : EventInterface {
fun amount(): BigDecimal?
fun message(): String
fun containedPost(): Event?
}
@@ -1,9 +1,15 @@
package com.vitorpamplona.amethyst.service.model
import com.vitorpamplona.amethyst.model.HexKey
import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.model.*
import nostr.postr.Bech32
import nostr.postr.Utils
import java.util.Date
import java.nio.charset.Charset
import java.security.SecureRandom
import java.util.*
import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
class LnZapRequestEvent(
id: HexKey,
@@ -30,7 +36,7 @@ class LnZapRequestEvent(
zapType: LnZapEvent.ZapType,
createdAt: Long = Date().time / 1000
): LnZapRequestEvent {
val content = message
var content = message
var privkey = privateKey
var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
var tags = listOf(
@@ -48,6 +54,14 @@ class LnZapRequestEvent(
tags = tags + listOf(listOf("anon", ""))
privkey = Utils.privkeyCreate()
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
} else if (zapType == LnZapEvent.ZapType.PRIVATE) {
var encryptionPrivateKey = createEncryptionPrivateKey(privateKey.toHexKey(), originalNote.id(), createdAt)
var noteJson = (create(privkey, 9733, listOf(tags[0], tags[1]), message)).toJson()
var encryptedContent = encryptPrivateZapMessage(noteJson, encryptionPrivateKey, originalNote.pubKey().toByteArray())
tags = tags + listOf(listOf("anon", encryptedContent))
content = "" // make sure public content is empty, as the content is encrypted
privkey = encryptionPrivateKey // sign event with generated privkey
pubKey = Utils.pubkeyCreate(encryptionPrivateKey).toHexKey() // updated event with according pubkey
}
val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = Utils.sign(id, privkey)
@@ -62,7 +76,7 @@ class LnZapRequestEvent(
zapType: LnZapEvent.ZapType,
createdAt: Long = Date().time / 1000
): LnZapRequestEvent {
val content = message
var content = message
var privkey = privateKey
var pubKey = Utils.pubkeyCreate(privateKey).toHexKey()
var tags = listOf(
@@ -70,18 +84,90 @@ class LnZapRequestEvent(
listOf("relays") + relays
)
if (zapType == LnZapEvent.ZapType.ANONYMOUS) {
tags = tags + listOf(listOf("anon", ""))
privkey = Utils.privkeyCreate()
pubKey = Utils.pubkeyCreate(privkey).toHexKey()
tags = tags + listOf(listOf("anon", ""))
} else if (zapType == LnZapEvent.ZapType.PRIVATE) {
var encryptionPrivateKey = createEncryptionPrivateKey(privateKey.toHexKey(), userHex, createdAt)
var noteJson = (create(privkey, 9733, listOf(tags[0], tags[1]), message)).toJson()
var encryptedContent = encryptPrivateZapMessage(noteJson, encryptionPrivateKey, userHex.toByteArray())
tags = tags + listOf(listOf("anon", encryptedContent))
content = ""
privkey = encryptionPrivateKey
pubKey = Utils.pubkeyCreate(encryptionPrivateKey).toHexKey()
}
val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = Utils.sign(id, privkey)
return LnZapRequestEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey())
}
fun createEncryptionPrivateKey(privkey: String, id: String, createdAt: Long): ByteArray {
var str = privkey + id + createdAt.toString()
var strbyte = str.toByteArray(Charset.forName("utf-8"))
return sha256.digest(strbyte)
}
fun encryptPrivateZapMessage(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
var sharedSecret = Utils.getSharedSecret(privkey, pubkey)
val iv = ByteArray(16)
SecureRandom().nextBytes(iv)
val keySpec = SecretKeySpec(sharedSecret, "AES")
val ivSpec = IvParameterSpec(iv)
var utf8message = msg.toByteArray(Charset.forName("utf-8"))
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
val encryptedMsg = cipher.doFinal(utf8message)
val encryptedMsgBech32 = Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32)
val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32)
return encryptedMsgBech32 + "_" + ivBech32
}
fun decryptPrivateZapMessage(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
var sharedSecret = Utils.getSharedSecret(privkey, pubkey)
if (sharedSecret.size != 16 && sharedSecret.size != 32) {
throw IllegalArgumentException("Invalid shared secret size")
}
val parts = msg.split("_")
if (parts.size != 2) {
throw IllegalArgumentException("Invalid message format")
}
val iv = parts[1].run { Bech32.decode(this) }
val encryptedMsg = parts.first().run { Bech32.decode(this) }
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(sharedSecret, "AES"), IvParameterSpec(Bech32.five2eight(iv.second, 0)))
try {
val decryptedMsgBytes = cipher.doFinal(Bech32.five2eight(encryptedMsg.second, 0))
return String(decryptedMsgBytes)
} catch (ex: BadPaddingException) {
throw IllegalArgumentException("Bad padding")
}
}
fun checkForPrivateZap(zaprequest: Event, loggedInUserPrivKey: ByteArray): Event? {
val anonTag = zaprequest.tags.firstOrNull { t -> t.count() >= 2 && t[0] == "anon" }
if (anonTag != null && anonTag.size > 1) {
val encnote = anonTag?.elementAt(1)
if (encnote != null && encnote != "") {
try {
val note = decryptPrivateZapMessage(encnote, loggedInUserPrivKey, zaprequest.pubKey.toByteArray())
val decryptedEvent = fromJson(note)
if (decryptedEvent.kind == 9733) {
return decryptedEvent
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
return null
}
}
}
/*
{
"pubkey": "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
@@ -162,16 +162,18 @@ fun ZoomableContentView(content: ZoomableContent, images: List<ZoomableContent>
}
)
if (imageState !is AsyncImagePainter.State.Success) {
if (content.bluehash != null) {
DisplayBlueHash(content, mainImageModifier)
} else {
DisplayUrlWithLoadingSymbol(content)
}
} else {
if (imageState is AsyncImagePainter.State.Success) {
HashVerificationSymbol(verifiedHash, Modifier.align(Alignment.TopEnd))
}
}
if (imageState !is AsyncImagePainter.State.Success) {
if (content.bluehash != null) {
DisplayBlueHash(content, mainImageModifier)
} else {
DisplayUrlWithLoadingSymbol(content)
}
}
} else {
VideoView(content.url) { dialogOpen = true }
}
@@ -183,7 +185,7 @@ fun ZoomableContentView(content: ZoomableContent, images: List<ZoomableContent>
@Composable
private fun DisplayUrlWithLoadingSymbol(content: ZoomableContent) {
ClickableUrl(urlText = "$content ", url = content.url)
ClickableUrl(urlText = "${content.url} ", url = content.url)
val myId = "inlineContent"
val emptytext = buildAnnotatedString {
@@ -375,7 +375,7 @@ fun NoteComposeInner(
baseNote = replyingDirectlyTo,
isQuotedNote = true,
modifier = Modifier
.padding(0.dp)
.padding(top = 5.dp)
.fillMaxWidth()
.clip(shape = RoundedCornerShape(15.dp))
.border(
@@ -67,6 +67,7 @@ fun ZapCustomDialog(onClose: () -> Unit, account: Account, accountViewModel: Acc
val zapTypes = listOf(
Pair(LnZapEvent.ZapType.PUBLIC, "Public"),
Pair(LnZapEvent.ZapType.PRIVATE, "Private"),
Pair(LnZapEvent.ZapType.ANONYMOUS, "Anonymous"),
Pair(LnZapEvent.ZapType.NONZAP, "Non-Zap")
)
@@ -89,6 +89,8 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
if (zappedPost != null) {
val zapRequest = zappedPost.zaps.filter { it.value == zapEvent }.keys.firstOrNull()
if (zapRequest != null) {
// var newZapRequestEvent = LocalCache.checkPrivateZap(zapRequest.event as Event)
// zapRequest.event = newZapRequestEvent
zapsPerEvent.getOrPut(zappedPost, { mutableMapOf() }).put(zapRequest, zapEvent)
}
} else {
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="236dp"
android:height="236dp"
android:viewportWidth="236"
android:viewportHeight="236">
<path
android:fillColor="#E102C2"
android:strokeWidth="1"
android:pathData="M168,2 C166.799,8.18727,164.947,14.0171,163,20 L173,19 C172.51,13.3852,171.014,6.79588,168,2 M180,142 C184.601,142.041,190.655,144.838,194.96,143.242 C198.824,141.81,201.214,137.39,203.124,134 C210.078,121.662,205.608,109.019,208.529,96 C209.595,91.2476,211.618,86.9521,211.907,82 C212.185,77.2133,210.665,72.7095,210.17,68 C209.701,63.5467,209.857,58.574,205.786,55.608 C201.265,52.3132,197.605,56.5867,197.109,61.0008 C196.625,65.3034,197.297,69.6886,196.896,74 C196.545,77.7718,195.281,81.1715,195.192,85 C195.122,88.0362,193.994,92.9444,190,92.9444 C182.816,92.9444,184.436,81.2708,183.471,77 C181.705,69.1818,178.855,62.145,178.174,54 C177.671,47.9876,179.574,42.0776,178.815,36 C178.301,31.8835,176.341,26.0742,171.957,24.6474 C165.913,22.6804,163.112,29.2432,163.019,34 C162.92,39.1355,164.73,43.9125,164.961,49 C165.331,57.1618,165.938,65.6008,166.06,73.7145 C166.102,76.5167,164.978,79.1797,165.148,82.0008 C165.401,86.2009,171.219,91.7501,168.342,95.6366 C164.867,100.33,159.865,95.1623,157.698,91.9992 C153.406,85.7334,150.568,78.4766,146.637,72.0193 C144.788,68.9835,141.904,66.4794,138.105,67.4529 C127.951,70.0551,136.163,83.457,139.475,88 C148.178,99.9397,155.763,112.385,165.069,124 C170.248,130.463,177.624,133.778,180,142 M201,31 C201.873,37.4822,203,43.4025,203,50 L211,53 C210.634,44.6039,207.808,36.2575,201,31 M134,45 C130.221,51.7137,128.788,59.5176,131,67 C133.684,65.6449,136.047,64.5637,139,64 C138.115,58.0095,136.467,50.4928,134,45 M69,46 C67.7386,52.0951,65.8947,58.0744,64,64 L75,65 C73.0087,58.8781,72.0169,51.6331,69,46 M58,187 C60.1785,179.456,65.298,178.506,69.5756,172.891 C76.4258,163.899,83.8065,155.158,90.3627,146 C93.3233,141.864,95.3809,137.163,98.3634,133 C101.618,128.457,110.219,115.016,99.9452,112.453 C96.1093,111.496,93.2422,113.949,91.3627,117.019 C87.4224,123.456,84.5515,130.765,80.3009,136.999 C78.2049,140.073,73.9249,144.782,70.3727,140.793 C66.7916,136.772,72.5283,131.392,72.8765,127 C73.1057,124.109,72.0273,121.426,71.99,118.576 C71.8412,107.222,73.1025,95.215,74.6998,84 C75.461,78.656,74.6292,66.8531,66.0432,69.6474 C61.6591,71.0742,59.6995,76.8835,59.1852,81 C58.5106,86.3994,60.0712,91.6669,59.6752,97 C59.0126,105.922,56.2059,113.456,54.3897,122 C53.4709,126.322,55.3265,137.793,48,137.793 C43.4396,137.793,42.7212,132.308,42.7153,129 C42.7089,125.453,41.0904,122.469,40.814,119 C40.4715,114.701,41.3203,110.323,40.9414,106.001 C40.5785,101.862,36.9418,97.2305,32.3904,100.032 C28.1086,102.668,28.2839,108.688,27.8302,113 C27.371,117.365,25.9672,121.574,26.054,126 C26.1513,130.962,27.9426,135.298,29.2153,140 C32.8567,153.455,27.7081,166.117,35.0432,179 C37.0472,182.52,39.8521,187.101,44.0008,188.303 C47.9872,189.459,53.7392,187.036,58,187 M36,76 C30.3783,82.2632,27.1802,89.5415,27,98 C29.653,96.7567,32.1579,95.7118,35,95 C35,89.2612,37.5867,81.2251,36,76 M103,90 C102.725,96.2961,100.405,101.927,99,108 C101.839,109.086,104.364,110.488,107,112 C109.117,104.839,108.468,95.4737,103,90 M180.108,151.742 C169.428,156.306,179.297,171.326,188.907,167.141 C201.335,161.729,191.315,146.953,180.108,151.742 M172,170 C172,176.766,171.53,183.278,171,190 C175.401,185.315,179.315,179.294,183,174 C179.113,173.098,175.607,171.693,172,170 M49.0046,196.533 C37.7274,199.326,45.4118,214.867,55,212.412 C61.5523,210.735,65.5024,202.582,59.581,197.603 C56.911,195.359,52.1706,195.749,49.0046,196.533 M65,215 C61.7705,216.818,58.5543,217.97,55,219 C59.1283,224.051,63.1959,229.072,66,235 C67.2105,229.96,67.0167,219.806,65,215 Z" />
</vector>
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:fillColor="#FF3700B3"
android:strokeWidth="1"
android:pathData="M18,1 C18.9992,13.6607,22.1338,27.7425,34,34.6366 C40.7028,38.5308,48.5179,39.5903,56,41 C54.3404,31.8037,49.5418,30.0009,41,30 L41,27 L48,27 C43.5259,17.4059,36.6076,16,27,16 L27,13 L34,13 C32.6931,11.3029,31.5948,10.0267,31,8 C26.6436,5.68091,22.6182,2.74787,18,1 Z" />
<path
android:fillColor="#FF6200EE"
android:strokeWidth="1"
android:pathData="M20,1 C23.7028,5.01085,28.4333,6.60192,33,9.37886 C37.2327,11.9527,40.6939,15.5138,45,18 C45,16.2032,45.0143,16.4785,46,15 C49.1978,22.5154,52.8144,28.929,57,36 C58.7383,31.8481,57.6225,27.1823,56.2508,23 C50.9595,6.86786,35.7333,1.01042,20,1 Z" />
<path
android:fillColor="#818181"
android:strokeWidth="1"
android:pathData="M39,4 L40,5 L39,4 Z" />
<path
android:fillColor="#35b458"
android:strokeWidth="1"
android:pathData="M30,9 C31.3926,10.4336,32.2328,11.0449,34,12 C31.5819,12.7224,29.5283,12.9481,27,13 L27,16 C36.9436,16,42.0965,18.6193,48,27 L41,27 L41,30 C44.205,30.0025,47.9651,29.5304,50.6713,31.6034 C54.7802,34.7509,55.7328,40.3378,57.0108,45 C60.2954,56.9827,62,69.5839,62,82 C62,87.7274,59.4347,99.821,66,102 C66,95.3343,66.0617,88.6654,66,82 C65.9762,79.4328,65.067,76.5127,65.5556,74 C66.6821,68.2063,71.7932,59.9436,75.0278,55 C76.5417,52.6862,78.2725,50.2574,81,49.3333 C84.7977,48.0467,89.9365,50.9632,91,46 L81,47 C87.2435,39.3331,91.8803,35.0279,102,35 L102,33 L95,33 L99,28 C92.7626,28.2768,88.8779,34.5639,84,38 C83.7893,35.2614,83.6975,34.578,81,34 C81.9074,41.9128,77.8444,45.756,73.5046,52 C70.4878,56.3406,67.7521,61.3024,64,65 C63.9237,55.7794,62.0513,45.3541,58.0193,37 C55.6122,32.0127,52.0583,27.809,49.4151,23 C47.9915,20.4099,47.5242,17.5234,46,15 C45.3152,16.2483,45.2512,16.5484,45,18 C40.5825,14.4148,35.9467,8.78864,30,9 Z" />
<path
android:fillColor="#818181"
android:strokeWidth="1"
android:pathData="M47,9 L48,10 L47,9 Z" />
<path
android:fillColor="#FF6200EE"
android:strokeWidth="1"
android:pathData="M70,57 C76.3094,50.934,82.6356,42.9806,81,34 C83.0347,35.2259,83.3265,35.7026,84,38 C90.3127,35.0562,94.6995,29.2957,101,26.0247 C103.882,24.5284,105.934,22.6997,109,24 C109.683,22.494,109.826,21.6852,110,20 C92.9496,20.3519,76.459,26.2355,71.2091,44 C69.9432,48.2837,70.0005,52.5793,70,57 Z" />
<path
android:fillColor="#818181"
android:strokeWidth="1"
android:pathData="M96,21 L97,22 L96,21 Z" />
<path
android:fillColor="#FF3700B3"
android:strokeWidth="1"
android:pathData="M98,27 C97.4257,29.3388,96.3153,30.952,95,33 L102,33 L102,35 C91.9916,35.0066,86.152,38.087,81,47 C84.4218,46.9717,87.6368,46.6245,91,46 C88.2508,50.2406,84.2142,47.9848,80.0401,49.6034 C75.8011,51.2471,73.6765,56.1154,72,60 C93.0315,59.0947,111.529,44.7797,109,22 C104.967,22.9474,101.721,25.2426,98,27 Z" />
<path
android:fillColor="#01ff01"
android:strokeWidth="1"
android:pathData="M23,23 L24,24 L23,23 M85,25 L86,26 L85,25 Z" />
<path
android:fillColor="#818181"
android:strokeWidth="1"
android:pathData="M72,40 L73,41 L72,40 Z" />
<path
android:fillColor="#f99721"
android:strokeWidth="1"
android:pathData="M18,127 C24.7416,127,33.546,128.5,40,126.437 C43.9557,125.172,46.9708,122.016,51,120.8 C53.8127,119.952,57.0165,120.515,59.7145,119.397 C66.4359,116.613,70.376,110.812,78,109 C73.2583,102.431,64.8777,99.3157,57,102.667 C53.9866,103.95,51.8253,106.485,49,108.066 C46.1443,109.665,42.7844,109.921,40.0147,111.727 C37.7156,113.226,36.0905,115.611,33.7145,116.977 C27.2551,120.69,22.0281,119.305,18,127 Z" />
<path
android:fillColor="#857f2d"
android:strokeWidth="1"
android:pathData="M62,101 L63,102 L62,101 Z" />
<path
android:fillColor="#ffff01"
android:strokeWidth="1"
android:pathData="M52,105 L53,106 L52,105 M75,105 L76,106 L75,105 Z" />
<path
android:fillColor="#df7f07"
android:strokeWidth="1"
android:pathData="M41,127 L110,127 C105.972,119.305,100.745,120.69,94.2855,116.977 C87.4988,113.076,83.904,107.518,75,109.53 C68.1753,111.072,64.8143,116.981,58.8302,119.397 C51.9278,122.185,46.424,120.458,41,127 Z" />
</vector>
@@ -0,0 +1,7 @@
<vector android:height="108dp" android:viewportHeight="216"
android:viewportWidth="216" android:width="108dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000"
android:pathData="M90.2,73.6l-17.2,16.6 0,19.7 0,19.7 3,2.9c1.6,1.6 3.3,2.6 3.6,2.2 0.4,-0.4 1,-4.2 1.5,-8.4 0.9,-9.6 4.5,-25.4 6.9,-30.8 0.5,-1.1 1.9,-4.4 3.1,-7.3 1.9,-4.6 2.4,-5.2 4.3,-4.5 1.1,0.5 5.5,0.7 9.6,0.5 10.8,-0.3 13.7,0.3 15.5,3.8 0.8,1.6 1.5,5 1.5,7.5 0,6.1 1,7.7 7,11.4 8,4.9 5.6,8.7 -4.4,6.8 -3.9,-0.7 -6.2,-0.5 -9.6,0.6 -2.5,0.9 -5.8,1.8 -7.3,2.2 -4.4,0.9 -5.7,5.3 -5.7,19.8 0,6.8 -0.5,13.9 -1.1,15.7 -1.1,3 -1,3.4 2.9,7.3l4.1,4.1 5.8,-5.4c3.2,-3 11.3,-10.7 18.1,-17.2l12.2,-11.9 0,-18.9 0,-19 -13.2,-12.8c-14.2,-13.7 -22.3,-21.2 -22.9,-21.2 -0.2,-0 -8.2,7.5 -17.7,16.6z" android:strokeColor="#00000000"/>
<path android:fillColor="#000000"
android:pathData="M111,91.5c0,3.1 2.6,4.3 4.6,2.3 2,-2 0.7,-4.8 -2.2,-4.8 -1.9,-0 -2.4,0.5 -2.4,2.5z" android:strokeColor="#00000000"/>
</vector>
@@ -0,0 +1,35 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="192.62"
android:viewportHeight="288.93">
<group android:scaleX="0.33333334"
android:scaleY="0.5"
android:translateX="64.206665"
android:translateY="72.2325">
<group>
<clip-path
android:pathData="m111.18,103.42c-4.68,-0 -8.47,-3.8 -8.47,-8.48 0,-4.68 3.79,-8.48 8.47,-8.48 4.68,-0 8.48,3.8 8.48,8.48 0,4.68 -3.79,8.48 -8.48,8.48zM96.31,-0 L0,91.3L0,197.63l19.9,18.86c0.63,-43.4 14.08,-106.43 37.41,-146.62 0,-0 6.05,5.23 16.74,5.93 11.02,0.73 36.71,-4.37 48.32,0.36 10.87,4.43 11.66,17.34 10.79,27.84 -1.66,20.02 8.14,25.99 25.54,34.66 8.67,4.32 10.67,9.28 7.87,14.44 -3.09,5.68 -17.49,3.05 -33.55,1.1 -17.16,-2.08 -26.79,9.45 -43.37,8.39 -23.4,30.62 -0.84,73.09 -16.14,104.73l22.81,21.62 96.31,-91.31l0,-106.32z"/>
<path
android:pathData="m111.18,103.42c-4.68,-0 -8.47,-3.8 -8.47,-8.48 0,-4.68 3.79,-8.48 8.47,-8.48 4.68,-0 8.48,3.8 8.48,8.48 0,4.68 -3.79,8.48 -8.48,8.48zM96.31,-0 L0,91.3L0,197.63l19.9,18.86c0.63,-43.4 14.08,-106.43 37.41,-146.62 0,-0 6.05,5.23 16.74,5.93 11.02,0.73 36.71,-4.37 48.32,0.36 10.87,4.43 11.66,17.34 10.79,27.84 -1.66,20.02 8.14,25.99 25.54,34.66 8.67,4.32 10.67,9.28 7.87,14.44 -3.09,5.68 -17.49,3.05 -33.55,1.1 -17.16,-2.08 -26.79,9.45 -43.37,8.39 -23.4,30.62 -0.84,73.09 -16.14,104.73L96.31,288.93 192.62,197.63L192.62,91.3L96.31,-0"
android:strokeWidth="0.04"
android:strokeColor="#00000000"
android:fillType="nonZero">
<aapt:attr name="android:fillColor">
<gradient
android:startX="33.75"
android:startY="252.82"
android:endX="158.87"
android:endY="36.12"
android:tileMode="clamp"
android:type="linear">
<item android:offset="0" android:color="#FF550066"/>
<item android:offset="0" android:color="#FF550066"/>
<item android:offset="1" android:color="#FFA75CCC"/>
</gradient>
</aapt:attr>
</path>
</group>
</group>
</vector>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/amethyst_monochrome"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>