@polkahub/multisig 0.3.1 → 0.5.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.
@@ -21,7 +21,7 @@ const multisigExternalSigner = (getMultisigUrl, thresholdOneFallback) => (info,
21
21
  throw new Error("Raw bytes can't be signed with a multisig");
22
22
  },
23
23
  async signTx(callData) {
24
- const url = getMultisigUrl(info, Binary.fromBytes(callData).asHex());
24
+ const url = getMultisigUrl(info, Binary.toHex(callData));
25
25
  setUrl(url);
26
26
  try {
27
27
  await firstValueFrom(url$.pipe(filter((v) => !v)));
@@ -1 +1 @@
1
- {"version":3,"file":"MultisigExternalSigner.js","sources":["../src/MultisigExternalSigner.tsx"],"sourcesContent":["import {\n AccountId,\n Binary,\n getMultisigAccountId,\n HexString,\n} from \"@polkadot-api/substrate-bindings\";\nimport { CreateMultisigSigner, MultisigInfo } from \"./provider\";\nimport { createSignal } from \"@react-rxjs/utils\";\nimport { state, useStateObservable } from \"@react-rxjs/core\";\nimport { filter, firstValueFrom } from \"rxjs\";\nimport { FC } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogBody,\n} from \"@polkahub/ui-components\";\n\nconst [urlChange$, setUrl] = createSignal<string | null>();\nconst url$ = state(urlChange$, null);\n\nconst [enc] = AccountId();\nexport const multisigExternalSigner =\n (\n getMultisigUrl: (info: MultisigInfo, callData: HexString) => string,\n thresholdOneFallback?: CreateMultisigSigner\n ): CreateMultisigSigner =>\n (info, signer) => {\n if (info.threshold === 1 && signer && thresholdOneFallback)\n return thresholdOneFallback(info, signer);\n\n const publicKey = getMultisigAccountId({\n threshold: info.threshold,\n signatories: info.signatories.map(enc),\n });\n\n return {\n publicKey,\n signBytes() {\n throw new Error(\"Raw bytes can't be signed with a multisig\");\n },\n async signTx(callData) {\n const url = getMultisigUrl(info, Binary.fromBytes(callData).asHex());\n setUrl(url);\n try {\n await firstValueFrom(url$.pipe(filter((v) => !v)));\n throw null;\n } catch (ex) {\n throw new Error(\"Dismissed\");\n }\n },\n };\n };\n\nexport const MultisigExternalSignerModal: FC = () => {\n const activeTx = useStateObservable(url$);\n\n return (\n <Dialog open={!!activeTx} onOpenChange={() => setUrl(null)}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Multisig Transaction</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <div>\n <p>\n To sign this multisig transaction, please share the following URL\n with the signatories\n </p>\n <a\n href={activeTx ?? \"\"}\n target=\"_blank\"\n className=\"cursor-pointer underline\"\n >\n {activeTx}\n </a>\n </div>\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAmBA,MAAM,CAAC,UAAA,EAAY,MAAM,CAAA,GAAI,YAAA,EAA4B;AACzD,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,EAAY,IAAI,CAAA;AAEnC,MAAM,CAAC,GAAG,CAAA,GAAI,SAAA,EAAU;AACjB,MAAM,yBACX,CACE,cAAA,EACA,oBAAA,KAEF,CAAC,MAAM,MAAA,KAAW;AAChB,EAAA,IAAI,IAAA,CAAK,SAAA,KAAc,CAAA,IAAK,MAAA,IAAU,oBAAA;AACpC,IAAA,OAAO,oBAAA,CAAqB,MAAM,MAAM,CAAA;AAE1C,EAAA,MAAM,YAAY,oBAAA,CAAqB;AAAA,IACrC,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,WAAA,EAAa,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAG;AAAA,GACtC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,IAC7D,CAAA;AAAA,IACA,MAAM,OAAO,QAAA,EAAU;AACrB,MAAA,MAAM,GAAA,GAAM,eAAe,IAAA,EAAM,MAAA,CAAO,UAAU,QAAQ,CAAA,CAAE,OAAO,CAAA;AACnE,MAAA,MAAA,CAAO,GAAG,CAAA;AACV,MAAA,IAAI;AACF,QAAA,MAAM,cAAA,CAAe,KAAK,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACjD,QAAA,MAAM,IAAA;AAAA,MACR,SAAS,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,MAAM,WAAW,CAAA;AAAA,MAC7B;AAAA,IACF;AAAA,GACF;AACF;AAEK,MAAM,8BAAkC,MAAM;AACnD,EAAA,MAAM,QAAA,GAAW,mBAAmB,IAAI,CAAA;AAExC,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,CAAC,CAAC,QAAA,EAAU,YAAA,EAAc,MAAM,MAAA,CAAO,IAAI,CAAA,EACvD,QAAA,kBAAA,IAAA,CAAC,aAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,QAAA,EAAA,sBAAA,EAAoB,CAAA,EACnC,CAAA;AAAA,oBACA,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAE,QAAA,EAAA,wFAAA,EAGH,CAAA;AAAA,sBACA,GAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,MAAM,QAAA,IAAY,EAAA;AAAA,UAClB,MAAA,EAAO,QAAA;AAAA,UACP,SAAA,EAAU,0BAAA;AAAA,UAET,QAAA,EAAA;AAAA;AAAA;AACH,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"MultisigExternalSigner.js","sources":["../src/MultisigExternalSigner.tsx"],"sourcesContent":["import {\n AccountId,\n Binary,\n getMultisigAccountId,\n HexString,\n} from \"@polkadot-api/substrate-bindings\";\nimport { CreateMultisigSigner, MultisigInfo } from \"./provider\";\nimport { createSignal } from \"@react-rxjs/utils\";\nimport { state, useStateObservable } from \"@react-rxjs/core\";\nimport { filter, firstValueFrom } from \"rxjs\";\nimport { FC } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogBody,\n} from \"@polkahub/ui-components\";\n\nconst [urlChange$, setUrl] = createSignal<string | null>();\nconst url$ = state(urlChange$, null);\n\nconst [enc] = AccountId();\nexport const multisigExternalSigner =\n (\n getMultisigUrl: (info: MultisigInfo, callData: HexString) => string,\n thresholdOneFallback?: CreateMultisigSigner\n ): CreateMultisigSigner =>\n (info, signer) => {\n if (info.threshold === 1 && signer && thresholdOneFallback)\n return thresholdOneFallback(info, signer);\n\n const publicKey = getMultisigAccountId({\n threshold: info.threshold,\n signatories: info.signatories.map(enc),\n });\n\n return {\n publicKey,\n signBytes() {\n throw new Error(\"Raw bytes can't be signed with a multisig\");\n },\n async signTx(callData) {\n const url = getMultisigUrl(info, Binary.toHex(callData));\n setUrl(url);\n try {\n await firstValueFrom(url$.pipe(filter((v) => !v)));\n throw null;\n } catch (ex) {\n throw new Error(\"Dismissed\");\n }\n },\n };\n };\n\nexport const MultisigExternalSignerModal: FC = () => {\n const activeTx = useStateObservable(url$);\n\n return (\n <Dialog open={!!activeTx} onOpenChange={() => setUrl(null)}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Multisig Transaction</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <div>\n <p>\n To sign this multisig transaction, please share the following URL\n with the signatories\n </p>\n <a\n href={activeTx ?? \"\"}\n target=\"_blank\"\n className=\"cursor-pointer underline\"\n >\n {activeTx}\n </a>\n </div>\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAmBA,MAAM,CAAC,UAAA,EAAY,MAAM,CAAA,GAAI,YAAA,EAA4B;AACzD,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,EAAY,IAAI,CAAA;AAEnC,MAAM,CAAC,GAAG,CAAA,GAAI,SAAA,EAAU;AACjB,MAAM,yBACX,CACE,cAAA,EACA,oBAAA,KAEF,CAAC,MAAM,MAAA,KAAW;AAChB,EAAA,IAAI,IAAA,CAAK,SAAA,KAAc,CAAA,IAAK,MAAA,IAAU,oBAAA;AACpC,IAAA,OAAO,oBAAA,CAAqB,MAAM,MAAM,CAAA;AAE1C,EAAA,MAAM,YAAY,oBAAA,CAAqB;AAAA,IACrC,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,WAAA,EAAa,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAG;AAAA,GACtC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,IAC7D,CAAA;AAAA,IACA,MAAM,OAAO,QAAA,EAAU;AACrB,MAAA,MAAM,MAAM,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAC,CAAA;AACvD,MAAA,MAAA,CAAO,GAAG,CAAA;AACV,MAAA,IAAI;AACF,QAAA,MAAM,cAAA,CAAe,KAAK,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACjD,QAAA,MAAM,IAAA;AAAA,MACR,SAAS,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,MAAM,WAAW,CAAA;AAAA,MAC7B;AAAA,IACF;AAAA,GACF;AACF;AAEK,MAAM,8BAAkC,MAAM;AACnD,EAAA,MAAM,QAAA,GAAW,mBAAmB,IAAI,CAAA;AAExC,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,CAAC,CAAC,QAAA,EAAU,YAAA,EAAc,MAAM,MAAA,CAAO,IAAI,CAAA,EACvD,QAAA,kBAAA,IAAA,CAAC,aAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,QAAA,EAAA,sBAAA,EAAoB,CAAA,EACnC,CAAA;AAAA,oBACA,GAAA,CAAC,UAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAE,QAAA,EAAA,wFAAA,EAGH,CAAA;AAAA,sBACA,GAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,MAAM,QAAA,IAAY,EAAA;AAAA,UAClB,MAAA,EAAO,QAAA;AAAA,UACP,SAAA,EAAU,0BAAA;AAAA,UAET,QAAA,EAAA;AAAA;AAAA;AACH,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sources":["../src/provider.ts"],"sourcesContent":["import {\n getMultisigSigner,\n MultisigSignerOptions,\n} from \"@polkadot-api/meta-signers\";\nimport {\n AccountId,\n FixedSizeBinary,\n getMultisigAccountId,\n getSs58AddressInfo,\n} from \"@polkadot-api/substrate-bindings\";\nimport {\n Account,\n AccountAddress,\n addrEq,\n localStorageProvider,\n persistedState,\n PersistenceProvider,\n Plugin,\n SerializableAccount,\n} from \"@polkahub/plugin\";\nimport { DefaultedStateObservable, state } from \"@react-rxjs/core\";\nimport { Binary, PolkadotSigner } from \"polkadot-api\";\nimport {\n BehaviorSubject,\n combineLatest,\n filter,\n firstValueFrom,\n map,\n switchMap,\n timeout,\n} from \"rxjs\";\n\nexport interface MultisigInfo {\n threshold: number;\n signatories: AccountAddress[];\n // If not set, it will be a read-only account.\n // But with the advantage that it will still figure out the resulting address\n parentSigner?: SerializableAccount;\n name?: string;\n}\n\nexport type CreateMultisigSigner = (\n info: MultisigInfo,\n parentSigner?: PolkadotSigner\n) => PolkadotSigner | null;\n\nexport const multisigProviderId = \"multisig\";\nexport interface MultisigAccount extends Account {\n provider: \"multisig\";\n info: MultisigInfo;\n}\n\nexport interface MultisigProvider extends Plugin<MultisigAccount> {\n id: \"multisig\";\n accounts$: DefaultedStateObservable<MultisigAccount[]>;\n\n setMultisigs: (multisigs: MultisigInfo[]) => void;\n addMultisig: (multisig: MultisigInfo) => Promise<MultisigAccount>;\n removeMultisig: (addr: AccountAddress) => void;\n}\n\nexport const createMultisigProvider = (\n createMultisigSigner: CreateMultisigSigner,\n opts?: Partial<{\n persist: PersistenceProvider;\n }>\n): MultisigProvider => {\n const { persist } = {\n persist: localStorageProvider(\"multisigs\"),\n ...opts,\n };\n\n const [persistedAccounts$, setPersistedAccounts] = persistedState(\n persist,\n [] as MultisigInfo[]\n );\n const plugins$ = new BehaviorSubject<Plugin<Account>[]>([]);\n\n const getAccount = (\n info: MultisigInfo,\n parentSigner: PolkadotSigner | undefined\n ): MultisigAccount => ({\n provider: multisigProviderId,\n address: getMultisigAddress(info),\n signer: createMultisigSigner(info, parentSigner) ?? undefined,\n info,\n name: info.name,\n });\n\n const multisigInfoToAccount = async (info: MultisigInfo) => {\n if (!info.parentSigner) return getAccount(info, undefined);\n\n try {\n const plugin = await firstValueFrom(\n plugins$.pipe(\n map((plugins) =>\n plugins.find((p) => info.parentSigner?.provider === p.id)\n ),\n filter((v) => v != null),\n timeout({\n first: 3000,\n })\n )\n );\n if (!plugin) return getAccount(info, undefined);\n\n const parentSigner = await plugin.deserialize(info.parentSigner);\n return getAccount(info, parentSigner?.signer);\n } catch (ex) {\n console.error(ex);\n return getAccount(info, undefined);\n }\n };\n\n const accounts$ = state(\n combineLatest([persistedAccounts$, plugins$]).pipe(\n switchMap(\n async ([accounts]) =>\n await Promise.all(accounts.map(multisigInfoToAccount))\n )\n ),\n []\n );\n\n return {\n id: multisigProviderId,\n deserialize: (account) => {\n const extra = account.extra as MultisigInfo;\n return multisigInfoToAccount(extra);\n },\n serialize: ({ address, info, provider }) => ({\n address,\n provider,\n extra: info,\n }),\n eq: (a, b) =>\n addrEq(a.address, b.address) &&\n addrEq(a.info.parentSigner?.address, b.info.parentSigner?.address),\n accounts$,\n receiveContext: (ctx) => plugins$.next(ctx.plugins),\n subscription$: accounts$,\n setMultisigs: setPersistedAccounts,\n addMultisig: (multisig) => {\n const addr = getMultisigAddress(multisig);\n setPersistedAccounts((prev) => {\n if (prev.some((v) => getMultisigAddress(v) === addr)) return prev;\n return [...prev, multisig];\n });\n return multisigInfoToAccount(multisig);\n },\n removeMultisig: (addr) =>\n setPersistedAccounts((prev) =>\n prev.filter((v) => getMultisigAddress(v) !== addr)\n ),\n };\n};\n\nconst getPublicKey = AccountId().enc;\nconst getMultisigAddress = (info: MultisigInfo) => {\n const accountId = getMultisigAccountId({\n threshold: info.threshold,\n signatories: info.signatories.map(getPublicKey),\n });\n const addrInfo = getSs58AddressInfo(info.signatories[0]);\n if (!addrInfo.isValid) {\n throw new Error(\"Unreachable\");\n }\n return AccountId(addrInfo.ss58Format).dec(accountId);\n};\n\nexport const multisigDirectSigner =\n (\n getMultisigInfo: (\n multisig: AccountAddress,\n callHash: FixedSizeBinary<32>\n ) => Promise<\n | {\n when: {\n height: number;\n index: number;\n };\n approvals: Array<AccountAddress>;\n }\n | undefined\n >,\n txPaymentInfo: (\n uxt: Binary,\n len: number\n ) => Promise<{\n weight: {\n ref_time: bigint;\n proof_size: bigint;\n };\n }>,\n opts?: MultisigSignerOptions<AccountAddress>\n ): CreateMultisigSigner =>\n (info, parentSigner) =>\n parentSigner\n ? getMultisigSigner(\n info,\n getMultisigInfo,\n txPaymentInfo,\n parentSigner,\n opts ?? {\n method: () => \"as_multi\",\n }\n )\n : null;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.js","sources":["../src/provider.ts"],"sourcesContent":["import {\n getMultisigSigner,\n MultisigSignerOptions,\n} from \"@polkadot-api/meta-signers\";\nimport {\n AccountId,\n getMultisigAccountId,\n getSs58AddressInfo,\n SizedHex,\n} from \"@polkadot-api/substrate-bindings\";\nimport {\n Account,\n AccountAddress,\n addrEq,\n localStorageProvider,\n persistedState,\n PersistenceProvider,\n Plugin,\n SerializableAccount,\n} from \"@polkahub/plugin\";\nimport { DefaultedStateObservable, state } from \"@react-rxjs/core\";\nimport { PolkadotSigner } from \"polkadot-api\";\nimport {\n BehaviorSubject,\n combineLatest,\n filter,\n firstValueFrom,\n map,\n switchMap,\n timeout,\n} from \"rxjs\";\n\nexport interface MultisigInfo {\n threshold: number;\n signatories: AccountAddress[];\n // If not set, it will be a read-only account.\n // But with the advantage that it will still figure out the resulting address\n parentSigner?: SerializableAccount;\n name?: string;\n}\n\nexport type CreateMultisigSigner = (\n info: MultisigInfo,\n parentSigner?: PolkadotSigner\n) => PolkadotSigner | null;\n\nexport const multisigProviderId = \"multisig\";\nexport interface MultisigAccount extends Account {\n provider: \"multisig\";\n info: MultisigInfo;\n}\n\nexport interface MultisigProvider extends Plugin<MultisigAccount> {\n id: \"multisig\";\n accounts$: DefaultedStateObservable<MultisigAccount[]>;\n\n setMultisigs: (multisigs: MultisigInfo[]) => void;\n addMultisig: (multisig: MultisigInfo) => Promise<MultisigAccount>;\n removeMultisig: (addr: AccountAddress) => void;\n}\n\nexport const createMultisigProvider = (\n createMultisigSigner: CreateMultisigSigner,\n opts?: Partial<{\n persist: PersistenceProvider;\n }>\n): MultisigProvider => {\n const { persist } = {\n persist: localStorageProvider(\"multisigs\"),\n ...opts,\n };\n\n const [persistedAccounts$, setPersistedAccounts] = persistedState(\n persist,\n [] as MultisigInfo[]\n );\n const plugins$ = new BehaviorSubject<Plugin<Account>[]>([]);\n\n const getAccount = (\n info: MultisigInfo,\n parentSigner: PolkadotSigner | undefined\n ): MultisigAccount => ({\n provider: multisigProviderId,\n address: getMultisigAddress(info),\n signer: createMultisigSigner(info, parentSigner) ?? undefined,\n info,\n name: info.name,\n });\n\n const multisigInfoToAccount = async (info: MultisigInfo) => {\n if (!info.parentSigner) return getAccount(info, undefined);\n\n try {\n const plugin = await firstValueFrom(\n plugins$.pipe(\n map((plugins) =>\n plugins.find((p) => info.parentSigner?.provider === p.id)\n ),\n filter((v) => v != null),\n timeout({\n first: 3000,\n })\n )\n );\n if (!plugin) return getAccount(info, undefined);\n\n const parentSigner = await plugin.deserialize(info.parentSigner);\n return getAccount(info, parentSigner?.signer);\n } catch (ex) {\n console.error(ex);\n return getAccount(info, undefined);\n }\n };\n\n const accounts$ = state(\n combineLatest([persistedAccounts$, plugins$]).pipe(\n switchMap(\n async ([accounts]) =>\n await Promise.all(accounts.map(multisigInfoToAccount))\n )\n ),\n []\n );\n\n return {\n id: multisigProviderId,\n deserialize: (account) => {\n const extra = account.extra as MultisigInfo;\n return multisigInfoToAccount(extra);\n },\n serialize: ({ address, info, provider }) => ({\n address,\n provider,\n extra: info,\n }),\n eq: (a, b) =>\n addrEq(a.address, b.address) &&\n addrEq(a.info.parentSigner?.address, b.info.parentSigner?.address),\n accounts$,\n receiveContext: (ctx) => plugins$.next(ctx.plugins),\n subscription$: accounts$,\n setMultisigs: setPersistedAccounts,\n addMultisig: (multisig) => {\n const addr = getMultisigAddress(multisig);\n setPersistedAccounts((prev) => {\n if (prev.some((v) => getMultisigAddress(v) === addr)) return prev;\n return [...prev, multisig];\n });\n return multisigInfoToAccount(multisig);\n },\n removeMultisig: (addr) =>\n setPersistedAccounts((prev) =>\n prev.filter((v) => getMultisigAddress(v) !== addr)\n ),\n };\n};\n\nconst getPublicKey = AccountId().enc;\nconst getMultisigAddress = (info: MultisigInfo) => {\n const accountId = getMultisigAccountId({\n threshold: info.threshold,\n signatories: info.signatories.map(getPublicKey),\n });\n const addrInfo = getSs58AddressInfo(info.signatories[0]);\n if (!addrInfo.isValid) {\n throw new Error(\"Unreachable\");\n }\n return AccountId(addrInfo.ss58Format).dec(accountId);\n};\n\nexport const multisigDirectSigner =\n (\n getMultisigInfo: (\n multisig: AccountAddress,\n callHash: SizedHex<32>\n ) => Promise<\n | {\n when: {\n height: number;\n index: number;\n };\n approvals: Array<AccountAddress>;\n }\n | undefined\n >,\n txPaymentInfo: (\n uxt: Uint8Array,\n len: number\n ) => Promise<{\n weight: {\n ref_time: bigint;\n proof_size: bigint;\n };\n }>,\n opts?: MultisigSignerOptions<AccountAddress>\n ): CreateMultisigSigner =>\n (info, parentSigner) =>\n parentSigner\n ? getMultisigSigner(\n info,\n getMultisigInfo,\n txPaymentInfo,\n parentSigner,\n opts ?? {\n method: () => \"as_multi\",\n }\n )\n : null;\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { MultisigSignerOptions } from '@polkadot-api/meta-signers';
2
- import { FixedSizeBinary, HexString } from '@polkadot-api/substrate-bindings';
2
+ import { SizedHex, HexString } from '@polkadot-api/substrate-bindings';
3
3
  import { AccountAddress, SerializableAccount, Account, Plugin, PersistenceProvider } from '@polkahub/plugin';
4
4
  import { DefaultedStateObservable } from '@react-rxjs/core';
5
- import { PolkadotSigner, Binary } from 'polkadot-api';
5
+ import { PolkadotSigner } from 'polkadot-api';
6
6
  import { FC } from 'react';
7
7
 
8
8
  interface MultisigInfo {
@@ -27,13 +27,13 @@ interface MultisigProvider extends Plugin<MultisigAccount> {
27
27
  declare const createMultisigProvider: (createMultisigSigner: CreateMultisigSigner, opts?: Partial<{
28
28
  persist: PersistenceProvider;
29
29
  }>) => MultisigProvider;
30
- declare const multisigDirectSigner: (getMultisigInfo: (multisig: AccountAddress, callHash: FixedSizeBinary<32>) => Promise<{
30
+ declare const multisigDirectSigner: (getMultisigInfo: (multisig: AccountAddress, callHash: SizedHex<32>) => Promise<{
31
31
  when: {
32
32
  height: number;
33
33
  index: number;
34
34
  };
35
35
  approvals: Array<AccountAddress>;
36
- } | undefined>, txPaymentInfo: (uxt: Binary, len: number) => Promise<{
36
+ } | undefined>, txPaymentInfo: (uxt: Uint8Array, len: number) => Promise<{
37
37
  weight: {
38
38
  ref_time: bigint;
39
39
  proof_size: bigint;
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@polkahub/multisig",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
+ "author": "Victor Oliva (https://github.com/voliva)",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/polkadot-api/polkahub.git"
8
+ },
4
9
  "license": "MIT",
5
10
  "sideEffects": false,
6
11
  "type": "module",
@@ -24,29 +29,28 @@
24
29
  "index.css"
25
30
  ],
26
31
  "dependencies": {
27
- "@polkadot-api/meta-signers": "^0.1.17",
28
- "@polkadot-api/substrate-bindings": "^0.16.5",
32
+ "@polkadot-api/meta-signers": "^0.1.21",
33
+ "@polkadot-api/substrate-bindings": "^0.19.0",
29
34
  "@react-rxjs/core": "^0.10.8",
30
35
  "@react-rxjs/utils": "^0.9.7",
31
- "lucide-react": "^0.553.0",
32
- "polkadot-api": "^1.20.2",
36
+ "lucide-react": "^0.575.0",
37
+ "polkadot-api": "^2.0.0-rc.2",
33
38
  "rxjs": "^7.8.2",
34
- "@polkahub/context": "0.3.1",
35
- "@polkahub/proxy": "0.3.1",
36
- "@polkahub/select-account": "0.3.1",
37
- "@polkahub/plugin": "0.3.1",
38
- "@polkahub/ui-components": "0.3.1"
39
+ "@polkahub/context": "0.5.0",
40
+ "@polkahub/plugin": "0.5.0",
41
+ "@polkahub/proxy": "0.5.0",
42
+ "@polkahub/select-account": "0.5.0",
43
+ "@polkahub/ui-components": "0.5.0"
39
44
  },
40
45
  "peerDependencies": {
41
46
  "@types/react": "^19.2.2",
42
47
  "react": "^19.2.0"
43
48
  },
44
49
  "devDependencies": {
45
- "@types/react": "^19.2.2",
46
- "react": "^19.2.0"
50
+ "@types/react": "^19.2.14",
51
+ "react": "^19.2.4"
47
52
  },
48
53
  "scripts": {
49
- "build": "tsc -b && rollup -c ../../rollup.config.js",
50
- "lint": "eslint ."
54
+ "build": "tsc -b && rollup -c ../../rollup.config.js"
51
55
  }
52
56
  }