/* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable no-nested-ternary */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable camelcase */ import { GenericAuthorization } from 'cosmjs-types/cosmos/authz/v1beta1/authz' import { MsgGrant } from 'cosmjs-types/cosmos/authz/v1beta1/tx' import { SendAuthorization } from 'cosmjs-types/cosmos/bank/v1beta1/authz' import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin' import type { AuthorizationType } from 'cosmjs-types/cosmos/staking/v1beta1/authz' import { StakeAuthorization, StakeAuthorization_Validators } from 'cosmjs-types/cosmos/staking/v1beta1/authz' import { AcceptedMessageKeysFilter, AllowAllMessagesFilter, CombinedLimit, ContractExecutionAuthorization, ContractMigrationAuthorization, MaxCallsLimit, MaxFundsLimit, } from 'cosmjs-types/cosmwasm/wasm/v1/authz' import type { AuthorizationMode, GenericAuthorizationType, GrantAuthorizationType } from 'pages/authz/grant' export interface Msg { typeUrl: string value: any } export interface AuthzMessage { authzMode: AuthorizationMode authzType: GrantAuthorizationType displayName: string typeUrl: string genericAuthzType?: GenericAuthorizationType } export const grantGenericStakeAuthorization: AuthzMessage = { authzMode: 'Grant', authzType: 'Generic', displayName: 'Stake', typeUrl: '/cosmos.staking.v1beta1.MsgDelegate', genericAuthzType: 'MsgDelegate', } export const grantGenericSendAuthorization: AuthzMessage = { authzMode: 'Grant', authzType: 'Generic', displayName: 'Send', typeUrl: '/cosmos.bank.v1beta1.MsgSend', genericAuthzType: 'MsgSend', } export const authzMessages: AuthzMessage[] = [grantGenericStakeAuthorization, grantGenericSendAuthorization] const msgAuthzGrantTypeUrl = '/cosmos.authz.v1beta1.MsgGrant' export function AuthzSendGrantMsg( granter: string, grantee: string, denom: string, spendLimit: number, expiration: number, allowList?: string[], ): Msg { const sendAuthValue = SendAuthorization.encode( SendAuthorization.fromPartial({ spendLimit: [ Coin.fromPartial({ amount: String(spendLimit), denom, }), ], // Needs cosmos-sdk >= 0.47 // allowList, }), ).finish() const grantValue = MsgGrant.fromPartial({ grant: { authorization: { typeUrl: '/cosmos.bank.v1beta1.SendAuthorization', value: sendAuthValue, }, expiration: expiration ? { seconds: BigInt(expiration) } : undefined, }, grantee, granter, }) return { typeUrl: msgAuthzGrantTypeUrl, value: grantValue, } } export function AuthzExecuteContractGrantMsg( granter: string, grantee: string, contract: string, expiration: number, callsRemaining?: number, amounts?: Coin[], allowedMessages?: string[], ): Msg { const sendAuthValue = ContractExecutionAuthorization.encode( ContractExecutionAuthorization.fromPartial({ grants: [ { contract, filter: { typeUrl: allowedMessages ? '/cosmwasm.wasm.v1.AcceptedMessageKeysFilter' : '/cosmwasm.wasm.v1.AllowAllMessagesFilter', value: allowedMessages ? AcceptedMessageKeysFilter.encode({ keys: allowedMessages }).finish() : AllowAllMessagesFilter.encode({}).finish(), }, limit: callsRemaining || amounts ? { typeUrl: callsRemaining && amounts ? '/cosmwasm.wasm.v1.CombinedLimit' : callsRemaining ? '/cosmwasm.wasm.v1.MaxCallsLimit' : '/cosmwasm.wasm.v1.MaxFundsLimit', value: callsRemaining && amounts ? CombinedLimit.encode({ callsRemaining: BigInt(callsRemaining), amounts, }).finish() : callsRemaining ? MaxCallsLimit.encode({ remaining: BigInt(callsRemaining), }).finish() : MaxFundsLimit.encode({ amounts: amounts || [], }).finish(), } : { // limit: undefined is not accepted typeUrl: '/cosmwasm.wasm.v1.MaxCallsLimit', value: MaxCallsLimit.encode({ remaining: BigInt(100000), }).finish(), }, }, ], }), ).finish() const grantValue = MsgGrant.fromPartial({ grant: { authorization: { typeUrl: '/cosmwasm.wasm.v1.ContractExecutionAuthorization', value: sendAuthValue, }, expiration: expiration ? { seconds: BigInt(expiration), nanos: 0 } : undefined, }, grantee, granter, }) return { typeUrl: msgAuthzGrantTypeUrl, value: grantValue, } } export function AuthzMigrateContractGrantMsg( granter: string, grantee: string, contract: string, expiration: number, callsRemaining?: number, amounts?: Coin[], allowedMessages?: string[], ): Msg { const sendAuthValue = ContractMigrationAuthorization.encode( ContractMigrationAuthorization.fromPartial({ grants: [ { contract, filter: { typeUrl: allowedMessages ? '/cosmwasm.wasm.v1.AcceptedMessageKeysFilter' : '/cosmwasm.wasm.v1.AllowAllMessagesFilter', value: allowedMessages ? AcceptedMessageKeysFilter.encode({ keys: allowedMessages }).finish() : AllowAllMessagesFilter.encode({}).finish(), }, limit: callsRemaining || amounts ? { typeUrl: callsRemaining && amounts ? '/cosmwasm.wasm.v1.CombinedLimit' : callsRemaining ? '/cosmwasm.wasm.v1.MaxCallsLimit' : '/cosmwasm.wasm.v1.MaxFundsLimit', value: callsRemaining && amounts ? CombinedLimit.encode({ callsRemaining: BigInt(callsRemaining), amounts, }).finish() : callsRemaining ? MaxCallsLimit.encode({ remaining: BigInt(callsRemaining), }).finish() : MaxFundsLimit.encode({ amounts: amounts || [], }).finish(), } : { // limit: undefined is not accepted typeUrl: '/cosmwasm.wasm.v1.MaxCallsLimit', value: MaxCallsLimit.encode({ remaining: BigInt(100000), }).finish(), }, }, ], }), ).finish() const grantValue = MsgGrant.fromPartial({ grant: { authorization: { typeUrl: '/cosmwasm.wasm.v1.ContractMigrationAuthorization', value: sendAuthValue, }, expiration: expiration ? { seconds: BigInt(expiration), nanos: 0 } : undefined, }, grantee, granter, }) return { typeUrl: msgAuthzGrantTypeUrl, value: grantValue, } } export function AuthzGenericGrantMsg(granter: string, grantee: string, typeURL: string, expiration: number): Msg { return { typeUrl: msgAuthzGrantTypeUrl, value: { grant: { authorization: { typeUrl: '/cosmos.authz.v1beta1.GenericAuthorization', value: GenericAuthorization.encode( GenericAuthorization.fromPartial({ msg: typeURL, }), ).finish(), }, expiration: expiration ? { seconds: expiration } : undefined, }, grantee, granter, }, } } export function AuthzStakeGrantMsg({ expiration, grantee, granter, allowList, denyList, maxTokens, denom, stakeAuthzType, }: { granter: string grantee: string expiration: number allowList?: string[] denyList?: string[] maxTokens?: string denom?: string stakeAuthzType: AuthorizationType }): Msg { const allow_list = StakeAuthorization_Validators.encode( StakeAuthorization_Validators.fromPartial({ address: allowList, }), ).finish() const deny_list = StakeAuthorization_Validators.encode( StakeAuthorization_Validators.fromPartial({ address: denyList, }), ).finish() const stakeAuthValue = StakeAuthorization.encode( StakeAuthorization.fromPartial({ authorizationType: stakeAuthzType, allowList: allowList?.length ? StakeAuthorization_Validators.decode(allow_list) : undefined, denyList: denyList?.length ? StakeAuthorization_Validators.decode(deny_list) : undefined, maxTokens: maxTokens ? Coin.fromPartial({ amount: maxTokens, denom, }) : undefined, }), ).finish() const grantValue = MsgGrant.fromPartial({ grant: { authorization: { typeUrl: '/cosmos.staking.v1beta1.StakeAuthorization', value: stakeAuthValue, }, expiration: { seconds: BigInt(expiration) }, }, grantee, granter, }) return { typeUrl: msgAuthzGrantTypeUrl, value: grantValue, } }