@ledgerhq/revault-sdk 0.21.5 → 0.21.6

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/lib/bake.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"sourcesContent":["import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\n\nexport * from \"./types\";\n\nexport { createAndApproveRequest, type CreateRequestInput } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n type CreateRequestInput,\n approveRequest,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account);\n }\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(account: ManifestAccount): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\"SEND\", \"STAKE\", \"DEPLOY_CONTRACT\", \"EXECUTE_CONTRACT\", \"SIGN_MESSAGE\"]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"],"mappings":"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","names":["invariant","invariant","_","account","invariant","exchange","blueprintExchange","_","invariant","invariant","assetManager","usersWithDeviceIndex","acc","exchange","invariant"]}
1
+ {"version":3,"sources":["../src/bake/index.ts","../src/bake/bake-pledge.ts","../src/bake/utils.ts","../src/bake/bake-tradelink-organization.ts","../src/bake/bake-workspace.ts","../src/bake/types.ts"],"sourcesContent":["import invariant from \"invariant\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { bakePledgeAdjustment } from \"./bake-pledge\";\nimport { bakeTradelinkOrganization } from \"./bake-tradelink-organization\";\nimport { bakeWorkspace } from \"./bake-workspace\";\nimport type { BakeOptions } from \"./types\";\n\nexport * from \"./bake-pledge\";\n\nexport * from \"./types\";\n\nexport { createAndApproveRequest, type CreateRequestInput } from \"./utils\";\n\nexport async function bakeManifest(options: BakeOptions, logger: Logger): Promise<void> {\n const {\n engine,\n workspaceName,\n rootAuthToken,\n manifest: { tradelink, workspace },\n } = options;\n\n if (tradelink) {\n invariant(rootAuthToken, `rootAuthToken is required to create Tradelink org entities`);\n await bakeTradelinkOrganization(\n {\n engine,\n tradelink,\n rootAuthToken,\n ...(workspace?.tradelink?.networkBlueprint && workspaceName\n ? { networkBlueprint: { blueprint: workspace.tradelink.networkBlueprint, workspaceName } }\n : {}),\n },\n logger,\n );\n }\n\n if (workspace) {\n invariant(workspaceName, `Can't bake workspace without specifying a workspace name`);\n await bakeWorkspace({ engine, workspace, workspaceName }, logger);\n\n if (workspace.pledges) {\n const engineWithWorkspace = engine.withWorkspace(workspaceName);\n for (const pledgeAdjustment of workspace.pledges) {\n await bakePledgeAdjustment({ engine: engineWithWorkspace, pledgeAdjustment }, logger);\n }\n }\n }\n\n logger.info(\"Successfully baked\");\n}\n","import invariant from \"invariant\";\n\nimport type { Engine, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type { ManifestPledgeAdjustment } from \"./types\";\nimport { createAndApproveRequest } from \"./utils\";\n\ntype Options = {\n engine: Engine<WithWorkspace>;\n pledgeAdjustment: ManifestPledgeAdjustment;\n};\n\nconst flattenApprovers = (groups: { quorum: number; userIds: string[] }[]): string[] => {\n return groups.reduce<string[]>((acc, cur) => {\n acc.push(...cur.userIds.slice(0, cur.quorum));\n return acc;\n }, []);\n};\n\nexport async function bakePledgeAdjustment(options: Options, logger: Logger): Promise<void> {\n const { pledgeAdjustment, engine } = options;\n\n const getDeviceIndex = createDeviceIndexResolver(engine);\n\n logger.info(\"Logging in with admin...\");\n const admin = await engine.withDeviceIndex(4).login();\n\n logger.info(\"Fetching account, tradelink blueprint and network...\");\n const [matchingAccounts, blueprint, network] = await Promise.all([\n fetchAll(admin.client.accounts.list.query, { name: pledgeAdjustment.account }),\n admin.client.tradelink.getNetworkBlueprint.query(),\n admin.client.tradelink.getNetwork.query(),\n ]);\n\n const account = matchingAccounts.find((account) => account.name === pledgeAdjustment.account);\n invariant(account, `Account ${pledgeAdjustment.account} not found`);\n\n invariant(blueprint, \"Tradelink blueprint is not created yet\");\n invariant(network, \"Tradelink network is not created yet\");\n\n const exchange = network.exchanges.find((exchange) => {\n const blueprintExchange = blueprint.exchanges.find(\n (blueprintExchange) => blueprintExchange.tradelinkId === exchange.tradelinkId,\n );\n invariant(blueprintExchange, `Exchange ${exchange.tradelinkId} not found in blueprint`);\n return blueprintExchange.name === pledgeAdjustment.exchange;\n });\n invariant(exchange, `Exchange ${pledgeAdjustment.exchange} not found in network`);\n\n const governance = account.governance;\n invariant(governance.type === \"TRADELINK\", \"Account governance is not TRADELINK\");\n const assetManager = network.assetManagers.find((am) => am.id === governance.assetManagerId);\n invariant(assetManager, `Asset manager ${governance.assetManagerId} not found in network`);\n\n const exchangeIsConfiguredForAccount = !!governance.exchangeConfigs.find(\n (e) => e.exchangeId === exchange.id,\n );\n invariant(\n exchangeIsConfiguredForAccount,\n `Exchange ${exchange.id} is not configured for account ${account.id}`,\n );\n\n const approverIds = [\n ...flattenApprovers(assetManager.groups),\n ...flattenApprovers(exchange.groups),\n ];\n\n const approvers = await Promise.all(\n approverIds.map((id) =>\n admin.client.users.findById\n .query({ id })\n .then((user) => getDeviceIndex(user.deviceUserId!))\n .then((index) => engine.withDeviceIndex(index).login()),\n ),\n );\n\n await createAndApproveRequest(\n {\n type: \"TRADELINK_ADJUST_PLEDGE\",\n data: {\n accountId: account.id,\n exchangeId: exchange.id,\n amount: pledgeAdjustment.amount,\n },\n },\n approvers,\n logger,\n );\n\n logger.info(\n `Successfully adjusted pledge for account ${pledgeAdjustment.account} on exchange ${pledgeAdjustment.exchange}`,\n );\n}\n","import type { VaultRequestResponse } from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\n\nimport type { Engine, WithDevice, WithPsdAuth, WithWorkspace } from \"@/engine\";\nimport type { Logger } from \"@/logger\";\nimport type { RouterInputs } from \"@/trpc\";\n\ntype LogFunction = (msg: string) => void;\n\ntype LogHelpers = {\n logTitle: LogFunction;\n logStep: LogFunction;\n logSubStep: LogFunction;\n};\n\nexport function createBakeLogHelpers(logger: Logger): LogHelpers {\n return {\n logTitle(title: string): void {\n logger.info(`:: ${title} ::`);\n },\n logStep(msg: string): void {\n logger.info(`=> ${msg}`);\n },\n logSubStep(msg: string): void {\n logger.info(` -> ${msg}`);\n },\n };\n}\n\nexport type CreateRequestInput = RouterInputs[\"requests\"][\"create\"][\"request\"];\n\nexport type inferRequestInputData<T extends RouterInputs[\"requests\"][\"create\"][\"request\"][\"type\"]> =\n Extract<RouterInputs[\"requests\"][\"create\"][\"request\"], { type: T }>[\"data\"];\n\nexport async function approveRequest(\n request: VaultRequestResponse,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n for (let i = 0; i < approvers.length; i++) {\n logSubStep(`Collecting approval (${i + 1}/${approvers.length})...`);\n const approver = approvers[i]!;\n request = await approver.approve(request);\n }\n return request;\n}\n\nexport async function createAndApproveRequest(\n input: CreateRequestInput,\n approvers: Engine<WithWorkspace & WithDevice & WithPsdAuth>[],\n logger: Logger,\n): Promise<VaultRequestResponse> {\n const { logSubStep } = createBakeLogHelpers(logger);\n const creator = approvers[0];\n invariant(creator, \"Need at least 1 user to create a request\");\n logSubStep(`Creating request of type ${input.type}...`);\n const request = await creator.client.requests.create.mutate({ request: input });\n return approveRequest(request, approvers, logger);\n}\n\nexport function stripUndefinedDeep<T>(obj: T): T {\n if (Array.isArray(obj)) {\n return obj.map(stripUndefinedDeep) as unknown as T;\n }\n\n if (obj && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, v]) => v !== undefined)\n .map(([k, v]) => [k, stripUndefinedDeep(v)]),\n ) as T;\n }\n\n return obj;\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { BakeOptions, ManifestTradelinkNetworkBlueprint, ManifestTradelinkOrg } from \"./types\";\nimport { createBakeLogHelpers } from \"./utils\";\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"rootAuthToken\"> & {\n tradelink: ManifestTradelinkOrg;\n rootAuthToken: string;\n networkBlueprint?: { workspaceName: string; blueprint: ManifestTradelinkNetworkBlueprint };\n};\n\nexport async function bakeTradelinkOrganization(options: Options, logger: Logger): Promise<void> {\n const { tradelink, engine, rootAuthToken, networkBlueprint } = options;\n\n const { logStep } = createBakeLogHelpers(logger);\n\n const rootClient = engine.createClient({ rootAuthToken });\n if (tradelink.exchanges) {\n logStep(\"Creating Tradelink organization exchanges...\");\n const existingOrgExchanges = await rootClient.tradelink.root.listOrgExchanges.query();\n for (const orgExchange of tradelink.exchanges) {\n const existingOrgExchange = existingOrgExchanges.find((e) => e.name === orgExchange.name);\n if (existingOrgExchange) {\n logger.info(\n `[SKIPPED] Organization exchange ${existingOrgExchange.name} (${existingOrgExchange.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgExchange.mutate({\n code: orgExchange.code,\n name: orgExchange.name,\n logoUrl: orgExchange.logo,\n });\n logger.info(`Created organization exchange ${orgExchange.name} (${orgExchange.code})`);\n }\n }\n }\n if (tradelink.assetManagers) {\n logStep(\"Creating Tradelink organization asset managers...\");\n const existingAssetManagers = await rootClient.tradelink.root.listOrgAssetManagers.query();\n for (const orgAssetManager of tradelink.assetManagers) {\n const existingOrgAssetManager = existingAssetManagers.find(\n (e) => e.name === orgAssetManager.name,\n );\n if (existingOrgAssetManager) {\n logger.info(\n `[SKIPPED] Organization asset manager ${existingOrgAssetManager.name} (${existingOrgAssetManager.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgAssetManager.mutate({\n code: orgAssetManager.code,\n name: orgAssetManager.name,\n logoUrl: orgAssetManager.logo,\n });\n logger.info(\n `Created organization asset manager ${orgAssetManager.name} (${orgAssetManager.code})`,\n );\n }\n }\n }\n if (tradelink.custodians) {\n logStep(\"Creating Tradelink organization custodians...\");\n const existingCustodians = await rootClient.tradelink.root.listOrgCustodians.query();\n for (const orgCustodian of tradelink.custodians) {\n const existingOrgCustodian = existingCustodians.find((e) => e.name === orgCustodian.name);\n if (existingOrgCustodian) {\n logger.info(\n `[SKIPPED] Organization custodian ${existingOrgCustodian.name} (${existingOrgCustodian.code}) already exists`,\n );\n } else {\n await rootClient.tradelink.root.createOrgCustodian.mutate({\n code: orgCustodian.code,\n name: orgCustodian.name,\n logoUrl: orgCustodian.logo,\n });\n logger.info(`Created organization custodian ${orgCustodian.name} (${orgCustodian.code})`);\n }\n }\n }\n if (networkBlueprint) {\n logStep(\"Creating Tradelink network blueprint...\");\n const { workspaceName, blueprint } = networkBlueprint;\n const existingBlueprints = await rootClient.tradelink.root.listNetworkBlueprints.query();\n const existingBlueprint = existingBlueprints.find((e) => e.workspaceName === workspaceName);\n if (existingBlueprint) {\n logger.info(`[SKIPPED] Network blueprint for ${workspaceName} workspace already exists`);\n } else {\n await rootClient.tradelink.root.createNetworkBlueprint.mutate({\n workspaceName,\n custodian: { name: blueprint.custodian },\n exchanges: blueprint.exchanges.map((_) => ({ name: _ })),\n assetManagers: blueprint.assetManagers.map((_) => ({ name: _ })),\n });\n logger.info(`Created network blueprint for ${networkBlueprint.workspaceName} workspace`);\n }\n }\n}\n","import type {\n ReviewStepWithUsers,\n TradelinkNetworkBlueprintResponse,\n UserResponse,\n VaultRequestResponse,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport _ from \"lodash\";\n\nimport { genKeys } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\nimport { createDeviceIndexResolver, fetchAll } from \"@/utils\";\n\nimport type {\n BakeOptions,\n ManifestAccount,\n ManifestApiUser,\n ManifestGovernanceRule,\n ManifestGroup,\n ManifestPolicy,\n ManifestTradelinkEntity,\n ManifestTradelinkGroup,\n ManifestTradelinkNetwork,\n ManifestWhitelist,\n ManifestWorkspace,\n} from \"./types\";\nimport {\n type CreateRequestInput,\n approveRequest,\n createAndApproveRequest,\n createBakeLogHelpers,\n type inferRequestInputData,\n stripUndefinedDeep,\n} from \"./utils\";\n\ntype GovRuleData = inferRequestInputData<\"CREATE_POLICY\">[\"govRules\"][number];\n\ntype Options = Omit<BakeOptions, \"manifest\" | \"workspaceName\"> & {\n workspace: ManifestWorkspace;\n workspaceName: string;\n};\n\nexport async function bakeWorkspace(options: Options, logger: Logger): Promise<void> {\n const { workspace, engine, workspaceName } = options;\n\n const workspaceEngine = engine.withWorkspace(workspaceName);\n const { logTitle, logStep, logSubStep } = createBakeLogHelpers(logger);\n\n // utility to retrieve device index based on device user id\n const findDeviceIndex = createDeviceIndexResolver(workspaceEngine);\n\n // Log-in once with the two admins (index 4 & 5 by convention) that will create all\n // the requests for the manifest objects.\n logger.info(\"Authenticating with two admins...\");\n const [admin1, admin2] = await Promise.all([\n workspaceEngine.withDeviceIndex(4).login(),\n workspaceEngine.withDeviceIndex(5).login(),\n ]);\n\n // Retrieve all existing data, so we are then able to skip creating stuff when not needed.\n logger.info(\"Fetching existing data...\");\n const [\n existingUsers,\n existingGroups,\n existingWhitelists,\n existingPolicies,\n existingAccounts,\n tradelinkNetworkBlueprint,\n ] = await Promise.all([\n fetchAll(admin1.client.users.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.groups.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.whitelists.list.query, { status: \"ACTIVE\" }),\n fetchAll(admin1.client.policies.list.query, { isPrivate: false }),\n fetchAll(admin1.client.accounts.list.query, { status: \"ACTIVE\" }),\n admin1.client.tradelink.getNetworkBlueprint.query(),\n ]);\n\n const tradelinkOrgExchangesByName = _.keyBy(tradelinkNetworkBlueprint?.exchanges, \"name\");\n const tradelinkOrgAssetManagersByName = _.keyBy(tradelinkNetworkBlueprint?.assetManagers, \"name\");\n\n let existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n\n // Merge admins & operators (we can't fetch all users in a row because we don't want API users,\n // and we don't have a way to retrieve both admins & operators in a single fetch)\n const existingPsdUsers = existingUsers.filter((user) => user.deviceType === \"PSD\");\n const existingApiUsers = existingUsers.filter((user) => user.deviceType === \"API\");\n // Retrieve all device indexes for the existing users\n const usersWithDeviceIndex = await resolveDevicesIndexes(existingPsdUsers);\n\n // ---------------------------------\n // USERS\n // ---------------------------------\n if (workspace.users) {\n logTitle(\"Users\");\n if (workspace.users.admins) {\n for (const deviceIndex of workspace.users.admins) {\n await createUser(\"ADMIN\", deviceIndex);\n }\n }\n if (workspace.users.operators) {\n for (const deviceIndex of workspace.users.operators) {\n await createUser(\"OPERATOR\", deviceIndex);\n }\n }\n if (workspace.users.api) {\n for (const apiUser of workspace.users.api) {\n await createApiUser(apiUser);\n }\n }\n }\n\n // ---------------------------------\n // GROUPS\n // ---------------------------------\n if (workspace.groups) {\n logTitle(\"Groups\");\n for (const group of workspace.groups) {\n await createGroup(group);\n }\n }\n\n // ---------------------------------\n // WHITELISTS\n // ---------------------------------\n if (workspace.whitelists) {\n logTitle(\"Whitelists\");\n await createWhitelists(workspace.whitelists);\n }\n\n // POLICIES\n // ---------------------------------\n if (workspace.policies) {\n logTitle(\"Policies\");\n for (const policy of workspace.policies) {\n await createPolicy(policy);\n }\n }\n\n // ---------------------------------\n // TRADELINK NETWORK\n // ---------------------------------\n if (workspace.tradelink) {\n logTitle(\"Tradelink\");\n await createTradelink(workspace.tradelink);\n }\n\n // ---------------------------------\n // ACCOUNTS\n // ---------------------------------\n if (workspace.accounts) {\n logTitle(\"Accounts\");\n for (const account of workspace.accounts) {\n await createAccount(account);\n }\n }\n\n async function createWhitelists(whitelists: ManifestWhitelist[]): Promise<void> {\n for (const whitelist of whitelists) {\n await createWhitelist(whitelist);\n }\n\n async function createWhitelist(whitelist: ManifestWhitelist): Promise<void> {\n const existing = existingWhitelists.find((w) => w.name === whitelist.name);\n\n // TODO: compare with existing to eventually do an EDIT\n if (existing) {\n logger.info(`[SKIPPED] Whitelist \"${whitelist.name}\" already exists`);\n return;\n }\n\n const input: CreateRequestInput = {\n type: \"CREATE_WHITELIST\",\n data: whitelist,\n };\n\n const req = await createAndApproveRequest(input, [admin1, admin2], logger);\n logSubStep(`Whitelist \"${whitelist.name}\" has been created`);\n\n const createdWhitelist = await admin1.client.whitelists.findById.query({ id: req.targetId! });\n existingWhitelists.push(createdWhitelist);\n }\n }\n\n function govRuleFromManifest(rule: ManifestGovernanceRule): GovRuleData {\n return {\n operationType: rule.type,\n reviewSteps: rule.steps.map((step) => {\n if (\"group\" in step) {\n return {\n quorum: step.quorum,\n groupId: groupIdFromName(step.group),\n };\n }\n return {\n quorum: step.quorum,\n userIds: step.members.map(userIdFromDeviceIndexOrName),\n };\n }),\n threshold: rule.threshold,\n whitelistIds: rule.whitelistNames?.map(whitelistIdFromName),\n };\n }\n\n async function createAccount(account: ManifestAccount): Promise<void> {\n let req: VaultRequestResponse | null = null;\n const existing = existingAccounts.find(\n (a) =>\n a.currency === account.currency &&\n a.index === account.index &&\n (a.contractAddress ?? null) === (account.contractAddress ?? null),\n );\n const createInput: CreateRequestInput = {\n type: \"CREATE_ACCOUNT\",\n data: {\n // general fields\n name: account.name,\n currency: account.currency,\n contractAddress: account.contractAddress,\n index: account.index,\n\n // governance fields\n governance:\n account.governance.type === \"TRADELINK\"\n ? {\n type: \"TRADELINK\",\n assetManagerId: assetManagerIdFromName(account.governance.assetManager),\n exchangeConfigs: account.governance.exchanges.map((exchangeConfig) => ({\n exchangeId: exchangeIdFromName(exchangeConfig.name),\n repledgeAuthorized: exchangeConfig.repledgeAuthorized === true,\n needsAssetManagerApprovalForSettlements:\n exchangeConfig.needsAssetManagerApprovalForSettlements === true,\n })),\n }\n : {\n type: \"CLASSIC\",\n policy: { rules: account.governance.rules.map(govRuleFromManifest) },\n },\n },\n };\n\n if (existing) {\n const editInput: CreateRequestInput = {\n ...createInput,\n type: \"EDIT_ACCOUNT\",\n targetId: existing.id,\n };\n\n const previousAccountRequests = await admin1.client.requests.list.query({\n type: [\"CREATE_ACCOUNT\", \"EDIT_ACCOUNT\"],\n targetId: existing.id,\n state: \"EXECUTED\",\n sortBy: \"createdAt\",\n sortOrder: \"desc\",\n });\n\n // Check if account needs an update\n // Look for the last request that updated its state\n if (previousAccountRequests?.results && previousAccountRequests.results.length > 0) {\n const stateRequest = previousAccountRequests.results?.[0];\n invariant(\n stateRequest &&\n (stateRequest.type === \"EDIT_ACCOUNT\" || stateRequest.type === \"CREATE_ACCOUNT\"),\n \"State request should be an edit account request\",\n );\n\n // Compare the create request data with current account config\n if (\n _.isEqual(\n stripUndefinedDeep(createInput.data.governance),\n stripUndefinedDeep(stateRequest.data.governance),\n ) &&\n createInput.data.name === stateRequest.data.name\n ) {\n logger.info(`[SKIPPED] Account \"${account.name}\" has not changed`);\n return;\n }\n\n // Account needs to be updated\n req = await createAndApproveRequest(editInput, [admin1, admin2], logger);\n logger.info(`[EDITED] Account \"${account.name}\" has been edited`);\n return;\n }\n } else {\n logStep(`Creating account \"${account.name}\"`);\n req = await createAndApproveRequest(createInput, [admin1, admin2], logger);\n\n const createdAccount = await admin1.client.accounts.findById.query({ id: req.targetId! });\n existingAccounts.push(createdAccount);\n }\n\n if (account.governance.type === \"TRADELINK\" && req) {\n logStep(`Activating tradelink account \"${account.name}\"`);\n // we need to activate the account with the asset manager\n const assetManagerId = assetManagerIdFromName(account.governance.assetManager);\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.id === assetManagerId,\n );\n invariant(assetManager, `Asset manager for account exists`);\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, userIds }) =>\n userIds.slice(0, quorum).map((userId) => {\n const deviceIndex = usersWithDeviceIndex.find((o) => o.user.id === userId)?.deviceIndex;\n return workspaceEngine.withDeviceIndex(deviceIndex!).login();\n }),\n ),\n );\n await createAndApproveRequest(\n { type: \"TRADELINK_ACTIVATE_ACCOUNT\", targetId: req.targetId!, data: null },\n loggedAssetManagerOperators,\n logger,\n );\n }\n\n logSubStep(`Account ${account.name} has been created`);\n }\n\n async function createUser(role: \"ADMIN\" | \"OPERATOR\", deviceIndex: number): Promise<void> {\n const userEngine = workspaceEngine.withDeviceIndex(deviceIndex);\n const deviceId = await userEngine.device.getDeviceUserId();\n\n // eventually check if we can skip user creation\n const existing = existingUsers.find((user) => user.deviceUserId === deviceId);\n if (existing) {\n logger.info(`[SKIPPED] User with device index ${deviceIndex} already exists`);\n return;\n }\n\n const name = `${role === \"ADMIN\" ? \"Admin\" : \"Operator\"} ${deviceIndex}`;\n logStep(`Creating ${name}`);\n\n logSubStep(\"Creating invitation...\");\n let registration = await admin1.client.userRegistrations.invite.mutate({\n name,\n role,\n deviceUserId: deviceId,\n psdModel: \"STAX\",\n });\n\n logSubStep(\"Completing registration...\");\n registration = await userEngine.register(registration);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_PSD_USER\",\n data: { registrationId: registration.id },\n },\n });\n\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`${name} has been created`);\n\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n\n // patch the current state with the newly created user\n existingUsers.push(createdUser);\n usersWithDeviceIndex.push({ user: createdUser, deviceIndex });\n }\n\n async function createApiUser(apiUser: ManifestApiUser): Promise<void> {\n const pubKey = apiUser.pubKey ?? genKeys(apiUser.name).hexPubKey;\n const existing = existingApiUsers.find(\n (user) => user.pubKey === pubKey || user.name === apiUser.name,\n );\n if (existing) {\n logger.info(\n `[SKIPPED] API user already exists with name \"${apiUser.name}\" or public key \"${pubKey}\"`,\n );\n return;\n }\n\n logStep(`Creating API user \"${apiUser.name}\"...`);\n\n logSubStep(\"Creating request...\");\n let req = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_API_USER\",\n data: {\n name: apiUser.name,\n role: apiUser.role,\n pubKey: pubKey,\n viewAll: apiUser.viewAll,\n },\n },\n });\n req = await approveRequest(req, [admin1, admin2], logger);\n logSubStep(`API user \"${apiUser.name}\" has been created`);\n\n logSubStep(\"Generating credentials...\");\n const credentials = await admin1.client.users.resetApiUserCredentials.mutate({\n id: req.targetId!,\n });\n logSubStep(\n `API user \"${apiUser.name}\" credentials have been generated: apiKeyId=${credentials.apiKeyId}, apiKeySecret=${credentials.apiKeySecret}`,\n );\n const createdUser = await admin1.client.users.findById.query({ id: req.targetId! });\n // patch the current state with the newly created user\n existingApiUsers.push(createdUser);\n }\n\n async function createGroup(group: ManifestGroup): Promise<void> {\n const existing = existingGroups.find((g) => g.name === group.name);\n if (existing) {\n logger.info(`[SKIPPED] Group \"${group.name}\" already exists`);\n return;\n }\n\n logStep(`Creating group ${group.name}...`);\n\n const members = group.members.map(userIdFromDeviceIndexOrName);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_GROUP\",\n data: {\n name: group.name,\n description: \"\",\n members,\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${group.name} has been created`);\n\n const createdGroup = await admin1.client.groups.findById.query({ id: request.targetId! });\n existingGroups.push(createdGroup);\n }\n\n async function createPolicy(policy: ManifestPolicy): Promise<void> {\n const existing = existingPolicies.find((p) => p.name === policy.name);\n if (existing) {\n logger.info(`[SKIPPED] Policy \"${policy.name}\" already exists`);\n return;\n }\n\n logStep(`Creating policy ${policy.name}...`);\n\n logSubStep(\"Creating request...\");\n let request = await admin1.client.requests.create.mutate({\n request: {\n type: \"CREATE_POLICY\",\n data: {\n name: policy.name,\n currency: policy.currency,\n description: \"\",\n govRules: policy.rules.map(govRuleFromManifest),\n },\n },\n });\n\n request = await approveRequest(request, [admin1, admin2], logger);\n logSubStep(`${policy.name} has been created`);\n\n const createdPolicy = await admin1.client.policies.findById.query({ id: request.targetId! });\n existingPolicies.push(createdPolicy);\n }\n\n async function createTradelink(tradelink: ManifestTradelinkNetwork): Promise<void> {\n if (tradelink.custodian) {\n if (existingTradelinkNetwork === null) {\n logStep(\"Creating custodian config...\");\n const { settlement, withdraw, arbitration } = tradelink.custodian;\n const data = {\n settlement: settlement.map(tradelinkReviewStepFromManifest),\n withdraw: withdraw.map(tradelinkReviewStepFromManifest),\n arbitration: arbitration.map(tradelinkReviewStepFromManifest),\n };\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_CUSTODIAN\",\n data,\n },\n });\n\n await approveRequest(request, [admin1, admin2], logger);\n logSubStep(\"Tradelink custodian config has been created\");\n\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n } else {\n logger.info(\"[SKIPPED] Custodian config already exists\");\n }\n\n const networkBlueprint = await admin1.client.tradelink.getNetworkBlueprint.query();\n if (networkBlueprint !== null) {\n if (tradelink.exchanges !== undefined) {\n await createTradelinkExchanges(networkBlueprint, tradelink.exchanges);\n }\n\n if (tradelink.assetManagers !== undefined) {\n await createTradelinkAssetManagers(networkBlueprint, tradelink.assetManagers);\n }\n } else {\n logger.error(\n \"Will not create exchanges and asset managers because there is no network blueprint for current workspace\",\n );\n }\n }\n }\n\n async function createTradelinkExchanges(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n exchanges: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintExchanges = networkBlueprint.exchanges;\n for (const exchange of exchanges) {\n // find uid\n const blueprintExchange = blueprintExchanges.find(({ name }) => name === exchange.name);\n invariant(\n blueprintExchange !== undefined,\n `Exchange ${exchange.name} does not exist in network blueprint`,\n );\n const exchangeId = blueprintExchange.tradelinkId;\n logStep(`Creating exchange ${exchange.name}...`);\n if (\n existingTradelinkNetwork.exchanges.find(({ tradelinkId }) => tradelinkId === exchangeId) !==\n undefined\n ) {\n logger.info(`[SKIPPED] Exchange \"${exchange.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_EXCHANGE\",\n data: {\n tradelinkId: exchangeId,\n groups: exchange.groups.map(tradelinkReviewStepFromManifest),\n whitelist: exchange.whitelist,\n },\n },\n });\n\n const loggedExchangeOperators = await Promise.all(\n exchange.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedExchangeOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n async function createTradelinkAssetManagers(\n networkBlueprint: TradelinkNetworkBlueprintResponse,\n assetManagers: ManifestTradelinkEntity[],\n ): Promise<void> {\n invariant(existingTradelinkNetwork !== null, \"Network should exist\");\n const blueprintAssetManagers = networkBlueprint.assetManagers;\n for (const assetManager of assetManagers) {\n // find uid\n const blueprintAssetManager = blueprintAssetManagers.find(\n ({ name }) => name === assetManager.name,\n );\n invariant(\n blueprintAssetManager !== undefined,\n `AssetManager ${assetManager.name} does not exist in network blueprint`,\n );\n const assetManagerId = blueprintAssetManager.tradelinkId;\n logStep(`Creating assetManager ${assetManager.name}...`);\n if (\n existingTradelinkNetwork.assetManagers.find(\n ({ tradelinkId }) => tradelinkId === assetManagerId,\n ) !== undefined\n ) {\n logger.info(`[SKIPPED] Asset manager \"${assetManager.name}\" already exists`);\n continue;\n }\n\n logSubStep(\"Creating request...\");\n const request = await admin1.client.requests.create.mutate({\n request: {\n type: \"TRADELINK_CREATE_ASSET_MANAGER\",\n data: {\n tradelinkId: assetManagerId,\n groups: assetManager.groups.map(tradelinkReviewStepFromManifest),\n whitelist: assetManager.whitelist,\n },\n },\n });\n\n const loggedAssetManagerOperators = await Promise.all(\n assetManager.groups.flatMap(({ quorum, members }) =>\n members\n .slice(0, quorum)\n .map((deviceIndex) => workspaceEngine.withDeviceIndex(deviceIndex).login()),\n ),\n );\n\n await approveRequest(request, [admin1, admin2, ...loggedAssetManagerOperators], logger);\n\n // refresh tradelink network\n existingTradelinkNetwork = await admin1.client.tradelink.getNetwork.query();\n invariant(existingTradelinkNetwork !== null, \"Tradelink network exists\");\n }\n }\n\n // For each given user, retrieve (by brute force) their device index, by comparing their\n // device user id with the one computed for each tested index.\n // Using .reduce() here to leverage caching existing discoveries\n async function resolveDevicesIndexes(\n users: UserResponse[],\n ): Promise<{ user: UserResponse; deviceIndex: number }[]> {\n const usersWithDeviceIndex = await users.reduce<\n Promise<{ user: UserResponse; deviceIndex: number }[]>\n >(\n (acc, cur) =>\n acc.then(async (acc) => {\n acc.push(await withDeviceIndex(cur));\n return acc;\n }),\n Promise.resolve([]),\n );\n return usersWithDeviceIndex;\n }\n\n async function withDeviceIndex(\n user: UserResponse,\n ): Promise<{ user: UserResponse; deviceIndex: number }> {\n invariant(user.deviceUserId, `User ${user.id} does not have any device user id`);\n const deviceIndex = await findDeviceIndex(user.deviceUserId);\n return { user, deviceIndex };\n }\n\n function userIdFromDeviceIndex(deviceIndex: number): string {\n const corresponding = usersWithDeviceIndex.find((o) => o.deviceIndex === deviceIndex);\n invariant(corresponding, `No user with device index ${deviceIndex}`);\n return corresponding.user.id;\n }\n\n function userIdFromUserName(name: string): string {\n const user = existingApiUsers.find((u) => u.name === name);\n invariant(user, `User ${name} not found`);\n return user.id;\n }\n\n function userIdFromDeviceIndexOrName(identifier: number | string): string {\n if (typeof identifier === \"number\") {\n return userIdFromDeviceIndex(identifier);\n }\n return userIdFromUserName(identifier);\n }\n\n function groupIdFromName(groupName: string): string {\n const group = existingGroups.find((g) => g.name === groupName);\n invariant(group, `Group ${groupName} not found`);\n return group.id;\n }\n\n function whitelistIdFromName(whitelistName: string): string {\n const whitelist = existingWhitelists.find((w) => w.name === whitelistName);\n invariant(whitelist, `Whitelist ${whitelistName} not found`);\n return whitelist.id;\n }\n\n function assetManagerIdFromName(assetManagerName: string): string {\n const orgAssetManager = tradelinkOrgAssetManagersByName[assetManagerName];\n invariant(\n orgAssetManager,\n `Can't find Tradelink organization asset manager ${assetManagerName}`,\n );\n const assetManager = existingTradelinkNetwork?.assetManagers.find(\n (assetManager) => assetManager.tradelinkId === orgAssetManager.tradelinkId,\n );\n invariant(assetManager, `Can't find Tradelink assetManager ${assetManagerName}`);\n return assetManager.id;\n }\n\n function exchangeIdFromName(exchangeName: string): string {\n const exchange = existingTradelinkNetwork?.exchanges.find((exchange) => {\n const orgExchange = tradelinkOrgExchangesByName[exchangeName];\n invariant(orgExchange, `Can't find Tradelink organization exchange ${exchange.tradelinkId}`);\n return orgExchange.name === exchangeName;\n });\n invariant(exchange, `Can't find Tradelink exchange ${exchangeName}`);\n return exchange.id;\n }\n\n function tradelinkReviewStepFromManifest({\n members,\n quorum,\n }: ManifestTradelinkGroup): ReviewStepWithUsers {\n return {\n userIds: members.map(userIdFromDeviceIndex),\n quorum,\n };\n }\n}\n","import z from \"zod\";\n\nimport type { Engine } from \"@/engine\";\n\n// #region ---------- General types ---------------------------------------------------------------\n\nexport type BakeOptions = {\n manifest: Manifest;\n engine: Engine;\n workspaceName?: string;\n rootAuthToken?: string;\n};\n\n// #endregion\n\n// #region ---------- Users -----------------------------------------------------------------------\n\nconst zManifestUser = z.number().meta({ description: \"User device index\" });\nconst zManifestUserName = z.string().meta({ description: \"User name\" });\nconst zManifestApiUser = z.object({\n name: z.string().meta({ description: \"API user name\" }),\n role: z.enum([\"ADMIN\", \"OPERATOR\"]).meta({ description: \"API user role\" }).default(\"OPERATOR\"),\n pubKey: z\n .string()\n .meta({\n description:\n \"API user public key. If not provided, one will be generated using the name as entropy\",\n })\n .optional(),\n viewAll: z.boolean().meta({ description: \"Whether the API user can view all accounts\" }),\n});\n\nexport type ManifestApiUser = z.infer<typeof zManifestApiUser>;\n\n// #endregion\n\n// #region ---------- Groups ----------------------------------------------------------------------\n\nconst zManifestGroup = z\n .object({\n name: z.string().meta({ description: \"Group name\" }),\n members: z\n .array(z.union([zManifestUser, zManifestUserName]))\n .meta({ description: \"Group members\" }),\n })\n .strict()\n .meta({ description: \"Operators group\" });\n\nexport type ManifestGroup = z.infer<typeof zManifestGroup>;\n\n// #endregion\n\n// #region ---------- Whitelists ------------------------------------------------------------------\n\nconst zManifestWhitelistAddress = z\n .object({\n name: z.string().meta({ description: \"Whitelist address name\" }),\n currency: z.string().meta({ description: \"Whitelist address currency\" }),\n address: z.string().meta({ description: \"Whitelist address\" }),\n destinationTags: z\n .array(z.string())\n .optional()\n .meta({ description: \"List of destination tags (applicable for Ripple currency)\" }),\n })\n .strict();\n\nconst zManifestWhitelist = z\n .object({\n name: z.string().meta({ description: \"Whitelist name\" }),\n description: z.string().optional().default(\"\").meta({ description: \"Whitelist description\" }),\n type: z\n .enum([\"TRANSACTION\", \"SMART_CONTRACT\"])\n .optional()\n .default(\"TRANSACTION\")\n .meta({ description: \"Whitelist type\" }),\n addresses: z.array(zManifestWhitelistAddress).meta({ description: \"Whitelist addresses\" }),\n })\n .strict()\n .meta({ description: \"Whitelist\" });\n\nexport type ManifestWhitelist = z.infer<typeof zManifestWhitelist>;\n\n// #endregion\n\n// #region ---------- Policies --------------------------------------------------------------------\n\nconst zManifestGovernanceStepWithUsers = z\n .object({\n quorum: z.number(),\n members: z.array(z.union([zManifestUser, zManifestUserName])),\n })\n .strict();\n\nconst zManifestGovernanceStepWithGroup = z\n .object({\n quorum: z.number(),\n group: z.string(),\n })\n .strict();\n\nconst zManifestGovernanceStep = z.union([\n zManifestGovernanceStepWithUsers,\n zManifestGovernanceStepWithGroup,\n]);\n\nconst zManifestGovernanceRule = z\n .object({\n // TODO see if there is a way to import this from `api` package\n // (the challenge there is that enums are not transpiled)\n type: z.enum([\n \"SEND\",\n \"STAKE\",\n \"DEPLOY_CONTRACT\",\n \"EXECUTE_CONTRACT\",\n \"SIGN_MESSAGE\",\n \"RECEIVE\",\n ]),\n steps: z.array(zManifestGovernanceStep).min(1),\n threshold: z\n .object({\n min: z.string(),\n max: z.string(),\n })\n .optional(),\n whitelistNames: z.array(z.string()).optional(),\n })\n .strict();\n\nexport type ManifestGovernanceRule = z.infer<typeof zManifestGovernanceRule>;\n\nexport const zManifestPolicy = z\n .object({\n name: z.string(),\n currency: z.string().nullable(),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nexport type ManifestPolicy = z.infer<typeof zManifestPolicy>;\n\n// #endregion\n\n// #region ---------- Accounts --------------------------------------------------------------------\n\nconst zManifestClassicAccountGovernance = z\n .object({\n type: z.literal(\"CLASSIC\"),\n rules: z.array(zManifestGovernanceRule),\n })\n .strict();\n\nconst zManifestTradelinkExchangeConfig = z\n .object({\n name: z.string().meta({ description: \"Exchange name\" }),\n repledgeAuthorized: z\n .boolean()\n .optional()\n .meta({ description: \"Whether repledge is authorized\" }),\n needsAssetManagerApprovalForSettlements: z\n .boolean()\n .optional()\n .meta({ description: \"Whether asset manager pre approval is needed\" }),\n })\n .strict();\n\nconst zManifestTradelinkAccountGovernance = z\n .object({\n type: z.literal(\"TRADELINK\"),\n assetManager: z.string().meta({ description: \"Asset manager name\" }),\n exchanges: z.array(zManifestTradelinkExchangeConfig),\n })\n .strict();\n\nconst zManifestAccountGovernance = z.discriminatedUnion(\"type\", [\n zManifestClassicAccountGovernance,\n zManifestTradelinkAccountGovernance,\n]);\n\nconst zManifestAccount = z\n .object({\n name: z.string(),\n currency: z.string(),\n index: z.number().nonnegative(),\n contractAddress: z.string().optional(),\n governance: zManifestAccountGovernance,\n })\n .strict();\n\nexport type ManifestAccount = z.infer<typeof zManifestAccount>;\n\n// #endregion\n\n// #region ---------- Pledge adjustments (increment/decrement) ------------------------------------\n\nconst zManifestPledgeAdjustment = z\n .object({\n account: z.string(),\n exchange: z.string(),\n amount: z.string(),\n })\n .strict();\n\nexport type ManifestPledgeAdjustment = z.infer<typeof zManifestPledgeAdjustment>;\n\n// #endregion\n\n// #region ---------- Tradelink network -----------------------------------------------------------\n\nconst zManifestTradelinkGroup = z\n .object({\n members: z.array(zManifestUser),\n quorum: z.number(),\n })\n .strict()\n .meta({ description: \"Tradelink group\" });\n\nexport type ManifestTradelinkGroup = z.infer<typeof zManifestTradelinkGroup>;\n\nconst zManifestTradelinkGroups = z.array(zManifestTradelinkGroup);\n\nconst zManifestTradelinkWhitelistAddress = z\n .object({\n name: z.string().min(1),\n currency: z.string().min(1),\n address: z.string().min(1),\n })\n .strict()\n .meta({ description: \"Tradelink whitelist address\" });\n\nconst zManifestTradelinkWhitelist = z\n .array(zManifestTradelinkWhitelistAddress)\n .meta({ description: \"Tradelink whitelist\" });\n\nconst zManifestTradelinkEntity = z\n .object({\n name: z.string(),\n groups: zManifestTradelinkGroups,\n whitelist: zManifestTradelinkWhitelist,\n })\n .strict();\n\nexport type ManifestTradelinkEntity = z.infer<typeof zManifestTradelinkEntity>;\n\nconst zManifestTradelinkCustodian = z\n .object({\n settlement: zManifestTradelinkGroups,\n withdraw: zManifestTradelinkGroups,\n arbitration: zManifestTradelinkGroups,\n })\n .strict();\n\nconst zManifestTradelinkNetworkBlueprint = z\n .object({\n custodian: z.string(),\n exchanges: z.array(z.string()),\n assetManagers: z.array(z.string()),\n })\n .strict();\n\nexport type ManifestTradelinkNetworkBlueprint = z.infer<typeof zManifestTradelinkNetworkBlueprint>;\n\nconst zManifestTradelinkNetwork = z\n .object({\n networkBlueprint: zManifestTradelinkNetworkBlueprint.optional(),\n custodian: zManifestTradelinkCustodian.optional(),\n exchanges: z.array(zManifestTradelinkEntity).optional(),\n assetManagers: z.array(zManifestTradelinkEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink network configuration\" });\n\nexport type ManifestTradelinkNetwork = z.infer<typeof zManifestTradelinkNetwork>;\n\n// #endregion\n\n// #region ---------- Workspace -------------------------------------------------------------------\n\nconst zManifestWorkspace = z\n .object({\n tradelink: zManifestTradelinkNetwork.optional(),\n users: z\n .object({\n admins: z.array(zManifestUser).optional(),\n operators: z.array(zManifestUser).optional(),\n api: z.array(zManifestApiUser).optional(),\n })\n .optional(),\n groups: z.array(zManifestGroup).optional(),\n whitelists: z.array(zManifestWhitelist).optional(),\n policies: z.array(zManifestPolicy).optional(),\n accounts: z.array(zManifestAccount).optional(),\n pledges: z.array(zManifestPledgeAdjustment).optional(),\n })\n .strict()\n .meta({ description: \"Workspace configuration\" });\n\nexport type ManifestWorkspace = z.infer<typeof zManifestWorkspace>;\n\n// #endregion\n\n// #region ---------- Tradelink organization ------------------------------------------------------\n\nconst zManifestTradelinkOrgEntity = z\n .object({\n name: z.string(),\n code: z.string(),\n logo: z.string(),\n })\n .strict()\n .meta({ description: \"Tradelink organization entity\" });\n\nconst zManifestTradelinkOrg = z\n .object({\n exchanges: z.array(zManifestTradelinkOrgEntity).optional(),\n assetManagers: z.array(zManifestTradelinkOrgEntity).optional(),\n custodians: z.array(zManifestTradelinkOrgEntity).optional(),\n })\n .strict()\n .meta({ description: \"Tradelink organization configuration\" });\n\nexport type ManifestTradelinkOrg = z.infer<typeof zManifestTradelinkOrg>;\n\n// #endregion\n\n// #region ---------- Manifest --------------------------------------------------------------------\n\nexport const zManifest = z\n .object({\n manifestVersion: z.literal(2),\n tradelink: zManifestTradelinkOrg.optional(),\n workspace: zManifestWorkspace.optional(),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof zManifest>;\n\n// #endregion\n"],"mappings":"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","names":["invariant","invariant","_","account","invariant","exchange","blueprintExchange","_","invariant","invariant","assetManager","usersWithDeviceIndex","acc","exchange","invariant"]}
@@ -73,7 +73,11 @@ function createApiDevice(options, logger) {
73
73
  );
