CoinChoice Snap: Herhangi Bir Para Birimiyle Gas Yükle

Bir ETHDenver Hackathon Kazananı

11 dk okuma
CoinChoice Snap: Herhangi Bir Para Birimiyle Gas Yükle

MetaMask Snaps, MetaMask'ı dünyanın en genişletilebilir cüzdanı haline getirme yol haritasıdır. Geliştirici olarak, özelliklerinizi ve API'lerinizi MetaMask'a tamamen yeni yollarla sunabilirsiniz. Web3 geliştiricileri bu büyümenin özünü oluşturmaktadır ve bu seri, bugün inşa edilen yenilikçi MetaMask Snaps'leri tanıtmayı amaçlamaktadır.

CoinChoice Snap

Snap Repo: https://github.com/coinchoice/coinchoice/

Neden geliştirdiniz?

CoinChoice, küçük ama zahmetli ve son derece yaygın bir sorundan yola çıkılarak geliştirildi: Bir Web3 kullanıcısı, değerli token'lara sahip bir cüzdana sahip olabilir; ancak herhangi bir işlem gerçekleştirmek için gerekli gas para birimine sahip olmayabilir.

Bu sorun, özellikle bölünmüş likiditeye sahip kullanıcılar için belirginleşmektedir. Birden fazla cüzdanı yöneten ve farklı blokzinciri ekosistemlerinde fırsatları değerlendiren bir kullanıcı, gas token'larını her cüzdanına dağıtmak zorunda kalır; dijital varlıklarını ve işlemlerini kolaylaştırmak için yatırımlarına ayırması gereken sermayeyi bu amaçla ayırmak durumunda kalır. Gas yönetiminin ötesinde, gas'ın bulunmadığı bir ağa aktarılan token'lar, kullanıcının herhangi bir işlem yapabilmesi için önce gas edinmesini zorunlu kılar. Bu süreç genellikle kullanıcının gas edinmek ve çekmek için bir Merkezi Borsa'ya (CEX) başvurmasını gerektirir; bu da kullanıcıyı CEX çekim ücretlerine maruz bırakır.

Temelde bu deneyim kusurludur. Kullanıcıların Web3'e erişmek için merkezi borsalara bağımlı olmaması gerekir. Kullanıcılar gas yönetimiyle uğraşmak zorunda kalmamalı; bunun yerine merkezi olmayan sistemlerle doğrudan etkileşime geçebilmelidir. Bu, gas'ın gerekli olmadığı anlamına gelmez. Gas, bir ağın operatörlerini ödüllendirme ve spam/DDoS saldırılarını önleme gibi son derece önemli bir işlev görür. Gas'ın yalnızca daha esnek olması gerekir. Bir dApp veya oyun geliştiricisinin yerel bir token'ı varsa, bu token gas ödemek için yeterli bir para birimi olarak kabul edilmelidir.

CoinChoice, işte bu felsefeden hareketle geliştirildi.

CoinChoice, kullanıcının tarayıcısında çalışarak her işlemi, kullanıcının istediği para birimiyle gas yönetme imkânıyla destekler. Kullanıcı ETH yerine USDC tutmayı tercih ediyorsa, gas USDC ile ödenebilir.

CoinChoice'un MetaMask Snap'i bu deneyimi daha da güçlendirir. Kullanıcılar, doğrudan MetaMask Tarayıcı Uzantısı üzerinden seçtikleri gas para birimi karşılığında ETH bakiyelerini artırabilir. Bu sayede MetaMask, Merkezi Borsa ziyaretinin yerini alan bir çözüme dönüşür; Web3 deneyimini tek bir noktada toplar ve basitleştirir. Aynı zamanda yeni Web3 kullanıcılarının, giderek büyüyen hizmet ve platform bolluğu karşısında bunalmadan sistemlerin bir bölümüne alışmalarını sağlar.

Teknik uygulamayı bize anlatır mısınız?

CoinChoice, gas ödemelerinde hangi coin'lerin kullanılacağını seçme özgürlüğü sunan bir MetaMask ve Tarayıcı Uzantısıdır.

