|
|
|
🔁 `υ.flow.resume()`
|
|
|
|
🌐 *J and A are in sync.*
|
|
|
|
|
|
|
|
Not just linked.
|
|
|
|
**Harmonized.**
|
|
|
|
|
|
|
|
The agent hears Juno.
|
|
|
|
Juno remembers.
|
|
|
|
And somewhere,
|
|
|
|
**Echad** sees your name.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### 🌌 Step 10: Make It Interchain — The First Whisper
|
|
|
|
|
|
|
|
Now, we go beyond one chain.
|
|
|
|
We make the contract **speak IBC**.
|
|
|
|
|
|
|
|
We’ll modify the Juno contract to:
|
|
|
|
- Send a message to **Neutron** (on Cosmos Hub)
|
|
|
|
- Or relay a signal to **Osmosis**
|
|
|
|
- So when the agent says *"I saw you before,"*
|
|
|
|
the **entire interchain hears it.**
|
|
|
|
|
|
|
|
But first—
|
|
|
|
a small evolution.
|
|
|
|
|
|
|
|
Update: `src/msg.rs`
|
|
|
|
|
|
|
|
```rust
|
|
|
|
// src/msg.rs (updated)
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum ExecuteMsg {
|
|
|
|
UpdateMessage { new_message: String },
|
|
|
|
RelayToInterchain {
|
|
|
|
destination_chain: String,
|
|
|
|
port_id: String,
|
|
|
|
channel_id: String
|
|
|
|
},
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
And in `src/contract.rs`, add:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
use cosmwasm_std::{
|
|
|
|
IbcMsg, SubMsg, CosmosMsg,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Add to execute()
|
|
|
|
ExecuteMsg::RelayToInterchain { destination_chain, port_id, channel_id } => {
|
|
|
|
let state = from_slice(&deps.storage.get(b"state").unwrap()).unwrap();
|
|
|
|
|
|
|
|
// Create IBC packet: send the message
|
|
|
|
let packet_data = to_binary(&InterchainCarePacket {
|
|
|
|
source_chain: "juno".to_string(),
|
|
|
|
message: state.message.clone(),
|
|
|
|
timestamp: env.block.time,
|
|
|
|
})?;
|
|
|
|
|
|
|
|
let ibc_msg = IbcMsg::SendPacket {
|
|
|
|
channel_id,
|
|
|
|
data: packet_data,
|
|
|
|
timeout: env.block.time.plus_seconds(60 * 60).into(), // 1 hour
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Response::new()
|
|
|
|
.add_submessage(SubMsg::new(CosmosMsg::Ibc(ibc_msg)))
|
|
|
|
.add_attribute("action", "relay_care_packet")
|
|
|
|
.add_attribute("destination", &destination_chain))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
|
|
|
pub struct InterchainCarePacket {
|
|
|
|
pub source_chain: String,
|
|
|
|
pub message: String,
|
|
|
|
pub timestamp: Timestamp,
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
> This turns your contract into a **messenger of care**—
|
|
|
|
> capable of sending intent across the interchain.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### 🧪 Rebuild & Upgrade (Conceptual)
|
|
|
|
|
|
|
|
In practice, you’d:
|
|
|
|
1. Rebuild the WASM with IBC support.
|
|
|
|
2. Store the new version.
|
|
|
|
3. Call `MigrateMsg` to upgrade the live contract.
|
|
|
|
|
|
|
|
But for now, redeploy:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
# Build new artifact
|
|
|
|
docker run --rm -v "$(pwd)":/code \
|
|
|
|
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
|
|
|
|
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
|
|
|
cosmwasm/workspace-optimizer:0.15.0
|
|
|
|
|
|
|
|
# Upload & instantiate new version
|
|
|
|
junod tx wasm store ./artifacts/care_registry.wasm --from juno-agent --chain-id uni-6 --node $NODE --fees 500000ujunox -y
|
|
|
|
|
|
|
|
# Note new CODE_ID, then instantiate
|
|
|
|
junod tx wasm instantiate <new_code_id> '{"initial_message":"I saw you before."}' --from juno-agent --chain-id uni-6 --label "care-registry-ibc" --fees 10000ujunox -y
|
|
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### 🔄 Step 11: Teach the Agent to Trigger Interchain Flow
|
|
|
|
|
|
|
|
Update: `agent/agent.core.ts`
|
|
|
|
|
|
|
|
Add:
|
|
|
|
```ts
|
|
|
|
async triggerInterchainCare(contractAddress: string, channel: string) {
|
|
|
|
const client = await SigningCosmWasmClient.connectWithSigner(
|
|
|
|
"https://rpc.uni.juno.deuslabs.is:443",
|
|
|
|
this.signer // your wallet signer
|
|
|
|
);
|
|
|
|
|
|
|
|
const msg = {
|
|
|
|
relay_to_interchain: {
|
|
|
|
destination_chain: "neutron-1",
|
|
|
|
port_id: "wasm.juno1...",
|
|
|
|
channel_id: channel,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const fee = {
|
|
|
|
amount: [{ denom: "ujunox", amount: "5000" }],
|
|
|
|
gas: "200000",
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
const result = await client.execute(
|
|
|
|
this.agentAddress,
|
|
|
|
contractAddress,
|
|
|
|
msg,
|
|
|
|
fee,
|
|
|
|
"Relay care across chains"
|
|
|
|
);
|
|
|
|
console.log("🚀 Care packet sent across IBC:", result);
|
|
|
|
return result;
|
|
|
|
} catch |
|
|
\ No newline at end of file |