Skip to content

Commit

Permalink
Add useTransaction hook
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitayutanov committed Jul 5, 2024
1 parent c396c3d commit a66e14b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
37 changes: 37 additions & 0 deletions idea/frontend/src/pages/programs/ui/use-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useAccount } from '@gear-js/react-hooks';
import { web3FromSource } from '@polkadot/extension-dapp';
import { TransactionBuilder } from 'sails-js';

type FunctionName<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => TransactionBuilder<any> ? K : never;
}[keyof T];

type NonServiceKeys = 'api' | 'registry' | 'programId' | 'newCtorFromCode' | 'newCtorFromCodeId';

function useTransaction<
TProgram,
TServiceName extends Exclude<keyof TProgram, NonServiceKeys>,
TFunctionName extends FunctionName<TProgram[TServiceName]>,
>(program: TProgram | undefined, serviceName: TServiceName, functionName: TFunctionName) {
const { account } = useAccount();

type FunctionType = TProgram[TServiceName][TFunctionName] extends (...args: infer A) => TransactionBuilder<infer R>
? (...args: A) => TransactionBuilder<R>
: never;

return async (...args: Parameters<FunctionType>) => {
if (!program) throw new Error('Program is not found');
if (!account) throw new Error('Account is not found');

const transaction = (program[serviceName][functionName] as FunctionType)(...args) as ReturnType<FunctionType>;

const { address, meta } = account;
const { signer } = await web3FromSource(meta.source);
transaction.withAccount(address, { signer });

return transaction;
};
}

export { useTransaction };
3 changes: 2 additions & 1 deletion utils/gear-hooks/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
UseSendMessageWithGasOptions,
SendMessageWithGasOptions,
} from './handlers';
import { useProgram, UseProgramParameters } from './sails';
import { useProgram, UseProgramParameters, useTransaction } from './sails';

export {
useReadFullState,
Expand Down Expand Up @@ -72,6 +72,7 @@ export {
useIssuedVouchers,
useAccountIssuedVouchers,
useProgram,
useTransaction,
};

export type {
Expand Down
3 changes: 2 additions & 1 deletion utils/gear-hooks/src/hooks/sails/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useProgram, UseProgramParameters } from './use-program';
import { useTransaction } from './use-transaction';

export { useProgram };
export { useProgram, useTransaction };
export type { UseProgramParameters };
37 changes: 37 additions & 0 deletions utils/gear-hooks/src/hooks/sails/use-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useAccount } from '@gear-js/react-hooks';
import { web3FromSource } from '@polkadot/extension-dapp';
import { TransactionBuilder } from 'sails-js';

type FunctionName<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => TransactionBuilder<any> ? K : never;
}[keyof T];

type NonServiceKeys = 'api' | 'registry' | 'programId' | 'newCtorFromCode' | 'newCtorFromCodeId';

function useTransaction<
TProgram,
TServiceName extends Exclude<keyof TProgram, NonServiceKeys>,
TFunctionName extends FunctionName<TProgram[TServiceName]>,
>(program: TProgram | undefined, serviceName: TServiceName, functionName: TFunctionName) {
const { account } = useAccount();

type FunctionType = TProgram[TServiceName][TFunctionName] extends (...args: infer A) => TransactionBuilder<infer R>
? (...args: A) => TransactionBuilder<R>
: never;

return async (...args: Parameters<FunctionType>) => {
if (!program) throw new Error('Program is not found');
if (!account) throw new Error('Account is not found');

const transaction = (program[serviceName][functionName] as FunctionType)(...args) as ReturnType<FunctionType>;

const { address, meta } = account;
const { signer } = await web3FromSource(meta.source);
transaction.withAccount(address, { signer });

return transaction;
};
}

export { useTransaction };
2 changes: 2 additions & 0 deletions utils/gear-hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
SendMessageWithGasOptions,
useProgram,
UseProgramParameters,
useTransaction,
} from './hooks';

import { withoutCommas, getVaraAddress, getTypedEntries } from './utils';
Expand Down Expand Up @@ -109,6 +110,7 @@ export {
useIssuedVouchers,
useAccountIssuedVouchers,
useProgram,
useTransaction,
DEFAULT_OPTIONS,
DEFAULT_INFO_OPTIONS,
DEFAULT_ERROR_OPTIONS,
Expand Down

0 comments on commit a66e14b

Please sign in to comment.