@ghostlytools/cli 1.3.0 → 1.3.1
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/README.md +9 -3
- package/dist/assets/{api-CrxVxtY1.js → api-Dq2QXQDk.js} +141 -40
- package/dist/assets/api-Dq2QXQDk.js.map +1 -0
- package/dist/assets/{api-BiaX6l6f.js → api-TiB5QSG9.js} +2 -2
- package/dist/assets/{apiKit-CajiDxdK.js → apiKit-CA2x5GJF.js} +7 -3
- package/dist/assets/apiKit-CA2x5GJF.js.map +1 -0
- package/dist/assets/{apps-CbfiCSIw.js → apps-BxV9i_Y4.js} +3 -4
- package/dist/assets/{apps-CbfiCSIw.js.map → apps-BxV9i_Y4.js.map} +1 -1
- package/dist/assets/{apps-t23gkc28.js → apps-C-T8jeji.js} +1 -1
- package/dist/assets/{arkade-D4BVJFEQ.js → arkade-C_qDmHnm.js} +2 -2
- package/dist/assets/{arkade-D4BVJFEQ.js.map → arkade-C_qDmHnm.js.map} +1 -1
- package/dist/assets/{backup-Cg52WeQi.js → backup-Bugnn3Ue.js} +1 -1
- package/dist/assets/{backup-BAMi2lAq.js → backup-CnMN2oUK.js} +8 -8
- package/dist/assets/backup-CnMN2oUK.js.map +1 -0
- package/dist/assets/bark_ffi_wasm_bg-EY2uc0Bx.js.map +1 -1
- package/dist/assets/bitcoind-CZchoh43.js +349 -0
- package/dist/assets/bitcoind-CZchoh43.js.map +1 -0
- package/dist/assets/bitcoindProvider-DGw3xBSa.js +97 -0
- package/dist/assets/bitcoindProvider-DGw3xBSa.js.map +1 -0
- package/dist/assets/bitcoindevkit_bg-B-iLWrmX.js.map +1 -1
- package/dist/assets/buttons-Bj7Vf7Pn.js +2 -0
- package/dist/assets/{buttons-CX1pKB0j.js → buttons-CvNBzh2S.js} +4 -5
- package/dist/assets/{buttons-CX1pKB0j.js.map → buttons-CvNBzh2S.js.map} +1 -1
- package/dist/assets/{endpoint-Dn7H8qE1.js → endpoint-BOTFMpfS.js} +44 -12
- package/dist/assets/endpoint-BOTFMpfS.js.map +1 -0
- package/dist/assets/{envelope-BvU0fLEt.js → envelope-WjingYSc.js} +2 -2
- package/dist/assets/{envelope-BvU0fLEt.js.map → envelope-WjingYSc.js.map} +1 -1
- package/dist/assets/{errors-my6VJR_0.js → errors-DO5z6h_l.js} +29 -1
- package/dist/assets/errors-DO5z6h_l.js.map +1 -0
- package/dist/assets/groupFiles-IEUW3DQz.js +3202 -0
- package/dist/assets/groupFiles-IEUW3DQz.js.map +1 -0
- package/dist/assets/{host-Cmd205Dc.js → host-CWt-jtqz.js} +41 -16
- package/dist/assets/host-CWt-jtqz.js.map +1 -0
- package/dist/assets/{hyperdhtRelay-CEmBpT0Q.js → hyperdhtRelay-CPYwSLLS.js} +2 -3
- package/dist/assets/{hyperdhtRelay-CEmBpT0Q.js.map → hyperdhtRelay-CPYwSLLS.js.map} +1 -1
- package/dist/assets/{irohWeb--YyEA-hX.js → irohWeb-4oChIOIp.js} +2 -3
- package/dist/assets/{irohWeb--YyEA-hX.js.map → irohWeb-4oChIOIp.js.map} +1 -1
- package/dist/assets/{main-BzNN6bkx.js → main-DbqcdShN.js} +142 -35
- package/dist/assets/main-DbqcdShN.js.map +1 -0
- package/dist/assets/{mainline-D5D5C-jT.js → mainline-ZkiOnevs.js} +2 -2
- package/dist/assets/{mainline-D5D5C-jT.js.map → mainline-ZkiOnevs.js.map} +1 -1
- package/dist/assets/{networkReason-DxZWHw6v.js → networkReason-CetKkTPo.js} +2 -2
- package/dist/assets/{networkReason-DxZWHw6v.js.map → networkReason-CetKkTPo.js.map} +1 -1
- package/dist/assets/nwc-CgkqyvsE.js +612 -0
- package/dist/assets/nwc-CgkqyvsE.js.map +1 -0
- package/dist/assets/nwcProvider-4eVz_8HP.js +77 -0
- package/dist/assets/nwcProvider-4eVz_8HP.js.map +1 -0
- package/dist/assets/{profiles-B6F4oa9K.js → profiles-BHc9pEYg.js} +2 -2
- package/dist/assets/{profiles-B6F4oa9K.js.map → profiles-BHc9pEYg.js.map} +1 -1
- package/dist/assets/registry-DlAKO0Fy.js +3793 -0
- package/dist/assets/registry-DlAKO0Fy.js.map +1 -0
- package/dist/assets/registry-OBJBnHVQ.js +2 -0
- package/dist/assets/resolve-CouHhCpJ.js +591 -0
- package/dist/assets/resolve-CouHhCpJ.js.map +1 -0
- package/dist/assets/{server-CBCEYKMN.js → server-Ss0gJ-nw.js} +184 -1181
- package/dist/assets/server-Ss0gJ-nw.js.map +1 -0
- package/dist/assets/{src-DhfGgAUu.js → src-DDzSERyc.js} +2249 -72
- package/dist/assets/src-DDzSERyc.js.map +1 -0
- package/dist/assets/{turnRefs-ChEfgbSX.js → turnRefs-B87dtrHM.js} +2 -2
- package/dist/assets/{turnRefs-ChEfgbSX.js.map → turnRefs-B87dtrHM.js.map} +1 -1
- package/dist/assets/types-C4_KafL_.js +122 -0
- package/dist/assets/types-C4_KafL_.js.map +1 -0
- package/dist/assets/{usdt-C1Xao2xH.js → usdt-Fj8CQO2z.js} +3 -3
- package/dist/assets/{usdt-C1Xao2xH.js.map → usdt-Fj8CQO2z.js.map} +1 -1
- package/dist/ghostly.mjs +1 -1
- package/package.json +1 -1
- package/dist/assets/api-CrxVxtY1.js.map +0 -1
- package/dist/assets/apiKit-CajiDxdK.js.map +0 -1
- package/dist/assets/backup-BAMi2lAq.js.map +0 -1
- package/dist/assets/buttons-CWl2yNJu.js +0 -2
- package/dist/assets/endpoint-Dn7H8qE1.js.map +0 -1
- package/dist/assets/errors-my6VJR_0.js.map +0 -1
- package/dist/assets/groupFiles-BNTSDaoq.js +0 -7685
- package/dist/assets/groupFiles-BNTSDaoq.js.map +0 -1
- package/dist/assets/groupFiles-DBbjOLuD.js +0 -2088
- package/dist/assets/groupFiles-DBbjOLuD.js.map +0 -1
- package/dist/assets/host-Cmd205Dc.js.map +0 -1
- package/dist/assets/main-BzNN6bkx.js.map +0 -1
- package/dist/assets/server-CBCEYKMN.js.map +0 -1
- package/dist/assets/src-DhfGgAUu.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as node, g as state, i as chatOrGroup, s as findGroup } from "./apiKit-
|
|
1
|
+
import { f as node, g as state, i as chatOrGroup, s as findGroup } from "./apiKit-CA2x5GJF.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
//#region src/engineMethods.ts
|
|
4
4
|
/**
|
|
@@ -320,4 +320,4 @@ async function withStoredIds(ctx, params) {
|
|
|
320
320
|
//#endregion
|
|
321
321
|
export { SECRET_RESULTS as a, ENGINE_READS as i, withStoredIds as n, ENGINE_METHODS as r, turnRef as t };
|
|
322
322
|
|
|
323
|
-
//# sourceMappingURL=turnRefs-
|
|
323
|
+
//# sourceMappingURL=turnRefs-B87dtrHM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turnRefs-ChEfgbSX.js","names":[],"sources":["../../src/engineMethods.ts","../../src/turnRefs.ts"],"sourcesContent":["/**\n * The engine's calls the daemon passes through as `engine.<method>` (WISP 1100 § Local control API): exactly the\n * app's `EngineApi` (packages/browser/src/shared/rpc.ts; `engineMethods.test.ts` keeps the two equal), plus two\n * reads every host has. Nothing else on the engine object is reachable.\n */\nexport const ENGINE_METHODS: readonly string[] = [\n \"usdtCreate\", \"usdtUnlock\", \"usdtReveal\", \"usdtLock\", \"usdtRefresh\", \"usdtExportBackup\", \"usdtRestoreBackup\",\n \"arkCreate\", \"arkUnlock\", \"arkLock\", \"arkBackup\", \"arkExportBackup\", \"arkRestoreBackup\", \"arkRefresh\", \"arkRecover\",\n \"barkCreate\", \"barkBackup\", \"barkExportBackup\", \"barkRestoreBackup\", \"barkRefresh\", \"barkBoard\", \"fedimintPreview\",\n \"fedimintJoin\", \"fedimintLeave\", \"fedimintRefresh\", \"fedimintSpendNotes\", \"fedimintReceiveNotes\", \"fedimintInvoice\",\n \"fedimintTakeBack\", \"fedimintBackup\", \"fedimintExportBackup\", \"fedimintRestoreBackup\", \"fedimintRestorePhrase\",\n \"sparkCreate\", \"sparkBackup\", \"sparkExportBackup\", \"sparkRestoreBackup\", \"sparkRefresh\", \"sparkUseForLightning\",\n \"preparePayment\", \"approvePayment\", \"reconcilePayment\", \"cancelPayment\", \"refreshPublicProfiles\",\n \"choosePublicProfile\", \"preparePeerProof\", \"submitPeerProof\", \"withdrawPeerProof\", \"beginIdentityProof\",\n \"completeIdentityProof\", \"cancelIdentityProof\", \"removeIdentityProof\", \"shareIdentityProof\",\n \"withdrawIdentityProof\", \"recheckIdentityProof\", \"lookupIdentityDisplay\", \"loadPublicProfile\", \"loadPublicPosts\",\n \"loadPublicGraph\", \"loadPublicPostImage\", \"clearProfileData\", \"setDidListed\", \"nostrLoadContact\", \"nostrForgetContact\", \"nostrLoadOwn\",\n \"nostrLookup\", \"nostrDraft\", \"nostrPublish\", \"createLink\", \"takeInvite\", \"joinLink\", \"ensureLink\", \"confirmPair\",\n \"pollNow\", \"removeLink\", \"renameLink\", \"setActiveLink\", \"sendMessage\", \"editMessage\", \"retryMessage\", \"react\", \"pinMessage\", \"appId\", \"appOpen\", \"appClose\", \"appSend\", \"messageDetails\",\n \"deleteMessage\", \"exportLinks\", \"sendFile\", \"forwardMessages\", \"fileAction\", \"setDeliveryMode\", \"setTransportPreference\",\n \"setChatTransport\", \"setChatPaymentMethods\", \"setChatHold\", \"connect\", \"walletAddMint\", \"walletCreate\",\n \"walletRemove\", \"walletTestCoins\", \"walletSetupRetry\", \"walletSetupDismiss\", \"wake\", \"peekProfile\", \"walletSetPrimaryMint\", \"walletRemoveMint\", \"walletReceiveLightning\",\n \"walletQuoteInvoice\", \"walletPayQuote\", \"lnurlResolve\", \"lnurlInvoice\", \"checkPayment\", \"lightningSetSource\",\n \"lightningClearSource\", \"lightningRetrySource\", \"lightningReconfigureSource\", \"lightningRefresh\",\n \"lightningSetReceive\", \"lightningRename\", \"bitcoinSetSource\", \"bitcoinClearSource\", \"bitcoinRetrySource\",\n \"bitcoinReconfigureSource\", \"bitcoinReceiveAddress\", \"bitcoinRefresh\", \"walletReceiveToken\", \"walletInspectCashu\",\n \"walletExport\", \"walletBackupReminder\", \"sendPayment\", \"requestPayment\", \"requestGroupPayment\", \"groupPaymentHello\", \"askToPay\",\n \"payRequest\", \"reclaimPayment\", \"disconnect\", \"addService\", \"removeService\", \"setServiceEnabled\",\n \"setServiceShared\", \"updateSettings\", \"setCallSignal\", \"setTyping\", \"setWakeSubscription\", \"setWakeMuted\", \"wakeForCall\", \"setCallOn\", \"wakeConfirm\", \"setFastPoll\", \"createGroup\", \"inviteToGroup\",\n \"acceptGroupInvitation\", \"declineGroupInvitation\", \"enableGroupLink\", \"disableGroupLink\", \"joinGroupByLink\",\n \"sendGroupMessage\", \"sendGroupFile\", \"groupFileCheck\", \"pressButton\", \"groupMessages\", \"messagePage\", \"statusCardIndex\", \"groupTaken\", \"leaveGroup\", \"removeGroupMember\", \"makeGroupAdmin\", \"setGroupHub\", \"rotateGroup\",\n \"setGroupPicture\", \"renameGroup\", \"setGroupTyping\", \"forgetGroup\", \"setGroupManage\",\n // One profile on several devices (WISP 06): a CLI profile is always on one device, so these answer `single` or refuse.\n \"deviceEnrollInvite\", \"deviceEnrollConfirm\", \"deviceEnrollCancel\", \"deviceEnrollView\", \"deviceEnrollJoin\", \"deviceEnrollReady\", \"deviceEnrollFinish\",\n \"deviceEnrollRemove\", \"deviceSet\", \"devicePing\", \"deviceHandoffVerifier\", \"deviceHandoffPush\", \"deviceHandoffPull\", \"deviceHandoffAccept\",\n \"deviceHandoffSettle\", \"deviceHandoffCancel\", \"deviceHandoffView\", \"deviceHandoffAllow\", \"deviceTakeoverInfo\", \"deviceTakeover\", \"deviceTurnPeek\", \"deviceForkDiscard\", \"deviceRestoreStartOwn\",\n \"deviceRemove\", \"deviceNewSecret\", \"deviceSecretOfferDismiss\", \"deviceSetNoticeSeen\", \"deviceTurnCheck\", \"devicePushState\", \"devicePushSet\",\n \"appList\", \"appBuiltIns\", \"appStoreList\", \"appStorePreview\", \"appStoreAdd\", \"appStoreRemove\", \"appStoreRefresh\", \"appPreview\", \"appInstall\",\n \"appUpdateAccept\", \"appCheckUpdates\", \"appUninstall\", \"appRunCheck\", \"appFetchFiles\", \"appEntry\", \"appFile\", \"appFileAt\", \"appStorageGet\", \"appStorageSet\",\n \"appStorageDelete\", \"appStorageKeys\", \"appDataExport\", \"appDataExportText\",\n];\n\n/** Reads the hosts use outside `EngineApi`: the whole state, and one chat's stored messages. */\nexport const ENGINE_READS: readonly string[] = [\"getState\", \"getMessages\"];\n\n/**\n * Calls whose answer holds a secret (chat seeds, wallet phrases and keys, ecash, backups): the CLI prints their\n * result only with `--show-secret`.\n */\nexport const SECRET_RESULTS: ReadonlySet<string> = new Set([\n \"exportLinks\", \"takeInvite\", \"walletExport\", \"usdtReveal\",\n \"arkBackup\", \"barkBackup\", \"sparkBackup\", \"fedimintBackup\",\n \"usdtExportBackup\", \"arkExportBackup\", \"barkExportBackup\", \"sparkExportBackup\", \"fedimintExportBackup\",\n \"fedimintSpendNotes\",\n]);\n","import { createHash } from \"node:crypto\";\nimport { chatOrGroup, findGroup, node, state, type ApiContext, type Params } from \"./apiKit\";\n\n/**\n * The id an agent turn names its message by (docs/CLI.md § Agent turns). A message is stored under an id its sender\n * chose most of (`peer_<the id they sent>`), so a turn carries this one instead, made here from the chat (or group) and\n * that id: `t_` and 32 hex digits, in which nobody can write a word. Every command that takes a message's id takes it.\n */\nexport function turnRef(where: string, messageId: string): string {\n return \"t_\" + createHash(\"sha256\").update(`${where}\\n${messageId}`).digest(\"hex\").slice(0, 32);\n}\n\nconst TURN_REF = /^t_[0-9a-f]{32}$/;\nconst isRef = (value: unknown): value is string => typeof value === \"string\" && TURN_REF.test(value);\n\n/**\n * `params` with each turn's id in `message`, `reply` and `messages` as the id its message is stored under: looked for\n * among the chat's (or group's) newest messages first, where a turn's almost always is, then in all of them. One that\n * names no message stays as given, and its command says so as for any unknown id.\n */\nexport async function withStoredIds(ctx: ApiContext, params: Params): Promise<Params> {\n const wanted = new Set([params.message, params.reply, ...(Array.isArray(params.messages) ? params.messages : [])].filter(isRef));\n if (!wanted.size) return params;\n let target: { id: string; linkId: string; group: boolean } | null = null;\n try {\n if (typeof params.group === \"string\") { const group = findGroup(state(ctx).groups, params.group); target = { id: group.id, linkId: `group:${group.id}`, group: true }; }\n else if (typeof params.chat === \"string\") target = chatOrGroup(ctx, params.chat);\n } catch { /* the command says what is wrong with its chat or group */ }\n if (!target) return params;\n const { id, linkId, group } = target;\n const found = new Map<string, string>();\n const look = (messages: readonly { id: string }[]) => {\n for (const message of messages) { const ref = turnRef(id, message.id); if (wanted.has(ref)) found.set(ref, message.id); }\n return found.size === wanted.size;\n };\n if (!look((await node(ctx).messagePage({ linkId, limit: 200 })).messages)) look(group ? await node(ctx).groupMessages({ groupId: id }) : await node(ctx).getMessages(linkId));\n const stored = (value: unknown) => (isRef(value) ? found.get(value) ?? value : value);\n return {\n ...params,\n ...(params.message !== undefined && { message: stored(params.message) }),\n ...(params.reply !== undefined && { reply: stored(params.reply) }),\n ...(Array.isArray(params.messages) && { messages: params.messages.map(stored) }),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"turnRefs-B87dtrHM.js","names":[],"sources":["../../src/engineMethods.ts","../../src/turnRefs.ts"],"sourcesContent":["/**\n * The engine's calls the daemon passes through as `engine.<method>` (WISP 1100 § Local control API): exactly the\n * app's `EngineApi` (packages/browser/src/shared/rpc.ts; `engineMethods.test.ts` keeps the two equal), plus two\n * reads every host has. Nothing else on the engine object is reachable.\n */\nexport const ENGINE_METHODS: readonly string[] = [\n \"usdtCreate\", \"usdtUnlock\", \"usdtReveal\", \"usdtLock\", \"usdtRefresh\", \"usdtExportBackup\", \"usdtRestoreBackup\",\n \"arkCreate\", \"arkUnlock\", \"arkLock\", \"arkBackup\", \"arkExportBackup\", \"arkRestoreBackup\", \"arkRefresh\", \"arkRecover\",\n \"barkCreate\", \"barkBackup\", \"barkExportBackup\", \"barkRestoreBackup\", \"barkRefresh\", \"barkBoard\", \"fedimintPreview\",\n \"fedimintJoin\", \"fedimintLeave\", \"fedimintRefresh\", \"fedimintSpendNotes\", \"fedimintReceiveNotes\", \"fedimintInvoice\",\n \"fedimintTakeBack\", \"fedimintBackup\", \"fedimintExportBackup\", \"fedimintRestoreBackup\", \"fedimintRestorePhrase\",\n \"sparkCreate\", \"sparkBackup\", \"sparkExportBackup\", \"sparkRestoreBackup\", \"sparkRefresh\", \"sparkUseForLightning\",\n \"preparePayment\", \"approvePayment\", \"reconcilePayment\", \"cancelPayment\", \"refreshPublicProfiles\",\n \"choosePublicProfile\", \"preparePeerProof\", \"submitPeerProof\", \"withdrawPeerProof\", \"beginIdentityProof\",\n \"completeIdentityProof\", \"cancelIdentityProof\", \"removeIdentityProof\", \"shareIdentityProof\",\n \"withdrawIdentityProof\", \"recheckIdentityProof\", \"lookupIdentityDisplay\", \"loadPublicProfile\", \"loadPublicPosts\",\n \"loadPublicGraph\", \"loadPublicPostImage\", \"clearProfileData\", \"setDidListed\", \"nostrLoadContact\", \"nostrForgetContact\", \"nostrLoadOwn\",\n \"nostrLookup\", \"nostrDraft\", \"nostrPublish\", \"createLink\", \"takeInvite\", \"joinLink\", \"ensureLink\", \"confirmPair\",\n \"pollNow\", \"removeLink\", \"renameLink\", \"setActiveLink\", \"sendMessage\", \"editMessage\", \"retryMessage\", \"react\", \"pinMessage\", \"appId\", \"appOpen\", \"appClose\", \"appSend\", \"messageDetails\",\n \"deleteMessage\", \"exportLinks\", \"sendFile\", \"forwardMessages\", \"fileAction\", \"setDeliveryMode\", \"setTransportPreference\",\n \"setChatTransport\", \"setChatPaymentMethods\", \"setChatHold\", \"connect\", \"walletAddMint\", \"walletCreate\",\n \"walletRemove\", \"walletTestCoins\", \"walletSetupRetry\", \"walletSetupDismiss\", \"wake\", \"peekProfile\", \"walletSetPrimaryMint\", \"walletRemoveMint\", \"walletReceiveLightning\",\n \"walletQuoteInvoice\", \"walletPayQuote\", \"lnurlResolve\", \"lnurlInvoice\", \"checkPayment\", \"lightningSetSource\",\n \"lightningClearSource\", \"lightningRetrySource\", \"lightningReconfigureSource\", \"lightningRefresh\",\n \"lightningSetReceive\", \"lightningRename\", \"bitcoinSetSource\", \"bitcoinClearSource\", \"bitcoinRetrySource\",\n \"bitcoinReconfigureSource\", \"bitcoinReceiveAddress\", \"bitcoinRefresh\", \"walletReceiveToken\", \"walletInspectCashu\",\n \"walletExport\", \"walletBackupReminder\", \"sendPayment\", \"requestPayment\", \"requestGroupPayment\", \"groupPaymentHello\", \"askToPay\",\n \"payRequest\", \"reclaimPayment\", \"disconnect\", \"addService\", \"removeService\", \"setServiceEnabled\",\n \"setServiceShared\", \"updateSettings\", \"setCallSignal\", \"setTyping\", \"setWakeSubscription\", \"setWakeMuted\", \"wakeForCall\", \"setCallOn\", \"wakeConfirm\", \"setFastPoll\", \"createGroup\", \"inviteToGroup\",\n \"acceptGroupInvitation\", \"declineGroupInvitation\", \"enableGroupLink\", \"disableGroupLink\", \"joinGroupByLink\",\n \"sendGroupMessage\", \"sendGroupFile\", \"groupFileCheck\", \"pressButton\", \"groupMessages\", \"messagePage\", \"statusCardIndex\", \"groupTaken\", \"leaveGroup\", \"removeGroupMember\", \"makeGroupAdmin\", \"setGroupHub\", \"rotateGroup\",\n \"setGroupPicture\", \"renameGroup\", \"setGroupTyping\", \"forgetGroup\", \"setGroupManage\",\n // One profile on several devices (WISP 06): a CLI profile is always on one device, so these answer `single` or refuse.\n \"deviceEnrollInvite\", \"deviceEnrollConfirm\", \"deviceEnrollCancel\", \"deviceEnrollView\", \"deviceEnrollJoin\", \"deviceEnrollReady\", \"deviceEnrollFinish\",\n \"deviceEnrollRemove\", \"deviceSet\", \"devicePing\", \"deviceHandoffVerifier\", \"deviceHandoffPush\", \"deviceHandoffPull\", \"deviceHandoffAccept\",\n \"deviceHandoffSettle\", \"deviceHandoffCancel\", \"deviceHandoffView\", \"deviceHandoffAllow\", \"deviceTakeoverInfo\", \"deviceTakeover\", \"deviceTurnPeek\", \"deviceForkDiscard\", \"deviceRestoreStartOwn\",\n \"deviceRemove\", \"deviceNewSecret\", \"deviceSecretOfferDismiss\", \"deviceSetNoticeSeen\", \"deviceTurnCheck\", \"devicePushState\", \"devicePushSet\",\n \"appList\", \"appBuiltIns\", \"appStoreList\", \"appStorePreview\", \"appStoreAdd\", \"appStoreRemove\", \"appStoreRefresh\", \"appPreview\", \"appInstall\",\n \"appUpdateAccept\", \"appCheckUpdates\", \"appUninstall\", \"appRunCheck\", \"appFetchFiles\", \"appEntry\", \"appFile\", \"appFileAt\", \"appStorageGet\", \"appStorageSet\",\n \"appStorageDelete\", \"appStorageKeys\", \"appDataExport\", \"appDataExportText\",\n];\n\n/** Reads the hosts use outside `EngineApi`: the whole state, and one chat's stored messages. */\nexport const ENGINE_READS: readonly string[] = [\"getState\", \"getMessages\"];\n\n/**\n * Calls whose answer holds a secret (chat seeds, wallet phrases and keys, ecash, backups): the CLI prints their\n * result only with `--show-secret`.\n */\nexport const SECRET_RESULTS: ReadonlySet<string> = new Set([\n \"exportLinks\", \"takeInvite\", \"walletExport\", \"usdtReveal\",\n \"arkBackup\", \"barkBackup\", \"sparkBackup\", \"fedimintBackup\",\n \"usdtExportBackup\", \"arkExportBackup\", \"barkExportBackup\", \"sparkExportBackup\", \"fedimintExportBackup\",\n \"fedimintSpendNotes\",\n]);\n","import { createHash } from \"node:crypto\";\nimport { chatOrGroup, findGroup, node, state, type ApiContext, type Params } from \"./apiKit\";\n\n/**\n * The id an agent turn names its message by (docs/CLI.md § Agent turns). A message is stored under an id its sender\n * chose most of (`peer_<the id they sent>`), so a turn carries this one instead, made here from the chat (or group) and\n * that id: `t_` and 32 hex digits, in which nobody can write a word. Every command that takes a message's id takes it.\n */\nexport function turnRef(where: string, messageId: string): string {\n return \"t_\" + createHash(\"sha256\").update(`${where}\\n${messageId}`).digest(\"hex\").slice(0, 32);\n}\n\nconst TURN_REF = /^t_[0-9a-f]{32}$/;\nconst isRef = (value: unknown): value is string => typeof value === \"string\" && TURN_REF.test(value);\n\n/**\n * `params` with each turn's id in `message`, `reply` and `messages` as the id its message is stored under: looked for\n * among the chat's (or group's) newest messages first, where a turn's almost always is, then in all of them. One that\n * names no message stays as given, and its command says so as for any unknown id.\n */\nexport async function withStoredIds(ctx: ApiContext, params: Params): Promise<Params> {\n const wanted = new Set([params.message, params.reply, ...(Array.isArray(params.messages) ? params.messages : [])].filter(isRef));\n if (!wanted.size) return params;\n let target: { id: string; linkId: string; group: boolean } | null = null;\n try {\n if (typeof params.group === \"string\") { const group = findGroup(state(ctx).groups, params.group); target = { id: group.id, linkId: `group:${group.id}`, group: true }; }\n else if (typeof params.chat === \"string\") target = chatOrGroup(ctx, params.chat);\n } catch { /* the command says what is wrong with its chat or group */ }\n if (!target) return params;\n const { id, linkId, group } = target;\n const found = new Map<string, string>();\n const look = (messages: readonly { id: string }[]) => {\n for (const message of messages) { const ref = turnRef(id, message.id); if (wanted.has(ref)) found.set(ref, message.id); }\n return found.size === wanted.size;\n };\n if (!look((await node(ctx).messagePage({ linkId, limit: 200 })).messages)) look(group ? await node(ctx).groupMessages({ groupId: id }) : await node(ctx).getMessages(linkId));\n const stored = (value: unknown) => (isRef(value) ? found.get(value) ?? value : value);\n return {\n ...params,\n ...(params.message !== undefined && { message: stored(params.message) }),\n ...(params.reply !== undefined && { reply: stored(params.reply) }),\n ...(Array.isArray(params.messages) && { messages: params.messages.map(stored) }),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//#region ../browser/src/engine/paymentAdapters/providers/types.ts
|
|
2
|
+
var PROVIDER_PLATFORMS = [
|
|
3
|
+
"web",
|
|
4
|
+
"extension",
|
|
5
|
+
"desktop"
|
|
6
|
+
];
|
|
7
|
+
var PROVIDER_NETWORKS = [
|
|
8
|
+
"bitcoin",
|
|
9
|
+
"signet",
|
|
10
|
+
"testnet",
|
|
11
|
+
"regtest",
|
|
12
|
+
"mutinynet"
|
|
13
|
+
];
|
|
14
|
+
var networkMode = (network) => network === "bitcoin" ? "mainnet" : "testnet";
|
|
15
|
+
/** A provider can be offered here: it runs on this platform and on a network of this mode. */
|
|
16
|
+
var offeredIn = (descriptor, platform, mode) => descriptor.platforms.includes(platform) && descriptor.networks.some((network) => networkMode(network) === mode);
|
|
17
|
+
var FIELD_KINDS = [
|
|
18
|
+
"text",
|
|
19
|
+
"url",
|
|
20
|
+
"secret",
|
|
21
|
+
"select",
|
|
22
|
+
"textarea"
|
|
23
|
+
];
|
|
24
|
+
/** What is stored with the profile and sent on the wire in journals: stable, short, lowercase. */
|
|
25
|
+
var PROVIDER_ID = /^[a-z][a-z0-9-]{0,31}$/;
|
|
26
|
+
/**
|
|
27
|
+
* Problems with a provider descriptor, empty when it is well-formed. The registry refuses a descriptor
|
|
28
|
+
* with any; the contract suite checks the same list, so an author sees them before the app does.
|
|
29
|
+
*/
|
|
30
|
+
function providerDescriptorProblems(d) {
|
|
31
|
+
const problems = [];
|
|
32
|
+
if (!PROVIDER_ID.test(d.id ?? "")) problems.push("id must match ^[a-z][a-z0-9-]{0,31}$");
|
|
33
|
+
if (!d.label?.trim()) problems.push("label is empty");
|
|
34
|
+
if (d.kind !== "lightning" && d.kind !== "onchain") problems.push("kind must be lightning or onchain");
|
|
35
|
+
if (!d.description?.trim()) problems.push("description is empty: say what it is and who holds the money");
|
|
36
|
+
if (!Array.isArray(d.networks) || !d.networks.length) problems.push("no networks");
|
|
37
|
+
else for (const n of d.networks) if (!PROVIDER_NETWORKS.includes(n)) problems.push(`unknown network ${String(n)}`);
|
|
38
|
+
if (!Array.isArray(d.platforms) || !d.platforms.length) problems.push("no platforms");
|
|
39
|
+
else for (const p of d.platforms) if (!PROVIDER_PLATFORMS.includes(p)) problems.push(`unknown platform ${String(p)}`);
|
|
40
|
+
if (!Array.isArray(d.fields)) problems.push("fields must be a list (empty when there is nothing to configure)");
|
|
41
|
+
else {
|
|
42
|
+
const names = d.fields.map((f) => f.name);
|
|
43
|
+
if (new Set(names).size !== names.length) problems.push("field names are not unique");
|
|
44
|
+
for (const f of d.fields) {
|
|
45
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/.test(f.name ?? "")) problems.push(`field ${String(f.name)} has an invalid name`);
|
|
46
|
+
if (!f.label?.trim()) problems.push(`field ${f.name} has no label`);
|
|
47
|
+
if (!FIELD_KINDS.includes(f.kind)) problems.push(`field ${f.name} has an unknown kind`);
|
|
48
|
+
if (f.kind === "select" && !f.options?.length) problems.push(`field ${f.name} is a select without options`);
|
|
49
|
+
if (f.suggestions !== void 0 && (!Array.isArray(f.suggestions) || f.suggestions.some((o) => typeof o?.value !== "string" || typeof o?.label !== "string"))) problems.push(`field ${f.name} has malformed suggestions`);
|
|
50
|
+
if (f.changeable && (f.kind === "secret" || f.kind === "select")) problems.push(`field ${f.name} cannot be changeable: only a server address can`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (typeof d.create !== "function") problems.push("create is not a function");
|
|
54
|
+
if (d.validate !== void 0 && typeof d.validate !== "function") problems.push("validate is not a function");
|
|
55
|
+
return problems;
|
|
56
|
+
}
|
|
57
|
+
/** Only these fields reach the UI, whatever else a provider module keeps on its descriptor. */
|
|
58
|
+
var describeProvider = ({ id, label, kind, description, networks, platforms, fields, custodial, experimental }) => ({
|
|
59
|
+
id,
|
|
60
|
+
label,
|
|
61
|
+
kind,
|
|
62
|
+
description,
|
|
63
|
+
networks,
|
|
64
|
+
platforms,
|
|
65
|
+
fields,
|
|
66
|
+
custodial,
|
|
67
|
+
experimental
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* The provider proved that nothing left the wallet (refused before sending, no route found before any
|
|
71
|
+
* HTLC, a transaction that was never broadcast). Safe to try again, with this or another source.
|
|
72
|
+
*
|
|
73
|
+
* Any other error from a spend means the outcome is UNKNOWN: the payment may be in flight or done. It is
|
|
74
|
+
* recorded as such and only reconciled (asked about), never retried. When in doubt, do not throw this.
|
|
75
|
+
*/
|
|
76
|
+
var NothingSpentError = class extends Error {
|
|
77
|
+
constructor(message) {
|
|
78
|
+
super(message);
|
|
79
|
+
this.name = "NothingSpentError";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* The source could not be reached: no answer, a time-out, a refused connection, a server error. The
|
|
84
|
+
* engine keeps trying by itself (with backoff) and shows the source as connecting meanwhile.
|
|
85
|
+
*/
|
|
86
|
+
var SourceUnreachableError = class extends Error {
|
|
87
|
+
constructor(message, cause) {
|
|
88
|
+
super(message);
|
|
89
|
+
this.name = "SourceUnreachableError";
|
|
90
|
+
if (cause !== void 0) Object.assign(this, { cause });
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* A setting of the source is wrong (a server on another network, a phrase that makes no wallet): trying
|
|
95
|
+
* again changes nothing until the setting does. The engine shows it as unavailable at once.
|
|
96
|
+
*/
|
|
97
|
+
var SourceConfigError = class extends Error {
|
|
98
|
+
constructor(message, cause) {
|
|
99
|
+
super(message);
|
|
100
|
+
this.name = "SourceConfigError";
|
|
101
|
+
if (cause !== void 0) Object.assign(this, { cause });
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var sourceProblem = (error) => error instanceof Error && error.name === "SourceUnreachableError" ? "unreachable" : error instanceof Error && error.name === "SourceConfigError" ? "config" : "other";
|
|
105
|
+
/**
|
|
106
|
+
* Whether an error says nothing was spent. By name, not by class: a provider built outside the app (an
|
|
107
|
+
* SDK plugin bundled with its own copy of `NothingSpentError`) must be understood the same way.
|
|
108
|
+
*/
|
|
109
|
+
var isNothingSpentError = (error) => error instanceof NothingSpentError || error instanceof Error && error.name === "NothingSpentError";
|
|
110
|
+
/**
|
|
111
|
+
* An error message fit to show and store: every secret the source was given is blanked out, in case a
|
|
112
|
+
* library echoed a URI or a key back.
|
|
113
|
+
*/
|
|
114
|
+
function redact(error, secrets = {}) {
|
|
115
|
+
let message = error instanceof Error ? error.message : String(error);
|
|
116
|
+
for (const value of Object.values(secrets)) if (value && value.length >= 4) message = message.split(value).join("•••");
|
|
117
|
+
return message.slice(0, 300);
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { describeProvider as a, offeredIn as c, sourceProblem as d, SourceUnreachableError as i, providerDescriptorProblems as l, PROVIDER_PLATFORMS as n, isNothingSpentError as o, SourceConfigError as r, networkMode as s, NothingSpentError as t, redact as u };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=types-C4_KafL_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-C4_KafL_.js","names":[],"sources":["../../../browser/src/engine/paymentAdapters/providers/types.ts"],"sourcesContent":["import type { BitcoinNetwork } from \"@ghostly/core\";\nimport type { WalletMode } from \"../../../shared/mints\";\n\n/**\n * What every wallet provider (a source of Lightning or of on-chain Bitcoin) shares: where it runs, how\n * it is configured, and the one distinction that keeps money safe. See PROVIDERS.md.\n */\n\n/** Where Ghostly runs: the web app, the browser extension (engine in an offscreen document), the Tauri app. */\nexport type ProviderPlatform = \"web\" | \"extension\" | \"desktop\";\nexport const PROVIDER_PLATFORMS: readonly ProviderPlatform[] = [\"web\", \"extension\", \"desktop\"];\nexport type ProviderKind = \"lightning\" | \"onchain\";\n/** The chain a provider's sats live on. Only `bitcoin` is real money; the others belong to the Testnet mode. */\nexport type ProviderNetwork = BitcoinNetwork;\nexport const PROVIDER_NETWORKS: readonly ProviderNetwork[] = [\"bitcoin\", \"signet\", \"testnet\", \"regtest\", \"mutinynet\"];\nexport const networkMode = (network: ProviderNetwork): WalletMode => (network === \"bitcoin\" ? \"mainnet\" : \"testnet\");\n\n/**\n * One field of a provider's configuration form. The wallet card renders these; a provider that needs\n * more registers its own form component instead (apps/ui/src/components/wallet/providers/forms.ts).\n * `secret` fields (an NWC URI, a macaroon, a rune, an API key, a password) are sealed before they are\n * stored, never shown again, never put in the engine state, and never logged.\n */\nexport interface ProviderField {\n name: string;\n label: string;\n kind: \"text\" | \"url\" | \"secret\" | \"select\" | \"textarea\";\n placeholder?: string;\n help?: string;\n optional?: boolean;\n /** `select` only. */\n options?: { value: string; label: string }[];\n /** Pre-filled per mode, e.g. a public test server for Testnet. */\n defaults?: Partial<Record<WalletMode, string>>;\n /**\n * Values offered under a `url` or `text` field (a list to pick from, anything may still be typed), each\n * only while the other fields hold `when`: e.g. a public Esplora server per network.\n */\n suggestions?: { value: string; label: string; when?: Record<string, string> }[];\n /**\n * A server address that can be changed on a saved source without its secrets being typed again, and\n * without changing whose money it is: an Esplora server of a BDK wallet (the wallet is the phrase). The\n * source's \"Change server\" edits these fields only. Never mark a field that picks another account (a\n * node's URL: another node is other money).\n */\n changeable?: boolean;\n}\n\n/** What the person typed, split by the field kinds: `config` is shown back, `secrets` never is. */\nexport interface ProviderSettings {\n config: Record<string, string>;\n secrets: Record<string, string>;\n}\n\n/** What the engine hands a provider's factory. */\nexport interface ProviderHost {\n platform: ProviderPlatform;\n /** The wallet mode the source is for: its provider must be on a network of this mode. */\n mode: WalletMode;\n /**\n * Reserved for the built-in Cashu mint source: the engine's own wallet. It is not part of the SDK, and\n * no other provider should read it.\n */\n cashu?: unknown;\n /** Reserved for the built-in Fedimint source: the engine's Fedimint wallet (its joined federations). Not part of the SDK. */\n fedimint?: unknown;\n /** Ends when the source is replaced, the mode switches or the engine stops: abort long waits on it. */\n signal: AbortSignal;\n /**\n * Desktop only: calls a command of the Tauri app (apps/desktop), for what a WebView cannot do (a pinned\n * certificate, no CORS, a raw socket). Absent on the web and in the extension.\n */\n invoke?: <T>(command: string, args: Record<string, unknown>) => Promise<T>;\n}\n\n/**\n * A provider module's export. Registering a provider is adding its module and one line in\n * `registry.ts`; everything else (storage, sealing, per-mode sources, the card, journals) is shared.\n */\nexport interface ProviderDescriptor<P> {\n id: string;\n label: string;\n kind: ProviderKind;\n /** One line under the name in the source picker: what it is and who holds the money. */\n description: string;\n /** Networks it can run on. A mode lists only providers with a network of that mode. */\n networks: readonly ProviderNetwork[];\n platforms: readonly ProviderPlatform[];\n fields: readonly ProviderField[];\n /** Custodial (someone else holds the sats) or still experimental: said in the picker. */\n custodial?: boolean;\n experimental?: boolean;\n /** Checks the form before anything is contacted; throws a message fit for the person. */\n validate?(settings: ProviderSettings, mode: WalletMode): void;\n /** Connects. The engine then asks `info()` and refuses a network of the other mode. */\n create(settings: ProviderSettings, host: ProviderHost): Promise<P>;\n}\n\n/** A provider can be offered here: it runs on this platform and on a network of this mode. */\nexport const offeredIn = (descriptor: { platforms: readonly ProviderPlatform[]; networks: readonly ProviderNetwork[] }, platform: ProviderPlatform, mode: WalletMode) =>\n descriptor.platforms.includes(platform) && descriptor.networks.some((network) => networkMode(network) === mode);\n\nconst FIELD_KINDS = [\"text\", \"url\", \"secret\", \"select\", \"textarea\"];\n/** What is stored with the profile and sent on the wire in journals: stable, short, lowercase. */\nexport const PROVIDER_ID = /^[a-z][a-z0-9-]{0,31}$/;\n\n/**\n * Problems with a provider descriptor, empty when it is well-formed. The registry refuses a descriptor\n * with any; the contract suite checks the same list, so an author sees them before the app does.\n */\nexport function providerDescriptorProblems(d: ProviderDescriptor<unknown>): string[] {\n const problems: string[] = [];\n if (!PROVIDER_ID.test(d.id ?? \"\")) problems.push(\"id must match ^[a-z][a-z0-9-]{0,31}$\");\n if (!d.label?.trim()) problems.push(\"label is empty\");\n if (d.kind !== \"lightning\" && d.kind !== \"onchain\") problems.push(\"kind must be lightning or onchain\");\n if (!d.description?.trim()) problems.push(\"description is empty: say what it is and who holds the money\");\n if (!Array.isArray(d.networks) || !d.networks.length) problems.push(\"no networks\");\n else for (const n of d.networks) if (!PROVIDER_NETWORKS.includes(n)) problems.push(`unknown network ${String(n)}`);\n if (!Array.isArray(d.platforms) || !d.platforms.length) problems.push(\"no platforms\");\n else for (const p of d.platforms) if (!PROVIDER_PLATFORMS.includes(p)) problems.push(`unknown platform ${String(p)}`);\n if (!Array.isArray(d.fields)) problems.push(\"fields must be a list (empty when there is nothing to configure)\");\n else {\n const names = d.fields.map((f) => f.name);\n if (new Set(names).size !== names.length) problems.push(\"field names are not unique\");\n for (const f of d.fields) {\n if (!/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/.test(f.name ?? \"\")) problems.push(`field ${String(f.name)} has an invalid name`);\n if (!f.label?.trim()) problems.push(`field ${f.name} has no label`);\n if (!FIELD_KINDS.includes(f.kind)) problems.push(`field ${f.name} has an unknown kind`);\n if (f.kind === \"select\" && !f.options?.length) problems.push(`field ${f.name} is a select without options`);\n if (f.suggestions !== undefined && (!Array.isArray(f.suggestions) || f.suggestions.some((o: { value?: unknown; label?: unknown } | undefined) => typeof o?.value !== \"string\" || typeof o?.label !== \"string\"))) problems.push(`field ${f.name} has malformed suggestions`);\n if (f.changeable && (f.kind === \"secret\" || f.kind === \"select\")) problems.push(`field ${f.name} cannot be changeable: only a server address can`);\n }\n }\n if (typeof d.create !== \"function\") problems.push(\"create is not a function\");\n if (d.validate !== undefined && typeof d.validate !== \"function\") problems.push(\"validate is not a function\");\n return problems;\n}\n\n/** The serializable part of a descriptor, for the UI (a function cannot cross the extension's port). */\nexport type ProviderDescriptorView = Omit<ProviderDescriptor<unknown>, \"create\" | \"validate\">;\n/** Only these fields reach the UI, whatever else a provider module keeps on its descriptor. */\nexport const describeProvider = ({ id, label, kind, description, networks, platforms, fields, custodial, experimental }: ProviderDescriptor<unknown>): ProviderDescriptorView =>\n ({ id, label, kind, description, networks, platforms, fields, custodial, experimental });\n\n/**\n * The provider proved that nothing left the wallet (refused before sending, no route found before any\n * HTLC, a transaction that was never broadcast). Safe to try again, with this or another source.\n *\n * Any other error from a spend means the outcome is UNKNOWN: the payment may be in flight or done. It is\n * recorded as such and only reconciled (asked about), never retried. When in doubt, do not throw this.\n */\nexport class NothingSpentError extends Error {\n constructor(message: string) { super(message); this.name = \"NothingSpentError\"; }\n}\n\n/**\n * The source could not be reached: no answer, a time-out, a refused connection, a server error. The\n * engine keeps trying by itself (with backoff) and shows the source as connecting meanwhile.\n */\nexport class SourceUnreachableError extends Error {\n constructor(message: string, cause?: unknown) { super(message); this.name = \"SourceUnreachableError\"; if (cause !== undefined) Object.assign(this, { cause }); }\n}\n\n/**\n * A setting of the source is wrong (a server on another network, a phrase that makes no wallet): trying\n * again changes nothing until the setting does. The engine shows it as unavailable at once.\n */\nexport class SourceConfigError extends Error {\n constructor(message: string, cause?: unknown) { super(message); this.name = \"SourceConfigError\"; if (cause !== undefined) Object.assign(this, { cause }); }\n}\n\n/** What went wrong connecting a source, by name (a plugin bundles its own copies of these classes). */\nexport type SourceProblem = \"unreachable\" | \"config\" | \"other\";\nexport const sourceProblem = (error: unknown): SourceProblem =>\n error instanceof Error && error.name === \"SourceUnreachableError\" ? \"unreachable\" : error instanceof Error && error.name === \"SourceConfigError\" ? \"config\" : \"other\";\n\n/**\n * Whether an error says nothing was spent. By name, not by class: a provider built outside the app (an\n * SDK plugin bundled with its own copy of `NothingSpentError`) must be understood the same way.\n */\nexport const isNothingSpentError = (error: unknown): error is NothingSpentError =>\n error instanceof NothingSpentError || (error instanceof Error && error.name === \"NothingSpentError\");\n\n/**\n * An error message fit to show and store: every secret the source was given is blanked out, in case a\n * library echoed a URI or a key back.\n */\nexport function redact(error: unknown, secrets: Record<string, string> = {}): string {\n let message = error instanceof Error ? error.message : String(error);\n for (const value of Object.values(secrets)) if (value && value.length >= 4) message = message.split(value).join(\"•••\");\n return message.slice(0, 300);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { an as EVM_TEST_CHAINS, cn as SEPOLIA_TEST_USDT, dn as USDT_PUBLIC_RPC, gn as validatePaymentTarget, ln as SEPOLIA_TEST_USDT_FAUCET,
|
|
2
|
-
import { a as sealSeed, n as rpcHost, o as unsealSeed, t as networkReason } from "./networkReason-
|
|
1
|
+
import { Yn as engineError, an as EVM_TEST_CHAINS, cn as SEPOLIA_TEST_USDT, dn as USDT_PUBLIC_RPC, gn as validatePaymentTarget, ln as SEPOLIA_TEST_USDT_FAUCET, sn as PaymentPreflightError, un as TEST_USDT_FAUCET_AMOUNT } from "./src-DDzSERyc.js";
|
|
2
|
+
import { a as sealSeed, n as rpcHost, o as unsealSeed, t as networkReason } from "./networkReason-CetKkTPo.js";
|
|
3
3
|
import { mnemonicToSeedSync } from "@scure/bip39";
|
|
4
4
|
import WalletManagerEvm from "@tetherto/wdk-wallet-evm";
|
|
5
5
|
import { Interface, Transaction, getAddress, keccak256 } from "ethers";
|
|
@@ -407,4 +407,4 @@ var UsdtAdapter = class UsdtAdapter {
|
|
|
407
407
|
//#endregion
|
|
408
408
|
export { UsdtAdapter, wireProvider };
|
|
409
409
|
|
|
410
|
-
//# sourceMappingURL=usdt-
|
|
410
|
+
//# sourceMappingURL=usdt-Fj8CQO2z.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usdt-C1Xao2xH.js","names":[],"sources":["../../../browser/src/engine/paymentAdapters/usdt.ts"],"sourcesContent":["import { mnemonicToSeedSync } from '@scure/bip39';\nimport WalletManagerEvm, { type WalletAccountEvm } from '@tetherto/wdk-wallet-evm';\nimport { Interface, Transaction, getAddress, keccak256 } from 'ethers';\nimport { ETHEREUM_USDT, EVM_TEST_CHAINS, USDT_PUBLIC_RPC, SEPOLIA_TEST_USDT, SEPOLIA_TEST_USDT_FAUCET, TEST_USDT_FAUCET_AMOUNT, PaymentPreflightError, engineError, validatePaymentTarget, type PaymentAdapter, type PaymentExecution, type PaymentReview, type PaymentTarget } from '@ghostly/core';\nimport { sealSeed, unsealSeed, type EncryptedSeed } from './persistence';\nimport { networkReason, rpcHost } from './networkReason';\n\nexport interface UsdtConfig {\n network: 'ethereum' | 'sepolia' | 'evm-local';\n provider: string;\n chainId: 1 | 11155111 | 31337;\n token: string;\n decimals: number;\n codeHash: string;\n}\nexport interface UsdtPrepared {\n from: string; to: string; data: string; value: string; chainId: number; nonce: number;\n gasLimit: string; maxFeePerGas: string; maxPriorityFeePerGas: string;\n signed?: EncryptedSeed; hash?: string;\n}\nconst faucet = new Interface(['function mint(address token,address to,uint256 amount) returns (uint256)']);\nconst erc20 = new Interface(['function decimals() view returns(uint8)', 'function balanceOf(address) view returns(uint256)', 'function transfer(address,uint256) returns(bool)', 'event Transfer(address indexed from,address indexed to,uint256 value)']);\nconst same = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\nconst CONFIRMATIONS = 2;\n/** The JSON-RPC methods that only read: asked again once when they fail (see `UsdtAdapter.rpc`). */\nconst RETRIED_READS = new Set(['eth_chainId', 'eth_getCode', 'eth_call', 'eth_getBalance', 'eth_blockNumber', 'eth_getLogs', 'eth_getTransactionCount', 'eth_estimateGas', 'eth_getBlockByNumber', 'eth_maxPriorityFeePerGas', 'eth_gasPrice', 'eth_feeHistory', 'eth_getTransactionByHash', 'eth_getTransactionReceipt']);\nconst RETRY_AFTER_MS = 1000;\n/** Failures that would fail the same way again at once: not retried. */\nconst FINAL = new WeakSet<object>();\nconst timedOut = (error: unknown) => error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError');\n\n/**\n * The `provider` a request carries to the contact. Which RPC pays is the payer's own choice, so it names none of\n * this wallet's: a typed RPC URL may hold an API key (`/v3/<key>`), and every contact would read it. Older apps\n * require a URL here and pay only when it equals their own RPC, so it is the chain's public RPC (the default both\n * start with), and a local test chain's origin, without its path.\n */\nexport function wireProvider(config: Pick<UsdtConfig, 'network' | 'provider'>): string {\n return config.network === 'evm-local' ? new URL(config.provider).origin : USDT_PUBLIC_RPC[config.network];\n}\n\n/** WDK signs locally. Every network call uses the configured RPC, never a peer-supplied URL. */\nexport class UsdtAdapter implements PaymentAdapter<UsdtPrepared> {\n readonly method = 'usdt' as const;\n private manager?: WalletManagerEvm;\n private account?: WalletAccountEvm;\n private mnemonic = '';\n private nextId = 0;\n private queue: Promise<unknown> = Promise.resolve();\n private constructor(readonly config: UsdtConfig) {}\n\n static async inspect(config: Omit<UsdtConfig, 'decimals' | 'codeHash'>): Promise<UsdtConfig> {\n if (config.network === 'ethereum' ? config.chainId !== 1 || !same(config.token, ETHEREUM_USDT) : !(config.network in EVM_TEST_CHAINS) || config.chainId !== EVM_TEST_CHAINS[config.network]) throw new Error('Unsupported USDT network or contract');\n const token = getAddress(config.token);\n const url = new URL(config.provider);\n if (url.username || url.password || url.search || url.hash || (url.protocol !== 'https:' && !(url.protocol === 'http:' && ['localhost','127.0.0.1','[::1]'].includes(url.hostname)))) throw new Error('Use HTTPS or a loopback test RPC');\n const adapter = new UsdtAdapter({...config, token, decimals: 6, codeHash: ''});\n await adapter.chain();\n const code = await adapter.rpc<string>('eth_getCode', [token, 'latest']);\n if (code === '0x') throw new Error('No token contract exists on this chain');\n const result = await adapter.rpc<string>('eth_call', [{to: token, data: erc20.encodeFunctionData('decimals')}, 'latest']);\n const decimals = Number(erc20.decodeFunctionResult('decimals', result)[0]);\n if (!Number.isInteger(decimals) || decimals < 0 || decimals > 18 || (config.chainId === 1 && decimals !== 6)) throw new Error('Unexpected token decimals');\n return {...config, token, decimals, codeHash: keccak256(code)};\n }\n static async connect(config: UsdtConfig, mnemonic: string): Promise<UsdtAdapter> {\n const inspected = await UsdtAdapter.inspect(config);\n if (inspected.decimals !== config.decimals || inspected.codeHash !== config.codeHash) throw new Error('Token metadata changed; do not use this wallet configuration');\n const adapter = new UsdtAdapter(config);\n adapter.mnemonic = mnemonic;\n // Pass standard BIP-39 seed bytes: WDK's string helper assumes a Node Buffer global.\n const seed = mnemonicToSeedSync(mnemonic);\n try { adapter.manager = new WalletManagerEvm(seed, {provider: {request: ({method, params}) => adapter.rpc(method, params as unknown[] ?? [])}, chainId: config.chainId}); } finally { seed.fill(0); }\n adapter.account = await adapter.manager.getAccount(0);\n return adapter;\n }\n /**\n * A read that fails is asked again, once, a moment later: a public RPC drops a request now and then, and a chain that\n * just made a block can refuse a read of \"latest\" it no longer holds. Without it a network switch, a restore or New\n * gave up on the first such answer. Never a broadcast or anything else that writes, nor a request that did not answer\n * in time (the person would wait twice as long), nor one the server refused as such (4xx).\n */\n async rpc<T>(method: string, params: unknown[] = []): Promise<T> {\n try { return await this.ask<T>(method, params); }\n catch (error) {\n if (!RETRIED_READS.has(method) || FINAL.has(error as object)) throw error;\n await new Promise((resolve) => setTimeout(resolve, RETRY_AFTER_MS));\n return this.ask<T>(method, params);\n }\n }\n private async ask<T>(method: string, params: unknown[]): Promise<T> {\n let response: Response;\n // The browser's words for a request that got no answer (\"Fetch is aborted\") say nothing: the RPC's host does.\n try { response = await fetch(this.config.provider, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({jsonrpc:'2.0',id:++this.nextId,method,params}), signal:AbortSignal.timeout(15000)}); }\n catch (error) {\n const reason = networkReason(error, rpcHost(this.config.provider));\n const thrown = reason ? Object.assign(new Error(reason), {cause: error}) : error;\n if (timedOut(error) && thrown && typeof thrown === 'object') FINAL.add(thrown);\n throw thrown;\n }\n if (!response.ok) { const error = engineError('usdtRpcUnavailable'); if (response.status !== 429 && response.status < 500) FINAL.add(error); throw error; }\n const result = await response.json();\n if (result.error || !Object.prototype.hasOwnProperty.call(result, 'result')) throw new Error('USDT RPC rejected the operation');\n return result.result as T;\n }\n private async chain() {\n if (BigInt(await this.rpc<string>('eth_chainId')) !== BigInt(this.config.chainId)) throw new Error('RPC chain does not match this wallet');\n }\n private async assertToken() {\n await this.chain();\n const code = await this.rpc<string>('eth_getCode', [this.config.token, 'latest']);\n if (code === '0x' || keccak256(code) !== this.config.codeHash) throw new Error('Token contract changed');\n }\n /**\n * Sepolia only: asks Aave's public faucet for test USDT, to this wallet, paid with its own test ETH.\n * Everything is fixed here (chain, contract, token, amount, recipient): nothing comes from outside.\n */\n mintTestTokens(): Promise<string> { return this.serial(async () => {\n if (this.config.chainId !== EVM_TEST_CHAINS.sepolia || !same(this.config.token, SEPOLIA_TEST_USDT)) throw new Error('Test USDT comes from a faucet on Sepolia only');\n await this.chain();\n const account = this.current(), from = await account.getAddress();\n const data = faucet.encodeFunctionData('mint', [SEPOLIA_TEST_USDT, from, BigInt(TEST_USDT_FAUCET_AMOUNT)]);\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount', [from, 'pending'])));\n const estimate = BigInt(await this.rpc<string>('eth_estimateGas', [{ from, to: SEPOLIA_TEST_USDT_FAUCET, data, value: '0x0' }]));\n const block = await this.rpc<{ baseFeePerGas?: string }>('eth_getBlockByNumber', ['latest', false]);\n if (!block.baseFeePerGas) throw new Error('This wallet requires an EIP-1559 chain');\n const priority = BigInt(await this.rpc<string>('eth_maxPriorityFeePerGas'));\n const maxFeePerGas = BigInt(block.baseFeePerGas) * 2n + priority, gasLimit = (estimate * 120n + 99n) / 100n;\n if (BigInt((await this.balances()).gasBalance) < gasLimit * maxFeePerGas) throw engineError('usdtNeedsSepoliaGas');\n const raw = await account.signTransaction({ type: 2, to: SEPOLIA_TEST_USDT_FAUCET, data, value: 0n, chainId: this.config.chainId, nonce, gasLimit, maxFeePerGas, maxPriorityFeePerGas: priority });\n await account.sendTransaction(raw);\n return Transaction.from(raw).hash!;\n }); }\n private current(): WalletAccountEvm { if (!this.account) throw new Error('Unlock the USDT wallet first'); return this.account; }\n address() { return this.current().getAddress(); }\n async balances() {\n await this.assertToken();\n const address = await this.address();\n const [token, gas] = await Promise.all([this.rpc<string>('eth_call',[{to:this.config.token,data:erc20.encodeFunctionData('balanceOf',[address])},'latest']),this.rpc<string>('eth_getBalance',[address,'pending'])]);\n return {balance:erc20.decodeFunctionResult('balanceOf',token)[0].toString(),gasBalance:BigInt(gas).toString()};\n }\n async target(): Promise<PaymentTarget> {\n const now = Date.now();\n return {method:'usdt',network:this.config.network,provider:wireProvider(this.config),asset:this.config.chainId === 1 ? 'USDT':'TEST-USDT',unit:'token-base',address:await this.address(),chainId:this.config.chainId,token:this.config.token,decimals:this.config.decimals,issuedAt:now,expiresAt:now+15*60*1000};\n }\n /** The request is for this wallet's token on its chain. Its `provider` is not compared: this wallet's own RPC pays. */\n private matches(target: PaymentTarget) {\n validatePaymentTarget(target);\n if (target.method !== 'usdt' || target.network !== this.config.network || target.chainId !== this.config.chainId || !same(target.token!,this.config.token) || target.decimals !== this.config.decimals) throw new Error('Request does not match the configured token and network');\n }\n prepare(target: PaymentTarget, amount: number, feeCap: number) { return this.serial(async () => {\n this.matches(target);\n await this.assertToken();\n const from = await this.address(), to = this.config.token;\n if (same(target.address, from) || same(target.address, to)) throw new Error('Choose a different recipient address');\n const {balance,gasBalance} = await this.balances();\n if (BigInt(balance) < BigInt(amount)) throw engineError('usdtNotEnoughTokens');\n const data = erc20.encodeFunctionData('transfer', [getAddress(target.address),BigInt(amount)]);\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[from,'pending'])));\n if (!Number.isSafeInteger(nonce)) throw new Error('Invalid account nonce');\n const estimate = BigInt(await this.rpc<string>('eth_estimateGas',[{from,to,data,value:'0x0'}]));\n const block = await this.rpc<{baseFeePerGas?:string}>('eth_getBlockByNumber',['latest',false]);\n if (!block.baseFeePerGas) throw new Error('This wallet requires an EIP-1559 chain');\n const priority = BigInt(await this.rpc<string>('eth_maxPriorityFeePerGas'));\n const maxFee = BigInt(block.baseFeePerGas)*2n + priority;\n const gasLimit = (estimate*120n+99n)/100n;\n const maximum = gasLimit*maxFee;\n if (maximum > BigInt(feeCap) || maximum > BigInt(Number.MAX_SAFE_INTEGER)) throw engineError('usdtGasAboveLimit');\n if (BigInt(gasBalance) < maximum) throw engineError('usdtNotEnoughGas');\n const prepared:UsdtPrepared = {from,to,data,value:'0',chainId:this.config.chainId,nonce,gasLimit:gasLimit.toString(),maxFeePerGas:maxFee.toString(),maxPriorityFeePerGas:priority.toString()};\n return {fee:Number(maximum),prepared,evm:{from,nonce,gasLimit:prepared.gasLimit,maxFeePerGas:prepared.maxFeePerGas,maxPriorityFeePerGas:prepared.maxPriorityFeePerGas,confirmations:CONFIRMATIONS}};\n }); }\n private verifyPrepared(review: PaymentReview, tx: UsdtPrepared) {\n if (tx.chainId !== this.config.chainId || !same(tx.to,this.config.token) || tx.value !== '0' || tx.data !== erc20.encodeFunctionData('transfer',[getAddress(review.address),BigInt(review.amount)]) || BigInt(tx.gasLimit)*BigInt(tx.maxFeePerGas) !== BigInt(review.fee) || review.fee > review.feeCap || tx.nonce !== review.evm?.nonce || !same(tx.from,review.evm?.from ?? '')) throw new Error('Transaction no longer matches the approved review');\n }\n private verifySigned(raw: string, saved: UsdtPrepared) {\n const tx = Transaction.from(raw);\n if (!tx.hash || !tx.from || !same(tx.from,saved.from) || tx.chainId !== BigInt(saved.chainId) || !tx.to || !same(tx.to,saved.to) || tx.data !== saved.data || tx.value !== 0n || tx.nonce !== saved.nonce || tx.gasLimit !== BigInt(saved.gasLimit) || tx.maxFeePerGas !== BigInt(saved.maxFeePerGas) || tx.maxPriorityFeePerGas !== BigInt(saved.maxPriorityFeePerGas)) throw new Error('Signature does not match the approved transaction');\n return tx.hash;\n }\n execute(review: PaymentReview, prepared: UsdtPrepared, persist?:()=>Promise<void>) { return this.serial(async () => {\n let account:WalletAccountEvm;\n try {\n this.matches(review); this.verifyPrepared(review,prepared);\n await this.assertToken(); account=this.current();\n if (!same(await account.getAddress(),prepared.from)) throw new Error('Wrong wallet');\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[prepared.from,'pending'])));\n if (nonce !== prepared.nonce) throw new Error('Account nonce changed. Create a new review');\n const balances = await this.balances();\n if (BigInt(balances.balance)<BigInt(review.amount) || BigInt(balances.gasBalance)<BigInt(review.fee)) throw new Error('Token or gas balance changed. Create a new review');\n if (!persist) throw new Error('Durable payment journal required');\n } catch (error) { throw new PaymentPreflightError(error instanceof Error ? error.message : 'Could not validate payment'); }\n const raw = await account.signTransaction({type:2,to:prepared.to,data:prepared.data,value:0n,chainId:prepared.chainId,nonce:prepared.nonce,gasLimit:BigInt(prepared.gasLimit),maxFeePerGas:BigInt(prepared.maxFeePerGas),maxPriorityFeePerGas:BigInt(prepared.maxPriorityFeePerGas)});\n prepared.hash = this.verifySigned(raw,prepared);\n prepared.signed = await sealSeed(raw,this.mnemonic);\n await persist!(); // Nothing may broadcast before the encrypted bytes are durable.\n await account.sendTransaction(raw);\n return this.receipt(prepared.hash,review,prepared.from);\n }); }\n reconcile(review: PaymentReview, prepared: UsdtPrepared) { return this.serial(async () => {\n await this.assertToken(); this.verifyPrepared(review,prepared);\n if (!prepared.signed || !prepared.hash) return {settled:false,failed:true,error:'No signed transaction was submitted. Create a new review.'};\n const result = await this.receipt(prepared.hash,review,prepared.from);\n if (result.settled || result.failed || result.pending) return result;\n // An uncertain network response permits only replay of exactly the saved bytes.\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[prepared.from,'pending'])));\n if (nonce > prepared.nonce) return result;\n const raw = await unsealSeed(prepared.signed,this.mnemonic);\n if (this.verifySigned(raw,prepared) !== prepared.hash || !same(await this.address(),prepared.from)) throw new Error('Recovery wallet mismatch');\n await this.current().sendTransaction(raw);\n return this.receipt(prepared.hash,review,prepared.from);\n }); }\n async receipt(hash: string, target: PaymentTarget & {amount:number}, expectedFrom?:string): Promise<PaymentExecution> {\n if (!/^0x[0-9a-fA-F]{64}$/.test(hash) || target.chainId !== this.config.chainId || !same(target.token ?? '',this.config.token) || target.decimals !== this.config.decimals) throw new Error('Invalid receipt target');\n await this.assertToken();\n const tx = await this.rpc<{from:string;to:string;input:string;value:string;nonce:string}|null>('eth_getTransactionByHash',[hash]);\n if (!tx) return {txid:hash,settled:false};\n if (!same(tx.to,this.config.token) || (expectedFrom && !same(tx.from,expectedFrom)) || BigInt(tx.value)!==0n || tx.input !== erc20.encodeFunctionData('transfer',[getAddress(target.address),BigInt(target.amount)])) throw new Error('Transaction is not the requested token transfer');\n const receipt = await this.rpc<{status:string;blockNumber:string;blockHash:string;logs:Array<{address:string;topics:string[];data:string}>}|null>('eth_getTransactionReceipt',[hash]);\n if (!receipt) return {txid:hash,settled:false,pending:true};\n const block = await this.rpc<{hash:string;timestamp:string}>('eth_getBlockByNumber',[receipt.blockNumber,false]);\n if (!block || block.hash !== receipt.blockHash || BigInt(block.timestamp)*1000n < BigInt((target.issuedAt ?? 0)-1000)) return {txid:hash,settled:false};\n const height = BigInt(await this.rpc<string>('eth_blockNumber'));\n if (height-BigInt(receipt.blockNumber)+1n < BigInt(CONFIRMATIONS)) return {txid:hash,settled:false,pending:true};\n if (BigInt(receipt.status)!==1n) return {txid:hash,settled:false,failed:true,error:'Transaction reverted. Tokens were not sent; gas was spent.'};\n const transfer = receipt.logs.some(log=>{\n if (!same(log.address,this.config.token)) return false;\n try {const event=erc20.parseLog(log);return event?.name==='Transfer' && same(event.args[0],tx.from) && same(event.args[1],target.address) && event.args[2]===BigInt(target.amount);} catch {return false;}\n });\n if (!transfer) throw new Error('Receipt has no matching token Transfer');\n return {txid:hash,settled:true};\n }\n async dispose() { await this.queue.catch(()=>{}); this.account=undefined;this.manager?.dispose();this.manager=undefined;this.mnemonic=''; }\n private serial<T>(work:()=>Promise<T>):Promise<T> { const operation=this.queue.then(work,work);this.queue=operation.catch(()=>{});return operation; }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usdt-Fj8CQO2z.js","names":[],"sources":["../../../browser/src/engine/paymentAdapters/usdt.ts"],"sourcesContent":["import { mnemonicToSeedSync } from '@scure/bip39';\nimport WalletManagerEvm, { type WalletAccountEvm } from '@tetherto/wdk-wallet-evm';\nimport { Interface, Transaction, getAddress, keccak256 } from 'ethers';\nimport { ETHEREUM_USDT, EVM_TEST_CHAINS, USDT_PUBLIC_RPC, SEPOLIA_TEST_USDT, SEPOLIA_TEST_USDT_FAUCET, TEST_USDT_FAUCET_AMOUNT, PaymentPreflightError, engineError, validatePaymentTarget, type PaymentAdapter, type PaymentExecution, type PaymentReview, type PaymentTarget } from '@ghostly/core';\nimport { sealSeed, unsealSeed, type EncryptedSeed } from './persistence';\nimport { networkReason, rpcHost } from './networkReason';\n\nexport interface UsdtConfig {\n network: 'ethereum' | 'sepolia' | 'evm-local';\n provider: string;\n chainId: 1 | 11155111 | 31337;\n token: string;\n decimals: number;\n codeHash: string;\n}\nexport interface UsdtPrepared {\n from: string; to: string; data: string; value: string; chainId: number; nonce: number;\n gasLimit: string; maxFeePerGas: string; maxPriorityFeePerGas: string;\n signed?: EncryptedSeed; hash?: string;\n}\nconst faucet = new Interface(['function mint(address token,address to,uint256 amount) returns (uint256)']);\nconst erc20 = new Interface(['function decimals() view returns(uint8)', 'function balanceOf(address) view returns(uint256)', 'function transfer(address,uint256) returns(bool)', 'event Transfer(address indexed from,address indexed to,uint256 value)']);\nconst same = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\nconst CONFIRMATIONS = 2;\n/** The JSON-RPC methods that only read: asked again once when they fail (see `UsdtAdapter.rpc`). */\nconst RETRIED_READS = new Set(['eth_chainId', 'eth_getCode', 'eth_call', 'eth_getBalance', 'eth_blockNumber', 'eth_getLogs', 'eth_getTransactionCount', 'eth_estimateGas', 'eth_getBlockByNumber', 'eth_maxPriorityFeePerGas', 'eth_gasPrice', 'eth_feeHistory', 'eth_getTransactionByHash', 'eth_getTransactionReceipt']);\nconst RETRY_AFTER_MS = 1000;\n/** Failures that would fail the same way again at once: not retried. */\nconst FINAL = new WeakSet<object>();\nconst timedOut = (error: unknown) => error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError');\n\n/**\n * The `provider` a request carries to the contact. Which RPC pays is the payer's own choice, so it names none of\n * this wallet's: a typed RPC URL may hold an API key (`/v3/<key>`), and every contact would read it. Older apps\n * require a URL here and pay only when it equals their own RPC, so it is the chain's public RPC (the default both\n * start with), and a local test chain's origin, without its path.\n */\nexport function wireProvider(config: Pick<UsdtConfig, 'network' | 'provider'>): string {\n return config.network === 'evm-local' ? new URL(config.provider).origin : USDT_PUBLIC_RPC[config.network];\n}\n\n/** WDK signs locally. Every network call uses the configured RPC, never a peer-supplied URL. */\nexport class UsdtAdapter implements PaymentAdapter<UsdtPrepared> {\n readonly method = 'usdt' as const;\n private manager?: WalletManagerEvm;\n private account?: WalletAccountEvm;\n private mnemonic = '';\n private nextId = 0;\n private queue: Promise<unknown> = Promise.resolve();\n private constructor(readonly config: UsdtConfig) {}\n\n static async inspect(config: Omit<UsdtConfig, 'decimals' | 'codeHash'>): Promise<UsdtConfig> {\n if (config.network === 'ethereum' ? config.chainId !== 1 || !same(config.token, ETHEREUM_USDT) : !(config.network in EVM_TEST_CHAINS) || config.chainId !== EVM_TEST_CHAINS[config.network]) throw new Error('Unsupported USDT network or contract');\n const token = getAddress(config.token);\n const url = new URL(config.provider);\n if (url.username || url.password || url.search || url.hash || (url.protocol !== 'https:' && !(url.protocol === 'http:' && ['localhost','127.0.0.1','[::1]'].includes(url.hostname)))) throw new Error('Use HTTPS or a loopback test RPC');\n const adapter = new UsdtAdapter({...config, token, decimals: 6, codeHash: ''});\n await adapter.chain();\n const code = await adapter.rpc<string>('eth_getCode', [token, 'latest']);\n if (code === '0x') throw new Error('No token contract exists on this chain');\n const result = await adapter.rpc<string>('eth_call', [{to: token, data: erc20.encodeFunctionData('decimals')}, 'latest']);\n const decimals = Number(erc20.decodeFunctionResult('decimals', result)[0]);\n if (!Number.isInteger(decimals) || decimals < 0 || decimals > 18 || (config.chainId === 1 && decimals !== 6)) throw new Error('Unexpected token decimals');\n return {...config, token, decimals, codeHash: keccak256(code)};\n }\n static async connect(config: UsdtConfig, mnemonic: string): Promise<UsdtAdapter> {\n const inspected = await UsdtAdapter.inspect(config);\n if (inspected.decimals !== config.decimals || inspected.codeHash !== config.codeHash) throw new Error('Token metadata changed; do not use this wallet configuration');\n const adapter = new UsdtAdapter(config);\n adapter.mnemonic = mnemonic;\n // Pass standard BIP-39 seed bytes: WDK's string helper assumes a Node Buffer global.\n const seed = mnemonicToSeedSync(mnemonic);\n try { adapter.manager = new WalletManagerEvm(seed, {provider: {request: ({method, params}) => adapter.rpc(method, params as unknown[] ?? [])}, chainId: config.chainId}); } finally { seed.fill(0); }\n adapter.account = await adapter.manager.getAccount(0);\n return adapter;\n }\n /**\n * A read that fails is asked again, once, a moment later: a public RPC drops a request now and then, and a chain that\n * just made a block can refuse a read of \"latest\" it no longer holds. Without it a network switch, a restore or New\n * gave up on the first such answer. Never a broadcast or anything else that writes, nor a request that did not answer\n * in time (the person would wait twice as long), nor one the server refused as such (4xx).\n */\n async rpc<T>(method: string, params: unknown[] = []): Promise<T> {\n try { return await this.ask<T>(method, params); }\n catch (error) {\n if (!RETRIED_READS.has(method) || FINAL.has(error as object)) throw error;\n await new Promise((resolve) => setTimeout(resolve, RETRY_AFTER_MS));\n return this.ask<T>(method, params);\n }\n }\n private async ask<T>(method: string, params: unknown[]): Promise<T> {\n let response: Response;\n // The browser's words for a request that got no answer (\"Fetch is aborted\") say nothing: the RPC's host does.\n try { response = await fetch(this.config.provider, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({jsonrpc:'2.0',id:++this.nextId,method,params}), signal:AbortSignal.timeout(15000)}); }\n catch (error) {\n const reason = networkReason(error, rpcHost(this.config.provider));\n const thrown = reason ? Object.assign(new Error(reason), {cause: error}) : error;\n if (timedOut(error) && thrown && typeof thrown === 'object') FINAL.add(thrown);\n throw thrown;\n }\n if (!response.ok) { const error = engineError('usdtRpcUnavailable'); if (response.status !== 429 && response.status < 500) FINAL.add(error); throw error; }\n const result = await response.json();\n if (result.error || !Object.prototype.hasOwnProperty.call(result, 'result')) throw new Error('USDT RPC rejected the operation');\n return result.result as T;\n }\n private async chain() {\n if (BigInt(await this.rpc<string>('eth_chainId')) !== BigInt(this.config.chainId)) throw new Error('RPC chain does not match this wallet');\n }\n private async assertToken() {\n await this.chain();\n const code = await this.rpc<string>('eth_getCode', [this.config.token, 'latest']);\n if (code === '0x' || keccak256(code) !== this.config.codeHash) throw new Error('Token contract changed');\n }\n /**\n * Sepolia only: asks Aave's public faucet for test USDT, to this wallet, paid with its own test ETH.\n * Everything is fixed here (chain, contract, token, amount, recipient): nothing comes from outside.\n */\n mintTestTokens(): Promise<string> { return this.serial(async () => {\n if (this.config.chainId !== EVM_TEST_CHAINS.sepolia || !same(this.config.token, SEPOLIA_TEST_USDT)) throw new Error('Test USDT comes from a faucet on Sepolia only');\n await this.chain();\n const account = this.current(), from = await account.getAddress();\n const data = faucet.encodeFunctionData('mint', [SEPOLIA_TEST_USDT, from, BigInt(TEST_USDT_FAUCET_AMOUNT)]);\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount', [from, 'pending'])));\n const estimate = BigInt(await this.rpc<string>('eth_estimateGas', [{ from, to: SEPOLIA_TEST_USDT_FAUCET, data, value: '0x0' }]));\n const block = await this.rpc<{ baseFeePerGas?: string }>('eth_getBlockByNumber', ['latest', false]);\n if (!block.baseFeePerGas) throw new Error('This wallet requires an EIP-1559 chain');\n const priority = BigInt(await this.rpc<string>('eth_maxPriorityFeePerGas'));\n const maxFeePerGas = BigInt(block.baseFeePerGas) * 2n + priority, gasLimit = (estimate * 120n + 99n) / 100n;\n if (BigInt((await this.balances()).gasBalance) < gasLimit * maxFeePerGas) throw engineError('usdtNeedsSepoliaGas');\n const raw = await account.signTransaction({ type: 2, to: SEPOLIA_TEST_USDT_FAUCET, data, value: 0n, chainId: this.config.chainId, nonce, gasLimit, maxFeePerGas, maxPriorityFeePerGas: priority });\n await account.sendTransaction(raw);\n return Transaction.from(raw).hash!;\n }); }\n private current(): WalletAccountEvm { if (!this.account) throw new Error('Unlock the USDT wallet first'); return this.account; }\n address() { return this.current().getAddress(); }\n async balances() {\n await this.assertToken();\n const address = await this.address();\n const [token, gas] = await Promise.all([this.rpc<string>('eth_call',[{to:this.config.token,data:erc20.encodeFunctionData('balanceOf',[address])},'latest']),this.rpc<string>('eth_getBalance',[address,'pending'])]);\n return {balance:erc20.decodeFunctionResult('balanceOf',token)[0].toString(),gasBalance:BigInt(gas).toString()};\n }\n async target(): Promise<PaymentTarget> {\n const now = Date.now();\n return {method:'usdt',network:this.config.network,provider:wireProvider(this.config),asset:this.config.chainId === 1 ? 'USDT':'TEST-USDT',unit:'token-base',address:await this.address(),chainId:this.config.chainId,token:this.config.token,decimals:this.config.decimals,issuedAt:now,expiresAt:now+15*60*1000};\n }\n /** The request is for this wallet's token on its chain. Its `provider` is not compared: this wallet's own RPC pays. */\n private matches(target: PaymentTarget) {\n validatePaymentTarget(target);\n if (target.method !== 'usdt' || target.network !== this.config.network || target.chainId !== this.config.chainId || !same(target.token!,this.config.token) || target.decimals !== this.config.decimals) throw new Error('Request does not match the configured token and network');\n }\n prepare(target: PaymentTarget, amount: number, feeCap: number) { return this.serial(async () => {\n this.matches(target);\n await this.assertToken();\n const from = await this.address(), to = this.config.token;\n if (same(target.address, from) || same(target.address, to)) throw new Error('Choose a different recipient address');\n const {balance,gasBalance} = await this.balances();\n if (BigInt(balance) < BigInt(amount)) throw engineError('usdtNotEnoughTokens');\n const data = erc20.encodeFunctionData('transfer', [getAddress(target.address),BigInt(amount)]);\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[from,'pending'])));\n if (!Number.isSafeInteger(nonce)) throw new Error('Invalid account nonce');\n const estimate = BigInt(await this.rpc<string>('eth_estimateGas',[{from,to,data,value:'0x0'}]));\n const block = await this.rpc<{baseFeePerGas?:string}>('eth_getBlockByNumber',['latest',false]);\n if (!block.baseFeePerGas) throw new Error('This wallet requires an EIP-1559 chain');\n const priority = BigInt(await this.rpc<string>('eth_maxPriorityFeePerGas'));\n const maxFee = BigInt(block.baseFeePerGas)*2n + priority;\n const gasLimit = (estimate*120n+99n)/100n;\n const maximum = gasLimit*maxFee;\n if (maximum > BigInt(feeCap) || maximum > BigInt(Number.MAX_SAFE_INTEGER)) throw engineError('usdtGasAboveLimit');\n if (BigInt(gasBalance) < maximum) throw engineError('usdtNotEnoughGas');\n const prepared:UsdtPrepared = {from,to,data,value:'0',chainId:this.config.chainId,nonce,gasLimit:gasLimit.toString(),maxFeePerGas:maxFee.toString(),maxPriorityFeePerGas:priority.toString()};\n return {fee:Number(maximum),prepared,evm:{from,nonce,gasLimit:prepared.gasLimit,maxFeePerGas:prepared.maxFeePerGas,maxPriorityFeePerGas:prepared.maxPriorityFeePerGas,confirmations:CONFIRMATIONS}};\n }); }\n private verifyPrepared(review: PaymentReview, tx: UsdtPrepared) {\n if (tx.chainId !== this.config.chainId || !same(tx.to,this.config.token) || tx.value !== '0' || tx.data !== erc20.encodeFunctionData('transfer',[getAddress(review.address),BigInt(review.amount)]) || BigInt(tx.gasLimit)*BigInt(tx.maxFeePerGas) !== BigInt(review.fee) || review.fee > review.feeCap || tx.nonce !== review.evm?.nonce || !same(tx.from,review.evm?.from ?? '')) throw new Error('Transaction no longer matches the approved review');\n }\n private verifySigned(raw: string, saved: UsdtPrepared) {\n const tx = Transaction.from(raw);\n if (!tx.hash || !tx.from || !same(tx.from,saved.from) || tx.chainId !== BigInt(saved.chainId) || !tx.to || !same(tx.to,saved.to) || tx.data !== saved.data || tx.value !== 0n || tx.nonce !== saved.nonce || tx.gasLimit !== BigInt(saved.gasLimit) || tx.maxFeePerGas !== BigInt(saved.maxFeePerGas) || tx.maxPriorityFeePerGas !== BigInt(saved.maxPriorityFeePerGas)) throw new Error('Signature does not match the approved transaction');\n return tx.hash;\n }\n execute(review: PaymentReview, prepared: UsdtPrepared, persist?:()=>Promise<void>) { return this.serial(async () => {\n let account:WalletAccountEvm;\n try {\n this.matches(review); this.verifyPrepared(review,prepared);\n await this.assertToken(); account=this.current();\n if (!same(await account.getAddress(),prepared.from)) throw new Error('Wrong wallet');\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[prepared.from,'pending'])));\n if (nonce !== prepared.nonce) throw new Error('Account nonce changed. Create a new review');\n const balances = await this.balances();\n if (BigInt(balances.balance)<BigInt(review.amount) || BigInt(balances.gasBalance)<BigInt(review.fee)) throw new Error('Token or gas balance changed. Create a new review');\n if (!persist) throw new Error('Durable payment journal required');\n } catch (error) { throw new PaymentPreflightError(error instanceof Error ? error.message : 'Could not validate payment'); }\n const raw = await account.signTransaction({type:2,to:prepared.to,data:prepared.data,value:0n,chainId:prepared.chainId,nonce:prepared.nonce,gasLimit:BigInt(prepared.gasLimit),maxFeePerGas:BigInt(prepared.maxFeePerGas),maxPriorityFeePerGas:BigInt(prepared.maxPriorityFeePerGas)});\n prepared.hash = this.verifySigned(raw,prepared);\n prepared.signed = await sealSeed(raw,this.mnemonic);\n await persist!(); // Nothing may broadcast before the encrypted bytes are durable.\n await account.sendTransaction(raw);\n return this.receipt(prepared.hash,review,prepared.from);\n }); }\n reconcile(review: PaymentReview, prepared: UsdtPrepared) { return this.serial(async () => {\n await this.assertToken(); this.verifyPrepared(review,prepared);\n if (!prepared.signed || !prepared.hash) return {settled:false,failed:true,error:'No signed transaction was submitted. Create a new review.'};\n const result = await this.receipt(prepared.hash,review,prepared.from);\n if (result.settled || result.failed || result.pending) return result;\n // An uncertain network response permits only replay of exactly the saved bytes.\n const nonce = Number(BigInt(await this.rpc<string>('eth_getTransactionCount',[prepared.from,'pending'])));\n if (nonce > prepared.nonce) return result;\n const raw = await unsealSeed(prepared.signed,this.mnemonic);\n if (this.verifySigned(raw,prepared) !== prepared.hash || !same(await this.address(),prepared.from)) throw new Error('Recovery wallet mismatch');\n await this.current().sendTransaction(raw);\n return this.receipt(prepared.hash,review,prepared.from);\n }); }\n async receipt(hash: string, target: PaymentTarget & {amount:number}, expectedFrom?:string): Promise<PaymentExecution> {\n if (!/^0x[0-9a-fA-F]{64}$/.test(hash) || target.chainId !== this.config.chainId || !same(target.token ?? '',this.config.token) || target.decimals !== this.config.decimals) throw new Error('Invalid receipt target');\n await this.assertToken();\n const tx = await this.rpc<{from:string;to:string;input:string;value:string;nonce:string}|null>('eth_getTransactionByHash',[hash]);\n if (!tx) return {txid:hash,settled:false};\n if (!same(tx.to,this.config.token) || (expectedFrom && !same(tx.from,expectedFrom)) || BigInt(tx.value)!==0n || tx.input !== erc20.encodeFunctionData('transfer',[getAddress(target.address),BigInt(target.amount)])) throw new Error('Transaction is not the requested token transfer');\n const receipt = await this.rpc<{status:string;blockNumber:string;blockHash:string;logs:Array<{address:string;topics:string[];data:string}>}|null>('eth_getTransactionReceipt',[hash]);\n if (!receipt) return {txid:hash,settled:false,pending:true};\n const block = await this.rpc<{hash:string;timestamp:string}>('eth_getBlockByNumber',[receipt.blockNumber,false]);\n if (!block || block.hash !== receipt.blockHash || BigInt(block.timestamp)*1000n < BigInt((target.issuedAt ?? 0)-1000)) return {txid:hash,settled:false};\n const height = BigInt(await this.rpc<string>('eth_blockNumber'));\n if (height-BigInt(receipt.blockNumber)+1n < BigInt(CONFIRMATIONS)) return {txid:hash,settled:false,pending:true};\n if (BigInt(receipt.status)!==1n) return {txid:hash,settled:false,failed:true,error:'Transaction reverted. Tokens were not sent; gas was spent.'};\n const transfer = receipt.logs.some(log=>{\n if (!same(log.address,this.config.token)) return false;\n try {const event=erc20.parseLog(log);return event?.name==='Transfer' && same(event.args[0],tx.from) && same(event.args[1],target.address) && event.args[2]===BigInt(target.amount);} catch {return false;}\n });\n if (!transfer) throw new Error('Receipt has no matching token Transfer');\n return {txid:hash,settled:true};\n }\n async dispose() { await this.queue.catch(()=>{}); this.account=undefined;this.manager?.dispose();this.manager=undefined;this.mnemonic=''; }\n private serial<T>(work:()=>Promise<T>):Promise<T> { const operation=this.queue.then(work,work);this.queue=operation.catch(()=>{});return operation; }\n}\n"],"mappings":";;;;;;AAoBA,IAAM,SAAS,IAAI,UAAU,CAAC,0EAA0E,CAAC;AACzG,IAAM,QAAQ,IAAI,UAAU;CAAC;CAA2C;CAAqD;CAAoD;AAAuE,CAAC;AACzP,IAAM,QAAQ,GAAW,MAAc,EAAE,YAAY,MAAM,EAAE,YAAY;AACzE,IAAM,gBAAgB;;AAEtB,IAAM,gCAAgB,IAAI,IAAI;CAAC;CAAe;CAAe;CAAY;CAAkB;CAAmB;CAAe;CAA2B;CAAmB;CAAwB;CAA4B;CAAgB;CAAkB;CAA4B;AAA2B,CAAC;AACzT,IAAM,iBAAiB;;AAEvB,IAAM,wBAAQ,IAAI,QAAgB;AAClC,IAAM,YAAY,UAAmB,iBAAiB,UAAU,MAAM,SAAS,gBAAgB,MAAM,SAAS;;;;;;;AAQ9G,SAAgB,aAAa,QAA0D;CACrF,OAAO,OAAO,YAAY,cAAc,IAAI,IAAI,OAAO,QAAQ,CAAC,CAAC,SAAS,gBAAgB,OAAO;AACnG;;AAGA,IAAa,cAAb,MAAa,YAAoD;CAOlC;CAN7B,SAAkB;CAClB;CACA;CACA,WAAmB;CACnB,SAAiB;CACjB,QAAkC,QAAQ,QAAQ;CAClD,YAAoB,QAA6B;EAApB,KAAA,SAAA;CAAqB;CAElD,aAAa,QAAQ,QAAwE;EAC3F,IAAI,OAAO,YAAY,aAAa,OAAO,YAAY,KAAK,CAAC,KAAK,OAAO,OAAA,4CAAoB,IAAI,EAAE,OAAO,WAAW,oBAAoB,OAAO,YAAY,gBAAgB,OAAO,UAAU,MAAM,IAAI,MAAM,sCAAsC;EACnP,MAAM,QAAQ,WAAW,OAAO,KAAK;EACrC,MAAM,MAAM,IAAI,IAAI,OAAO,QAAQ;EACnC,IAAI,IAAI,YAAY,IAAI,YAAY,IAAI,UAAU,IAAI,QAAS,IAAI,aAAa,YAAY,EAAE,IAAI,aAAa,WAAW;GAAC;GAAY;GAAY;EAAO,CAAC,CAAC,SAAS,IAAI,QAAQ,IAAK,MAAM,IAAI,MAAM,kCAAkC;EACxO,MAAM,UAAU,IAAI,YAAY;GAAC,GAAG;GAAQ;GAAO,UAAU;GAAG,UAAU;EAAE,CAAC;EAC7E,MAAM,QAAQ,MAAM;EACpB,MAAM,OAAO,MAAM,QAAQ,IAAY,eAAe,CAAC,OAAO,QAAQ,CAAC;EACvE,IAAI,SAAS,MAAM,MAAM,IAAI,MAAM,wCAAwC;EAC3E,MAAM,SAAS,MAAM,QAAQ,IAAY,YAAY,CAAC;GAAC,IAAI;GAAO,MAAM,MAAM,mBAAmB,UAAU;EAAC,GAAG,QAAQ,CAAC;EACxH,MAAM,WAAW,OAAO,MAAM,qBAAqB,YAAY,MAAM,CAAC,CAAC,EAAE;EACzE,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,KAAK,WAAW,MAAO,OAAO,YAAY,KAAK,aAAa,GAAI,MAAM,IAAI,MAAM,2BAA2B;EACzJ,OAAO;GAAC,GAAG;GAAQ;GAAO;GAAU,UAAU,UAAU,IAAI;EAAC;CAC/D;CACA,aAAa,QAAQ,QAAoB,UAAwC;EAC/E,MAAM,YAAY,MAAM,YAAY,QAAQ,MAAM;EAClD,IAAI,UAAU,aAAa,OAAO,YAAY,UAAU,aAAa,OAAO,UAAU,MAAM,IAAI,MAAM,8DAA8D;EACpK,MAAM,UAAU,IAAI,YAAY,MAAM;EACtC,QAAQ,WAAW;EAEnB,MAAM,OAAO,mBAAmB,QAAQ;EACxC,IAAI;GAAE,QAAQ,UAAU,IAAI,iBAAiB,MAAM;IAAC,UAAU,EAAC,UAAU,EAAC,QAAQ,aAAY,QAAQ,IAAI,QAAQ,UAAuB,CAAC,CAAC,EAAC;IAAG,SAAS,OAAO;GAAO,CAAC;EAAG,UAAU;GAAE,KAAK,KAAK,CAAC;EAAG;EACpM,QAAQ,UAAU,MAAM,QAAQ,QAAQ,WAAW,CAAC;EACpD,OAAO;CACT;;;;;;;CAOA,MAAM,IAAO,QAAgB,SAAoB,CAAC,GAAe;EAC/D,IAAI;GAAE,OAAO,MAAM,KAAK,IAAO,QAAQ,MAAM;EAAG,SACzC,OAAO;GACZ,IAAI,CAAC,cAAc,IAAI,MAAM,KAAK,MAAM,IAAI,KAAe,GAAG,MAAM;GACpE,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,cAAc,CAAC;GAClE,OAAO,KAAK,IAAO,QAAQ,MAAM;EACnC;CACF;CACA,MAAc,IAAO,QAAgB,QAA+B;EAClE,IAAI;EAEJ,IAAI;GAAE,WAAW,MAAM,MAAM,KAAK,OAAO,UAAU;IAAC,QAAO;IAAQ,SAAQ,EAAC,gBAAe,mBAAkB;IAAG,MAAK,KAAK,UAAU;KAAC,SAAQ;KAAM,IAAG,EAAE,KAAK;KAAO;KAAO;IAAM,CAAC;IAAG,QAAO,YAAY,QAAQ,IAAK;GAAC,CAAC;EAAG,SACnN,OAAO;GACZ,MAAM,SAAS,cAAc,OAAO,QAAQ,KAAK,OAAO,QAAQ,CAAC;GACjE,MAAM,SAAS,SAAS,OAAO,OAAO,IAAI,MAAM,MAAM,GAAG,EAAC,OAAO,MAAK,CAAC,IAAI;GAC3E,IAAI,SAAS,KAAK,KAAK,UAAU,OAAO,WAAW,UAAU,MAAM,IAAI,MAAM;GAC7E,MAAM;EACR;EACA,IAAI,CAAC,SAAS,IAAI;GAAE,MAAM,QAAQ,YAAY,oBAAoB;GAAG,IAAI,SAAS,WAAW,OAAO,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK;GAAG,MAAM;EAAO;EAC1J,MAAM,SAAS,MAAM,SAAS,KAAK;EACnC,IAAI,OAAO,SAAS,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,QAAQ,GAAG,MAAM,IAAI,MAAM,iCAAiC;EAC9H,OAAO,OAAO;CAChB;CACA,MAAc,QAAQ;EACpB,IAAI,OAAO,MAAM,KAAK,IAAY,aAAa,CAAC,MAAM,OAAO,KAAK,OAAO,OAAO,GAAG,MAAM,IAAI,MAAM,sCAAsC;CAC3I;CACA,MAAc,cAAc;EAC1B,MAAM,KAAK,MAAM;EACjB,MAAM,OAAO,MAAM,KAAK,IAAY,eAAe,CAAC,KAAK,OAAO,OAAO,QAAQ,CAAC;EAChF,IAAI,SAAS,QAAQ,UAAU,IAAI,MAAM,KAAK,OAAO,UAAU,MAAM,IAAI,MAAM,wBAAwB;CACzG;;;;;CAKA,iBAAkC;EAAE,OAAO,KAAK,OAAO,YAAY;GACjE,IAAI,KAAK,OAAO,YAAY,gBAAgB,WAAW,CAAC,KAAK,KAAK,OAAO,OAAA,4CAAwB,GAAG,MAAM,IAAI,MAAM,+CAA+C;GACnK,MAAM,KAAK,MAAM;GACjB,MAAM,UAAU,KAAK,QAAQ,GAAG,OAAO,MAAM,QAAQ,WAAW;GAChE,MAAM,OAAO,OAAO,mBAAmB,QAAQ;IAAC;IAAmB;IAAM,OAAO,uBAAuB;GAAC,CAAC;GACzG,MAAM,QAAQ,OAAO,OAAO,MAAM,KAAK,IAAY,2BAA2B,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC;GACjG,MAAM,WAAW,OAAO,MAAM,KAAK,IAAY,mBAAmB,CAAC;IAAE;IAAM,IAAI;IAA0B;IAAM,OAAO;GAAM,CAAC,CAAC,CAAC;GAC/H,MAAM,QAAQ,MAAM,KAAK,IAAgC,wBAAwB,CAAC,UAAU,KAAK,CAAC;GAClG,IAAI,CAAC,MAAM,eAAe,MAAM,IAAI,MAAM,wCAAwC;GAClF,MAAM,WAAW,OAAO,MAAM,KAAK,IAAY,0BAA0B,CAAC;GAC1E,MAAM,eAAe,OAAO,MAAM,aAAa,IAAI,KAAK,UAAU,YAAY,WAAW,OAAO,OAAO;GACvG,IAAI,QAAQ,MAAM,KAAK,SAAS,EAAA,CAAG,UAAU,IAAI,WAAW,cAAc,MAAM,YAAY,qBAAqB;GACjH,MAAM,MAAM,MAAM,QAAQ,gBAAgB;IAAE,MAAM;IAAG,IAAI;IAA0B;IAAM,OAAO;IAAI,SAAS,KAAK,OAAO;IAAS;IAAO;IAAU;IAAc,sBAAsB;GAAS,CAAC;GACjM,MAAM,QAAQ,gBAAgB,GAAG;GACjC,OAAO,YAAY,KAAK,GAAG,CAAC,CAAC;EAC/B,CAAC;CAAG;CACJ,UAAoC;EAAE,IAAI,CAAC,KAAK,SAAS,MAAM,IAAI,MAAM,8BAA8B;EAAG,OAAO,KAAK;CAAS;CAC/H,UAAU;EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,WAAW;CAAG;CAChD,MAAM,WAAW;EACf,MAAM,KAAK,YAAY;EACvB,MAAM,UAAU,MAAM,KAAK,QAAQ;EACnC,MAAM,CAAC,OAAO,OAAO,MAAM,QAAQ,IAAI,CAAC,KAAK,IAAY,YAAW,CAAC;GAAC,IAAG,KAAK,OAAO;GAAM,MAAK,MAAM,mBAAmB,aAAY,CAAC,OAAO,CAAC;EAAC,GAAE,QAAQ,CAAC,GAAE,KAAK,IAAY,kBAAiB,CAAC,SAAQ,SAAS,CAAC,CAAC,CAAC;EACnN,OAAO;GAAC,SAAQ,MAAM,qBAAqB,aAAY,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS;GAAE,YAAW,OAAO,GAAG,CAAC,CAAC,SAAS;EAAC;CAC/G;CACA,MAAM,SAAiC;EACrC,MAAM,MAAM,KAAK,IAAI;EACrB,OAAO;GAAC,QAAO;GAAO,SAAQ,KAAK,OAAO;GAAQ,UAAS,aAAa,KAAK,MAAM;GAAE,OAAM,KAAK,OAAO,YAAY,IAAI,SAAO;GAAY,MAAK;GAAa,SAAQ,MAAM,KAAK,QAAQ;GAAE,SAAQ,KAAK,OAAO;GAAQ,OAAM,KAAK,OAAO;GAAM,UAAS,KAAK,OAAO;GAAS,UAAS;GAAI,WAAU,MAAI;EAAU;CAClT;;CAEA,QAAgB,QAAuB;EACrC,sBAAsB,MAAM;EAC5B,IAAI,OAAO,WAAW,UAAU,OAAO,YAAY,KAAK,OAAO,WAAW,OAAO,YAAY,KAAK,OAAO,WAAW,CAAC,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK,KAAK,OAAO,aAAa,KAAK,OAAO,UAAU,MAAM,IAAI,MAAM,yDAAyD;CACnR;CACA,QAAQ,QAAuB,QAAgB,QAAgB;EAAE,OAAO,KAAK,OAAO,YAAY;GAC9F,KAAK,QAAQ,MAAM;GACnB,MAAM,KAAK,YAAY;GACvB,MAAM,OAAO,MAAM,KAAK,QAAQ,GAAG,KAAK,KAAK,OAAO;GACpD,IAAI,KAAK,OAAO,SAAS,IAAI,KAAK,KAAK,OAAO,SAAS,EAAE,GAAG,MAAM,IAAI,MAAM,sCAAsC;GAClH,MAAM,EAAC,SAAQ,eAAc,MAAM,KAAK,SAAS;GACjD,IAAI,OAAO,OAAO,IAAI,OAAO,MAAM,GAAG,MAAM,YAAY,qBAAqB;GAC7E,MAAM,OAAO,MAAM,mBAAmB,YAAY,CAAC,WAAW,OAAO,OAAO,GAAE,OAAO,MAAM,CAAC,CAAC;GAC7F,MAAM,QAAQ,OAAO,OAAO,MAAM,KAAK,IAAY,2BAA0B,CAAC,MAAK,SAAS,CAAC,CAAC,CAAC;GAC/F,IAAI,CAAC,OAAO,cAAc,KAAK,GAAG,MAAM,IAAI,MAAM,uBAAuB;GACzE,MAAM,WAAW,OAAO,MAAM,KAAK,IAAY,mBAAkB,CAAC;IAAC;IAAK;IAAG;IAAK,OAAM;GAAK,CAAC,CAAC,CAAC;GAC9F,MAAM,QAAQ,MAAM,KAAK,IAA6B,wBAAuB,CAAC,UAAS,KAAK,CAAC;GAC7F,IAAI,CAAC,MAAM,eAAe,MAAM,IAAI,MAAM,wCAAwC;GAClF,MAAM,WAAW,OAAO,MAAM,KAAK,IAAY,0BAA0B,CAAC;GAC1E,MAAM,SAAS,OAAO,MAAM,aAAa,IAAE,KAAK;GAChD,MAAM,YAAY,WAAS,OAAK,OAAK;GACrC,MAAM,UAAU,WAAS;GACzB,IAAI,UAAU,OAAO,MAAM,KAAK,UAAU,OAAO,OAAO,gBAAgB,GAAG,MAAM,YAAY,mBAAmB;GAChH,IAAI,OAAO,UAAU,IAAI,SAAS,MAAM,YAAY,kBAAkB;GACtE,MAAM,WAAwB;IAAC;IAAK;IAAG;IAAK,OAAM;IAAI,SAAQ,KAAK,OAAO;IAAQ;IAAM,UAAS,SAAS,SAAS;IAAE,cAAa,OAAO,SAAS;IAAE,sBAAqB,SAAS,SAAS;GAAC;GAC5L,OAAO;IAAC,KAAI,OAAO,OAAO;IAAE;IAAS,KAAI;KAAC;KAAK;KAAM,UAAS,SAAS;KAAS,cAAa,SAAS;KAAa,sBAAqB,SAAS;KAAqB,eAAc;IAAa;GAAC;EACpM,CAAC;CAAG;CACJ,eAAuB,QAAuB,IAAkB;EAC9D,IAAI,GAAG,YAAY,KAAK,OAAO,WAAW,CAAC,KAAK,GAAG,IAAG,KAAK,OAAO,KAAK,KAAK,GAAG,UAAU,OAAO,GAAG,SAAS,MAAM,mBAAmB,YAAW,CAAC,WAAW,OAAO,OAAO,GAAE,OAAO,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,GAAG,QAAQ,IAAE,OAAO,GAAG,YAAY,MAAM,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM,OAAO,UAAU,GAAG,UAAU,OAAO,KAAK,SAAS,CAAC,KAAK,GAAG,MAAK,OAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,IAAI,MAAM,mDAAmD;CACzb;CACA,aAAqB,KAAa,OAAqB;EACrD,MAAM,KAAK,YAAY,KAAK,GAAG;EAC/B,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAG,MAAK,MAAM,IAAI,KAAK,GAAG,YAAY,OAAO,MAAM,OAAO,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,IAAG,MAAM,EAAE,KAAK,GAAG,SAAS,MAAM,QAAQ,GAAG,UAAU,MAAM,GAAG,UAAU,MAAM,SAAS,GAAG,aAAa,OAAO,MAAM,QAAQ,KAAK,GAAG,iBAAiB,OAAO,MAAM,YAAY,KAAK,GAAG,yBAAyB,OAAO,MAAM,oBAAoB,GAAG,MAAM,IAAI,MAAM,mDAAmD;EAC5a,OAAO,GAAG;CACZ;CACA,QAAQ,QAAuB,UAAwB,SAA4B;EAAE,OAAO,KAAK,OAAO,YAAY;GAClH,IAAI;GACJ,IAAI;IACF,KAAK,QAAQ,MAAM;IAAG,KAAK,eAAe,QAAO,QAAQ;IACzD,MAAM,KAAK,YAAY;IAAG,UAAQ,KAAK,QAAQ;IAC/C,IAAI,CAAC,KAAK,MAAM,QAAQ,WAAW,GAAE,SAAS,IAAI,GAAG,MAAM,IAAI,MAAM,cAAc;IAEnF,IADc,OAAO,OAAO,MAAM,KAAK,IAAY,2BAA0B,CAAC,SAAS,MAAK,SAAS,CAAC,CAAC,CACnG,MAAU,SAAS,OAAO,MAAM,IAAI,MAAM,4CAA4C;IAC1F,MAAM,WAAW,MAAM,KAAK,SAAS;IACrC,IAAI,OAAO,SAAS,OAAO,IAAE,OAAO,OAAO,MAAM,KAAK,OAAO,SAAS,UAAU,IAAE,OAAO,OAAO,GAAG,GAAG,MAAM,IAAI,MAAM,mDAAmD;IACzK,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,kCAAkC;GAClE,SAAS,OAAO;IAAE,MAAM,IAAI,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,4BAA4B;GAAG;GAC1H,MAAM,MAAM,MAAM,QAAQ,gBAAgB;IAAC,MAAK;IAAE,IAAG,SAAS;IAAG,MAAK,SAAS;IAAK,OAAM;IAAG,SAAQ,SAAS;IAAQ,OAAM,SAAS;IAAM,UAAS,OAAO,SAAS,QAAQ;IAAE,cAAa,OAAO,SAAS,YAAY;IAAE,sBAAqB,OAAO,SAAS,oBAAoB;GAAC,CAAC;GACpR,SAAS,OAAO,KAAK,aAAa,KAAI,QAAQ;GAC9C,SAAS,SAAS,MAAM,SAAS,KAAI,KAAK,QAAQ;GAClD,MAAM,QAAS;GACf,MAAM,QAAQ,gBAAgB,GAAG;GACjC,OAAO,KAAK,QAAQ,SAAS,MAAK,QAAO,SAAS,IAAI;EACxD,CAAC;CAAG;CACJ,UAAU,QAAuB,UAAwB;EAAE,OAAO,KAAK,OAAO,YAAY;GACxF,MAAM,KAAK,YAAY;GAAG,KAAK,eAAe,QAAO,QAAQ;GAC7D,IAAI,CAAC,SAAS,UAAU,CAAC,SAAS,MAAM,OAAO;IAAC,SAAQ;IAAM,QAAO;IAAK,OAAM;GAA2D;GAC3I,MAAM,SAAS,MAAM,KAAK,QAAQ,SAAS,MAAK,QAAO,SAAS,IAAI;GACpE,IAAI,OAAO,WAAW,OAAO,UAAU,OAAO,SAAS,OAAO;GAG9D,IADc,OAAO,OAAO,MAAM,KAAK,IAAY,2BAA0B,CAAC,SAAS,MAAK,SAAS,CAAC,CAAC,CACnG,IAAQ,SAAS,OAAO,OAAO;GACnC,MAAM,MAAM,MAAM,WAAW,SAAS,QAAO,KAAK,QAAQ;GAC1D,IAAI,KAAK,aAAa,KAAI,QAAQ,MAAM,SAAS,QAAQ,CAAC,KAAK,MAAM,KAAK,QAAQ,GAAE,SAAS,IAAI,GAAG,MAAM,IAAI,MAAM,0BAA0B;GAC9I,MAAM,KAAK,QAAQ,CAAC,CAAC,gBAAgB,GAAG;GACxC,OAAO,KAAK,QAAQ,SAAS,MAAK,QAAO,SAAS,IAAI;EACxD,CAAC;CAAG;CACJ,MAAM,QAAQ,MAAc,QAAyC,cAAiD;EACpH,IAAI,CAAC,sBAAsB,KAAK,IAAI,KAAK,OAAO,YAAY,KAAK,OAAO,WAAW,CAAC,KAAK,OAAO,SAAS,IAAG,KAAK,OAAO,KAAK,KAAK,OAAO,aAAa,KAAK,OAAO,UAAU,MAAM,IAAI,MAAM,wBAAwB;EACpN,MAAM,KAAK,YAAY;EACvB,MAAM,KAAK,MAAM,KAAK,IAAyE,4BAA2B,CAAC,IAAI,CAAC;EAChI,IAAI,CAAC,IAAI,OAAO;GAAC,MAAK;GAAK,SAAQ;EAAK;EACxC,IAAI,CAAC,KAAK,GAAG,IAAG,KAAK,OAAO,KAAK,KAAM,gBAAgB,CAAC,KAAK,GAAG,MAAK,YAAY,KAAM,OAAO,GAAG,KAAK,MAAI,MAAM,GAAG,UAAU,MAAM,mBAAmB,YAAW,CAAC,WAAW,OAAO,OAAO,GAAE,OAAO,OAAO,MAAM,CAAC,CAAC,GAAG,MAAM,IAAI,MAAM,iDAAiD;EACvR,MAAM,UAAU,MAAM,KAAK,IAAuH,6BAA4B,CAAC,IAAI,CAAC;EACpL,IAAI,CAAC,SAAS,OAAO;GAAC,MAAK;GAAK,SAAQ;GAAM,SAAQ;EAAI;EAC1D,MAAM,QAAQ,MAAM,KAAK,IAAoC,wBAAuB,CAAC,QAAQ,aAAY,KAAK,CAAC;EAC/G,IAAI,CAAC,SAAS,MAAM,SAAS,QAAQ,aAAa,OAAO,MAAM,SAAS,IAAE,QAAQ,QAAQ,OAAO,YAAY,KAAG,GAAI,GAAG,OAAO;GAAC,MAAK;GAAK,SAAQ;EAAK;EAEtJ,IADe,OAAO,MAAM,KAAK,IAAY,iBAAiB,CAC1D,IAAO,OAAO,QAAQ,WAAW,IAAE,KAAK,OAAO,aAAa,GAAG,OAAO;GAAC,MAAK;GAAK,SAAQ;GAAM,SAAQ;EAAI;EAC/G,IAAI,OAAO,QAAQ,MAAM,MAAI,IAAI,OAAO;GAAC,MAAK;GAAK,SAAQ;GAAM,QAAO;GAAK,OAAM;EAA4D;EAK/I,IAAI,CAJa,QAAQ,KAAK,MAAK,QAAK;GACtC,IAAI,CAAC,KAAK,IAAI,SAAQ,KAAK,OAAO,KAAK,GAAG,OAAO;GACjD,IAAI;IAAC,MAAM,QAAM,MAAM,SAAS,GAAG;IAAE,OAAO,OAAO,SAAO,cAAc,KAAK,MAAM,KAAK,IAAG,GAAG,IAAI,KAAK,KAAK,MAAM,KAAK,IAAG,OAAO,OAAO,KAAK,MAAM,KAAK,OAAK,OAAO,OAAO,MAAM;GAAE,QAAQ;IAAC,OAAO;GAAM;EAC3M,CACK,GAAU,MAAM,IAAI,MAAM,wCAAwC;EACvE,OAAO;GAAC,MAAK;GAAK,SAAQ;EAAI;CAChC;CACA,MAAM,UAAU;EAAE,MAAM,KAAK,MAAM,YAAU,CAAC,CAAC;EAAG,KAAK,UAAQ,KAAA;EAAU,KAAK,SAAS,QAAQ;EAAE,KAAK,UAAQ,KAAA;EAAU,KAAK,WAAS;CAAI;CAC1I,OAAkB,MAAgC;EAAE,MAAM,YAAU,KAAK,MAAM,KAAK,MAAK,IAAI;EAAE,KAAK,QAAM,UAAU,YAAU,CAAC,CAAC;EAAE,OAAO;CAAW;AACtJ"}
|
package/dist/ghostly.mjs
CHANGED
|
@@ -24,7 +24,7 @@ function quietWebStorage(scope = globalThis, execArgv = process.execArgv, nodeOp
|
|
|
24
24
|
//#region src/bin.ts
|
|
25
25
|
quietWebStorage();
|
|
26
26
|
enableCompileCache();
|
|
27
|
-
var { run } = await import("./assets/main-
|
|
27
|
+
var { run } = await import("./assets/main-DbqcdShN.js");
|
|
28
28
|
run(process.argv.slice(2));
|
|
29
29
|
//#endregion
|
|
30
30
|
export {};
|
package/package.json
CHANGED