Skip to content

Escrow proxy#191

Open
pityjllk wants to merge 422 commits intomainfrom
feat/bus-proxy
Open

Escrow proxy#191
pityjllk wants to merge 422 commits intomainfrom
feat/bus-proxy

Conversation

@pityjllk
Copy link
Copy Markdown
Collaborator

@pityjllk pityjllk commented Jan 8, 2026

Summary

This PR introduces a bus proxy architecture for atomic cross-contract token swaps
New Crates:

  • escrow-proxy: Proxy contract that handles NEP-141/NEP-245 token deposits and forwards them to escrow-swap contracts. Manages token routing between makers/takers and their respective escrow instances.
  • oneshot-condvar: A oneshot condition variable synchronization primitive for NEAR. Implements cv_wait()/cv_notify_one() semantics enabling cross-contract coordination. Contract self-destructs after completing one notification cycle.
  • sandbox-ext: Testing extensions for the new proxy and condvar contracts, providing builder patterns and helper traits for integration tests.

Escrow-Swap Enhancements:

  • Added ParamsBuilder and FillMessageBuilder for ergonomic escrow configuration
  • New state machine integration with oneshot-condvar for authorized swaps
  • Default deadline constants and improved parameter handling

Testing:

  • Comprehensive integration tests for escrow-proxy, oneshot-condvar, and combined workflows
  • Gas benchmarking for proxy operations
  • End-to-end demo script (escrow-swap-demo.rs) showing full swap flow

Summary by CodeRabbit