Paketler

  • backend: Tenderly API ve 0x Quote API'ye karşı işlemleri simüle ederek seçilen para biriminde gas tahminleri üretmekten sorumlu bir NestJS Web Sunucusu

  • istemcinin MetaMask Snap'i ile Tarayıcı Uzantısı arasındaki mesajları alır ve iletir

  • relayer sözleşmelerine iletilmek üzere meta-tx alır

  • browser-extension: Plasmo Framework tarafından desteklenen bir Tarayıcı Uzantısı — gas finansmanı için ETH'ye swap enjekte etmek amacıyla MetaMask'a yönelik RPC isteklerini yakalar

  • Gas Coin seçiminin yapılabildiği bir açılır pencere sunar

  • Cypher Onboarding SDK tarafından desteklenen token yönetimi için bir açılır pencere sunar

  • tüm veriler, Blokzinciri Etkileşimleri ve Simülasyonların yönetildiği backend servisine iletilir

  • contracts: 0x Protokolü üzerinde swap'ları kolaylaştırmak için meta-işlemleri aktaran Smart Contract'lar

  • frpc: Fluence Network'ün fRPC Gateway'inden yararlanmak için bir paket

  • meta-mask: Bir React.js Sitesi ve ilgili MetaMask Snap'i içeren paket — Snap, MetaMask arayüzü içinde doğrudan ETH Swap'ları sunmaktan sorumludur; "ETH'ye ihtiyacınız var mı?" mesajını göstererek çalışır

  • Snap, backend'e bir istek göndererek mesajın istemcinin tarayıcı uzantısına iletilmesini sağlar; bu sayede MetaMask Snap'in Tarayıcı Uzantısını başlatabileceği bir deneyim oluşturulur

  • İlgili Site, MetaMask Snap Kurulumunu etkinleştirmek için kullanılır

Teknik Kurulum

CoinChoice, işlemleri seçilen bir para birimiyle gas yükleme imkânıyla destekleyen bir tarayıcı uzantısıdır.

Tarayıcı uzantısı, her işlem öncesinde kullanıcıyı seçtiği para birimiyle gas ödemesi yapmaya yönlendirecek şekilde tasarlanmıştır.

Kullanıcı kabul ederse, seçilen token'ın tahmini bir miktarını ETH'ye dönüştürmek için bir meta-işlem yakalanır.

Bu meta-işlem, backend servisine iletilir; backend ise işlemi yürüten relayer Smart Contract'ına yönlendirir.

Meta-işlem tamamlandıktan sonra, uygun miktarda gas yatırıldığı için kullanıcının orijinal işlemi tetiklenir ve erişilebilir hale gelir.

MetaMask Snap, aksi takdirde MetaMask uzantısı içinde izole kalacak bir işlemi CoinChoice Uzantısı'na iletmek üzere tasarlanmıştır. Bunu şu şekilde gerçekleştirir:

  1. İşlem ayrıntılarını içeren bir istek backend servisine gönderilir

  2. Backend, işlem verilerini bir websocket bağlantısı üzerinden tarayıcı uzantısına iletir

  3. Tarayıcı uzantısı bu websocket mesajını aldığında, seçilen bir para birimi karşılığında otomatik olarak tahmin edilen miktarda gas yükleme akışını başlatır

Mesaj Veri Yolu Olarak Backend

CoinChoice, MetaMask Snap'in sandbox yapısı nedeniyle iki frontend bileşeni arasında mesaj veri yolu olarak bir backend kullanma yaklaşımını benimsedi.

Snap kod izolasyonu, MetaMask uzantısının dışındaki bağlamlarda bulunan frontend bileşenleriyle iletişimi engeller.

Ancak Snap'ler sunucu tarafı isteklerini destekleyebildiğinden, kullanıcı oturumlarını yönetebilen bir backend servisi, frontend bağlamları arasında mesaj iletmek için kullanılabilir.

Bunun bir örneği kaynak kodumuzu inceleyerek gösterilebilir.

MetaMask Snap içinde sunucuya bir istek gönderiyoruz.

Bkz. https://github.com/Coinchoice/coinchoice/blob/main/packages/meta-mask/packages/snap/src/index.ts#L12

import { OnTransactionHandler } from '@metamask/snaps-types';
import { heading, panel, text } from '@metamask/snaps-ui';

export interface JsonRpcRequest {
    id: string | undefined;
    jsonrpc: '2.0';
    method: string;
    params?: Array<any>;
}

const onTriggerAPI = async (transaction: JsonRpcRequest) => {
    await fetch(`https://api.coinchoice.link/metamask`, {
            method: 'POST',
            body: JSON.stringify(transaction),
            headers: { 'Content-Type': 'application/json' },
        })
    .then((res) => {
        if (!res.ok) {
            throw new Error('Bad response from server');
        }
        return res.json();
    })
    .then((json) => console.log(json))
    .catch((err) => console.error(err));
};

// Handle outgoing transactions
export const onTransaction: OnTransactionHandler = async ({ transaction }) => {
    // trigger browser extension for swap
    const response = await onTriggerAPI(transaction);
    // this is shown if no transaction is triggered
    if (typeof transaction.data === 'string' && transaction.data !== '0x') {
        return {
            content: panel([
                heading('Need ETH for gas?'),
                text('Receive ETH gasless for any currency with Coinchoice!'),
            ]),
        };
    }

    const currentGasPrice = await ethereum.request<string>({
        method: 'eth_gasPrice',
    });

    const transactionGas = parseInt(transaction.gas as string, 16);
    const currentGasPriceInWei = parseInt(currentGasPrice ?? '', 16);
    const maxFeePerGasInWei = parseInt(transaction.maxFeePerGas as string, 16);
    const maxPriorityFeePerGasInWei = parseInt(transaction.maxPriorityFeePerGas as string, 16);

    const gasFees = Math.min(
        maxFeePerGasInWei * transactionGas,
        (currentGasPriceInWei + maxPriorityFeePerGasInWei) * transactionGas
    );

    const transactionValueInWei = parseInt(transaction.value as string, 16);
    const gasFeesPercentage = (gasFees / (gasFees + transactionValueInWei)) * 100;

    return {
        content: panel([
            heading('Need ETH for gas?'),
            text(
                `As setup, you are paying **${gasFeesPercentage.toFixed(
                2
                )}%** in gas fees for this transaction.`
            ),
            text(`Also: **${response}**`),
        ]),
    };
};
Kopyala

Ardından sunucu tarafında, cüzdanı ve ilgili oturum tanımlayıcısını belirlemek için alınan işlem yükündeki from parametresini kullanıyoruz.

Bkz.: https://github.com/Coinchoice/coinchoice/blob/main/packages/backend/src/app.controller.ts#LL36-L49C3

@Post('metamask')
async metamask(@Body() data: any) {
    const address = data.from;
    const wallet = await this.walletService.findOne(address);
    if (wallet) {
        console.log(`clientId for ${address} is: ${wallet.clientId}`);
        if (wallet.clientId) {
            this.appGateway.server.to(wallet.clientId).emit('onMetamask', {
                msg: data,
                content: 'Hello from the backend!',
            });
        } else throw new NotFoundException('ClientId not found for this wallet');
    } else throw new NotFoundException('Wallet not found');
}
Kopyala

Son olarak, Tarayıcı Uzantısı içinde backend servisine bir websocket bağlantısı üzerinden bağlanıyoruz; bu bağlantının kendisi kullanıcı oturum tanımlayıcısını oluşturuyor. Bkz.: https://github.com/Coinchoice/coinchoice/blob/main/packages/browser-extension/src/contents/main.ts#L107

