Skip to content

Commit

Permalink
feat(logic): add bank_spendable_coin predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
bdeneux committed Jan 18, 2023
1 parent d616946 commit e7acefa
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
1 change: 1 addition & 0 deletions x/logic/interpreter/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ var Registry = map[string]RegistryEntry{
"block_height/1": {predicate.BlockHeight, 1},
"block_time/1": {predicate.BlockTime, 1},
"bank_balances/2": {predicate.BankBalances, 1},
"bank_spendable_coins/2": {predicate.BankSpendableCoins, 1},
}

// RegistryNames is the list of the predicate names in the Registry.
Expand Down
28 changes: 27 additions & 1 deletion x/logic/predicate/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func BankBalances(vm *engine.VM, account, balances engine.Term, cont engine.Cont
}

if bech32Addr != nil {
fetchedBalances := BalancesSorted(sdkContext, bankKeeper, bech32Addr)
fetchedBalances := AllBalancesSorted(sdkContext, bankKeeper, bech32Addr)

return engine.Unify(vm, CoinsToTerm(fetchedBalances), balances, cont, env)
}
Expand All @@ -73,3 +73,29 @@ func BankBalances(vm *engine.VM, account, balances engine.Term, cont engine.Cont
return engine.Delay(promises...)
})
}

func BankSpendableCoins(vm *engine.VM, account, balances engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise {
return engine.Delay(func(ctx context.Context) *engine.Promise {
sdkContext, err := util.UnwrapSDKContext(ctx)
if err != nil {
return engine.Error(err)
}
bankKeeper := sdkContext.Value(types.BankKeeperContextKey).(types.BankKeeper)

bech32Addr := sdk.AccAddress(nil)
switch acc := env.Resolve(account).(type) {
case engine.Atom:
bech32Addr, err = sdk.AccAddressFromBech32(acc.String())
if err != nil {
return engine.Error(fmt.Errorf("bank_spendable_coins/2: %w", err))
}

fetchedBalances := SpendableCoinsSorted(sdkContext, bankKeeper, bech32Addr)

return engine.Unify(vm, CoinsToTerm(fetchedBalances), balances, cont, env)
default:
return engine.Error(fmt.Errorf("bank_spendable_coins/2: cannot unify account address with %T", acc))
}

})
}
22 changes: 16 additions & 6 deletions x/logic/predicate/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,24 @@ import (
"github.com/okp4/okp4d/x/logic/types"
)

// BalancesSorted returns the list of balances for the given address, sorted by coin denomination.
func BalancesSorted(sdkContext sdk.Context, bankKeeper types.BankKeeper, bech32Addr sdk.AccAddress) sdk.Coins {
fetchedBalances := bankKeeper.GetAllBalances(sdkContext, bech32Addr)
sort.SliceStable(fetchedBalances, func(i, j int) bool {
return fetchedBalances[i].Denom < fetchedBalances[j].Denom
// BalancesSorted returns given balances sorted by coin denomination.
func BalancesSorted(balances sdk.Coins) sdk.Coins {
sort.SliceStable(balances, func(i, j int) bool {
return balances[i].Denom < balances[j].Denom
})
return balances
}

// AllBalancesSorted returns the list of balances for the given address, sorted by coin denomination.
func AllBalancesSorted(sdkContext sdk.Context, bankKeeper types.BankKeeper, bech32Addr sdk.AccAddress) sdk.Coins {
fetchedBalances := bankKeeper.GetAllBalances(sdkContext, bech32Addr)
return BalancesSorted(fetchedBalances)
}

return fetchedBalances
// SpendableCoinsSorted returns the list of spendable coins for the given address, sorted by coin denomination.
func SpendableCoinsSorted(sdkContext sdk.Context, bankKeeper types.BankKeeper, bech32Addr sdk.AccAddress) sdk.Coins {
fetchedBalances := bankKeeper.SpendableCoins(sdkContext, bech32Addr)
return BalancesSorted(fetchedBalances)
}

// CoinsToTerm converts the given coins to a term of the form:
Expand Down

0 comments on commit e7acefa

Please sign in to comment.