@pioneer-platform/osmosis-client 0.0.1
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.
- package/lib/index.d.ts +71 -0
- package/lib/index.js +282 -0
- package/package.json +32 -0
- package/tsconfig.json +13 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
declare const TAG = " | osmosis | ";
|
|
2
|
+
declare const log: any;
|
|
3
|
+
declare let shortListSymbolToCaip: any;
|
|
4
|
+
declare let networkOsmo: any;
|
|
5
|
+
declare let networkAtom: any;
|
|
6
|
+
declare let networkSupport: any[];
|
|
7
|
+
interface QuoteResult {
|
|
8
|
+
amountOut: string;
|
|
9
|
+
slippage: string;
|
|
10
|
+
}
|
|
11
|
+
declare function quoteFromPool(amountAtomSwap: string, amountAtomPool: string, amountOsmoPool: string): QuoteResult;
|
|
12
|
+
declare const build_swap_tx: (from: string, tokenIn: string, tokenOut: string, amountIn: string, tokenOutMinAmount: string) => Promise<{
|
|
13
|
+
account_number: any;
|
|
14
|
+
chain_id: string;
|
|
15
|
+
fee: {
|
|
16
|
+
amount: {
|
|
17
|
+
amount: string;
|
|
18
|
+
denom: string;
|
|
19
|
+
}[];
|
|
20
|
+
gas: string;
|
|
21
|
+
};
|
|
22
|
+
memo: string;
|
|
23
|
+
msg: {
|
|
24
|
+
type: string;
|
|
25
|
+
value: {
|
|
26
|
+
routes: {
|
|
27
|
+
pool_id: string;
|
|
28
|
+
token_out_denom: string;
|
|
29
|
+
}[];
|
|
30
|
+
sender: string;
|
|
31
|
+
token_in: {
|
|
32
|
+
amount: string;
|
|
33
|
+
denom: string;
|
|
34
|
+
};
|
|
35
|
+
token_out_min_amount: string;
|
|
36
|
+
};
|
|
37
|
+
}[];
|
|
38
|
+
sequence: string;
|
|
39
|
+
} | undefined>;
|
|
40
|
+
declare const build_ibc_tx: (from: string, to: string, amount: string) => Promise<{
|
|
41
|
+
account_number: any;
|
|
42
|
+
chain_id: string;
|
|
43
|
+
fee: {
|
|
44
|
+
amount: {
|
|
45
|
+
amount: string;
|
|
46
|
+
denom: string;
|
|
47
|
+
}[];
|
|
48
|
+
gas: string;
|
|
49
|
+
};
|
|
50
|
+
memo: string;
|
|
51
|
+
msg: {
|
|
52
|
+
type: string;
|
|
53
|
+
value: {
|
|
54
|
+
receiver: string;
|
|
55
|
+
sender: string;
|
|
56
|
+
source_channel: string;
|
|
57
|
+
source_port: string;
|
|
58
|
+
timeout_height: {
|
|
59
|
+
revision_height: string;
|
|
60
|
+
revision_number: string;
|
|
61
|
+
};
|
|
62
|
+
token: {
|
|
63
|
+
amount: string;
|
|
64
|
+
denom: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
}[];
|
|
68
|
+
signatures: never[];
|
|
69
|
+
sequence: any;
|
|
70
|
+
} | undefined>;
|
|
71
|
+
declare const get_quote: (quote: any) => Promise<QuoteResult | undefined>;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Osmosis Swap Intergration
|
|
4
|
+
-Highlander
|
|
5
|
+
|
|
6
|
+
*/
|
|
7
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
17
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
18
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
19
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
20
|
+
function step(op) {
|
|
21
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
22
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
23
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
24
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
25
|
+
switch (op[0]) {
|
|
26
|
+
case 0: case 1: t = op; break;
|
|
27
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
28
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
29
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
30
|
+
default:
|
|
31
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
32
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
33
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
34
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
35
|
+
if (t[2]) _.ops.pop();
|
|
36
|
+
_.trys.pop(); continue;
|
|
37
|
+
}
|
|
38
|
+
op = body.call(thisArg, _);
|
|
39
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
40
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var TAG = " | osmosis | ";
|
|
44
|
+
var log = require('@pioneer-platform/loggerdog')();
|
|
45
|
+
var shortListSymbolToCaip = require("@pioneer-platform/pioneer-caip").shortListSymbolToCaip;
|
|
46
|
+
var networkOsmo = require("@pioneer-platform/osmosis-network");
|
|
47
|
+
var networkAtom = require("@pioneer-platform/cosmos-network");
|
|
48
|
+
var networkSupport = [
|
|
49
|
+
shortListSymbolToCaip["OSMO"],
|
|
50
|
+
shortListSymbolToCaip["GAIA"],
|
|
51
|
+
];
|
|
52
|
+
module.exports = {
|
|
53
|
+
init: function (settings) {
|
|
54
|
+
return true;
|
|
55
|
+
},
|
|
56
|
+
networkSupport: function () {
|
|
57
|
+
return networkSupport;
|
|
58
|
+
},
|
|
59
|
+
getQuote: function (quote) {
|
|
60
|
+
return get_quote(quote);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
function quoteFromPool(amountAtomSwap, amountAtomPool, amountOsmoPool) {
|
|
64
|
+
// Convert string inputs to numbers and scale the swap amount
|
|
65
|
+
var swapAmount = parseFloat(amountAtomSwap) * 1e6;
|
|
66
|
+
var atomPoolAmount = parseFloat(amountAtomPool);
|
|
67
|
+
var osmoPoolAmount = parseFloat(amountOsmoPool);
|
|
68
|
+
// Calculate the constant product
|
|
69
|
+
var k = atomPoolAmount * osmoPoolAmount;
|
|
70
|
+
// New amount of ATOM in the pool after the swap
|
|
71
|
+
var newAtomPoolAmount = atomPoolAmount + swapAmount;
|
|
72
|
+
// Calculate the amount of OSMO received
|
|
73
|
+
var newOsmoPoolAmount = k / newAtomPoolAmount;
|
|
74
|
+
var osmoReceived = osmoPoolAmount - newOsmoPoolAmount;
|
|
75
|
+
// Scale back down the amount of OSMO received
|
|
76
|
+
var scaledOsmoReceived = osmoReceived / 1e6;
|
|
77
|
+
// Calculate the actual rate of the swap
|
|
78
|
+
var actualRate = scaledOsmoReceived / (swapAmount / 1e6);
|
|
79
|
+
// Calculate the ideal rate
|
|
80
|
+
var idealRate = osmoPoolAmount / atomPoolAmount;
|
|
81
|
+
// Calculate the slippage
|
|
82
|
+
var slippage = ((idealRate - actualRate) / idealRate) * 100;
|
|
83
|
+
return {
|
|
84
|
+
amountOut: scaledOsmoReceived.toFixed(6),
|
|
85
|
+
slippage: Math.max(slippage, 0).toFixed(6)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//
|
|
89
|
+
var build_swap_tx = function (from, tokenIn, tokenOut, amountIn, tokenOutMinAmount) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
91
|
+
var tag, accountInfo, tx, e_1;
|
|
92
|
+
return __generator(this, function (_a) {
|
|
93
|
+
switch (_a.label) {
|
|
94
|
+
case 0:
|
|
95
|
+
tag = TAG + " | build_swap_tx | ";
|
|
96
|
+
_a.label = 1;
|
|
97
|
+
case 1:
|
|
98
|
+
_a.trys.push([1, 3, , 4]);
|
|
99
|
+
return [4 /*yield*/, networkOsmo.getAccount(from)];
|
|
100
|
+
case 2:
|
|
101
|
+
accountInfo = _a.sent();
|
|
102
|
+
log.info(tag, "accountInfo: ", accountInfo);
|
|
103
|
+
if (!accountInfo.account.account_number)
|
|
104
|
+
throw new Error("missing account_number");
|
|
105
|
+
tx = {
|
|
106
|
+
"account_number": accountInfo.account.account_number,
|
|
107
|
+
"chain_id": 'osmosis-1',
|
|
108
|
+
"fee": {
|
|
109
|
+
"amount": [
|
|
110
|
+
{
|
|
111
|
+
"amount": "2291",
|
|
112
|
+
"denom": "uosmo"
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"gas": "100000"
|
|
116
|
+
},
|
|
117
|
+
"memo": "memo",
|
|
118
|
+
"msg": [
|
|
119
|
+
{
|
|
120
|
+
"type": "osmosis/gamm/swap-exact-amount-in",
|
|
121
|
+
"value": {
|
|
122
|
+
"routes": [
|
|
123
|
+
{
|
|
124
|
+
"pool_id": "1",
|
|
125
|
+
"token_out_denom": tokenOut
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
"sender": from,
|
|
129
|
+
"token_in": {
|
|
130
|
+
"amount": amountIn,
|
|
131
|
+
"denom": tokenIn
|
|
132
|
+
},
|
|
133
|
+
"token_out_min_amount": "8204"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"sequence": "90"
|
|
138
|
+
};
|
|
139
|
+
return [2 /*return*/, tx];
|
|
140
|
+
case 3:
|
|
141
|
+
e_1 = _a.sent();
|
|
142
|
+
log.error(e_1);
|
|
143
|
+
return [3 /*break*/, 4];
|
|
144
|
+
case 4: return [2 /*return*/];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
var build_ibc_tx = function (from, to, amount) {
|
|
150
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
151
|
+
var tag, accountInfo, currentHeight, expireBlockHeight, tx, e_2;
|
|
152
|
+
return __generator(this, function (_a) {
|
|
153
|
+
switch (_a.label) {
|
|
154
|
+
case 0:
|
|
155
|
+
tag = TAG + " | build_ibc_tx | ";
|
|
156
|
+
_a.label = 1;
|
|
157
|
+
case 1:
|
|
158
|
+
_a.trys.push([1, 3, , 4]);
|
|
159
|
+
log.info(tag, "from: ", from);
|
|
160
|
+
log.info(tag, "to: ", to);
|
|
161
|
+
log.info(tag, "amount: ", amount);
|
|
162
|
+
return [4 /*yield*/, networkAtom.getAccount(to)];
|
|
163
|
+
case 2:
|
|
164
|
+
accountInfo = _a.sent();
|
|
165
|
+
log.info(tag, "accountInfo: ", accountInfo);
|
|
166
|
+
if (!accountInfo.result.value.account_number)
|
|
167
|
+
throw new Error("missing account_number");
|
|
168
|
+
if (!accountInfo.result.value.sequence)
|
|
169
|
+
throw new Error("missing account_number");
|
|
170
|
+
currentHeight = accountInfo.height;
|
|
171
|
+
expireBlockHeight = parseInt(currentHeight) + 10000;
|
|
172
|
+
tx = {
|
|
173
|
+
"account_number": accountInfo.result.value.account_number,
|
|
174
|
+
"chain_id": "cosmoshub-4",
|
|
175
|
+
"fee": {
|
|
176
|
+
"amount": [
|
|
177
|
+
{
|
|
178
|
+
"amount": "2800",
|
|
179
|
+
"denom": "uatom"
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"gas": "290000"
|
|
183
|
+
},
|
|
184
|
+
"memo": "",
|
|
185
|
+
"msg": [
|
|
186
|
+
{
|
|
187
|
+
"type": "cosmos-sdk/MsgTransfer",
|
|
188
|
+
"value": {
|
|
189
|
+
"receiver": to,
|
|
190
|
+
"sender": from,
|
|
191
|
+
"source_channel": "channel-141",
|
|
192
|
+
"source_port": "transfer",
|
|
193
|
+
"timeout_height": {
|
|
194
|
+
"revision_height": expireBlockHeight.toString(),
|
|
195
|
+
"revision_number": "1"
|
|
196
|
+
},
|
|
197
|
+
"token": {
|
|
198
|
+
"amount": amount,
|
|
199
|
+
"denom": "uatom"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
"signatures": [],
|
|
205
|
+
"sequence": accountInfo.result.value.sequence
|
|
206
|
+
};
|
|
207
|
+
return [2 /*return*/, tx];
|
|
208
|
+
case 3:
|
|
209
|
+
e_2 = _a.sent();
|
|
210
|
+
log.error(e_2);
|
|
211
|
+
return [3 /*break*/, 4];
|
|
212
|
+
case 4: return [2 /*return*/];
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
var get_quote = function (quote) {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
219
|
+
var tag, output, pools, amountAtom, amountOsmo, rate, result, tx1, tx2, tx2, tx1, e_3;
|
|
220
|
+
return __generator(this, function (_a) {
|
|
221
|
+
switch (_a.label) {
|
|
222
|
+
case 0:
|
|
223
|
+
tag = TAG + " | get_quote | ";
|
|
224
|
+
_a.label = 1;
|
|
225
|
+
case 1:
|
|
226
|
+
_a.trys.push([1, 10, , 11]);
|
|
227
|
+
output = {};
|
|
228
|
+
if (!quote.sellAsset)
|
|
229
|
+
throw new Error("missing sellAsset");
|
|
230
|
+
if (!quote.buyAsset)
|
|
231
|
+
throw new Error("missing buyAsset");
|
|
232
|
+
if (!quote.sellAmount)
|
|
233
|
+
throw new Error("missing sellAmount");
|
|
234
|
+
if (!quote.senderAddress)
|
|
235
|
+
throw new Error("missing senderAddress");
|
|
236
|
+
if (!quote.recipientAddress)
|
|
237
|
+
throw new Error("missing recipientAddress");
|
|
238
|
+
return [4 /*yield*/, networkOsmo.getPools()];
|
|
239
|
+
case 2:
|
|
240
|
+
pools = _a.sent();
|
|
241
|
+
if (!pools.pools[0])
|
|
242
|
+
throw Error("Unable to get pools from network!");
|
|
243
|
+
log.info(tag, "resp: ", pools.pools[0].pool_assets);
|
|
244
|
+
amountAtom = pools.pools[0].pool_assets[0].token.amount;
|
|
245
|
+
amountOsmo = pools.pools[0].pool_assets[1].token.amount;
|
|
246
|
+
rate = amountOsmo / amountAtom;
|
|
247
|
+
log.info(tag, "rate: ", rate);
|
|
248
|
+
result = void 0;
|
|
249
|
+
if (!(quote.sellAsset === shortListSymbolToCaip["OSMO"])) return [3 /*break*/, 5];
|
|
250
|
+
result = quoteFromPool(quote.sellAmount, amountAtom, amountOsmo);
|
|
251
|
+
return [4 /*yield*/, build_swap_tx(quote.senderAddress, quote.sellAsset, quote.buyAsset, quote.sellAmount, result.amountOut)];
|
|
252
|
+
case 3:
|
|
253
|
+
tx1 = _a.sent();
|
|
254
|
+
log.info(tag, "tx1: ", tx1);
|
|
255
|
+
return [4 /*yield*/, build_ibc_tx(quote.senderAddress, quote.recipientAddress, result.amountOut)];
|
|
256
|
+
case 4:
|
|
257
|
+
tx2 = _a.sent();
|
|
258
|
+
log.info(tag, "tx2: ", tx2);
|
|
259
|
+
return [3 /*break*/, 9];
|
|
260
|
+
case 5:
|
|
261
|
+
if (!(quote.sellAsset === shortListSymbolToCaip["ATOM"])) return [3 /*break*/, 8];
|
|
262
|
+
result = quoteFromPool(quote.sellAmount, amountAtom, amountOsmo);
|
|
263
|
+
return [4 /*yield*/, build_ibc_tx(quote.recipientAddress, quote.senderAddress, result.amountOut)];
|
|
264
|
+
case 6:
|
|
265
|
+
tx2 = _a.sent();
|
|
266
|
+
log.info(tag, "tx2: ", tx2);
|
|
267
|
+
return [4 /*yield*/, build_swap_tx(quote.senderAddress, quote.sellAsset, quote.buyAsset, quote.sellAmount, result.amountOut)];
|
|
268
|
+
case 7:
|
|
269
|
+
tx1 = _a.sent();
|
|
270
|
+
log.info(tag, "tx1: ", tx1);
|
|
271
|
+
return [3 /*break*/, 9];
|
|
272
|
+
case 8: throw Error("Asset not supported! asset:" + quote.sellAsset);
|
|
273
|
+
case 9: return [2 /*return*/, result];
|
|
274
|
+
case 10:
|
|
275
|
+
e_3 = _a.sent();
|
|
276
|
+
console.error(tag, "e: ", e_3);
|
|
277
|
+
return [3 /*break*/, 11];
|
|
278
|
+
case 11: return [2 /*return*/];
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pioneer-platform/osmosis-client",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "./lib/index.js",
|
|
5
|
+
"types": "./lib/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@pioneer-platform/cosmos-network": "^8.3.1",
|
|
8
|
+
"@pioneer-platform/loggerdog": "^8.3.1",
|
|
9
|
+
"@pioneer-platform/pioneer-coins": "^9.2.3",
|
|
10
|
+
"axios": "^1.3.4",
|
|
11
|
+
"dotenv": "^8.2.0",
|
|
12
|
+
"rango-sdk": "^0.1.45"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"npm": "npm i",
|
|
16
|
+
"test": "npm run build && node __tests__/test-module.js",
|
|
17
|
+
"build": "tsc -p .",
|
|
18
|
+
"prepublish": "npm run build",
|
|
19
|
+
"refresh": "rm -rf ./node_modules ./package-lock.json && npm install"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/jest": "^25.2.3",
|
|
23
|
+
"@types/node": "^13.13.21",
|
|
24
|
+
"@types/source-map-support": "^0.5.3",
|
|
25
|
+
"jest": "^26.4.2",
|
|
26
|
+
"onchange": "^7.0.2",
|
|
27
|
+
"serve": "^11.3.2",
|
|
28
|
+
"ts-jest": "^29.0.5",
|
|
29
|
+
"typescript": "^5.0.2"
|
|
30
|
+
},
|
|
31
|
+
"gitHead": "a76012f6693a12181c4744e53e977a9eaeef0ed3"
|
|
32
|
+
}
|
package/tsconfig.json
ADDED