From 23115c98bda5ccccd56703b24f719c5e04096c85 Mon Sep 17 00:00:00 2001 From: bexan Date: Wed, 28 Feb 2024 08:25:20 +0100 Subject: [PATCH 01/19] Hooker: use abigen & add whitelisting --- packages/core/examples/createListing.ts | 9 +++++-- packages/core/examples/utils/getOwnerOf.ts | 27 ++++++++++++++++++++ packages/core/src/utils/index.ts | 29 +++++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 packages/core/examples/utils/getOwnerOf.ts diff --git a/packages/core/examples/createListing.ts b/packages/core/examples/createListing.ts index afae6063c..882ef6d6e 100644 --- a/packages/core/examples/createListing.ts +++ b/packages/core/examples/createListing.ts @@ -6,6 +6,7 @@ */ import { shortString } from "starknet"; +import { getSolisProvider, getStarknetProvider } from "../../deployer/src/providers"; import "dotenv/config"; @@ -22,7 +23,7 @@ import { STARKNET_NFT_ADDRESS } from "./constants"; import { getCurrentTokenId } from "./utils/getCurrentTokenId"; import { getTokenOwner } from "./utils/getTokenOwner"; import { mintERC721 } from "./utils/mintERC721"; -import { whitelistBroker } from "./utils/whitelistBroker"; +import { whitelistBroker } from "../src/utils"; /** * Creates a listing on the blockchain using provided order details. @@ -37,7 +38,11 @@ import { whitelistBroker } from "./utils/whitelistBroker"; ); console.log(`=> Whitelisting broker ${brokerId}`); - await whitelistBroker(config, solisAdminAccount, brokerId); + await whitelistBroker( + config, + solisAdminAccount, + brokerId + ); console.log(`=> Creating account`); // Create a new account for the listing using the provider diff --git a/packages/core/examples/utils/getOwnerOf.ts b/packages/core/examples/utils/getOwnerOf.ts new file mode 100644 index 000000000..5a9bc4ce5 --- /dev/null +++ b/packages/core/examples/utils/getOwnerOf.ts @@ -0,0 +1,27 @@ +import { BigNumberish, cairo, CairoOption, CairoOptionVariant, Call, CallData, Contract, Uint256 } from "starknet"; + +import { Config } from "../../src/createConfig"; +import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../constants"; +import { getStarknetProvider } from "../../../deployer/src/providers"; + +export const getOwnerOf = async ( + config: Config, + nftContractAddress: string, + tokenId: number +) => { + + const starknetProvider = getStarknetProvider("dev"); + console.log("starknetProvider", starknetProvider); + const { abi } = await starknetProvider.getClassAt(nftContractAddress); + if (abi === undefined) { + throw new Error("no abi."); + } + console.log("abi", abi); + + const erc721Contract = + new Contract(abi, nftContractAddress, starknetProvider); + + const result = await erc721Contract.call('owner_of', [tokenId]); + console.log(result); + return result; +}; diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 0113376ce..626021b4d 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,8 +1,9 @@ import * as starknet from "@scure/starknet"; -import { CallData } from "starknet"; +import { Account, BigNumberish, CallData, Contract } from "starknet"; import { Config } from "../createConfig"; import { OrderV1 } from "../types"; +import * as sn from "starknet"; export const getOrderHashFromOrderV1 = (order: OrderV1) => { const compiledOrder = CallData.compile({ @@ -23,3 +24,29 @@ export const getOrderbookAbi = async (config: Config) => { return orderbookAbi; } }; + + +export const whitelistBroker = async ( + config: Config, + adminAccount: Account, + brokerId: BigNumberish +) => { + const { abi: orderbookAbi } = await config.arkProvider.getClassAt( + config.arkchainContracts.orderbook + ); + + if (orderbookAbi === undefined) { + throw new Error("no abi."); + } + + const whitelist_hash_calldata = CallData.compile({ + broker_id: brokerId + }); + + const result = await adminAccount.execute({ + contractAddress: config.arkchainContracts.orderbook, + entrypoint: "whitelist_broker", + calldata: whitelist_hash_calldata + }); + +}; From b4134ce64008f619882d4096cf526b588e006a98 Mon Sep 17 00:00:00 2001 From: bexan Date: Wed, 28 Feb 2024 09:00:01 +0100 Subject: [PATCH 02/19] createListing: update log & move whitelist function : --- Cargo.lock | 26 ++++++++++++------------- crates/solis/messaging.local.json | 2 +- packages/core/examples/createListing.ts | 4 ++-- packages/core/src/utils/index.ts | 26 ------------------------- 4 files changed, 16 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c946bf35..0232a2b6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -961,13 +961,13 @@ dependencies = [ [[package]] name = "cainome" version = "0.2.3" -source = "git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-#9a217c56e7adcac81acc6576526e7e90f552333a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord#c29e4f837fedd5cf0d842361463a33bdde7f340f" dependencies = [ "anyhow", "async-trait", - "cainome-cairo-serde 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", - "cainome-parser 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", - "cainome-rs 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", "cainome-rs-macro", "camino", "clap", @@ -994,7 +994,7 @@ dependencies = [ [[package]] name = "cainome-cairo-serde" version = "0.1.0" -source = "git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-#9a217c56e7adcac81acc6576526e7e90f552333a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord#c29e4f837fedd5cf0d842361463a33bdde7f340f" dependencies = [ "starknet 0.8.0", "thiserror", @@ -1015,7 +1015,7 @@ dependencies = [ [[package]] name = "cainome-parser" version = "0.1.0" -source = "git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-#9a217c56e7adcac81acc6576526e7e90f552333a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord#c29e4f837fedd5cf0d842361463a33bdde7f340f" dependencies = [ "convert_case 0.6.0", "quote", @@ -1044,11 +1044,11 @@ dependencies = [ [[package]] name = "cainome-rs" version = "0.1.0" -source = "git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-#9a217c56e7adcac81acc6576526e7e90f552333a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord#c29e4f837fedd5cf0d842361463a33bdde7f340f" dependencies = [ "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", - "cainome-parser 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", "proc-macro2", "quote", "serde_json", @@ -1060,12 +1060,12 @@ dependencies = [ [[package]] name = "cainome-rs-macro" version = "0.1.0" -source = "git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-#9a217c56e7adcac81acc6576526e7e90f552333a" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord#c29e4f837fedd5cf0d842361463a33bdde7f340f" dependencies = [ "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", - "cainome-parser 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", - "cainome-rs 0.1.0 (git+https://github.com/ybensacq/cainome?branch=feat-add-partial-ord-)", + "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", + "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", + "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.2.4-fix-ord)", "proc-macro2", "quote", "serde_json", diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index fe52b84da..68f17dfda 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -6,4 +6,4 @@ "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, "from_block": 0 -} +} \ No newline at end of file diff --git a/packages/core/examples/createListing.ts b/packages/core/examples/createListing.ts index 882ef6d6e..1c7094165 100644 --- a/packages/core/examples/createListing.ts +++ b/packages/core/examples/createListing.ts @@ -23,7 +23,7 @@ import { STARKNET_NFT_ADDRESS } from "./constants"; import { getCurrentTokenId } from "./utils/getCurrentTokenId"; import { getTokenOwner } from "./utils/getTokenOwner"; import { mintERC721 } from "./utils/mintERC721"; -import { whitelistBroker } from "../src/utils"; +import { whitelistBroker } from "./utils/whitelistBroker"; /** * Creates a listing on the blockchain using provided order details. @@ -61,7 +61,7 @@ import { whitelistBroker } from "../src/utils"; await mintERC721(config.starknetProvider, starknetOffererAccount); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); const owner = await getTokenOwner(config, STARKNET_NFT_ADDRESS, tokenId); - const ownerHex = "0x" + owner.toString(16).padStart(64, "0"); + const ownerHex = "0x" + owner.toString(16).padStart(64, '0'); console.log("Owner of tokenId", tokenId, "is", ownerHex); console.log(`=> Approving for all`); diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 626021b4d..716fb3cbe 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -24,29 +24,3 @@ export const getOrderbookAbi = async (config: Config) => { return orderbookAbi; } }; - - -export const whitelistBroker = async ( - config: Config, - adminAccount: Account, - brokerId: BigNumberish -) => { - const { abi: orderbookAbi } = await config.arkProvider.getClassAt( - config.arkchainContracts.orderbook - ); - - if (orderbookAbi === undefined) { - throw new Error("no abi."); - } - - const whitelist_hash_calldata = CallData.compile({ - broker_id: brokerId - }); - - const result = await adminAccount.execute({ - contractAddress: config.arkchainContracts.orderbook, - entrypoint: "whitelist_broker", - calldata: whitelist_hash_calldata - }); - -}; From 56f5b3e2cd5179c5d57fa5976342339a708d8abc Mon Sep 17 00:00:00 2001 From: bexan Date: Wed, 28 Feb 2024 16:43:51 +0100 Subject: [PATCH 03/19] Hooker & js examples --- .../core/examples/createListingOtherOffer.ts | 103 ++++++++++++++++++ packages/core/examples/fulfillListing.ts | 6 +- packages/core/src/contracts.ts | 12 +- 3 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 packages/core/examples/createListingOtherOffer.ts diff --git a/packages/core/examples/createListingOtherOffer.ts b/packages/core/examples/createListingOtherOffer.ts new file mode 100644 index 000000000..0c6f82bdc --- /dev/null +++ b/packages/core/examples/createListingOtherOffer.ts @@ -0,0 +1,103 @@ +/** + * Demonstrates how to use the Starknet SDK for creating a listing on the arkchain. + * This example shows the process of initializing a provider, creating an account, + * submitting a listing order. + * checking the order status + */ + +import { shortString } from "starknet"; +import { getSolisProvider, getStarknetProvider } from "../../deployer/src/providers"; + +import "dotenv/config"; + +import { + approveERC721, + createAccount, + createListing, + fetchOrCreateAccount, + getOrderStatus, + ListingV1 +} from "../src"; +import { config } from "./config"; +import { STARKNET_NFT_ADDRESS } from "./constants"; +import { getCurrentTokenId } from "./utils/getCurrentTokenId"; +import { getTokenOwner } from "./utils/getTokenOwner"; +import { mintERC721 } from "./utils/mintERC721"; +import { whitelistBroker } from "./utils/whitelistBroker"; + +/** + * Creates a listing on the blockchain using provided order details. + */ +(async () => { + + const brokerId = 123; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + console.log(`=> Whitelisting broker ${brokerId}`); + await whitelistBroker( + config, + solisAdminAccount, + brokerId + ); + + console.log(`=> Creating account`); + // Create a new account for the listing using the provider + const { account: arkAccount } = await createAccount(config.arkProvider); + + console.log( + `=> Fetching or creating offerer starknet account, for test purpose only` + ); + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + const starknetOffererAccount2 = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY + ); + + console.log("=> Minting token at contract address: ", STARKNET_NFT_ADDRESS); + await mintERC721(config.starknetProvider, starknetOffererAccount); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + const owner = await getTokenOwner(config, STARKNET_NFT_ADDRESS, tokenId); + const ownerHex = "0x" + owner.toString(16).padStart(64, '0'); + console.log("Owner of tokenId", tokenId, "is", ownerHex); + + console.log(`=> Approving for all`); + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetOffererAccount + }); + + console.log(`=> Creating order`); + // Define the order details + const order: ListingV1 = { + brokerId: 123, // The broker ID + tokenAddress: STARKNET_NFT_ADDRESS, // The token address + tokenId: tokenId, // The ID of the token + startAmount: 100000000000000000 // The starting amount for the order + }; + + console.log("=> Creating listing..."); + // Create the listing on the arkchain using the order details + const orderHash = await createListing(config, { + starknetAccount: starknetOffererAccount2, + arkAccount, + order + }); + + console.log("=> Fetching order status..."); + const { orderStatus } = await getOrderStatus(config, { + orderHash + }); + + console.log("orderStatus", shortString.decodeShortString(orderStatus)); +})(); diff --git a/packages/core/examples/fulfillListing.ts b/packages/core/examples/fulfillListing.ts index 3aaf677b5..3d61b07da 100644 --- a/packages/core/examples/fulfillListing.ts +++ b/packages/core/examples/fulfillListing.ts @@ -38,7 +38,11 @@ import { whitelistBroker } from "./utils/whitelistBroker"; ); console.log(`=> Whitelisting broker ${brokerId}`); - await whitelistBroker(config, solisAdminAccount, brokerId); + await whitelistBroker( + config, + solisAdminAccount, + brokerId + ); console.log(`=> Getting config...`); const { arkProvider, starknetProvider } = config; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index baa21e168..e312e6b44 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -11,11 +11,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - messaging: - "0x53a0b0ca4b9d248dff574299c98340b67197f7ffc79df9afef66d01e83022c6", - executor: "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", - nftContract: - "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", - eth: "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - orderbook: "0x33b337f2c708c08e49f5e0161658ed093101dd629c3147ad9eea921e6a6afe3" + "messaging": "0x53a0b0ca4b9d248dff574299c98340b67197f7ffc79df9afef66d01e83022c6", + "executor": "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", + "nftContract": "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", + "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", + "orderbook": "0x1d79fd515a38526eace5872fb3377e5648ea921f320ea8945a09f3f77ecb58d" }; From d554f31833ec66c193ce7968074b50e6dd7bac64 Mon Sep 17 00:00:00 2001 From: bexan Date: Thu, 29 Feb 2024 17:40:18 +0100 Subject: [PATCH 04/19] hooker: check allowance & balance --- .../core/examples/createListingOtherOffer.ts | 103 ------------------ packages/core/examples/utils/getOwnerOf.ts | 27 ----- packages/core/src/contracts.ts | 2 +- packages/core/tests/createListing.test.ts | 49 +++++++++ 4 files changed, 50 insertions(+), 131 deletions(-) delete mode 100644 packages/core/examples/createListingOtherOffer.ts delete mode 100644 packages/core/examples/utils/getOwnerOf.ts diff --git a/packages/core/examples/createListingOtherOffer.ts b/packages/core/examples/createListingOtherOffer.ts deleted file mode 100644 index 0c6f82bdc..000000000 --- a/packages/core/examples/createListingOtherOffer.ts +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Demonstrates how to use the Starknet SDK for creating a listing on the arkchain. - * This example shows the process of initializing a provider, creating an account, - * submitting a listing order. - * checking the order status - */ - -import { shortString } from "starknet"; -import { getSolisProvider, getStarknetProvider } from "../../deployer/src/providers"; - -import "dotenv/config"; - -import { - approveERC721, - createAccount, - createListing, - fetchOrCreateAccount, - getOrderStatus, - ListingV1 -} from "../src"; -import { config } from "./config"; -import { STARKNET_NFT_ADDRESS } from "./constants"; -import { getCurrentTokenId } from "./utils/getCurrentTokenId"; -import { getTokenOwner } from "./utils/getTokenOwner"; -import { mintERC721 } from "./utils/mintERC721"; -import { whitelistBroker } from "./utils/whitelistBroker"; - -/** - * Creates a listing on the blockchain using provided order details. - */ -(async () => { - - const brokerId = 123; - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ); - - console.log(`=> Whitelisting broker ${brokerId}`); - await whitelistBroker( - config, - solisAdminAccount, - brokerId - ); - - console.log(`=> Creating account`); - // Create a new account for the listing using the provider - const { account: arkAccount } = await createAccount(config.arkProvider); - - console.log( - `=> Fetching or creating offerer starknet account, for test purpose only` - ); - const starknetOffererAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - const starknetOffererAccount2 = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY - ); - - console.log("=> Minting token at contract address: ", STARKNET_NFT_ADDRESS); - await mintERC721(config.starknetProvider, starknetOffererAccount); - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - const owner = await getTokenOwner(config, STARKNET_NFT_ADDRESS, tokenId); - const ownerHex = "0x" + owner.toString(16).padStart(64, '0'); - console.log("Owner of tokenId", tokenId, "is", ownerHex); - - console.log(`=> Approving for all`); - await approveERC721(config, { - contractAddress: STARKNET_NFT_ADDRESS, - starknetAccount: starknetOffererAccount - }); - - console.log(`=> Creating order`); - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: STARKNET_NFT_ADDRESS, // The token address - tokenId: tokenId, // The ID of the token - startAmount: 100000000000000000 // The starting amount for the order - }; - - console.log("=> Creating listing..."); - // Create the listing on the arkchain using the order details - const orderHash = await createListing(config, { - starknetAccount: starknetOffererAccount2, - arkAccount, - order - }); - - console.log("=> Fetching order status..."); - const { orderStatus } = await getOrderStatus(config, { - orderHash - }); - - console.log("orderStatus", shortString.decodeShortString(orderStatus)); -})(); diff --git a/packages/core/examples/utils/getOwnerOf.ts b/packages/core/examples/utils/getOwnerOf.ts deleted file mode 100644 index 5a9bc4ce5..000000000 --- a/packages/core/examples/utils/getOwnerOf.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BigNumberish, cairo, CairoOption, CairoOptionVariant, Call, CallData, Contract, Uint256 } from "starknet"; - -import { Config } from "../../src/createConfig"; -import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../constants"; -import { getStarknetProvider } from "../../../deployer/src/providers"; - -export const getOwnerOf = async ( - config: Config, - nftContractAddress: string, - tokenId: number -) => { - - const starknetProvider = getStarknetProvider("dev"); - console.log("starknetProvider", starknetProvider); - const { abi } = await starknetProvider.getClassAt(nftContractAddress); - if (abi === undefined) { - throw new Error("no abi."); - } - console.log("abi", abi); - - const erc721Contract = - new Contract(abi, nftContractAddress, starknetProvider); - - const result = await erc721Contract.call('owner_of', [tokenId]); - console.log(result); - return result; -}; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index e312e6b44..a12730092 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -15,5 +15,5 @@ export const DEV_CONTRACTS = { "executor": "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", "nftContract": "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x1d79fd515a38526eace5872fb3377e5648ea921f320ea8945a09f3f77ecb58d" + "orderbook": "0x33b337f2c708c08e49f5e0161658ed093101dd629c3147ad9eea921e6a6afe3" }; diff --git a/packages/core/tests/createListing.test.ts b/packages/core/tests/createListing.test.ts index 1b528f241..8213e1a73 100644 --- a/packages/core/tests/createListing.test.ts +++ b/packages/core/tests/createListing.test.ts @@ -107,4 +107,53 @@ describe("ArkProject Create listing", () => { ) ).to.eventually.equal("OPEN"); }); + + it("should fail because offerer is not the owner", async function () { + // Initialize the RPC provider with the ArkChain node URL + const starknetProvider = new RpcProvider({ + nodeUrl: "http://0.0.0.0:7777" + }); + + // Initialize the RPC provider with the katana node URL for starknet + const arkProvider = new RpcProvider({ + nodeUrl: "http://0.0.0.0:7777" + }); + + // Create a new account using the provider + const { account: arkAccount } = await createAccount(arkProvider); + const { account: starknetAccount } = await createAccount(starknetProvider); + const { account: starknetAccountOther } = await createAccount(starknetProvider); + + expect(arkAccount).to.exist; + expect(starknetAccount).to.exist; + + // Define the order details + const order: ListingV1 = { + brokerId: 123, // The broker ID + tokenAddress: + "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address + tokenId: generateRandomTokenId(), // The ID of the token + startAmount: 600000000000000000 // The starting amount for the order + }; + + // Create the listing on the arkchain using the order details + const orderHash = await createListing(config, { + starknetAccount: starknetAccountOther, + arkAccount, + order + }); + await sleep(1000); // Wait for the transaction to be processed + + // Assert that we received an order hash + expect(orderHash).to.exist; + + // Assert that the order is open + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).to.eventually.equal("OPEN"); + + }); + }); From d135e896a3089223c21b827b9eba899341334c94 Mon Sep 17 00:00:00 2001 From: bexan Date: Mon, 4 Mar 2024 14:02:33 +0100 Subject: [PATCH 05/19] Test: add createListing --- crates/solis/messaging.local.json | 2 +- packages/core/src/contracts.ts | 2 +- packages/core/tests-new/cancel.test.ts | 13 +++ packages/core/tests-new/createListing.test.ts | 98 +++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/core/tests-new/createListing.test.ts diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 68f17dfda..e77a3e4ac 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x53a0b0ca4b9d248dff574299c98340b67197f7ffc79df9afef66d01e83022c6", + "contract_address": "0xeaa57fbf5d788e725deaedbd9f4df15d27283cf172dc292e6ae7e10cae534e", "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index a12730092..f1a0d0844 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -15,5 +15,5 @@ export const DEV_CONTRACTS = { "executor": "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", "nftContract": "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x33b337f2c708c08e49f5e0161658ed093101dd629c3147ad9eea921e6a6afe3" + "orderbook": "0x3a17e9b01be196724e940c1f2e5cbbfe2e5f106fffc2669772e36b9b900a75b" }; diff --git a/packages/core/tests-new/cancel.test.ts b/packages/core/tests-new/cancel.test.ts index 695b320a4..50f2de75c 100644 --- a/packages/core/tests-new/cancel.test.ts +++ b/packages/core/tests-new/cancel.test.ts @@ -11,6 +11,7 @@ import { import { cancelOrder, createListing } from "../src/actions/order"; import { getOrderStatus } from "../src/actions/read"; import { ListingV1 } from "../src/types"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; test("ArkProject Cancel listing should create and then cancel a listing", async () => { const { account: arkAccount } = await createAccount(config.arkProvider); @@ -22,6 +23,18 @@ test("ArkProject Cancel listing should create and then cancel a listing", async process.env.STARKNET_ACCOUNT1_PRIVATE_KEY ); + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + await mintERC721(config.starknetProvider, starknetOffererAccount); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); diff --git a/packages/core/tests-new/createListing.test.ts b/packages/core/tests-new/createListing.test.ts new file mode 100644 index 000000000..12655320f --- /dev/null +++ b/packages/core/tests-new/createListing.test.ts @@ -0,0 +1,98 @@ +import { shortString } from "starknet"; + +import { config } from "../examples/config"; +import { STARKNET_NFT_ADDRESS } from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { + createAccount, + fetchOrCreateAccount +} from "../src/actions/account/account"; +import { createListing } from "../src/actions/order"; +import { getOrderStatus } from "../src/actions/read"; +import { ListingV1 } from "../src/types"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; + +test("ArkProject create a listing", async () => { + const { account: arkAccount } = await createAccount(config.arkProvider); + expect(arkAccount).toBeDefined(); + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + await mintERC721(config.starknetProvider, starknetOffererAccount); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + + const order: ListingV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: BigInt(tokenId) + BigInt(1), + startAmount: 600000000000000000 + }; + + const orderHash = await createListing(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + order + }); + expect(orderHash).toBeDefined(); + + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + +}, 20000); + +test("ArkProject create a listing without whitelisting broker", async () => { + const { account: arkAccount } = await createAccount(config.arkProvider); + expect(arkAccount).toBeDefined(); + + + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + await mintERC721(config.starknetProvider, starknetOffererAccount); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + + const order: ListingV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: BigInt(tokenId) + BigInt(1), + startAmount: 600000000000000000 + }; + + const orderHash = await createListing(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + order + }); + console.log(orderHash); + expect(orderHash).toBeDefined(); + + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + +}, 20000); From e4f8fdfdd601f93ffce3fe1f3e4329032486b7d0 Mon Sep 17 00:00:00 2001 From: bexan Date: Mon, 4 Mar 2024 20:04:58 +0100 Subject: [PATCH 06/19] Tests: add cancelOffer --- crates/solis/messaging.local.json | 2 +- packages/core/README.md | 2 +- packages/core/examples/createOffer.ts | 15 ++- packages/core/src/contracts.ts | 8 +- packages/core/tests-new/cancelOffer.test.ts | 99 +++++++++++++++++++ packages/core/tests-new/createAccount.test.ts | 24 +++++ packages/core/tests-new/createListing.test.ts | 26 +++-- packages/core/tests-new/utils/index.ts | 28 ++++++ 8 files changed, 179 insertions(+), 25 deletions(-) create mode 100644 packages/core/tests-new/cancelOffer.test.ts create mode 100644 packages/core/tests-new/createAccount.test.ts create mode 100644 packages/core/tests-new/utils/index.ts diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index e77a3e4ac..11f9aae9c 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0xeaa57fbf5d788e725deaedbd9f4df15d27283cf172dc292e6ae7e10cae534e", + "contract_address": "0x57267e9d7fcba7826d324b3766887fee7882e11c52553999f83bf7746ac4c65", "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, diff --git a/packages/core/README.md b/packages/core/README.md index 352c7b61e..6d0f261ed 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -41,7 +41,7 @@ npx ts-node examples/createListing.ts ``` ```bash -npx ts-node examples/create-offer.ts +npx ts-node examples/createOffer.ts ``` ```bash diff --git a/packages/core/examples/createOffer.ts b/packages/core/examples/createOffer.ts index ec4e1f5c8..6ed8c3dad 100644 --- a/packages/core/examples/createOffer.ts +++ b/packages/core/examples/createOffer.ts @@ -5,7 +5,7 @@ * checking the order status */ -import { shortString } from "starknet"; +import { Contract, shortString } from "starknet"; import "dotenv/config"; @@ -20,6 +20,7 @@ import { import { config } from "./config"; import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "./constants"; import { mintERC20 } from "./utils/mintERC20"; +import { whitelistBroker } from "./utils/whitelistBroker"; /** * Creates a offer on the blockchain using provided order details. @@ -27,11 +28,21 @@ import { mintERC20 } from "./utils/mintERC20"; (async () => { console.log(`=> Getting config...`); const { arkProvider, starknetProvider } = config; + const brokerId = 123; console.log(`=> Creating account`); // Create a new account for the offer using the provider const { account: arkAccount } = await createAccount(arkProvider); + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + console.log(`=> Whitelisting broker ${brokerId}`); + await whitelistBroker(config, solisAdminAccount, brokerId); + console.log( `=> Fetching or creating offerer starknet account, for test purpose only` ); @@ -44,7 +55,7 @@ import { mintERC20 } from "./utils/mintERC20"; console.log(`=> Creating order`); // Define the offer details const offer: OfferV1 = { - brokerId: 123, // The broker ID + brokerId, // The broker ID tokenAddress: STARKNET_NFT_ADDRESS, // The token address tokenId: 20, // The ID of the token startAmount: 100000000000000000, // The starting amount for the order diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index f1a0d0844..7165c4a30 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -10,10 +10,4 @@ export const GOERLI_CONTRACTS = { }; export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; -export const DEV_CONTRACTS = { - "messaging": "0x53a0b0ca4b9d248dff574299c98340b67197f7ffc79df9afef66d01e83022c6", - "executor": "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", - "nftContract": "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", - "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x3a17e9b01be196724e940c1f2e5cbbfe2e5f106fffc2669772e36b9b900a75b" -}; +export const DEV_CONTRACTS = {"messaging":"0x57267e9d7fcba7826d324b3766887fee7882e11c52553999f83bf7746ac4c65","executor":"0x78f192d8081c68ec4fcc95b17435ceaad4abb26b3227b5d86553fda351912ae","nftContract":"0x552e8522d541d69f608b30a7f5c26092003c2ac5cbdf64ac6da6a03674a56d3","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x4b6fd3b86c499ce95497234c4cc34bc2db6ba689f8b43ae770535d882984ab7"}; diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts new file mode 100644 index 000000000..9ec73e74e --- /dev/null +++ b/packages/core/tests-new/cancelOffer.test.ts @@ -0,0 +1,99 @@ +import { Account, AccountInterface, RpcProvider, shortString } from "starknet"; + +import { config } from "../examples/config"; + +import { + approveERC20, + cancelOrder, + createAccount, + createOffer, fetchOrCreateAccount, + getOrderStatus, + getOrderType, + ListingV1 +} from "../src"; +import { + generateRandomTokenId, + getTypeFromCairoCustomEnum, + sleep +} from "./utils"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; + +describe("ArkProject cancel offer", () => { + it("should cancel an offer and verify its status and type", async () => { + const { arkProvider, starknetProvider } = config; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + + const { account: arkAccount } = await createAccount(arkProvider); + const { account: starknetAccount } = await createAccount(starknetProvider); + const order: ListingV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: generateRandomTokenId(), + startAmount: 600000000000000000, + currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address + }; + + await mintERC20( + starknetProvider, + starknetAccount, + order.startAmount + ); + + await approveERC20(config, { + starknetAccount: starknetAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + + const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); + await sleep(1000); // Wait for the transaction to be processed + /* + // Use Jest's expect for promise resolution + await expect( + await getOrderStatus(config, { + orderHash + }).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("OPEN"); + + await expect( + getOrderType(config, {orderHash}).then((res) => + getTypeFromCairoCustomEnum(res.orderType) + ) + ).resolves.toEqual("OFFER"); + + + const cancelInfo = { + orderHash: orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId + }; + + await cancelOrder(config, { + starknetAccount, + arkAccount, + cancelInfo + }); + + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("CANCELLED_USER");*/ + }, 30000); +}); diff --git a/packages/core/tests-new/createAccount.test.ts b/packages/core/tests-new/createAccount.test.ts new file mode 100644 index 000000000..8d9b32db0 --- /dev/null +++ b/packages/core/tests-new/createAccount.test.ts @@ -0,0 +1,24 @@ +import { RpcProvider } from "starknet"; + +import { createAccount } from "../src/actions/account/account"; + +describe("ArkProject Account Creation", () => { + it("should successfully create an account", async () => { + // Initialize the RPC provider with the ArkChain node URL + const provider = new RpcProvider({ + nodeUrl: "http://0.0.0.0:7777" + }); + + // Create an account using the provider + const accountDetails = await createAccount(provider); + + // Assertions to verify account creation + expect(accountDetails).toHaveProperty("address"); + expect(typeof accountDetails.address).toBe("string"); + expect(accountDetails).toHaveProperty("privateKey"); + expect(typeof accountDetails.privateKey).toBe("string"); + expect(accountDetails).toHaveProperty("publicKey"); + expect(typeof accountDetails.publicKey).toBe("string"); + expect(accountDetails).toHaveProperty("account"); + }); +}); diff --git a/packages/core/tests-new/createListing.test.ts b/packages/core/tests-new/createListing.test.ts index 12655320f..4cbb774fa 100644 --- a/packages/core/tests-new/createListing.test.ts +++ b/packages/core/tests-new/createListing.test.ts @@ -75,24 +75,22 @@ test("ArkProject create a listing without whitelisting broker", async () => { const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); const order: ListingV1 = { - brokerId: 123, + brokerId: 12345, tokenAddress: STARKNET_NFT_ADDRESS, tokenId: BigInt(tokenId) + BigInt(1), startAmount: 600000000000000000 }; - const orderHash = await createListing(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - order - }); - console.log(orderHash); - expect(orderHash).toBeDefined(); - - const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { - orderHash - }); - - expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + try { + await createListing(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + order + }); + } + catch (e) { + const errorString = e instanceof Error ? e.message : JSON.stringify(e); + expect(errorString).toMatch(/Transaction execution has failed./); + } }, 20000); diff --git a/packages/core/tests-new/utils/index.ts b/packages/core/tests-new/utils/index.ts new file mode 100644 index 000000000..cbc53d590 --- /dev/null +++ b/packages/core/tests-new/utils/index.ts @@ -0,0 +1,28 @@ +import { CairoCustomEnum } from "starknet"; + +export function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +export function generateRandomTokenId(): number { + return Math.floor(Math.random() * 10000) + 1; +} + +type VariantKey = "Listing" | "Auction" | "Offer" | "CollectionOffer"; + +export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) { + const keyMap = { + Listing: "LISTING", + Auction: "AUCTION", + Offer: "OFFER", + CollectionOffer: "COLLECTION_OFFER" + }; + + for (const key in cairoCustomEnum.variant) { + if (cairoCustomEnum.variant[key as VariantKey] !== undefined) { + return keyMap[key as VariantKey] || "Unknown"; + } + } + + throw new Error("No valid variant found in CairoCustomEnum"); +} From 7f7d856cf1754a871dd738854e95a4faa846f5b1 Mon Sep 17 00:00:00 2001 From: bexan Date: Tue, 5 Mar 2024 06:47:53 +0100 Subject: [PATCH 07/19] Solis Tests: add missing tests --- crates/solis/messaging.local.json | 2 +- crates/solis/src/hooker.rs | 1 - packages/core/src/contracts.ts | 18 +-- packages/core/src/utils/index.ts | 3 +- packages/core/tests-new/cancelOffer.test.ts | 30 ++--- .../core/tests-new/fulfillListing.test.ts | 83 ++++++++++++++ packages/core/tests-new/fulfillOffer.test.ts | 108 ++++++++++++++++++ 7 files changed, 215 insertions(+), 30 deletions(-) create mode 100644 packages/core/tests-new/fulfillListing.test.ts create mode 100644 packages/core/tests-new/fulfillOffer.test.ts diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 11f9aae9c..7321236e5 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x57267e9d7fcba7826d324b3766887fee7882e11c52553999f83bf7746ac4c65", + "contract_address": "0x39158ac23c270863af623b7f3f9f5d4d723406df4e7b6153bd2a81ea320304d", "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs index 4c2420230..4fb7126d1 100644 --- a/crates/solis/src/hooker.rs +++ b/crates/solis/src/hooker.rs @@ -213,7 +213,6 @@ impl KatanaHooker for Sol order.currency_address.into(), self.sn_utils_reader.provider(), ); - let allowance = sn_utils_reader_erc20_address .allowance(&order.offerer, &self.sn_executor_address.into()) .call() diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index 7165c4a30..52bd34e41 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -1,13 +1,17 @@ // This file is auto-generated. Do not edit directly. export const GOERLI_CONTRACTS = { - nftContract: - "0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436", - messaging: - "0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8", - executor: "0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc", - orderbook: "0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310" + "nftContract": "0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436", + "messaging": "0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8", + "executor": "0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc", + "orderbook": "0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310" }; export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; -export const DEV_CONTRACTS = {"messaging":"0x57267e9d7fcba7826d324b3766887fee7882e11c52553999f83bf7746ac4c65","executor":"0x78f192d8081c68ec4fcc95b17435ceaad4abb26b3227b5d86553fda351912ae","nftContract":"0x552e8522d541d69f608b30a7f5c26092003c2ac5cbdf64ac6da6a03674a56d3","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x4b6fd3b86c499ce95497234c4cc34bc2db6ba689f8b43ae770535d882984ab7"}; +export const DEV_CONTRACTS = { + "messaging": "0x39158ac23c270863af623b7f3f9f5d4d723406df4e7b6153bd2a81ea320304d", + "executor": "0xf15cf88c171ed5c762b895331319ca57177cf31f575c76536e7657c8874bc6", + "nftContract": "0x5672baf1f4f06d36ef564ace9248b7df377ec112853aa605dd51bbd006323a7", + "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", + "orderbook": "0x78cb9198f2e5015f29387b5db24c27a42eb143d4d5093d2716f4452a2e2559" +}; diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 716fb3cbe..0113376ce 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,9 +1,8 @@ import * as starknet from "@scure/starknet"; -import { Account, BigNumberish, CallData, Contract } from "starknet"; +import { CallData } from "starknet"; import { Config } from "../createConfig"; import { OrderV1 } from "../types"; -import * as sn from "starknet"; export const getOrderHashFromOrderV1 = (order: OrderV1) => { const compiledOrder = CallData.compile({ diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts index 9ec73e74e..db71da6d1 100644 --- a/packages/core/tests-new/cancelOffer.test.ts +++ b/packages/core/tests-new/cancelOffer.test.ts @@ -58,24 +58,17 @@ describe("ArkProject cancel offer", () => { amount: order.startAmount }); - const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); await sleep(1000); // Wait for the transaction to be processed - /* // Use Jest's expect for promise resolution - await expect( - await getOrderStatus(config, { - orderHash - }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("OPEN"); + const r1 = await getOrderStatus(config, { orderHash }); + const orderStatusBefore = shortString.decodeShortString(r1.orderStatus) + expect(orderStatusBefore).toEqual("OPEN"); + + const r2 = await getOrderType(config, { orderHash }); + const orderType = getTypeFromCairoCustomEnum(r2.orderType); - await expect( - getOrderType(config, {orderHash}).then((res) => - getTypeFromCairoCustomEnum(res.orderType) - ) - ).resolves.toEqual("OFFER"); + expect(orderType).toEqual("OFFER"); const cancelInfo = { @@ -90,10 +83,9 @@ describe("ArkProject cancel offer", () => { cancelInfo }); - await expect( - getOrderStatus(config, {orderHash}).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("CANCELLED_USER");*/ + const r3 = await getOrderStatus(config, { orderHash }); + const orderStatusAfter = shortString.decodeShortString(r3.orderStatus) + expect(orderStatusAfter).toEqual("CANCELLED_USER"); + }, 30000); }); diff --git a/packages/core/tests-new/fulfillListing.test.ts b/packages/core/tests-new/fulfillListing.test.ts new file mode 100644 index 000000000..e2b11e248 --- /dev/null +++ b/packages/core/tests-new/fulfillListing.test.ts @@ -0,0 +1,83 @@ +import { BigNumberish, shortString } from "starknet"; + +import { createAccount, fetchOrCreateAccount } from "../src/actions/account/account"; +import { createListing, fulfillListing } from "../src/actions/order"; +import { getOrderHash, getOrderStatus } from "../src/actions/read"; +import { ListingV1 } from "../src/types"; +import { generateRandomTokenId, sleep } from "./utils"; + +import { config } from "../examples/config"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; + + +describe("ArkProject Listing", () => { + it("should create and fulfill a listing", async () => { + const { arkProvider, starknetProvider } = config; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + + // Create a new account using the provider + const { account: arkAccount } = await createAccount(arkProvider); + const { account: starknetAccount } = await createAccount(starknetProvider); + + const order: ListingV1 = { + brokerId: 123, // The broker ID + tokenAddress: + "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address + tokenId: generateRandomTokenId(), // The ID of the token + startAmount: 600000000000000000 // The starting amount for the order + }; + + const orderHash = await createListing(config, { + starknetAccount, + arkAccount, + order + }); + + await sleep(1000); + + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + + // Create a new accounts for the fulfill using the provider + const { account: starknetFulfillerAccount } = + await createAccount(starknetProvider); + + const fulfill_info = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId, + brokerId: 123 + }; + + fulfillListing( + config, + { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillListingInfo: fulfill_info + } + ); + await sleep(2000); + + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + + expect(shortString.decodeShortString(orderStatusAfter)).toBe("FULFILLED"); + + }, 30000); +}); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts new file mode 100644 index 000000000..21746615a --- /dev/null +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -0,0 +1,108 @@ +import { shortString } from "starknet"; + +import { + approveERC20, + createAccount, + createOffer, fetchOrCreateAccount, + fulfillOffer, + getOrderStatus, ListingV1, + OfferV1 +} from "../src"; +import { generateRandomTokenId } from "./utils"; +import { config } from "../examples/config"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; +import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; +import { mintERC20 } from "../examples/utils/mintERC20"; + + +describe("ArkProject Listing and Offer Fulfillment", () => { + it("should create an offer and fulfill the offer", async function () { + + const { arkProvider, starknetProvider } = config; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + + // Create a new account for the listing using the provider + const { account: arkAccount } = await createAccount(arkProvider); + const { account: starknetAccount } = await createAccount(starknetProvider); + + // Define the order details + const order: OfferV1 = { + brokerId: 123, // The broker ID + tokenAddress: STARKNET_NFT_ADDRESS, // The token address + tokenId: generateRandomTokenId(), // The ID of the token + startAmount: 600000000000000000, // The starting amount for the order + currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address + }; + + await mintERC20( + starknetProvider, + starknetAccount, + order.startAmount + ); + + // for allowance + await approveERC20(config, { + starknetAccount: starknetAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + // Create the listing on the arkchain using the order details + const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); + + expect(orderHash).toBeDefined(); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("OPEN"); + + + // Create a new account for fulfilling the offer + const { account: starknetFulfillerAccount } = + await createAccount(starknetProvider); + + expect(starknetFulfillerAccount).toBeDefined(); + + // Define the fulfill details + const fulfill_info = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId, + brokerId: 123 + }; + + // Fulfill the offer + await fulfillOffer( + config, + { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillOfferInfo: fulfill_info + } + ); + + await new Promise((resolve) => setTimeout(resolve, 5000)); + + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("FULFILLED"); + + }, 40000); +}); From c528bcd14a6a39ab56fa5559bd41a486bc9af733 Mon Sep 17 00:00:00 2001 From: bexan Date: Wed, 6 Mar 2024 09:16:00 +0100 Subject: [PATCH 08/19] Core: fix readme --- packages/core/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/README.md b/packages/core/README.md index 6d0f261ed..d14f6ac5f 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -45,15 +45,15 @@ npx ts-node examples/createOffer.ts ``` ```bash -npx ts-node examples/cancel-offer.ts +npx ts-node examples/cancelListing.ts ``` ```bash -npx ts-node examples/fulfill-listing.ts +npx ts-node examples/fulfillListing.ts ``` ```bash -npx ts-node examples/fulfill-offer.ts +npx ts-node examples/fulfillOffer.ts ``` ## Usage From e85b414b03dc7f325261ce09eb0afbbc2ae1fb63 Mon Sep 17 00:00:00 2001 From: bexan Date: Thu, 7 Mar 2024 12:35:34 +0100 Subject: [PATCH 09/19] Hooker: add verification ownership & balance --- artifacts/starknet_utils.json | 46 +++ crates/solis/src/hooker.rs | 292 ++++++++++++------ packages/core/.env.example | 4 + .../core/examples/utils/changeTokenOwner.ts | 46 +++ packages/core/src/contracts.ts | 2 +- packages/core/tests-new/cancelOffer.test.ts | 2 +- packages/core/tests-new/fulfillOffer.test.ts | 153 ++++++++- 7 files changed, 447 insertions(+), 98 deletions(-) create mode 100644 packages/core/examples/utils/changeTokenOwner.ts diff --git a/artifacts/starknet_utils.json b/artifacts/starknet_utils.json index ff6bde387..9c3ca5169 100644 --- a/artifacts/starknet_utils.json +++ b/artifacts/starknet_utils.json @@ -1,4 +1,50 @@ [ + { + "type": "struct", + "name": "package_name::ExecutionInfo", + "members": [ + { + "name": "order_hash", + "type": "core::felt252" + }, + { + "name": "nft_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "nft_from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "nft_to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "nft_token_id", + "type": "core::integer::u256" + }, + { + "name": "payment_from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "payment_to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "payment_amount", + "type": "core::integer::u256" + }, + { + "name": "payment_currency_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "payment_currency_chain_id", + "type": "core::felt252" + } + ] + }, { "type": "struct", "name": "core::integer::u256", diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs index 4fb7126d1..32bd0488f 100644 --- a/crates/solis/src/hooker.rs +++ b/crates/solis/src/hooker.rs @@ -1,6 +1,6 @@ //! Solis hooker on Katana transaction lifecycle. //! -use crate::contracts::starknet_utils::U256; +use crate::contracts::starknet_utils::{ExecutionInfo, U256}; use async_trait::async_trait; use cainome::cairo_serde::CairoSerde; use cainome::rs::abigen; @@ -21,6 +21,18 @@ use crate::contracts::orderbook::{OrderV1, RouteType}; use crate::contracts::starknet_utils::StarknetUtilsReader; use crate::CHAIN_ID_SOLIS; +struct OwnershipVerifier { + token_address: ContractAddress, + token_id: U256, + current_owner: cainome::cairo_serde::ContractAddress, +} + +struct BalanceVerifier { + currency_address: ContractAddress, + offerer: cainome::cairo_serde::ContractAddress, + start_amount: U256, +} + abigen!(CallContract, "./artifacts/contract.abi.json"); /// Hooker struct, with already instanciated contracts/readers @@ -36,6 +48,139 @@ pub struct SolisHooker { sequencer: Option>, } +impl SolisHooker

{ + /// Verify the ownership of a token + async fn verify_ownership(&self, ownership_verifier: &OwnershipVerifier) -> bool { + let sn_utils_reader_nft_address = StarknetUtilsReader::new( + ownership_verifier.token_address.into(), + self.sn_utils_reader.provider(), + ); + + // check the current owner of the token. + let owner = sn_utils_reader_nft_address + .ownerOf(&ownership_verifier.token_id) + .call() + .await; + + if let Ok(owner_address) = owner { + if owner_address != ownership_verifier.current_owner { + tracing::trace!( + "\nOwner {:?} differs from offerer {:?} ", + owner, + ownership_verifier.current_owner + ); + + println!( + "\nOwner {:?} differs from offerer {:?} ", + owner, ownership_verifier.current_owner + ); + + return false; + } + } + + true + } + + async fn verify_balance(&self, balance_verifier: &BalanceVerifier) -> bool { + let sn_utils_reader_erc20_address = StarknetUtilsReader::new( + balance_verifier.currency_address.into(), + self.sn_utils_reader.provider(), + ); + let allowance = sn_utils_reader_erc20_address + .allowance(&balance_verifier.offerer, &self.sn_executor_address.into()) + .call() + .await; + + if let Ok(allowance) = allowance { + if allowance < balance_verifier.start_amount { + tracing::trace!( + "\nAllowance {:?} is not enough {:?} ", + allowance, + balance_verifier.start_amount + ); + println!( + "\nAllowance {:?} is not enough {:?} ", + allowance, balance_verifier.start_amount + ); + return false; + } + } + + // check the balance + let balance = sn_utils_reader_erc20_address + .balanceOf(&balance_verifier.offerer) + .call() + .await; + if let Ok(balance) = balance { + if balance < balance_verifier.start_amount { + tracing::trace!( + "\nBalance {:?} is not enough {:?} ", + balance, + balance_verifier.start_amount + ); + println!( + "\nBalance {:?} is not enough {:?} ", + balance, balance_verifier.start_amount + ); + return false; + } + } + + true + } + + async fn verify_call(&self, call: &TxCall) -> bool { + let order = match OrderV1::cairo_deserialize(&call.calldata, 0) { + Ok(order) => order, + Err(e) => { + tracing::error!("Fail deserializing OrderV1: {:?}", e); + return false; + } + }; + + // ERC721 to ERC20 + if order.route == RouteType::Erc721ToErc20 { + let token_id = order.token_id.clone().unwrap(); + let n_token_id = U256 { + low: token_id.low, + high: token_id.high, + }; + + let verifier = OwnershipVerifier { + token_address: ContractAddress(order.token_address.into()), + token_id: n_token_id, + current_owner: cainome::cairo_serde::ContractAddress(order.offerer.into()), + }; + + let owner_ship_verification = self.verify_ownership(&verifier).await; + if !owner_ship_verification { + println!("verify ownership for starknet before failed"); + return false; + } + } + + // ERC20 to ERC721 : we check the allowance and the offerer balance. + if order.route == RouteType::Erc20ToErc721 { + if !self + .verify_balance(&BalanceVerifier { + currency_address: ContractAddress(order.currency_address.into()), + offerer: cainome::cairo_serde::ContractAddress(order.offerer.into()), + start_amount: U256 { + low: order.start_amount.low, + high: order.start_amount.high, + }, + }) + .await + { + println!("verify balance for starknet before failed"); + return false; + } + } + return true; + } +} + impl SolisHooker

{ /// Initializes a new instance. pub fn new( @@ -169,96 +314,8 @@ impl KatanaHooker for Sol continue; } - let order = match OrderV1::cairo_deserialize(&call.calldata, 0) { - Ok(order) => order, - Err(e) => { - tracing::error!("Fail deserializing OrderV1: {:?}", e); - return false; - } - }; - - let sn_utils_reader_nft_address = StarknetUtilsReader::new( - order.token_address.into(), - self.sn_utils_reader.provider(), - ); - - // ERC721 to ERC20 - if order.route == RouteType::Erc721ToErc20 { - let token_id = order.token_id.clone().unwrap(); - let n_token_id = U256 { - low: token_id.low, - high: token_id.high, - }; - - // check the current owner of the token. - let owner = sn_utils_reader_nft_address - .ownerOf(&n_token_id) - .call() - .await; - if let Ok(owner_address) = owner { - if owner_address != order.offerer { - tracing::trace!( - "\nOwner {:?} differs from offerer {:?} ", - owner, - order.offerer - ); - return false; - } - } - } - - // ERC20 to ERC721 : we check the allowance and the offerer balance. - if order.route == RouteType::Erc20ToErc721 { - let sn_utils_reader_erc20_address = StarknetUtilsReader::new( - order.currency_address.into(), - self.sn_utils_reader.provider(), - ); - let allowance = sn_utils_reader_erc20_address - .allowance(&order.offerer, &self.sn_executor_address.into()) - .call() - .await; - if let Ok(allowance) = allowance { - let n_start_amount = U256 { - low: order.start_amount.low, - high: order.start_amount.high, - }; - if allowance < n_start_amount { - tracing::trace!( - "\nAllowance {:?} is not enough {:?} ", - allowance, - order.start_amount - ); - println!( - "\nAllowance {:?} is not enough {:?} ", - allowance, order.start_amount - ); - return false; - } - } - - // check the balance - let balance = sn_utils_reader_erc20_address - .balanceOf(&order.offerer) - .call() - .await; - if let Ok(balance) = balance { - let n_start_amount = U256 { - low: order.start_amount.low, - high: order.start_amount.high, - }; - if balance < n_start_amount { - tracing::trace!( - "\nBalance {:?} is not enough {:?} ", - balance, - order.start_amount - ); - println!( - "\nBalance {:?} is not enough {:?} ", - balance, order.start_amount - ); - return false; - } - } + if !self.verify_call(&call).await { + return false; } // TODO: check assets on starknet. @@ -271,9 +328,56 @@ impl KatanaHooker for Sol async fn verify_tx_for_starknet(&self, call: Call) -> bool { println!("verify message to starknet before tx: {:?}", call); - // TODO: Decode the ExecutionInfo from the calldata. - // Check that assets are still in the good location. When this function - // returns true, a transaction is fired on Starknet for the execution. + let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { + Ok(execution_info) => execution_info, + Err(e) => { + tracing::error!("Fail deserializing ExecutionInfo: {:?}", e); + return false; + } + }; + + println!( + "verify balance for starknet before from : {:?}", + execution_info.nft_from + ); + println!( + "verify balance for starknet before to : {:?}", + execution_info.nft_to + ); + println!( + "verify balance for starknet before amount : {:?}", + execution_info.payment_amount.low + ); + + let verifier = OwnershipVerifier { + token_address: ContractAddress(execution_info.nft_address.into()), + token_id: execution_info.nft_token_id, + current_owner: cainome::cairo_serde::ContractAddress(execution_info.nft_to.into()), + }; + + let owner_ship_verification = self.verify_ownership(&verifier).await; + if !owner_ship_verification { + println!("verify ownership for starknet before failed"); + return false; + } + + if !self + .verify_balance(&BalanceVerifier { + currency_address: ContractAddress(execution_info.payment_currency_address.into()), + offerer: cainome::cairo_serde::ContractAddress(execution_info.nft_from.into()), + start_amount: U256 { + low: execution_info.payment_amount.low, + high: execution_info.payment_amount.high, + }, + }) + .await + { + return false; + } + + println!("order nft_address{:?}", &execution_info.nft_address); + println!("order nft_from{:?}", &execution_info.nft_from); + true } diff --git a/packages/core/.env.example b/packages/core/.env.example index 6560c651b..714b52488 100644 --- a/packages/core/.env.example +++ b/packages/core/.env.example @@ -12,6 +12,10 @@ STARKNET_ACCOUNT2_ADDRESS=0x5686a647a9cdd63ade617e0baf3b364856b813b508f03903eb58 STARKNET_ACCOUNT2_PRIVATE_KEY=0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b STARKNET_ACCOUNT2_PUBLIC_KEY=0x4c0f884b8e5b4f00d97a3aad26b2e5de0c0c76a555060c837da2e287403c01d +SOLIS_ADMIN_ADDRESS_DEV=0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca +SOLIS_ADMIN_PRIVATE_KEY_DEV=0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a +SOLIS_ADMIN_PUBLIC_KEY_DEV=0x640466ebd2ce505209d3e5c4494b4276ed8f1cde764d757eb48831961f7cdea + # Starknet network STARKNET_NETWORK_ID=dev # Solis network diff --git a/packages/core/examples/utils/changeTokenOwner.ts b/packages/core/examples/utils/changeTokenOwner.ts new file mode 100644 index 000000000..21c147be6 --- /dev/null +++ b/packages/core/examples/utils/changeTokenOwner.ts @@ -0,0 +1,46 @@ +import { BigNumberish, cairo, CairoOption, CairoOptionVariant, CallData, Uint256 } from "starknet"; + +import { Config } from "../../src/createConfig"; +import { fetchOrCreateAccount } from "../../src"; +import { getCurrentTokenId } from "./getCurrentTokenId"; + +export const changeTokenOwner = async ( + config: Config, + nftContractAddress: string, + from: string, + to: string, + tokenId: BigNumberish +) => { + const { abi } = await config.starknetProvider.getClassAt(nftContractAddress); + if (abi === undefined) { + throw new Error("no abi."); + } + + const token = new CairoOption( + CairoOptionVariant.Some, + cairo.uint256(tokenId) + ); + + const adminAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_ADDRESS_DEV + ); + + const nTokenId = await getCurrentTokenId(config, nftContractAddress) + BigInt(1); + console.log("nTokenId", nTokenId) + const hash_calldata = CallData.compile({ + from, + to, + tokenId: cairo.uint256(nTokenId), + }); + + const result = await adminAccount.execute({ + contractAddress: config.starknetContracts.nftContract, + entrypoint: "transfer_from", + calldata: hash_calldata + }); + + console.log("result change", result) + return; +}; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index 52bd34e41..77db0ca64 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -13,5 +13,5 @@ export const DEV_CONTRACTS = { "executor": "0xf15cf88c171ed5c762b895331319ca57177cf31f575c76536e7657c8874bc6", "nftContract": "0x5672baf1f4f06d36ef564ace9248b7df377ec112853aa605dd51bbd006323a7", "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x78cb9198f2e5015f29387b5db24c27a42eb143d4d5093d2716f4452a2e2559" + "orderbook": "0x66cdd48f252d5d982550bc5e78db7038aa330460ad87be82495ba32676d3a91" }; diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts index db71da6d1..48e4f4222 100644 --- a/packages/core/tests-new/cancelOffer.test.ts +++ b/packages/core/tests-new/cancelOffer.test.ts @@ -87,5 +87,5 @@ describe("ArkProject cancel offer", () => { const orderStatusAfter = shortString.decodeShortString(r3.orderStatus) expect(orderStatusAfter).toEqual("CANCELLED_USER"); - }, 30000); + }, 40000); }); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts index 21746615a..eef2a3207 100644 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -1,8 +1,8 @@ -import { shortString } from "starknet"; +import { Contract, shortString } from "starknet"; import { approveERC20, - createAccount, + createAccount, createListing, createOffer, fetchOrCreateAccount, fulfillOffer, getOrderStatus, ListingV1, @@ -13,6 +13,10 @@ import { config } from "../examples/config"; import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; import { mintERC20 } from "../examples/utils/mintERC20"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { changeTokenOwner } from "../examples/utils/changeTokenOwner"; +import { getTokenOwner } from "../examples/utils/getTokenOwner"; describe("ArkProject Listing and Offer Fulfillment", () => { @@ -105,4 +109,149 @@ describe("ArkProject Listing and Offer Fulfillment", () => { ).resolves.toEqual("FULFILLED"); }, 40000); + + + it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { + + const { arkProvider, starknetProvider } = config; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker( + config, + solisAdminAccount, + 123 + ); + + const { account: starknetOwner } = await createAccount(starknetProvider); + const { account: arkAccount } = await createAccount(arkProvider); + + await mintERC721(config.starknetProvider, starknetOwner); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + + const orderListing: ListingV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId, + startAmount: 600000000000000000 + }; + + await createListing(config, { + starknetAccount: starknetOwner, + arkAccount, + order: orderListing + }); + + // Create a new account for the listing using the provider + const { account: starknetAccount } = await createAccount(starknetProvider); + + // Define the order details + const order: OfferV1 = { + brokerId: 123, // The broker ID + tokenAddress: STARKNET_NFT_ADDRESS, // The token address + tokenId: tokenId, // The ID of the token + startAmount: 600000000000000000, // The starting amount for the order + currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address + }; + + await mintERC20( + starknetProvider, + starknetAccount, + order.startAmount + ); + + // for allowance + await approveERC20(config, { + starknetAccount: starknetAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + // Create the offer on the arkchain using the order details + const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); + + expect(orderHash).toBeDefined(); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("OPEN"); + + + // Create a new account for fulfilling the offer + const { account: starknetFulfillerAccount } = + await createAccount(starknetProvider); + + expect(starknetFulfillerAccount).toBeDefined(); + + // change owner of token + /* await changeTokenOwner(config, + STARKNET_NFT_ADDRESS, + starknetOwner.address, + starknetFulfillerAccount.address, + order.tokenId + );*/ + + // Define the fulfill details + const fulfill_info = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId, + brokerId: 123 + }; + + // Fulfill the offer + await fulfillOffer( + config, + { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillOfferInfo: fulfill_info + } + ); + + const compressedContract = await config?.starknetProvider.getClassAt( + STARKNET_ETH_ADDRESS + ); + + const tokenContract = new Contract( + compressedContract?.abi, + STARKNET_ETH_ADDRESS, + config.starknetProvider + ); + + const allowance = await tokenContract.allowance( + starknetFulfillerAccount.address, + config?.starknetContracts.executor + ); + + const balance = await tokenContract.allowance( + starknetFulfillerAccount.address, + config?.starknetContracts.executor + ); + + const owner = await getTokenOwner(config, STARKNET_NFT_ADDRESS, tokenId); + + console.log("allowance", allowance.toString()); + console.log("balance", balance.toString()); + const ownerHex = "0x" + owner.toString(16).padStart(64, '0'); + console.log("Owner of tokenId", tokenId, "is", ownerHex); + console.log("offerer", starknetFulfillerAccount.address); + + await new Promise((resolve) => setTimeout(resolve, 5000)); + + await expect( + getOrderStatus(config, {orderHash}).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("FULFILLED"); + + }, 50000); }); From c5b770819b1848199c339a8db96d26173308bd1f Mon Sep 17 00:00:00 2001 From: kwiss Date: Fri, 8 Mar 2024 10:50:00 +0100 Subject: [PATCH 10/19] fix(test): update fulfill test --- contracts.json | 10 +- contracts/.tool-versions | 1 + contracts/ark_tokens/.tool-versions | 2 +- crates/solis/messaging.local.json | 6 +- packages/core/examples/fulfillListing.ts | 6 +- .../core/examples/utils/whitelistBroker.ts | 4 + packages/core/src/actions/account/account.ts | 2 - packages/core/src/contracts.ts | 10 +- packages/core/tests-new/cancel.test.ts | 8 +- packages/core/tests-new/cancelOffer.test.ts | 82 +++++------ packages/core/tests-new/createListing.test.ts | 14 +- .../core/tests-new/fulfillListing.test.ts | 127 ++++++++++++------ 12 files changed, 145 insertions(+), 127 deletions(-) create mode 100644 contracts/.tool-versions diff --git a/contracts.json b/contracts.json index deb6de131..f449728ec 100644 --- a/contracts.json +++ b/contracts.json @@ -8,10 +8,10 @@ "sepolia": {}, "mainnet": {}, "dev": { - "messaging": "0x53a0b0ca4b9d248dff574299c98340b67197f7ffc79df9afef66d01e83022c6", - "executor": "0x32cee2469074dabb6ee8dcce24df08d79e9ffd5f978163fbdd0704bce269bab", - "nftContract": "0x305bf776b8976a9709dde4cf307aebed4060e201ab3fca7154ca6db386f13c", - "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x33b337f2c708c08e49f5e0161658ed093101dd629c3147ad9eea921e6a6afe3" + "messaging": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", + "executor": "0x6c07c302d12d3798b83549356b9cd3c99607a5adbbf18ec7b7360bff75c4109", + "nftContract": "0x42cd09375b6744dbba98cc5e966c6de785ac5d47331df712f990c32bf3c7339", + "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", + "orderbook": "0x74e0489622f837f00cffe63cb4acaaed3f2ad38eec11218eabcdc4f09cfa644" } } diff --git a/contracts/.tool-versions b/contracts/.tool-versions new file mode 100644 index 000000000..0bcd69207 --- /dev/null +++ b/contracts/.tool-versions @@ -0,0 +1 @@ +scarb 2.4.1 \ No newline at end of file diff --git a/contracts/ark_tokens/.tool-versions b/contracts/ark_tokens/.tool-versions index 0bcd69207..963d7a0c6 100644 --- a/contracts/ark_tokens/.tool-versions +++ b/contracts/ark_tokens/.tool-versions @@ -1 +1 @@ -scarb 2.4.1 \ No newline at end of file +scarb 2.3.1 \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 7321236e5..56e43a057 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,9 +1,9 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x39158ac23c270863af623b7f3f9f5d4d723406df4e7b6153bd2a81ea320304d", - "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", - "private_key": "0x1800000000300000180000000000030000000000003006001800006600", + "contract_address": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", + "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", + "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", "interval": 2, "from_block": 0 } \ No newline at end of file diff --git a/packages/core/examples/fulfillListing.ts b/packages/core/examples/fulfillListing.ts index 3d61b07da..3aaf677b5 100644 --- a/packages/core/examples/fulfillListing.ts +++ b/packages/core/examples/fulfillListing.ts @@ -38,11 +38,7 @@ import { whitelistBroker } from "./utils/whitelistBroker"; ); console.log(`=> Whitelisting broker ${brokerId}`); - await whitelistBroker( - config, - solisAdminAccount, - brokerId - ); + await whitelistBroker(config, solisAdminAccount, brokerId); console.log(`=> Getting config...`); const { arkProvider, starknetProvider } = config; diff --git a/packages/core/examples/utils/whitelistBroker.ts b/packages/core/examples/utils/whitelistBroker.ts index 3e2f58760..8e90b490a 100644 --- a/packages/core/examples/utils/whitelistBroker.ts +++ b/packages/core/examples/utils/whitelistBroker.ts @@ -25,5 +25,9 @@ export const whitelistBroker = async ( calldata: whitelist_hash_calldata }); + await config.arkProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 200 + }); + return result; }; diff --git a/packages/core/src/actions/account/account.ts b/packages/core/src/actions/account/account.ts index cf2465117..c4d6ef14d 100644 --- a/packages/core/src/actions/account/account.ts +++ b/packages/core/src/actions/account/account.ts @@ -50,8 +50,6 @@ export const createAccount = async (provider: ProviderInterface) => { constructorCalldata: CallData.compile({ publicKey }), addressSalt: publicKey }); - console.log(provider); - console.log(transaction_hash, contract_address); const test = await provider.waitForTransaction(transaction_hash, { retryInterval: 100 }); diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index 77db0ca64..df72d5de4 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x39158ac23c270863af623b7f3f9f5d4d723406df4e7b6153bd2a81ea320304d", - "executor": "0xf15cf88c171ed5c762b895331319ca57177cf31f575c76536e7657c8874bc6", - "nftContract": "0x5672baf1f4f06d36ef564ace9248b7df377ec112853aa605dd51bbd006323a7", - "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x66cdd48f252d5d982550bc5e78db7038aa330460ad87be82495ba32676d3a91" + "messaging": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", + "executor": "0x6c07c302d12d3798b83549356b9cd3c99607a5adbbf18ec7b7360bff75c4109", + "nftContract": "0x42cd09375b6744dbba98cc5e966c6de785ac5d47331df712f990c32bf3c7339", + "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", + "orderbook": "0x74e0489622f837f00cffe63cb4acaaed3f2ad38eec11218eabcdc4f09cfa644" }; diff --git a/packages/core/tests-new/cancel.test.ts b/packages/core/tests-new/cancel.test.ts index 50f2de75c..a9895dc9d 100644 --- a/packages/core/tests-new/cancel.test.ts +++ b/packages/core/tests-new/cancel.test.ts @@ -4,6 +4,7 @@ import { config } from "../examples/config"; import { STARKNET_NFT_ADDRESS } from "../examples/constants"; import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { createAccount, fetchOrCreateAccount @@ -11,7 +12,6 @@ import { import { cancelOrder, createListing } from "../src/actions/order"; import { getOrderStatus } from "../src/actions/read"; import { ListingV1 } from "../src/types"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; test("ArkProject Cancel listing should create and then cancel a listing", async () => { const { account: arkAccount } = await createAccount(config.arkProvider); @@ -29,11 +29,7 @@ test("ArkProject Cancel listing should create and then cancel a listing", async process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - await whitelistBroker( - config, - solisAdminAccount, - 123 - ); + await whitelistBroker(config, solisAdminAccount, 123); await mintERC721(config.starknetProvider, starknetOffererAccount); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts index 48e4f4222..4a4cb5d36 100644 --- a/packages/core/tests-new/cancelOffer.test.ts +++ b/packages/core/tests-new/cancelOffer.test.ts @@ -1,24 +1,23 @@ -import { Account, AccountInterface, RpcProvider, shortString } from "starknet"; +import { shortString } from "starknet"; import { config } from "../examples/config"; - +import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { approveERC20, cancelOrder, createAccount, - createOffer, fetchOrCreateAccount, + createOffer, + fetchOrCreateAccount, getOrderStatus, getOrderType, ListingV1 } from "../src"; -import { - generateRandomTokenId, - getTypeFromCairoCustomEnum, - sleep -} from "./utils"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { mintERC20 } from "../examples/utils/mintERC20"; -import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; +import { generateRandomTokenId, getTypeFromCairoCustomEnum } from "./utils"; describe("ArkProject cancel offer", () => { it("should cancel an offer and verify its status and type", async () => { @@ -30,11 +29,7 @@ describe("ArkProject cancel offer", () => { process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - await whitelistBroker( - config, - solisAdminAccount, - 123 - ); + await whitelistBroker(config, solisAdminAccount, 123); const { account: arkAccount } = await createAccount(arkProvider); const { account: starknetAccount } = await createAccount(starknetProvider); @@ -46,11 +41,7 @@ describe("ArkProject cancel offer", () => { currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address }; - await mintERC20( - starknetProvider, - starknetAccount, - order.startAmount - ); + await mintERC20(starknetProvider, starknetAccount, order.startAmount); await approveERC20(config, { starknetAccount: starknetAccount, @@ -58,34 +49,35 @@ describe("ArkProject cancel offer", () => { amount: order.startAmount }); - const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); - await sleep(1000); // Wait for the transaction to be processed - // Use Jest's expect for promise resolution - const r1 = await getOrderStatus(config, { orderHash }); - const orderStatusBefore = shortString.decodeShortString(r1.orderStatus) - expect(orderStatusBefore).toEqual("OPEN"); - - const r2 = await getOrderType(config, { orderHash }); - const orderType = getTypeFromCairoCustomEnum(r2.orderType); + const orderHash = await createOffer(config, { + starknetAccount, + arkAccount, + offer: order + }); - expect(orderType).toEqual("OFFER"); + const r1 = await getOrderStatus(config, { orderHash }); + const orderStatusBefore = shortString.decodeShortString(r1.orderStatus); + expect(orderStatusBefore).toEqual("OPEN"); + const r2 = await getOrderType(config, { orderHash }); + const orderType = getTypeFromCairoCustomEnum(r2.orderType); - const cancelInfo = { - orderHash: orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - }; + expect(orderType).toEqual("OFFER"); - await cancelOrder(config, { - starknetAccount, - arkAccount, - cancelInfo - }); + const cancelInfo = { + orderHash: orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId + }; - const r3 = await getOrderStatus(config, { orderHash }); - const orderStatusAfter = shortString.decodeShortString(r3.orderStatus) - expect(orderStatusAfter).toEqual("CANCELLED_USER"); + await cancelOrder(config, { + starknetAccount, + arkAccount, + cancelInfo + }); - }, 40000); + const r3 = await getOrderStatus(config, { orderHash }); + const orderStatusAfter = shortString.decodeShortString(r3.orderStatus); + expect(orderStatusAfter).toEqual("CANCELLED_USER"); + }, 30000); }); diff --git a/packages/core/tests-new/createListing.test.ts b/packages/core/tests-new/createListing.test.ts index 4cbb774fa..3a0f33e6b 100644 --- a/packages/core/tests-new/createListing.test.ts +++ b/packages/core/tests-new/createListing.test.ts @@ -4,6 +4,7 @@ import { config } from "../examples/config"; import { STARKNET_NFT_ADDRESS } from "../examples/constants"; import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { createAccount, fetchOrCreateAccount @@ -11,7 +12,6 @@ import { import { createListing } from "../src/actions/order"; import { getOrderStatus } from "../src/actions/read"; import { ListingV1 } from "../src/types"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; test("ArkProject create a listing", async () => { const { account: arkAccount } = await createAccount(config.arkProvider); @@ -23,11 +23,7 @@ test("ArkProject create a listing", async () => { process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - await whitelistBroker( - config, - solisAdminAccount, - 123 - ); + await whitelistBroker(config, solisAdminAccount, 123); const starknetOffererAccount = await fetchOrCreateAccount( config.starknetProvider, @@ -57,14 +53,12 @@ test("ArkProject create a listing", async () => { }); expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); - }, 20000); test("ArkProject create a listing without whitelisting broker", async () => { const { account: arkAccount } = await createAccount(config.arkProvider); expect(arkAccount).toBeDefined(); - const starknetOffererAccount = await fetchOrCreateAccount( config.starknetProvider, process.env.STARKNET_ACCOUNT1_ADDRESS, @@ -87,10 +81,8 @@ test("ArkProject create a listing without whitelisting broker", async () => { arkAccount, order }); - } - catch (e) { + } catch (e) { const errorString = e instanceof Error ? e.message : JSON.stringify(e); expect(errorString).toMatch(/Transaction execution has failed./); } - }, 20000); diff --git a/packages/core/tests-new/fulfillListing.test.ts b/packages/core/tests-new/fulfillListing.test.ts index e2b11e248..6ed0d7b2f 100644 --- a/packages/core/tests-new/fulfillListing.test.ts +++ b/packages/core/tests-new/fulfillListing.test.ts @@ -1,50 +1,72 @@ -import { BigNumberish, shortString } from "starknet"; - -import { createAccount, fetchOrCreateAccount } from "../src/actions/account/account"; -import { createListing, fulfillListing } from "../src/actions/order"; -import { getOrderHash, getOrderStatus } from "../src/actions/read"; -import { ListingV1 } from "../src/types"; -import { generateRandomTokenId, sleep } from "./utils"; +import { shortString } from "starknet"; import { config } from "../examples/config"; +import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { mintERC721 } from "../examples/utils/mintERC721"; import { whitelistBroker } from "../examples/utils/whitelistBroker"; - +import { + approveERC20, + approveERC721, + createAccount, + createListing, + fulfillListing, + ListingV1 +} from "../src"; +import { fetchOrCreateAccount } from "../src/actions/account/account"; +import { getOrderStatus } from "../src/actions/read"; describe("ArkProject Listing", () => { it("should create and fulfill a listing", async () => { + const brokerId = 123; const { arkProvider, starknetProvider } = config; + const { account: arkAccount } = await createAccount(arkProvider); const solisAdminAccount = await fetchOrCreateAccount( config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + process.env.SOLIS_ADMIN_ADDRESS_DEV!, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV! ); - await whitelistBroker( - config, - solisAdminAccount, - 123 + await whitelistBroker(config, solisAdminAccount, brokerId); + + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS!, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY! ); - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); + const transaction_hash = await mintERC721( + starknetProvider, + starknetOffererAccount + ); + expect(transaction_hash).toBeDefined(); + + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + expect(tokenId).toBeDefined(); + + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetOffererAccount + }); const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order + brokerId, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId, + startAmount: "100000000000000000" }; const orderHash = await createListing(config, { - starknetAccount, + starknetAccount: starknetOffererAccount, arkAccount, order }); - - await sleep(1000); + expect(orderHash).toBeDefined(); const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { orderHash @@ -52,32 +74,49 @@ describe("ArkProject Listing", () => { expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); - // Create a new accounts for the fulfill using the provider - const { account: starknetFulfillerAccount } = - await createAccount(starknetProvider); + const starknetFulfillerAccount = await fetchOrCreateAccount( + starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS!, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY! + ); - const fulfill_info = { + if (process.env.STARKNET_NETWORK_ID === "dev") { + await mintERC20( + starknetProvider, + starknetFulfillerAccount, + order.startAmount + ); + } + + await approveERC20(config, { + starknetAccount: starknetFulfillerAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + const fulfillListingInfo = { orderHash, tokenAddress: order.tokenAddress, - tokenId: order.tokenId, - brokerId: 123 + tokenId, + brokerId }; - fulfillListing( - config, - { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillListingInfo: fulfill_info - } - ); - await sleep(2000); + await fulfillListing(config, { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillListingInfo + }); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { orderHash }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - expect(shortString.decodeShortString(orderStatusAfter)).toBe("FULFILLED"); - - }, 30000); + await new Promise((resolve) => setTimeout(resolve, 5000)); + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); + }, 60000); }); From 86c5724ebb1d8aab4f498f7085ce9cc7ab18a6df Mon Sep 17 00:00:00 2001 From: kwiss Date: Mon, 11 Mar 2024 17:17:48 +0100 Subject: [PATCH 11/19] tests(core-sdk): update sdk core tests, fix account creation for starknet --- contracts.json | 4 + crates/solis/messaging.local.json | 2 +- packages/core/examples/createOffer.ts | 2 +- packages/core/examples/utils/mintERC20.ts | 4 +- packages/core/src/contracts.ts | 10 +- packages/core/tests-new/cancelOffer.test.ts | 41 +++--- packages/core/tests-new/fulfillOffer.test.ts | 136 ++++++++----------- 7 files changed, 95 insertions(+), 104 deletions(-) diff --git a/contracts.json b/contracts.json index f449728ec..263080436 100644 --- a/contracts.json +++ b/contracts.json @@ -1,3 +1,4 @@ +<<<<<<< HEAD { "goerli": { "nftContract": "0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436", @@ -15,3 +16,6 @@ "orderbook": "0x74e0489622f837f00cffe63cb4acaaed3f2ad38eec11218eabcdc4f09cfa644" } } +======= +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661","executor":"0x6ff4994f777255c9e4960332514dd00e4bfe9e4bac277214d860f27873f6cca","nftContract":"0x2fc78cd380a43b5b989364a766ddc1e996dc55eca36fbd487b385ffc9d99683","eth":"0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4","orderbook":"0x3207adb845ac3b0099ee12d186df5fc5d5cfdc493290c0f80e57caf67439a31"}} +>>>>>>> ba42dbd (tests(core-sdk): update sdk core tests, fix account creation for starknet) diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 56e43a057..f70003f6e 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", + "contract_address": "0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661", "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", "interval": 2, diff --git a/packages/core/examples/createOffer.ts b/packages/core/examples/createOffer.ts index 6ed8c3dad..a7cebee27 100644 --- a/packages/core/examples/createOffer.ts +++ b/packages/core/examples/createOffer.ts @@ -5,7 +5,7 @@ * checking the order status */ -import { Contract, shortString } from "starknet"; +import { shortString } from "starknet"; import "dotenv/config"; diff --git a/packages/core/examples/utils/mintERC20.ts b/packages/core/examples/utils/mintERC20.ts index 62f2f5990..6ebba7ad8 100644 --- a/packages/core/examples/utils/mintERC20.ts +++ b/packages/core/examples/utils/mintERC20.ts @@ -18,7 +18,7 @@ export const mintERC20 = async ( if (erc20abi === undefined) { throw new Error("no abi."); } - + console.log(STARKNET_ETH_ADDRESS); const mintERC20Call: Call = { contractAddress: STARKNET_ETH_ADDRESS, entrypoint: "mint", @@ -26,5 +26,7 @@ export const mintERC20 = async ( }; const result = await starknetAccount.execute(mintERC20Call, [erc20abi]); + console.log("Mint ERC20 result", result.transaction_hash); await provider.waitForTransaction(result.transaction_hash); + return result.transaction_hash; }; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index df72d5de4..ab84cbd62 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", - "executor": "0x6c07c302d12d3798b83549356b9cd3c99607a5adbbf18ec7b7360bff75c4109", - "nftContract": "0x42cd09375b6744dbba98cc5e966c6de785ac5d47331df712f990c32bf3c7339", - "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", - "orderbook": "0x74e0489622f837f00cffe63cb4acaaed3f2ad38eec11218eabcdc4f09cfa644" + "messaging": "0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661", + "executor": "0x6ff4994f777255c9e4960332514dd00e4bfe9e4bac277214d860f27873f6cca", + "nftContract": "0x2fc78cd380a43b5b989364a766ddc1e996dc55eca36fbd487b385ffc9d99683", + "eth": "0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4", + "orderbook": "0x3207adb845ac3b0099ee12d186df5fc5d5cfdc493290c0f80e57caf67439a31" }; diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts index 4a4cb5d36..6d02e32d2 100644 --- a/packages/core/tests-new/cancelOffer.test.ts +++ b/packages/core/tests-new/cancelOffer.test.ts @@ -1,5 +1,6 @@ import { shortString } from "starknet"; +import { OfferV1 } from "../dist"; import { config } from "../examples/config"; import { STARKNET_ETH_ADDRESS, @@ -14,8 +15,7 @@ import { createOffer, fetchOrCreateAccount, getOrderStatus, - getOrderType, - ListingV1 + getOrderType } from "../src"; import { generateRandomTokenId, getTypeFromCairoCustomEnum } from "./utils"; @@ -32,52 +32,59 @@ describe("ArkProject cancel offer", () => { await whitelistBroker(config, solisAdminAccount, 123); const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); - const order: ListingV1 = { + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + const offerStarAmount = 600000000000000000; + + await mintERC20(starknetProvider, starknetOffererAccount, offerStarAmount); + + const offer: OfferV1 = { brokerId: 123, tokenAddress: STARKNET_NFT_ADDRESS, tokenId: generateRandomTokenId(), - startAmount: 600000000000000000, + startAmount: offerStarAmount, currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address }; - await mintERC20(starknetProvider, starknetAccount, order.startAmount); - await approveERC20(config, { - starknetAccount: starknetAccount, + starknetAccount: starknetOffererAccount, contractAddress: STARKNET_ETH_ADDRESS, - amount: order.startAmount + amount: offer.startAmount }); const orderHash = await createOffer(config, { - starknetAccount, + starknetAccount: starknetOffererAccount, arkAccount, - offer: order + offer: offer }); - + await new Promise((resolve) => setTimeout(resolve, 2000)); const r1 = await getOrderStatus(config, { orderHash }); const orderStatusBefore = shortString.decodeShortString(r1.orderStatus); expect(orderStatusBefore).toEqual("OPEN"); const r2 = await getOrderType(config, { orderHash }); const orderType = getTypeFromCairoCustomEnum(r2.orderType); - expect(orderType).toEqual("OFFER"); const cancelInfo = { orderHash: orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId + tokenAddress: offer.tokenAddress, + tokenId: offer.tokenId }; await cancelOrder(config, { - starknetAccount, + starknetAccount: starknetOffererAccount, arkAccount, cancelInfo }); + await new Promise((resolve) => setTimeout(resolve, 2000)); const r3 = await getOrderStatus(config, { orderHash }); const orderStatusAfter = shortString.decodeShortString(r3.orderStatus); expect(orderStatusAfter).toEqual("CANCELLED_USER"); - }, 30000); + }, 35000); }); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts index eef2a3207..57c7f340f 100644 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -1,27 +1,28 @@ import { Contract, shortString } from "starknet"; +import { config } from "../examples/config"; +import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { getTokenOwner } from "../examples/utils/getTokenOwner"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { approveERC20, - createAccount, createListing, - createOffer, fetchOrCreateAccount, + createAccount, + createOffer, + fetchOrCreateAccount, fulfillOffer, - getOrderStatus, ListingV1, + getOrderStatus, OfferV1 } from "../src"; import { generateRandomTokenId } from "./utils"; -import { config } from "../examples/config"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; -import { mintERC20 } from "../examples/utils/mintERC20"; -import { mintERC721 } from "../examples/utils/mintERC721"; -import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; -import { changeTokenOwner } from "../examples/utils/changeTokenOwner"; -import { getTokenOwner } from "../examples/utils/getTokenOwner"; - describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { - const { arkProvider, starknetProvider } = config; const solisAdminAccount = await fetchOrCreateAccount( @@ -30,15 +31,15 @@ describe("ArkProject Listing and Offer Fulfillment", () => { process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - await whitelistBroker( - config, - solisAdminAccount, - 123 - ); + await whitelistBroker(config, solisAdminAccount, 123); // Create a new account for the listing using the provider const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); // Define the order details const order: OfferV1 = { @@ -51,34 +52,40 @@ describe("ArkProject Listing and Offer Fulfillment", () => { await mintERC20( starknetProvider, - starknetAccount, + starknetOffererAccount, order.startAmount ); // for allowance await approveERC20(config, { - starknetAccount: starknetAccount, + starknetAccount: starknetOffererAccount, contractAddress: STARKNET_ETH_ADDRESS, amount: order.startAmount }); // Create the listing on the arkchain using the order details - const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); + const orderHash = await createOffer(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + offer: order + }); expect(orderHash).toBeDefined(); await new Promise((resolve) => setTimeout(resolve, 2000)); await expect( - getOrderStatus(config, {orderHash}).then((res) => + getOrderStatus(config, { orderHash }).then((res) => shortString.decodeShortString(res.orderStatus) ) ).resolves.toEqual("OPEN"); - // Create a new account for fulfilling the offer - const { account: starknetFulfillerAccount } = - await createAccount(starknetProvider); + const starknetFulfillerAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY + ); expect(starknetFulfillerAccount).toBeDefined(); @@ -91,28 +98,22 @@ describe("ArkProject Listing and Offer Fulfillment", () => { }; // Fulfill the offer - await fulfillOffer( - config, - { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillOfferInfo: fulfill_info - } - ); + await fulfillOffer(config, { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillOfferInfo: fulfill_info + }); await new Promise((resolve) => setTimeout(resolve, 5000)); await expect( - getOrderStatus(config, {orderHash}).then((res) => + getOrderStatus(config, { orderHash }).then((res) => shortString.decodeShortString(res.orderStatus) ) ).resolves.toEqual("FULFILLED"); - }, 40000); - it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { - const { arkProvider, starknetProvider } = config; const solisAdminAccount = await fetchOrCreateAccount( @@ -121,11 +122,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - await whitelistBroker( - config, - solisAdminAccount, - 123 - ); + await whitelistBroker(config, solisAdminAccount, 123); const { account: starknetOwner } = await createAccount(starknetProvider); const { account: arkAccount } = await createAccount(arkProvider); @@ -133,19 +130,6 @@ describe("ArkProject Listing and Offer Fulfillment", () => { await mintERC721(config.starknetProvider, starknetOwner); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - const orderListing: ListingV1 = { - brokerId: 123, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: 600000000000000000 - }; - - await createListing(config, { - starknetAccount: starknetOwner, - arkAccount, - order: orderListing - }); - // Create a new account for the listing using the provider const { account: starknetAccount } = await createAccount(starknetProvider); @@ -158,11 +142,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address }; - await mintERC20( - starknetProvider, - starknetAccount, - order.startAmount - ); + await mintERC20(starknetProvider, starknetAccount, order.startAmount); // for allowance await approveERC20(config, { @@ -172,19 +152,22 @@ describe("ArkProject Listing and Offer Fulfillment", () => { }); // Create the offer on the arkchain using the order details - const orderHash = await createOffer(config,{starknetAccount, arkAccount, offer: order }); + const orderHash = await createOffer(config, { + starknetAccount, + arkAccount, + offer: order + }); expect(orderHash).toBeDefined(); await new Promise((resolve) => setTimeout(resolve, 2000)); await expect( - getOrderStatus(config, {orderHash}).then((res) => + getOrderStatus(config, { orderHash }).then((res) => shortString.decodeShortString(res.orderStatus) ) ).resolves.toEqual("OPEN"); - // Create a new account for fulfilling the offer const { account: starknetFulfillerAccount } = await createAccount(starknetProvider); @@ -192,7 +175,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { expect(starknetFulfillerAccount).toBeDefined(); // change owner of token - /* await changeTokenOwner(config, + /* await changeTokenOwner(config, STARKNET_NFT_ADDRESS, starknetOwner.address, starknetFulfillerAccount.address, @@ -208,18 +191,14 @@ describe("ArkProject Listing and Offer Fulfillment", () => { }; // Fulfill the offer - await fulfillOffer( - config, - { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillOfferInfo: fulfill_info - } - ); + await fulfillOffer(config, { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillOfferInfo: fulfill_info + }); - const compressedContract = await config?.starknetProvider.getClassAt( - STARKNET_ETH_ADDRESS - ); + const compressedContract = + await config?.starknetProvider.getClassAt(STARKNET_ETH_ADDRESS); const tokenContract = new Contract( compressedContract?.abi, @@ -241,17 +220,16 @@ describe("ArkProject Listing and Offer Fulfillment", () => { console.log("allowance", allowance.toString()); console.log("balance", balance.toString()); - const ownerHex = "0x" + owner.toString(16).padStart(64, '0'); + const ownerHex = "0x" + owner.toString(16).padStart(64, "0"); console.log("Owner of tokenId", tokenId, "is", ownerHex); console.log("offerer", starknetFulfillerAccount.address); await new Promise((resolve) => setTimeout(resolve, 5000)); await expect( - getOrderStatus(config, {orderHash}).then((res) => + getOrderStatus(config, { orderHash }).then((res) => shortString.decodeShortString(res.orderStatus) ) ).resolves.toEqual("FULFILLED"); - }, 50000); }); From c52d9c811c03b9bf540661bb4c103c86f4ea2e15 Mon Sep 17 00:00:00 2001 From: bexan Date: Mon, 11 Mar 2024 20:21:25 +0100 Subject: [PATCH 12/19] hooker: fix allowance & update from/to --- contracts.json | 22 +--------------------- crates/solis/messaging.local.json | 6 +++--- crates/solis/src/hooker.rs | 21 ++++----------------- packages/core/examples/fulfillOffer.ts | 9 +++++++++ packages/core/src/contracts.ts | 10 +++++----- 5 files changed, 22 insertions(+), 46 deletions(-) diff --git a/contracts.json b/contracts.json index 263080436..ce69036ed 100644 --- a/contracts.json +++ b/contracts.json @@ -1,21 +1 @@ -<<<<<<< HEAD -{ - "goerli": { - "nftContract": "0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436", - "messaging": "0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8", - "executor": "0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc", - "orderbook": "0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310" - }, - "sepolia": {}, - "mainnet": {}, - "dev": { - "messaging": "0x7577b258cdfaee586933097fd2407ab40f73814a355b6af8508515dd5abe752", - "executor": "0x6c07c302d12d3798b83549356b9cd3c99607a5adbbf18ec7b7360bff75c4109", - "nftContract": "0x42cd09375b6744dbba98cc5e966c6de785ac5d47331df712f990c32bf3c7339", - "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", - "orderbook": "0x74e0489622f837f00cffe63cb4acaaed3f2ad38eec11218eabcdc4f09cfa644" - } -} -======= -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661","executor":"0x6ff4994f777255c9e4960332514dd00e4bfe9e4bac277214d860f27873f6cca","nftContract":"0x2fc78cd380a43b5b989364a766ddc1e996dc55eca36fbd487b385ffc9d99683","eth":"0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4","orderbook":"0x3207adb845ac3b0099ee12d186df5fc5d5cfdc493290c0f80e57caf67439a31"}} ->>>>>>> ba42dbd (tests(core-sdk): update sdk core tests, fix account creation for starknet) +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa","executor":"0x4ad786f44c2be2e03512beea7c6c9d3aa07b6742c1d754f4aecc17a1807c341","nftContract":"0x42976b3c3ae2a6d4cd597dc0414a4ebf9b8d0a1f5eaf5cdd0996eb476b1c2e2","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x12bc8a3eb9ccc2bee48a93e3a6501342fdc60f54c33af291b4e851b8abeb8da"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index f70003f6e..d45608e0f 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,9 +1,9 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661", - "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", - "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", + "contract_address": "0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa", + "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", + "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, "from_block": 0 } \ No newline at end of file diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs index 32bd0488f..49b12ef16 100644 --- a/crates/solis/src/hooker.rs +++ b/crates/solis/src/hooker.rs @@ -100,8 +100,8 @@ impl SolisHooker

{ balance_verifier.start_amount ); println!( - "\nAllowance {:?} is not enough {:?} ", - allowance, balance_verifier.start_amount + "\nAllowance {:?} is not enough {:?} for offerer {:?}", + allowance, balance_verifier.start_amount, balance_verifier.offerer ); return false; } @@ -336,23 +336,10 @@ impl KatanaHooker for Sol } }; - println!( - "verify balance for starknet before from : {:?}", - execution_info.nft_from - ); - println!( - "verify balance for starknet before to : {:?}", - execution_info.nft_to - ); - println!( - "verify balance for starknet before amount : {:?}", - execution_info.payment_amount.low - ); - let verifier = OwnershipVerifier { token_address: ContractAddress(execution_info.nft_address.into()), token_id: execution_info.nft_token_id, - current_owner: cainome::cairo_serde::ContractAddress(execution_info.nft_to.into()), + current_owner: cainome::cairo_serde::ContractAddress(execution_info.nft_from.into()), }; let owner_ship_verification = self.verify_ownership(&verifier).await; @@ -364,7 +351,7 @@ impl KatanaHooker for Sol if !self .verify_balance(&BalanceVerifier { currency_address: ContractAddress(execution_info.payment_currency_address.into()), - offerer: cainome::cairo_serde::ContractAddress(execution_info.nft_from.into()), + offerer: cainome::cairo_serde::ContractAddress(execution_info.nft_to.into()), start_amount: U256 { low: execution_info.payment_amount.low, high: execution_info.payment_amount.high, diff --git a/packages/core/examples/fulfillOffer.ts b/packages/core/examples/fulfillOffer.ts index af9f711c1..f1c0293ee 100644 --- a/packages/core/examples/fulfillOffer.ts +++ b/packages/core/examples/fulfillOffer.ts @@ -23,6 +23,7 @@ import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "./constants"; import { getCurrentTokenId } from "./utils/getCurrentTokenId"; import { mintERC20 } from "./utils/mintERC20"; import { mintERC721 } from "./utils/mintERC721"; +import { whitelistBroker } from "./utils/whitelistBroker"; /** * Creates a listing on the blockchain using provided order details. @@ -31,6 +32,14 @@ import { mintERC721 } from "./utils/mintERC721"; console.log(`=> Getting config...`); const { arkProvider, starknetProvider } = config; + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker(config, solisAdminAccount, 123); + console.log(`=> Creating account`); // Create a new account for the listing using the provider const { account: arkAccount } = await createAccount(arkProvider); diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index ab84cbd62..e73489b8c 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x4804915b8f254713023522b04737186be542408a003aa275cd6325f85906661", - "executor": "0x6ff4994f777255c9e4960332514dd00e4bfe9e4bac277214d860f27873f6cca", - "nftContract": "0x2fc78cd380a43b5b989364a766ddc1e996dc55eca36fbd487b385ffc9d99683", - "eth": "0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4", - "orderbook": "0x3207adb845ac3b0099ee12d186df5fc5d5cfdc493290c0f80e57caf67439a31" + "messaging": "0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa", + "executor": "0x4ad786f44c2be2e03512beea7c6c9d3aa07b6742c1d754f4aecc17a1807c341", + "nftContract": "0x42976b3c3ae2a6d4cd597dc0414a4ebf9b8d0a1f5eaf5cdd0996eb476b1c2e2", + "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", + "orderbook": "0x12bc8a3eb9ccc2bee48a93e3a6501342fdc60f54c33af291b4e851b8abeb8da" }; From 4e59bbe01e211faaa245a5bc9063acb0f794ded5 Mon Sep 17 00:00:00 2001 From: bexan Date: Mon, 11 Mar 2024 22:07:49 +0100 Subject: [PATCH 13/19] rework tests --- contracts.json | 2 +- crates/solis/messaging.local.json | 2 +- crates/solis/src/hooker.rs | 3 + packages/core/src/contracts.ts | 8 +-- packages/core/tests-new/fulfillOffer.test.ts | 66 +++++++++++--------- 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/contracts.json b/contracts.json index ce69036ed..3bd3ed6fe 100644 --- a/contracts.json +++ b/contracts.json @@ -1 +1 @@ -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa","executor":"0x4ad786f44c2be2e03512beea7c6c9d3aa07b6742c1d754f4aecc17a1807c341","nftContract":"0x42976b3c3ae2a6d4cd597dc0414a4ebf9b8d0a1f5eaf5cdd0996eb476b1c2e2","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x12bc8a3eb9ccc2bee48a93e3a6501342fdc60f54c33af291b4e851b8abeb8da"}} \ No newline at end of file +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074","executor":"0x6133e5dc38b89af374045985849d0e966d8bbb4e5ddb606642309c48fc96347","nftContract":"0x57963344b2150b711dbc2e6bc91d961a0aae2f182e01bb6a689f42941c9ee53","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x3ae1e975add64cf7be63aeda263417a9474205e670e5a2b3ee411ab61b30b6e"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index d45608e0f..f19303c57 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa", + "contract_address": "0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074", "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs index 49b12ef16..17d9f235a 100644 --- a/crates/solis/src/hooker.rs +++ b/crates/solis/src/hooker.rs @@ -326,6 +326,9 @@ impl KatanaHooker for Sol } async fn verify_tx_for_starknet(&self, call: Call) -> bool { + if call.selector != selector!("fulfill_order") { + return true; + } println!("verify message to starknet before tx: {:?}", call); let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index e73489b8c..a83ff17f0 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x69229e7f314bc2f8b668704e9d541bb1a8f0f6a572682671d7c5313cc91c6fa", - "executor": "0x4ad786f44c2be2e03512beea7c6c9d3aa07b6742c1d754f4aecc17a1807c341", - "nftContract": "0x42976b3c3ae2a6d4cd597dc0414a4ebf9b8d0a1f5eaf5cdd0996eb476b1c2e2", + "messaging": "0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074", + "executor": "0x6133e5dc38b89af374045985849d0e966d8bbb4e5ddb606642309c48fc96347", + "nftContract": "0x57963344b2150b711dbc2e6bc91d961a0aae2f182e01bb6a689f42941c9ee53", "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x12bc8a3eb9ccc2bee48a93e3a6501342fdc60f54c33af291b4e851b8abeb8da" + "orderbook": "0x3ae1e975add64cf7be63aeda263417a9474205e670e5a2b3ee411ab61b30b6e" }; diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts index 57c7f340f..727a1d518 100644 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -6,12 +6,11 @@ import { STARKNET_NFT_ADDRESS } from "../examples/constants"; import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; -import { getTokenOwner } from "../examples/utils/getTokenOwner"; import { mintERC20 } from "../examples/utils/mintERC20"; import { mintERC721 } from "../examples/utils/mintERC721"; import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { - approveERC20, + approveERC20, approveERC721, createAccount, createOffer, fetchOrCreateAccount, @@ -19,7 +18,7 @@ import { getOrderStatus, OfferV1 } from "../src"; -import { generateRandomTokenId } from "./utils"; +import { getTokenOwner } from "../examples/utils/getTokenOwner"; describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { @@ -35,21 +34,35 @@ describe("ArkProject Listing and Offer Fulfillment", () => { // Create a new account for the listing using the provider const { account: arkAccount } = await createAccount(arkProvider); - const starknetOffererAccount = await fetchOrCreateAccount( + + // Create a new account for fulfilling the offer + const starknetFulfillerAccount = await fetchOrCreateAccount( config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY ); + expect(starknetFulfillerAccount).toBeDefined(); + + + await mintERC721(starknetProvider, starknetFulfillerAccount); + + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + // Define the order details const order: OfferV1 = { brokerId: 123, // The broker ID tokenAddress: STARKNET_NFT_ADDRESS, // The token address - tokenId: generateRandomTokenId(), // The ID of the token + tokenId, // The ID of the token startAmount: 600000000000000000, // The starting amount for the order - currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address }; + const starknetOffererAccount = await fetchOrCreateAccount( + starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + await mintERC20( starknetProvider, starknetOffererAccount, @@ -72,6 +85,11 @@ describe("ArkProject Listing and Offer Fulfillment", () => { expect(orderHash).toBeDefined(); + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetFulfillerAccount + }); + await new Promise((resolve) => setTimeout(resolve, 2000)); await expect( @@ -80,17 +98,8 @@ describe("ArkProject Listing and Offer Fulfillment", () => { ) ).resolves.toEqual("OPEN"); - // Create a new account for fulfilling the offer - const starknetFulfillerAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY - ); - - expect(starknetFulfillerAccount).toBeDefined(); - // Define the fulfill details - const fulfill_info = { + const fulfillOfferInfo = { orderHash, tokenAddress: order.tokenAddress, tokenId: order.tokenId, @@ -101,9 +110,10 @@ describe("ArkProject Listing and Offer Fulfillment", () => { await fulfillOffer(config, { starknetAccount: starknetFulfillerAccount, arkAccount, - fulfillOfferInfo: fulfill_info + fulfillOfferInfo }); + await new Promise((resolve) => setTimeout(resolve, 5000)); await expect( @@ -111,7 +121,15 @@ describe("ArkProject Listing and Offer Fulfillment", () => { shortString.decodeShortString(res.orderStatus) ) ).resolves.toEqual("FULFILLED"); - }, 40000); + + await new Promise((resolve) => setTimeout(resolve, 6000)); + await expect( + getOrderStatus(config, { orderHash }).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("EXECUTED"); + + }, 60000); it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { const { arkProvider, starknetProvider } = config; @@ -174,14 +192,6 @@ describe("ArkProject Listing and Offer Fulfillment", () => { expect(starknetFulfillerAccount).toBeDefined(); - // change owner of token - /* await changeTokenOwner(config, - STARKNET_NFT_ADDRESS, - starknetOwner.address, - starknetFulfillerAccount.address, - order.tokenId - );*/ - // Define the fulfill details const fulfill_info = { orderHash, From 5712e30cbfee0640f3997c1b28dd73aa546ecdcc Mon Sep 17 00:00:00 2001 From: bexan Date: Mon, 11 Mar 2024 22:58:45 +0100 Subject: [PATCH 14/19] some fixes --- contracts.json | 2 +- crates/solis/messaging.local.json | 2 +- crates/solis/src/hooker.rs | 3 +-- packages/core/examples/fulfillOffer.ts | 2 +- packages/core/src/contracts.ts | 8 ++++---- packages/core/tests-new/createListing.test.ts | 2 +- packages/core/tests-new/fulfillOffer.test.ts | 4 ++-- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/contracts.json b/contracts.json index 3bd3ed6fe..af546eb38 100644 --- a/contracts.json +++ b/contracts.json @@ -1 +1 @@ -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074","executor":"0x6133e5dc38b89af374045985849d0e966d8bbb4e5ddb606642309c48fc96347","nftContract":"0x57963344b2150b711dbc2e6bc91d961a0aae2f182e01bb6a689f42941c9ee53","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x3ae1e975add64cf7be63aeda263417a9474205e670e5a2b3ee411ab61b30b6e"}} \ No newline at end of file +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c","executor":"0x6bc937f58725eeec9500ec43228ee84edaa112791b2aa94874962b7fd5c07b5","nftContract":"0x21c5584242b7d03474cc6f83f49505f81918f97221b2178e7774ceef976f7c7","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x7a2ba6b590838ed93cfda427dc3f46d8a4fe4e9758dbe3b03bc75301b220421"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index f19303c57..7dc6ea95f 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,7 +1,7 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074", + "contract_address": "0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c", "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, diff --git a/crates/solis/src/hooker.rs b/crates/solis/src/hooker.rs index 17d9f235a..ed8ecdfab 100644 --- a/crates/solis/src/hooker.rs +++ b/crates/solis/src/hooker.rs @@ -326,11 +326,10 @@ impl KatanaHooker for Sol } async fn verify_tx_for_starknet(&self, call: Call) -> bool { + println!("verify message to starknet before tx: {:?}", call); if call.selector != selector!("fulfill_order") { return true; } - println!("verify message to starknet before tx: {:?}", call); - let execution_info = match ExecutionInfo::cairo_deserialize(&call.calldata, 0) { Ok(execution_info) => execution_info, Err(e) => { diff --git a/packages/core/examples/fulfillOffer.ts b/packages/core/examples/fulfillOffer.ts index f1c0293ee..7fe3fae3f 100644 --- a/packages/core/examples/fulfillOffer.ts +++ b/packages/core/examples/fulfillOffer.ts @@ -146,7 +146,7 @@ import { whitelistBroker } from "./utils/whitelistBroker"; ); await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000)); } else { - await new Promise((resolve) => setTimeout(resolve, 6000)); + await new Promise((resolve) => setTimeout(resolve, 10000)); } console.log("=> Fetching order status..."); diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index a83ff17f0..dc2402ccb 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x22afef4e721b1c5934450c2912b654922b6d794886d5b284fa1c64592d0c074", - "executor": "0x6133e5dc38b89af374045985849d0e966d8bbb4e5ddb606642309c48fc96347", - "nftContract": "0x57963344b2150b711dbc2e6bc91d961a0aae2f182e01bb6a689f42941c9ee53", + "messaging": "0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c", + "executor": "0x6bc937f58725eeec9500ec43228ee84edaa112791b2aa94874962b7fd5c07b5", + "nftContract": "0x21c5584242b7d03474cc6f83f49505f81918f97221b2178e7774ceef976f7c7", "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x3ae1e975add64cf7be63aeda263417a9474205e670e5a2b3ee411ab61b30b6e" + "orderbook": "0x7a2ba6b590838ed93cfda427dc3f46d8a4fe4e9758dbe3b03bc75301b220421" }; diff --git a/packages/core/tests-new/createListing.test.ts b/packages/core/tests-new/createListing.test.ts index 3a0f33e6b..3978da80d 100644 --- a/packages/core/tests-new/createListing.test.ts +++ b/packages/core/tests-new/createListing.test.ts @@ -53,7 +53,7 @@ test("ArkProject create a listing", async () => { }); expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); -}, 20000); +}, 30000); test("ArkProject create a listing without whitelisting broker", async () => { const { account: arkAccount } = await createAccount(config.arkProvider); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts index 727a1d518..20698e14c 100644 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -114,7 +114,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { }); - await new Promise((resolve) => setTimeout(resolve, 5000)); + await new Promise((resolve) => setTimeout(resolve, 2000)); await expect( getOrderStatus(config, { orderHash }).then((res) => @@ -122,7 +122,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { ) ).resolves.toEqual("FULFILLED"); - await new Promise((resolve) => setTimeout(resolve, 6000)); + await new Promise((resolve) => setTimeout(resolve, 7000)); await expect( getOrderStatus(config, { orderHash }).then((res) => shortString.decodeShortString(res.orderStatus) From 790b6df9b8d13574f548f3c4d6af551f604549ce Mon Sep 17 00:00:00 2001 From: kwiss Date: Tue, 12 Mar 2024 00:57:10 +0100 Subject: [PATCH 15/19] fix(tests): update tests --- contracts.json | 2 +- crates/solis/messaging.local.json | 6 +- packages/core/examples/utils/mintERC20.ts | 3 +- packages/core/src/actions/account/account.ts | 5 +- packages/core/src/contracts.ts | 10 +- packages/core/tests-new/cancel.test.ts | 1 - packages/core/tests-new/fulfillOffer.test.ts | 108 +++++++------------ 7 files changed, 53 insertions(+), 82 deletions(-) diff --git a/contracts.json b/contracts.json index af546eb38..8db142d29 100644 --- a/contracts.json +++ b/contracts.json @@ -1 +1 @@ -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c","executor":"0x6bc937f58725eeec9500ec43228ee84edaa112791b2aa94874962b7fd5c07b5","nftContract":"0x21c5584242b7d03474cc6f83f49505f81918f97221b2178e7774ceef976f7c7","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x7a2ba6b590838ed93cfda427dc3f46d8a4fe4e9758dbe3b03bc75301b220421"}} \ No newline at end of file +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"nftContract":"0x3ca9649b19d91a7110e2f2c0361ba0f65d6f1a3eb4615b041e51a3eb634ed4e","eth":"0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9","messaging":"0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953","executor":"0x5cca831be0da6eca88141ae3a52de3ff576e5770b6ec06d8f05416f252975e2","orderbook":"0x4de16bc47e25fa8e4d029f63c197ef77a1e6fbcb2be481fb8d5896d52af507e"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 7dc6ea95f..3d8fbd71f 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,9 +1,9 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c", - "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", - "private_key": "0x1800000000300000180000000000030000000000003006001800006600", + "contract_address": "0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953", + "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", + "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", "interval": 2, "from_block": 0 } \ No newline at end of file diff --git a/packages/core/examples/utils/mintERC20.ts b/packages/core/examples/utils/mintERC20.ts index 6ebba7ad8..143ffb001 100644 --- a/packages/core/examples/utils/mintERC20.ts +++ b/packages/core/examples/utils/mintERC20.ts @@ -18,7 +18,7 @@ export const mintERC20 = async ( if (erc20abi === undefined) { throw new Error("no abi."); } - console.log(STARKNET_ETH_ADDRESS); + const mintERC20Call: Call = { contractAddress: STARKNET_ETH_ADDRESS, entrypoint: "mint", @@ -26,7 +26,6 @@ export const mintERC20 = async ( }; const result = await starknetAccount.execute(mintERC20Call, [erc20abi]); - console.log("Mint ERC20 result", result.transaction_hash); await provider.waitForTransaction(result.transaction_hash); return result.transaction_hash; }; diff --git a/packages/core/src/actions/account/account.ts b/packages/core/src/actions/account/account.ts index c4d6ef14d..aa34d38d3 100644 --- a/packages/core/src/actions/account/account.ts +++ b/packages/core/src/actions/account/account.ts @@ -50,10 +50,9 @@ export const createAccount = async (provider: ProviderInterface) => { constructorCalldata: CallData.compile({ publicKey }), addressSalt: publicKey }); - const test = await provider.waitForTransaction(transaction_hash, { - retryInterval: 100 + await provider.waitForTransaction(transaction_hash, { + retryInterval: 1000 }); - console.log(test); return { address: contract_address, privateKey, diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index dc2402ccb..bd96e7f6f 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x39f2c1a7c8490c97c1e66ab1acdcdd6e6185cef26416481ae445ff5a090611c", - "executor": "0x6bc937f58725eeec9500ec43228ee84edaa112791b2aa94874962b7fd5c07b5", - "nftContract": "0x21c5584242b7d03474cc6f83f49505f81918f97221b2178e7774ceef976f7c7", - "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x7a2ba6b590838ed93cfda427dc3f46d8a4fe4e9758dbe3b03bc75301b220421" + "nftContract": "0x3ca9649b19d91a7110e2f2c0361ba0f65d6f1a3eb4615b041e51a3eb634ed4e", + "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", + "messaging": "0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953", + "executor": "0x5cca831be0da6eca88141ae3a52de3ff576e5770b6ec06d8f05416f252975e2", + "orderbook": "0x4de16bc47e25fa8e4d029f63c197ef77a1e6fbcb2be481fb8d5896d52af507e" }; diff --git a/packages/core/tests-new/cancel.test.ts b/packages/core/tests-new/cancel.test.ts index a9895dc9d..f2b3282f9 100644 --- a/packages/core/tests-new/cancel.test.ts +++ b/packages/core/tests-new/cancel.test.ts @@ -71,7 +71,6 @@ test("ArkProject Cancel listing should create and then cancel a listing", async const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { orderHash }); - console.log("orderStatus", shortString.decodeShortString(orderStatusAfter)); expect(shortString.decodeShortString(orderStatusAfter)).toBe( "CANCELLED_USER" ); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts index 20698e14c..7283b76c8 100644 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ b/packages/core/tests-new/fulfillOffer.test.ts @@ -1,4 +1,4 @@ -import { Contract, shortString } from "starknet"; +import { shortString } from "starknet"; import { config } from "../examples/config"; import { @@ -10,7 +10,8 @@ import { mintERC20 } from "../examples/utils/mintERC20"; import { mintERC721 } from "../examples/utils/mintERC721"; import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { - approveERC20, approveERC721, + approveERC20, + approveERC721, createAccount, createOffer, fetchOrCreateAccount, @@ -18,7 +19,6 @@ import { getOrderStatus, OfferV1 } from "../src"; -import { getTokenOwner } from "../examples/utils/getTokenOwner"; describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { @@ -44,7 +44,6 @@ describe("ArkProject Listing and Offer Fulfillment", () => { expect(starknetFulfillerAccount).toBeDefined(); - await mintERC721(starknetProvider, starknetFulfillerAccount); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); @@ -54,7 +53,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { brokerId: 123, // The broker ID tokenAddress: STARKNET_NFT_ADDRESS, // The token address tokenId, // The ID of the token - startAmount: 600000000000000000, // The starting amount for the order + startAmount: 600000000000000000 // The starting amount for the order }; const starknetOffererAccount = await fetchOrCreateAccount( @@ -113,22 +112,17 @@ describe("ArkProject Listing and Offer Fulfillment", () => { fulfillOfferInfo }); + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - await new Promise((resolve) => setTimeout(resolve, 2000)); - - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("FULFILLED"); - - await new Promise((resolve) => setTimeout(resolve, 7000)); - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("EXECUTED"); - + await new Promise((resolve) => setTimeout(resolve, 5000)); + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); }, 60000); it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { @@ -142,14 +136,28 @@ describe("ArkProject Listing and Offer Fulfillment", () => { await whitelistBroker(config, solisAdminAccount, 123); - const { account: starknetOwner } = await createAccount(starknetProvider); const { account: arkAccount } = await createAccount(arkProvider); + // Create a new account for the listing using the provider + const starknetFulfillerAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY + ); + + await mintERC721(config.starknetProvider, starknetFulfillerAccount); + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetFulfillerAccount + }); - await mintERC721(config.starknetProvider, starknetOwner); const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); // Create a new account for the listing using the provider - const { account: starknetAccount } = await createAccount(starknetProvider); + const starknetAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); // Define the order details const order: OfferV1 = { @@ -180,15 +188,10 @@ describe("ArkProject Listing and Offer Fulfillment", () => { await new Promise((resolve) => setTimeout(resolve, 2000)); - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("OPEN"); - - // Create a new account for fulfilling the offer - const { account: starknetFulfillerAccount } = - await createAccount(starknetProvider); + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); expect(starknetFulfillerAccount).toBeDefined(); @@ -207,39 +210,10 @@ describe("ArkProject Listing and Offer Fulfillment", () => { fulfillOfferInfo: fulfill_info }); - const compressedContract = - await config?.starknetProvider.getClassAt(STARKNET_ETH_ADDRESS); - - const tokenContract = new Contract( - compressedContract?.abi, - STARKNET_ETH_ADDRESS, - config.starknetProvider - ); - - const allowance = await tokenContract.allowance( - starknetFulfillerAccount.address, - config?.starknetContracts.executor - ); - - const balance = await tokenContract.allowance( - starknetFulfillerAccount.address, - config?.starknetContracts.executor - ); - - const owner = await getTokenOwner(config, STARKNET_NFT_ADDRESS, tokenId); - - console.log("allowance", allowance.toString()); - console.log("balance", balance.toString()); - const ownerHex = "0x" + owner.toString(16).padStart(64, "0"); - console.log("Owner of tokenId", tokenId, "is", ownerHex); - console.log("offerer", starknetFulfillerAccount.address); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("FULFILLED"); - }, 50000); + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); + }, 60000); }); From fc809018b4a60fc589c6d2e3e498622410684c14 Mon Sep 17 00:00:00 2001 From: kwiss Date: Tue, 12 Mar 2024 00:57:37 +0100 Subject: [PATCH 16/19] fix(tests): remove old tests --- packages/core/package.json | 2 +- packages/core/tests-new/cancelOffer.test.ts | 90 ------- packages/core/tests-new/createAccount.test.ts | 24 -- packages/core/tests-new/createListing.test.ts | 88 ------- .../core/tests-new/fulfillListing.test.ts | 122 ---------- packages/core/tests-new/fulfillOffer.test.ts | 219 ----------------- packages/core/tests-new/utils/index.ts | 28 --- .../core/{tests-new => tests}/cancel.test.ts | 0 packages/core/tests/cancelListing.test.ts | 95 -------- packages/core/tests/cancelOffer.test.ts | 129 +++++----- packages/core/tests/createAccount.test.ts | 15 +- packages/core/tests/createListing.test.ts | 217 ++++++----------- packages/core/tests/fulfillListing.test.ts | 166 ++++++++----- packages/core/tests/fulfillOffer.test.ts | 227 ++++++++++++++---- 14 files changed, 431 insertions(+), 991 deletions(-) delete mode 100644 packages/core/tests-new/cancelOffer.test.ts delete mode 100644 packages/core/tests-new/createAccount.test.ts delete mode 100644 packages/core/tests-new/createListing.test.ts delete mode 100644 packages/core/tests-new/fulfillListing.test.ts delete mode 100644 packages/core/tests-new/fulfillOffer.test.ts delete mode 100644 packages/core/tests-new/utils/index.ts rename packages/core/{tests-new => tests}/cancel.test.ts (100%) delete mode 100644 packages/core/tests/cancelListing.test.ts diff --git a/packages/core/package.json b/packages/core/package.json index 78c385b09..a3abbcb86 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -12,7 +12,7 @@ "generate-contracts": "ts-node src/generateContracts.ts", "build": "npm run generate-contracts && tsup src/index.ts --format cjs,esm --dts", "dev": "nodemon --watch ../../contracts.json --exec 'npm run generate-contracts' & tsup src/index.ts --format cjs,esm --dts --watch", - "test": "jest tests-new" + "test": "jest tests" }, "dependencies": { "@scure/starknet": "^0.3.0", diff --git a/packages/core/tests-new/cancelOffer.test.ts b/packages/core/tests-new/cancelOffer.test.ts deleted file mode 100644 index 6d02e32d2..000000000 --- a/packages/core/tests-new/cancelOffer.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { shortString } from "starknet"; - -import { OfferV1 } from "../dist"; -import { config } from "../examples/config"; -import { - STARKNET_ETH_ADDRESS, - STARKNET_NFT_ADDRESS -} from "../examples/constants"; -import { mintERC20 } from "../examples/utils/mintERC20"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { - approveERC20, - cancelOrder, - createAccount, - createOffer, - fetchOrCreateAccount, - getOrderStatus, - getOrderType -} from "../src"; -import { generateRandomTokenId, getTypeFromCairoCustomEnum } from "./utils"; - -describe("ArkProject cancel offer", () => { - it("should cancel an offer and verify its status and type", async () => { - const { arkProvider, starknetProvider } = config; - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ); - - await whitelistBroker(config, solisAdminAccount, 123); - - const { account: arkAccount } = await createAccount(arkProvider); - const starknetOffererAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - const offerStarAmount = 600000000000000000; - - await mintERC20(starknetProvider, starknetOffererAccount, offerStarAmount); - - const offer: OfferV1 = { - brokerId: 123, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId: generateRandomTokenId(), - startAmount: offerStarAmount, - currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address - }; - - await approveERC20(config, { - starknetAccount: starknetOffererAccount, - contractAddress: STARKNET_ETH_ADDRESS, - amount: offer.startAmount - }); - - const orderHash = await createOffer(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - offer: offer - }); - await new Promise((resolve) => setTimeout(resolve, 2000)); - const r1 = await getOrderStatus(config, { orderHash }); - const orderStatusBefore = shortString.decodeShortString(r1.orderStatus); - expect(orderStatusBefore).toEqual("OPEN"); - - const r2 = await getOrderType(config, { orderHash }); - const orderType = getTypeFromCairoCustomEnum(r2.orderType); - expect(orderType).toEqual("OFFER"); - - const cancelInfo = { - orderHash: orderHash, - tokenAddress: offer.tokenAddress, - tokenId: offer.tokenId - }; - - await cancelOrder(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - cancelInfo - }); - - await new Promise((resolve) => setTimeout(resolve, 2000)); - const r3 = await getOrderStatus(config, { orderHash }); - const orderStatusAfter = shortString.decodeShortString(r3.orderStatus); - expect(orderStatusAfter).toEqual("CANCELLED_USER"); - }, 35000); -}); diff --git a/packages/core/tests-new/createAccount.test.ts b/packages/core/tests-new/createAccount.test.ts deleted file mode 100644 index 8d9b32db0..000000000 --- a/packages/core/tests-new/createAccount.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { RpcProvider } from "starknet"; - -import { createAccount } from "../src/actions/account/account"; - -describe("ArkProject Account Creation", () => { - it("should successfully create an account", async () => { - // Initialize the RPC provider with the ArkChain node URL - const provider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Create an account using the provider - const accountDetails = await createAccount(provider); - - // Assertions to verify account creation - expect(accountDetails).toHaveProperty("address"); - expect(typeof accountDetails.address).toBe("string"); - expect(accountDetails).toHaveProperty("privateKey"); - expect(typeof accountDetails.privateKey).toBe("string"); - expect(accountDetails).toHaveProperty("publicKey"); - expect(typeof accountDetails.publicKey).toBe("string"); - expect(accountDetails).toHaveProperty("account"); - }); -}); diff --git a/packages/core/tests-new/createListing.test.ts b/packages/core/tests-new/createListing.test.ts deleted file mode 100644 index 3978da80d..000000000 --- a/packages/core/tests-new/createListing.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { shortString } from "starknet"; - -import { config } from "../examples/config"; -import { STARKNET_NFT_ADDRESS } from "../examples/constants"; -import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; -import { mintERC721 } from "../examples/utils/mintERC721"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { - createAccount, - fetchOrCreateAccount -} from "../src/actions/account/account"; -import { createListing } from "../src/actions/order"; -import { getOrderStatus } from "../src/actions/read"; -import { ListingV1 } from "../src/types"; - -test("ArkProject create a listing", async () => { - const { account: arkAccount } = await createAccount(config.arkProvider); - expect(arkAccount).toBeDefined(); - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ); - - await whitelistBroker(config, solisAdminAccount, 123); - - const starknetOffererAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - await mintERC721(config.starknetProvider, starknetOffererAccount); - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - - const order: ListingV1 = { - brokerId: 123, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId: BigInt(tokenId) + BigInt(1), - startAmount: 600000000000000000 - }; - - const orderHash = await createListing(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - order - }); - expect(orderHash).toBeDefined(); - - const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { - orderHash - }); - - expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); -}, 30000); - -test("ArkProject create a listing without whitelisting broker", async () => { - const { account: arkAccount } = await createAccount(config.arkProvider); - expect(arkAccount).toBeDefined(); - - const starknetOffererAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - await mintERC721(config.starknetProvider, starknetOffererAccount); - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - - const order: ListingV1 = { - brokerId: 12345, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId: BigInt(tokenId) + BigInt(1), - startAmount: 600000000000000000 - }; - - try { - await createListing(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - order - }); - } catch (e) { - const errorString = e instanceof Error ? e.message : JSON.stringify(e); - expect(errorString).toMatch(/Transaction execution has failed./); - } -}, 20000); diff --git a/packages/core/tests-new/fulfillListing.test.ts b/packages/core/tests-new/fulfillListing.test.ts deleted file mode 100644 index 6ed0d7b2f..000000000 --- a/packages/core/tests-new/fulfillListing.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { shortString } from "starknet"; - -import { config } from "../examples/config"; -import { - STARKNET_ETH_ADDRESS, - STARKNET_NFT_ADDRESS -} from "../examples/constants"; -import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; -import { mintERC20 } from "../examples/utils/mintERC20"; -import { mintERC721 } from "../examples/utils/mintERC721"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { - approveERC20, - approveERC721, - createAccount, - createListing, - fulfillListing, - ListingV1 -} from "../src"; -import { fetchOrCreateAccount } from "../src/actions/account/account"; -import { getOrderStatus } from "../src/actions/read"; - -describe("ArkProject Listing", () => { - it("should create and fulfill a listing", async () => { - const brokerId = 123; - const { arkProvider, starknetProvider } = config; - const { account: arkAccount } = await createAccount(arkProvider); - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV!, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV! - ); - - await whitelistBroker(config, solisAdminAccount, brokerId); - - const starknetOffererAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS!, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY! - ); - - const transaction_hash = await mintERC721( - starknetProvider, - starknetOffererAccount - ); - expect(transaction_hash).toBeDefined(); - - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - expect(tokenId).toBeDefined(); - - await approveERC721(config, { - contractAddress: STARKNET_NFT_ADDRESS, - starknetAccount: starknetOffererAccount - }); - - const order: ListingV1 = { - brokerId, - tokenAddress: STARKNET_NFT_ADDRESS, - tokenId, - startAmount: "100000000000000000" - }; - - const orderHash = await createListing(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - order - }); - expect(orderHash).toBeDefined(); - - const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { - orderHash - }); - - expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); - - const starknetFulfillerAccount = await fetchOrCreateAccount( - starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS!, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY! - ); - - if (process.env.STARKNET_NETWORK_ID === "dev") { - await mintERC20( - starknetProvider, - starknetFulfillerAccount, - order.startAmount - ); - } - - await approveERC20(config, { - starknetAccount: starknetFulfillerAccount, - contractAddress: STARKNET_ETH_ADDRESS, - amount: order.startAmount - }); - - const fulfillListingInfo = { - orderHash, - tokenAddress: order.tokenAddress, - tokenId, - brokerId - }; - - await fulfillListing(config, { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillListingInfo - }); - - await new Promise((resolve) => setTimeout(resolve, 3000)); - const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); - }, 60000); -}); diff --git a/packages/core/tests-new/fulfillOffer.test.ts b/packages/core/tests-new/fulfillOffer.test.ts deleted file mode 100644 index 7283b76c8..000000000 --- a/packages/core/tests-new/fulfillOffer.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { shortString } from "starknet"; - -import { config } from "../examples/config"; -import { - STARKNET_ETH_ADDRESS, - STARKNET_NFT_ADDRESS -} from "../examples/constants"; -import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; -import { mintERC20 } from "../examples/utils/mintERC20"; -import { mintERC721 } from "../examples/utils/mintERC721"; -import { whitelistBroker } from "../examples/utils/whitelistBroker"; -import { - approveERC20, - approveERC721, - createAccount, - createOffer, - fetchOrCreateAccount, - fulfillOffer, - getOrderStatus, - OfferV1 -} from "../src"; - -describe("ArkProject Listing and Offer Fulfillment", () => { - it("should create an offer and fulfill the offer", async function () { - const { arkProvider, starknetProvider } = config; - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ); - - await whitelistBroker(config, solisAdminAccount, 123); - - // Create a new account for the listing using the provider - const { account: arkAccount } = await createAccount(arkProvider); - - // Create a new account for fulfilling the offer - const starknetFulfillerAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY - ); - - expect(starknetFulfillerAccount).toBeDefined(); - - await mintERC721(starknetProvider, starknetFulfillerAccount); - - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - - // Define the order details - const order: OfferV1 = { - brokerId: 123, // The broker ID - tokenAddress: STARKNET_NFT_ADDRESS, // The token address - tokenId, // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order - }; - - const starknetOffererAccount = await fetchOrCreateAccount( - starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - await mintERC20( - starknetProvider, - starknetOffererAccount, - order.startAmount - ); - - // for allowance - await approveERC20(config, { - starknetAccount: starknetOffererAccount, - contractAddress: STARKNET_ETH_ADDRESS, - amount: order.startAmount - }); - - // Create the listing on the arkchain using the order details - const orderHash = await createOffer(config, { - starknetAccount: starknetOffererAccount, - arkAccount, - offer: order - }); - - expect(orderHash).toBeDefined(); - - await approveERC721(config, { - contractAddress: STARKNET_NFT_ADDRESS, - starknetAccount: starknetFulfillerAccount - }); - - await new Promise((resolve) => setTimeout(resolve, 2000)); - - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).resolves.toEqual("OPEN"); - - // Define the fulfill details - const fulfillOfferInfo = { - orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId, - brokerId: 123 - }; - - // Fulfill the offer - await fulfillOffer(config, { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillOfferInfo - }); - - await new Promise((resolve) => setTimeout(resolve, 3000)); - const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - - await new Promise((resolve) => setTimeout(resolve, 5000)); - const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); - }, 60000); - - it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { - const { arkProvider, starknetProvider } = config; - - const solisAdminAccount = await fetchOrCreateAccount( - config.arkProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV - ); - - await whitelistBroker(config, solisAdminAccount, 123); - - const { account: arkAccount } = await createAccount(arkProvider); - // Create a new account for the listing using the provider - const starknetFulfillerAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT2_ADDRESS, - process.env.STARKNET_ACCOUNT2_PRIVATE_KEY - ); - - await mintERC721(config.starknetProvider, starknetFulfillerAccount); - await approveERC721(config, { - contractAddress: STARKNET_NFT_ADDRESS, - starknetAccount: starknetFulfillerAccount - }); - - const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - - // Create a new account for the listing using the provider - const starknetAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.STARKNET_ACCOUNT1_ADDRESS, - process.env.STARKNET_ACCOUNT1_PRIVATE_KEY - ); - - // Define the order details - const order: OfferV1 = { - brokerId: 123, // The broker ID - tokenAddress: STARKNET_NFT_ADDRESS, // The token address - tokenId: tokenId, // The ID of the token - startAmount: 600000000000000000, // The starting amount for the order - currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address - }; - - await mintERC20(starknetProvider, starknetAccount, order.startAmount); - - // for allowance - await approveERC20(config, { - starknetAccount: starknetAccount, - contractAddress: STARKNET_ETH_ADDRESS, - amount: order.startAmount - }); - - // Create the offer on the arkchain using the order details - const orderHash = await createOffer(config, { - starknetAccount, - arkAccount, - offer: order - }); - - expect(orderHash).toBeDefined(); - - await new Promise((resolve) => setTimeout(resolve, 2000)); - - const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); - - expect(starknetFulfillerAccount).toBeDefined(); - - // Define the fulfill details - const fulfill_info = { - orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId, - brokerId: 123 - }; - - // Fulfill the offer - await fulfillOffer(config, { - starknetAccount: starknetFulfillerAccount, - arkAccount, - fulfillOfferInfo: fulfill_info - }); - - await new Promise((resolve) => setTimeout(resolve, 3000)); - const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { - orderHash - }); - expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - }, 60000); -}); diff --git a/packages/core/tests-new/utils/index.ts b/packages/core/tests-new/utils/index.ts deleted file mode 100644 index cbc53d590..000000000 --- a/packages/core/tests-new/utils/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CairoCustomEnum } from "starknet"; - -export function sleep(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -export function generateRandomTokenId(): number { - return Math.floor(Math.random() * 10000) + 1; -} - -type VariantKey = "Listing" | "Auction" | "Offer" | "CollectionOffer"; - -export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) { - const keyMap = { - Listing: "LISTING", - Auction: "AUCTION", - Offer: "OFFER", - CollectionOffer: "COLLECTION_OFFER" - }; - - for (const key in cairoCustomEnum.variant) { - if (cairoCustomEnum.variant[key as VariantKey] !== undefined) { - return keyMap[key as VariantKey] || "Unknown"; - } - } - - throw new Error("No valid variant found in CairoCustomEnum"); -} diff --git a/packages/core/tests-new/cancel.test.ts b/packages/core/tests/cancel.test.ts similarity index 100% rename from packages/core/tests-new/cancel.test.ts rename to packages/core/tests/cancel.test.ts diff --git a/packages/core/tests/cancelListing.test.ts b/packages/core/tests/cancelListing.test.ts deleted file mode 100644 index f4618420b..000000000 --- a/packages/core/tests/cancelListing.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import chai, { expect } from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { Account, AccountInterface, RpcProvider, shortString } from "starknet"; - -import { config } from "../examples/config"; // Assuming you have a sleep utility function -import { - CancelInfo, - cancelOrder, - createAccount, - createListing, - getOrderStatus, - ListingV1 -} from "../src"; -import { generateRandomTokenId, sleep } from "./utils"; - -chai.use(chaiAsPromised); - -interface cancelOrderParameters { - starknetAccount: AccountInterface; - arkAccount: Account; - cancelInfo: CancelInfo; - owner?: string; -} - -describe("ArkProject Cancel listing", () => { - it("should create and then cancel a listing", async function () { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); - - expect(arkAccount).to.exist; - expect(starknetAccount).to.exist; - - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order - }; - - // Create the listing on the arkchain using the order details - const orderHash = await createListing(config, { - starknetAccount, - arkAccount, - order - }); - await sleep(1000); // Wait for the transaction to be processed - - // Assert that we received an order hash - expect(orderHash).to.exist; - - // Assert that the order is open - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); - - // Define the cancel details - const cancelInfo = { - orderHash: orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId - }; - - // Cancel the order - const cancelOrderParams: cancelOrderParameters = { - starknetAccount: starknetAccount, - arkAccount: arkAccount, - cancelInfo, - owner: arkAccount.address - }; - // Cancel the order - cancelOrder(config, cancelOrderParams); - await sleep(1000); // Wait for the transaction to be processed - // Assert that the order was cancelled successfully - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("CANCELLED_USER"); - }); -}); diff --git a/packages/core/tests/cancelOffer.test.ts b/packages/core/tests/cancelOffer.test.ts index ef1a09d90..6d02e32d2 100644 --- a/packages/core/tests/cancelOffer.test.ts +++ b/packages/core/tests/cancelOffer.test.ts @@ -1,87 +1,90 @@ -import chai, { expect } from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { RpcProvider, shortString } from "starknet"; +import { shortString } from "starknet"; +import { OfferV1 } from "../dist"; +import { config } from "../examples/config"; import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; +import { + approveERC20, cancelOrder, createAccount, createOffer, + fetchOrCreateAccount, getOrderStatus, - getOrderType, - ListingV1 + getOrderType } from "../src"; -import { - generateRandomTokenId, - getTypeFromCairoCustomEnum, - sleep -} from "./utils"; - -chai.use(chaiAsPromised); +import { generateRandomTokenId, getTypeFromCairoCustomEnum } from "./utils"; describe("ArkProject cancel offer", () => { - it("should create an offer and verify its status and type", async function () { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + it("should cancel an offer and verify its status and type", async () => { + const { arkProvider, starknetProvider } = config; - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker(config, solisAdminAccount, 123); - // Create a new account using the provider const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + const offerStarAmount = 600000000000000000; - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order + await mintERC20(starknetProvider, starknetOffererAccount, offerStarAmount); + + const offer: OfferV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: generateRandomTokenId(), + startAmount: offerStarAmount, + currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address }; - // Create the listing on the blockchain using the order details - const orderHash = await createOffer( - arkProvider, - starknetAccount, - arkAccount, - order - ); - // Assert that the listing was created successfully (if possible) - await sleep(1000); // Wait for the transaction to be processed + await approveERC20(config, { + starknetAccount: starknetOffererAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: offer.startAmount + }); - // Assert that the order is open - await expect( - getOrderStatus(orderHash, arkProvider).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); + const orderHash = await createOffer(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + offer: offer + }); + await new Promise((resolve) => setTimeout(resolve, 2000)); + const r1 = await getOrderStatus(config, { orderHash }); + const orderStatusBefore = shortString.decodeShortString(r1.orderStatus); + expect(orderStatusBefore).toEqual("OPEN"); - // Assert that the order type is 'OFFER' - await expect( - getOrderType(orderHash, arkProvider).then((res) => - getTypeFromCairoCustomEnum(res.orderType) - ) - ).to.eventually.equal("OFFER"); + const r2 = await getOrderType(config, { orderHash }); + const orderType = getTypeFromCairoCustomEnum(r2.orderType); + expect(orderType).toEqual("OFFER"); - // Define the cancel details const cancelInfo = { orderHash: orderHash, - tokenAddress: order.tokenAddress, - tokenId: order.tokenId + tokenAddress: offer.tokenAddress, + tokenId: offer.tokenId }; - // Cancel the order - await cancelOrder(arkProvider, starknetAccount, arkAccount, cancelInfo); + await cancelOrder(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + cancelInfo + }); - // Assert that the order was cancelled successfully - await expect( - getOrderStatus(orderHash, arkProvider).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("CANCELLED_USER"); - }); + await new Promise((resolve) => setTimeout(resolve, 2000)); + const r3 = await getOrderStatus(config, { orderHash }); + const orderStatusAfter = shortString.decodeShortString(r3.orderStatus); + expect(orderStatusAfter).toEqual("CANCELLED_USER"); + }, 35000); }); diff --git a/packages/core/tests/createAccount.test.ts b/packages/core/tests/createAccount.test.ts index be1ca438b..8d9b32db0 100644 --- a/packages/core/tests/createAccount.test.ts +++ b/packages/core/tests/createAccount.test.ts @@ -1,4 +1,3 @@ -import { expect } from "chai"; import { RpcProvider } from "starknet"; import { createAccount } from "../src/actions/account/account"; @@ -14,12 +13,12 @@ describe("ArkProject Account Creation", () => { const accountDetails = await createAccount(provider); // Assertions to verify account creation - expect(accountDetails).to.have.property("address"); - expect(accountDetails.address).to.be.a("string"); - expect(accountDetails).to.have.property("privateKey"); - expect(accountDetails.privateKey).to.be.a("string"); - expect(accountDetails).to.have.property("publicKey"); - expect(accountDetails.publicKey).to.be.a("string"); - expect(accountDetails).to.have.property("account"); + expect(accountDetails).toHaveProperty("address"); + expect(typeof accountDetails.address).toBe("string"); + expect(accountDetails).toHaveProperty("privateKey"); + expect(typeof accountDetails.privateKey).toBe("string"); + expect(accountDetails).toHaveProperty("publicKey"); + expect(typeof accountDetails.publicKey).toBe("string"); + expect(accountDetails).toHaveProperty("account"); }); }); diff --git a/packages/core/tests/createListing.test.ts b/packages/core/tests/createListing.test.ts index 8213e1a73..3978da80d 100644 --- a/packages/core/tests/createListing.test.ts +++ b/packages/core/tests/createListing.test.ts @@ -1,159 +1,88 @@ -import chai, { expect } from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { RpcProvider, shortString } from "starknet"; +import { shortString } from "starknet"; -import { config } from "../examples/config"; // Assuming you have a sleep utility function +import { config } from "../examples/config"; +import { STARKNET_NFT_ADDRESS } from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; import { createAccount, - createListing, - getOrderStatus, - ListingV1 -} from "../src"; -import { generateRandomTokenId, sleep } from "./utils"; - -chai.use(chaiAsPromised); - -describe("ArkProject Create listing", () => { - it("should create a listing", async function () { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); - - expect(arkAccount).to.exist; - expect(starknetAccount).to.exist; - - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order - }; - - // Create the listing on the arkchain using the order details - const orderHash = await createListing(config, { - starknetAccount, - arkAccount, - order - }); - await sleep(1000); // Wait for the transaction to be processed - - // Assert that we received an order hash - expect(orderHash).to.exist; - - // Assert that the order is open - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); + fetchOrCreateAccount +} from "../src/actions/account/account"; +import { createListing } from "../src/actions/order"; +import { getOrderStatus } from "../src/actions/read"; +import { ListingV1 } from "../src/types"; + +test("ArkProject create a listing", async () => { + const { account: arkAccount } = await createAccount(config.arkProvider); + expect(arkAccount).toBeDefined(); + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); + + await whitelistBroker(config, solisAdminAccount, 123); + + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + await mintERC721(config.starknetProvider, starknetOffererAccount); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + + const order: ListingV1 = { + brokerId: 123, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: BigInt(tokenId) + BigInt(1), + startAmount: 600000000000000000 + }; + + const orderHash = await createListing(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + order }); + expect(orderHash).toBeDefined(); - it("should fail because offerer is not the owner", async function () { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); - - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); - const { account: starknetAccountOther } = - await createAccount(starknetProvider); - - expect(arkAccount).to.exist; - expect(starknetAccount).to.exist; - - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order - }; - - // Create the listing on the arkchain using the order details - const orderHash = await createListing(config, { - starknetAccount: starknetAccountOther, - arkAccount, - order - }); - await sleep(1000); // Wait for the transaction to be processed - - // Assert that we received an order hash - expect(orderHash).to.exist; - - // Assert that the order is open - await expect( - getOrderStatus(config, { orderHash }).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash }); - it("should fail because offerer is not the owner", async function () { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); +}, 30000); - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); +test("ArkProject create a listing without whitelisting broker", async () => { + const { account: arkAccount } = await createAccount(config.arkProvider); + expect(arkAccount).toBeDefined(); - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); - const { account: starknetAccountOther } = await createAccount(starknetProvider); + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); - expect(arkAccount).to.exist; - expect(starknetAccount).to.exist; + await mintERC721(config.starknetProvider, starknetOffererAccount); + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); - // Define the order details - const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order - }; + const order: ListingV1 = { + brokerId: 12345, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId: BigInt(tokenId) + BigInt(1), + startAmount: 600000000000000000 + }; - // Create the listing on the arkchain using the order details - const orderHash = await createListing(config, { - starknetAccount: starknetAccountOther, + try { + await createListing(config, { + starknetAccount: starknetOffererAccount, arkAccount, order }); - await sleep(1000); // Wait for the transaction to be processed - - // Assert that we received an order hash - expect(orderHash).to.exist; - - // Assert that the order is open - await expect( - getOrderStatus(config, {orderHash}).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); - - }); - -}); + } catch (e) { + const errorString = e instanceof Error ? e.message : JSON.stringify(e); + expect(errorString).toMatch(/Transaction execution has failed./); + } +}, 20000); diff --git a/packages/core/tests/fulfillListing.test.ts b/packages/core/tests/fulfillListing.test.ts index 4438005df..6ed0d7b2f 100644 --- a/packages/core/tests/fulfillListing.test.ts +++ b/packages/core/tests/fulfillListing.test.ts @@ -1,74 +1,122 @@ -import chai, { expect } from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { RpcProvider, shortString } from "starknet"; +import { shortString } from "starknet"; -import { createAccount } from "../src/actions/account/account"; -import { createListing, fulfillListing } from "../src/actions/order"; -import { getOrderHash, getOrderStatus } from "../src/actions/read"; -import { ListingV1 } from "../src/types"; -import { generateRandomTokenId, sleep } from "./utils"; - -chai.use(chaiAsPromised); +import { config } from "../examples/config"; +import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; +import { + approveERC20, + approveERC721, + createAccount, + createListing, + fulfillListing, + ListingV1 +} from "../src"; +import { fetchOrCreateAccount } from "../src/actions/account/account"; +import { getOrderStatus } from "../src/actions/read"; describe("ArkProject Listing", () => { it("should create and fulfill a listing", async () => { - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + const brokerId = 123; + const { arkProvider, starknetProvider } = config; + const { account: arkAccount } = await createAccount(arkProvider); - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV!, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV! + ); - // Create a new account using the provider - const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); + await whitelistBroker(config, solisAdminAccount, brokerId); + + const starknetOffererAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS!, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY! + ); + + const transaction_hash = await mintERC721( + starknetProvider, + starknetOffererAccount + ); + expect(transaction_hash).toBeDefined(); + + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + expect(tokenId).toBeDefined(); + + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetOffererAccount + }); const order: ListingV1 = { - brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token - startAmount: 600000000000000000 // The starting amount for the order + brokerId, + tokenAddress: STARKNET_NFT_ADDRESS, + tokenId, + startAmount: "100000000000000000" }; - await createListing(arkProvider, starknetAccount, arkAccount, order); - await sleep(2000); - const { orderHash } = await getOrderHash( - order.tokenId, - order.tokenAddress, - arkProvider + const orderHash = await createListing(config, { + starknetAccount: starknetOffererAccount, + arkAccount, + order + }); + expect(orderHash).toBeDefined(); + + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + + const starknetFulfillerAccount = await fetchOrCreateAccount( + starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS!, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY! ); - await expect( - getOrderStatus(orderHash, arkProvider).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("OPEN"); - - // Create a new accounts for the fulfill using the provider - const { account: starknetFulfillerAccount } = - await createAccount(starknetProvider); - - const fulfill_info = { - order_hash: orderHash, - token_address: order.tokenAddress, - token_id: order.tokenId + + if (process.env.STARKNET_NETWORK_ID === "dev") { + await mintERC20( + starknetProvider, + starknetFulfillerAccount, + order.startAmount + ); + } + + await approveERC20(config, { + starknetAccount: starknetFulfillerAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + const fulfillListingInfo = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId, + brokerId }; - fulfillListing( - arkProvider, - starknetFulfillerAccount, + await fulfillListing(config, { + starknetAccount: starknetFulfillerAccount, arkAccount, - fulfill_info - ); - await sleep(1000); - - await expect( - getOrderStatus(orderHash, arkProvider).then((res) => - shortString.decodeShortString(res.orderStatus) - ) - ).to.eventually.equal("FULFILLED"); - }); + fulfillListingInfo + }); + + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); + + await new Promise((resolve) => setTimeout(resolve, 5000)); + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); + }, 60000); }); diff --git a/packages/core/tests/fulfillOffer.test.ts b/packages/core/tests/fulfillOffer.test.ts index c10bf968a..7283b76c8 100644 --- a/packages/core/tests/fulfillOffer.test.ts +++ b/packages/core/tests/fulfillOffer.test.ts @@ -1,92 +1,219 @@ -import chai, { expect } from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { RpcProvider, shortString } from "starknet"; +import { shortString } from "starknet"; +import { config } from "../examples/config"; import { + STARKNET_ETH_ADDRESS, + STARKNET_NFT_ADDRESS +} from "../examples/constants"; +import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; +import { mintERC20 } from "../examples/utils/mintERC20"; +import { mintERC721 } from "../examples/utils/mintERC721"; +import { whitelistBroker } from "../examples/utils/whitelistBroker"; +import { + approveERC20, + approveERC721, createAccount, createOffer, + fetchOrCreateAccount, fulfillOffer, getOrderStatus, OfferV1 } from "../src"; -import { generateRandomTokenId } from "./utils"; - -chai.use(chaiAsPromised); describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { - this.timeout(10000); // Extend timeout if necessary + const { arkProvider, starknetProvider } = config; - // Initialize the RPC provider with the ArkChain node URL - const starknetProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV + ); - // Initialize the RPC provider with the katana node URL for starknet - const arkProvider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + await whitelistBroker(config, solisAdminAccount, 123); // Create a new account for the listing using the provider const { account: arkAccount } = await createAccount(arkProvider); - const { account: starknetAccount } = await createAccount(starknetProvider); + + // Create a new account for fulfilling the offer + const starknetFulfillerAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY + ); + + expect(starknetFulfillerAccount).toBeDefined(); + + await mintERC721(starknetProvider, starknetFulfillerAccount); + + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); // Define the order details const order: OfferV1 = { brokerId: 123, // The broker ID - tokenAddress: - "0x01435498bf393da86b4733b9264a86b58a42b31f8d8b8ba309593e5c17847672", // The token address - tokenId: generateRandomTokenId(), // The ID of the token + tokenAddress: STARKNET_NFT_ADDRESS, // The token address + tokenId, // The ID of the token startAmount: 600000000000000000 // The starting amount for the order }; + const starknetOffererAccount = await fetchOrCreateAccount( + starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + await mintERC20( + starknetProvider, + starknetOffererAccount, + order.startAmount + ); + + // for allowance + await approveERC20(config, { + starknetAccount: starknetOffererAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + // Create the listing on the arkchain using the order details - const orderHash = await createOffer( - arkProvider, - starknetAccount, + const orderHash = await createOffer(config, { + starknetAccount: starknetOffererAccount, arkAccount, - order - ); - expect(orderHash).to.exist; + offer: order + }); - await new Promise((resolve) => setTimeout(resolve, 2000)); + expect(orderHash).toBeDefined(); - const { orderStatus: orderStatusBefore } = await getOrderStatus( - orderHash, - arkProvider - ); - expect(shortString.decodeShortString(orderStatusBefore)).to.equal("OPEN"); + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetFulfillerAccount + }); - // Create a new account for fulfilling the offer - const { account: starknetFulfillerAccount } = - await createAccount(starknetProvider); + await new Promise((resolve) => setTimeout(resolve, 2000)); - expect(starknetFulfillerAccount).to.exist; + await expect( + getOrderStatus(config, { orderHash }).then((res) => + shortString.decodeShortString(res.orderStatus) + ) + ).resolves.toEqual("OPEN"); // Define the fulfill details - const fulfill_info = { - order_hash: orderHash, - token_address: order.tokenAddress, - token_id: order.tokenId + const fulfillOfferInfo = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId, + brokerId: 123 }; // Fulfill the offer - await fulfillOffer( - arkProvider, - starknetFulfillerAccount, + await fulfillOffer(config, { + starknetAccount: starknetFulfillerAccount, arkAccount, - fulfill_info - ); + fulfillOfferInfo + }); + + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); await new Promise((resolve) => setTimeout(resolve, 5000)); + const { orderStatus: orderStatusAfter } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); + }, 60000); - const { orderStatus: orderStatusAfter } = await getOrderStatus( - orderHash, - arkProvider + it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { + const { arkProvider, starknetProvider } = config; + + const solisAdminAccount = await fetchOrCreateAccount( + config.arkProvider, + process.env.SOLIS_ADMIN_ADDRESS_DEV, + process.env.SOLIS_ADMIN_PRIVATE_KEY_DEV ); - expect(shortString.decodeShortString(orderStatusAfter)).to.equal( - "FULFILLED" + await whitelistBroker(config, solisAdminAccount, 123); + + const { account: arkAccount } = await createAccount(arkProvider); + // Create a new account for the listing using the provider + const starknetFulfillerAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT2_ADDRESS, + process.env.STARKNET_ACCOUNT2_PRIVATE_KEY ); - }); + + await mintERC721(config.starknetProvider, starknetFulfillerAccount); + await approveERC721(config, { + contractAddress: STARKNET_NFT_ADDRESS, + starknetAccount: starknetFulfillerAccount + }); + + const tokenId = await getCurrentTokenId(config, STARKNET_NFT_ADDRESS); + + // Create a new account for the listing using the provider + const starknetAccount = await fetchOrCreateAccount( + config.starknetProvider, + process.env.STARKNET_ACCOUNT1_ADDRESS, + process.env.STARKNET_ACCOUNT1_PRIVATE_KEY + ); + + // Define the order details + const order: OfferV1 = { + brokerId: 123, // The broker ID + tokenAddress: STARKNET_NFT_ADDRESS, // The token address + tokenId: tokenId, // The ID of the token + startAmount: 600000000000000000, // The starting amount for the order + currencyAddress: STARKNET_ETH_ADDRESS // The ERC20 address + }; + + await mintERC20(starknetProvider, starknetAccount, order.startAmount); + + // for allowance + await approveERC20(config, { + starknetAccount: starknetAccount, + contractAddress: STARKNET_ETH_ADDRESS, + amount: order.startAmount + }); + + // Create the offer on the arkchain using the order details + const orderHash = await createOffer(config, { + starknetAccount, + arkAccount, + offer: order + }); + + expect(orderHash).toBeDefined(); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + const { orderStatus: orderStatusBefore } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBefore)).toBe("OPEN"); + + expect(starknetFulfillerAccount).toBeDefined(); + + // Define the fulfill details + const fulfill_info = { + orderHash, + tokenAddress: order.tokenAddress, + tokenId: order.tokenId, + brokerId: 123 + }; + + // Fulfill the offer + await fulfillOffer(config, { + starknetAccount: starknetFulfillerAccount, + arkAccount, + fulfillOfferInfo: fulfill_info + }); + + await new Promise((resolve) => setTimeout(resolve, 3000)); + const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { + orderHash + }); + expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); + }, 60000); }); From 05ba1e47d4eedf7bf1f3bd880413c0fcab60fb22 Mon Sep 17 00:00:00 2001 From: bexan Date: Tue, 12 Mar 2024 11:23:39 +0100 Subject: [PATCH 17/19] test: rework changeTokenOwner method --- contracts.json | 2 +- crates/solis/messaging.local.json | 6 ++--- .../core/examples/utils/changeTokenOwner.ts | 24 +++++-------------- packages/core/package.json | 2 +- packages/core/src/contracts.ts | 10 ++++---- packages/core/tests/fulfillOffer.test.ts | 5 +++- 6 files changed, 20 insertions(+), 29 deletions(-) diff --git a/contracts.json b/contracts.json index 8db142d29..8a20b64d9 100644 --- a/contracts.json +++ b/contracts.json @@ -1 +1 @@ -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"nftContract":"0x3ca9649b19d91a7110e2f2c0361ba0f65d6f1a3eb4615b041e51a3eb634ed4e","eth":"0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9","messaging":"0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953","executor":"0x5cca831be0da6eca88141ae3a52de3ff576e5770b6ec06d8f05416f252975e2","orderbook":"0x4de16bc47e25fa8e4d029f63c197ef77a1e6fbcb2be481fb8d5896d52af507e"}} \ No newline at end of file +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d","executor":"0x7c62c109647896d8b4ed0362512d421a3c7f3f3fbc91ecbf21750f51602931d","nftContract":"0x79a3ff14e4708933c59cf66c1772ff5023ffa0680b26ea819768ce7bd696dba","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x4ef6415a131b80898f08059b9b96574d6164e13df53e46d374849b52d080cb1"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 3d8fbd71f..4fc39a401 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,9 +1,9 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953", - "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", - "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", + "contract_address": "0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d", + "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", + "private_key": "0x1800000000300000180000000000030000000000003006001800006600", "interval": 2, "from_block": 0 } \ No newline at end of file diff --git a/packages/core/examples/utils/changeTokenOwner.ts b/packages/core/examples/utils/changeTokenOwner.ts index 21c147be6..a1b54e188 100644 --- a/packages/core/examples/utils/changeTokenOwner.ts +++ b/packages/core/examples/utils/changeTokenOwner.ts @@ -1,13 +1,14 @@ -import { BigNumberish, cairo, CairoOption, CairoOptionVariant, CallData, Uint256 } from "starknet"; +import { AccountInterface, BigNumberish, cairo, CairoOption, CairoOptionVariant, CallData, Uint256 } from "starknet"; import { Config } from "../../src/createConfig"; import { fetchOrCreateAccount } from "../../src"; import { getCurrentTokenId } from "./getCurrentTokenId"; +import { config } from "../config"; export const changeTokenOwner = async ( config: Config, nftContractAddress: string, - from: string, + owner: AccountInterface, to: string, tokenId: BigNumberish ) => { @@ -16,26 +17,13 @@ export const changeTokenOwner = async ( throw new Error("no abi."); } - const token = new CairoOption( - CairoOptionVariant.Some, - cairo.uint256(tokenId) - ); - - const adminAccount = await fetchOrCreateAccount( - config.starknetProvider, - process.env.SOLIS_ADMIN_ADDRESS_DEV, - process.env.SOLIS_ADMIN_ADDRESS_DEV - ); - - const nTokenId = await getCurrentTokenId(config, nftContractAddress) + BigInt(1); - console.log("nTokenId", nTokenId) const hash_calldata = CallData.compile({ - from, + from: owner.address, to, - tokenId: cairo.uint256(nTokenId), + tokenId: cairo.uint256(tokenId), }); - const result = await adminAccount.execute({ + const result = await owner.execute({ contractAddress: config.starknetContracts.nftContract, entrypoint: "transfer_from", calldata: hash_calldata diff --git a/packages/core/package.json b/packages/core/package.json index a3abbcb86..3f527ef36 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -12,7 +12,7 @@ "generate-contracts": "ts-node src/generateContracts.ts", "build": "npm run generate-contracts && tsup src/index.ts --format cjs,esm --dts", "dev": "nodemon --watch ../../contracts.json --exec 'npm run generate-contracts' & tsup src/index.ts --format cjs,esm --dts --watch", - "test": "jest tests" + "test": "jest tests/fulfillOffer.test.ts" }, "dependencies": { "@scure/starknet": "^0.3.0", diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index bd96e7f6f..d244b9f6b 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "nftContract": "0x3ca9649b19d91a7110e2f2c0361ba0f65d6f1a3eb4615b041e51a3eb634ed4e", - "eth": "0x4007c4afac7b79c2119c1d417e3106294cb28d92bdfba26474e8e250b1e91c9", - "messaging": "0x5d27da7e17c7e6879196568b51acc7deb29bc8a0f10f52bea77844a07411953", - "executor": "0x5cca831be0da6eca88141ae3a52de3ff576e5770b6ec06d8f05416f252975e2", - "orderbook": "0x4de16bc47e25fa8e4d029f63c197ef77a1e6fbcb2be481fb8d5896d52af507e" + "messaging": "0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d", + "executor": "0x7c62c109647896d8b4ed0362512d421a3c7f3f3fbc91ecbf21750f51602931d", + "nftContract": "0x79a3ff14e4708933c59cf66c1772ff5023ffa0680b26ea819768ce7bd696dba", + "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", + "orderbook": "0x4ef6415a131b80898f08059b9b96574d6164e13df53e46d374849b52d080cb1" }; diff --git a/packages/core/tests/fulfillOffer.test.ts b/packages/core/tests/fulfillOffer.test.ts index 7283b76c8..acb90d6b7 100644 --- a/packages/core/tests/fulfillOffer.test.ts +++ b/packages/core/tests/fulfillOffer.test.ts @@ -19,6 +19,7 @@ import { getOrderStatus, OfferV1 } from "../src"; +import { changeTokenOwner } from "../examples/utils/changeTokenOwner"; describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { @@ -203,6 +204,8 @@ describe("ArkProject Listing and Offer Fulfillment", () => { brokerId: 123 }; + await changeTokenOwner(config, STARKNET_NFT_ADDRESS, starknetFulfillerAccount, starknetAccount.address, tokenId); + // Fulfill the offer await fulfillOffer(config, { starknetAccount: starknetFulfillerAccount, @@ -210,7 +213,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { fulfillOfferInfo: fulfill_info }); - await new Promise((resolve) => setTimeout(resolve, 3000)); + await new Promise((resolve) => setTimeout(resolve, 7000)); const { orderStatus: orderStatusBetween } = await getOrderStatus(config, { orderHash }); From 244ed060bcf0116ac69a325cf2d28b706ab71f8c Mon Sep 17 00:00:00 2001 From: kwiss Date: Tue, 12 Mar 2024 13:49:03 +0100 Subject: [PATCH 18/19] fix(tests): use sequencial testing --- packages/core/examples/utils/whitelistBroker.ts | 2 +- packages/core/package.json | 2 +- packages/core/src/actions/order/_create.ts | 2 +- packages/core/tests/createAccount.test.ts | 9 +++------ 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/core/examples/utils/whitelistBroker.ts b/packages/core/examples/utils/whitelistBroker.ts index 8e90b490a..8ea5bb8bf 100644 --- a/packages/core/examples/utils/whitelistBroker.ts +++ b/packages/core/examples/utils/whitelistBroker.ts @@ -26,7 +26,7 @@ export const whitelistBroker = async ( }); await config.arkProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 200 + retryInterval: 1000 }); return result; diff --git a/packages/core/package.json b/packages/core/package.json index 3f527ef36..1e56dfd7a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -12,7 +12,7 @@ "generate-contracts": "ts-node src/generateContracts.ts", "build": "npm run generate-contracts && tsup src/index.ts --format cjs,esm --dts", "dev": "nodemon --watch ../../contracts.json --exec 'npm run generate-contracts' & tsup src/index.ts --format cjs,esm --dts --watch", - "test": "jest tests/fulfillOffer.test.ts" + "test": "jest tests -i" }, "dependencies": { "@scure/starknet": "^0.3.0", diff --git a/packages/core/src/actions/order/_create.ts b/packages/core/src/actions/order/_create.ts index 141408904..8e3e087f2 100644 --- a/packages/core/src/actions/order/_create.ts +++ b/packages/core/src/actions/order/_create.ts @@ -74,7 +74,7 @@ const createOrder = async ( }); await config.arkProvider.waitForTransaction(result.transaction_hash, { - retryInterval: 200 + retryInterval: 1000 }); const orderHash = getOrderHashFromOrderV1(order); diff --git a/packages/core/tests/createAccount.test.ts b/packages/core/tests/createAccount.test.ts index 8d9b32db0..8c01c3310 100644 --- a/packages/core/tests/createAccount.test.ts +++ b/packages/core/tests/createAccount.test.ts @@ -1,16 +1,13 @@ -import { RpcProvider } from "starknet"; - +import { config } from "../examples/config"; import { createAccount } from "../src/actions/account/account"; describe("ArkProject Account Creation", () => { it("should successfully create an account", async () => { // Initialize the RPC provider with the ArkChain node URL - const provider = new RpcProvider({ - nodeUrl: "http://0.0.0.0:7777" - }); + const { arkProvider } = config; // Create an account using the provider - const accountDetails = await createAccount(provider); + const accountDetails = await createAccount(arkProvider); // Assertions to verify account creation expect(accountDetails).toHaveProperty("address"); From 314314454696e22645c36cc828138ed99c86c12f Mon Sep 17 00:00:00 2001 From: kwiss Date: Tue, 12 Mar 2024 15:12:32 +0100 Subject: [PATCH 19/19] fix(tests): update wait for transactions & fix tests --- contracts.json | 2 +- crates/solis/messaging.local.json | 6 +++--- packages/core/examples/utils/changeTokenOwner.ts | 10 +++------- packages/core/examples/utils/mintERC20.ts | 4 +++- packages/core/examples/utils/mintERC721.ts | 4 +++- packages/core/src/actions/contract/approve.ts | 8 ++++++-- packages/core/src/contracts.ts | 10 +++++----- packages/core/tests/cancel.test.ts | 2 +- packages/core/tests/cancelOffer.test.ts | 2 +- packages/core/tests/fulfillListing.test.ts | 2 +- packages/core/tests/fulfillOffer.test.ts | 14 ++++++++++---- 11 files changed, 37 insertions(+), 27 deletions(-) diff --git a/contracts.json b/contracts.json index 8a20b64d9..d3ce3b69b 100644 --- a/contracts.json +++ b/contracts.json @@ -1 +1 @@ -{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"messaging":"0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d","executor":"0x7c62c109647896d8b4ed0362512d421a3c7f3f3fbc91ecbf21750f51602931d","nftContract":"0x79a3ff14e4708933c59cf66c1772ff5023ffa0680b26ea819768ce7bd696dba","eth":"0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c","orderbook":"0x4ef6415a131b80898f08059b9b96574d6164e13df53e46d374849b52d080cb1"}} \ No newline at end of file +{"goerli":{"nftContract":"0x22411b480425fe6e627fdf4d1b6ac7f8567314ada5617a0a6d8ef3e74b69436","messaging":"0x2c3d3e0c37d29364a13ba8cff046e7bc5624655a72526961876a1c8bb3f63c8","executor":"0x73148536f8ea9546e92761d11515548cc433df46883d5ee98871a6f63a0bbbc","orderbook":"0x66f1e6acf9bdbd23837b2eea271430298b355c506978edb132737e7fcb6b310"},"sepolia":{},"mainnet":{},"dev":{"nftContract":"0x6f63d7d261c2d2c5409ba80ab0b235303fdcd01daeef61ca5ae7238285d7b78","eth":"0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4","messaging":"0x38e142d3d69cfe6757fd9d11704652f6bd8302dd23f483555e9b5698bf69d5","executor":"0x1f303987f8a61ee25d5a153791fd778f0c478947bb32613d15fc8194e0360a6","orderbook":"0x3d7a3a02741c905fdb3cccf14e376a7d64c8cb071874f47f0b01d73015eae6b"}} \ No newline at end of file diff --git a/crates/solis/messaging.local.json b/crates/solis/messaging.local.json index 4fc39a401..60ff344fe 100644 --- a/crates/solis/messaging.local.json +++ b/crates/solis/messaging.local.json @@ -1,9 +1,9 @@ { "chain": "starknet", "rpc_url": "http://127.0.0.1:5050", - "contract_address": "0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d", - "sender_address": "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03", - "private_key": "0x1800000000300000180000000000030000000000003006001800006600", + "contract_address": "0x38e142d3d69cfe6757fd9d11704652f6bd8302dd23f483555e9b5698bf69d5", + "sender_address": "0x2d71e9c974539bb3ffb4b115e66a23d0f62a641ea66c4016e903454c8753bbc", + "private_key": "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b", "interval": 2, "from_block": 0 } \ No newline at end of file diff --git a/packages/core/examples/utils/changeTokenOwner.ts b/packages/core/examples/utils/changeTokenOwner.ts index a1b54e188..1ca8a0cb6 100644 --- a/packages/core/examples/utils/changeTokenOwner.ts +++ b/packages/core/examples/utils/changeTokenOwner.ts @@ -1,9 +1,6 @@ -import { AccountInterface, BigNumberish, cairo, CairoOption, CairoOptionVariant, CallData, Uint256 } from "starknet"; +import { AccountInterface, BigNumberish, cairo, CallData } from "starknet"; import { Config } from "../../src/createConfig"; -import { fetchOrCreateAccount } from "../../src"; -import { getCurrentTokenId } from "./getCurrentTokenId"; -import { config } from "../config"; export const changeTokenOwner = async ( config: Config, @@ -20,15 +17,14 @@ export const changeTokenOwner = async ( const hash_calldata = CallData.compile({ from: owner.address, to, - tokenId: cairo.uint256(tokenId), + tokenId: cairo.uint256(tokenId) }); - const result = await owner.execute({ + await owner.execute({ contractAddress: config.starknetContracts.nftContract, entrypoint: "transfer_from", calldata: hash_calldata }); - console.log("result change", result) return; }; diff --git a/packages/core/examples/utils/mintERC20.ts b/packages/core/examples/utils/mintERC20.ts index 143ffb001..72262ac74 100644 --- a/packages/core/examples/utils/mintERC20.ts +++ b/packages/core/examples/utils/mintERC20.ts @@ -26,6 +26,8 @@ export const mintERC20 = async ( }; const result = await starknetAccount.execute(mintERC20Call, [erc20abi]); - await provider.waitForTransaction(result.transaction_hash); + await provider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); return result.transaction_hash; }; diff --git a/packages/core/examples/utils/mintERC721.ts b/packages/core/examples/utils/mintERC721.ts index 3391af9e3..b7250315c 100644 --- a/packages/core/examples/utils/mintERC721.ts +++ b/packages/core/examples/utils/mintERC721.ts @@ -24,6 +24,8 @@ export async function mintERC721( const result = await starknetAccount.execute(mintCall, [erc721abi]); - await provider.waitForTransaction(result.transaction_hash); + await provider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); return result.transaction_hash; } diff --git a/packages/core/src/actions/contract/approve.ts b/packages/core/src/actions/contract/approve.ts index cb0e1da3a..9bf521558 100644 --- a/packages/core/src/actions/contract/approve.ts +++ b/packages/core/src/actions/contract/approve.ts @@ -33,7 +33,9 @@ export const approveERC721 = async ( }; const result = await starknetAccount.execute(approveCall, [erc721abi]); - await config.starknetProvider.waitForTransaction(result.transaction_hash); + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); }; interface ERC20Parameters { @@ -65,7 +67,9 @@ export const approveERC20 = async ( const result = await starknetAccount.execute(approuveERC20Call, [erc20abi]); - await config.starknetProvider.waitForTransaction(result.transaction_hash); + await config.starknetProvider.waitForTransaction(result.transaction_hash, { + retryInterval: 1000 + }); return result; }; diff --git a/packages/core/src/contracts.ts b/packages/core/src/contracts.ts index d244b9f6b..bdcff550d 100644 --- a/packages/core/src/contracts.ts +++ b/packages/core/src/contracts.ts @@ -9,9 +9,9 @@ export const GOERLI_CONTRACTS = { export const SEPOLIA_CONTRACTS = {}; export const MAINNET_CONTRACTS = {}; export const DEV_CONTRACTS = { - "messaging": "0x130b19a105839bef30311cd197dea6796b5c0d0c330f75ee4109808e9710a8d", - "executor": "0x7c62c109647896d8b4ed0362512d421a3c7f3f3fbc91ecbf21750f51602931d", - "nftContract": "0x79a3ff14e4708933c59cf66c1772ff5023ffa0680b26ea819768ce7bd696dba", - "eth": "0x144a0c8ae6e665dc3652e164ba2881eda87ad9cb5dcc93d30ca6d61b818014c", - "orderbook": "0x4ef6415a131b80898f08059b9b96574d6164e13df53e46d374849b52d080cb1" + "nftContract": "0x6f63d7d261c2d2c5409ba80ab0b235303fdcd01daeef61ca5ae7238285d7b78", + "eth": "0x7b8fc5c78bf249bb4173ef45267da1a710c65d76bb9ff03deb6b8fc21f35ba4", + "messaging": "0x38e142d3d69cfe6757fd9d11704652f6bd8302dd23f483555e9b5698bf69d5", + "executor": "0x1f303987f8a61ee25d5a153791fd778f0c478947bb32613d15fc8194e0360a6", + "orderbook": "0x3d7a3a02741c905fdb3cccf14e376a7d64c8cb071874f47f0b01d73015eae6b" }; diff --git a/packages/core/tests/cancel.test.ts b/packages/core/tests/cancel.test.ts index f2b3282f9..596bbd003 100644 --- a/packages/core/tests/cancel.test.ts +++ b/packages/core/tests/cancel.test.ts @@ -74,4 +74,4 @@ test("ArkProject Cancel listing should create and then cancel a listing", async expect(shortString.decodeShortString(orderStatusAfter)).toBe( "CANCELLED_USER" ); -}, 20000); +}, 15000); diff --git a/packages/core/tests/cancelOffer.test.ts b/packages/core/tests/cancelOffer.test.ts index 6d02e32d2..c8b728477 100644 --- a/packages/core/tests/cancelOffer.test.ts +++ b/packages/core/tests/cancelOffer.test.ts @@ -86,5 +86,5 @@ describe("ArkProject cancel offer", () => { const r3 = await getOrderStatus(config, { orderHash }); const orderStatusAfter = shortString.decodeShortString(r3.orderStatus); expect(orderStatusAfter).toEqual("CANCELLED_USER"); - }, 35000); + }, 20000); }); diff --git a/packages/core/tests/fulfillListing.test.ts b/packages/core/tests/fulfillListing.test.ts index 6ed0d7b2f..98623a1d3 100644 --- a/packages/core/tests/fulfillListing.test.ts +++ b/packages/core/tests/fulfillListing.test.ts @@ -118,5 +118,5 @@ describe("ArkProject Listing", () => { orderHash }); expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); - }, 60000); + }, 30000); }); diff --git a/packages/core/tests/fulfillOffer.test.ts b/packages/core/tests/fulfillOffer.test.ts index acb90d6b7..206434349 100644 --- a/packages/core/tests/fulfillOffer.test.ts +++ b/packages/core/tests/fulfillOffer.test.ts @@ -5,6 +5,7 @@ import { STARKNET_ETH_ADDRESS, STARKNET_NFT_ADDRESS } from "../examples/constants"; +import { changeTokenOwner } from "../examples/utils/changeTokenOwner"; import { getCurrentTokenId } from "../examples/utils/getCurrentTokenId"; import { mintERC20 } from "../examples/utils/mintERC20"; import { mintERC721 } from "../examples/utils/mintERC721"; @@ -19,7 +20,6 @@ import { getOrderStatus, OfferV1 } from "../src"; -import { changeTokenOwner } from "../examples/utils/changeTokenOwner"; describe("ArkProject Listing and Offer Fulfillment", () => { it("should create an offer and fulfill the offer", async function () { @@ -124,7 +124,7 @@ describe("ArkProject Listing and Offer Fulfillment", () => { orderHash }); expect(shortString.decodeShortString(orderStatusAfter)).toBe("EXECUTED"); - }, 60000); + }, 30000); it("should create an offer and fail to fulfill the offer because owner of token changed", async function () { const { arkProvider, starknetProvider } = config; @@ -204,7 +204,13 @@ describe("ArkProject Listing and Offer Fulfillment", () => { brokerId: 123 }; - await changeTokenOwner(config, STARKNET_NFT_ADDRESS, starknetFulfillerAccount, starknetAccount.address, tokenId); + await changeTokenOwner( + config, + STARKNET_NFT_ADDRESS, + starknetFulfillerAccount, + starknetAccount.address, + tokenId + ); // Fulfill the offer await fulfillOffer(config, { @@ -218,5 +224,5 @@ describe("ArkProject Listing and Offer Fulfillment", () => { orderHash }); expect(shortString.decodeShortString(orderStatusBetween)).toBe("FULFILLED"); - }, 60000); + }, 30000); });