@unconfirmed/sui-effect 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/AGENTS.md +47 -14
  2. package/CHANGELOG.md +86 -0
  3. package/LLMS.md +2889 -1726
  4. package/README.md +517 -11
  5. package/dist/domain/bcs.d.ts +44 -0
  6. package/dist/domain/bcs.d.ts.map +1 -1
  7. package/dist/domain/bcs.js +64 -0
  8. package/dist/domain/bcs.js.map +1 -1
  9. package/dist/domain/errors.d.ts +164 -26
  10. package/dist/domain/errors.d.ts.map +1 -1
  11. package/dist/domain/errors.js +193 -15
  12. package/dist/domain/errors.js.map +1 -1
  13. package/dist/domain/executed.d.ts +123 -18
  14. package/dist/domain/executed.d.ts.map +1 -1
  15. package/dist/domain/executed.js +196 -5
  16. package/dist/domain/executed.js.map +1 -1
  17. package/dist/domain/journal-entry.d.ts +6 -2
  18. package/dist/domain/journal-entry.d.ts.map +1 -1
  19. package/dist/domain/schemas.d.ts +234 -67
  20. package/dist/domain/schemas.d.ts.map +1 -1
  21. package/dist/domain/schemas.js +82 -4
  22. package/dist/domain/schemas.js.map +1 -1
  23. package/dist/domain/sui-schema.d.ts +3 -2
  24. package/dist/domain/sui-schema.d.ts.map +1 -1
  25. package/dist/domain/sui-schema.js +3 -2
  26. package/dist/domain/sui-schema.js.map +1 -1
  27. package/dist/extension.d.ts +1 -1
  28. package/dist/extension.d.ts.map +1 -1
  29. package/dist/extension.js +1 -1
  30. package/dist/extension.js.map +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/script.d.ts +1 -1
  36. package/dist/script.d.ts.map +1 -1
  37. package/dist/script.js +1 -1
  38. package/dist/script.js.map +1 -1
  39. package/dist/services/Script.d.ts +42 -0
  40. package/dist/services/Script.d.ts.map +1 -1
  41. package/dist/services/Script.js +69 -2
  42. package/dist/services/Script.js.map +1 -1
  43. package/dist/services/Signer.d.ts +32 -7
  44. package/dist/services/Signer.d.ts.map +1 -1
  45. package/dist/services/Signer.js +69 -10
  46. package/dist/services/Signer.js.map +1 -1
  47. package/dist/services/Sui.d.ts +42 -1
  48. package/dist/services/Sui.d.ts.map +1 -1
  49. package/dist/services/Sui.js +18 -4
  50. package/dist/services/Sui.js.map +1 -1
  51. package/dist/services/SuiCore.d.ts +12 -0
  52. package/dist/services/SuiCore.d.ts.map +1 -1
  53. package/dist/services/SuiCore.js +124 -0
  54. package/dist/services/SuiCore.js.map +1 -1
  55. package/dist/services/SuiCoreFake.d.ts +59 -4
  56. package/dist/services/SuiCoreFake.d.ts.map +1 -1
  57. package/dist/services/SuiCoreFake.js +199 -23
  58. package/dist/services/SuiCoreFake.js.map +1 -1
  59. package/dist/services/SuiExtension.d.ts +127 -14
  60. package/dist/services/SuiExtension.d.ts.map +1 -1
  61. package/dist/services/SuiExtension.js +125 -28
  62. package/dist/services/SuiExtension.js.map +1 -1
  63. package/dist/services/SuiGraphQL.d.ts +13 -0
  64. package/dist/services/SuiGraphQL.d.ts.map +1 -1
  65. package/dist/services/SuiGraphQL.js +13 -0
  66. package/dist/services/SuiGraphQL.js.map +1 -1
  67. package/dist/services/Tx.d.ts +630 -12
  68. package/dist/services/Tx.d.ts.map +1 -1
  69. package/dist/services/Tx.js +187 -8
  70. package/dist/services/Tx.js.map +1 -1
  71. package/dist/testing.d.ts +22 -3
  72. package/dist/testing.d.ts.map +1 -1
  73. package/dist/testing.js +39 -3
  74. package/dist/testing.js.map +1 -1
  75. package/dist/tx.d.ts +1 -1
  76. package/dist/tx.d.ts.map +1 -1
  77. package/dist/tx.js +1 -1
  78. package/dist/tx.js.map +1 -1
  79. package/docs/extensions.md +871 -33
  80. package/examples/extension-template/src/Escrow.ts +1 -1
  81. package/examples/extension-template/test/escrow.test.ts +91 -2
  82. package/package.json +3 -2
