UNPKG

@lukasrosario/account

Version:

Base Account SDK

107 lines (93 loc) 3.17 kB
import { standardErrors } from ':core/error/errors.js'; import { RequestArguments } from ':core/provider/interface.js'; import { OwnerAccount } from ':core/type/index.js'; import { getClient } from ':store/chain-clients/utils.js'; import { store } from ':store/store.js'; import { assertPresence } from ':util/assertPresence.js'; import { decodeAbiParameters, encodeFunctionData, numberToHex, toHex } from 'viem'; import { waitForCallsStatus } from 'viem/experimental'; import { abi } from './constants.js'; import { findOwnerIndex } from './findOwnerIndex.js'; import { presentAddOwnerDialog } from './presentAddOwnerDialog.js'; export async function handleAddSubAccountOwner({ ownerAccount, globalAccountRequest, }: { ownerAccount: OwnerAccount; globalAccountRequest: (request: RequestArguments) => Promise<unknown>; }) { const account = store.account.get(); const subAccount = store.subAccounts.get(); const globalAccount = account.accounts?.find( (account) => account.toLowerCase() !== subAccount?.address.toLowerCase() ); assertPresence(globalAccount, standardErrors.provider.unauthorized('no global account')); assertPresence(account.chain?.id, standardErrors.provider.unauthorized('no chain id')); assertPresence(subAccount?.address, standardErrors.provider.unauthorized('no sub account')); const calls = []; if (ownerAccount.type === 'local' && ownerAccount.address) { calls.push({ to: subAccount.address, data: encodeFunctionData({ abi, functionName: 'addOwnerAddress', args: [ownerAccount.address] as const, }), value: toHex(0), }); } if (ownerAccount.publicKey) { const [x, y] = decodeAbiParameters( [{ type: 'bytes32' }, { type: 'bytes32' }], ownerAccount.publicKey ); calls.push({ to: subAccount.address, data: encodeFunctionData({ abi, functionName: 'addOwnerPublicKey', args: [x, y] as const, }), value: toHex(0), }); } const request: RequestArguments = { method: 'wallet_sendCalls', params: [ { version: '1', calls, chainId: numberToHex(84532), from: globalAccount, }, ], }; const selection = await presentAddOwnerDialog(); if (selection === 'cancel') { throw standardErrors.provider.unauthorized('user cancelled'); } const callsId = (await globalAccountRequest(request)) as string; const client = getClient(account.chain.id); assertPresence( client, standardErrors.rpc.internal(`client not found for chainId ${account.chain.id}`) ); const callsResult = await waitForCallsStatus(client, { id: callsId, }); if (callsResult.status !== 'success') { throw standardErrors.rpc.internal('add owner call failed'); } const ownerIndex = await findOwnerIndex({ address: subAccount.address, publicKey: ownerAccount.type === 'local' && ownerAccount.address ? ownerAccount.address : ownerAccount.publicKey, client, }); if (ownerIndex === -1) { throw standardErrors.rpc.internal('failed to find owner index'); } return ownerIndex; }