UNPKG

@mai3/phaser-sdk

Version:

A UI component library based on the Phaser game engine

390 lines (389 loc) 17.7 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import { getHttpV4Endpoint, TonConnectUI, Address, AssetsSDK, TonClient4, beginCell } from './external'; import { TonConnectSender } from './ton-connect-sender'; import { ProxyContentResolver } from './content-resolver'; /** * GameFiBase is a parent for every implementation of GameFi. * Game engine specific implementations like Phaser only needs to define * its own `create` and `createConnectButton` methods. */ var GameFiBase = /** @class */ (function () { function GameFiBase(params) { if (params.assetsSdk.sender == null) { throw new Error('Sender is not configured.'); } this.walletConnector = params.walletConnector; this.assetsSdk = params.assetsSdk; this.sender = params.assetsSdk.sender; if (params.merchant != null) { this.merchant = params.merchant; } } Object.defineProperty(GameFiBase.prototype, "wallet", { get: function () { if (this.walletConnector.wallet == null) { throw new Error('Connect a wallet before using it.'); } return this.walletConnector.wallet; }, enumerable: false, configurable: true }); Object.defineProperty(GameFiBase.prototype, "walletAccount", { get: function () { return this.wallet.account; }, enumerable: false, configurable: true }); Object.defineProperty(GameFiBase.prototype, "walletAddress", { get: function () { return Address.parseRaw(this.wallet.account.address); }, enumerable: false, configurable: true }); Object.defineProperty(GameFiBase.prototype, "merchantAddress", { get: function () { if (this.merchant == null || this.merchant.tonAddress == null) { throw new Error('To make payments with TON pass "merchant.tonAddress" parameter to "GameFi.create" method.'); } return this.merchant.tonAddress; }, enumerable: false, configurable: true }); Object.defineProperty(GameFiBase.prototype, "merchantJettonAddress", { get: function () { if (this.merchant == null || this.merchant.jettonAddress == null) { throw new Error('To make payments with jetton pass "merchant.jettonAddress" parameter to "GameFi.create" method.'); } return this.merchant.jettonAddress; }, enumerable: false, configurable: true }); /** * Send TON to merchant wallet address (in-game shop). */ GameFiBase.prototype.buyWithTon = function (params) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { this.transferTon(__assign(__assign({}, params), { to: this.merchantAddress })); return [2 /*return*/]; }); }); }; /** * Send TON to other wallet address. */ GameFiBase.prototype.transferTon = function (params) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (this.assetsSdk.sender == null) { throw new Error('Sender is not configured.'); } return [2 /*return*/, this.assetsSdk.sender.send({ to: params.to, value: params.amount, body: params.comment ? this.createMessagePayload(params.comment) : null })]; }); }); }; /** * Send jetton to merchant wallet address (in-game shop). */ GameFiBase.prototype.buyWithJetton = function (params) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { this.transferJetton(__assign(__assign({}, params), { to: this.merchantAddress })); return [2 /*return*/]; }); }); }; /** * Send jetton to other wallet address. */ GameFiBase.prototype.transferJetton = function (params) { return __awaiter(this, void 0, void 0, function () { var jetton, jettonWallet, options; return __generator(this, function (_a) { switch (_a.label) { case 0: jetton = this.assetsSdk.openJetton(this.merchantJettonAddress); return [4 /*yield*/, jetton.getWallet(this.walletAddress)]; case 1: jettonWallet = _a.sent(); options = { returnExcess: { address: this.walletAddress } }; if (params.customPayload != null) { options.customPayload = this.createMessagePayload(params.customPayload); } if (params.forwardAmount != null || params.forwardPayload != null) { options.notify = {}; if (params.forwardAmount != null) { options.notify.amount = params.forwardAmount; } if (params.forwardPayload != null) { options.notify.payload = this.createMessagePayload(params.forwardPayload); } } return [2 /*return*/, jettonWallet.send(this.sender, params.to, params.amount, options)]; } }); }); }; /** * Open NFT collection contract. */ GameFiBase.prototype.openNftCollection = function (address) { return this.assetsSdk.openNftCollection(address); }; /** * Open NFT sale contract. */ GameFiBase.prototype.openNftSale = function (address) { return this.assetsSdk.openNftSale(address); }; /** * Open NFT contract. */ GameFiBase.prototype.openNftItem = function (address) { return this.assetsSdk.openNftItem(address); }; /** * Get NFT item from collection using its index. */ GameFiBase.prototype.openNftItemByIndex = function (collectionAddress, itemIndex) { return __awaiter(this, void 0, void 0, function () { var nftAddress; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.assetsSdk .openNftCollection(collectionAddress) .getItemAddress(itemIndex)]; case 1: nftAddress = _a.sent(); return [2 /*return*/, this.assetsSdk.openNftItem(nftAddress)]; } }); }); }; /** * Open SBT collection contract. */ GameFiBase.prototype.openSbtCollection = function (address) { return this.assetsSdk.openSbtCollection(address); }; /** * Open Jetton contract. */ GameFiBase.prototype.openJetton = function (address) { return this.assetsSdk.openJetton(address); }; /** * Open Jetton Wallet contract. */ GameFiBase.prototype.openJettonWallet = function (address) { return this.assetsSdk.openJettonWallet(address); }; /** * Call connectWallet programmatically in case * you are not going to use TonConnectUI provided UI or game engine provided button * and you draw your own UI. */ GameFiBase.prototype.connectWallet = function (app) { return this.walletConnector.openSingleWalletModal(app); }; /** * Watch weather wallet was connected or disconnected. * Use the method to reflect it on the UI state. */ GameFiBase.prototype.onWalletChange = function () { var _a; var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } var unsubscribe = (_a = this.walletConnector).onStatusChange.apply(_a, params); // by default onStatusChange doesn't trigger when no wallet to restore // do manually trigger to user doesn't need to handle the case by himself this.walletConnector.connectionRestored.then(function (connected) { if (!connected) { params[0](null); } }); return unsubscribe; }; /** * Call connectWallet programmatically in case * you draw your own UI. */ GameFiBase.prototype.disconnectWallet = function () { return this.walletConnector.disconnect(); }; GameFiBase.prototype.createMessagePayload = function (message) { return beginCell().storeUint(0, 32).storeStringTail(message).endCell(); }; /** * Prepares dependencies to game engine implementations use it for `create` method. * These dependencies will be used to create an GameFi instance further. */ GameFiBase.createDependencies = function () { return __awaiter(this, arguments, void 0, function (params) { var connector, client, _a, network, merchant, walletConnector, tonClient, clientParams, endpoint, contentResolverParams, _b, ipfsGateway, urlProxy_1, contentResolver, assetsSdk, dependencies; if (params === void 0) { params = {}; } return __generator(this, function (_c) { switch (_c.label) { case 0: connector = params.connector, client = params.client, _a = params.network, network = _a === void 0 ? 'testnet' : _a, merchant = params.merchant; walletConnector = GameFiBase.isTonConnectUiInstance(connector) ? connector : GameFiBase.createConnectUiWorkaround(connector); if (!(client instanceof TonClient4)) return [3 /*break*/, 1]; tonClient = client; return [3 /*break*/, 5]; case 1: clientParams = void 0; if (!(client == null)) return [3 /*break*/, 3]; return [4 /*yield*/, getHttpV4Endpoint({ network: network })]; case 2: endpoint = _c.sent(); clientParams = { endpoint: endpoint }; return [3 /*break*/, 4]; case 3: clientParams = client; _c.label = 4; case 4: tonClient = new TonClient4(clientParams); _c.label = 5; case 5: contentResolverParams = {}; if (params.contentResolver != null) { _b = params.contentResolver, ipfsGateway = _b.ipfsGateway, urlProxy_1 = _b.urlProxy; if (ipfsGateway != null) { contentResolverParams.ipfsGateway = ipfsGateway; } if (urlProxy_1 != null) { if (typeof urlProxy_1 === 'string') { contentResolverParams.urlProxy = function (url) { return urlProxy_1.replace(ProxyContentResolver.replaceable, url); }; } else { contentResolverParams.urlProxy = urlProxy_1; } } } contentResolver = new ProxyContentResolver(contentResolverParams); assetsSdk = AssetsSDK.create({ api: tonClient, contentResolver: contentResolver, sender: new TonConnectSender(walletConnector) }); dependencies = { walletConnector: walletConnector, assetsSdk: assetsSdk }; if (merchant != null) { dependencies.merchant = { tonAddress: GameFiBase.addressToObject(merchant.tonAddress) }; if (merchant.jettonAddress != null) { dependencies.merchant.jettonAddress = GameFiBase.addressToObject(merchant.jettonAddress); } } return [2 /*return*/, dependencies]; } }); }); }; GameFiBase.addressToObject = function (address) { if (typeof address === 'string') { return Address.parse(address); } return address; }; GameFiBase.isTonConnectUiInstance = function (instance) { // because TonConnectUI cleared outside of the lib, in a consumer app // instance instanceof TonConnectUI returns false // so we need implement the check differently // todo figure out how to fix return typeof instance === 'object' && instance != null && 'openModal' in instance; }; GameFiBase.createConnectUiWorkaround = function (params) { if (params === void 0) { params = {}; } // we need 100% TonConnectUI functionality, but without visual parts // to reuse the logic, but not to implement fork, use the workaround // todo remove this workaround var hide = function (element) { element.style.overflow = 'hidden'; element.style.display = 'none'; element.style.position = 'absolute'; element.style.left = '-9999px'; }; var buttonRoot = document.createElement('div'); buttonRoot.id = '__ton-connect-ui--button-root'; hide(buttonRoot); document.body.appendChild(buttonRoot); var widgetRoot = document.createElement('div'); widgetRoot.id = '__ton-connect-ui--widget-root'; hide(widgetRoot); document.body.appendChild(widgetRoot); return new TonConnectUI(__assign(__assign({}, params), { buttonRootId: buttonRoot.id, widgetRootId: widgetRoot.id })); }; return GameFiBase; }()); export { GameFiBase };