{"version":3,"sources":["../../src/normalizer.ts"],"sourcesContent":["import type { Address, Instruction, Transaction } from \"@solana/kit\";\nimport { isSwigTransaction, parseSwigTransaction, getTokenPayerFromTransaction } from \"./utils\";\n\nexport interface NormalizedTransaction {\n  instructions: Array<{\n    programAddress: Address;\n    accounts: Array<{ address: Address; role: number }>;\n    data: Uint8Array;\n  }>;\n  payer: string;\n}\n\n/**\n * Normalizes different SVM transaction shapes into a single facilitator-friendly\n * instruction list plus the effective payer that should be used for settlement.\n */\nexport interface TransactionNormalizer {\n  /**\n   * Returns true when this normalizer understands the provided instruction layout.\n   *\n   * @param instructions - Decompiled instruction list from the transaction.\n   * @returns True when the implementation can normalize the transaction.\n   */\n  canHandle(instructions: ReadonlyArray<Instruction>): boolean;\n  /**\n   * Converts a transaction into the canonical shape expected by facilitator verification.\n   *\n   * @param instructions - Decompiled instruction list from the transaction.\n   * @param staticAccounts - Ordered static account list from the compiled message.\n   * @param transaction - Original decoded transaction.\n   * @returns The normalized instruction set and payer.\n   */\n  normalize(\n    instructions: ReadonlyArray<Instruction>,\n    staticAccounts: ReadonlyArray<Address>,\n    transaction: Transaction,\n  ): Promise<NormalizedTransaction>;\n}\n\n/**\n * Handles Swig smart-wallet transactions by flattening the SignV2 payload into\n * the same normalized shape used for regular token transfers.\n */\nclass SwigNormalizer implements TransactionNormalizer {\n  /**\n   * Detects whether the instruction list matches the Swig SignV2 layout.\n   *\n   * @param instructions - Decompiled instruction list from the transaction.\n   * @returns True when the transaction should be normalized as Swig.\n   */\n  canHandle(instructions: ReadonlyArray<Instruction>): boolean {\n    return isSwigTransaction(instructions);\n  }\n\n  /**\n   * Flattens the Swig SignV2 payload and uses the Swig PDA as the logical payer.\n   *\n   * @param instructions - Decompiled instruction list from the transaction.\n   * @param staticAccounts - Ordered static account list from the compiled message.\n   * @returns The normalized Swig instructions and payer.\n   */\n  async normalize(\n    instructions: ReadonlyArray<Instruction>,\n    staticAccounts: ReadonlyArray<Address>,\n  ): Promise<NormalizedTransaction> {\n    const result = await parseSwigTransaction(instructions, staticAccounts);\n    return {\n      instructions: result.instructions,\n      payer: result.swigPda,\n    };\n  }\n}\n\n/**\n * Handles ordinary SVM transfers that do not require special wallet decoding.\n */\nclass RegularNormalizer implements TransactionNormalizer {\n  /**\n   * Acts as the fallback normalizer once specialized handlers decline the payload.\n   *\n   * @returns Always true because regular normalization is the default path.\n   */\n  canHandle(): boolean {\n    return true;\n  }\n\n  /**\n   * Passes through decompiled instructions and derives the transfer payer directly\n   * from the decoded transaction.\n   *\n   * @param instructions - Decompiled instruction list from the transaction.\n   * @param _staticAccounts - Unused static accounts for the regular path.\n   * @param transaction - Original decoded transaction.\n   * @returns The normalized instruction list and derived payer.\n   */\n  async normalize(\n    instructions: ReadonlyArray<Instruction>,\n    _staticAccounts: ReadonlyArray<Address>,\n    transaction: Transaction,\n  ): Promise<NormalizedTransaction> {\n    const payer = getTokenPayerFromTransaction(transaction);\n    if (!payer) {\n      throw new Error(\"invalid_exact_svm_payload_no_transfer_instruction\");\n    }\n\n    return {\n      // The caller already decompiled the instructions; pass them through.\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      instructions: instructions as any,\n      payer,\n    };\n  }\n}\n\nconst defaultNormalizers: TransactionNormalizer[] = [new SwigNormalizer(), new RegularNormalizer()];\n\n/**\n * Chooses the first matching normalizer and converts the transaction into the\n * canonical instruction shape consumed by the facilitator verifier.\n *\n * @param instructions - Decompiled instruction list from the transaction.\n * @param staticAccounts - Ordered static account list from the compiled message.\n * @param transaction - Original decoded transaction.\n * @returns The normalized instruction list and payer.\n */\nexport async function normalizeTransaction(\n  instructions: ReadonlyArray<Instruction>,\n  staticAccounts: ReadonlyArray<Address>,\n  transaction: Transaction,\n): Promise<NormalizedTransaction> {\n  for (const n of defaultNormalizers) {\n    if (n.canHandle(instructions)) {\n      return await n.normalize(instructions, staticAccounts, transaction);\n    }\n  }\n  throw new Error(\"no normalizer found for transaction\");\n}\n"],"mappings":";;;;;;;AA2CA,IAAM,iBAAN,MAAsD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpD,UAAU,cAAmD;AAC3D,WAAO,kBAAkB,YAAY;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UACJ,cACA,gBACgC;AAChC,UAAM,SAAS,MAAM,qBAAqB,cAAc,cAAc;AACtE,WAAO;AAAA,MACL,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACF;AAKA,IAAM,oBAAN,MAAyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvD,YAAqB;AACnB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,UACJ,cACA,iBACA,aACgC;AAChC,UAAM,QAAQ,6BAA6B,WAAW;AACtD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAEA,WAAO;AAAA;AAAA;AAAA,MAGL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,qBAA8C,CAAC,IAAI,eAAe,GAAG,IAAI,kBAAkB,CAAC;AAWlG,eAAsB,qBACpB,cACA,gBACA,aACgC;AAChC,aAAW,KAAK,oBAAoB;AAClC,QAAI,EAAE,UAAU,YAAY,GAAG;AAC7B,aAAO,MAAM,EAAE,UAAU,cAAc,gBAAgB,WAAW;AAAA,IACpE;AAAA,EACF;AACA,QAAM,IAAI,MAAM,qCAAqC;AACvD;","names":[]}