UNPKG

solana-options

Version:

Minting of options contract NFTs on the Solana blockchain

252 lines (251 loc) 18.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); // import { SystemProgram } from "@solana/web3.js"; const web3_js_1 = require("@solana/web3.js"); const web3_js_2 = require("@solana/web3.js"); // import PrintClass from "jimp" const chai_1 = require("chai"); // const expect = require('chai').expect; const chai_2 = require("chai"); // var sinon = require("sinon"); // import {sinon} from "sinon" const sinon_1 = __importDefault(require("sinon")); const rewire_1 = __importDefault(require("rewire")); let [sol_key, usd_key] = [new web3_js_1.Keypair().publicKey.toString(), new web3_js_1.Keypair().publicKey.toString()]; let sol_options = (0, rewire_1.default)("./"); const _1 = require("."); const doc_1 = require("./doc"); const jimp_1 = __importDefault(require("jimp")); const qrcode_1 = __importDefault(require("qrcode")); // import { create_call, excercise_call, OptionType } from pack; // pack.cre // let [create_call, excercise_call, OptionType] = [sol_options.create_call, sol_options.exercise_call,sol_options.OptionType] const programId = "4ktt843KtvduVq7yDdSXoTpt8uev4tBFue2pot7NdiRR"; const bob_private_key = [58, 61, 83, 12, 252, 164, 114, 167, 16, 61, 196, 241, 213, 70, 111, 76, 253, 145, 3, 249, 205, 251, 23, 52, 237, 158, 140, 188, 84, 202, 116, 216, 78, 242, 2, 9, 33, 177, 53, 200, 7, 221, 76, 53, 149, 13, 243, 125, 153, 187, 239, 178, 76, 197, 203, 88, 218, 186, 174, 108, 71, 19, 254, 203]; let creator_strike_instrument_acc = new web3_js_2.PublicKey('8Tv1h2eNjhfQJXyNR3Ey8WwoHAF1qZW7s7aNH49oCMBP'); let creator_instrument_acc = new web3_js_2.PublicKey("GsnpfUQTFnQBuokhttUajopkEeg4YNgwf7j2SSKhRigJ"); let creator_acc = web3_js_1.Keypair.fromSecretKey(new Uint8Array(bob_private_key)); const connection = new web3_js_2.Connection("http://localhost:8899", 'singleGossip'); // setup some stubs let get_rent = sinon_1.default.fake(); sinon_1.default.replace(connection, "getMinimumBalanceForRentExemption", get_rent); let confirm_tx = sinon_1.default.fake(); sinon_1.default.replace(connection, "confirmTransaction", confirm_tx); let send_tx = sinon_1.default.fake(); sinon_1.default.replace(connection, "sendTransaction", send_tx); const mocked_keypair = new web3_js_1.Keypair(); let find_address_stub = sinon_1.default.stub(); sinon_1.default.replace(web3_js_2.PublicKey, "findProgramAddress", find_address_stub); find_address_stub.returns([mocked_keypair.publicKey, 42]); afterEach(function () { sinon_1.default.resetHistory(); }); describe('create call', function () { it('create call contract using existing public keys without error', async function () { let strike = 100; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_call)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); (0, chai_2.expect)(contract.instrument.toString()).to.equal(instrument.toString(), "inst value"); (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(strike_instrument.toString(), "strike instr value"); // expect(contract.nft_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft id") (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); // expect(contract.account_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "account id") (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_strike_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(_1.OptionType.call); (0, chai_2.expect)(send_tx.callCount).to.equal(1, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(2, "find address used twice"); }).catch(); }); it('create call contract using minted nft instrument without error', async function () { let strike = 101; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; // let instrument = new PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf') let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_call)(connection, strike, expiry, multiple, creator_acc, null, strike_instrument, null, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); // expect(contract.instrument.toString()).to.equal(instrument.toString(), "inst value") (0, chai_2.expect)(contract.instrument).to.be.a("object"); (0, chai_2.expect)(contract.instrument).to.be.ok; (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(strike_instrument.toString(), "strike instr value"); (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_strike_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(_1.OptionType.call); (0, chai_2.expect)(send_tx.callCount).to.equal(2, "tx sent only once"); (0, chai_2.expect)(confirm_tx.callCount).to.equal(1, "nft mint confirmed"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(4, "find address used twice"); }).catch(); }); it('create call contract using symbols without error', async function () { let strike = 101; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; // let instrument = new PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf') // let strike_instrument = new PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ') let fake_tok_list = [{ symbol: "SOL", address: sol_key }, { symbol: "USDC", address: usd_key }]; sol_options.__set__("TOKEN_LIST", fake_tok_list); console.log("using token list", fake_tok_list); let [create_call, excercise_call, OptionType] = [sol_options.create_call, sol_options.exercise_call, sol_options.OptionType]; return create_call(connection, strike, expiry, multiple, creator_acc, "USDC", "SOL", creator_instrument_acc, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.instrument.toString()).to.be.equal(usd_key, "use USD token"); (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(sol_key, "use SOL strike instr value"); (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); (0, chai_2.expect)(contract.kind).to.equal(OptionType.call); (0, chai_2.expect)(send_tx.callCount).to.equal(1, "tx sent only once"); (0, chai_2.expect)(confirm_tx.callCount).to.equal(0, "nft mint confirmed"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(2, "find address used twice"); }).catch(); }); it('create call contract using minted nft instrument and symbol strike instrument without error', async function () { let strike = 101; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let fake_tok_list = [{ symbol: "SOL", address: sol_key }, { symbol: "USDC", address: usd_key }]; sol_options.__set__("TOKEN_LIST", fake_tok_list); console.log("using token list", fake_tok_list); let [create_call, excercise_call, OptionType] = [sol_options.create_call, sol_options.exercise_call, sol_options.OptionType]; return create_call(connection, strike, expiry, multiple, creator_acc, null, "SOL", null, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); // expect(contract.instrument.toString()).to.equal(instrument.toString(), "inst value") (0, chai_2.expect)(contract.instrument).to.be.a("object"); (0, chai_2.expect)(contract.instrument).to.be.ok; (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(sol_key.toString(), "strike instr value"); (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_strike_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(OptionType.call); (0, chai_2.expect)(send_tx.callCount).to.equal(2, "tx sent only once"); (0, chai_2.expect)(confirm_tx.callCount).to.equal(1, "nft mint confirmed"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(4, "find address used twice"); }).catch(); }); it('create call contract then close it without error', async function () { let strike = 100; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_call)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc).then(([sig, contract]) => { return (0, _1.close_option)(connection, contract, creator_acc, creator_instrument_acc).then(sig => { (0, chai_2.expect)(send_tx.callCount).to.equal(2, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(3, "find address used twice"); }); }).catch(); }); }); describe("create put", function () { it('create put contract has correct receiving address', async function () { let strike = 100; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_put)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); (0, chai_2.expect)(contract.instrument.toString()).to.equal(instrument.toString(), "inst value"); (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(strike_instrument.toString(), "strike instr value"); // expect(contract.nft_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft id") (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); // expect(contract.account_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "account id") (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(_1.OptionType.put, "contract type"); (0, chai_2.expect)(send_tx.callCount).to.equal(1, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(2, "find address used twice"); }).catch(); }); }); describe("exercise contract", function () { it('exercising a call contract ', async function () { let strike = 100; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_call)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc).then(([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); (0, chai_2.expect)(contract.instrument.toString()).to.equal(instrument.toString(), "inst value"); (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(strike_instrument.toString(), "strike instr value"); // expect(contract.nft_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft id") (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); // expect(contract.account_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "account id") (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_strike_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(_1.OptionType.call, "contract type"); (0, chai_2.expect)(send_tx.callCount).to.equal(1, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(2, "find address used twice"); let buyer_nft_acc = new web3_js_1.Keypair().publicKey; let buyer_send_acc = new web3_js_1.Keypair().publicKey; let buyer_receive_acc = new web3_js_1.Keypair().publicKey; let buyer_acc = creator_acc; return (0, _1.exercise_call)(connection, contract, buyer_acc, buyer_nft_acc, buyer_receive_acc, buyer_send_acc).then(sig => { (0, chai_2.expect)(send_tx.callCount).to.equal(2, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(3, "find address used twice"); }); }).catch(); }); it('exercising an expired contract should fail ', async function () { let strike = 100; let expiry = Date.now() / 1000 - 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); return (0, _1.create_call)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc).then(async ([sig, contract]) => { (0, chai_2.expect)(contract.strike).to.equal(strike, "strike value"); (0, chai_2.expect)(contract.expiry).to.equal(expiry); (0, chai_2.expect)(contract.multiple).to.equal(multiple); (0, chai_2.expect)(contract.instrument.toString()).to.equal(instrument.toString(), "inst value"); (0, chai_2.expect)(contract.strike_instrument.toString()).to.equal(strike_instrument.toString(), "strike instr value"); // expect(contract.nft_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft id") (0, chai_2.expect)(contract.nft_account.toString()).to.equal(mocked_keypair.publicKey.toString(), "nft account"); // expect(contract.account_id.toString()).to.equal(mocked_keypair.publicKey.toString(), "account id") (0, chai_2.expect)(contract.writer_recv_acc).to.equal(creator_strike_instrument_acc, "receiving acc"); (0, chai_2.expect)(contract.kind).to.equal(_1.OptionType.call, "contract type"); (0, chai_2.expect)(send_tx.callCount).to.equal(1, "tx sent only once"); (0, chai_2.expect)(find_address_stub.callCount).to.equal(2, "find address used twice"); let buyer_nft_acc = new web3_js_1.Keypair().publicKey; let buyer_send_acc = new web3_js_1.Keypair().publicKey; let buyer_receive_acc = new web3_js_1.Keypair().publicKey; let buyer_acc = creator_acc; return (0, _1.exercise_call)(connection, contract, buyer_acc, buyer_nft_acc, buyer_receive_acc, buyer_send_acc).then(async (sig) => { chai_1.assert.fail("expire contract should not be exercised"); }).catch(err => { (0, chai_2.expect)(err).to.be.equal("contract has exipired"); }); }).catch(err => { chai_1.assert.fail(err); }); }); }); describe("create contract doc", function () { this.timeout(60000); it('create put contract doc', async function () { let strike = 100; let expiry = Date.now() / 1000 + 600; let multiple = 1000000000; let instrument = new web3_js_2.PublicKey('D3KCKMTY8rgWtVmxKdCeugKEFbJMjSHk7iWiLMAKrrMf'); let strike_instrument = new web3_js_2.PublicKey('6Uhbk6FwCLLQfsKJ8kn8uCsiF5iZNVQDw5QxMNJh9XiJ'); let font_spy = sinon_1.default.spy(jimp_1.default, "loadFont"); let qrcode_spy = sinon_1.default.spy(qrcode_1.default, "toDataURL"); const [sig, contract] = await (0, _1.create_put)(connection, strike, expiry, multiple, creator_acc, instrument, strike_instrument, creator_instrument_acc, creator_strike_instrument_acc); const img = await (0, doc_1.create_doc_img)(contract); (0, chai_2.expect)(font_spy.callCount).to.equal(1); (0, chai_2.expect)(qrcode_spy.callCount).to.equal(1); }); });