Skip to content

Commit

Permalink
Fee of 500 CHAT to list a new token
Browse files Browse the repository at this point in the history
  • Loading branch information
megrogan committed Nov 14, 2024
1 parent 23fb208 commit 9e3d14f
Show file tree
Hide file tree
Showing 19 changed files with 75 additions and 33 deletions.
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

0 comments on commit 9e3d14f

Please sign in to comment.