@helium/sus 0.6.24-next.8 → 0.6.30
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 +23 -18
- package/lib/cjs/index.js +441 -345
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/src/index.js +347 -244
- package/lib/esm/src/index.js.map +1 -1
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/index.d.ts +14 -12
- package/lib/types/src/index.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.fetchMetadatas = exports.getMetadataId = exports.
|
|
15
|
+
exports.fetchMetadatas = exports.getMetadataId = exports.getDetailedWritableAccountsWithoutTM = exports.isInsufficientBal = exports.sus = void 0;
|
|
16
16
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
17
17
|
const idl_1 = require("@coral-xyz/anchor/dist/cjs/idl");
|
|
18
18
|
const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
|
|
@@ -25,17 +25,8 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
25
25
|
const pako_1 = require("pako");
|
|
26
26
|
const BUBBLEGUM_PROGRAM_ID = new web3_js_1.PublicKey("BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY");
|
|
27
27
|
const ACCOUNT_COMPRESSION_PROGRAM_ID = new web3_js_1.PublicKey("cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK");
|
|
28
|
-
function
|
|
29
|
-
/// CNFT specific params
|
|
30
|
-
checkCNfts = false, extraSearchAssetParams, cNfts,
|
|
31
|
-
// Cluster for explorer
|
|
32
|
-
cluster = "mainnet-beta", }) {
|
|
33
|
-
var _a;
|
|
28
|
+
function getAccountKeys({ connection, transaction, }) {
|
|
34
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
const warnings = [];
|
|
36
|
-
const transaction = web3_js_1.VersionedTransaction.deserialize(serializedTransaction);
|
|
37
|
-
const message = transaction.message.serialize().toString("base64");
|
|
38
|
-
const explorerLink = `https://explorer.solana.com/tx/inspector?cluster=${cluster}&message=${encodeURIComponent(message)}`;
|
|
39
30
|
const addressLookupTableAccounts = [];
|
|
40
31
|
const { addressTableLookups } = transaction.message;
|
|
41
32
|
if (addressTableLookups.length > 0) {
|
|
@@ -48,40 +39,107 @@ cluster = "mainnet-beta", }) {
|
|
|
48
39
|
}
|
|
49
40
|
}
|
|
50
41
|
}
|
|
51
|
-
|
|
42
|
+
return transaction.message.getAccountKeys({
|
|
52
43
|
addressLookupTableAccounts,
|
|
53
44
|
});
|
|
54
|
-
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function getMultipleAccounts({ connection, keys, }) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const batchSize = 100;
|
|
50
|
+
const batches = Math.ceil(keys.length / batchSize);
|
|
51
|
+
const results = [];
|
|
52
|
+
for (let i = 0; i < batches; i++) {
|
|
53
|
+
const batchKeys = keys.slice(i * batchSize, (i + 1) * batchSize);
|
|
54
|
+
const batchResults = yield connection.getMultipleAccountsInfo(batchKeys);
|
|
55
|
+
results.push(...batchResults);
|
|
56
|
+
}
|
|
57
|
+
return results;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function sus({ connection, wallet, serializedTransactions,
|
|
61
|
+
/// CNFT specific params
|
|
62
|
+
checkCNfts = false, extraSearchAssetParams, cNfts,
|
|
63
|
+
// Cluster for explorer
|
|
64
|
+
cluster = "mainnet-beta", accountBlacklist, }) {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
let assets = cNfts;
|
|
68
|
+
if (checkCNfts) {
|
|
69
|
+
if (!assets) {
|
|
70
|
+
const assetsResponse = yield axios_1.default.post(connection.rpcEndpoint, {
|
|
71
|
+
jsonrpc: "2.0",
|
|
72
|
+
method: "searchAssets",
|
|
73
|
+
id: "get-assets-op-1",
|
|
74
|
+
params: Object.assign({ page: 1,
|
|
75
|
+
// limit to checking 200 assets
|
|
76
|
+
limit: 200, compressed: true, ownerAddress: wallet.toBase58() }, extraSearchAssetParams),
|
|
77
|
+
headers: {
|
|
78
|
+
"Cache-Control": "no-cache",
|
|
79
|
+
Pragma: "no-cache",
|
|
80
|
+
Expires: "0",
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
assets = (_a = assetsResponse.data.result) === null || _a === void 0 ? void 0 : _a.items;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const warningsByTx = serializedTransactions.map(() => []);
|
|
87
|
+
const transactions = serializedTransactions.map((t) => web3_js_1.VersionedTransaction.deserialize(t));
|
|
88
|
+
const accountKeysByTx = yield Promise.all(transactions.map((transaction) => getAccountKeys({ connection, transaction })));
|
|
89
|
+
const simulationAccountsByTx = accountKeysByTx.map((accountKeys, txIndex) => [
|
|
55
90
|
...new Set(accountKeys.staticAccountKeys
|
|
56
|
-
.filter((_, index) =>
|
|
91
|
+
.filter((_, index) => transactions[txIndex].message.isAccountWritable(index))
|
|
57
92
|
.concat(accountKeys.accountKeysFromLookups
|
|
58
93
|
? // Only writable accounts will contribute to balance changes
|
|
59
94
|
accountKeys.accountKeysFromLookups.writable
|
|
60
95
|
: [])),
|
|
61
|
-
];
|
|
62
|
-
const
|
|
96
|
+
].filter((a) => !(accountBlacklist === null || accountBlacklist === void 0 ? void 0 : accountBlacklist.has(a.toBase58()))));
|
|
97
|
+
const allAccounts = [...new Set(simulationAccountsByTx.flat())];
|
|
98
|
+
const fetchedAccounts = yield getMultipleAccounts({
|
|
99
|
+
connection,
|
|
100
|
+
keys: allAccounts,
|
|
101
|
+
});
|
|
102
|
+
const fetchedAccountsByAddr = fetchedAccounts.reduce((acc, account, index) => {
|
|
103
|
+
acc[allAccounts[index].toBase58()] = account;
|
|
104
|
+
return acc;
|
|
105
|
+
}, {});
|
|
63
106
|
const { blockhash } = yield (connection === null || connection === void 0 ? void 0 : connection.getLatestBlockhash());
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
107
|
+
const simulatedTxs = [];
|
|
108
|
+
// Linearly simulate txs so as not to hit rate limits
|
|
109
|
+
for (const [index, transaction] of transactions.entries()) {
|
|
110
|
+
transaction.message.recentBlockhash = blockhash;
|
|
111
|
+
const simulatedTxn = yield (connection === null || connection === void 0 ? void 0 : connection.simulateTransaction(transaction, {
|
|
112
|
+
accounts: {
|
|
113
|
+
encoding: "base64",
|
|
114
|
+
addresses: ((_b = simulationAccountsByTx[index]) === null || _b === void 0 ? void 0 : _b.map((account) => account.toBase58())) ||
|
|
115
|
+
[],
|
|
116
|
+
},
|
|
117
|
+
}));
|
|
118
|
+
simulatedTxs.push(simulatedTxn);
|
|
119
|
+
}
|
|
120
|
+
const fullAccountsByTxn = simulationAccountsByTx.map((simulationAccounts, transactionIndex) => {
|
|
121
|
+
const simulatedTxn = simulatedTxs[transactionIndex];
|
|
122
|
+
return simulationAccounts.map((account, index) => {
|
|
123
|
+
var _a;
|
|
124
|
+
const post = (_a = simulatedTxn.value.accounts) === null || _a === void 0 ? void 0 : _a[index];
|
|
125
|
+
return {
|
|
126
|
+
address: account,
|
|
127
|
+
post: post
|
|
128
|
+
? Object.assign(Object.assign({}, post), { owner: new web3_js_1.PublicKey(post.owner), data: Buffer.from(post.data[0], post.data[1]) }) : undefined,
|
|
129
|
+
pre: fetchedAccountsByAddr[account.toBase58()],
|
|
130
|
+
};
|
|
77
131
|
});
|
|
78
132
|
});
|
|
79
|
-
const
|
|
133
|
+
const instructionProgramIds = transactions
|
|
134
|
+
.flatMap((transaction, index) => transaction.message.compiledInstructions.map((ix) => accountKeysByTx[index].get(ix.programIdIndex) || null))
|
|
135
|
+
.filter(truthy);
|
|
136
|
+
const programKeys = fullAccountsByTxn
|
|
137
|
+
.flat()
|
|
80
138
|
.map((acc) => { var _a; return ((_a = acc === null || acc === void 0 ? void 0 : acc.pre) === null || _a === void 0 ? void 0 : _a.owner) || (acc.post ? new web3_js_1.PublicKey(acc.post.owner) : null); })
|
|
81
|
-
.concat(...
|
|
139
|
+
.concat(...instructionProgramIds)
|
|
82
140
|
.filter(truthy);
|
|
83
141
|
const idlKeys = programKeys.map(getIdlKey);
|
|
84
|
-
const idls = (yield connection
|
|
142
|
+
const idls = (yield getMultipleAccounts({ connection, keys: idlKeys }))
|
|
85
143
|
.map((acc, index) => {
|
|
86
144
|
if (acc) {
|
|
87
145
|
return {
|
|
@@ -97,52 +155,129 @@ cluster = "mainnet-beta", }) {
|
|
|
97
155
|
}
|
|
98
156
|
return acc;
|
|
99
157
|
}, {});
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
accounts: fullAccounts,
|
|
158
|
+
const writableAccountsByTxRaw = fullAccountsByTxn.map((accounts) => getDetailedWritableAccountsWithoutTM({
|
|
159
|
+
accounts,
|
|
103
160
|
idls,
|
|
161
|
+
}));
|
|
162
|
+
const tokens = [
|
|
163
|
+
...new Set(writableAccountsByTxRaw.flatMap((w) => w.tokens).map((t) => t.toBase58())),
|
|
164
|
+
].map((t) => new web3_js_1.PublicKey(t));
|
|
165
|
+
const metadatas = (yield fetchMetadatas(connection, tokens)).reduce((acc, m, index) => {
|
|
166
|
+
if (m) {
|
|
167
|
+
acc[tokens[index].toBase58()] = m;
|
|
168
|
+
}
|
|
169
|
+
return acc;
|
|
170
|
+
}, {});
|
|
171
|
+
const writableAccountsByTx = writableAccountsByTxRaw.map(({ withoutMetadata }, index) => {
|
|
172
|
+
const writableAccounts = withoutMetadata.map((acc) => {
|
|
173
|
+
var _a, _b;
|
|
174
|
+
let name = acc.name;
|
|
175
|
+
let metadata;
|
|
176
|
+
// Attempt to take last known type
|
|
177
|
+
const type = (acc.pre.type !== "Unknown" && acc.pre.type) ||
|
|
178
|
+
(acc.post.type !== "Unknown" && acc.post.type) ||
|
|
179
|
+
"Unknown";
|
|
180
|
+
// If token, get the name based on the metadata
|
|
181
|
+
if (type === "Mint") {
|
|
182
|
+
metadata = metadatas[acc.address.toBase58()];
|
|
183
|
+
if (metadata) {
|
|
184
|
+
name = `${metadata.symbol} Mint`;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
name = `Unknown Mint`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (type === "TokenAccount") {
|
|
191
|
+
metadata =
|
|
192
|
+
metadatas[(((_a = acc.pre.parsed) === null || _a === void 0 ? void 0 : _a.mint) || ((_b = acc.post.parsed) === null || _b === void 0 ? void 0 : _b.mint)).toBase58()];
|
|
193
|
+
if (metadata) {
|
|
194
|
+
name = `${metadata.symbol} Token Account`;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
name = `Unknown Token Account`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return Object.assign(Object.assign({}, acc), { name,
|
|
201
|
+
metadata });
|
|
202
|
+
});
|
|
203
|
+
writableAccounts.forEach((acc) => {
|
|
204
|
+
var _a, _b, _c, _d;
|
|
205
|
+
if (!acc.changedInSimulation) {
|
|
206
|
+
warningsByTx[index].push({
|
|
207
|
+
severity: "warning",
|
|
208
|
+
shortMessage: "Unchanged",
|
|
209
|
+
message: "Account did not change in simulation but was labeled as writable. The behavior of the transaction may differ from the simulation.",
|
|
210
|
+
account: acc.address,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
// Catch malicious sol ownwer change
|
|
214
|
+
const sysProg = new web3_js_1.PublicKey("11111111111111111111111111111111");
|
|
215
|
+
const postOwner = ((_a = acc.post.account) === null || _a === void 0 ? void 0 : _a.owner) || sysProg;
|
|
216
|
+
const preOwner = ((_b = acc.pre.account) === null || _b === void 0 ? void 0 : _b.owner) || sysProg;
|
|
217
|
+
const accountOwnerChanged = !preOwner.equals(postOwner);
|
|
218
|
+
if (acc.name === "Native SOL Account" && acc.owner && acc.owner.equals(wallet) && accountOwnerChanged) {
|
|
219
|
+
warningsByTx[index].push({
|
|
220
|
+
severity: "critical",
|
|
221
|
+
shortMessage: "Owner Changed",
|
|
222
|
+
message: `The owner of ${acc.name} changed to ${(_d = (_c = acc.post.parsed) === null || _c === void 0 ? void 0 : _c.owner) === null || _d === void 0 ? void 0 : _d.toBase58()}. This gives that wallet full custody of these tokens.`,
|
|
223
|
+
account: acc.address,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
return writableAccounts;
|
|
104
228
|
});
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
229
|
+
const instructionsByTx = yield Promise.all(transactions.map((transaction, index) => __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
const instructions = parseInstructions({
|
|
231
|
+
idls,
|
|
232
|
+
instructions: transaction.message.compiledInstructions.map((ix) => ({
|
|
233
|
+
data: Buffer.from(ix.data),
|
|
234
|
+
programId: accountKeysByTx[index].get(ix.programIdIndex),
|
|
235
|
+
accounts: ix.accountKeyIndexes.map((ix) => ({
|
|
236
|
+
pubkey: accountKeysByTx[index].get(ix),
|
|
237
|
+
isSigner: transaction.message.isAccountSigner(ix),
|
|
238
|
+
isWritable: transaction.message.isAccountWritable(ix),
|
|
239
|
+
})),
|
|
114
240
|
})),
|
|
115
|
-
})),
|
|
116
|
-
});
|
|
117
|
-
if (instructions.some((ix) => { var _a; return ((_a = ix.parsed) === null || _a === void 0 ? void 0 : _a.name) === "ledgerTransferPositionV0"; })) {
|
|
118
|
-
warnings.push({
|
|
119
|
-
severity: "critical",
|
|
120
|
-
shortMessage: "Theft of Locked HNT",
|
|
121
|
-
message: "This transaction is attempting to steal your locked HNT positions",
|
|
122
241
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
242
|
+
if (instructions.some((ix) => { var _a; return ((_a = ix.parsed) === null || _a === void 0 ? void 0 : _a.name) === "ledgerTransferPositionV0"; })) {
|
|
243
|
+
warningsByTx[index].push({
|
|
244
|
+
severity: "critical",
|
|
245
|
+
shortMessage: "Theft of Locked HNT",
|
|
246
|
+
message: "This transaction is attempting to steal your locked HNT positions",
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
if ((yield Promise.all(instructions.map((ix) => isBurnHotspot(connection, ix, assets)))).some((isBurn) => isBurn)) {
|
|
250
|
+
warningsByTx[index].push({
|
|
251
|
+
severity: "critical",
|
|
252
|
+
shortMessage: "Hotspot Destroyed",
|
|
253
|
+
message: "This transaction will brick your Hotspot!",
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return instructions;
|
|
257
|
+
})));
|
|
258
|
+
const results = [];
|
|
259
|
+
for (const [index, simulatedTxn] of simulatedTxs.entries()) {
|
|
260
|
+
const warnings = warningsByTx[index];
|
|
261
|
+
const instructions = instructionsByTx[index];
|
|
262
|
+
const writableAccounts = writableAccountsByTx[index];
|
|
263
|
+
const transaction = transactions[index];
|
|
264
|
+
const message = transaction.message.serialize().toString("base64");
|
|
265
|
+
const explorerLink = `https://explorer.solana.com/tx/inspector?cluster=${cluster}&message=${encodeURIComponent(message)}`;
|
|
266
|
+
const logs = simulatedTxn.value.logs;
|
|
267
|
+
let result;
|
|
268
|
+
if (simulatedTxn === null || simulatedTxn === void 0 ? void 0 : simulatedTxn.value.err) {
|
|
134
269
|
warnings.push({
|
|
135
|
-
severity: "
|
|
270
|
+
severity: "critical",
|
|
136
271
|
shortMessage: "Simulation Failed",
|
|
137
272
|
message: "Transaction failed in simulation",
|
|
138
273
|
});
|
|
139
|
-
|
|
274
|
+
result = {
|
|
140
275
|
instructions,
|
|
141
276
|
error: simulatedTxn.value.err,
|
|
142
277
|
logs,
|
|
143
278
|
solFee: 0,
|
|
144
279
|
priorityFee: 0,
|
|
145
|
-
insufficientFunds:
|
|
280
|
+
insufficientFunds: isInsufficientBal(simulatedTxn === null || simulatedTxn === void 0 ? void 0 : simulatedTxn.value.err),
|
|
146
281
|
explorerLink,
|
|
147
282
|
balanceChanges: [],
|
|
148
283
|
possibleCNftChanges: [],
|
|
@@ -151,106 +286,94 @@ cluster = "mainnet-beta", }) {
|
|
|
151
286
|
warnings,
|
|
152
287
|
};
|
|
153
288
|
}
|
|
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
|
-
|
|
289
|
+
else {
|
|
290
|
+
let solFee = ((transaction === null || transaction === void 0 ? void 0 : transaction.signatures.length) || 1) * 5000;
|
|
291
|
+
let priorityFee = 0;
|
|
292
|
+
const fee = (yield (connection === null || connection === void 0 ? void 0 : connection.getFeeForMessage(transaction.message, "confirmed")))
|
|
293
|
+
.value || solFee;
|
|
294
|
+
priorityFee = fee - solFee;
|
|
295
|
+
const balanceChanges = writableAccounts
|
|
296
|
+
.map((acc) => {
|
|
297
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
298
|
+
const type = (acc.pre.type !== "Unknown" && acc.pre.type) ||
|
|
299
|
+
(acc.post.type !== "Unknown" && acc.post.type);
|
|
300
|
+
switch (type) {
|
|
301
|
+
case "TokenAccount":
|
|
302
|
+
if (((_a = acc.post.parsed) === null || _a === void 0 ? void 0 : _a.delegate) && !((_b = acc.pre.parsed) === null || _b === void 0 ? void 0 : _b.delegate)) {
|
|
303
|
+
warnings.push({
|
|
304
|
+
severity: "warning",
|
|
305
|
+
shortMessage: "Withdraw Authority Given",
|
|
306
|
+
message: `Delegation was taken on ${acc.name}. This gives permission to withdraw tokens without the owner's permission.`,
|
|
307
|
+
account: acc.address,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (acc.post.parsed &&
|
|
311
|
+
acc.pre.parsed &&
|
|
312
|
+
!acc.post.parsed.owner.equals(acc.pre.parsed.owner)) {
|
|
313
|
+
warnings.push({
|
|
314
|
+
severity: "warning",
|
|
315
|
+
shortMessage: "Owner Changed",
|
|
316
|
+
message: `The owner of ${acc.name} changed to ${(_d = (_c = acc.post.parsed) === null || _c === void 0 ? void 0 : _c.owner) === null || _d === void 0 ? void 0 : _d.toBase58()}. This gives that wallet full custody of these tokens.`,
|
|
317
|
+
account: acc.address,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
owner: ((_e = acc.post.parsed) === null || _e === void 0 ? void 0 : _e.owner) || ((_f = acc.pre.parsed) === null || _f === void 0 ? void 0 : _f.owner),
|
|
322
|
+
address: acc.address,
|
|
323
|
+
amount: (((_g = acc.post.parsed) === null || _g === void 0 ? void 0 : _g.amount) || BigInt(0)) -
|
|
324
|
+
(((_h = acc.pre.parsed) === null || _h === void 0 ? void 0 : _h.amount) || BigInt(0)),
|
|
325
|
+
metadata: acc.metadata,
|
|
326
|
+
};
|
|
327
|
+
case "NativeAccount":
|
|
328
|
+
return {
|
|
329
|
+
owner: acc.address,
|
|
330
|
+
address: acc.address,
|
|
331
|
+
amount: BigInt((((_j = acc.post.account) === null || _j === void 0 ? void 0 : _j.lamports) || 0) -
|
|
332
|
+
(((_k = acc.pre.account) === null || _k === void 0 ? void 0 : _k.lamports) || 0)),
|
|
333
|
+
metadata: {
|
|
334
|
+
mint: spl_token_1.NATIVE_MINT,
|
|
335
|
+
decimals: 9,
|
|
336
|
+
name: "SOL",
|
|
337
|
+
symbol: "SOL",
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
default:
|
|
341
|
+
return null;
|
|
183
342
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
message: "More than 2 accounts with negative balance change. Is this emptying your wallet?",
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
let possibleCNftChanges = [];
|
|
218
|
-
if (checkCNfts) {
|
|
219
|
-
let assets = cNfts;
|
|
220
|
-
if (!assets) {
|
|
221
|
-
const assetsResponse = yield axios_1.default.post(connection.rpcEndpoint, {
|
|
222
|
-
jsonrpc: "2.0",
|
|
223
|
-
method: "searchAssets",
|
|
224
|
-
id: "get-assets-op-1",
|
|
225
|
-
params: Object.assign({ page: 1,
|
|
226
|
-
// limit to checking 200 assets
|
|
227
|
-
limit: 200, compressed: true }, extraSearchAssetParams),
|
|
228
|
-
headers: {
|
|
229
|
-
"Cache-Control": "no-cache",
|
|
230
|
-
Pragma: "no-cache",
|
|
231
|
-
Expires: "0",
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
assets = (_a = assetsResponse.data.result) === null || _a === void 0 ? void 0 : _a.items;
|
|
343
|
+
})
|
|
344
|
+
.filter(truthy);
|
|
345
|
+
// Don't count new mints being created, as this might flag on candymachine txs
|
|
346
|
+
if (balanceChanges.filter((b) => b.owner.equals(wallet) && fetchedAccountsByAddr[b.address.toBase58()]).length >= 3) {
|
|
347
|
+
warnings.push({
|
|
348
|
+
severity: "warning",
|
|
349
|
+
shortMessage: "3+ Token Accounts",
|
|
350
|
+
message: "3 or more token accounts are impacted by this transaction. Any token account listed as writable can be emptied by the transaction, is this okay?",
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
let possibleCNftChanges = [];
|
|
354
|
+
if (checkCNfts) {
|
|
355
|
+
const possibleMerkles = new Set(writableAccounts
|
|
356
|
+
.filter((acc) => acc.name === "Merkle Tree")
|
|
357
|
+
.map((a) => a.address.toBase58()));
|
|
358
|
+
possibleCNftChanges = (assets || []).filter((item) => item.compression.tree && possibleMerkles.has(item.compression.tree));
|
|
359
|
+
}
|
|
360
|
+
result = {
|
|
361
|
+
instructions,
|
|
362
|
+
logs,
|
|
363
|
+
solFee,
|
|
364
|
+
priorityFee,
|
|
365
|
+
insufficientFunds: false,
|
|
366
|
+
explorerLink,
|
|
367
|
+
balanceChanges,
|
|
368
|
+
possibleCNftChanges,
|
|
369
|
+
writableAccounts,
|
|
370
|
+
rawSimulation: simulatedTxn.value,
|
|
371
|
+
warnings,
|
|
372
|
+
};
|
|
235
373
|
}
|
|
236
|
-
|
|
237
|
-
.filter((acc) => acc.name === "Merkle Tree")
|
|
238
|
-
.map((a) => a.address.toBase58()));
|
|
239
|
-
possibleCNftChanges = (assets || []).filter((item) => item.compression.tree && possibleMerkles.has(item.compression.tree));
|
|
374
|
+
results.push(result);
|
|
240
375
|
}
|
|
241
|
-
return
|
|
242
|
-
instructions,
|
|
243
|
-
logs,
|
|
244
|
-
solFee,
|
|
245
|
-
priorityFee,
|
|
246
|
-
insufficientFunds: false,
|
|
247
|
-
explorerLink,
|
|
248
|
-
balanceChanges,
|
|
249
|
-
possibleCNftChanges,
|
|
250
|
-
writableAccounts,
|
|
251
|
-
rawSimulation: simulatedTxn.value,
|
|
252
|
-
warnings,
|
|
253
|
-
};
|
|
376
|
+
return results;
|
|
254
377
|
});
|
|
255
378
|
}
|
|
256
379
|
exports.sus = sus;
|
|
@@ -263,34 +386,32 @@ function isInsufficientBal(e) {
|
|
|
263
386
|
}
|
|
264
387
|
exports.isInsufficientBal = isInsufficientBal;
|
|
265
388
|
function parseInstructions({ idls, instructions, }) {
|
|
266
|
-
return
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
};
|
|
285
|
-
}
|
|
389
|
+
return instructions.map((ix) => {
|
|
390
|
+
const idl = idls[ix.programId.toBase58()];
|
|
391
|
+
if (idl) {
|
|
392
|
+
try {
|
|
393
|
+
const coder = new anchor_1.BorshInstructionCoder(idl);
|
|
394
|
+
const parsed = coder.decode(ix.data, "base58");
|
|
395
|
+
if (parsed) {
|
|
396
|
+
const formatted = coder.format(parsed, ix.accounts);
|
|
397
|
+
if (formatted) {
|
|
398
|
+
return {
|
|
399
|
+
parsed: {
|
|
400
|
+
name: parsed.name,
|
|
401
|
+
programName: idl.name,
|
|
402
|
+
data: parsed.data,
|
|
403
|
+
accounts: formatted.accounts,
|
|
404
|
+
},
|
|
405
|
+
raw: ix,
|
|
406
|
+
};
|
|
286
407
|
}
|
|
287
408
|
}
|
|
288
|
-
catch (e) {
|
|
289
|
-
// Ignore, not a valid ix
|
|
290
|
-
}
|
|
291
409
|
}
|
|
292
|
-
|
|
293
|
-
|
|
410
|
+
catch (e) {
|
|
411
|
+
// Ignore, not a valid ix
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return { raw: ix };
|
|
294
415
|
});
|
|
295
416
|
}
|
|
296
417
|
function getIdlKey(programId) {
|
|
@@ -313,137 +434,99 @@ function decodeIdl(account) {
|
|
|
313
434
|
// Ignore, not a valid IDL
|
|
314
435
|
}
|
|
315
436
|
}
|
|
316
|
-
function
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
post.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
? {
|
|
333
|
-
executable: post.executable,
|
|
334
|
-
owner: new web3_js_1.PublicKey(post.owner),
|
|
335
|
-
lamports: post.lamports,
|
|
336
|
-
data: postData,
|
|
337
|
-
rentEpoch: post.rentEpoch,
|
|
338
|
-
}
|
|
339
|
-
: null;
|
|
340
|
-
const owner = (pre === null || pre === void 0 ? void 0 : pre.owner) || (post ? new web3_js_1.PublicKey(post.owner) : null);
|
|
341
|
-
switch (owner === null || owner === void 0 ? void 0 : owner.toBase58()) {
|
|
342
|
-
case ACCOUNT_COMPRESSION_PROGRAM_ID.toBase58():
|
|
343
|
-
name = "Merkle Tree";
|
|
344
|
-
type = "MerkleTree";
|
|
345
|
-
break;
|
|
346
|
-
case web3_js_1.SystemProgram.programId.toBase58():
|
|
347
|
-
name = "Native SOL Account";
|
|
348
|
-
type = "NativeAccount";
|
|
349
|
-
accountOwner = address;
|
|
350
|
-
break;
|
|
351
|
-
case spl_token_1.TOKEN_2022_PROGRAM_ID.toBase58():
|
|
352
|
-
({ parsed: preParsed, type } = decodeTokenStruct(address, pre, spl_token_1.TOKEN_2022_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
353
|
-
({ parsed: postParsed, type } = decodeTokenStruct(address, postAccount, spl_token_1.TOKEN_2022_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
354
|
-
break;
|
|
355
|
-
case spl_token_1.TOKEN_PROGRAM_ID.toBase58():
|
|
356
|
-
({ parsed: preParsed, type } = decodeTokenStruct(address, pre, spl_token_1.TOKEN_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
357
|
-
({ parsed: postParsed, type } = decodeTokenStruct(address, postAccount, spl_token_1.TOKEN_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
358
|
-
break;
|
|
359
|
-
default:
|
|
360
|
-
if (owner) {
|
|
361
|
-
const idl = idls[owner.toBase58()];
|
|
362
|
-
if (idl) {
|
|
363
|
-
({ parsed: preParsed, type } = decodeIdlStruct(idl, pre) || {
|
|
364
|
-
type: "No Published IDL",
|
|
365
|
-
});
|
|
366
|
-
({ parsed: postParsed, type } = decodeIdlStruct(idl, postAccount) || {
|
|
367
|
-
type: "No Published IDL",
|
|
368
|
-
});
|
|
369
|
-
name = type;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
break;
|
|
437
|
+
function getDetailedWritableAccountsWithoutTM({ accounts, idls, }) {
|
|
438
|
+
const uniqueTokens = new Set();
|
|
439
|
+
const withoutMetadata = accounts.map(({ address, pre, post }) => {
|
|
440
|
+
let name = "Unknown";
|
|
441
|
+
let type = "Unknown";
|
|
442
|
+
let preParsed = null;
|
|
443
|
+
let postParsed = null;
|
|
444
|
+
let accountOwner = undefined;
|
|
445
|
+
const postData = post && post.data;
|
|
446
|
+
const postAccount = post && postData
|
|
447
|
+
? {
|
|
448
|
+
executable: post.executable,
|
|
449
|
+
owner: new web3_js_1.PublicKey(post.owner),
|
|
450
|
+
lamports: post.lamports,
|
|
451
|
+
data: postData,
|
|
452
|
+
rentEpoch: post.rentEpoch,
|
|
373
453
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
454
|
+
: null;
|
|
455
|
+
const owner = (pre === null || pre === void 0 ? void 0 : pre.owner) || (post ? new web3_js_1.PublicKey(post.owner) : null);
|
|
456
|
+
switch (owner === null || owner === void 0 ? void 0 : owner.toBase58()) {
|
|
457
|
+
case ACCOUNT_COMPRESSION_PROGRAM_ID.toBase58():
|
|
458
|
+
name = "Merkle Tree";
|
|
459
|
+
type = "MerkleTree";
|
|
460
|
+
break;
|
|
461
|
+
case web3_js_1.SystemProgram.programId.toBase58():
|
|
462
|
+
name = "Native SOL Account";
|
|
463
|
+
type = "NativeAccount";
|
|
464
|
+
accountOwner = address;
|
|
465
|
+
break;
|
|
466
|
+
case spl_token_1.TOKEN_2022_PROGRAM_ID.toBase58():
|
|
467
|
+
({ parsed: preParsed, type } = decodeTokenStruct(address, pre, spl_token_1.TOKEN_2022_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
468
|
+
({ parsed: postParsed, type } = decodeTokenStruct(address, postAccount, spl_token_1.TOKEN_2022_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
469
|
+
break;
|
|
470
|
+
case spl_token_1.TOKEN_PROGRAM_ID.toBase58():
|
|
471
|
+
({ parsed: preParsed, type } = decodeTokenStruct(address, pre, spl_token_1.TOKEN_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
472
|
+
({ parsed: postParsed, type } = decodeTokenStruct(address, postAccount, spl_token_1.TOKEN_PROGRAM_ID) || { type: "Unknown Token Program" });
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
if (owner) {
|
|
476
|
+
const idl = idls[owner.toBase58()];
|
|
477
|
+
if (idl) {
|
|
478
|
+
const decodedPre = decodeIdlStruct(idl, pre);
|
|
479
|
+
const decodedPost = decodeIdlStruct(idl, postAccount);
|
|
480
|
+
preParsed = decodedPre === null || decodedPre === void 0 ? void 0 : decodedPre.parsed;
|
|
481
|
+
postParsed = decodedPost === null || decodedPost === void 0 ? void 0 : decodedPost.parsed;
|
|
482
|
+
type = (decodedPre === null || decodedPre === void 0 ? void 0 : decodedPre.type) || (decodedPost === null || decodedPost === void 0 ? void 0 : decodedPost.type) || "Unknown";
|
|
483
|
+
name = type;
|
|
484
|
+
}
|
|
386
485
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
account: pre || null,
|
|
395
|
-
parsed: preParsed,
|
|
396
|
-
},
|
|
397
|
-
post: {
|
|
398
|
-
type,
|
|
399
|
-
account: post || null,
|
|
400
|
-
parsed: postParsed,
|
|
401
|
-
},
|
|
402
|
-
changedInSimulation: pre && postData
|
|
403
|
-
? !pre.data.equals(postData) ||
|
|
404
|
-
pre.lamports != post.lamports ||
|
|
405
|
-
!pre.owner.equals(new web3_js_1.PublicKey(post.owner))
|
|
406
|
-
: true,
|
|
407
|
-
};
|
|
408
|
-
});
|
|
409
|
-
const tokens = [...uniqueTokens].map((t) => new web3_js_1.PublicKey(t));
|
|
410
|
-
const metadatas = (yield fetchMetadatas(connection, tokens)).reduce((acc, m, index) => {
|
|
411
|
-
if (m) {
|
|
412
|
-
acc[tokens[index].toBase58()] = m;
|
|
413
|
-
}
|
|
414
|
-
return acc;
|
|
415
|
-
}, {});
|
|
416
|
-
return withoutMetadata.map((acc) => {
|
|
417
|
-
var _a, _b;
|
|
418
|
-
let name = acc.name;
|
|
419
|
-
let metadata;
|
|
420
|
-
const type = acc.pre.type || acc.post.type;
|
|
421
|
-
// If token, get the name based on the metadata
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
// If token, get the name based on the metadata
|
|
489
|
+
if (new Set([
|
|
490
|
+
spl_token_1.TOKEN_2022_PROGRAM_ID.toBase58(),
|
|
491
|
+
spl_token_1.TOKEN_PROGRAM_ID.toBase58(),
|
|
492
|
+
]).has((owner === null || owner === void 0 ? void 0 : owner.toBase58()) || "")) {
|
|
422
493
|
if (type === "Mint") {
|
|
423
|
-
|
|
424
|
-
if (metadata) {
|
|
425
|
-
name = `${metadata.symbol} Mint`;
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
name = `Unknown Mint`;
|
|
429
|
-
}
|
|
494
|
+
uniqueTokens.add(address.toBase58());
|
|
430
495
|
}
|
|
431
496
|
else if (type === "TokenAccount") {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
name = `${metadata.symbol} Token Account`;
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
name = `Unknown Token Account`;
|
|
439
|
-
}
|
|
497
|
+
const mint = ((preParsed === null || preParsed === void 0 ? void 0 : preParsed.mint) || (postParsed === null || postParsed === void 0 ? void 0 : postParsed.mint)).toBase58();
|
|
498
|
+
accountOwner = (preParsed === null || preParsed === void 0 ? void 0 : preParsed.owner) || (postParsed === null || postParsed === void 0 ? void 0 : postParsed.owner);
|
|
499
|
+
uniqueTokens.add(mint);
|
|
440
500
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
address,
|
|
504
|
+
name,
|
|
505
|
+
owner: accountOwner,
|
|
506
|
+
pre: {
|
|
507
|
+
type,
|
|
508
|
+
account: pre || null,
|
|
509
|
+
parsed: preParsed,
|
|
510
|
+
},
|
|
511
|
+
post: {
|
|
512
|
+
type,
|
|
513
|
+
account: post || null,
|
|
514
|
+
parsed: postParsed,
|
|
515
|
+
},
|
|
516
|
+
changedInSimulation: pre && postData
|
|
517
|
+
? !pre.data.equals(postData) ||
|
|
518
|
+
pre.lamports != post.lamports ||
|
|
519
|
+
!pre.owner.equals(new web3_js_1.PublicKey(post.owner))
|
|
520
|
+
: true,
|
|
521
|
+
};
|
|
444
522
|
});
|
|
523
|
+
const tokens = [...uniqueTokens].map((t) => new web3_js_1.PublicKey(t));
|
|
524
|
+
return {
|
|
525
|
+
withoutMetadata,
|
|
526
|
+
tokens,
|
|
527
|
+
};
|
|
445
528
|
}
|
|
446
|
-
exports.
|
|
529
|
+
exports.getDetailedWritableAccountsWithoutTM = getDetailedWritableAccountsWithoutTM;
|
|
447
530
|
function decodeIdlStruct(idl, account) {
|
|
448
531
|
var _a, _b;
|
|
449
532
|
if (!account) {
|
|
@@ -505,58 +588,71 @@ exports.getMetadataId = getMetadataId;
|
|
|
505
588
|
function fetchMetadatas(connection, tokens) {
|
|
506
589
|
return __awaiter(this, void 0, void 0, function* () {
|
|
507
590
|
const metadatas = tokens.map(getMetadataId);
|
|
508
|
-
const all = yield
|
|
509
|
-
...metadatas,
|
|
510
|
-
|
|
511
|
-
|
|
591
|
+
const all = yield getMultipleAccounts({
|
|
592
|
+
keys: [...metadatas, ...tokens],
|
|
593
|
+
connection,
|
|
594
|
+
});
|
|
512
595
|
const metadataAccounts = all.slice(0, metadatas.length);
|
|
513
596
|
const mintAccounts = all.slice(metadatas.length, metadatas.length * 2);
|
|
514
597
|
return metadataAccounts.map((acc, index) => {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
598
|
+
try {
|
|
599
|
+
const mint = (0, spl_token_1.unpackMint)(tokens[index], mintAccounts[index]);
|
|
600
|
+
if (acc) {
|
|
601
|
+
const collectable = mpl_token_metadata_1.Metadata.fromAccountInfo(acc)[0];
|
|
602
|
+
return {
|
|
603
|
+
name: collectable.data.name.replace(/\0/g, ""),
|
|
604
|
+
symbol: collectable.data.symbol.replace(/\0/g, ""),
|
|
605
|
+
uri: collectable.data.uri.replace(/\0/g, ""),
|
|
606
|
+
decimals: mint.decimals,
|
|
607
|
+
mint: tokens[index],
|
|
608
|
+
};
|
|
609
|
+
}
|
|
518
610
|
return {
|
|
519
|
-
name: collectable.data.name.replace(/\0/g, ""),
|
|
520
|
-
symbol: collectable.data.symbol.replace(/\0/g, ""),
|
|
521
|
-
uri: collectable.data.uri.replace(/\0/g, ""),
|
|
522
|
-
decimals: mint.decimals,
|
|
523
611
|
mint: tokens[index],
|
|
612
|
+
decimals: mint.decimals,
|
|
524
613
|
};
|
|
525
614
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
615
|
+
catch (e) {
|
|
616
|
+
// Ignore, not a valid mint
|
|
617
|
+
}
|
|
618
|
+
return null;
|
|
530
619
|
});
|
|
531
620
|
});
|
|
532
621
|
}
|
|
533
622
|
exports.fetchMetadatas = fetchMetadatas;
|
|
534
623
|
const truthy = (value) => !!value;
|
|
535
|
-
function isBurnHotspot(connection, ix) {
|
|
536
|
-
var _a, _b, _c, _d, _e, _f;
|
|
624
|
+
function isBurnHotspot(connection, ix, assets) {
|
|
625
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
537
626
|
return __awaiter(this, void 0, void 0, function* () {
|
|
538
627
|
if (ix.raw.programId.equals(BUBBLEGUM_PROGRAM_ID) &&
|
|
539
628
|
((_a = ix.parsed) === null || _a === void 0 ? void 0 : _a.name) === "burn") {
|
|
540
|
-
const tree = (_c = (_b = ix.parsed) === null || _b === void 0 ? void 0 : _b.accounts.find((acc) => acc.name === "
|
|
629
|
+
const tree = (_c = (_b = ix.parsed) === null || _b === void 0 ? void 0 : _b.accounts.find((acc) => acc.name === "Merkle Tree")) === null || _c === void 0 ? void 0 : _c.pubkey;
|
|
541
630
|
if (tree) {
|
|
542
|
-
const
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
id
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
631
|
+
const index = (_e = (_d = ix.parsed) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.index;
|
|
632
|
+
const assetId = yield (0, mpl_bubblegum_1.getLeafAssetId)(tree, new anchor_1.BN(index));
|
|
633
|
+
let asset;
|
|
634
|
+
if (assets) {
|
|
635
|
+
asset = assets.find(a => a.id === assetId.toBase58());
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
const assetResponse = yield axios_1.default.post(connection.rpcEndpoint, {
|
|
639
|
+
jsonrpc: "2.0",
|
|
640
|
+
method: "getAsset",
|
|
641
|
+
id: "get-asset-op-1",
|
|
642
|
+
params: {
|
|
643
|
+
id: assetId.toBase58(),
|
|
644
|
+
},
|
|
645
|
+
headers: {
|
|
646
|
+
"Cache-Control": "no-cache",
|
|
647
|
+
Pragma: "no-cache",
|
|
648
|
+
Expires: "0",
|
|
649
|
+
},
|
|
650
|
+
});
|
|
651
|
+
asset = assetResponse.data.result;
|
|
652
|
+
}
|
|
557
653
|
return (asset &&
|
|
558
|
-
((
|
|
559
|
-
((
|
|
654
|
+
((_f = asset.creators[0]) === null || _f === void 0 ? void 0 : _f.address) == HELIUM_ENTITY_CREATOR.toBase58() &&
|
|
655
|
+
((_g = asset.creators[0]) === null || _g === void 0 ? void 0 : _g.verified));
|
|
560
656
|
}
|
|
561
657
|
}
|
|
562
658
|
return false;
|