1
1
import { NonNullish , makeTracer } from '@agoric/internal' ;
2
2
import { Fail , makeError , q } from '@endo/errors' ;
3
3
import { M , mustMatch } from '@endo/patterns' ;
4
- import { RatioShape } from '@agoric/ertp' ;
5
4
6
5
const trace = makeTracer ( 'SwapAnything' ) ;
7
6
8
7
const { entries } = Object ;
9
8
10
9
/**
10
+ * @typedef {{
11
+ * destAddr: string;
12
+ * receiverAddr: string;
13
+ * outDenom: Denom;
14
+ * slippage: { slippagePercentage: string; windowSeconds: number };
15
+ * onFailedDelivery: string;
16
+ * nextMemo?: string;
17
+ * }} SwapInfo
18
+ *
11
19
* @import {GuestInterface, GuestOf} from '@agoric/async-flow';
12
- * @import {Denom, DenomDetail} from '@agoric/orchestration';
13
- * @import {ZCF, ZCFSeat} from '@agoric/zoe';
14
- * @import {Brand} from '@agoric/ertp';
20
+ * @import {Denom} from '@agoric/orchestration';
21
+ * @import {ZCFSeat} from '@agoric/zoe';
15
22
* @import {Vow} from '@agoric/vow';
16
23
* @import {LocalOrchestrationAccountKit} from '../exos/local-orchestration-account.js';
17
24
* @import {ZoeTools} from '../utils/zoe-tools.js';
18
- * @import {Orchestrator, OrchestrationFlow, ChainHub, ChainInfo} from '../types.js';
19
- * @import {AccountIdArg} from '../orchestration-api.ts';
25
+ * @import {Orchestrator, OrchestrationFlow, ChainHub, ChainInfo, CosmosChainInfo} from '../types.js';
20
26
*/
21
27
22
28
const denomForBrand = async ( orch , brand ) => {
@@ -29,6 +35,34 @@ const denomForBrand = async (orch, brand) => {
29
35
return denom ;
30
36
} ;
31
37
38
+ /**
39
+ * @param {SwapInfo } swapInfo
40
+ * @returns {string }
41
+ */
42
+ const buildXCSMemo = swapInfo => {
43
+ const memo = {
44
+ wasm : {
45
+ contract : swapInfo . destAddr ,
46
+ msg : {
47
+ osmosis_swap : {
48
+ output_denom : swapInfo . outDenom ,
49
+ slippage : {
50
+ twap : {
51
+ window_seconds : swapInfo . slippage . windowSeconds ,
52
+ slippage_percentage : swapInfo . slippage . slippagePercentage ,
53
+ } ,
54
+ } ,
55
+ receiver : swapInfo . receiverAddr ,
56
+ on_failed_delivery : swapInfo . onFailedDelivery ,
57
+ nextMemo : swapInfo . nextMemo ,
58
+ } ,
59
+ } ,
60
+ } ,
61
+ } ;
62
+
63
+ return JSON . stringify ( memo ) ;
64
+ } ;
65
+
32
66
/**
33
67
* @satisfies {OrchestrationFlow }
34
68
* @param {Orchestrator } orch
@@ -38,14 +72,7 @@ const denomForBrand = async (orch, brand) => {
38
72
* @param {GuestInterface<ZoeTools> } ctx.zoeTools
39
73
* @param {GuestOf<(msg: string) => Vow<void>> } ctx.log
40
74
* @param {ZCFSeat } seat
41
- * @param {{
42
- * destAddr: string;
43
- * receiverAddr: string;
44
- * outDenom: Denom;
45
- * slippage: { slippageRatio: Ratio; windowSeconds: bigint };
46
- * onFailedDelivery: string;
47
- * nextMemo?: string;
48
- * }} offerArgs
75
+ * @param {SwapInfo } offerArgs
49
76
*/
50
77
51
78
// Given USDC, swap to desired token with slippage
@@ -61,15 +88,6 @@ export const swapIt = async (
61
88
seat ,
62
89
offerArgs ,
63
90
) => {
64
- // offerArgs,
65
- // harden({
66
- // destAddr: M.string(),
67
- // receiverAddr: M.string(),
68
- // outDenom: M.string(),
69
- // onFailedDelivery: M.string(),
70
- // slippage: { slippageRatio: RatioShape, windowSeconds: M.bigint() },
71
- // }),
72
- // );
73
91
mustMatch (
74
92
offerArgs ,
75
93
M . splitRecord (
@@ -78,24 +96,19 @@ export const swapIt = async (
78
96
receiverAddr : M . string ( ) ,
79
97
outDenom : M . string ( ) ,
80
98
onFailedDelivery : M . string ( ) ,
81
- slippage : { slippageRatio : RatioShape , windowSeconds : M . bigint ( ) } ,
99
+ slippage : { slippagePercentage : M . string ( ) , windowSeconds : M . number ( ) } ,
82
100
} ,
83
- { nextMemo : M . or ( undefined , M . string ( ) ) } ,
101
+ { nextMemo : M . string ( ) } ,
84
102
) ,
85
103
) ;
86
104
87
- trace ( 'HELLLOOOOO' ) ;
88
-
89
- const { destAddr } = offerArgs ;
105
+ const { receiverAddr, destAddr } = offerArgs ;
90
106
// NOTE the proposal shape ensures that the `give` is a single asset
91
107
const { give } = seat . getProposal ( ) ;
92
108
const [ [ _kw , amt ] ] = entries ( give ) ;
93
- void log ( `sending {${ amt . value } } from osmosis to ${ destAddr } ` ) ;
109
+ void log ( `sending {${ amt . value } } from osmosis to ${ receiverAddr } ` ) ;
94
110
const denom = await denomForBrand ( orch , amt . brand ) ;
95
111
96
- /** @type {ChainInfo } */
97
- const info = await chainHub . getChainInfo ( 'osmosis' ) ;
98
-
99
112
/**
100
113
* @type {any } XXX methods returning vows
101
114
* https://github.com/Agoric/agoric-sdk/issues/9822
@@ -115,26 +128,29 @@ export const swapIt = async (
115
128
throw makeError ( errorMsg ) ;
116
129
} ;
117
130
118
- const { chainId } = info ;
119
- assert ( typeof chainId === 'string' , 'bad chainId' ) ;
120
-
121
- const [ _a , _o , connection ] = await chainHub . getChainsAndConnection (
122
- 'agoric' ,
123
- 'osmosis' ,
124
- ) ;
131
+ const [ _a , osmosisChainInfo , connection ] =
132
+ await chainHub . getChainsAndConnection ( 'agoric' , 'osmosis' ) ;
125
133
126
134
connection . counterparty || Fail `No IBC connection to Osmosis` ;
127
135
128
- void log ( `got info for chain: osmosis ${ chainId } ` ) ;
136
+ void log ( `got info for chain: osmosis ${ osmosisChainInfo } ` ) ;
137
+ trace ( osmosisChainInfo ) ;
129
138
130
139
await localTransfer ( seat , sharedLocalAccount , give ) ;
131
140
void log ( `completed transfer to localAccount` ) ;
132
141
133
142
try {
143
+ const memo = buildXCSMemo ( offerArgs ) ;
144
+ trace ( memo ) ;
145
+
134
146
await sharedLocalAccount . transfer (
135
- { value : destAddr , encoding : 'bech32' , chainId } ,
147
+ {
148
+ value : destAddr ,
149
+ encoding : 'bech32' ,
150
+ chainId : /** @type {CosmosChainInfo } */ ( osmosisChainInfo ) . chainId ,
151
+ } ,
136
152
{ denom, value : amt . value } ,
137
- // memo here
153
+ { memo } ,
138
154
) ;
139
155
void log ( `completed transfer to ${ destAddr } ` ) ;
140
156
} catch ( e ) {
0 commit comments