Ana içeriğe geç

Teklif Yapma

Teklif Yapma

Eğer buraya kadar geldiyseniz, bir cüzdana bağlanan, kullanıcının IST cüzdan bakiyesini gösteren ve chainStorageWatcher ile zinciri okuyan bir React uygulaması oluşturmuşsunuz demektir. Herhangi bir sorunla karşılaştıysanız, referans için dalına göz atabilirsiniz.

Bu son eğitimde, uygulamanızdan teklifler yapmayı öğrenecek, her şeyi kullanıcı için temel bir uçtan uca deneyimde birleştireceksiniz.

UI Oluşturma

Bir teklif göndermeden önce, kullanıcının istedikleri öğeleri belirtmesi için bazı temel girişler oluşturmamız gerekiyor. Sözleşmede satış için mevcut 3 tür öğe bulunmaktadır, bu yüzden Trade.tsx dosyasında bunları listelemek için bir dizi oluşturun:

const allItems = ['scroll', 'map', 'potion'];

Sonra, kullanıcının teklifteki her bir öğenin miktarını seçebilmesi için Trade.tsx dosyasına başka bir bileşen ekleyin:

const Item = ({
label,
value,
onChange,
inputStep
}: {
label: string;
value: number | string;
onChange: React.ChangeEventHandler;
inputStep?: string;
}) => (

{label}


);

Ve App.css dosyasına bazı stiller ekleyin:

.item-col {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 15px 25px 15px;
margin: 5px;
}

.row-center {
display: flex;
flex-direction: row;
align-items: center;
}

.input {
border: none;
background: #242424;
text-align: center;
padding: 5px 10px;
border-radius: 8px;
font-size: 1.2rem;
width: 75px;
}

.input[type='number']::-webkit-inner-spin-button {
opacity: 1;
}

Şimdi, Trade bileşeninizde listedeki her biri için bir Item render edin:

const Trade = () => {
...

const [choices, setChoices] = useState>({
map: 1n,
scroll: 2n,
});

const changeChoice = (ev: FormEvent) => {
if (!ev.target) return;
const elt = ev.target as HTMLInputElement;
const title = elt.title;
if (!title) return;
const qty = BigInt(elt.value);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { [title]: _old, ...rest } = choices;
const newChoices = qty > 0 ? { ...rest, [title]: qty } : rest;
setChoices(newChoices);
};

return (

İstediğiniz: En fazla 3 öğe seçin

{allItems.map(title => (

))}


);
}

Gördüğünüz gibi, choices'ı bir useState kancası ile saklıyorsunuz. Böylece, kullanıcı girişleri değiştirdikçe, her tür öğenin sayısı güncelleniyor. Daha sonra choices kullanarak teklifi belirleyeceksiniz.

Sonraki adımda, kullanıcının öğeler için vermek istediği IST miktarını belirtmesi için bir giriş alanı ekleyeceksiniz. Öncelikle önceden oluşturduğunuz usePurse ile IST cüzdanına bir referans alın ve IST değeri için bir durum kancası oluşturun:

const Trade = () => {
const istPurse = usePurse('IST');
const [giveValue, setGiveValue] = useState(0n);

...
}

Sonra, IST "verme" miktarı için bir giriş eklemek üzere `` bileşenini kullanın:

import { AmountInput } from '@agoric/react-components';

...

// 'Trade' bileşeninde:
{istPurse && (
<>
Verilecek: En az 0.25 IST




)}

Teklif Gönderme

Bu bileşenler oluşturulduğunda, kullanıcı öğe ve IST miktarlarını seçebilir ve uygulama bunları durumunda saklayabilir. Şimdi, seçilen miktarlarla akıllı sözleşmeye bir teklif yapmak için makeOffer fonksiyonunu nasıl kullanacağınızı göreceksiniz.

Daha önce Trade bileşeninize eklediğiniz useContract kancasını hatırlayın. Teklifi göndermek için markaları ve örneği ihtiyaç duyacaksınız:

const { brands, instance } = useContract();

Ardından, useAgoric() kancasından makeOffer fonksiyonunu alın:

const { makeOffer } = useAgoric();

Şimdi teklifi göndermek için bir fonksiyon oluşturun. Bunun nasıl çalıştığına dair daha fazla bilgi için dokümanına bakın:

import { makeCopyBag } from '@agoric/store';

// 'Trade' bileşeninin içinde:
const submitOffer = () => {
assert(brands && instance && makeOffer);
const value = makeCopyBag(Object.entries(choices));
const want = { Items: { brand: brands.Item, value } };
const give = { Price: { brand: brands.IST, value: giveValue } };

makeOffer(
{
source: 'contract',
instance,
publicInvitationMaker: 'makeTradeInvitation'
},
{ give, want },
undefined,
(update: { status: string; data?: unknown }) => {
console.log('GÜNCELLEME', update);
if (update.status === 'error') {
alert(`Teklif hatası: ${update.data}`);
}
if (update.status === 'accepted') {
alert('Teklif kabul edildi');
}
if (update.status === 'refunded') {
alert('Teklif reddedildi');
}
}
);
};

Tekliflerin nasıl çalıştığı hakkında özel bilgiler için belgesine bakın. makeOffer fonksiyonu, bir InvitationSpec belirtmenizi sağlar, otomatik olarak verilerin marshalling işlemini gerçekleştirir ve teklif durumuna yapılan güncellemeleri kolayca yönetmenize olanak tanır.

Yeni yazdığınız fonksiyon, sözleşmenin anlayabileceği şekilde öğe miktarını oluşturmak için makeCopyBag yardımcı fonksiyonunu kullanır. Bunu bağımlılıklarınıza ekleyin:

yarn add -D @agoric/store@0.9.2

Ve vite-env.d.ts dosyasına türü ekleyin:

declare module '@agoric/store' {
export const makeCopyBag;
}

Artık, teklifi göndermek için bir buton ekleyin:

{
!!(brands && instance && makeOffer && istPurse) && (
Teklif Yap
);
}

Teklife tıkladığınızda, seçtiğiniz "Verilecek" ve "İstenecek"lerle birlikte bir Keplr penceresinin onay verme isteği ile açıldığını görmelisiniz. 3 öğe seçmeyi ve 0.25 IST vermeyi deneyin; teklif kabul edilmelidir. 3'ten fazla öğe seçerseniz ya da 0.25 IST'den az verirseniz, teklif reddedilmelidir ve IST'niz geri alınmalıdır (bkz. ).

Öğelerin Cüzdanını Görsel Olarak Gösterme

Öyleyse, başarılı bir teklif verdiniz ve bazı öğeler aldınız, ama onlar nerede? Öğeleri IST cüzdanına benzer bir şekilde görselleştirebilirsiniz. Purses.tsx dosyasına aşağıdakileri ekleyin:

...

const itemsPurse = usePurse('Item');
...


Öğeler:
{itemsPurse ? (

{itemsPurse.currentAmount.value.payload.map(
// @ts-expect-error 'any' türünü görmezden gel
([name, number]) => (

{String(number)} {name}

)
)}

) : (
'Yok'
)}

Şimdi, başka bir teklif yapın ve teklif kabul edildikten sonra öğeler cüzdanınızın otomatik olarak güncellendiğini görün. Bu örnek için tam çözümü görmek için dalına göz atın.

Sonuç

Uygulama sonrası neye benzediğini merak ediyor musunuz? Uygulamanın sonucunu görmek için göz atabilirsiniz.