@bananapus/nana-sdk-core 2.12.2 → 2.14.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/bendystrawOperations.d.ts +38 -0
- package/dist/cjs/bendystrawOperations.d.ts.map +1 -0
- package/dist/cjs/bendystrawOperations.js +212 -0
- package/dist/cjs/bendystrawOperations.js.map +1 -0
- package/dist/cjs/review/contractWrite.d.ts +38 -0
- package/dist/cjs/review/contractWrite.d.ts.map +1 -0
- package/dist/cjs/review/contractWrite.js +57 -0
- package/dist/cjs/review/contractWrite.js.map +1 -0
- package/dist/cjs/review/gas.d.ts +28 -0
- package/dist/cjs/review/gas.d.ts.map +1 -0
- package/dist/cjs/review/gas.js +40 -0
- package/dist/cjs/review/gas.js.map +1 -0
- package/dist/cjs/review/index.d.ts +4 -0
- package/dist/cjs/review/index.d.ts.map +1 -0
- package/dist/cjs/review/index.js +20 -0
- package/dist/cjs/review/index.js.map +1 -0
- package/dist/cjs/review/transactionReview.d.ts +99 -0
- package/dist/cjs/review/transactionReview.d.ts.map +1 -0
- package/dist/cjs/review/transactionReview.js +233 -0
- package/dist/cjs/review/transactionReview.js.map +1 -0
- package/dist/cjs/safeService.d.ts +36 -0
- package/dist/cjs/safeService.d.ts.map +1 -0
- package/dist/cjs/safeService.js +142 -0
- package/dist/cjs/safeService.js.map +1 -0
- package/dist/cjs/utils/bendystraw.d.ts +15 -0
- package/dist/cjs/utils/bendystraw.d.ts.map +1 -1
- package/dist/cjs/utils/bendystraw.js +54 -0
- package/dist/cjs/utils/bendystraw.js.map +1 -1
- package/dist/cjs/v6/feeBuyback.d.ts +43 -0
- package/dist/cjs/v6/feeBuyback.d.ts.map +1 -0
- package/dist/cjs/v6/feeBuyback.js +306 -0
- package/dist/cjs/v6/feeBuyback.js.map +1 -0
- package/dist/esm/bendystrawOperations.d.ts +38 -0
- package/dist/esm/bendystrawOperations.d.ts.map +1 -0
- package/dist/esm/bendystrawOperations.js +206 -0
- package/dist/esm/bendystrawOperations.js.map +1 -0
- package/dist/esm/review/contractWrite.d.ts +38 -0
- package/dist/esm/review/contractWrite.d.ts.map +1 -0
- package/dist/esm/review/contractWrite.js +54 -0
- package/dist/esm/review/contractWrite.js.map +1 -0
- package/dist/esm/review/gas.d.ts +28 -0
- package/dist/esm/review/gas.d.ts.map +1 -0
- package/dist/esm/review/gas.js +36 -0
- package/dist/esm/review/gas.js.map +1 -0
- package/dist/esm/review/index.d.ts +4 -0
- package/dist/esm/review/index.d.ts.map +1 -0
- package/dist/esm/review/index.js +4 -0
- package/dist/esm/review/index.js.map +1 -0
- package/dist/esm/review/transactionReview.d.ts +99 -0
- package/dist/esm/review/transactionReview.d.ts.map +1 -0
- package/dist/esm/review/transactionReview.js +219 -0
- package/dist/esm/review/transactionReview.js.map +1 -0
- package/dist/esm/safeService.d.ts +36 -0
- package/dist/esm/safeService.d.ts.map +1 -0
- package/dist/esm/safeService.js +135 -0
- package/dist/esm/safeService.js.map +1 -0
- package/dist/esm/utils/bendystraw.d.ts +15 -0
- package/dist/esm/utils/bendystraw.d.ts.map +1 -1
- package/dist/esm/utils/bendystraw.js +53 -0
- package/dist/esm/utils/bendystraw.js.map +1 -1
- package/dist/esm/v6/feeBuyback.d.ts +43 -0
- package/dist/esm/v6/feeBuyback.d.ts.map +1 -0
- package/dist/esm/v6/feeBuyback.js +299 -0
- package/dist/esm/v6/feeBuyback.js.map +1 -0
- package/package.json +30 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Address } from "viem";
|
|
2
|
+
export type ReviewedWritePhase = "review" | "simulating" | "signing";
|
|
3
|
+
export type ReviewedContractWriteOptions<TRequest extends {
|
|
4
|
+
chainId: number;
|
|
5
|
+
}, TSimulated, THash> = {
|
|
6
|
+
request: TRequest;
|
|
7
|
+
expectedAccount: Address | undefined;
|
|
8
|
+
review: (request: TRequest) => Promise<unknown>;
|
|
9
|
+
switchChain: (chainId: number) => Promise<unknown>;
|
|
10
|
+
currentAccount: () => Address | undefined;
|
|
11
|
+
simulate: (request: TRequest) => Promise<TSimulated>;
|
|
12
|
+
reverify?: (request: TRequest) => Promise<unknown>;
|
|
13
|
+
/** Persist recovery intent after simulation, before a wallet can broadcast. */
|
|
14
|
+
beforeWrite?: () => unknown | Promise<unknown>;
|
|
15
|
+
/** The persisted intent was rejected by a final gate before write was invoked. */
|
|
16
|
+
onBeforeWriteAborted?: () => unknown | Promise<unknown>;
|
|
17
|
+
/** Clear that intent only when the wallet explicitly rejects the write. */
|
|
18
|
+
onWriteRejected?: () => unknown | Promise<unknown>;
|
|
19
|
+
write: (simulated: TSimulated) => Promise<THash>;
|
|
20
|
+
onPhase?: (phase: ReviewedWritePhase) => void;
|
|
21
|
+
accountChangedError?: string;
|
|
22
|
+
/**
|
|
23
|
+
* An app-specific gate run before anything else, such as refusing writes while
|
|
24
|
+
* the app is impersonating another account. It throws to stop the write.
|
|
25
|
+
*/
|
|
26
|
+
guard?: () => void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Shared review-to-wallet boundary for direct contract writes.
|
|
30
|
+
*
|
|
31
|
+
* The exact request object accepted by review is also handed to simulation,
|
|
32
|
+
* and only the simulation result reaches the wallet writer. Account identity
|
|
33
|
+
* is checked after a chain switch and again immediately before signing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function submitReviewedContractWrite<TRequest extends {
|
|
36
|
+
chainId: number;
|
|
37
|
+
}, TSimulated, THash>({ request, expectedAccount, review, switchChain, currentAccount, simulate, reverify, beforeWrite, onBeforeWriteAborted, onWriteRejected, write, onPhase, accountChangedError, guard, }: ReviewedContractWriteOptions<TRequest, TSimulated, THash>): Promise<THash>;
|
|
38
|
+
//# sourceMappingURL=contractWrite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractWrite.d.ts","sourceRoot":"","sources":["../../../src/review/contractWrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAErE,MAAM,MAAM,4BAA4B,CACtC,QAAQ,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EACpC,UAAU,EACV,KAAK,IACH;IACF,OAAO,EAAE,QAAQ,CAAC;IAClB,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,cAAc,EAAE,MAAM,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EACpC,UAAU,EACV,KAAK,EACL,EACA,OAAO,EACP,eAAe,EACf,MAAM,EACN,WAAW,EACX,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACP,mBAAgF,EAChF,KAAK,GACN,EAAE,4BAA4B,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CA+C5E"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { BaseError, UserRejectedRequestError } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Shared review-to-wallet boundary for direct contract writes.
|
|
4
|
+
*
|
|
5
|
+
* The exact request object accepted by review is also handed to simulation,
|
|
6
|
+
* and only the simulation result reaches the wallet writer. Account identity
|
|
7
|
+
* is checked after a chain switch and again immediately before signing.
|
|
8
|
+
*/
|
|
9
|
+
export async function submitReviewedContractWrite({ request, expectedAccount, review, switchChain, currentAccount, simulate, reverify, beforeWrite, onBeforeWriteAborted, onWriteRejected, write, onPhase, accountChangedError = "Connected account changed. Review the transaction again.", guard, }) {
|
|
10
|
+
guard?.();
|
|
11
|
+
if (!expectedAccount)
|
|
12
|
+
throw new Error("Connect a wallet first.");
|
|
13
|
+
onPhase?.("review");
|
|
14
|
+
await review(request);
|
|
15
|
+
onPhase?.("simulating");
|
|
16
|
+
await switchChain(request.chainId);
|
|
17
|
+
assertExpectedAccount(currentAccount(), expectedAccount, accountChangedError);
|
|
18
|
+
await reverify?.(request);
|
|
19
|
+
assertExpectedAccount(currentAccount(), expectedAccount, accountChangedError);
|
|
20
|
+
const simulated = await simulate(request);
|
|
21
|
+
assertExpectedAccount(currentAccount(), expectedAccount, accountChangedError);
|
|
22
|
+
if (beforeWrite) {
|
|
23
|
+
await beforeWrite();
|
|
24
|
+
try {
|
|
25
|
+
assertExpectedAccount(currentAccount(), expectedAccount, accountChangedError);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
// This is strictly before the wallet writer is invoked. An ambiguous
|
|
29
|
+
// write error must never reach this cleanup path.
|
|
30
|
+
await onBeforeWriteAborted?.();
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
onPhase?.("signing");
|
|
35
|
+
try {
|
|
36
|
+
return await write(simulated);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// The same-looking error from review/simulation never reaches this catch.
|
|
40
|
+
// An RPC timeout or ambiguous submission must preserve the recovery lock.
|
|
41
|
+
const rejected = error instanceof UserRejectedRequestError ||
|
|
42
|
+
(error instanceof BaseError &&
|
|
43
|
+
error.walk((cause) => cause instanceof UserRejectedRequestError) instanceof UserRejectedRequestError);
|
|
44
|
+
if (rejected)
|
|
45
|
+
await onWriteRejected?.();
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function assertExpectedAccount(current, expected, message) {
|
|
50
|
+
if (!current || current.toLowerCase() !== expected.toLowerCase()) {
|
|
51
|
+
throw new Error(message);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=contractWrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractWrite.js","sourceRoot":"","sources":["../../../src/review/contractWrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAgB,MAAM,MAAM,CAAC;AAgCzE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAI/C,EACA,OAAO,EACP,eAAe,EACf,MAAM,EACN,WAAW,EACX,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACP,mBAAmB,GAAG,0DAA0D,EAChF,KAAK,GACqD;IAC1D,KAAK,EAAE,EAAE,CAAC;IACV,IAAI,CAAC,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAEjE,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEtB,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC;IACxB,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,qBAAqB,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAC9E,MAAM,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IAC1B,qBAAqB,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAE9E,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1C,qBAAqB,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAE9E,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,qBAAqB,CACnB,cAAc,EAAE,EAChB,eAAe,EACf,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qEAAqE;YACrE,kDAAkD;YAClD,MAAM,oBAAoB,EAAE,EAAE,CAAC;YAC/B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,QAAQ,GACZ,KAAK,YAAY,wBAAwB;YACzC,CAAC,KAAK,YAAY,SAAS;gBACzB,KAAK,CAAC,IAAI,CACR,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,wBAAwB,CACrD,YAAY,wBAAwB,CAAC,CAAC;QAC3C,IAAI,QAAQ;YAAE,MAAM,eAAe,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAA4B,EAC5B,QAAiB,EACjB,OAAe;IAEf,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Address, Hex, PublicClient } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Wallet gas limits are deliberately twice the latest RPC estimate.
|
|
4
|
+
*
|
|
5
|
+
* Some Juicebox terminal calls catch a failed internal fee payment and keep
|
|
6
|
+
* going. An RPC can therefore return an estimate for that cheaper recovery
|
|
7
|
+
* path even though the intended fee route needs more gas. Unused gas is not
|
|
8
|
+
* spent, so a 2x limit is a cheap guard against that under-estimation.
|
|
9
|
+
*/
|
|
10
|
+
export declare function gasWithHeadroom(estimate: bigint): bigint;
|
|
11
|
+
/**
|
|
12
|
+
* The gas limit to send for a call that carries a reviewed cap.
|
|
13
|
+
*
|
|
14
|
+
* A cap bounds an `eth_call` against a target-controlled contract; it is not
|
|
15
|
+
* what the call costs. Wallets reject a transaction whose `gas * maxFeePerGas`
|
|
16
|
+
* exceeds the balance, so sending the cap itself turns a 1M-gas mainnet cap
|
|
17
|
+
* into a ~0.003 ETH balance requirement for a call that burns a tenth of that.
|
|
18
|
+
*
|
|
19
|
+
* Measurement stays bounded by the cap, and the cap survives when the node
|
|
20
|
+
* cannot measure.
|
|
21
|
+
*/
|
|
22
|
+
export declare function gasWithinCap(client: PublicClient, tx: {
|
|
23
|
+
account: Address;
|
|
24
|
+
to: Address;
|
|
25
|
+
data: Hex;
|
|
26
|
+
value?: bigint;
|
|
27
|
+
}, cap?: bigint): Promise<bigint | undefined>;
|
|
28
|
+
//# sourceMappingURL=gas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas.d.ts","sourceRoot":"","sources":["../../../src/review/gas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAChE,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW7B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet gas limits are deliberately twice the latest RPC estimate.
|
|
3
|
+
*
|
|
4
|
+
* Some Juicebox terminal calls catch a failed internal fee payment and keep
|
|
5
|
+
* going. An RPC can therefore return an estimate for that cheaper recovery
|
|
6
|
+
* path even though the intended fee route needs more gas. Unused gas is not
|
|
7
|
+
* spent, so a 2x limit is a cheap guard against that under-estimation.
|
|
8
|
+
*/
|
|
9
|
+
export function gasWithHeadroom(estimate) {
|
|
10
|
+
return estimate * 2n;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The gas limit to send for a call that carries a reviewed cap.
|
|
14
|
+
*
|
|
15
|
+
* A cap bounds an `eth_call` against a target-controlled contract; it is not
|
|
16
|
+
* what the call costs. Wallets reject a transaction whose `gas * maxFeePerGas`
|
|
17
|
+
* exceeds the balance, so sending the cap itself turns a 1M-gas mainnet cap
|
|
18
|
+
* into a ~0.003 ETH balance requirement for a call that burns a tenth of that.
|
|
19
|
+
*
|
|
20
|
+
* Measurement stays bounded by the cap, and the cap survives when the node
|
|
21
|
+
* cannot measure.
|
|
22
|
+
*/
|
|
23
|
+
export async function gasWithinCap(client, tx, cap) {
|
|
24
|
+
try {
|
|
25
|
+
const estimate = await client.estimateGas({
|
|
26
|
+
...tx,
|
|
27
|
+
...(cap === undefined ? {} : { gas: cap }),
|
|
28
|
+
});
|
|
29
|
+
const measured = gasWithHeadroom(estimate);
|
|
30
|
+
return cap !== undefined && cap < measured ? cap : measured;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return cap;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=gas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas.js","sourceRoot":"","sources":["../../../src/review/gas.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,QAAQ,GAAG,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAoB,EACpB,EAAgE,EAChE,GAAY;IAEZ,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACxC,GAAG,EAAE;YACL,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/review/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/review/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { type Abi, type Address, type Hex } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* How review prompts name a chain and link its explorer. Apps pass their own
|
|
4
|
+
* chain display, which also keeps a chain table out of the review bundle.
|
|
5
|
+
*/
|
|
6
|
+
export type TransactionReviewDisplay = {
|
|
7
|
+
chainName: (chainId: number) => string;
|
|
8
|
+
explorerOrigin: (chainId: number) => string | null;
|
|
9
|
+
};
|
|
10
|
+
export type TransactionReviewCall = {
|
|
11
|
+
chainId: number;
|
|
12
|
+
to: Address;
|
|
13
|
+
data: Hex;
|
|
14
|
+
value?: bigint;
|
|
15
|
+
/** The gas limit the wallet or forwarder signs, when it is fixed before review. */
|
|
16
|
+
gas?: bigint;
|
|
17
|
+
/** A Safe proposal's signed `safeTxGas`. At 0 the Safe transaction reverts if this call fails. */
|
|
18
|
+
safeTxGas?: bigint;
|
|
19
|
+
from?: Address;
|
|
20
|
+
abi?: Abi;
|
|
21
|
+
functionName?: string;
|
|
22
|
+
args?: readonly unknown[];
|
|
23
|
+
/** Plain-language action shown above the decoded call. */
|
|
24
|
+
label?: string;
|
|
25
|
+
/** Optional known contract name. The full address is always shown too. */
|
|
26
|
+
contractName?: string;
|
|
27
|
+
/** The calls a batching destination (MultiSend) makes in order, decoded by the caller. */
|
|
28
|
+
calls?: readonly TransactionReviewCall[];
|
|
29
|
+
};
|
|
30
|
+
export type TransactionReviewRequest = {
|
|
31
|
+
calls: readonly TransactionReviewCall[];
|
|
32
|
+
title?: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
confirmLabel?: string;
|
|
35
|
+
/** Distinguishes a wallet transaction from an authorization which a relayer/Safe will submit. */
|
|
36
|
+
kind?: "transaction" | "authorization";
|
|
37
|
+
/** Exact typed data committed by a Safe/relayer signature, when applicable. */
|
|
38
|
+
authorization?: unknown;
|
|
39
|
+
};
|
|
40
|
+
export type ContractTransactionReviewCall = {
|
|
41
|
+
chainId: number;
|
|
42
|
+
address: Address;
|
|
43
|
+
abi: Abi;
|
|
44
|
+
functionName: string;
|
|
45
|
+
args?: readonly unknown[];
|
|
46
|
+
value?: bigint;
|
|
47
|
+
gas?: bigint;
|
|
48
|
+
safeTxGas?: bigint;
|
|
49
|
+
account?: Address;
|
|
50
|
+
};
|
|
51
|
+
export type TransactionReviewOptions = Omit<TransactionReviewRequest, "calls"> & {
|
|
52
|
+
label?: string;
|
|
53
|
+
contractName?: string;
|
|
54
|
+
};
|
|
55
|
+
type TransactionReviewHandler = (request: TransactionReviewRequest) => Promise<boolean>;
|
|
56
|
+
/** The person closed a review or a funding-chain choice. Nothing was sent; apps need not show an error. */
|
|
57
|
+
export declare class TransactionReviewCancelledError extends Error {
|
|
58
|
+
constructor(message?: string);
|
|
59
|
+
}
|
|
60
|
+
export type FundingChainOption = {
|
|
61
|
+
chainId: number;
|
|
62
|
+
/** The chain and its quoted cost, from {@link fundingChainLabel}. */
|
|
63
|
+
label: string;
|
|
64
|
+
};
|
|
65
|
+
type FundingChainSelectionHandler = (options: readonly FundingChainOption[],
|
|
66
|
+
/** The option to preselect, or null when the person must pick one of several. */
|
|
67
|
+
initialChainId: number | null) => Promise<number | null>;
|
|
68
|
+
/** "Base (~0.000123 ETH)": a chain and the relay fee quoted on it. */
|
|
69
|
+
export declare function fundingChainLabel(chainName: string, amountWei: bigint): string;
|
|
70
|
+
export declare function registerFundingChainSelectionHandler(handler: FundingChainSelectionHandler): () => void;
|
|
71
|
+
/**
|
|
72
|
+
* Asks where to pay a relay fee. The connected chain is preselected when it is
|
|
73
|
+
* quoted, and so is a lone quote; otherwise the person picks. The exact payment
|
|
74
|
+
* still gets its own review.
|
|
75
|
+
*/
|
|
76
|
+
export declare function requireFundingChainSelection(options: readonly FundingChainOption[], preferredChainId?: number): Promise<number>;
|
|
77
|
+
/**
|
|
78
|
+
* The provider registers the only UI capable of approving a transaction.
|
|
79
|
+
* Keeping the entry point in a small client module lets non-React wallet
|
|
80
|
+
* helpers (Safe and Relayr) use the same mandatory review queue.
|
|
81
|
+
*/
|
|
82
|
+
export declare function registerTransactionReviewHandler(handler: TransactionReviewHandler): () => void;
|
|
83
|
+
export declare function requestContractTransactionReview(call: ContractTransactionReviewCall, options?: TransactionReviewOptions): Promise<boolean>;
|
|
84
|
+
export declare function requireTransactionReview(request: TransactionReviewRequest): Promise<void>;
|
|
85
|
+
export declare function requireContractTransactionReview(call: ContractTransactionReviewCall, options?: TransactionReviewOptions): Promise<void>;
|
|
86
|
+
export declare function transactionReviewJson(request: TransactionReviewRequest): string;
|
|
87
|
+
/**
|
|
88
|
+
* The post-transaction counterpart of the review prompt: a mined tx the user
|
|
89
|
+
* wants explained (or diagnosed) from explorer evidence. Points at Etherscan's
|
|
90
|
+
* transaction-debugger skill when the reader's agent has it, and degrades to
|
|
91
|
+
* the explorer page when it doesn't.
|
|
92
|
+
*/
|
|
93
|
+
export declare function buildTransactionDebugPrompt(calls: {
|
|
94
|
+
chainId: number;
|
|
95
|
+
txHash: string;
|
|
96
|
+
}[], { chainName: displayChainName, explorerOrigin }: TransactionReviewDisplay): string;
|
|
97
|
+
export declare function buildTransactionReviewPrompt(request: TransactionReviewRequest, { explorerOrigin }: Pick<TransactionReviewDisplay, "explorerOrigin">): string;
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=transactionReview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionReview.d.ts","sourceRoot":"","sources":["../../../src/review/transactionReview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { encodeFunctionData, formatEther, } from "viem";
|
|
3
|
+
const transactionReviewHandlers = [];
|
|
4
|
+
/** The person closed a review or a funding-chain choice. Nothing was sent; apps need not show an error. */
|
|
5
|
+
export class TransactionReviewCancelledError extends Error {
|
|
6
|
+
constructor(message = "Review closed. Nothing was sent.") {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "TransactionReviewCancelledError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** "Base (~0.000123 ETH)": a chain and the relay fee quoted on it. */
|
|
12
|
+
export function fundingChainLabel(chainName, amountWei) {
|
|
13
|
+
const exact = formatEther(amountWei);
|
|
14
|
+
const shown = new Intl.NumberFormat("en-US", {
|
|
15
|
+
maximumSignificantDigits: 3,
|
|
16
|
+
}).format(Number(exact));
|
|
17
|
+
return `${chainName} (${shown === exact ? "" : "~"}${shown} ETH)`;
|
|
18
|
+
}
|
|
19
|
+
const fundingChainSelectionHandlers = [];
|
|
20
|
+
export function registerFundingChainSelectionHandler(handler) {
|
|
21
|
+
fundingChainSelectionHandlers.push(handler);
|
|
22
|
+
return () => {
|
|
23
|
+
const index = fundingChainSelectionHandlers.lastIndexOf(handler);
|
|
24
|
+
if (index >= 0)
|
|
25
|
+
fundingChainSelectionHandlers.splice(index, 1);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Asks where to pay a relay fee. The connected chain is preselected when it is
|
|
30
|
+
* quoted, and so is a lone quote; otherwise the person picks. The exact payment
|
|
31
|
+
* still gets its own review.
|
|
32
|
+
*/
|
|
33
|
+
export async function requireFundingChainSelection(options, preferredChainId) {
|
|
34
|
+
const snapshot = options.map((option) => ({ ...option }));
|
|
35
|
+
const chainIds = new Set(snapshot.map((option) => option.chainId));
|
|
36
|
+
if (!snapshot.length ||
|
|
37
|
+
chainIds.size !== snapshot.length ||
|
|
38
|
+
snapshot.some((option) => !Number.isSafeInteger(option.chainId) ||
|
|
39
|
+
option.chainId <= 0 ||
|
|
40
|
+
!option.label.trim())) {
|
|
41
|
+
throw new Error("No valid funding chain choices are available. Request a new quote.");
|
|
42
|
+
}
|
|
43
|
+
const handler = fundingChainSelectionHandlers[fundingChainSelectionHandlers.length - 1];
|
|
44
|
+
if (!handler) {
|
|
45
|
+
throw new Error("Funding chain selection is unavailable. Reload the page before continuing.");
|
|
46
|
+
}
|
|
47
|
+
const initialChainId = preferredChainId !== undefined && chainIds.has(preferredChainId)
|
|
48
|
+
? preferredChainId
|
|
49
|
+
: snapshot.length === 1
|
|
50
|
+
? snapshot[0].chainId
|
|
51
|
+
: null;
|
|
52
|
+
const selected = await handler(snapshot, initialChainId);
|
|
53
|
+
if (selected === null) {
|
|
54
|
+
throw new TransactionReviewCancelledError("Funding chain selection cancelled. Nothing was sent.");
|
|
55
|
+
}
|
|
56
|
+
if (!chainIds.has(selected)) {
|
|
57
|
+
throw new Error("The selected funding chain is not available in this quote.");
|
|
58
|
+
}
|
|
59
|
+
return selected;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The provider registers the only UI capable of approving a transaction.
|
|
63
|
+
* Keeping the entry point in a small client module lets non-React wallet
|
|
64
|
+
* helpers (Safe and Relayr) use the same mandatory review queue.
|
|
65
|
+
*/
|
|
66
|
+
export function registerTransactionReviewHandler(handler) {
|
|
67
|
+
transactionReviewHandlers.push(handler);
|
|
68
|
+
return () => {
|
|
69
|
+
const index = transactionReviewHandlers.lastIndexOf(handler);
|
|
70
|
+
if (index >= 0)
|
|
71
|
+
transactionReviewHandlers.splice(index, 1);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function requestTransactionReview(request) {
|
|
75
|
+
if (!request.calls.length && !request.authorization) {
|
|
76
|
+
throw new Error("There is no transaction to review.");
|
|
77
|
+
}
|
|
78
|
+
const transactionReviewHandler = transactionReviewHandlers[transactionReviewHandlers.length - 1];
|
|
79
|
+
if (!transactionReviewHandler) {
|
|
80
|
+
throw new Error("Transaction review is unavailable. Reload the page before continuing.");
|
|
81
|
+
}
|
|
82
|
+
return transactionReviewHandler(request);
|
|
83
|
+
}
|
|
84
|
+
/** Encode once for review using the same ABI/function/args passed to wagmi. */
|
|
85
|
+
function contractCallForReview(call, options = {}) {
|
|
86
|
+
const data = encodeFunctionData({
|
|
87
|
+
abi: call.abi,
|
|
88
|
+
functionName: call.functionName,
|
|
89
|
+
args: call.args,
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
chainId: call.chainId,
|
|
93
|
+
to: call.address,
|
|
94
|
+
data,
|
|
95
|
+
value: call.value,
|
|
96
|
+
gas: call.gas,
|
|
97
|
+
safeTxGas: call.safeTxGas,
|
|
98
|
+
from: call.account,
|
|
99
|
+
abi: call.abi,
|
|
100
|
+
functionName: call.functionName,
|
|
101
|
+
args: call.args,
|
|
102
|
+
label: options.label,
|
|
103
|
+
contractName: options.contractName,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function requestContractTransactionReview(call, options = {}) {
|
|
107
|
+
const { label, contractName, ...requestOptions } = options;
|
|
108
|
+
const reviewed = contractCallForReview(call, { label, contractName });
|
|
109
|
+
return requestTransactionReview({
|
|
110
|
+
...requestOptions,
|
|
111
|
+
calls: [reviewed],
|
|
112
|
+
}).then((approved) => {
|
|
113
|
+
if (!approved)
|
|
114
|
+
return false;
|
|
115
|
+
const current = contractCallForReview(call, { label, contractName });
|
|
116
|
+
if (current.chainId !== reviewed.chainId ||
|
|
117
|
+
current.to.toLowerCase() !== reviewed.to.toLowerCase() ||
|
|
118
|
+
(current.value ?? 0n) !== (reviewed.value ?? 0n) ||
|
|
119
|
+
current.gas !== reviewed.gas ||
|
|
120
|
+
current.safeTxGas !== reviewed.safeTxGas ||
|
|
121
|
+
current.data !== reviewed.data) {
|
|
122
|
+
throw new Error("Transaction data changed after review. Nothing was sent; review it again.");
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
export async function requireTransactionReview(request) {
|
|
128
|
+
if (!(await requestTransactionReview(request))) {
|
|
129
|
+
throw new TransactionReviewCancelledError();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export async function requireContractTransactionReview(call, options = {}) {
|
|
133
|
+
if (!(await requestContractTransactionReview(call, options))) {
|
|
134
|
+
throw new TransactionReviewCancelledError();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export function transactionReviewJson(request) {
|
|
138
|
+
const transactions = request.calls.map((call) => ({
|
|
139
|
+
chainId: call.chainId,
|
|
140
|
+
from: call.from,
|
|
141
|
+
to: call.to,
|
|
142
|
+
value: `0x${(call.value ?? 0n).toString(16)}`,
|
|
143
|
+
...(call.gas === undefined ? {} : { gas: `0x${call.gas.toString(16)}` }),
|
|
144
|
+
...(call.safeTxGas === undefined
|
|
145
|
+
? {}
|
|
146
|
+
: { safeTxGas: `0x${call.safeTxGas.toString(16)}` }),
|
|
147
|
+
data: call.data,
|
|
148
|
+
}));
|
|
149
|
+
const calls = transactions.length === 1 ? transactions[0] : { transactions };
|
|
150
|
+
const payload = request.authorization
|
|
151
|
+
? transactions.length > 0
|
|
152
|
+
? { authorization: request.authorization, resultingCall: calls }
|
|
153
|
+
: { authorization: request.authorization }
|
|
154
|
+
: calls;
|
|
155
|
+
return JSON.stringify(payload, (_, value) => (typeof value === "bigint" ? value.toString() : value), 2);
|
|
156
|
+
}
|
|
157
|
+
/** A website/-style prompt which keeps the exact reviewed RPC call intact. */
|
|
158
|
+
const ETHERSCAN_SKILL_LINE = "If your agent has Etherscan's skills installed (`npx skills add etherscan/skills`), run `etherscan-contract-review` on each target address to pull its verified source, proxy roles, and privileged controls before decoding. Otherwise work from the explorer pages.";
|
|
159
|
+
/**
|
|
160
|
+
* The post-transaction counterpart of the review prompt: a mined tx the user
|
|
161
|
+
* wants explained (or diagnosed) from explorer evidence. Points at Etherscan's
|
|
162
|
+
* transaction-debugger skill when the reader's agent has it, and degrades to
|
|
163
|
+
* the explorer page when it doesn't.
|
|
164
|
+
*/
|
|
165
|
+
export function buildTransactionDebugPrompt(calls, { chainName: displayChainName, explorerOrigin }) {
|
|
166
|
+
const lines = [
|
|
167
|
+
"A Juicebox V6 transaction (the nana V6 / revnet V6 protocol release, not an older Juicebox version) was mined. Explain what happened in it and whether it did what a Juicebox user would expect.",
|
|
168
|
+
"",
|
|
169
|
+
];
|
|
170
|
+
calls.forEach((call) => {
|
|
171
|
+
const explorer = explorerOrigin(call.chainId);
|
|
172
|
+
lines.push(`- ${displayChainName(call.chainId)} (chain ${call.chainId}): ${explorer ? `${explorer}/tx/${call.txHash}` : call.txHash}`);
|
|
173
|
+
});
|
|
174
|
+
lines.push("", "If your agent has Etherscan's skills installed (`npx skills add etherscan/skills`), use `etherscan-transaction-debugger` in security mode on each hash. Otherwise work from the explorer page: receipt status, decoded input, event logs, and internal transactions.", "", "Verify contract source only against the Juicebox V6 repositories: https://github.com/Bananapus/version-6 (repositories ending in `-v6`; same-named repositories without that suffix are older versions).", "", "Report the decoded method and arguments, every native and token movement with its recipient, every permission, ownership, or ruleset change, and, if it reverted, the narrowest root cause the evidence supports. Mark each claim observed, derived, or inferred. Never invent a function name, amount, or revert reason. End with one line: what the transaction did in plain English, and anything that looks wrong.");
|
|
175
|
+
return lines.join("\n");
|
|
176
|
+
}
|
|
177
|
+
export function buildTransactionReviewPrompt(request, { explorerOrigin }) {
|
|
178
|
+
const lines = [
|
|
179
|
+
"I'm about to authorize a blockchain action in a Juicebox V6 app (the nana V6 / revnet V6 protocol release, not an older Juicebox version). Act as a careful security reviewer. Independently verify the payload against the deployed contracts and V6 source, confirm it matches my intent, and give a go/no-go. Assume the UI could be spoofed; trust the onchain call and verified V6 source over the page.",
|
|
180
|
+
"",
|
|
181
|
+
"Exact app-controlled transaction payload:",
|
|
182
|
+
"```json",
|
|
183
|
+
transactionReviewJson(request),
|
|
184
|
+
"```",
|
|
185
|
+
"",
|
|
186
|
+
];
|
|
187
|
+
if (typeof window !== "undefined") {
|
|
188
|
+
lines.push("Audit the app build I am using:");
|
|
189
|
+
lines.push(`- Page: ${window.location.href}`);
|
|
190
|
+
lines.push("- Confirm this page builds exactly the destination, native value, and calldata above, with no hidden or substituted call.");
|
|
191
|
+
lines.push("");
|
|
192
|
+
}
|
|
193
|
+
lines.push("Verify the contracts and protocol version:");
|
|
194
|
+
lines.push("- Juicebox V6 ecosystem source: https://github.com/Bananapus/version-6");
|
|
195
|
+
lines.push("- Use only V6 repositories (normally ending in `-v6`); same-named repositories without that suffix may be older and incompatible.");
|
|
196
|
+
lines.push(`- ${ETHERSCAN_SKILL_LINE}`);
|
|
197
|
+
request.calls.forEach((call, index) => {
|
|
198
|
+
// Apps pass their one explorer registry; a second copy once drifted on OP mainnet.
|
|
199
|
+
const explorer = explorerOrigin(call.chainId);
|
|
200
|
+
const prefix = request.calls.length > 1 ? `Transaction ${index + 1}` : "Target";
|
|
201
|
+
lines.push(explorer
|
|
202
|
+
? `- ${prefix} onchain: ${explorer}/address/${call.to}`
|
|
203
|
+
: `- ${prefix}: chain ${call.chainId}, address ${call.to}`);
|
|
204
|
+
});
|
|
205
|
+
lines.push("");
|
|
206
|
+
lines.push("Check specifically:");
|
|
207
|
+
lines.push("1. Decode the calldata selector and every argument. Explain in plain English what state, permissions, ownership, tokens, or funds can change.");
|
|
208
|
+
lines.push("2. Verify the chain ID, `to` address, native `value`, calldata, and any `gas` or `safeTxGas` exactly. Flag any unexpected non-zero value or unknown target.");
|
|
209
|
+
lines.push("3. Identify every beneficiary, recipient, spender, operator, owner, hook, terminal, and permission-bearing address in the decoded arguments.");
|
|
210
|
+
lines.push("4. Warn about unlimited approvals, arbitrary-call capability, delegatecalls, ownership transfers, permission grants, upgradeability, or drain paths.");
|
|
211
|
+
lines.push("5. For multiple chains, confirm the intended change is consistent and that no extra chain or call was added.");
|
|
212
|
+
lines.push("6. For a Relayr or Safe authorization, separate what I sign now from the later onchain execution. A Safe `safeTxGas` of 0 makes the Safe transaction revert if the call fails; a nonzero value lets it execute and record the failure.");
|
|
213
|
+
lines.push("");
|
|
214
|
+
lines.push("Before your verdict, quiz me with 2–4 short plain-English questions about what I expect to happen (what changes, who receives or controls what, how much value moves, and on which chain). Wait for my answers, compare them with the decoded payload, and flag every mismatch.");
|
|
215
|
+
lines.push("");
|
|
216
|
+
lines.push("End with one verdict: SAFE TO SIGN / DO NOT SIGN / NEEDS MORE INFO, followed by the most important reasons. If the target is not a recognizable verified Juicebox V6 deployment, say so explicitly.");
|
|
217
|
+
return lines.join("\n");
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=transactionReview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionReview.js","sourceRoot":"","sources":["../../../src/review/transactionReview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Address, Hex } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Safe's per-chain app URL prefix. Wider than {@link SAFE_SERVICE_PREFIX}:
|
|
4
|
+
* Safe app links work on chains without a hosted transaction service.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SAFE_PREFIX: Partial<Record<number, string>>;
|
|
7
|
+
/**
|
|
8
|
+
* Chains with a HOSTED Safe Transaction Service — a smaller set than the
|
|
9
|
+
* chains Safe app links work on: `api.safe.global/tx-service/{opsepolia,
|
|
10
|
+
* arb1-sep}` both 404, while `basesep` is live. Probed against
|
|
11
|
+
* `/api/v1/about/`. This split from {@link SAFE_PREFIX} is DELIBERATE:
|
|
12
|
+
* conflating the two maps is what made service calls fire at chains with
|
|
13
|
+
* none. Every tx-service URL must come from here, never from `SAFE_PREFIX`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SAFE_SERVICE_PREFIX: Partial<Record<number, string>>;
|
|
16
|
+
/** The Safe Transaction Service base URL for a chain, honoring the
|
|
17
|
+
* `jb-safe-tx-base` localStorage override; null when the chain has none. */
|
|
18
|
+
export declare function safeServiceBase(chainId: number): string | null;
|
|
19
|
+
export declare const SAFE_NONCE_GUIDANCE = "On Safe\u2019s confirmation screen, Nonce defaults to the next available value. Open its dropdown to see queued nonces and replace one if desired.";
|
|
20
|
+
/** The unix deadline for a swap/liquidity transaction proposed now. */
|
|
21
|
+
export declare function swapDeadline(isSafe: boolean, nowMs?: number): bigint;
|
|
22
|
+
export declare function safeQueueUrl(chainId: number, safe: Address): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a Safe proposal identifier to its actual onchain execution hash.
|
|
25
|
+
* A safeTxHash is not a transaction hash and must never be receipt-polled.
|
|
26
|
+
*
|
|
27
|
+
* The polling URL comes from {@link safeServiceBase} (the hosted-service
|
|
28
|
+
* map), NOT `SAFE_PREFIX`: OP Sepolia and Arbitrum Sepolia have Safe app
|
|
29
|
+
* URLs but no hosted transaction service, and polling a nonexistent service
|
|
30
|
+
* left every Safe write there pending forever.
|
|
31
|
+
*/
|
|
32
|
+
export declare function waitForSafeExecutionHash(chainId: number, safeTxHash: Hex, options?: {
|
|
33
|
+
pollingIntervalMs?: number;
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}): Promise<Hex>;
|
|
36
|
+
//# sourceMappingURL=safeService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeService.d.ts","sourceRoot":"","sources":["../../src/safeService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASvD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO/D,CAAC;AAEF;6EAC6E;AAC7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW9D;AAED,eAAO,MAAM,mBAAmB,uJACiH,CAAC;AAUlJ,uEAAuE;AACvE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,MAAmB,GACzB,MAAM,CAKR;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK1E;AAWD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,GAAG,EACf,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACjE,OAAO,CAAC,GAAG,CAAC,CAiEd"}
|