@w3lib/solana-batch-call 0.6.0 → 0.7.0
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/CHANGELOG.md +33 -0
- package/README.md +16 -8
- package/dist/accountReader.d.ts +57 -0
- package/dist/accountReader.d.ts.map +1 -0
- package/dist/accountReader.js +149 -0
- package/dist/accountReader.js.map +1 -0
- package/dist/address.d.ts +9 -0
- package/dist/address.d.ts.map +1 -1
- package/dist/address.js +36 -6
- package/dist/address.js.map +1 -1
- package/dist/approvals.d.ts +5 -3
- package/dist/approvals.d.ts.map +1 -1
- package/dist/approvals.js +25 -36
- package/dist/approvals.js.map +1 -1
- package/dist/balances.d.ts +178 -0
- package/dist/balances.d.ts.map +1 -0
- package/dist/balances.js +524 -0
- package/dist/balances.js.map +1 -0
- package/dist/batchPlan.d.ts +2 -2
- package/dist/batchPlan.d.ts.map +1 -1
- package/dist/batchPlan.js +5 -26
- package/dist/batchPlan.js.map +1 -1
- package/dist/bytes.d.ts +31 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +74 -0
- package/dist/bytes.js.map +1 -0
- package/dist/claim.d.ts +5 -3
- package/dist/claim.d.ts.map +1 -1
- package/dist/claim.js +10 -10
- package/dist/claim.js.map +1 -1
- package/dist/client.d.ts +26 -41
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +41 -986
- package/dist/client.js.map +1 -1
- package/dist/clientConfig.d.ts +11 -0
- package/dist/clientConfig.d.ts.map +1 -0
- package/dist/clientConfig.js +3 -0
- package/dist/clientConfig.js.map +1 -0
- package/dist/decode.d.ts.map +1 -1
- package/dist/decode.js +2 -29
- package/dist/decode.js.map +1 -1
- package/dist/fees.d.ts.map +1 -1
- package/dist/fees.js +2 -12
- package/dist/fees.js.map +1 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +4 -15
- package/dist/history.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +21 -0
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +50 -69
- package/dist/layout.js.map +1 -1
- package/dist/liquidity/common.js +2 -2
- package/dist/liquidity/common.js.map +1 -1
- package/dist/lp.d.ts +9 -13
- package/dist/lp.d.ts.map +1 -1
- package/dist/lp.js +67 -55
- package/dist/lp.js.map +1 -1
- package/dist/portfolio.d.ts.map +1 -1
- package/dist/portfolio.js +3 -8
- package/dist/portfolio.js.map +1 -1
- package/dist/reclaim.d.ts +4 -2
- package/dist/reclaim.d.ts.map +1 -1
- package/dist/reclaim.js +16 -16
- package/dist/reclaim.js.map +1 -1
- package/dist/risk.js +2 -2
- package/dist/risk.js.map +1 -1
- package/dist/rpc.d.ts +30 -7
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +400 -109
- package/dist/rpc.js.map +1 -1
- package/dist/simulate.d.ts.map +1 -1
- package/dist/simulate.js +3 -26
- package/dist/simulate.js.map +1 -1
- package/dist/source.d.ts +8 -4
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +11 -4
- package/dist/source.js.map +1 -1
- package/dist/subpaths/approvals.d.ts +3 -3
- package/dist/subpaths/approvals.d.ts.map +1 -1
- package/dist/subpaths/approvals.js.map +1 -1
- package/dist/subpaths/claim.d.ts +3 -3
- package/dist/subpaths/claim.d.ts.map +1 -1
- package/dist/subpaths/claim.js.map +1 -1
- package/dist/subpaths/reclaim.d.ts +3 -3
- package/dist/subpaths/reclaim.d.ts.map +1 -1
- package/dist/subpaths/reclaim.js.map +1 -1
- package/dist/swap/index.js +3 -3
- package/dist/swap/index.js.map +1 -1
- package/dist/tokenDetails.d.ts +12 -0
- package/dist/tokenDetails.d.ts.map +1 -0
- package/dist/tokenDetails.js +196 -0
- package/dist/tokenDetails.js.map +1 -0
- package/dist/tokenMeta.d.ts +63 -0
- package/dist/tokenMeta.d.ts.map +1 -0
- package/dist/tokenMeta.js +226 -0
- package/dist/tokenMeta.js.map +1 -0
- package/dist/tradeCheck.js +3 -3
- package/dist/tradeCheck.js.map +1 -1
- package/dist/util.d.ts +22 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +107 -0
- package/dist/util.js.map +1 -0
- package/dist/write/chain.d.ts +51 -0
- package/dist/write/chain.d.ts.map +1 -0
- package/dist/write/chain.js +184 -0
- package/dist/write/chain.js.map +1 -0
- package/dist/write/collect.js +2 -2
- package/dist/write/collect.js.map +1 -1
- package/dist/write/errors.d.ts +10 -0
- package/dist/write/errors.d.ts.map +1 -0
- package/dist/write/errors.js +77 -0
- package/dist/write/errors.js.map +1 -0
- package/dist/write/pack.d.ts +28 -0
- package/dist/write/pack.d.ts.map +1 -0
- package/dist/write/pack.js +125 -0
- package/dist/write/pack.js.map +1 -0
- package/dist/write/send.d.ts +23 -9
- package/dist/write/send.d.ts.map +1 -1
- package/dist/write/send.js +53 -351
- package/dist/write/send.js.map +1 -1
- package/dist/write/tracker.d.ts +24 -0
- package/dist/write/tracker.d.ts.map +1 -0
- package/dist/write/tracker.js +129 -0
- package/dist/write/tracker.js.map +1 -0
- package/package.json +1 -1
- package/src/accountReader.ts +187 -0
- package/src/address.ts +41 -6
- package/src/approvals.ts +36 -44
- package/src/balances.ts +678 -0
- package/src/batchPlan.ts +6 -26
- package/src/bytes.ts +89 -0
- package/src/claim.ts +15 -11
- package/src/client.ts +59 -1239
- package/src/clientConfig.ts +12 -0
- package/src/decode.ts +4 -30
- package/src/fees.ts +2 -9
- package/src/history.ts +4 -15
- package/src/index.ts +13 -1
- package/src/layout.ts +63 -82
- package/src/liquidity/common.ts +2 -2
- package/src/lp.ts +86 -60
- package/src/portfolio.ts +8 -11
- package/src/reclaim.ts +20 -17
- package/src/risk.ts +2 -2
- package/src/rpc.ts +472 -116
- package/src/simulate.ts +3 -21
- package/src/source.ts +14 -5
- package/src/subpaths/approvals.ts +3 -2
- package/src/subpaths/claim.ts +3 -2
- package/src/subpaths/reclaim.ts +3 -2
- package/src/swap/index.ts +3 -3
- package/src/tokenDetails.ts +240 -0
- package/src/tokenMeta.ts +270 -0
- package/src/tradeCheck.ts +3 -3
- package/src/util.ts +110 -0
- package/src/write/chain.ts +218 -0
- package/src/write/collect.ts +2 -2
- package/src/write/errors.ts +82 -0
- package/src/write/pack.ts +142 -0
- package/src/write/send.ts +74 -407
- package/src/write/tracker.ts +152 -0
package/src/reclaim.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Wrapped SOL 账户:关闭 = 解包,余额和租金一起退回
|
|
8
8
|
* - 已清空的集中流动性仓位(Orca Whirlpool、Raydium CLMM:流动性、手续费、奖励都是 0):关闭仓位账户并销毁 NFT。还有没领的手续费 / 奖励时列在 blocked,先用 /claim 领取
|
|
9
9
|
*/
|
|
10
|
-
import { decodeAddress, findProgramAddress, isAddress } from './address.js'
|
|
10
|
+
import { decodeAddress, findProgramAddress, InvalidAddressError, isAddress } from './address.js'
|
|
11
11
|
import type { RequestOptions, SolanaClient } from './client.js'
|
|
12
12
|
import { TOKEN_2022_PROGRAM_ID } from './constants.js'
|
|
13
13
|
import { approvals, parseTokenAccountState, type TokenAccountApproval } from './approvals.js'
|
|
@@ -90,7 +90,7 @@ export interface JunkContext {
|
|
|
90
90
|
risk: SolanaTokenRisk | null
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export interface
|
|
93
|
+
export interface ReclaimableOptions extends RequestOptions {
|
|
94
94
|
/** 只看这些 mint 的关联代币账户(免费公共节点也能用);不传时列出全部代币账户(getTokenAccountsByOwner,需要支持它的节点) */
|
|
95
95
|
mints?: readonly string[]
|
|
96
96
|
/** 找垃圾币(有余额的代币),默认 true;false 只找空账户、Wrapped SOL 和空仓位 */
|
|
@@ -111,6 +111,9 @@ export interface ReclaimQuery extends RequestOptions {
|
|
|
111
111
|
fetch?: typeof fetch
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/** @deprecated 改名为 ReclaimableOptions(与其他查询的 options 命名统一),旧名保留 */
|
|
115
|
+
export type ReclaimQuery = ReclaimableOptions
|
|
116
|
+
|
|
114
117
|
/** 垃圾特征里足以自动勾选的风险标记(只有这些:legit 的 RWA / 稳定币常有 permanent-delegate、transfer-hook,不能据此判断) */
|
|
115
118
|
const JUNK_RISK_FLAGS = ['non-transferable', 'high-transfer-fee', 'paused']
|
|
116
119
|
/** 垃圾币常见的名字:链接 / 域名、领奖广告。只作提示(reasons 里的 spam-name),不会让代币被自动勾选 */
|
|
@@ -160,16 +163,16 @@ function tokenItem(a: TokenAccountApproval, kind: ReclaimKind, extra: { selected
|
|
|
160
163
|
* r.items.filter((i) => i.selected) // 建议勾选的
|
|
161
164
|
* ```
|
|
162
165
|
*/
|
|
163
|
-
export async function reclaimable(client: SolanaClient, owner: string,
|
|
166
|
+
export async function reclaimable(client: SolanaClient, owner: string, options: ReclaimableOptions = {}): Promise<Reclaimable> {
|
|
164
167
|
if (!isAddress(owner)) {
|
|
165
|
-
throw new
|
|
168
|
+
throw new InvalidAddressError(`Invalid owner address: ${owner}`, owner)
|
|
166
169
|
}
|
|
167
|
-
const { signal } =
|
|
168
|
-
const maxJunkUsd =
|
|
170
|
+
const { signal } = options
|
|
171
|
+
const maxJunkUsd = options.maxJunkUsd ?? 0.01
|
|
169
172
|
if (!(maxJunkUsd >= 0)) {
|
|
170
173
|
throw new RangeError(`maxJunkUsd must be >= 0: ${maxJunkUsd}`)
|
|
171
174
|
}
|
|
172
|
-
const accounts = (await approvals(client, owner, { mints:
|
|
175
|
+
const accounts = (await approvals(client, owner, { mints: options.mints, all: true, signal })).filter((a) => ownedBy(a, owner))
|
|
173
176
|
const items: ReclaimItem[] = []
|
|
174
177
|
const blocked: ReclaimItem[] = []
|
|
175
178
|
const warnings: string[] = []
|
|
@@ -190,11 +193,11 @@ export async function reclaimable(client: SolanaClient, owner: string, query: Re
|
|
|
190
193
|
}
|
|
191
194
|
}
|
|
192
195
|
|
|
193
|
-
if (
|
|
196
|
+
if (options.positions ?? true) {
|
|
194
197
|
await scanPositions(client, accounts.filter(nft), push, signal)
|
|
195
198
|
}
|
|
196
|
-
if ((
|
|
197
|
-
await scanJunk(client, rest,
|
|
199
|
+
if ((options.junk ?? true) && rest.length) {
|
|
200
|
+
await scanJunk(client, rest, options, maxJunkUsd, push, warnings)
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
const byKind: Reclaimable['byKind'] = {}
|
|
@@ -245,20 +248,20 @@ async function scanPositions(client: SolanaClient, nfts: readonly TokenAccountAp
|
|
|
245
248
|
async function scanJunk(
|
|
246
249
|
client: SolanaClient,
|
|
247
250
|
list: readonly TokenAccountApproval[],
|
|
248
|
-
|
|
251
|
+
options: ReclaimableOptions,
|
|
249
252
|
maxJunkUsd: number,
|
|
250
253
|
push: (item: ReclaimItem, blocker?: ReclaimBlocker) => void,
|
|
251
254
|
warnings: string[],
|
|
252
255
|
): Promise<void> {
|
|
253
|
-
const { signal } =
|
|
256
|
+
const { signal } = options
|
|
254
257
|
const mints = [...new Set(list.map((a) => a.mint))]
|
|
255
|
-
const source =
|
|
258
|
+
const source = options.prices === false ? null : options.prices && options.prices !== true ? options.prices : defillamaPrices()
|
|
256
259
|
// 价格没查到(关闭 / 服务出错)时不知道哪些值钱:不自动勾选任何垃圾币
|
|
257
260
|
let pricesOk = source !== null
|
|
258
261
|
let priceMap = new Map<string, number>()
|
|
259
262
|
if (source) {
|
|
260
263
|
try {
|
|
261
|
-
const fetchFn =
|
|
264
|
+
const fetchFn = options.fetch ?? ((...args: Parameters<typeof fetch>) => fetch(...args))
|
|
262
265
|
priceMap = await source.prices({ mints, fetch: fetchFn, signal, client })
|
|
263
266
|
} catch (err) {
|
|
264
267
|
if (signal?.aborted) throw err
|
|
@@ -269,7 +272,7 @@ async function scanJunk(
|
|
|
269
272
|
warnings.push('Prices are off: junk tokens are not auto-selected')
|
|
270
273
|
}
|
|
271
274
|
const risks = new Map<string, SolanaTokenRisk>()
|
|
272
|
-
if (
|
|
275
|
+
if (options.risk ?? true) {
|
|
273
276
|
try {
|
|
274
277
|
const found = await tokenRisks(client, mints, { signal })
|
|
275
278
|
found.forEach((r, i) => risks.set(mints[i] as string, r))
|
|
@@ -282,7 +285,7 @@ async function scanJunk(
|
|
|
282
285
|
const price = priceMap.get(a.mint) ?? null
|
|
283
286
|
const usd = price !== null && a.formatted !== null ? Number(a.formatted) * price : null
|
|
284
287
|
const risk = risks.get(a.mint) ?? null
|
|
285
|
-
const custom =
|
|
288
|
+
const custom = options.isJunk?.({ account: a, price, usd, risk })
|
|
286
289
|
const valuable = usd !== null && usd > maxJunkUsd
|
|
287
290
|
if (custom === false || (valuable && custom !== true)) continue
|
|
288
291
|
const reasons: string[] = []
|
|
@@ -354,7 +357,7 @@ export interface ReclaimPlan {
|
|
|
354
357
|
*/
|
|
355
358
|
export async function buildReclaim(client: SolanaClient, owner: string, items: readonly ReclaimItem[], options: BuildReclaimOptions = {}): Promise<ReclaimPlan> {
|
|
356
359
|
if (!isAddress(owner)) {
|
|
357
|
-
throw new
|
|
360
|
+
throw new InvalidAddressError(`Invalid owner address: ${owner}`, owner)
|
|
358
361
|
}
|
|
359
362
|
const destination = options.destination ?? owner
|
|
360
363
|
if (!isAddress(destination)) {
|
package/src/risk.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 影响持有人的设置(转账手续费、永久授权、转账 hook、不可转让、新账户默认冻结、可暂停、保密转账、mint 可关闭等),一次 getMultipleAccounts 读完。
|
|
4
4
|
* 可选:持币集中度(getTokenLargestAccounts,免费公共节点大多不支持);能不能买、能不能卖用 tradeChecks(在主网模拟“买入 → 卖出”)
|
|
5
5
|
*/
|
|
6
|
-
import { isAddress } from './address.js'
|
|
6
|
+
import { InvalidAddressError, isAddress } from './address.js'
|
|
7
7
|
import type { RequestOptions, SolanaClient } from './client.js'
|
|
8
8
|
import { NATIVE_MINT, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from './constants.js'
|
|
9
9
|
import { findExtension, parseMint, parseTransferFeeConfig, type AccountInfo } from './layout.js'
|
|
@@ -89,7 +89,7 @@ export interface TokenRisksOptions extends RequestOptions {
|
|
|
89
89
|
export async function tokenRisks(client: SolanaClient, mints: readonly string[], options: TokenRisksOptions = {}): Promise<SolanaTokenRisk[]> {
|
|
90
90
|
const keys = mints.map((m) => (client.isNativeMint(m) ? NATIVE_MINT : m))
|
|
91
91
|
for (const m of keys) {
|
|
92
|
-
if (!isAddress(m)) throw new
|
|
92
|
+
if (!isAddress(m)) throw new InvalidAddressError(`Invalid mint address: ${m}`, m)
|
|
93
93
|
}
|
|
94
94
|
const unique = [...new Set(keys)]
|
|
95
95
|
const accounts = await client.accounts([CLOCK_SYSVAR_ID, ...unique], { signal: options.signal })
|