Skip to content
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

Add JSONification of Soroban invocation trees. #669

Merged
merged 12 commits into from
Sep 1, 2023
Merged

Conversation

Shaptic
Copy link
Contributor

@Shaptic Shaptic commented Aug 9, 2023

No description provided.

@github-actions
Copy link

github-actions bot commented Aug 9, 2023

Size Change: +41.6 kB (+1%)

Total Size: 3.11 MB

Filename Size Change
dist/stellar-base.js 2.28 MB +31.4 kB (+1%)
dist/stellar-base.min.js 828 kB +10.1 kB (+1%)

compressed-size-action

@Shaptic Shaptic changed the title [DRAFT] Add human-friendly representations of invocation trees. [Proposal] Add human-friendly representations of invocation trees. Aug 21, 2023
@Shaptic Shaptic marked this pull request as ready for review August 21, 2023 20:02
Copy link
Contributor

@paulbellamy paulbellamy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really clear what the point of this is. Maybe a before/after example would help?

The JSON produces is marginally more human-friendly, but I'd imagine wallets/apps would be walking through the SorobanAuthorizedInvocation to produce HTML out the other end. This fn doesn't seem super useful for that. Maybe a invocationTree.walk(fn: (node: SorobanAuthorizedInvocation, parent: null | SorobanAuthorizedInvocation, depth: number) => boolean) (or maybe tree.map(fn)?) would be more useful for that.

Generally, I've found it more useful to try to do stuff in the dapp example, and then see what helpers I can extract from there into the sdk/base. That way you have a motivating example and can make sure you've got an abstraction that is at least useful.

But idk tho.

src/invocation.js Show resolved Hide resolved
src/invocation.js Show resolved Hide resolved
src/invocation.js Show resolved Hide resolved
src/invocation.js Show resolved Hide resolved
@Shaptic
Copy link
Contributor Author

Shaptic commented Aug 22, 2023

Thank you for the review, @paulbellamy 🙏

try to do stuff in the dapp example [...] motivating example [...]

I forgot to include the context that motivated this: Slack thread. The idea is for Freighter et al. to have meaningful popups when asking users to authorize invocation trees.

The JSON produces is marginally more human-friendly

Hard disagree, but this isn't obvious without an example. Flattening the structure and leveraging scValToNative makes a huge difference in readability. Which one is easier to grok (both are JSON.stringifyd)? And which one would be easier for a dapp user (not dev)?


Scenario

This is a complicated, albeit contrived invocation tree whose pseudo-structure is supposed to represent a high-level contract interaction involving two transfers of native SAC tokens underneath it.

 purchase("SomeNft:G...", 7 xlm)
     |
     +--- swap(xlm, usdc, from, to)
     |      |
     |      |- xlm.transfer(from, to, 7)
     |      |
     |      |- usdc.transfer(to, from, 1)
     |
     +--- someNft.transfer(invoker, contract, 1)

XDR

{
  "_attributes": {
    "function": {
      "_switch": {
        "name": "sorobanAuthorizedFunctionTypeContractFn",
        "value": 0
      },
      "_arm": "contractFn",
      "_value": {
        "_attributes": {
          "contractAddress": {
            "_switch": {
              "name": "scAddressTypeContract",
              "value": 1
            },
            "_arm": "contractId",
            "_armType": {
              "_length": 32
            },
            "_value": {
              "type": "Buffer",
              "data": [
                232,
                8,
                251,
                255,
                185,
                70,
                175,
                127,
                248,
                65,
                1,
                210,
                82,
                54,
                174,
                141,
                74,
                125,
                242,
                129,
                116,
                44,
                34,
                107,
                197,
                3,
                127,
                111,
                110,
                162,
                113,
                83
              ]
            }
          },
          "functionName": "purchase",
          "args": [
            {
              "_switch": {
                "name": "scvString",
                "value": 14
              },
              "_arm": "str",
              "_armType": {
                "_maxLength": 4294967295
              },
              "_value": "SomeNft:GBS7D7AJFWKIMWLD7KFAV2AXHSKCOE4DSSVKZQBGJCC3FRGS7WAS5WA6"
            },
            {
              "_switch": {
                "name": "scvU64",
                "value": 5
              },
              "_arm": "u64",
              "_value": {
                "_value": "7"
              }
            }
          ]
        }
      }
    },
    "subInvocations": [
      {
        "_attributes": {
          "function": {
            "_switch": {
              "name": "sorobanAuthorizedFunctionTypeContractFn",
              "value": 0
            },
            "_arm": "contractFn",
            "_value": {
              "_attributes": {
                "contractAddress": {
                  "_switch": {
                    "name": "scAddressTypeContract",
                    "value": 1
                  },
                  "_arm": "contractId",
                  "_armType": {
                    "_length": 32
                  },
                  "_value": {
                    "type": "Buffer",
                    "data": [
                      83,
                      50,
                      135,
                      62,
                      59,
                      72,
                      227,
                      3,
                      235,
                      42,
                      185,
                      176,
                      229,
                      104,
                      99,
                      81,
                      154,
                      204,
                      198,
                      232,
                      58,
                      194,
                      20,
                      154,
                      167,
                      60,
                      88,
                      140,
                      145,
                      89,
                      180,
                      48
                    ]
                  }
                },
                "functionName": "swap",
                "args": [
                  {
                    "_switch": {
                      "name": "scvString",
                      "value": 14
                    },
                    "_arm": "str",
                    "_armType": {
                      "_maxLength": 4294967295
                    },
                    "_value": "native"
                  },
                  {
                    "_switch": {
                      "name": "scvString",
                      "value": 14
                    },
                    "_arm": "str",
                    "_armType": {
                      "_maxLength": 4294967295
                    },
                    "_value": "USDC:GDEWIEQEB657FDO3GZIUTYS57T4M65QP352A2PN4CJPBCR55I5FWVAKG"
                  },
                  {
                    "_switch": {
                      "name": "scvAddress",
                      "value": 18
                    },
                    "_arm": "address",
                    "_value": {
                      "_switch": {
                        "name": "scAddressTypeAccount",
                        "value": 0
                      },
                      "_arm": "accountId",
                      "_value": {
                        "_switch": {
                          "name": "publicKeyTypeEd25519",
                          "value": 0
                        },
                        "_arm": "ed25519",
                        "_armType": {
                          "_length": 32
                        },
                        "_value": {
                          "type": "Buffer",
                          "data": [
                            76,
                            219,
                            245,
                            104,
                            41,
                            198,
                            51,
                            53,
                            239,
                            66,
                            121,
                            235,
                            61,
                            236,
                            110,
                            210,
                            177,
                            117,
                            102,
                            181,
                            16,
                            35,
                            129,
                            214,
                            69,
                            128,
                            154,
                            252,
                            64,
                            79,
                            52,
                            127
                          ]
                        }
                      }
                    }
                  },
                  {
                    "_switch": {
                      "name": "scvAddress",
                      "value": 18
                    },
                    "_arm": "address",
                    "_value": {
                      "_switch": {
                        "name": "scAddressTypeAccount",
                        "value": 0
                      },
                      "_arm": "accountId",
                      "_value": {
                        "_switch": {
                          "name": "publicKeyTypeEd25519",
                          "value": 0
                        },
                        "_arm": "ed25519",
                        "_armType": {
                          "_length": 32
                        },
                        "_value": {
                          "type": "Buffer",
                          "data": [
                            52,
                            74,
                            39,
                            21,
                            56,
                            39,
                            157,
                            177,
                            87,
                            193,
                            83,
                            66,
                            151,
                            143,
                            125,
                            19,
                            6,
                            239,
                            212,
                            82,
                            148,
                            51,
                            22,
                            140,
                            81,
                            169,
                            48,
                            184,
                            248,
                            113,
                            124,
                            83
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          },
          "subInvocations": [
            {
              "_attributes": {
                "function": {
                  "_switch": {
                    "name": "sorobanAuthorizedFunctionTypeContractFn",
                    "value": 0
                  },
                  "_arm": "contractFn",
                  "_value": {
                    "_attributes": {
                      "contractAddress": {
                        "_switch": {
                          "name": "scAddressTypeContract",
                          "value": 1
                        },
                        "_arm": "contractId",
                        "_armType": {
                          "_length": 32
                        },
                        "_value": {
                          "type": "Buffer",
                          "data": [
                            36,
                            67,
                            12,
                            76,
                            242,
                            197,
                            130,
                            66,
                            144,
                            142,
                            29,
                            145,
                            208,
                            242,
                            207,
                            18,
                            181,
                            117,
                            253,
                            41,
                            48,
                            141,
                            3,
                            69,
                            36,
                            114,
                            219,
                            194,
                            117,
                            150,
                            132,
                            109
                          ]
                        }
                      },
                      "functionName": "transfer",
                      "args": [
                        {
                          "_switch": {
                            "name": "scvAddress",
                            "value": 18
                          },
                          "_arm": "address",
                          "_value": {
                            "_switch": {
                              "name": "scAddressTypeAccount",
                              "value": 0
                            },
                            "_arm": "accountId",
                            "_value": {
                              "_switch": {
                                "name": "publicKeyTypeEd25519",
                                "value": 0
                              },
                              "_arm": "ed25519",
                              "_armType": {
                                "_length": 32
                              },
                              "_value": {
                                "type": "Buffer",
                                "data": [
                                  76,
                                  219,
                                  245,
                                  104,
                                  41,
                                  198,
                                  51,
                                  53,
                                  239,
                                  66,
                                  121,
                                  235,
                                  61,
                                  236,
                                  110,
                                  210,
                                  177,
                                  117,
                                  102,
                                  181,
                                  16,
                                  35,
                                  129,
                                  214,
                                  69,
                                  128,
                                  154,
                                  252,
                                  64,
                                  79,
                                  52,
                                  127
                                ]
                              }
                            }
                          }
                        },
                        {
                          "_switch": {
                            "name": "scvString",
                            "value": 14
                          },
                          "_arm": "str",
                          "_armType": {
                            "_maxLength": 4294967295
                          },
                          "_value": "7"
                        }
                      ]
                    }
                  }
                },
                "subInvocations": []
              }
            },
            {
              "_attributes": {
                "function": {
                  "_switch": {
                    "name": "sorobanAuthorizedFunctionTypeContractFn",
                    "value": 0
                  },
                  "_arm": "contractFn",
                  "_value": {
                    "_attributes": {
                      "contractAddress": {
                        "_switch": {
                          "name": "scAddressTypeContract",
                          "value": 1
                        },
                        "_arm": "contractId",
                        "_armType": {
                          "_length": 32
                        },
                        "_value": {
                          "type": "Buffer",
                          "data": [
                            56,
                            133,
                            65,
                            88,
                            225,
                            40,
                            234,
                            250,
                            236,
                            145,
                            45,
                            73,
                            128,
                            111,
                            87,
                            142,
                            198,
                            124,
                            243,
                            151,
                            85,
                            5,
                            37,
                            42,
                            194,
                            53,
                            2,
                            51,
                            250,
                            227,
                            108,
                            176
                          ]
                        }
                      },
                      "functionName": "transfer",
                      "args": [
                        {
                          "_switch": {
                            "name": "scvAddress",
                            "value": 18
                          },
                          "_arm": "address",
                          "_value": {
                            "_switch": {
                              "name": "scAddressTypeAccount",
                              "value": 0
                            },
                            "_arm": "accountId",
                            "_value": {
                              "_switch": {
                                "name": "publicKeyTypeEd25519",
                                "value": 0
                              },
                              "_arm": "ed25519",
                              "_armType": {
                                "_length": 32
                              },
                              "_value": {
                                "type": "Buffer",
                                "data": [
                                  76,
                                  219,
                                  245,
                                  104,
                                  41,
                                  198,
                                  51,
                                  53,
                                  239,
                                  66,
                                  121,
                                  235,
                                  61,
                                  236,
                                  110,
                                  210,
                                  177,
                                  117,
                                  102,
                                  181,
                                  16,
                                  35,
                                  129,
                                  214,
                                  69,
                                  128,
                                  154,
                                  252,
                                  64,
                                  79,
                                  52,
                                  127
                                ]
                              }
                            }
                          }
                        },
                        {
                          "_switch": {
                            "name": "scvString",
                            "value": 14
                          },
                          "_arm": "str",
                          "_armType": {
                            "_maxLength": 4294967295
                          },
                          "_value": "7"
                        }
                      ]
                    }
                  }
                },
                "subInvocations": []
              }
            }
          ]
        }
      },
      {
        "_attributes": {
          "function": {
            "_switch": {
              "name": "sorobanAuthorizedFunctionTypeContractFn",
              "value": 0
            },
            "_arm": "contractFn",
            "_value": {
              "_attributes": {
                "contractAddress": {
                  "_switch": {
                    "name": "scAddressTypeContract",
                    "value": 1
                  },
                  "_arm": "contractId",
                  "_armType": {
                    "_length": 32
                  },
                  "_value": {
                    "type": "Buffer",
                    "data": [
                      232,
                      8,
                      251,
                      255,
                      185,
                      70,
                      175,
                      127,
                      248,
                      65,
                      1,
                      210,
                      82,
                      54,
                      174,
                      141,
                      74,
                      125,
                      242,
                      129,
                      116,
                      44,
                      34,
                      107,
                      197,
                      3,
                      127,
                      111,
                      110,
                      162,
                      113,
                      83
                    ]
                  }
                },
                "functionName": "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
                "args": [
                  {
                    "_switch": {
                      "name": "scvAddress",
                      "value": 18
                    },
                    "_arm": "address",
                    "_value": {
                      "_switch": {
                        "name": "scAddressTypeAccount",
                        "value": 0
                      },
                      "_arm": "accountId",
                      "_value": {
                        "_switch": {
                          "name": "publicKeyTypeEd25519",
                          "value": 0
                        },
                        "_arm": "ed25519",
                        "_armType": {
                          "_length": 32
                        },
                        "_value": {
                          "type": "Buffer",
                          "data": [
                            76,
                            219,
                            245,
                            104,
                            41,
                            198,
                            51,
                            53,
                            239,
                            66,
                            121,
                            235,
                            61,
                            236,
                            110,
                            210,
                            177,
                            117,
                            102,
                            181,
                            16,
                            35,
                            129,
                            214,
                            69,
                            128,
                            154,
                            252,
                            64,
                            79,
                            52,
                            127
                          ]
                        }
                      }
                    }
                  },
                  {
                    "_switch": {
                      "name": "scvU64",
                      "value": 5
                    },
                    "_arm": "u64",
                    "_value": {
                      "_value": "1"
                    }
                  }
                ]
              }
            }
          },
          "subInvocations": []
        }
      }
    ]
  }
}

JSON

{
  "type": "execute",
  "args": {
    "source": "CDUAR677XFDK677YIEA5EURWV2GUU7PSQF2CYITLYUBX633OUJYVGTSS",
    "function": "purchase",
    "args": [
      "SomeNft:GBS7D7AJFWKIMWLD7KFAV2AXHSKCOE4DSSVKZQBGJCC3FRGS7WAS5WA6",
      "7"
    ]
  },
  "subInvocations": [
    {
      "type": "execute",
      "args": {
        "source": "CBJTFBZ6HNEOGA7LFK43BZLIMNIZVTGG5A5MEFE2U46FRDERLG2DAJTB",
        "function": "swap",
        "args": [
          "native",
          "USDC:GDEWIEQEB657FDO3GZIUTYS57T4M65QP352A2PN4CJPBCR55I5FWVAKG",
          "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
          "GA2EUJYVHATZ3MKXYFJUFF4PPUJQN36UKKKDGFUMKGUTBOHYOF6FHSUZ"
        ]
      },
      "subInvocations": [
        {
          "type": "execute",
          "args": {
            "source": "CASEGDCM6LCYEQUQRYOZDUHSZ4JLK5P5FEYI2A2FERZNXQTVS2CG3BAH",
            "function": "transfer",
            "args": [
              "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
              "7"
            ]
          },
          "subInvocations": []
        },
        {
          "type": "execute",
          "args": {
            "source": "CA4IKQKY4EUOV6XMSEWUTADPK6HMM7HTS5KQKJJKYI2QEM724NWLAKEI",
            "function": "transfer",
            "args": [
              "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
              "7"
            ]
          },
          "subInvocations": []
        }
      ]
    },
    {
      "type": "execute",
      "args": {
        "source": "CDUAR677XFDK677YIEA5EURWV2GUU7PSQF2CYITLYUBX633OUJYVGTSS",
        "function": "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
        "args": [
          "GBGNX5LIFHDDGNPPIJ46WPPMN3JLC5LGWUICHAOWIWAJV7CAJ42H6FBG",
          "1"
        ]
      },
      "subInvocations": []
    }
  ]
}

Analysis

While I will admit that the contract IDs don't help you (e.g. what is CDUAR...?), this could easily be built upon by e.g. block explorers or Freighter itself caching explanations for common contracts.

@paulbellamy
Copy link
Contributor

Putting on my, "non technical user" hat. Both the xdr and json examples you gave look like unintelligible computer-nonsense. Fine, the json outputs contract IDs instead of byte arrays, etc. 🤷

Interestingly, when you actually wanted to explain what the tree structure you were building does you invented a different (more graphical) format to do that. 😉

 purchase("SomeNft:G...", 7 xlm)
     |
     +--- swap(xlm, usdc, from, to)
     |      |
     |      |- xlm.transfer(from, to, 7)
     |      |
     |      |- usdc.transfer(to, from, 1)
     |
     +--- someNft.transfer(invoker, contract, 1)

^ This is what I would expect wallets to do. So if xdr -> json -> html is easier for wallets/dapps than xdr -> html, then fine, I guess.

@lmorgan824
Copy link

lmorgan824 commented Aug 23, 2023 via email

@paulbellamy
Copy link
Contributor

To clarify, by "xdr" in the above comment, I mean the js classes from stellar-base, not like base64 strings. But sounds like an intermediate representation might still be helpful. 👍

@Shaptic Shaptic changed the title [Proposal] Add human-friendly representations of invocation trees. Add JSONification of Soroban invocation trees. Aug 31, 2023
@Shaptic Shaptic merged commit 268a1a6 into soroban Sep 1, 2023
4 checks passed
@Shaptic Shaptic deleted the build-auth-trees branch September 1, 2023 18:24
Shaptic added a commit that referenced this pull request Sep 12, 2023
* Correctly set `minAccountSequence` in `TransactionBuilder` for large values (#539)
* Add support of CAP40 ed25519SignedPayload signer for SetOptionOp (#542)
* Add TypeScript interfaces for Ed25519SignedPayload signers
* Coalesce all xLM, Xlm, etc. => 'XLM' native asset code (#546)
* make sure sodium is not an empty object in service workers (#567)
* Add futurenet passphrase for soroban. (#550)
* Include standalone network passphrase (#555)
* Soroban auth next updates (#570)
* Add strkey parsing for contracts, and Address helper for building ScAddresses (#572)
* Update xdr to include HashIdPreimageContractAuth.nonce (#577)
* Add Address.toBuffer method (#578)
* Soroban value overhaul (#582)
* Update generated XDR to latest version. (#587)
* Update XDR and contract invocations to conform to the latest version (Preview 9). (#601)
* added soroban transaction data as tx builder param (#604)
* Add Contract support for strkey-style contract IDs (#612)
* Add Contract.address() method (#614)
* Add wrappers to easily deal with the myriad of `ScVal` integer types. (#620)
* Upgrade `js-xdr` to v3.0.0 to support `bigint` encoding.
* Add wrappers to easily convert between `ScVal` and native types. (#630)
* Update XDR to support Preview 10 (#633)
* Fix TypeScript definition for `invokeHostFunction` options (#635)
* Add fully-qualified `Operation` type to XDR type definitions. (#591)
* Adds Operation.isValidAmount jsdoc (#609)
* Removes the dependency on `crc` by calculating checksum in strkey (#621)
* Improve type flexibility when building `ScVal`s from native types (#638)
* Fix Preview 10 contract invoke & release `v10.0.0-soroban.3` (#642)
* Add GitHub Action that compares before-and-after bundle sizes. (#644)
* Make opinionated judgements about string/symbol decoding (#645)
* Make Node 16 the minimum version. (#651)
* Add standalone/futurenet passphrases to jsdoc (#654)
* Clean up unnecessary dependency entries (#652)
* Add `SorobanDataBuilder` builder pattern to prepare transactions easier (#660)
* Adds a way to create a `TransactionBuilder` from an existing transaction. (#656)
* Add basic contract event parsing into a human-readable structure (#659)
* Drop support for deprecated hex contract IDs (#658)
* Add helpers method to build authorization entries. (#663)
* Fix TypeScript definition for new static `TransactionBuilder` constructor (#665)
* Add ability to clear out operations from the transaction builder (#670)
* Add an existing method to XdrLargeInt, jsdoc/types fixup (#668)
* Expand contract footprint with contract code ledger key. (#662)
* Decode base64-encoded strings in new SorobanDataBuilder (#673)
* Add ability to modify and retrieve the resource footprint (#680)
* Fixes error messages for required amount parameters (#679)
* Add `Asset.contractId()` helper to predict contract IDs (#684)
* Upgrade dependencies to their latest minor/patch version (#685)
* Improves `SorobanDataBuilder` construction and adds a getter (#686)
* Add JSON-ification of Soroban invocation trees. (#669)
* Add utilities for formatting token amounts (`formatTokenAmount` & `parseTokenAmount`) (#667)
* Merges the final Protocol 20 XDR (i.e. for testnet) into `soroban` (#688)
* Add support to convert strings to large integer and address `ScVal`s (#690)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Paul Bellamy <paul@stellar.org>
Co-authored-by: George <Shaptic@users.noreply.github.com>
Co-authored-by: Jun Luo <4catcode@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: OrbitLens <33724849+orbitlens@users.noreply.github.com>
Co-authored-by: Piyal Basu <pbasu235@gmail.com>
Co-authored-by: George Kudrayvtsev <george@stellar.org>
Co-authored-by: shawn <sreuland@users.noreply.github.com>
Co-authored-by: Silence <35656692+silence48@users.noreply.github.com>
Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com>
Co-authored-by: jeesun 지선 <jeesunikim@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants