Giter Site home page Giter Site logo

onflow / fcl-js Goto Github PK

View Code? Open in Web Editor NEW
323.0 46.0 120.0 51.46 MB

FCL (Flow Client Library) - The best tool for building JavaScript (browser & NodeJS) applications on Flow ๐ŸŒŠ

Home Page: https://onflow.org

License: Apache License 2.0

Makefile 0.06% JavaScript 86.37% TypeScript 13.57%
js blockchain smart-contracts onflow hacktoberfest cadence

fcl-js's Introduction

FLOW-JS-SDK Continuous Integration lerna



FCL JS

Connect your dapp to users, their wallets and Flow.

Quickstart ยท Report Bug ยท Contribute

What is FCL?

The Flow Client Library (FCL) JS is a package used to interact with user wallets and the Flow blockchain. When using FCL for authentication, dapps are able to support all FCL-compatible wallets on Flow and their users without any custom integrations or changes needed to the dapp code.

It was created to make developing applications that connect to the Flow blockchain easy and secure. It defines a standardized set of communication patterns between wallets, applications, and users that is used to perform a wide variety of actions for your dapp. FCL also offers a full featured SDK and utilities to interact with the Flow blockchain.

While FCL itself is a concept and standard, FCL JS is the javascript implementation of FCL and can be used in both browser and server environments. All functionality for connecting and communicating with wallet providers is restricted to the browser. We also have FCL Swift implementation for iOS, see FCL Swift contributed by @lmcmz.


Getting Started

Requirements

  • Node version v12.0.0 or higher.

Build

npm i
npm run build

Release

Packages stable versions releases are controlled by changesets from the master branch

Prerelease(alpha)

In order to create an alpha (pre-)release

  • create a branch with release-<VERSION> as a branch name
  • run:
npm run changeset pre enter alpha
npm run changeset version
npm run changeset publish

NOTE: you need to have an npm account and be a member of OnFlow organization

changeset commands should preferably be run from the release branch and not from feature branches in order to avoid merge conflicts with other feature branches when the release is ready to be published as stable run from the release branch

npm run changeset pre exit

and merge release-<VERSION> branch to master

Installation

To use the FCL JS in your application, install using yarn or npm

npm i -S @onflow/fcl
yarn add @onflow/fcl

Importing

ES6

import * as fcl from "@onflow/fcl";

Node.js

const fcl = require("@onflow/fcl");

FCL for Dapps

Wallet Interactions

  • Wallet Discovery and Sign-up/Login: Onboard users with ease. Never worry about supporting multiple wallets. Authenticate users with any FCL compatible wallet.
// in the browser
import * as fcl from "@onflow/fcl"

fcl.config({
  "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn", // Endpoint set to Testnet
})

fcl.authenticate()

FCL Default Discovery UI

Note: A Dapper Wallet developer account is required. To enable Dapper Wallet inside FCL, you need to follow this guide.

  • Interact with smart contracts: Authorize transactions via the user's chosen wallet
  • Prove ownership of a wallet address: Signing and verifying user signed data

Learn more about wallet interactions >

Blockchain Interactions

  • Query the chain: Send arbitrary Cadence scripts to the chain and receive back decoded values
import * as fcl from "@onflow/fcl";

const result = await fcl.query({
  cadence: `
    pub fun main(a: Int, b: Int, addr: Address): Int {
      log(addr)
      return a + b
    }
  `,
  args: (arg, t) => [
    arg(7, t.Int), // a: Int
    arg(6, t.Int), // b: Int
    arg("0xba1132bc08f82fe2", t.Address), // addr: Address
  ],
});
console.log(result); // 13
  • Mutate the chain: Send arbitrary transactions with your own signatures or via a user's wallet to perform state changes on chain.
import * as fcl from "@onflow/fcl";
// in the browser, FCL will automatically connect to the user's wallet to request signatures to run the transaction
const txId = await fcl.mutate({
  cadence: `
    import Profile from 0xba1132bc08f82fe2
    
    transaction(name: String) {
      prepare(account: AuthAccount) {
        account.borrow<&{Profile.Owner}>(from: Profile.privatePath)!.setName(name)
      }
    }
  `,
  args: (arg, t) => [arg("myName", t.String)],
});

Learn more about on-chain interactions >

Utilities

  • Get account details from any Flow address
  • Get the latest block
  • Transaction status polling
  • Event polling
  • Custom authorization functions

