@radixdlt/atom-transaction-mapping
Version:
94 lines (83 loc) • 2.55 kB
text/typescript
import { TokensActionBase, UserAction, UserActionType } from '@radixdlt/actions'
import {
AnyUpParticle,
spunParticles,
TokenDefinitionParticleBase,
} from '@radixdlt/atom'
import { AddressT } from '@radixdlt/account'
import { err, ok, Result } from 'neverthrow'
import { MapperInput } from './_types'
import { ValidationWitness } from '@radixdlt/util'
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types */
export const validate = (
...validators: ((input: any) => Result<MapperInput, Error>)[]
) => (input: MapperInput) =>
validators.reduce<Result<MapperInput, Error>>(
(result, validator) => result.andThen(validator),
ok(input),
)
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types */
export const validateUserActionSender = <
T extends Readonly<{
action: UserAction<unknown>
addressOfActiveAccount: AddressT
}>
>(
input: T,
): Result<T, Error> => {
return input.action.sender.equals(input.addressOfActiveAccount)
? ok(input)
: err(new Error('Wrong sender/signer'))
}
export const alwaysValid: ValidationWitness = { witness: 'always valid' }
export const validateConsumeTokensAction = (
validateTokenDefinition?: (
input: Readonly<{
tokenDefinitionParticle: TokenDefinitionParticleBase
burner: AddressT
}>,
) => Result<ValidationWitness, Error>,
) => <
T extends Readonly<{
upParticles: AnyUpParticle[]
action: A
}>,
A extends TokensActionBase<unknown>
>(
input: T,
): Result<T, Error> => {
const resourceIdentifier = input.action.resourceIdentifier
const tokenDefValidation =
validateTokenDefinition ?? (() => ok(alwaysValid))
const spunParticles_ = spunParticles(input.upParticles)
const tokenDefinitionParticle = spunParticles_.tokenDefinitionParticleMatchingIdentifier(
resourceIdentifier,
)
if (!tokenDefinitionParticle) {
return err(
new Error(
`Unknown token with identifier: '${resourceIdentifier.toString()}'`,
),
)
}
if (
!input.action.amount.isMultipleOf(tokenDefinitionParticle.granularity)
) {
return err(new Error('Amount not multiple of granularity'))
}
return tokenDefValidation({
tokenDefinitionParticle,
burner: input.action.sender,
}).map((_) => input)
}
export const validateUserActionType = (filterOnType: UserActionType) => <
T extends {
action: UserAction<unknown>
}
>(
input: T,
): Result<T, Error> => {
if (input.action.actionType !== filterOnType)
return err(new Error('Incorrect UserAction type.'))
return ok(input)
}