@prb/effect-evm-safe 2.0.1 → 2.1.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/CHANGELOG.md +25 -0
- package/dist/react-hooks/index.d.ts +1 -0
- package/dist/react-hooks/index.d.ts.map +1 -1
- package/dist/react-hooks/index.js +1 -0
- package/dist/react-hooks/index.js.map +1 -1
- package/dist/react-hooks/safe-app-origins.d.ts.map +1 -1
- package/dist/react-hooks/safe-app-origins.js +2 -10
- package/dist/react-hooks/safe-app-origins.js.map +1 -1
- package/dist/react-hooks/use-wallet-execution.d.ts +14 -0
- package/dist/react-hooks/use-wallet-execution.d.ts.map +1 -0
- package/dist/react-hooks/use-wallet-execution.js +110 -0
- package/dist/react-hooks/use-wallet-execution.js.map +1 -0
- package/dist/safe/allowance.d.ts +22 -2
- package/dist/safe/allowance.d.ts.map +1 -1
- package/dist/safe/allowance.js +20 -1
- package/dist/safe/allowance.js.map +1 -1
- package/dist/safe/errors.d.ts +2 -0
- package/dist/safe/errors.d.ts.map +1 -1
- package/dist/safe/errors.js +11 -0
- package/dist/safe/errors.js.map +1 -1
- package/dist/safe/index.d.ts +4 -2
- package/dist/safe/index.d.ts.map +1 -1
- package/dist/safe/index.js +3 -1
- package/dist/safe/index.js.map +1 -1
- package/dist/safe/live.d.ts.map +1 -1
- package/dist/safe/live.js +7 -37
- package/dist/safe/live.js.map +1 -1
- package/dist/safe/pipeline-adapter.d.ts +6 -0
- package/dist/safe/pipeline-adapter.d.ts.map +1 -0
- package/dist/safe/pipeline-adapter.js +143 -0
- package/dist/safe/pipeline-adapter.js.map +1 -0
- package/dist/safe/tx-lifecycle.d.ts +1 -1
- package/dist/safe/tx-lifecycle.d.ts.map +1 -1
- package/dist/safe/tx-lifecycle.js +1 -0
- package/dist/safe/tx-lifecycle.js.map +1 -1
- package/dist/safe/write-and-track.d.ts +72 -0
- package/dist/safe/write-and-track.d.ts.map +1 -0
- package/dist/safe/write-and-track.js +116 -0
- package/dist/safe/write-and-track.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,31 @@ The format is based on [Common Changelog](https://common-changelog.org/).
|
|
|
10
10
|
[1.1.1]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm-safe%401.1.1
|
|
11
11
|
[2.0.0]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm-safe%402.0.0
|
|
12
12
|
[2.0.1]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm-safe%402.0.1
|
|
13
|
+
[2.0.2]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm-safe%402.0.2
|
|
14
|
+
[2.1.0]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm-safe%402.1.0
|
|
15
|
+
|
|
16
|
+
## [2.1.0] - 2026-02-18
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Add optional `multiSendStrategy: "fallback-required-approval"` to `safeMultisigAllowAndWrite` for chains without
|
|
21
|
+
MultiSend
|
|
22
|
+
- Normalize Safe lookup failures via shared `toSafeMultisigTxLookupError` constructor
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Add `safeWriteAndTrack` with lifecycle callbacks and streamed Safe state transitions
|
|
27
|
+
- Add `SafeWriteExecutionAdapterLive` to bridge Safe execution into `@prb/effect-evm` `ContractPipeline`
|
|
28
|
+
- Add `useWalletExecution` hook for Safe-versus-EOA routing across context, connector, origin, and owners probe
|
|
29
|
+
- Add `cancelled` status support to `SafeMultisigTxStatus`
|
|
30
|
+
- Export `SafeMultisigAllowAndWriteResult` and Safe write-and-track types from `safe` module
|
|
31
|
+
|
|
32
|
+
## [2.0.2] - 2026-02-18
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Allow `setSafeAppOrigins` and `extendSafeAppOrigins` to be called multiple times by removing the one-time
|
|
37
|
+
configuration guard
|
|
13
38
|
|
|
14
39
|
## [2.0.1] - 2026-02-18
|
|
15
40
|
|
|
@@ -2,4 +2,5 @@ export { DEFAULT_SAFE_APP_ORIGINS, extendSafeAppOrigins, getSafeAppOrigins, setS
|
|
|
2
2
|
export { useIsHostSafeApp } from "./use-is-host-safe-app.js";
|
|
3
3
|
export { useIsSafeAppContext } from "./use-is-safe-app-context.js";
|
|
4
4
|
export { useIsSafeMultisigWallet } from "./use-is-safe-multisig-wallet.js";
|
|
5
|
+
export { useWalletExecution, type WalletExecution, type WalletExecutionDetectionSource, type WalletExecutionHost, type WalletExecutionOptions, type WalletExecutionType, } from "./use-wallet-execution.js";
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-hooks/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-hooks/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,8BAA8B,EACnC,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC"}
|
|
@@ -3,4 +3,5 @@ export { DEFAULT_SAFE_APP_ORIGINS, extendSafeAppOrigins, getSafeAppOrigins, setS
|
|
|
3
3
|
export { useIsHostSafeApp } from "./use-is-host-safe-app.js";
|
|
4
4
|
export { useIsSafeAppContext } from "./use-is-safe-app-context.js";
|
|
5
5
|
export { useIsSafeMultisigWallet } from "./use-is-safe-multisig-wallet.js";
|
|
6
|
+
export { useWalletExecution, } from "./use-wallet-execution.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-hooks/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC","sourcesContent":["\"use client\";\n\nexport {\n DEFAULT_SAFE_APP_ORIGINS,\n extendSafeAppOrigins,\n getSafeAppOrigins,\n setSafeAppOrigins,\n} from \"./safe-app-origins.js\";\nexport { useIsHostSafeApp } from \"./use-is-host-safe-app.js\";\nexport { useIsSafeAppContext } from \"./use-is-safe-app-context.js\";\nexport { useIsSafeMultisigWallet } from \"./use-is-safe-multisig-wallet.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-hooks/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EACL,kBAAkB,GAMnB,MAAM,2BAA2B,CAAC","sourcesContent":["\"use client\";\n\nexport {\n DEFAULT_SAFE_APP_ORIGINS,\n extendSafeAppOrigins,\n getSafeAppOrigins,\n setSafeAppOrigins,\n} from \"./safe-app-origins.js\";\nexport { useIsHostSafeApp } from \"./use-is-host-safe-app.js\";\nexport { useIsSafeAppContext } from \"./use-is-safe-app-context.js\";\nexport { useIsSafeMultisigWallet } from \"./use-is-safe-multisig-wallet.js\";\nexport {\n useWalletExecution,\n type WalletExecution,\n type WalletExecutionDetectionSource,\n type WalletExecutionHost,\n type WalletExecutionOptions,\n type WalletExecutionType,\n} from \"./use-wallet-execution.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-app-origins.d.ts","sourceRoot":"","sources":["../../src/react-hooks/safe-app-origins.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,wBAAwB,yMAU3B,CAAC;
|
|
1
|
+
{"version":3,"file":"safe-app-origins.d.ts","sourceRoot":"","sources":["../../src/react-hooks/safe-app-origins.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,wBAAwB,yMAU3B,CAAC;AAQX,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,QAE3D;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,QAE9D;AAGD,wBAAgB,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAErD;AAGD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKxE;AAGD,wBAAgB,oBAAoB,IAAI,OAAO,CAM9C;AAGD,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
|
|
@@ -12,12 +12,11 @@ const ORIGIN_PROTOCOL_PATTERN = /^[a-z]+:\/\//i;
|
|
|
12
12
|
let safeAppOrigins = normalizeOrigins(DEFAULT_SAFE_APP_ORIGINS);
|
|
13
13
|
let safeAppOriginSet = new Set(safeAppOrigins);
|
|
14
14
|
const safeAppOriginListeners = new Set();
|
|
15
|
-
let safeAppOriginsConfigured = false;
|
|
16
15
|
export function setSafeAppOrigins(origins) {
|
|
17
|
-
|
|
16
|
+
updateSafeAppOrigins(normalizeOrigins(origins));
|
|
18
17
|
}
|
|
19
18
|
export function extendSafeAppOrigins(origins) {
|
|
20
|
-
|
|
19
|
+
updateSafeAppOrigins(normalizeOrigins([...safeAppOrigins, ...origins]));
|
|
21
20
|
}
|
|
22
21
|
export function getSafeAppOrigins() {
|
|
23
22
|
return [...safeAppOrigins];
|
|
@@ -68,13 +67,6 @@ function updateSafeAppOrigins(nextOrigins) {
|
|
|
68
67
|
safeAppOriginSet = new Set(safeAppOrigins);
|
|
69
68
|
notifySafeAppOriginListeners();
|
|
70
69
|
}
|
|
71
|
-
function configureSafeAppOrigins(nextOrigins) {
|
|
72
|
-
if (safeAppOriginsConfigured) {
|
|
73
|
-
throw new Error("Safe App origins already configured.");
|
|
74
|
-
}
|
|
75
|
-
safeAppOriginsConfigured = true;
|
|
76
|
-
updateSafeAppOrigins(nextOrigins);
|
|
77
|
-
}
|
|
78
70
|
function notifySafeAppOriginListeners() {
|
|
79
71
|
for (const listener of safeAppOriginListeners) {
|
|
80
72
|
listener();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-app-origins.js","sourceRoot":"","sources":["../../src/react-hooks/safe-app-origins.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAMb,MAAM,CAAC,MAAM,wBAAwB,GAAG;IAEtC,yBAAyB;IACzB,wBAAwB;IACxB,qBAAqB;IAErB,4BAA4B;IAC5B,yBAAyB;IACzB,2BAA2B;IAC3B,0BAA0B;CAClB,CAAC;AAEX,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAChD,IAAI,cAAc,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAChE,IAAI,gBAAgB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;AAC/C,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"safe-app-origins.js","sourceRoot":"","sources":["../../src/react-hooks/safe-app-origins.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Known Safe App domains for iframe origin validation.\n * Includes the main Safe App and chain-specific Safe deployments.\n */\nexport const DEFAULT_SAFE_APP_ORIGINS = [\n // Main Safe domains\n \"https://app.safe.global\",\n \"https://gnosis-safe.io\",\n \"https://safe.global\",\n // Chain-specific Safe deployments\n \"https://safe.berachain.com\",\n \"https://safe.chiliz.com\",\n \"https://safe.lightlink.io\",\n \"https://safe.optimism.io\",\n] as const;\n\nconst ORIGIN_PROTOCOL_PATTERN = /^[a-z]+:\\/\\//i;\nlet safeAppOrigins = normalizeOrigins(DEFAULT_SAFE_APP_ORIGINS);\nlet safeAppOriginSet = new Set(safeAppOrigins);\nconst safeAppOriginListeners = new Set<() => void>();\n\n/** Replace the Safe App origins list. */\nexport function setSafeAppOrigins(origins: readonly string[]) {\n updateSafeAppOrigins(normalizeOrigins(origins));\n}\n\n/** Extend the Safe App origins list. */\nexport function extendSafeAppOrigins(origins: readonly string[]) {\n updateSafeAppOrigins(normalizeOrigins([...safeAppOrigins, ...origins]));\n}\n\n/** Read the currently configured Safe App origins list. */\nexport function getSafeAppOrigins(): readonly string[] {\n return [...safeAppOrigins];\n}\n\n/** Subscribe to Safe App origin changes. */\nexport function subscribeSafeAppOrigins(listener: () => void): () => void {\n safeAppOriginListeners.add(listener);\n return () => {\n safeAppOriginListeners.delete(listener);\n };\n}\n\n/** Check if the parent browsing context origin is a Safe App domain. */\nexport function isValidSafeAppOrigin(): boolean {\n const origin = getAncestorOrigin();\n if (!origin) {\n return false;\n }\n return safeAppOriginSet.has(origin);\n}\n\n/** Check whether the app is running inside an iframe. */\nexport function isHostEmbedded(): boolean {\n return typeof window !== \"undefined\" && window.parent !== window;\n}\n\n/**\n * Get the origin of the parent browsing context.\n * Returns null if it cannot be determined due to cross-origin restrictions.\n */\nfunction getAncestorOrigin(): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n try {\n return window.parent.location.origin;\n } catch {\n if (window.location.ancestorOrigins?.length) {\n return window.location.ancestorOrigins[0];\n }\n\n if (document.referrer) {\n try {\n return new URL(document.referrer).origin;\n } catch {\n return null;\n }\n }\n\n return null;\n }\n}\n\nfunction updateSafeAppOrigins(nextOrigins: string[]) {\n if (areSameOrigins(safeAppOrigins, nextOrigins)) {\n return;\n }\n\n safeAppOrigins = nextOrigins;\n safeAppOriginSet = new Set(safeAppOrigins);\n notifySafeAppOriginListeners();\n}\n\nfunction notifySafeAppOriginListeners() {\n for (const listener of safeAppOriginListeners) {\n listener();\n }\n}\n\nfunction normalizeOrigins(origins: readonly string[]): string[] {\n const normalized: string[] = [];\n const seen = new Set<string>();\n\n for (const origin of origins) {\n const normalizedOrigin = normalizeOrigin(origin);\n if (!normalizedOrigin || seen.has(normalizedOrigin)) {\n continue;\n }\n seen.add(normalizedOrigin);\n normalized.push(normalizedOrigin);\n }\n\n return normalized;\n}\n\nfunction normalizeOrigin(origin: string): string | null {\n const trimmed = origin.trim();\n if (!trimmed) {\n return null;\n }\n\n const candidate = ORIGIN_PROTOCOL_PATTERN.test(trimmed) ? trimmed : `https://${trimmed}`;\n\n try {\n const url = new URL(candidate);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return null;\n }\n return url.origin;\n } catch {\n return null;\n }\n}\n\nfunction areSameOrigins(left: readonly string[], right: readonly string[]): boolean {\n if (left.length !== right.length) {\n return false;\n }\n\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] !== right[index]) {\n return false;\n }\n }\n\n return true;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type WalletExecutionDetectionSource = "safe-context" | "safe-connector" | "safe-origin" | "owners-probe" | "none";
|
|
2
|
+
export type WalletExecutionHost = "safe" | "browser";
|
|
3
|
+
export type WalletExecutionType = "safe-multisig" | "eoa" | "unknown";
|
|
4
|
+
export type WalletExecution = {
|
|
5
|
+
readonly detectionSource: WalletExecutionDetectionSource;
|
|
6
|
+
readonly host: WalletExecutionHost;
|
|
7
|
+
readonly isSafeMultisig: boolean;
|
|
8
|
+
readonly walletType: WalletExecutionType;
|
|
9
|
+
};
|
|
10
|
+
export type WalletExecutionOptions = {
|
|
11
|
+
readonly enableOwnersProbe?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare function useWalletExecution(options?: WalletExecutionOptions): WalletExecution;
|
|
14
|
+
//# sourceMappingURL=use-wallet-execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-wallet-execution.d.ts","sourceRoot":"","sources":["../../src/react-hooks/use-wallet-execution.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,8BAA8B,GACtC,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,MAAM,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG,KAAK,GAAG,SAAS,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,eAAe,EAAE,8BAA8B,CAAC;IACzD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AAKF,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAyGxF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import { useAccount, usePublicClient } from "wagmi";
|
|
4
|
+
import { isHostEmbedded, isValidSafeAppOrigin, subscribeSafeAppOrigins, } from "./safe-app-origins.js";
|
|
5
|
+
import { useIsSafeAppContext } from "./use-is-safe-app-context.js";
|
|
6
|
+
const safeOwnersAbi = [
|
|
7
|
+
{
|
|
8
|
+
inputs: [],
|
|
9
|
+
name: "getOwners",
|
|
10
|
+
outputs: [{ name: "", type: "address[]" }],
|
|
11
|
+
stateMutability: "view",
|
|
12
|
+
type: "function",
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
export function useWalletExecution(options = {}) {
|
|
16
|
+
const { address, connector, isConnected } = useAccount();
|
|
17
|
+
const publicClient = usePublicClient();
|
|
18
|
+
const isSafeContext = useIsSafeAppContext();
|
|
19
|
+
const isSafeOrigin = useSyncExternalStore(subscribeSafeAppOrigins, getSafeHostSnapshot, getServerSnapshot);
|
|
20
|
+
const enableOwnersProbe = options.enableOwnersProbe ?? true;
|
|
21
|
+
const [ownersProbeDetectedSafe, setOwnersProbeDetectedSafe] = useState(false);
|
|
22
|
+
const isSafeConnector = isConnected && connector?.id === "safe";
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!enableOwnersProbe ||
|
|
25
|
+
!address ||
|
|
26
|
+
!isConnected ||
|
|
27
|
+
!publicClient ||
|
|
28
|
+
isSafeContext ||
|
|
29
|
+
isSafeConnector ||
|
|
30
|
+
isSafeOrigin) {
|
|
31
|
+
setOwnersProbeDetectedSafe(false);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let cancelled = false;
|
|
35
|
+
void publicClient
|
|
36
|
+
.readContract({
|
|
37
|
+
abi: safeOwnersAbi,
|
|
38
|
+
address,
|
|
39
|
+
functionName: "getOwners",
|
|
40
|
+
})
|
|
41
|
+
.then((owners) => {
|
|
42
|
+
if (!cancelled) {
|
|
43
|
+
setOwnersProbeDetectedSafe(Array.isArray(owners) && owners.length > 0);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.catch(() => {
|
|
47
|
+
if (!cancelled) {
|
|
48
|
+
setOwnersProbeDetectedSafe(false);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return () => {
|
|
52
|
+
cancelled = true;
|
|
53
|
+
};
|
|
54
|
+
}, [
|
|
55
|
+
address,
|
|
56
|
+
enableOwnersProbe,
|
|
57
|
+
isConnected,
|
|
58
|
+
isSafeConnector,
|
|
59
|
+
isSafeContext,
|
|
60
|
+
isSafeOrigin,
|
|
61
|
+
publicClient,
|
|
62
|
+
]);
|
|
63
|
+
return useMemo(() => {
|
|
64
|
+
if (isSafeContext) {
|
|
65
|
+
return {
|
|
66
|
+
detectionSource: "safe-context",
|
|
67
|
+
host: "safe",
|
|
68
|
+
isSafeMultisig: true,
|
|
69
|
+
walletType: "safe-multisig",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (isSafeConnector) {
|
|
73
|
+
return {
|
|
74
|
+
detectionSource: "safe-connector",
|
|
75
|
+
host: "safe",
|
|
76
|
+
isSafeMultisig: true,
|
|
77
|
+
walletType: "safe-multisig",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (isSafeOrigin) {
|
|
81
|
+
return {
|
|
82
|
+
detectionSource: "safe-origin",
|
|
83
|
+
host: "safe",
|
|
84
|
+
isSafeMultisig: true,
|
|
85
|
+
walletType: "safe-multisig",
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (ownersProbeDetectedSafe) {
|
|
89
|
+
return {
|
|
90
|
+
detectionSource: "owners-probe",
|
|
91
|
+
host: "browser",
|
|
92
|
+
isSafeMultisig: true,
|
|
93
|
+
walletType: "safe-multisig",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
detectionSource: "none",
|
|
98
|
+
host: "browser",
|
|
99
|
+
isSafeMultisig: false,
|
|
100
|
+
walletType: isConnected ? "eoa" : "unknown",
|
|
101
|
+
};
|
|
102
|
+
}, [isConnected, isSafeConnector, isSafeContext, isSafeOrigin, ownersProbeDetectedSafe]);
|
|
103
|
+
}
|
|
104
|
+
function getSafeHostSnapshot() {
|
|
105
|
+
return isHostEmbedded() && isValidSafeAppOrigin();
|
|
106
|
+
}
|
|
107
|
+
function getServerSnapshot() {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=use-wallet-execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-wallet-execution.js","sourceRoot":"","sources":["../../src/react-hooks/use-wallet-execution.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useState, useSyncExternalStore } from \"react\";\nimport type { PublicClient } from \"viem\";\nimport { useAccount, usePublicClient } from \"wagmi\";\nimport {\n isHostEmbedded,\n isValidSafeAppOrigin,\n subscribeSafeAppOrigins,\n} from \"./safe-app-origins.js\";\nimport { useIsSafeAppContext } from \"./use-is-safe-app-context.js\";\n\nconst safeOwnersAbi = [\n {\n inputs: [],\n name: \"getOwners\",\n outputs: [{ name: \"\", type: \"address[]\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\nexport type WalletExecutionDetectionSource =\n | \"safe-context\"\n | \"safe-connector\"\n | \"safe-origin\"\n | \"owners-probe\"\n | \"none\";\n\nexport type WalletExecutionHost = \"safe\" | \"browser\";\n\nexport type WalletExecutionType = \"safe-multisig\" | \"eoa\" | \"unknown\";\n\nexport type WalletExecution = {\n readonly detectionSource: WalletExecutionDetectionSource;\n readonly host: WalletExecutionHost;\n readonly isSafeMultisig: boolean;\n readonly walletType: WalletExecutionType;\n};\n\nexport type WalletExecutionOptions = {\n readonly enableOwnersProbe?: boolean;\n};\n\n/**\n * Unified wallet execution detection for Safe vs EOA routing.\n */\nexport function useWalletExecution(options: WalletExecutionOptions = {}): WalletExecution {\n const { address, connector, isConnected } = useAccount();\n const publicClient = usePublicClient() as PublicClient | undefined;\n const isSafeContext = useIsSafeAppContext();\n const isSafeOrigin = useSyncExternalStore(\n subscribeSafeAppOrigins,\n getSafeHostSnapshot,\n getServerSnapshot\n );\n\n const enableOwnersProbe = options.enableOwnersProbe ?? true;\n const [ownersProbeDetectedSafe, setOwnersProbeDetectedSafe] = useState(false);\n\n const isSafeConnector = isConnected && connector?.id === \"safe\";\n\n useEffect(() => {\n if (\n !enableOwnersProbe ||\n !address ||\n !isConnected ||\n !publicClient ||\n isSafeContext ||\n isSafeConnector ||\n isSafeOrigin\n ) {\n setOwnersProbeDetectedSafe(false);\n return;\n }\n\n let cancelled = false;\n\n void publicClient\n .readContract({\n abi: safeOwnersAbi,\n address,\n functionName: \"getOwners\",\n })\n .then((owners) => {\n if (!cancelled) {\n setOwnersProbeDetectedSafe(Array.isArray(owners) && owners.length > 0);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setOwnersProbeDetectedSafe(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [\n address,\n enableOwnersProbe,\n isConnected,\n isSafeConnector,\n isSafeContext,\n isSafeOrigin,\n publicClient,\n ]);\n\n return useMemo(() => {\n if (isSafeContext) {\n return {\n detectionSource: \"safe-context\",\n host: \"safe\",\n isSafeMultisig: true,\n walletType: \"safe-multisig\",\n } satisfies WalletExecution;\n }\n\n if (isSafeConnector) {\n return {\n detectionSource: \"safe-connector\",\n host: \"safe\",\n isSafeMultisig: true,\n walletType: \"safe-multisig\",\n } satisfies WalletExecution;\n }\n\n if (isSafeOrigin) {\n return {\n detectionSource: \"safe-origin\",\n host: \"safe\",\n isSafeMultisig: true,\n walletType: \"safe-multisig\",\n } satisfies WalletExecution;\n }\n\n if (ownersProbeDetectedSafe) {\n return {\n detectionSource: \"owners-probe\",\n host: \"browser\",\n isSafeMultisig: true,\n walletType: \"safe-multisig\",\n } satisfies WalletExecution;\n }\n\n return {\n detectionSource: \"none\",\n host: \"browser\",\n isSafeMultisig: false,\n walletType: isConnected ? \"eoa\" : \"unknown\",\n } satisfies WalletExecution;\n }, [isConnected, isSafeConnector, isSafeContext, isSafeOrigin, ownersProbeDetectedSafe]);\n}\n\nfunction getSafeHostSnapshot(): boolean {\n return isHostEmbedded() && isValidSafeAppOrigin();\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n"]}
|
package/dist/safe/allowance.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import type { Address } from "viem";
|
|
2
|
+
import type { Address, Hash } from "viem";
|
|
3
|
+
import { SafeMultiSendUnavailableError } from "./errors.js";
|
|
3
4
|
import type { SafeMultisigTx } from "./types.js";
|
|
4
5
|
export type SafeMultisigAllowAndWriteParams = {
|
|
5
6
|
readonly mainTransaction: SafeMultisigTx;
|
|
@@ -9,6 +10,15 @@ export type SafeMultisigAllowAndWriteParams = {
|
|
|
9
10
|
readonly chainId: number;
|
|
10
11
|
};
|
|
11
12
|
readonly amount: bigint;
|
|
13
|
+
readonly multiSendStrategy?: "require" | "fallback-required-approval";
|
|
14
|
+
};
|
|
15
|
+
export type SafeMultisigAllowAndWriteResult = {
|
|
16
|
+
readonly _tag: "batched";
|
|
17
|
+
readonly safeTxHash: Hash;
|
|
18
|
+
} | {
|
|
19
|
+
readonly _tag: "fallback-required-approval";
|
|
20
|
+
readonly approveSafeTxHash: Hash;
|
|
21
|
+
readonly mainSafeTxHash: Hash;
|
|
12
22
|
};
|
|
13
23
|
export type SafeMultisigApproveTxParams = {
|
|
14
24
|
readonly amount: bigint;
|
|
@@ -16,5 +26,15 @@ export type SafeMultisigApproveTxParams = {
|
|
|
16
26
|
readonly tokenAddress: Address;
|
|
17
27
|
};
|
|
18
28
|
export declare function buildSafeApproveTx(params: SafeMultisigApproveTxParams): SafeMultisigTx;
|
|
19
|
-
export declare const safeMultisigAllowAndWrite: (params: SafeMultisigAllowAndWriteParams) => Effect.Effect
|
|
29
|
+
export declare const safeMultisigAllowAndWrite: (params: SafeMultisigAllowAndWriteParams) => Effect.Effect<{
|
|
30
|
+
_tag: "batched";
|
|
31
|
+
safeTxHash: `0x${string}`;
|
|
32
|
+
approveSafeTxHash?: undefined;
|
|
33
|
+
mainSafeTxHash?: undefined;
|
|
34
|
+
} | {
|
|
35
|
+
_tag: "fallback-required-approval";
|
|
36
|
+
approveSafeTxHash: `0x${string}`;
|
|
37
|
+
mainSafeTxHash: `0x${string}`;
|
|
38
|
+
safeTxHash?: undefined;
|
|
39
|
+
}, import("./errors.js").SafeMultisigTxSubmissionError | SafeMultiSendUnavailableError, import("./service.js").SafeAppsService>;
|
|
20
40
|
//# sourceMappingURL=allowance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowance.d.ts","sourceRoot":"","sources":["../../src/safe/allowance.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"allowance.d.ts","sourceRoot":"","sources":["../../src/safe/allowance.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,MAAM,MAAM,+BAA+B,GAAG;IAE5C,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;IAEzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,4BAA4B,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,+BAA+B,GACvC;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC;CAC/B,CAAC;AAGN,MAAM,MAAM,2BAA2B,GAAG;IAExC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC,CAAC;AASF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,2BAA2B,GAAG,cAAc,CAUtF;AAgBD,eAAO,MAAM,yBAAyB;;;;;;;;;;+HAuCpC,CAAC"}
|
package/dist/safe/allowance.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { encodeFunctionData, erc20Abi } from "viem";
|
|
3
3
|
import { safeMultisigBatchWrite } from "./batch.js";
|
|
4
|
+
import { SafeMultiSendUnavailableError } from "./errors.js";
|
|
4
5
|
export function buildSafeApproveTx(params) {
|
|
5
6
|
const { amount, spender, tokenAddress } = params;
|
|
6
7
|
const data = encodeFunctionData({
|
|
@@ -12,11 +13,29 @@ export function buildSafeApproveTx(params) {
|
|
|
12
13
|
}
|
|
13
14
|
export const safeMultisigAllowAndWrite = Effect.fn("safeMultisigAllowAndWrite")(function* (params) {
|
|
14
15
|
const { amount, mainTransaction, spender, token } = params;
|
|
16
|
+
const strategy = params.multiSendStrategy ?? "require";
|
|
15
17
|
const approveTx = buildSafeApproveTx({
|
|
16
18
|
amount,
|
|
17
19
|
spender,
|
|
18
20
|
tokenAddress: token.address,
|
|
19
21
|
});
|
|
20
|
-
|
|
22
|
+
const batched = yield* safeMultisigBatchWrite([approveTx, mainTransaction], token.chainId).pipe(Effect.either);
|
|
23
|
+
if (batched._tag === "Right") {
|
|
24
|
+
return {
|
|
25
|
+
_tag: "batched",
|
|
26
|
+
safeTxHash: batched.right,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const error = batched.left;
|
|
30
|
+
if (!(error instanceof SafeMultiSendUnavailableError) || strategy === "require") {
|
|
31
|
+
return yield* Effect.fail(error);
|
|
32
|
+
}
|
|
33
|
+
const approveSafeTxHash = yield* safeMultisigBatchWrite([approveTx], token.chainId);
|
|
34
|
+
const mainSafeTxHash = yield* safeMultisigBatchWrite([mainTransaction], token.chainId);
|
|
35
|
+
return {
|
|
36
|
+
_tag: "fallback-required-approval",
|
|
37
|
+
approveSafeTxHash,
|
|
38
|
+
mainSafeTxHash,
|
|
39
|
+
};
|
|
21
40
|
});
|
|
22
41
|
//# sourceMappingURL=allowance.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowance.js","sourceRoot":"","sources":["../../src/safe/allowance.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"allowance.js","sourceRoot":"","sources":["../../src/safe/allowance.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAwD5D,MAAM,UAAU,kBAAkB,CAAC,MAAmC;IACpE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEjD,MAAM,IAAI,GAAG,kBAAkB,CAAC;QAC9B,GAAG,EAAE,QAAQ;QACb,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,SAAS;KACxB,CAAC,CAAC;IAEH,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC/C,CAAC;AAgBD,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC,EACvF,MAAuC;IAEvC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,IAAI,SAAS,CAAC;IAEvD,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACnC,MAAM;QACN,OAAO;QACP,YAAY,EAAE,KAAK,CAAC,OAAO;KAC5B,CAAC,CAAC;IAGH,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAC7F,MAAM,CAAC,MAAM,CACd,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO;YACL,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,OAAO,CAAC,KAAK;SACgB,CAAC;IAC9C,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3B,IAAI,CAAC,CAAC,KAAK,YAAY,6BAA6B,CAAC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChF,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAGD,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACpF,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAEvF,OAAO;QACL,IAAI,EAAE,4BAA4B;QAClC,iBAAiB;QACjB,cAAc;KAC2B,CAAC;AAC9C,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Safe multisig allowance batching.\n *\n * Prepends an ERC-20 approve() tx to a main tx and submits both as a\n * single atomic Safe batch. Every dApp doing token operations through\n * Safe needs this \"approve + action\" pattern.\n *\n * @module safe/allowance\n */\n\nimport { Effect } from \"effect\";\nimport type { Address, Hash } from \"viem\";\nimport { encodeFunctionData, erc20Abi } from \"viem\";\nimport { safeMultisigBatchWrite } from \"./batch.js\";\nimport { SafeMultiSendUnavailableError } from \"./errors.js\";\nimport type { SafeMultisigTx } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Parameters for Safe multisig allowance batching. */\nexport type SafeMultisigAllowAndWriteParams = {\n /** Main transaction to execute after approval. */\n readonly mainTransaction: SafeMultisigTx;\n /** Spender contract that needs the allowance. */\n readonly spender: Address;\n /** Token to approve. */\n readonly token: {\n readonly address: Address;\n readonly chainId: number;\n };\n /** Approval amount (e.g. MaxUint256 or a computed amount). */\n readonly amount: bigint;\n /**\n * MultiSend behavior:\n * - \"require\": fail if MultiSend is unavailable\n * - \"fallback-required-approval\": submit separate Safe proposals for approve and main tx\n */\n readonly multiSendStrategy?: \"require\" | \"fallback-required-approval\";\n};\n\nexport type SafeMultisigAllowAndWriteResult =\n | {\n readonly _tag: \"batched\";\n readonly safeTxHash: Hash;\n }\n | {\n readonly _tag: \"fallback-required-approval\";\n readonly approveSafeTxHash: Hash;\n readonly mainSafeTxHash: Hash;\n };\n\n/** Parameters for building a standalone ERC-20 approve tx. */\nexport type SafeMultisigApproveTxParams = {\n /** Approval amount. */\n readonly amount: bigint;\n /** Spender contract that needs the allowance. */\n readonly spender: Address;\n /** Token contract address. */\n readonly tokenAddress: Address;\n};\n\n// ---------------------------------------------------------------------------\n// buildSafeApproveTx\n// ---------------------------------------------------------------------------\n\n/**\n * Encode an ERC-20 `approve(spender, amount)` call as a Safe transaction.\n */\nexport function buildSafeApproveTx(params: SafeMultisigApproveTxParams): SafeMultisigTx {\n const { amount, spender, tokenAddress } = params;\n\n const data = encodeFunctionData({\n abi: erc20Abi,\n args: [spender, amount],\n functionName: \"approve\",\n });\n\n return { data, to: tokenAddress, value: 0n };\n}\n\n// ---------------------------------------------------------------------------\n// safeMultisigAllowAndWrite\n// ---------------------------------------------------------------------------\n\n/**\n * Batch an ERC-20 approve tx with a main tx as a single Safe proposal.\n *\n * Approve is placed first so the allowance is set before the main contract\n * interaction. Both execute atomically — Safe users sign once.\n *\n * On chains where MultiSend is not deployed, fails with\n * `SafeMultiSendUnavailableError`. Callers should catch that tag and fall\n * back to sequential approve → action flow.\n */\nexport const safeMultisigAllowAndWrite = Effect.fn(\"safeMultisigAllowAndWrite\")(function* (\n params: SafeMultisigAllowAndWriteParams\n) {\n const { amount, mainTransaction, spender, token } = params;\n const strategy = params.multiSendStrategy ?? \"require\";\n\n const approveTx = buildSafeApproveTx({\n amount,\n spender,\n tokenAddress: token.address,\n });\n\n // Approve first, then main transaction\n const batched = yield* safeMultisigBatchWrite([approveTx, mainTransaction], token.chainId).pipe(\n Effect.either\n );\n\n if (batched._tag === \"Right\") {\n return {\n _tag: \"batched\",\n safeTxHash: batched.right,\n } satisfies SafeMultisigAllowAndWriteResult;\n }\n\n const error = batched.left;\n\n if (!(error instanceof SafeMultiSendUnavailableError) || strategy === \"require\") {\n return yield* Effect.fail(error);\n }\n\n // Fallback for chains without MultiSend: submit two standalone Safe tx proposals.\n const approveSafeTxHash = yield* safeMultisigBatchWrite([approveTx], token.chainId);\n const mainSafeTxHash = yield* safeMultisigBatchWrite([mainTransaction], token.chainId);\n\n return {\n _tag: \"fallback-required-approval\",\n approveSafeTxHash,\n mainSafeTxHash,\n } satisfies SafeMultisigAllowAndWriteResult;\n});\n"]}
|
package/dist/safe/errors.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
+
import type { Hash, Hex } from "viem";
|
|
2
3
|
declare const SafeAppsSdkUnavailableError_base: Schema.TaggedErrorClass<SafeAppsSdkUnavailableError, "SafeAppsSdkUnavailableError", {
|
|
3
4
|
readonly _tag: Schema.tag<"SafeAppsSdkUnavailableError">;
|
|
4
5
|
} & {
|
|
@@ -85,6 +86,7 @@ declare const SafeMultiSendUnavailableError_base: Schema.TaggedErrorClass<SafeMu
|
|
|
85
86
|
export declare class SafeMultiSendUnavailableError extends SafeMultiSendUnavailableError_base {
|
|
86
87
|
}
|
|
87
88
|
export declare function getSafeErrorMessage(error: unknown): string | undefined;
|
|
89
|
+
export declare function toSafeMultisigTxLookupError(safeTxHash: Hash | Hex, cause: unknown, retryable?: boolean): SafeMultisigTxLookupError;
|
|
88
90
|
export declare function isMultiSendUnavailableError(error: unknown): boolean;
|
|
89
91
|
export {};
|
|
90
92
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/safe/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/safe/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;;;;;;;AAGtC,qBAAa,2BAA4B,SAAQ,gCAGhD;CAAG;;;;;;AAEJ,qBAAa,wBAAyB,SAAQ,6BAG7C;CAAG;;;;;;;AAGJ,qBAAa,gCAAiC,SAAQ,qCAGrD;CAAG;;;;;;;AAEJ,qBAAa,yBAA0B,SAAQ,8BAG9C;CAAG;;;;;;;AAEJ,qBAAa,6BAA8B,SAAQ,kCAGlD;CAAG;;;;;;;;;AAEJ,qBAAa,yBAA0B,SAAQ,8BAQ9C;CAAG;;;;;;;;;AAEJ,qBAAa,mCAAoC,SAAQ,wCAQxD;CAAG;;;;;;;AAGJ,qBAAa,kBAAmB,SAAQ,uBAGvC;CAAG;;;;;;;;AAEJ,qBAAa,6BAA8B,SAAQ,kCAOlD;CAAG;;;;;;;;AAIJ,qBAAa,6BAA8B,SAAQ,kCAOlD;CAAG;AA0GJ,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEtE;AAKD,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,IAAI,GAAG,GAAG,EACtB,KAAK,EAAE,OAAO,EACd,SAAS,UAAO,GACf,yBAAyB,CAU3B;AAMD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnE"}
|
package/dist/safe/errors.js
CHANGED
|
@@ -109,6 +109,17 @@ function getSafeErrorMessageInternal(error, depth) {
|
|
|
109
109
|
export function getSafeErrorMessage(error) {
|
|
110
110
|
return getSafeErrorMessageInternal(error, 0);
|
|
111
111
|
}
|
|
112
|
+
export function toSafeMultisigTxLookupError(safeTxHash, cause, retryable = true) {
|
|
113
|
+
const detail = getSafeErrorMessage(cause);
|
|
114
|
+
return new SafeMultisigTxLookupError({
|
|
115
|
+
cause,
|
|
116
|
+
message: detail
|
|
117
|
+
? `Failed to lookup Safe tx ${safeTxHash}: ${detail}`
|
|
118
|
+
: `Failed to lookup Safe tx ${safeTxHash}`,
|
|
119
|
+
retryable,
|
|
120
|
+
safeTxHash,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
112
123
|
export function isMultiSendUnavailableError(error) {
|
|
113
124
|
return checkMultiSendError(error, 0);
|
|
114
125
|
}
|
package/dist/safe/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/safe/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { Schema } from \"effect\";\n\n// SDK availability errors\nexport class SafeAppsSdkUnavailableError extends Schema.TaggedError<SafeAppsSdkUnavailableError>()(\n \"SafeAppsSdkUnavailableError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class NotInSafeAppContextError extends Schema.TaggedError<NotInSafeAppContextError>()(\n \"NotInSafeAppContextError\",\n { message: Schema.String }\n) {}\n\n// Safe operation errors\nexport class SafeMultisigInfoUnavailableError extends Schema.TaggedError<SafeMultisigInfoUnavailableError>()(\n \"SafeMultisigInfoUnavailableError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigSettingsError extends Schema.TaggedError<SafeMultisigSettingsError>()(\n \"SafeMultisigSettingsError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigTxSubmissionError extends Schema.TaggedError<SafeMultisigTxSubmissionError>()(\n \"SafeMultisigTxSubmissionError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigTxLookupError extends Schema.TaggedError<SafeMultisigTxLookupError>()(\n \"SafeMultisigTxLookupError\",\n {\n cause: Schema.optional(Schema.Unknown),\n message: Schema.String,\n retryable: Schema.Boolean,\n safeTxHash: Schema.String,\n }\n) {}\n\nexport class SafeMultisigTxExecutionTimeoutError extends Schema.TaggedError<SafeMultisigTxExecutionTimeoutError>()(\n \"SafeMultisigTxExecutionTimeoutError\",\n {\n lastStatus: Schema.optional(Schema.String),\n message: Schema.String,\n safeTxHash: Schema.String,\n timeout: Schema.Number,\n }\n) {}\n\n// Signing errors\nexport class SignTypedDataError extends Schema.TaggedError<SignTypedDataError>()(\n \"SignTypedDataError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class OffchainSignatureTimeoutError extends Schema.TaggedError<OffchainSignatureTimeoutError>()(\n \"OffchainSignatureTimeoutError\",\n {\n message: Schema.String,\n messageHash: Schema.String,\n timeout: Schema.Number,\n }\n) {}\n\n// MultiSend errors\n\nexport class SafeMultiSendUnavailableError extends Schema.TaggedError<SafeMultiSendUnavailableError>()(\n \"SafeMultiSendUnavailableError\",\n {\n cause: Schema.optional(Schema.Unknown),\n chainId: Schema.optional(Schema.Number),\n message: Schema.String,\n }\n) {}\n\n// MultiSend error detection\n\nconst MULTISEND_ERROR_PATTERN = /MultiSend contract not deployed|MultiSend call failed/i;\nconst MAX_ERROR_DEPTH = 10;\nconst USER_REJECTION_CODE = 4001;\nconst MAX_ERROR_MESSAGE_DEPTH = 10;\n\ntype ErrorMessageShape = {\n readonly cause?: unknown;\n readonly code?: unknown;\n readonly error?: unknown;\n readonly errors?: unknown;\n readonly message?: unknown;\n readonly shortMessage?: unknown;\n};\n\nfunction toNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction isUserRejectionCode(code: unknown): boolean {\n return code === USER_REJECTION_CODE || code === `${USER_REJECTION_CODE}`;\n}\n\nfunction getSafeErrorMessageInternal(error: unknown, depth: number): string | undefined {\n if (!error || depth >= MAX_ERROR_MESSAGE_DEPTH) {\n return undefined;\n }\n\n if (typeof error === \"string\") {\n return toNonEmptyString(error);\n }\n\n if (error instanceof Error) {\n if (isUserRejectionCode((error as { code?: unknown }).code)) {\n return \"User rejected the request\";\n }\n\n const shortMessage = toNonEmptyString((error as { shortMessage?: unknown }).shortMessage);\n if (shortMessage) {\n return shortMessage;\n }\n\n const message = toNonEmptyString(error.message);\n if (message) {\n return message;\n }\n\n return getSafeErrorMessageInternal((error as { cause?: unknown }).cause, depth + 1);\n }\n\n if (typeof error !== \"object\") {\n return undefined;\n }\n\n const typedError = error as ErrorMessageShape;\n\n if (isUserRejectionCode(typedError.code)) {\n return \"User rejected the request\";\n }\n\n const shortMessage = toNonEmptyString(typedError.shortMessage);\n if (shortMessage) {\n return shortMessage;\n }\n\n const message = toNonEmptyString(typedError.message);\n if (message) {\n return message;\n }\n\n const causeMessage = getSafeErrorMessageInternal(typedError.cause, depth + 1);\n if (causeMessage) {\n return causeMessage;\n }\n\n const nestedErrorMessage = getSafeErrorMessageInternal(typedError.error, depth + 1);\n if (nestedErrorMessage) {\n return nestedErrorMessage;\n }\n\n if (!Array.isArray(typedError.errors)) {\n return undefined;\n }\n\n for (const nestedError of typedError.errors) {\n const nestedMessage = getSafeErrorMessageInternal(nestedError, depth + 1);\n if (nestedMessage) {\n return nestedMessage;\n }\n }\n\n return undefined;\n}\n\n/**\n * Best-effort extraction of a human-readable Safe SDK error message.\n * Preserves nested `cause` / `error` chains and handles EIP-1193 user rejection codes.\n */\nexport function getSafeErrorMessage(error: unknown): string | undefined {\n return getSafeErrorMessageInternal(error, 0);\n}\n\n/**\n * Check if an error is caused by MultiSend contract unavailability.\n * Recursively checks error messages and causes for MultiSend-related strings.\n */\nexport function isMultiSendUnavailableError(error: unknown): boolean {\n return checkMultiSendError(error, 0);\n}\n\nfunction checkMultiSendError(error: unknown, depth: number): boolean {\n if (depth >= MAX_ERROR_DEPTH) {\n return false;\n }\n\n if (typeof error === \"string\") {\n return MULTISEND_ERROR_PATTERN.test(error);\n }\n\n if (typeof error === \"object\" && error !== null) {\n const { message, cause } = error as { message?: unknown; cause?: unknown };\n\n if (typeof message === \"string\" && MULTISEND_ERROR_PATTERN.test(message)) {\n return true;\n }\n\n if (cause) {\n return checkMultiSendError(cause, depth + 1);\n }\n }\n\n return false;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/safe/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { Schema } from \"effect\";\nimport type { Hash, Hex } from \"viem\";\n\n// SDK availability errors\nexport class SafeAppsSdkUnavailableError extends Schema.TaggedError<SafeAppsSdkUnavailableError>()(\n \"SafeAppsSdkUnavailableError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class NotInSafeAppContextError extends Schema.TaggedError<NotInSafeAppContextError>()(\n \"NotInSafeAppContextError\",\n { message: Schema.String }\n) {}\n\n// Safe operation errors\nexport class SafeMultisigInfoUnavailableError extends Schema.TaggedError<SafeMultisigInfoUnavailableError>()(\n \"SafeMultisigInfoUnavailableError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigSettingsError extends Schema.TaggedError<SafeMultisigSettingsError>()(\n \"SafeMultisigSettingsError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigTxSubmissionError extends Schema.TaggedError<SafeMultisigTxSubmissionError>()(\n \"SafeMultisigTxSubmissionError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class SafeMultisigTxLookupError extends Schema.TaggedError<SafeMultisigTxLookupError>()(\n \"SafeMultisigTxLookupError\",\n {\n cause: Schema.optional(Schema.Unknown),\n message: Schema.String,\n retryable: Schema.Boolean,\n safeTxHash: Schema.String,\n }\n) {}\n\nexport class SafeMultisigTxExecutionTimeoutError extends Schema.TaggedError<SafeMultisigTxExecutionTimeoutError>()(\n \"SafeMultisigTxExecutionTimeoutError\",\n {\n lastStatus: Schema.optional(Schema.String),\n message: Schema.String,\n safeTxHash: Schema.String,\n timeout: Schema.Number,\n }\n) {}\n\n// Signing errors\nexport class SignTypedDataError extends Schema.TaggedError<SignTypedDataError>()(\n \"SignTypedDataError\",\n { cause: Schema.optional(Schema.Unknown), message: Schema.String }\n) {}\n\nexport class OffchainSignatureTimeoutError extends Schema.TaggedError<OffchainSignatureTimeoutError>()(\n \"OffchainSignatureTimeoutError\",\n {\n message: Schema.String,\n messageHash: Schema.String,\n timeout: Schema.Number,\n }\n) {}\n\n// MultiSend errors\n\nexport class SafeMultiSendUnavailableError extends Schema.TaggedError<SafeMultiSendUnavailableError>()(\n \"SafeMultiSendUnavailableError\",\n {\n cause: Schema.optional(Schema.Unknown),\n chainId: Schema.optional(Schema.Number),\n message: Schema.String,\n }\n) {}\n\n// MultiSend error detection\n\nconst MULTISEND_ERROR_PATTERN = /MultiSend contract not deployed|MultiSend call failed/i;\nconst MAX_ERROR_DEPTH = 10;\nconst USER_REJECTION_CODE = 4001;\nconst MAX_ERROR_MESSAGE_DEPTH = 10;\n\ntype ErrorMessageShape = {\n readonly cause?: unknown;\n readonly code?: unknown;\n readonly error?: unknown;\n readonly errors?: unknown;\n readonly message?: unknown;\n readonly shortMessage?: unknown;\n};\n\nfunction toNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction isUserRejectionCode(code: unknown): boolean {\n return code === USER_REJECTION_CODE || code === `${USER_REJECTION_CODE}`;\n}\n\nfunction getSafeErrorMessageInternal(error: unknown, depth: number): string | undefined {\n if (!error || depth >= MAX_ERROR_MESSAGE_DEPTH) {\n return undefined;\n }\n\n if (typeof error === \"string\") {\n return toNonEmptyString(error);\n }\n\n if (error instanceof Error) {\n if (isUserRejectionCode((error as { code?: unknown }).code)) {\n return \"User rejected the request\";\n }\n\n const shortMessage = toNonEmptyString((error as { shortMessage?: unknown }).shortMessage);\n if (shortMessage) {\n return shortMessage;\n }\n\n const message = toNonEmptyString(error.message);\n if (message) {\n return message;\n }\n\n return getSafeErrorMessageInternal((error as { cause?: unknown }).cause, depth + 1);\n }\n\n if (typeof error !== \"object\") {\n return undefined;\n }\n\n const typedError = error as ErrorMessageShape;\n\n if (isUserRejectionCode(typedError.code)) {\n return \"User rejected the request\";\n }\n\n const shortMessage = toNonEmptyString(typedError.shortMessage);\n if (shortMessage) {\n return shortMessage;\n }\n\n const message = toNonEmptyString(typedError.message);\n if (message) {\n return message;\n }\n\n const causeMessage = getSafeErrorMessageInternal(typedError.cause, depth + 1);\n if (causeMessage) {\n return causeMessage;\n }\n\n const nestedErrorMessage = getSafeErrorMessageInternal(typedError.error, depth + 1);\n if (nestedErrorMessage) {\n return nestedErrorMessage;\n }\n\n if (!Array.isArray(typedError.errors)) {\n return undefined;\n }\n\n for (const nestedError of typedError.errors) {\n const nestedMessage = getSafeErrorMessageInternal(nestedError, depth + 1);\n if (nestedMessage) {\n return nestedMessage;\n }\n }\n\n return undefined;\n}\n\n/**\n * Best-effort extraction of a human-readable Safe SDK error message.\n * Preserves nested `cause` / `error` chains and handles EIP-1193 user rejection codes.\n */\nexport function getSafeErrorMessage(error: unknown): string | undefined {\n return getSafeErrorMessageInternal(error, 0);\n}\n\n/**\n * Canonical constructor for Safe tx lookup errors.\n */\nexport function toSafeMultisigTxLookupError(\n safeTxHash: Hash | Hex,\n cause: unknown,\n retryable = true\n): SafeMultisigTxLookupError {\n const detail = getSafeErrorMessage(cause);\n return new SafeMultisigTxLookupError({\n cause,\n message: detail\n ? `Failed to lookup Safe tx ${safeTxHash}: ${detail}`\n : `Failed to lookup Safe tx ${safeTxHash}`,\n retryable,\n safeTxHash,\n });\n}\n\n/**\n * Check if an error is caused by MultiSend contract unavailability.\n * Recursively checks error messages and causes for MultiSend-related strings.\n */\nexport function isMultiSendUnavailableError(error: unknown): boolean {\n return checkMultiSendError(error, 0);\n}\n\nfunction checkMultiSendError(error: unknown, depth: number): boolean {\n if (depth >= MAX_ERROR_DEPTH) {\n return false;\n }\n\n if (typeof error === \"string\") {\n return MULTISEND_ERROR_PATTERN.test(error);\n }\n\n if (typeof error === \"object\" && error !== null) {\n const { message, cause } = error as { message?: unknown; cause?: unknown };\n\n if (typeof message === \"string\" && MULTISEND_ERROR_PATTERN.test(message)) {\n return true;\n }\n\n if (cause) {\n return checkMultiSendError(cause, depth + 1);\n }\n }\n\n return false;\n}\n"]}
|
package/dist/safe/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
export { buildSafeApproveTx, type SafeMultisigAllowAndWriteParams, type SafeMultisigApproveTxParams, safeMultisigAllowAndWrite, } from "./allowance.js";
|
|
1
|
+
export { buildSafeApproveTx, type SafeMultisigAllowAndWriteParams, type SafeMultisigAllowAndWriteResult, type SafeMultisigApproveTxParams, safeMultisigAllowAndWrite, } from "./allowance.js";
|
|
2
2
|
export { safeMultisigBatchWrite } from "./batch.js";
|
|
3
3
|
export type { SafeDetectionParams, SafeDetectionResult } from "./detection.js";
|
|
4
4
|
export { isSafeMultisig, SafeMultisigDetectionError } from "./detection.js";
|
|
5
|
-
export { isMultiSendUnavailableError, NotInSafeAppContextError, OffchainSignatureTimeoutError, SafeAppsSdkUnavailableError, SafeMultiSendUnavailableError, SafeMultisigInfoUnavailableError, SafeMultisigSettingsError, SafeMultisigTxExecutionTimeoutError, SafeMultisigTxLookupError, SafeMultisigTxSubmissionError, SignTypedDataError, } from "./errors.js";
|
|
5
|
+
export { isMultiSendUnavailableError, NotInSafeAppContextError, OffchainSignatureTimeoutError, SafeAppsSdkUnavailableError, SafeMultiSendUnavailableError, SafeMultisigInfoUnavailableError, SafeMultisigSettingsError, SafeMultisigTxExecutionTimeoutError, SafeMultisigTxLookupError, SafeMultisigTxSubmissionError, SignTypedDataError, toSafeMultisigTxLookupError, } from "./errors.js";
|
|
6
6
|
export { type SafeAppsServiceConfig, SafeAppsServiceLive } from "./live.js";
|
|
7
|
+
export { SafeWriteExecutionAdapterLive } from "./pipeline-adapter.js";
|
|
7
8
|
export { SafeAppsService, type SafeAppsServiceShape } from "./service.js";
|
|
8
9
|
export * from "./simulation/index.js";
|
|
9
10
|
export { getSafeMultisigTxStatus, type SafeMultisigTxStatus, type SafeMultisigWaitOptions, type SafeMultisigWaitResult, waitForSafeMultisigTx, } from "./tx-lifecycle.js";
|
|
10
11
|
export { type GetSafeMultisigTxUrlParams, getSafeMultisigTxUrl } from "./tx-url.js";
|
|
11
12
|
export type { EIP712TypedData, OffchainSignaturePolicy, OffchainSignatureResult, SafeMultisigInfo, SafeMultisigTx, SafeMultisigTxInfo, SafeMultisigTxResult, SafeMultisigTxSubmission, SafeWaitPolicy, SignTypedDataResult, } from "./types.js";
|
|
13
|
+
export { type SafeWriteAndTrackError, type SafeWriteAndTrackParams, type SafeWriteAndTrackResult, type SafeWriteAndTrackState, safeWriteAndTrack, } from "./write-and-track.js";
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/safe/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/safe/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/safe/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,KAAK,+BAA+B,EACpC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAE1E,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EACL,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEpF,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,iBAAiB,GAClB,MAAM,sBAAsB,CAAC"}
|
package/dist/safe/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { buildSafeApproveTx, safeMultisigAllowAndWrite, } from "./allowance.js";
|
|
2
2
|
export { safeMultisigBatchWrite } from "./batch.js";
|
|
3
3
|
export { isSafeMultisig, SafeMultisigDetectionError } from "./detection.js";
|
|
4
|
-
export { isMultiSendUnavailableError, NotInSafeAppContextError, OffchainSignatureTimeoutError, SafeAppsSdkUnavailableError, SafeMultiSendUnavailableError, SafeMultisigInfoUnavailableError, SafeMultisigSettingsError, SafeMultisigTxExecutionTimeoutError, SafeMultisigTxLookupError, SafeMultisigTxSubmissionError, SignTypedDataError, } from "./errors.js";
|
|
4
|
+
export { isMultiSendUnavailableError, NotInSafeAppContextError, OffchainSignatureTimeoutError, SafeAppsSdkUnavailableError, SafeMultiSendUnavailableError, SafeMultisigInfoUnavailableError, SafeMultisigSettingsError, SafeMultisigTxExecutionTimeoutError, SafeMultisigTxLookupError, SafeMultisigTxSubmissionError, SignTypedDataError, toSafeMultisigTxLookupError, } from "./errors.js";
|
|
5
5
|
export { SafeAppsServiceLive } from "./live.js";
|
|
6
|
+
export { SafeWriteExecutionAdapterLive } from "./pipeline-adapter.js";
|
|
6
7
|
export { SafeAppsService } from "./service.js";
|
|
7
8
|
export * from "./simulation/index.js";
|
|
8
9
|
export { getSafeMultisigTxStatus, waitForSafeMultisigTx, } from "./tx-lifecycle.js";
|
|
9
10
|
export { getSafeMultisigTxUrl } from "./tx-url.js";
|
|
11
|
+
export { safeWriteAndTrack, } from "./write-and-track.js";
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
package/dist/safe/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/safe/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/safe/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAIlB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EAA8B,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,eAAe,EAA6B,MAAM,cAAc,CAAC;AAE1E,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EACL,uBAAuB,EAIvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAmC,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAcpF,OAAO,EAKL,iBAAiB,GAClB,MAAM,sBAAsB,CAAC","sourcesContent":["// Allowance batching (approve + action as one Safe proposal)\nexport {\n buildSafeApproveTx,\n type SafeMultisigAllowAndWriteParams,\n type SafeMultisigAllowAndWriteResult,\n type SafeMultisigApproveTxParams,\n safeMultisigAllowAndWrite,\n} from \"./allowance.js\";\n// Batch write (atomic multi-call via MultiSend)\nexport { safeMultisigBatchWrite } from \"./batch.js\";\n// Detection\nexport type { SafeDetectionParams, SafeDetectionResult } from \"./detection.js\";\nexport { isSafeMultisig, SafeMultisigDetectionError } from \"./detection.js\";\n// Errors\nexport {\n isMultiSendUnavailableError,\n NotInSafeAppContextError,\n OffchainSignatureTimeoutError,\n SafeAppsSdkUnavailableError,\n SafeMultiSendUnavailableError,\n SafeMultisigInfoUnavailableError,\n SafeMultisigSettingsError,\n SafeMultisigTxExecutionTimeoutError,\n SafeMultisigTxLookupError,\n SafeMultisigTxSubmissionError,\n SignTypedDataError,\n toSafeMultisigTxLookupError,\n} from \"./errors.js\";\n// Service and layer\nexport { type SafeAppsServiceConfig, SafeAppsServiceLive } from \"./live.js\";\nexport { SafeWriteExecutionAdapterLive } from \"./pipeline-adapter.js\";\nexport { SafeAppsService, type SafeAppsServiceShape } from \"./service.js\";\n// Simulation\nexport * from \"./simulation/index.js\";\n// Transaction lifecycle (polling, status checks)\nexport {\n getSafeMultisigTxStatus,\n type SafeMultisigTxStatus,\n type SafeMultisigWaitOptions,\n type SafeMultisigWaitResult,\n waitForSafeMultisigTx,\n} from \"./tx-lifecycle.js\";\n// Safe URL helpers\nexport { type GetSafeMultisigTxUrlParams, getSafeMultisigTxUrl } from \"./tx-url.js\";\n// Types\nexport type {\n EIP712TypedData,\n OffchainSignaturePolicy,\n OffchainSignatureResult,\n SafeMultisigInfo,\n SafeMultisigTx,\n SafeMultisigTxInfo,\n SafeMultisigTxResult,\n SafeMultisigTxSubmission,\n SafeWaitPolicy,\n SignTypedDataResult,\n} from \"./types.js\";\nexport {\n type SafeWriteAndTrackError,\n type SafeWriteAndTrackParams,\n type SafeWriteAndTrackResult,\n type SafeWriteAndTrackState,\n safeWriteAndTrack,\n} from \"./write-and-track.js\";\n"]}
|
package/dist/safe/live.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/safe/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAU,KAAK,EAAe,MAAM,QAAQ,CAAC;AASpD,OAAO,KAAK,EAAuB,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/safe/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAU,KAAK,EAAe,MAAM,QAAQ,CAAC;AASpD,OAAO,KAAK,EAAuB,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAgB3E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AA4CtD,eAAO,MAAM,mBAAmB,GAAI,SAAS,qBAAqB,mDA+T/D,CAAC"}
|