{"version":3,"file":"app-spec.mjs","sources":["../../src/types/app-spec.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { Arc56Contract, Method as Arc56Method, StorageKey, StructField } from './app-arc56'\nimport ABIContractParams = algosdk.ABIContractParams\nimport ABIMethodParams = algosdk.ABIMethodParams\nimport ABIMethod = algosdk.ABIMethod\n\n/**\n * Converts an ARC-32 Application Specification to an ARC-56 Contract\n * @param appSpec The ARC-32 Application Specification\n * @returns The ARC-56 Contract\n * @example\n * ```typescript\n * const arc56AppSpec = arc32ToArc56(arc32AppSpec)\n * ```\n */\nexport function arc32ToArc56(appSpec: AppSpec): Arc56Contract {\n  const arc32Structs = Object.values(appSpec.hints).flatMap((hint) => Object.entries(hint.structs ?? {}))\n  const structs = Object.fromEntries(\n    arc32Structs.map(([_, struct]) => {\n      const fields = struct.elements.map((e) => ({ name: e[0], type: e[1] }))\n      return [struct.name, fields]\n    }),\n  ) satisfies { [structName: string]: StructField[] }\n  const hint = (m: ABIMethodParams) => appSpec.hints[new ABIMethod(m).getSignature()] as Hint | undefined\n  const actions = (m: ABIMethodParams, type: 'CREATE' | 'CALL') => {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n    return hint(m)?.call_config !== undefined ? callConfigToActions(hint(m)?.call_config!, type) : []\n  }\n  const bareActions = (type: 'CREATE' | 'CALL') => {\n    return callConfigToActions(appSpec.bare_call_config, type)\n  }\n  const callConfigToActions = (c: CallConfig, type: 'CREATE' | 'CALL') => {\n    const actions: ('NoOp' | 'OptIn' | 'CloseOut' | 'ClearState' | 'UpdateApplication' | 'DeleteApplication')[] = []\n    if (c.close_out && ['ALL', type].includes(c.close_out)) actions.push('CloseOut')\n    if (c.delete_application && ['ALL', type].includes(c.delete_application)) actions.push('DeleteApplication')\n    if (c.no_op && ['ALL', type].includes(c.no_op)) actions.push('NoOp')\n    if (c.opt_in && ['ALL', type].includes(c.opt_in)) actions.push('OptIn')\n    if (c.update_application && ['ALL', type].includes(c.update_application)) actions.push('UpdateApplication')\n    return actions\n  }\n  const getDefaultArgValue = (\n    type: string,\n    defaultArg: DefaultArgument | undefined,\n  ): Arc56Contract['methods'][0]['args'][0]['defaultValue'] => {\n    if (!defaultArg) return undefined\n\n    if (defaultArg.source === 'abi-method') {\n      return {\n        source: 'method',\n        data: defaultArg.data.name,\n      }\n    }\n\n    return {\n      source: defaultArg.source === 'constant' ? 'literal' : defaultArg.source === 'global-state' ? 'global' : 'local',\n      data: Buffer.from(\n        typeof defaultArg.data === 'number' ? algosdk.ABIType.from('uint64').encode(defaultArg.data) : defaultArg.data,\n      ).toString('base64'),\n      type: type === 'string' ? 'AVMString' : type,\n    }\n  }\n\n  return {\n    arcs: [],\n    name: appSpec.contract.name,\n    desc: appSpec.contract.desc,\n    structs: structs,\n    methods: appSpec.contract.methods.map(\n      (m) =>\n        ({\n          name: m.name,\n          desc: m.desc,\n          args: m.args.map((a) => ({\n            name: a.name,\n            type: a.type,\n            desc: a.desc,\n            struct: a.name ? hint(m)?.structs?.[a.name]?.name : undefined,\n            defaultValue: getDefaultArgValue(a.type, !a.name ? undefined : hint(m)?.default_arguments?.[a.name]),\n          })),\n          returns: {\n            type: m.returns.type,\n            desc: m.returns.desc,\n            struct: hint(m)?.structs?.output?.name,\n          },\n          events: [],\n          readonly: hint(m)?.read_only,\n          actions: {\n            create: actions(m, 'CREATE') as Arc56Method['actions']['create'],\n            call: actions(m, 'CALL'),\n          },\n        }) satisfies Arc56Method,\n    ),\n    state: {\n      schema: {\n        global: {\n          ints: appSpec.state.global.num_uints,\n          bytes: appSpec.state.global.num_byte_slices,\n        },\n        local: {\n          ints: appSpec.state.local.num_uints,\n          bytes: appSpec.state.local.num_byte_slices,\n        },\n      },\n      keys: {\n        global: Object.fromEntries(\n          Object.entries(appSpec.schema.global.declared).map((s) => [\n            s[0],\n            {\n              key: Buffer.from(s[1].key, 'utf-8').toString('base64'),\n              keyType: 'AVMString',\n              valueType: s[1].type === 'uint64' ? 'AVMUint64' : 'AVMBytes',\n              desc: s[1].descr,\n            } satisfies StorageKey,\n          ]),\n        ),\n        local: Object.fromEntries(\n          Object.entries(appSpec.schema.local.declared).map((s) => [\n            s[0],\n            {\n              key: Buffer.from(s[1].key, 'utf-8').toString('base64'),\n              keyType: 'AVMString',\n              valueType: s[1].type === 'uint64' ? 'AVMUint64' : 'AVMBytes',\n              desc: s[1].descr,\n            } satisfies StorageKey,\n          ]),\n        ),\n        box: {},\n      },\n      maps: {\n        global: {},\n        local: {},\n        box: {},\n      },\n    },\n    source: appSpec.source,\n    bareActions: {\n      create: bareActions('CREATE') as unknown as Arc56Contract['bareActions']['create'],\n      call: bareActions('CALL'),\n    },\n    byteCode: undefined,\n    compilerInfo: undefined,\n    events: undefined,\n    networks: undefined,\n    scratchVariables: undefined,\n    sourceInfo: undefined,\n    templateVariables: undefined,\n  } satisfies Arc56Contract\n}\n\n/** An ARC-0032 Application Specification see https://github.com/algorandfoundation/ARCs/pull/150 */\nexport interface AppSpec {\n  /** Method call hints */\n  hints: HintSpec\n  /** The TEAL source */\n  source: AppSources\n  /** The ABI-0004 contract definition see https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0004.md */\n  contract: ABIContractParams\n  /** The values that make up the local and global state */\n  schema: SchemaSpec\n  /** The rolled-up schema allocation values for local and global state */\n  state: StateSchemaSpec\n  /** The config of all BARE calls (i.e. non ABI calls with no args) */\n  bare_call_config: CallConfig\n}\n\n/** A lookup of encoded method call spec to hint */\nexport type HintSpec = Record<string, Hint>\n\n/** The TEAL source of a contract */\nexport interface AppSources {\n  /** The TEAL source of the approval program */\n  approval: string\n  /** The TEAL source of the clear program */\n  clear: string\n}\n\n/** The various call configs:\n *  * `NEVER`: Will not be called\n *  * `CALL`: Can be called during a non-create call i.e. app id != 0\n *  * `CREATE`: Can be called during a create call i.e. app id = 0\n *  * `ALL`: Can be during a create OR non-create call\n **/\nexport type CallConfigValue = 'NEVER' | 'CALL' | 'CREATE' | 'ALL'\n\n/** Call configuration for a method */\nexport interface CallConfig {\n  /** NoOp call config */\n  no_op?: CallConfigValue\n  /** Opt-in call config */\n  opt_in?: CallConfigValue\n  /** Close out call config */\n  close_out?: CallConfigValue\n  /** Update call config */\n  update_application?: CallConfigValue\n  /** Delete call config */\n  delete_application?: CallConfigValue\n}\n\n/** Hint information for a given method call to allow client generation */\nexport interface Hint {\n  /** Any user-defined struct/tuple types used in the method call, keyed by parameter name or `output` for return type */\n  structs?: Record<string, Struct>\n  read_only?: boolean\n  default_arguments?: Record<string, DefaultArgument>\n  call_config: CallConfig\n}\n\n/** The name of a field */\nexport type FieldName = string\n\n/** The string name of an ABI type */\nexport type ABIType = string\n\n/** The elements of the struct/tuple: `FieldName`, `ABIType` */\nexport type StructElement = [FieldName, ABIType]\n\n/** A user-defined struct/tuple type */\nexport interface Struct {\n  /** The name of the type */\n  name: string\n  /** The elements (in order) that make up the struct/tuple */\n  elements: StructElement[]\n}\n\n/**\n * Defines a strategy for obtaining a default value for a given ABI arg.\n */\nexport type DefaultArgument =\n  | {\n      /**\n       * The default value should be fetched by invoking an ABI method\n       */\n      source: 'abi-method'\n      data: ABIMethodParams\n    }\n  | {\n      /**\n       * The default value should be fetched from global state\n       */\n      source: 'global-state'\n      /**\n       * The key of the state variable\n       */\n      data: string\n    }\n  | {\n      /**\n       * The default value should be fetched from the local state of the sender user\n       */\n      source: 'local-state'\n      /**\n       * The key of the state variable\n       */\n      data: string\n    }\n  | {\n      /**\n       * The default value is a constant.\n       */\n      source: 'constant'\n      /**\n       * The static default value to use.\n       */\n      data: string | number\n    }\n\n/** AVM data type */\nexport type AVMType = 'uint64' | 'bytes'\n\n/** Declared schema value specification */\nexport interface DeclaredSchemaValueSpec {\n  /** The type of value */\n  type: AVMType\n  /** The name of the key */\n  key: string\n  /** A description of the variable */\n  descr?: string\n  /** Whether or not the value is set statically (at create time only) or dynamically */\n  static?: boolean\n}\n\n/** Reserved schema value specification */\nexport interface ReservedSchemaValueSpec {\n  /** The type of value */\n  type: AVMType\n  /** The description of the reserved storage space */\n  descr: string\n  /** The maximum number of slots to reserve */\n  max_keys: number\n}\n\n/** The schema for global and local storage */\nexport interface SchemaSpec {\n  /** The local storage schema */\n  local: Schema\n  /** The global storage schema */\n  global: Schema\n}\n\n/** The storage schema definition */\nexport interface Schema {\n  /** Declared storage schema */\n  declared: Record<string, DeclaredSchemaValueSpec>\n  /** Reserved storage schema */\n  reserved: Record<string, ReservedSchemaValueSpec>\n}\n\n/** The rolled-up schema allocation specification for local and global state */\nexport interface StateSchemaSpec {\n  /** Global storage spec */\n  global: StateSchema\n  /** Local storage spec */\n  local: StateSchema\n}\n\n/** Schema spec summary for global or local storage */\nexport type StateSchema = {\n  /** Number of uint slots */\n  num_uints: number\n  /** Number of byte slots */\n  num_byte_slices: number\n}\n"],"names":[],"mappings":";;AAIA,IAAO,SAAS,GAAG,OAAO,CAAC,SAAS;AAEpC;;;;;;;;AAQG;AACG,SAAU,YAAY,CAAC,OAAgB,EAAA;AAC3C,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACvG,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAI;AAC/B,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACvE,QAAA,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;KAC7B,CAAC,CAC+C;IACnD,MAAM,IAAI,GAAG,CAAC,CAAkB,KAAK,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAqB;AACvG,IAAA,MAAM,OAAO,GAAG,CAAC,CAAkB,EAAE,IAAuB,KAAI;;QAE9D,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAY,EAAE,IAAI,CAAC,GAAG,EAAE;AACnG,KAAC;AACD,IAAA,MAAM,WAAW,GAAG,CAAC,IAAuB,KAAI;QAC9C,OAAO,mBAAmB,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;AAC5D,KAAC;AACD,IAAA,MAAM,mBAAmB,GAAG,CAAC,CAAa,EAAE,IAAuB,KAAI;QACrE,MAAM,OAAO,GAAiG,EAAE;AAChH,QAAA,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAAE,YAAA,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;AAChF,QAAA,IAAI,CAAC,CAAC,kBAAkB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAAE,YAAA,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC;AAC3G,QAAA,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AACpE,QAAA,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AACvE,QAAA,IAAI,CAAC,CAAC,kBAAkB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAAE,YAAA,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC;AAC3G,QAAA,OAAO,OAAO;AAChB,KAAC;AACD,IAAA,MAAM,kBAAkB,GAAG,CACzB,IAAY,EACZ,UAAuC,KACmB;AAC1D,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,SAAS;AAEjC,QAAA,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,EAAE;YACtC,OAAO;AACL,gBAAA,MAAM,EAAE,QAAQ;AAChB,gBAAA,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI;aAC3B;;QAGH,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,MAAM,KAAK,cAAc,GAAG,QAAQ,GAAG,OAAO;AAChH,YAAA,IAAI,EAAE,MAAM,CAAC,IAAI,CACf,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAC/G,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,IAAI,KAAK,QAAQ,GAAG,WAAW,GAAG,IAAI;SAC7C;AACH,KAAC;IAED,OAAO;AACL,QAAA,IAAI,EAAE,EAAE;AACR,QAAA,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;AAC3B,QAAA,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;AAC3B,QAAA,OAAO,EAAE,OAAO;AAChB,QAAA,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CACnC,CAAC,CAAC,MACC;YACC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;AACZ,YAAA,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;gBACvB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS;AAC7D,gBAAA,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACrG,aAAA,CAAC,CAAC;AACH,YAAA,OAAO,EAAE;AACP,gBAAA,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;AACpB,gBAAA,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;gBACpB,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI;AACvC,aAAA;AACD,YAAA,MAAM,EAAE,EAAE;AACV,YAAA,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS;AAC5B,YAAA,OAAO,EAAE;AACP,gBAAA,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAqC;AAChE,gBAAA,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC;AACzB,aAAA;AACF,SAAA,CAAuB,CAC3B;AACD,QAAA,KAAK,EAAE;AACL,YAAA,MAAM,EAAE;AACN,gBAAA,MAAM,EAAE;AACN,oBAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS;AACpC,oBAAA,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe;AAC5C,iBAAA;AACD,gBAAA,KAAK,EAAE;AACL,oBAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS;AACnC,oBAAA,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe;AAC3C,iBAAA;AACF,aAAA;AACD,YAAA,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;oBACxD,CAAC,CAAC,CAAC,CAAC;AACJ,oBAAA;AACE,wBAAA,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACtD,wBAAA,OAAO,EAAE,WAAW;AACpB,wBAAA,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,GAAG,WAAW,GAAG,UAAU;AAC5D,wBAAA,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;AACI,qBAAA;AACvB,iBAAA,CAAC,CACH;gBACD,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;oBACvD,CAAC,CAAC,CAAC,CAAC;AACJ,oBAAA;AACE,wBAAA,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACtD,wBAAA,OAAO,EAAE,WAAW;AACpB,wBAAA,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,GAAG,WAAW,GAAG,UAAU;AAC5D,wBAAA,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;AACI,qBAAA;AACvB,iBAAA,CAAC,CACH;AACD,gBAAA,GAAG,EAAE,EAAE;AACR,aAAA;AACD,YAAA,IAAI,EAAE;AACJ,gBAAA,MAAM,EAAE,EAAE;AACV,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,GAAG,EAAE,EAAE;AACR,aAAA;AACF,SAAA;QACD,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,QAAA,WAAW,EAAE;AACX,YAAA,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAsD;AAClF,YAAA,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC;AAC1B,SAAA;AACD,QAAA,QAAQ,EAAE,SAAS;AACnB,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,QAAQ,EAAE,SAAS;AACnB,QAAA,gBAAgB,EAAE,SAAS;AAC3B,QAAA,UAAU,EAAE,SAAS;AACrB,QAAA,iBAAiB,EAAE,SAAS;KACL;AAC3B;;;;"}