near-safe 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/lib/bundler.d.ts +5 -2
- package/dist/cjs/lib/bundler.js +3 -2
- package/dist/cjs/near-safe.d.ts +3 -3
- package/dist/cjs/near-safe.js +6 -6
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/util.d.ts +26 -0
- package/dist/cjs/util.js +65 -1
- package/dist/esm/lib/bundler.d.ts +5 -2
- package/dist/esm/lib/bundler.js +3 -2
- package/dist/esm/near-safe.d.ts +3 -3
- package/dist/esm/near-safe.js +6 -6
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/util.d.ts +26 -0
- package/dist/esm/util.js +65 -3
- package/package.json +3 -3
@@ -1,9 +1,12 @@
|
|
1
1
|
import { Address, Hash, PublicClient, Transport } from "viem";
|
2
2
|
import { GasPrices, PaymasterData, UnsignedUserOperation, UserOperation, UserOperationReceipt } from "../types";
|
3
|
+
type SponsorshipPolicy = {
|
4
|
+
sponsorshipPolicyId: string;
|
5
|
+
};
|
3
6
|
type BundlerRpcSchema = [
|
4
7
|
{
|
5
8
|
Method: "pm_sponsorUserOperation";
|
6
|
-
Parameters: [UnsignedUserOperation, Address];
|
9
|
+
Parameters: [UnsignedUserOperation, Address, SponsorshipPolicy];
|
7
10
|
ReturnType: PaymasterData;
|
8
11
|
},
|
9
12
|
{
|
@@ -28,7 +31,7 @@ export declare class Erc4337Bundler {
|
|
28
31
|
apiKey: string;
|
29
32
|
chainId: number;
|
30
33
|
constructor(entryPointAddress: Address, apiKey: string, chainId: number);
|
31
|
-
getPaymasterData(rawUserOp: UnsignedUserOperation,
|
34
|
+
getPaymasterData(rawUserOp: UnsignedUserOperation, safeNotDeployed: boolean, sponsorshipPolicy?: string): Promise<PaymasterData>;
|
32
35
|
sendUserOperation(userOp: UserOperation): Promise<Hash>;
|
33
36
|
getGasPrice(): Promise<GasPrices>;
|
34
37
|
getUserOpReceipt(userOpHash: Hash): Promise<UserOperationReceipt>;
|
package/dist/cjs/lib/bundler.js
CHANGED
@@ -17,15 +17,16 @@ class Erc4337Bundler {
|
|
17
17
|
rpcSchema: (0, viem_1.rpcSchema)(),
|
18
18
|
});
|
19
19
|
}
|
20
|
-
async getPaymasterData(rawUserOp,
|
20
|
+
async getPaymasterData(rawUserOp, safeNotDeployed, sponsorshipPolicy) {
|
21
21
|
// TODO: Keep this option out of the bundler
|
22
|
-
if (
|
22
|
+
if (sponsorshipPolicy) {
|
23
23
|
console.log("Requesting paymaster data...");
|
24
24
|
return handleRequest(() => this.client.request({
|
25
25
|
method: "pm_sponsorUserOperation",
|
26
26
|
params: [
|
27
27
|
{ ...rawUserOp, signature: util_1.PLACEHOLDER_SIG },
|
28
28
|
this.entryPointAddress,
|
29
|
+
{ sponsorshipPolicyId: sponsorshipPolicy },
|
29
30
|
],
|
30
31
|
}));
|
31
32
|
}
|
package/dist/cjs/near-safe.d.ts
CHANGED
@@ -70,7 +70,7 @@ export declare class NearSafe {
|
|
70
70
|
buildTransaction(args: {
|
71
71
|
chainId: number;
|
72
72
|
transactions: MetaTransaction[];
|
73
|
-
|
73
|
+
sponsorshipPolicy?: string;
|
74
74
|
}): Promise<UserOperation>;
|
75
75
|
/**
|
76
76
|
* Signs a transaction with the NEAR adapter using the provided operation hash.
|
@@ -93,7 +93,7 @@ export declare class NearSafe {
|
|
93
93
|
* @param {boolean} usePaymaster - Flag indicating whether to use a paymaster for gas fees. If true, the transaction will be sponsored by the paymaster.
|
94
94
|
* @returns {Promise<EncodedTxData>} - A promise that resolves to the encoded transaction data for the NEAR and EVM networks.
|
95
95
|
*/
|
96
|
-
encodeSignRequest(signRequest: SignRequestData,
|
96
|
+
encodeSignRequest(signRequest: SignRequestData, sponsorshipPolicy?: string): Promise<EncodedTxData>;
|
97
97
|
/**
|
98
98
|
* Broadcasts a user operation to the EVM network with a provided signature.
|
99
99
|
* Warning: Uses a private ethRPC with sensitive Pimlico API key (should be run server side).
|
@@ -173,7 +173,7 @@ export declare class NearSafe {
|
|
173
173
|
* - Returns a promise that resolves to an object containing the Ethereum Virtual Machine (EVM) message,
|
174
174
|
* the payload (hashed data), and recovery data needed for reconstructing the signature request.
|
175
175
|
*/
|
176
|
-
requestRouter({ method, chainId, params }: SignRequestData,
|
176
|
+
requestRouter({ method, chainId, params }: SignRequestData, sponsorshipPolicy?: string): Promise<{
|
177
177
|
evmMessage: string;
|
178
178
|
payload: number[];
|
179
179
|
hash: Hash;
|
package/dist/cjs/near-safe.js
CHANGED
@@ -87,7 +87,7 @@ class NearSafe {
|
|
87
87
|
* @throws {Error} - Throws an error if the transaction set is empty or if any operation fails during the building process.
|
88
88
|
*/
|
89
89
|
async buildTransaction(args) {
|
90
|
-
const { transactions,
|
90
|
+
const { transactions, sponsorshipPolicy, chainId } = args;
|
91
91
|
if (transactions.length === 0) {
|
92
92
|
throw new Error("Empty transaction set!");
|
93
93
|
}
|
@@ -101,7 +101,7 @@ class NearSafe {
|
|
101
101
|
// Build Singular MetaTransaction for Multisend from transaction list.
|
102
102
|
const tx = transactions.length > 1 ? (0, multisend_1.encodeMulti)(transactions) : transactions[0];
|
103
103
|
const rawUserOp = await this.safePack.buildUserOp(nonce, tx, this.address, gasFees.fast, this.setup, !safeDeployed, this.safeSaltNonce);
|
104
|
-
const paymasterData = await bundler.getPaymasterData(rawUserOp,
|
104
|
+
const paymasterData = await bundler.getPaymasterData(rawUserOp, !safeDeployed, sponsorshipPolicy);
|
105
105
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
106
106
|
return unsignedUserOp;
|
107
107
|
}
|
@@ -131,8 +131,8 @@ class NearSafe {
|
|
131
131
|
* @param {boolean} usePaymaster - Flag indicating whether to use a paymaster for gas fees. If true, the transaction will be sponsored by the paymaster.
|
132
132
|
* @returns {Promise<EncodedTxData>} - A promise that resolves to the encoded transaction data for the NEAR and EVM networks.
|
133
133
|
*/
|
134
|
-
async encodeSignRequest(signRequest,
|
135
|
-
const { payload, evmMessage, hash } = await this.requestRouter(signRequest,
|
134
|
+
async encodeSignRequest(signRequest, sponsorshipPolicy) {
|
135
|
+
const { payload, evmMessage, hash } = await this.requestRouter(signRequest, sponsorshipPolicy);
|
136
136
|
return {
|
137
137
|
nearPayload: await this.nearAdapter.mpcContract.encodeSignatureRequestTx({
|
138
138
|
path: this.nearAdapter.derivationPath,
|
@@ -283,7 +283,7 @@ class NearSafe {
|
|
283
283
|
* - Returns a promise that resolves to an object containing the Ethereum Virtual Machine (EVM) message,
|
284
284
|
* the payload (hashed data), and recovery data needed for reconstructing the signature request.
|
285
285
|
*/
|
286
|
-
async requestRouter({ method, chainId, params },
|
286
|
+
async requestRouter({ method, chainId, params }, sponsorshipPolicy) {
|
287
287
|
const safeInfo = {
|
288
288
|
address: { value: this.address },
|
289
289
|
chainId: chainId.toString(),
|
@@ -318,7 +318,7 @@ class NearSafe {
|
|
318
318
|
const userOp = await this.buildTransaction({
|
319
319
|
chainId,
|
320
320
|
transactions,
|
321
|
-
|
321
|
+
...(sponsorshipPolicy ? { sponsorshipPolicy } : {}),
|
322
322
|
});
|
323
323
|
const opHash = await this.opHash(chainId, userOp);
|
324
324
|
return {
|
package/dist/cjs/types.d.ts
CHANGED
@@ -80,7 +80,7 @@ export interface PaymasterData {
|
|
80
80
|
*/
|
81
81
|
export interface UserOptions {
|
82
82
|
/** Whether to use a paymaster for gas fee coverage. */
|
83
|
-
|
83
|
+
sponsorshipPolicy?: string;
|
84
84
|
/** The unique nonce used to differentiate multiple Safe setups. */
|
85
85
|
safeSaltNonce: string;
|
86
86
|
/** The NEAR contract ID for the MPC contract. */
|
package/dist/cjs/util.d.ts
CHANGED
@@ -11,4 +11,30 @@ export declare function isContract(address: Address, chainId: number): Promise<b
|
|
11
11
|
export declare function getClient(chainId: number): PublicClient;
|
12
12
|
export declare function metaTransactionsFromRequest(params: SessionRequestParams): MetaTransaction[];
|
13
13
|
export declare function saltNonceFromMessage(input: string): string;
|
14
|
+
/**
|
15
|
+
* Fetches the signature for a NEAR transaction hash. If an `accountId` is provided,
|
16
|
+
* it fetches the signature from the appropriate network. Otherwise, it races across
|
17
|
+
* both `testnet` and `mainnet`.
|
18
|
+
*
|
19
|
+
* @param {string} txHash - The NEAR transaction hash for which to fetch the signature.
|
20
|
+
* @param {string} [accountId] - (Optional) The account ID associated with the transaction.
|
21
|
+
* Providing this will reduce dangling promises as the network is determined by the account.
|
22
|
+
*
|
23
|
+
* @returns {Promise<Hex>} A promise that resolves to the hex-encoded signature.
|
24
|
+
*
|
25
|
+
* @throws Will throw an error if no signature is found for the given transaction hash.
|
26
|
+
*/
|
27
|
+
export declare function signatureFromTxHash(txHash: string, accountId?: string): Promise<Hex>;
|
28
|
+
/**
|
29
|
+
* Races an array of promises and resolves with the first promise that fulfills.
|
30
|
+
* If all promises reject, the function will reject with an error.
|
31
|
+
*
|
32
|
+
* @template T
|
33
|
+
* @param {Promise<T>[]} promises - An array of promises to race. Each promise should resolve to type `T`.
|
34
|
+
*
|
35
|
+
* @returns {Promise<T>} A promise that resolves to the value of the first successfully resolved promise.
|
36
|
+
*
|
37
|
+
* @throws Will throw an error if all promises reject with the message "All promises rejected".
|
38
|
+
*/
|
39
|
+
export declare function raceToFirstResolve<T>(promises: Promise<T>[]): Promise<T>;
|
14
40
|
export {};
|
package/dist/cjs/util.js
CHANGED
@@ -8,9 +8,10 @@ exports.isContract = isContract;
|
|
8
8
|
exports.getClient = getClient;
|
9
9
|
exports.metaTransactionsFromRequest = metaTransactionsFromRequest;
|
10
10
|
exports.saltNonceFromMessage = saltNonceFromMessage;
|
11
|
+
exports.signatureFromTxHash = signatureFromTxHash;
|
12
|
+
exports.raceToFirstResolve = raceToFirstResolve;
|
11
13
|
const near_ca_1 = require("near-ca");
|
12
14
|
const viem_1 = require("viem");
|
13
|
-
//
|
14
15
|
exports.PLACEHOLDER_SIG = (0, viem_1.encodePacked)(["uint48", "uint48"], [0, 0]);
|
15
16
|
const packGas = (hi, lo) => (0, viem_1.encodePacked)(["uint128", "uint128"], [BigInt(hi), BigInt(lo)]);
|
16
17
|
exports.packGas = packGas;
|
@@ -66,3 +67,66 @@ function saltNonceFromMessage(input) {
|
|
66
67
|
// Return string for readability and transport.
|
67
68
|
return BigInt((0, viem_1.keccak256)((0, viem_1.toBytes)(input))).toString();
|
68
69
|
}
|
70
|
+
/**
|
71
|
+
* Fetches the signature for a NEAR transaction hash. If an `accountId` is provided,
|
72
|
+
* it fetches the signature from the appropriate network. Otherwise, it races across
|
73
|
+
* both `testnet` and `mainnet`.
|
74
|
+
*
|
75
|
+
* @param {string} txHash - The NEAR transaction hash for which to fetch the signature.
|
76
|
+
* @param {string} [accountId] - (Optional) The account ID associated with the transaction.
|
77
|
+
* Providing this will reduce dangling promises as the network is determined by the account.
|
78
|
+
*
|
79
|
+
* @returns {Promise<Hex>} A promise that resolves to the hex-encoded signature.
|
80
|
+
*
|
81
|
+
* @throws Will throw an error if no signature is found for the given transaction hash.
|
82
|
+
*/
|
83
|
+
async function signatureFromTxHash(txHash, accountId) {
|
84
|
+
if (accountId) {
|
85
|
+
const signature = await (0, near_ca_1.signatureFromTxHash)(`https://archival-rpc.${(0, near_ca_1.getNetworkId)(accountId)}.near.org`, txHash, accountId);
|
86
|
+
return packSignature((0, viem_1.serializeSignature)(signature));
|
87
|
+
}
|
88
|
+
try {
|
89
|
+
const signature = await raceToFirstResolve(["testnet", "mainnet"].map((network) => (0, near_ca_1.signatureFromTxHash)(archiveNode(network), txHash)));
|
90
|
+
return packSignature((0, viem_1.serializeSignature)(signature));
|
91
|
+
}
|
92
|
+
catch {
|
93
|
+
throw new Error(`No signature found for txHash ${txHash}`);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
/**
|
97
|
+
* Utility function to construct an archive node URL for a given NEAR network.
|
98
|
+
*
|
99
|
+
* @param {string} networkId - The ID of the NEAR network (e.g., 'testnet', 'mainnet').
|
100
|
+
*
|
101
|
+
* @returns {string} The full URL of the archival RPC node for the specified network.
|
102
|
+
*/
|
103
|
+
const archiveNode = (networkId) => `https://archival-rpc.${networkId}.near.org`;
|
104
|
+
/**
|
105
|
+
* Races an array of promises and resolves with the first promise that fulfills.
|
106
|
+
* If all promises reject, the function will reject with an error.
|
107
|
+
*
|
108
|
+
* @template T
|
109
|
+
* @param {Promise<T>[]} promises - An array of promises to race. Each promise should resolve to type `T`.
|
110
|
+
*
|
111
|
+
* @returns {Promise<T>} A promise that resolves to the value of the first successfully resolved promise.
|
112
|
+
*
|
113
|
+
* @throws Will throw an error if all promises reject with the message "All promises rejected".
|
114
|
+
*/
|
115
|
+
async function raceToFirstResolve(promises) {
|
116
|
+
return new Promise((resolve, reject) => {
|
117
|
+
let rejectionCount = 0;
|
118
|
+
const totalPromises = promises.length;
|
119
|
+
promises.forEach((promise) => {
|
120
|
+
// Wrap each promise so it only resolves when fulfilled
|
121
|
+
Promise.resolve(promise)
|
122
|
+
.then(resolve) // Resolve when any promise resolves
|
123
|
+
.catch(() => {
|
124
|
+
rejectionCount++;
|
125
|
+
// If all promises reject, reject the race with an error
|
126
|
+
if (rejectionCount === totalPromises) {
|
127
|
+
reject(new Error("All promises rejected"));
|
128
|
+
}
|
129
|
+
});
|
130
|
+
});
|
131
|
+
});
|
132
|
+
}
|
@@ -1,9 +1,12 @@
|
|
1
1
|
import { Address, Hash, PublicClient, Transport } from "viem";
|
2
2
|
import { GasPrices, PaymasterData, UnsignedUserOperation, UserOperation, UserOperationReceipt } from "../types";
|
3
|
+
type SponsorshipPolicy = {
|
4
|
+
sponsorshipPolicyId: string;
|
5
|
+
};
|
3
6
|
type BundlerRpcSchema = [
|
4
7
|
{
|
5
8
|
Method: "pm_sponsorUserOperation";
|
6
|
-
Parameters: [UnsignedUserOperation, Address];
|
9
|
+
Parameters: [UnsignedUserOperation, Address, SponsorshipPolicy];
|
7
10
|
ReturnType: PaymasterData;
|
8
11
|
},
|
9
12
|
{
|
@@ -28,7 +31,7 @@ export declare class Erc4337Bundler {
|
|
28
31
|
apiKey: string;
|
29
32
|
chainId: number;
|
30
33
|
constructor(entryPointAddress: Address, apiKey: string, chainId: number);
|
31
|
-
getPaymasterData(rawUserOp: UnsignedUserOperation,
|
34
|
+
getPaymasterData(rawUserOp: UnsignedUserOperation, safeNotDeployed: boolean, sponsorshipPolicy?: string): Promise<PaymasterData>;
|
32
35
|
sendUserOperation(userOp: UserOperation): Promise<Hash>;
|
33
36
|
getGasPrice(): Promise<GasPrices>;
|
34
37
|
getUserOpReceipt(userOpHash: Hash): Promise<UserOperationReceipt>;
|
package/dist/esm/lib/bundler.js
CHANGED
@@ -17,15 +17,16 @@ export class Erc4337Bundler {
|
|
17
17
|
rpcSchema: rpcSchema(),
|
18
18
|
});
|
19
19
|
}
|
20
|
-
async getPaymasterData(rawUserOp,
|
20
|
+
async getPaymasterData(rawUserOp, safeNotDeployed, sponsorshipPolicy) {
|
21
21
|
// TODO: Keep this option out of the bundler
|
22
|
-
if (
|
22
|
+
if (sponsorshipPolicy) {
|
23
23
|
console.log("Requesting paymaster data...");
|
24
24
|
return handleRequest(() => this.client.request({
|
25
25
|
method: "pm_sponsorUserOperation",
|
26
26
|
params: [
|
27
27
|
{ ...rawUserOp, signature: PLACEHOLDER_SIG },
|
28
28
|
this.entryPointAddress,
|
29
|
+
{ sponsorshipPolicyId: sponsorshipPolicy },
|
29
30
|
],
|
30
31
|
}));
|
31
32
|
}
|
package/dist/esm/near-safe.d.ts
CHANGED
@@ -70,7 +70,7 @@ export declare class NearSafe {
|
|
70
70
|
buildTransaction(args: {
|
71
71
|
chainId: number;
|
72
72
|
transactions: MetaTransaction[];
|
73
|
-
|
73
|
+
sponsorshipPolicy?: string;
|
74
74
|
}): Promise<UserOperation>;
|
75
75
|
/**
|
76
76
|
* Signs a transaction with the NEAR adapter using the provided operation hash.
|
@@ -93,7 +93,7 @@ export declare class NearSafe {
|
|
93
93
|
* @param {boolean} usePaymaster - Flag indicating whether to use a paymaster for gas fees. If true, the transaction will be sponsored by the paymaster.
|
94
94
|
* @returns {Promise<EncodedTxData>} - A promise that resolves to the encoded transaction data for the NEAR and EVM networks.
|
95
95
|
*/
|
96
|
-
encodeSignRequest(signRequest: SignRequestData,
|
96
|
+
encodeSignRequest(signRequest: SignRequestData, sponsorshipPolicy?: string): Promise<EncodedTxData>;
|
97
97
|
/**
|
98
98
|
* Broadcasts a user operation to the EVM network with a provided signature.
|
99
99
|
* Warning: Uses a private ethRPC with sensitive Pimlico API key (should be run server side).
|
@@ -173,7 +173,7 @@ export declare class NearSafe {
|
|
173
173
|
* - Returns a promise that resolves to an object containing the Ethereum Virtual Machine (EVM) message,
|
174
174
|
* the payload (hashed data), and recovery data needed for reconstructing the signature request.
|
175
175
|
*/
|
176
|
-
requestRouter({ method, chainId, params }: SignRequestData,
|
176
|
+
requestRouter({ method, chainId, params }: SignRequestData, sponsorshipPolicy?: string): Promise<{
|
177
177
|
evmMessage: string;
|
178
178
|
payload: number[];
|
179
179
|
hash: Hash;
|
package/dist/esm/near-safe.js
CHANGED
@@ -90,7 +90,7 @@ export class NearSafe {
|
|
90
90
|
* @throws {Error} - Throws an error if the transaction set is empty or if any operation fails during the building process.
|
91
91
|
*/
|
92
92
|
async buildTransaction(args) {
|
93
|
-
const { transactions,
|
93
|
+
const { transactions, sponsorshipPolicy, chainId } = args;
|
94
94
|
if (transactions.length === 0) {
|
95
95
|
throw new Error("Empty transaction set!");
|
96
96
|
}
|
@@ -104,7 +104,7 @@ export class NearSafe {
|
|
104
104
|
// Build Singular MetaTransaction for Multisend from transaction list.
|
105
105
|
const tx = transactions.length > 1 ? encodeMulti(transactions) : transactions[0];
|
106
106
|
const rawUserOp = await this.safePack.buildUserOp(nonce, tx, this.address, gasFees.fast, this.setup, !safeDeployed, this.safeSaltNonce);
|
107
|
-
const paymasterData = await bundler.getPaymasterData(rawUserOp,
|
107
|
+
const paymasterData = await bundler.getPaymasterData(rawUserOp, !safeDeployed, sponsorshipPolicy);
|
108
108
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
109
109
|
return unsignedUserOp;
|
110
110
|
}
|
@@ -134,8 +134,8 @@ export class NearSafe {
|
|
134
134
|
* @param {boolean} usePaymaster - Flag indicating whether to use a paymaster for gas fees. If true, the transaction will be sponsored by the paymaster.
|
135
135
|
* @returns {Promise<EncodedTxData>} - A promise that resolves to the encoded transaction data for the NEAR and EVM networks.
|
136
136
|
*/
|
137
|
-
async encodeSignRequest(signRequest,
|
138
|
-
const { payload, evmMessage, hash } = await this.requestRouter(signRequest,
|
137
|
+
async encodeSignRequest(signRequest, sponsorshipPolicy) {
|
138
|
+
const { payload, evmMessage, hash } = await this.requestRouter(signRequest, sponsorshipPolicy);
|
139
139
|
return {
|
140
140
|
nearPayload: await this.nearAdapter.mpcContract.encodeSignatureRequestTx({
|
141
141
|
path: this.nearAdapter.derivationPath,
|
@@ -286,7 +286,7 @@ export class NearSafe {
|
|
286
286
|
* - Returns a promise that resolves to an object containing the Ethereum Virtual Machine (EVM) message,
|
287
287
|
* the payload (hashed data), and recovery data needed for reconstructing the signature request.
|
288
288
|
*/
|
289
|
-
async requestRouter({ method, chainId, params },
|
289
|
+
async requestRouter({ method, chainId, params }, sponsorshipPolicy) {
|
290
290
|
const safeInfo = {
|
291
291
|
address: { value: this.address },
|
292
292
|
chainId: chainId.toString(),
|
@@ -321,7 +321,7 @@ export class NearSafe {
|
|
321
321
|
const userOp = await this.buildTransaction({
|
322
322
|
chainId,
|
323
323
|
transactions,
|
324
|
-
|
324
|
+
...(sponsorshipPolicy ? { sponsorshipPolicy } : {}),
|
325
325
|
});
|
326
326
|
const opHash = await this.opHash(chainId, userOp);
|
327
327
|
return {
|
package/dist/esm/types.d.ts
CHANGED
@@ -80,7 +80,7 @@ export interface PaymasterData {
|
|
80
80
|
*/
|
81
81
|
export interface UserOptions {
|
82
82
|
/** Whether to use a paymaster for gas fee coverage. */
|
83
|
-
|
83
|
+
sponsorshipPolicy?: string;
|
84
84
|
/** The unique nonce used to differentiate multiple Safe setups. */
|
85
85
|
safeSaltNonce: string;
|
86
86
|
/** The NEAR contract ID for the MPC contract. */
|
package/dist/esm/util.d.ts
CHANGED
@@ -11,4 +11,30 @@ export declare function isContract(address: Address, chainId: number): Promise<b
|
|
11
11
|
export declare function getClient(chainId: number): PublicClient;
|
12
12
|
export declare function metaTransactionsFromRequest(params: SessionRequestParams): MetaTransaction[];
|
13
13
|
export declare function saltNonceFromMessage(input: string): string;
|
14
|
+
/**
|
15
|
+
* Fetches the signature for a NEAR transaction hash. If an `accountId` is provided,
|
16
|
+
* it fetches the signature from the appropriate network. Otherwise, it races across
|
17
|
+
* both `testnet` and `mainnet`.
|
18
|
+
*
|
19
|
+
* @param {string} txHash - The NEAR transaction hash for which to fetch the signature.
|
20
|
+
* @param {string} [accountId] - (Optional) The account ID associated with the transaction.
|
21
|
+
* Providing this will reduce dangling promises as the network is determined by the account.
|
22
|
+
*
|
23
|
+
* @returns {Promise<Hex>} A promise that resolves to the hex-encoded signature.
|
24
|
+
*
|
25
|
+
* @throws Will throw an error if no signature is found for the given transaction hash.
|
26
|
+
*/
|
27
|
+
export declare function signatureFromTxHash(txHash: string, accountId?: string): Promise<Hex>;
|
28
|
+
/**
|
29
|
+
* Races an array of promises and resolves with the first promise that fulfills.
|
30
|
+
* If all promises reject, the function will reject with an error.
|
31
|
+
*
|
32
|
+
* @template T
|
33
|
+
* @param {Promise<T>[]} promises - An array of promises to race. Each promise should resolve to type `T`.
|
34
|
+
*
|
35
|
+
* @returns {Promise<T>} A promise that resolves to the value of the first successfully resolved promise.
|
36
|
+
*
|
37
|
+
* @throws Will throw an error if all promises reject with the message "All promises rejected".
|
38
|
+
*/
|
39
|
+
export declare function raceToFirstResolve<T>(promises: Promise<T>[]): Promise<T>;
|
14
40
|
export {};
|
package/dist/esm/util.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
import { Network } from "near-ca";
|
2
|
-
import { concatHex, encodePacked, toHex, isHex, parseTransaction, zeroAddress, toBytes, keccak256, } from "viem";
|
3
|
-
//
|
1
|
+
import { getNetworkId, Network, signatureFromTxHash as sigFromHash, } from "near-ca";
|
2
|
+
import { concatHex, encodePacked, toHex, isHex, parseTransaction, zeroAddress, toBytes, keccak256, serializeSignature, } from "viem";
|
4
3
|
export const PLACEHOLDER_SIG = encodePacked(["uint48", "uint48"], [0, 0]);
|
5
4
|
export const packGas = (hi, lo) => encodePacked(["uint128", "uint128"], [BigInt(hi), BigInt(lo)]);
|
6
5
|
export function packSignature(signature, validFrom = 0, validTo = 0) {
|
@@ -55,3 +54,66 @@ export function saltNonceFromMessage(input) {
|
|
55
54
|
// Return string for readability and transport.
|
56
55
|
return BigInt(keccak256(toBytes(input))).toString();
|
57
56
|
}
|
57
|
+
/**
|
58
|
+
* Fetches the signature for a NEAR transaction hash. If an `accountId` is provided,
|
59
|
+
* it fetches the signature from the appropriate network. Otherwise, it races across
|
60
|
+
* both `testnet` and `mainnet`.
|
61
|
+
*
|
62
|
+
* @param {string} txHash - The NEAR transaction hash for which to fetch the signature.
|
63
|
+
* @param {string} [accountId] - (Optional) The account ID associated with the transaction.
|
64
|
+
* Providing this will reduce dangling promises as the network is determined by the account.
|
65
|
+
*
|
66
|
+
* @returns {Promise<Hex>} A promise that resolves to the hex-encoded signature.
|
67
|
+
*
|
68
|
+
* @throws Will throw an error if no signature is found for the given transaction hash.
|
69
|
+
*/
|
70
|
+
export async function signatureFromTxHash(txHash, accountId) {
|
71
|
+
if (accountId) {
|
72
|
+
const signature = await sigFromHash(`https://archival-rpc.${getNetworkId(accountId)}.near.org`, txHash, accountId);
|
73
|
+
return packSignature(serializeSignature(signature));
|
74
|
+
}
|
75
|
+
try {
|
76
|
+
const signature = await raceToFirstResolve(["testnet", "mainnet"].map((network) => sigFromHash(archiveNode(network), txHash)));
|
77
|
+
return packSignature(serializeSignature(signature));
|
78
|
+
}
|
79
|
+
catch {
|
80
|
+
throw new Error(`No signature found for txHash ${txHash}`);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
/**
|
84
|
+
* Utility function to construct an archive node URL for a given NEAR network.
|
85
|
+
*
|
86
|
+
* @param {string} networkId - The ID of the NEAR network (e.g., 'testnet', 'mainnet').
|
87
|
+
*
|
88
|
+
* @returns {string} The full URL of the archival RPC node for the specified network.
|
89
|
+
*/
|
90
|
+
const archiveNode = (networkId) => `https://archival-rpc.${networkId}.near.org`;
|
91
|
+
/**
|
92
|
+
* Races an array of promises and resolves with the first promise that fulfills.
|
93
|
+
* If all promises reject, the function will reject with an error.
|
94
|
+
*
|
95
|
+
* @template T
|
96
|
+
* @param {Promise<T>[]} promises - An array of promises to race. Each promise should resolve to type `T`.
|
97
|
+
*
|
98
|
+
* @returns {Promise<T>} A promise that resolves to the value of the first successfully resolved promise.
|
99
|
+
*
|
100
|
+
* @throws Will throw an error if all promises reject with the message "All promises rejected".
|
101
|
+
*/
|
102
|
+
export async function raceToFirstResolve(promises) {
|
103
|
+
return new Promise((resolve, reject) => {
|
104
|
+
let rejectionCount = 0;
|
105
|
+
const totalPromises = promises.length;
|
106
|
+
promises.forEach((promise) => {
|
107
|
+
// Wrap each promise so it only resolves when fulfilled
|
108
|
+
Promise.resolve(promise)
|
109
|
+
.then(resolve) // Resolve when any promise resolves
|
110
|
+
.catch(() => {
|
111
|
+
rejectionCount++;
|
112
|
+
// If all promises reject, reject the race with an error
|
113
|
+
if (rejectionCount === totalPromises) {
|
114
|
+
reject(new Error("All promises rejected"));
|
115
|
+
}
|
116
|
+
});
|
117
|
+
});
|
118
|
+
});
|
119
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "near-safe",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.7.0",
|
4
4
|
"license": "MIT",
|
5
5
|
"description": "An SDK for controlling Ethereum Smart Accounts via ERC4337 from a Near Account.",
|
6
6
|
"author": "bh2smith",
|
@@ -36,15 +36,15 @@
|
|
36
36
|
"start": "yarn example",
|
37
37
|
"example": "tsx examples/send-tx.ts",
|
38
38
|
"lint": "eslint . --ignore-pattern dist/",
|
39
|
-
"test": "jest",
|
40
39
|
"fmt": "prettier --write '{src,examples,tests}/**/*.{js,jsx,ts,tsx}' && yarn lint --fix",
|
40
|
+
"test": "jest",
|
41
41
|
"all": "yarn fmt && yarn lint && yarn build"
|
42
42
|
},
|
43
43
|
"dependencies": {
|
44
44
|
"@safe-global/safe-gateway-typescript-sdk": "^3.22.2",
|
45
45
|
"ethers-multisend": "^3.1.0",
|
46
46
|
"near-api-js": "^5.0.0",
|
47
|
-
"near-ca": "^0.5.
|
47
|
+
"near-ca": "^0.5.10",
|
48
48
|
"semver": "^7.6.3",
|
49
49
|
"viem": "^2.16.5"
|
50
50
|
},
|