@ledgerhq/device-signer-kit-solana 0.0.0-develop-20250627001242 → 0.0.0-develop-20250628001217

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.
@@ -1,4 +1,4 @@
1
- "use strict";var l=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var S=(c,n)=>{for(var t in n)l(c,t,{get:n[t],enumerable:!0})},b=(c,n,t,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of h(n))!k.call(c,r)&&r!==t&&l(c,r,{get:()=>n[r],enumerable:!(e=g(n,r))||e.enumerable});return c};var x=c=>b(l({},"__esModule",{value:!0}),c);var K={};S(K,{SolanaTransactionTypes:()=>f,TransactionInspector:()=>P});module.exports=x(K);var p=require("@solana/spl-token"),a=require("@solana/web3.js"),m=require("buffer"),f=(t=>(t.STANDARD="Standard",t.SPL="SPL",t))(f||{});class P{constructor(n){this.rawTransactionBytes=n}async inspectTransactionType(){try{const n=this.extractMessage(this.rawTransactionBytes),t=n.compiledInstructions.filter(e=>n.staticAccountKeys[e.programIdIndex]?.equals(p.TOKEN_PROGRAM_ID)).map(e=>({programIdIndex:e.programIdIndex,accountIndexes:e.accountKeyIndexes,data:e.data instanceof Uint8Array?e.data:new Uint8Array(e.data)}));if(t.length===0)return{transactionType:"Standard",data:{}};for(const{programIdIndex:e,accountIndexes:r,data:d}of t){const s=new a.TransactionInstruction({programId:n.staticAccountKeys[e],keys:r.map(i=>({pubkey:n.staticAccountKeys[i],isSigner:n.isAccountSigner(i),isWritable:n.isAccountWritable(i)})),data:m.Buffer.from(d)}),o=(0,p.decodeInstruction)(s);if(o instanceof Error)continue;const u=o.data;if("amount"in u&&!("mint"in u)){const i=s.keys[2]?.pubkey;if(!i)throw new Error("Transfer instruction does not have a destination key");return{transactionType:"SPL",data:{tokenAddress:i.toBase58()}}}if(this.isTransferCheckedData(u)){const{mint:i,authority:T,source:A,destination:I}=u,y=await(0,p.getAssociatedTokenAddress)(i,T);return A.equals(y)||I.equals(y)?{transactionType:"SPL",data:{tokenAddress:y.toBase58()}}:{transactionType:"SPL",data:{createATA:{address:y.toBase58(),mintAddress:i.toBase58()}}}}}throw new Error("Found SPL-token instructions, but none decoded as Transfer or TransferChecked")}catch{return{transactionType:"Standard",data:{}}}}isTransferCheckedData(n){if(n===null||typeof n!="object")return!1;const t=n;return"mint"in t&&t.mint instanceof a.PublicKey&&"authority"in t&&t.authority instanceof a.PublicKey&&"source"in t&&t.source instanceof a.PublicKey&&"destination"in t&&t.destination instanceof a.PublicKey}extractMessage(n){const t=[];try{return a.VersionedTransaction.deserialize(n).message}catch(e){t.push(e instanceof Error?e.message:String(e))}try{return a.VersionedMessage.deserialize(n)}catch(e){t.push(e instanceof Error?e.message:String(e))}try{const e=a.Transaction.from(n),r=e.instructions.flatMap(s=>s.keys.map(o=>o.pubkey)),d=[...new Set([e.feePayer,...r])].filter(Boolean);return{compiledInstructions:e.instructions.map(s=>({programIdIndex:d.findIndex(o=>o.equals(s.programId)),accountKeyIndexes:s.keys.map(o=>d.findIndex(u=>u.equals(o.pubkey))),data:s.data})),staticAccountKeys:d,isAccountSigner:s=>e.signatures.some(o=>o.publicKey.equals(d[s])),isAccountWritable:s=>!0}}catch(e){t.push(e instanceof Error?e.message:String(e))}throw new Error(`Invalid transaction payload \u2013 all deserializers failed:
2
- `+t.map((e,r)=>`${r+1}) ${e}`).join(`
1
+ "use strict";var d=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var I=(c,e)=>{for(var s in e)d(c,s,{get:e[s],enumerable:!0})},f=(c,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of T(e))!A.call(c,a)&&a!==s&&d(c,a,{get:()=>e[a],enumerable:!(n=m(e,a))||n.enumerable});return c};var g=c=>f(d({},"__esModule",{value:!0}),c);var b={};I(b,{SolanaTransactionTypes:()=>y,TransactionInspector:()=>k});module.exports=g(b);var r=require("@solana/spl-token"),i=require("@solana/web3.js"),p=require("buffer"),y=(s=>(s.STANDARD="Standard",s.SPL="SPL",s))(y||{});class k{constructor(e){this.rawTransactionBytes=e}inspectTransactionType(){try{const e=this.extractMessage(this.rawTransactionBytes);for(const s of e.compiledInstructions){const n=e.staticAccountKeys[s.programIdIndex];if(!n.equals(r.TOKEN_PROGRAM_ID))continue;const a=new i.TransactionInstruction({programId:n,keys:s.accountKeyIndexes.map(t=>({pubkey:e.staticAccountKeys[t],isSigner:e.isAccountSigner(t),isWritable:e.isAccountWritable(t)})),data:p.Buffer.from(s.data)});switch(a.data[0]){case r.TokenInstruction.Transfer:{const{keys:{destination:t}}=(0,r.decodeTransferInstruction)(a);return{transactionType:"SPL",data:{tokenAddress:t.pubkey.toBase58()}}}case r.TokenInstruction.TransferChecked:{const{keys:{destination:t}}=(0,r.decodeTransferCheckedInstruction)(a);return{transactionType:"SPL",data:{tokenAddress:t.pubkey.toBase58()}}}case r.TokenInstruction.InitializeAccount:{const{keys:{account:t,mint:o}}=(0,r.decodeInitializeAccountInstruction)(a);return{transactionType:"SPL",data:{createATA:{address:t.pubkey.toBase58(),mintAddress:o.pubkey.toBase58()}}}}default:continue}}return{transactionType:"Standard",data:{}}}catch{return{transactionType:"Standard",data:{}}}}extractMessage(e){const s=[];try{return i.VersionedTransaction.deserialize(e).message}catch(n){s.push(n.message)}try{return i.VersionedMessage.deserialize(e)}catch(n){s.push(n.message)}try{const n=i.Transaction.from(e),a=[n.feePayer,...n.instructions.flatMap(t=>t.keys.map(o=>o.pubkey))],u=Array.from(new Map(a.filter(Boolean).map(t=>[t.toBase58(),t])).values());return{compiledInstructions:n.instructions.map(t=>({programIdIndex:u.findIndex(o=>o.equals(t.programId)),accountKeyIndexes:t.keys.map(o=>u.findIndex(l=>l.equals(o.pubkey))),data:t.data})),staticAccountKeys:u,isAccountSigner:t=>n.signatures.some(o=>o.publicKey.equals(u[t])),isAccountWritable:()=>!0}}catch(n){s.push(n.message)}throw new Error(`Invalid transaction payload \u2013 all deserializers failed:
2
+ `+s.map((n,a)=>`${a+1}) ${n}`).join(`
3
3
  `))}}0&&(module.exports={SolanaTransactionTypes,TransactionInspector});
4
4
  //# sourceMappingURL=TransactionInspector.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/services/TransactionInspector.ts"],
4
- "sourcesContent": ["import {\n decodeInstruction,\n getAssociatedTokenAddress,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport {\n PublicKey,\n Transaction,\n TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { Buffer } from \"buffer\";\n\nexport enum SolanaTransactionTypes {\n STANDARD = \"Standard\",\n SPL = \"SPL\",\n}\n\nexport interface TxInspectorResult {\n transactionType: SolanaTransactionTypes;\n data: {\n tokenAddress?: string;\n createATA?: {\n address: string;\n mintAddress: string;\n };\n };\n}\n\ninterface ParsedSplInstruction {\n programIdIndex: number;\n accountIndexes: number[];\n data: Uint8Array;\n}\n\ntype TransferCheckedData = {\n mint: PublicKey;\n authority: PublicKey;\n source: PublicKey;\n destination: PublicKey;\n};\n\nexport class TransactionInspector {\n constructor(private readonly rawTransactionBytes: Uint8Array) {}\n\n public async inspectTransactionType(): Promise<TxInspectorResult> {\n try {\n const message = this.extractMessage(this.rawTransactionBytes);\n\n const splInstructions: ParsedSplInstruction[] =\n message.compiledInstructions\n .filter((instruction) => {\n const programId =\n message.staticAccountKeys[instruction.programIdIndex];\n return programId?.equals(TOKEN_PROGRAM_ID);\n })\n .map((instruction) => ({\n programIdIndex: instruction.programIdIndex,\n accountIndexes: instruction.accountKeyIndexes,\n data:\n instruction.data instanceof Uint8Array\n ? instruction.data\n : new Uint8Array(instruction.data),\n }));\n\n if (splInstructions.length === 0) {\n return { transactionType: SolanaTransactionTypes.STANDARD, data: {} };\n }\n\n for (const { programIdIndex, accountIndexes, data } of splInstructions) {\n const instruction = new TransactionInstruction({\n programId: message.staticAccountKeys[programIdIndex]!,\n keys: accountIndexes.map((index) => ({\n pubkey: message.staticAccountKeys[index]!,\n isSigner: message.isAccountSigner(index),\n isWritable: message.isAccountWritable(index),\n })),\n data: Buffer.from(data),\n });\n\n const decodedInstruction = decodeInstruction(instruction);\n if (decodedInstruction instanceof Error) continue;\n\n const decodedData = decodedInstruction.data;\n\n // transfer without mint info (likely a direct SPL transfer)\n if (\"amount\" in decodedData && !(\"mint\" in decodedData)) {\n const destinationAccount = instruction.keys[2]?.pubkey;\n if (!destinationAccount) {\n throw new Error(\n \"Transfer instruction does not have a destination key\",\n );\n }\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destinationAccount.toBase58() },\n };\n }\n\n // transferChecked or CreateAssociatedTokenAccount\n if (this.isTransferCheckedData(decodedData)) {\n const { mint, authority, source, destination } = decodedData;\n\n const associatedTokenAccount = await getAssociatedTokenAddress(\n mint,\n authority,\n );\n const isATAUsed =\n source.equals(associatedTokenAccount) ||\n destination.equals(associatedTokenAccount);\n\n if (isATAUsed) {\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: associatedTokenAccount.toBase58() },\n };\n } else {\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: associatedTokenAccount.toBase58(),\n mintAddress: mint.toBase58(),\n },\n },\n };\n }\n }\n }\n\n throw new Error(\n \"Found SPL-token instructions, but none decoded as Transfer or TransferChecked\",\n );\n } catch (_e) {\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {}, // Fallback to standard if any error occurs\n };\n }\n }\n\n private isTransferCheckedData(data: unknown): data is TransferCheckedData {\n if (data === null || typeof data !== \"object\") return false;\n const d = data as Record<string, unknown>;\n return (\n \"mint\" in d &&\n d[\"mint\"] instanceof PublicKey &&\n \"authority\" in d &&\n d[\"authority\"] instanceof PublicKey &&\n \"source\" in d &&\n d[\"source\"] instanceof PublicKey &&\n \"destination\" in d &&\n d[\"destination\"] instanceof PublicKey\n );\n }\n\n private extractMessage(rawBytes: Uint8Array): VersionedMessage {\n const errors: string[] = [];\n\n try {\n return VersionedTransaction.deserialize(rawBytes).message;\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n try {\n return VersionedMessage.deserialize(rawBytes);\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n try {\n const legacyTx = Transaction.from(rawBytes);\n const accountKeys = legacyTx.instructions.flatMap((ix) =>\n ix.keys.map((k) => k.pubkey),\n );\n const staticAccountKeys = [\n ...new Set([legacyTx.feePayer, ...accountKeys]),\n ].filter(Boolean) as PublicKey[];\n\n return {\n compiledInstructions: legacyTx.instructions.map((ix) => ({\n programIdIndex: staticAccountKeys.findIndex((k) =>\n k.equals(ix.programId),\n ),\n accountKeyIndexes: ix.keys.map((k) =>\n staticAccountKeys.findIndex((key) => key.equals(k.pubkey)),\n ),\n data: ix.data,\n })),\n staticAccountKeys,\n isAccountSigner: (i: number) =>\n legacyTx.signatures.some((sig) =>\n sig.publicKey.equals(staticAccountKeys[i]!),\n ),\n isAccountWritable: (_: number) => true,\n } as unknown as VersionedMessage;\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n throw new Error(\n \"Invalid transaction payload \u2013 all deserializers failed:\\n\" +\n errors.map((msg, i) => `${i + 1}) ${msg}`).join(\"\\n\"),\n );\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["TransactionInspector_exports", "__export", "SolanaTransactionTypes", "TransactionInspector", "__toCommonJS", "import_spl_token", "import_web3", "import_buffer", "rawTransactionBytes", "message", "splInstructions", "instruction", "programIdIndex", "accountIndexes", "data", "index", "decodedInstruction", "decodedData", "destinationAccount", "mint", "authority", "source", "destination", "associatedTokenAccount", "d", "rawBytes", "errors", "err", "legacyTx", "accountKeys", "ix", "k", "staticAccountKeys", "key", "i", "sig", "_", "msg"]
4
+ "sourcesContent": ["import {\n decodeInitializeAccountInstruction,\n decodeTransferCheckedInstruction,\n decodeTransferInstruction,\n TOKEN_PROGRAM_ID,\n TokenInstruction,\n} from \"@solana/spl-token\";\nimport {\n type PublicKey,\n Transaction,\n TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { Buffer } from \"buffer\";\n\nexport enum SolanaTransactionTypes {\n STANDARD = \"Standard\",\n SPL = \"SPL\",\n}\nexport interface TxInspectorResult {\n transactionType: SolanaTransactionTypes;\n data: {\n tokenAddress?: string;\n createATA?: {\n address: string;\n mintAddress: string;\n };\n };\n}\n\nexport class TransactionInspector {\n constructor(private readonly rawTransactionBytes: Uint8Array) {}\n\n public inspectTransactionType(): TxInspectorResult {\n try {\n const message = this.extractMessage(this.rawTransactionBytes);\n\n for (const ixMeta of message.compiledInstructions) {\n const programId = message.staticAccountKeys[ixMeta.programIdIndex]!;\n if (!programId.equals(TOKEN_PROGRAM_ID)) continue;\n\n const instruction = new TransactionInstruction({\n programId,\n keys: ixMeta.accountKeyIndexes.map((i) => ({\n pubkey: message.staticAccountKeys[i]!,\n isSigner: message.isAccountSigner(i),\n isWritable: message.isAccountWritable(i),\n })),\n data: Buffer.from(ixMeta.data),\n });\n\n const instructionType = instruction.data[0];\n switch (instructionType) {\n case TokenInstruction.Transfer: {\n const {\n keys: { destination },\n } = decodeTransferInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destination.pubkey.toBase58() },\n };\n }\n case TokenInstruction.TransferChecked: {\n const {\n keys: { destination },\n } = decodeTransferCheckedInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destination.pubkey.toBase58() },\n };\n }\n case TokenInstruction.InitializeAccount: {\n const {\n keys: { account, mint },\n } = decodeInitializeAccountInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: account.pubkey.toBase58(),\n mintAddress: mint.pubkey.toBase58(),\n },\n },\n };\n }\n default:\n continue;\n }\n }\n\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n };\n } catch {\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n };\n }\n }\n\n private extractMessage(rawBytes: Uint8Array): VersionedMessage {\n const errors: string[] = [];\n try {\n return VersionedTransaction.deserialize(rawBytes).message;\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n try {\n return VersionedMessage.deserialize(rawBytes);\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n try {\n const tx = Transaction.from(rawBytes);\n const allKeys = [\n tx.feePayer,\n ...tx.instructions.flatMap((ix) => ix.keys.map((k) => k.pubkey)),\n ];\n\n const staticAccountKeys = Array.from(\n new Map(\n (allKeys.filter(Boolean) as PublicKey[]).map((pk) => [\n pk.toBase58(),\n pk,\n ]),\n ).values(),\n );\n\n interface CustomCompiledInstruction {\n programIdIndex: number;\n accountKeyIndexes: number[];\n data: Uint8Array;\n }\n\n return {\n compiledInstructions: tx.instructions.map(\n (ix): CustomCompiledInstruction => ({\n programIdIndex: staticAccountKeys.findIndex((k) =>\n k.equals(ix.programId),\n ),\n accountKeyIndexes: ix.keys.map((k) =>\n staticAccountKeys.findIndex((s) => s.equals(k.pubkey)),\n ),\n data: ix.data,\n }),\n ),\n staticAccountKeys,\n isAccountSigner: (i: number) =>\n tx.signatures.some((sig) =>\n sig.publicKey.equals(staticAccountKeys[i]!),\n ),\n isAccountWritable: () => true,\n } as unknown as VersionedMessage;\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n throw new Error(\n \"Invalid transaction payload \u2013 all deserializers failed:\\n\" +\n errors.map((m, i) => `${i + 1}) ${m}`).join(\"\\n\"),\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TransactionInspector_exports", "__export", "SolanaTransactionTypes", "TransactionInspector", "__toCommonJS", "import_spl_token", "import_web3", "import_buffer", "rawTransactionBytes", "message", "ixMeta", "programId", "instruction", "i", "destination", "account", "mint", "rawBytes", "errors", "e", "tx", "allKeys", "ix", "k", "staticAccountKeys", "pk", "s", "sig", "m"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var m=Object.create;var p=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var T=(e,t,a,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of A(t))!g.call(e,o)&&o!==a&&p(e,o,{get:()=>t[o],enumerable:!(s=f(t,o))||s.enumerable});return e};var k=(e,t,a)=>(a=e!=null?m(w(e)):{},T(t||!e||!e.__esModule?p(a,"default",{value:e,enumerable:!0}):a,e));var x=k(require("@solana/spl-token")),n=require("@solana/web3.js"),r=require("./TransactionInspector");function i(e){return{compiledInstructions:e.compiledInstructions.map(t=>({...t,data:t.data instanceof Uint8Array||typeof Buffer<"u"&&t.data instanceof Buffer?t.data:new Uint8Array(t.data)})),staticAccountKeys:e.staticAccountKeys,isAccountSigner:t=>!1,isAccountWritable:t=>!1}}vi.mock("@solana/spl-token",async()=>{const e=await vi.importActual("@solana/spl-token");return{...e,decodeInstruction:vi.fn(),getAssociatedTokenAddress:vi.fn(),TOKEN_PROGRAM_ID:e.TOKEN_PROGRAM_ID}});const{decodeInstruction:d,getAssociatedTokenAddress:y,TOKEN_PROGRAM_ID:u}=x;describe("TransactionInspector",()=>{beforeEach(()=>{vi.clearAllMocks()}),afterEach(()=>{vi.restoreAllMocks()}),it("returns STANDARD when no SPL instructions are found",async()=>{const e=new r.TransactionInspector(new Uint8Array);vi.spyOn(e,"extractMessage").mockReturnValue(i({compiledInstructions:[],staticAccountKeys:[]}));const t=await e.inspectTransactionType();expect(t).toEqual({transactionType:r.SolanaTransactionTypes.STANDARD,data:{}})}),it("ignores instructions not targeting TOKEN_PROGRAM_ID",async()=>{const e=n.Keypair.generate().publicKey,t=i({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1],data:new Uint8Array([1])}],staticAccountKeys:[e,n.Keypair.generate().publicKey]}),a=new r.TransactionInspector(new Uint8Array);vi.spyOn(a,"extractMessage").mockReturnValue(t);const s=await a.inspectTransactionType();expect(s.transactionType).toBe(r.SolanaTransactionTypes.STANDARD)}),it("skips a first bad decodeInstruction and succeeds on the next",async()=>{const e=n.Keypair.generate().publicKey,t=n.Keypair.generate().publicKey,a=i({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[0,1,2],data:new Uint8Array([0])},{programIdIndex:0,accountKeyIndexes:[0,1,2],data:new Uint8Array([0])}],staticAccountKeys:[u,t,e]}),s=new r.TransactionInspector(new Uint8Array);vi.spyOn(s,"extractMessage").mockReturnValue(a),d.mockReturnValueOnce(new Error("bad")).mockReturnValueOnce({data:{amount:7}});const o=await s.inspectTransactionType();expect(o).toEqual({transactionType:r.SolanaTransactionTypes.SPL,data:{tokenAddress:e.toBase58()}})}),it("converts Buffer or number[] data into Uint8Array before decoding",async()=>{const e=n.Keypair.generate().publicKey,t=n.Keypair.generate().publicKey,a=i({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[0,1,2],data:Buffer.from([5,6,7])},{programIdIndex:0,accountKeyIndexes:[0,1,2],data:[8,9,10]}],staticAccountKeys:[u,t,e]}),s=new r.TransactionInspector(new Uint8Array);vi.spyOn(s,"extractMessage").mockReturnValue(a),d.mockReturnValueOnce(new Error("nope")).mockImplementation(c=>(expect(c.data).toBeInstanceOf(Uint8Array),{data:{amount:21}}));const o=await s.inspectTransactionType();expect(o.data).toEqual({tokenAddress:e.toBase58()})}),it("detects TransferChecked with existing ATA",async()=>{const e=n.Keypair.generate().publicKey,t=n.Keypair.generate().publicKey,a=n.Keypair.generate().publicKey;y.mockResolvedValue(a);const s=i({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1,2,3,4],data:new Uint8Array([3])}],staticAccountKeys:[u,t,a,a,e]}),o=new r.TransactionInspector(new Uint8Array);vi.spyOn(o,"extractMessage").mockReturnValue(s),d.mockReturnValue({data:{mint:e,authority:t,source:a,destination:a}});const c=await o.inspectTransactionType();expect(c).toEqual({transactionType:r.SolanaTransactionTypes.SPL,data:{tokenAddress:a.toBase58()}})}),it("detects TransferChecked without existing ATA \u21D2 createATA",async()=>{const e=n.Keypair.generate().publicKey,t=n.Keypair.generate().publicKey,a=n.Keypair.generate().publicKey,s=n.Keypair.generate().publicKey;y.mockResolvedValue(a);const o=i({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1,2,3,4],data:new Uint8Array([3])}],staticAccountKeys:[u,t,s,s,e]}),c=new r.TransactionInspector(new Uint8Array);vi.spyOn(c,"extractMessage").mockReturnValue(o),d.mockReturnValue({data:{mint:e,authority:t,source:s,destination:s}});const l=await c.inspectTransactionType();expect(l).toEqual({transactionType:r.SolanaTransactionTypes.SPL,data:{createATA:{address:a.toBase58(),mintAddress:e.toBase58()}}})}),it("extractMessage: throws combined error if all three deserializers fail",()=>{vi.spyOn(n.VersionedTransaction,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(n.VersionedMessage,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")}),vi.spyOn(n.Transaction,"from").mockImplementation(()=>{throw new Error("tx fail")});const e=new r.TransactionInspector(new Uint8Array([1,2]));expect(()=>e.extractMessage(new Uint8Array([1,2]))).toThrow(/Invalid transaction payload[\s\S]*1\) vtx fail[\s\S]*2\) vmd fail[\s\S]*3\) tx fail/)}),it("returns STANDARD fallback when all deserialisers throw",async()=>{vi.spyOn(n.VersionedTransaction,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(n.VersionedMessage,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")}),vi.spyOn(n.Transaction,"from").mockImplementation(()=>{throw new Error("tx fail")});const t=await new r.TransactionInspector(new Uint8Array([222,173,190,239])).inspectTransactionType();expect(t).toEqual({transactionType:r.SolanaTransactionTypes.STANDARD,data:{}})})});describe("isTransferCheckedData",()=>{const e=new r.TransactionInspector(new Uint8Array);it("returns false for null or primitive values",()=>{expect(e.isTransferCheckedData(null)).toBe(!1),expect(e.isTransferCheckedData(42)).toBe(!1),expect(e.isTransferCheckedData("string")).toBe(!1)}),it("returns false for objects missing required keys or wrong types",()=>{const t=n.Keypair.generate().publicKey;expect(e.isTransferCheckedData({mint:t,authority:t})).toBe(!1),expect(e.isTransferCheckedData({mint:"nope",authority:null,source:{},destination:[]})).toBe(!1)}),it("returns true for a properly shaped object",()=>{const t=n.Keypair.generate().publicKey,a={mint:t,authority:t,source:t,destination:t};expect(e.isTransferCheckedData(a)).toBe(!0)})});describe("extractMessage legacy fallback",()=>{it("handles a legacy Transaction via serializeMessage and returns STANDARD",async()=>{vi.spyOn(n.VersionedTransaction,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(n.VersionedMessage,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")});const e=n.Keypair.generate(),t=n.Keypair.generate(),a=new n.Transaction().add(n.SystemProgram.transfer({fromPubkey:e.publicKey,toPubkey:t.publicKey,lamports:1}));a.feePayer=e.publicKey,a.recentBlockhash="11111111111111111111111111111111",a.sign(e);const s=a.serialize(),o=await new r.TransactionInspector(s).inspectTransactionType();expect(o.transactionType).toBe("Standard"),expect(o.data).toEqual({})})});
1
+ "use strict";var T=Object.create;var d=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var m=(e,t,r,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of A(t))!g.call(e,n)&&n!==r&&d(e,n,{get:()=>t[n],enumerable:!(c=b(t,n))||c.enumerable});return e};var K=(e,t,r)=>(r=e!=null?T(f(e)):{},m(t||!e||!e.__esModule?d(r,"default",{value:e,enumerable:!0}):r,e));var p=require("@solana/spl-token"),a=require("@solana/web3.js"),u=K(require("bs58")),s=require("vitest"),o=require("./TransactionInspector");const l=u.default.encode(new Uint8Array(32).fill(1));(0,s.describe)("TransactionInspector",()=>{(0,s.it)("falls back to STANDARD for a plain SystemProgram transfer",()=>{const e=a.Keypair.generate(),t=a.Keypair.generate().publicKey,r=new a.Transaction().add(a.SystemProgram.transfer({fromPubkey:e.publicKey,toPubkey:t,lamports:1e3}));r.recentBlockhash=l,r.feePayer=e.publicKey,r.sign(e);const c=r.serialize(),n=new o.TransactionInspector(c).inspectTransactionType();(0,s.expect)(n.transactionType).toBe(o.SolanaTransactionTypes.STANDARD),(0,s.expect)(n.data).toEqual({})}),(0,s.it)("detects an SPL Transfer and returns the destination address",()=>{const e=a.Keypair.generate(),t=a.Keypair.generate().publicKey,r=a.Keypair.generate().publicKey,c=e.publicKey,n=new a.Transaction().add((0,p.createTransferInstruction)(t,r,c,42n,[],p.TOKEN_PROGRAM_ID));n.recentBlockhash=l,n.feePayer=e.publicKey,n.sign(e);const i=new o.TransactionInspector(n.serialize()).inspectTransactionType();(0,s.expect)(i.transactionType).toBe(o.SolanaTransactionTypes.SPL),(0,s.expect)(i.data.tokenAddress).toBe(r.toBase58())}),(0,s.it)("detects an SPL TransferChecked and returns the destination address",()=>{const e=a.Keypair.generate(),t=a.Keypair.generate().publicKey,r=a.Keypair.generate().publicKey,c=a.Keypair.generate().publicKey,n=e.publicKey,i=new a.Transaction().add((0,p.createTransferCheckedInstruction)(r,t,c,n,123n,0,[],p.TOKEN_PROGRAM_ID));i.recentBlockhash=l,i.feePayer=e.publicKey,i.sign(e);const y=new o.TransactionInspector(i.serialize()).inspectTransactionType();(0,s.expect)(y.transactionType).toBe(o.SolanaTransactionTypes.SPL),(0,s.expect)(y.data.tokenAddress).toBe(c.toBase58())}),(0,s.it)("detects an SPL InitializeAccount and returns the new ATA and mint",()=>{const e=a.Keypair.generate(),t=a.Keypair.generate().publicKey,r=a.Keypair.generate().publicKey,c=e.publicKey,n=new a.Transaction().add((0,p.createInitializeAccountInstruction)(r,t,c,p.TOKEN_PROGRAM_ID));n.recentBlockhash=l,n.feePayer=e.publicKey,n.sign(e);const i=new o.TransactionInspector(n.serialize()).inspectTransactionType();(0,s.expect)(i.transactionType).toBe(o.SolanaTransactionTypes.SPL),(0,s.expect)(i.data.createATA).toEqual({address:r.toBase58(),mintAddress:t.toBase58()})}),(0,s.it)("falls back to STANDARD if the payload is unparseable",()=>{const e=new Uint8Array([0,1,2,3,4,5]),t=new o.TransactionInspector(e).inspectTransactionType();(0,s.expect)(t.transactionType).toBe(o.SolanaTransactionTypes.STANDARD),(0,s.expect)(t.data).toEqual({})})});
2
2
  //# sourceMappingURL=TransactionInspector.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/services/TransactionInspector.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as splToken from \"@solana/spl-token\";\nimport {\n Keypair,\n type PublicKey,\n SystemProgram,\n Transaction,\n type TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\n\nimport {\n SolanaTransactionTypes,\n TransactionInspector,\n} from \"./TransactionInspector\";\n\nfunction makeFakeMessage(opts: {\n compiledInstructions: Array<{\n programIdIndex: number;\n accountKeyIndexes: number[];\n data: Uint8Array | number[] | Buffer;\n }>;\n staticAccountKeys: PublicKey[];\n}): VersionedMessage {\n return {\n compiledInstructions: opts.compiledInstructions.map((ix) => ({\n ...ix,\n data:\n ix.data instanceof Uint8Array\n ? ix.data\n : typeof Buffer !== \"undefined\" && ix.data instanceof Buffer\n ? ix.data\n : new Uint8Array(ix.data as number[]),\n })),\n staticAccountKeys: opts.staticAccountKeys,\n isAccountSigner: (_: number) => false,\n isAccountWritable: (_: number) => false,\n } as any;\n}\n\nvi.mock(\"@solana/spl-token\", async () => {\n const actual = await vi.importActual<any>(\"@solana/spl-token\");\n return {\n ...actual,\n decodeInstruction: vi.fn(),\n getAssociatedTokenAddress: vi.fn(),\n TOKEN_PROGRAM_ID: actual.TOKEN_PROGRAM_ID,\n };\n});\nconst { decodeInstruction, getAssociatedTokenAddress, TOKEN_PROGRAM_ID } =\n splToken as any;\n\ndescribe(\"TransactionInspector\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n it(\"returns STANDARD when no SPL instructions are found\", async () => {\n // given\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(\n makeFakeMessage({ compiledInstructions: [], staticAccountKeys: [] }),\n );\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n });\n });\n\n it(\"ignores instructions not targeting TOKEN_PROGRAM_ID\", async () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1],\n data: new Uint8Array([1]),\n },\n ],\n staticAccountKeys: [fakePk, Keypair.generate().publicKey],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n });\n\n it(\"skips a first bad decodeInstruction and succeeds on the next\", async () => {\n // given\n const dest = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: new Uint8Array([0]),\n },\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: new Uint8Array([0]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, other, dest],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction\n .mockReturnValueOnce(new Error(\"bad\"))\n .mockReturnValueOnce({ data: { amount: 7 } });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: dest.toBase58() },\n });\n });\n\n it(\"converts Buffer or number[] data into Uint8Array before decoding\", async () => {\n // given\n const dest = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: Buffer.from([5, 6, 7]),\n },\n { programIdIndex: 0, accountKeyIndexes: [0, 1, 2], data: [8, 9, 10] },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, other, dest],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction\n .mockReturnValueOnce(new Error(\"nope\"))\n .mockImplementation((ix: TransactionInstruction) => {\n expect(ix.data).toBeInstanceOf(Uint8Array);\n return { data: { amount: 21 } };\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res.data).toEqual({ tokenAddress: dest.toBase58() });\n });\n\n it(\"detects TransferChecked with existing ATA\", async () => {\n // given\n const mint = Keypair.generate().publicKey;\n const auth = Keypair.generate().publicKey;\n const ata = Keypair.generate().publicKey;\n getAssociatedTokenAddress.mockResolvedValue(ata);\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1, 2, 3, 4],\n data: new Uint8Array([3]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, auth, ata, ata, mint],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction.mockReturnValue({\n data: { mint, authority: auth, source: ata, destination: ata },\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: ata.toBase58() },\n });\n });\n\n it(\"detects TransferChecked without existing ATA \u21D2 createATA\", async () => {\n // given\n const mint = Keypair.generate().publicKey;\n const auth = Keypair.generate().publicKey;\n const ata = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n getAssociatedTokenAddress.mockResolvedValue(ata);\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1, 2, 3, 4],\n data: new Uint8Array([3]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, auth, other, other, mint],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction.mockReturnValue({\n data: { mint, authority: auth, source: other, destination: other },\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: ata.toBase58(),\n mintAddress: mint.toBase58(),\n },\n },\n });\n });\n\n it(\"extractMessage: throws combined error if all three deserializers fail\", () => {\n // given\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n vi.spyOn(Transaction, \"from\").mockImplementation(() => {\n throw new Error(\"tx fail\");\n });\n\n // when\n const inspector = new TransactionInspector(new Uint8Array([0x01, 0x02]));\n\n // then\n expect(() =>\n (inspector as any).extractMessage(new Uint8Array([0x01, 0x02])),\n ).toThrow(\n /Invalid transaction payload[\\s\\S]*1\\) vtx fail[\\s\\S]*2\\) vmd fail[\\s\\S]*3\\) tx fail/,\n );\n });\n\n it(\"returns STANDARD fallback when all deserialisers throw\", async () => {\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n vi.spyOn(Transaction, \"from\").mockImplementation(() => {\n throw new Error(\"tx fail\");\n });\n\n const inspector = new TransactionInspector(\n new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n );\n const result = await inspector.inspectTransactionType();\n\n expect(result).toEqual({\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n });\n });\n});\n\ndescribe(\"isTransferCheckedData\", () => {\n const inspector = new TransactionInspector(new Uint8Array());\n\n it(\"returns false for null or primitive values\", () => {\n expect((inspector as any).isTransferCheckedData(null)).toBe(false);\n expect((inspector as any).isTransferCheckedData(42)).toBe(false);\n expect((inspector as any).isTransferCheckedData(\"string\")).toBe(false);\n });\n\n it(\"returns false for objects missing required keys or wrong types\", () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n\n // when / then\n // Missing keys\n expect(\n (inspector as any).isTransferCheckedData({\n mint: fakePk,\n authority: fakePk,\n }),\n ).toBe(false);\n // Wrong types\n expect(\n (inspector as any).isTransferCheckedData({\n mint: \"nope\",\n authority: null,\n source: {},\n destination: [],\n }),\n ).toBe(false);\n });\n\n it(\"returns true for a properly shaped object\", () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n const data = {\n mint: fakePk,\n authority: fakePk,\n source: fakePk,\n destination: fakePk,\n };\n\n // when / then\n expect((inspector as any).isTransferCheckedData(data)).toBe(true);\n });\n});\n\ndescribe(\"extractMessage legacy fallback\", () => {\n it(\"handles a legacy Transaction via serializeMessage and returns STANDARD\", async () => {\n // given\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n\n const from = Keypair.generate();\n const to = Keypair.generate();\n const tx = new Transaction().add(\n SystemProgram.transfer({\n fromPubkey: from.publicKey,\n toPubkey: to.publicKey,\n lamports: 1,\n }),\n );\n tx.feePayer = from.publicKey;\n tx.recentBlockhash = \"11111111111111111111111111111111\";\n\n tx.sign(from);\n\n const raw = tx.serialize();\n\n // when\n const result = await new TransactionInspector(raw).inspectTransactionType();\n\n // then\n expect(result.transactionType).toBe(\"Standard\");\n expect(result.data).toEqual({});\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["splToken", "import_web3", "import_TransactionInspector", "makeFakeMessage", "opts", "ix", "_", "actual", "decodeInstruction", "getAssociatedTokenAddress", "TOKEN_PROGRAM_ID", "inspector", "res", "fakePk", "msg", "dest", "other", "mint", "auth", "ata", "result", "data", "from", "to", "tx", "raw"]
4
+ "sourcesContent": ["import {\n createInitializeAccountInstruction,\n createTransferCheckedInstruction,\n createTransferInstruction,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { Keypair, SystemProgram, Transaction } from \"@solana/web3.js\";\nimport bs58 from \"bs58\";\nimport { describe, expect, it } from \"vitest\";\n\nimport {\n SolanaTransactionTypes,\n TransactionInspector,\n} from \"./TransactionInspector\";\n\nconst DUMMY_BLOCKHASH = bs58.encode(new Uint8Array(32).fill(1));\n\ndescribe(\"TransactionInspector\", () => {\n it(\"falls back to STANDARD for a plain SystemProgram transfer\", () => {\n const payer = Keypair.generate();\n const dest = Keypair.generate().publicKey;\n\n const tx = new Transaction().add(\n SystemProgram.transfer({\n fromPubkey: payer.publicKey,\n toPubkey: dest,\n lamports: 1_000,\n }),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const raw = tx.serialize();\n const result = new TransactionInspector(raw).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n expect(result.data).toEqual({});\n });\n\n it(\"detects an SPL Transfer and returns the destination address\", () => {\n const payer = Keypair.generate();\n const source = Keypair.generate().publicKey;\n const destination = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createTransferInstruction(\n source,\n destination,\n owner,\n 42n,\n [],\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.tokenAddress).toBe(destination.toBase58());\n });\n\n it(\"detects an SPL TransferChecked and returns the destination address\", () => {\n const payer = Keypair.generate();\n const mint = Keypair.generate().publicKey;\n const source = Keypair.generate().publicKey;\n const destination = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createTransferCheckedInstruction(\n source,\n mint,\n destination,\n owner,\n 123n,\n 0,\n [],\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.tokenAddress).toBe(destination.toBase58());\n });\n\n it(\"detects an SPL InitializeAccount and returns the new ATA and mint\", () => {\n const payer = Keypair.generate();\n const mint = Keypair.generate().publicKey;\n const newAccount = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createInitializeAccountInstruction(\n newAccount,\n mint,\n owner,\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.createATA).toEqual({\n address: newAccount.toBase58(),\n mintAddress: mint.toBase58(),\n });\n });\n\n it(\"falls back to STANDARD if the payload is unparseable\", () => {\n const garbage = new Uint8Array([0, 1, 2, 3, 4, 5]);\n const result = new TransactionInspector(garbage).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n expect(result.data).toEqual({});\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_spl_token", "import_web3", "import_bs58", "import_vitest", "import_TransactionInspector", "DUMMY_BLOCKHASH", "bs58", "payer", "dest", "tx", "raw", "result", "source", "destination", "owner", "mint", "newAccount", "garbage"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import{decodeInstruction as m,getAssociatedTokenAddress as f,TOKEN_PROGRAM_ID as T}from"@solana/spl-token";import{PublicKey as u,Transaction as A,TransactionInstruction as I,VersionedMessage as g,VersionedTransaction as h}from"@solana/web3.js";import{Buffer as k}from"buffer";var S=(n=>(n.STANDARD="Standard",n.SPL="SPL",n))(S||{});class D{constructor(t){this.rawTransactionBytes=t}async inspectTransactionType(){try{const t=this.extractMessage(this.rawTransactionBytes),n=t.compiledInstructions.filter(e=>t.staticAccountKeys[e.programIdIndex]?.equals(T)).map(e=>({programIdIndex:e.programIdIndex,accountIndexes:e.accountKeyIndexes,data:e.data instanceof Uint8Array?e.data:new Uint8Array(e.data)}));if(n.length===0)return{transactionType:"Standard",data:{}};for(const{programIdIndex:e,accountIndexes:o,data:i}of n){const a=new I({programId:t.staticAccountKeys[e],keys:o.map(s=>({pubkey:t.staticAccountKeys[s],isSigner:t.isAccountSigner(s),isWritable:t.isAccountWritable(s)})),data:k.from(i)}),r=m(a);if(r instanceof Error)continue;const c=r.data;if("amount"in c&&!("mint"in c)){const s=a.keys[2]?.pubkey;if(!s)throw new Error("Transfer instruction does not have a destination key");return{transactionType:"SPL",data:{tokenAddress:s.toBase58()}}}if(this.isTransferCheckedData(c)){const{mint:s,authority:p,source:y,destination:l}=c,d=await f(s,p);return y.equals(d)||l.equals(d)?{transactionType:"SPL",data:{tokenAddress:d.toBase58()}}:{transactionType:"SPL",data:{createATA:{address:d.toBase58(),mintAddress:s.toBase58()}}}}}throw new Error("Found SPL-token instructions, but none decoded as Transfer or TransferChecked")}catch{return{transactionType:"Standard",data:{}}}}isTransferCheckedData(t){if(t===null||typeof t!="object")return!1;const n=t;return"mint"in n&&n.mint instanceof u&&"authority"in n&&n.authority instanceof u&&"source"in n&&n.source instanceof u&&"destination"in n&&n.destination instanceof u}extractMessage(t){const n=[];try{return h.deserialize(t).message}catch(e){n.push(e instanceof Error?e.message:String(e))}try{return g.deserialize(t)}catch(e){n.push(e instanceof Error?e.message:String(e))}try{const e=A.from(t),o=e.instructions.flatMap(a=>a.keys.map(r=>r.pubkey)),i=[...new Set([e.feePayer,...o])].filter(Boolean);return{compiledInstructions:e.instructions.map(a=>({programIdIndex:i.findIndex(r=>r.equals(a.programId)),accountKeyIndexes:a.keys.map(r=>i.findIndex(c=>c.equals(r.pubkey))),data:a.data})),staticAccountKeys:i,isAccountSigner:a=>e.signatures.some(r=>r.publicKey.equals(i[a])),isAccountWritable:a=>!0}}catch(e){n.push(e instanceof Error?e.message:String(e))}throw new Error(`Invalid transaction payload \u2013 all deserializers failed:
2
- `+n.map((e,o)=>`${o+1}) ${e}`).join(`
3
- `))}}export{S as SolanaTransactionTypes,D as TransactionInspector};
1
+ import{decodeInitializeAccountInstruction as u,decodeTransferCheckedInstruction as d,decodeTransferInstruction as p,TOKEN_PROGRAM_ID as y,TokenInstruction as c}from"@solana/spl-token";import{Transaction as l,TransactionInstruction as m,VersionedMessage as T,VersionedTransaction as A}from"@solana/web3.js";import{Buffer as I}from"buffer";var f=(n=>(n.STANDARD="Standard",n.SPL="SPL",n))(f||{});class x{constructor(s){this.rawTransactionBytes=s}inspectTransactionType(){try{const s=this.extractMessage(this.rawTransactionBytes);for(const n of s.compiledInstructions){const t=s.staticAccountKeys[n.programIdIndex];if(!t.equals(y))continue;const r=new m({programId:t,keys:n.accountKeyIndexes.map(e=>({pubkey:s.staticAccountKeys[e],isSigner:s.isAccountSigner(e),isWritable:s.isAccountWritable(e)})),data:I.from(n.data)});switch(r.data[0]){case c.Transfer:{const{keys:{destination:e}}=p(r);return{transactionType:"SPL",data:{tokenAddress:e.pubkey.toBase58()}}}case c.TransferChecked:{const{keys:{destination:e}}=d(r);return{transactionType:"SPL",data:{tokenAddress:e.pubkey.toBase58()}}}case c.InitializeAccount:{const{keys:{account:e,mint:a}}=u(r);return{transactionType:"SPL",data:{createATA:{address:e.pubkey.toBase58(),mintAddress:a.pubkey.toBase58()}}}}default:continue}}return{transactionType:"Standard",data:{}}}catch{return{transactionType:"Standard",data:{}}}}extractMessage(s){const n=[];try{return A.deserialize(s).message}catch(t){n.push(t.message)}try{return T.deserialize(s)}catch(t){n.push(t.message)}try{const t=l.from(s),r=[t.feePayer,...t.instructions.flatMap(e=>e.keys.map(a=>a.pubkey))],o=Array.from(new Map(r.filter(Boolean).map(e=>[e.toBase58(),e])).values());return{compiledInstructions:t.instructions.map(e=>({programIdIndex:o.findIndex(a=>a.equals(e.programId)),accountKeyIndexes:e.keys.map(a=>o.findIndex(i=>i.equals(a.pubkey))),data:e.data})),staticAccountKeys:o,isAccountSigner:e=>t.signatures.some(a=>a.publicKey.equals(o[e])),isAccountWritable:()=>!0}}catch(t){n.push(t.message)}throw new Error(`Invalid transaction payload \u2013 all deserializers failed:
2
+ `+n.map((t,r)=>`${r+1}) ${t}`).join(`
3
+ `))}}export{f as SolanaTransactionTypes,x as TransactionInspector};
4
4
  //# sourceMappingURL=TransactionInspector.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/services/TransactionInspector.ts"],
4
- "sourcesContent": ["import {\n decodeInstruction,\n getAssociatedTokenAddress,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport {\n PublicKey,\n Transaction,\n TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { Buffer } from \"buffer\";\n\nexport enum SolanaTransactionTypes {\n STANDARD = \"Standard\",\n SPL = \"SPL\",\n}\n\nexport interface TxInspectorResult {\n transactionType: SolanaTransactionTypes;\n data: {\n tokenAddress?: string;\n createATA?: {\n address: string;\n mintAddress: string;\n };\n };\n}\n\ninterface ParsedSplInstruction {\n programIdIndex: number;\n accountIndexes: number[];\n data: Uint8Array;\n}\n\ntype TransferCheckedData = {\n mint: PublicKey;\n authority: PublicKey;\n source: PublicKey;\n destination: PublicKey;\n};\n\nexport class TransactionInspector {\n constructor(private readonly rawTransactionBytes: Uint8Array) {}\n\n public async inspectTransactionType(): Promise<TxInspectorResult> {\n try {\n const message = this.extractMessage(this.rawTransactionBytes);\n\n const splInstructions: ParsedSplInstruction[] =\n message.compiledInstructions\n .filter((instruction) => {\n const programId =\n message.staticAccountKeys[instruction.programIdIndex];\n return programId?.equals(TOKEN_PROGRAM_ID);\n })\n .map((instruction) => ({\n programIdIndex: instruction.programIdIndex,\n accountIndexes: instruction.accountKeyIndexes,\n data:\n instruction.data instanceof Uint8Array\n ? instruction.data\n : new Uint8Array(instruction.data),\n }));\n\n if (splInstructions.length === 0) {\n return { transactionType: SolanaTransactionTypes.STANDARD, data: {} };\n }\n\n for (const { programIdIndex, accountIndexes, data } of splInstructions) {\n const instruction = new TransactionInstruction({\n programId: message.staticAccountKeys[programIdIndex]!,\n keys: accountIndexes.map((index) => ({\n pubkey: message.staticAccountKeys[index]!,\n isSigner: message.isAccountSigner(index),\n isWritable: message.isAccountWritable(index),\n })),\n data: Buffer.from(data),\n });\n\n const decodedInstruction = decodeInstruction(instruction);\n if (decodedInstruction instanceof Error) continue;\n\n const decodedData = decodedInstruction.data;\n\n // transfer without mint info (likely a direct SPL transfer)\n if (\"amount\" in decodedData && !(\"mint\" in decodedData)) {\n const destinationAccount = instruction.keys[2]?.pubkey;\n if (!destinationAccount) {\n throw new Error(\n \"Transfer instruction does not have a destination key\",\n );\n }\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destinationAccount.toBase58() },\n };\n }\n\n // transferChecked or CreateAssociatedTokenAccount\n if (this.isTransferCheckedData(decodedData)) {\n const { mint, authority, source, destination } = decodedData;\n\n const associatedTokenAccount = await getAssociatedTokenAddress(\n mint,\n authority,\n );\n const isATAUsed =\n source.equals(associatedTokenAccount) ||\n destination.equals(associatedTokenAccount);\n\n if (isATAUsed) {\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: associatedTokenAccount.toBase58() },\n };\n } else {\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: associatedTokenAccount.toBase58(),\n mintAddress: mint.toBase58(),\n },\n },\n };\n }\n }\n }\n\n throw new Error(\n \"Found SPL-token instructions, but none decoded as Transfer or TransferChecked\",\n );\n } catch (_e) {\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {}, // Fallback to standard if any error occurs\n };\n }\n }\n\n private isTransferCheckedData(data: unknown): data is TransferCheckedData {\n if (data === null || typeof data !== \"object\") return false;\n const d = data as Record<string, unknown>;\n return (\n \"mint\" in d &&\n d[\"mint\"] instanceof PublicKey &&\n \"authority\" in d &&\n d[\"authority\"] instanceof PublicKey &&\n \"source\" in d &&\n d[\"source\"] instanceof PublicKey &&\n \"destination\" in d &&\n d[\"destination\"] instanceof PublicKey\n );\n }\n\n private extractMessage(rawBytes: Uint8Array): VersionedMessage {\n const errors: string[] = [];\n\n try {\n return VersionedTransaction.deserialize(rawBytes).message;\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n try {\n return VersionedMessage.deserialize(rawBytes);\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n try {\n const legacyTx = Transaction.from(rawBytes);\n const accountKeys = legacyTx.instructions.flatMap((ix) =>\n ix.keys.map((k) => k.pubkey),\n );\n const staticAccountKeys = [\n ...new Set([legacyTx.feePayer, ...accountKeys]),\n ].filter(Boolean) as PublicKey[];\n\n return {\n compiledInstructions: legacyTx.instructions.map((ix) => ({\n programIdIndex: staticAccountKeys.findIndex((k) =>\n k.equals(ix.programId),\n ),\n accountKeyIndexes: ix.keys.map((k) =>\n staticAccountKeys.findIndex((key) => key.equals(k.pubkey)),\n ),\n data: ix.data,\n })),\n staticAccountKeys,\n isAccountSigner: (i: number) =>\n legacyTx.signatures.some((sig) =>\n sig.publicKey.equals(staticAccountKeys[i]!),\n ),\n isAccountWritable: (_: number) => true,\n } as unknown as VersionedMessage;\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err));\n }\n\n throw new Error(\n \"Invalid transaction payload \u2013 all deserializers failed:\\n\" +\n errors.map((msg, i) => `${i + 1}) ${msg}`).join(\"\\n\"),\n );\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["decodeInstruction", "getAssociatedTokenAddress", "TOKEN_PROGRAM_ID", "PublicKey", "Transaction", "TransactionInstruction", "VersionedMessage", "VersionedTransaction", "Buffer", "SolanaTransactionTypes", "TransactionInspector", "rawTransactionBytes", "message", "splInstructions", "instruction", "programIdIndex", "accountIndexes", "data", "index", "decodedInstruction", "decodedData", "destinationAccount", "mint", "authority", "source", "destination", "associatedTokenAccount", "d", "rawBytes", "errors", "err", "legacyTx", "accountKeys", "ix", "k", "staticAccountKeys", "key", "i", "sig", "_", "msg"]
4
+ "sourcesContent": ["import {\n decodeInitializeAccountInstruction,\n decodeTransferCheckedInstruction,\n decodeTransferInstruction,\n TOKEN_PROGRAM_ID,\n TokenInstruction,\n} from \"@solana/spl-token\";\nimport {\n type PublicKey,\n Transaction,\n TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { Buffer } from \"buffer\";\n\nexport enum SolanaTransactionTypes {\n STANDARD = \"Standard\",\n SPL = \"SPL\",\n}\nexport interface TxInspectorResult {\n transactionType: SolanaTransactionTypes;\n data: {\n tokenAddress?: string;\n createATA?: {\n address: string;\n mintAddress: string;\n };\n };\n}\n\nexport class TransactionInspector {\n constructor(private readonly rawTransactionBytes: Uint8Array) {}\n\n public inspectTransactionType(): TxInspectorResult {\n try {\n const message = this.extractMessage(this.rawTransactionBytes);\n\n for (const ixMeta of message.compiledInstructions) {\n const programId = message.staticAccountKeys[ixMeta.programIdIndex]!;\n if (!programId.equals(TOKEN_PROGRAM_ID)) continue;\n\n const instruction = new TransactionInstruction({\n programId,\n keys: ixMeta.accountKeyIndexes.map((i) => ({\n pubkey: message.staticAccountKeys[i]!,\n isSigner: message.isAccountSigner(i),\n isWritable: message.isAccountWritable(i),\n })),\n data: Buffer.from(ixMeta.data),\n });\n\n const instructionType = instruction.data[0];\n switch (instructionType) {\n case TokenInstruction.Transfer: {\n const {\n keys: { destination },\n } = decodeTransferInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destination.pubkey.toBase58() },\n };\n }\n case TokenInstruction.TransferChecked: {\n const {\n keys: { destination },\n } = decodeTransferCheckedInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: destination.pubkey.toBase58() },\n };\n }\n case TokenInstruction.InitializeAccount: {\n const {\n keys: { account, mint },\n } = decodeInitializeAccountInstruction(instruction);\n return {\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: account.pubkey.toBase58(),\n mintAddress: mint.pubkey.toBase58(),\n },\n },\n };\n }\n default:\n continue;\n }\n }\n\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n };\n } catch {\n return {\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n };\n }\n }\n\n private extractMessage(rawBytes: Uint8Array): VersionedMessage {\n const errors: string[] = [];\n try {\n return VersionedTransaction.deserialize(rawBytes).message;\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n try {\n return VersionedMessage.deserialize(rawBytes);\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n try {\n const tx = Transaction.from(rawBytes);\n const allKeys = [\n tx.feePayer,\n ...tx.instructions.flatMap((ix) => ix.keys.map((k) => k.pubkey)),\n ];\n\n const staticAccountKeys = Array.from(\n new Map(\n (allKeys.filter(Boolean) as PublicKey[]).map((pk) => [\n pk.toBase58(),\n pk,\n ]),\n ).values(),\n );\n\n interface CustomCompiledInstruction {\n programIdIndex: number;\n accountKeyIndexes: number[];\n data: Uint8Array;\n }\n\n return {\n compiledInstructions: tx.instructions.map(\n (ix): CustomCompiledInstruction => ({\n programIdIndex: staticAccountKeys.findIndex((k) =>\n k.equals(ix.programId),\n ),\n accountKeyIndexes: ix.keys.map((k) =>\n staticAccountKeys.findIndex((s) => s.equals(k.pubkey)),\n ),\n data: ix.data,\n }),\n ),\n staticAccountKeys,\n isAccountSigner: (i: number) =>\n tx.signatures.some((sig) =>\n sig.publicKey.equals(staticAccountKeys[i]!),\n ),\n isAccountWritable: () => true,\n } as unknown as VersionedMessage;\n } catch (e) {\n errors.push((e as Error).message);\n }\n\n throw new Error(\n \"Invalid transaction payload \u2013 all deserializers failed:\\n\" +\n errors.map((m, i) => `${i + 1}) ${m}`).join(\"\\n\"),\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["decodeInitializeAccountInstruction", "decodeTransferCheckedInstruction", "decodeTransferInstruction", "TOKEN_PROGRAM_ID", "TokenInstruction", "Transaction", "TransactionInstruction", "VersionedMessage", "VersionedTransaction", "Buffer", "SolanaTransactionTypes", "TransactionInspector", "rawTransactionBytes", "message", "ixMeta", "programId", "instruction", "i", "destination", "account", "mint", "rawBytes", "errors", "e", "tx", "allKeys", "ix", "k", "staticAccountKeys", "pk", "s", "sig", "m"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import*as w from"@solana/spl-token";import{Keypair as a,SystemProgram as g,Transaction as y,VersionedMessage as l,VersionedTransaction as m}from"@solana/web3.js";import{SolanaTransactionTypes as i,TransactionInspector as o}from"./TransactionInspector";function d(e){return{compiledInstructions:e.compiledInstructions.map(t=>({...t,data:t.data instanceof Uint8Array||typeof Buffer<"u"&&t.data instanceof Buffer?t.data:new Uint8Array(t.data)})),staticAccountKeys:e.staticAccountKeys,isAccountSigner:t=>!1,isAccountWritable:t=>!1}}vi.mock("@solana/spl-token",async()=>{const e=await vi.importActual("@solana/spl-token");return{...e,decodeInstruction:vi.fn(),getAssociatedTokenAddress:vi.fn(),TOKEN_PROGRAM_ID:e.TOKEN_PROGRAM_ID}});const{decodeInstruction:u,getAssociatedTokenAddress:f,TOKEN_PROGRAM_ID:p}=w;describe("TransactionInspector",()=>{beforeEach(()=>{vi.clearAllMocks()}),afterEach(()=>{vi.restoreAllMocks()}),it("returns STANDARD when no SPL instructions are found",async()=>{const e=new o(new Uint8Array);vi.spyOn(e,"extractMessage").mockReturnValue(d({compiledInstructions:[],staticAccountKeys:[]}));const t=await e.inspectTransactionType();expect(t).toEqual({transactionType:i.STANDARD,data:{}})}),it("ignores instructions not targeting TOKEN_PROGRAM_ID",async()=>{const e=a.generate().publicKey,t=d({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1],data:new Uint8Array([1])}],staticAccountKeys:[e,a.generate().publicKey]}),n=new o(new Uint8Array);vi.spyOn(n,"extractMessage").mockReturnValue(t);const s=await n.inspectTransactionType();expect(s.transactionType).toBe(i.STANDARD)}),it("skips a first bad decodeInstruction and succeeds on the next",async()=>{const e=a.generate().publicKey,t=a.generate().publicKey,n=d({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[0,1,2],data:new Uint8Array([0])},{programIdIndex:0,accountKeyIndexes:[0,1,2],data:new Uint8Array([0])}],staticAccountKeys:[p,t,e]}),s=new o(new Uint8Array);vi.spyOn(s,"extractMessage").mockReturnValue(n),u.mockReturnValueOnce(new Error("bad")).mockReturnValueOnce({data:{amount:7}});const r=await s.inspectTransactionType();expect(r).toEqual({transactionType:i.SPL,data:{tokenAddress:e.toBase58()}})}),it("converts Buffer or number[] data into Uint8Array before decoding",async()=>{const e=a.generate().publicKey,t=a.generate().publicKey,n=d({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[0,1,2],data:Buffer.from([5,6,7])},{programIdIndex:0,accountKeyIndexes:[0,1,2],data:[8,9,10]}],staticAccountKeys:[p,t,e]}),s=new o(new Uint8Array);vi.spyOn(s,"extractMessage").mockReturnValue(n),u.mockReturnValueOnce(new Error("nope")).mockImplementation(c=>(expect(c.data).toBeInstanceOf(Uint8Array),{data:{amount:21}}));const r=await s.inspectTransactionType();expect(r.data).toEqual({tokenAddress:e.toBase58()})}),it("detects TransferChecked with existing ATA",async()=>{const e=a.generate().publicKey,t=a.generate().publicKey,n=a.generate().publicKey;f.mockResolvedValue(n);const s=d({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1,2,3,4],data:new Uint8Array([3])}],staticAccountKeys:[p,t,n,n,e]}),r=new o(new Uint8Array);vi.spyOn(r,"extractMessage").mockReturnValue(s),u.mockReturnValue({data:{mint:e,authority:t,source:n,destination:n}});const c=await r.inspectTransactionType();expect(c).toEqual({transactionType:i.SPL,data:{tokenAddress:n.toBase58()}})}),it("detects TransferChecked without existing ATA \u21D2 createATA",async()=>{const e=a.generate().publicKey,t=a.generate().publicKey,n=a.generate().publicKey,s=a.generate().publicKey;f.mockResolvedValue(n);const r=d({compiledInstructions:[{programIdIndex:0,accountKeyIndexes:[1,2,3,4],data:new Uint8Array([3])}],staticAccountKeys:[p,t,s,s,e]}),c=new o(new Uint8Array);vi.spyOn(c,"extractMessage").mockReturnValue(r),u.mockReturnValue({data:{mint:e,authority:t,source:s,destination:s}});const A=await c.inspectTransactionType();expect(A).toEqual({transactionType:i.SPL,data:{createATA:{address:n.toBase58(),mintAddress:e.toBase58()}}})}),it("extractMessage: throws combined error if all three deserializers fail",()=>{vi.spyOn(m,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(l,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")}),vi.spyOn(y,"from").mockImplementation(()=>{throw new Error("tx fail")});const e=new o(new Uint8Array([1,2]));expect(()=>e.extractMessage(new Uint8Array([1,2]))).toThrow(/Invalid transaction payload[\s\S]*1\) vtx fail[\s\S]*2\) vmd fail[\s\S]*3\) tx fail/)}),it("returns STANDARD fallback when all deserialisers throw",async()=>{vi.spyOn(m,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(l,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")}),vi.spyOn(y,"from").mockImplementation(()=>{throw new Error("tx fail")});const t=await new o(new Uint8Array([222,173,190,239])).inspectTransactionType();expect(t).toEqual({transactionType:i.STANDARD,data:{}})})});describe("isTransferCheckedData",()=>{const e=new o(new Uint8Array);it("returns false for null or primitive values",()=>{expect(e.isTransferCheckedData(null)).toBe(!1),expect(e.isTransferCheckedData(42)).toBe(!1),expect(e.isTransferCheckedData("string")).toBe(!1)}),it("returns false for objects missing required keys or wrong types",()=>{const t=a.generate().publicKey;expect(e.isTransferCheckedData({mint:t,authority:t})).toBe(!1),expect(e.isTransferCheckedData({mint:"nope",authority:null,source:{},destination:[]})).toBe(!1)}),it("returns true for a properly shaped object",()=>{const t=a.generate().publicKey,n={mint:t,authority:t,source:t,destination:t};expect(e.isTransferCheckedData(n)).toBe(!0)})});describe("extractMessage legacy fallback",()=>{it("handles a legacy Transaction via serializeMessage and returns STANDARD",async()=>{vi.spyOn(m,"deserialize").mockImplementation(()=>{throw new Error("vtx fail")}),vi.spyOn(l,"deserialize").mockImplementation(()=>{throw new Error("vmd fail")});const e=a.generate(),t=a.generate(),n=new y().add(g.transfer({fromPubkey:e.publicKey,toPubkey:t.publicKey,lamports:1}));n.feePayer=e.publicKey,n.recentBlockhash="11111111111111111111111111111111",n.sign(e);const s=n.serialize(),r=await new o(s).inspectTransactionType();expect(r.transactionType).toBe("Standard"),expect(r.data).toEqual({})})});
1
+ import{createInitializeAccountInstruction as b,createTransferCheckedInstruction as A,createTransferInstruction as f,TOKEN_PROGRAM_ID as u}from"@solana/spl-token";import{Keypair as a,SystemProgram as g,Transaction as y}from"@solana/web3.js";import m from"bs58";import{describe as K,expect as o,it as i}from"vitest";import{SolanaTransactionTypes as p,TransactionInspector as l}from"./TransactionInspector";const d=m.encode(new Uint8Array(32).fill(1));K("TransactionInspector",()=>{i("falls back to STANDARD for a plain SystemProgram transfer",()=>{const e=a.generate(),s=a.generate().publicKey,n=new y().add(g.transfer({fromPubkey:e.publicKey,toPubkey:s,lamports:1e3}));n.recentBlockhash=d,n.feePayer=e.publicKey,n.sign(e);const c=n.serialize(),t=new l(c).inspectTransactionType();o(t.transactionType).toBe(p.STANDARD),o(t.data).toEqual({})}),i("detects an SPL Transfer and returns the destination address",()=>{const e=a.generate(),s=a.generate().publicKey,n=a.generate().publicKey,c=e.publicKey,t=new y().add(f(s,n,c,42n,[],u));t.recentBlockhash=d,t.feePayer=e.publicKey,t.sign(e);const r=new l(t.serialize()).inspectTransactionType();o(r.transactionType).toBe(p.SPL),o(r.data.tokenAddress).toBe(n.toBase58())}),i("detects an SPL TransferChecked and returns the destination address",()=>{const e=a.generate(),s=a.generate().publicKey,n=a.generate().publicKey,c=a.generate().publicKey,t=e.publicKey,r=new y().add(A(n,s,c,t,123n,0,[],u));r.recentBlockhash=d,r.feePayer=e.publicKey,r.sign(e);const T=new l(r.serialize()).inspectTransactionType();o(T.transactionType).toBe(p.SPL),o(T.data.tokenAddress).toBe(c.toBase58())}),i("detects an SPL InitializeAccount and returns the new ATA and mint",()=>{const e=a.generate(),s=a.generate().publicKey,n=a.generate().publicKey,c=e.publicKey,t=new y().add(b(n,s,c,u));t.recentBlockhash=d,t.feePayer=e.publicKey,t.sign(e);const r=new l(t.serialize()).inspectTransactionType();o(r.transactionType).toBe(p.SPL),o(r.data.createATA).toEqual({address:n.toBase58(),mintAddress:s.toBase58()})}),i("falls back to STANDARD if the payload is unparseable",()=>{const e=new Uint8Array([0,1,2,3,4,5]),s=new l(e).inspectTransactionType();o(s.transactionType).toBe(p.STANDARD),o(s.data).toEqual({})})});
2
2
  //# sourceMappingURL=TransactionInspector.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/services/TransactionInspector.test.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport * as splToken from \"@solana/spl-token\";\nimport {\n Keypair,\n type PublicKey,\n SystemProgram,\n Transaction,\n type TransactionInstruction,\n VersionedMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\n\nimport {\n SolanaTransactionTypes,\n TransactionInspector,\n} from \"./TransactionInspector\";\n\nfunction makeFakeMessage(opts: {\n compiledInstructions: Array<{\n programIdIndex: number;\n accountKeyIndexes: number[];\n data: Uint8Array | number[] | Buffer;\n }>;\n staticAccountKeys: PublicKey[];\n}): VersionedMessage {\n return {\n compiledInstructions: opts.compiledInstructions.map((ix) => ({\n ...ix,\n data:\n ix.data instanceof Uint8Array\n ? ix.data\n : typeof Buffer !== \"undefined\" && ix.data instanceof Buffer\n ? ix.data\n : new Uint8Array(ix.data as number[]),\n })),\n staticAccountKeys: opts.staticAccountKeys,\n isAccountSigner: (_: number) => false,\n isAccountWritable: (_: number) => false,\n } as any;\n}\n\nvi.mock(\"@solana/spl-token\", async () => {\n const actual = await vi.importActual<any>(\"@solana/spl-token\");\n return {\n ...actual,\n decodeInstruction: vi.fn(),\n getAssociatedTokenAddress: vi.fn(),\n TOKEN_PROGRAM_ID: actual.TOKEN_PROGRAM_ID,\n };\n});\nconst { decodeInstruction, getAssociatedTokenAddress, TOKEN_PROGRAM_ID } =\n splToken as any;\n\ndescribe(\"TransactionInspector\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n it(\"returns STANDARD when no SPL instructions are found\", async () => {\n // given\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(\n makeFakeMessage({ compiledInstructions: [], staticAccountKeys: [] }),\n );\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n });\n });\n\n it(\"ignores instructions not targeting TOKEN_PROGRAM_ID\", async () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1],\n data: new Uint8Array([1]),\n },\n ],\n staticAccountKeys: [fakePk, Keypair.generate().publicKey],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n });\n\n it(\"skips a first bad decodeInstruction and succeeds on the next\", async () => {\n // given\n const dest = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: new Uint8Array([0]),\n },\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: new Uint8Array([0]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, other, dest],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction\n .mockReturnValueOnce(new Error(\"bad\"))\n .mockReturnValueOnce({ data: { amount: 7 } });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: dest.toBase58() },\n });\n });\n\n it(\"converts Buffer or number[] data into Uint8Array before decoding\", async () => {\n // given\n const dest = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [0, 1, 2],\n data: Buffer.from([5, 6, 7]),\n },\n { programIdIndex: 0, accountKeyIndexes: [0, 1, 2], data: [8, 9, 10] },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, other, dest],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction\n .mockReturnValueOnce(new Error(\"nope\"))\n .mockImplementation((ix: TransactionInstruction) => {\n expect(ix.data).toBeInstanceOf(Uint8Array);\n return { data: { amount: 21 } };\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res.data).toEqual({ tokenAddress: dest.toBase58() });\n });\n\n it(\"detects TransferChecked with existing ATA\", async () => {\n // given\n const mint = Keypair.generate().publicKey;\n const auth = Keypair.generate().publicKey;\n const ata = Keypair.generate().publicKey;\n getAssociatedTokenAddress.mockResolvedValue(ata);\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1, 2, 3, 4],\n data: new Uint8Array([3]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, auth, ata, ata, mint],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction.mockReturnValue({\n data: { mint, authority: auth, source: ata, destination: ata },\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: { tokenAddress: ata.toBase58() },\n });\n });\n\n it(\"detects TransferChecked without existing ATA \u21D2 createATA\", async () => {\n // given\n const mint = Keypair.generate().publicKey;\n const auth = Keypair.generate().publicKey;\n const ata = Keypair.generate().publicKey;\n const other = Keypair.generate().publicKey;\n getAssociatedTokenAddress.mockResolvedValue(ata);\n\n const msg = makeFakeMessage({\n compiledInstructions: [\n {\n programIdIndex: 0,\n accountKeyIndexes: [1, 2, 3, 4],\n data: new Uint8Array([3]),\n },\n ],\n staticAccountKeys: [TOKEN_PROGRAM_ID, auth, other, other, mint],\n });\n const inspector = new TransactionInspector(new Uint8Array());\n vi.spyOn(inspector as any, \"extractMessage\").mockReturnValue(msg);\n\n decodeInstruction.mockReturnValue({\n data: { mint, authority: auth, source: other, destination: other },\n });\n\n // when\n const res = await inspector.inspectTransactionType();\n\n // then\n expect(res).toEqual({\n transactionType: SolanaTransactionTypes.SPL,\n data: {\n createATA: {\n address: ata.toBase58(),\n mintAddress: mint.toBase58(),\n },\n },\n });\n });\n\n it(\"extractMessage: throws combined error if all three deserializers fail\", () => {\n // given\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n vi.spyOn(Transaction, \"from\").mockImplementation(() => {\n throw new Error(\"tx fail\");\n });\n\n // when\n const inspector = new TransactionInspector(new Uint8Array([0x01, 0x02]));\n\n // then\n expect(() =>\n (inspector as any).extractMessage(new Uint8Array([0x01, 0x02])),\n ).toThrow(\n /Invalid transaction payload[\\s\\S]*1\\) vtx fail[\\s\\S]*2\\) vmd fail[\\s\\S]*3\\) tx fail/,\n );\n });\n\n it(\"returns STANDARD fallback when all deserialisers throw\", async () => {\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n vi.spyOn(Transaction, \"from\").mockImplementation(() => {\n throw new Error(\"tx fail\");\n });\n\n const inspector = new TransactionInspector(\n new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n );\n const result = await inspector.inspectTransactionType();\n\n expect(result).toEqual({\n transactionType: SolanaTransactionTypes.STANDARD,\n data: {},\n });\n });\n});\n\ndescribe(\"isTransferCheckedData\", () => {\n const inspector = new TransactionInspector(new Uint8Array());\n\n it(\"returns false for null or primitive values\", () => {\n expect((inspector as any).isTransferCheckedData(null)).toBe(false);\n expect((inspector as any).isTransferCheckedData(42)).toBe(false);\n expect((inspector as any).isTransferCheckedData(\"string\")).toBe(false);\n });\n\n it(\"returns false for objects missing required keys or wrong types\", () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n\n // when / then\n // Missing keys\n expect(\n (inspector as any).isTransferCheckedData({\n mint: fakePk,\n authority: fakePk,\n }),\n ).toBe(false);\n // Wrong types\n expect(\n (inspector as any).isTransferCheckedData({\n mint: \"nope\",\n authority: null,\n source: {},\n destination: [],\n }),\n ).toBe(false);\n });\n\n it(\"returns true for a properly shaped object\", () => {\n // given\n const fakePk = Keypair.generate().publicKey;\n const data = {\n mint: fakePk,\n authority: fakePk,\n source: fakePk,\n destination: fakePk,\n };\n\n // when / then\n expect((inspector as any).isTransferCheckedData(data)).toBe(true);\n });\n});\n\ndescribe(\"extractMessage legacy fallback\", () => {\n it(\"handles a legacy Transaction via serializeMessage and returns STANDARD\", async () => {\n // given\n vi.spyOn(VersionedTransaction, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vtx fail\");\n });\n vi.spyOn(VersionedMessage, \"deserialize\").mockImplementation(() => {\n throw new Error(\"vmd fail\");\n });\n\n const from = Keypair.generate();\n const to = Keypair.generate();\n const tx = new Transaction().add(\n SystemProgram.transfer({\n fromPubkey: from.publicKey,\n toPubkey: to.publicKey,\n lamports: 1,\n }),\n );\n tx.feePayer = from.publicKey;\n tx.recentBlockhash = \"11111111111111111111111111111111\";\n\n tx.sign(from);\n\n const raw = tx.serialize();\n\n // when\n const result = await new TransactionInspector(raw).inspectTransactionType();\n\n // then\n expect(result.transactionType).toBe(\"Standard\");\n expect(result.data).toEqual({});\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["splToken", "Keypair", "SystemProgram", "Transaction", "VersionedMessage", "VersionedTransaction", "SolanaTransactionTypes", "TransactionInspector", "makeFakeMessage", "opts", "ix", "_", "actual", "decodeInstruction", "getAssociatedTokenAddress", "TOKEN_PROGRAM_ID", "inspector", "res", "fakePk", "msg", "dest", "other", "mint", "auth", "ata", "result", "data", "from", "to", "tx", "raw"]
4
+ "sourcesContent": ["import {\n createInitializeAccountInstruction,\n createTransferCheckedInstruction,\n createTransferInstruction,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { Keypair, SystemProgram, Transaction } from \"@solana/web3.js\";\nimport bs58 from \"bs58\";\nimport { describe, expect, it } from \"vitest\";\n\nimport {\n SolanaTransactionTypes,\n TransactionInspector,\n} from \"./TransactionInspector\";\n\nconst DUMMY_BLOCKHASH = bs58.encode(new Uint8Array(32).fill(1));\n\ndescribe(\"TransactionInspector\", () => {\n it(\"falls back to STANDARD for a plain SystemProgram transfer\", () => {\n const payer = Keypair.generate();\n const dest = Keypair.generate().publicKey;\n\n const tx = new Transaction().add(\n SystemProgram.transfer({\n fromPubkey: payer.publicKey,\n toPubkey: dest,\n lamports: 1_000,\n }),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const raw = tx.serialize();\n const result = new TransactionInspector(raw).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n expect(result.data).toEqual({});\n });\n\n it(\"detects an SPL Transfer and returns the destination address\", () => {\n const payer = Keypair.generate();\n const source = Keypair.generate().publicKey;\n const destination = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createTransferInstruction(\n source,\n destination,\n owner,\n 42n,\n [],\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.tokenAddress).toBe(destination.toBase58());\n });\n\n it(\"detects an SPL TransferChecked and returns the destination address\", () => {\n const payer = Keypair.generate();\n const mint = Keypair.generate().publicKey;\n const source = Keypair.generate().publicKey;\n const destination = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createTransferCheckedInstruction(\n source,\n mint,\n destination,\n owner,\n 123n,\n 0,\n [],\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.tokenAddress).toBe(destination.toBase58());\n });\n\n it(\"detects an SPL InitializeAccount and returns the new ATA and mint\", () => {\n const payer = Keypair.generate();\n const mint = Keypair.generate().publicKey;\n const newAccount = Keypair.generate().publicKey;\n const owner = payer.publicKey;\n\n const tx = new Transaction().add(\n createInitializeAccountInstruction(\n newAccount,\n mint,\n owner,\n TOKEN_PROGRAM_ID,\n ),\n );\n tx.recentBlockhash = DUMMY_BLOCKHASH;\n tx.feePayer = payer.publicKey;\n tx.sign(payer);\n\n const result = new TransactionInspector(\n tx.serialize(),\n ).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.SPL);\n expect(result.data.createATA).toEqual({\n address: newAccount.toBase58(),\n mintAddress: mint.toBase58(),\n });\n });\n\n it(\"falls back to STANDARD if the payload is unparseable\", () => {\n const garbage = new Uint8Array([0, 1, 2, 3, 4, 5]);\n const result = new TransactionInspector(garbage).inspectTransactionType();\n\n expect(result.transactionType).toBe(SolanaTransactionTypes.STANDARD);\n expect(result.data).toEqual({});\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["createInitializeAccountInstruction", "createTransferCheckedInstruction", "createTransferInstruction", "TOKEN_PROGRAM_ID", "Keypair", "SystemProgram", "Transaction", "bs58", "describe", "expect", "it", "SolanaTransactionTypes", "TransactionInspector", "DUMMY_BLOCKHASH", "payer", "dest", "tx", "raw", "result", "source", "destination", "owner", "mint", "newAccount", "garbage"]
7
7
  }
@@ -15,8 +15,7 @@ export interface TxInspectorResult {
15
15
  export declare class TransactionInspector {
16
16
  private readonly rawTransactionBytes;
17
17
  constructor(rawTransactionBytes: Uint8Array);
18
- inspectTransactionType(): Promise<TxInspectorResult>;
19
- private isTransferCheckedData;
18
+ inspectTransactionType(): TxInspectorResult;
20
19
  private extractMessage;
21
20
  }
22
21
  //# sourceMappingURL=TransactionInspector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionInspector.d.ts","sourceRoot":"","sources":["../../../../../src/internal/app-binder/services/TransactionInspector.ts"],"names":[],"mappings":"AAcA,oBAAY,sBAAsB;IAChC,QAAQ,aAAa;IACrB,GAAG,QAAQ;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,sBAAsB,CAAC;IACxC,IAAI,EAAE;QACJ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE;YACV,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;KACH,CAAC;CACH;AAeD,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,UAAU;IAE/C,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAgGjE,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,cAAc;CAkDvB"}
1
+ {"version":3,"file":"TransactionInspector.d.ts","sourceRoot":"","sources":["../../../../../src/internal/app-binder/services/TransactionInspector.ts"],"names":[],"mappings":"AAgBA,oBAAY,sBAAsB;IAChC,QAAQ,aAAa;IACrB,GAAG,QAAQ;CACZ;AACD,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,sBAAsB,CAAC;IACxC,IAAI,EAAE;QACJ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE;YACV,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;KACH,CAAC;CACH;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,UAAU;IAErD,sBAAsB,IAAI,iBAAiB;IAqElD,OAAO,CAAC,cAAc;CAgEvB"}