From 22a8a1c4e5d7a20c8bdf4dbd534a455463aaffe2 Mon Sep 17 00:00:00 2001 From: ennucore Date: Tue, 27 Dec 2022 22:37:38 +0100 Subject: [PATCH] Modified collection & item --- build/_deploy.ts | 3 + build/{main.deploy.ts => main._dep.ts} | 0 build/nft-collection.deploy.ts | 34 ++++++ contracts/imports/op-codes.fc | 2 +- contracts/main.fc | 7 +- contracts/main.ts | 17 +++ contracts/nft-collection.fc | 55 ++++----- contracts/nft-item.fc | 147 +++++++++---------------- package-lock.json | 76 +++++++++++-- package.json | 2 +- test/creation.spec.ts | 44 ++++++++ 11 files changed, 253 insertions(+), 134 deletions(-) rename build/{main.deploy.ts => main._dep.ts} (100%) create mode 100644 build/nft-collection.deploy.ts create mode 100644 test/creation.spec.ts diff --git a/build/_deploy.ts b/build/_deploy.ts index 876dd3a..e4f16eb 100644 --- a/build/_deploy.ts +++ b/build/_deploy.ts @@ -76,13 +76,16 @@ async function main() { console.log(` - ERROR: '${rootContract}' does not have 'initData()' function`); process.exit(1); } + console.log(1); const initDataCell = deployInitScript.initData() as Cell; + console.log(2); // prepare the init message if (typeof deployInitScript.initMessage !== "function") { console.log(` - ERROR: '${rootContract}' does not have 'initMessage()' function`); process.exit(1); } + console.log(1); const initMessageCell = deployInitScript.initMessage() as Cell | null; // prepare the init code cell diff --git a/build/main.deploy.ts b/build/main._dep.ts similarity index 100% rename from build/main.deploy.ts rename to build/main._dep.ts diff --git a/build/nft-collection.deploy.ts b/build/nft-collection.deploy.ts new file mode 100644 index 0000000..acdb260 --- /dev/null +++ b/build/nft-collection.deploy.ts @@ -0,0 +1,34 @@ +import * as main from "../contracts/main"; +import { Address, toNano, TupleSlice, WalletContract } from "ton"; +// import { sendInternalMessageWithWallet } from "../test/helpers"; +import { hex } from "../build/nft-item.compiled.json"; +import { Builder, Cell, Slice } from "ton"; + +// return the init Cell of the contract storage (according to load_data() contract method) +export function initData() { + return main.collectionData({ + ownerAddress: Address.parseFriendly("kQBw4_jZTQVbOSDbUjAMibTHWbstrCqjOnzvUTCphGpTFDrK").address, + code: Cell.fromBoc(hex)[0], + ownerKey: 0 // 63181357919630091755807889549433422416741950993093777020964723182484811889834 + }); +} + +// return the op that should be sent to the contract on deployment, can be "null" to send an empty message +export function initMessage() { + return null; +} + +// optional end-to-end sanity test for the actual on-chain contract to see it is actually working on-chain +// export async function postDeployTest(walletContract: WalletContract, secretKey: Buffer, contractAddress: Address) { +// const call = await walletContract.client.callGetMethod(contractAddress, "counter"); +// const counter = new TupleSlice(call.stack).readBigNumber(); +// console.log(` # Getter 'counter' = ${counter.toString()}`); +// +// const message = main.increment(); +// await sendInternalMessageWithWallet({ walletContract, secretKey, to: contractAddress, value: toNano(0.02), body: message }); +// console.log(` # Sent 'increment' op message`); +// +// const call2 = await walletContract.client.callGetMethod(contractAddress, "counter"); +// const counter2 = new TupleSlice(call2.stack).readBigNumber(); +// console.log(` # Getter 'counter' = ${counter2.toString()}`); +// } diff --git a/contracts/imports/op-codes.fc b/contracts/imports/op-codes.fc index 16c2773..e1912db 100644 --- a/contracts/imports/op-codes.fc +++ b/contracts/imports/op-codes.fc @@ -17,7 +17,7 @@ int op::editorship_assigned() asm "0x511a4463 PUSHINT"; ;; Collection int op::new_nft() asm "0x1a039a51 PUSHINT"; -int op::instant_buy_new_nft() asm "16c7d435 PUSHINT"; +int op::instant_buy_new_nft() asm "0x16c7d435 PUSHINT"; ;; DNS const int op::fill_up = 0x370fec51; diff --git a/contracts/main.fc b/contracts/main.fc index 1a5fdae..e98abd4 100644 --- a/contracts/main.fc +++ b/contracts/main.fc @@ -9,6 +9,7 @@ int min_tons_for_storage() asm "1000000000 PUSHINT"; ;; 1 TON +const sign_key = 0; ;; =============== storage ============================= ;; @@ -328,14 +329,14 @@ cell pack_nft_item_state(cell nft_item_code, cell data) impure { throw_unless(411, slice_bits(new_domain) > 0); throw_unless(412, equal_slices(receiver_addr, sender_address)); ;; TODO: Unsure here throw_unless(413, equal_slices(issued_collection_addr, my_address())); - int success = check_data_signature(option_data.begin_parse(), signature.begin_parse(), owner_address); + int success = check_signature(slice_hash(option_data.begin_parse()), signature.begin_parse(), sign_key); throw_unless(413, success); throw_unless(414, msg_value > amount); - amount_to_send = msg_value - amount; ;; TODO: Handle this later, reroute coins + var amount_to_send = msg_value - amount; ;; TODO: Handle this later, reroute coins int new_item_index = slice_hash(new_domain); - deploy_bought_item(item_index, cell item_code, slice receiver_addr, slice new_domain); +;; deploy_bought_item(item_index, cell item_code, slice receiver_addr, slice new_domain); return (); ;; init_state = pack_state(... add domain here ...) diff --git a/contracts/main.ts b/contracts/main.ts index 35c8c10..7114310 100644 --- a/contracts/main.ts +++ b/contracts/main.ts @@ -26,6 +26,16 @@ export function data(params: { ownerAddress: Address; collectionAddress: Address .storeUint(0, 64).endCell(); } +export function collectionData(params: { code: Cell, ownerAddress: Address, ownerKey: number }): Cell { + return beginCell() + .storeRef(encodeOffChainContent("https://agorata.io/collection.json")) + .storeRef(params.code) + .storeRef(beginCell().endCell()) + .storeUint(params.ownerKey, 256) + .storeAddress(params.ownerAddress) + .endCell(); +} + export function auctionWithWinner(winnerAddress: Address) { return beginCell().storeAddress(winnerAddress).storeCoins(0).storeUint(0, 64) } @@ -42,6 +52,13 @@ export function transferOwnership(params: { newOwnerAddress: Address }): Cell { return beginCell().storeUint(0x5fcc3d14, 32).storeUint(0, 64).storeAddress(params.newOwnerAddress).storeAddress(null).storeInt(0, 1).storeCoins(1 * TON()).endCell(); } +export function createItem(params: { domain: String }): Cell { + return beginCell() + .storeUint(0, 32) + .storeRef(makeSnakeCell(Buffer.from(params.domain))) + .endCell(); +} + export function currentState(contract: SmartContract) { let reader = contract.dataCell.beginParse(); return { diff --git a/contracts/nft-collection.fc b/contracts/nft-collection.fc index c7d6c45..dc63692 100644 --- a/contracts/nft-collection.fc +++ b/contracts/nft-collection.fc @@ -4,25 +4,43 @@ #include "imports/params.fc"; ;; storage scheme -;; storage#_ collection_content:^Cell -;; nft_item_code:^Cell -;; = Storage; +;; cell collection_content +;; cell nft_item_code +;; cell pricing +;; uint256(key) owner_key +;; address owner_address -(cell, cell) load_data() inline { +(cell, cell, cell, int, slice) load_data() inline { var ds = get_data().begin_parse(); return ( ds~load_ref(), ;; content - ds~load_ref() ;; nft_item_code + ds~load_ref(), ;; nft_item_code + ds~load_ref(), ;; pricing + ds~load_uint(256), ;; owner key + ds~load_msg_addr() ;; owner address ); } -() save_data(cell content, cell nft_item_code) impure inline { +() save_data(cell content, cell nft_item_code, cell pricing, int owner_key, slice owner_addr) impure inline { set_data(begin_cell() .store_ref(content) .store_ref(nft_item_code) + .store_ref(pricing) + .store_uint(owner_key, 256) + .store_slice(owner_addr) .end_cell()); } +;; Calculate the price and check validness (otherwise throw exceptions) +int calcprice(slice domain, cell pricing) inline_ref { + int len = slice_bits(domain); + throw_unless(200, len > 3 * 8); ;; minimum 4 characters + throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters + throw_unless(202, mod(len, 8) == 0); + throw_unless(203, check_domain_string(domain)); + return 100000; ;; todo +} + cell calculate_nft_item_state_init(int item_index, cell nft_item_code) { cell data = begin_cell().store_uint(item_index, 256).store_slice(my_address()).end_cell(); return begin_cell().store_uint(0, 2).store_dict(nft_item_code).store_dict(data).store_uint(0, 1).end_cell(); @@ -60,34 +78,21 @@ slice calculate_nft_item_address(int wc, cell state_init) { if (flags & 1) { ;; ignore all bounced messages return (); } - slice sender_address = cs~load_msg_addr(); int op = in_msg_body~load_uint(32); - var (content, nft_item_code) = load_data(); + var (content, nft_item_code, pricing, key, addr) = load_data(); if (op == 0) { ;; deploy new nft int now_time = now(); - throw_unless(199, now_time > auction_start_time); ;; start of auction slice domain = read_domain_from_comment(in_msg_body); int len = slice_bits(domain); - throw_unless(200, len > 3 * 8); ;; minimum 4 characters - throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters - throw_unless(202, mod(len, 8) == 0); - throw_unless(203, check_domain_string(domain)); - int min_price = get_min_price(len, now_time); - throw_unless(204, msg_value >= min_price); + int price = calcprice(domain, pricing); + throw_unless(204, msg_value >= price); int item_index = slice_hash(domain); - cell config_cell = config_param(dns_config_id); - if (~ cell_null?(config_cell)) { - slice config_cs = config_cell.begin_parse(); - cell config = config_cs~load_dict(); - (slice config_value, int found) = config.udict_get?(256, item_index); - throw_if(205, found); - } - + slice sender_address = cs~load_msg_addr(); cell nft_content = begin_cell() .store_slice(sender_address) .store_ref(begin_cell().store_slice(domain).end_cell()) @@ -105,12 +110,12 @@ slice calculate_nft_item_address(int wc, cell state_init) { ;; Get methods (int, cell, slice) get_collection_data() method_id { - var (content, nft_item_code) = load_data(); + var (content, nft_item_code, pricing, key, addr) = load_data(); return (-1, content, zero_address()); } slice get_nft_address_by_index(int index) method_id { - var (content, nft_item_code) = load_data(); + var (content, nft_item_code, pricing, key, addr) = load_data(); cell state_init = calculate_nft_item_state_init(index, nft_item_code); return calculate_nft_item_address(workchain(), state_init); } diff --git a/contracts/nft-item.fc b/contracts/nft-item.fc index 86b2522..cdd40ae 100644 --- a/contracts/nft-item.fc +++ b/contracts/nft-item.fc @@ -5,52 +5,27 @@ int min_tons_for_storage() asm "1000000000 PUSHINT"; ;; 1 TON -const auction_start_duration = 604800; ;; 1 week = 60 * 60 * 24 * 7; in testnet 5 min -const auction_end_duration = 3600; ;; 1 hour = 60 * 60; in testnet 1 min -const auction_prolongation = 3600; ;; 1 hour = 60 * 60; in testnet 1 min - -;; MsgAddressInt max_bid_address -;; Coins max_bid_amount -;; int auction_end_time -(slice, int, int) unpack_auction(cell auction) { - if (cell_null?(auction)) { - return (null(), 0, 0); - } else { - slice ds = auction.begin_parse(); - return (ds~load_msg_addr(), ds~load_coins(), ds~load_uint(64)); - } -} - -cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_time) { - return begin_cell() - .store_slice(max_bid_address) - .store_coins(max_bid_amount) - .store_uint(auction_end_time, 64) - .end_cell(); -} - ;; -;; Storage +;; === Storage === ;; ;; uint256 index ;; MsgAddressInt collection_address ;; MsgAddressInt owner_address ;; cell content ;; cell domain - e.g contains "alice" (without ending \0) for "alice.ton" domain -;; cell auction - auction info ;; int last_fill_up_time -(int, int, slice, slice, cell, cell, cell, int) load_data() { +(int, int, slice, slice, cell, cell, int) load_data() { slice ds = get_data().begin_parse(); var (index, collection_address) = (ds~load_uint(256), ds~load_msg_addr()); if (ds.slice_bits() > 0) { - return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref(), ds~load_ref(), ds~load_dict(), ds~load_uint(64)); + return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref(), ds~load_ref(), ds~load_uint(64)); } else { - return (0, index, collection_address, null(), null(), null(), null(), 0); ;; nft not initialized yet + return (0, index, collection_address, null(), null(), null(), 0); ;; nft not initialized yet } } -() store_data(int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) impure { +() store_data(int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) impure { set_data( begin_cell() .store_uint(index, 256) @@ -58,7 +33,6 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim .store_slice(owner_address) .store_ref(content) .store_ref(domain) - .store_dict(auction) .store_uint(last_fill_up_time, 64) .end_cell() ); @@ -80,7 +54,7 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim send_raw_message(msg.end_cell(), send_mode); } -() transfer_ownership(int my_balance, int index, slice collection_address, slice owner_address, cell content, slice sender_address, int query_id, slice in_msg_body, int fwd_fees, cell domain, cell auction) impure inline { +() transfer_ownership(int my_balance, int index, slice collection_address, slice owner_address, cell content, slice sender_address, int query_id, slice in_msg_body, int fwd_fees, cell domain) impure inline { slice new_owner_address = in_msg_body~load_msg_addr(); force_chain(new_owner_address); slice response_destination = in_msg_body~load_msg_addr(); @@ -106,7 +80,7 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim send_msg(response_destination, rest_amount, op::excesses(), query_id, null(), 1); ;; paying fees, revert on errors } - store_data(index, collection_address, new_owner_address, content, domain, auction, now()); + store_data(index, collection_address, new_owner_address, content, domain, now()); } () recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { @@ -125,23 +99,14 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim cs~load_coins(); ;; skip ihr_fee int fwd_fee = cs~load_coins(); ;; we use message fwd_fee for estimation of forward_payload costs - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); if (~ init?) { throw_unless(405, equal_slices(collection_address, sender_address)); slice from_address = in_msg_body~load_msg_addr(); cell domain = in_msg_body~load_ref(); cell content = begin_cell().store_uint(0, 8).store_dict(new_dict()).end_cell(); - - int seconds = now() - auction_start_time; - int months = seconds / one_month; - if (months > 12) { - months = 12; - } - int duration = auction_start_duration - (auction_start_duration - auction_end_duration) * months / 12; - - int auction_end_time = now() + duration; - store_data(index, collection_address, zero_address(), content, domain, pack_auction(from_address, msg_value, auction_end_time), now()); + store_data(index, collection_address, from_address, content, domain, now()); return (); } @@ -153,55 +118,53 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim int op = in_msg_body.slice_empty?() ? 0 : in_msg_body~load_uint(32); - (slice max_bid_address, int max_bid_amount, int auction_end_time) = unpack_auction(auction); - int auction_complete = now() > auction_end_time; - if (op == 0) { - if (auction_complete) { - throw_unless(406, equal_slices(sender_address, owner_address)); ;; only owner can fill-up balance, prevent coins lost right after the auction - ;; if owner send bid right after auction he can restore it by transfer resonse message - store_data(index, collection_address, owner_address, content, domain, auction, now()); - } else { - throw_unless(407, msg_value >= muldiv(max_bid_amount, 105, 100)); ;; 5% greater then previous bid - int amount_to_send = (max_bid_amount > my_balance - min_tons_for_storage()) ? (my_balance - min_tons_for_storage()) : max_bid_amount; - if (amount_to_send > 0) { - send_msg(max_bid_address, amount_to_send, op::outbid_notification, cur_lt(), null(), 1); ;; pay transfer fees separately - } - max_bid_amount = msg_value; - max_bid_address = sender_address; - int delta_time = auction_prolongation - (auction_end_time - now()); - if (delta_time > 0) { - auction_end_time += delta_time; - } - store_data(index, collection_address, owner_address, content, domain, pack_auction(max_bid_address, max_bid_amount, auction_end_time), now()); - } + if (op == 0) { ;; todo +;; if (auction_complete) { +;; throw_unless(406, equal_slices(sender_address, owner_address)); ;; only owner can fill-up balance, prevent coins lost right after the auction +;; ;; if owner send bid right after auction he can restore it by transfer resonse message + store_data(index, collection_address, owner_address, content, domain, now()); +;; } else { +;; throw_unless(407, msg_value >= muldiv(max_bid_amount, 105, 100)); ;; 5% greater then previous bid +;; int amount_to_send = (max_bid_amount > my_balance - min_tons_for_storage()) ? (my_balance - min_tons_for_storage()) : max_bid_amount; +;; if (amount_to_send > 0) { +;; send_msg(max_bid_address, amount_to_send, op::outbid_notification, cur_lt(), null(), 1); ;; pay transfer fees separately +;; } +;; max_bid_amount = msg_value; +;; max_bid_address = sender_address; +;; int delta_time = auction_prolongation - (auction_end_time - now()); +;; if (delta_time > 0) { +;; auction_end_time += delta_time; +;; } +;; store_data(index, collection_address, owner_address, content, domain, now()); +;; } return (); } int query_id = in_msg_body~load_uint(64); - if ((auction_complete) & (~ cell_null?(auction))) { ;; take domain after auction - int balance_without_msg = my_balance - msg_value; - int amount_to_send = (max_bid_amount > balance_without_msg - min_tons_for_storage()) ? (balance_without_msg - min_tons_for_storage()) : max_bid_amount; - if (amount_to_send > 0) { - send_msg(collection_address, amount_to_send, op::fill_up, query_id, null(), 2); ;; ignore errors - my_balance -= amount_to_send; - } - owner_address = max_bid_address; - auction = null(); - store_data(index, collection_address, owner_address, content, domain, auction, last_fill_up_time); - } +;; if ((auction_complete) & (~ cell_null?(auction))) { ;; take domain after auction ;; todo +;; int balance_without_msg = my_balance - msg_value; +;; int amount_to_send = (max_bid_amount > balance_without_msg - min_tons_for_storage()) ? (balance_without_msg - min_tons_for_storage()) : max_bid_amount; +;; if (amount_to_send > 0) { +;; send_msg(collection_address, amount_to_send, op::fill_up, query_id, null(), 2); ;; ignore errors +;; my_balance -= amount_to_send; +;; } +;; owner_address = max_bid_address; +;; auction = null(); +;; store_data(index, collection_address, owner_address, content, domain, last_fill_up_time); +;; } if (op == op::transfer()) { throw_unless(401, equal_slices(sender_address, owner_address)); - transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, in_msg_body, fwd_fee, domain, auction); + transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, in_msg_body, fwd_fee, domain); return (); } if (op == op::edit_content()) { ;; owner can change content and dns records throw_unless(410, equal_slices(sender_address, owner_address)); - store_data(index, collection_address, owner_address, in_msg_body~load_ref(), domain, auction, now()); + store_data(index, collection_address, owner_address, in_msg_body~load_ref(), domain, now()); return (); } if (op == op::change_dns_record) { ;; change dns record @@ -223,11 +186,10 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim content = begin_cell().store_uint(0, 8).store_dict(keyvalue_map).end_cell(); - store_data(index, collection_address, owner_address, content, domain, auction, now()); + store_data(index, collection_address, owner_address, content, domain, now()); return (); } if (op == op::process_governance_decision) { ;; governance - throw_unless(413, cell_null?(auction)); slice cs = config_param(dns_config_id).begin_parse(); cell config = cs~load_dict(); (slice config_value, int found) = config.udict_get?(256, index); @@ -235,7 +197,7 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim int config_op = config_value~load_uint(8); throw_unless(416, (config_op == 0) | (config_op == 1)); if (config_op == 0) { ;; transfer - transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, config_value, fwd_fee, domain, auction); + transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, config_value, fwd_fee, domain); } if (config_op == 1) { ;; destroy send_msg(collection_address, 0, op::fill_up, query_id, null(), 128 + 32); ;; carry all the remaining balance + destroy @@ -243,7 +205,7 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim return (); } if (op == op::dns_balance_release) { ;; release domain - throw_unless(414, (now() - last_fill_up_time > one_year) & (cell_null?(auction))); + throw_unless(414, (now() - last_fill_up_time > one_year)); int min_price = get_min_price(domain.begin_parse().slice_bits(), now()); throw_unless(407, msg_value >= min_price); int balance_without_msg = my_balance - msg_value; @@ -251,12 +213,8 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim if (amount_to_send > 0) { send_msg(owner_address, amount_to_send, op::dns_balance_release, query_id, null(), 2); ;; ignore errors } - max_bid_amount = msg_value; - max_bid_address = sender_address; - auction_end_time = now() + auction_start_duration; ;; always 1 week owner_address = zero_address(); - auction = pack_auction(max_bid_address, max_bid_amount, auction_end_time); - store_data(index, collection_address, owner_address, content, domain, auction, now()); + store_data(index, collection_address, owner_address, content, domain, now()); return (); } if (op == op::get_static_data()) { @@ -271,27 +229,22 @@ cell pack_auction(slice max_bid_address, int max_bid_amount, int auction_end_tim ;; (int, int, slice, slice, cell) get_nft_data() method_id { - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); return (init?, index, collection_address, owner_address, content); } slice get_editor() method_id { - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); return owner_address; } slice get_domain() method_id { - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); return domain.begin_parse(); } -(slice, int, int) get_auction_info() method_id { - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); - return unpack_auction(auction); -} - int get_last_fill_up_time() method_id { - (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell domain, int last_fill_up_time) = load_data(); return last_fill_up_time; } @@ -300,7 +253,7 @@ int get_last_fill_up_time() method_id { throw_unless(70, mod(subdomain_bits, 8) == 0); - (int init?, int index, slice collection_address, slice owner_address, cell content, cell my_domain_cell, cell auction, int last_fill_up_time) = load_data(); + (int init?, int index, slice collection_address, slice owner_address, cell content, cell my_domain_cell, int last_fill_up_time) = load_data(); slice cs = content.begin_parse(); throw_unless(412, cs~load_uint(8) == 0); ;; data onchain tag diff --git a/package-lock.json b/package-lock.json index f0b25b6..9363f32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "mocha": "^9.1.3", "prando": "^6.0.1", "prettier": "^2.6.2", - "ton": "9.9.0", + "ton": "^12.1.3", "ton-contract-executor": "^0.4.8", "ton-crypto": "^3.1.0", "ts-node": "^10.4.0", @@ -1715,9 +1715,9 @@ } }, "node_modules/ton": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/ton/-/ton-9.9.0.tgz", - "integrity": "sha512-6t+/5b/6DbQH58ywJoc96CN1txcxXjZfYXk/vDeJClqfFR5Z9QikfoPGjLPHTkpLo8jALGPrcKnZDYIwU6biew==", + "version": "12.3.3", + "resolved": "https://registry.npmjs.org/ton/-/ton-12.3.3.tgz", + "integrity": "sha512-5vwy7bwuUgOY7Injqi5Ei+Opsr9AjcS4qHzzdiUdt51O2W9oz4LE/GREXuv7Uvxsxev4cWXx0sic0ohfR8Yu4g==", "dev": true, "dependencies": { "axios": "^0.25.0", @@ -1765,6 +1765,36 @@ "ton-compiler": "^0.9.0" } }, + "node_modules/ton-contract-executor/node_modules/ton": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/ton/-/ton-9.9.0.tgz", + "integrity": "sha512-6t+/5b/6DbQH58ywJoc96CN1txcxXjZfYXk/vDeJClqfFR5Z9QikfoPGjLPHTkpLo8jALGPrcKnZDYIwU6biew==", + "dev": true, + "dependencies": { + "axios": "^0.25.0", + "bn.js": "5.2.0", + "dataloader": "^2.0.0", + "ethjs-unit": "0.1.6", + "fp-ts": "^2.11.1", + "io-ts": "^2.2.16", + "io-ts-reporters": "^2.0.0", + "symbol.inspect": "1.0.1", + "teslabot": "^1.3.0", + "ton-crypto": "2.1.0", + "tweetnacl": "1.0.3" + } + }, + "node_modules/ton-contract-executor/node_modules/ton-crypto": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ton-crypto/-/ton-crypto-2.1.0.tgz", + "integrity": "sha512-PZnmCOShfgq9tCRM8E7hG8nCkpkOyZvDLPXmZN92ZEBrfTT0NKKf0imndkxG5DkgWMjc6IKfgpnEaJDH9qN6ZQ==", + "dev": true, + "dependencies": { + "jssha": "3.2.0", + "ton-crypto-primitives": "2.0.0", + "tweetnacl": "1.0.3" + } + }, "node_modules/ton-crypto": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ton-crypto/-/ton-crypto-3.1.0.tgz", @@ -3161,9 +3191,9 @@ } }, "ton": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/ton/-/ton-9.9.0.tgz", - "integrity": "sha512-6t+/5b/6DbQH58ywJoc96CN1txcxXjZfYXk/vDeJClqfFR5Z9QikfoPGjLPHTkpLo8jALGPrcKnZDYIwU6biew==", + "version": "12.3.3", + "resolved": "https://registry.npmjs.org/ton/-/ton-12.3.3.tgz", + "integrity": "sha512-5vwy7bwuUgOY7Injqi5Ei+Opsr9AjcS4qHzzdiUdt51O2W9oz4LE/GREXuv7Uvxsxev4cWXx0sic0ohfR8Yu4g==", "dev": true, "requires": { "axios": "^0.25.0", @@ -3219,6 +3249,38 @@ "bn.js": "^5.2.0", "ton": "^9.6.3", "ton-compiler": "^0.9.0" + }, + "dependencies": { + "ton": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/ton/-/ton-9.9.0.tgz", + "integrity": "sha512-6t+/5b/6DbQH58ywJoc96CN1txcxXjZfYXk/vDeJClqfFR5Z9QikfoPGjLPHTkpLo8jALGPrcKnZDYIwU6biew==", + "dev": true, + "requires": { + "axios": "^0.25.0", + "bn.js": "5.2.0", + "dataloader": "^2.0.0", + "ethjs-unit": "0.1.6", + "fp-ts": "^2.11.1", + "io-ts": "^2.2.16", + "io-ts-reporters": "^2.0.0", + "symbol.inspect": "1.0.1", + "teslabot": "^1.3.0", + "ton-crypto": "2.1.0", + "tweetnacl": "1.0.3" + } + }, + "ton-crypto": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ton-crypto/-/ton-crypto-2.1.0.tgz", + "integrity": "sha512-PZnmCOShfgq9tCRM8E7hG8nCkpkOyZvDLPXmZN92ZEBrfTT0NKKf0imndkxG5DkgWMjc6IKfgpnEaJDH9qN6ZQ==", + "dev": true, + "requires": { + "jssha": "3.2.0", + "ton-crypto-primitives": "2.0.0", + "tweetnacl": "1.0.3" + } + } } }, "ton-crypto": { diff --git a/package.json b/package.json index dc67c33..59f45fc 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "mocha": "^9.1.3", "prando": "^6.0.1", "prettier": "^2.6.2", - "ton": "9.9.0", + "ton": "^12.1.3", "ton-contract-executor": "^0.4.8", "ton-crypto": "^3.1.0", "ts-node": "^10.4.0", diff --git a/test/creation.spec.ts b/test/creation.spec.ts new file mode 100644 index 0000000..95b2826 --- /dev/null +++ b/test/creation.spec.ts @@ -0,0 +1,44 @@ +import chai, { assert, expect } from "chai"; +import chaiBN from "chai-bn"; +import BN from "bn.js"; +chai.use(chaiBN(BN)); + +import { Builder, Cell, Slice } from "ton"; +import { SmartContract } from "ton-contract-executor"; +import * as main from "../contracts/main"; +import { internalMessage, randomAddress } from "./helpers"; + +import { hex } from "../build/nft-collection.compiled.json"; + +describe("Creating items tests", () => { + let contract: SmartContract; + let debug: boolean = false; + + beforeEach(async () => { + contract = await SmartContract.fromCell( + Cell.fromBoc(hex)[0], + main.collectionData({ + ownerAddress: randomAddress("owner"), + code: Cell.fromBoc(hex)[0], + ownerKey: 0, + }), + { debug: debug } + ); + }); + + it("allows to buy an item", async () => { + main.setContractBalance(contract, 10 * main.TON()); + let ownerAddr = randomAddress("owner"); + const sendToSelfMessage = internalMessage({ + from: ownerAddr, + body: main.createItem({ domain: "test" }), + value: new BN(10 * main.TON()), + }); + const res = await contract.sendInternalMessage(sendToSelfMessage); + console.log(res); + expect(res.type).to.equal("success"); + expect(res.exit_code).to.equal(0); + + }); + +});