Learn more about utilities >

Typescript Support

FCL JS supports TypeScript. If you need to import specific types, you can do so via the @onflow/typedefs package.

import {CurrentUser} from "@onflow/typedefs"

const newUser: CurrentUser = { 
  addr: null,
  cid: null,
  expiresAt: null,
  f_type: 'User',
  f_vsn: '1.0.0',
  loggedIn: null,
  services: []
}

For all type definitions available, see this file

Next Steps

See the Flow App Quick Start.

See the full API Reference for all FCL functionality.

Learn Flow's smart contract language to build any script or transactions: Cadence.

Explore all of Flow docs and tools.


FCL for Wallet Providers

Wallet providers on Flow have the flexibility to build their user interactions and UI through a variety of ways:

  • Front channel communication via Iframe, pop-up, tab, or extension
  • Back channel communication via HTTP

FCL is agnostic to the communication channel and be configured to create both custodial and non-custodial wallets. This enables users to interact with wallet providers without needing to download an app or extension.

The communication channels involve responding to a set of pre-defined FCL messages to deliver the requested information to the dapp. Implementing a FCL compatible wallet on Flow is as simple as filling in the responses with the appropriate data when FCL requests them. If using any of the front-channel communication methods, FCL also provides a set of wallet utilities to simplify this process.

Current Wallet Providers

Wallet Discovery

It can be difficult to get users to discover new wallets on a chain. To solve this, we created a wallet discovery service that can be configured and accessed through FCL to display all available Flow wallet providers to the user. This means:

  • Dapps can display and support all FCL compatible wallets that launch on Flow without needing to change any code
  • Users don't need to sign up for new wallets - they can carry over their existing one to any dapp that uses FCL for authentication and authorization.

The discovery feature can be used via API allowing you to customize your own UI or you can use the default UI without any additional configuration.

Note: To get your wallet added to the discovery service, make a PR in fcl-discovery.

Building a FCL compatible wallet

  • Read the wallet guide to understand the implementation details.
  • Review the architecture of the FCL dev wallet for an overview.
  • If building a non-custodial wallet, see the Account API and the FLIP on derivation paths and key generation.

Support

Notice an problem or want to request a feature? Add an issue.

Discuss FCL with the community on the forum.

Join the Flow community on Discord to keep up to date and to talk to the team.

fcl-js's People

Contributors

10thfloor avatar alxocity avatar avcdsld avatar benjaminkvm avatar boczeratul avatar bthaile avatar btspoony avatar chasefleming avatar codingone21 avatar cybercent avatar danielhour avatar dependabot[bot] avatar github-actions[bot] avatar gnujoow avatar gregsantos avatar gyorgy-kurucz-vacuum avatar janezpodhostnik avatar jeffreydoyle avatar jribbink avatar justinbarry avatar kerrywei avatar leoncoe avatar marcoroth avatar maxstalker avatar muttoni avatar nialexsan avatar orodio avatar psiemens avatar srinjoyc avatar wise4rmgod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fcl-js's Issues

Encode made to match interaction adt

Encode Made to Match Interaction ADT

Background

The original design of the encode package for the Flow JS-SDK introduced a unique interface to pass in arguments to be encoded. A more robust solution would be to update the interface of the encode package to more closely reflect the structure of the interaction ADT that flows through the entire JS-SDK.

The encode package should expose two functions with the following signatures:

const rlpEncodedInsideMessage = encodeInsideMessage({
   ...ix.message,
   proposer: ix.accounts[ix.proposer],
   payer: ix.accounts[ix.payer].addr,
   authorizers: ix.authorizers.map(cid => ix.accounts[cid].addr)
})

const rlpEncodedOutsideMessage =encodeOutsideMessage({
   ...ix.message,
   proposer: ix.accounts[ix.proposer],
   payer: ix.accounts[ix.payer].addr,
   authorizers: ix.authorizers.map(cid => ix.accounts[cid].addr),
   payloadSigs: insideSignatures,
})

Expected Outcomes

  • The encode package exposes two functions encodeInsideMessage and encodeOutsideMessage.
  • encodeInsideMessage and encodeOutsideMessage have signatures that reflect the above.

Create build-script

build-script

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-script is created

Create build-authorizations

build-authorizations

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-authorizations is created

Pull fcl.config out into its own module

