@ledgerhq/device-signer-kit-solana 1.13.1 → 1.13.2

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 (20) hide show
  1. package/lib/cjs/internal/app-binder/clear-sign/requirements/rules/tokenRule.js +1 -1
  2. package/lib/cjs/internal/app-binder/clear-sign/requirements/rules/tokenRule.js.map +2 -2
  3. package/lib/cjs/internal/app-binder/clear-sign/requirements/rules/tokenRule.test.js +1 -1
  4. package/lib/cjs/internal/app-binder/clear-sign/requirements/rules/tokenRule.test.js.map +3 -3
  5. package/lib/cjs/internal/app-binder/clear-sign/requirements/valueResolution.js +1 -1
  6. package/lib/cjs/internal/app-binder/clear-sign/requirements/valueResolution.js.map +3 -3
  7. package/lib/cjs/package.json +3 -3
  8. package/lib/esm/internal/app-binder/clear-sign/requirements/rules/tokenRule.js +1 -1
  9. package/lib/esm/internal/app-binder/clear-sign/requirements/rules/tokenRule.js.map +3 -3
  10. package/lib/esm/internal/app-binder/clear-sign/requirements/rules/tokenRule.test.js +1 -1
  11. package/lib/esm/internal/app-binder/clear-sign/requirements/rules/tokenRule.test.js.map +3 -3
  12. package/lib/esm/internal/app-binder/clear-sign/requirements/valueResolution.js +1 -1
  13. package/lib/esm/internal/app-binder/clear-sign/requirements/valueResolution.js.map +3 -3
  14. package/lib/esm/package.json +3 -3
  15. package/lib/types/internal/app-binder/clear-sign/requirements/rules/tokenRule.d.ts +6 -5
  16. package/lib/types/internal/app-binder/clear-sign/requirements/rules/tokenRule.d.ts.map +1 -1
  17. package/lib/types/internal/app-binder/clear-sign/requirements/valueResolution.d.ts +12 -0
  18. package/lib/types/internal/app-binder/clear-sign/requirements/valueResolution.d.ts.map +1 -1
  19. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  20. package/package.json +6 -6
@@ -1,2 +1,2 @@
1
- "use strict";var I=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var p=(o,e)=>{for(var s in e)I(o,s,{get:e[s],enumerable:!0})},v=(o,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of y(e))!x.call(o,r)&&r!==s&&I(o,r,{get:()=>e[r],enumerable:!(n=T(e,r))||n.enumerable});return o};var P=o=>v(I({},"__esModule",{value:!0}),o);var S={};p(S,{applyTokenRule:()=>q});module.exports=P(S);var c=require("../../../../app-binder/clear-sign/requirements/records"),f=require("../../../../app-binder/clear-sign/requirements/valueResolution"),R=require("../../../../app-binder/services/bs58Encoder");function q(o,e,s,n,r=R.DefaultBs58Encoder){const a=s.mints;for(const t of o.valueFlowPorts){const d=t.tokenValue;if(d!==void 0){if(d.kind===c.TokenKind.RESOLVE){const i=d.accountIndex??(0,f.resolvePortAccountIndex)(t,e),u=(0,f.accountAddressAt)(e,i);if(u!==void 0){const l=a.get(u);l===void 0?n.addTokenAccountState(u):n.addTokenInfo(l)}else A((0,f.accountAltRefAt)(e,i),n);k(d.fallbackAccountIndex,e,n)}else if(d.kind===c.TokenKind.DIRECT&&d.value){const i=(0,f.resolvePubkeyValue)(d.value,e,r);i!==void 0&&n.addTokenInfo(i)}}}for(const t of o.accountResets){if(!t.requirePreBalanceZero&&!t.requireNativePreBalanceZero)continue;const d=(0,f.accountAddressAt)(e,t.accountIndex);d!==void 0?n.addTokenAccountState(d):A((0,f.accountAltRefAt)(e,t.accountIndex),n)}for(const t of o.accountResets){if(t.valueKind!==c.ValueKind.SPL_TOKEN)continue;const d=t.tokenValue;if(d===void 0||d.kind!==c.TokenKind.RESOLVE)continue;const i=d.accountIndex??t.accountIndex,u=(0,f.accountAddressAt)(e,i);if(u!==void 0){const l=a.get(u);l===void 0&&d.fallbackAccountIndex===void 0&&n.addTokenAccountState(u),l!==void 0&&n.addTokenInfo(l)}else A((0,f.accountAltRefAt)(e,i),n);k(d.fallbackAccountIndex,e,n)}E(o,e,s,n,r);for(const t of o.displayFields){if(t.paramType!==c.PARAM_TYPE_TOKEN_AMOUNT||t.token===void 0)continue;if(t.token.source!==c.ValueSource.ACCOUNT_PATH){const u=(0,f.resolvePubkeyValue)(t.token,e,r);u!==void 0&&n.addTokenInfo(a.get(u)??u);continue}const d=t.token.payload.length>0?t.token.payload[0]:void 0;if(d===void 0)continue;const i=e.accounts[d];if(i!==void 0)if(i.address!==void 0){const u=a.get(i.address);u!==void 0?n.addTokenInfo(u):n.addTokenAmountRef(i.address)}else i.altRef!==void 0&&n.addTokenAmountAltRef(i.altRef.altAddress,i.altRef.entryIndex)}}function k(o,e,s){if(o===void 0)return;const n=e.accounts[o];n!==void 0&&(n.address!==void 0?s.addTokenInfo(n.address):n.altRef!==void 0&&s.addMintAltRef(n.altRef.altAddress,n.altRef.entryIndex))}function E(o,e,s,n,r){const a=t=>{t!==void 0&&(s.owners.has(t)||n.addTokenAccountState(t))};for(const t of o.hideRules){if(t.condition!==c.HideCondition.IS_SIGNER)continue;const d=t.target;if(d===void 0)continue;const i=(0,f.resolvePubkeyValue)(d,e,r);i!==void 0?a(i):A((0,f.altRefForPubkeyValue)(d,e),n)}for(const t of o.valueFlowPorts){if(!t.activeWhen.includes(c.ActiveWhenPredicate.IS_SIGNER))continue;const d=(0,f.resolvePortAccountIndex)(t,e),i=(0,f.accountAddressAt)(e,d);i!==void 0?a(i):A((0,f.accountAltRefAt)(e,d),n)}}function A(o,e){o!==void 0&&e.addTokenAccountStateAltRef(o.altAddress,o.entryIndex)}0&&(module.exports={applyTokenRule});
1
+ "use strict";var I=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var x=(o,e)=>{for(var s in e)I(o,s,{get:e[s],enumerable:!0})},v=(o,e,s,d)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of y(e))!p.call(o,r)&&r!==s&&I(o,r,{get:()=>e[r],enumerable:!(d=T(e,r))||d.enumerable});return o};var P=o=>v(I({},"__esModule",{value:!0}),o);var q={};x(q,{applyTokenRule:()=>S});module.exports=P(q);var c=require("../../../../app-binder/clear-sign/requirements/records"),i=require("../../../../app-binder/clear-sign/requirements/valueResolution"),R=require("../../../../app-binder/services/bs58Encoder");function S(o,e,s,d,r=R.DefaultBs58Encoder){const a=s.mints;for(const t of o.valueFlowPorts){const n=t.tokenValue;if(n!==void 0){if(n.kind===c.TokenKind.RESOLVE){const f=n.accountIndex??(0,i.resolvePortAccountIndex)(t,e),u=(0,i.accountAddressAt)(e,f);if(u!==void 0){const l=a.get(u);l===void 0?d.addTokenAccountState(u):d.addTokenInfo(l)}else A((0,i.accountAltRefAt)(e,f),d);k(n.fallbackAccountIndex,e,d)}else if(n.kind===c.TokenKind.DIRECT&&n.value){const f=(0,i.resolvePubkeyValue)(n.value,e,r);f!==void 0&&d.addTokenInfo(f)}}}for(const t of o.accountResets){if(!t.requirePreBalanceZero&&!t.requireNativePreBalanceZero)continue;const n=(0,i.accountAddressAt)(e,t.accountIndex);n!==void 0?d.addTokenAccountState(n):A((0,i.accountAltRefAt)(e,t.accountIndex),d)}for(const t of o.accountResets){if(t.valueKind!==c.ValueKind.SPL_TOKEN)continue;const n=t.tokenValue;if(n===void 0||n.kind!==c.TokenKind.RESOLVE)continue;const f=n.accountIndex??t.accountIndex,u=(0,i.accountAddressAt)(e,f);if(u!==void 0){const l=a.get(u);l===void 0&&n.fallbackAccountIndex===void 0&&d.addTokenAccountState(u),l!==void 0&&d.addTokenInfo(l)}else A((0,i.accountAltRefAt)(e,f),d);k(n.fallbackAccountIndex,e,d)}m(o,e,s,d,r);for(const t of o.displayFields){if(t.paramType!==c.PARAM_TYPE_TOKEN_AMOUNT||t.token===void 0)continue;if(t.token.source!==c.ValueSource.ACCOUNT_PATH){const u=(0,i.resolvePubkeyValue)(t.token,e,r);u!==void 0&&d.addTokenInfo(a.get(u)??u);continue}const n=t.token.payload.length>0?t.token.payload[0]:void 0;if(n===void 0)continue;const f=e.accounts[n];if(f!==void 0)if(f.address!==void 0){const u=a.get(f.address);u!==void 0?d.addTokenInfo(u):d.addTokenAmountRef(f.address)}else f.altRef!==void 0&&d.addTokenAmountAltRef(f.altRef.altAddress,f.altRef.entryIndex)}}function k(o,e,s){if(o===void 0)return;const d=e.accounts[o];d!==void 0&&(d.address!==void 0?s.addTokenInfo(d.address):d.altRef!==void 0&&s.addMintAltRef(d.altRef.altAddress,d.altRef.entryIndex))}function m(o,e,s,d,r){const a=(t,n)=>{t!==void 0&&(s.owners.has(t)||n!==void 0&&(0,i.accountIsSignerAt)(e,n)||d.addTokenAccountState(t))};for(const t of o.hideRules){if(t.condition!==c.HideCondition.IS_SIGNER)continue;const n=t.target;if(n===void 0)continue;const f=(0,i.resolvePubkeyValue)(n,e,r);f!==void 0?a(f,(0,i.pubkeyValueAccountIndex)(n)):A((0,i.altRefForPubkeyValue)(n,e),d)}for(const t of o.valueFlowPorts){if(!t.activeWhen.includes(c.ActiveWhenPredicate.IS_SIGNER))continue;const n=(0,i.resolvePortAccountIndex)(t,e),f=(0,i.accountAddressAt)(e,n);f!==void 0?a(f,n):A((0,i.accountAltRefAt)(e,n),d)}}function A(o,e){o!==void 0&&e.addTokenAccountStateAltRef(o.altAddress,o.entryIndex)}0&&(module.exports={applyTokenRule});
2
2
  //# sourceMappingURL=tokenRule.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/internal/app-binder/clear-sign/requirements/rules/tokenRule.ts"],