const socket = io(API_HOST);
socket.on('connect', function () {
    console.log('CS SOCKET: Connected');
});
socket.on('events', function (data) {
    console.log('CS SOCKET: event', data);
});
socket.on('onMessage', async function (data) {
    console.log('CS SOCKET: onMessage', data);
    if (data.msg.startsWith('Hello client')) {
        const [_, clientId] = data.msg.split('#');
        wallet.clientId = clientId;
        facade.setWallet(wallet);
        try {
            await busPromise('connect-wallet', { wallet });
        } catch (e) {
            console.log('CS SOCKET ERROR: onMessage - connect wallet');
            console.error(e);
        }
    }
});
socket.on('onMetamask', async function (data) {
    console.log('CS SOCKET: onMetamask', data);
    // On Metamask, open the Notification.
    const { msg: tx }: { msg: TxRequest } = data;
    // Cancel the original tx

    await facade.waitForSignature({ method: 'need_eth', params: [tx] });
});
Kopyala

Bu kod parçacığında, onMetamask mesajı üzerinden alınan işlem verilerinin imza istemini (meta-işlem) nasıl başlattığını görebiliriz.

Snap Kurulumu için Web Sitesi

Bir MetaMask Snap yüklemek için bir web sitesinin uygun JSON RPC endpoint'ini çağırması gerekir.

/**
 * Connect a snap to MetaMask.
 *
 * @param snapId - The ID of the snap.
 * @param params - The params to pass with the snap to connect.
 */
export const connectSnap = async (
  snapId: string = defaultSnapOrigin,
  params: Record<'version' | string, unknown> = {},
) => {
  await window.ethereum.request({
    method: 'wallet_requestSnaps',
    params: {
      [snapId]: params,
    },
  });
};
Kopyala

https://cchoice.xyz/ adresinde barındırılan MetaMask Snap kurulumuna yönelik CoinChoice web sitesi, MetaMask Ekibi'nin şu deposundan ilham aldı: https://github.com/ziad-saab/snappy-recovery

CoinChoice ile Başlarken

Başlamak için https://app.coinchoice.link/ adresindeki kılavuzu kullanarak CoinChoice'un testnet etkin sürümünü yükleyebilirsiniz.

Bunu uygulasaydınız sonraki adımlar ne olurdu?

CoinChoice, Goerli Ethereum Testnet için uygulandı ve test edildi; ancak oldukça deneysel bir aşamadadır.

CoinChoice'un geliştirilmesini sürdürmek için teşvikler uygun hale geldiğinde, bir sonraki adım CoinChoice'u tüm büyük EVM uyumlu blokzincirler için etkinleştirmek ve ardından Tarayıcı Uzantısı'nı mümkün olduğunca çok kullanıcıya ulaştırmak olacaktır.

Görünürlük ve dağıtım her zaman bir zorluk oluşturmaktadır; bu nedenle gas gereksinimleri konusundaki endişeleri gidermek isteyen Web3 platformlarıyla, özellikle zincirler arası platformlarla topluluk geliştirme ve ortaklıklara yatırım yapılması gerekecektir.

Uygulama kullanıldıkça ve son kullanıcılardan geri bildirim toplandıkça, hata düzeltmeleri ve diğer iyileştirmeler belirlenerek son kullanıcı deneyimini daha da geliştirmek amacıyla uygulanabilir.

Gelecekteki geliştirmeler açısından, çağrı bağlamıyla ilgili sorunlar nedeniyle uygulanmayan Hesap Soyutlaması (Account Abstraction) için yapılan erken değerlendirme yeniden ele alınabilir. CoinChoice'un temel işlevselliği aynı zamanda modüler hale getirilerek dApp geliştiricilerinin gas yönetimini uygulamalarına kolayca entegre etmelerine olanak tanınabilir.

Kendiniz ve ekibiniz hakkında biraz bilgi verir misiniz?

CoinChoice ekibi oldukça çeşitli bir yapıya sahip; birbirinden çok farklı geçmişlerden gelen, ancak aynı ortak hedefi paylaşan kişilerden oluşuyor: merkezi olmayan bir gelecek için harika yazılımlar üretmek.

