createProlinkUrl missing from Node build; sub-account personal_sign requires hex while universal path does not
- Dominant language
- TypeScript
- Stars
- 172
- Forks
- 207
- Avg merge
- 49m
- Merged PRs (30d)
- 1
Description
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:
```typescript
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:
```typescript
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`/`decodeProlink` — `createProlinkUrl` 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`:
```javascript
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:
```javascript
// 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.
Contributor guide
Research direction
Start with package.json's ./prolink exports and dist/interface/public-utilities/prolink/index.node.js, then inspect dist/sign/base-account/utils/createSubAccountSigner.js and storybook/stories/components/smart-wallet/SubAccount.tsx. Verify the intended fix for both reported behaviors, ensure the documented Node import and sub-account personal_sign example work consistently, and confirm the relevant exports and validation no longer contradict each other.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, storybook, typescript
- Domain
- api, build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100