-
Notifications
You must be signed in to change notification settings - Fork 208
/
orchestration-api.ts
201 lines (182 loc) · 6.76 KB
/
orchestration-api.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/* eslint-disable no-use-before-define */
/**
* @file General API of orchestration
* - must not have chain-specific types without runtime narrowing by chain id
* - should remain relatively stable.
*/
import type {
Amount,
Brand,
NatAmount,
Payment,
} from '@agoric/ertp/src/types.js';
import type { LocalChainAccount } from '@agoric/vats/src/localchain.js';
import type { Timestamp } from '@agoric/time';
import type {
ChainInfo,
CosmosChainAccountMethods,
CosmosChainInfo,
IBCMsgTransferOptions,
KnownChains,
} from './types.js';
/**
* A denom that designates a path to a token type on some blockchain.
*
* Multiple denoms may designate the same underlying base denom (e.g., `uist`,
* `uatom`) on different Chains or on the same Chain via different paths. On
* Cosmos chains, all but the base denom are IBC style denoms, but that may vary
* across other chains. All the denoms that designate the same underlying base
* denom form an equivalence class, along with the unique Brand on the local
* Chain. Some operations accept any member of the equivalence class to
* effectively designate the corresponding token type on the target chain.
*/
export type Denom = string; // ibc/... or uist
// ??? when multiple Denoms provide paths to the same remote token type,
// should the brand be 1:1 with that equivalence class or each Denom?
/**
* In many cases, either a denom string or a local Brand can be used to
* designate a remote token type.
*/
export type DenomArg = Denom | Brand;
/**
* Count of some fungible token on some blockchain.
*
* @see {@link Orchestrator.asAmount} to convert to an Amount surjectively
*/
export type DenomAmount = {
denom: Denom;
value: bigint; // Nat
};
/** Amounts can be provided as pure data using denoms or as ERTP Amounts */
export type AmountArg = DenomAmount | Amount;
/** An address on some blockchain, e.g., cosmos, eth, etc. */
export type ChainAddress = {
/** e.g. 1 for Ethereum, agoric-3 for Agoric, cosmoshub-4 for Cosmos */
chainId: string;
address: string;
// TODO what's the right way to scope the address? it's not chainId
addressEncoding: 'bech32' | 'ethereum';
};
export type OrchestrationAccount<CI extends ChainInfo> = OrchestrationAccountI &
(CI extends CosmosChainInfo ? CosmosChainAccountMethods<CI> : never);
/**
* An object for access the core functions of a remote chain.
*
* Note that "remote" can mean the local chain; it's just that
* accounts are treated as remote/arms length for consistency.
*/
export interface Chain<CI extends ChainInfo> {
getChainInfo: () => Promise<CI>;
// "makeAccount" suggests an operation within a vat
/**
* Creates a new account on the remote chain.
* @returns an object that controls a new remote account on Chain
*/
makeAccount: () => Promise<OrchestrationAccount<CI>>;
// FUTURE supply optional port object; also fetch port object
// TODO provide a way to get the local denom/brand/whatever for this chain
}
/**
* Provided in the callback to `orchestrate()`.
*/
export interface Orchestrator {
getChain: <C extends string>(
chainName: C,
) => Promise<Chain<C extends keyof KnownChains ? KnownChains[C] : any>>;
makeLocalAccount: () => Promise<LocalChainAccount>;
/**
* For a denom, return information about a denom including the equivalent
* local Brand, the Chain on which the denom is held, and the Chain that
* issues the corresponding asset.
* @param denom
*/
getBrandInfo: <
HoldingChain extends keyof KnownChains,
IssuingChain extends keyof KnownChains,
>(
denom: Denom,
) => {
/** The well-known Brand on Agoric for the direct asset */
brand?: Brand;
/** The Chain at which the argument `denom` exists (where the asset is currently held) */
chain: Chain<KnownChains[HoldingChain]>;
/** The Chain that is the issuer of the underlying asset */
base: Chain<KnownChains[IssuingChain]>;
/** the Denom for the underlying asset on its issuer chain */
baseDenom: Denom;
};
// TODO preload the mapping so this can be synchronous
/**
* Convert an amount described in native data to a local, structured Amount.
* @param amount - the described amount
* @returns the Amount in local structuerd format
*/
asAmount: (amount: DenomAmount) => NatAmount;
}
/**
* An object that supports high-level operations for an account on a remote chain.
*/
export interface OrchestrationAccountI {
/**
* @returns the address of the account on the remote chain
*/
getAddress: () => ChainAddress;
/** @returns an array of amounts for every balance in the account. */
getBalances: () => Promise<DenomAmount[]>;
/** @returns the balance of a specific denom for the account. */
getBalance: (denom: DenomArg) => Promise<DenomAmount>;
/**
* Transfer amount to another account on the same chain. The promise settles when the transfer is complete.
* @param toAccount - the account to send the amount to. MUST be on the same chain
* @param amount - the amount to send
* @returns void
*/
send: (toAccount: ChainAddress, amount: AmountArg) => Promise<void>;
/**
* Transfer an amount to another account, typically on another chain.
* The promise settles when the transfer is complete.
* @param amount - the amount to transfer. Can be provided as pure data using denoms or as ERTP Amounts.
* @param destination - the account to transfer the amount to.
* @param [opts] - an optional memo to include with the transfer, which could drive custom PFM behavior, and timeout parameters
* @returns void
*
* TODO document the mapping from the address to the destination chain.
*/
transfer: (
amount: AmountArg,
destination: ChainAddress,
opts?: IBCMsgTransferOptions,
) => Promise<void>;
/**
* Transfer an amount to another account in multiple steps. The promise settles when
* the entire path of the transfer is complete.
* @param amount - the amount to transfer
* @param msg - the transfer message, including follow-up steps
* @returns void
*/
transferSteps: (amount: AmountArg, msg: TransferMsg) => Promise<void>;
/**
* deposit payment from zoe to the account. For remote accounts,
* an IBC Transfer will be executed to transfer funds there.
*/
deposit: (payment: Payment<'nat'>) => Promise<void>;
}
/**
* Internal structure for TransferMsgs.
* The type must be able to express transfers across different chains and transports.
*
* NOTE Expected to change, so consider an opaque structure.
*/
export type TransferMsg = {
toAccount: ChainAddress;
timeout?: Timestamp;
next?: TransferMsg;
data?: object;
};
export type AfterAction = { destChain: string; destAddress: ChainAddress };
export type SwapExact = { amountIn: Amount; amountOut: Amount };
export type SwapMaxSlippage = {
amountIn: Amount;
brandOut: Brand;
slippage: number;
};