We are trying to create a centralized location for configuration, for both the SDK and FCL. One of the reasons for this is so that we can have a version of sdk.send that can find the accessNode from a centralized application level configuration.

Requires the following to be done first

  • #194 Pull Actor out of FCL

Expected Outcomes

  • @onflow/sdk-config exists and conforms to module standards
  • @onflow/fcl uses @onflow/sdk-config instead of packages/fcl/src/config/

Docs for Send

Docs for send

Background

As more people onboard and get started building their next-gen apps on Flow, having great documentation surrounding the use of the JS-SDK Send package will empower developers to get started building their apps fast. Currently there isn't sufficient documentation and examples surrounding using the JS-SDK Send package, and developers are experiencing some friction when getting started. Since Flow is designed to be the go-to blockchain for empowering developers, the JS-SDK Send package must meet and exceed this standard by providing best in class documentation and examples.

Expected Outcomes

  • Documentation and Examples exist for Send Transaction
  • Documentation and Examples exist for Send Execute Script
  • Documentation and Examples exist for Send Get Latest Block
  • Documentation and Examples exist for Send Get Transaction Status
  • Documentation and Examples exist for Send Get Events
  • Documentation and Examples exist for Send Get Account

Transaction Metadata for Media rich wallet transactions

Transactions currently only contain the absolute minimum amount of data needed for signingFunctions to sign, verify and recreate them.

Background

Currently the data we send to a signingFunction looks like this:

type Interaction {
  // the entire interaction used for reconstruction
}

type Roles {
  proposer: Boolean
  payer: Boolean
  authorizer: Boolean
}

type payload {
  message: Hex
  addr: String
  roles: Roles
  interaction: Interaction
}

This isn't exactly what it should be, but a very quick first pass could add something like this:

type Image {
  src: String
  alt: String
  width: Number
  height: Number
}

type Meta {
  title: String
  description: String
  image: Image
}

type Payload {
  ...
  meta: Meta
}

Really it only needs to be enough to enable wallets to make the experience a little better.

Using the rest of the sdk as an example it could look something like this:

sdk.build([
  sdk.transaction(TRANSFER_NFT),
  sdk.title("Title of NFT"),
  sdk.description("Its the best NFT"),
  sdk.image("https://placekitten.com/g/200/200", {
    width: 200,
    height: 200,
    alt: "An adorable NFT"
  })
])

// -- or --

sdk.build([
  sdk.transaction(TRANSFER_NFT),
  sdk.meta([
    sdk.title("Title of NFT"),
    sdk.description("Its the best NFT"),
    sdk.image("https://placekitten.com/g/200/200", {
      width: 200,
      height: 200,
      alt: "An adorable NFT"
    })
  ])
])

Expected Outcomes

Add the ability to optionally send along to the signingFunction the following meta data

  • Title
  • Description
  • Price
  • Image

Types of meta data values are checked

  • Strings
    • Title
    • Description
    • Price
    • Image
  • Complex Types
    • [ ] Image (type Image from above)

Documentation that outlines how to set the following meta data

  • Title
  • Description
  • Price
  • Image

Create build-invariant

Create build-invariant

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-invariant is created

Document outline expectations of new modules and guidelines on how to achieve expectations.

We want our artifacts to be as consumable as possible on as many platforms as possible. Currently our modules only allow for the consumption by platforms and build tools that support CommonJS. As we start to break down our larger modules into smaller more composable modules, it should be a good time to start supporting more things. We are in need of some sort of documentation on how to construct our modules in a way that can support as many platforms as reasonably possible at this time.

Expected Outcomes

Documentation contains instructions that enable the use of the module with the following platforms

  • CommonJS
  • TypeScript
  • Browser-ESM
  • Deno

Stretch Outcomes

  • Node-ESM
  • Browser Global

Notes for the Future

Right now this is going to be an extremely manual process, as no build tools realistically produce the sort of outcome we are wanting here, in particular around Browser-ESM and Deno support.

Create build-get-latest-block

Create build-get-latest-block

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-get-latest-block is created

Pull tag constants out of @onflow/interaction

The interaction adt has a tag field that uses a binary representation of the different types of interactions it can be. We originally did this for performance, but now it seems that was a little premature. The idea here is to pull these individual tags out into their own modules, so other modules in the future can depend on them in the future without requiring the entire interaction module. We also want to add and remove tags in the future, and needing to update everything that consumes a tag because we added somethings that has nothing to do with it seems like a hassle and a burden we don't want to push on the consumers of things, so they should be in separate modules.

Expected Outcomes

  • @onflow/ix-tag-get-account exists and is consumed by interaction
  • @onflow/ix-tag-get-events exists and is consumed by interaction
  • @onflow/ix-tag-get-latest-block exists and is consumed by interaction
  • @onflow/ix-tag-get-transaction-status exists and is consumed by interaction
  • @onflow/ix-tag-ping exists and is consumed by interaction
  • @onflow/ix-tag-script exists and is consumed by interaction
  • @onflow/ix-tag-transaction exists and is consumed by interaction

Create build-get-transaction-status

Create build-get-transaction-status

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-get-transaction-status is created

Deprecate Params

We are wanting to remove the current param mechanism from the sdk. Due to our commitment to backwards compatibility, this issue is mostly about adding deprecation warnings when params are used and how to migrate away from them.

Background

Currently we can write a script like this using params:

function add(a, b, message) {
  return fcl.send([
    fcl.script`
      pub fun main(): Int {
        log("${p => p.msg}")
        return ${p => p.a} + ${p => p.b}
      }
    `,
    fcl.params([
      fcl.param(a, t.Identity, "a"),
      fcl.param(b, t.Identity, "b"),
      fcl.param(message, t.Identity, "msg")
    ])
  ])
}

add(5, 6)
  .then(fcl.decode)
  .then(value => assert(value === 5 + 6)) // true

Originally we were hoping to gracefully transition this into the arguments (which were recently added), thinking that people would only need injection style interop or interaction level arguments, but this line of thought proved to be incorrect. We now understand that what the consumer needs is arguments for user input to scripts and transactions, and being able to dynamically change the script/transaction given some sort of external value that is completely in control of the consumer, all of which we can already do.

Injection style interop (params) is also quite tricky. It is susceptible to injection attacks (where the value escapes the current expression, does its own malicious expression, continues on as if nothing happend), the user is responsible for making sure the cadence is valid. For example: log(${p => p.imAString}) would break because the string isn't wrapped in quotes and would have to be written like: log("${p => p.imAString}"), a subtle but devastating issue if missed.

Also the code example above can be done a couple other ways.

First as arguments (the preferred way) which has the following benefits

  • not susceptible to inject attacks via input as it is typed, and checked by the Cadence VM
  • no need for thinking about stuff like "do i need to wrap this in quotes".
function add(a, b, message) {
  return fcl.send([
    fcl.script`
      pub fun main(a: Int, b: Int): Int {
        return a + b
      }
    `,
    fcl.args([
      fcl.arg(a, t.Int),
      fcl.arg(b, t.Int),
    ])
  ])
}
// original assert should still hold true

As standard string interop. This has many of the original issues with params, but it is way less complex, closer to what people understand as standard javascript, and is more obvious that the users are responsible for making sure the values once injected into the cadence is valid. (I think its also easier to read and understand the intent than the params)

function add(a, b, message) {
  return fcl.send([
    fcl.script`
      pub fun main(): Int {
        log("${message}")
        return ${a} + ${b}
      }
    `
  ])
}
// original assert should still hold true

As a mix of the above.
The case for this one would be where the message is in control of the dapp (consumer) while the user of the dapp is in control of a and b. Pros and Cons of the above two examples also apply to this one.

function add(a, b, message) {
  return fcl.send([
    fcl.script`
      pub fun main(a: Int, b: Int): Int {
        log("${message}")
        return a + b
      }
    `,
    fcl.args([
      fcl.arg(a, t.Int),
      fcl.arg(b, t.Int),
    ])
  ])
}

Expected Outcome

Transition documentation

  • How to migrate from current params to arguments and standard interop
  • Examples of params vs arguments vs standard interop

Display deprecation notices with transition documentation when

  • fcl.params is called
  • When a function is interopped into the template literal ${p => p.a}

Documentation on when to use arguments vs standard interop

  • when to use arguments
  • when to user standard interop

Stretch Outcome

  • Display deprecation notices when a value is accessed on the params object (maybe using a proxy?)

Document Current State of FCL

Need a blog or forum post to document what the current state of FCL.

-What we have
-Where we are going
-Where we need help

Create build-transaction

build-transaction

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-transaction is created

Create build-proposer

build-proposer

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-proposer is created

