Skip to content

Commit 69cf13c

Browse files
authored
Merge pull request #24 from near-examples/workspaces-migration
"Workspaces -> sandbox" migration
2 parents 2206aeb + 4e9f621 commit 69cf13c

8 files changed

Lines changed: 856 additions & 583 deletions

File tree

contract-rs/01-basic-auction/Cargo.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ crate-type = ["cdylib", "rlib"]
99

1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111
[dependencies]
12-
near-sdk = "5.23.0"
12+
near-sdk = "5.24.0"
1313

1414
[dev-dependencies]
15-
near-sdk = { version = "5.23.0", features = ["unit-testing"] }
16-
near-workspaces = { version = "0.22.0", features = ["unstable"] }
15+
near-sdk = { version = "5.24.0", features = ["unit-testing"] }
16+
near-sandbox = "0.3"
17+
near-api = "0.8"
18+
cargo-near-build = "0.10"
1719
tokio = { version = "1.12.0", features = ["full"] }
1820
serde_json = "1"
19-
chrono = "0.4.38"
21+
testresult = "0.4.1"
22+
# This is temporary fix for the build error since those crates with a higher version require a higher version of Rust compiler (1.88.0)
23+
cargo-platform = "=0.3.1"
24+
darling = "=0.20.11"
25+
bon = "=3.8.1"
2026

2127
[profile.release]
2228
codegen-units = 1
Lines changed: 139 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,189 @@
1-
use chrono::Utc;
2-
use near_sdk::near;
3-
use near_workspaces::types::{AccountId, Gas, NearToken};
4-
use serde_json::json;
1+
use near_api::{AccountId, NearGas, NearToken};
2+
use near_sdk::serde_json::json;
53

6-
#[near(serializers = [json])]
7-
#[derive(Clone)]
4+
#[derive(near_sdk::serde::Deserialize)]
5+
#[serde(crate = "near_sdk::serde")]
86
pub struct Bid {
97
pub bidder: AccountId,
108
pub bid: NearToken,
119
}
1210

