-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SDK-621 Generate boilerplate for JS user library setup #176
Conversation
Ported from #56. Try babel-loader next. See https://github.com/microsoft/TypeScript-Babel-Starter
This reverts commit eec6a2d.
…to paulyoung/js-user-lib-example
Now that dfx generates canister IDs as unsigned 64-bit integers (little endian) we need to make sure we can handle that in JavaScript. At present, the HTTP handler of the client rejects submit calls with a HTTP status code of 422, and the message "Could not parse body: invalid type: byte array, expected u64" despite attempting to send the canister_id field as a uint64 little endian typed array per the CBOR spec.
After pulling the latest from I’ve made updates to represent little endian u64 canister IDs as a typed array with a tag of 71 (per the CBOR spec). When I make a call to the
Here it is as hex: |
Since canister.js has no impact on invoking executables.
}, | ||
"dfx": "0.4.0", | ||
"version": 1 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from removing deployment_id
, these changes are due to using dfx config
.
I created SDK-626 to track that.
try { | ||
const reply = await actor.greet(); | ||
const reply = await hello.greet(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file now matches what @stanleygjones posted in #153 (comment)
js-user-library/src/canisterId.ts
Outdated
return new borc.Tagged( | ||
CborTag.Uint64LittleEndian, | ||
Buffer.from(`0x${hex}`), | ||
) as CanisterId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the HTTP handler of the client should recognize this as a u64.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently serde_cbor
doesn't support tags: https://docs.rs/serde_cbor/0.10.2/serde_cbor/#limitations
Tags are ignored during deserialization and can't be emitted during serialization. This is because Serde has no concept of tagged values. See: #3
I'm not sure how to proceed. @nmattia, do you have any advice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I fully grasp the issue, sorry! do you have some context?
Major types from the spec is: https://tools.ietf.org/html/rfc7049#section-2.1 Tags are still in draft, so ignore (serde ignores too). A valid CBOR (sent by the CLI) can be found here. You should try to make a CBOR binary the same as this. |
For reference: --- a/node_modules/borc/src/encoder.js
+++ b/Users/paulyoung/Downloads/encoder.js
@@ -19,6 +19,7 @@ const UNDEFINED = (constants.MT.SIMPLE_FLOAT << 5) | constants.SIMPLE.UNDEFINED
const NULL = (constants.MT.SIMPLE_FLOAT << 5) | constants.SIMPLE.NULL
const MAXINT_BN = new Bignumber('0x20000000000000')
+const MAXINT64_BN = new Bignumber('0xffffffffffffffff')
const BUF_NAN = Buffer.from('f97e00', 'hex')
const BUF_INF_NEG = Buffer.from('f9fc00', 'hex')
const BUF_INF_POS = Buffer.from('f97c00', 'hex')
@@ -117,6 +118,10 @@ class Encoder {
return this.pushWrite(val, 3, 4)
}
+ _pushUInt64BE (val) {
+ return this.pushWrite(val.toString(16), 6, 8)
+ }
+
_pushDoubleBE (val) {
return this.pushWrite(val, 4, 8)
}
@@ -267,6 +272,11 @@ class Encoder {
}
_pushBigint (obj) {
+ // if less than uint64::MAX, use a uint64 field and return.
+ if (obj.isLessThan(MAXINT64_BN) && obj.isPositive()) {
+ return this._pushUInt8(8, MT.POS_INT) && this._pushUInt64BE(obj);
+ }
+
let tag = TAG.POS_BIGINT
if (obj.isNegative()) {
obj = obj.negated().minus(1)
@@ -480,6 +490,9 @@ class Encoder {
case 5:
res.write(result[i], index, length, 'utf8')
break
+ case 6:
+ res.write(result[i], index, length, 'hex')
+ break
default:
throw new Error('unkown method')
} |
This looks fishy (from your original post)
it looks like you have a hex-encoded blob as a blob, instead of just the blob. |
And I guess the implementation might be behind the spec in the sense that canister ids are still numbers, not blobs, e.g. |
Looks like I need to fix something with |
Sorry for all of the noise here. I believe the issues with encoding canister IDs are now resolved. The purpose of this pull request, as the title says, is to generate some boilerplate on behalf of users so that that may import (a JS interface to) their canisters and interact with them directly. This is partly in response to #153 (comment) A before and after view of this can be seen in To achieve this we rely on the same mechanism used to create a new project which uses the template at |
makeHttpAgent, | ||
} from "{js_user_lib}"; | ||
|
||
const { publicKey, secretKey } = generateKeyPair(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will need to be updated when we have a better story around this.
// canister IDs. However, simple-cbor does not yet provide deserialization so | ||
// we are using `BigNumber` and `Buffer` types instead of `BigInt` and | ||
// `Uint8Array` (respectively) so that we can use the dignifiedquire/borc CBOR | ||
// decoder. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is noteworthy, and explains many of the changes in this PR.
@@ -38,6 +39,7 @@ drv.overrideAttrs (oldAttrs: { | |||
cp ${motoko.didc}/bin/didc $out | |||
cp ${motoko.rts}/rts/mo-rts.wasm $out | |||
mkdir $out/stdlib && cp -R ${motoko.stdlib}/. $out/stdlib | |||
mkdir $out/js-user-library && cp -R ${dfinity-sdk.packages.js-user-library}/. $out/js-user-library |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This puts the JS user library in ~/.cache/dfinity/...
with other things we depend on (for now)
generateKeyPair, | ||
makeActor, | ||
makeHttpAgent, | ||
} from "{js_user_lib}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, this ends up being a path to ~/.cache/dfinity/.../js-user-library
I'm blocked on an issue unrelated to SDK-621, with sending the canister IDs generated by dfx to the client. Some info is in the commit message, but more details to follow.