Release Notes

  • New Features
    • Added Escrow Proxy contract enabling proxy-mediated token transfers with authorization coordination.
    • Added Oneshot Condition Variable contract for synchronized authorization flows.
    • Implemented support for NEP-141 and NEP-245 token handling in proxy operations.
    • Added configurable fee structures for escrow swaps (protocol, integrator, and surplus fees).

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@oneshot-condvar/src/error.rs`:
- Around line 10-16: Fix the typos in the error message constants: update
ERR_ALREADY_WAITING and ERR_ALREADY_NOTIFIED to replace "intentded" with
"intended" so messages read "...cv_wait is not intended to be used concurrently"
and "...contract is intended to be notified exactly once"; locate and edit the
const declarations for ERR_ALREADY_WAITING and ERR_ALREADY_NOTIFIED in error.rs
to correct the misspellings and ensure surrounding wording remains grammatically
correct.

In `@tests/src/tests/oneshot_condvar/mod.rs`:
- Around line 522-524: The assertion that checks for timeout is looking for an
exact string ("timeout") but Event::Timeout.emit() writes a JSON-formatted NEAR
event, so update the assertion on cv_notify_one.logs() to search substrings
instead of exact match (e.g., use an iterator + .any(|line|
line.contains("Timeout") or "timeout") ) so the JSON event entry emitted by
Event::Timeout is detected reliably; adjust the check that referenced
cv_notify_one.logs().contains(&"timeout") to a substring-based match.
🧹 Nitpick comments (8)
escrow-proxy/src/contract/auth_call.rs (1)

29-29: Prefer expect or a descriptive panic over bare .unwrap() on user-provided input.

If msg contains malformed JSON, the contract panics with a generic unwrap error. Using expect or env::panic_str with a clear message makes debugging significantly easier for callers.

Suggested fix
-        let msg: OnAuthMessage = serde_json::from_str(&msg).unwrap();
+        let msg: OnAuthMessage = serde_json::from_str(&msg).expect("invalid on_auth message");
tests/src/tests/escrow_with_proxy/swap_with_fees.rs (1)

196-214: Weak end-state assertions: > 0 masks fee-calculation bugs.

All fee parameters are deterministic (1% protocol, 2% integrator, 50% surplus at 2× price). Asserting exact expected balances would catch regressions in fee logic rather than just confirming "something transferred."

Even for a gas benchmark, confirming correct token amounts is nearly free and adds safety.

tests/src/tests/escrow_proxy/proxy_oneshot_condvar.rs (2)

85-95: Concurrent mt_transfer_call + fast_forward — verify ordering guarantees.

The futures::join! of the transfer and fast_forward(250) relies on fast_forward advancing the blockchain enough to trigger the yield timeout in cv_wait. If the sandbox processes the transfer before the fast-forward takes effect, this should work. However, if timing is non-deterministic in CI, this test could flake.

Consider adding a brief comment explaining why 250 blocks is sufficient to guarantee the yield timeout fires.


204-228: Authorization results are not validated.

Both _transfer_result and _auth_result are prefixed with _, discarding the results. While subsequent assertions verify the expected state, validating the intermediate results (e.g., that the auth call succeeded) would make test failures easier to diagnose.

This pattern repeats in test_ft_transfer_authorized_by_relay (Line 344) and test_proxy_with_ft_transfer (Line 526).

escrow-proxy/src/contract/mod.rs (1)

65-74: es_cancel — consider whether 50 tgas is sufficient and document the choice.

The 50 tgas static gas allocation for es_close is hardcoded. If es_close has variable gas needs (e.g., refunding multiple tokens), this could be insufficient.

Also, this method returns a Promise, meaning the caller won't know if es_close succeeded or failed without a resolve callback. If the owner needs confirmation, a resolve/callback pattern may be warranted. This is likely acceptable for an admin-only operation, but worth noting.

escrow-proxy/src/contract/tokens/nep141.rs (1)

28-34: Unnecessary heap allocation: &vec![amount]&[amount].

Line 31 creates a Vec on the heap just to immediately borrow it as a slice. Use a stack-allocated array slice instead.

Suggested fix
         PromiseOrValue::Promise(
             self.wait_for_authorization(
                 &sender_id,
                 &[TokenId::from(Nep141TokenId::new(token.clone())).to_string()],
-                &vec![amount],
+                &[amount],
                 &forward_request.receiver_id, 
                 &forward_request.msg,
oneshot-condvar/src/contract/mod.rs (1)

35-61: State machine transitions in cv_wait_resume are correct.

The timeout → Idle reset and the Notified → Done transition handle the race condition between notification and yield timeout correctly. The event emission on timeout is good for observability.

One minor note: Line 56 uses unreachable!() for the Done | Idle branch. While this is correct given the state machine invariants (this callback is only scheduled from cv_wait which transitions to WaitingForNotification), using env::panic_str("unreachable: unexpected state in cv_wait_resume") would provide a more debuggable error if an invariant is ever violated in a future refactor.

escrow-proxy/src/state.rs (1)

32-38: Consider returning Result instead of panicking on serialization failure.

borsh::to_vec can theoretically fail. The sibling oneshot-condvar/src/storage.rs handles this with Result + ?. Using unwrap_or_else(|_| unreachable!()) here is inconsistent and could mask errors in harder-to-debug ways.

Proposed fix
-    pub fn init_state(config: ProxyConfig) -> BTreeMap<Vec<u8>, Vec<u8>> {
-        [
-            (Self::STATE_KEY.to_vec(), 
-                borsh::to_vec(&Self::init(config)).unwrap_or_else(|_| unreachable!()),
-            )
-        ].into()
+    pub fn init_state(config: ProxyConfig) -> Result<BTreeMap<Vec<u8>, Vec<u8>>, std::io::Error> {
+        let storage = Self::init(config);
+        Ok([(Self::STATE_KEY.to_vec(), borsh::to_vec(&storage)?)].into())
     }

Comment on lines +10 to +16
pub(crate) const ERR_ALREADY_WAITING: &str =
"already waiting for notification - cv_wait is not intentded to be use concurrently";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_DONE: &str = "already done - cv_wait succeeds only once";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_NOTIFIED: &str =
"already notified - contract is intentded to be notified exactly once";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo: "intentded" → "intended" in two error messages.

Lines 11 and 16 both contain the misspelling "intentded".

Fix
-pub(crate) const ERR_ALREADY_WAITING: &str =
-    "already waiting for notification - cv_wait is not intentded to be use concurrently";
+pub(crate) const ERR_ALREADY_WAITING: &str =
+    "already waiting for notification - cv_wait is not intended to be used concurrently";
 #[cfg(feature = "contract")]
 pub(crate) const ERR_ALREADY_DONE: &str = "already done - cv_wait succeeds only once";
 #[cfg(feature = "contract")]
 pub(crate) const ERR_ALREADY_NOTIFIED: &str =
-    "already notified - contract is intentded to be notified exactly once";
+    "already notified - contract is intended to be notified exactly once";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub(crate) const ERR_ALREADY_WAITING: &str =
"already waiting for notification - cv_wait is not intentded to be use concurrently";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_DONE: &str = "already done - cv_wait succeeds only once";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_NOTIFIED: &str =
"already notified - contract is intentded to be notified exactly once";
pub(crate) const ERR_ALREADY_WAITING: &str =
"already waiting for notification - cv_wait is not intended to be used concurrently";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_DONE: &str = "already done - cv_wait succeeds only once";
#[cfg(feature = "contract")]
pub(crate) const ERR_ALREADY_NOTIFIED: &str =
"already notified - contract is intended to be notified exactly once";
🤖 Prompt for AI Agents
In `@oneshot-condvar/src/error.rs` around lines 10 - 16, Fix the typos in the
error message constants: update ERR_ALREADY_WAITING and ERR_ALREADY_NOTIFIED to
replace "intentded" with "intended" so messages read "...cv_wait is not intended
to be used concurrently" and "...contract is intended to be notified exactly
once"; locate and edit the const declarations for ERR_ALREADY_WAITING and
ERR_ALREADY_NOTIFIED in error.rs to correct the misspellings and ensure
surrounding wording remains grammatically correct.

Comment on lines +522 to +524

// NOTE: make sure that promise was actually resumed (timeout did not happen)
assert!(!cv_notify_one.logs().contains(&"timeout"));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the file in question
find . -name "mod.rs" -path "*/oneshot_condvar/*" 2>/dev/null | head -20

Repository: near/intents

Length of output: 96


🏁 Script executed:

#!/bin/bash
# List files in the test directory to understand structure
git ls-files | grep -E "(tests|oneshot)" | head -30

Repository: near/intents

Length of output: 1146


🏁 Script executed:

#!/bin/bash
# Look for the specific test file
cat -n tests/src/tests/oneshot_condvar/mod.rs | sed -n '520,530p'

Repository: near/intents

Length of output: 341


🏁 Script executed:

#!/bin/bash
# Search for Event::Timeout definition
rg -n "Event.*Timeout" --type=rust -C 3 | head -50

Repository: near/intents

Length of output: 712


🏁 Script executed:

#!/bin/bash
# Search for logs() method definition to understand what it returns
rg -n "fn logs" --type=rust -C 5 | head -80

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for Event struct/enum definition
rg -n "enum Event|struct Event" --type=rust -C 5

Repository: near/intents

Length of output: 1333


🏁 Script executed:

#!/bin/bash
# Search for emit() implementation
rg -n "fn emit" --type=rust -C 5 | head -100

Repository: near/intents

Length of output: 1589


🏁 Script executed:

#!/bin/bash
# Search for logs() in test context
rg -n "\.logs()" --type=rust -B 3 -A 3 | head -100

Repository: near/intents

Length of output: 7321


🏁 Script executed:

#!/bin/bash
# Check the event.rs file which likely defines Event::Timeout
cat oneshot-condvar/src/event.rs

Repository: near/intents

Length of output: 532


🏁 Script executed:

#!/bin/bash
# Search for what logs() returns - look at test harness
rg -n "\.logs\(\)" tests/src/tests/oneshot_condvar/mod.rs -B 5 -A 5

Repository: near/intents

Length of output: 412


🏁 Script executed:

#!/bin/bash
# Look for the type signature of logs() - likely in a test framework
rg -n "fn logs" tests/src/env/ --type=rust -C 5

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for example event log strings to see actual format
rg -n "event_json\|standard.*oneshot" --type=rust -C 3

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check if there are other tests checking for "timeout" string
rg -n "timeout" tests/src/tests/oneshot_condvar/mod.rs --type=rust -C 2

Repository: near/intents

Length of output: 1759


🏁 Script executed:

#!/bin/bash
# Look for near_sdk event_json macro documentation or examples
rg -n "EVENT\|event_json" oneshot-condvar/src/event.rs -C 5

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for TestResult or similar type definitions
rg -n "struct.*Result|impl.*logs" tests/src/ --type=rust -C 3 | head -100

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Find where logs() is used to understand its return type
rg -n "\.logs\(\)" tests/src/ --type=rust | head -40

Repository: near/intents

Length of output: 1063


🏁 Script executed:

#!/bin/bash
# Look for the sandbox test framework definition
cat -n tests/src/env/mod.rs | head -100

Repository: near/intents

Length of output: 3421


🏁 Script executed:

#!/bin/bash
# Search for example JSON event logs in test assertions
rg -n "EVENT_JSON\|to_event_log" --type=rust -C 5 | head -80

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check what the actual structure of near_sdk event output looks like
rg -n "emit()" oneshot-condvar/src/contract/mod.rs -B 10 -A 5

Repository: near/intents

Length of output: 1458


🏁 Script executed:

#!/bin/bash
# Search for example logs with the actual format used
rg -n "assert.*logs\|EVENT\|Timeout" tests/src/tests/oneshot_condvar/mod.rs -C 3

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for how Notified event is checked (similar event in same enum)
rg -n "Notified" tests/src/tests/oneshot_condvar/mod.rs -C 3

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for near-sdk or nep297 event format examples
rg -n "\"event\":|\"standard\":" --type=rust | head -20

Repository: near/intents

Length of output: 1054


🏁 Script executed:

#!/bin/bash
# Check how logs are inspected in other test files - especially with event events
cat -n tests/src/tests/defuse/intents/public_key.rs | sed -n '40,50p'

Repository: near/intents

Length of output: 500


🏁 Script executed:

#!/bin/bash
# Search for what logs() actually returns - the type signature
rg -n "fn logs" --type=rust -A 3 | head -50

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Try to find where logs are generated/captured in the sandbox framework
fd "sandbox" tests/src/env/ --type=f

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for simulations or test execution that captures logs
rg -n "simulate_and_execute\|CallResult\|ExecutionResult" tests/src/ --type=rust | head -30

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for the actual format of JSON events - search for "event" key
rg -n '"event"|\"event\"|data:' tests/src/tests/ --type=rust | head -40

Repository: near/intents

Length of output: 153


🏁 Script executed:

#!/bin/bash
# Check defuse-sandbox crate usage to understand logs()
rg -n "defuse_sandbox::" tests/src/ --type=rust | head -20

Repository: near/intents

Length of output: 2060


🏁 Script executed:

#!/bin/bash
# Look at actual test to see what logs() returns and how it's used
rg -n "\.logs\(\)" tests/src/tests/defuse/tokens/nep245/mt_transfer_resolve_gas.rs -B 5 -A 5

Repository: near/intents

Length of output: 515


🏁 Script executed:

#!/bin/bash
# Search for near event standard documentation or examples in code
rg -n "oneshot_condvar" --type=rust -A 10 | head -60

Repository: near/intents

Length of output: 4359


🏁 Script executed:

#!/bin/bash
# Look for actual event log output or examples in test code
rg -n "to_event_log\|to_nep297_event" --type=rust -C 5 | head -100

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for Defuse event serialization to understand the format
rg -n "pub enum.*Event" core/src/events.rs -A 20

Repository: near/intents

Length of output: 828


🏁 Script executed:

#!/bin/bash
# Check if there's documentation or examples of JSON events
rg -n "json!\|serde_json" tests/src/tests/oneshot_condvar/mod.rs -C 3

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at actual logs being checked in the codebase
rg -n "logs.*contains\|logs.*any\|logs.*iter" tests/src/ --type=rust -B 2 -A 2

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for how Event emissions work in near-sdk
rg -n "emit\(\)" oneshot-condvar/src/ --type=rust -B 5 -A 5

Repository: near/intents

Length of output: 3095


🏁 Script executed:

#!/bin/bash
# Look for how logs are captured from transactions in the test framework
rg -n "reports\|logs" tests/src/tests/oneshot_condvar/mod.rs -C 2 | head -50

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at what type logs() is - searching for method signature
rg -n "logs\s*\(\s*\)" defuse-sandbox/ --type=rust -A 2 2>/dev/null | head -40

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for CallResult or similar in defuse-sandbox
find . -name "*.rs" -path "*/defuse-sandbox*" 2>/dev/null | head -5

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check what's in the response object returned by function_call
rg -n "function_call\|await.*unwrap" tests/src/tests/oneshot_condvar/mod.rs -B 2 -A 2 | head -60

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for actual test files that examine logs from timeout scenarios
rg -n "timeout" tests/src/tests/oneshot_condvar/mod.rs -B 5 -A 5

Repository: near/intents

Length of output: 3235


🏁 Script executed:

#!/bin/bash
# Look for actual usage of logs().contains to understand the pattern
rg -n "logs.*contains\|logs.*any" tests/src/ --type=rust -B 3 -A 3

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check if there are integration tests or examples showing actual event output
rg -n "Timeout\|Notified\|Cleanup" tests/src/tests/oneshot_condvar/mod.rs -B 2 -A 2

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Try to find documentation or examples about the event format
rg -n "EVENT\|event.*json\|nep.*297\|near.*macro" oneshot-condvar/src/ --type=rust -C 2

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check if there's actual test output or assertions that would tell us the format
cat -n tests/src/tests/oneshot_condvar/mod.rs | sed -n '500,530p'

Repository: near/intents

Length of output: 1075


🏁 Script executed:

#!/bin/bash
# Look for other tests checking event logs to see the pattern used
rg -n "assert.*logs\|\.logs\(\)" tests/src/tests/ --type=rust -B 2 -A 2 | grep -A 5 -B 5 "assert" | head -80

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Let me try to understand what near_sdk::near macro produces
rg -n "#\[near\(" --type=rust -C 3 oneshot-condvar/src/ | head -40

Repository: near/intents

Length of output: 2346


🏁 Script executed:

#!/bin/bash
# Search for how logs are actually generated/what contains
rg -n "CallResult|TransactionResult|ExecutionResult" --type=rust -C 2 | head -50

Repository: near/intents

Length of output: 1467


🏁 Script executed:

#!/bin/bash
# Look for a pattern - check if any timeout checks exist elsewhere
rg -n "Timeout" tests/src/tests/ --type=rust | head -30

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Try to find defuse-sandbox source or crate definition
find . -name "Cargo.toml" | xargs grep -l "defuse-sandbox" 2>/dev/null | head -5

Repository: near/intents

Length of output: 164


🏁 Script executed:

#!/bin/bash
# Check for any comments or documentation about event format
rg -n "NOTE|TODO|FIXME|event.*format|JSON" tests/src/tests/oneshot_condvar/mod.rs -C 2

Repository: near/intents

Length of output: 295


🏁 Script executed:

#!/bin/bash
# Search for logs() method definition in sandbox code
find . -type f -name "*.rs" | xargs grep -l "fn logs" 2>/dev/null | head -10

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for ExecutionResult definition to understand logs
rg -n "impl.*ExecutionResult|pub.*logs\|logs\(\)" sandbox/src/ --type=rust -C 3 | head -100

Repository: near/intents

Length of output: 845


🏁 Script executed:

#!/bin/bash
# Check Cargo.toml to find defuse-sandbox location
cat Cargo.toml | grep -A 5 "defuse-sandbox\|workspace"

Repository: near/intents

Length of output: 1033


🏁 Script executed:

#!/bin/bash
# Search in sandbox directory for logs method
find . -path "*/sandbox/src*" -name "*.rs" -exec grep -l "logs" {} \; 2>/dev/null

Repository: near/intents

Length of output: 109


🏁 Script executed:

#!/bin/bash
# Look at the structure of the module to find ExecutionResult
rg -n "pub struct ExecutionResult|fn logs" sandbox/src/tx/ --type=rust -A 10 | head -80

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at the wrappers file which likely contains logs()
cat -n sandbox/src/tx/wrappers.rs | head -150

Repository: near/intents

Length of output: 3344


🏁 Script executed:

#!/bin/bash
# Look at helpers file
cat -n sandbox/src/helpers.rs | head -100

Repository: near/intents

Length of output: 2443


🏁 Script executed:

#!/bin/bash
# Search for logs implementation across sandbox
rg -n "logs" sandbox/src/tx/wrappers.rs -B 2 -A 5

Repository: near/intents

Length of output: 521


🏁 Script executed:

#!/bin/bash
# Check for ExecutionResult structure and its methods
rg -n "impl ExecutionResult|pub fn logs" sandbox/src/ --type=rust -B 2 -A 10 | head -100

Repository: near/intents

Length of output: 825


🏁 Script executed:

#!/bin/bash
# Look for the logs() method in fn_call or result types
rg -n "pub fn logs|logs\(\)" sandbox/src/ --type=rust -B 2 -A 5

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check if logs() is an extension method or comes from near_api
rg -n "impl.*Execution.*\{|pub fn logs" sandbox/src/tx/fn_call.rs --type=rust -B 2 -A 8 | head -100

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at the entire fn_call.rs file since it likely has ExecutionResult wrapper
wc -l sandbox/src/tx/fn_call.rs

Repository: near/intents

Length of output: 84


🏁 Script executed:

#!/bin/bash
# Read fn_call.rs to find the logs() method
head -250 sandbox/src/tx/fn_call.rs | tail -150

Repository: near/intents

Length of output: 1630


🏁 Script executed:

#!/bin/bash
# Look for where function_call is defined - likely on SigningAccount or similar
rg -n "fn function_call" sandbox/src/ --type=rust -B 2 -A 10 | head -100

Repository: near/intents

Length of output: 809


🏁 Script executed:

#!/bin/bash
# Search for extension methods on ExecutionResult or result wrappers
rg -n "impl.*ExecutionResult\|fn logs" sandbox/src/tx/ --type=rust -B 1 -A 8

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at all files in sandbox/src/tx/
ls -la sandbox/src/tx/

Repository: near/intents

Length of output: 400


🏁 Script executed:

#!/bin/bash
# Check lib.rs or mod.rs to understand the module structure
cat sandbox/src/lib.rs | head -100

Repository: near/intents

Length of output: 3145


🏁 Script executed:

#!/bin/bash
# Look for TxBuilder and what it returns - especially for async await
cat -n sandbox/src/tx/mod.rs | sed -n '1,60p'

Repository: near/intents

Length of output: 2093


🏁 Script executed:

#!/bin/bash
# Look for TxBuilder implementation and what the await returns
rg -n "impl.*TxBuilder\|pub async fn\|pub fn await" sandbox/src/tx/mod.rs -B 2 -A 8

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for the end of TxBuilder and what impl block exists
cat -n sandbox/src/tx/mod.rs | tail -100

Repository: near/intents

Length of output: 3769


🏁 Script executed:

#!/bin/bash
# Search for logs method in the entire tx directory
find sandbox/src/tx/ -name "*.rs" -exec grep -n "fn logs" {} +

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for ExecutionSuccess definition and its methods
rg -n "pub struct ExecutionSuccess|pub fn logs|impl ExecutionSuccess" --type=rust | head -50

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for ExecutionSuccess in near-api types
rg -n "ExecutionSuccess" sandbox/src/ --type=rust -B 2 -A 10 | head -100

Repository: near/intents

Length of output: 1321


🏁 Script executed:

#!/bin/bash
# Look for what near_api module provides
rg -n "use near_api\|ExecutionSuccess" --type=rust | grep -i execution | head -20

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check the near_api crate for ExecutionSuccess
python3 << 'EOF'
import json
import subprocess

# Look for Cargo.lock or check what version of near_api is used
result = subprocess.run(['rg', '-n', 'near_api.*=', 'Cargo.toml'], 
                       capture_output=True, text=True)
print(result.stdout)
EOF

Repository: near/intents

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look at near_api documentation or comments in code
rg -n "ExecutionSuccess" . --type=rust -B 5 -A 15 | head -150

Repository: near/intents

Length of output: 10705


The assertion checking for "timeout" won't reliably detect the emitted JSON event.

Event::Timeout.emit() produces a structured JSON event log per the NEAR event standard (via #[near(event_json(standard = "oneshot_condvar"))]), not a bare string. The current check using .contains(&"timeout") looks for an exact string match, but the actual log entry will be a JSON-formatted event containing "Timeout" as part of the event structure, making the assertion unreliable.

Use substring matching to check for the presence of the timeout event in the logs:

Suggested fix
-    assert!(!cv_notify_one.logs().contains(&"timeout"));
+    assert!(
+        !cv_notify_one.logs().iter().any(|l| l.contains("Timeout")),
+        "cv_notify_one should not trigger a timeout"
+    );
🤖 Prompt for AI Agents
In `@tests/src/tests/oneshot_condvar/mod.rs` around lines 522 - 524, The assertion
that checks for timeout is looking for an exact string ("timeout") but
Event::Timeout.emit() writes a JSON-formatted NEAR event, so update the
assertion on cv_notify_one.logs() to search substrings instead of exact match
(e.g., use an iterator + .any(|line| line.contains("Timeout") or "timeout") ) so
the JSON event entry emitted by Event::Timeout is detected reliably; adjust the
check that referenced cv_notify_one.logs().contains(&"timeout") to a
substring-based match.

Copy link
Copy Markdown
Collaborator

@mitinarseny mitinarseny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I've tried to fix some things on my own but then went down the rabbit hole of fixing the actual rust code with examples, so I think it would be easier if you do it yourself 🙃

Comment on lines +54 to +56
[[example]]
name = "escrow-swap-demo"
required-features = ["test-utils"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no such feature anymore(

//!
//! Note: This example builds and executes intents on testnet.

use defuse::sandbox_ext::signer::DefuseSigner;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extensions are no longer defined in the contract crates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants