I’m using vite, trying to build an extremely simple frontend. I have a simple backend canister that exposes some methods, and I’ve used dfx generate
to generate the agent frontend code. No matter what I do I run into errors on the frontend, as if the agent isn’t really setup to work with anything but a node-polyfilled and opinionated webpack frontend.
This is the latest round of errors:
ror: Failed to parse
at Uint8ArrayDecoder._decode (decoder.js:566:13)
at Uint8ArrayDecoder.decodeFirst (decoder.js:577:10)
at decode3 (cbor.ts:131:18)
at HttpAgent.status (index.ts:528:17)
at async HttpAgent.fetchRootKey (index.ts:534:24)
(anonymous) @ index.js:31
Promise.catch (async)
createActor @ index.js:27
(anonymous) @ index.js:43
ck-app.ts:46 POST http://127.0.0.1:8000/api/v2/canister/7ugoi-yiaaa-aaaaa-aabaa-cai/call 403 (Forbidden)
(anonymous) @ index.ts:325
_requestAndRetry @ index.ts:350
call @ index.ts:324
await in call (async)
caller @ actor.ts:361
handler @ actor.ts:384
getBalance @ ck-app.ts:46
connectedCallback @ ck-app.ts:20
await in connectedCallback (async)
legacyCustomElement @ custom-element.ts:21
(anonymous) @ custom-element.ts:64
__decorateClass @ ck-app.ts:7
(anonymous) @ ck-app.ts:9
Show 7 more frames
ck-app.ts:46 Server returned an error:
Code: 403 (Forbidden)
Body: Failed to authenticate request 0x9c8958c0dcd740d866de9710e19d2a09c59664e106ed390bf77ca647df964387 due to: Invalid delegation: Invalid canister signature: IcCanisterSignature signature could not be verified: public key 0a00000000000000070101364827569d1f66bedaa3311ba159e725920c16783773f549afe4eac95daf8446, signature d9d9f7a26b6365727469666963617465590489d9d9f7a3647472656583018301830183024863616e69737465728301830183024a0000000000000007010183018301830183024e6365727469666965645f6461746182035820d35b0d40c9fd19d39fd20fa1e245a87fe5d14eeb7a42979fe5072956c81ce48782045820fd5b59459758c8afecaf7285da359e4b5adb945fb86a3c1f0efd996c21a96938820458205f037bd92faf11cb7d76ea072ef27ba79499e56ab9344dfeb57609d445dd691182045820aa20324fc55c8061cea61b9b73bb12da019edb6726c5f822a6a1c0cb5abbeee982045820d9ca4c089f657e20f26a6270ebbeb7556f79f598b9120b5b87ccd3bb8e9aadca8204582077f0bb8fe7d6e79bc0060fc41a475527485c94b5bb00d989a77126090a4eccec8204582059607b76078b45de64776b334e2d7f2395c4c2cfddf0f2a8bd35b3591def249e82045820df9c94f7c01a25de910472d76f73e39b020e63266235d64c6ad69620b0f639b7830182045820cc578109fc5dbde591cf79cb3fa6326cdccdd9fa88ea27592ca888824366afe383024474696d6582034997a5aae3aebae4b017697369676e6174757265583097a971738f6cea92494f9c6729f7e3055cb1f59be2c89c390633ec95b6c0f08507faa5551c8abc788c2b30a4c84f60dc6a64656c65676174696f6ea2697375626e65745f6964581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d026b636572746966696361746559026ed9d9f7a264747265658301820458200ec991d75af7076a592939e333a11e1dab4445ede347a645b51246edf9bb15c383018302467375626e657483018301830182045820267fe55111b56e3c3975532ea3373f7b72e9f82072fe8e607ed34486478a5b39830182045820466a70286cf9ace9801ca53e22af6ee059a094fd60498606d484b6854058307d83018301820458208b2f6c15078ae4d3b93470915ca53e373327f37ea74ba1b8177d986bb79b31ae8302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec806820458202c51db7b5650b7a3dbbb8530a7449cc6f90144778b62f20f3c26d72e95e5069882045820a7f251951eed726811460449388214773c94153c758afe3aaa54f9b51704268682045820df1124435df1c9bae1f1344ef3fda6a60f8faf7d06720e35f01349d8a64fc96483024474696d65820349929ab3b2ec94e0b017697369676e617475726558308e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe1206474726565830182045820065064c0e21c1539409dcc408d2ad11e5356c8abe1bbc7f990dd7699784972ca83024373696783025820a45b16124e26ecdf787aa9b91cb89fe95672a3f5483c97d4c95e62ad7ac512278301830258205ebc40cdda83ce2f69e0f9f3c562184e9936c70c578e78604b1316a347448430820340820458207f7ac0667c3dd3c683471af468e8edb2e19dfba234126a57d5b4f9e1a53a4d70, error: certificate verification failed: failed to verify threshold signature: certificate_tree_hash=CryptoHash(0x90990f2030e965348d83cfe74adff9ac769e5769c032a037c2b17d042d622608), sig=Blob{48 bytes;8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120}, pk=ThresholdSigPublicKey { internal: ThresBls12_381(0xa5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214) }, error=ThresBls12_381 signature could not be verified: public key a5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214, signature 8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120, error: Invalid combined threshold signature
Should I expect thedfx generate
code to work in a browser without webpack? If not, what are the expectations here?
2 Likes
I think I have overcome this (by unfortunately adding node polyfills which is undesirable) though I am not sure.
I am now getting these errors:
-app.ts:48 POST http://127.0.0.1:8000/api/v2/canister/7ugoi-yiaaa-aaaaa-aabaa-cai/call 403 (Forbidden)
(anonymous) @ index.ts:325
_requestAndRetry @ index.ts:350
call @ index.ts:324
await in call (async)
caller @ actor.ts:361
handler @ actor.ts:384
getBalance @ ck-app.ts:48
connectedCallback @ ck-app.ts:20
await in connectedCallback (async)
legacyCustomElement @ custom-element.ts:21
(anonymous) @ custom-element.ts:64
__decorateClass @ ck-app.ts:7
(anonymous) @ ck-app.ts:9
Show 7 more frames
ck-app.ts:48 Server returned an error:
Code: 403 (Forbidden)
Body: Failed to authenticate request 0xd8afc1769b8ed135e8f56ca89bb001f60e287d4800d9ee925e18a4aa10738274 due to: Invalid delegation: Invalid canister signature: IcCanisterSignature signature could not be verified: public key 0a00000000000000070101364827569d1f66bedaa3311ba159e725920c16783773f549afe4eac95daf8446, signature d9d9f7a26b6365727469666963617465590489d9d9f7a3647472656583018301830183024863616e69737465728301830183024a0000000000000007010183018301830183024e6365727469666965645f6461746182035820d35b0d40c9fd19d39fd20fa1e245a87fe5d14eeb7a42979fe5072956c81ce48782045820fd5b59459758c8afecaf7285da359e4b5adb945fb86a3c1f0efd996c21a96938820458205f037bd92faf11cb7d76ea072ef27ba79499e56ab9344dfeb57609d445dd691182045820aa20324fc55c8061cea61b9b73bb12da019edb6726c5f822a6a1c0cb5abbeee982045820d9ca4c089f657e20f26a6270ebbeb7556f79f598b9120b5b87ccd3bb8e9aadca8204582077f0bb8fe7d6e79bc0060fc41a475527485c94b5bb00d989a77126090a4eccec8204582059607b76078b45de64776b334e2d7f2395c4c2cfddf0f2a8bd35b3591def249e82045820df9c94f7c01a25de910472d76f73e39b020e63266235d64c6ad69620b0f639b7830182045820cc578109fc5dbde591cf79cb3fa6326cdccdd9fa88ea27592ca888824366afe383024474696d6582034997a5aae3aebae4b017697369676e6174757265583097a971738f6cea92494f9c6729f7e3055cb1f59be2c89c390633ec95b6c0f08507faa5551c8abc788c2b30a4c84f60dc6a64656c65676174696f6ea2697375626e65745f6964581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d026b636572746966696361746559026ed9d9f7a264747265658301820458200ec991d75af7076a592939e333a11e1dab4445ede347a645b51246edf9bb15c383018302467375626e657483018301830182045820267fe55111b56e3c3975532ea3373f7b72e9f82072fe8e607ed34486478a5b39830182045820466a70286cf9ace9801ca53e22af6ee059a094fd60498606d484b6854058307d83018301820458208b2f6c15078ae4d3b93470915ca53e373327f37ea74ba1b8177d986bb79b31ae8302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec806820458202c51db7b5650b7a3dbbb8530a7449cc6f90144778b62f20f3c26d72e95e5069882045820a7f251951eed726811460449388214773c94153c758afe3aaa54f9b51704268682045820df1124435df1c9bae1f1344ef3fda6a60f8faf7d06720e35f01349d8a64fc96483024474696d65820349929ab3b2ec94e0b017697369676e617475726558308e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe1206474726565830182045820065064c0e21c1539409dcc408d2ad11e5356c8abe1bbc7f990dd7699784972ca83024373696783025820a45b16124e26ecdf787aa9b91cb89fe95672a3f5483c97d4c95e62ad7ac512278301830258205ebc40cdda83ce2f69e0f9f3c562184e9936c70c578e78604b1316a347448430820340820458207f7ac0667c3dd3c683471af468e8edb2e19dfba234126a57d5b4f9e1a53a4d70, error: certificate verification failed: failed to verify threshold signature: certificate_tree_hash=CryptoHash(0x90990f2030e965348d83cfe74adff9ac769e5769c032a037c2b17d042d622608), sig=Blob{48 bytes;8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120}, pk=ThresholdSigPublicKey { internal: ThresBls12_381(0xa5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214) }, error=ThresBls12_381 signature could not be verified: public key a5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214, signature 8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120, error: Invalid combined threshold signature
Retrying request.
_
My understanding is that fetchRootKey is now called automatically by createActor, but it doesn’t seem to be working. And when I call it myself it seems to have no effect either. Here’s my frontend code:
async getBalance() {
const agent = new HttpAgent({
host: '127.0.0.1:8000',
identity: this.identity
});
await agent.fetchRootKey();
const walletBackend = createActor('7ugoi-yiaaa-aaaaa-aabaa-cai', {
agent
});
const result = await walletBackend.getBalance();
this.balance = result;
}
I’m running my vite server on http://localhost:5173/
and my replica on http://127.0.0.1:8000
could this have anything to do with it? I haven’t deployed my asset canister, I’m just running a vite server.
Here is a vite config that I’ve been using: auth-client-demo/vite.config.js at main · krpeacock/auth-client-demo · GitHub
I haven’t cleaned it up for a universal dfx new
starter yet, since there are still a couple sticky issues with the way that the fallback canisterIds are handled from dfx generate
, but it should help
1 Like
So you don’t have any node polyfills defined, just the global thing? I can’t get past these 403 errors for some reason, I don’t know what’s going on. I’ve tried from the vite server and deploying as an asset canister.
The root and build configs are irrelevant, but the steps that I recommend following are:
- define global as window
- set up a dev server proxy
- configure EnvironmentPlugin to replace CANISTER_ and DFX_ prefixed environment variables
I don’t have any node polyfills. If you have the host
set to undefined
during local development and you’re using the proxy
server, it should work fine. You can omit host
from your getBalance
method
Also, i don’t really know why, but vite
seems to ignore vite.config.js
in my experience, so make sure you specify the -c vite.config.js
in your package.json
script
I would like to avoid creating a proxy server, is that necessary?
It’s not a new server - you’re already using the vite
development server, so this is just proxying traffic to the replica on /api
the same way a canister frontend on ic0.app works
My ideal experience would have been to just boot up any frontend server, import the generated code, and have it work. I understand the global issue (easy to get around in a variety of ways) and even polyfilling process.env (again easy), but the hosts and root key fetching seem very brittle and I think it’s undesirable to require all of this process
My frontend’s deployed URL is http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/
.
My agent looks like this:
const agent = new HttpAgent({
host: '127.0.0.1:8000',
identity: this.identity
});
Why should I need a proxy server?
I’ve been trying other configurations as well, the goal is 0 config for vite, so far doesn’t seem necessary (the process/global are easy enough).
I think you may need to specify http//:127.0.0.1:8000
but otherwise should be fine. Cutting out fetchRootKey
would be nice, but isn’t within my authority due to security constraints
Problem is I can’t do 127.0.0.1 with subdomains in the browser, and for some reason host
in the HttpAgent
settings doesn’t allow localhost
.
yeah, it’s almost like the proxy configuration is less painful 
edit: apologies - this was unnecessarily snarky
No you’re good
I just see a few small issues that if cleaned up would seem to me to make things more composable and work well with various setups.
I think there’s a better way though, it shouldn’t be necessary with a few fixes in the agent code. HttpAgent
should accept localhost
or 127.0.0.1
, because it doesn’t this seems to be breaking things.
I don’t think it’s forbidden anywhere in the agent itself - in fact we use localhost in e2e tests: agent-js/counter.ts at 1d35889e0d0c0fd4a33d02a341bd90ee156da1cd · dfinity/agent-js · GitHub
I don’t think we do it in-browser anywhere though.
I think the localhost vs 127.0.0.1 discrepancy is a dependency issue somewhere in the vite ecosystem. The same behavior started taking place in webpack starting with Node 17, if I recall
1 Like
I can see that the root key is fetched by looking at the network tab in Chrome devtools, but I keep getting these errors:
127.0.0.1:8000/api/v2/canister/7ugoi-yiaaa-aaaaa-aabaa-cai/call 403 (Forbidden)
(anony
-app.ts:48 Server returned an error:
Code: 403 (Forbidden)
Body: Failed to authenticate request 0x06fb68ba0987ef20247b14f4c60e4dd7c242b9d9145c4453eb25c8bbea1aa80f due to: Invalid delegation: Invalid canister signature: IcCanisterSignature signature could not be verified: public key 0a00000000000000070101364827569d1f66bedaa3311ba159e725920c16783773f549afe4eac95daf8446, signature d9d9f7a26b6365727469666963617465590489d9d9f7a3647472656583018301830183024863616e69737465728301830183024a0000000000000007010183018301830183024e6365727469666965645f6461746182035820d35b0d40c9fd19d39fd20fa1e245a87fe5d14eeb7a42979fe5072956c81ce48782045820fd5b59459758c8afecaf7285da359e4b5adb945fb86a3c1f0efd996c21a96938820458205f037bd92faf11cb7d76ea072ef27ba79499e56ab9344dfeb57609d445dd691182045820aa20324fc55c8061cea61b9b73bb12da019edb6726c5f822a6a1c0cb5abbeee982045820d9ca4c089f657e20f26a6270ebbeb7556f79f598b9120b5b87ccd3bb8e9aadca8204582077f0bb8fe7d6e79bc0060fc41a475527485c94b5bb00d989a77126090a4eccec8204582059607b76078b45de64776b334e2d7f2395c4c2cfddf0f2a8bd35b3591def249e82045820df9c94f7c01a25de910472d76f73e39b020e63266235d64c6ad69620b0f639b7830182045820cc578109fc5dbde591cf79cb3fa6326cdccdd9fa88ea27592ca888824366afe383024474696d6582034997a5aae3aebae4b017697369676e6174757265583097a971738f6cea92494f9c6729f7e3055cb1f59be2c89c390633ec95b6c0f08507faa5551c8abc788c2b30a4c84f60dc6a64656c65676174696f6ea2697375626e65745f6964581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d026b636572746966696361746559026ed9d9f7a264747265658301820458200ec991d75af7076a592939e333a11e1dab4445ede347a645b51246edf9bb15c383018302467375626e657483018301830182045820267fe55111b56e3c3975532ea3373f7b72e9f82072fe8e607ed34486478a5b39830182045820466a70286cf9ace9801ca53e22af6ee059a094fd60498606d484b6854058307d83018301820458208b2f6c15078ae4d3b93470915ca53e373327f37ea74ba1b8177d986bb79b31ae8302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec806820458202c51db7b5650b7a3dbbb8530a7449cc6f90144778b62f20f3c26d72e95e5069882045820a7f251951eed726811460449388214773c94153c758afe3aaa54f9b51704268682045820df1124435df1c9bae1f1344ef3fda6a60f8faf7d06720e35f01349d8a64fc96483024474696d65820349929ab3b2ec94e0b017697369676e617475726558308e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe1206474726565830182045820065064c0e21c1539409dcc408d2ad11e5356c8abe1bbc7f990dd7699784972ca83024373696783025820a45b16124e26ecdf787aa9b91cb89fe95672a3f5483c97d4c95e62ad7ac512278301830258205ebc40cdda83ce2f69e0f9f3c562184e9936c70c578e78604b1316a347448430820340820458207f7ac0667c3dd3c683471af468e8edb2e19dfba234126a57d5b4f9e1a53a4d70, error: certificate verification failed: failed to verify threshold signature: certificate_tree_hash=CryptoHash(0x90990f2030e965348d83cfe74adff9ac769e5769c032a037c2b17d042d622608), sig=Blob{48 bytes;8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120}, pk=ThresholdSigPublicKey { internal: ThresBls12_381(0xa5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214) }, error=ThresBls12_381 signature could not be verified: public key a5004a15dc60bce9e9a4456648757ff3e1cfa673fd273f6559239b2710017370ea796429e024519075f97ba957795e8f165a5f8eb2a68373437a4246dd8cfc6fe30fef0f064154e1a1e414329f85b20de244d0cfc5a9e48ea5ed8b1730f68214, signature 8e64dedf235872ccea40e5bbf1450f85c246e818b54e3bc5703da959064942a636e4a6e5c7ddc5a788335a3dcf1fe120, error: Invalid combined threshold signature
Retrying request.
_
Is that because the host of the agent and the actually host in the URL must be exactly the same?
It seems to work sometimes but not others, what is the criteria for validation?
So to simplify, currently I just want to use vite to build the static assets and deploy them, and then access the frontend from this URL: http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/
.
My agent code looks like this:
async getBalance() {
const agent = new HttpAgent({
identity: this.identity
});
const walletBackend = createActor('7ugoi-yiaaa-aaaaa-aabaa-cai', {
agent
});
const result = await walletBackend.getBalance();
this.balance = result;
}
I’ve started my replica like this:
dfx start --clean --host 127.0.0.1:8000 --enable-bitcoin
And the root key looks like it is fetched, here’s the response to http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/api/v2/status
:
����nic_api_versionf0.18.0hroot_keyX�0��0
+��|+��|a�J�`���EfHu��Ϧs�'?eY#�'sp�yd)�$Q�u�{�Wy^�Z_����sCzBF�o��AT��2���
�D��ũ䎥�0��limpl_versione0.8.0iimpl_hashx@e7d9c995fabd40679cf2a6025f5825a93e2520329ebe7751b2e94cd4a2b454e2ureplica_health_statusghealthy
But I keep getting:
403 forbidden
iled to authenticate request 0xb8a21f89cc90587074ae5c8a1197680946e02419c626942433d0d3275d0c43a4 due to: Invalid delegation: Invalid canister signature: IcCanisterSignature signature could not be verified: public key 0
valid combined threshold signature