@@ -213,7 +213,7 @@ const make = (
213
213
  Effect.flatMap((raw) =>
214
214
  decodeAddress(raw).pipe(
215
215
  Effect.mapError((issue) =>
216
- new DecodeError({ expectedType: "SuiAddress", issue: issue.message })
216
+ new DecodeError({ expectedType: "SuiAddress", kind: "shape", issue: issue.message })
217
217
  )
218
218
  )
219
219
  ),
@@ -22,13 +22,16 @@ import {
22
22
  Stream
23
23
  } from "effect"
24
24
  import { TestClock } from "effect/testing"
25
- import type { Sui, SuiCore } from "@unconfirmed/sui-effect"
26
- import { KNOWN_CHAIN_IDS, ObjectId, SuiAddress, SuiSchema } from "@unconfirmed/sui-effect"
25
+ import type { ChangedRef, Recipe, Sui, SuiCore } from "@unconfirmed/sui-effect"
26
+ import { KNOWN_CHAIN_IDS, ObjectId, SuiAddress, SuiError, SuiSchema } from "@unconfirmed/sui-effect"
27
+ import type { PromiseFace } from "@unconfirmed/sui-effect/extension"
27
28
  import { FakeOutcome, layerExtensionTest, layerTest, SuiCoreFake, SuiTest } from "@unconfirmed/sui-effect/testing"
28
29
  import { Journal, Signer } from "@unconfirmed/sui-effect/tx"
30
+ import type { EscrowObject, EscrowService } from "../src/Escrow.ts"
29
31
  import { DEPLOYMENTS, Escrow } from "../src/Escrow.ts"
30
32
  import { escrow as escrowRegistration } from "../src/extension.ts"
31
33
  import { EscrowNotFound, EscrowSettlementUnknown, EscrowUnsupportedNetwork } from "../src/errors.ts"
34
+ import type { PlatformService } from "../src/Platform.ts"
32
35
  import { Platform, platform as platformRegistration } from "../src/Platform.ts"
33
36
  import { ESCROW_PACKAGE, receiptType, Settlement, SettlementContent } from "../src/schema.ts"
34
37
 
@@ -557,3 +560,89 @@ describe("layerConfig validates through the typed deployment path", () => {
557
560
  expect(String(exit)).toContain("32-byte Sui object id")
558
561
  })
559
562
  })
