Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fee of 500 CHAT to list a new token #6817

Merged
merged 3 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions backend/canisters/registry/api/src/updates/add_token.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::TokenStandard;
use candid::CandidType;
use candid::{CandidType, Principal};
use human_readable::{HumanReadablePrincipal, ToHumanReadable};
use serde::{Deserialize, Serialize};
use types::{CanisterId, UserId};
Expand Down Expand Up @@ -27,7 +27,7 @@ pub enum Response {
#[derive(Serialize)]
pub struct HumanReadableArgs {
ledger_canister_id: HumanReadablePrincipal,
payer: Option<String>,
payer: Option<HumanReadablePrincipal>,
token_standard: String,
info_url: String,
how_to_buy_url: String,
Expand All @@ -41,7 +41,7 @@ impl ToHumanReadable for Args {
fn to_human_readable(&self) -> Self::Target {
HumanReadableArgs {
ledger_canister_id: self.ledger_canister_id.into(),
payer: self.payer.map(|user_id| user_id.to_string()),
payer: self.payer.map(|user_id| Principal::from(user_id).into()),
token_standard: self.token_standard.to_string(),
info_url: self.info_url.clone(),
how_to_buy_url: self.how_to_buy_url.clone(),
Expand Down
50 changes: 35 additions & 15 deletions frontend/app/src/components/home/MakeProposalModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
const MIN_AWARDS = 200;
const CHAT_FEE_PER_CHIT_AWARD: bigint = 20_000n; // 1/5000th of a CHAT
const ONE_MONTH = 1000 * 60 * 60 * 24 * 7 * 4;
const TOKEN_LISTING_FEE: bigint = 50_000_100_000n; // 500 CHAT + transfer fee
const client = getContext<OpenChat>("client");
const dispatch = createEventDispatcher();
Expand Down Expand Up @@ -103,12 +104,14 @@
$: achievementChatCost =
BigInt(chitReward * maxAwards) * CHAT_FEE_PER_CHIT_AWARD + tokenDetails.transferFee;
$: insufficientFunds = cryptoBalance < requiredFunds;
$: insufficientFundsForAchievement =
$: insufficientFundsForPayment =
cryptoBalance <
requiredFunds +
(selectedProposalType === "register_external_acievement" && step == 2
(selectedProposalType === "register_external_acievement"
? achievementChatCost
: BigInt(0));
: selectedProposalType === "add_token"
? TOKEN_LISTING_FEE
: BigInt(0));
$: padding = $mobileWidth ? 16 : 24; // yes this is horrible
$: left = step * (actualWidth - padding);
$: token = treasury === "SNS" ? symbol : "ICP";
Expand All @@ -134,7 +137,7 @@
$: awardingAchievementCanisterId = "";
$: valid =
!insufficientFunds &&
!insufficientFundsForAchievement &&
!insufficientFundsForPayment &&
titleValid &&
urlValid &&
summaryValid &&
Expand Down Expand Up @@ -199,8 +202,19 @@
busy = true;
if (selectedProposalType === "register_external_acievement") {
if (!(await approveExternalAchievementPayment())) {
if (
selectedProposalType === "register_external_acievement" ||
selectedProposalType === "add_token"
) {
let spender =
selectedProposalType === "add_token"
? process.env.REGISTRY_CANISTER!
: process.env.USER_INDEX_CANISTER!;
let amount =
selectedProposalType === "add_token" ? TOKEN_LISTING_FEE : achievementChatCost;
if (!(await approvePayment(spender, amount))) {
busy = false;
return;
}
Expand Down Expand Up @@ -250,6 +264,7 @@
functionId: BigInt(7000),
payload: createAddTokenPayload(
addOrUpdateTokenLedgerCanisterId,
$user.userId,
addOrUpdateTokenInfoUrl,
addOrUpdateTokenHowToBuyUrl,
addOrUpdateTokenTransactionUrlFormat,
Expand Down Expand Up @@ -292,12 +307,12 @@
}
}
async function approveExternalAchievementPayment(): Promise<boolean> {
async function approvePayment(spender_canister_id: string, amount: bigint): Promise<boolean> {
return client
.approveTransfer(
process.env.USER_INDEX_CANISTER!,
spender_canister_id,
tokenDetails.ledger,
achievementChatCost,
amount,
BigInt(Date.now() + 1000 * 60 * 60 * 24 * 5), // allow 5 days for proposal
)
.then((resp) => {
Expand Down Expand Up @@ -679,13 +694,18 @@
</div>
</div>
<span class="footer" slot="footer">
{#if selectedProposalType === "register_external_acievement" && step === 2}
<p class="message" class:error={insufficientFundsForAchievement}>
{#if (selectedProposalType === "register_external_acievement" || selectedProposalType === "add_token") && step === 2}
<p class="message" class:error={insufficientFundsForPayment}>
<Translatable
resourceKey={i18nKey("proposal.maker.achievementChatCost", {
cost: client.formatTokens(achievementChatCost, 8),
token: symbol,
})} />
resourceKey={i18nKey(
"proposal.maker." + selectedProposalType === "add_token"
? "addTokenChatCost"
: "achievementChatCost",
{
cost: client.formatTokens(achievementChatCost, 8),
chat: "CHAT",
},
)} />
</p>
{/if}
{#if fundingMessage !== undefined}
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "集团指数行动",
"makeProposal": "提案",
"maker": {
"achievementChatCost": "需要支付 {cost} {token} 代币才能提供所请求的 CHIT。成就到期后,所有未使用的 CHAT 都将退还。",
"achievementChatCost": "需要支付 {cost} {chat} 代币才能提供所请求的 CHIT。成就到期后,所有未使用的 CHAT 都将退还。",
"achievementExpiry": "到期",
"achievementLogo": "成就标志",
"achievementName": "成就名称",
"achievementUrl": "成就网址",
"addTokenChatCost": "需要支付 {cost} {chat} 个代币才能在 OpenChat 上列出新代币。",
"amount": "数量",
"amountRules": "至少 1 个 {token} 令牌",
"approvalError": "无法批准 CHAT 转移",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Gruppenindexaktionen",
"makeProposal": "Machen Sie einen Vorschlag",
"maker": {
"achievementChatCost": "Zur Bereitstellung des angeforderten CHIT ist eine Zahlung von {cost} {token}-Tokens erforderlich. Nicht ausgegebene CHATs werden nach Ablauf der Errungenschaft zurückerstattet.",
"achievementChatCost": "Zur Bereitstellung des angeforderten CHIT ist eine Zahlung von {cost} {chat}-Tokens erforderlich. Nicht ausgegebene CHATs werden nach Ablauf der Errungenschaft zurückerstattet.",
"achievementExpiry": "Ablauf",
"achievementLogo": "Leistungslogo",
"achievementName": "Name der Leistung",
"achievementUrl": "Erfolgs-URL",
"addTokenChatCost": "Um ein neues Token auf OpenChat aufzulisten, ist eine Zahlung von {cost} {chat}-Token erforderlich.",
"amount": "Menge",
"amountRules": "mindestens 1 {token}-Token",
"approvalError": "Die Genehmigung der CHAT-Übertragung ist fehlgeschlagen",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Group Index Actions",
"makeProposal": "Make proposal",
"maker": {
"achievementChatCost": "A payment of {cost} {token} tokens is required to provision the requested CHIT. Any unspent CHAT will be refunded when the achievement expires.",
"achievementChatCost": "A payment of {cost} {chat} tokens is required to provision the requested CHIT. Any unspent CHAT will be refunded when the achievement expires.",
"achievementExpiry": "Expiry",
"achievementLogo": "Achievement Logo",
"achievementName": "Achievement name",
"achievementUrl": "Achievement URL",
"addTokenChatCost": "A payment of {cost} {chat} tokens is required to list a new token on OpenChat.",
"amount": "Amount",
"amountRules": "at least 1 {token} token",
"approvalError": "Failed to approve the CHAT transfer",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Acciones de índice de grupo",
"makeProposal": "hacer propuesta",
"maker": {
"achievementChatCost": "Se requiere un pago de tokens {cost} {token} para obtener el CHIT solicitado. Cualquier CHAT no utilizado se reembolsará cuando caduque el logro.",
"achievementChatCost": "Se requiere un pago de tokens {cost} {chat} para obtener el CHIT solicitado. Cualquier CHAT no utilizado se reembolsará cuando caduque el logro.",
"achievementExpiry": "Expiración",
"achievementLogo": "Logotipo de logros",
"achievementName": "Nombre del logro",
"achievementUrl": "URL del logro",
"addTokenChatCost": "Se requiere un pago de tokens {cost} {chat} para incluir un nuevo token en OpenChat.",
"amount": "Cantidad",
"amountRules": "al menos 1 token {token}",
"approvalError": "No se pudo aprobar la transferencia de CHAT",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/fa.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "اقدامات فهرست گروهی",
"makeProposal": "پیشنهاد بدهید",
"maker": {
"achievementChatCost": "برای ارائه CHIT درخواستی، پرداخت {cost} {token} توکن مورد نیاز است. هر چت خرج نشده پس از انقضای جایزه بازپرداخت خواهد شد.",
"achievementChatCost": "برای ارائه CHIT درخواستی، پرداخت {cost} {chat} توکن مورد نیاز است. هر چت خرج نشده پس از منقضی شدن جایزه بازپرداخت می شود.",
"achievementExpiry": "انقضا",
"achievementLogo": "لوگوی دستاورد",
"achievementName": "نام دستاورد",
"achievementUrl": "URL دستاورد",
"addTokenChatCost": "برای فهرست کردن یک نشانه جدید در OpenChat، پرداخت {cost} {chat} توکن لازم است.",
"amount": "میزان",
"amountRules": "حداقل 1 نشانه {token}",
"approvalError": "تایید انتقال CHAT انجام نشد",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Actions d'index de groupe",
"makeProposal": "Faire une proposition",
"maker": {
"achievementChatCost": "Un paiement de {cost} {token} jetons est requis pour provisionner le CHIT demandé. Tout CHAT non dépensé sera remboursé à l'expiration de la réussite.",
"achievementChatCost": "Un paiement de {cost} {chat} jetons est requis pour provisionner le CHIT demandé. Tout CHAT non dépensé sera remboursé à l'expiration de la réussite.",
"achievementExpiry": "Expiration",
"achievementLogo": "Logo de réussite",
"achievementName": "Nom de la réalisation",
"achievementUrl": "URL de réussite",
"addTokenChatCost": "Un paiement de {cost} {chat} jetons est requis pour répertorier un nouveau jeton sur OpenChat.",
"amount": "Montant",
"amountRules": "au moins 1 jeton {token}",
"approvalError": "Impossible d'approuver le transfert CHAT",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "समूह सूचकांक क्रियाएँ",
"makeProposal": "प्रस्ताव बनाएं",
"maker": {
"achievementChatCost": "अनुरोधित CHIT का प्रावधान करने के लिए {cost} {token} टोकन का भुगतान आवश्यक है। उपलब्धि समाप्त होने पर कोई भी अप्रयुक्त CHAT वापस कर दी जाएगी।",
"achievementChatCost": "अनुरोधित CHIT का प्रावधान करने के लिए {cost} {chat} टोकन का भुगतान आवश्यक है। उपलब्धि समाप्त होने पर कोई भी अप्रयुक्त CHAT वापस कर दी जाएगी।",
"achievementExpiry": "समाप्ति",
"achievementLogo": "उपलब्धि लोगो",
"achievementName": "उपलब्धि का नाम",
"achievementUrl": "उपलब्धि यूआरएल",
"addTokenChatCost": "ओपनचैट पर नया टोकन सूचीबद्ध करने के लिए {cost} {chat} टोकन का भुगतान आवश्यक है।",
"amount": "मात्रा",
"amountRules": "कम से कम 1 {token} टोकन",
"approvalError": "CHAT स्थानांतरण स्वीकृत करने में विफल",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Azioni indice di gruppo",
"makeProposal": "Fai una proposta",
"maker": {
"achievementChatCost": "È richiesto un pagamento di {cost} {token} token per fornire il CHIT richiesto. Qualsiasi CHAT non speso verrà rimborsato alla scadenza dell'obiettivo.",
"achievementChatCost": "È richiesto un pagamento di {cost} {chat} token per fornire il CHIT richiesto. Qualsiasi CHAT non speso verrà rimborsato alla scadenza dell'obiettivo.",
"achievementExpiry": "Scadenza",
"achievementLogo": "Logo del risultato",
"achievementName": "Nome del risultato",
"achievementUrl": "URL del risultato",
"addTokenChatCost": "Per elencare un nuovo token su OpenChat è richiesto il pagamento di {cost} {chat} token.",
"amount": "Quantità",
"amountRules": "almeno 1 token {token}",
"approvalError": "Impossibile approvare il trasferimento CHAT",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/iw.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "פעולות אינדקס קבוצתיות",
"makeProposal": "תציע הצעה",
"maker": {
"achievementChatCost": "נדרש תשלום של {cost} {token} אסימונים כדי לספק את ה-CHIT המבוקש. כל צ'אט שלא הוצא יוחזר כאשר ההישג יפוג.",
"achievementChatCost": "נדרש תשלום של {cost} {chat} אסימונים כדי לספק את ה-CHIT המבוקש. כל CHAT שלא הוצא יוחזר כאשר יפוג ההישג.",
"achievementExpiry": "תְפוּגָה",
"achievementLogo": "לוגו הישג",
"achievementName": "שם הישג",
"achievementUrl": "כתובת אתר של הישג",
"addTokenChatCost": "נדרש תשלום של {cost} {chat} אסימונים כדי לרשום אסימון חדש ב-OpenChat.",
"amount": "כמות",
"amountRules": "לפחות אסימון {token} אחד",
"approvalError": "אישור העברת ה-CHAT נכשל",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "グループ インデックス アクション",
"makeProposal": "提案する",
"maker": {
"achievementChatCost": "要求された CHIT をプロビジョニングするには、{cost} {token} トークンの支払いが必要です。未使用の CHAT は、実績の有効期限が切れると返金されます。",
"achievementChatCost": "要求された CHIT をプロビジョニングするには、{cost} {chat} トークンの支払いが必要です。未使用の CHAT は、実績の有効期限が切れると返金されます。",
"achievementExpiry": "有効期限",
"achievementLogo": "達成ロゴ",
"achievementName": "実績名",
"achievementUrl": "実績URL",
"addTokenChatCost": "OpenChatに新しいトークンを掲載するには、{cost} {chat}トークンの支払いが必要です。",
"amount": "",
"amountRules": "少なくとも 1 つの {token} トークン",
"approvalError": "CHAT 転送の承認に失敗しました",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Akcje indeksu grupowego",
"makeProposal": "Złóż propozycję",
"maker": {
"achievementChatCost": "Wymagana jest płatność {cost} {token} tokenów, aby zapewnić żądany CHIT. Wszelkie niewydane CHAT zostaną zwrócone po wygaśnięciu osiągnięcia.",
"achievementChatCost": "Wymagana jest płatność {cost} {chat} tokenów, aby zapewnić żądany CHIT. Wszelkie niewydane CHAT zostaną zwrócone po wygaśnięciu osiągnięcia.",
"achievementExpiry": "Wygaśnięcie",
"achievementLogo": "Logo osiągnięć",
"achievementName": "Nazwa osiągnięcia",
"achievementUrl": "Adres URL osiągnięcia",
"addTokenChatCost": "Aby dodać nowy token na OpenChat, wymagana jest zapłata {cost} {chat} tokenów.",
"amount": "Kwota",
"amountRules": "co najmniej 1 token {token}",
"approvalError": "Nie udało się zatwierdzić transferu CHAT",
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/src/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,12 @@
"groupIndexAction": "Действия группового индекса",
"makeProposal": "Сделать предложение",
"maker": {
"achievementChatCost": "Для предоставления запрошенного CHIT требуется оплата {cost} {token} токенов. Любой неизрасходованный CHAT будет возвращен, когда достижение истечет.",
"achievementChatCost": "Для предоставления запрошенного CHIT требуется оплата {cost} {chat} токенов. Любой неизрасходованный CHAT будет возвращен, когда достижение истечет.",
"achievementExpiry": "Истечение срока действия",
"achievementLogo": "Логотип достижения",
"achievementName": "Название достижения",
"achievementUrl": "URL-адрес достижения",
"addTokenChatCost": "Для добавления нового токена на OpenChat требуется оплата токенов {cost} {chat}.",
"amount": "Количество",
"amountRules": "хотя бы 1 токен {token}",
"approvalError": "Не удалось одобрить передачу ЧАТ",
Expand Down
Loading
Loading