Skip to content

Instantly share code, notes, and snippets.

@ducphamle2
Created October 23, 2024 06:17
Show Gist options
  • Save ducphamle2/eda30e1709c94cffa76ca603963fde7d to your computer and use it in GitHub Desktop.
Save ducphamle2/eda30e1709c94cffa76ca603963fde7d to your computer and use it in GitHub Desktop.

Revisions

  1. ducphamle2 created this gist Oct 23, 2024.
    79 changes: 79 additions & 0 deletions feegrant-osmosis.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    import { stringToPath } from '@cosmjs/crypto';
    import { coins, DirectSecp256k1HdWallet, EncodeObject } from '@cosmjs/proto-signing';
    import { SigningStargateClient, GasPrice } from '@cosmjs/stargate';
    import { OfflineDirectSigner } from '@keplr-wallet/types';
    import { PeriodicAllowance } from 'cosmjs-types/cosmos/feegrant/v1beta1/feegrant';
    import { MsgGrantAllowance } from 'cosmjs-types/cosmos/feegrant/v1beta1/tx';
    import dotenv from 'dotenv';
    dotenv.config();

    const numOfMsToExpiration = (numOfMs: number) => {
    const dateNow = new Date();
    const dateIn2Years = new Date(dateNow.getTime() + numOfMs);
    const timeMS = dateIn2Years.getTime();
    return {
    seconds: BigInt(Math.round(timeMS / 1000)),
    nanos: (timeMS % 1000) * 1e6,
    };
    };

    export function createFeeGrantMsg(
    granter: string,
    grantee: string,
    base: string,
    decimals: number,
    amount: bigint = 1n,
    ): EncodeObject {
    const periodicAllowance = PeriodicAllowance.fromPartial({
    period: numOfMsToExpiration(100),
    periodSpendLimit: coins((amount * 10n ** BigInt(decimals)).toString(), base),
    periodCanSpend: coins((amount * 10n ** BigInt(decimals)).toString(), base),
    });
    const grantMsg = MsgGrantAllowance.fromPartial({
    grantee,
    granter,
    allowance: {
    typeUrl: PeriodicAllowance.typeUrl,
    value: PeriodicAllowance.encode(periodicAllowance).finish(),
    },
    });
    return {
    typeUrl: MsgGrantAllowance.typeUrl,
    value: grantMsg,
    };
    }

    export async function getOfflineSignerAndSigningClient(
    rpc: string,
    prefix: string,
    coinType: number,
    gasPrice: string,
    ): Promise<{ signer: OfflineDirectSigner; client: SigningStargateClient }> {
    const signer = await DirectSecp256k1HdWallet.fromMnemonic(process.env.MNEMONIC, {
    prefix,
    hdPaths: [stringToPath(`m/44'/${coinType}'/0'/0/0`)],
    });
    const client = await SigningStargateClient.connectWithSigner(rpc, signer, {
    gasPrice: GasPrice.fromString(gasPrice),
    });

    return { signer, client };
    }

    (async () => {
    const { signer, client } = await getOfflineSignerAndSigningClient(
    'https://osmosis.rpc.orai.io',
    'osmo',
    118,
    '0.006uosmo',
    );
    const acc = (await signer.getAccounts())[0];
    const message = createFeeGrantMsg(
    acc.address,
    'osmo14h0n2nlfrfz8tn9usfyjrxqd23fhj9a0zs2jvl',
    'uosmo',
    6,
    );
    const result = await client.signAndBroadcast(acc.address, [message], 'auto');
    console.log(result);
    })();