solana-options
Version:
Minting of options contract NFTs on the Solana blockchain
273 lines (272 loc) • 11.7 kB
JavaScript
;
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;