Agent-js does not work in Next.js SSG

Am I doing something wrong, or does the @dfinity/agent not work in the Next.js SSG context?

In a pre-rendered Next.js project set for static export (output: "export"), I am defining the request generateStaticParams, which is used to generate the dynamic routes at build time. Within that function, I use the HttpClient to fetch some data, as in this dummy example:

export async function generateStaticParams() {
    const agent = await HttpAgent.create({
        identity: new AnonymousIdentity(),
        host: "https://icp-api.io",
        verifyQuerySignatures: true,
    });

    const actor = Actor.createActor(idlFactory, {
        agent,
        canisterId: "ryjl3-tyaaa-aaaaa-aaaba-cai"
    });

    const {icrc1_balance_of} = actor;

    // ⚠️ ERRORS
    // - Invalid signature from replica
    // - Certificate is signed more than 5 minutes in the past ...
    console.log(await icrc1_balance_of({
        owner: Principal.fromText("2vxsx-fae"),
        subaccount: []
    }))

    return [{product_id: "2vxsx-fae"}]
}

As a result, I end up facing the following errors (one or the other):

Error: Invalid certificate: Invalid signature from replica ncr4b-rasb7-tueb3-n4uos-5nxou-3wbxv-xmyt3-wfdsd-vu4b6-5x3cp-aqe signed query.

or

Error: Invalid certificate: Certificate is signed more than 5 minutes in the past. Certificate time: 2024-08-11T15:55:32.249Z Current time: 2024-08-11T16:03:35.551Z

So I’m wondering if I am doing something wrong or if indeed Agent-js does not work in that context?

This error was reported by a Juno developer, and I am able to reproduce it with a sample repo:

git clone https://github.com/peterpeterparker/next-agentjs
cd next-agentjs
npm ci
npm run dev

Open URL http://localhost:3000/products/2vxsx-fae

1 Like

@peterparker Did you find any workarounds?

Kind of, see this PR.

I’d use createSync for SSG contexts as the simple fix, but the point is probably more to do with fetch or syncTime not working as intended.

I have another reported issue with the syncTime flow, so I’m going to dive into this and get back to you

2 Likes

Hi Any luck fixing this?

Hi @kpeacock, I am also seeing an issue with syncTime where I am being told the time of the server I am using to make calls to the IC is ahead of the IC network. Any update on your investigation into this?

I’ve been able to “solve” the syncTime issue by parsing the error response, but it reveals a fundamental design problem that there’s no secure way to bring a client into agreement with the replica time without first agreeing upon the actual time!

It will be a while before I can ship doing this automatically, but I can instead come up with a flow that allows a developer to override the time manually, and I’ll document a flow for that

2 Likes

I’ll probably roll this into an interface spec proposal as well.

I think the only way to guard against a replay attack is to have an endpoint where you can request the state_tree using a nonce, and to have the nonce reflected back to you, so you can be sure that the replica is responding to your unique request.

Have you made any further progress with this? I am really hoping there is a genuine fix coming in

I thought I had, but then the 2.0.0 release was bugged. Still needs more development, and a proper way to get back a certified time that we could update to. The research team is discussing how certified time could be discovered