Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/slow-parents-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wagemos-graz-nextjs": patch
"@abstract-money/core": patch
"@abstract-money/react": patch
---

Introduces new hooks for the savings app.
5 changes: 5 additions & 0 deletions .changeset/spicy-shoes-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@abstract-money/core": patch
---

Added authz utils and util to retrieve account address before creation.
786 changes: 0 additions & 786 deletions .yarn/releases/yarn-3.2.1.cjs

This file was deleted.

2 changes: 1 addition & 1 deletion examples/wagemos-cosmoskit-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"chain-registry": "^1.18.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cosmjs-types": "^0.8.0",
"cosmjs-types": "^0.9.0",
"long": "^5.2.3",
"lucide-react": "^0.293.0",
"next": "14.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function useBettingBetsQuery<TData = BetsResponse>({
args,
options
}: BettingBetsQuery<TData>) {
return useQuery<BetsResponse, Error, TData>(bettingQueryKeys.bets(client?.moduleId, args), () => client && args ? client.bets({
return useQuery<BetsResponse, Error, TData>(bettingQueryKeys.bets(client?.moduleId, args), () => client && args ? client.bets({
roundId: args.roundId
}) : Promise.reject(new Error("Invalid client or args")), { ...options, enabled: !!args && !!client && (options?.enabled != undefined ? options.enabled : true)
});
Expand All @@ -81,7 +81,7 @@ export function useBettingListOddsQuery<TData = ListOddsResponse>({
args,
options
}: BettingListOddsQuery<TData>) {
return useQuery<ListOddsResponse, Error, TData>(bettingQueryKeys.listOdds(client?.moduleId, args), () => client && args ? client.listOdds({
return useQuery<ListOddsResponse, Error, TData>(bettingQueryKeys.listOdds(client?.moduleId, args), () => client && args ? client.listOdds({
roundId: args.roundId
}) : Promise.reject(new Error("Invalid client or args")), { ...options, enabled: !!args && !!client && (options?.enabled != undefined ? options.enabled : true)
});
Expand All @@ -97,7 +97,7 @@ export function useBettingOddsQuery<TData = OddsResponse>({
args,
options
}: BettingOddsQuery<TData>) {
return useQuery<OddsResponse, Error, TData>(bettingQueryKeys.odds(client?.moduleId, args), () => client && args ? client.odds({
return useQuery<OddsResponse, Error, TData>(bettingQueryKeys.odds(client?.moduleId, args), () => client && args ? client.odds({
roundId: args.roundId,
teamId: args.teamId
}) : Promise.reject(new Error("Invalid client or args")), { ...options, enabled: !!args && !!client && (options?.enabled != undefined ? options.enabled : true)
Expand All @@ -114,7 +114,7 @@ export function useBettingListRoundsQuery<TData = RoundsResponse>({
args,
options
}: BettingListRoundsQuery<TData>) {
return useQuery<RoundsResponse, Error, TData>(bettingQueryKeys.listRounds(client?.moduleId, args), () => client && args ? client.listRounds({
return useQuery<RoundsResponse, Error, TData>(bettingQueryKeys.listRounds(client?.moduleId, args), () => client && args ? client.listRounds({
limit: args.limit,
startAfter: args.startAfter
}) : Promise.reject(new Error("Invalid client or args")), { ...options, enabled: !!args && !!client && (options?.enabled != undefined ? options.enabled : true)
Expand All @@ -130,7 +130,7 @@ export function useBettingRoundQuery<TData = RoundResponse>({
args,
options
}: BettingRoundQuery<TData>) {
return useQuery<RoundResponse, Error, TData>(bettingQueryKeys.round(client?.moduleId, args), () => client && args ? client.round({
return useQuery<RoundResponse, Error, TData>(bettingQueryKeys.round(client?.moduleId, args), () => client && args ? client.round({
roundId: args.roundId
}) : Promise.reject(new Error("Invalid client or args")), { ...options, enabled: !!args && !!client && (options?.enabled != undefined ? options.enabled : true)
});
Expand Down
10 changes: 5 additions & 5 deletions examples/wagemos-cosmoskit-nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={cn(inter.variable, poppins.variable)}>
<CosmosKitProvider>
<CosmosKitProvider>
<body className={cn(inter.variable, poppins.variable)}>
<AbstractProvider config={abstractConfig}>
<AbstractAccountIdProvider
accountId={stringToAccountId('neutron-18')}
Expand All @@ -42,9 +42,9 @@ export default function RootLayout({
</main>
</AbstractAccountIdProvider>
</AbstractProvider>
</CosmosKitProvider>
<Toaster />
</body>
<Toaster />
</body>
</CosmosKitProvider>
</html>
)
}
4 changes: 3 additions & 1 deletion examples/wagemos-graz-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"typecheck": "tsc --noEmit",
"lint": "next lint",
"postinstall": "pnpm generate",
"generate": "graz generate -g -M neutron -T neutrontestnet"
"generate": "graz generate -g -M neutron,osmosis -T neutrontestnet,osmosistestnet"
},
"dependencies": {
"@abstract-money/core": "workspace:*",
Expand All @@ -23,6 +23,8 @@
"@cosmjs/stargate": "^0.31.0",
"@cosmjs/tendermint-rpc": "^0.31.0",
"@hookform/resolvers": "^3.3.2",
"@osmosis-labs/math": "^5.1.0",
"@osmosis-labs/proto-codecs": "^5.1.0",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useToast } from '../../components/ui/use-toast'
function DisconnectButton() {
const { disconnect } = useDisconnect()
const { data: account } = useAccount({
chainId: 'neutron-1',
chainId: 'osmosis-1',
})

const { toast } = useToast()
Expand Down Expand Up @@ -55,7 +55,7 @@ function ConnectButton() {
const { toast } = useToast()

const { isConnecting } = useAccount({
chainId: 'neutron-1',
chainId: 'osmosis-1',
onConnect: ({ walletType, chains }) => {
toast({
title: `Wallet connected! using ${walletType} to ${chains.map(
Expand All @@ -73,7 +73,7 @@ function ConnectButton() {
const { connect } = useConnect()

const handleConnect = (wallet: WalletType) => {
connect({ walletType: wallet, chainId: 'neutron-1' })
connect({ walletType: wallet, chainId: 'osmosis-1' })
setIsOpen(false)
}
return (
Expand Down Expand Up @@ -107,7 +107,7 @@ function ConnectButton() {

export function WalletButton() {
const { isConnected } = useAccount({
chainId: 'neutron-1',
chainId: ['neutron-1', 'osmosis-1'],
})
if (isConnected) {
return <DisconnectButton />
Expand Down
8 changes: 7 additions & 1 deletion examples/wagemos-graz-nextjs/src/app/_providers/graz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ export function GrazProvider(props: PropsWithChildren) {
return (
<Provider
grazOptions={{
chains: [mainnetChains.neutron],
chains: [mainnetChains.neutron, mainnetChains.osmosis],
chainsConfig: {
[mainnetChains.osmosis.chainId]: {
gas: {
price: '0.25',
denom: 'osmo',
},
},
[mainnetChains.neutron.chainId]: {
gas: {
price: '0.1',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
export interface Root {
result: Result
}

export interface Result {
data: Data
}

export interface Data {
json: Json
meta: Meta
}

export interface Json {
id: string
type: string
raw: Raw
spreadFactor: string
reserveCoins: string[]
totalFiatValueLocked: string
coinDenoms: string[]
}

export interface Raw {
address: string
incentives_address: string
spread_rewards_address: string
id: string
current_tick_liquidity: string
token0: string
token1: string
current_sqrt_price: string
current_tick: string
tick_spacing: string
exponent_at_price_one: string
spread_factor: string
last_liquidity_update: string
}

export interface Meta {
values: Values
}

export interface Values {
spreadFactor: string[][]
'reserveCoins.0': string[][]
'reserveCoins.1': string[][]
totalFiatValueLocked: string[][]
}

const GET_POOL_DATA_LINK =
'/osmosis/pools-edge-trpc/pools.getPool?input=%7B%22json%22%3A%7B%22poolId%22%3A%221220%22%7D%7D'

const EXCHANGES = ['osmosis']

export async function prepareInstantiateMsg() {
const poolData = (await fetch(GET_POOL_DATA_LINK).then((res) =>
res.json(),
)) as Root
console.log(poolData)
const tick = BigInt(poolData.result.data.json.raw.current_tick)
const tickSpacing = BigInt(poolData.result.data.json.raw.tick_spacing)
const sqrtPrice = poolData.result.data.json.raw.current_sqrt_price
// transforming dot-notated sqrtPrice to get the most precise pool ratio
const amount0FromPrice = BigInt(sqrtPrice.replace('.', '')) ** 2n
// getting `ratio1` as if we would have swapped all `amount0FromPrice` to `ratio1`
// to do that, we transform `amount0FromPrice` to string and replace all [1, ...] symbols to zero.
// it is safe to do so as we just need the ratio, and the `amount1FromPrice = amount0FromPrice / sqrtPrice^2`
const amount1FromPrice = BigInt(
`1${Array.from({
length: amount0FromPrice.toString().length - 1,
})
.fill('0')
.join('')}`,
)

const lowerTick = tick - (tick % tickSpacing)
const higherTick = tick + (tickSpacing - (tick % tickSpacing))

console.log({ amount0FromPrice, amount1FromPrice, lowerTick, higherTick })
}
128 changes: 128 additions & 0 deletions examples/wagemos-graz-nextjs/src/app/authz-osmosis/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
'use client'
import {
BankTransactionTypeUrl,
encodeAuthzExecMsg,
encodeAuthzGrantGenericAuthorizationMsg,
encodeAuthzGrantSendAuthorizationMsg,
encodeBankSendMsg,
stringToAccountId,
} from '@abstract-money/core/utils'

import {
useAccountFactoryQueryClientFromApi,
useCreateAccountMonarchy,
useSignAndBroadcast,
} from '@abstract-money/react'
import { useAccount } from 'graz'
import { useCallback, useEffect, useMemo } from 'react'
import { Button } from '../../components/ui/button'
import { WalletButton } from '../_components/wallet-button'
import { prepareInstantiateMsg } from './_utils/prepare-instantiate-msg'

const GRANTER = 'osmo1jzyqffltm2s5wxmnjyze5hzrpcady0gmpz738n'
const GRANTEE = 'osmo1ak64euh4tyzetkny6t0y0v5tw47n3y6y0ys3md'

export default function AuthzPage() {
useEffect(() => {
prepareInstantiateMsg()
}, [])

const { mutate: signAndBroadcast } = useSignAndBroadcast({
args: { chainName: 'osmosis' },
})
const { data: account } = useAccount({ chainId: 'osmosis-1' })

const { data: accountFactory, isLoading } =
useAccountFactoryQueryClientFromApi('osmosis')

const { mutate: createAccount } = useCreateAccountMonarchy({
args: { chainName: 'osmosis' },
})

const onCreateAccount = useCallback(async () => {
if (!accountFactory || !account)
throw new Error('no account factory or account')

const config = await accountFactory.config()
const sequence = config.local_account_sequence + 1

createAccount({
fee: 'auto',
args: {
name: 'funny-squid',
accountId: stringToAccountId(`local-${sequence}`, 'osmosis'),
owner: account.bech32Address,
},
})
}, [accountFactory])

const onGrantAuthzClick = useMemo(() => {
if (!account) return undefined

return () => {
signAndBroadcast({
fee: 'auto',
args: {
messages: [
...[
'/osmosis.concentratedliquidity.v1beta1.MsgCreatePosition',
'/osmosis.poolmanager.v1beta1.MsgSplitRouteSwapExactAmountIn',
'/osmosis.concentratedliquidity.v1beta1.MsgAddToPosition',
'/osmosis.concentratedliquidity.v1beta1.MsgWithdrawPosition',
'/osmosis.concentratedliquidity.v1beta1.MsgCollectIncentives',
'/osmosis.concentratedliquidity.v1beta1.MsgCollectSpreadRewards',
].map((typeUrl) =>
encodeAuthzGrantGenericAuthorizationMsg(
account.bech32Address,
GRANTEE,
typeUrl,
),
),
encodeAuthzGrantGenericAuthorizationMsg(
account.bech32Address,
GRANTEE,
BankTransactionTypeUrl.Send,
),
encodeAuthzGrantSendAuthorizationMsg(
account.bech32Address,
GRANTEE,
{ spendLimit: [{ denom: 'uosmo', amount: '100' }] },
),
],
},
})
}
}, [signAndBroadcast])

const onTransferClick = useMemo(() => {
if (!account) return undefined

return () => {
signAndBroadcast({
fee: 'auto',
args: {
messages: [
encodeAuthzExecMsg(account.bech32Address, [
encodeBankSendMsg(GRANTER, account.bech32Address, [
{ denom: 'uosmo', amount: '100' },
]),
]),
],
},
})
}
}, [signAndBroadcast])

return (
<>
<Button onClick={onGrantAuthzClick}> Grant AuthZ</Button>
<Button onClick={onTransferClick}> Transfer</Button>
{isLoading ? (
'Loading'
) : (
<Button onClick={onCreateAccount}>Create Account</Button>
)}
<WalletButton />
</>
)
}
Loading