Skip to content

Prolink createProlinkUrl missing from Node build; sub-account personal_sign hex-encoding requirement breaks the repo's own Storybook example #368

Description

@Kajko25

Found while building an agent (Kokosh) that exercises @base-org/account v2.5.7 end-to-end on Base mainnet (sub accounts + prolinks). Both reproduced against the installed npm package, not just inferred from docs.

1. createProlinkUrl missing from the Node build; docs' root-package import doesn't work at all in v2.5.7

docs.base.org's prolink pages (encodeProlink, decodeProlink, createProlinkUrl) all show:

import { encodeProlink } from '@base-org/account';

In the installed v2.5.7 package, none of encodeProlink/decodeProlink/createProlinkUrl are exported from the package root at all — confirmed by listing Object.keys(await import('@base-org/account')), which does not include any of them. They're only reachable via the /prolink subpath:

import { encodeProlink, decodeProlink } from '@base-org/account/prolink';

And even that subpath is incomplete for Node: package.json's exports["./prolink"].node points at dist/interface/public-utilities/prolink/index.node.js, which only exports encodeProlink/decodeProlinkcreateProlinkUrl is only re-exported from the browser build (dist/interface/public-utilities/prolink/index.js, via export { createProlinkUrl } from './createProlinkUrl.js'). Importing createProlinkUrl from @base-org/account/prolink in a Node script throws:

SyntaxError: The requested module '@base-org/account/prolink' does not provide an export named 'createProlinkUrl'

Worked around by inlining the (trivial) URL-building logic rather than importing it. Either the root package should re-export the prolink utilities (matching the docs' import path), or index.node.js should re-export createProlinkUrl alongside encodeProlink/decodeProlink (it has no browser-only dependency — it's pure URL/query-param construction).

2. Sub-account signer's personal_sign requires a pre-hex-encoded message, contradicting the SDK's own Storybook example

dist/sign/base-account/utils/createSubAccountSigner.js:

case 'personal_sign': {
    assertArrayPresence(args.params);
    // Param is expected to be a hex encoded string
    if (!isHex(args.params[0])) {
        throw standardErrors.rpc.invalidParams('message must be a hex encoded string');
    }
    const message = hexToString(args.params[0]);
    return account.signMessage({ message });
}

So calling personal_sign against a sub account requires params[0] to already be 0x-prefixed hex bytes of the message — the opposite of the usual EIP-1193 convention (and of personal_sign against the universal account, which accepts a plain string).

This repo's own Storybook example (storybook/stories/components/smart-wallet/SubAccount.tsx) passes a plain string to both:

// Universal Account Signing Function
const hash = await provider.request({
  method: "personal_sign",
  params: ["Hello, world!", universalAccount],
});

// Sub Account Signing Function
const hash = await provider.request({
  method: "personal_sign",
  params: ["Hello, world!", subAccount],
});

Against the current shipped 2.5.7 behavior, the sub-account call would throw invalidParams('message must be a hex encoded string') — the storybook example doesn't hex-encode "Hello, world!" first. Either the storybook example is stale (worth fixing so it doesn't silently break for anyone copying it), or createSubAccountSigner's personal_sign should accept a plain UTF-8 string like the universal-account path does, for parity with EIP-1193 convention.


Both reproduced while building https://github.com/Kajko25/kokosh (JOURNAL.md has the full reproduction trail with tx hashes) and while updating base/skills#148.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions