@w3lib/solana-batch-call 0.0.0-stage → 0.1.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +169 -2
  4. package/dist/address.d.ts +14 -0
  5. package/dist/address.d.ts.map +1 -0
  6. package/dist/address.js +81 -0
  7. package/dist/address.js.map +1 -0
  8. package/dist/client.d.ts +96 -0
  9. package/dist/client.d.ts.map +1 -0
  10. package/dist/client.js +575 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/constants.d.ts +21 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +35 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/index.d.ts +9 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +9 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/layout.d.ts +55 -0
  21. package/dist/layout.d.ts.map +1 -0
  22. package/dist/layout.js +177 -0
  23. package/dist/layout.js.map +1 -0
  24. package/dist/rpc.d.ts +59 -0
  25. package/dist/rpc.d.ts.map +1 -0
  26. package/dist/rpc.js +295 -0
  27. package/dist/rpc.js.map +1 -0
  28. package/dist/shortcuts.d.ts +60 -0
  29. package/dist/shortcuts.d.ts.map +1 -0
  30. package/dist/shortcuts.js +136 -0
  31. package/dist/shortcuts.js.map +1 -0
  32. package/dist/source.d.ts +35 -0
  33. package/dist/source.d.ts.map +1 -0
  34. package/dist/source.js +126 -0
  35. package/dist/source.js.map +1 -0
  36. package/dist/types.d.ts +104 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +2 -0
  39. package/dist/types.js.map +1 -0
  40. package/package.json +56 -3
  41. package/src/address.ts +92 -0
  42. package/src/client.ts +753 -0
  43. package/src/constants.ts +41 -0
  44. package/src/index.ts +54 -0
  45. package/src/layout.ts +238 -0
  46. package/src/rpc.ts +349 -0
  47. package/src/shortcuts.ts +173 -0
  48. package/src/source.ts +151 -0
  49. package/src/types.ts +108 -0