Remove "Profile" concept from dev-wallet

FCL is changing, we have plans for bringing profiles back later, but that will be in a fairly different way (FCL Profile Services).
In order to safeguard against developers using something that will be going away we should bring the dev-wallet as close to what it will be as we can, in this case it should mostly be removing functionality from the dev-wallet.

Expected Outcomes

  • Remove "Use this profile" portion of authentication process.

Stretch Outcomes

  • Remove the concept of profiles completely from the dev-wallet.

State of FCL document

The concept of FCL and the role it plays in the bigger picture of things has changed drastically over the last couple months. Before we had a lot of trouble explaining to people the difference between the SDK and FCL, but now I think those dividing lines are much clearer. I think we are now in need of a document that sort of explains where we are, where we are going, and our plan to get there.

Expected Outcomes

Document needs to outline the following

  • Overview of FCL
  • Where FCL is currently at
  • Where we think FCL is going
  • How we think we are going to get FCL to where we think it is going
  • Outline underlying mechanisms
    • Authentication
    • Identity as Configuration
    • FCL Services

Documentation Showing Example Uses of SDK

Documentation Showing Example Uses of SDK

Background

As more people onboard and get started building their next-gen apps on Flow, having great documentation surrounding the use of the JS-SDK will empower developers to get started building their apps fast. Currently there isn't sufficient documentation and examples surrounding using the JS-SDK, and developers are experiencing some friction when getting started. Since Flow is designed to be the go-to blockchain for empowering developers, the JS-SDK must meet and exceed this standard by providing best in class documentation and examples.

Expected Outcomes

  • Documentation and Examples of interacting with Flow to execute a Script.
    • Example of executing a Script with Script Arguments
  • Documentation and Examples of interacting with Flow to get an Account.
  • Documentation and Examples of interacting with Flow to execute a Transaction.
    • Example of executing a Transaction with Transaction Arguments.
    • Detailed explanation of Authorizers, Proposer and Payer.
    • Detailed explanation of Authorizer concept and philosophy.
  • Documentation and Examples of interacting with Flow to get a Transaction Status.
  • Documentation and Examples of interacting with Flow to get Events.
  • Documentation and Examples of interacting with Flow to get the Latest Block.

Deprecate the current fields returned in `fcl.currentUser().subscribe(callback)` and `fcl.currentUser().snapshot()`

fcl.currentUser().subscribe() and fcl.currentUser().snapshot() are used to access the current state of the user. FCL will be moving in a slightly different direction, these functions will still be usable to know the status of the currentUser such as if they are authenticated or not, but we have now discovered this shouldn't be the home of other things like the current users profile. Because of our commitment to backwards compatibility we will be deprecating access to individual fields on the object, and removing them in a later issue. This issue is only about making consumers of the functions aware that certain fields they are using should not be used anymore.

Background

The current data structure fcl.currentUser().subscribe() and fcl.currentUser().snapshot() return look like this:

type Identity {
  name: String
  addr: String
  avatar: String
  cover: String
  color: String
  bio: String
}

type Scope {
  email: String
}

type Provider {
  addr: String
  pid: String
  name: String
  icon: String
}

type Authorization {
  // Will eventually be replaced with fcl authorization services
}

type CurrentUser {
  cid: String
  loggedIn: Boolean
  verified: Boolean
  identity: Identity
  scoped: Scope
  provider: Provider
  authorizations: [Authorization]
}

For now the only things we have confidence in keeping around are:

type CurrentUser {
  cid: String                // Who is currently authenticated
  loggedIn: Boolean   // Are they authenticated
  authorizations: [Authorization] // This is still needed for fcl to work, will be deprecated later
}

Expected Outcome

Documentation on the deprecation of the available values

  • Docs on verified
  • Docs on identity
  • Docs on scoped
  • Docs on provider

Let consumer of fcl know when they access one of the deprecated values including a link to the docs.

  • warn on verified
  • warn on identity
  • warn on scope
  • warn on provider

Stretch Outcome

  • Docs explaining the upcoming changes/deprecation to the authorizations in the currentUser data
  • Selectively warn the consumer if authorizations is accessed outside of fcl doing its thing

Create build-validator

build-validator

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-validator is created

Docs for Stored Interactions

Docs for Stored Interactions

Background

