Browse Source

Modified collection & item

dev/signature-instant-buy
Lev 2 years ago
parent
commit
22a8a1c4e5
  1. 3
      build/_deploy.ts
  2. 0
      build/main._dep.ts
  3. 34
      build/nft-collection.deploy.ts
  4. 2
      contracts/imports/op-codes.fc
  5. 7
      contracts/main.fc
  6. 17
      contracts/main.ts
  7. 55
      contracts/nft-collection.fc
  8. 147
      contracts/nft-item.fc
  9. 76
      package-lock.json
  10. 2
      package.json
  11. 44
      test/creation.spec.ts

3
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

0
build/main.deploy.ts → build/main._dep.ts

34
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()}`);
// }

2
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;

7
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 ...)

17
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 {

55
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);
}

147
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

76
package-lock.json generated

@ -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": {

2
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",

44
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);
});
});
Loading…
Cancel
Save