74
74
  return {
75
75
  with: (index) => {
76
- const seed = genSeed({ salt: options.salt, index });
76
+ const __seed = genSeed({ salt: options.salt, index });
77
+ const getSeed = async () => {
78
+ if (typeof __seed === "string") return Promise.resolve(__seed);
79
+ return __seed;
80
+ };
77
81
  const authenticate = async ({
78
82
  challenge,
79
83
  workspaceName
@@ -82,7 +86,7 @@ function createApiDevice(options, logger) {
82
86
  if (role === "READ_ONLY_API_KEY")
83
87
  throw new Error("Invalid role for authenticate: READ_ONLY_API_KEY");
84
88
  const { data } = await deviceApi.post("/authenticate", {
85
- seed,
89
+ seed: await getSeed(),
86
90
  challenge: Buffer.from(challenge.challenge, "base64").toString("hex"),
87
91
  application: APPID_VAULT_ADMINISTRATOR,
88
92
  key_handle: challenge.keyHandle,
@@ -96,13 +100,13 @@ function createApiDevice(options, logger) {
96
100
  };
97
101
  const finalizePairingHandshake = async (params) => {
98
102
  const { handshake, partitionId } = params;
99
- const payload = { seed, handshake, ciphertext: partitionId };
103
+ const payload = { seed: await getSeed(), handshake, ciphertext: partitionId };
100
104
  const res = await deviceApi.post("/finalize-pairing-handshake", payload);
101
105
  return res.data;
102
106
  };
103
107
  const generateSeedFragment = async () => {
104
108
  const payload = {
105
- seed,
109
+ seed: await getSeed(),
106
110
  path: PATHS.KEY_MATERIAL,
107
111
  goal: 0
108
112
  // seed fragment
@@ -112,12 +116,14 @@ function createApiDevice(options, logger) {
112
116
  };
113
117
  const generateWrappingKeyFragment = async () => {
114
118
  const goal = 1;
115
- const payload = { seed, goal, path: PATHS.KEY_MATERIAL };
119
+ const payload = { seed: await getSeed(), goal, path: PATHS.KEY_MATERIAL };
116
120
  const res = await deviceApi.post("/generate-key-fragments", payload);
117
121
  return Buffer.from(res.data, "hex").toString("base64");
118
122
  };
119
123
  const getAttestation = async () => {
120
- const { data: attestationStr } = await deviceApi.post("/get-attestation", { seed });
124
+ const { data: attestationStr } = await deviceApi.post("/get-attestation", {
125
+ seed: await getSeed()
126
+ });
121
127
  const attestationBuffer = Buffer.from(attestationStr, "hex");
122
128
  const certLen = attestationBuffer.readInt8(32 + 65 + 1);
123
129
  return {
@@ -130,7 +136,7 @@ function createApiDevice(options, logger) {
130
136
  };
131
137
  };
132
138
  const getConfidentialityKey = async () => {
133
- const res = await deviceApi.post("/get-confidentiality-key", { seed });
139
+ const res = await deviceApi.post("/get-confidentiality-key", { seed: await getSeed() });
134
140
  return {
135
141
  confidentialityKeyCurve25519: res.data.confidentiality_key_curve25519,
136
142
  confidentialityKeySignature: res.data.confidentiality_key_signature
@@ -140,7 +146,9 @@ function createApiDevice(options, logger) {
140
146
  return getPublicKey({ path: PATHS.CONFIDENTIALITY });
141
147
  };
142
148
  const getDeviceUserId = async () => {
143
- const res = await deviceApi.post("/blue-device-id", { seed });
149
+ const res = await deviceApi.post("/blue-device-id", {
150
+ seed: await getSeed()
151
+ });
144
152
  return res.data.blue_device_id.toUpperCase();
145
153
  };
146
154
  const getU2FPubKey = async () => {
@@ -150,13 +158,13 @@ function createApiDevice(options, logger) {
150
158
  return getPublicKey({ path: PATHS.VALIDATION });
151
159
  };
152
160
  const hasPairing = async () => {
153
- const res = await deviceApi.post("/get-partition-ids", { seed });
161
+ const res = await deviceApi.post("/get-partition-ids", { seed: await getSeed() });
154
162
  return res.data.length > 0;
155
163
  };
156
164
  const initPairingHandshake = async () => {
157
165
  const { data } = await deviceApi.post(
158
166
  "/initiate-pairing-handshake",
159
- { seed }
167
+ { seed: await getSeed() }
160
168
  );
161
169
  return {
162
170
  pubKey: data.pubKey,
@@ -176,7 +184,7 @@ function createApiDevice(options, logger) {
176
184
  attestationCertificate
177
185
  ]);
178
186
  const payload = {
179
- seed,
187
+ seed: await getSeed(),
180
188
  path: PATHS.CONFIDENTIALITY,
181
189
  pubKey: secureChannel.pubKey,
182
190
  attestation: attestation.toString("hex"),
@@ -190,7 +198,7 @@ function createApiDevice(options, logger) {
190
198
  const register = async (params) => {
191
199
  const { challenge, u2fRegisterData, name, role } = params;
192
200
  const payload = {
193
- seed,
201
+ seed: await getSeed(),
194
202
  challenge,
195
203
  name,
196
204
  role: STR_ROLES[role],
@@ -215,13 +223,13 @@ function createApiDevice(options, logger) {
215
223
  };
216
224
  const registerData = async (params) => {
217
225
  const { challenge } = params;
218
- const payload = { seed, challenge };
226
+ const payload = { seed: await getSeed(), challenge };
219
227
  const res = await deviceApi.post("/u2f-register-data", payload);
220
228
  return res.data;
221
229
  };
222
230
  const setPairing = async ({ pairing }) => {
223
231
  const payload = {
224
- seed,
232
+ seed: await getSeed(),
225
233
  blob: pairing.blob,
226
234
  pairing: {
227
235
  bootstrap_enabled: pairing.pairing.bootstrapEnabled,
@@ -239,7 +247,7 @@ function createApiDevice(options, logger) {
239
247
  };
240
248
  const startKKPatternAsResponder = async (params) => {
241
249
  const payload = {
242
- seed,
250
+ seed: await getSeed(),
243
251
  script_id: SCRIPT_IDS.ACCOUNT_MANAGER_SESSION,
244
252
  handshake: params.handshake,
245
253
  // for device-api it's normal to have empty string as handshake_attestation
@@ -257,7 +265,7 @@ function createApiDevice(options, logger) {
257
265
  const startKPatternAsResponder = async (params) => {
258
266
  const { handshake, partitionId } = params;
259
267
  const payload = {
260
- seed,
268
+ seed: await getSeed(),
261
269
  script_id: SCRIPT_IDS.ACCOUNT_MANAGER_SESSION,
262
270
  handshake,
263
271
  // for device-api it's normal to have empty string as handshake_attestation
@@ -274,7 +282,7 @@ function createApiDevice(options, logger) {
274
282
  };
275
283
  const getPublicKey = async (params) => {
276
284
  const { path } = params;
277
- const payload = { seed, secp256k1: true, path };
285
+ const payload = { seed: await getSeed(), secp256k1: true, path };
278
286
  const res = await deviceApi.post("/get-public-key", payload);
279
287
  return {
280
288
  pubKey: res.data.pubKey,
@@ -284,7 +292,7 @@ function createApiDevice(options, logger) {
284
292
  const validateVaultOperation = async (params) => {
285
293
  const { actions } = params;
286
294
  const payload = {
287
- seed,
295
+ seed: await getSeed(),
288
296
  path: PATHS.VALIDATION,
289
297
  actions
290
298
  };
@@ -497,4 +505,4 @@ var withDevicePolling = (deviceId) => (job, acceptError = () => false) => withDe
497
505
 
498
506
 
499
507
  exports.PATHS = PATHS; exports.STATUS_LENGTH = STATUS_LENGTH; exports.SCRIPT_IDS = SCRIPT_IDS; exports.STR_ROLES = STR_ROLES; exports.APPID_VAULT_ADMINISTRATOR = APPID_VAULT_ADMINISTRATOR; exports.PAGINATED_STATUS = PAGINATED_STATUS; exports.STREAMING_RESPONSE = STREAMING_RESPONSE; exports.STREAMING_NEXT_ACTION = STREAMING_NEXT_ACTION; exports.createApiDevice = createApiDevice; exports.isTransportStatusError = isTransportStatusError; exports.isDeviceCancelError = isDeviceCancelError; exports.registerTransportModule = registerTransportModule; exports.withDevicePolling = withDevicePolling;
500
- //# sourceMappingURL=chunk-B5EUR3HT.cjs.map
508
+ //# sourceMappingURL=chunk-KS6SB3HR.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/_work/revault/revault/packages/sdk/lib/chunk-KS6SB3HR.cjs","../src/device/api-device.ts","../src/device/constants.ts","../src/device/utils.ts","../src/device/device-access.ts"],"names":["TransportStatusError"],"mappings":"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","file":"/home/runner/_work/revault/revault/packages/sdk/lib/chunk-KS6SB3HR.cjs","sourcesContent":[null,"import type {\n HsmCertificate,\n PsdAuthChallengeResponse,\n PsdPairingData,\n PubKey,\n} from \"@ledgerhq/revault-api\";\nimport axios from \"axios\";\nimport axiosRetry from \"axios-retry\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport type { Logger } from \"@/logger\";\n\nimport { APPID_VAULT_ADMINISTRATOR, PATHS, SCRIPT_IDS, STR_ROLES } from \"./constants\";\nimport type { Device } from \"./types\";\n\ntype Options = {\n /**\n * device-api URL\n */\n deviceApiUrl: string;\n\n /**\n * salt used by device-api\n */\n salt: string;\n\n /**\n * seed generation function used for device-api device spawn\n */\n genSeed: (p: { salt: string; index: number }) => string | Promise<string>;\n};\n\nexport type ApiDevice = {\n /**\n * bind a device to the given device index\n */\n with: (index: number) => Device;\n};\n\nexport function createApiDevice(options: Options, logger: Logger): ApiDevice {\n const { genSeed } = options;\n const sessionId = uuidv4();\n const deviceApi = axios.create({ baseURL: options.deviceApiUrl });\n\n axiosRetry(deviceApi, {\n retryDelay: axiosRetry.linearDelay(1000),\n retries: 3,\n /* v8 ignore start */\n retryCondition: () => true,\n onRetry: (retryCount, err) => {\n const formattedErr = `${err.code ?? `UNKNOWN`} on ${err.config?.method?.toUpperCase() ?? \"UNKNOWN_METHOD\"} ${err.config?.url ?? \"UNKNOWN_URL\"}`;\n logger.warning(\n `Retrying request to device-api (attempt ${retryCount}) - Cause: ${formattedErr}`,\n );\n },\n /* v8 ignore stop */\n });\n\n deviceApi.interceptors.request.use(\n (config) => {\n /* v8 ignore start */\n logger.debug(\n `[device-api] ${config.method?.toUpperCase()} ${config.url}${config.data ? ` ${JSON.stringify(config.data)}` : \"\"}`,\n );\n if ([\"post\", \"put\"].includes(config.method!)) {\n // when interceptor is called in combination with axios-retry, config.data can be a string or an object\n // and we should return either a string or an object compatible with the original type\n const isStringMode = typeof config.data === \"string\";\n const data = (isStringMode ? JSON.parse(config.data) : config.data) as Record<\n string,\n unknown\n >;\n const enhancedData = {\n sessionID: sessionId, // Used to ensure dedicated session if someones else uses same seed\n psd_model: \"02\", // Stax\n version: 3, // Used to properly enable noise channel\n ...data,\n };\n config.data = isStringMode ? JSON.stringify(enhancedData) : enhancedData;\n }\n return config;\n },\n /* v8 ignore stop */\n (error: Error) => Promise.reject(error),\n );\n\n return {\n with: (index: number): Device => {\n const __seed = genSeed({ salt: options.salt, index });\n\n const getSeed = async (): Promise<string> => {\n if (typeof __seed === \"string\") return Promise.resolve(__seed);\n return __seed;\n };\n\n const authenticate = async ({\n challenge,\n workspaceName,\n }: {\n challenge: PsdAuthChallengeResponse;\n workspaceName: string;\n }): Promise<string> => {\n const role = challenge.role;\n if (role === \"READ_ONLY_API_KEY\")\n throw new Error(\"Invalid role for authenticate: READ_ONLY_API_KEY\");\n const { data } = await deviceApi.post<string>(\"/authenticate\", {\n seed: await getSeed(),\n challenge: Buffer.from(challenge.challenge, \"base64\").toString(\"hex\"),\n application: APPID_VAULT_ADMINISTRATOR,\n key_handle: challenge.keyHandle,\n name: challenge.name,\n role: STR_ROLES[role],\n type: \"02\", // Stax\n workspaceName,\n });\n return data;\n };\n\n const finalizePairingHandshake = async (params: {\n handshake: string;\n partitionId: string;\n }): Promise<string> => {\n const { handshake, partitionId } = params;\n const payload = { seed: await getSeed(), handshake, ciphertext: partitionId };\n const res = await deviceApi.post<string>(\"/finalize-pairing-handshake\", payload);\n return res.data;\n };\n\n const generateSeedFragment = async (): Promise<string> => {\n const payload = {\n seed: await getSeed(),\n path: PATHS.KEY_MATERIAL,\n goal: 0, // seed fragment\n };\n const { data } = await deviceApi.post<string>(\"/generate-key-component\", payload);\n return data;\n };\n\n const generateWrappingKeyFragment = async (): Promise<string> => {\n const goal = 1; // means Wrapping Key\n const payload = { seed: await getSeed(), goal, path: PATHS.KEY_MATERIAL };\n const res = await deviceApi.post<string>(\"/generate-key-fragments\", payload);\n return Buffer.from(res.data, \"hex\").toString(\"base64\");\n };\n\n const getAttestation = async (): Promise<{\n attestation: {\n codeHash: string;\n attestationPub: string;\n certificate: string;\n };\n buffer: Buffer;\n }> => {\n const { data: attestationStr } = await deviceApi.post<string>(\"/get-attestation\", {\n seed: await getSeed(),\n });\n const attestationBuffer = Buffer.from(attestationStr, \"hex\");\n const certLen = attestationBuffer.readInt8(32 + 65 + 1);\n return {\n attestation: {\n codeHash: attestationBuffer.slice(0, 32).toString(\"base64\"),\n attestationPub: attestationBuffer.slice(32, 32 + 65).toString(\"base64\"),\n certificate: attestationBuffer.slice(32 + 65, 32 + 65 + 2 + certLen).toString(\"base64\"),\n },\n buffer: attestationBuffer,\n };\n };\n\n const getConfidentialityKey = async (): Promise<{\n confidentialityKeyCurve25519: string;\n confidentialityKeySignature: string;\n }> => {\n const res = await deviceApi.post<{\n confidentiality_key_curve25519: string;\n confidentiality_key_signature: string;\n }>(\"/get-confidentiality-key\", { seed: await getSeed() });\n return {\n confidentialityKeyCurve25519: res.data.confidentiality_key_curve25519,\n confidentialityKeySignature: res.data.confidentiality_key_signature,\n };\n };\n\n const getConfidentialityPubKey = async (): Promise<{ pubKey: string; signature: string }> => {\n return getPublicKey({ path: PATHS.CONFIDENTIALITY });\n };\n\n const getDeviceUserId = async (): Promise<string> => {\n const res = await deviceApi.post<{ blue_device_id: string }>(\"/blue-device-id\", {\n seed: await getSeed(),\n });\n return res.data.blue_device_id.toUpperCase();\n };\n\n const getU2FPubKey = async (): Promise<{ pubKey: string; signature: string }> => {\n return getPublicKey({ path: PATHS.U2F });\n };\n\n const getValidationPubKey = async (): Promise<{ pubKey: string; signature: string }> => {\n return getPublicKey({ path: PATHS.VALIDATION });\n };\n\n const hasPairing = async (): Promise<boolean> => {\n const res = await deviceApi.post<string[]>(\"/get-partition-ids\", { seed: await getSeed() });\n return res.data.length > 0;\n };\n\n const initPairingHandshake = async (): Promise<{ pubKey: string; signature: string }> => {\n const { data } = await deviceApi.post<{ attestation: string; pubKey: string }>(\n \"/initiate-pairing-handshake\",\n { seed: await getSeed() },\n );\n return {\n pubKey: data.pubKey,\n signature: Buffer.from(data.attestation, \"hex\").toString(\"base64\"),\n };\n };\n\n const openSession = async (params: {\n secureChannel: { pubKey: PubKey; certificate: HsmCertificate };\n }): Promise<void> => {\n const { secureChannel } = params;\n const signature = Buffer.from(secureChannel.certificate.signature, \"base64\");\n const attestationPubKey = Buffer.from(secureChannel.certificate.attestationPub, \"base64\");\n const attestationCertificate = Buffer.from(secureChannel.certificate.certificate, \"base64\");\n const attestation = Buffer.concat([\n Buffer.from([signature.length]),\n signature,\n attestationPubKey,\n Buffer.from([attestationCertificate.length]),\n attestationCertificate,\n ]);\n const payload = {\n seed: await getSeed(),\n path: PATHS.CONFIDENTIALITY,\n pubKey: secureChannel.pubKey,\n attestation: attestation.toString(\"hex\"),\n scriptId: SCRIPT_IDS.INIT_SESSION,\n };\n const { data: deviceResponse } = await deviceApi.post<string>(\"/open-session\", payload);\n if (deviceResponse !== \"9000\") {\n throw new Error(`device-api device failed with code: ${deviceResponse}`);\n }\n };\n\n const register = async (params: {\n challenge: string;\n u2fRegisterData: string;\n name: string;\n role: \"ADMIN\" | \"SHARED_OWNER\" | \"OPERATOR\";\n }): Promise<{\n u2fRegister: Buffer;\n keyHandle: Buffer;\n rfu: number;\n pubKey: string;\n }> => {\n const { challenge, u2fRegisterData, name, role } = params;\n const payload = {\n seed: await getSeed(),\n challenge,\n name,\n role: STR_ROLES[role],\n hsm_data: u2fRegisterData,\n type: \"02\", // Stax\n application: APPID_VAULT_ADMINISTRATOR,\n };\n const { data } = await deviceApi.post<string>(\"/register\", payload);\n const response = Buffer.from(data, \"hex\");\n let i = 0;\n const rfu = response.slice(i, (i += 1))[0]!;\n const pubKey = response.slice(i, (i += 65)).toString(\"hex\");\n const keyHandleLength = response.slice(i, ++i)[0]!;\n const keyHandle = response.slice(i, (i += keyHandleLength));\n return {\n u2fRegister: response.slice(0, response.length - 2),\n keyHandle,\n rfu,\n pubKey,\n };\n };\n\n const registerData = async (params: { challenge: string }): Promise<string> => {\n const { challenge } = params;\n const payload = { seed: await getSeed(), challenge };\n const res = await deviceApi.post<string>(\"/u2f-register-data\", payload);\n return res.data;\n };\n\n const setPairing = async ({ pairing }: { pairing: PsdPairingData }): Promise<void> => {\n const payload = {\n seed: await getSeed(),\n blob: pairing.blob,\n pairing: {\n bootstrap_enabled: pairing.pairing.bootstrapEnabled,\n partition_key: pairing.pairing.partitionKey,\n workspace_name: pairing.pairing.workspaceName,\n },\n partition_key_attestation: {\n code_hash: pairing.partitionKeyAttestation.codeHash,\n attestation_pub: pairing.partitionKeyAttestation.attestationPub,\n certificate: pairing.partitionKeyAttestation.certificate,\n signature: pairing.partitionKeyAttestation.signature,\n },\n };\n await deviceApi.post(\"/set-partition-key\", payload);\n };\n\n const startKKPatternAsResponder = async (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n }): Promise<{ handshake: string; signature: string }> => {\n const payload = {\n seed: await getSeed(),\n script_id: SCRIPT_IDS.ACCOUNT_MANAGER_SESSION,\n handshake: params.handshake,\n // for device-api it's normal to have empty string as handshake_attestation\n handshake_attestation: \"\",\n partition_id: params.partitionId,\n };\n const { data } = await deviceApi.post<string>(\"/start-kk-pattern-as-responder\", payload);\n const buffer = Buffer.from(data, \"hex\");\n const dataLength = buffer.readInt8(0);\n return {\n handshake: buffer.slice(1, dataLength + 1).toString(\"base64\"),\n signature: buffer.slice(dataLength + 1).toString(\"base64\"),\n };\n };\n\n const startKPatternAsResponder = async (params: {\n handshake: string;\n handshakeAttestation: HsmCertificate;\n partitionId: string;\n }): Promise<void> => {\n const { handshake, partitionId } = params;\n const payload = {\n seed: await getSeed(),\n script_id: SCRIPT_IDS.ACCOUNT_MANAGER_SESSION,\n handshake,\n // for device-api it's normal to have empty string as handshake_attestation\n handshake_attestation: \"\",\n partition_id: partitionId,\n };\n const { data: deviceResponse } = await deviceApi.post<string>(\n \"/start-k-pattern-as-responder\",\n payload,\n );\n if (deviceResponse !== \"9000\") {\n throw new Error(`device-api device failed with code: ${deviceResponse}`);\n }\n };\n\n const getPublicKey = async (params: {\n path: string;\n }): Promise<{ pubKey: string; signature: string }> => {\n const { path } = params;\n type DeviceApiGetPubKeyResponse = { attestation: string; pubKey: string };\n const payload = { seed: await getSeed(), secp256k1: true, path };\n const res = await deviceApi.post<DeviceApiGetPubKeyResponse>(\"/get-public-key\", payload);\n return {\n pubKey: res.data.pubKey,\n signature: Buffer.from(res.data.attestation, \"hex\").toString(\"base64\"),\n };\n };\n\n const validateVaultOperation = async (params: { actions: string[] }): Promise<string> => {\n const { actions } = params;\n const payload = {\n seed: await getSeed(),\n path: PATHS.VALIDATION,\n actions,\n };\n const { data: signature } = await deviceApi.post<string>(\"/validate-op\", payload);\n return signature;\n };\n\n const sendAPDU = (_apdu: string): Promise<string> => {\n logger.info(\"Can't send arbitrary APDU to software device\");\n return Promise.resolve(\"9000\");\n };\n\n const getVersion = async (): Promise<string> => {\n return \"1.2.3\";\n };\n\n const poll = async (): Promise<{ isAppOpened: boolean }> => {\n await new Promise((r) => setTimeout(r, 1e3));\n return { isAppOpened: true };\n };\n\n const pollApp = async (): Promise<string> => {\n await new Promise((r) => setTimeout(r, 1e3));\n return \"9000\";\n };\n\n return {\n authenticate,\n finalizePairingHandshake,\n generateSeedFragment,\n generateWrappingKeyFragment,\n getAttestation,\n getConfidentialityKey,\n getConfidentialityPubKey,\n getDeviceUserId,\n getU2FPubKey,\n getValidationPubKey,\n hasPairing,\n initPairingHandshake,\n openSession,\n register,\n registerData,\n setPairing,\n startKKPatternAsResponder,\n startKPatternAsResponder,\n validateVaultOperation,\n getVersion,\n sendAPDU,\n poll,\n pollApp,\n };\n },\n };\n}\n","export const PATHS = {\n U2F: \"5655636'/5583430'\",\n CONFIDENTIALITY: \"5655636'/4410950'\",\n KEY_MATERIAL: \"5655636'/4932953'\",\n VALIDATION: \"5655636'/5652812'\",\n} as const;\n\nexport const STATUS_LENGTH = 2;\n\nexport const SCRIPT_IDS = {\n INIT_SESSION: 3,\n ACCOUNT_MANAGER_SESSION: 2,\n} as const;\n\nexport const STR_ROLES: Record<\"OPERATOR\" | \"ADMIN\" | \"SHARED_OWNER\", string> = {\n OPERATOR: \"00\",\n ADMIN: \"01\",\n SHARED_OWNER: \"02\",\n} as const;\n\nexport const APPID_VAULT_ADMINISTRATOR =\n \"ad5be1a1fe011ce7f53ae081a22ae000a42021f3f94106a3bac9f76e8230e4b9\";\n\nconst all61xxStatus = [];\nfor (let i = 0x6100; i <= 0x61ff; i++) {\n all61xxStatus.push(i);\n}\n\nexport const PAGINATED_STATUS = all61xxStatus;\nexport const STREAMING_RESPONSE = 0x02;\nexport const STREAMING_NEXT_ACTION = 0x01;\n","import { TransportStatusError } from \"@ledgerhq/errors\";\n\nexport const isTransportStatusError = (error: unknown): error is TransportStatusError => {\n return (\n error instanceof TransportStatusError ||\n (error instanceof Error && \"statusCode\" in error && error.message.startsWith(\"Ledger device:\"))\n );\n};\n\nconst CANCEL_STATUS_CODES = [\n 0x6985, // cancel on Ledger Blue\n\n // STAX\n 0xb00c, // cancel collect wk fragment\n 0xb00d, // cancel user registration\n 0xb010, // cancel review\n 0xb012, // cancel master seed generation\n 0xb013, // cancel login\n];\n\nexport const isDeviceCancelError = (error: Error): boolean => {\n return isTransportStatusError(error) && CANCEL_STATUS_CODES.includes(error.statusCode);\n};\n","// ------------------------------------------------------------------------------------------------\n// ------------------------------------------------------------------------------------------------\n// THIS IS SOME HORRIBLE CODE IMPORTED JUST\n// FOR THE SAKE OF NOT IMPORTING UGLY, WICKED, AND\n// BROKEN @ledgerhq/live-* LIBRARIES\n//\n// IT'S MEANT TO BE CONSIDERED AS A BLACK BOX\n// ------------------------------------------------------------------------------------------------\n// ------------------------------------------------------------------------------------------------\nimport {\n BluetoothRequired,\n CantOpenDevice,\n DeviceHalted,\n FirmwareOrAppUpdateRequired,\n TransportInterfaceNotAvailable,\n TransportStatusError,\n TransportWebUSBGestureRequired,\n} from \"@ledgerhq/errors\";\nimport type Transport from \"@ledgerhq/hw-transport\";\nimport { Observable, throwError, timer } from \"rxjs\";\nimport { catchError, mergeMap, retryWhen } from \"rxjs/operators\";\n\nconst initialErrorRemapping = (error: Error): Observable<never> =>\n throwError(\n error && error instanceof TransportStatusError && error.statusCode === 0x6faa\n ? new DeviceHalted(error.message)\n : error instanceof TransportStatusError && error.statusCode === 0x6b00\n ? new FirmwareOrAppUpdateRequired(error.message)\n : error,\n );\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nconst never = new Promise(() => {});\n\ntype Discovery = Observable<{\n type: \"add\" | \"remove\";\n id: string;\n name: string;\n}>;\n\nexport type TransportModule = {\n // unique transport name that identify the transport module\n id: string;\n // open a device by an id, this id must be unique across all modules\n // you can typically prefix it with `something|` that identify it globally\n // returns falsy if the transport module can't handle this id\n // here, open means we want to START doing something with the transport\n open: (id: string) => Promise<Transport> | null | undefined;\n // here, close means we want to STOP doing something with the transport\n close?: (transport: Transport, id: string) => Promise<void> | null | undefined;\n // disconnect/interrupt a device connection globally\n // returns falsy if the transport module can't handle this id\n disconnect: (id: string) => Promise<void> | null | undefined;\n // optional observable that allows to discover a transport\n discovery?: Discovery;\n};\n\nconst modules: TransportModule[] = [];\n\nexport const registerTransportModule = (module: TransportModule): void => {\n modules.push(module);\n};\n\nexport const close = (transport: Transport, deviceId: string): Promise<void> => {\n for (const m of modules) {\n const p = m.close?.(transport, deviceId);\n if (p) return p;\n }\n // fallback on an actual close\n return transport.close();\n};\n\nexport const open = (deviceId: string): Promise<Transport> => {\n for (const m of modules) {\n const p = m.open(deviceId);\n if (p) return p;\n }\n return Promise.reject(new Error(`Can't find handler to open ${deviceId}`));\n};\n\nconst transportFinally =\n (cleanup: () => Promise<void>) =>\n <T>(observable: Observable<T>): Observable<T> =>\n // @ts-expect-error typescript not checking against the instanceof\n Observable.create((o) => {\n let done = false;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const finalize = (): any => {\n if (done) return never;\n done = true;\n return cleanup();\n };\n\n const sub = observable.subscribe({\n next: (e) => o.next(e),\n complete: () => {\n void finalize().then(() => o.complete());\n },\n error: (e) => {\n void finalize().then(() => o.error(e));\n },\n });\n return () => {\n sub.unsubscribe();\n void finalize();\n };\n });\n\ntype AccessHook = () => () => void;\n\nconst accessHooks: AccessHook[] = [];\n\nconst deviceQueues = {};\n\nexport const withDevice =\n (deviceId: string) =>\n <T>(job: (t: Transport) => Observable<T>): Observable<T> =>\n new Observable((o) => {\n // @ts-expect-error typescript not checking against the instanceof\n let unsubscribed;\n // @ts-expect-error typescript not checking against the instanceof\n let sub;\n // @ts-expect-error typescript not checking against the instanceof\n const deviceQueue = deviceQueues[deviceId] ?? Promise.resolve();\n\n // @ts-expect-error typescript not checking against the instanceof\n const finalize = (transport, cleanups): Promise<void> =>\n close(transport, deviceId)\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n .catch(() => {})\n .then(() => {\n // @ts-expect-error typescript not checking against the instanceof\n cleanups.forEach((c) => c());\n });\n\n // when we'll finish all the current job, we'll call finish\n // @ts-expect-error typescript not checking against the instanceof\n let finish;\n // this new promise is the next exec queue\n // @ts-expect-error typescript not checking against the instanceof\n deviceQueues[deviceId] = new Promise((resolve) => {\n finish = resolve;\n });\n // for any new job, we'll now wait the exec queue to be available\n deviceQueue\n .then(() => open(deviceId)) // open the transport\n // @ts-expect-error typescript not checking against the instanceof\n .then(async (transport) => {\n // @ts-expect-error typescript not checking against the instanceof\n if (unsubscribed) {\n // it was unsubscribed prematurely\n // @ts-expect-error typescript not checking against the instanceof\n return finalize(transport, [finish]);\n }\n\n if (\n transport.requestConnectionPriority &&\n typeof transport.requestConnectionPriority === \"function\"\n ) {\n await transport.requestConnectionPriority(\"High\");\n }\n\n return transport;\n })\n // @ts-expect-error typescript not checking against the instanceof\n .catch((e) => {\n // @ts-expect-error typescript not checking against the instanceof\n finish();\n if (e instanceof BluetoothRequired) throw e;\n if (e instanceof TransportWebUSBGestureRequired) throw e;\n if (e instanceof TransportInterfaceNotAvailable) throw e;\n throw new CantOpenDevice(e.message);\n })\n // @ts-expect-error typescript not checking against the instanceof\n .then((transport) => {\n if (!transport) return;\n\n // @ts-expect-error typescript not checking against the instanceof\n if (unsubscribed) {\n // it was unsubscribed prematurely\n // @ts-expect-error typescript not checking against the instanceof\n return finalize(transport, [finish]);\n }\n\n const cleanups = accessHooks.map((hook) => hook());\n sub = job(transport) // $FlowFixMe\n .pipe(\n catchError(initialErrorRemapping),\n // $FlowFixMe\n transportFinally(() =>\n // @ts-expect-error typescript not checking against the instanceof\n finalize(transport, [...cleanups, finish]),\n ),\n )\n .subscribe(o);\n })\n // @ts-expect-error typescript not checking against the instanceof\n .catch((error) => o.error(error));\n return () => {\n unsubscribed = true;\n // @ts-expect-error typescript not checking against the instanceof\n if (sub) sub.unsubscribe();\n };\n });\n\nconst WITH_DEVICE_POLLING_DELAY = 500;\n\nexport const retryWhileErrors =\n (acceptError: (arg0: Error) => boolean) =>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (attempts: Observable<any>): Observable<any> =>\n attempts.pipe(\n mergeMap((error) => {\n if (!acceptError(error)) {\n return throwError(error);\n }\n\n return timer(WITH_DEVICE_POLLING_DELAY);\n }),\n );\n\nexport const withDevicePolling =\n (deviceId: string) =>\n <T>(\n job: (arg0: Transport) => Observable<T>,\n acceptError: (arg0: Error) => boolean = () => false,\n ): Observable<T> =>\n withDevice(deviceId)(job).pipe(retryWhen(retryWhileErrors(acceptError)));\n"]}