Stored Interactions encapsulate common use cases of the Flow JS-SDK. Instead of building an entire interaction yourself, you can choose to use a stored interaction which will accomplish your desired outcome for you. Currently, there exists no documentation for any stored interaction in the JS-SDK. In order to provide a better experience for our developers, documentation must be created to better explain the purpose of stored interactions and each stored interaction that is created.

Expected Outcomes

  • There exists a Readme that explains the purpose of stored interactions.
  • There exists a Readme that explains and documents each stored interaction that is created.

Create resolve-accounts

resolve-accounts

Background

Moving resolvers out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-resolve-accounts is created

Create build-limit

build-limit

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-limit is created

Pull status constants out of @onflow/interaction

The interaction adt has a status field that uses a binary representation of the different types statuses it can have. We originally did this for performance, but now it seems that was a little premature. The idea here is to pull these individual statuses out into their own modules, so other modules in the future can depend on them in the future without requiring the entire interaction module. We also want to add and remove statuses in the future, and needing to update everything that consumes a status because we added something that has nothing to do with it seems like a hassle and a burden we don't want to push on the consumers of things, so they should be in separate modules.

Expected Outcomes

  • @onflow/ix-status-ok exists and is consumed by @onflow/interaction
  • @onflow/ix-status-bad exists and is consumed by @onflow/interaction

FCL Documentation Cleanup

Need to go through the current FCL documentation and make sure everything is updated to the latest and greatest.

Stored Interaction - Set Code on Account

Stored Interaction - Set Code on Account

Background

A common use case for the Flow JS SDK is to set the code for an Account on Flow. In Flow, Accounts contain a string of Cadence Code within them, and a transaction is required to set the code within that account. Having a stored interaction for setting an accounts code will be valuable in that developers will not need to build their own solutions for what is a common use case.

The Set Code on Account Stored Interaction must follow the same format as the stored interaction for creating an account which already exists in the repo.

Expected Outcomes.

  • A Stored Interaction for setting an Accounts Code Exists.
  • An example of using the Stored Interaction is in its Readme.
  • An example of using the Stored Interaction is in the React-Example project.
  • The Stored Interaction has a valid Title
  • The Stored Interaction has a valid Description
  • The Stored Interaction has a valid Hash
  • The Stored Interaction has a valid Version Number

Create build-get-events

build-get-events

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-get-events is created

Create a UID Module

Create a UID Module

Background

We need a module which exposes a single function which can generate a string which is extremely unlikely to be generated again - a unique identifier.

Purpose

This unique identifier will be used to generate ids used in the interaction ADT.

Expected Outcomes

  • A new module @onflow/uid is created.
  • The new module exposes a single function to generate a UID.
  • A UID which is generated is extremely unlikely to be generated again - unique.

Documentation for Types

Documentation for Types

Background

As more people onboard and get started building their next-gen apps on Flow, having great documentation surrounding the use of the JS-SDK Types will empower developers to get started building their apps fast. Currently there isn't sufficient documentation and examples surrounding using the JS-SDK Types, and developers are experiencing some friction when getting started. Since Flow is designed to be the go-to blockchain for empowering developers, the JS-SDK Types must meet and exceed this standard by providing best in class documentation and examples.

Expected Outcomes

  • Types include an example use for each valid JSON-CDC type (JSON encoding of Cadence Types).
  • Types include valid examples of types as arguments for Transactions.
  • Types include valid examples of types as arguments for Scripts.

Create build-get-account

build-get-account

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-get-account is created

Authorization Function Docs/Spec

We have landed on a concept we call Authorization Functions as a standardized way to sign transactions. We need some documentation and specs outlining their role to play, what they are, how they work, what they need to do, what they are passed and what they need to return.

Expected Outcomes

Documentation

  • Outlines how the Authorization function works
  • Outlines what it needs to return
  • Outlines how it is consumed by the sdk

Spec

  • Authorization Function
  • Internal Signing Function

Stretch Outcomes

  • Examples of authorization functions

In Depth Interaction Documentation

In Depth Interaction Documentation

Background

In order to improve the usability of the Flow JS-SDK, better, in depth documentation is required for the Interaction ADT which is used throughout the codebase.

Expected Outcomes

  • An in depth explanation of the structure of the Interaction Object. Including points on why each part is included.
  • An in depth discussion on the philosophy of the Interaction Object. Including discussion on lazy evaluation and async decomposition.
  • Overview of how the Interaction moves between phases of Build to Resolve to Send

