@rango-dev/provider-safe 0.53.1-next.3 → 0.54.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/chunk-IWQRD3YN.js +2 -0
- package/dist/chunk-IWQRD3YN.js.map +7 -0
- package/dist/constants.d.ts +4 -0
- package/dist/evm-GF64T75N.js +2 -0
- package/dist/evm-GF64T75N.js.map +7 -0
- package/dist/mod.d.ts +2 -0
- package/dist/mod.js +2 -0
- package/dist/mod.js.map +7 -0
- package/dist/namespaces/evm.d.ts +3 -0
- package/dist/provider-safe.build.json +1 -1
- package/dist/provider.d.ts +2 -0
- package/dist/safe.d.ts +5 -0
- package/dist/signers/evm.d.ts +9 -6
- package/dist/utils.d.ts +6 -0
- package/package.json +11 -9
- package/readme.md +12 -1
- package/src/constants.ts +42 -0
- package/src/mod.ts +8 -0
- package/src/namespaces/evm.ts +50 -0
- package/src/provider.ts +30 -0
- package/src/safe.ts +53 -0
- package/src/signers/evm.ts +24 -9
- package/src/utils.ts +24 -0
- package/dist/chunk-5CP7BBMP.js +0 -2
- package/dist/chunk-5CP7BBMP.js.map +0 -7
- package/dist/evm-TZ6OXXGG.js +0 -2
- package/dist/evm-TZ6OXXGG.js.map +0 -7
- package/dist/helpers.d.ts +0 -3
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -7
- package/src/helpers.ts +0 -29
- package/src/index.ts +0 -94
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var s=Object.defineProperty;var n=(r,e)=>s(r,"name",{value:e,configurable:!0});import{SafeAppProvider as u}from"@safe-global/safe-apps-provider";import t from"@safe-global/safe-apps-sdk";var p={debug:!1},f=t;typeof t!="function"&&typeof t.default=="function"&&(f=t.default);var a=new f(p),o=null;async function S(){let e=await Promise.race([a.safe.getInfo(),new Promise(i=>setTimeout(i,200))]);return e?(o=new u(e,a),!0):(o=null,!1)}n(S,"initSafe");var m=n(()=>{if(!o)throw new Error("Safe is not available. Make sure the dApp is running as a Safe App inside Safe{Wallet}.");return o},"getSafeProviderOrThrow");export{n as a,a as b,S as c,m as d};
|
|
2
|
+
//# sourceMappingURL=chunk-IWQRD3YN.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/safe.ts"],
|
|
4
|
+
"sourcesContent": ["import { SafeAppProvider } from '@safe-global/safe-apps-provider';\nimport SafeAppsSDK from '@safe-global/safe-apps-sdk';\n\nconst options = {\n debug: false,\n};\n\n/*\n * similar to:\n * https://github.com/wagmi-dev/references/pull/114\n */\nlet SDK = SafeAppsSDK;\nif (\n typeof SafeAppsSDK !== 'function' &&\n // @ts-expect-error This import error is not visible to TypeScript\n typeof SafeAppsSDK.default === 'function'\n) {\n SDK = (SafeAppsSDK as unknown as { default: typeof SafeAppsSDK }).default;\n}\nexport const sdk = new SDK(options);\n\n/*\n * Safe runs as a Safe App inside the Safe{Wallet} iframe, so the provider can\n * only be created asynchronously once the SDK resolves the Safe info. We cache\n * the instance here so the hub actions (connect, getChainId, signers, \u2026) can\n * retrieve it synchronously via `evmSafe()` after detection has completed.\n */\nlet safeProvider: SafeAppProvider | null = null;\n\nexport async function initSafe(): Promise<boolean> {\n const timeout = 200;\n const accountInfo = await Promise.race([\n sdk.safe.getInfo(),\n new Promise<undefined>((resolve) => setTimeout(resolve, timeout)),\n ]);\n\n if (!accountInfo) {\n safeProvider = null;\n return false;\n }\n\n safeProvider = new SafeAppProvider(accountInfo, sdk);\n return true;\n}\n\nexport const getSafeProviderOrThrow = () => {\n if (!safeProvider) {\n throw new Error(\n 'Safe is not available. Make sure the dApp is running as a Safe App inside Safe{Wallet}.'\n );\n }\n return safeProvider;\n};\n"],
|
|
5
|
+
"mappings": "+EAAA,OAAS,mBAAAA,MAAuB,kCAChC,OAAOC,MAAiB,6BAExB,IAAMC,EAAU,CACd,MAAO,EACT,EAMIC,EAAMC,EAER,OAAOA,GAAgB,YAEvB,OAAOA,EAAY,SAAY,aAE/BD,EAAOC,EAA2D,SAE7D,IAAMC,EAAM,IAAIF,EAAID,CAAO,EAQ9BI,EAAuC,KAE3C,eAAsBC,GAA6B,CAEjD,IAAMC,EAAc,MAAM,QAAQ,KAAK,CACrCH,EAAI,KAAK,QAAQ,EACjB,IAAI,QAAoBI,GAAY,WAAWA,EAAS,GAAO,CAAC,CAClE,CAAC,EAED,OAAKD,GAKLF,EAAe,IAAII,EAAgBF,EAAaH,CAAG,EAC5C,KALLC,EAAe,KACR,GAKX,CAdsBK,EAAAJ,EAAA,YAgBf,IAAMK,EAAyBD,EAAA,IAAM,CAC1C,GAAI,CAACL,EACH,MAAM,IAAI,MACR,yFACF,EAEF,OAAOA,CACT,EAPsC",
|
|
6
|
+
"names": ["SafeAppProvider", "SafeAppsSDK", "options", "SDK", "SafeAppsSDK", "sdk", "safeProvider", "initSafe", "accountInfo", "resolve", "SafeAppProvider", "__name", "getSafeProviderOrThrow"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as i,b as r}from"./chunk-IWQRD3YN.js";import{DefaultEvmSigner as h,waitMs as m}from"@rango-dev/signer-evm";import{TransactionStatus as o}from"@safe-global/safe-apps-sdk";async function c(n){let s;for(;!s;)try{let t=await r.txs.getBySafeTxHash(n);t.txStatus===o.AWAITING_CONFIRMATIONS||t.txStatus===o.AWAITING_EXECUTION?await m(5e3):t.txHash&&(s=t.txHash)}catch{s=n}return{txHash:s}}i(c,"getTxHash");var g=class{static{i(this,"CustomEvmSigner")}signer;constructor(s){this.signer=new h(s)}async signMessage(s){let{signature:e}=await r.txs.signMessage(s);return e}async signAndSendTx(s,e,t){let{hash:a,response:p}=await this.signer.signAndSendTx(s,e,t);return{hash:a,response:{...p,hashRequiringUpdate:!0}}}async wait(s,e,t){if(t&&!t.hashRequiringUpdate)return{hash:s,response:t,chainId:e};let{txHash:a}=await c(s);return{hash:a,response:{...t,hashRequiringUpdate:!1},chainId:e}}};export{g as CustomEvmSigner,c as getTxHash};
|
|
2
|
+
//# sourceMappingURL=evm-GF64T75N.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/signers/evm.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ProviderAPI } from '@hub3js/evm';\nimport type { OffChainSignMessageResponse } from '@safe-global/safe-apps-sdk';\nimport type { TransactionResponse } from 'ethers';\nimport type { GenericSigner } from 'rango-types';\nimport type { EvmTransaction } from 'rango-types/mainApi';\n\nimport { DefaultEvmSigner, waitMs } from '@rango-dev/signer-evm';\nimport { TransactionStatus } from '@safe-global/safe-apps-sdk';\n\nimport { sdk } from '../safe.ts';\n\ntype SafeTransactionResponse = Partial<TransactionResponse> & {\n hashRequiringUpdate: boolean;\n};\n\nexport async function getTxHash(safeHash: string): Promise<{ txHash: string }> {\n let txHash;\n const timeout = 5_000;\n\n while (!txHash) {\n try {\n /** The SDK will be pinged until a txHash is available and the txStatus is in an end-state */\n const queued = await sdk.txs.getBySafeTxHash(safeHash);\n if (\n queued.txStatus === TransactionStatus.AWAITING_CONFIRMATIONS ||\n queued.txStatus === TransactionStatus.AWAITING_EXECUTION\n ) {\n /** Mimic a status watcher by checking once every 5 seconds */\n await waitMs(timeout);\n } else if (queued.txHash) {\n /** The txStatus is in an end-state (e.g. success) so we probably have a valid, on chain txHash*/\n txHash = queued.txHash;\n }\n } catch {\n txHash = safeHash;\n }\n }\n return { txHash };\n}\n\nexport class CustomEvmSigner implements GenericSigner<EvmTransaction> {\n private signer;\n\n constructor(provider: ProviderAPI) {\n this.signer = new DefaultEvmSigner(provider);\n }\n\n async signMessage(msg: string): Promise<string> {\n const { signature } = (await sdk.txs.signMessage(\n msg\n )) as OffChainSignMessageResponse & { signature: string };\n\n return signature;\n }\n\n async signAndSendTx(\n tx: EvmTransaction,\n address: string,\n chainId: string | null\n ): Promise<{ hash: string; response: SafeTransactionResponse }> {\n const { hash, response } = await this.signer.signAndSendTx(\n tx,\n address,\n chainId\n );\n return {\n hash,\n response: { ...response, hashRequiringUpdate: true },\n };\n }\n\n async wait(\n safeHash: string,\n chainId: string,\n response: SafeTransactionResponse\n ): Promise<{\n hash: string;\n response: SafeTransactionResponse;\n chainId: string;\n }> {\n /*\n * `wait` is called on every status poll. On the first poll `safeHash` is the\n * safeTxHash, which `getTxHash` maps to the on-chain hash; the queue then\n * updates `executedTransactionId` to that on-chain hash. From the next poll\n * onwards `wait` receives the on-chain hash, and querying the Safe gateway\n * with it 404s (the gateway resolves by safeTxHash, not the on-chain hash),\n * which makes Safe{Wallet} log a harmless `Code 901`. Once the hash no longer\n * requires updating we already have the final hash, so skip the lookup.\n */\n if (response && !response.hashRequiringUpdate) {\n return { hash: safeHash, response, chainId };\n }\n\n const { txHash: hash } = await getTxHash(safeHash);\n return {\n hash,\n response: { ...response, hashRequiringUpdate: false },\n chainId,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "+CAMA,OAAS,oBAAAA,EAAkB,UAAAC,MAAc,wBACzC,OAAS,qBAAAC,MAAyB,6BAQlC,eAAsBC,EAAUC,EAA+C,CAC7E,IAAIC,EAGJ,KAAO,CAACA,GACN,GAAI,CAEF,IAAMC,EAAS,MAAMC,EAAI,IAAI,gBAAgBH,CAAQ,EAEnDE,EAAO,WAAaE,EAAkB,wBACtCF,EAAO,WAAaE,EAAkB,mBAGtC,MAAMC,EAAO,GAAO,EACXH,EAAO,SAEhBD,EAASC,EAAO,OAEpB,MAAQ,CACND,EAASD,CACX,CAEF,MAAO,CAAE,OAAAC,CAAO,CAClB,CAvBsBK,EAAAP,EAAA,aAyBf,IAAMQ,EAAN,KAA+D,CAxCtE,MAwCsE,CAAAD,EAAA,wBAC5D,OAER,YAAYE,EAAuB,CACjC,KAAK,OAAS,IAAIC,EAAiBD,CAAQ,CAC7C,CAEA,MAAM,YAAYE,EAA8B,CAC9C,GAAM,CAAE,UAAAC,CAAU,EAAK,MAAMR,EAAI,IAAI,YACnCO,CACF,EAEA,OAAOC,CACT,CAEA,MAAM,cACJC,EACAC,EACAC,EAC8D,CAC9D,GAAM,CAAE,KAAAC,EAAM,SAAAC,CAAS,EAAI,MAAM,KAAK,OAAO,cAC3CJ,EACAC,EACAC,CACF,EACA,MAAO,CACL,KAAAC,EACA,SAAU,CAAE,GAAGC,EAAU,oBAAqB,EAAK,CACrD,CACF,CAEA,MAAM,KACJhB,EACAc,EACAE,EAKC,CAUD,GAAIA,GAAY,CAACA,EAAS,oBACxB,MAAO,CAAE,KAAMhB,EAAU,SAAAgB,EAAU,QAAAF,CAAQ,EAG7C,GAAM,CAAE,OAAQC,CAAK,EAAI,MAAMhB,EAAUC,CAAQ,EACjD,MAAO,CACL,KAAAe,EACA,SAAU,CAAE,GAAGC,EAAU,oBAAqB,EAAM,EACpD,QAAAF,CACF,CACF,CACF",
|
|
6
|
+
"names": ["DefaultEvmSigner", "waitMs", "TransactionStatus", "getTxHash", "safeHash", "txHash", "queued", "sdk", "TransactionStatus", "waitMs", "__name", "CustomEvmSigner", "provider", "DefaultEvmSigner", "msg", "signature", "tx", "address", "chainId", "hash", "response"]
|
|
7
|
+
}
|
package/dist/mod.d.ts
ADDED
package/dist/mod.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e,c as m,d}from"./chunk-IWQRD3YN.js";import{defineVersions as L}from"@hub3js/core/utils";import{ProviderBuilder as B}from"@hub3js/core";import{WalletTypes as P}from"@rango-dev/wallets-shared";import{evmBlockchains as A}from"rango-types";import{dynamicImportWithRefinedError as v}from"@rango-dev/wallets-shared";import{DefaultSignerFactory as S,TransactionType as b}from"rango-types";async function s(t){let r=new S,{CustomEvmSigner:n}=await v(async()=>await import("./evm-GF64T75N.js"));return r.registerSigner(b.EVM,new n(t)),r}e(s,"getSigners");function o(){return d()}e(o,"evmSafe");async function p(t){let[r,n]=await Promise.all([t.request({method:"eth_accounts"}),t.request({method:"eth_chainId"})]);return{accounts:r,chainId:n}}e(p,"getSafeAccounts");var i=P.SAFE,u={name:"Safe",icon:"https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg",extensions:{homepage:"https://app.safe.global/"},properties:[{name:"namespaces",value:{selection:"multiple",data:[{label:"EVM",value:"EVM",id:"ETH",getSupportedChains:t=>A(t)}]}},{name:"details",value:{isContractWallet:!0}},{name:"signers",value:{getSigners:async()=>s(o())}}]};import{NamespaceBuilder as y}from"@hub3js/core";import{actions as a,builders as c,hooks as w}from"@hub3js/evm";import*as f from"@hub3js/std/builders";import{standardizeAndThrowError as E}from"@hub3js/std/operators";var[I,l]=w.changeAccountSubscriber(o),C=c.connect().action(a.connect(o,{getAccounts:p})).before(I).or(l).or(E).build(),T=f.disconnect().after(l).build(),x=c.canSwitchNetwork().action(a.canSwitchNetwork()).build(),M=c.canEagerConnect().action(a.canEagerConnect(o)).build(),k=c.getChainId().action(a.getChainId(o)).build(),g=new y("EVM",i).action(C).action(T).action(M).action(x).action(k).build();var h=e(()=>new B(i).init(function(t){let[,r]=t.state();async function n(){await m()&&(r("installed",!0),console.debug("[safe] instance detected.",t))}e(n,"detectSafe"),n()}).config("metadata",u).add("evm",g).build(),"buildProvider");var ie=e(()=>L().version("1.0.0",h()).build(),"versions");export{ie as versions};
|
|
2
|
+
//# sourceMappingURL=mod.js.map
|
package/dist/mod.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/mod.ts", "../src/provider.ts", "../src/constants.ts", "../src/signer.ts", "../src/utils.ts", "../src/namespaces/evm.ts"],
|
|
4
|
+
"sourcesContent": ["import { defineVersions } from '@hub3js/core/utils';\n\nimport { buildProvider } from './provider.js';\n\nconst versions = () =>\n defineVersions().version('1.0.0', buildProvider()).build();\n\nexport { versions };\n", "import { ProviderBuilder } from '@hub3js/core';\n\nimport { metadata, WALLET_ID } from './constants.js';\nimport { evm } from './namespaces/evm.js';\nimport { initSafe } from './safe.js';\n\nconst buildProvider = () =>\n new ProviderBuilder(WALLET_ID)\n .init(function (context) {\n const [, setState] = context.state();\n\n /*\n * Safe detection is asynchronous (the SDK only resolves when embedded in\n * Safe{Wallet}), so we kick it off here and flip `installed` once the Safe\n * provider is available. Detection fails fast outside of Safe.\n */\n async function detectSafe() {\n if (await initSafe()) {\n setState('installed', true);\n console.debug('[safe] instance detected.', context);\n }\n }\n\n void detectSafe();\n })\n .config('metadata', metadata)\n .add('evm', evm)\n .build();\n\nexport { buildProvider };\n", "import type { ProviderMetadata } from '@hub3js/core';\n\nimport { WalletTypes } from '@rango-dev/wallets-shared';\nimport { type BlockchainMeta, evmBlockchains } from 'rango-types';\n\nimport getSigners from './signer.js';\nimport { evmSafe } from './utils.js';\n\nexport const WALLET_ID = WalletTypes.SAFE;\n\nexport const metadata: ProviderMetadata = {\n name: 'Safe',\n icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg',\n extensions: {\n homepage: 'https://app.safe.global/',\n },\n properties: [\n {\n name: 'namespaces',\n value: {\n selection: 'multiple',\n data: [\n {\n label: 'EVM',\n value: 'EVM',\n id: 'ETH',\n getSupportedChains: (allBlockchains: BlockchainMeta[]) =>\n evmBlockchains(allBlockchains),\n },\n ],\n },\n },\n {\n name: 'details',\n value: { isContractWallet: true },\n },\n {\n name: 'signers',\n value: { getSigners: async () => getSigners(evmSafe()) },\n },\n ],\n};\n", "import type { ProviderAPI } from '@hub3js/evm';\nimport type { SignerFactory } from 'rango-types';\n\nimport { dynamicImportWithRefinedError } from '@rango-dev/wallets-shared';\nimport { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';\n\nexport default async function getSigners(\n provider: ProviderAPI\n): Promise<SignerFactory> {\n const signers = new DefaultSignerFactory();\n const { CustomEvmSigner } = await dynamicImportWithRefinedError(\n async () => await import('./signers/evm.js')\n );\n signers.registerSigner(TxType.EVM, new CustomEvmSigner(provider));\n\n return signers;\n}\n", "import type { ChainId, ProviderAPI } from '@hub3js/evm';\n\nimport { getSafeProviderOrThrow } from './safe.ts';\n\nexport function evmSafe(): ProviderAPI {\n return getSafeProviderOrThrow() as ProviderAPI;\n}\n\n/*\n * Safe is a contract wallet embedded in an iframe: the account is already\n * available without a connection prompt, so we read it with `eth_accounts`\n * instead of the default `eth_requestAccounts` (which Safe's provider does not\n * implement).\n */\nexport async function getSafeAccounts(\n instance: ProviderAPI\n): Promise<{ accounts: string[]; chainId: ChainId }> {\n const [accounts, chainId] = await Promise.all([\n instance.request({ method: 'eth_accounts' }),\n instance.request({ method: 'eth_chainId' }),\n ]);\n\n return { accounts, chainId };\n}\n", "import type { EvmActions } from '@hub3js/evm';\n\nimport { NamespaceBuilder } from '@hub3js/core';\nimport { actions, builders, hooks } from '@hub3js/evm';\nimport * as commonBuilders from '@hub3js/std/builders';\nimport { standardizeAndThrowError } from '@hub3js/std/operators';\n\nimport { WALLET_ID } from '../constants.js';\nimport { evmSafe, getSafeAccounts } from '../utils.js';\n\nconst [changeAccountSubscriber, changeAccountCleanup] =\n hooks.changeAccountSubscriber(evmSafe);\n\nconst connect = builders\n .connect()\n .action(actions.connect(evmSafe, { getAccounts: getSafeAccounts }))\n .before(changeAccountSubscriber)\n .or(changeAccountCleanup)\n .or(standardizeAndThrowError)\n .build();\n\nconst disconnect = commonBuilders\n .disconnect<EvmActions>()\n .after(changeAccountCleanup)\n .build();\n\nconst canSwitchNetwork = builders\n .canSwitchNetwork()\n .action(actions.canSwitchNetwork())\n .build();\n\nconst canEagerConnect = builders\n .canEagerConnect()\n .action(actions.canEagerConnect(evmSafe))\n .build();\n\nconst getChainId = builders\n .getChainId()\n .action(actions.getChainId(evmSafe))\n .build();\n\nconst evm = new NamespaceBuilder<EvmActions>('EVM', WALLET_ID)\n .action(connect)\n .action(disconnect)\n .action(canEagerConnect)\n .action(canSwitchNetwork)\n .action(getChainId)\n .build();\n\nexport { evm };\n"],
|
|
5
|
+
"mappings": "iDAAA,OAAS,kBAAAA,MAAsB,qBCA/B,OAAS,mBAAAC,MAAuB,eCEhC,OAAS,eAAAC,MAAmB,4BAC5B,OAA8B,kBAAAC,MAAsB,cCApD,OAAS,iCAAAC,MAAqC,4BAC9C,OAAS,wBAAAC,EAAsB,mBAAmBC,MAAc,cAEhE,eAAOC,EACLC,EACwB,CACxB,IAAMC,EAAU,IAAIC,EACd,CAAE,gBAAAC,CAAgB,EAAI,MAAMC,EAChC,SAAY,KAAM,QAAO,mBAAkB,CAC7C,EACA,OAAAH,EAAQ,eAAeI,EAAO,IAAK,IAAIF,EAAgBH,CAAQ,CAAC,EAEzDC,CACT,CAV8BK,EAAAP,EAAA,cCFvB,SAASQ,GAAuB,CACrC,OAAOC,EAAuB,CAChC,CAFgBC,EAAAF,EAAA,WAUhB,eAAsBG,EACpBC,EACmD,CACnD,GAAM,CAACC,EAAUC,CAAO,EAAI,MAAM,QAAQ,IAAI,CAC5CF,EAAS,QAAQ,CAAE,OAAQ,cAAe,CAAC,EAC3CA,EAAS,QAAQ,CAAE,OAAQ,aAAc,CAAC,CAC5C,CAAC,EAED,MAAO,CAAE,SAAAC,EAAU,QAAAC,CAAQ,CAC7B,CATsBJ,EAAAC,EAAA,mBFNf,IAAMI,EAAYC,EAAY,KAExBC,EAA6B,CACxC,KAAM,OACN,KAAM,qFACN,WAAY,CACV,SAAU,0BACZ,EACA,WAAY,CACV,CACE,KAAM,aACN,MAAO,CACL,UAAW,WACX,KAAM,CACJ,CACE,MAAO,MACP,MAAO,MACP,GAAI,MACJ,mBAAqBC,GACnBC,EAAeD,CAAc,CACjC,CACF,CACF,CACF,EACA,CACE,KAAM,UACN,MAAO,CAAE,iBAAkB,EAAK,CAClC,EACA,CACE,KAAM,UACN,MAAO,CAAE,WAAY,SAAYE,EAAWC,EAAQ,CAAC,CAAE,CACzD,CACF,CACF,EGvCA,OAAS,oBAAAC,MAAwB,eACjC,OAAS,WAAAC,EAAS,YAAAC,EAAU,SAAAC,MAAa,cACzC,UAAYC,MAAoB,uBAChC,OAAS,4BAAAC,MAAgC,wBAKzC,GAAM,CAACC,EAAyBC,CAAoB,EAClDC,EAAM,wBAAwBC,CAAO,EAEjCC,EAAUC,EACb,QAAQ,EACR,OAAOC,EAAQ,QAAQH,EAAS,CAAE,YAAaI,CAAgB,CAAC,CAAC,EACjE,OAAOP,CAAuB,EAC9B,GAAGC,CAAoB,EACvB,GAAGO,CAAwB,EAC3B,MAAM,EAEHC,EACH,aAAuB,EACvB,MAAMR,CAAoB,EAC1B,MAAM,EAEHS,EAAmBL,EACtB,iBAAiB,EACjB,OAAOC,EAAQ,iBAAiB,CAAC,EACjC,MAAM,EAEHK,EAAkBN,EACrB,gBAAgB,EAChB,OAAOC,EAAQ,gBAAgBH,CAAO,CAAC,EACvC,MAAM,EAEHS,EAAaP,EAChB,WAAW,EACX,OAAOC,EAAQ,WAAWH,CAAO,CAAC,EAClC,MAAM,EAEHU,EAAM,IAAIC,EAA6B,MAAOC,CAAS,EAC1D,OAAOX,CAAO,EACd,OAAOK,CAAU,EACjB,OAAOE,CAAe,EACtB,OAAOD,CAAgB,EACvB,OAAOE,CAAU,EACjB,MAAM,EJzCT,IAAMI,EAAgBC,EAAA,IACpB,IAAIC,EAAgBC,CAAS,EAC1B,KAAK,SAAUC,EAAS,CACvB,GAAM,CAAC,CAAEC,CAAQ,EAAID,EAAQ,MAAM,EAOnC,eAAeE,GAAa,CACtB,MAAMC,EAAS,IACjBF,EAAS,YAAa,EAAI,EAC1B,QAAQ,MAAM,4BAA6BD,CAAO,EAEtD,CALeH,EAAAK,EAAA,cAOVA,EAAW,CAClB,CAAC,EACA,OAAO,WAAYE,CAAQ,EAC3B,IAAI,MAAOC,CAAG,EACd,MAAM,EArBW,iBDFtB,IAAMC,GAAWC,EAAA,IACfC,EAAe,EAAE,QAAQ,QAASC,EAAc,CAAC,EAAE,MAAM,EAD1C",
|
|
6
|
+
"names": ["defineVersions", "ProviderBuilder", "WalletTypes", "evmBlockchains", "dynamicImportWithRefinedError", "DefaultSignerFactory", "TxType", "getSigners", "provider", "signers", "DefaultSignerFactory", "CustomEvmSigner", "dynamicImportWithRefinedError", "TxType", "__name", "evmSafe", "getSafeProviderOrThrow", "__name", "getSafeAccounts", "instance", "accounts", "chainId", "WALLET_ID", "WalletTypes", "metadata", "allBlockchains", "evmBlockchains", "getSigners", "evmSafe", "NamespaceBuilder", "actions", "builders", "hooks", "commonBuilders", "standardizeAndThrowError", "changeAccountSubscriber", "changeAccountCleanup", "hooks", "evmSafe", "connect", "builders", "actions", "getSafeAccounts", "standardizeAndThrowError", "disconnect", "canSwitchNetwork", "canEagerConnect", "getChainId", "evm", "NamespaceBuilder", "WALLET_ID", "buildProvider", "__name", "ProviderBuilder", "WALLET_ID", "context", "setState", "detectSafe", "initSafe", "metadata", "evm", "versions", "__name", "defineVersions", "buildProvider"]
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/
|
|
1
|
+
{"inputs":{"src/safe.ts":{"bytes":1495,"imports":[{"path":"@safe-global/safe-apps-provider","kind":"import-statement","external":true},{"path":"@safe-global/safe-apps-sdk","kind":"import-statement","external":true},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/signers/evm.ts":{"bytes":3197,"imports":[{"path":"@rango-dev/signer-evm","kind":"import-statement","external":true},{"path":"@safe-global/safe-apps-sdk","kind":"import-statement","external":true},{"path":"src/safe.ts","kind":"import-statement","original":"../safe.ts"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/signer.ts":{"bytes":605,"imports":[{"path":"@rango-dev/wallets-shared","kind":"import-statement","external":true},{"path":"rango-types","kind":"import-statement","external":true},{"path":"src/signers/evm.ts","kind":"dynamic-import","original":"./signers/evm.js"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/utils.ts":{"bytes":766,"imports":[{"path":"src/safe.ts","kind":"import-statement","original":"./safe.ts"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/constants.ts":{"bytes":1056,"imports":[{"path":"@rango-dev/wallets-shared","kind":"import-statement","external":true},{"path":"rango-types","kind":"import-statement","external":true},{"path":"src/signer.ts","kind":"import-statement","original":"./signer.js"},{"path":"src/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"src/namespaces/evm.ts":{"bytes":1323,"imports":[{"path":"@hub3js/core","kind":"import-statement","external":true},{"path":"@hub3js/evm","kind":"import-statement","external":true},{"path":"@hub3js/std/builders","kind":"import-statement","external":true},{"path":"@hub3js/std/operators","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"../constants.js"},{"path":"src/utils.ts","kind":"import-statement","original":"../utils.js"}],"format":"esm"},"src/provider.ts":{"bytes":890,"imports":[{"path":"@hub3js/core","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"./constants.js"},{"path":"src/namespaces/evm.ts","kind":"import-statement","original":"./namespaces/evm.js"},{"path":"src/safe.ts","kind":"import-statement","original":"./safe.js"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"},"src/mod.ts":{"bytes":209,"imports":[{"path":"@hub3js/core/utils","kind":"import-statement","external":true},{"path":"src/provider.ts","kind":"import-statement","original":"./provider.js"},{"path":"<runtime>","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/mod.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":8332},"dist/mod.js":{"imports":[{"path":"dist/chunk-IWQRD3YN.js","kind":"import-statement"},{"path":"@hub3js/core/utils","kind":"import-statement","external":true},{"path":"@hub3js/core","kind":"import-statement","external":true},{"path":"@rango-dev/wallets-shared","kind":"import-statement","external":true},{"path":"rango-types","kind":"import-statement","external":true},{"path":"@rango-dev/wallets-shared","kind":"import-statement","external":true},{"path":"rango-types","kind":"import-statement","external":true},{"path":"dist/evm-GF64T75N.js","kind":"dynamic-import"},{"path":"@hub3js/core","kind":"import-statement","external":true},{"path":"@hub3js/evm","kind":"import-statement","external":true},{"path":"@hub3js/std/builders","kind":"import-statement","external":true},{"path":"@hub3js/std/operators","kind":"import-statement","external":true}],"exports":["versions"],"entryPoint":"src/mod.ts","inputs":{"src/mod.ts":{"bytesInOutput":110},"src/provider.ts":{"bytesInOutput":281},"src/constants.ts":{"bytesInOutput":497},"src/signer.ts":{"bytesInOutput":310},"src/utils.ts":{"bytesInOutput":210},"src/namespaces/evm.ts":{"bytesInOutput":611}},"bytes":2124},"dist/evm-GF64T75N.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":4671},"dist/evm-GF64T75N.js":{"imports":[{"path":"dist/chunk-IWQRD3YN.js","kind":"import-statement"},{"path":"@rango-dev/signer-evm","kind":"import-statement","external":true},{"path":"@safe-global/safe-apps-sdk","kind":"import-statement","external":true}],"exports":["CustomEvmSigner","getTxHash"],"entryPoint":"src/signers/evm.ts","inputs":{"src/signers/evm.ts":{"bytesInOutput":840}},"bytes":973},"dist/chunk-IWQRD3YN.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":2348},"dist/chunk-IWQRD3YN.js":{"imports":[{"path":"@safe-global/safe-apps-provider","kind":"import-statement","external":true},{"path":"@safe-global/safe-apps-sdk","kind":"import-statement","external":true}],"exports":["a","b","c","d"],"inputs":{"src/safe.ts":{"bytesInOutput":532}},"bytes":691}}}
|
package/dist/safe.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SafeAppProvider } from '@safe-global/safe-apps-provider';
|
|
2
|
+
import SafeAppsSDK from '@safe-global/safe-apps-sdk';
|
|
3
|
+
export declare const sdk: SafeAppsSDK;
|
|
4
|
+
export declare function initSafe(): Promise<boolean>;
|
|
5
|
+
export declare const getSafeProviderOrThrow: () => SafeAppProvider;
|
package/dist/signers/evm.d.ts
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
import type { ProviderAPI } from '@hub3js/evm';
|
|
1
2
|
import type { TransactionResponse } from 'ethers';
|
|
2
3
|
import type { GenericSigner } from 'rango-types';
|
|
3
4
|
import type { EvmTransaction } from 'rango-types/mainApi';
|
|
5
|
+
type SafeTransactionResponse = Partial<TransactionResponse> & {
|
|
6
|
+
hashRequiringUpdate: boolean;
|
|
7
|
+
};
|
|
4
8
|
export declare function getTxHash(safeHash: string): Promise<{
|
|
5
9
|
txHash: string;
|
|
6
10
|
}>;
|
|
7
11
|
export declare class CustomEvmSigner implements GenericSigner<EvmTransaction> {
|
|
8
12
|
private signer;
|
|
9
|
-
constructor(provider:
|
|
13
|
+
constructor(provider: ProviderAPI);
|
|
10
14
|
signMessage(msg: string): Promise<string>;
|
|
11
15
|
signAndSendTx(tx: EvmTransaction, address: string, chainId: string | null): Promise<{
|
|
12
16
|
hash: string;
|
|
13
|
-
response:
|
|
14
|
-
hashRequiringUpdate: boolean;
|
|
15
|
-
};
|
|
17
|
+
response: SafeTransactionResponse;
|
|
16
18
|
}>;
|
|
17
|
-
wait(safeHash: string, chainId: string, response:
|
|
19
|
+
wait(safeHash: string, chainId: string, response: SafeTransactionResponse): Promise<{
|
|
18
20
|
hash: string;
|
|
19
|
-
response:
|
|
21
|
+
response: SafeTransactionResponse;
|
|
20
22
|
chainId: string;
|
|
21
23
|
}>;
|
|
22
24
|
}
|
|
25
|
+
export {};
|
package/dist/utils.d.ts
ADDED
package/package.json
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rango-dev/provider-safe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"source": "./src/
|
|
7
|
-
"main": "./dist/
|
|
6
|
+
"source": "./src/mod.ts",
|
|
7
|
+
"main": "./dist/mod.js",
|
|
8
8
|
"exports": {
|
|
9
|
-
".": "./dist/
|
|
9
|
+
".": "./dist/mod.js"
|
|
10
10
|
},
|
|
11
|
-
"typings": "dist/
|
|
11
|
+
"typings": "dist/mod.d.ts",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
14
14
|
"src"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "node ../../scripts/build/command.mjs --path wallets/provider-safe --splitting",
|
|
17
|
+
"build": "node ../../scripts/build/command.mjs --path wallets/provider-safe --splitting --inputs src/mod.ts",
|
|
18
18
|
"ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json",
|
|
19
19
|
"clean": "rimraf dist",
|
|
20
20
|
"format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
|
|
21
21
|
"lint": "eslint \"**/*.{ts,tsx}\""
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"@hub3js/core": "^0.60.1",
|
|
24
25
|
"@hub3js/evm": "^0.2.1",
|
|
25
|
-
"@
|
|
26
|
-
"@rango-dev/
|
|
27
|
-
"@
|
|
26
|
+
"@hub3js/std": "^0.1.1",
|
|
27
|
+
"@rango-dev/signer-evm": "^0.43.0",
|
|
28
|
+
"@rango-dev/wallets-shared": "^0.61.0",
|
|
29
|
+
"@safe-global/safe-apps-provider": "^0.18.6",
|
|
28
30
|
"@safe-global/safe-apps-sdk": "^9.1.0",
|
|
29
31
|
"ethers": "^6.13.2",
|
|
30
32
|
"rango-types": "^0.5.0"
|
package/readme.md
CHANGED
|
@@ -1 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Safe
|
|
2
|
+
Safe{Wallet} (smart-contract multisig) integration for hub. EVM only; runs as a Safe App inside the Safe iframe and submits transactions through the Safe transaction service.
|
|
3
|
+
|
|
4
|
+
## Account switching
|
|
5
|
+
|
|
6
|
+
`changeAccountSubscriber` is wired up on the namespace but is not exercised in practice. When the user switches the active account in Safe{Wallet}, Safe reloads the Safe App iframe, so the whole dApp (and our provider state) is reinitialized from scratch rather than reacting to an in-place account-change event. There is therefore no live session in which the change-account subscriber would fire — the new account is picked up on the fresh load via `eth_accounts`. It is kept for interface parity with other EVM namespaces.
|
|
7
|
+
|
|
8
|
+
## Switch network
|
|
9
|
+
|
|
10
|
+
The same reload behavior applies to network switching. A Safe App is bound to the chain of the Safe it is embedded in, and changing the active network in Safe{Wallet} reloads the Safe App iframe — reinitializing the whole dApp (and our provider state) from scratch rather than emitting an in-place chain-change event. There is therefore no live session in which an in-place network switch could be observed; the new chain is picked up on the fresh load via `eth_chainId`.
|
|
11
|
+
|
|
12
|
+
More about implementation status can be found [here](../readme.md).
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProviderMetadata } from '@hub3js/core';
|
|
2
|
+
|
|
3
|
+
import { WalletTypes } from '@rango-dev/wallets-shared';
|
|
4
|
+
import { type BlockchainMeta, evmBlockchains } from 'rango-types';
|
|
5
|
+
|
|
6
|
+
import getSigners from './signer.js';
|
|
7
|
+
import { evmSafe } from './utils.js';
|
|
8
|
+
|
|
9
|
+
export const WALLET_ID = WalletTypes.SAFE;
|
|
10
|
+
|
|
11
|
+
export const metadata: ProviderMetadata = {
|
|
12
|
+
name: 'Safe',
|
|
13
|
+
icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg',
|
|
14
|
+
extensions: {
|
|
15
|
+
homepage: 'https://app.safe.global/',
|
|
16
|
+
},
|
|
17
|
+
properties: [
|
|
18
|
+
{
|
|
19
|
+
name: 'namespaces',
|
|
20
|
+
value: {
|
|
21
|
+
selection: 'multiple',
|
|
22
|
+
data: [
|
|
23
|
+
{
|
|
24
|
+
label: 'EVM',
|
|
25
|
+
value: 'EVM',
|
|
26
|
+
id: 'ETH',
|
|
27
|
+
getSupportedChains: (allBlockchains: BlockchainMeta[]) =>
|
|
28
|
+
evmBlockchains(allBlockchains),
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'details',
|
|
35
|
+
value: { isContractWallet: true },
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'signers',
|
|
39
|
+
value: { getSigners: async () => getSigners(evmSafe()) },
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
package/src/mod.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { EvmActions } from '@hub3js/evm';
|
|
2
|
+
|
|
3
|
+
import { NamespaceBuilder } from '@hub3js/core';
|
|
4
|
+
import { actions, builders, hooks } from '@hub3js/evm';
|
|
5
|
+
import * as commonBuilders from '@hub3js/std/builders';
|
|
6
|
+
import { standardizeAndThrowError } from '@hub3js/std/operators';
|
|
7
|
+
|
|
8
|
+
import { WALLET_ID } from '../constants.js';
|
|
9
|
+
import { evmSafe, getSafeAccounts } from '../utils.js';
|
|
10
|
+
|
|
11
|
+
const [changeAccountSubscriber, changeAccountCleanup] =
|
|
12
|
+
hooks.changeAccountSubscriber(evmSafe);
|
|
13
|
+
|
|
14
|
+
const connect = builders
|
|
15
|
+
.connect()
|
|
16
|
+
.action(actions.connect(evmSafe, { getAccounts: getSafeAccounts }))
|
|
17
|
+
.before(changeAccountSubscriber)
|
|
18
|
+
.or(changeAccountCleanup)
|
|
19
|
+
.or(standardizeAndThrowError)
|
|
20
|
+
.build();
|
|
21
|
+
|
|
22
|
+
const disconnect = commonBuilders
|
|
23
|
+
.disconnect<EvmActions>()
|
|
24
|
+
.after(changeAccountCleanup)
|
|
25
|
+
.build();
|
|
26
|
+
|
|
27
|
+
const canSwitchNetwork = builders
|
|
28
|
+
.canSwitchNetwork()
|
|
29
|
+
.action(actions.canSwitchNetwork())
|
|
30
|
+
.build();
|
|
31
|
+
|
|
32
|
+
const canEagerConnect = builders
|
|
33
|
+
.canEagerConnect()
|
|
34
|
+
.action(actions.canEagerConnect(evmSafe))
|
|
35
|
+
.build();
|
|
36
|
+
|
|
37
|
+
const getChainId = builders
|
|
38
|
+
.getChainId()
|
|
39
|
+
.action(actions.getChainId(evmSafe))
|
|
40
|
+
.build();
|
|
41
|
+
|
|
42
|
+
const evm = new NamespaceBuilder<EvmActions>('EVM', WALLET_ID)
|
|
43
|
+
.action(connect)
|
|
44
|
+
.action(disconnect)
|
|
45
|
+
.action(canEagerConnect)
|
|
46
|
+
.action(canSwitchNetwork)
|
|
47
|
+
.action(getChainId)
|
|
48
|
+
.build();
|
|
49
|
+
|
|
50
|
+
export { evm };
|
package/src/provider.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ProviderBuilder } from '@hub3js/core';
|
|
2
|
+
|
|
3
|
+
import { metadata, WALLET_ID } from './constants.js';
|
|
4
|
+
import { evm } from './namespaces/evm.js';
|
|
5
|
+
import { initSafe } from './safe.js';
|
|
6
|
+
|
|
7
|
+
const buildProvider = () =>
|
|
8
|
+
new ProviderBuilder(WALLET_ID)
|
|
9
|
+
.init(function (context) {
|
|
10
|
+
const [, setState] = context.state();
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Safe detection is asynchronous (the SDK only resolves when embedded in
|
|
14
|
+
* Safe{Wallet}), so we kick it off here and flip `installed` once the Safe
|
|
15
|
+
* provider is available. Detection fails fast outside of Safe.
|
|
16
|
+
*/
|
|
17
|
+
async function detectSafe() {
|
|
18
|
+
if (await initSafe()) {
|
|
19
|
+
setState('installed', true);
|
|
20
|
+
console.debug('[safe] instance detected.', context);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
void detectSafe();
|
|
25
|
+
})
|
|
26
|
+
.config('metadata', metadata)
|
|
27
|
+
.add('evm', evm)
|
|
28
|
+
.build();
|
|
29
|
+
|
|
30
|
+
export { buildProvider };
|
package/src/safe.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SafeAppProvider } from '@safe-global/safe-apps-provider';
|
|
2
|
+
import SafeAppsSDK from '@safe-global/safe-apps-sdk';
|
|
3
|
+
|
|
4
|
+
const options = {
|
|
5
|
+
debug: false,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* similar to:
|
|
10
|
+
* https://github.com/wagmi-dev/references/pull/114
|
|
11
|
+
*/
|
|
12
|
+
let SDK = SafeAppsSDK;
|
|
13
|
+
if (
|
|
14
|
+
typeof SafeAppsSDK !== 'function' &&
|
|
15
|
+
// @ts-expect-error This import error is not visible to TypeScript
|
|
16
|
+
typeof SafeAppsSDK.default === 'function'
|
|
17
|
+
) {
|
|
18
|
+
SDK = (SafeAppsSDK as unknown as { default: typeof SafeAppsSDK }).default;
|
|
19
|
+
}
|
|
20
|
+
export const sdk = new SDK(options);
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Safe runs as a Safe App inside the Safe{Wallet} iframe, so the provider can
|
|
24
|
+
* only be created asynchronously once the SDK resolves the Safe info. We cache
|
|
25
|
+
* the instance here so the hub actions (connect, getChainId, signers, …) can
|
|
26
|
+
* retrieve it synchronously via `evmSafe()` after detection has completed.
|
|
27
|
+
*/
|
|
28
|
+
let safeProvider: SafeAppProvider | null = null;
|
|
29
|
+
|
|
30
|
+
export async function initSafe(): Promise<boolean> {
|
|
31
|
+
const timeout = 200;
|
|
32
|
+
const accountInfo = await Promise.race([
|
|
33
|
+
sdk.safe.getInfo(),
|
|
34
|
+
new Promise<undefined>((resolve) => setTimeout(resolve, timeout)),
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
if (!accountInfo) {
|
|
38
|
+
safeProvider = null;
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
safeProvider = new SafeAppProvider(accountInfo, sdk);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const getSafeProviderOrThrow = () => {
|
|
47
|
+
if (!safeProvider) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
'Safe is not available. Make sure the dApp is running as a Safe App inside Safe{Wallet}.'
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return safeProvider;
|
|
53
|
+
};
|
package/src/signers/evm.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProviderAPI } from '@hub3js/evm';
|
|
1
2
|
import type { OffChainSignMessageResponse } from '@safe-global/safe-apps-sdk';
|
|
2
3
|
import type { TransactionResponse } from 'ethers';
|
|
3
4
|
import type { GenericSigner } from 'rango-types';
|
|
@@ -6,7 +7,11 @@ import type { EvmTransaction } from 'rango-types/mainApi';
|
|
|
6
7
|
import { DefaultEvmSigner, waitMs } from '@rango-dev/signer-evm';
|
|
7
8
|
import { TransactionStatus } from '@safe-global/safe-apps-sdk';
|
|
8
9
|
|
|
9
|
-
import { sdk } from '../
|
|
10
|
+
import { sdk } from '../safe.ts';
|
|
11
|
+
|
|
12
|
+
type SafeTransactionResponse = Partial<TransactionResponse> & {
|
|
13
|
+
hashRequiringUpdate: boolean;
|
|
14
|
+
};
|
|
10
15
|
|
|
11
16
|
export async function getTxHash(safeHash: string): Promise<{ txHash: string }> {
|
|
12
17
|
let txHash;
|
|
@@ -36,7 +41,7 @@ export async function getTxHash(safeHash: string): Promise<{ txHash: string }> {
|
|
|
36
41
|
export class CustomEvmSigner implements GenericSigner<EvmTransaction> {
|
|
37
42
|
private signer;
|
|
38
43
|
|
|
39
|
-
constructor(provider:
|
|
44
|
+
constructor(provider: ProviderAPI) {
|
|
40
45
|
this.signer = new DefaultEvmSigner(provider);
|
|
41
46
|
}
|
|
42
47
|
|
|
@@ -52,10 +57,7 @@ export class CustomEvmSigner implements GenericSigner<EvmTransaction> {
|
|
|
52
57
|
tx: EvmTransaction,
|
|
53
58
|
address: string,
|
|
54
59
|
chainId: string | null
|
|
55
|
-
): Promise<{
|
|
56
|
-
hash: string;
|
|
57
|
-
response: Partial<TransactionResponse> & { hashRequiringUpdate: boolean };
|
|
58
|
-
}> {
|
|
60
|
+
): Promise<{ hash: string; response: SafeTransactionResponse }> {
|
|
59
61
|
const { hash, response } = await this.signer.signAndSendTx(
|
|
60
62
|
tx,
|
|
61
63
|
address,
|
|
@@ -70,16 +72,29 @@ export class CustomEvmSigner implements GenericSigner<EvmTransaction> {
|
|
|
70
72
|
async wait(
|
|
71
73
|
safeHash: string,
|
|
72
74
|
chainId: string,
|
|
73
|
-
response:
|
|
75
|
+
response: SafeTransactionResponse
|
|
74
76
|
): Promise<{
|
|
75
77
|
hash: string;
|
|
76
|
-
response:
|
|
78
|
+
response: SafeTransactionResponse;
|
|
77
79
|
chainId: string;
|
|
78
80
|
}> {
|
|
81
|
+
/*
|
|
82
|
+
* `wait` is called on every status poll. On the first poll `safeHash` is the
|
|
83
|
+
* safeTxHash, which `getTxHash` maps to the on-chain hash; the queue then
|
|
84
|
+
* updates `executedTransactionId` to that on-chain hash. From the next poll
|
|
85
|
+
* onwards `wait` receives the on-chain hash, and querying the Safe gateway
|
|
86
|
+
* with it 404s (the gateway resolves by safeTxHash, not the on-chain hash),
|
|
87
|
+
* which makes Safe{Wallet} log a harmless `Code 901`. Once the hash no longer
|
|
88
|
+
* requires updating we already have the final hash, so skip the lookup.
|
|
89
|
+
*/
|
|
90
|
+
if (response && !response.hashRequiringUpdate) {
|
|
91
|
+
return { hash: safeHash, response, chainId };
|
|
92
|
+
}
|
|
93
|
+
|
|
79
94
|
const { txHash: hash } = await getTxHash(safeHash);
|
|
80
95
|
return {
|
|
81
96
|
hash,
|
|
82
|
-
response,
|
|
97
|
+
response: { ...response, hashRequiringUpdate: false },
|
|
83
98
|
chainId,
|
|
84
99
|
};
|
|
85
100
|
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ChainId, ProviderAPI } from '@hub3js/evm';
|
|
2
|
+
|
|
3
|
+
import { getSafeProviderOrThrow } from './safe.ts';
|
|
4
|
+
|
|
5
|
+
export function evmSafe(): ProviderAPI {
|
|
6
|
+
return getSafeProviderOrThrow() as ProviderAPI;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Safe is a contract wallet embedded in an iframe: the account is already
|
|
11
|
+
* available without a connection prompt, so we read it with `eth_accounts`
|
|
12
|
+
* instead of the default `eth_requestAccounts` (which Safe's provider does not
|
|
13
|
+
* implement).
|
|
14
|
+
*/
|
|
15
|
+
export async function getSafeAccounts(
|
|
16
|
+
instance: ProviderAPI
|
|
17
|
+
): Promise<{ accounts: string[]; chainId: ChainId }> {
|
|
18
|
+
const [accounts, chainId] = await Promise.all([
|
|
19
|
+
instance.request({ method: 'eth_accounts' }),
|
|
20
|
+
instance.request({ method: 'eth_chainId' }),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
return { accounts, chainId };
|
|
24
|
+
}
|
package/dist/chunk-5CP7BBMP.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var i=Object.defineProperty;var o=(n,e)=>i(n,"name",{value:e,configurable:!0});import{SafeAppProvider as u}from"@safe-global/safe-apps-provider";import t from"@safe-global/safe-apps-sdk";var p={debug:!1},a=t;typeof t!="function"&&typeof t.default=="function"&&(a=t.default);var f=new a(p);async function d(){let e=await Promise.race([f.safe.getInfo(),new Promise(s=>setTimeout(s,200))]);return e?new u(e,f):null}o(d,"getSafeInstance");export{o as a,f as b,d as c};
|
|
2
|
-
//# sourceMappingURL=chunk-5CP7BBMP.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/helpers.ts"],
|
|
4
|
-
"sourcesContent": ["import { SafeAppProvider } from '@safe-global/safe-apps-provider';\nimport SafeAppsSDK from '@safe-global/safe-apps-sdk';\n\nconst options = {\n debug: false,\n};\n\n/*\n * similar to:\n * https://github.com/wagmi-dev/references/pull/114\n */\nlet SDK = SafeAppsSDK;\nif (\n typeof SafeAppsSDK !== 'function' &&\n // @ts-expect-error This import error is not visible to TypeScript\n typeof SafeAppsSDK.default === 'function'\n) {\n SDK = (SafeAppsSDK as unknown as { default: typeof SafeAppsSDK }).default;\n}\nexport const sdk = new SDK(options);\n\nexport async function getSafeInstance(): Promise<any> {\n const timeout = 200;\n const accountInfo = await Promise.race([\n sdk.safe.getInfo(),\n new Promise<undefined>((resolve) => setTimeout(resolve, timeout)),\n ]);\n return accountInfo ? new SafeAppProvider(accountInfo, sdk as any) : null;\n}\n"],
|
|
5
|
-
"mappings": "+EAAA,OAAS,mBAAAA,MAAuB,kCAChC,OAAOC,MAAiB,6BAExB,IAAMC,EAAU,CACd,MAAO,EACT,EAMIC,EAAMC,EAER,OAAOA,GAAgB,YAEvB,OAAOA,EAAY,SAAY,aAE/BD,EAAOC,EAA2D,SAE7D,IAAMC,EAAM,IAAIF,EAAID,CAAO,EAElC,eAAsBI,GAAgC,CAEpD,IAAMC,EAAc,MAAM,QAAQ,KAAK,CACrCF,EAAI,KAAK,QAAQ,EACjB,IAAI,QAAoBG,GAAY,WAAWA,EAAS,GAAO,CAAC,CAClE,CAAC,EACD,OAAOD,EAAc,IAAIE,EAAgBF,EAAaF,CAAU,EAAI,IACtE,CAPsBK,EAAAJ,EAAA",
|
|
6
|
-
"names": ["SafeAppProvider", "SafeAppsSDK", "options", "SDK", "SafeAppsSDK", "sdk", "getSafeInstance", "accountInfo", "resolve", "SafeAppProvider", "__name"]
|
|
7
|
-
}
|
package/dist/evm-TZ6OXXGG.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as i,b as r}from"./chunk-5CP7BBMP.js";import{DefaultEvmSigner as c,waitMs as h}from"@rango-dev/signer-evm";import{TransactionStatus as o}from"@safe-global/safe-apps-sdk";async function m(e){let s;for(;!s;)try{let t=await r.txs.getBySafeTxHash(e);t.txStatus===o.AWAITING_CONFIRMATIONS||t.txStatus===o.AWAITING_EXECUTION?await h(5e3):t.txHash&&(s=t.txHash)}catch{s=e}return{txHash:s}}i(m,"getTxHash");var g=class{static{i(this,"CustomEvmSigner")}signer;constructor(s){this.signer=new c(s)}async signMessage(s){let{signature:n}=await r.txs.signMessage(s);return n}async signAndSendTx(s,n,t){let{hash:a,response:p}=await this.signer.signAndSendTx(s,n,t);return{hash:a,response:{...p,hashRequiringUpdate:!0}}}async wait(s,n,t){let{txHash:a}=await m(s);return{hash:a,response:t,chainId:n}}};export{g as CustomEvmSigner,m as getTxHash};
|
|
2
|
-
//# sourceMappingURL=evm-TZ6OXXGG.js.map
|
package/dist/evm-TZ6OXXGG.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/signers/evm.ts"],
|
|
4
|
-
"sourcesContent": ["import type { OffChainSignMessageResponse } from '@safe-global/safe-apps-sdk';\nimport type { TransactionResponse } from 'ethers';\nimport type { GenericSigner } from 'rango-types';\nimport type { EvmTransaction } from 'rango-types/mainApi';\n\nimport { DefaultEvmSigner, waitMs } from '@rango-dev/signer-evm';\nimport { TransactionStatus } from '@safe-global/safe-apps-sdk';\n\nimport { sdk } from '../helpers.js';\n\nexport async function getTxHash(safeHash: string): Promise<{ txHash: string }> {\n let txHash;\n const timeout = 5_000;\n\n while (!txHash) {\n try {\n /** The SDK will be pinged until a txHash is available and the txStatus is in an end-state */\n const queued = await sdk.txs.getBySafeTxHash(safeHash);\n if (\n queued.txStatus === TransactionStatus.AWAITING_CONFIRMATIONS ||\n queued.txStatus === TransactionStatus.AWAITING_EXECUTION\n ) {\n /** Mimic a status watcher by checking once every 5 seconds */\n await waitMs(timeout);\n } else if (queued.txHash) {\n /** The txStatus is in an end-state (e.g. success) so we probably have a valid, on chain txHash*/\n txHash = queued.txHash;\n }\n } catch {\n txHash = safeHash;\n }\n }\n return { txHash };\n}\n\nexport class CustomEvmSigner implements GenericSigner<EvmTransaction> {\n private signer;\n\n constructor(provider: any) {\n this.signer = new DefaultEvmSigner(provider);\n }\n\n async signMessage(msg: string): Promise<string> {\n const { signature } = (await sdk.txs.signMessage(\n msg\n )) as OffChainSignMessageResponse & { signature: string };\n\n return signature;\n }\n\n async signAndSendTx(\n tx: EvmTransaction,\n address: string,\n chainId: string | null\n ): Promise<{\n hash: string;\n response: Partial<TransactionResponse> & { hashRequiringUpdate: boolean };\n }> {\n const { hash, response } = await this.signer.signAndSendTx(\n tx,\n address,\n chainId\n );\n return {\n hash,\n response: { ...response, hashRequiringUpdate: true },\n };\n }\n\n async wait(\n safeHash: string,\n chainId: string,\n response: TransactionResponse\n ): Promise<{\n hash: string;\n response: TransactionResponse;\n chainId: string;\n }> {\n const { txHash: hash } = await getTxHash(safeHash);\n return {\n hash,\n response,\n chainId,\n };\n }\n}\n"],
|
|
5
|
-
"mappings": "+CAKA,OAAS,oBAAAA,EAAkB,UAAAC,MAAc,wBACzC,OAAS,qBAAAC,MAAyB,6BAIlC,eAAsBC,EAAUC,EAA+C,CAC7E,IAAIC,EAGJ,KAAO,CAACA,GACN,GAAI,CAEF,IAAMC,EAAS,MAAMC,EAAI,IAAI,gBAAgBH,CAAQ,EAEnDE,EAAO,WAAaE,EAAkB,wBACtCF,EAAO,WAAaE,EAAkB,mBAGtC,MAAMC,EAAO,GAAO,EACXH,EAAO,SAEhBD,EAASC,EAAO,OAEpB,MAAQ,CACND,EAASD,CACX,CAEF,MAAO,CAAE,OAAAC,CAAO,CAClB,CAvBsBK,EAAAP,EAAA,aAyBf,IAAMQ,EAAN,KAA+D,CAnCtE,MAmCsE,CAAAD,EAAA,wBAC5D,OAER,YAAYE,EAAe,CACzB,KAAK,OAAS,IAAIC,EAAiBD,CAAQ,CAC7C,CAEA,MAAM,YAAYE,EAA8B,CAC9C,GAAM,CAAE,UAAAC,CAAU,EAAK,MAAMR,EAAI,IAAI,YACnCO,CACF,EAEA,OAAOC,CACT,CAEA,MAAM,cACJC,EACAC,EACAC,EAIC,CACD,GAAM,CAAE,KAAAC,EAAM,SAAAC,CAAS,EAAI,MAAM,KAAK,OAAO,cAC3CJ,EACAC,EACAC,CACF,EACA,MAAO,CACL,KAAAC,EACA,SAAU,CAAE,GAAGC,EAAU,oBAAqB,EAAK,CACrD,CACF,CAEA,MAAM,KACJhB,EACAc,EACAE,EAKC,CACD,GAAM,CAAE,OAAQD,CAAK,EAAI,MAAMhB,EAAUC,CAAQ,EACjD,MAAO,CACL,KAAAe,EACA,SAAAC,EACA,QAAAF,CACF,CACF,CACF",
|
|
6
|
-
"names": ["DefaultEvmSigner", "waitMs", "TransactionStatus", "getTxHash", "safeHash", "txHash", "queued", "sdk", "TransactionStatus", "waitMs", "__name", "CustomEvmSigner", "provider", "DefaultEvmSigner", "msg", "signature", "tx", "address", "chainId", "hash", "response"]
|
|
7
|
-
}
|
package/dist/helpers.d.ts
DELETED
package/dist/index.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { CanEagerConnect, CanSwitchNetwork, Connect, GetInstance, Subscribe, SwitchNetwork, WalletInfo } from '@rango-dev/wallets-shared';
|
|
2
|
-
import type { BlockchainMeta, SignerFactory } from 'rango-types';
|
|
3
|
-
import { WalletTypes } from '@rango-dev/wallets-shared';
|
|
4
|
-
export declare const config: {
|
|
5
|
-
type: WalletTypes;
|
|
6
|
-
isAsyncInstance: boolean;
|
|
7
|
-
};
|
|
8
|
-
export declare const getInstance: GetInstance;
|
|
9
|
-
export declare const connect: Connect;
|
|
10
|
-
export declare const subscribe: Subscribe;
|
|
11
|
-
export declare const switchNetwork: SwitchNetwork;
|
|
12
|
-
export declare const canSwitchNetworkTo: CanSwitchNetwork;
|
|
13
|
-
export declare const getSigners: (provider: any) => Promise<SignerFactory>;
|
|
14
|
-
export declare const canEagerConnect: CanEagerConnect;
|
|
15
|
-
export declare const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo;
|
package/dist/index.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as o,c as a}from"./chunk-5CP7BBMP.js";import{canEagerlyConnectToEvm as w,canSwitchNetworkToEvm as u,subscribeToEvm as y,switchNetworkForEvm as S,WalletTypes as k}from"@rango-dev/wallets-shared";import{evmBlockchains as v,isEvmBlockchain as E}from"rango-types";import{dynamicImportWithRefinedError as g}from"@rango-dev/wallets-shared";import{DefaultSignerFactory as f,TransactionType as h}from"rango-types";async function r(t){let e=new f,{CustomEvmSigner:n}=await g(async()=>await import("./evm-TZ6OXXGG.js"));return e.registerSigner(h.EVM,new n(t)),e}o(r,"getSigners");var C=k.SAFE,A={type:C,isAsyncInstance:!0},B=o(async()=>await a(),"getInstance"),P=o(async({instance:t})=>{let e=await t.request({method:"eth_accounts"}),{chainId:n}=t;return{accounts:e,chainId:n}},"connect"),L=o(({instance:t,state:e,updateChainId:n,updateAccounts:s,meta:i,connect:m,disconnect:p})=>{let l=i.filter(E),c=y({instance:t,state:e,updateChainId:n,updateAccounts:s,meta:l,connect:m,disconnect:p});return()=>{c&&c()}},"subscribe"),M=S,D=u,G=r,j=w,q=o(t=>{let e=v(t);return{name:"Safe",img:"https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg",installLink:{DEFAULT:"https://app.safe.global/"},color:"#ffffff",supportedChains:e,isContractWallet:!0}},"getWalletInfo");export{j as canEagerConnect,D as canSwitchNetworkTo,A as config,P as connect,B as getInstance,G as getSigners,q as getWalletInfo,L as subscribe,M as switchNetwork};
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/signer.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n CanEagerConnect,\n CanSwitchNetwork,\n Connect,\n GetInstance,\n Subscribe,\n SwitchNetwork,\n WalletInfo,\n} from '@rango-dev/wallets-shared';\nimport type { BlockchainMeta, SignerFactory } from 'rango-types';\n\nimport {\n canEagerlyConnectToEvm,\n canSwitchNetworkToEvm,\n subscribeToEvm,\n switchNetworkForEvm,\n WalletTypes,\n} from '@rango-dev/wallets-shared';\nimport { evmBlockchains, isEvmBlockchain } from 'rango-types';\n\nimport { getSafeInstance } from './helpers.js';\nimport signer from './signer.js';\n\nconst WALLET = WalletTypes.SAFE;\n\nexport const config = {\n type: WALLET,\n isAsyncInstance: true,\n};\n\nexport const getInstance: GetInstance = async () => {\n return await getSafeInstance();\n};\n\nexport const connect: Connect = async ({ instance }) => {\n const accounts = await instance.request({\n method: 'eth_accounts',\n });\n\n const { chainId } = instance;\n\n return { accounts, chainId };\n};\n\nexport const subscribe: Subscribe = ({\n instance,\n state,\n updateChainId,\n updateAccounts,\n meta,\n connect,\n disconnect,\n}) => {\n const evmBlockchainMeta = meta.filter(isEvmBlockchain);\n\n const cleanup = subscribeToEvm({\n instance,\n state,\n updateChainId,\n updateAccounts,\n meta: evmBlockchainMeta,\n connect,\n disconnect,\n });\n return () => {\n if (cleanup) {\n cleanup();\n }\n };\n};\n\nexport const switchNetwork: SwitchNetwork = switchNetworkForEvm;\n\nexport const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm;\n\nexport const getSigners: (provider: any) => Promise<SignerFactory> = signer;\n\nexport const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm;\n\nexport const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (\n allBlockChains\n) => {\n const evms = evmBlockchains(allBlockChains);\n return {\n name: 'Safe',\n img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg',\n installLink: {\n DEFAULT: 'https://app.safe.global/',\n },\n color: '#ffffff',\n supportedChains: evms,\n isContractWallet: true,\n };\n};\n", "import type { ProviderAPI } from '@hub3js/evm';\nimport type { SignerFactory } from 'rango-types';\n\nimport { dynamicImportWithRefinedError } from '@rango-dev/wallets-shared';\nimport { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';\n\nexport default async function getSigners(\n provider: ProviderAPI\n): Promise<SignerFactory> {\n const signers = new DefaultSignerFactory();\n const { CustomEvmSigner } = await dynamicImportWithRefinedError(\n async () => await import('./signers/evm.js')\n );\n signers.registerSigner(TxType.EVM, new CustomEvmSigner(provider));\n\n return signers;\n}\n"],
|
|
5
|
-
"mappings": "+CAWA,OACE,0BAAAA,EACA,yBAAAC,EACA,kBAAAC,EACA,uBAAAC,EACA,eAAAC,MACK,4BACP,OAAS,kBAAAC,EAAgB,mBAAAC,MAAuB,cCfhD,OAAS,iCAAAC,MAAqC,4BAC9C,OAAS,wBAAAC,EAAsB,mBAAmBC,MAAc,cAEhE,eAAOC,EACLC,EACwB,CACxB,IAAMC,EAAU,IAAIC,EACd,CAAE,gBAAAC,CAAgB,EAAI,MAAMC,EAChC,SAAY,KAAM,QAAO,mBAAkB,CAC7C,EACA,OAAAH,EAAQ,eAAeI,EAAO,IAAK,IAAIF,EAAgBH,CAAQ,CAAC,EAEzDC,CACT,CAV8BK,EAAAP,EAAA,cDiB9B,IAAMQ,EAASC,EAAY,KAEdC,EAAS,CACpB,KAAMF,EACN,gBAAiB,EACnB,EAEaG,EAA2BC,EAAA,SAC/B,MAAMC,EAAgB,EADS,eAI3BC,EAAmBF,EAAA,MAAO,CAAE,SAAAG,CAAS,IAAM,CACtD,IAAMC,EAAW,MAAMD,EAAS,QAAQ,CACtC,OAAQ,cACV,CAAC,EAEK,CAAE,QAAAE,CAAQ,EAAIF,EAEpB,MAAO,CAAE,SAAAC,EAAU,QAAAC,CAAQ,CAC7B,EARgC,WAUnBC,EAAuBN,EAAA,CAAC,CACnC,SAAAG,EACA,MAAAI,EACA,cAAAC,EACA,eAAAC,EACA,KAAAC,EACA,QAAAR,EACA,WAAAS,CACF,IAAM,CACJ,IAAMC,EAAoBF,EAAK,OAAOG,CAAe,EAE/CC,EAAUC,EAAe,CAC7B,SAAAZ,EACA,MAAAI,EACA,cAAAC,EACA,eAAAC,EACA,KAAMG,EACN,QAAAV,EACA,WAAAS,CACF,CAAC,EACD,MAAO,IAAM,CACPG,GACFA,EAAQ,CAEZ,CACF,EAzBoC,aA2BvBE,EAA+BC,EAE/BC,EAAuCC,EAEvCC,EAAwDA,EAExDC,EAAmCC,EAEnCC,EAAkEvB,EAC7EwB,GACG,CACH,IAAMC,EAAOC,EAAeF,CAAc,EAC1C,MAAO,CACL,KAAM,OACN,IAAK,qFACL,YAAa,CACX,QAAS,0BACX,EACA,MAAO,UACP,gBAAiBC,EACjB,iBAAkB,EACpB,CACF,EAd+E",
|
|
6
|
-
"names": ["canEagerlyConnectToEvm", "canSwitchNetworkToEvm", "subscribeToEvm", "switchNetworkForEvm", "WalletTypes", "evmBlockchains", "isEvmBlockchain", "dynamicImportWithRefinedError", "DefaultSignerFactory", "TxType", "getSigners", "provider", "signers", "DefaultSignerFactory", "CustomEvmSigner", "dynamicImportWithRefinedError", "TxType", "__name", "WALLET", "WalletTypes", "config", "getInstance", "__name", "getSafeInstance", "connect", "instance", "accounts", "chainId", "subscribe", "state", "updateChainId", "updateAccounts", "meta", "disconnect", "evmBlockchainMeta", "isEvmBlockchain", "cleanup", "subscribeToEvm", "switchNetwork", "switchNetworkForEvm", "canSwitchNetworkTo", "canSwitchNetworkToEvm", "getSigners", "canEagerConnect", "canEagerlyConnectToEvm", "getWalletInfo", "allBlockChains", "evms", "evmBlockchains"]
|
|
7
|
-
}
|
package/src/helpers.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { SafeAppProvider } from '@safe-global/safe-apps-provider';
|
|
2
|
-
import SafeAppsSDK from '@safe-global/safe-apps-sdk';
|
|
3
|
-
|
|
4
|
-
const options = {
|
|
5
|
-
debug: false,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* similar to:
|
|
10
|
-
* https://github.com/wagmi-dev/references/pull/114
|
|
11
|
-
*/
|
|
12
|
-
let SDK = SafeAppsSDK;
|
|
13
|
-
if (
|
|
14
|
-
typeof SafeAppsSDK !== 'function' &&
|
|
15
|
-
// @ts-expect-error This import error is not visible to TypeScript
|
|
16
|
-
typeof SafeAppsSDK.default === 'function'
|
|
17
|
-
) {
|
|
18
|
-
SDK = (SafeAppsSDK as unknown as { default: typeof SafeAppsSDK }).default;
|
|
19
|
-
}
|
|
20
|
-
export const sdk = new SDK(options);
|
|
21
|
-
|
|
22
|
-
export async function getSafeInstance(): Promise<any> {
|
|
23
|
-
const timeout = 200;
|
|
24
|
-
const accountInfo = await Promise.race([
|
|
25
|
-
sdk.safe.getInfo(),
|
|
26
|
-
new Promise<undefined>((resolve) => setTimeout(resolve, timeout)),
|
|
27
|
-
]);
|
|
28
|
-
return accountInfo ? new SafeAppProvider(accountInfo, sdk as any) : null;
|
|
29
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CanEagerConnect,
|
|
3
|
-
CanSwitchNetwork,
|
|
4
|
-
Connect,
|
|
5
|
-
GetInstance,
|
|
6
|
-
Subscribe,
|
|
7
|
-
SwitchNetwork,
|
|
8
|
-
WalletInfo,
|
|
9
|
-
} from '@rango-dev/wallets-shared';
|
|
10
|
-
import type { BlockchainMeta, SignerFactory } from 'rango-types';
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
canEagerlyConnectToEvm,
|
|
14
|
-
canSwitchNetworkToEvm,
|
|
15
|
-
subscribeToEvm,
|
|
16
|
-
switchNetworkForEvm,
|
|
17
|
-
WalletTypes,
|
|
18
|
-
} from '@rango-dev/wallets-shared';
|
|
19
|
-
import { evmBlockchains, isEvmBlockchain } from 'rango-types';
|
|
20
|
-
|
|
21
|
-
import { getSafeInstance } from './helpers.js';
|
|
22
|
-
import signer from './signer.js';
|
|
23
|
-
|
|
24
|
-
const WALLET = WalletTypes.SAFE;
|
|
25
|
-
|
|
26
|
-
export const config = {
|
|
27
|
-
type: WALLET,
|
|
28
|
-
isAsyncInstance: true,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const getInstance: GetInstance = async () => {
|
|
32
|
-
return await getSafeInstance();
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export const connect: Connect = async ({ instance }) => {
|
|
36
|
-
const accounts = await instance.request({
|
|
37
|
-
method: 'eth_accounts',
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const { chainId } = instance;
|
|
41
|
-
|
|
42
|
-
return { accounts, chainId };
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const subscribe: Subscribe = ({
|
|
46
|
-
instance,
|
|
47
|
-
state,
|
|
48
|
-
updateChainId,
|
|
49
|
-
updateAccounts,
|
|
50
|
-
meta,
|
|
51
|
-
connect,
|
|
52
|
-
disconnect,
|
|
53
|
-
}) => {
|
|
54
|
-
const evmBlockchainMeta = meta.filter(isEvmBlockchain);
|
|
55
|
-
|
|
56
|
-
const cleanup = subscribeToEvm({
|
|
57
|
-
instance,
|
|
58
|
-
state,
|
|
59
|
-
updateChainId,
|
|
60
|
-
updateAccounts,
|
|
61
|
-
meta: evmBlockchainMeta,
|
|
62
|
-
connect,
|
|
63
|
-
disconnect,
|
|
64
|
-
});
|
|
65
|
-
return () => {
|
|
66
|
-
if (cleanup) {
|
|
67
|
-
cleanup();
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export const switchNetwork: SwitchNetwork = switchNetworkForEvm;
|
|
73
|
-
|
|
74
|
-
export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm;
|
|
75
|
-
|
|
76
|
-
export const getSigners: (provider: any) => Promise<SignerFactory> = signer;
|
|
77
|
-
|
|
78
|
-
export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm;
|
|
79
|
-
|
|
80
|
-
export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
|
|
81
|
-
allBlockChains
|
|
82
|
-
) => {
|
|
83
|
-
const evms = evmBlockchains(allBlockChains);
|
|
84
|
-
return {
|
|
85
|
-
name: 'Safe',
|
|
86
|
-
img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg',
|
|
87
|
-
installLink: {
|
|
88
|
-
DEFAULT: 'https://app.safe.global/',
|
|
89
|
-
},
|
|
90
|
-
color: '#ffffff',
|
|
91
|
-
supportedChains: evms,
|
|
92
|
-
isContractWallet: true,
|
|
93
|
-
};
|
|
94
|
-
};
|