@agoric/orchestration 0.1.1-dev-e26d66b.0 → 0.1.1-dev-9b9282d.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @file Implements the orchestration flow which does the following:
3
+ *
4
+ * - Creates an EVM account on the target chain.
5
+ * - Sets up and monitors the Local Chain Account (LCA).
6
+ * - Coordinates IBC-related logic through `createAndMonitorLCA()`.
7
+ *
8
+ * For more details, see: docs/axelar-gmp/create-and-use-wallet.mmd in
9
+ * orchestration package.
10
+ */
11
+
12
+ import { Fail, makeError, q } from '@endo/errors';
13
+ import { makeTracer, NonNullish } from '@agoric/internal';
14
+ import { denomHash } from '../utils/denomHash.js';
15
+ import { gmpAddresses } from '../utils/gmp.js';
16
+ import { AxelarGMPMessageType } from '../axelar-types.js';
17
+
18
+ /**
19
+ * @import {GuestInterface, GuestOf} from '@agoric/async-flow';
20
+ * @import {Orchestrator, OrchestrationFlow} from '@agoric/orchestration';
21
+ * @import {MakeEvmAccountKit} from './axelar-gmp-account-kit.js';
22
+ * @import {ChainHub} from '@agoric/orchestration/src/exos/chain-hub.js';
23
+ * @import {Vow} from '@agoric/vow';
24
+ * @import {ZCFSeat, AmountKeywordRecord} from '@agoric/zoe';
25
+ * @import {LocalAccountMethods} from '@agoric/orchestration';
26
+ * @import {AxelarGmpOutgoingMemo} from '../axelar-types.js'
27
+ */
28
+
29
+ const trace = makeTracer('EvmFlow');
30
+
31
+ /**
32
+ * @satisfies {OrchestrationFlow}
33
+ * @param {Orchestrator} orch
34
+ * @param {{
35
+ * makeEvmAccountKit: MakeEvmAccountKit;
36
+ * chainHub: GuestInterface<ChainHub>;
37
+ * log: GuestOf<(msg: string) => Vow<void>>;
38
+ * localTransfer: GuestOf<
39
+ * (
40
+ * srcSeat: ZCFSeat,
41
+ * localAccount: LocalAccountMethods,
42
+ * amounts: AmountKeywordRecord,
43
+ * ) => Vow<void>
44
+ * >;
45
+ * withdrawToSeat: GuestOf<
46
+ * (
47
+ * localAccount: LocalAccountMethods,
48
+ * destSeat: ZCFSeat,
49
+ * amounts: AmountKeywordRecord,
50
+ * ) => Vow<void>
51
+ * >;
52
+ * }} ctx
53
+ * @param {ZCFSeat} seat
54
+ */
55
+ export const createAndMonitorLCA = async (
56
+ orch,
57
+ { makeEvmAccountKit, chainHub, log, localTransfer, withdrawToSeat },
58
+ seat,
59
+ ) => {
60
+ void log('Inside createAndMonitorLCA');
61
+ const [agoric, remoteChain] = await Promise.all([
62
+ orch.getChain('agoric'),
63
+ orch.getChain('axelar'),
64
+ ]);
65
+ const { chainId, stakingTokens } = await remoteChain.getChainInfo();
66
+ const remoteDenom = stakingTokens[0].denom;
67
+ remoteDenom || Fail`${chainId} does not have stakingTokens in config`;
68
+
69
+ const localAccount = await agoric.makeAccount();
70
+ void log('localAccount created successfully');
71
+ const localChainAddress = await localAccount.getAddress();
72
+ trace('Local Chain Address:', localChainAddress);
73
+
74
+ const agoricChainId = (await agoric.getChainInfo()).chainId;
75
+ const { transferChannel } = await chainHub.getConnectionInfo(
76
+ agoricChainId,
77
+ chainId,
78
+ );
79
+ assert(transferChannel.counterPartyChannelId, 'unable to find sourceChannel');
80
+
81
+ const localDenom = `ibc/${denomHash({
82
+ denom: remoteDenom,
83
+ channelId: transferChannel.channelId,
84
+ })}`;
85
+
86
+ const assets = await agoric.getVBankAssetInfo();
87
+ const info = await remoteChain.getChainInfo();
88
+ const evmAccountKit = makeEvmAccountKit({
89
+ localAccount,
90
+ localChainAddress,
91
+ sourceChannel: transferChannel.counterPartyChannelId,
92
+ localDenom,
93
+ assets,
94
+ remoteChainInfo: info,
95
+ });
96
+ void log('tap created successfully');
97
+ // XXX consider storing appRegistration, so we can .revoke() or .updateTargetApp()
98
+ // @ts-expect-error tap.receiveUpcall: 'Vow<void> | undefined' not assignable to 'Promise<any>'
99
+ await localAccount.monitorTransfers(evmAccountKit.tap);
100
+ void log('Monitoring transfers setup successfully');
101
+
102
+ const { give } = seat.getProposal();
103
+ const [[_kw, amt]] = Object.entries(give);
104
+
105
+ const { denom } = NonNullish(
106
+ assets.find(a => a.brand === amt.brand),
107
+ `${amt.brand} not registered in vbank`,
108
+ );
109
+
110
+ await localTransfer(seat, localAccount, give);
111
+
112
+ // Factory contract address when using local dev environment
113
+ // TODO: pass it via terms?
114
+ const factoryContractAddress = '0xef8651dD30cF990A1e831224f2E0996023163A81';
115
+
116
+ /** @type {AxelarGmpOutgoingMemo} */
117
+ const memo = {
118
+ destination_chain: 'Ethereum',
119
+ destination_address: factoryContractAddress,
120
+ payload: [],
121
+ type: AxelarGMPMessageType.ContractCall,
122
+ fee: {
123
+ amount: '1', // TODO: Get fee amount from api
124
+ recipient: gmpAddresses.AXELAR_GAS,
125
+ },
126
+ };
127
+
128
+ try {
129
+ void log('Initiating IBC transfer');
130
+ await localAccount.transfer(
131
+ {
132
+ value: gmpAddresses.AXELAR_GMP,
133
+ encoding: 'bech32',
134
+ chainId,
135
+ },
136
+ {
137
+ denom,
138
+ value: amt.value,
139
+ },
140
+ { memo: JSON.stringify(memo) },
141
+ );
142
+
143
+ void log('Done');
144
+ } catch (e) {
145
+ await withdrawToSeat(localAccount, seat, give);
146
+ const errorMsg = `IBC Transfer failed ${q(e)}`;
147
+ seat.exit(errorMsg);
148
+ throw makeError(errorMsg);
149
+ }
150
+
151
+ seat.exit();
152
+ // TODO: When used from the portfolio contract, expose the `holder` facet directly
153
+ // to bypass Zoe and walletFactory, since smart wallet constraints don't apply there.
154
+ return harden({ invitationMakers: evmAccountKit.invitationMakers });
155
+ };
156
+ harden(createAndMonitorLCA);
@@ -11,7 +11,7 @@ export function prepareOrchestrator(zone: Zone, powers: {
11
11
  vowTools: VowTools;
12
12
  }): () => import("@endo/exo").Guarded<{
13
13
  getChain(chainName: string): Vow<HostInterface<Chain<any> & object>>;
14
- getDenomInfo(denom: string, srcChainName: "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon"): HostInterface<import("../orchestration-api.js").DenomInfo<"agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon", "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon">>;
14
+ getDenomInfo(denom: string, srcChainName: "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon"): HostInterface<import("../orchestration-api.js").DenomInfo<"agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon", "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon">>;
15
15
  /** @type {HostOf<Orchestrator['asAmount']>} */
16
16
  asAmount: HostOf<Orchestrator["asAmount"]>;
17
17
  }>;