Pull Get/Put/Update/Destroy Out of Interaction Package

Pull Get/Put/Update/Destroy Out of Interaction Package

Background

The CRUD style Get/Put/Update/Destroy functions available in the current interaction package must be removed as to allow for greater decoupling of packages and overall better code health.

Expected Outcomes

  • New package @onflow/ix-assigns is created
  • Function Get is available on @onflow/ix-assigns
  • Function Put is available on @onflow/ix-assigns
  • Function Update is available on @onflow/ix-assigns
  • Function Delete is available on @onflow/ix-assigns

Create build-payer

build-payer

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-payer is created

SDK - Sign Arbitrary Data

SDK - Sign Arbitrary Data.

Background

An upcoming change to the Flow Access API will require a network tag to be prepended to each signed data as it is sent to the Access API. This network tag will determine whether the data is valid for the specified network it is to be sent to. Signing functions must consume a tag variable in their interface as to determine if the data it is to sign is being signed for the correct network it is intended for. If, for example, a piece of data is to be signed without necessarily being sent to a network (ie: without a network tag), a standardized method is needed as to construct the correct call to a signing function for this case.

Implementation

A new sdk.sign function available in the Flow JS-SDK will allow arbitrary pieces of data to be signed without specifying a network tag.

Example Implementation

sdk.sign will contain an implemenatation potentially like:

async function sign(authorization, data) {
  const acct = await authorization(account())
  return acct.signingFunction({
    message: data,
    tag: "ARBITRARY",
    addr: acct.addr,
    keyId: acct.keyId,
    roles: {
      proposer: false,
      payer: false,
      authorizer: false,
    },
    interaction: null,
  })
}

This implementation proxies the call to sdk.sign to the signing function available on the account derived from the authorization passed into it. The tag ARBITRARY will allow the signing function to determine that this data to be signed is not intended to have a network tag prepended to it.

Expected Outcomes

  • signingFunction consumes a tag variable in its interface.
  • There exists a method sdk.sign which can sign arbitrary data.

Create resolve-arguments

resolve-arguments

Background

Moving resolvers out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-resolve-arguments is created

Busted Link in README

Issue To Be Solved

  1. Link Busted in line 2 of the README
    For a guide on how to use the SDK Start Here

Not sure what the link was to display, so I can't suggest a solution.

Create build-params

build-params

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-params is created

Allow wallet provider to handle the sending of TXs

Instructions

Currently when user sends a transaction, FCL gathers signatures from wallet provider and then calls access node gRPC by itself. In this case, wallet provider wouldn't necessarily know the status of the TX, or if it's sent to blockchain at all (maybe user gets disconnected from internet after wallet signs the TX).

Issue To Be Solved

Wallet provider doesn't necessarily know the status of the TX after it has been signed.

Proposed Solution

https://github.com/onflow/flow-js-sdk/blob/master/packages/send/src/send-transaction.js#L47

  • To make the process as consistent with others as possible, make the gRPC request step configurable, depending on wallet configs. The configs can come from the handshake hook.

Context

As custodial wallet provider serving also as payer, we would need to keep track of the status of the TX.
An alternative solution is to notify wallet provider the TX ID so wallet provider can track itself, which seems a bit ugly IMO.

FCL: requests to access node use the protocol of the host page instead of configured value

Problem

If the FCL (using dev-wallet) is used on a host page running with https, then calls to the access node also use https, despite FCL being configured with http.

For example, dapper-web-services runs on localhost using https. It uses the FCL/dev-wallet and the FLOW emulator running locally to allow a user to pay for purchases using Flow tokens. FCL is configured as:

 fcl
    .config()
    .put('accessNode.api', 'http://localhost:8080')
    .put('challenge.handshake', 'http://localhost:8701/flow/authenticate');

When the user attempts to pay for something with their Flow tokens, we call FCL:

  const authorization = fcl.currentUser().authorization;

  const transaction = await fcl.serialize([
    fcl.payer(authorization),
    fcl.proposer(authorization),
    fcl.authorizations([authorization]),
    fcl.transaction`${cadenceTx}`,
  ]);

which pops open the dev-wallet iframe:

image

The iframe makes requests to the challenge.handshake url on http as expected by the configuration above.

image

However, when the user clicks "Use this profile", FCL will attempt to make a request to the accessNode.api on https, not http as specified in the configuration:

