UNPKG

solana-options

Version:

Minting of options contract NFTs on the Solana blockchain

273 lines (272 loc) 11.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.publish_doc = exports.create_doc_img = void 0; const jimp_1 = __importDefault(require("jimp")); const util_1 = __importDefault(require("util")); const dayjs_1 = __importDefault(require("dayjs")); const qrcode_1 = __importDefault(require("qrcode")); const spl_token_registry_1 = require("@solana/spl-token-registry"); const axios_1 = __importDefault(require("axios")); const utils_1 = require("./utils"); const HEIGHT = 700; const WIDTH = 600; const CALL_CONTRACT = "This contract gives holder of this token the right but not obligation to buy %d units of %s tokens" + " at a price of %d %s tokens per unit at or before %s"; const PUT_CONTRACT = "This contract gives holder of this token the right but not obligation to sell %d units of %s tokens" + " at a price of %d %s tokens per unit at or before %s"; let TOKEN_LIST = null; const ENDPOINT = "https://nftoptions.app/contract/"; function write_doc_img(contract, image) { return new Promise(async (resolve, reject) => { // console.log("writing to img", contract) // console.log("exp", Math.round(contract.expiry)) let font = await jimp_1.default.loadFont(jimp_1.default.FONT_SANS_16_BLACK); let logo = null; let line = 0; function load_logo(url, cb, xx, yy) { function load_logo_cb(err, image, { x, y }) { if (y && y > line) { line = y; } jimp_1.default.read(url).then(logo_img => { logo_img.resize(18, 18, (e, l) => { image.blit(l, xx || x, yy || y, cb); }); }).catch(err => reject(err)); } return load_logo_cb; } function contract_txt(err, image, coord) { console.log("writing contract txt"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } var msg = ""; get_token(contract.instrument, (instr_tok) => { get_token(contract.strike_instrument, (strike_tok) => { var inst_sym = contract.instrument; var strike_sym = contract.strike_instrument; if (instr_tok) { console.log("instr tok", instr_tok); inst_sym = instr_tok.symbol || inst_sym; } if (strike_tok) { strike_sym = strike_tok.symbol || strike_sym; } if (contract.kind == "call") { msg = util_1.default.format(CALL_CONTRACT, contract.multiple, inst_sym, contract.strike, strike_sym, (0, dayjs_1.default)(Math.round(contract.expiry * 1000)).format("DD MMM, YYYY")); } else { // put msg = util_1.default.format(PUT_CONTRACT, contract.multiple, inst_sym, contract.strike, strike_sym, (0, dayjs_1.default)(Math.round(contract.expiry * 1000)).format("DD MMM, YYYY HH:mm:ss Z")); } image.print(font, 30, line + 30, { text: msg, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH - 40, (err, img) => { if (err) return reject(err); resolve(img); }); }); }); } function qqrcode(err, image, coord) { console.log("writing qrcode"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } let data_url = qrcode_1.default.toDataURL("https://nftoptions.app?nft=" + contract.nft_id); data_url.then(url => { // console.log(url) const [, data] = url.split(','); jimp_1.default.read(Buffer.from(data, 'base64')).then(qrimg => { let [w, h] = [200, 200]; let margin = 60; line = line + margin + h; qrimg.resize(w, h, (e, qrimg) => { image.blit(qrimg, 300 - w / 2, line - h, contract_txt); }); }).catch(err => reject(err)); }).catch(err => reject(err)); } function nft_token_id(err, image, coord) { console.log("writing nft token id"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } image.print(font, 30, line + 10, { text: 'NFT ID: ' + contract.nft_id, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, qqrcode); } function account(err, image, coord) { console.log("writing account"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } image.print(font, 30, line + 50, { text: 'ACCOUNT ID: ' + contract.account_id, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, nft_token_id); } function expiry(err, image, coord) { console.log("writing expiry"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } image.print(font, 30, line + 10, { text: 'EXPIRY: ' + (0, dayjs_1.default)(Math.round(contract.expiry * 1000)).format("DD MMM, YYYY HH:mm:ss Z"), alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, account); } function multiple_fn(err, image, coord) { console.log("writing multiple"); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } image.print(font, 30, line + 10, { text: 'MULTIPLE: ' + contract.multiple, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, expiry); } function strike_token(err, image, coord) { console.log("writing strike token", err, coord); if (err) return reject(err); let pos = coord || { x: 0, y: 0 }; if (pos.y && pos.y > line) { line = pos.y; } get_token(contract.strike_instrument, (tokl) => { if (tokl) { let tok = tokl; logo = tok.logoURI; image.print(font, 30, line + 10, { text: 'STRIKE: ' + contract.strike + ' ' + tok.symbol, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, load_logo(logo, multiple_fn, null, line + 10)); } else { image.print(font, 30, line + 10, { text: 'STRIKE: ' + contract.strike + ' ' + contract.strike_instrument, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, multiple_fn); } }); } function instrument(err, image) { console.log("writing instruments"); if (err) return reject(err); get_token(contract.instrument, (tokl) => { if (tokl) { let tok = tokl; logo = tok.logoURI; image.print(font, 30, 60, { text: 'INSTRUMENT: ' + tok.symbol, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, load_logo(logo, strike_token, null, 60)); } else { image.print(font, 30, 60, { text: 'INSTRUMENT: ' + contract.instrument, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_LEFT, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH - 30, strike_token); } }); } function title(header) { console.log("writing title"); image.print(font, 0, 20, { text: header, alignmentX: jimp_1.default.HORIZONTAL_ALIGN_CENTER, alignmentY: jimp_1.default.VERTICAL_ALIGN_MIDDLE }, WIDTH, instrument); } if (contract.kind == "call") { title('CALL OPTION CONTRACT'); } else { title('PUT OPTION CONTRACT'); } }); } function create_doc_img(contract) { return new Promise((resolve, reject) => { new jimp_1.default(WIDTH, HEIGHT, "#eeeee4", async (err, image) => { if (err) reject(err); let img = await write_doc_img((0, utils_1.print_contract)(contract), image); resolve(img); }); }); } exports.create_doc_img = create_doc_img; function get_token(mint, cb) { if (TOKEN_LIST) { let res = TOKEN_LIST.filter(t => t.address == mint); if (res.length > 0) return cb(res[0]); return cb(null); } else { new spl_token_registry_1.TokenListProvider().resolve().then((tokens) => { const tokenList = tokens.filterByClusterSlug('mainnet-beta').getList(); TOKEN_LIST = tokenList; get_token(mint, cb); }).catch(err => { throw err; }); } // const Icon = (props: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }) => { // const [tokenMap, setTokenMap] = useState<Map<string, TokenInfo>>(new Map()); // useEffect(() => { // new TokenListProvider().resolve().then(tokens => { // const tokenList = tokens.filterByChainId(ENV.MainnetBeta).getList(); // setTokenMap(tokenList.reduce((map, item) => { // map.set(item.address, item); // return map; // },new Map())); // }); // }, [setTokenMap]); // const token = tokenMap.get(props.mint); // if (!token || !token.logoURI) return null; // return token // } } async function publish_doc(contract, url = ENDPOINT) { let contract_json = (0, utils_1.print_contract)(contract); let res = await axios_1.default .post(ENDPOINT, contract_json); return res; } exports.publish_doc = publish_doc;