Skip to content

Commit

Permalink
Update SDK encoding/decoding for Cadence 1.0 (#1863)
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink committed May 9, 2024
1 parent 11b8f9d commit 7ef7edf
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 52 deletions.
6 changes: 6 additions & 0 deletions .changeset/giant-bananas-watch.md
@@ -0,0 +1,6 @@
---
"@onflow/sdk": minor
"@onflow/types": minor
---

Update SDK encoding/decoding for Cadence 1.0 JSON-CDC changes
41 changes: 21 additions & 20 deletions packages/sdk/src/decode/decode.js
Expand Up @@ -27,26 +27,9 @@ const decodeType = async type => {
return type.staticType
}

const decodePath = async path => {
return {
domain: path.domain,
identifier: path.identifier,
}
}

const decodeCapability = async cap => {
return {
path: cap.path,
address: cap.address,
borrowType: cap.borrowType,
}
}

const decodeOptional = async (optional, decoders, stack) =>
optional ? await recurseDecode(optional, decoders, stack) : null

const decodeReference = async v => ({address: v.address, type: v.type})

const decodeArray = async (array, decoders, stack) =>
await Promise.all(
array.map(
Expand Down Expand Up @@ -75,6 +58,21 @@ const decodeComposite = async (composite, decoders, stack) => {
return decoder ? await decoder(decoded) : decoded
}

const decodeInclusiveRange = async (range, decoders, stack) => {
// Recursive decode for start, end, and step
// We don't do all fields just in case there are future API changes
// where fields added and are not Cadence values
const keys = ["start", "end", "step"]
const decoded = await Object.keys(range).reduce(async (acc, key) => {
acc = await acc
if (keys.includes(key)) {
acc[key] = await recurseDecode(range[key], decoders, [...stack, key])
}
return acc
}, Promise.resolve({}))
return decoded
}

const defaultDecoders = {
UInt: decodeImplicit,
Int: decodeImplicit,
Expand All @@ -94,6 +92,8 @@ const defaultDecoders = {
Word16: decodeImplicit,
Word32: decodeImplicit,
Word64: decodeImplicit,
Word128: decodeImplicit,
Word256: decodeImplicit,
UFix64: decodeImplicit,
Fix64: decodeImplicit,
String: decodeImplicit,
Expand All @@ -102,16 +102,17 @@ const defaultDecoders = {
Address: decodeImplicit,
Void: decodeVoid,
Optional: decodeOptional,
Reference: decodeReference,
Reference: decodeImplicit,
Array: decodeArray,
Dictionary: decodeDictionary,
Event: decodeComposite,
Resource: decodeComposite,
Struct: decodeComposite,
Enum: decodeComposite,
Type: decodeType,
Path: decodePath,
Capability: decodeCapability,
Path: decodeImplicit,
Capability: decodeImplicit,
InclusiveRange: decodeInclusiveRange,
}

const decoderLookup = (decoders, lookup) => {
Expand Down
71 changes: 53 additions & 18 deletions packages/sdk/src/decode/decode.test.js
Expand Up @@ -296,39 +296,55 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual("4294967295")
})

it("returns the correct response given a json-cdc payload 30 WORD64", async () => {
it("returns the correct response given a json-cdc payload 30 WORD128", async () => {
const payload = {type: "Word128", value: "12412531315"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("12412531315")
})

it("returns the correct response given a json-cdc payload 31 WORD256", async () => {
const payload = {type: "Word256", value: "555153134124"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("555153134124")
})

it("returns the correct response given a json-cdc payload 32 WORD64", async () => {
const payload = {type: "Word64", value: "18446744073709551615"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("18446744073709551615")
})

it("returns the correct response given a json-cdc payload 31 FIX64", async () => {
it("returns the correct response given a json-cdc payload 33 FIX64", async () => {
const payload = {type: "Fix64", value: "789.00123010"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("789.00123010")
})

it("returns the correct response given a json-cdc payload 32 FIX64", async () => {
it("returns the correct response given a json-cdc payload 34 FIX64", async () => {
const payload = {type: "Fix64", value: "-12345.00678900"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("-12345.00678900")
})

it("returns the correct response given a json-cdc payload 33 UFIX64", async () => {
it("returns the correct response given a json-cdc payload 35 UFIX64", async () => {
const payload = {type: "UFix64", value: "789.00123010"}

const decoded = await decode(payload)

expect(decoded).toStrictEqual("789.00123010")
})

it("returns the correct response given a json-cdc payload 34 ARRAY", async () => {
it("returns the correct response given a json-cdc payload 36 ARRAY", async () => {
const payload = {
type: "Array",
value: [
Expand All @@ -343,7 +359,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual(["1", "2", "3"])
})

it("returns the correct response given a json-cdc payload 35 ARRAY", async () => {
it("returns the correct response given a json-cdc payload 37 ARRAY", async () => {
const payload = {
type: "Array",
value: [
Expand Down Expand Up @@ -376,7 +392,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual([{bar: "1"}, {bar: "2"}, {bar: "3"}])
})

it("returns the correct response given a json-cdc payload 36 DICTIONARY", async () => {
it("returns the correct response given a json-cdc payload 38 DICTIONARY", async () => {
const payload = {
type: "Dictionary",
value: [
Expand All @@ -391,7 +407,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "1", b: "2", c: "3"})
})

it("returns the correct response given a json-cdc payload 37 DICTIONARY", async () => {
it("returns the correct response given a json-cdc payload 39 DICTIONARY", async () => {
const payload = {
type: "Dictionary",
value: [
Expand Down Expand Up @@ -439,7 +455,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: {1: "1"}, b: {2: "2"}, c: {3: "3"}})
})

it("returns the correct response given a json-cdc payload 38 DICTIONARY", async () => {
it("returns the correct response given a json-cdc payload 40 DICTIONARY", async () => {
const payload = {
type: "Dictionary",
value: [
Expand Down Expand Up @@ -481,7 +497,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: {bar: "1"}, b: {bar: "2"}, c: {bar: "3"}})
})

it("returns the correct response given a json-cdc payload 39 RESOURCE", async () => {
it("returns the correct response given a json-cdc payload 41 RESOURCE", async () => {
const payload = {
type: "Resource",
value: {
Expand All @@ -495,7 +511,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({bar: "42"})
})

it("returns the correct response given a json-cdc payload 40 RESOURCE", async () => {
it("returns the correct response given a json-cdc payload 42 RESOURCE", async () => {
const payload = {
type: "Resource",
value: {
Expand All @@ -520,7 +536,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({bar: {x: "42"}})
})

it("returns the correct response given a json-cdc payload 41 STRUCT", async () => {
it("returns the correct response given a json-cdc payload 43 STRUCT", async () => {
const payload = {
type: "Struct",
value: {
Expand All @@ -537,7 +553,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "1", b: "foo"})
})

it("returns the correct response given a json-cdc payload 42 STRUCT", async () => {
it("returns the correct response given a json-cdc payload 44 STRUCT", async () => {
const payload = {
type: "Struct",
value: {
Expand All @@ -563,7 +579,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "foo", b: {bar: "42"}})
})

it("returns the correct response given a json-cdc payload 43 STRUCT", async () => {
it("returns the correct response given a json-cdc payload 45 STRUCT", async () => {
const payload = {
type: "Struct",
value: {
Expand All @@ -589,7 +605,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "foo", b: {bar: "42"}})
})

it("returns the correct response given a json-cdc payload 44 EVENT", async () => {
it("returns the correct response given a json-cdc payload 46 EVENT", async () => {
const payload = {
type: "Event",
value: {
Expand All @@ -606,7 +622,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "1", b: "foo"})
})

it("returns the correct response given a json-cdc payload 44 EVENT", async () => {
it("returns the correct response given a json-cdc payload 47 EVENT", async () => {
const payload = {
type: "Event",
value: {
Expand All @@ -632,7 +648,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual({a: "foo", b: {bar: "42"}})
})

it("returns the correct response given a json-cdc payload 45 TYPE", async () => {
it("returns the correct response given a json-cdc payload 48 TYPE", async () => {
const payload = {
type: "Type",
value: {
Expand All @@ -645,7 +661,7 @@ describe("unit tests to cover all types", () => {
expect(decoded).toStrictEqual("FooType")
})

it("returns the correct response given a json-cdc payload 46 PATH", async () => {
it("returns the correct response given a json-cdc payload 49 PATH", async () => {
const payload = {
type: "Path",
value: {
Expand All @@ -661,6 +677,25 @@ describe("unit tests to cover all types", () => {
identifier: "123abc",
})
})

it("returns the correct response given a json-cdc payload 50 INCLUSIVERANGE", async () => {
const payload = {
type: "InclusiveRange",
value: {
start: {type: "Int", value: "2"},
end: {type: "Int", value: "10"},
step: {type: "Int", value: "1"},
},
}

const decoded = await decode(payload)

expect(decoded).toStrictEqual({
start: "2",
end: "10",
step: "1",
})
})
})

// Boolean
Expand Down
30 changes: 30 additions & 0 deletions packages/types/README.md
Expand Up @@ -242,6 +242,26 @@ sdk.build([
])
```

### Word128

```javascript
import * as t from "@onflow/types"

sdk.build([
sdk.args([ sdk.arg(128, t.Word128) ])
])
```

### Word256

```javascript
import * as t from "@onflow/types"

sdk.build([
sdk.args([ sdk.arg(256, t.Word256) ])
])
```

### UFix64

```javascript
Expand Down Expand Up @@ -456,3 +476,13 @@ sdk.build([
])
])
```

### InclusiveRange

```javascript
import * as t from "@onflow/types"

sdk.build([
sdk.args([ sdk.arg({start: "1", end: "10", step: "1"}, t.InclusiveRange(t.Int)) ])
])
```
23 changes: 23 additions & 0 deletions packages/types/src/types.test.ts
Expand Up @@ -18,6 +18,8 @@ registerTest([t.Word8, "8", {type: "Word8", value: "8"}, "8"])
registerTest([t.Word16, "16", {type: "Word16", value: "16"}, "16"])
registerTest([t.Word32, "32", {type: "Word32", value: "32"}, "32"])
registerTest([t.Word64, "64", {type: "Word64", value: "64"}, "64"])
registerTest([t.Word128, "128", {type: "Word128", value: "128"}, "128"])
registerTest([t.Word256, "256", {type: "Word256", value: "256"}, "256"])
registerTest([t.UFix64, "64", {type: "UFix64", value: "64"}, "64", true])
registerTest([t.Fix64, "64", {type: "Fix64", value: "64"}, "64", true])
registerTest([
Expand Down Expand Up @@ -222,6 +224,27 @@ registerTest([
},
true,
])
registerTest([
t.InclusiveRange(t.Int),
{
start: 5,
end: 10,
step: 1,
},
{
type: "InclusiveRange",
value: {
start: {type: "Int", value: "5"},
end: {type: "Int", value: "10"},
step: {type: "Int", value: "1"},
},
},
{
start: 5,
end: 10,
step: 1,
},
])

function registerTest<X, Y extends string, Z>([
cast,
Expand Down

0 comments on commit 7ef7edf

Please sign in to comment.