@7kprotocol/sdk-ts 3.4.2-beta.4 → 3.4.2-beta.5
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/README.md +151 -4
- package/lib/cjs/constants/_7k.js +5 -1
- package/lib/cjs/constants/sui.js +4 -0
- package/lib/cjs/features/metaAg/index.js +243 -0
- package/lib/cjs/features/metaAg/providers/bluefin.js +69 -0
- package/lib/cjs/features/metaAg/providers/cetus.js +67 -0
- package/lib/cjs/features/metaAg/providers/flowx.js +56 -0
- package/lib/cjs/index.js +6 -1
- package/lib/cjs/types/constants/_7k.d.ts +4 -0
- package/lib/cjs/types/constants/_7k.d.ts.map +1 -1
- package/lib/cjs/types/constants/sui.d.ts +2 -0
- package/lib/cjs/types/constants/sui.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/index.d.ts +28 -0
- package/lib/cjs/types/features/metaAg/index.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/providers/bluefin.d.ts +11 -0
- package/lib/cjs/types/features/metaAg/providers/bluefin.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/providers/cetus.d.ts +13 -0
- package/lib/cjs/types/features/metaAg/providers/cetus.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/providers/flowx.d.ts +14 -0
- package/lib/cjs/types/features/metaAg/providers/flowx.d.ts.map +1 -0
- package/lib/cjs/types/index.d.ts +4 -1
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/metaAg.js +12 -0
- package/lib/cjs/types/types/metaAg.d.ts +127 -0
- package/lib/cjs/types/types/metaAg.d.ts.map +1 -0
- package/lib/cjs/types/utils/ObjectCache.d.ts +87 -0
- package/lib/cjs/types/utils/ObjectCache.d.ts.map +1 -0
- package/lib/cjs/types/utils/SuiClientUtils.d.ts +15 -0
- package/lib/cjs/types/utils/SuiClientUtils.d.ts.map +1 -0
- package/lib/cjs/types/utils/condition.d.ts +2 -0
- package/lib/cjs/types/utils/condition.d.ts.map +1 -0
- package/lib/cjs/utils/ObjectCache.js +273 -0
- package/lib/cjs/utils/SuiClientUtils.js +50 -0
- package/lib/cjs/utils/condition.js +8 -0
- package/lib/esm/constants/_7k.js +4 -0
- package/lib/esm/constants/sui.js +1 -0
- package/lib/esm/features/metaAg/index.js +209 -0
- package/lib/esm/features/metaAg/providers/bluefin.js +67 -0
- package/lib/esm/features/metaAg/providers/cetus.js +66 -0
- package/lib/esm/features/metaAg/providers/flowx.js +56 -0
- package/lib/esm/index.mjs +5 -1
- package/lib/esm/types/constants/_7k.d.ts +4 -0
- package/lib/esm/types/constants/_7k.d.ts.map +1 -1
- package/lib/esm/types/constants/sui.d.ts +2 -0
- package/lib/esm/types/constants/sui.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/index.d.ts +28 -0
- package/lib/esm/types/features/metaAg/index.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/providers/bluefin.d.ts +11 -0
- package/lib/esm/types/features/metaAg/providers/bluefin.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/providers/cetus.d.ts +13 -0
- package/lib/esm/types/features/metaAg/providers/cetus.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/providers/flowx.d.ts +14 -0
- package/lib/esm/types/features/metaAg/providers/flowx.d.ts.map +1 -0
- package/lib/esm/types/index.d.ts +4 -1
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/metaAg.js +8 -0
- package/lib/esm/types/types/metaAg.d.ts +127 -0
- package/lib/esm/types/types/metaAg.d.ts.map +1 -0
- package/lib/esm/types/utils/ObjectCache.d.ts +87 -0
- package/lib/esm/types/utils/ObjectCache.d.ts.map +1 -0
- package/lib/esm/types/utils/SuiClientUtils.d.ts +15 -0
- package/lib/esm/types/utils/SuiClientUtils.d.ts.map +1 -0
- package/lib/esm/types/utils/condition.d.ts +2 -0
- package/lib/esm/types/utils/condition.d.ts.map +1 -0
- package/lib/esm/utils/ObjectCache.js +250 -0
- package/lib/esm/utils/SuiClientUtils.js +34 -0
- package/lib/esm/utils/condition.js +5 -0
- package/package.json +8 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var _InMemoryObjectCache_caches, _CustomObjectCache_client, _CustomObjectCache_cache, _CustomObjectCache_onEffects;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CustomObjectCache = exports.InMemoryObjectCache = exports.AsyncCache = void 0;
|
|
16
|
+
const utils_1 = require("@mysten/sui/utils");
|
|
17
|
+
class AsyncCache {
|
|
18
|
+
async getObject(id) {
|
|
19
|
+
const [owned, shared] = await Promise.all([
|
|
20
|
+
this.get("OwnedObject", id),
|
|
21
|
+
this.get("SharedOrImmutableObject", id),
|
|
22
|
+
]);
|
|
23
|
+
return owned ?? shared ?? null;
|
|
24
|
+
}
|
|
25
|
+
async getObjects(ids) {
|
|
26
|
+
return Promise.all(ids.map((id) => this.getObject(id)));
|
|
27
|
+
}
|
|
28
|
+
async addObject(object) {
|
|
29
|
+
if (object.owner) {
|
|
30
|
+
await this.set("OwnedObject", object.objectId, object);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
await this.set("SharedOrImmutableObject", object.objectId, object);
|
|
34
|
+
}
|
|
35
|
+
return object;
|
|
36
|
+
}
|
|
37
|
+
async addObjects(objects) {
|
|
38
|
+
await Promise.all(objects.map(async (object) => this.addObject(object)));
|
|
39
|
+
}
|
|
40
|
+
async deleteObject(id) {
|
|
41
|
+
await Promise.all([
|
|
42
|
+
this.delete("OwnedObject", id),
|
|
43
|
+
this.delete("SharedOrImmutableObject", id),
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
async deleteObjects(ids) {
|
|
47
|
+
await Promise.all(ids.map((id) => this.deleteObject(id)));
|
|
48
|
+
}
|
|
49
|
+
async getMoveFunctionDefinition(ref) {
|
|
50
|
+
const functionName = `${(0, utils_1.normalizeSuiAddress)(ref.package)}::${ref.module}::${ref.function}`;
|
|
51
|
+
return this.get("MoveFunction", functionName);
|
|
52
|
+
}
|
|
53
|
+
async addMoveFunctionDefinition(functionEntry) {
|
|
54
|
+
const pkg = (0, utils_1.normalizeSuiAddress)(functionEntry.package);
|
|
55
|
+
const functionName = `${pkg}::${functionEntry.module}::${functionEntry.function}`;
|
|
56
|
+
const entry = {
|
|
57
|
+
...functionEntry,
|
|
58
|
+
package: pkg,
|
|
59
|
+
};
|
|
60
|
+
await this.set("MoveFunction", functionName, entry);
|
|
61
|
+
return entry;
|
|
62
|
+
}
|
|
63
|
+
async deleteMoveFunctionDefinition(ref) {
|
|
64
|
+
const functionName = `${(0, utils_1.normalizeSuiAddress)(ref.package)}::${ref.module}::${ref.function}`;
|
|
65
|
+
await this.delete("MoveFunction", functionName);
|
|
66
|
+
}
|
|
67
|
+
async getCustom(key) {
|
|
68
|
+
return this.get("Custom", key);
|
|
69
|
+
}
|
|
70
|
+
async setCustom(key, value) {
|
|
71
|
+
return this.set("Custom", key, value);
|
|
72
|
+
}
|
|
73
|
+
async deleteCustom(key) {
|
|
74
|
+
return this.delete("Custom", key);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.AsyncCache = AsyncCache;
|
|
78
|
+
class InMemoryObjectCache extends AsyncCache {
|
|
79
|
+
constructor() {
|
|
80
|
+
super(...arguments);
|
|
81
|
+
_InMemoryObjectCache_caches.set(this, {
|
|
82
|
+
OwnedObject: new Map(),
|
|
83
|
+
SharedOrImmutableObject: new Map(),
|
|
84
|
+
MoveFunction: new Map(),
|
|
85
|
+
Custom: new Map(),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async get(type, key) {
|
|
89
|
+
return __classPrivateFieldGet(this, _InMemoryObjectCache_caches, "f")[type].get(key) ?? null;
|
|
90
|
+
}
|
|
91
|
+
async set(type, key, value) {
|
|
92
|
+
__classPrivateFieldGet(this, _InMemoryObjectCache_caches, "f")[type].set(key, value);
|
|
93
|
+
}
|
|
94
|
+
async delete(type, key) {
|
|
95
|
+
__classPrivateFieldGet(this, _InMemoryObjectCache_caches, "f")[type].delete(key);
|
|
96
|
+
}
|
|
97
|
+
async clear(type) {
|
|
98
|
+
if (type) {
|
|
99
|
+
__classPrivateFieldGet(this, _InMemoryObjectCache_caches, "f")[type].clear();
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
for (const cache of Object.values(__classPrivateFieldGet(this, _InMemoryObjectCache_caches, "f"))) {
|
|
103
|
+
cache.clear();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.InMemoryObjectCache = InMemoryObjectCache;
|
|
109
|
+
_InMemoryObjectCache_caches = new WeakMap();
|
|
110
|
+
class CustomObjectCache {
|
|
111
|
+
constructor({ cache = new InMemoryObjectCache(), onEffects, client, }) {
|
|
112
|
+
_CustomObjectCache_client.set(this, void 0);
|
|
113
|
+
_CustomObjectCache_cache.set(this, void 0);
|
|
114
|
+
_CustomObjectCache_onEffects.set(this, void 0);
|
|
115
|
+
__classPrivateFieldSet(this, _CustomObjectCache_client, client, "f");
|
|
116
|
+
__classPrivateFieldSet(this, _CustomObjectCache_cache, cache, "f");
|
|
117
|
+
__classPrivateFieldSet(this, _CustomObjectCache_onEffects, onEffects, "f");
|
|
118
|
+
}
|
|
119
|
+
async applyCache(transactionData, unresolvedObjects) {
|
|
120
|
+
const cached = (await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").getObjects(unresolvedObjects)).filter((obj) => obj !== null);
|
|
121
|
+
const byId = new Map(cached.map((obj) => [obj.objectId, obj]));
|
|
122
|
+
const unresolved = [];
|
|
123
|
+
for (const input of transactionData.inputs) {
|
|
124
|
+
if (!input.UnresolvedObject) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const cached = byId.get(input.UnresolvedObject.objectId);
|
|
128
|
+
if (!cached) {
|
|
129
|
+
unresolved.push(input.UnresolvedObject.objectId);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (cached.initialSharedVersion &&
|
|
133
|
+
!input.UnresolvedObject.initialSharedVersion) {
|
|
134
|
+
input.UnresolvedObject.initialSharedVersion =
|
|
135
|
+
cached.initialSharedVersion;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
if (cached.version && !input.UnresolvedObject.version) {
|
|
139
|
+
input.UnresolvedObject.version = cached.version;
|
|
140
|
+
}
|
|
141
|
+
if (cached.digest && !input.UnresolvedObject.digest) {
|
|
142
|
+
input.UnresolvedObject.digest = cached.digest;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return unresolved;
|
|
147
|
+
}
|
|
148
|
+
async resolveObjects(transactionData, unresolved) {
|
|
149
|
+
const unresolvedObjects = await this.applyCache(transactionData, unresolved);
|
|
150
|
+
if (unresolvedObjects.length === 0) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const dedup = [...new Set(unresolvedObjects)];
|
|
154
|
+
const res = await __classPrivateFieldGet(this, _CustomObjectCache_client, "f").multiGetObjects({
|
|
155
|
+
ids: dedup,
|
|
156
|
+
options: {
|
|
157
|
+
showOwner: true,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
const objects = [];
|
|
161
|
+
for (const obj of res || []) {
|
|
162
|
+
if (!obj.data) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const owner = obj.data.owner;
|
|
166
|
+
const initialSharedVersion = owner && typeof owner === "object" && "Shared" in owner
|
|
167
|
+
? owner.Shared.initial_shared_version
|
|
168
|
+
: null;
|
|
169
|
+
const ownerAddress = owner && typeof owner === "object" && "AddressOwner" in owner
|
|
170
|
+
? owner.AddressOwner
|
|
171
|
+
: null;
|
|
172
|
+
const cached = {
|
|
173
|
+
objectId: obj.data.objectId,
|
|
174
|
+
version: obj.data.version,
|
|
175
|
+
digest: obj.data.digest,
|
|
176
|
+
initialSharedVersion,
|
|
177
|
+
owner: ownerAddress,
|
|
178
|
+
};
|
|
179
|
+
objects.push(cached);
|
|
180
|
+
}
|
|
181
|
+
await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").addObjects(objects);
|
|
182
|
+
return await this.applyCache(transactionData, unresolvedObjects);
|
|
183
|
+
}
|
|
184
|
+
asPlugin() {
|
|
185
|
+
return async (transactionData, _options, next) => {
|
|
186
|
+
const unresolvedObjects = transactionData.inputs
|
|
187
|
+
.filter((input) => input.UnresolvedObject)
|
|
188
|
+
.map((input) => input.UnresolvedObject.objectId);
|
|
189
|
+
// if object is not in cache yet, fetch from RPC and save to cache and resolve all objects
|
|
190
|
+
await this.resolveObjects(transactionData, unresolvedObjects);
|
|
191
|
+
await Promise.all(transactionData.commands.map(async (commands) => {
|
|
192
|
+
if (commands.MoveCall) {
|
|
193
|
+
const def = await this.getMoveFunctionDefinition({
|
|
194
|
+
package: commands.MoveCall.package,
|
|
195
|
+
module: commands.MoveCall.module,
|
|
196
|
+
function: commands.MoveCall.function,
|
|
197
|
+
});
|
|
198
|
+
if (def) {
|
|
199
|
+
commands.MoveCall._argumentTypes = def.parameters;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}));
|
|
203
|
+
await next();
|
|
204
|
+
await Promise.all(transactionData.commands.map(async (commands) => {
|
|
205
|
+
if (commands.MoveCall?._argumentTypes) {
|
|
206
|
+
await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").addMoveFunctionDefinition({
|
|
207
|
+
package: commands.MoveCall.package,
|
|
208
|
+
module: commands.MoveCall.module,
|
|
209
|
+
function: commands.MoveCall.function,
|
|
210
|
+
parameters: commands.MoveCall._argumentTypes,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}));
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async clear() {
|
|
217
|
+
await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").clear();
|
|
218
|
+
}
|
|
219
|
+
async getMoveFunctionDefinition(ref) {
|
|
220
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").getMoveFunctionDefinition(ref);
|
|
221
|
+
}
|
|
222
|
+
async getObjects(ids) {
|
|
223
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").getObjects(ids);
|
|
224
|
+
}
|
|
225
|
+
async deleteObjects(ids) {
|
|
226
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").deleteObjects(ids);
|
|
227
|
+
}
|
|
228
|
+
async clearOwnedObjects() {
|
|
229
|
+
await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").clear("OwnedObject");
|
|
230
|
+
}
|
|
231
|
+
async clearCustom() {
|
|
232
|
+
await __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").clear("Custom");
|
|
233
|
+
}
|
|
234
|
+
async getCustom(key) {
|
|
235
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").getCustom(key);
|
|
236
|
+
}
|
|
237
|
+
async setCustom(key, value) {
|
|
238
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").setCustom(key, value);
|
|
239
|
+
}
|
|
240
|
+
async deleteCustom(key) {
|
|
241
|
+
return __classPrivateFieldGet(this, _CustomObjectCache_cache, "f").deleteCustom(key);
|
|
242
|
+
}
|
|
243
|
+
async applyEffects(effects) {
|
|
244
|
+
if (!effects.V2) {
|
|
245
|
+
throw new Error(`Unsupported transaction effects version ${effects.$kind}`);
|
|
246
|
+
}
|
|
247
|
+
const { lamportVersion, changedObjects } = effects.V2;
|
|
248
|
+
const deletedIds = [];
|
|
249
|
+
const addedObjects = [];
|
|
250
|
+
changedObjects.forEach(([id, change]) => {
|
|
251
|
+
if (change.outputState.NotExist) {
|
|
252
|
+
deletedIds.push(id);
|
|
253
|
+
}
|
|
254
|
+
else if (change.outputState.ObjectWrite) {
|
|
255
|
+
const [digest, owner] = change.outputState.ObjectWrite;
|
|
256
|
+
addedObjects.push({
|
|
257
|
+
objectId: id,
|
|
258
|
+
digest,
|
|
259
|
+
version: lamportVersion,
|
|
260
|
+
owner: owner.AddressOwner ?? owner.ObjectOwner ?? null,
|
|
261
|
+
initialSharedVersion: owner.Shared?.initialSharedVersion ?? null,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
await Promise.all([
|
|
266
|
+
__classPrivateFieldGet(this, _CustomObjectCache_cache, "f").addObjects(addedObjects),
|
|
267
|
+
__classPrivateFieldGet(this, _CustomObjectCache_cache, "f").deleteObjects(deletedIds),
|
|
268
|
+
__classPrivateFieldGet(this, _CustomObjectCache_onEffects, "f")?.call(this, effects),
|
|
269
|
+
]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
exports.CustomObjectCache = CustomObjectCache;
|
|
273
|
+
_CustomObjectCache_client = new WeakMap(), _CustomObjectCache_cache = new WeakMap(), _CustomObjectCache_onEffects = new WeakMap();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _SuiClientUtils_devInspectCache;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SuiClientUtils = void 0;
|
|
16
|
+
const transactions_1 = require("@mysten/sui/transactions");
|
|
17
|
+
const ObjectCache_1 = require("./ObjectCache");
|
|
18
|
+
/**
|
|
19
|
+
* Utility class for interacting with Sui blockchain coins
|
|
20
|
+
*/
|
|
21
|
+
class SuiClientUtils {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new instance of SuiClientUtils
|
|
24
|
+
* @param client - The Sui client instance to use for blockchain interactions
|
|
25
|
+
*/
|
|
26
|
+
constructor(client) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
_SuiClientUtils_devInspectCache.set(this, void 0);
|
|
29
|
+
this.devInspectTransactionBlock = async (params) => {
|
|
30
|
+
if (params.transactionBlock instanceof transactions_1.Transaction) {
|
|
31
|
+
params.transactionBlock.addBuildPlugin(__classPrivateFieldGet(this, _SuiClientUtils_devInspectCache, "f").asPlugin());
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const res = await this.client.devInspectTransactionBlock(params);
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// clear all cache if devInspectTransactionBlock fails
|
|
39
|
+
await __classPrivateFieldGet(this, _SuiClientUtils_devInspectCache, "f").clear();
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
await __classPrivateFieldGet(this, _SuiClientUtils_devInspectCache, "f").clearOwnedObjects();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
__classPrivateFieldSet(this, _SuiClientUtils_devInspectCache, new ObjectCache_1.CustomObjectCache({ client: this.client }), "f");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.SuiClientUtils = SuiClientUtils;
|
|
50
|
+
_SuiClientUtils_devInspectCache = new WeakMap();
|
package/lib/esm/constants/_7k.js
CHANGED
|
@@ -7,3 +7,7 @@ export const _7K_CONFIG = "0x47442a93f7727d188ba7cb71031170d1786af70013cb7ad5115
|
|
|
7
7
|
//legacy v3: "0x0f8fc23dbcc9362b72c7a4c5aa53fcefa02ebfbb83a812c8c262ccd2c076d9ee";
|
|
8
8
|
export const _7K_VAULT = "0x442ad50389ed5cda6f7a6f5a7ae6361a4c05ef1d9fb2e54fbba5a268d690bfe6";
|
|
9
9
|
//legacy v3: "0x39a3c55742c0e011b6f65548e73cf589e1ae5e82dbfab449ca57f24c3bcd9514";
|
|
10
|
+
export const _7K_META_PUBLISHED_AT = "0x17c0b1f7a6ad73f51268f16b8c06c049eecc2f28a270cdd29c06e3d2dea23302";
|
|
11
|
+
export const _7K_META_PACKAGE_ID = "0x17c0b1f7a6ad73f51268f16b8c06c049eecc2f28a270cdd29c06e3d2dea23302";
|
|
12
|
+
export const _7K_META_VAULT = "0x9a8abd32fe5721307ce3b697cf982ee84e9ffbd58d667a4a199f1683c1a3d23c";
|
|
13
|
+
export const _7K_META_CONFIG = "0xbbb3a51877ed9b492f26f4e2181811cfb2bd70c532f6f7621263d122d5e96b56";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SUI_ADDRESS_ZERO = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client";
|
|
2
|
+
import { coinWithBalance, Transaction, } from "@mysten/sui/transactions";
|
|
3
|
+
import { _7K_META_CONFIG, _7K_META_PACKAGE_ID, _7K_META_PUBLISHED_AT, _7K_META_VAULT, } from "../../constants/_7k";
|
|
4
|
+
import { SUI_ADDRESS_ZERO } from "../../constants/sui";
|
|
5
|
+
import { EProvider, } from "../../types/metaAg";
|
|
6
|
+
import { assert } from "../../utils/condition";
|
|
7
|
+
import { SuiClientUtils } from "../../utils/SuiClientUtils";
|
|
8
|
+
import { getExpectedReturn } from "../swap/buildTx";
|
|
9
|
+
import { BluefinProvider } from "./providers/bluefin";
|
|
10
|
+
const HERMES_API = "https://hermes.pyth.network";
|
|
11
|
+
const DEFAULT_PROVIDERS = {
|
|
12
|
+
[EProvider.BLUEFIN7K]: {},
|
|
13
|
+
[EProvider.FLOWX]: {},
|
|
14
|
+
[EProvider.CETUS]: {},
|
|
15
|
+
};
|
|
16
|
+
export class MetaAg {
|
|
17
|
+
client;
|
|
18
|
+
providers = {};
|
|
19
|
+
inspector;
|
|
20
|
+
options;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.options = {
|
|
23
|
+
providers: options?.providers ?? DEFAULT_PROVIDERS,
|
|
24
|
+
slippageBps: options?.slippageBps ?? 100,
|
|
25
|
+
fullnodeUrl: options?.fullnodeUrl ?? getFullnodeUrl("mainnet"),
|
|
26
|
+
hermesApi: options?.hermesApi ?? HERMES_API,
|
|
27
|
+
partner: options?.partner ?? SUI_ADDRESS_ZERO,
|
|
28
|
+
partnerCommissionBps: options?.partnerCommissionBps ?? 0,
|
|
29
|
+
tipBps: options?.tipBps ?? 0,
|
|
30
|
+
};
|
|
31
|
+
this.client = new SuiClient({
|
|
32
|
+
url: this.options.fullnodeUrl,
|
|
33
|
+
});
|
|
34
|
+
this.inspector = new SuiClientUtils(this.client);
|
|
35
|
+
}
|
|
36
|
+
async _getProvider(provider) {
|
|
37
|
+
const p = this.providers[provider];
|
|
38
|
+
if (p)
|
|
39
|
+
return p;
|
|
40
|
+
switch (provider) {
|
|
41
|
+
case EProvider.BLUEFIN7K:
|
|
42
|
+
const bluefinOptions = this.options.providers[provider];
|
|
43
|
+
assert(!!bluefinOptions, `Provider not found: ${provider}`);
|
|
44
|
+
this.providers[EProvider.BLUEFIN7K] = new BluefinProvider(bluefinOptions, this.options, this.client);
|
|
45
|
+
break;
|
|
46
|
+
case EProvider.FLOWX:
|
|
47
|
+
const flowxOptions = this.options.providers[provider];
|
|
48
|
+
assert(!!flowxOptions, `Provider not found: ${provider}`);
|
|
49
|
+
const { FlowxProvider } = await import("./providers/flowx").catch(catchImportError(EProvider.FLOWX));
|
|
50
|
+
this.providers[EProvider.FLOWX] = new FlowxProvider(flowxOptions, this.options, this.client);
|
|
51
|
+
break;
|
|
52
|
+
case EProvider.CETUS:
|
|
53
|
+
const cetusOptions = this.options.providers[provider];
|
|
54
|
+
assert(!!cetusOptions, `Provider not found: ${provider}`);
|
|
55
|
+
const { CetusProvider } = await import("./providers/cetus").catch(catchImportError(EProvider.CETUS));
|
|
56
|
+
this.providers[EProvider.CETUS] = new CetusProvider(cetusOptions, this.options, this.client);
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Provider not supported: ${provider}`);
|
|
60
|
+
}
|
|
61
|
+
return this.providers[provider];
|
|
62
|
+
}
|
|
63
|
+
async _simulate(provider, quote, simulation) {
|
|
64
|
+
try {
|
|
65
|
+
const tx = new Transaction();
|
|
66
|
+
const id = quote.id;
|
|
67
|
+
const coinOut = await provider.swap({
|
|
68
|
+
quote,
|
|
69
|
+
coinIn: coinWithBalance({
|
|
70
|
+
balance: BigInt(quote.amountIn),
|
|
71
|
+
type: quote.coinTypeIn,
|
|
72
|
+
}),
|
|
73
|
+
signer: simulation.sender,
|
|
74
|
+
tx,
|
|
75
|
+
});
|
|
76
|
+
tx.add(metaSettle(quote, coinOut, 10000, this.options.tipBps, this.options.partner, this.options.partnerCommissionBps));
|
|
77
|
+
tx.transferObjects([coinOut], simulation.sender);
|
|
78
|
+
const res = await timeout(() => this.inspector.devInspectTransactionBlock({
|
|
79
|
+
sender: simulation.sender,
|
|
80
|
+
transactionBlock: tx,
|
|
81
|
+
}), simulation.timeout ?? 2000, `simulation for ${provider.kind} provider with id ${id}`);
|
|
82
|
+
const amountOut = extractAmountOutWrapper(res.events);
|
|
83
|
+
return {
|
|
84
|
+
id,
|
|
85
|
+
simulatedAmountOut: amountOut,
|
|
86
|
+
gasUsed: res.effects.gasUsed,
|
|
87
|
+
provider: provider.kind,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.warn(`Failed to simulate ${provider.kind}: `, error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async _quote(provider, options, simulation) {
|
|
95
|
+
const quote = await timeout(() => provider.quote(options), options.timeout ?? 2000, `quote for ${provider.kind} provider from ${options.coinInType} to ${options.coinOutType}`);
|
|
96
|
+
if (simulation) {
|
|
97
|
+
if (simulation.onSimulated) {
|
|
98
|
+
this._simulate(provider, quote, simulation).then((payload) => {
|
|
99
|
+
payload && simulation.onSimulated?.(payload);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const updated = await this._simulate(provider, quote, simulation);
|
|
104
|
+
quote.simulatedAmountOut = updated?.simulatedAmountOut;
|
|
105
|
+
quote.gasUsed = updated?.gasUsed;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return quote;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get quotes from all providers
|
|
112
|
+
* @param options - quote options
|
|
113
|
+
* @param simulation - if present, the quote will be simulated
|
|
114
|
+
* @returns quotes from all providers
|
|
115
|
+
*/
|
|
116
|
+
async quote(options, simulation) {
|
|
117
|
+
const quotes = await Promise.allSettled(Object.keys(this.options.providers).map(async (provider) => {
|
|
118
|
+
const p = await this._getProvider(provider);
|
|
119
|
+
return this._quote(p, options, simulation);
|
|
120
|
+
}));
|
|
121
|
+
return quotes
|
|
122
|
+
.map((quote) => quote.status === "fulfilled"
|
|
123
|
+
? quote.value
|
|
124
|
+
: (console.log(quote.reason), null))
|
|
125
|
+
.filter((quote) => quote !== null);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Build transaction from quote
|
|
129
|
+
* @param options - build tx options
|
|
130
|
+
* @param slippageBps - slippage bps if not specified, fallback to global slippage bps, if none of them specified, default to 100
|
|
131
|
+
* @returns coin out object, you must consume it by transferObjects, or other sub sequence commands
|
|
132
|
+
*/
|
|
133
|
+
async swap(options, slippageBps) {
|
|
134
|
+
const provider = await this._getProvider(options.quote.provider);
|
|
135
|
+
assert(!!provider, `Provider not found: ${options.quote.provider}`);
|
|
136
|
+
const coinOut = await provider.swap(options);
|
|
137
|
+
options.tx.add(metaSettle(options.quote, coinOut, slippageBps ?? this.options.slippageBps ?? 100, this.options.tipBps, this.options.partner, this.options.partnerCommissionBps));
|
|
138
|
+
return coinOut;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* this settlement does not charge commission fee for partner, since all integrated aggregators already charge commission fee for partner
|
|
143
|
+
* @param quote Meta Aggregator Quote
|
|
144
|
+
* @param coinOut Coin Out Object
|
|
145
|
+
* @param slippageBps Slippage Bps
|
|
146
|
+
* @param tipBps Tip Bps default = 0
|
|
147
|
+
* @param partner address of partner for analytic default is zero address
|
|
148
|
+
*/
|
|
149
|
+
const metaSettle = (quote, coinOut, slippageBps = 100, tipBps = 0, partner, commissionBps = 0) => {
|
|
150
|
+
return (tx) => {
|
|
151
|
+
const { minAmount, expectedAmount } = getExpectedReturn(quote.rawAmountOut, slippageBps, commissionBps, // use for calculate expected amount out
|
|
152
|
+
tipBps);
|
|
153
|
+
if (tipBps > 0) {
|
|
154
|
+
tx.moveCall({
|
|
155
|
+
target: `${_7K_META_PUBLISHED_AT}::vault::collect_tip`,
|
|
156
|
+
typeArguments: [quote.coinTypeOut],
|
|
157
|
+
arguments: [
|
|
158
|
+
tx.object(_7K_META_VAULT),
|
|
159
|
+
tx.object(_7K_META_CONFIG),
|
|
160
|
+
coinOut,
|
|
161
|
+
tx.pure.u64(tipBps),
|
|
162
|
+
],
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
tx.moveCall({
|
|
166
|
+
target: `${_7K_META_PUBLISHED_AT}::settle::settle`,
|
|
167
|
+
typeArguments: [quote.coinTypeIn, quote.coinTypeOut],
|
|
168
|
+
arguments: [
|
|
169
|
+
tx.object(_7K_META_CONFIG),
|
|
170
|
+
tx.object(_7K_META_VAULT),
|
|
171
|
+
tx.pure.u64(quote.amountIn),
|
|
172
|
+
coinOut,
|
|
173
|
+
tx.pure.u64(minAmount),
|
|
174
|
+
tx.pure.u64(expectedAmount),
|
|
175
|
+
tx.pure.option("address", partner),
|
|
176
|
+
tx.pure.u64(0), // commission must be 0 since all integrated aggregators already charge commission fee for partner
|
|
177
|
+
tx.pure.u64(0), // ps
|
|
178
|
+
],
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
const extractAmountOutWrapper = (events) => {
|
|
183
|
+
const swapEvent = events
|
|
184
|
+
.filter((event) => event.type === `${_7K_META_PACKAGE_ID}::settle::Swap`)
|
|
185
|
+
?.pop();
|
|
186
|
+
return swapEvent?.parsedJson?.amount_out;
|
|
187
|
+
};
|
|
188
|
+
const catchImportError = (provider) => {
|
|
189
|
+
return (e) => {
|
|
190
|
+
const map = {
|
|
191
|
+
[EProvider.CETUS]: "@cetusprotocol/aggregator-sdk",
|
|
192
|
+
[EProvider.FLOWX]: "@flowx-finance/sdk",
|
|
193
|
+
[EProvider.BLUEFIN7K]: "@7kprotocol/sdk-ts",
|
|
194
|
+
};
|
|
195
|
+
console.warn(`Please install ${map[provider]} to use ${provider} provider`);
|
|
196
|
+
throw e;
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
const timeout = async (fn, timeout, msg) => {
|
|
200
|
+
if (timeout <= 0)
|
|
201
|
+
return fn();
|
|
202
|
+
return new Promise((resolve, reject) => {
|
|
203
|
+
const timer = setTimeout(() => reject(new Error(`Timeout ${msg ?? "operation"}`)), timeout);
|
|
204
|
+
fn()
|
|
205
|
+
.then(resolve)
|
|
206
|
+
.catch(reject)
|
|
207
|
+
.finally(() => clearTimeout(timer));
|
|
208
|
+
});
|
|
209
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SuiPriceServiceConnection, SuiPythClient, } from "@pythnetwork/pyth-sui-js";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
import { Config } from "../../../config";
|
|
4
|
+
import { API_ENDPOINTS } from "../../../constants/apiEndpoints";
|
|
5
|
+
import { SUI_ADDRESS_ZERO } from "../../../constants/sui";
|
|
6
|
+
import { EProvider, } from "../../../types/metaAg";
|
|
7
|
+
import { assert } from "../../../utils/condition";
|
|
8
|
+
import { getExpectedReturn } from "../../swap/buildTx";
|
|
9
|
+
import { buildTxV2 } from "../../swap/buildTxV2";
|
|
10
|
+
import { getQuote } from "../../swap/getQuote";
|
|
11
|
+
const WORMHOLE_STATE_ID = "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c";
|
|
12
|
+
const PYTH_STATE_ID = "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8";
|
|
13
|
+
export class BluefinProvider {
|
|
14
|
+
options;
|
|
15
|
+
metaOptions;
|
|
16
|
+
kind = EProvider.BLUEFIN7K;
|
|
17
|
+
constructor(options, metaOptions, client) {
|
|
18
|
+
this.options = options;
|
|
19
|
+
this.metaOptions = metaOptions;
|
|
20
|
+
const pythClient = new SuiPythClient(client, PYTH_STATE_ID, WORMHOLE_STATE_ID);
|
|
21
|
+
const pythConnection = new SuiPriceServiceConnection(this.metaOptions.hermesApi);
|
|
22
|
+
options.apiKey && Config.setApiKey(options.apiKey);
|
|
23
|
+
Config.setSuiClient(client);
|
|
24
|
+
Config.setPythClient(pythClient);
|
|
25
|
+
Config.setPythConnection(pythConnection);
|
|
26
|
+
}
|
|
27
|
+
async quote(options) {
|
|
28
|
+
const quote = await getQuote({
|
|
29
|
+
amountIn: options.amountIn,
|
|
30
|
+
tokenIn: options.coinInType,
|
|
31
|
+
tokenOut: options.coinOutType,
|
|
32
|
+
api: this.options.api || API_ENDPOINTS.MAIN,
|
|
33
|
+
sources: this.options.sources,
|
|
34
|
+
maxPaths: this.options.maxPaths,
|
|
35
|
+
excludedPools: this.options.excludedPools,
|
|
36
|
+
targetPools: this.options.targetPools,
|
|
37
|
+
});
|
|
38
|
+
const { expectedAmount } = getExpectedReturn(quote.returnAmountWithDecimal.toString(), 0, this.metaOptions.partnerCommissionBps ?? 0, this.metaOptions.tipBps ?? 0);
|
|
39
|
+
return {
|
|
40
|
+
id: v4(),
|
|
41
|
+
provider: EProvider.BLUEFIN7K,
|
|
42
|
+
quote,
|
|
43
|
+
amountIn: quote.swapAmountWithDecimal,
|
|
44
|
+
rawAmountOut: quote.returnAmountWithDecimal,
|
|
45
|
+
amountOut: expectedAmount,
|
|
46
|
+
coinTypeIn: quote.tokenIn,
|
|
47
|
+
coinTypeOut: quote.tokenOut,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async swap({ quote, signer, tx, coinIn }) {
|
|
51
|
+
assert(quote.provider === EProvider.BLUEFIN7K, "Invalid quote");
|
|
52
|
+
const { coinOut } = await buildTxV2({
|
|
53
|
+
quoteResponse: quote.quote,
|
|
54
|
+
accountAddress: signer,
|
|
55
|
+
commission: {
|
|
56
|
+
commissionBps: this.metaOptions.partnerCommissionBps ?? 0,
|
|
57
|
+
partner: this.metaOptions.partner ?? SUI_ADDRESS_ZERO,
|
|
58
|
+
},
|
|
59
|
+
slippage: 1,
|
|
60
|
+
extendTx: {
|
|
61
|
+
tx,
|
|
62
|
+
coinIn,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return coinOut;
|
|
66
|
+
}
|
|
67
|
+
}
|