• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Mintbase / mintbase-js / 13994325548

21 Mar 2025 02:43PM CUT coverage: 77.007%. First build
13994325548

Pull #555

github

rubenmarcus
deprecate packages
Pull Request #555: deprecate react and wallet packages

890 of 1336 branches covered (66.62%)

Branch coverage included in aggregate %.

1153 of 1317 relevant lines covered (87.55%)

15.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.16
/packages/sdk/src/execute/execute.utils.ts
1
import type { Wallet, FinalExecutionOutcome } from '@near-wallet-selector/core';
2
import type { providers, Account } from 'near-api-js';
3
import type {
4
  CallBackArgs,
5
  ContractCall,
6
  TxnOptionalSignerId,
7
  NearExecuteOptions,
8
  ExecuteArgsResponse,
9
  ComposableCall,
10
} from '../types';
11
import { NoSigningMethodPassedError } from '../errors';
3✔
12

13
/**
14
 * checkCallbackUrl()
15
 * method to check if its a regular browser wallet or a InjectedWallet, and make them have the same behavior (redirect) to the desired url.
16
 * @param callbackUrl url that should redirect after transaction
17
 * @param callbackArgs metadata that should be passed via url to the success page
18
 * @returns an outcome object or an array of outcome objects if batching calls {@link FinalExecutionOutcome[]} | {@link FinalExecutionOutcome}, or a redirect to selected callbackUrl
19
 */
20
export const checkCallbackUrl = (
3✔
21
  callbackUrl: string,
22
  callbackArgs: CallBackArgs,
23
  wallet: Wallet,
24
  outcomes: void | FinalExecutionOutcome[],
25
): void | FinalExecutionOutcome[] | FinalExecutionOutcome => {
26
  const isNotBrowserWallet = wallet?.type !== 'browser';
18✔
27
  const hasCallbackUrl = Boolean(
18✔
28
    typeof window !== 'undefined' && callbackUrl?.length > 0,
12!
29
  );
30

31
  if (hasCallbackUrl && isNotBrowserWallet) {
18!
32
    const { transactionHash } = checkTransactionHash(outcomes);
×
33

34
    let finalUrl = `${callbackUrl}?transactionHashes=${transactionHash}`;
×
35

36
    if (callbackArgs) {
×
37
      const args = JSON.stringify({
×
38
        type: callbackArgs?.type ?? '',
×
39
        args: callbackArgs?.args ?? '',
×
40
      });
41

42
      const signMeta = encodeURIComponent(args);
×
43

44
      finalUrl = `${callbackUrl}?transactionHashes=${transactionHash}&signMeta=${signMeta}`;
×
45
    }
46
    return window.location.assign(finalUrl);
×
47
  }
48

49
  return outcomes && outcomes.length == 1 ? outcomes[0] : outcomes;
18✔
50
};
51

52
/**
53
 * checkTransactionHash()
54
 * check what transaction receipt to return to the user.
55
 * @param receipt near transaction Receipt object
56
 * @returns transactionHash object
57
 */
58
const checkTransactionHash = (receipt): { transactionHash: string } => {
3✔
59
  let transactionHash = receipt?.transaction_outcome?.id;
×
60

61
  if (receipt?.length == 1) {
×
62
    transactionHash = receipt[0]?.transaction_outcome?.id;
×
63
  }
64

65
  if (receipt?.length > 1) {
×
66
    transactionHash = receipt[1]?.transaction_outcome?.id;
×
67
  }
68

69
  return { transactionHash };
×
70
};
71

72
export const callbackUrlFormatter = (
3✔
73
  callbackUrl: string,
74
  callbackArgs: CallBackArgs,
75
): string => {
76
  let url =
77
    callbackUrl && typeof callbackUrl !== 'undefined' ? callbackUrl : null;
18✔
78

79
  if (callbackArgs?.type && callbackUrl) {
18!
80
    const args = JSON.stringify({
×
81
      type: callbackArgs?.type,
×
82
      args: callbackArgs?.args,
×
83
    });
84

85
    const signMeta = encodeURIComponent(args);
×
86
    url = `${callbackUrl}?signMeta=${signMeta}`;
×
87
  }
88

89
  return url;
18✔
90
};
91

92
export const genericBatchExecute = async (
3✔
93
  call: ContractCall<ExecuteArgsResponse>[],
94
  wallet: Wallet,
95
  account: Account,
96
  callbackUrl: string,
97
  callbackArgs: CallBackArgs,
98
): Promise<void | providers.FinalExecutionOutcome[]> => {
18✔
99
  const url = callbackUrlFormatter(callbackUrl, callbackArgs);
18✔
100
  if (wallet) {
18✔
101
    return url
9✔
102
      ? batchExecuteWithBrowserWallet(call, wallet, url, callbackArgs)
103
      : batchExecuteWithBrowserWallet(call, wallet);
104
  }
105
  return batchExecuteWithNearAccount(call, account, url);
9✔
106
};
107

108
// account call translation wrappers https://docs.near.org/tools/near-api-js/faq#how-to-send-batch-transactions
109
// TODO: share batch signature with wallet selector sendAndSignTransaction when method becomes public
110
const batchExecuteWithNearAccount = async (
3✔
111
  calls: ContractCall<ExecuteArgsResponse>[],
112
  account: Account,
113
  callbackUrl?: string,
114
): Promise<FinalExecutionOutcome[]> => {
9✔
115
  const outcomes: FinalExecutionOutcome[] = [];
9✔
116
  for (const call of calls) {
9✔
117
    try {
27✔
118
      outcomes.push(
27✔
119
        await account.functionCall({
120
          contractId: call.contractAddress,
121
          methodName: call.methodName,
122
          args: call.args,
123
          gas: BigInt(call.gas),
124
          attachedDeposit: BigInt(call.deposit),
125
          ...(callbackUrl && { walletCallbackUrl: callbackUrl }),
18!
126
        }),
127
      );
128
    } catch (err: unknown) {
129
      console.error(
9✔
130
        `${call.contractAddress}:${call.methodName} in batch failed: ${err}`,
131
      );
132
    }
133
  }
134

135
  return outcomes;
9✔
136
};
137

138
const batchExecuteWithBrowserWallet = async (
3✔
139
  calls: ContractCall<ExecuteArgsResponse>[],
140
  wallet: Wallet,
141
  callback?: string,
142
  callbackArgs?: CallBackArgs,
143
): Promise<void | FinalExecutionOutcome[]> => {
9✔
144
  const res = await wallet.signAndSendTransactions({
9✔
145
    transactions: calls.map(
146
      convertGenericCallToWalletCall,
147
    ) as TxnOptionalSignerId[],
148
    ...(callback && { callbackUrl: callback }),
8✔
149
    ...(callbackArgs && { callbackArgs: callbackArgs }),
6!
150
  });
151

152
  return res;
9✔
153
};
154

155
export const convertGenericCallToWalletCall = (
3✔
156
  call: ContractCall<ExecuteArgsResponse>,
157
): TxnOptionalSignerId => {
158
  return {
15✔
159
    signerId: call.signerId,
160
    receiverId: call.contractAddress,
161
    actions: [
162
      {
163
        type: 'FunctionCall',
164
        params: {
165
          methodName: call.methodName,
166
          args: call.args,
167
          gas: call.gas as string,
168
          deposit: call.deposit as string,
169
        },
170
      },
171
    ],
172
  };
173
};
174

175
export function flattenArgs(
3✔
176
  calls: ComposableCall[],
177
): ContractCall<ExecuteArgsResponse>[] {
178
  const contractCalls: ContractCall<ExecuteArgsResponse>[] = [];
18✔
179
  for (const call of calls) {
18✔
180
    if (
33✔
181
      call instanceof Array &&
38✔
182
      call.length > 0 &&
183
      (call as ContractCall<ExecuteArgsResponse>[])
184
    ) {
185
      call.map((item: ComposableCall) =>
12✔
186
        contractCalls.push(item as ContractCall<ExecuteArgsResponse>),
21✔
187
      );
188
    } else {
189
      contractCalls.push(call as ContractCall<ExecuteArgsResponse>);
21✔
190
    }
191
  }
192
  return contractCalls;
18✔
193
}
194

195
export const validateSigningOptions = ({
3✔
196
  wallet,
197
  account,
198
}: NearExecuteOptions): void => {
199
  if (!wallet && !account) {
21✔
200
    throw NoSigningMethodPassedError;
3✔
201
  }
202
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc