mirror of
https://github.com/alexgo-io/clarity-codegen.git
synced 2026-01-12 22:22:01 +08:00
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { ContractCallTransaction } from "@stacks/stacks-blockchain-api-types";
|
|
import { deserializeCV } from "@stacks/transactions";
|
|
import {
|
|
ContractBaseType,
|
|
FunctionDescriptor,
|
|
ParameterObjOfDescriptor,
|
|
ReturnTypeOfDescriptor,
|
|
} from "./contractBase";
|
|
|
|
export type ContractCallTransactionResultMap<Contracts extends ContractBaseType> = {
|
|
[C in keyof Contracts]: {
|
|
[F in keyof Contracts[C]]: {
|
|
contractName: C;
|
|
functionName: F;
|
|
args: ParameterObjOfDescriptor<Contracts[C][F]>;
|
|
result: ReturnTypeOfDescriptor<Contracts[C][F]>;
|
|
};
|
|
};
|
|
};
|
|
|
|
export type ContractCallTransactionResult<Contracts extends ContractBaseType> = {
|
|
[K in keyof ContractCallTransactionResultMap<Contracts>]: ContractCallTransactionResultMap<Contracts>[K][keyof ContractCallTransactionResultMap<Contracts>[K]];
|
|
}[keyof ContractCallTransactionResultMap<Contracts>];
|
|
|
|
export function decodeContractCallTransaction<
|
|
Contracts extends ContractBaseType
|
|
>(
|
|
contracts: Contracts,
|
|
tx: ContractCallTransaction
|
|
): ContractCallTransactionResult<Contracts> {
|
|
if (!(tx.contract_call.contract_id in contracts)) {
|
|
throw new Error(
|
|
`[decodeContractCallTransaction] unknown contract id ${tx.contract_call.contract_id}`
|
|
);
|
|
}
|
|
const contractName = tx.contract_call.contract_id as keyof Contracts;
|
|
|
|
if (!(tx.contract_call.function_name in contracts[contractName])) {
|
|
throw new Error(
|
|
`[decodeContractCallTransaction] unknown function name ${contractName}.${tx.contract_call.function_name}`
|
|
);
|
|
}
|
|
const functionName = tx.contract_call
|
|
.function_name as keyof Contracts[keyof Contracts];
|
|
|
|
return {
|
|
contractName,
|
|
functionName,
|
|
...decodeSpecifiedContractCallTransaction(
|
|
contracts,
|
|
contractName,
|
|
functionName,
|
|
tx
|
|
),
|
|
};
|
|
}
|
|
|
|
export function decodeSpecifiedContractCallTransaction<
|
|
Contracts extends ContractBaseType,
|
|
T extends keyof Contracts,
|
|
F extends keyof Contracts[T]
|
|
>(
|
|
contracts: Contracts,
|
|
contractOrType: T,
|
|
functionName: F,
|
|
tx: ContractCallTransaction
|
|
): {
|
|
args: ParameterObjOfDescriptor<Contracts[T][F]>;
|
|
result: ReturnTypeOfDescriptor<Contracts[T][F]>;
|
|
raw: ContractCallTransaction;
|
|
} {
|
|
const functionDescriptor = contracts[contractOrType][
|
|
functionName
|
|
] as any as FunctionDescriptor;
|
|
|
|
const args = functionDescriptor.input.reduce(
|
|
(acc, arg, index) => ({
|
|
...acc,
|
|
[arg.name]: arg.type.decode(
|
|
deserializeCV(tx.contract_call.function_args![index]!.hex)
|
|
),
|
|
}),
|
|
{} as Record<string, any>
|
|
);
|
|
|
|
const result = functionDescriptor.output.decode(
|
|
deserializeCV(tx.tx_result.hex)
|
|
);
|
|
|
|
return { args: args as any, result, raw: tx };
|
|
}
|