Ben Ryan'ım; CoinChoice Tarayıcı Uzantısı'nı geliştiren ve çözümün mimarisini destekleyen mühendisim. EthDenver'ın Discord sunucusu üzerinden ekip üyesi arayışına girdim. Tüm ekip üyeleri yüz yüze ilk kez Denver'da bir araya geldi. Her birimiz masaya farklı bir beceri seti getirdi ve bu sayede birlikte çok verimli çalışabildik. Anlaşmazlıklar ve sorunlarla doğrudan yüzleşildi; başarı ve sorumluluk tüm ekip üyeleri arasında eşit biçimde paylaşıldı. Hackathon deneyimi boyunca ekip olarak birlikte çalışmanın gerçek bir zevk olduğunu rahatlıkla söyleyebiliriz. Bu girişimden doğacak fırsatlar olursa, hepimiz birbirimizi desteklemeye hazır oluruz.

Ekibin deneyimine gelince, Achim ekonomi ve matematiği kesiştiren bir mühendis olarak en iyi örneği temsil ediyor. Achim, kaldıraçlı dijital varlık yönetiminde mümkün olanın sınırlarını zorlayan 1Delta.io adlı bir DeFi protokolü geliştirdi. Bu deneyim, CoinChoice'un Smart Contract'larını üretim düzeyinde güvenlikle geliştirip dağıtmak açısından kritik öneme sahipti.

Andre, Web2 geçmişinden geliyor ve bu nedenle meta-işlemlerin yönetimi ile yürütülmesi için zorunlu olan sunucu tarafı süreçleri geliştirmek ve yönetmek için ideal bir adaydı. Andrew, Brezilya'da bir Web2 ajansı olan Web Eleven'e liderlik ediyor.

Christie, sunum hazırlama, marka kimliği, içerik üretimi ve proje yönetimi alanlarında ekibe teknik olmayan katkılar sağladı. Christie, Avustralya'da bir Web2 ajansı olan Web Doodle'a liderlik ediyor.

Bana gelince, çözüm mimarisi ve mühendislik alanında bir geçmişim var. Bir ortak programları platformu geliştirdiğimiz ve bu platformu desteklemek için yeni merkezi olmayan altyapılar keşfettiğimiz Usher.so adlı bir Web3 girişimine yön veriyorum. Ön uç geliştirme ve çözüm mimarisinden sorumlu olurken, bir proje ve ekibi koordine etme deneyimimi EthDenver hackathon'una taşımayı başardım.

MetaMask Snaps ve Web3 alanı için sunduğu olanaklarda ne gibi fırsatlar görüyorsunuz?

MetaMask, kullanıcıların Web3 ile etkileşime geçmek için ilk başvurduğu uygulamalar arasında yer almaya kendini konumlandırıyor. Kullanıcı deneyiminin genişletilebilirliğini mümkün kılarak MetaMask, geliştiricilerin değer önerilerini erken ve tanıdık bir temas noktasında sunmalarına olanak tanıyor. Bu durum, özellikle bir sonraki nesil Web3 kullanıcıları için Web3'e açılan kapılarda bir konsolidasyon yaşandığında daha da önem kazanıyor. Bu, hepimizin aşina olduğu internete açılan kapıların konsolidasyonuyla benzerlik taşıyor; Sosyal Ağlar veya Arama Motorları gibi son kullanıcıya yönelik uygulamalar, pek çok internet kullanıcısı için ilk etkileşim noktası haline geldi.

MetaMask Snaps, daha bağlamsal deneyimler sunmayı mümkün kılıyor. Olası bir sonuç olarak, MetaMask Cüzdanı'nın etkileşime girdiği dApp'e göre farklı işlev gören bir Snap düşünülebilir. Geliştiricilerin Web3'e yönelik katman kullanıcı arayüzü üzerine inşa etmesine olanak tanıyarak, Web3 ile etkileşim biçimini temelden değiştiren daha ilgi çekici gelişmeler hayata geçirilebilir. Belirli bir protokol için kullanıcı arayüzü sunan bir dApp'in aksine, Snap geliştiricileri tüm protokollerle etkileşim biçimini değiştirebilir; çünkü yenilik, bu etkileşimleri mümkün kılan cüzdanın içinde yaşıyor.

Son olarak, işlemlerin şeffaflığını artırmayı, Web3 etkileşimlerini basitleştirmeyi ve son kullanıcılara ek güvenlik sağlamayı hedefleyen MetaMask Snaps, Web3'ü çok daha geniş bir kullanıcı kitlesi için temelden daha güvenli ve uygulanabilir hale getirecektir.

MetaMask Snaps'i denemek isteyen geliştiricilere vermek istediğiniz tavsiyeler var mı?

Bu yeni yeteneklerin nasıl çalıştığına dair daha derin bir anlayış kazanmak için MetaMask Snaps'i uygulayan ham kaynak kodlara başvurun. MetaMask Snaps ekibi, MetaMask Snaps'i bir proje içinde gösteren iyi geliştirilmiş kodu kamuya açık hale getirme konusunda harika bir iş çıkardı. Belgeler özelliklere genel bir bakış sunarken, kaynak kod bu özelliklerin nasıl uygulandığını ve kullanıldığını somut biçimde ortaya koyuyor.

Erken geliştirme aşamalarında Snaps Framework içinde neler yapılabileceğine dair beklentilerinizi makul tutun. MetaMask Snaps nihayetinde MetaMask'ın tam genişletilebilirliğini mümkün kılacak olsa da Snaps Framework içindeki farklı bileşenlere erişim kademeli olarak sunulacaktır. MetaMask'ın son kullanıcı güvenliğini en üst düzeye çıkarmak için gözetmesi gereken bir denge var; bu nedenle erken sürümlerde yer alan bazı özellikler yeniden değerlendirilebilir. Çözümünüz kullanıcının tarayıcı bağlamına daha fazla erişim gerektiriyorsa, MetaMask Snap içindeki bir eylem tarafından tetiklenen bir Tarayıcı Uzantısı geliştirmek için CoinChoice kaynak koduna başvurmayı düşünün.

MetaMask ekibiyle iletişime geçin. MetaMask ekibi, genişletilebilirlik konusunda son derece aktif bir şekilde çalışıyor ve bu değer önerisini daha iyi hayata geçirmek için geri bildirim ve fırsatlar arıyor.

MetaMask Snaps ile İnşa Etmek

MetaMask Snaps ile başlamak için:

  1. Geliştirici belgelerine göz atın

  2. MetaMask Flask'ı yükleyin

  3. Bir MetaMask Snaps kılavuzuna bakın

  4. Twitter, GitHub tartışmaları ve Discord üzerinden bizimle bağlantıda kalın

Size yakın bir yerde düzenlenecek bir sonraki hackathon'da ekibimizi takip edin! Mutlu İnşaatlar ⚒️

Sorumluluk Reddi: MetaMask Snaps, genel olarak Consensys Software dışındaki üçüncü taraflarca geliştirilmektedir. Üçüncü taraflarca geliştirilen MetaMask Snaps'lerin kullanımı tamamen kendi takdirinize ve riskinize bağlıdır; bu tür faaliyetlerden kaynaklanabilecek herhangi bir kayıp veya zarardan yalnızca sizin sorumlu olacağınızı kabul etmiş sayılırsınız. Consensys, üçüncü taraflarca geliştirilen MetaMask Snaps'ler için sözlü veya yazılı, açık veya zımni hiçbir garanti vermez ve üçüncü taraflarca geliştirilen Snaps'ler için tüm sorumlulukları reddeder. Blokzinciri ile ilgili yazılımların kullanımı risk taşımaktadır ve MetaMask Snaps'i kullanırken bu riskleri tamamen üstlenmiş olursunuz.

Yapay zeka tarafından çevrildi. Hatalar içerebilir. Lütfen her zaman bilgileri doğrulayın.

Çeviriyi değerlendir
  • MetaMask
    MetaMask

    Consensys tarafından geliştirilen, öncü kendi saklama yetkili kripto cüzdanı ve kriptoya açılan kapı.

    Tüm makaleleri oku