image

From what I've seen from tracing through the running code, the url //localhost:8080/access.AccessAPI/GetAccount is passed to fetch, and since the request is coming from the host app (ie. dapper-web-services running on https), it uses https as the scheme instead of http.

Steps to Reproduce

Try to use the dev wallet + flow emulator on an app that is using https instead of http.

Context

This is blocking a "Pay with Flow tokens" POC on dapper-web-services. The POC would allow a user to buy NBA Top Shot moments using Flow tokens when running the Dapper app locally.

Initial Error Documents Structure

Initial Error Documents Structure

Background

A key part of the usability of the Flow JS-SDK will be in being able to quickly identify and remedy errors that occur during development. Since errors can naturally occur anywhere in the codebase, common errors that can come up in each of those parts of the codebase must be identified and tracked. Since common errors will likely require the same solution to fixed, those solutions to those common errors should be also tracked.

An ERRORS.md document should be created in each module to list each common error and its corresponding solution. A UID (Unique identifier) must be generated for each error and solution, and should accompany each error and solution in each ERRORS.md document.

Future work to the JS-SDK will be to implement code to catch these common errors, and throw a new error with an accompanying link to the right part of the ERRORS.md document stored in this repo. The developer receiving these errors will be able to identify which common error they are seeing, and using the UID for that error, they can find the corresponding solution to that error.

Expected Outcomes.

  • An ERRORS.md document is included in each module in this repository.
  • A common format is created for the ERRORS.md documents.
  • A method for generating common error UIDs is identified and stored in a common README.md for reference.

Repo Cleanup

Context:
Need to break down modules into smaller single purpose better documented modules with types.

Create build-ref

build-ref

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-ref is created

Pull Actor out of FCL so it can be used by the SDK

Actor is a mechanism in FCL that helps eliminate certain race conditions, allowing for async communication between two entities but still allowing for a forced order where it matters. In the future we want to be able to pull fcl.config out into its own module so the SDK can be more usable, fcl.config depends on Actor so this issue is also a prerequisite for this.

Expected Outcomes

  • @onflow/actor module exists and conforms to the module standards
  • @onflow/fcl uses @onflow/actor in place of packages/fcl/src/actor

Create build-arguments

build-arguments

Background

Moving builders out of the SDK package into their own single purpose package will enable better code health, smaller bundle size and generally decrease entropy between packages when things inevitably change and progress.

Expected Outcomes

  • @onflow/sdk-build-arguments is created

Bring React Example up to Date

Bring React Example up to Date

Background

As more people onboard and get started building their next-gen apps on Flow, having great documentation surrounding the use of the JS-SDK will empower developers to get started building their apps fast. Currently there isn't sufficient documentation and examples surrounding using the JS-SDK, and developers are experiencing some friction when getting started. Since Flow is designed to be the go-to blockchain for empowering developers, the JS-SDK must meet and exceed this standard by providing best in class documentation and examples.

Expected Outcomes

  • React Example contains a Transaction Example.
    • Transaction Example uses an Authorization Function.
    • Transaction Example overviews difference in Payer, Proposer and Authorizer.
    • Transaction Example includes a Transaction Arguments example.
  • React Example contains a Script Example.
    • Script Example includes a Script Arguments example.
  • React Example contains a Get Account Example
  • React Example contains a Get Transaction Status example.
  • React Example contains a Get Latest Block example.
  • React Example contains a Get Events example.

Accept different authorization logic when current user is used as proposer / payer

Instructions

Currently the authorization logic is exactly the same when user identity is used as a proposer and payer

fcl.proposer(fcl.currentUser().authorization)
fcl.payer(fcl.currentUser().authorization)

And they will be merged into a single authorization request and will only get a single signature.
For some wallet providers this may need to be different when an identity is used as proposer and when it's used as payer. For example, a custodial wallet provider may use the same payer account for all of its users.

Issue To Be Solved

Accept configuration from handshake hook so proposer and payer logic can be different.

Suggested Solution

Augment the hook API spec to specify different address when the identity is used as a payer

{
  addr: '0000000000000000000000000000000000000002',
  keyId: 0,
  // Add this. When payerAddr is not present then use addr as payerAddr.
  payerAddr: '0000000000000000000000000000000000000003',
  identity: {},
  ...,
},

Then perhaps in interactions handle makePayer and makeProposer differently

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.