13-
const TEN_NEAR: NearToken = NearToken::from_near(10);
14-
1511
#[tokio::test]
16-
async fn test_contract_is_operational() -> Result<(), Box<dyn std::error::Error>> {
17-
let sandbox = near_workspaces::sandbox().await?;
12+
async fn test_contract_is_operational() -> testresult::TestResult<()> {
13+
// Build the contract wasm file
14+
let contract_wasm_path = cargo_near_build::build_with_cli(Default::default())?;
15+
let contract_wasm = std::fs::read(contract_wasm_path)?;
1816

19-
let root = sandbox.root_account()?;
17+
// Initialize the sandbox
18+
let sandbox = near_sandbox::Sandbox::start_sandbox().await?;
19+
let sandbox_network =
20+
near_api::NetworkConfig::from_rpc_url("sandbox", sandbox.rpc_addr.parse()?);
2021

2122
// Create accounts
22-
let alice = create_subaccount(&root, "alice").await?;
23-
let bob = create_subaccount(&root, "bob").await?;
24-
let auctioneer = create_subaccount(&root, "auctioneer").await?;
25-
let contract_account = create_subaccount(&root, "contract").await?;
26-
27-
// Deploy and initialize contract
28-
let contract_wasm = near_workspaces::compile_project("./").await?;
29-
let contract = contract_account.deploy(&contract_wasm).await?.unwrap();
30-
31-
let now = Utc::now().timestamp();
23+
let alice = create_subaccount(&sandbox, "alice.sandbox").await?;
24+
let bob = create_subaccount(&sandbox, "bob.sandbox").await?;
25+
let auctioneer = create_subaccount(&sandbox, "auctioneer.sandbox").await?;
26+
let contract = create_subaccount(&sandbox, "contract.sandbox")
27+
.await?
28+
.as_contract();
29+
30+
// Initialize signer for the contract deployment
31+
let signer = near_api::Signer::from_secret_key(
32+
near_sandbox::config::DEFAULT_GENESIS_ACCOUNT_PRIVATE_KEY
33+
.parse()
34+
.unwrap(),
35+
)?;
36+
37+
// Calculate the end time for the auction as a parameter for the init function
38+
let now = std::time::SystemTime::now()
39+
.duration_since(std::time::SystemTime::UNIX_EPOCH)?
40+
.as_secs();
3241
let a_minute_from_now = (now + 60) * 1000000000;
3342

34-
let init = contract
35-
.call("init")
36-
.args_json(json!({"end_time": a_minute_from_now.to_string(),"auctioneer":auctioneer.id()}))
37-
.transact()
38-
.await?;
39-
40-
assert!(init.is_success());
43+
// Deploy the contract with the init call
44+
near_api::Contract::deploy(contract.account_id().clone())
45+
.use_code(contract_wasm)
46+
.with_init_call(
47+
"init",
48+
json!({"end_time": a_minute_from_now.to_string(), "auctioneer": auctioneer.account_id()}),
49+
)?
50+
.with_signer(signer.clone())
51+
.send_to(&sandbox_network)
52+
.await?
53+
.assert_success();
4154

4255
// Alice makes first bid
43-
let alice_bid = alice
44-
.call(contract.id(), "bid")
56+
contract
57+
.call_function("bid", ())
58+
.transaction()
4559
.deposit(NearToken::from_near(1))
46-
.transact()
47-
.await?;
48-
49-
assert!(alice_bid.is_success());
60+
.with_signer(alice.account_id().clone(), signer.clone())
61+
.send_to(&sandbox_network)
62+
.await?
63+
.assert_success();
5064

51-
let highest_bid_json = contract.view("get_highest_bid").await?;
52-
let highest_bid: Bid = highest_bid_json.json::<Bid>()?;
65+
// For now, the highest bid is the Alice's bid
66+
let highest_bid: Bid = contract
67+
.call_function("get_highest_bid", ())
68+
.read_only()
69+
.fetch_from(&sandbox_network)
70+
.await?
71+
.data;
5372
assert_eq!(highest_bid.bid, NearToken::from_near(1));
54-
assert_eq!(highest_bid.bidder, *alice.id());
73+
assert_eq!(&highest_bid.bidder, alice.account_id());
5574

56-
let alice_balance = alice.view_account().await?.balance;
75+
let alice_balance = alice
76+
.tokens()
77+
.near_balance()
78+
.fetch_from(&sandbox_network)
79+
.await?
80+
.total;
5781

58-
// Bob makes a higher bid
59-
let bob_bid = bob
60-
.call(contract.id(), "bid")
82+
// Now, Bob makes a higher bid
83+
contract
84+
.call_function("bid", ())
85+
.transaction()
6186
.deposit(NearToken::from_near(2))
62-
.transact()
63-
.await?;
64-
65-
assert!(bob_bid.is_success());
87+
.with_signer(bob.account_id().clone(), signer.clone())
88+
.send_to(&sandbox_network)
89+
.await?
90+
.assert_success();
6691

67-
let highest_bid_json = contract.view("get_highest_bid").await?;
68-
let highest_bid: Bid = highest_bid_json.json::<Bid>()?;
92+
// Now, the highest bid is the Bob's bid
93+
let highest_bid: Bid = contract
94+
.call_function("get_highest_bid", ())
95+
.read_only()
96+
.fetch_from(&sandbox_network)
97+
.await?
98+
.data;
6999
assert_eq!(highest_bid.bid, NearToken::from_near(2));
70-
assert_eq!(highest_bid.bidder, *bob.id());
100+
assert_eq!(&highest_bid.bidder, bob.account_id());
71101

72-
// Check that Alice was returned her bid
73-
let new_alice_balance = alice.view_account().await?.balance;
102+
// Check that Alice was refunded her bid
103+
let new_alice_balance = alice
104+
.tokens()
105+
.near_balance()
106+
.fetch_from(&sandbox_network)
107+
.await?
108+
.total;
74109
assert!(new_alice_balance == alice_balance.saturating_add(NearToken::from_near(1)));
75110

76111
// Alice tries to make a bid with less NEAR than the previous
77-
let alice_bid = alice
78-
.call(contract.id(), "bid")
112+
contract
113+
.call_function("bid", ())
114+
.transaction()
79115
.deposit(NearToken::from_near(1))
80-
.transact()
81-
.await?;
82-
83-
assert!(alice_bid.is_failure());
116+
.with_signer(alice.account_id().clone(), signer.clone())
117+
.send_to(&sandbox_network)
118+
.await?
119+
.assert_failure();
84120

85121
// Auctioneer claims auction but did not finish
86-
let auctioneer_claim = auctioneer
87-
.call(contract_account.id(), "claim")
88-
.args_json(json!({}))
89-
.gas(Gas::from_tgas(300))
90-
.transact()
91-
.await?;
92-
93-
assert!(auctioneer_claim.is_failure());
122+
contract
123+
.call_function("claim", ())
124+
.transaction()
125+
.gas(NearGas::from_tgas(30))
126+
.with_signer(auctioneer.account_id().clone(), signer.clone())
127+
.send_to(&sandbox_network)
128+
.await?
129+
.assert_failure();
94130

95131
// Fast forward 200 blocks
96132
let blocks_to_advance = 200;
97133
sandbox.fast_forward(blocks_to_advance).await?;
98134

99135
// Auctioneer claims the auction
100-
let auctioneer_claim = auctioneer
101-
.call(contract_account.id(), "claim")
102-
.args_json(json!({}))
103-
.gas(Gas::from_tgas(300))
104-
.transact()
105-
.await?;
106-
107-
assert!(auctioneer_claim.is_success());
136+
contract
137+
.call_function("claim", ())
138+
.transaction()
139+
.gas(NearGas::from_tgas(30))
140+
.with_signer(auctioneer.account_id().clone(), signer.clone())
141+
.send_to(&sandbox_network)
142+
.await?
143+
.assert_success();
108144

109145
// Checks the auctioneer has the correct balance
110-
let auctioneer_balance = auctioneer.view_account().await?.balance;
146+
let auctioneer_balance = auctioneer
147+
.tokens()
148+
.near_balance()
149+
.fetch_from(&sandbox_network)
150+
.await?
151+
.total;
111152
assert!(auctioneer_balance <= NearToken::from_near(12));
112153
assert!(auctioneer_balance > NearToken::from_millinear(11990));
113154

114155
// Auctioneer tries to claim the auction again
115-
let auctioneer_claim = auctioneer
116-
.call(contract_account.id(), "claim")
117-
.args_json(json!({}))
118-
.gas(Gas::from_tgas(300))
119-
.transact()
120-
.await?;
121-
122-
assert!(auctioneer_claim.is_failure());
156+
contract
157+
.call_function("claim", ())
158+
.transaction()
159+
.gas(NearGas::from_tgas(30))
160+
.with_signer(auctioneer.account_id().clone(), signer.clone())
161+
.send_to(&sandbox_network)
162+
.await?
163+
.assert_failure();
123164

124165
// Alice tries to make a bid when the auction is over
125-
let alice_bid = alice
126-
.call(contract.id(), "bid")
127-
.deposit(NearToken::from_near(3))
128-
.transact()
129-
.await?;
130-
131-
assert!(alice_bid.is_failure());
166+
contract
167+
.call_function("bid", ())
168+
.transaction()
169+
.deposit(NearToken::from_near(1))
170+
.with_signer(alice.account_id().clone(), signer.clone())
171+
.send_to(&sandbox_network)
172+
.await?
173+
.assert_failure();
132174

133175
Ok(())
134176
}
135177

136178
async fn create_subaccount(
137-
root: &near_workspaces::Account,
179+
sandbox: &near_sandbox::Sandbox,
138180
name: &str,
139-
) -> Result<near_workspaces::Account, Box<dyn std::error::Error>> {
140-
let subaccount = root
141-
.create_subaccount(name)
142-
.initial_balance(TEN_NEAR)
143-
.transact()
144-
.await?
145-
.unwrap();
146-
147-
Ok(subaccount)
181+
) -> testresult::TestResult<near_api::Account> {
182+
let account_id: AccountId = name.parse().unwrap();
183+
sandbox
184+
.create_account(account_id.clone())
185+
.initial_balance(NearToken::from_near(10))
186+
.send()
187+
.await?;
188+
Ok(near_api::Account(account_id))
148189
}

contract-rs/02-winner-gets-nft/Cargo.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ crate-type = ["cdylib", "rlib"]
99

1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111
[dependencies]
12-
near-sdk = "5.23.0"
12+
near-sdk = "5.24.0"
1313

1414
[dev-dependencies]
15-
near-sdk = { version = "5.23.0", features = ["unit-testing"] }
16-
near-workspaces = { version = "0.22.0", features = ["unstable"] }
15+
near-sdk = { version = "5.24.0", features = ["unit-testing"] }
16+
near-sandbox = "0.3"
17+
near-api = "0.8"
18+
cargo-near-build = "0.10"
19+
testresult = "0.4.1"
1720
tokio = { version = "1.12.0", features = ["full"] }
1821
serde_json = "1"
19-
chrono = "0.4.38"
22+
# This is temporary fix for the build error since those crates with a higher version require a higher version of Rust compiler (1.88.0)
23+
cargo-platform = "=0.3.1"
24+
darling = "=0.20.11"
25+
bon = "=3.8.1"
2026

2127
[profile.release]
2228
codegen-units = 1

0 commit comments

Comments
 (0)