@riocrypto/common-server 1.0.2842 → 1.0.2843
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/build/clients/cluster-client.d.ts +2 -1
- package/build/clients/cluster-client.js +2 -1
- package/build/clients/kraken-client.d.ts +60 -0
- package/build/clients/kraken-client.js +219 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/models/external-trade.d.ts +4 -0
- package/build/models/external-trade.js +6 -0
- package/build/models/internal-balances.d.ts +3 -0
- package/build/models/internal-balances.js +3 -0
- package/build/models/internal-trade.d.ts +2 -0
- package/build/models/internal-trade.js +3 -0
- package/package.json +2 -2
|
@@ -180,7 +180,7 @@ declare class ClusterClient {
|
|
|
180
180
|
stopExternalTradingAlgorithm(id: string): Promise<ExternalTradingAlgorithm>;
|
|
181
181
|
getExternalTradingAlgorithm(id: string): Promise<ExternalTradingAlgorithm>;
|
|
182
182
|
getExternalTrade(id: string): Promise<ExternalTrade>;
|
|
183
|
-
placeExternalTrade({ provider, type, originCurrency, destinationCurrency, requestedOriginAmount, requestedDestinationAmount, limitPrice, twoWaySettlementDateOffset, arbitrageSessionId, fxTradeId, timeInForce, valueDate, }: {
|
|
183
|
+
placeExternalTrade({ provider, type, originCurrency, destinationCurrency, requestedOriginAmount, requestedDestinationAmount, limitPrice, twoWaySettlementDateOffset, arbitrageSessionId, fxTradeId, internalTradeId, timeInForce, valueDate, }: {
|
|
184
184
|
provider: ExternalTradingProvider;
|
|
185
185
|
type: ExternalTradeType;
|
|
186
186
|
originCurrency: Crypto | Fiat;
|
|
@@ -191,6 +191,7 @@ declare class ClusterClient {
|
|
|
191
191
|
twoWaySettlementDateOffset?: number;
|
|
192
192
|
arbitrageSessionId?: string;
|
|
193
193
|
fxTradeId?: string;
|
|
194
|
+
internalTradeId?: string;
|
|
194
195
|
timeInForce?: "day" | "gtc" | "ioc" | "fok";
|
|
195
196
|
valueDate?: string;
|
|
196
197
|
}): Promise<ExternalTrade>;
|
|
@@ -654,7 +654,7 @@ class ClusterClient {
|
|
|
654
654
|
return response.data;
|
|
655
655
|
});
|
|
656
656
|
}
|
|
657
|
-
placeExternalTrade({ provider, type, originCurrency, destinationCurrency, requestedOriginAmount, requestedDestinationAmount, limitPrice, twoWaySettlementDateOffset, arbitrageSessionId, fxTradeId, timeInForce, valueDate, }) {
|
|
657
|
+
placeExternalTrade({ provider, type, originCurrency, destinationCurrency, requestedOriginAmount, requestedDestinationAmount, limitPrice, twoWaySettlementDateOffset, arbitrageSessionId, fxTradeId, internalTradeId, timeInForce, valueDate, }) {
|
|
658
658
|
return __awaiter(this, void 0, void 0, function* () {
|
|
659
659
|
const response = yield this.axios.post(`${this.baseUrl}/api/trading/external/trades`, {
|
|
660
660
|
provider,
|
|
@@ -667,6 +667,7 @@ class ClusterClient {
|
|
|
667
667
|
twoWaySettlementDateOffset,
|
|
668
668
|
arbitrageSessionId,
|
|
669
669
|
fxTradeId,
|
|
670
|
+
internalTradeId,
|
|
670
671
|
timeInForce,
|
|
671
672
|
valueDate,
|
|
672
673
|
}, {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { RioEnv } from "@riocrypto/common";
|
|
2
|
+
export declare const KRAKEN_ASSET_USD = "ZUSD";
|
|
3
|
+
export interface KrakenDepositMethod {
|
|
4
|
+
method: string;
|
|
5
|
+
limit: string | boolean;
|
|
6
|
+
fee?: string;
|
|
7
|
+
"gen-address"?: boolean;
|
|
8
|
+
"address-setup-fee"?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface KrakenDepositAddress {
|
|
11
|
+
address: string;
|
|
12
|
+
expiretm: string;
|
|
13
|
+
new?: boolean;
|
|
14
|
+
tag?: string;
|
|
15
|
+
memo?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface KrakenFundingStatus {
|
|
18
|
+
method: string;
|
|
19
|
+
aclass: string;
|
|
20
|
+
asset: string;
|
|
21
|
+
refid: string;
|
|
22
|
+
txid: string;
|
|
23
|
+
info: string;
|
|
24
|
+
amount: string;
|
|
25
|
+
fee: string;
|
|
26
|
+
time: number;
|
|
27
|
+
status: string;
|
|
28
|
+
"status-prop"?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface KrakenWithdrawInfo {
|
|
31
|
+
method: string;
|
|
32
|
+
limit: string;
|
|
33
|
+
amount: string;
|
|
34
|
+
fee: string;
|
|
35
|
+
}
|
|
36
|
+
declare class KrakenClient {
|
|
37
|
+
private apiKey;
|
|
38
|
+
private env;
|
|
39
|
+
private axiosClient;
|
|
40
|
+
private decodedSecret;
|
|
41
|
+
private lastNonce;
|
|
42
|
+
private restBaseUrl;
|
|
43
|
+
constructor(apiKey: string, apiSecret: string, env: RioEnv);
|
|
44
|
+
private assertFundingAllowed;
|
|
45
|
+
private nextNonce;
|
|
46
|
+
private sign;
|
|
47
|
+
private privatePost;
|
|
48
|
+
getBalance(asset: string): Promise<number>;
|
|
49
|
+
getAllBalances(assets: string[]): Promise<Record<string, number>>;
|
|
50
|
+
getDepositMethods(asset: string): Promise<KrakenDepositMethod[]>;
|
|
51
|
+
getDepositAddresses(asset: string, method: string, isNew?: boolean): Promise<KrakenDepositAddress[]>;
|
|
52
|
+
getDepositStatus(asset: string, method?: string): Promise<KrakenFundingStatus[]>;
|
|
53
|
+
getWithdrawInfo(asset: string, key: string, amount: number): Promise<KrakenWithdrawInfo>;
|
|
54
|
+
withdraw(asset: string, key: string, amount: number): Promise<string>;
|
|
55
|
+
getWithdrawStatus(asset: string, method?: string): Promise<KrakenFundingStatus[]>;
|
|
56
|
+
getWithdrawStatusByRefid(asset: string, refid: string): Promise<KrakenFundingStatus | undefined>;
|
|
57
|
+
getDepositByTxId(asset: string, txid: string): Promise<KrakenFundingStatus | undefined>;
|
|
58
|
+
}
|
|
59
|
+
export declare const buildKrakenClient: () => Promise<KrakenClient>;
|
|
60
|
+
export type { KrakenClient };
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.buildKrakenClient = exports.KRAKEN_ASSET_USD = void 0;
|
|
16
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
17
|
+
const common_1 = require("@riocrypto/common");
|
|
18
|
+
const axios_with_logging_1 = require("./axios-with-logging");
|
|
19
|
+
const secret_manager_client_1 = require("./secret-manager-client");
|
|
20
|
+
// Kraken REST hosts. There is no public Kraken spot testnet, but institutional
|
|
21
|
+
// clients get a separate UAT environment. The host is selected purely from
|
|
22
|
+
// RIO_ENV: only production talks to the live account; every other environment
|
|
23
|
+
// points at the UAT host so it can never move funds on the real account.
|
|
24
|
+
const KRAKEN_PROD_REST_BASE_URL = "https://api.kraken.com";
|
|
25
|
+
const KRAKEN_UAT_REST_BASE_URL = "https://api.uat.kraken.com";
|
|
26
|
+
const getKrakenRestBaseUrl = (env) => env === common_1.RioEnv.Production
|
|
27
|
+
? KRAKEN_PROD_REST_BASE_URL
|
|
28
|
+
: KRAKEN_UAT_REST_BASE_URL;
|
|
29
|
+
// Kraken Balance keys. Fiat USD is `ZUSD`; the stablecoins use their ticker.
|
|
30
|
+
exports.KRAKEN_ASSET_USD = "ZUSD";
|
|
31
|
+
class KrakenClient {
|
|
32
|
+
constructor(apiKey, apiSecret, env) {
|
|
33
|
+
this.apiKey = apiKey;
|
|
34
|
+
this.env = env;
|
|
35
|
+
// Kraken nonces must strictly increase per key. We keep a monotonic floor so
|
|
36
|
+
// two calls in the same millisecond can't produce a decreasing nonce.
|
|
37
|
+
this.lastNonce = 0;
|
|
38
|
+
this.decodedSecret = Buffer.from(apiSecret, "base64");
|
|
39
|
+
this.axiosClient = (0, axios_with_logging_1.buildAxiosWithLogging)();
|
|
40
|
+
this.restBaseUrl = getKrakenRestBaseUrl(env);
|
|
41
|
+
}
|
|
42
|
+
// Fail-closed guard: a non-production environment must never move funds
|
|
43
|
+
// against the LIVE Kraken host. The host is derived from RIO_ENV, so this
|
|
44
|
+
// also catches an unknown/unset RIO_ENV resolving to the live host.
|
|
45
|
+
assertFundingAllowed() {
|
|
46
|
+
const isLiveHost = this.restBaseUrl === KRAKEN_PROD_REST_BASE_URL;
|
|
47
|
+
if (this.env !== common_1.RioEnv.Production && isLiveHost) {
|
|
48
|
+
throw new Error("Refusing to move Kraken funds: a non-production environment is pointed at the live Kraken host.");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
nextNonce() {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
const nonce = now > this.lastNonce ? now : this.lastNonce + 1;
|
|
54
|
+
this.lastNonce = nonce;
|
|
55
|
+
return nonce;
|
|
56
|
+
}
|
|
57
|
+
sign(path, nonce, postData) {
|
|
58
|
+
// API-Sign = base64( HMAC-SHA512( path + SHA256(nonce + postData),
|
|
59
|
+
// base64decode(secret) ) )
|
|
60
|
+
const sha256 = crypto_1.default
|
|
61
|
+
.createHash("sha256")
|
|
62
|
+
.update(nonce + postData)
|
|
63
|
+
.digest();
|
|
64
|
+
const message = Buffer.concat([Buffer.from(path, "utf8"), sha256]);
|
|
65
|
+
return crypto_1.default
|
|
66
|
+
.createHmac("sha512", this.decodedSecret)
|
|
67
|
+
.update(message)
|
|
68
|
+
.digest("base64");
|
|
69
|
+
}
|
|
70
|
+
privatePost(method, params = {}) {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const path = `/0/private/${method}`;
|
|
73
|
+
const nonce = this.nextNonce();
|
|
74
|
+
const form = new URLSearchParams();
|
|
75
|
+
form.set("nonce", String(nonce));
|
|
76
|
+
for (const [key, value] of Object.entries(params)) {
|
|
77
|
+
if (value !== undefined && value !== null) {
|
|
78
|
+
form.set(key, String(value));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const postData = form.toString();
|
|
82
|
+
const signature = this.sign(path, nonce, postData);
|
|
83
|
+
const { data } = yield this.axiosClient.post(`${this.restBaseUrl}${path}`, postData, {
|
|
84
|
+
headers: {
|
|
85
|
+
"API-Key": this.apiKey,
|
|
86
|
+
"API-Sign": signature,
|
|
87
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
// Kraken returns HTTP 200 with errors inside an `error` array.
|
|
91
|
+
if ((data === null || data === void 0 ? void 0 : data.error) && data.error.length > 0) {
|
|
92
|
+
throw new Error(`Kraken API error: ${data.error.join(", ")}`);
|
|
93
|
+
}
|
|
94
|
+
return data.result;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// ----- Balances -----
|
|
98
|
+
getBalance(asset) {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
const balances = yield this.privatePost("Balance", {});
|
|
101
|
+
const value = balances[asset];
|
|
102
|
+
return value ? parseFloat(value) : 0;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
getAllBalances(assets) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
const balances = yield this.privatePost("Balance", {});
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const asset of assets) {
|
|
110
|
+
result[asset] = balances[asset] ? parseFloat(balances[asset]) : 0;
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// ----- Deposits -----
|
|
116
|
+
getDepositMethods(asset) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
return this.privatePost("DepositMethods", { asset });
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Retrieve (or generate) deposit addresses for an asset + method. `method`
|
|
122
|
+
// must exactly match one of the values returned by DepositMethods.
|
|
123
|
+
getDepositAddresses(asset, method, isNew = false) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
return this.privatePost("DepositAddresses", {
|
|
126
|
+
asset,
|
|
127
|
+
method,
|
|
128
|
+
new: isNew ? true : undefined,
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
getDepositStatus(asset, method) {
|
|
133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
+
return this.privatePost("DepositStatus", {
|
|
135
|
+
asset,
|
|
136
|
+
method,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// ----- Withdrawals -----
|
|
141
|
+
getWithdrawInfo(asset, key, amount) {
|
|
142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
return this.privatePost("WithdrawInfo", {
|
|
144
|
+
asset,
|
|
145
|
+
key,
|
|
146
|
+
amount,
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// Withdraw to a pre-configured, account-whitelisted address referenced by
|
|
151
|
+
// `key` (Kraken does not allow withdrawing to an arbitrary address via API).
|
|
152
|
+
// Returns Kraken's withdrawal reference id (refid).
|
|
153
|
+
withdraw(asset, key, amount) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
this.assertFundingAllowed();
|
|
156
|
+
const result = yield this.privatePost("Withdraw", {
|
|
157
|
+
asset,
|
|
158
|
+
key,
|
|
159
|
+
amount,
|
|
160
|
+
});
|
|
161
|
+
if (!(result === null || result === void 0 ? void 0 : result.refid)) {
|
|
162
|
+
throw new Error("Kraken Withdraw returned no refid");
|
|
163
|
+
}
|
|
164
|
+
return result.refid;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
getWithdrawStatus(asset, method) {
|
|
168
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
return this.privatePost("WithdrawStatus", {
|
|
170
|
+
asset,
|
|
171
|
+
method,
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
getWithdrawStatusByRefid(asset, refid) {
|
|
176
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
const statuses = yield this.getWithdrawStatus(asset);
|
|
178
|
+
return statuses.find((s) => s.refid === refid);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
getDepositByTxId(asset, txid) {
|
|
182
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
+
const statuses = yield this.getDepositStatus(asset);
|
|
184
|
+
return statuses.find((s) => s.txid === txid);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Cache a single client per process so the monotonic nonce floor is effective
|
|
189
|
+
// process-wide; building a fresh client per call would reset it and risk
|
|
190
|
+
// `EAPI:Invalid nonce`.
|
|
191
|
+
let krakenClient = null;
|
|
192
|
+
let krakenClientPromise = null;
|
|
193
|
+
const buildKrakenClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
194
|
+
if (krakenClient) {
|
|
195
|
+
return krakenClient;
|
|
196
|
+
}
|
|
197
|
+
if (!krakenClientPromise) {
|
|
198
|
+
krakenClientPromise = (() => __awaiter(void 0, void 0, void 0, function* () {
|
|
199
|
+
const KRAKEN_API_KEY = yield secret_manager_client_1.secretManagerClient.getSecretValue("KRAKEN_API_KEY");
|
|
200
|
+
if (!KRAKEN_API_KEY) {
|
|
201
|
+
throw new common_1.SecretManagerError();
|
|
202
|
+
}
|
|
203
|
+
const KRAKEN_API_SECRET = yield secret_manager_client_1.secretManagerClient.getSecretValue("KRAKEN_API_SECRET");
|
|
204
|
+
if (!KRAKEN_API_SECRET) {
|
|
205
|
+
throw new common_1.SecretManagerError();
|
|
206
|
+
}
|
|
207
|
+
krakenClient = new KrakenClient(KRAKEN_API_KEY, KRAKEN_API_SECRET, process.env.RIO_ENV);
|
|
208
|
+
return krakenClient;
|
|
209
|
+
}))();
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
return yield krakenClientPromise;
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
krakenClientPromise = null;
|
|
216
|
+
throw err;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
exports.buildKrakenClient = buildKrakenClient;
|
package/build/index.d.ts
CHANGED
|
@@ -148,6 +148,7 @@ export * from "./clients/circle-client";
|
|
|
148
148
|
export * from "./clients/coincover-client";
|
|
149
149
|
export * from "./clients/google-sheets-api-client";
|
|
150
150
|
export * from "./clients/binance-client";
|
|
151
|
+
export * from "./clients/kraken-client";
|
|
151
152
|
export * from "./helpers/get-user-helper";
|
|
152
153
|
export * from "./helpers/get-processor-fees";
|
|
153
154
|
export * from "./helpers/get-network-fees";
|
package/build/index.js
CHANGED
|
@@ -164,6 +164,7 @@ __exportStar(require("./clients/circle-client"), exports);
|
|
|
164
164
|
__exportStar(require("./clients/coincover-client"), exports);
|
|
165
165
|
__exportStar(require("./clients/google-sheets-api-client"), exports);
|
|
166
166
|
__exportStar(require("./clients/binance-client"), exports);
|
|
167
|
+
__exportStar(require("./clients/kraken-client"), exports);
|
|
167
168
|
__exportStar(require("./helpers/get-user-helper"), exports);
|
|
168
169
|
__exportStar(require("./helpers/get-processor-fees"), exports);
|
|
169
170
|
__exportStar(require("./helpers/get-network-fees"), exports);
|
|
@@ -19,6 +19,8 @@ interface ExternalTradeAttrs {
|
|
|
19
19
|
associatedMidmarketPrice?: number;
|
|
20
20
|
status: ExternalTradeStatus;
|
|
21
21
|
fxTradeId?: string;
|
|
22
|
+
internalTradeId?: string;
|
|
23
|
+
coinbaseConversionId?: string;
|
|
22
24
|
providerOptions?: {
|
|
23
25
|
emarkets?: {
|
|
24
26
|
settlementType?: EmarketsSettlementType;
|
|
@@ -60,6 +62,8 @@ interface ExternalTradeDoc extends Document {
|
|
|
60
62
|
associatedMidmarketPrice?: number;
|
|
61
63
|
status: ExternalTradeStatus;
|
|
62
64
|
fxTradeId?: string;
|
|
65
|
+
internalTradeId?: string;
|
|
66
|
+
coinbaseConversionId?: string;
|
|
63
67
|
providerOptions?: {
|
|
64
68
|
emarkets?: {
|
|
65
69
|
settlementType?: EmarketsSettlementType;
|
|
@@ -19,6 +19,7 @@ interface InternalTradeAttrs {
|
|
|
19
19
|
amountFilled?: number;
|
|
20
20
|
limitPrice?: number;
|
|
21
21
|
coinbaseConversionId?: string;
|
|
22
|
+
externalTradeId?: string;
|
|
22
23
|
}
|
|
23
24
|
interface InternalTradeDoc extends mongoose.Document {
|
|
24
25
|
id: string;
|
|
@@ -40,6 +41,7 @@ interface InternalTradeDoc extends mongoose.Document {
|
|
|
40
41
|
amountFilled?: number;
|
|
41
42
|
limitPrice?: number;
|
|
42
43
|
coinbaseConversionId?: string;
|
|
44
|
+
externalTradeId?: string;
|
|
43
45
|
}
|
|
44
46
|
interface InternalTradeModel extends mongoose.Model<InternalTradeDoc> {
|
|
45
47
|
build(attrs: InternalTradeAttrs): HydratedDocument<InternalTradeDoc>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riocrypto/common-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2843",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@google-cloud/secret-manager": "^5.6.0",
|
|
29
29
|
"@google-cloud/storage": "^7.19.0",
|
|
30
30
|
"@hyperdx/node-opentelemetry": "^0.10.3",
|
|
31
|
-
"@riocrypto/common": "1.0.
|
|
31
|
+
"@riocrypto/common": "1.0.2647",
|
|
32
32
|
"@slack/web-api": "^7.15.0",
|
|
33
33
|
"@types/express": "^4.17.25",
|
|
34
34
|
"axios": "1.16.0",
|