@@ -0,0 +1,35 @@
1
+ export const SYSTEM_PROGRAM_ID = '11111111111111111111111111111111';
2
+ export const TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
3
+ export const TOKEN_2022_PROGRAM_ID = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb';
4
+ export const ASSOCIATED_TOKEN_PROGRAM_ID = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
5
+ export const METADATA_PROGRAM_ID = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s';
6
+ /** Wrapped SOL 的 mint,按惯例也用来表示原生 SOL */
7
+ export const NATIVE_MINT = 'So11111111111111111111111111111111111111112';
8
+ /** 原生 SOL 的精度(lamports) */
9
+ export const SOL_DECIMALS = 9;
10
+ /** 各网络的创世区块哈希(getGenesisHash),用于识别节点所在网络 */
11
+ export const GENESIS_HASHES = {
12
+ mainnet: '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d',
13
+ devnet: 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG',
14
+ testnet: '4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY',
15
+ };
16
+ export function clusterOfGenesis(hash) {
17
+ for (const [cluster, genesis] of Object.entries(GENESIS_HASHES)) {
18
+ if (genesis === hash) {
19
+ return cluster;
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ /**
25
+ * 内置公共节点(按优先级排序,2026-10 实测):
26
+ * - publicnode:放行跨域、支持批量请求,但不支持 getTokenAccountsByOwner 等需要索引的方法
27
+ * - 官方节点:对带浏览器 Origin 的请求返回 403,只能在服务端使用
28
+ * 公共节点限频严,生产环境建议传入自己的节点(Helius / QuickNode / Triton 等)。
29
+ */
30
+ export const DEFAULT_RPC_URLS = {
31
+ mainnet: ['https://solana-rpc.publicnode.com', 'https://api.mainnet-beta.solana.com'],
32
+ devnet: ['https://api.devnet.solana.com'],
33
+ testnet: ['https://api.testnet.solana.com'],
34
+ };
35
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,kCAAkC,CAAA;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,6CAA6C,CAAA;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,6CAA6C,CAAA;AAClF,MAAM,CAAC,MAAM,2BAA2B,GAAG,8CAA8C,CAAA;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,6CAA6C,CAAA;AAEhF,wCAAwC;AACxC,MAAM,CAAC,MAAM,WAAW,GAAG,6CAA6C,CAAA;AAExE,2BAA2B;AAC3B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,4CAA4C;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAsC;IAC/D,OAAO,EAAE,8CAA8C;IACvD,MAAM,EAAE,8CAA8C;IACtD,OAAO,EAAE,8CAA8C;CACxD,CAAA;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAChE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,OAAkB,CAAA;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAiD;IAC5E,OAAO,EAAE,CAAC,mCAAmC,EAAE,qCAAqC,CAAC;IACrF,MAAM,EAAE,CAAC,+BAA+B,CAAC;IACzC,OAAO,EAAE,CAAC,gCAAgC,CAAC;CAC5C,CAAA"}
@@ -0,0 +1,9 @@
1
+ export { SolanaClient, type BalancesOptions, type ClientConfig, type OwnerTokensOptions, type TokensOptions } from './client.js';
2
+ export { getBalances, getNftOwners, getNfts, getOwnerNfts, getOwnerTokens, getSolBalances, getTokens, type GetBalancesOptions, type GetOwnerTokensOptions, type GetTokensOptions, type ShortcutOptions, } from './shortcuts.js';
3
+ export { DEFAULT_TOKEN_FIELDS, type Commitment, type DefaultTokenField, type NftDetails, type NftOwner, type OwnedToken, type SolBalance, type TokenBalance, type TokenDetails, type TokenField, type TokenStandard, } from './types.js';
4
+ export { ASSOCIATED_TOKEN_PROGRAM_ID, DEFAULT_RPC_URLS, GENESIS_HASHES, METADATA_PROGRAM_ID, NATIVE_MINT, SOL_DECIMALS, SYSTEM_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, clusterOfGenesis, type Cluster, } from './constants.js';
5
+ export { decodeAddress, encodeAddress, findProgramAddress, getAssociatedTokenAddress, getMetadataAddress, isAddress } from './address.js';
6
+ export { formatAmount, parseMetaplexMetadata, parseMint, parseTokenAccount, type AccountInfo, type MetaplexMetadata, type MintInfo, type TokenAccountInfo, type TokenMetadata, } from './layout.js';
7
+ export { FallbackRpc, HttpError, HttpRpc, RpcError, isNodeFault, type FallbackOptions, type HttpRpcOptions, type RpcTransport } from './rpc.js';
8
+ export { NetworkCheckedRpc, NetworkMismatchError, type RpcSource, type SourceOptions } from './source.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAChI,OAAO,EACL,WAAW,EACX,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,cAAc,EACd,cAAc,EACd,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,2BAA2B,EAC3B,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,OAAO,GACb,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACzI,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,SAAS,EACT,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { SolanaClient } from './client.js';
2
+ export { getBalances, getNftOwners, getNfts, getOwnerNfts, getOwnerTokens, getSolBalances, getTokens, } from './shortcuts.js';
3
+ export { DEFAULT_TOKEN_FIELDS, } from './types.js';
4
+ export { ASSOCIATED_TOKEN_PROGRAM_ID, DEFAULT_RPC_URLS, GENESIS_HASHES, METADATA_PROGRAM_ID, NATIVE_MINT, SOL_DECIMALS, SYSTEM_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, clusterOfGenesis, } from './constants.js';
5
+ export { decodeAddress, encodeAddress, findProgramAddress, getAssociatedTokenAddress, getMetadataAddress, isAddress } from './address.js';
6
+ export { formatAmount, parseMetaplexMetadata, parseMint, parseTokenAccount, } from './layout.js';
7
+ export { FallbackRpc, HttpError, HttpRpc, RpcError, isNodeFault } from './rpc.js';
8
+ export { NetworkCheckedRpc, NetworkMismatchError } from './source.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwF,MAAM,aAAa,CAAA;AAChI,OAAO,EACL,WAAW,EACX,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,cAAc,EACd,cAAc,EACd,SAAS,GAKV,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,oBAAoB,GAWrB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,2BAA2B,EAC3B,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,GAEjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACzI,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,SAAS,EACT,iBAAiB,GAMlB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAgE,MAAM,UAAU,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAsC,MAAM,aAAa,CAAA"}
@@ -0,0 +1,55 @@
1
+ /** getMultipleAccounts 解析后的账户 */
2
+ export interface AccountInfo {
3
+ address: string;
4
+ lamports: bigint;
5
+ /** 所属程序 */
6
+ owner: string;
7
+ data: Uint8Array;
8
+ executable: boolean;
9
+ }
10
+ export interface MintInfo {
11
+ mintAuthority: string | null;
12
+ supply: bigint;
13
+ decimals: number;
14
+ isInitialized: boolean;
15
+ freezeAuthority: string | null;
16
+ /** Token-2022 TokenMetadata 扩展(如有) */
17
+ metadata: TokenMetadata | null;
18
+ }
19
+ export interface TokenMetadata {
20
+ name: string;
21
+ symbol: string;
22
+ uri: string;
23
+ }
24
+ /** 解析 Mint 账户(SPL Token / Token-2022 通用,Token-2022 额外解析 TokenMetadata 扩展) */
25
+ export declare function parseMint(data: Uint8Array): MintInfo;
26
+ export interface TokenAccountInfo {
27
+ mint: string;
28
+ owner: string;
29
+ amount: bigint;
30
+ }
31
+ /** 解析代币账户(SPL Token / Token-2022 前 72 字节相同) */
32
+ export declare function parseTokenAccount(data: Uint8Array): TokenAccountInfo;
33
+ export interface MetaplexMetadata extends TokenMetadata {
34
+ updateAuthority: string;
35
+ mint: string;
36
+ sellerFeeBasisPoints: number;
37
+ creators: Array<{
38
+ address: string;
39
+ verified: boolean;
40
+ share: number;
41
+ }>;
42
+ primarySaleHappened: boolean;
43
+ isMutable: boolean;
44
+ /** 0 NonFungible,1 FungibleAsset,2 Fungible,3 NonFungibleEdition,4 ProgrammableNonFungible,5 ProgrammableNonFungibleEdition */
45
+ tokenStandard: number | null;
46
+ collection: {
47
+ address: string;
48
+ verified: boolean;
49
+ } | null;
50
+ }
51
+ /** 解析 Metaplex Token Metadata 账户;老版本账户缺少后面的字段时,缺的部分为默认值 */
52
+ export declare function parseMetaplexMetadata(data: Uint8Array): MetaplexMetadata;
53
+ /** 按精度格式化:formatAmount(1_500_000_000n, 9) === '1.5' */
54
+ export declare function formatAmount(value: bigint, decimals: number): string;
55
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAEA,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;CACpB;AA4ED,MAAM,WAAW,QAAQ;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,sCAAsC;IACtC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ;AAWD,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,QAAQ,CAqBpD;AAyBD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAMpE;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB,EAAE,MAAM,CAAA;IAC5B,QAAQ,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtE,mBAAmB,EAAE,OAAO,CAAA;IAC5B,SAAS,EAAE,OAAO,CAAA;IAClB,+HAA+H;IAC/H,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAA;CAC1D;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,CA0CxE;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMpE"}
package/dist/layout.js ADDED
@@ -0,0 +1,177 @@
1
+ import { encodeAddress } from './address.js';
2
+ class Reader {
3
+ bytes;
4
+ #offset;
5
+ #view;
6
+ constructor(bytes, offset = 0) {
7
+ this.bytes = bytes;
8
+ this.#offset = offset;
9
+ this.#view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
10
+ }
11
+ get offset() {
12
+ return this.#offset;
13
+ }
14
+ #need(n) {
15
+ if (this.#offset + n > this.bytes.length) {
16
+ throw new RangeError('Account data is shorter than expected');
17
+ }
18
+ }
19
+ skip(n) {
20
+ this.#need(n);
21
+ this.#offset += n;
22
+ }
23
+ u8() {
24
+ this.#need(1);
25
+ return this.bytes[this.#offset++];
26
+ }
27
+ u16() {
28
+ this.#need(2);
29
+ const v = this.#view.getUint16(this.#offset, true);
30
+ this.#offset += 2;
31
+ return v;
32
+ }
33
+ u32() {
34
+ this.#need(4);
35
+ const v = this.#view.getUint32(this.#offset, true);
36
+ this.#offset += 4;
37
+ return v;
38
+ }
39
+ u64() {
40
+ this.#need(8);
41
+ const v = this.#view.getBigUint64(this.#offset, true);
42
+ this.#offset += 8;
43
+ return v;
44
+ }
45
+ pubkey() {
46
+ this.#need(32);
47
+ const v = encodeAddress(this.bytes.slice(this.#offset, this.#offset + 32));
48
+ this.#offset += 32;
49
+ return v;
50
+ }
51
+ /** borsh string:u32 长度 + UTF-8;去掉 Metaplex 用来补齐长度的 \0 */
52
+ string() {
53
+ const len = this.u32();
54
+ this.#need(len);
55
+ const v = new TextDecoder().decode(this.bytes.slice(this.#offset, this.#offset + len));
56
+ this.#offset += len;
57
+ return v.replace(/\0+$/, '').trim();
58
+ }
59
+ option(read) {
60
+ return this.u8() === 1 ? read() : null;
61
+ }
62
+ }
63
+ const MINT_SIZE = 82;
64
+ const ACCOUNT_SIZE = 165;
65
+ /** Token-2022 带扩展的账户:基础布局补齐到 165(Account 的大小),第 165 字节是账户类型,之后是扩展 */
66
+ const ACCOUNT_TYPE_OFFSET = 165;
67
+ const EXTENSIONS_OFFSET = 166;
68
+ const ACCOUNT_TYPE_MINT = 1;
69
+ const ACCOUNT_TYPE_ACCOUNT = 2;
70
+ const EXTENSION_TOKEN_METADATA = 19;
71
+ /** 解析 Mint 账户(SPL Token / Token-2022 通用,Token-2022 额外解析 TokenMetadata 扩展) */
72
+ export function parseMint(data) {
73
+ // 只接受真正的 mint:SPL Token 恰好 82 字节;Token-2022 带扩展时账户类型必须是 Mint(避免把代币账户 / 多签账户当成 mint)
74
+ if (data.length !== MINT_SIZE && !(data.length > ACCOUNT_TYPE_OFFSET && data[ACCOUNT_TYPE_OFFSET] === ACCOUNT_TYPE_MINT)) {
75
+ throw new RangeError('Not a mint account');
76
+ }
77
+ const r = new Reader(data);
78
+ const hasMintAuthority = r.u32() === 1;
79
+ const mintAuthority = r.pubkey();
80
+ const supply = r.u64();
81
+ const decimals = r.u8();
82
+ const isInitialized = r.u8() === 1;
83
+ const hasFreezeAuthority = r.u32() === 1;
84
+ const freezeAuthority = r.pubkey();
85
+ return {
86
+ mintAuthority: hasMintAuthority ? mintAuthority : null,
87
+ supply,
88
+ decimals,
89
+ isInitialized,
90
+ freezeAuthority: hasFreezeAuthority ? freezeAuthority : null,
91
+ metadata: data.length > EXTENSIONS_OFFSET ? parseTokenMetadataExtension(data) : null,
92
+ };
93
+ }
94
+ function parseTokenMetadataExtension(data) {
95
+ try {
96
+ const r = new Reader(data, EXTENSIONS_OFFSET);
97
+ while (r.offset + 4 <= data.length) {
98
+ const type = r.u16();
99
+ const length = r.u16();
100
+ if (type === 0 && length === 0) {
101
+ return null; // 未初始化的填充
102
+ }
103
+ if (type === EXTENSION_TOKEN_METADATA) {
104
+ const m = new Reader(data.slice(r.offset, r.offset + length));
105
+ m.pubkey(); // updateAuthority
106
+ m.pubkey(); // mint
107
+ return { name: m.string(), symbol: m.string(), uri: m.string() };
108
+ }
109
+ r.skip(length);
110
+ }
111
+ }
112
+ catch {
113
+ // 扩展数据不完整:当作没有
114
+ }
115
+ return null;
116
+ }
117
+ /** 解析代币账户(SPL Token / Token-2022 前 72 字节相同) */
118
+ export function parseTokenAccount(data) {
119
+ if (data.length !== ACCOUNT_SIZE && !(data.length > ACCOUNT_TYPE_OFFSET && data[ACCOUNT_TYPE_OFFSET] === ACCOUNT_TYPE_ACCOUNT)) {
120
+ throw new RangeError('Not a token account');
121
+ }
122
+ const r = new Reader(data);
123
+ return { mint: r.pubkey(), owner: r.pubkey(), amount: r.u64() };
124
+ }
125
+ /** 解析 Metaplex Token Metadata 账户;老版本账户缺少后面的字段时,缺的部分为默认值 */
126
+ export function parseMetaplexMetadata(data) {
127
+ const r = new Reader(data);
128
+ if (r.u8() !== 4) {
129
+ throw new RangeError('Not a Metaplex metadata account'); // Key::MetadataV1 = 4
130
+ }
131
+ const updateAuthority = r.pubkey();
132
+ const mint = r.pubkey();
133
+ const name = r.string();
134
+ const symbol = r.string();
135
+ const uri = r.string();
136
+ const sellerFeeBasisPoints = r.u16();
137
+ const creators = r.option(() => {
138
+ const count = r.u32();
139
+ return Array.from({ length: count }, () => ({ address: r.pubkey(), verified: r.u8() === 1, share: r.u8() }));
140
+ }) ?? [];
141
+ const result = {
142
+ updateAuthority,
143
+ mint,
144
+ name,
145
+ symbol,
146
+ uri,
147
+ sellerFeeBasisPoints,
148
+ creators,
149
+ primarySaleHappened: false,
150
+ isMutable: false,
151
+ tokenStandard: null,
152
+ collection: null,
153
+ };
154
+ try {
155
+ result.primarySaleHappened = r.u8() === 1;
156
+ result.isMutable = r.u8() === 1;
157
+ r.option(() => r.u8()); // editionNonce
158
+ result.tokenStandard = r.option(() => r.u8());
159
+ result.collection = r.option(() => {
160
+ const verified = r.u8() === 1;
161
+ return { address: r.pubkey(), verified };
162
+ });
163
+ }
164
+ catch {
165
+ // 老版本账户没有这些字段
166
+ }
167
+ return result;
168
+ }
169
+ /** 按精度格式化:formatAmount(1_500_000_000n, 9) === '1.5' */
170
+ export function formatAmount(value, decimals) {
171
+ const negative = value < 0n;
172
+ const digits = (negative ? -value : value).toString().padStart(decimals + 1, '0');
173
+ const whole = digits.slice(0, digits.length - decimals);
174
+ const fraction = digits.slice(digits.length - decimals).replace(/0+$/, '');
175
+ return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
176
+ }
177
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAY5C,MAAM,MAAM;IAKC;IAJX,OAAO,CAAQ;IACN,KAAK,CAAU;IAExB,YACW,KAAiB,EAC1B,MAAM,GAAG,CAAC;QADD,UAAK,GAAL,KAAK,CAAY;QAG1B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IAC7E,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,CAAS;QACb,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAS;QACZ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACb,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;IACnB,CAAC;IAED,EAAE;QACA,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAW,CAAA;IAC7C,CAAC;IAED,GAAG;QACD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAClD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,GAAG;QACD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAClD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,GAAG;QACD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAA;QAC1E,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAClB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,yDAAyD;IACzD,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACf,MAAM,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAA;QACtF,IAAI,CAAC,OAAO,IAAI,GAAG,CAAA;QACnB,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACrC,CAAC;IAED,MAAM,CAAI,IAAa;QACrB,OAAO,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;CACF;AAkBD,MAAM,SAAS,GAAG,EAAE,CAAA;AACpB,MAAM,YAAY,GAAG,GAAG,CAAA;AACxB,qEAAqE;AACrE,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAC/B,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAA;AAC3B,MAAM,oBAAoB,GAAG,CAAC,CAAA;AAC9B,MAAM,wBAAwB,GAAG,EAAE,CAAA;AAEnC,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,oFAAoF;IACpF,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,iBAAiB,CAAC,EAAE,CAAC;QACzH,MAAM,IAAI,UAAU,CAAC,oBAAoB,CAAC,CAAA;IAC5C,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,gBAAgB,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACtC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IAChC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;IACtB,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,EAAE,CAAA;IACvB,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAClC,MAAM,kBAAkB,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACxC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IAClC,OAAO;QACL,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;QACtD,MAAM;QACN,QAAQ;QACR,aAAa;QACb,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;QAC5D,QAAQ,EAAE,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;KACrF,CAAA;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAgB;IACnD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;QAC7C,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;YACpB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;YACtB,IAAI,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO,IAAI,CAAA,CAAC,UAAU;YACxB,CAAC;YACD,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAA;gBAC7D,CAAC,CAAC,MAAM,EAAE,CAAA,CAAC,kBAAkB;gBAC7B,CAAC,CAAC,MAAM,EAAE,CAAA,CAAC,OAAO;gBAClB,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAA;YAClE,CAAC;YACD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAQD,+CAA+C;AAC/C,MAAM,UAAU,iBAAiB,CAAC,IAAgB;IAChD,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,oBAAoB,CAAC,EAAE,CAAC;QAC/H,MAAM,IAAI,UAAU,CAAC,qBAAqB,CAAC,CAAA;IAC7C,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAA;AACjE,CAAC;AAcD,2DAA2D;AAC3D,MAAM,UAAU,qBAAqB,CAAC,IAAgB;IACpD,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAAC,iCAAiC,CAAC,CAAA,CAAC,sBAAsB;IAChF,CAAC;IACD,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IACvB,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IACvB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;IACtB,MAAM,oBAAoB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;IACpC,MAAM,QAAQ,GACZ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;QACZ,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;QACrB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9G,CAAC,CAAC,IAAI,EAAE,CAAA;IACV,MAAM,MAAM,GAAqB;QAC/B,eAAe;QACf,IAAI;QACJ,IAAI;QACJ,MAAM;QACN,GAAG;QACH,oBAAoB;QACpB,QAAQ;QACR,mBAAmB,EAAE,KAAK;QAC1B,SAAS,EAAE,KAAK;QAChB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;KACjB,CAAA;IACD,IAAI,CAAC;QACH,MAAM,CAAC,mBAAmB,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QACzC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QAC/B,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA,CAAC,eAAe;QACtC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC7C,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;YAChC,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;YAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAgB;IAC1D,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC1E,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAC1E,CAAC"}
package/dist/rpc.d.ts ADDED
@@ -0,0 +1,59 @@
1
+ /** 最小的 JSON-RPC 传输接口:可以传入自己的实现(如包一层 @solana/kit 的 rpc) */
2
+ export interface RpcTransport {
3
+ request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
4
+ }
5
+ /** 节点返回的 JSON-RPC 错误 */
6
+ export declare class RpcError extends Error {
7
+ readonly code: number | undefined;
8
+ readonly data: unknown;
9
+ /** 是否是节点自身的限制(限频、需要 API Key、禁止访问等),换节点可能成功 */
10
+ readonly nodeFault: boolean;
11
+ constructor(message: string, code?: number, data?: unknown);
12
+ }
13
+ /** HTTP 层错误(非 2xx、网络错误、超时) */
14
+ export declare class HttpError extends Error {
15
+ readonly status: number | undefined;
16
+ constructor(message: string, status?: number);
17
+ }
18
+ /** 是否是节点问题(应换节点重试):除了确定性的 JSON-RPC 错误(如参数错误),其余都算 */
19
+ export declare function isNodeFault(err: unknown): boolean;
20
+ export interface HttpRpcOptions {
21
+ /** 单次 HTTP 请求超时(毫秒),<= 0 不限制。默认 10000 */
22
+ timeout?: number;
23
+ headers?: Record<string, string>;
24
+ /** 一个 HTTP 批量请求最多包含的调用数。默认 20 */
25
+ maxBatchSize?: number;
26
+ /** 是否合并成 JSON-RPC 批量请求。默认 true;节点不支持时会自动关闭 */
27
+ batch?: boolean;
28
+ /** 收集窗口(毫秒),窗口内的调用合并成一个 HTTP 请求。默认 0(同一 tick) */
29
+ batchWait?: number;
30
+ /** 遇到 HTTP 429 时的重试次数(指数退避,从 500ms 开始)。默认 2 */
31
+ retries?: number;
32
+ /** 自定义 fetch(如需要代理时) */
33
+ fetch?: typeof fetch;
34
+ }
35
+ /**
36
+ * 基于 fetch 的 JSON-RPC 传输:同一收集窗口内的调用合并成一个 JSON-RPC 批量请求。
37
+ * 节点不支持批量(返回非数组)或限制批量大小(如 drpc 免费档最多 3 条)时自动降级。
38
+ */
39
+ export declare class HttpRpc implements RpcTransport {
40
+ #private;
41
+ readonly url: string;
42
+ constructor(url: string, options?: HttpRpcOptions);
43
+ request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
44
+ }
45
+ export interface FallbackOptions {
46
+ /** 出错节点的冷却时间(毫秒),期间排到最后。默认 30000 */
47
+ cooldown?: number;
48
+ }
49
+ /**
50
+ * 多节点故障切换:按顺序使用,节点问题(网络、超时、限频、需要 Key、403 等)换下一个;
51
+ * 参数错误等确定性错误直接抛出。出错的节点在冷却期内排到最后。
52
+ */
53
+ export declare class FallbackRpc implements RpcTransport {
54
+ #private;
55
+ readonly nodes: readonly RpcTransport[];
56
+ constructor(nodes: readonly RpcTransport[], options?: FallbackOptions);
57
+ request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
58
+ }
59
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC9E;AAED,wBAAwB;AACxB,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;gBAEf,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;CAW3D;AAED,8BAA8B;AAC9B,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;gBAEvB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAK7C;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKjD;AAED,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB;AAwBD;;;GAGG;AACH,qBAAa,OAAQ,YAAW,YAAY;;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;gBAWR,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAWrD,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAwJlF;AAsCD,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,qBAAa,WAAY,YAAW,YAAY;;IAC9C,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;gBAI3B,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,GAAE,eAAoB;IASnE,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;CA0BpF"}