563
+
564
+ /**
565
+ * The face's **type**, asserted rather than described.
566
+ *
567
+ * This is the test every extension copies. `PromiseFace<Service>` is what a
568
+ * Promise consumer actually holds, and it is derived, so nothing in the service
569
+ * says out loud what it produced: an `Effect` member has to become a
570
+ * Promise-returning method, a `Stream` member an `AsyncIterable`, a synchronous
571
+ * member has to stay synchronous, and a **namespace has to be mapped all the
572
+ * way down** — `PlatformService.escrow` is an interface, and until 0.1.1 an
573
+ * interface-typed namespace kept its `Effect` members in the type while the
574
+ * runtime handed back Promises.
575
+ *
576
+ * Write one of these per namespace. It costs four lines and it is the only
577
+ * thing that catches a face type that has quietly stopped matching the runtime.
578
+ */
579
+ describe("the Promise face type", () => {
580
+ /** Compile-time assignability, as a value a test can assert on. */
581
+ const assignableTo = <_A extends _B, _B>(): true => true
582
+
583
+ type EscrowFace = PromiseFace<EscrowService>
584
+ type PlatformFace = PromiseFace<PlatformService>
585
+
586
+ test("an Effect member becomes a Promise-returning method", () => {
587
+ expect(assignableTo<EscrowFace["get"], (id: ObjectId) => Promise<EscrowObject>>()).toBe(true)
588
+ expect(assignableTo<EscrowFace["feeCollector"], () => Promise<SuiAddress>>()).toBe(true)
589
+ })
590
+
591
+ test("a Stream member becomes an AsyncIterable", () => {
592
+ expect(
593
+ assignableTo<EscrowFace["owned"]["stream"], (owner: SuiAddress) => AsyncIterable<EscrowObject>>()
594
+ ).toBe(true)
595
+ })
596
+
597
+ test("a synchronous member stays synchronous", () => {
598
+ expect(assignableTo<EscrowFace["packageId"], string>()).toBe(true)
599
+ expect(assignableTo<EscrowFace["claim"], (escrow: EscrowObject) => Recipe>()).toBe(true)
600
+ })
601
+
602
+ test("an interface-typed namespace is mapped all the way down", () => {
603
+ // `PlatformService.escrow` is `EscrowService`, an interface. The members
604
+ // reached through it must be the mapped ones, not the Effect ones.
605
+ expect(assignableTo<PlatformFace["escrow"]["get"], (id: ObjectId) => Promise<EscrowObject>>())
606
+ .toBe(true)
607
+ expect(
608
+ assignableTo<
609
+ PlatformFace["escrow"]["owned"]["count"],
610
+ (owner: SuiAddress) => Promise<number>
611
+ >()
612
+ ).toBe(true)
613
+ expect(assignableTo<PlatformFace["escrow"]["packageId"], string>()).toBe(true)
614
+ })
615
+
616
+ test("the composition's own member is mapped too", () => {
617
+ expect(
618
+ assignableTo<
619
+ PlatformFace["claimEverything"],
620
+ (ids: ReadonlyArray<ObjectId>, opts: { readonly signer: Signer }) => Promise<
621
+ ReadonlyArray<ChangedRef>
622
+ >
623
+ >()
624
+ ).toBe(true)
625
+ })
626
+ })
627
+
628
+ /**
629
+ * The errors serialize with their `outcome`, which is what a wrapper script
630
+ * acts on and what an operator reads out of a log line.
631
+ */
632
+ describe("the errors", () => {
633
+ test("SuiError.toJson keeps the outcome, though it is a class field", () => {
634
+ const error = new EscrowSettlementUnknown({
635
+ escrowId: ESCROW_ID,
636
+ digest: "1".repeat(32) as never,
637
+ message: "the operator never confirmed"
638
+ })
639
+ const json = SuiError.toJson(error)
640
+ expect(json["_tag"]).toBe("escrow/EscrowSettlementUnknown")
641
+ expect(json["escrowId"]).toBe(ESCROW_ID)
642
+ // `outcome` is declared as a class field — not a schema field — because
643
+ // that is the shape that reads well at the call site. `toJson` reads it off
644
+ // the instance, so it is in the JSON anyway.
645
+ expect(json["outcome"]).toBe("unknown")
646
+ expect(json["outcome"]).toBe(SuiError.outcome(error))
647
+ })
648
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unconfirmed/sui-effect",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "An opinionated Effect v4 layer over @mysten/sui: two client tiers, closed error unions, and a typed transaction lifecycle.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,6 +33,7 @@
33
33
  "files": [
34
34
  "dist",
35
35
  "README.md",
36
+ "CHANGELOG.md",
36
37
  "LICENSE",
37
38
  "LLMS.md",
38
39
  "AGENTS.md",
@@ -53,7 +54,7 @@
53
54
  },
54
55
  "repository": {
55
56
  "type": "git",
56
- "url": "https://github.com/unconfirmedlabs/sui-effect"
57
+ "url": "git+https://github.com/unconfirmedlabs/sui-effect.git"
57
58
  },
58
59
  "keywords": [
59
60
  "sui",