@@ -105,7 +105,7 @@ declare function prepareOrchestratorKit(zone: Zone, { chainHub, makeLocalChainFa
105
105
  };
106
106
  orchestrator: {
107
107
  getChain(chainName: string): Vow<HostInterface<Chain<any> & object>>;
108
- getDenomInfo(denom: string, srcChainName: "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon"): HostInterface<import("../orchestration-api.js").DenomInfo<"agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon", "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon">>;
108
+ getDenomInfo(denom: string, srcChainName: "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon"): HostInterface<import("../orchestration-api.js").DenomInfo<"agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon", "agoric" | "base" | "solana" | "celestia" | "cosmoshub" | "juno" | "neutron" | "noble" | "omniflixhub" | "osmosis" | "secretnetwork" | "stargaze" | "stride" | "umee" | "dydx" | "archway" | "axelar" | "evmos" | "haqq" | "kava" | "kujira" | "migaloo" | "nolus" | "persistence" | "pryzm" | "sei" | "shido" | "titan" | "beezee" | "carbon" | "coreum" | "crescent" | "doravota" | "dymension" | "empowerchain" | "injective" | "lava" | "nibiru" | "planq" | "provenance" | "quicksilver" | "sifchain" | "terra2" | "ethereum" | "avalanche" | "optimism" | "arbitrum" | "polygon">>;
109
109
  /** @type {HostOf<Orchestrator['asAmount']>} */
110
110
  asAmount: HostOf<Orchestrator["asAmount"]>;
111
111
  };