UNPKG

@kippurocks/libticketto-papi

Version:

A Kippu implementation of The Ticketto Protocol with Polkadot-API

251 lines (250 loc) 9.8 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { inject } from "inversify"; import { TOKEN, } from "./types.js"; import { TransactionSubmitter } from "./submitter.js"; import { Binary } from "polkadot-api"; import { TickettoModelConverter } from "./tickettoModel.js"; let KippuTicketsCalls = class KippuTicketsCalls { accountProvider; api; tickets; submitter; merchantId; constructor(accountProvider, api, tickets, submitter, merchantId) { this.accountProvider = accountProvider; this.api = api; this.tickets = tickets; this.submitter = submitter; this.merchantId = merchantId; } async issue(eventId) { const result = await this.tickets.query("issue_ticket", { origin: this.accountProvider.getAccountId(), data: { event_id: eventId, }, }); if (!result.success) { throw new Error(result.value.type); } let ticketId = result.value.response; const tx = this.tickets.send("issue_ticket", { data: { event_id: eventId, }, gasLimit: result.value.gasRequired, }); await this.submitter.signAndSubmit(tx); return ticketId; } submitAttendanceCall(input) { return this.submitter.quickSubmit(Binary.fromBytes(input)); } async initiatePendingTransfer(eventId, id, beneficiary) { const data = { event_id: eventId, ticket_id: id, beneficiary, }; const result = await this.tickets.query("initiate_pending_transfer", { origin: this.accountProvider.getAccountId(), data, }); if (!result.success) { throw new Error(result.value.type); } const tx = this.tickets.send("initiate_pending_transfer", { data, gasLimit: result.value.gasRequired, }); await this.submitter.signAndSubmit(tx); } async acceptPendingTransfer(eventId, id) { const data = { event_id: eventId, ticket_id: id, }; const result = await this.tickets.query("accept_pending_transfer", { origin: this.accountProvider.getAccountId(), data, }); if (!result.success) { throw new Error(result.value.type); } const tx = this.tickets.send("accept_pending_transfer", { data, gasLimit: result.value.gasRequired, }); await this.submitter.signAndSubmit(tx); } async cancelPendingTransfer(eventId, id) { const data = { event_id: eventId, ticket_id: id, }; const result = await this.tickets.query("cancel_pending_transfer", { origin: this.accountProvider.getAccountId(), data, }); if (!result.success) { throw new Error(result.value.type); } const tx = this.tickets.send("cancel_pending_transfer", { data, gasLimit: result.value.gasRequired, }); await this.submitter.signAndSubmit(tx); } sell(_issuer, _id, _receiver) { // TODO: We'll implement this øn the second stage of the project. // // This is intended for reselling, and requires some changes in the protocol library // definition. throw new Error("Method not implemented."); } async withdrawSell(_eventId, _id) { // TODO: We'll implement this øn the second stage of the project. // // This needs a change in `pallet-listings` to allow clearing the price of an item. throw new Error("Method not implemented."); } async buy(issuer, id) { const orderId = await this.api.query.Orders.NextOrderId.getValue(); // Quickly creates the cart. We'll figure out the process of handling the cart // in a further protocol extension. await this.submitter.signAndSubmit(this.api.tx.Orders.create_cart({ maybe_items: [[[[2, issuer], id], undefined]], })); // Checkout and pay. This is the moment. await this.submitter.signAndSubmit(this.api.tx.Utility.batch({ calls: [ this.api.tx.Orders.checkout({ order_id: orderId }).decodedCall, this.api.tx.Orders.pay({ order_id: orderId }).decodedCall, ], })); } }; KippuTicketsCalls = __decorate([ __param(0, inject(TOKEN.ACCUNT_PROVIDER)), __param(1, inject(TOKEN.KREIVO_API)), __param(2, inject(TOKEN.TICKETS_CONTRACT)), __param(3, inject(TOKEN.SUBMITTER)), __param(4, inject(TOKEN.MERCHANT_ID)), __metadata("design:paramtypes", [Object, Object, Object, TransactionSubmitter, Number]) ], KippuTicketsCalls); export { KippuTicketsCalls }; let KippuTicketsStorage = class KippuTicketsStorage { accountProvider; api; tickets; submitter; merchantId; converter; constructor(accountProvider, api, tickets, submitter, merchantId, converter) { this.accountProvider = accountProvider; this.api = api; this.tickets = tickets; this.submitter = submitter; this.merchantId = merchantId; this.converter = converter; } async get(eventId, id) { const response = await this.tickets.query("get", { origin: this.accountProvider.getAccountId(), data: { event_id: eventId, ticket_id: id, }, }); if (!response.success || response.value.response === undefined) { return undefined; } const ticket = response.value.response; return { id, eventId, attendancePolicy: this.converter.intoTickettoAttendancePolicy(ticket.attendance_policy), attendances: new Array(ticket.attendances.count).fill(ticket.attendances.last), restrictions: { cannotResale: ticket.restrictions.cannot_resale, cannotTransfer: ticket.restrictions.cannot_transfer, }, price: ticket.price ? { amount: ticket.price.amount, asset: await this.converter.assetMetadata(ticket.price.asset), } : undefined, }; } async all(eventId) { const items = await this.api.query.ListingsCatalog.Item.getEntries([ this.merchantId, eventId, ]); return Promise.all(items.map(({ keyArgs: [[, eventId], id] }) => this.get(eventId, id))).then((ts) => ts.filter((t) => t !== undefined)); } async ticketHolderOf(who, eventId) { const items = eventId !== undefined ? await this.api.query.ListingsCatalog.Account.getEntries(who, [ this.merchantId, eventId, ]) : await this.api.query.ListingsCatalog.Account.getEntries(who); return Promise.all(items.map(({ keyArgs: [, [m, eventId], id] }) => m === this.merchantId ? this.get(eventId, id) : undefined)).then((ts) => ts.filter((t) => t !== undefined)); } async attendances(eventId, id) { const data = { event_id: eventId, ticket_id: id, }; const response = await this.tickets.query("attendances", { origin: this.accountProvider.getAccountId(), data, }); if (!response.success) { throw new Error(response.value.type); } return new Array(response.value.response.count).fill(response.value.response.last); } async pendingTransfersFor(who) { // TODO: This implementation definitely needs the indexer. Until // we got it, it's better not to deal with it. throw new Error("Method not implemented"); } async attendanceRequest(eventId, id) { // This implementation doesn't care about weight limits since it's // already too small. // // TODO: Ideally, sign this using the offline signer. const { normal: gasLimit } = await this.api.query.System.BlockWeight.getValue(); return this.submitter.signTx(this.tickets.send("mark_attendance", { data: { event_id: eventId, id, }, gasLimit, })); } }; KippuTicketsStorage = __decorate([ __param(0, inject(TOKEN.ACCUNT_PROVIDER)), __param(1, inject(TOKEN.KREIVO_API)), __param(2, inject(TOKEN.TICKETS_CONTRACT)), __param(3, inject(TOKEN.SUBMITTER)), __param(4, inject(TOKEN.MERCHANT_ID)), __param(5, inject(TickettoModelConverter)), __metadata("design:paramtypes", [Object, Object, Object, TransactionSubmitter, Number, TickettoModelConverter]) ], KippuTicketsStorage); export { KippuTicketsStorage };