diff --git a/scripts/generate_typescript.sh b/scripts/generate_typescript.sh index d4b4fb8..becab8a 100755 --- a/scripts/generate_typescript.sh +++ b/scripts/generate_typescript.sh @@ -85,7 +85,7 @@ java -jar target/generator-*-jar-with-dependencies.jar \ -s "$ALGOD_SPEC" \ -t "$TEMPLATE_DIR" \ -m "$SDK_DIR/src/client/v2/algod/models" \ - -p "$TEMPLATE_DIR/algod_config.properties,$TEMPLATE_DIR/parameter_order_overrides.properties" \ + -p "$TEMPLATE_DIR/algod_config.properties" \ java -jar target/generator-*-jar-with-dependencies.jar \ template \ diff --git a/typescript_templates/algod_config.properties b/typescript_templates/algod_config.properties index 338a772..afff77c 100644 --- a/typescript_templates/algod_config.properties +++ b/typescript_templates/algod_config.properties @@ -7,3 +7,56 @@ # changes. use_object_params_if_greater_than=0 indexer=false +# Type override conventions: +# * All Algo and asset amounts should be bigint (including fees) +# * All round numbers should be bigint, including any quantities you would add +# to a round number (e.g. offset or duration) +# * All application and asset IDs should be bigint +# * All timestamps in nanoseconds should be bigint +# * If there is a quantity whose purpose is to be added to, subtracted from, or +# otherwise operated on with a bigint, it should be a bigint for ease of use +# * Other quantities outside of the above and which will never exceed the maximum +# safe javascript integer should be number +type_override_Account_amount=bigint +type_override_Account_amountWithoutPendingRewards=bigint +type_override_Account_minBalance=bigint +type_override_Account_pendingRewards=bigint +type_override_Account_rewards=bigint +type_override_Account_round=bigint +type_override_Account_rewardBase=bigint +type_override_AccountApplicationResponse_round=bigint +type_override_AccountAssetResponse_round=bigint +type_override_AccountParticipation_voteFirstValid=bigint +type_override_AccountParticipation_voteKeyDilution=bigint +type_override_AccountParticipation_voteLastValid=bigint +type_override_Application_id=bigint +type_override_ApplicationLocalState_id=bigint +type_override_Asset_index=bigint +type_override_AssetHolding_assetId=bigint +type_override_Box_round=bigint +type_override_BoxReference_app=bigint +type_override_GetSyncRoundResponse_round=bigint +type_override_NodeStatusResponse_catchupTime=bigint +type_override_NodeStatusResponse_lastRound=bigint +type_override_NodeStatusResponse_nextVersionRound=bigint +type_override_NodeStatusResponse_timeSinceLastRound=bigint +type_override_NodeStatusResponse_upgradeDelay=bigint +type_override_NodeStatusResponse_upgradeNextProtocolVoteBefore=bigint +type_override_PendingTransactionResponse_applicationIndex=bigint +type_override_PendingTransactionResponse_assetClosingAmount=bigint +type_override_PendingTransactionResponse_assetIndex=bigint +type_override_PendingTransactionResponse_closeRewards=bigint +type_override_PendingTransactionResponse_closingAmount=bigint +type_override_PendingTransactionResponse_confirmedRound=bigint +type_override_PendingTransactionResponse_receiverRewards=bigint +type_override_PendingTransactionResponse_senderRewards=bigint +type_override_SimulateRequest_round=bigint +type_override_SimulateResponse_lastRound=bigint +type_override_SupplyResponse_currentRound=bigint +type_override_SupplyResponse_onlineMoney=bigint +type_override_SupplyResponse_totalMoney=bigint +type_override_TransactionParametersResponse_fee=bigint +type_override_TransactionParametersResponse_lastRound=bigint +type_override_TransactionParametersResponse_minFee=bigint +type_override_TealValue_bytes=binary +type_override_TealKeyValue_key=binary diff --git a/typescript_templates/indexer_config.properties b/typescript_templates/indexer_config.properties index 2a0d48c..560bc25 100644 --- a/typescript_templates/indexer_config.properties +++ b/typescript_templates/indexer_config.properties @@ -1,2 +1,78 @@ use_object_params_if_greater_than=0 indexer=true +# Type override conventions: +# * All Algo and asset amounts should be bigint (including fees) +# * All round numbers should be bigint, including any quantities you would add +# to a round number (e.g. offset or duration) +# * All application and asset IDs should be bigint +# * All timestamps in nanoseconds should be bigint +# * If there is a quantity whose purpose is to be added to, subtracted from, or +# otherwise operated on with a bigint, it should be a bigint for ease of use +# * Other quantities outside of the above and which will never exceed the maximum +# safe javascript integer should be number +type_override_Account_amount=bigint +type_override_Account_amountWithoutPendingRewards=bigint +type_override_Account_pendingRewards=bigint +type_override_Account_rewards=bigint +type_override_Account_round=bigint +type_override_Account_rewardBase=bigint +type_override_AccountParticipation_voteFirstValid=bigint +type_override_AccountParticipation_voteKeyDilution=bigint +type_override_AccountParticipation_voteLastValid=bigint +type_override_AccountResponse_currentRound=bigint +type_override_AccountsResponse_currentRound=bigint +type_override_Application_id=bigint +type_override_ApplicationLocalState_id=bigint +type_override_ApplicationLocalStatesResponse_currentRound=bigint +type_override_ApplicationLogsResponse_applicationId=bigint +type_override_ApplicationLogsResponse_currentRound=bigint +type_override_ApplicationResponse_currentRound=bigint +type_override_ApplicationsResponse_currentRound=bigint +type_override_Asset_index=bigint +type_override_AssetBalancesResponse_currentRound=bigint +type_override_AssetHolding_assetId=bigint +type_override_AssetHoldingsResponse_currentRound=bigint +type_override_AssetResponse_currentRound=bigint +type_override_AssetsResponse_currentRound=bigint +type_override_Block_round=bigint +type_override_BlockRewards_rewardsCalculationRound=bigint +type_override_BlockRewards_rewardsLevel=bigint +type_override_BlockRewards_rewardsRate=bigint +type_override_BlockRewards_rewardsResidue=bigint +type_override_BlockUpgradeState_nextProtocolSwitchOn=bigint +type_override_BlockUpgradeState_nextProtocolVoteBefore=bigint +type_override_BlockUpgradeVote_upgradeDelay=bigint +type_override_Box_round=bigint +type_override_BoxesResponse_applicationId=bigint +type_override_HealthCheck_round=bigint +type_override_StateProofTracking_nextRound=bigint +type_override_StateProofTracking_onlineTotalWeight=bigint +type_override_StateProofTracking_type=number +type_override_StateSchema_numByteSlice=number +type_override_StateSchema_numUint=number +type_override_Transaction_fee=bigint +type_override_Transaction_firstValid=bigint +type_override_Transaction_lastValid=bigint +type_override_Transaction_closeRewards=bigint +type_override_Transaction_closingAmount=bigint +type_override_Transaction_confirmedRound=bigint +type_override_Transaction_createdApplicationIndex=bigint +type_override_Transaction_createdAssetIndex=bigint +type_override_Transaction_receiverRewards=bigint +type_override_Transaction_senderRewards=bigint +type_override_TransactionApplication_applicationId=bigint +type_override_TransactionApplication_foreignApps=bigint +type_override_TransactionApplication_foreignAssets=bigint +type_override_TransactionAssetConfig_assetId=bigint +type_override_TransactionAssetFreeze_assetId=bigint +type_override_TransactionAssetTransfer_assetId=bigint +type_override_TransactionKeyreg_voteFirstValid=bigint +type_override_TransactionKeyreg_voteKeyDilution=bigint +type_override_TransactionKeyreg_voteLastValid=bigint +type_override_TransactionPayment_amount=bigint +type_override_TransactionPayment_closeAmount=bigint +type_override_TransactionResponse_currentRound=bigint +type_override_TransactionStateProof_stateProofType=number +type_override_TransactionsResponse_currentRound=bigint +type_override_TealValue_bytes=binary +type_override_TealKeyValue_key=binary diff --git a/typescript_templates/model.vm b/typescript_templates/model.vm index 9991638..04aa7f8 100644 --- a/typescript_templates/model.vm +++ b/typescript_templates/model.vm @@ -1,21 +1,41 @@ +## Create a variable in order to insert a $ into the code +#set( $dollar = "$" ) +## Create a variable in order to insert a ! into the code +#set( $exclamation = "!" ) ## Map generated name from spec to hand written name #macro ( paramName $param ) $str.kebabToCamel($param.propertyName.replaceAll("_", "-"))## #end ## Converts a parameter type into the SDK specific type. -#macro ( toSdkType $param $isArgType ) +#macro ( toSdkType $className $param $isArgType ) +#set( $type_override_variable = "${dollar}${exclamation}propFile.type_override_${className}_#paramName(${param})" ) +#set( $type_override = "#evaluate($type_override_variable)" ) #if ( $param.algorandFormat == "SignedTransaction" ) -EncodedSignedTransaction## -#elseif ( $param.algorandFormat == "Address" ) ## No special handling for Address in go SDK -string## +SignedTransaction## +#elseif ( $param.algorandFormat == "Address" ) +#if ( $isArgType ) +(Address | string)## +#else +Address## +#end #elseif ( $param.algorandFormat == "BlockHeader" ) -BlockHeader## -#elseif ( $param.algorandFormat == "uint64" ) +Block## +#elseif ( $param.algorandFormat == "StateDelta" ) +LedgerStateDelta## +#elseif ( $type_override == "bigint" || ( $param.algorandFormat == "uint64" && $type_override.length() == 0 ) ) +#if ( $isArgType ) (number | bigint)## +#else +bigint## +#end #elseif ( $param.type == "object" ) -Record## -#elseif ( $param.type == "integer" || $param.arrayType == "integer" ) +UntypedValue## +#elseif ( $type_override == "number" || ( ( $param.type == "integer" || $param.arrayType == "integer" ) && $type_override.length() == 0 ) ) +#if ( $isArgType ) (number | bigint)## +#else +number## +#end #elseif ( $param.type == "boolean" ) boolean## #elseif( $param.type == "address" ) @@ -24,7 +44,7 @@ string## Uint8Array## #elseif($param.arrayType && $param.format == "byte") Uint8Array## -#elseif( $param.type == "string" && $param.format == "byte" ) +#elseif( ($param.type == "string" && $param.format == "byte") || $type_override == "binary" ) #if ( $isArgType ) string | Uint8Array## #else @@ -34,7 +54,7 @@ Uint8Array## string## #elseif( $param.arrayType ) ${param.arrayType}## -#elseif( $param.refType ) ## This is second because the old code avoids typedef of references +#elseif( $param.refType )## This is second because the old code avoids typedef of references ${param.refType}## #else UNHANDLED TYPE @@ -47,6 +67,54 @@ $unknown.type ## force a template failure with an unknown type #end #if ($param.arrayType && $param.arrayType != "")[]#end## Add array postfix to arrays... #end +## Gets the Schema object for a given type. +#macro ( toSchema $className $param ) +#set( $type_override_variable = "${dollar}${exclamation}propFile.type_override_${className}_#paramName(${param})" ) +#set( $type_override = "#evaluate($type_override_variable)" ) +#if ( !$param.required ) +new OptionalSchema(## +#end +#if ( $param.arrayType ) +new ArraySchema(## +#end +#if ( $param.algorandFormat == "BlockHeader" ) +Block.encodingSchema## +#elseif ( $param.algorandFormat == "StateDelta" ) +LedgerStateDelta.encodingSchema## +#elseif ( $param.algorandFormat == "SignedTransaction" ) +SignedTransaction.encodingSchema## +#elseif ( $param.type == "object" || $param.arrayType == "object" ) +UntypedValue.encodingSchema## +#elseif ( $param.algorandFormat == "Address" ) +new StringSchema()## # To comply with existing msgpack REST API behavior, encode addresses as strings +#elseif ( $param.algorandFormat == "uint64" || $param.type == "integer" || $param.arrayType == "integer" ) +new Uint64Schema()## +#elseif ( $param.type == "boolean" || $param.arrayType == "boolean" ) +new BooleanSchema()## +#elseif( (( $param.type == "string" || $param.arrayType == "string" ) && ( $param.format == "byte" || $param.format == "binary" )) || $type_override == "binary" ) +new ByteArraySchema()## +#elseif( $param.type == "string" || $param.arrayType == "string" ) +new StringSchema()## +#elseif ( "#isClassType($param)" == "true" ) +#if ( $param.arrayType ) +${param.arrayType}## +#else +${param.refType}## +#end +.encodingSchema## +#else +UNHANDLED SCHEMA TYPE +- property: $param +- isClassType: #isClassType($param) +$unknown.type ## force a template failure with an unknown type +#end +#if ( $param.arrayType ) +)## +#end +#if ( !$param.required ) +)## +#end +#end ## Check if there's a class associated with this type #macro ( isClassType $param ) #if ( $param.algorandFormat == "SignedTransaction" ) @@ -55,6 +123,8 @@ false## false## #elseif ( $param.algorandFormat == "BlockHeader" ) false## +#elseif ( $param.algorandFormat == "StateDelta" ) +false## #elseif ( $param.algorandFormat == "uint64" ) false## #elseif ( $param.type == "object" ) @@ -77,15 +147,64 @@ false## true## #end #end +## Returns "true" if the type is a primative, meaning it's not an object that requires manipulation +## when converting to & from encoding data. +#macro ( isPrimativeType $param ) +#if ( $param.algorandFormat == "uint64" || $param.type == "integer" || $param.arrayType == "integer" ) +true## +#elseif ( $param.type == "boolean" || $param.arrayType == "boolean" ) +true## +#elseif( $param.type == "string" || $param.arrayType == "string" ) +#if ( $param.algorandFormat == "Address" || $param.algorandFormat == "SignedTransaction" ) +false## +#else +true## +#end +#else +false## +#end +#end ## Create an expression to assign a field in a constructor -#macro ( constructorAssignType $prop ) -#set( $argType = "#toSdkType($prop, true)" ) -#set( $fieldType = "#toSdkType($prop, false)" ) +#macro ( constructorAssignType $className $prop ) +#set( $argType = "#toSdkType($className, $prop, true)" ) +#set( $fieldType = "#toSdkType($className, $prop, false)" ) #set( $name = "#paramName($prop)" ) #if ( $argType == $fieldType ) $name## +#elseif ( $argType == "(Address | string)" && $fieldType == "Address" ) +typeof $name === 'string' ? Address.fromString($name) : $name## +#elseif ( $argType == "(Address | string)[]" && $fieldType == "Address[]" ) +#if ( $prop.required ) +${name}.map(addr => typeof addr === 'string' ? Address.fromString(addr) : addr)## +#else +typeof $name !== 'undefined' ? ${name}.map(addr => typeof addr === 'string' ? Address.fromString(addr) : addr) : undefined## +#end #elseif ( $argType == "string | Uint8Array" && $fieldType == "Uint8Array" ) -typeof $name === 'string' ? new Uint8Array(Buffer.from($name, 'base64')) : $name## +typeof $name === 'string' ? base64ToBytes($name) : $name## +#elseif ( $argType == "(number | bigint)" && $fieldType == "bigint" ) +#if ( $prop.required ) +ensureBigInt($name)## +#else +typeof $name === 'undefined' ? undefined : ensureBigInt($name)## +#end +#elseif ( $argType == "(number | bigint)[]" && $fieldType == "bigint[]" ) +#if ( $prop.required ) +${name}.map(ensureBigInt)## +#else +typeof ${name} === 'undefined' ? undefined : ${name}.map(ensureBigInt)## +#end +#elseif ( $argType == "(number | bigint)" && $fieldType == "number" ) +#if ( $prop.required ) +ensureSafeInteger($name)## +#else +typeof $name === 'undefined' ? undefined : ensureSafeInteger($name)## +#end +#elseif ( $argType == "(number | bigint)[]" && $fieldType == "number[]" ) +#if ( $prop.required ) +${name}.map(ensureSafeInteger)## +#else +typeof ${name} === 'undefined' ? undefined : ${name}.map(ensureSafeInteger)## +#end #else UNHANDLED CONSTRUCTOR TYPE CONVERSION - property: $prop @@ -95,24 +214,73 @@ UNHANDLED CONSTRUCTOR TYPE CONVERSION $unknown.type ## force a template failure with an unknown type #end #end -## Create an expression to assign a field in the from_obj_for_encoding function -#macro ( fromObjForEncodingAssignType $value $prop ) -#if ( "#isClassType($prop)" == "false" ) +## Create an expression to assign a field in the toEncodingData function +#macro ( fieldToEncodingData $prop ) +#set( $value = "this.#paramName($prop)" ) +#set( $isPrimative = "#isPrimativeType($prop)" == "true" ) +#set( $needsUndefinedCheck = !$isPrimative && !$prop.required ) +#if ( $needsUndefinedCheck ) +typeof ${value} !== "undefined" ? ## +#end +#if ( $prop.arrayType && !$isPrimative )## No need to map a primative type +${value}.map(v => ## +#set ( $value = "v" ) +#end +#if ( $prop.algorandFormat == "Address" ) +${value}.toString()## +#elseif ( $isPrimative ) $value## -#elseif ( $prop.arrayType ) -#set ( $assignment = "${value}.map(${prop.arrayType}.from_obj_for_encoding)" ) -#if ($prop.required) -$assignment## #else -typeof $value !== 'undefined' ? $assignment : undefined## +${value}.toEncodingData()## +#end +#if ( $prop.arrayType && !$isPrimative ) +)## +#end +#if ( $needsUndefinedCheck ) +: undefined## +#end +#end +## Create an expression to assign a field in the fromEncodingData function +#macro ( fromEncodingDataAssignType $value $prop ) +#set( $isPrimative = "#isPrimativeType($prop)" == "true" || $prop.algorandFormat == "Address" )## Addresses are encoded as strings, so treat them as primatives here +#set( $needsUndefinedCheck = !$isPrimative && !$prop.required ) +#if ( $needsUndefinedCheck ) +typeof ${value} !== "undefined" ? ## +#end +#if ( $prop.arrayType && !$isPrimative ) +#if ( $prop.required ) +(${value} ?? [])## +#else +$value## #end +.map((v: unknown) => ## +#set ( $value = "v" ) +#elseif ( $prop.required && !$isPrimative ) +#set ( $value = "($value ?? new Map())" )## +#end +#if ( $isPrimative ) +${value}## #else -#set ( $assignment = "${prop.refType}.from_obj_for_encoding($value)" ) -#if ($prop.required) -$assignment## +#if ( $prop.algorandFormat == "SignedTransaction" ) +SignedTransaction## +#elseif ( $prop.algorandFormat == "BlockHeader" ) +Block## +#elseif ( $prop.algorandFormat == "StateDelta" ) +LedgerStateDelta## +#elseif ( $prop.type == "object" ) +UntypedValue## +#elseif ( $prop.arrayType ) +${prop.arrayType}## #else -typeof $value !== 'undefined' ? $assignment : undefined## +${prop.refType}## #end +.fromEncodingData($value) +#end +#if ( $prop.arrayType && !$isPrimative ) +)## +#end +#if ( $needsUndefinedCheck ) +: undefined## #end #end #macro ( questionMarkIfOptional $param ) @@ -129,19 +297,22 @@ typeof $value !== 'undefined' ? $assignment : undefined## */ /* eslint-disable no-use-before-define */ -import { Buffer } from 'buffer'; -import BaseModel from '../../basemodel'; +import { ensureBigInt, ensureSafeInteger } from '../../../../utils/utils.js'; +import { Encodable, Schema } from '../../../../encoding/encoding.js'; +import { NamedMapSchema, ArraySchema, Uint64Schema, StringSchema, BooleanSchema, ByteArraySchema, OptionalSchema } from '../../../../encoding/schema/index.js'; +import { base64ToBytes } from '../../../../encoding/binarydata.js'; #if ( $propFile.indexer == "false" ) -import { EncodedSignedTransaction } from '../../../../types/transactions/encoded'; -import BlockHeader from '../../../../types/blockHeader'; +import { Block } from '../../../../types/block.js'; +import { LedgerStateDelta } from '../../../../types/statedelta.js'; +import { SignedTransaction } from '../../../../signedTransaction.js'; #end +import { Address } from '../../../../encoding/address.js'; +import { UntypedValue } from '../../untypedmodel.js'; #foreach( $modelEntry in $models.entrySet() ) #set( $def = $modelEntry.key ) #set( $props = $def.propertiesSortedByRequired ) -#set( $d = "$" ) -#set( $e = "!" ) -#set( $override_variable_name = "${d}${e}propFile.override_${def.name}_order" ) +#set( $override_variable_name = "${dollar}${exclamation}propFile.override_${def.name}_order" ) #set( $preferred_order_str = "#evaluate($override_variable_name)" ) #if ( $preferred_order_str.length() > 0 ) #set( $preferred_order = $preferred_order_str.split(",") ) @@ -153,14 +324,31 @@ import BlockHeader from '../../../../types/blockHeader'; * $str.formatDoc($def.doc, " * ") */ #end -export class $def.name extends BaseModel { +export class $def.name implements Encodable { + + private static encodingSchemaValue: Schema | undefined; + + static get encodingSchema(): Schema { + if (!this.encodingSchemaValue) { + this.encodingSchemaValue = new NamedMapSchema([]); +## By assigning a value to this.encodingSchemaValue before getting the .encodingSchema fields of other types, +## we allow circular references to be handled properly. + (this.encodingSchemaValue as NamedMapSchema).pushEntries( +#foreach( $prop in $props ) + { key: '$prop.propertyName', valueSchema: #toSchema($def.name, $prop), omitEmpty: true }, +#end + ); + } + return this.encodingSchemaValue; + } + #foreach( $prop in $props ) #if ( !$prop.doc.isEmpty() ) /** * $str.formatDoc($prop.doc, " * ") */ #end - public #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, false); + public #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, false); #end /** @@ -178,61 +366,55 @@ export class $def.name extends BaseModel { #if ($use_object_params) #paramName($prop), #else - #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, true), + #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, true), #end #end #if ($use_object_params) }: { #foreach ( $prop in $props ) - #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, true) + #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, true) #end }) { #else ) { #end - super(); #foreach( $prop in $props ) #set( $var = "#paramName($prop)" ) - this.$var = #constructorAssignType($prop); + this.$var = #constructorAssignType($def.name, $prop); #end + } - this.attribute_map = { -#foreach( $prop in $props ) - #paramName($prop): '$prop.propertyName', -#end - } + // eslint-disable-next-line class-methods-use-this + getEncodingSchema(): Schema { + return ${def.name}.encodingSchema; } - // eslint-disable-next-line camelcase - static from_obj_for_encoding(data: Record): $def.name { - /* eslint-disable dot-notation */ -#set ( $d = "$" )## Create a variable in order to insert a $ into the code + toEncodingData(): Map { + return new Map([ #foreach( $prop in $props ) -#if ($prop.required) -#if ($prop.arrayType) - if (!Array.isArray(data['$prop.propertyName'])) - throw new Error(`Response is missing required array field '${prop.propertyName}': ${d}{data}`); -#else - if (typeof data['$prop.propertyName'] === 'undefined') - throw new Error(`Response is missing required field '${prop.propertyName}': ${d}{data}`); -#end -#end + ['$prop.propertyName', #fieldToEncodingData($prop)], #end + ]); + } + + static fromEncodingData(data: unknown): $def.name { + if (!(data instanceof Map)) { + throw new Error(`Invalid decoded ${def.name}: ${dollar}{data}`); + } #if ($use_object_params) return new ${def.name}({ #foreach( $prop in $props ) - #paramName($prop): #fromObjForEncodingAssignType("data['$prop.propertyName']", $prop), + #paramName($prop): #fromEncodingDataAssignType("data.get('$prop.propertyName')", $prop), #end }); #else return new ${def.name}( #foreach( $prop in $props ) - #fromObjForEncodingAssignType("data['$prop.propertyName']", $prop), + #fromEncodingDataAssignType("data.get('$prop.propertyName')", $prop), #end ); #end - /* eslint-enable dot-notation */ } } diff --git a/typescript_templates/parameter_order_overrides.properties b/typescript_templates/parameter_order_overrides.properties deleted file mode 100644 index a1c8aff..0000000 --- a/typescript_templates/parameter_order_overrides.properties +++ /dev/null @@ -1,10 +0,0 @@ -# List of the new order for each respective override -override_DryrunSource_order = field-name,source,txn-index,app-index -override_Application_order = id,params -override_ApplicationStateSchema_order = num-uint,num-byte-slice -override_ApplicationLocalStates_order = id,state -override_ApplicationLocalState_order = id,schema,key-value -override_TealKeyValue_order = key,value -override_TealValue_order = type,bytes,uint -override_AssetHolding_order = amount,asset-id,is-frozen -override_Asset_order = index,params