4
- "sourcesContent": ["import {\n type AltEntryKey,\n type RequirementInstruction,\n type TxBindings,\n} from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n PARAM_TYPE_TOKEN_AMOUNT,\n type ParsedInstruction,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { type RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport {\n accountAddressAt,\n accountAltRefAt,\n altRefForPubkeyValue,\n resolvePortAccountIndex,\n resolvePubkeyValue,\n} from \"@internal/app-binder/clear-sign/requirements/valueResolution\";\nimport {\n type Bs58Encoder,\n DefaultBs58Encoder,\n} from \"@internal/app-binder/services/bs58Encoder\";\n\n/**\n * TOKEN_INFO + TOKEN_ACCOUNT_STATE requirements:\n * - RESOLVE port: TOKEN_ACCOUNT_STATE for its token account unless a TX-derived\n * MINT_ASSOC binding already covers it; the bound mint (when any) needs\n * TOKEN_INFO. An ALT-backed token account can carry no such binding (a\n * binding needs both halves resolved host-side), so it goes to\n * `tokenAccountStateAltRefs` and is fetched once its address is known.\n * A candidate-array port resolves to its first *provided*\n * candidate. A `FALLBACK_ACCOUNT` is the mint of last resort, so its address\n * needs TOKEN_INFO too \u2014 every `fallbackAccount` in the registry names a mint\n * slot, and it is the only ticker source when both binding sources miss.\n * - DIRECT port: the embedded mint needs TOKEN_INFO.\n * - ACCOUNT_RESET path 2: mandatory TOKEN_ACCOUNT_STATE when `requirePreBalanceZero`\n * or `requireNativePreBalanceZero` is set (the device must read the pre-balance\n * to validate the reset is applicable).\n * - ACCOUNT_RESET path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose `TOKEN_VALUE`\n * is `RESOLVE`, unless the mint is already bound by a TX-derived `MINT_ASSOC`\n * pair or by a `FALLBACK_ACCOUNT`. Without the mint the reset resolves to no\n * domain and establishes nothing.\n * - IS_SIGNER hide rule / port activation predicate: TOKEN_ACCOUNT_STATE for the\n * target unless a TX-derived OWNER_ASSOC binding already covers it. The\n * device's `IS_SIGNER` predicate matches a token account only through the\n * owner map, which it seeds from OWNER_ASSOC pairs first and from attested\n * `TOKEN_ACCOUNT_STATE.OWNER` second. An ALT-backed target goes to\n * `tokenAccountStateAltRefs`, the post-ALT_RESOLUTION equivalent.\n * - PARAM_TOKEN_AMOUNT display field: the amount formatter's token needs\n * TOKEN_INFO. For CONSTANT source: always a mint. For ACCOUNT_PATH source:\n * if covered by a TX-derived MINT_ASSOC binding, use the bound mint. If not,\n * add as a `tokenAmountRef` (non-ALT) or `tokenAmountAltRef` (ALT-backed)\n * so the fetch stage can try TOKEN_INFO first then fall back to\n * TOKEN_ACCOUNT_STATE + TOKEN_INFO for the attested mint.\n */\nexport function applyTokenRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder = DefaultBs58Encoder,\n): void {\n const mintBindings = bindings.mints;\n\n for (const port of parsed.valueFlowPorts) {\n const tokenValue = port.tokenValue;\n if (tokenValue === undefined) continue;\n\n if (tokenValue.kind === TokenKind.RESOLVE) {\n const accountIndex =\n tokenValue.accountIndex ?? resolvePortAccountIndex(port, instruction);\n const account = accountAddressAt(instruction, accountIndex);\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (boundMint === undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n // ALT-backed: no MINT_ASSOC binding can cover it, so the mint has to\n // come from the attested state fetched once the entry resolves.\n requestAltState(\n accountAltRefAt(instruction, accountIndex),\n accumulator,\n );\n }\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n } else if (tokenValue.kind === TokenKind.DIRECT && tokenValue.value) {\n const mint = resolvePubkeyValue(\n tokenValue.value,\n instruction,\n bs58Encoder,\n );\n if (mint !== undefined) accumulator.addTokenInfo(mint);\n }\n }\n\n for (const reset of parsed.accountResets) {\n if (!reset.requirePreBalanceZero && !reset.requireNativePreBalanceZero)\n continue;\n const account = accountAddressAt(instruction, reset.accountIndex);\n if (account !== undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n requestAltState(\n accountAltRefAt(instruction, reset.accountIndex),\n accumulator,\n );\n }\n }\n\n // Path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose TOKEN_VALUE is RESOLVE,\n // unless the mint is already bound by a TX-derived MINT_ASSOC pair or by a\n // FALLBACK_ACCOUNT. Without the mint the reset resolves to no domain.\n for (const reset of parsed.accountResets) {\n if (reset.valueKind !== ValueKind.SPL_TOKEN) continue;\n const tokenValue = reset.tokenValue;\n if (tokenValue === undefined || tokenValue.kind !== TokenKind.RESOLVE)\n continue;\n\n const accountIndex = tokenValue.accountIndex ?? reset.accountIndex;\n const account = accountAddressAt(instruction, accountIndex);\n\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (\n boundMint === undefined &&\n tokenValue.fallbackAccountIndex === undefined\n ) {\n accumulator.addTokenAccountState(account);\n }\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n }\n\n applyOwnerAttestationRule(\n parsed,\n instruction,\n bindings,\n accumulator,\n bs58Encoder,\n );\n\n for (const field of parsed.displayFields) {\n if (\n field.paramType !== PARAM_TYPE_TOKEN_AMOUNT ||\n field.token === undefined\n )\n continue;\n\n if (field.token.source !== ValueSource.ACCOUNT_PATH) {\n // CONSTANT: hardcoded in CAL, always a mint\n const ref = resolvePubkeyValue(field.token, instruction, bs58Encoder);\n if (ref !== undefined) {\n accumulator.addTokenInfo(mintBindings.get(ref) ?? ref);\n }\n continue;\n }\n\n // ACCOUNT_PATH: may be a mint, an ATA, or behind an ALT\n const accountIndex =\n field.token.payload.length > 0 ? field.token.payload[0]! : undefined;\n if (accountIndex === undefined) continue;\n const account = instruction.accounts[accountIndex];\n if (account === undefined) continue;\n\n if (account.address !== undefined) {\n const boundMint = mintBindings.get(account.address);\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n } else {\n accumulator.addTokenAmountRef(account.address);\n }\n } else if (account.altRef !== undefined) {\n // ALT-backed: resolve after ALT_RESOLUTION is fetched\n accumulator.addTokenAmountAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n }\n}\n\n/**\n * `TOKEN_VALUE.FALLBACK_ACCOUNT`: the device uses the referenced account's\n * *address* as the mint, with no further resolution. Every `fallbackAccount` an\n * overlay declares names a mint slot (`sourceMint`, `poolMint`, \u2026), so this is\n * a real mint whose TOKEN_INFO renders the ticker whenever the port does fall\n * through \u2014 the common case for a swap into an ATA that does not exist yet.\n * Requesting it when the binding map *does* resolve the port costs nothing: all\n * mints are fetched in one batched CAL call.\n *\n * An ALT-backed fallback goes to `mintAltRefs`, the bucket that streams the\n * `ALT_RESOLUTION` finalize requires and then resolves TOKEN_INFO for the\n * resolved address.\n */\nfunction requestFallbackMint(\n fallbackAccountIndex: number | undefined,\n instruction: RequirementInstruction,\n accumulator: RequirementAccumulator,\n): void {\n if (fallbackAccountIndex === undefined) return;\n const account = instruction.accounts[fallbackAccountIndex];\n if (account === undefined) return;\n if (account.address !== undefined) {\n accumulator.addTokenInfo(account.address);\n } else if (account.altRef !== undefined) {\n accumulator.addMintAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n}\n\n/**\n * `TOKEN_ACCOUNT_STATE` trigger path 3: an `IS_SIGNER` predicate \u2014 on a\n * `HIDE_RULE` target or on a port's `ACTIVE_WHEN` \u2014 matches a token account only\n * if the device can bind it to an owner. A TX-derived `OWNER_ASSOC` pair covers\n * that binding; otherwise the only source is the attested\n * `TOKEN_ACCOUNT_STATE.OWNER`, so request one.\n *\n * An ALT-backed target has no host-side address, so neither the binding lookup\n * nor a build-time fetch is possible: it goes to `tokenAccountStateAltRefs` and\n * the provide phase fetches the state once `ALT_RESOLUTION` names the address.\n * Skipping it would leave the owner map unseeded and the predicate false. And\n * ALT-supplied slots are never message signers, so a target reached through one\n * can only ever satisfy `IS_SIGNER` *through* the owner map \u2014 making the\n * attestation the sole path to a true answer rather than a second opinion.\n *\n * `IS_SIGNER` is the only predicate worth a descriptor. The structural ones\n * (`CREATED_IN_TRANSACTION`, `ACCOUNT_USED_ELSEWHERE`,\n * `ACCOUNT_EFFECTS_DISPLAYED_ELSEWHERE`) never read the owner map.\n * `IS_ANOTHER_SIGNER` does read it, but only to short-circuit to `false`:\n * without the binding it falls through to a header signer check, which a\n * program-owned token account can never pass, so the answer is `false` either\n * way and the descriptor changes nothing.\n *\n * The host cannot tell a token account from a plain wallet key, so a predicate\n * targeting the signer's own key costs one fetch that finds nothing. That is the\n * cheap side of the trade: without the descriptor the predicate silently\n * evaluates false and the device shows plumbing screens that should be hidden.\n */\nfunction applyOwnerAttestationRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder,\n): void {\n const request = (address: string | undefined): void => {\n if (address === undefined) return;\n if (bindings.owners.has(address)) return;\n accumulator.addTokenAccountState(address);\n };\n\n for (const rule of parsed.hideRules) {\n if (rule.condition !== HideCondition.IS_SIGNER) continue;\n const target = rule.target;\n if (target === undefined) continue;\n const address = resolvePubkeyValue(target, instruction, bs58Encoder);\n if (address !== undefined) {\n request(address);\n } else {\n requestAltState(altRefForPubkeyValue(target, instruction), accumulator);\n }\n }\n\n for (const port of parsed.valueFlowPorts) {\n if (!port.activeWhen.includes(ActiveWhenPredicate.IS_SIGNER)) continue;\n const accountIndex = resolvePortAccountIndex(port, instruction);\n const address = accountAddressAt(instruction, accountIndex);\n if (address !== undefined) {\n request(address);\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n }\n}\n\n/**\n * Queue the `TOKEN_ACCOUNT_STATE` an ALT-backed account needs. No binding map is\n * consulted: a binding requires both halves resolved host-side, which an\n * ALT-supplied slot never is.\n */\nfunction requestAltState(\n altRef: AltEntryKey | undefined,\n accumulator: RequirementAccumulator,\n): void {\n if (altRef === undefined) return;\n accumulator.addTokenAccountStateAltRef(altRef.altAddress, altRef.entryIndex);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n type AltEntryKey,\n type RequirementInstruction,\n type TxBindings,\n} from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n PARAM_TYPE_TOKEN_AMOUNT,\n type ParsedInstruction,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { type RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport {\n accountAddressAt,\n accountAltRefAt,\n accountIsSignerAt,\n altRefForPubkeyValue,\n pubkeyValueAccountIndex,\n resolvePortAccountIndex,\n resolvePubkeyValue,\n} from \"@internal/app-binder/clear-sign/requirements/valueResolution\";\nimport {\n type Bs58Encoder,\n DefaultBs58Encoder,\n} from \"@internal/app-binder/services/bs58Encoder\";\n\n/**\n * TOKEN_INFO + TOKEN_ACCOUNT_STATE requirements:\n * - RESOLVE port: TOKEN_ACCOUNT_STATE for its token account unless a TX-derived\n * MINT_ASSOC binding already covers it; the bound mint (when any) needs\n * TOKEN_INFO. An ALT-backed token account can carry no such binding (a\n * binding needs both halves resolved host-side), so it goes to\n * `tokenAccountStateAltRefs` and is fetched once its address is known.\n * A candidate-array port resolves to its first *provided*\n * candidate. A `FALLBACK_ACCOUNT` is the mint of last resort, so its address\n * needs TOKEN_INFO too \u2014 every `fallbackAccount` in the registry names a mint\n * slot, and it is the only ticker source when both binding sources miss.\n * - DIRECT port: the embedded mint needs TOKEN_INFO.\n * - ACCOUNT_RESET path 2: mandatory TOKEN_ACCOUNT_STATE when `requirePreBalanceZero`\n * or `requireNativePreBalanceZero` is set (the device must read the pre-balance\n * to validate the reset is applicable).\n * - ACCOUNT_RESET path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose `TOKEN_VALUE`\n * is `RESOLVE`, unless the mint is already bound by a TX-derived `MINT_ASSOC`\n * pair or by a `FALLBACK_ACCOUNT`. Without the mint the reset resolves to no\n * domain and establishes nothing.\n * - IS_SIGNER hide rule / port activation predicate: TOKEN_ACCOUNT_STATE for the\n * target unless a TX-derived OWNER_ASSOC binding already covers it, or the\n * header already marks the slot a signer. The device's `IS_SIGNER` predicate\n * reaches a token account only through the owner map, which it seeds from\n * OWNER_ASSOC pairs first and from attested `TOKEN_ACCOUNT_STATE.OWNER`\n * second. An ALT-backed target goes to `tokenAccountStateAltRefs`, the\n * post-ALT_RESOLUTION equivalent.\n * - PARAM_TOKEN_AMOUNT display field: the amount formatter's token needs\n * TOKEN_INFO. For CONSTANT source: always a mint. For ACCOUNT_PATH source:\n * if covered by a TX-derived MINT_ASSOC binding, use the bound mint. If not,\n * add as a `tokenAmountRef` (non-ALT) or `tokenAmountAltRef` (ALT-backed)\n * so the fetch stage can try TOKEN_INFO first then fall back to\n * TOKEN_ACCOUNT_STATE + TOKEN_INFO for the attested mint.\n */\nexport function applyTokenRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder = DefaultBs58Encoder,\n): void {\n const mintBindings = bindings.mints;\n\n for (const port of parsed.valueFlowPorts) {\n const tokenValue = port.tokenValue;\n if (tokenValue === undefined) continue;\n\n if (tokenValue.kind === TokenKind.RESOLVE) {\n const accountIndex =\n tokenValue.accountIndex ?? resolvePortAccountIndex(port, instruction);\n const account = accountAddressAt(instruction, accountIndex);\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (boundMint === undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n // ALT-backed: no MINT_ASSOC binding can cover it, so the mint has to\n // come from the attested state fetched once the entry resolves.\n requestAltState(\n accountAltRefAt(instruction, accountIndex),\n accumulator,\n );\n }\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n } else if (tokenValue.kind === TokenKind.DIRECT && tokenValue.value) {\n const mint = resolvePubkeyValue(\n tokenValue.value,\n instruction,\n bs58Encoder,\n );\n if (mint !== undefined) accumulator.addTokenInfo(mint);\n }\n }\n\n for (const reset of parsed.accountResets) {\n if (!reset.requirePreBalanceZero && !reset.requireNativePreBalanceZero)\n continue;\n const account = accountAddressAt(instruction, reset.accountIndex);\n if (account !== undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n requestAltState(\n accountAltRefAt(instruction, reset.accountIndex),\n accumulator,\n );\n }\n }\n\n // Path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose TOKEN_VALUE is RESOLVE,\n // unless the mint is already bound by a TX-derived MINT_ASSOC pair or by a\n // FALLBACK_ACCOUNT. Without the mint the reset resolves to no domain.\n for (const reset of parsed.accountResets) {\n if (reset.valueKind !== ValueKind.SPL_TOKEN) continue;\n const tokenValue = reset.tokenValue;\n if (tokenValue === undefined || tokenValue.kind !== TokenKind.RESOLVE)\n continue;\n\n const accountIndex = tokenValue.accountIndex ?? reset.accountIndex;\n const account = accountAddressAt(instruction, accountIndex);\n\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (\n boundMint === undefined &&\n tokenValue.fallbackAccountIndex === undefined\n ) {\n accumulator.addTokenAccountState(account);\n }\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n }\n\n applyOwnerAttestationRule(\n parsed,\n instruction,\n bindings,\n accumulator,\n bs58Encoder,\n );\n\n for (const field of parsed.displayFields) {\n if (\n field.paramType !== PARAM_TYPE_TOKEN_AMOUNT ||\n field.token === undefined\n )\n continue;\n\n if (field.token.source !== ValueSource.ACCOUNT_PATH) {\n // CONSTANT: hardcoded in CAL, always a mint\n const ref = resolvePubkeyValue(field.token, instruction, bs58Encoder);\n if (ref !== undefined) {\n accumulator.addTokenInfo(mintBindings.get(ref) ?? ref);\n }\n continue;\n }\n\n // ACCOUNT_PATH: may be a mint, an ATA, or behind an ALT\n const accountIndex =\n field.token.payload.length > 0 ? field.token.payload[0]! : undefined;\n if (accountIndex === undefined) continue;\n const account = instruction.accounts[accountIndex];\n if (account === undefined) continue;\n\n if (account.address !== undefined) {\n const boundMint = mintBindings.get(account.address);\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n } else {\n accumulator.addTokenAmountRef(account.address);\n }\n } else if (account.altRef !== undefined) {\n // ALT-backed: resolve after ALT_RESOLUTION is fetched\n accumulator.addTokenAmountAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n }\n}\n\n/**\n * `TOKEN_VALUE.FALLBACK_ACCOUNT`: the device uses the referenced account's\n * *address* as the mint, with no further resolution. Every `fallbackAccount` an\n * overlay declares names a mint slot (`sourceMint`, `poolMint`, \u2026), so this is\n * a real mint whose TOKEN_INFO renders the ticker whenever the port does fall\n * through \u2014 the common case for a swap into an ATA that does not exist yet.\n * Requesting it when the binding map *does* resolve the port costs nothing: all\n * mints are fetched in one batched CAL call.\n *\n * An ALT-backed fallback goes to `mintAltRefs`, the bucket that streams the\n * `ALT_RESOLUTION` finalize requires and then resolves TOKEN_INFO for the\n * resolved address.\n */\nfunction requestFallbackMint(\n fallbackAccountIndex: number | undefined,\n instruction: RequirementInstruction,\n accumulator: RequirementAccumulator,\n): void {\n if (fallbackAccountIndex === undefined) return;\n const account = instruction.accounts[fallbackAccountIndex];\n if (account === undefined) return;\n if (account.address !== undefined) {\n accumulator.addTokenInfo(account.address);\n } else if (account.altRef !== undefined) {\n accumulator.addMintAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n}\n\n/**\n * `TOKEN_ACCOUNT_STATE` trigger path 3: an `IS_SIGNER` predicate \u2014 on a\n * `HIDE_RULE` target or on a port's `ACTIVE_WHEN`.\n *\n * The device answers `IS_SIGNER` by deriving the address from its own seed and\n * comparing, which needs no help for a plain key. A token account defeats that:\n * its address is a program derivation the seed never produces, so the device\n * first dereferences the account to its owner \u2014 from a TX-derived `OWNER_ASSOC`\n * pair, else from an attested `TOKEN_ACCOUNT_STATE.OWNER` \u2014 and derives against\n * that instead. The descriptor is therefore worth fetching only where the target\n * may be a token account; anywhere else there is nothing to dereference and the\n * fetch buys no answer the device could not already reach.\n *\n * A slot the message header marks as a signer is one case the host can settle\n * for free: it produced an ed25519 signature, so it is a plain key and never a\n * program-owned token account. Requesting state for it asks the backend to\n * attest an address that is not a token account \u2014 and a descriptor that comes\n * back anyway seeds the device's owner map with a binding that has no business\n * being there, turning a wasted round trip into a wrong answer.\n *\n * An ALT-backed target has no host-side address, so neither the binding lookup\n * nor the signer check nor a build-time fetch is possible: it goes to\n * `tokenAccountStateAltRefs` and the provide phase fetches the state once\n * `ALT_RESOLUTION` names the address. Skipping it would leave a token account's\n * owner map unseeded and the predicate false. ALT-supplied slots are never\n * message signers, so the check below cannot pre-empt that fetch the way it does\n * for a static slot: a plain key reached through an ALT still costs one fetch\n * that finds nothing.\n *\n * `IS_SIGNER` is the only predicate worth a descriptor. The structural ones\n * (`CREATED_IN_TRANSACTION`, `ACCOUNT_USED_ELSEWHERE`,\n * `ACCOUNT_EFFECTS_DISPLAYED_ELSEWHERE`) never read the owner map.\n * `IS_ANOTHER_SIGNER` does read it, but only to short-circuit to `false`:\n * without the binding it falls through to a header signer check, which a\n * program-owned token account can never pass, so the answer is `false` either\n * way and the descriptor changes nothing.\n */\nfunction applyOwnerAttestationRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder,\n): void {\n // `accountIndex` is the slot the target was reached through, when it was\n // reached through one \u2014 a `CONSTANT` target carries its address inline and\n // names no slot, so it cannot be signer-checked.\n const request = (\n address: string | undefined,\n accountIndex: number | undefined,\n ): void => {\n if (address === undefined) return;\n if (bindings.owners.has(address)) return;\n if (\n accountIndex !== undefined &&\n accountIsSignerAt(instruction, accountIndex)\n )\n return;\n accumulator.addTokenAccountState(address);\n };\n\n for (const rule of parsed.hideRules) {\n if (rule.condition !== HideCondition.IS_SIGNER) continue;\n const target = rule.target;\n if (target === undefined) continue;\n const address = resolvePubkeyValue(target, instruction, bs58Encoder);\n if (address !== undefined) {\n request(address, pubkeyValueAccountIndex(target));\n } else {\n requestAltState(altRefForPubkeyValue(target, instruction), accumulator);\n }\n }\n\n for (const port of parsed.valueFlowPorts) {\n if (!port.activeWhen.includes(ActiveWhenPredicate.IS_SIGNER)) continue;\n const accountIndex = resolvePortAccountIndex(port, instruction);\n const address = accountAddressAt(instruction, accountIndex);\n if (address !== undefined) {\n request(address, accountIndex);\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n }\n}\n\n/**\n * Queue the `TOKEN_ACCOUNT_STATE` an ALT-backed account needs. No binding map is\n * consulted: a binding requires both halves resolved host-side, which an\n * ALT-supplied slot never is.\n */\nfunction requestAltState(\n altRef: AltEntryKey | undefined,\n accumulator: RequirementAccumulator,\n): void {\n if (altRef === undefined) return;\n accumulator.addTokenAccountStateAltRef(altRef.altAddress, altRef.entryIndex);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["tokenRule_exports", "__export", "applyTokenRule", "__toCommonJS", "import_records", "import_valueResolution", "import_bs58Encoder", "parsed", "instruction", "bindings", "accumulator", "bs58Encoder", "mintBindings", "port", "tokenValue", "accountIndex", "account", "boundMint", "requestAltState", "requestFallbackMint", "mint", "reset", "applyOwnerAttestationRule", "field", "ref", "fallbackAccountIndex", "request", "address", "rule", "target", "altRef"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var t=require("../../../../app-binder/clear-sign/requirements/records"),p=require("../../../../app-binder/clear-sign/requirements/RequirementAccumulator"),E=require("../../../../app-binder/services/bs58Encoder"),T=require("./tokenRule");const I={typePool:[],rootType:0,mintAssociations:[],ownerAssociations:[]};function c(e){const{accountIndex:s,accountIndices:u,...l}=e;return{accountIndices:u??(s!==void 0?[s]:[]),optionalAccountStrategy:t.OptionalAccountStrategy.PROGRAM_ID,activeWhen:[],...l}}function A(e){return{paramType:t.PARAM_TYPE_TOKEN_AMOUNT,token:e}}function n(e){return{info:{...I,ownerAssociations:e.ownerAssociations??[]},valueFlowPorts:e.valueFlowPorts??[],accountResets:e.accountResets??[],displayFields:e.displayFields??[],hideRules:e.hideRules??[]}}function a(e,s="P"){return{programId:s,accounts:e.map(u=>({address:u,isWritable:!1,isSigner:!1})),data:new Uint8Array}}function r(e,s,u){const l=[...e.accounts];return l[s]={isWritable:!1,isSigner:!1,altRef:{altAddress:"ALT",entryIndex:u}},{...e,accounts:l}}function i(e){return{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(e)}}function d(e){return{ruleSetIndex:0,condition:t.HideCondition.IS_SIGNER,target:e}}function o(e,s,u=new Map,l=new Map){const k=new p.RequirementAccumulator;return(0,T.applyTokenRule)(e,s,{mints:u,owners:l},k),k.build()}describe("applyTokenRule",()=>{describe("DIRECT port",()=>{it("emits TOKEN_INFO for a 32-byte constant mint",()=>{const e=new Uint8Array(32).fill(4),s=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.CONSTANT,payload:e}}})]}),a(["a"]));expect(s.tokenInfos).toEqual([E.DefaultBs58Encoder.encode(e)])}),it("ignores a constant that is not 32 bytes",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.CONSTANT,payload:new Uint8Array(8)}}})]}),a(["a"]));expect(e.tokenInfos).toEqual([])}),it("resolves an ACCOUNT_PATH mint to the account address",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(1)}}})]}),a(["acct","theMint"]));expect(e.tokenInfos).toEqual(["theMint"])}),it("ignores an out-of-bounds ACCOUNT_PATH index",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(9)}}})]}),a(["a"]));expect(e.tokenInfos).toEqual([])})}),describe("RESOLVE port",()=>{it("sends TOKEN_ACCOUNT_STATE when no MINT_ASSOC binding covers it",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["userAta"]));expect(e.tokenAccountStates).toEqual(["userAta"]),expect(e.tokenInfos).toEqual([])}),it("emits TOKEN_INFO and skips account-state when MINT_ASSOC binds it",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["createdAta"]),new Map([["createdAta","boundMint"]]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toEqual(["boundMint"])}),it("uses the explicit token account index overrides the port's own",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:1}})]}),a(["wrong","rightAta"]));expect(e.tokenAccountStates).toEqual(["rightAta"])}),it("resolves a candidate-array port to its first provided candidate",()=>{const e=o(n({valueFlowPorts:[c({accountIndices:[0,1],tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["P","realAta"]));expect(e.tokenAccountStates).toEqual(["realAta"])}),it("adds nothing for an unresolved slot that carries no ALT ref either",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a([void 0]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([]),expect(e.tokenInfos).toEqual([])}),it("routes an ALT-backed token account to tokenAccountStateAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),r(a([void 0]),0,4));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:4}]),expect(e.tokenAccountStates).toEqual([])})}),it("ignores NATIVE and NULL ports and ports without a token value",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.NATIVE}}),c({accountIndex:0,tokenValue:{kind:t.TokenKind.NULL}}),c({accountIndex:0})]}),a(["a"]));expect(e.tokenInfos).toEqual([]),expect(e.tokenAccountStates).toEqual([])}),describe("ACCOUNT_RESET",()=>{it("forces TOKEN_ACCOUNT_STATE when requirePreBalanceZero is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!0,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("forces TOKEN_ACCOUNT_STATE when requireNativePreBalanceZero is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!0}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("does nothing without the flag or for an out-of-bounds index",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([]);const s=o(n({accountResets:[{accountIndex:9,requirePreBalanceZero:!0,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(s.tokenAccountStates).toEqual([])}),it("path 5: adds TOKEN_ACCOUNT_STATE for splToken+RESOLVE reset with no binding and no fallback",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("path 5: skips TOKEN_ACCOUNT_STATE when mint is already bound, emits TOKEN_INFO instead",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]),new Map([["ata","MINT"]]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toContain("MINT")}),it("path 5: skips TOKEN_ACCOUNT_STATE when fallbackAccountIndex is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE,fallbackAccountIndex:1}}]}),a(["ata","MINT"]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toContain("MINT")}),it("path 5: does not trigger for a native reset",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: does not trigger when tokenValue is absent",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: does not trigger for a splToken reset with a DIRECT token value",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.DIRECT}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: uses tokenValue.accountIndex instead of reset.accountIndex when set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:1}}]}),a(["wrong","rightAta"]));expect(e.tokenAccountStates).toEqual(["rightAta"])}),it("path 5: routes an ALT-backed token account to tokenAccountStateAltRefs",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),r(a([void 0]),0,7));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:7}]),expect(e.tokenAccountStates).toEqual([])}),it("path 2: an ALT-backed account with a pre-balance flag set produces a TAS ALT ref requirement",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!0}]}),r(a([void 0]),0,5));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:5}])})}),describe("PARAM_TOKEN_AMOUNT display field",()=>{it("emits TOKEN_INFO for a constant-mint amount-formatter token",()=>{const e=new Uint8Array(32).fill(9),s=o(n({displayFields:[A({source:t.ValueSource.CONSTANT,payload:e})]}),a(["a"]));expect(s.tokenInfos).toEqual([E.DefaultBs58Encoder.encode(e)])}),it("adds an unbound ACCOUNT_PATH token ref as a tokenAmountRef (try TOKEN_INFO first, fallback TOKEN_ACCOUNT_STATE)",()=>{const e=o(n({displayFields:[A({source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)})]}),a(["someMint"]));expect(e.tokenInfos).toEqual([]),expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAmountRefs).toEqual(["someMint"])}),it("redirects a bound token-account reference to its mint",()=>{const e=o(n({displayFields:[A({source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)})]}),a(["tokenAccount"]),new Map([["tokenAccount","itsMint"]]));expect(e.tokenInfos).toEqual(["itsMint"]),expect(e.tokenAccountStates).toEqual([])}),it("ignores non-token-amount display fields",()=>{const e=o(n({displayFields:[{paramType:t.PARAM_TYPE_TRUSTED_NAME,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)}}]}),a(["addr"]));expect(e.tokenInfos).toEqual([])})}),describe("RESOLVE port FALLBACK_ACCOUNT",()=>{it("emits TOKEN_INFO for the fallback account's address",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:0,fallbackAccountIndex:1}})]}),a(["ephemeralAta","mintOfLastResort"]));expect(e.tokenInfos).toEqual(["mintOfLastResort"]),expect(e.tokenAccountStates).toEqual(["ephemeralAta"])}),it("routes an ALT-backed fallback account to mintAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:0,fallbackAccountIndex:1}})]}),r(a(["ata",void 0]),1,9));expect(e.mintAltRefs).toEqual([{altAddress:"ALT",entryIndex:9}]),expect(e.tokenInfos).toEqual([])}),it("ignores a fallback account on a non-RESOLVE token value",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.NATIVE,fallbackAccountIndex:1}})]}),a(["a","notAMint"]));expect(e.tokenInfos).toEqual([])})}),describe("IS_SIGNER owner attestation (trigger path 3)",()=>{it("emits TOKEN_ACCOUNT_STATE for an IS_SIGNER hide-rule target",()=>{const e=o(n({hideRules:[d(i(1))]}),a(["other","maybeAta"]));expect(e.tokenAccountStates).toEqual(["maybeAta"])}),it("skips a target already bound by a TX-derived OWNER_ASSOC",()=>{const e=o(n({hideRules:[d(i(0))]}),a(["boundAta"]),new Map,new Map([["boundAta","itsOwner"]]));expect(e.tokenAccountStates).toEqual([])}),it("ignores hide rules on any other condition",()=>{const e=o(n({hideRules:[{ruleSetIndex:0,condition:t.HideCondition.CREATED_IN_TRANSACTION,target:i(0)}]}),a(["someAccount"]));expect(e.tokenAccountStates).toEqual([])}),it("emits TOKEN_ACCOUNT_STATE for a port with an IS_SIGNER ACTIVE_WHEN",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:1,activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),a(["other","portAccount"]));expect(e.tokenAccountStates).toEqual(["portAccount"])}),it("routes an ALT-backed hide-rule target to tokenAccountStateAltRefs",()=>{const e=o(n({hideRules:[d(i(0))]}),r(a([void 0]),0,6));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:6}]),expect(e.tokenAccountStates).toEqual([])}),it("routes an ALT-backed IS_SIGNER ACTIVE_WHEN port to tokenAccountStateAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),r(a([void 0]),0,7));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:7}])}),it("ignores a constant IS_SIGNER target: a CONSTANT is already an address, never an ALT ref",()=>{const e=o(n({hideRules:[d({source:t.ValueSource.CONSTANT,payload:new Uint8Array(4)})]}),r(a([void 0]),0,8));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([])}),it("ignores a port whose ACTIVE_WHEN carries no IS_SIGNER",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,activeWhen:[t.ActiveWhenPredicate.CREATED_IN_TRANSACTION],tokenValue:{kind:t.TokenKind.NATIVE}})]}),a(["portAccount"]));expect(e.tokenAccountStates).toEqual([])})})});
1
+ "use strict";var t=require("../../../../app-binder/clear-sign/requirements/records"),T=require("../../../../app-binder/clear-sign/requirements/RequirementAccumulator"),k=require("../../../../app-binder/services/bs58Encoder"),I=require("./tokenRule");const f={typePool:[],rootType:0,mintAssociations:[],ownerAssociations:[]};function c(e){const{accountIndex:s,accountIndices:u,...d}=e;return{accountIndices:u??(s!==void 0?[s]:[]),optionalAccountStrategy:t.OptionalAccountStrategy.PROGRAM_ID,activeWhen:[],...d}}function E(e){return{paramType:t.PARAM_TYPE_TOKEN_AMOUNT,token:e}}function n(e){return{info:{...f,ownerAssociations:e.ownerAssociations??[]},valueFlowPorts:e.valueFlowPorts??[],accountResets:e.accountResets??[],displayFields:e.displayFields??[],hideRules:e.hideRules??[]}}function a(e,s="P"){return{programId:s,accounts:e.map(u=>({address:u,isWritable:!1,isSigner:!1})),data:new Uint8Array}}function r(e,s,u){const d=[...e.accounts];return d[s]={isWritable:!1,isSigner:!1,altRef:{altAddress:"ALT",entryIndex:u}},{...e,accounts:d}}function A(e,s){const u=[...e.accounts];return u[s]={...u[s],isSigner:!0},{...e,accounts:u}}function l(e){return{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(e)}}function i(e){return{ruleSetIndex:0,condition:t.HideCondition.IS_SIGNER,target:e}}function o(e,s,u=new Map,d=new Map){const p=new T.RequirementAccumulator;return(0,I.applyTokenRule)(e,s,{mints:u,owners:d},p),p.build()}describe("applyTokenRule",()=>{describe("DIRECT port",()=>{it("emits TOKEN_INFO for a 32-byte constant mint",()=>{const e=new Uint8Array(32).fill(4),s=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.CONSTANT,payload:e}}})]}),a(["a"]));expect(s.tokenInfos).toEqual([k.DefaultBs58Encoder.encode(e)])}),it("ignores a constant that is not 32 bytes",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.CONSTANT,payload:new Uint8Array(8)}}})]}),a(["a"]));expect(e.tokenInfos).toEqual([])}),it("resolves an ACCOUNT_PATH mint to the account address",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(1)}}})]}),a(["acct","theMint"]));expect(e.tokenInfos).toEqual(["theMint"])}),it("ignores an out-of-bounds ACCOUNT_PATH index",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.DIRECT,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(9)}}})]}),a(["a"]));expect(e.tokenInfos).toEqual([])})}),describe("RESOLVE port",()=>{it("sends TOKEN_ACCOUNT_STATE when no MINT_ASSOC binding covers it",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["userAta"]));expect(e.tokenAccountStates).toEqual(["userAta"]),expect(e.tokenInfos).toEqual([])}),it("emits TOKEN_INFO and skips account-state when MINT_ASSOC binds it",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["createdAta"]),new Map([["createdAta","boundMint"]]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toEqual(["boundMint"])}),it("uses the explicit token account index overrides the port's own",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:1}})]}),a(["wrong","rightAta"]));expect(e.tokenAccountStates).toEqual(["rightAta"])}),it("resolves a candidate-array port to its first provided candidate",()=>{const e=o(n({valueFlowPorts:[c({accountIndices:[0,1],tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a(["P","realAta"]));expect(e.tokenAccountStates).toEqual(["realAta"])}),it("adds nothing for an unresolved slot that carries no ALT ref either",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),a([void 0]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([]),expect(e.tokenInfos).toEqual([])}),it("routes an ALT-backed token account to tokenAccountStateAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE}})]}),r(a([void 0]),0,4));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:4}]),expect(e.tokenAccountStates).toEqual([])})}),it("ignores NATIVE and NULL ports and ports without a token value",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.NATIVE}}),c({accountIndex:0,tokenValue:{kind:t.TokenKind.NULL}}),c({accountIndex:0})]}),a(["a"]));expect(e.tokenInfos).toEqual([]),expect(e.tokenAccountStates).toEqual([])}),describe("ACCOUNT_RESET",()=>{it("forces TOKEN_ACCOUNT_STATE when requirePreBalanceZero is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!0,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("forces TOKEN_ACCOUNT_STATE when requireNativePreBalanceZero is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!0}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("does nothing without the flag or for an out-of-bounds index",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([]);const s=o(n({accountResets:[{accountIndex:9,requirePreBalanceZero:!0,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(s.tokenAccountStates).toEqual([])}),it("path 5: adds TOKEN_ACCOUNT_STATE for splToken+RESOLVE reset with no binding and no fallback",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual(["ata"])}),it("path 5: skips TOKEN_ACCOUNT_STATE when mint is already bound, emits TOKEN_INFO instead",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]),new Map([["ata","MINT"]]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toContain("MINT")}),it("path 5: skips TOKEN_ACCOUNT_STATE when fallbackAccountIndex is set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE,fallbackAccountIndex:1}}]}),a(["ata","MINT"]));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenInfos).toContain("MINT")}),it("path 5: does not trigger for a native reset",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: does not trigger when tokenValue is absent",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: does not trigger for a splToken reset with a DIRECT token value",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.DIRECT}}]}),a(["ata"]));expect(e.tokenAccountStates).toEqual([])}),it("path 5: uses tokenValue.accountIndex instead of reset.accountIndex when set",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:1}}]}),a(["wrong","rightAta"]));expect(e.tokenAccountStates).toEqual(["rightAta"])}),it("path 5: routes an ALT-backed token account to tokenAccountStateAltRefs",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.SPL_TOKEN,requireNativePreBalanceZero:!1,tokenValue:{kind:t.TokenKind.RESOLVE}}]}),r(a([void 0]),0,7));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:7}]),expect(e.tokenAccountStates).toEqual([])}),it("path 2: an ALT-backed account with a pre-balance flag set produces a TAS ALT ref requirement",()=>{const e=o(n({accountResets:[{accountIndex:0,requirePreBalanceZero:!1,valueKind:t.ValueKind.NATIVE,requireNativePreBalanceZero:!0}]}),r(a([void 0]),0,5));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:5}])})}),describe("PARAM_TOKEN_AMOUNT display field",()=>{it("emits TOKEN_INFO for a constant-mint amount-formatter token",()=>{const e=new Uint8Array(32).fill(9),s=o(n({displayFields:[E({source:t.ValueSource.CONSTANT,payload:e})]}),a(["a"]));expect(s.tokenInfos).toEqual([k.DefaultBs58Encoder.encode(e)])}),it("adds an unbound ACCOUNT_PATH token ref as a tokenAmountRef (try TOKEN_INFO first, fallback TOKEN_ACCOUNT_STATE)",()=>{const e=o(n({displayFields:[E({source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)})]}),a(["someMint"]));expect(e.tokenInfos).toEqual([]),expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAmountRefs).toEqual(["someMint"])}),it("redirects a bound token-account reference to its mint",()=>{const e=o(n({displayFields:[E({source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)})]}),a(["tokenAccount"]),new Map([["tokenAccount","itsMint"]]));expect(e.tokenInfos).toEqual(["itsMint"]),expect(e.tokenAccountStates).toEqual([])}),it("ignores non-token-amount display fields",()=>{const e=o(n({displayFields:[{paramType:t.PARAM_TYPE_TRUSTED_NAME,value:{source:t.ValueSource.ACCOUNT_PATH,payload:Uint8Array.of(0)}}]}),a(["addr"]));expect(e.tokenInfos).toEqual([])})}),describe("RESOLVE port FALLBACK_ACCOUNT",()=>{it("emits TOKEN_INFO for the fallback account's address",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:0,fallbackAccountIndex:1}})]}),a(["ephemeralAta","mintOfLastResort"]));expect(e.tokenInfos).toEqual(["mintOfLastResort"]),expect(e.tokenAccountStates).toEqual(["ephemeralAta"])}),it("routes an ALT-backed fallback account to mintAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.RESOLVE,accountIndex:0,fallbackAccountIndex:1}})]}),r(a(["ata",void 0]),1,9));expect(e.mintAltRefs).toEqual([{altAddress:"ALT",entryIndex:9}]),expect(e.tokenInfos).toEqual([])}),it("ignores a fallback account on a non-RESOLVE token value",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,tokenValue:{kind:t.TokenKind.NATIVE,fallbackAccountIndex:1}})]}),a(["a","notAMint"]));expect(e.tokenInfos).toEqual([])})}),describe("IS_SIGNER owner attestation (trigger path 3)",()=>{it("emits TOKEN_ACCOUNT_STATE for an IS_SIGNER hide-rule target",()=>{const e=o(n({hideRules:[i(l(1))]}),a(["other","maybeAta"]));expect(e.tokenAccountStates).toEqual(["maybeAta"])}),it("skips a target already bound by a TX-derived OWNER_ASSOC",()=>{const e=o(n({hideRules:[i(l(0))]}),a(["boundAta"]),new Map,new Map([["boundAta","itsOwner"]]));expect(e.tokenAccountStates).toEqual([])}),it("ignores hide rules on any other condition",()=>{const e=o(n({hideRules:[{ruleSetIndex:0,condition:t.HideCondition.CREATED_IN_TRANSACTION,target:l(0)}]}),a(["someAccount"]));expect(e.tokenAccountStates).toEqual([])}),it("emits TOKEN_ACCOUNT_STATE for a port with an IS_SIGNER ACTIVE_WHEN",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:1,activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),a(["other","portAccount"]));expect(e.tokenAccountStates).toEqual(["portAccount"])}),it("routes an ALT-backed hide-rule target to tokenAccountStateAltRefs",()=>{const e=o(n({hideRules:[i(l(0))]}),r(a([void 0]),0,6));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:6}]),expect(e.tokenAccountStates).toEqual([])}),it("routes an ALT-backed IS_SIGNER ACTIVE_WHEN port to tokenAccountStateAltRefs",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),r(a([void 0]),0,7));expect(e.tokenAccountStateAltRefs).toEqual([{altAddress:"ALT",entryIndex:7}])}),it("ignores a constant IS_SIGNER target: a CONSTANT is already an address, never an ALT ref",()=>{const e=o(n({hideRules:[i({source:t.ValueSource.CONSTANT,payload:new Uint8Array(4)})]}),r(a([void 0]),0,8));expect(e.tokenAccountStates).toEqual([]),expect(e.tokenAccountStateAltRefs).toEqual([])}),it("ignores a port whose ACTIVE_WHEN carries no IS_SIGNER",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:0,activeWhen:[t.ActiveWhenPredicate.CREATED_IN_TRANSACTION],tokenValue:{kind:t.TokenKind.NATIVE}})]}),a(["portAccount"]));expect(e.tokenAccountStates).toEqual([])}),it("skips a hide-rule target the header marks as a signer",()=>{const e=o(n({hideRules:[i(l(0))]}),A(a(["walletKey"]),0));expect(e.tokenAccountStates).toEqual([])}),it("skips an IS_SIGNER ACTIVE_WHEN port whose account is a header signer",()=>{const e=o(n({valueFlowPorts:[c({accountIndex:1,activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),A(a(["other","walletKey"]),1));expect(e.tokenAccountStates).toEqual([])}),it("guards per slot: a non-signer target alongside a signer one still fetches",()=>{const e=o(n({hideRules:[i(l(0)),i(l(1))]}),A(a(["walletKey","maybeAta"]),0));expect(e.tokenAccountStates).toEqual(["maybeAta"])}),it("still fetches for a signer's candidate port when the port resolves to a non-signer slot",()=>{const e=o(n({valueFlowPorts:[c({accountIndices:[5,1],activeWhen:[t.ActiveWhenPredicate.IS_SIGNER],tokenValue:{kind:t.TokenKind.NATIVE}})]}),A(a(["walletKey","maybeAta"]),0));expect(e.tokenAccountStates).toEqual(["maybeAta"])})})});
2
2
  //# sourceMappingURL=tokenRule.test.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/internal/app-binder/clear-sign/requirements/rules/tokenRule.test.ts"],
4
- "sourcesContent": ["import { type RequirementInstruction } from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n OptionalAccountStrategy,\n PARAM_TYPE_TOKEN_AMOUNT,\n PARAM_TYPE_TRUSTED_NAME,\n type ParsedAccountReset,\n type ParsedDisplayField,\n type ParsedHideRule,\n type ParsedInstruction,\n type ParsedOwnerAssociation,\n type ParsedValue,\n type ParsedValueFlowPort,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport { DefaultBs58Encoder } from \"@internal/app-binder/services/bs58Encoder\";\n\nimport { applyTokenRule } from \"./tokenRule\";\n\nconst EMPTY_INFO = {\n typePool: [],\n rootType: 0,\n mintAssociations: [],\n ownerAssociations: [],\n};\n\n/** Build a port, defaulting the candidate list and strategy. */\nfunction port(\n overrides: Partial<ParsedValueFlowPort> & { accountIndex?: number },\n): ParsedValueFlowPort {\n const { accountIndex, accountIndices, ...rest } = overrides;\n return {\n accountIndices:\n accountIndices ?? (accountIndex !== undefined ? [accountIndex] : []),\n optionalAccountStrategy: OptionalAccountStrategy.PROGRAM_ID,\n activeWhen: [],\n ...rest,\n };\n}\n\n/** A PARAM_TOKEN_AMOUNT display field whose TOKEN reference is `token`. */\nfunction tokenAmountField(token: ParsedValue): ParsedDisplayField {\n return { paramType: PARAM_TYPE_TOKEN_AMOUNT, token };\n}\n\nfunction parsed(overrides: {\n valueFlowPorts?: ParsedValueFlowPort[];\n accountResets?: ParsedAccountReset[];\n displayFields?: ParsedDisplayField[];\n hideRules?: ParsedHideRule[];\n ownerAssociations?: ParsedOwnerAssociation[];\n}): ParsedInstruction {\n return {\n info: {\n ...EMPTY_INFO,\n ownerAssociations: overrides.ownerAssociations ?? [],\n },\n valueFlowPorts: overrides.valueFlowPorts ?? [],\n accountResets: overrides.accountResets ?? [],\n displayFields: overrides.displayFields ?? [],\n hideRules: overrides.hideRules ?? [],\n };\n}\n\nfunction makeInstruction(\n addresses: (string | undefined)[],\n programId = \"P\",\n): RequirementInstruction {\n return {\n programId,\n accounts: addresses.map((address) => ({\n address,\n isWritable: false,\n isSigner: false,\n })),\n data: new Uint8Array(),\n };\n}\n\n/** An instruction whose slot `altIndex` is ALT-backed instead of resolved. */\nfunction withAltSlot(\n instruction: RequirementInstruction,\n altIndex: number,\n entryIndex: number,\n): RequirementInstruction {\n const accounts = [...instruction.accounts];\n accounts[altIndex] = {\n isWritable: false,\n isSigner: false,\n altRef: { altAddress: \"ALT\", entryIndex },\n };\n return { ...instruction, accounts };\n}\n\nfunction accountPathValue(index: number): ParsedValue {\n return {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(index),\n };\n}\n\nfunction isSignerRule(target: ParsedValue): ParsedHideRule {\n return { ruleSetIndex: 0, condition: HideCondition.IS_SIGNER, target };\n}\n\nfunction run(\n records: ParsedInstruction,\n instruction: RequirementInstruction,\n mints: Map<string, string> = new Map(),\n owners: Map<string, string> = new Map(),\n) {\n const accumulator = new RequirementAccumulator();\n applyTokenRule(records, instruction, { mints, owners }, accumulator);\n return accumulator.build();\n}\n\ndescribe(\"applyTokenRule\", () => {\n describe(\"DIRECT port\", () => {\n it(\"emits TOKEN_INFO for a 32-byte constant mint\", () => {\n const mint = new Uint8Array(32).fill(4);\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: { source: ValueSource.CONSTANT, payload: mint },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([DefaultBs58Encoder.encode(mint)]);\n });\n\n it(\"ignores a constant that is not 32 bytes\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.CONSTANT,\n payload: new Uint8Array(8),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"resolves an ACCOUNT_PATH mint to the account address\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(1),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"acct\", \"theMint\"]),\n );\n expect(result.tokenInfos).toEqual([\"theMint\"]);\n });\n\n it(\"ignores an out-of-bounds ACCOUNT_PATH index\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(9),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n\n describe(\"RESOLVE port\", () => {\n it(\"sends TOKEN_ACCOUNT_STATE when no MINT_ASSOC binding covers it\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([\"userAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"userAta\"]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"emits TOKEN_INFO and skips account-state when MINT_ASSOC binds it\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([\"createdAta\"]),\n new Map([[\"createdAta\", \"boundMint\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toEqual([\"boundMint\"]);\n });\n\n it(\"uses the explicit token account index overrides the port's own\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: { kind: TokenKind.RESOLVE, accountIndex: 1 },\n }),\n ],\n }),\n makeInstruction([\"wrong\", \"rightAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"rightAta\"]);\n });\n\n it(\"resolves a candidate-array port to its first provided candidate\", () => {\n // First candidate (index 0) holds the program id under PROGRAM_ID\n // strategy, so it is unset; the next provided candidate (index 1) wins.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndices: [0, 1],\n tokenValue: { kind: TokenKind.RESOLVE },\n }),\n ],\n }),\n makeInstruction([\"P\", \"realAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"realAta\"]);\n });\n\n it(\"adds nothing for an unresolved slot that carries no ALT ref either\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([undefined]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"routes an ALT-backed token account to tokenAccountStateAltRefs\", () => {\n // No MINT_ASSOC binding can cover an ALT-backed slot (both halves must be\n // resolved host-side), so the mint can only come from the attested state,\n // fetched once ALT_RESOLUTION names the address.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 4),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 4 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n });\n\n it(\"ignores NATIVE and NULL ports and ports without a token value\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.NATIVE } }),\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.NULL } }),\n port({ accountIndex: 0 }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n describe(\"ACCOUNT_RESET\", () => {\n it(\"forces TOKEN_ACCOUNT_STATE when requirePreBalanceZero is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: true,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"forces TOKEN_ACCOUNT_STATE when requireNativePreBalanceZero is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: true,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"does nothing without the flag or for an out-of-bounds index\", () => {\n const noFlag = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(noFlag.tokenAccountStates).toEqual([]);\n\n const oob = run(\n parsed({\n accountResets: [\n {\n accountIndex: 9,\n requirePreBalanceZero: true,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(oob.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: adds TOKEN_ACCOUNT_STATE for splToken+RESOLVE reset with no binding and no fallback\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"path 5: skips TOKEN_ACCOUNT_STATE when mint is already bound, emits TOKEN_INFO instead\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n new Map([[\"ata\", \"MINT\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toContain(\"MINT\");\n });\n\n it(\"path 5: skips TOKEN_ACCOUNT_STATE when fallbackAccountIndex is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE, fallbackAccountIndex: 1 },\n },\n ],\n }),\n makeInstruction([\"ata\", \"MINT\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toContain(\"MINT\");\n });\n\n it(\"path 5: does not trigger for a native reset\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n // native reset with no pre-balance flags emits nothing from path 5\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: does not trigger when tokenValue is absent\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: does not trigger for a splToken reset with a DIRECT token value\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.DIRECT },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: uses tokenValue.accountIndex instead of reset.accountIndex when set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE, accountIndex: 1 },\n },\n ],\n }),\n makeInstruction([\"wrong\", \"rightAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"rightAta\"]);\n });\n\n it(\"path 5: routes an ALT-backed token account to tokenAccountStateAltRefs\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 7),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 7 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 2: an ALT-backed account with a pre-balance flag set produces a TAS ALT ref requirement\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: true,\n },\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 5),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 5 },\n ]);\n });\n });\n\n describe(\"PARAM_TOKEN_AMOUNT display field\", () => {\n it(\"emits TOKEN_INFO for a constant-mint amount-formatter token\", () => {\n const mint = new Uint8Array(32).fill(9);\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({ source: ValueSource.CONSTANT, payload: mint }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([DefaultBs58Encoder.encode(mint)]);\n });\n\n it(\"adds an unbound ACCOUNT_PATH token ref as a tokenAmountRef (try TOKEN_INFO first, fallback TOKEN_ACCOUNT_STATE)\", () => {\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n }),\n ],\n }),\n makeInstruction([\"someMint\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAmountRefs).toEqual([\"someMint\"]);\n });\n\n it(\"redirects a bound token-account reference to its mint\", () => {\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n }),\n ],\n }),\n makeInstruction([\"tokenAccount\"]),\n new Map([[\"tokenAccount\", \"itsMint\"]]),\n );\n expect(result.tokenInfos).toEqual([\"itsMint\"]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"ignores non-token-amount display fields\", () => {\n const result = run(\n parsed({\n displayFields: [\n {\n paramType: PARAM_TYPE_TRUSTED_NAME,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n },\n },\n ],\n }),\n makeInstruction([\"addr\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n describe(\"RESOLVE port FALLBACK_ACCOUNT\", () => {\n it(\"emits TOKEN_INFO for the fallback account's address\", () => {\n // The device uses the fallback slot's address as the mint verbatim once\n // both binding sources miss, so that address is a mint candidate.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.RESOLVE,\n accountIndex: 0,\n fallbackAccountIndex: 1,\n },\n }),\n ],\n }),\n makeInstruction([\"ephemeralAta\", \"mintOfLastResort\"]),\n );\n expect(result.tokenInfos).toEqual([\"mintOfLastResort\"]);\n expect(result.tokenAccountStates).toEqual([\"ephemeralAta\"]);\n });\n\n it(\"routes an ALT-backed fallback account to mintAltRefs\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.RESOLVE,\n accountIndex: 0,\n fallbackAccountIndex: 1,\n },\n }),\n ],\n }),\n withAltSlot(makeInstruction([\"ata\", undefined]), 1, 9),\n );\n expect(result.mintAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 9 },\n ]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"ignores a fallback account on a non-RESOLVE token value\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: { kind: TokenKind.NATIVE, fallbackAccountIndex: 1 },\n }),\n ],\n }),\n makeInstruction([\"a\", \"notAMint\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n\n describe(\"IS_SIGNER owner attestation (trigger path 3)\", () => {\n it(\"emits TOKEN_ACCOUNT_STATE for an IS_SIGNER hide-rule target\", () => {\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(1))] }),\n makeInstruction([\"other\", \"maybeAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"maybeAta\"]);\n });\n\n it(\"skips a target already bound by a TX-derived OWNER_ASSOC\", () => {\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(0))] }),\n makeInstruction([\"boundAta\"]),\n new Map(),\n new Map([[\"boundAta\", \"itsOwner\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"ignores hide rules on any other condition\", () => {\n const result = run(\n parsed({\n hideRules: [\n {\n ruleSetIndex: 0,\n condition: HideCondition.CREATED_IN_TRANSACTION,\n target: accountPathValue(0),\n },\n ],\n }),\n makeInstruction([\"someAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"emits TOKEN_ACCOUNT_STATE for a port with an IS_SIGNER ACTIVE_WHEN\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 1,\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n makeInstruction([\"other\", \"portAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"portAccount\"]);\n });\n\n it(\"routes an ALT-backed hide-rule target to tokenAccountStateAltRefs\", () => {\n // Without this the owner map stays unseeded, the predicate evaluates\n // false, and the device shows the screens the rule meant to hide.\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(0))] }),\n withAltSlot(makeInstruction([undefined]), 0, 6),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 6 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"routes an ALT-backed IS_SIGNER ACTIVE_WHEN port to tokenAccountStateAltRefs\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 7),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 7 },\n ]);\n });\n\n it(\"ignores a constant IS_SIGNER target: a CONSTANT is already an address, never an ALT ref\", () => {\n const result = run(\n parsed({\n hideRules: [\n isSignerRule({\n source: ValueSource.CONSTANT,\n payload: new Uint8Array(4),\n }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 8),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([]);\n });\n\n it(\"ignores a port whose ACTIVE_WHEN carries no IS_SIGNER\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n activeWhen: [ActiveWhenPredicate.CREATED_IN_TRANSACTION],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n makeInstruction([\"portAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n });\n});\n"],
5
- "mappings": "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",
6
- "names": ["import_records", "import_RequirementAccumulator", "import_bs58Encoder", "import_tokenRule", "EMPTY_INFO", "port", "overrides", "accountIndex", "accountIndices", "rest", "tokenAmountField", "token", "parsed", "makeInstruction", "addresses", "programId", "address", "withAltSlot", "instruction", "altIndex", "entryIndex", "accounts", "accountPathValue", "index", "isSignerRule", "target", "run", "records", "mints", "owners", "accumulator", "mint", "result", "noFlag", "oob"]
4
+ "sourcesContent": ["import { type RequirementInstruction } from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n OptionalAccountStrategy,\n PARAM_TYPE_TOKEN_AMOUNT,\n PARAM_TYPE_TRUSTED_NAME,\n type ParsedAccountReset,\n type ParsedDisplayField,\n type ParsedHideRule,\n type ParsedInstruction,\n type ParsedOwnerAssociation,\n type ParsedValue,\n type ParsedValueFlowPort,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport { DefaultBs58Encoder } from \"@internal/app-binder/services/bs58Encoder\";\n\nimport { applyTokenRule } from \"./tokenRule\";\n\nconst EMPTY_INFO = {\n typePool: [],\n rootType: 0,\n mintAssociations: [],\n ownerAssociations: [],\n};\n\n/** Build a port, defaulting the candidate list and strategy. */\nfunction port(\n overrides: Partial<ParsedValueFlowPort> & { accountIndex?: number },\n): ParsedValueFlowPort {\n const { accountIndex, accountIndices, ...rest } = overrides;\n return {\n accountIndices:\n accountIndices ?? (accountIndex !== undefined ? [accountIndex] : []),\n optionalAccountStrategy: OptionalAccountStrategy.PROGRAM_ID,\n activeWhen: [],\n ...rest,\n };\n}\n\n/** A PARAM_TOKEN_AMOUNT display field whose TOKEN reference is `token`. */\nfunction tokenAmountField(token: ParsedValue): ParsedDisplayField {\n return { paramType: PARAM_TYPE_TOKEN_AMOUNT, token };\n}\n\nfunction parsed(overrides: {\n valueFlowPorts?: ParsedValueFlowPort[];\n accountResets?: ParsedAccountReset[];\n displayFields?: ParsedDisplayField[];\n hideRules?: ParsedHideRule[];\n ownerAssociations?: ParsedOwnerAssociation[];\n}): ParsedInstruction {\n return {\n info: {\n ...EMPTY_INFO,\n ownerAssociations: overrides.ownerAssociations ?? [],\n },\n valueFlowPorts: overrides.valueFlowPorts ?? [],\n accountResets: overrides.accountResets ?? [],\n displayFields: overrides.displayFields ?? [],\n hideRules: overrides.hideRules ?? [],\n };\n}\n\nfunction makeInstruction(\n addresses: (string | undefined)[],\n programId = \"P\",\n): RequirementInstruction {\n return {\n programId,\n accounts: addresses.map((address) => ({\n address,\n isWritable: false,\n isSigner: false,\n })),\n data: new Uint8Array(),\n };\n}\n\n/** An instruction whose slot `altIndex` is ALT-backed instead of resolved. */\nfunction withAltSlot(\n instruction: RequirementInstruction,\n altIndex: number,\n entryIndex: number,\n): RequirementInstruction {\n const accounts = [...instruction.accounts];\n accounts[altIndex] = {\n isWritable: false,\n isSigner: false,\n altRef: { altAddress: \"ALT\", entryIndex },\n };\n return { ...instruction, accounts };\n}\n\n/** An instruction whose slot `signerIndex` is a required signer in the header. */\nfunction withSignerSlot(\n instruction: RequirementInstruction,\n signerIndex: number,\n): RequirementInstruction {\n const accounts = [...instruction.accounts];\n accounts[signerIndex] = { ...accounts[signerIndex]!, isSigner: true };\n return { ...instruction, accounts };\n}\n\nfunction accountPathValue(index: number): ParsedValue {\n return {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(index),\n };\n}\n\nfunction isSignerRule(target: ParsedValue): ParsedHideRule {\n return { ruleSetIndex: 0, condition: HideCondition.IS_SIGNER, target };\n}\n\nfunction run(\n records: ParsedInstruction,\n instruction: RequirementInstruction,\n mints: Map<string, string> = new Map(),\n owners: Map<string, string> = new Map(),\n) {\n const accumulator = new RequirementAccumulator();\n applyTokenRule(records, instruction, { mints, owners }, accumulator);\n return accumulator.build();\n}\n\ndescribe(\"applyTokenRule\", () => {\n describe(\"DIRECT port\", () => {\n it(\"emits TOKEN_INFO for a 32-byte constant mint\", () => {\n const mint = new Uint8Array(32).fill(4);\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: { source: ValueSource.CONSTANT, payload: mint },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([DefaultBs58Encoder.encode(mint)]);\n });\n\n it(\"ignores a constant that is not 32 bytes\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.CONSTANT,\n payload: new Uint8Array(8),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"resolves an ACCOUNT_PATH mint to the account address\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(1),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"acct\", \"theMint\"]),\n );\n expect(result.tokenInfos).toEqual([\"theMint\"]);\n });\n\n it(\"ignores an out-of-bounds ACCOUNT_PATH index\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.DIRECT,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(9),\n },\n },\n }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n\n describe(\"RESOLVE port\", () => {\n it(\"sends TOKEN_ACCOUNT_STATE when no MINT_ASSOC binding covers it\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([\"userAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"userAta\"]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"emits TOKEN_INFO and skips account-state when MINT_ASSOC binds it\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([\"createdAta\"]),\n new Map([[\"createdAta\", \"boundMint\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toEqual([\"boundMint\"]);\n });\n\n it(\"uses the explicit token account index overrides the port's own\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: { kind: TokenKind.RESOLVE, accountIndex: 1 },\n }),\n ],\n }),\n makeInstruction([\"wrong\", \"rightAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"rightAta\"]);\n });\n\n it(\"resolves a candidate-array port to its first provided candidate\", () => {\n // First candidate (index 0) holds the program id under PROGRAM_ID\n // strategy, so it is unset; the next provided candidate (index 1) wins.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndices: [0, 1],\n tokenValue: { kind: TokenKind.RESOLVE },\n }),\n ],\n }),\n makeInstruction([\"P\", \"realAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"realAta\"]);\n });\n\n it(\"adds nothing for an unresolved slot that carries no ALT ref either\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n makeInstruction([undefined]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"routes an ALT-backed token account to tokenAccountStateAltRefs\", () => {\n // No MINT_ASSOC binding can cover an ALT-backed slot (both halves must be\n // resolved host-side), so the mint can only come from the attested state,\n // fetched once ALT_RESOLUTION names the address.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.RESOLVE } }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 4),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 4 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n });\n\n it(\"ignores NATIVE and NULL ports and ports without a token value\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.NATIVE } }),\n port({ accountIndex: 0, tokenValue: { kind: TokenKind.NULL } }),\n port({ accountIndex: 0 }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n describe(\"ACCOUNT_RESET\", () => {\n it(\"forces TOKEN_ACCOUNT_STATE when requirePreBalanceZero is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: true,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"forces TOKEN_ACCOUNT_STATE when requireNativePreBalanceZero is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: true,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"does nothing without the flag or for an out-of-bounds index\", () => {\n const noFlag = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(noFlag.tokenAccountStates).toEqual([]);\n\n const oob = run(\n parsed({\n accountResets: [\n {\n accountIndex: 9,\n requirePreBalanceZero: true,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(oob.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: adds TOKEN_ACCOUNT_STATE for splToken+RESOLVE reset with no binding and no fallback\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"ata\"]);\n });\n\n it(\"path 5: skips TOKEN_ACCOUNT_STATE when mint is already bound, emits TOKEN_INFO instead\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n new Map([[\"ata\", \"MINT\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toContain(\"MINT\");\n });\n\n it(\"path 5: skips TOKEN_ACCOUNT_STATE when fallbackAccountIndex is set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE, fallbackAccountIndex: 1 },\n },\n ],\n }),\n makeInstruction([\"ata\", \"MINT\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenInfos).toContain(\"MINT\");\n });\n\n it(\"path 5: does not trigger for a native reset\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n // native reset with no pre-balance flags emits nothing from path 5\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: does not trigger when tokenValue is absent\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: does not trigger for a splToken reset with a DIRECT token value\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.DIRECT },\n },\n ],\n }),\n makeInstruction([\"ata\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 5: uses tokenValue.accountIndex instead of reset.accountIndex when set\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE, accountIndex: 1 },\n },\n ],\n }),\n makeInstruction([\"wrong\", \"rightAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"rightAta\"]);\n });\n\n it(\"path 5: routes an ALT-backed token account to tokenAccountStateAltRefs\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.SPL_TOKEN,\n requireNativePreBalanceZero: false,\n tokenValue: { kind: TokenKind.RESOLVE },\n },\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 7),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 7 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"path 2: an ALT-backed account with a pre-balance flag set produces a TAS ALT ref requirement\", () => {\n const result = run(\n parsed({\n accountResets: [\n {\n accountIndex: 0,\n requirePreBalanceZero: false,\n valueKind: ValueKind.NATIVE,\n requireNativePreBalanceZero: true,\n },\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 5),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 5 },\n ]);\n });\n });\n\n describe(\"PARAM_TOKEN_AMOUNT display field\", () => {\n it(\"emits TOKEN_INFO for a constant-mint amount-formatter token\", () => {\n const mint = new Uint8Array(32).fill(9);\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({ source: ValueSource.CONSTANT, payload: mint }),\n ],\n }),\n makeInstruction([\"a\"]),\n );\n expect(result.tokenInfos).toEqual([DefaultBs58Encoder.encode(mint)]);\n });\n\n it(\"adds an unbound ACCOUNT_PATH token ref as a tokenAmountRef (try TOKEN_INFO first, fallback TOKEN_ACCOUNT_STATE)\", () => {\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n }),\n ],\n }),\n makeInstruction([\"someMint\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAmountRefs).toEqual([\"someMint\"]);\n });\n\n it(\"redirects a bound token-account reference to its mint\", () => {\n const result = run(\n parsed({\n displayFields: [\n tokenAmountField({\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n }),\n ],\n }),\n makeInstruction([\"tokenAccount\"]),\n new Map([[\"tokenAccount\", \"itsMint\"]]),\n );\n expect(result.tokenInfos).toEqual([\"itsMint\"]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"ignores non-token-amount display fields\", () => {\n const result = run(\n parsed({\n displayFields: [\n {\n paramType: PARAM_TYPE_TRUSTED_NAME,\n value: {\n source: ValueSource.ACCOUNT_PATH,\n payload: Uint8Array.of(0),\n },\n },\n ],\n }),\n makeInstruction([\"addr\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n describe(\"RESOLVE port FALLBACK_ACCOUNT\", () => {\n it(\"emits TOKEN_INFO for the fallback account's address\", () => {\n // The device uses the fallback slot's address as the mint verbatim once\n // both binding sources miss, so that address is a mint candidate.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.RESOLVE,\n accountIndex: 0,\n fallbackAccountIndex: 1,\n },\n }),\n ],\n }),\n makeInstruction([\"ephemeralAta\", \"mintOfLastResort\"]),\n );\n expect(result.tokenInfos).toEqual([\"mintOfLastResort\"]);\n expect(result.tokenAccountStates).toEqual([\"ephemeralAta\"]);\n });\n\n it(\"routes an ALT-backed fallback account to mintAltRefs\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: {\n kind: TokenKind.RESOLVE,\n accountIndex: 0,\n fallbackAccountIndex: 1,\n },\n }),\n ],\n }),\n withAltSlot(makeInstruction([\"ata\", undefined]), 1, 9),\n );\n expect(result.mintAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 9 },\n ]);\n expect(result.tokenInfos).toEqual([]);\n });\n\n it(\"ignores a fallback account on a non-RESOLVE token value\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n tokenValue: { kind: TokenKind.NATIVE, fallbackAccountIndex: 1 },\n }),\n ],\n }),\n makeInstruction([\"a\", \"notAMint\"]),\n );\n expect(result.tokenInfos).toEqual([]);\n });\n });\n\n describe(\"IS_SIGNER owner attestation (trigger path 3)\", () => {\n it(\"emits TOKEN_ACCOUNT_STATE for an IS_SIGNER hide-rule target\", () => {\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(1))] }),\n makeInstruction([\"other\", \"maybeAta\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"maybeAta\"]);\n });\n\n it(\"skips a target already bound by a TX-derived OWNER_ASSOC\", () => {\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(0))] }),\n makeInstruction([\"boundAta\"]),\n new Map(),\n new Map([[\"boundAta\", \"itsOwner\"]]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"ignores hide rules on any other condition\", () => {\n const result = run(\n parsed({\n hideRules: [\n {\n ruleSetIndex: 0,\n condition: HideCondition.CREATED_IN_TRANSACTION,\n target: accountPathValue(0),\n },\n ],\n }),\n makeInstruction([\"someAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"emits TOKEN_ACCOUNT_STATE for a port with an IS_SIGNER ACTIVE_WHEN\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 1,\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n makeInstruction([\"other\", \"portAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([\"portAccount\"]);\n });\n\n it(\"routes an ALT-backed hide-rule target to tokenAccountStateAltRefs\", () => {\n // Without this the owner map stays unseeded, the predicate evaluates\n // false, and the device shows the screens the rule meant to hide.\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(0))] }),\n withAltSlot(makeInstruction([undefined]), 0, 6),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 6 },\n ]);\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"routes an ALT-backed IS_SIGNER ACTIVE_WHEN port to tokenAccountStateAltRefs\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 7),\n );\n expect(result.tokenAccountStateAltRefs).toEqual([\n { altAddress: \"ALT\", entryIndex: 7 },\n ]);\n });\n\n it(\"ignores a constant IS_SIGNER target: a CONSTANT is already an address, never an ALT ref\", () => {\n const result = run(\n parsed({\n hideRules: [\n isSignerRule({\n source: ValueSource.CONSTANT,\n payload: new Uint8Array(4),\n }),\n ],\n }),\n withAltSlot(makeInstruction([undefined]), 0, 8),\n );\n expect(result.tokenAccountStates).toEqual([]);\n expect(result.tokenAccountStateAltRefs).toEqual([]);\n });\n\n it(\"ignores a port whose ACTIVE_WHEN carries no IS_SIGNER\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 0,\n activeWhen: [ActiveWhenPredicate.CREATED_IN_TRANSACTION],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n makeInstruction([\"portAccount\"]),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"skips a hide-rule target the header marks as a signer\", () => {\n // A header signer produced an ed25519 signature, so it is a plain key and\n // never a token account: the device derives it from its own seed and the\n // owner map has nothing to add. Asking the backend to attest a non-token\n // address risks a descriptor that binds an owner that should not exist.\n const result = run(\n parsed({ hideRules: [isSignerRule(accountPathValue(0))] }),\n withSignerSlot(makeInstruction([\"walletKey\"]), 0),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"skips an IS_SIGNER ACTIVE_WHEN port whose account is a header signer\", () => {\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndex: 1,\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n withSignerSlot(makeInstruction([\"other\", \"walletKey\"]), 1),\n );\n expect(result.tokenAccountStates).toEqual([]);\n });\n\n it(\"guards per slot: a non-signer target alongside a signer one still fetches\", () => {\n const result = run(\n parsed({\n hideRules: [\n isSignerRule(accountPathValue(0)),\n isSignerRule(accountPathValue(1)),\n ],\n }),\n withSignerSlot(makeInstruction([\"walletKey\", \"maybeAta\"]), 0),\n );\n expect(result.tokenAccountStates).toEqual([\"maybeAta\"]);\n });\n\n it(\"still fetches for a signer's candidate port when the port resolves to a non-signer slot\", () => {\n // `resolvePortAccountIndex` picks the first provided candidate; the guard\n // has to read the slot that was actually chosen, not the first listed.\n const result = run(\n parsed({\n valueFlowPorts: [\n port({\n accountIndices: [5, 1],\n activeWhen: [ActiveWhenPredicate.IS_SIGNER],\n tokenValue: { kind: TokenKind.NATIVE },\n }),\n ],\n }),\n withSignerSlot(makeInstruction([\"walletKey\", \"maybeAta\"]), 0),\n );\n expect(result.tokenAccountStates).toEqual([\"maybeAta\"]);\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_records", "import_RequirementAccumulator", "import_bs58Encoder", "import_tokenRule", "EMPTY_INFO", "port", "overrides", "accountIndex", "accountIndices", "rest", "tokenAmountField", "token", "parsed", "makeInstruction", "addresses", "programId", "address", "withAltSlot", "instruction", "altIndex", "entryIndex", "accounts", "withSignerSlot", "signerIndex", "accountPathValue", "index", "isSignerRule", "target", "run", "records", "mints", "owners", "accumulator", "mint", "result", "noFlag", "oob"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var c=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var l=(e,n)=>{for(var t in n)c(e,t,{get:n[t],enumerable:!0})},p=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of s(n))!f.call(e,o)&&o!==t&&c(e,o,{get:()=>n[o],enumerable:!(r=i(n,o))||r.enumerable});return e};var y=e=>p(c({},"__esModule",{value:!0}),e);var I={};l(I,{accountAddressAt:()=>d,accountAltRefAt:()=>a,altRefForPubkeyValue:()=>g,resolvePortAccountIndex:()=>A,resolvePubkeyValue:()=>P});module.exports=y(I);var u=require("./records");const m=32;function d(e,n){if(!(n<0||n>=e.accounts.length))return e.accounts[n].address}function a(e,n){if(!(n<0||n>=e.accounts.length))return e.accounts[n].altRef}function A(e,n){const t=e.accountIndices;if(t.length===0)return-1;for(const r of t.slice(0,-1))if(!(r<0||r>=n.accounts.length)&&!(e.optionalAccountStrategy!==u.OptionalAccountStrategy.OMITTED&&n.accounts[r].address===n.programId))return r;return t[t.length-1]}function g(e,n){if(e.source===u.ValueSource.ACCOUNT_PATH&&e.payload.length!==0)return a(n,e.payload[0])}function P(e,n,t){switch(e.source){case u.ValueSource.CONSTANT:return e.payload.length===m?t.encode(e.payload):void 0;case u.ValueSource.ACCOUNT_PATH:return e.payload.length>0?d(n,e.payload[0]):void 0;default:return}}0&&(module.exports={accountAddressAt,accountAltRefAt,altRefForPubkeyValue,resolvePortAccountIndex,resolvePubkeyValue});
1
+ "use strict";var c=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var p=(e,n)=>{for(var t in n)c(e,t,{get:n[t],enumerable:!0})},y=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of f(n))!l.call(e,o)&&o!==t&&c(e,o,{get:()=>n[o],enumerable:!(r=s(n,o))||r.enumerable});return e};var m=e=>y(c({},"__esModule",{value:!0}),e);var R={};p(R,{accountAddressAt:()=>d,accountAltRefAt:()=>a,accountIsSignerAt:()=>P,altRefForPubkeyValue:()=>I,pubkeyValueAccountIndex:()=>i,resolvePortAccountIndex:()=>g,resolvePubkeyValue:()=>h});module.exports=m(R);var u=require("./records");const A=32;function d(e,n){if(!(n<0||n>=e.accounts.length))return e.accounts[n].address}function a(e,n){if(!(n<0||n>=e.accounts.length))return e.accounts[n].altRef}function g(e,n){const t=e.accountIndices;if(t.length===0)return-1;for(const r of t.slice(0,-1))if(!(r<0||r>=n.accounts.length)&&!(e.optionalAccountStrategy!==u.OptionalAccountStrategy.OMITTED&&n.accounts[r].address===n.programId))return r;return t[t.length-1]}function P(e,n){return n<0||n>=e.accounts.length?!1:e.accounts[n].isSigner}function i(e){if(e.source===u.ValueSource.ACCOUNT_PATH&&e.payload.length!==0)return e.payload[0]}function I(e,n){const t=i(e);if(t!==void 0)return a(n,t)}function h(e,n,t){switch(e.source){case u.ValueSource.CONSTANT:return e.payload.length===A?t.encode(e.payload):void 0;case u.ValueSource.ACCOUNT_PATH:return e.payload.length>0?d(n,e.payload[0]):void 0;default:return}}0&&(module.exports={accountAddressAt,accountAltRefAt,accountIsSignerAt,altRefForPubkeyValue,pubkeyValueAccountIndex,resolvePortAccountIndex,resolvePubkeyValue});
2
2
  //# sourceMappingURL=valueResolution.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/clear-sign/requirements/valueResolution.ts"],
4
- "sourcesContent": ["import { type Bs58Encoder } from \"@internal/app-binder/services/bs58Encoder\";\n\nimport { type AltEntryKey, type RequirementInstruction } from \"./model\";\nimport {\n OptionalAccountStrategy,\n type ParsedValue,\n type ParsedValueFlowPort,\n ValueSource,\n} from \"./records\";\n\nconst PUBKEY_LENGTH = 32;\n\n/** The resolved address of an account slot, bounds-checked. */\nexport function accountAddressAt(\n instruction: RequirementInstruction,\n index: number,\n): string | undefined {\n if (index < 0 || index >= instruction.accounts.length) return undefined;\n return instruction.accounts[index]!.address;\n}\n\n/**\n * The ALT reference of an account slot, bounds-checked. Set only for slots the\n * host cannot resolve (ALT-supplied, no `ALT_RESOLUTION` streamed yet), so it is\n * the natural complement of {@link accountAddressAt}: exactly one of the two\n * answers for any slot of a parsed message.\n */\nexport function accountAltRefAt(\n instruction: RequirementInstruction,\n index: number,\n): AltEntryKey | undefined {\n if (index < 0 || index >= instruction.accounts.length) return undefined;\n return instruction.accounts[index]!.altRef;\n}\n\n/**\n * Resolve a value-flow port to a single account index. A single-candidate port\n * returns that candidate. An ordered candidate list (optional accounts with\n * fallbacks) returns the first *provided* candidate: a non-final candidate is\n * *unset* when its slot is out of range, or \u2014 under the `PROGRAM_ID` strategy \u2014\n * when the slot holds the program id. The final candidate is non-optional and\n * always resolves. Returns `-1` for an empty candidate list.\n */\nexport function resolvePortAccountIndex(\n port: ParsedValueFlowPort,\n instruction: RequirementInstruction,\n): number {\n const indices = port.accountIndices;\n if (indices.length === 0) return -1;\n for (const idx of indices.slice(0, -1)) {\n if (idx < 0 || idx >= instruction.accounts.length) continue;\n if (\n port.optionalAccountStrategy !== OptionalAccountStrategy.OMITTED &&\n instruction.accounts[idx]!.address === instruction.programId\n ) {\n continue;\n }\n return idx;\n }\n return indices[indices.length - 1]!;\n}\n\n/**\n * The ALT reference behind a pubkey-bearing VALUE \u2014 the complement of\n * {@link resolvePubkeyValue} for an `ACCOUNT_PATH` into an unresolved slot.\n * A `CONSTANT` is already an address and an `ARGUMENT_PATH` names no slot, so\n * both yield `undefined`.\n */\nexport function altRefForPubkeyValue(\n value: ParsedValue,\n instruction: RequirementInstruction,\n): AltEntryKey | undefined {\n if (value.source !== ValueSource.ACCOUNT_PATH) return undefined;\n if (value.payload.length === 0) return undefined;\n return accountAltRefAt(instruction, value.payload[0]!);\n}\n\n/**\n * Resolve a pubkey-bearing VALUE to a base58 address: a 32-byte CONSTANT, or an\n * ACCOUNT_PATH into the instruction's accounts. ARGUMENT_PATH and unresolved\n * accounts yield `undefined`.\n */\nexport function resolvePubkeyValue(\n value: ParsedValue,\n instruction: RequirementInstruction,\n bs58Encoder: Bs58Encoder,\n): string | undefined {\n switch (value.source) {\n case ValueSource.CONSTANT:\n return value.payload.length === PUBKEY_LENGTH\n ? bs58Encoder.encode(value.payload)\n : undefined;\n case ValueSource.ACCOUNT_PATH:\n return value.payload.length > 0\n ? accountAddressAt(instruction, value.payload[0]!)\n : undefined;\n default:\n return undefined;\n }\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,oBAAAC,EAAA,yBAAAC,EAAA,4BAAAC,EAAA,uBAAAC,IAAA,eAAAC,EAAAP,GAGA,IAAAQ,EAKO,qBAEP,MAAMC,EAAgB,GAGf,SAASP,EACdQ,EACAC,EACoB,CACpB,GAAI,EAAAA,EAAQ,GAAKA,GAASD,EAAY,SAAS,QAC/C,OAAOA,EAAY,SAASC,CAAK,EAAG,OACtC,CAQO,SAASR,EACdO,EACAC,EACyB,CACzB,GAAI,EAAAA,EAAQ,GAAKA,GAASD,EAAY,SAAS,QAC/C,OAAOA,EAAY,SAASC,CAAK,EAAG,MACtC,CAUO,SAASN,EACdO,EACAF,EACQ,CACR,MAAMG,EAAUD,EAAK,eACrB,GAAIC,EAAQ,SAAW,EAAG,MAAO,GACjC,UAAWC,KAAOD,EAAQ,MAAM,EAAG,EAAE,EACnC,GAAI,EAAAC,EAAM,GAAKA,GAAOJ,EAAY,SAAS,SAEzC,EAAAE,EAAK,0BAA4B,0BAAwB,SACzDF,EAAY,SAASI,CAAG,EAAG,UAAYJ,EAAY,WAIrD,OAAOI,EAET,OAAOD,EAAQA,EAAQ,OAAS,CAAC,CACnC,CAQO,SAAST,EACdW,EACAL,EACyB,CACzB,GAAIK,EAAM,SAAW,cAAY,cAC7BA,EAAM,QAAQ,SAAW,EAC7B,OAAOZ,EAAgBO,EAAaK,EAAM,QAAQ,CAAC,CAAE,CACvD,CAOO,SAAST,EACdS,EACAL,EACAM,EACoB,CACpB,OAAQD,EAAM,OAAQ,CACpB,KAAK,cAAY,SACf,OAAOA,EAAM,QAAQ,SAAWN,EAC5BO,EAAY,OAAOD,EAAM,OAAO,EAChC,OACN,KAAK,cAAY,aACf,OAAOA,EAAM,QAAQ,OAAS,EAC1Bb,EAAiBQ,EAAaK,EAAM,QAAQ,CAAC,CAAE,EAC/C,OACN,QACE,MACJ,CACF",
6
- "names": ["valueResolution_exports", "__export", "accountAddressAt", "accountAltRefAt", "altRefForPubkeyValue", "resolvePortAccountIndex", "resolvePubkeyValue", "__toCommonJS", "import_records", "PUBKEY_LENGTH", "instruction", "index", "port", "indices", "idx", "value", "bs58Encoder"]
4
+ "sourcesContent": ["import { type Bs58Encoder } from \"@internal/app-binder/services/bs58Encoder\";\n\nimport { type AltEntryKey, type RequirementInstruction } from \"./model\";\nimport {\n OptionalAccountStrategy,\n type ParsedValue,\n type ParsedValueFlowPort,\n ValueSource,\n} from \"./records\";\n\nconst PUBKEY_LENGTH = 32;\n\n/** The resolved address of an account slot, bounds-checked. */\nexport function accountAddressAt(\n instruction: RequirementInstruction,\n index: number,\n): string | undefined {\n if (index < 0 || index >= instruction.accounts.length) return undefined;\n return instruction.accounts[index]!.address;\n}\n\n/**\n * The ALT reference of an account slot, bounds-checked. Set only for slots the\n * host cannot resolve (ALT-supplied, no `ALT_RESOLUTION` streamed yet), so it is\n * the natural complement of {@link accountAddressAt}: exactly one of the two\n * answers for any slot of a parsed message.\n */\nexport function accountAltRefAt(\n instruction: RequirementInstruction,\n index: number,\n): AltEntryKey | undefined {\n if (index < 0 || index >= instruction.accounts.length) return undefined;\n return instruction.accounts[index]!.altRef;\n}\n\n/**\n * Resolve a value-flow port to a single account index. A single-candidate port\n * returns that candidate. An ordered candidate list (optional accounts with\n * fallbacks) returns the first *provided* candidate: a non-final candidate is\n * *unset* when its slot is out of range, or \u2014 under the `PROGRAM_ID` strategy \u2014\n * when the slot holds the program id. The final candidate is non-optional and\n * always resolves. Returns `-1` for an empty candidate list.\n */\nexport function resolvePortAccountIndex(\n port: ParsedValueFlowPort,\n instruction: RequirementInstruction,\n): number {\n const indices = port.accountIndices;\n if (indices.length === 0) return -1;\n for (const idx of indices.slice(0, -1)) {\n if (idx < 0 || idx >= instruction.accounts.length) continue;\n if (\n port.optionalAccountStrategy !== OptionalAccountStrategy.OMITTED &&\n instruction.accounts[idx]!.address === instruction.programId\n ) {\n continue;\n }\n return idx;\n }\n return indices[indices.length - 1]!;\n}\n\n/**\n * Whether a slot is a required signer in the message header, bounds-checked.\n * Out-of-range answers `false`: a slot that is not there signed nothing.\n */\nexport function accountIsSignerAt(\n instruction: RequirementInstruction,\n index: number,\n): boolean {\n if (index < 0 || index >= instruction.accounts.length) return false;\n return instruction.accounts[index]!.isSigner;\n}\n\n/**\n * The account slot a pubkey-bearing VALUE reads, when it reads one. A\n * `CONSTANT` carries its address inline and an `ARGUMENT_PATH` names no slot,\n * so both yield `undefined` \u2014 the value is an address with no slot behind it\n * to ask anything else about.\n */\nexport function pubkeyValueAccountIndex(\n value: ParsedValue,\n): number | undefined {\n if (value.source !== ValueSource.ACCOUNT_PATH) return undefined;\n if (value.payload.length === 0) return undefined;\n return value.payload[0]!;\n}\n\n/**\n * The ALT reference behind a pubkey-bearing VALUE \u2014 the complement of\n * {@link resolvePubkeyValue} for an `ACCOUNT_PATH` into an unresolved slot.\n * A `CONSTANT` is already an address and an `ARGUMENT_PATH` names no slot, so\n * both yield `undefined`.\n */\nexport function altRefForPubkeyValue(\n value: ParsedValue,\n instruction: RequirementInstruction,\n): AltEntryKey | undefined {\n const index = pubkeyValueAccountIndex(value);\n if (index === undefined) return undefined;\n return accountAltRefAt(instruction, index);\n}\n\n/**\n * Resolve a pubkey-bearing VALUE to a base58 address: a 32-byte CONSTANT, or an\n * ACCOUNT_PATH into the instruction's accounts. ARGUMENT_PATH and unresolved\n * accounts yield `undefined`.\n */\nexport function resolvePubkeyValue(\n value: ParsedValue,\n instruction: RequirementInstruction,\n bs58Encoder: Bs58Encoder,\n): string | undefined {\n switch (value.source) {\n case ValueSource.CONSTANT:\n return value.payload.length === PUBKEY_LENGTH\n ? bs58Encoder.encode(value.payload)\n : undefined;\n case ValueSource.ACCOUNT_PATH:\n return value.payload.length > 0\n ? accountAddressAt(instruction, value.payload[0]!)\n : undefined;\n default:\n return undefined;\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,oBAAAC,EAAA,sBAAAC,EAAA,yBAAAC,EAAA,4BAAAC,EAAA,4BAAAC,EAAA,uBAAAC,IAAA,eAAAC,EAAAT,GAGA,IAAAU,EAKO,qBAEP,MAAMC,EAAgB,GAGf,SAAST,EACdU,EACAC,EACoB,CACpB,GAAI,EAAAA,EAAQ,GAAKA,GAASD,EAAY,SAAS,QAC/C,OAAOA,EAAY,SAASC,CAAK,EAAG,OACtC,CAQO,SAASV,EACdS,EACAC,EACyB,CACzB,GAAI,EAAAA,EAAQ,GAAKA,GAASD,EAAY,SAAS,QAC/C,OAAOA,EAAY,SAASC,CAAK,EAAG,MACtC,CAUO,SAASN,EACdO,EACAF,EACQ,CACR,MAAMG,EAAUD,EAAK,eACrB,GAAIC,EAAQ,SAAW,EAAG,MAAO,GACjC,UAAWC,KAAOD,EAAQ,MAAM,EAAG,EAAE,EACnC,GAAI,EAAAC,EAAM,GAAKA,GAAOJ,EAAY,SAAS,SAEzC,EAAAE,EAAK,0BAA4B,0BAAwB,SACzDF,EAAY,SAASI,CAAG,EAAG,UAAYJ,EAAY,WAIrD,OAAOI,EAET,OAAOD,EAAQA,EAAQ,OAAS,CAAC,CACnC,CAMO,SAASX,EACdQ,EACAC,EACS,CACT,OAAIA,EAAQ,GAAKA,GAASD,EAAY,SAAS,OAAe,GACvDA,EAAY,SAASC,CAAK,EAAG,QACtC,CAQO,SAASP,EACdW,EACoB,CACpB,GAAIA,EAAM,SAAW,cAAY,cAC7BA,EAAM,QAAQ,SAAW,EAC7B,OAAOA,EAAM,QAAQ,CAAC,CACxB,CAQO,SAASZ,EACdY,EACAL,EACyB,CACzB,MAAMC,EAAQP,EAAwBW,CAAK,EAC3C,GAAIJ,IAAU,OACd,OAAOV,EAAgBS,EAAaC,CAAK,CAC3C,CAOO,SAASL,EACdS,EACAL,EACAM,EACoB,CACpB,OAAQD,EAAM,OAAQ,CACpB,KAAK,cAAY,SACf,OAAOA,EAAM,QAAQ,SAAWN,EAC5BO,EAAY,OAAOD,EAAM,OAAO,EAChC,OACN,KAAK,cAAY,aACf,OAAOA,EAAM,QAAQ,OAAS,EAC1Bf,EAAiBU,EAAaK,EAAM,QAAQ,CAAC,CAAE,EAC/C,OACN,QACE,MACJ,CACF",
6
+ "names": ["valueResolution_exports", "__export", "accountAddressAt", "accountAltRefAt", "accountIsSignerAt", "altRefForPubkeyValue", "pubkeyValueAccountIndex", "resolvePortAccountIndex", "resolvePubkeyValue", "__toCommonJS", "import_records", "PUBKEY_LENGTH", "instruction", "index", "port", "indices", "idx", "value", "bs58Encoder"]
7
7
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "dependencies": {
3
- "@ledgerhq/context-module": "workspace:^",
3
+ "@ledgerhq/context-module": "^2.6.0",
4
4
  "@ledgerhq/signer-utils": "^1.3.0",
5
5
  "@solana/transaction-messages": "catalog:",
6
6
  "@solana/web3.js": "catalog:",
@@ -42,7 +42,7 @@
42
42
  "license": "Apache-2.0",
43
43
  "name": "@ledgerhq/device-signer-kit-solana",
44
44
  "peerDependencies": {
45
- "@ledgerhq/device-management-kit": "workspace:^"
45
+ "@ledgerhq/device-management-kit": "^1.9.1"
46
46
  },
47
47
  "private": false,
48
48
  "repository": {
@@ -65,5 +65,5 @@
65
65
  "watch:builds": "pnpm ldmk-tool watch --entryPoints src/index.ts,src/**/*.ts --tsconfig tsconfig.prod.json",
66
66
  "watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
67
67
  },
68
- "version": "1.13.1"
68
+ "version": "1.13.2"
69
69
  }
@@ -1,2 +1,2 @@
1
- import{ActiveWhenPredicate as y,HideCondition as x,PARAM_TYPE_TOKEN_AMOUNT as p,TokenKind as I,ValueKind as v,ValueSource as P}from"../../../../app-binder/clear-sign/requirements/records";import{accountAddressAt as l,accountAltRefAt as A,altRefForPubkeyValue as q,resolvePortAccountIndex as T,resolvePubkeyValue as k}from"../../../../app-binder/clear-sign/requirements/valueResolution";import{DefaultBs58Encoder as E}from"../../../../app-binder/services/bs58Encoder";function V(i,d,u,n,r=E){const c=u.mints;for(const e of i.valueFlowPorts){const t=e.tokenValue;if(t!==void 0){if(t.kind===I.RESOLVE){const o=t.accountIndex??T(e,d),f=l(d,o);if(f!==void 0){const s=c.get(f);s===void 0?n.addTokenAccountState(f):n.addTokenInfo(s)}else a(A(d,o),n);R(t.fallbackAccountIndex,d,n)}else if(t.kind===I.DIRECT&&t.value){const o=k(t.value,d,r);o!==void 0&&n.addTokenInfo(o)}}}for(const e of i.accountResets){if(!e.requirePreBalanceZero&&!e.requireNativePreBalanceZero)continue;const t=l(d,e.accountIndex);t!==void 0?n.addTokenAccountState(t):a(A(d,e.accountIndex),n)}for(const e of i.accountResets){if(e.valueKind!==v.SPL_TOKEN)continue;const t=e.tokenValue;if(t===void 0||t.kind!==I.RESOLVE)continue;const o=t.accountIndex??e.accountIndex,f=l(d,o);if(f!==void 0){const s=c.get(f);s===void 0&&t.fallbackAccountIndex===void 0&&n.addTokenAccountState(f),s!==void 0&&n.addTokenInfo(s)}else a(A(d,o),n);R(t.fallbackAccountIndex,d,n)}S(i,d,u,n,r);for(const e of i.displayFields){if(e.paramType!==p||e.token===void 0)continue;if(e.token.source!==P.ACCOUNT_PATH){const f=k(e.token,d,r);f!==void 0&&n.addTokenInfo(c.get(f)??f);continue}const t=e.token.payload.length>0?e.token.payload[0]:void 0;if(t===void 0)continue;const o=d.accounts[t];if(o!==void 0)if(o.address!==void 0){const f=c.get(o.address);f!==void 0?n.addTokenInfo(f):n.addTokenAmountRef(o.address)}else o.altRef!==void 0&&n.addTokenAmountAltRef(o.altRef.altAddress,o.altRef.entryIndex)}}function R(i,d,u){if(i===void 0)return;const n=d.accounts[i];n!==void 0&&(n.address!==void 0?u.addTokenInfo(n.address):n.altRef!==void 0&&u.addMintAltRef(n.altRef.altAddress,n.altRef.entryIndex))}function S(i,d,u,n,r){const c=e=>{e!==void 0&&(u.owners.has(e)||n.addTokenAccountState(e))};for(const e of i.hideRules){if(e.condition!==x.IS_SIGNER)continue;const t=e.target;if(t===void 0)continue;const o=k(t,d,r);o!==void 0?c(o):a(q(t,d),n)}for(const e of i.valueFlowPorts){if(!e.activeWhen.includes(y.IS_SIGNER))continue;const t=T(e,d),o=l(d,t);o!==void 0?c(o):a(A(d,t),n)}}function a(i,d){i!==void 0&&d.addTokenAccountStateAltRef(i.altAddress,i.entryIndex)}export{V as applyTokenRule};
1
+ import{ActiveWhenPredicate as y,HideCondition as p,PARAM_TYPE_TOKEN_AMOUNT as x,TokenKind as I,ValueKind as v,ValueSource as P}from"../../../../app-binder/clear-sign/requirements/records";import{accountAddressAt as l,accountAltRefAt as A,accountIsSignerAt as S,altRefForPubkeyValue as m,pubkeyValueAccountIndex as q,resolvePortAccountIndex as T,resolvePubkeyValue as k}from"../../../../app-binder/clear-sign/requirements/valueResolution";import{DefaultBs58Encoder as E}from"../../../../app-binder/services/bs58Encoder";function K(i,t,u,d,r=E){const c=u.mints;for(const n of i.valueFlowPorts){const e=n.tokenValue;if(e!==void 0){if(e.kind===I.RESOLVE){const o=e.accountIndex??T(n,t),f=l(t,o);if(f!==void 0){const s=c.get(f);s===void 0?d.addTokenAccountState(f):d.addTokenInfo(s)}else a(A(t,o),d);R(e.fallbackAccountIndex,t,d)}else if(e.kind===I.DIRECT&&e.value){const o=k(e.value,t,r);o!==void 0&&d.addTokenInfo(o)}}}for(const n of i.accountResets){if(!n.requirePreBalanceZero&&!n.requireNativePreBalanceZero)continue;const e=l(t,n.accountIndex);e!==void 0?d.addTokenAccountState(e):a(A(t,n.accountIndex),d)}for(const n of i.accountResets){if(n.valueKind!==v.SPL_TOKEN)continue;const e=n.tokenValue;if(e===void 0||e.kind!==I.RESOLVE)continue;const o=e.accountIndex??n.accountIndex,f=l(t,o);if(f!==void 0){const s=c.get(f);s===void 0&&e.fallbackAccountIndex===void 0&&d.addTokenAccountState(f),s!==void 0&&d.addTokenInfo(s)}else a(A(t,o),d);R(e.fallbackAccountIndex,t,d)}g(i,t,u,d,r);for(const n of i.displayFields){if(n.paramType!==x||n.token===void 0)continue;if(n.token.source!==P.ACCOUNT_PATH){const f=k(n.token,t,r);f!==void 0&&d.addTokenInfo(c.get(f)??f);continue}const e=n.token.payload.length>0?n.token.payload[0]:void 0;if(e===void 0)continue;const o=t.accounts[e];if(o!==void 0)if(o.address!==void 0){const f=c.get(o.address);f!==void 0?d.addTokenInfo(f):d.addTokenAmountRef(o.address)}else o.altRef!==void 0&&d.addTokenAmountAltRef(o.altRef.altAddress,o.altRef.entryIndex)}}function R(i,t,u){if(i===void 0)return;const d=t.accounts[i];d!==void 0&&(d.address!==void 0?u.addTokenInfo(d.address):d.altRef!==void 0&&u.addMintAltRef(d.altRef.altAddress,d.altRef.entryIndex))}function g(i,t,u,d,r){const c=(n,e)=>{n!==void 0&&(u.owners.has(n)||e!==void 0&&S(t,e)||d.addTokenAccountState(n))};for(const n of i.hideRules){if(n.condition!==p.IS_SIGNER)continue;const e=n.target;if(e===void 0)continue;const o=k(e,t,r);o!==void 0?c(o,q(e)):a(m(e,t),d)}for(const n of i.valueFlowPorts){if(!n.activeWhen.includes(y.IS_SIGNER))continue;const e=T(n,t),o=l(t,e);o!==void 0?c(o,e):a(A(t,e),d)}}function a(i,t){i!==void 0&&t.addTokenAccountStateAltRef(i.altAddress,i.entryIndex)}export{K as applyTokenRule};
2
2
  //# sourceMappingURL=tokenRule.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/internal/app-binder/clear-sign/requirements/rules/tokenRule.ts"],
4
- "sourcesContent": ["import {\n type AltEntryKey,\n type RequirementInstruction,\n type TxBindings,\n} from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n PARAM_TYPE_TOKEN_AMOUNT,\n type ParsedInstruction,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { type RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport {\n accountAddressAt,\n accountAltRefAt,\n altRefForPubkeyValue,\n resolvePortAccountIndex,\n resolvePubkeyValue,\n} from \"@internal/app-binder/clear-sign/requirements/valueResolution\";\nimport {\n type Bs58Encoder,\n DefaultBs58Encoder,\n} from \"@internal/app-binder/services/bs58Encoder\";\n\n/**\n * TOKEN_INFO + TOKEN_ACCOUNT_STATE requirements:\n * - RESOLVE port: TOKEN_ACCOUNT_STATE for its token account unless a TX-derived\n * MINT_ASSOC binding already covers it; the bound mint (when any) needs\n * TOKEN_INFO. An ALT-backed token account can carry no such binding (a\n * binding needs both halves resolved host-side), so it goes to\n * `tokenAccountStateAltRefs` and is fetched once its address is known.\n * A candidate-array port resolves to its first *provided*\n * candidate. A `FALLBACK_ACCOUNT` is the mint of last resort, so its address\n * needs TOKEN_INFO too \u2014 every `fallbackAccount` in the registry names a mint\n * slot, and it is the only ticker source when both binding sources miss.\n * - DIRECT port: the embedded mint needs TOKEN_INFO.\n * - ACCOUNT_RESET path 2: mandatory TOKEN_ACCOUNT_STATE when `requirePreBalanceZero`\n * or `requireNativePreBalanceZero` is set (the device must read the pre-balance\n * to validate the reset is applicable).\n * - ACCOUNT_RESET path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose `TOKEN_VALUE`\n * is `RESOLVE`, unless the mint is already bound by a TX-derived `MINT_ASSOC`\n * pair or by a `FALLBACK_ACCOUNT`. Without the mint the reset resolves to no\n * domain and establishes nothing.\n * - IS_SIGNER hide rule / port activation predicate: TOKEN_ACCOUNT_STATE for the\n * target unless a TX-derived OWNER_ASSOC binding already covers it. The\n * device's `IS_SIGNER` predicate matches a token account only through the\n * owner map, which it seeds from OWNER_ASSOC pairs first and from attested\n * `TOKEN_ACCOUNT_STATE.OWNER` second. An ALT-backed target goes to\n * `tokenAccountStateAltRefs`, the post-ALT_RESOLUTION equivalent.\n * - PARAM_TOKEN_AMOUNT display field: the amount formatter's token needs\n * TOKEN_INFO. For CONSTANT source: always a mint. For ACCOUNT_PATH source:\n * if covered by a TX-derived MINT_ASSOC binding, use the bound mint. If not,\n * add as a `tokenAmountRef` (non-ALT) or `tokenAmountAltRef` (ALT-backed)\n * so the fetch stage can try TOKEN_INFO first then fall back to\n * TOKEN_ACCOUNT_STATE + TOKEN_INFO for the attested mint.\n */\nexport function applyTokenRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder = DefaultBs58Encoder,\n): void {\n const mintBindings = bindings.mints;\n\n for (const port of parsed.valueFlowPorts) {\n const tokenValue = port.tokenValue;\n if (tokenValue === undefined) continue;\n\n if (tokenValue.kind === TokenKind.RESOLVE) {\n const accountIndex =\n tokenValue.accountIndex ?? resolvePortAccountIndex(port, instruction);\n const account = accountAddressAt(instruction, accountIndex);\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (boundMint === undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n // ALT-backed: no MINT_ASSOC binding can cover it, so the mint has to\n // come from the attested state fetched once the entry resolves.\n requestAltState(\n accountAltRefAt(instruction, accountIndex),\n accumulator,\n );\n }\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n } else if (tokenValue.kind === TokenKind.DIRECT && tokenValue.value) {\n const mint = resolvePubkeyValue(\n tokenValue.value,\n instruction,\n bs58Encoder,\n );\n if (mint !== undefined) accumulator.addTokenInfo(mint);\n }\n }\n\n for (const reset of parsed.accountResets) {\n if (!reset.requirePreBalanceZero && !reset.requireNativePreBalanceZero)\n continue;\n const account = accountAddressAt(instruction, reset.accountIndex);\n if (account !== undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n requestAltState(\n accountAltRefAt(instruction, reset.accountIndex),\n accumulator,\n );\n }\n }\n\n // Path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose TOKEN_VALUE is RESOLVE,\n // unless the mint is already bound by a TX-derived MINT_ASSOC pair or by a\n // FALLBACK_ACCOUNT. Without the mint the reset resolves to no domain.\n for (const reset of parsed.accountResets) {\n if (reset.valueKind !== ValueKind.SPL_TOKEN) continue;\n const tokenValue = reset.tokenValue;\n if (tokenValue === undefined || tokenValue.kind !== TokenKind.RESOLVE)\n continue;\n\n const accountIndex = tokenValue.accountIndex ?? reset.accountIndex;\n const account = accountAddressAt(instruction, accountIndex);\n\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (\n boundMint === undefined &&\n tokenValue.fallbackAccountIndex === undefined\n ) {\n accumulator.addTokenAccountState(account);\n }\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n }\n\n applyOwnerAttestationRule(\n parsed,\n instruction,\n bindings,\n accumulator,\n bs58Encoder,\n );\n\n for (const field of parsed.displayFields) {\n if (\n field.paramType !== PARAM_TYPE_TOKEN_AMOUNT ||\n field.token === undefined\n )\n continue;\n\n if (field.token.source !== ValueSource.ACCOUNT_PATH) {\n // CONSTANT: hardcoded in CAL, always a mint\n const ref = resolvePubkeyValue(field.token, instruction, bs58Encoder);\n if (ref !== undefined) {\n accumulator.addTokenInfo(mintBindings.get(ref) ?? ref);\n }\n continue;\n }\n\n // ACCOUNT_PATH: may be a mint, an ATA, or behind an ALT\n const accountIndex =\n field.token.payload.length > 0 ? field.token.payload[0]! : undefined;\n if (accountIndex === undefined) continue;\n const account = instruction.accounts[accountIndex];\n if (account === undefined) continue;\n\n if (account.address !== undefined) {\n const boundMint = mintBindings.get(account.address);\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n } else {\n accumulator.addTokenAmountRef(account.address);\n }\n } else if (account.altRef !== undefined) {\n // ALT-backed: resolve after ALT_RESOLUTION is fetched\n accumulator.addTokenAmountAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n }\n}\n\n/**\n * `TOKEN_VALUE.FALLBACK_ACCOUNT`: the device uses the referenced account's\n * *address* as the mint, with no further resolution. Every `fallbackAccount` an\n * overlay declares names a mint slot (`sourceMint`, `poolMint`, \u2026), so this is\n * a real mint whose TOKEN_INFO renders the ticker whenever the port does fall\n * through \u2014 the common case for a swap into an ATA that does not exist yet.\n * Requesting it when the binding map *does* resolve the port costs nothing: all\n * mints are fetched in one batched CAL call.\n *\n * An ALT-backed fallback goes to `mintAltRefs`, the bucket that streams the\n * `ALT_RESOLUTION` finalize requires and then resolves TOKEN_INFO for the\n * resolved address.\n */\nfunction requestFallbackMint(\n fallbackAccountIndex: number | undefined,\n instruction: RequirementInstruction,\n accumulator: RequirementAccumulator,\n): void {\n if (fallbackAccountIndex === undefined) return;\n const account = instruction.accounts[fallbackAccountIndex];\n if (account === undefined) return;\n if (account.address !== undefined) {\n accumulator.addTokenInfo(account.address);\n } else if (account.altRef !== undefined) {\n accumulator.addMintAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n}\n\n/**\n * `TOKEN_ACCOUNT_STATE` trigger path 3: an `IS_SIGNER` predicate \u2014 on a\n * `HIDE_RULE` target or on a port's `ACTIVE_WHEN` \u2014 matches a token account only\n * if the device can bind it to an owner. A TX-derived `OWNER_ASSOC` pair covers\n * that binding; otherwise the only source is the attested\n * `TOKEN_ACCOUNT_STATE.OWNER`, so request one.\n *\n * An ALT-backed target has no host-side address, so neither the binding lookup\n * nor a build-time fetch is possible: it goes to `tokenAccountStateAltRefs` and\n * the provide phase fetches the state once `ALT_RESOLUTION` names the address.\n * Skipping it would leave the owner map unseeded and the predicate false. And\n * ALT-supplied slots are never message signers, so a target reached through one\n * can only ever satisfy `IS_SIGNER` *through* the owner map \u2014 making the\n * attestation the sole path to a true answer rather than a second opinion.\n *\n * `IS_SIGNER` is the only predicate worth a descriptor. The structural ones\n * (`CREATED_IN_TRANSACTION`, `ACCOUNT_USED_ELSEWHERE`,\n * `ACCOUNT_EFFECTS_DISPLAYED_ELSEWHERE`) never read the owner map.\n * `IS_ANOTHER_SIGNER` does read it, but only to short-circuit to `false`:\n * without the binding it falls through to a header signer check, which a\n * program-owned token account can never pass, so the answer is `false` either\n * way and the descriptor changes nothing.\n *\n * The host cannot tell a token account from a plain wallet key, so a predicate\n * targeting the signer's own key costs one fetch that finds nothing. That is the\n * cheap side of the trade: without the descriptor the predicate silently\n * evaluates false and the device shows plumbing screens that should be hidden.\n */\nfunction applyOwnerAttestationRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder,\n): void {\n const request = (address: string | undefined): void => {\n if (address === undefined) return;\n if (bindings.owners.has(address)) return;\n accumulator.addTokenAccountState(address);\n };\n\n for (const rule of parsed.hideRules) {\n if (rule.condition !== HideCondition.IS_SIGNER) continue;\n const target = rule.target;\n if (target === undefined) continue;\n const address = resolvePubkeyValue(target, instruction, bs58Encoder);\n if (address !== undefined) {\n request(address);\n } else {\n requestAltState(altRefForPubkeyValue(target, instruction), accumulator);\n }\n }\n\n for (const port of parsed.valueFlowPorts) {\n if (!port.activeWhen.includes(ActiveWhenPredicate.IS_SIGNER)) continue;\n const accountIndex = resolvePortAccountIndex(port, instruction);\n const address = accountAddressAt(instruction, accountIndex);\n if (address !== undefined) {\n request(address);\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n }\n}\n\n/**\n * Queue the `TOKEN_ACCOUNT_STATE` an ALT-backed account needs. No binding map is\n * consulted: a binding requires both halves resolved host-side, which an\n * ALT-supplied slot never is.\n */\nfunction requestAltState(\n altRef: AltEntryKey | undefined,\n accumulator: RequirementAccumulator,\n): void {\n if (altRef === undefined) return;\n accumulator.addTokenAccountStateAltRef(altRef.altAddress, altRef.entryIndex);\n}\n"],
5
- "mappings": "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",
6
- "names": ["ActiveWhenPredicate", "HideCondition", "PARAM_TYPE_TOKEN_AMOUNT", "TokenKind", "ValueKind", "ValueSource", "accountAddressAt", "accountAltRefAt", "altRefForPubkeyValue", "resolvePortAccountIndex", "resolvePubkeyValue", "DefaultBs58Encoder", "applyTokenRule", "parsed", "instruction", "bindings", "accumulator", "bs58Encoder", "mintBindings", "port", "tokenValue", "accountIndex", "account", "boundMint", "requestAltState", "requestFallbackMint", "mint", "reset", "applyOwnerAttestationRule", "field", "ref", "fallbackAccountIndex", "request", "address", "rule", "target", "altRef"]
4
+ "sourcesContent": ["import {\n type AltEntryKey,\n type RequirementInstruction,\n type TxBindings,\n} from \"@internal/app-binder/clear-sign/requirements/model\";\nimport {\n ActiveWhenPredicate,\n HideCondition,\n PARAM_TYPE_TOKEN_AMOUNT,\n type ParsedInstruction,\n TokenKind,\n ValueKind,\n ValueSource,\n} from \"@internal/app-binder/clear-sign/requirements/records\";\nimport { type RequirementAccumulator } from \"@internal/app-binder/clear-sign/requirements/RequirementAccumulator\";\nimport {\n accountAddressAt,\n accountAltRefAt,\n accountIsSignerAt,\n altRefForPubkeyValue,\n pubkeyValueAccountIndex,\n resolvePortAccountIndex,\n resolvePubkeyValue,\n} from \"@internal/app-binder/clear-sign/requirements/valueResolution\";\nimport {\n type Bs58Encoder,\n DefaultBs58Encoder,\n} from \"@internal/app-binder/services/bs58Encoder\";\n\n/**\n * TOKEN_INFO + TOKEN_ACCOUNT_STATE requirements:\n * - RESOLVE port: TOKEN_ACCOUNT_STATE for its token account unless a TX-derived\n * MINT_ASSOC binding already covers it; the bound mint (when any) needs\n * TOKEN_INFO. An ALT-backed token account can carry no such binding (a\n * binding needs both halves resolved host-side), so it goes to\n * `tokenAccountStateAltRefs` and is fetched once its address is known.\n * A candidate-array port resolves to its first *provided*\n * candidate. A `FALLBACK_ACCOUNT` is the mint of last resort, so its address\n * needs TOKEN_INFO too \u2014 every `fallbackAccount` in the registry names a mint\n * slot, and it is the only ticker source when both binding sources miss.\n * - DIRECT port: the embedded mint needs TOKEN_INFO.\n * - ACCOUNT_RESET path 2: mandatory TOKEN_ACCOUNT_STATE when `requirePreBalanceZero`\n * or `requireNativePreBalanceZero` is set (the device must read the pre-balance\n * to validate the reset is applicable).\n * - ACCOUNT_RESET path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose `TOKEN_VALUE`\n * is `RESOLVE`, unless the mint is already bound by a TX-derived `MINT_ASSOC`\n * pair or by a `FALLBACK_ACCOUNT`. Without the mint the reset resolves to no\n * domain and establishes nothing.\n * - IS_SIGNER hide rule / port activation predicate: TOKEN_ACCOUNT_STATE for the\n * target unless a TX-derived OWNER_ASSOC binding already covers it, or the\n * header already marks the slot a signer. The device's `IS_SIGNER` predicate\n * reaches a token account only through the owner map, which it seeds from\n * OWNER_ASSOC pairs first and from attested `TOKEN_ACCOUNT_STATE.OWNER`\n * second. An ALT-backed target goes to `tokenAccountStateAltRefs`, the\n * post-ALT_RESOLUTION equivalent.\n * - PARAM_TOKEN_AMOUNT display field: the amount formatter's token needs\n * TOKEN_INFO. For CONSTANT source: always a mint. For ACCOUNT_PATH source:\n * if covered by a TX-derived MINT_ASSOC binding, use the bound mint. If not,\n * add as a `tokenAmountRef` (non-ALT) or `tokenAmountAltRef` (ALT-backed)\n * so the fetch stage can try TOKEN_INFO first then fall back to\n * TOKEN_ACCOUNT_STATE + TOKEN_INFO for the attested mint.\n */\nexport function applyTokenRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder = DefaultBs58Encoder,\n): void {\n const mintBindings = bindings.mints;\n\n for (const port of parsed.valueFlowPorts) {\n const tokenValue = port.tokenValue;\n if (tokenValue === undefined) continue;\n\n if (tokenValue.kind === TokenKind.RESOLVE) {\n const accountIndex =\n tokenValue.accountIndex ?? resolvePortAccountIndex(port, instruction);\n const account = accountAddressAt(instruction, accountIndex);\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (boundMint === undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n // ALT-backed: no MINT_ASSOC binding can cover it, so the mint has to\n // come from the attested state fetched once the entry resolves.\n requestAltState(\n accountAltRefAt(instruction, accountIndex),\n accumulator,\n );\n }\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n } else if (tokenValue.kind === TokenKind.DIRECT && tokenValue.value) {\n const mint = resolvePubkeyValue(\n tokenValue.value,\n instruction,\n bs58Encoder,\n );\n if (mint !== undefined) accumulator.addTokenInfo(mint);\n }\n }\n\n for (const reset of parsed.accountResets) {\n if (!reset.requirePreBalanceZero && !reset.requireNativePreBalanceZero)\n continue;\n const account = accountAddressAt(instruction, reset.accountIndex);\n if (account !== undefined) {\n accumulator.addTokenAccountState(account);\n } else {\n requestAltState(\n accountAltRefAt(instruction, reset.accountIndex),\n accumulator,\n );\n }\n }\n\n // Path 5: TOKEN_ACCOUNT_STATE for an SPL reset whose TOKEN_VALUE is RESOLVE,\n // unless the mint is already bound by a TX-derived MINT_ASSOC pair or by a\n // FALLBACK_ACCOUNT. Without the mint the reset resolves to no domain.\n for (const reset of parsed.accountResets) {\n if (reset.valueKind !== ValueKind.SPL_TOKEN) continue;\n const tokenValue = reset.tokenValue;\n if (tokenValue === undefined || tokenValue.kind !== TokenKind.RESOLVE)\n continue;\n\n const accountIndex = tokenValue.accountIndex ?? reset.accountIndex;\n const account = accountAddressAt(instruction, accountIndex);\n\n if (account !== undefined) {\n const boundMint = mintBindings.get(account);\n if (\n boundMint === undefined &&\n tokenValue.fallbackAccountIndex === undefined\n ) {\n accumulator.addTokenAccountState(account);\n }\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n }\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n\n requestFallbackMint(\n tokenValue.fallbackAccountIndex,\n instruction,\n accumulator,\n );\n }\n\n applyOwnerAttestationRule(\n parsed,\n instruction,\n bindings,\n accumulator,\n bs58Encoder,\n );\n\n for (const field of parsed.displayFields) {\n if (\n field.paramType !== PARAM_TYPE_TOKEN_AMOUNT ||\n field.token === undefined\n )\n continue;\n\n if (field.token.source !== ValueSource.ACCOUNT_PATH) {\n // CONSTANT: hardcoded in CAL, always a mint\n const ref = resolvePubkeyValue(field.token, instruction, bs58Encoder);\n if (ref !== undefined) {\n accumulator.addTokenInfo(mintBindings.get(ref) ?? ref);\n }\n continue;\n }\n\n // ACCOUNT_PATH: may be a mint, an ATA, or behind an ALT\n const accountIndex =\n field.token.payload.length > 0 ? field.token.payload[0]! : undefined;\n if (accountIndex === undefined) continue;\n const account = instruction.accounts[accountIndex];\n if (account === undefined) continue;\n\n if (account.address !== undefined) {\n const boundMint = mintBindings.get(account.address);\n if (boundMint !== undefined) {\n accumulator.addTokenInfo(boundMint);\n } else {\n accumulator.addTokenAmountRef(account.address);\n }\n } else if (account.altRef !== undefined) {\n // ALT-backed: resolve after ALT_RESOLUTION is fetched\n accumulator.addTokenAmountAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n }\n}\n\n/**\n * `TOKEN_VALUE.FALLBACK_ACCOUNT`: the device uses the referenced account's\n * *address* as the mint, with no further resolution. Every `fallbackAccount` an\n * overlay declares names a mint slot (`sourceMint`, `poolMint`, \u2026), so this is\n * a real mint whose TOKEN_INFO renders the ticker whenever the port does fall\n * through \u2014 the common case for a swap into an ATA that does not exist yet.\n * Requesting it when the binding map *does* resolve the port costs nothing: all\n * mints are fetched in one batched CAL call.\n *\n * An ALT-backed fallback goes to `mintAltRefs`, the bucket that streams the\n * `ALT_RESOLUTION` finalize requires and then resolves TOKEN_INFO for the\n * resolved address.\n */\nfunction requestFallbackMint(\n fallbackAccountIndex: number | undefined,\n instruction: RequirementInstruction,\n accumulator: RequirementAccumulator,\n): void {\n if (fallbackAccountIndex === undefined) return;\n const account = instruction.accounts[fallbackAccountIndex];\n if (account === undefined) return;\n if (account.address !== undefined) {\n accumulator.addTokenInfo(account.address);\n } else if (account.altRef !== undefined) {\n accumulator.addMintAltRef(\n account.altRef.altAddress,\n account.altRef.entryIndex,\n );\n }\n}\n\n/**\n * `TOKEN_ACCOUNT_STATE` trigger path 3: an `IS_SIGNER` predicate \u2014 on a\n * `HIDE_RULE` target or on a port's `ACTIVE_WHEN`.\n *\n * The device answers `IS_SIGNER` by deriving the address from its own seed and\n * comparing, which needs no help for a plain key. A token account defeats that:\n * its address is a program derivation the seed never produces, so the device\n * first dereferences the account to its owner \u2014 from a TX-derived `OWNER_ASSOC`\n * pair, else from an attested `TOKEN_ACCOUNT_STATE.OWNER` \u2014 and derives against\n * that instead. The descriptor is therefore worth fetching only where the target\n * may be a token account; anywhere else there is nothing to dereference and the\n * fetch buys no answer the device could not already reach.\n *\n * A slot the message header marks as a signer is one case the host can settle\n * for free: it produced an ed25519 signature, so it is a plain key and never a\n * program-owned token account. Requesting state for it asks the backend to\n * attest an address that is not a token account \u2014 and a descriptor that comes\n * back anyway seeds the device's owner map with a binding that has no business\n * being there, turning a wasted round trip into a wrong answer.\n *\n * An ALT-backed target has no host-side address, so neither the binding lookup\n * nor the signer check nor a build-time fetch is possible: it goes to\n * `tokenAccountStateAltRefs` and the provide phase fetches the state once\n * `ALT_RESOLUTION` names the address. Skipping it would leave a token account's\n * owner map unseeded and the predicate false. ALT-supplied slots are never\n * message signers, so the check below cannot pre-empt that fetch the way it does\n * for a static slot: a plain key reached through an ALT still costs one fetch\n * that finds nothing.\n *\n * `IS_SIGNER` is the only predicate worth a descriptor. The structural ones\n * (`CREATED_IN_TRANSACTION`, `ACCOUNT_USED_ELSEWHERE`,\n * `ACCOUNT_EFFECTS_DISPLAYED_ELSEWHERE`) never read the owner map.\n * `IS_ANOTHER_SIGNER` does read it, but only to short-circuit to `false`:\n * without the binding it falls through to a header signer check, which a\n * program-owned token account can never pass, so the answer is `false` either\n * way and the descriptor changes nothing.\n */\nfunction applyOwnerAttestationRule(\n parsed: ParsedInstruction,\n instruction: RequirementInstruction,\n bindings: TxBindings,\n accumulator: RequirementAccumulator,\n bs58Encoder: Bs58Encoder,\n): void {\n // `accountIndex` is the slot the target was reached through, when it was\n // reached through one \u2014 a `CONSTANT` target carries its address inline and\n // names no slot, so it cannot be signer-checked.\n const request = (\n address: string | undefined,\n accountIndex: number | undefined,\n ): void => {\n if (address === undefined) return;\n if (bindings.owners.has(address)) return;\n if (\n accountIndex !== undefined &&\n accountIsSignerAt(instruction, accountIndex)\n )\n return;\n accumulator.addTokenAccountState(address);\n };\n\n for (const rule of parsed.hideRules) {\n if (rule.condition !== HideCondition.IS_SIGNER) continue;\n const target = rule.target;\n if (target === undefined) continue;\n const address = resolvePubkeyValue(target, instruction, bs58Encoder);\n if (address !== undefined) {\n request(address, pubkeyValueAccountIndex(target));\n } else {\n requestAltState(altRefForPubkeyValue(target, instruction), accumulator);\n }\n }\n\n for (const port of parsed.valueFlowPorts) {\n if (!port.activeWhen.includes(ActiveWhenPredicate.IS_SIGNER)) continue;\n const accountIndex = resolvePortAccountIndex(port, instruction);\n const address = accountAddressAt(instruction, accountIndex);\n if (address !== undefined) {\n request(address, accountIndex);\n } else {\n requestAltState(accountAltRefAt(instruction, accountIndex), accumulator);\n }\n }\n}\n\n/**\n * Queue the `TOKEN_ACCOUNT_STATE` an ALT-backed account needs. No binding map is\n * consulted: a binding requires both halves resolved host-side, which an\n * ALT-supplied slot never is.\n */\nfunction requestAltState(\n altRef: AltEntryKey | undefined,\n accumulator: RequirementAccumulator,\n): void {\n if (altRef === undefined) return;\n accumulator.addTokenAccountStateAltRef(altRef.altAddress, altRef.entryIndex);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["ActiveWhenPredicate", "HideCondition", "PARAM_TYPE_TOKEN_AMOUNT", "TokenKind", "ValueKind", "ValueSource", "accountAddressAt", "accountAltRefAt", "accountIsSignerAt", "altRefForPubkeyValue", "pubkeyValueAccountIndex", "resolvePortAccountIndex", "resolvePubkeyValue", "DefaultBs58Encoder", "applyTokenRule", "parsed", "instruction", "bindings", "accumulator", "bs58Encoder", "mintBindings", "port", "tokenValue", "accountIndex", "account", "boundMint", "requestAltState", "requestFallbackMint", "mint", "reset", "applyOwnerAttestationRule", "field", "ref", "fallbackAccountIndex", "request", "address", "rule", "target", "altRef"]
7
7
  }