Skip to content

Commit

Permalink
update: add FCLCrypto contract and deploy instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Greg Santos committed Jul 11, 2022
1 parent fc91ed0 commit 2e2e37c
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 6 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@ It demonstrates some of the basic features of a **Flow Dapp** using **FCL**

## Getting Started

First, run the development server:
```bash
npm install
```

Run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

Check the console output for useful logs and transaction status.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
### Deploy Contracts to Emulator

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
For local development you can deploy contracts to the Flow emulator.
Add them to `flow.json` and run:

```js
flow project deploy --network=emulator
```

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/verify](http://localhost:3000/api/verify).

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

## FCL Local Development

Expand Down
27 changes: 27 additions & 0 deletions flow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"emulators": {
"default": {
"port": 3569,
"serviceAccount": "emulator-account"
}
},
"contracts": {
"FCLCrypto": "./flow/cadence/contracts/FCLCrypto.cdc"
},
"networks": {
"emulator": "127.0.0.1:3569",
"mainnet": "access.mainnet.nodes.onflow.org:9000",
"testnet": "access.devnet.nodes.onflow.org:9000"
},
"accounts": {
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"key": "28b9aa18adda109686c9d4937a58e4b3044ab57bac55679b1050ef9898bf4bba"
}
},
"deployments": {
"emulator": {
"emulator-account": ["FCLCrypto"]
}
}
}
108 changes: 108 additions & 0 deletions flow/cadence/contracts/FCLCrypto.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
pub contract FCLCrypto {

pub fun verifyUserSignatures(
address: Address,
message: String,
keyIndices: [Int],
signatures: [String]
): Bool {
return self.verifySignatures(
address: address,
message: message,
keyIndices: keyIndices,
signatures: signatures,
domainSeparationTag: self.domainSeparationTagFlowUser,
)
}

pub fun verifyAccountProofSignatures(
address: Address,
message: String,
keyIndices: [Int],
signatures: [String]
): Bool {
return self.verifySignatures(
address: address,
message: message,
keyIndices: keyIndices,
signatures: signatures,
domainSeparationTag: self.domainSeparationTagAccountProof,
) ||
self.verifySignatures(
address: address,
message: message,
keyIndices: keyIndices,
signatures: signatures,
domainSeparationTag: self.domainSeparationTagFlowUser,
)
}

priv fun verifySignatures(
address: Address,
message: String,
keyIndices: [Int],
signatures: [String],
domainSeparationTag: String,
): Bool {
pre {
keyIndices.length == signatures.length : "Key index list length does not match signature list length"
}

let account = getAccount(address)
let messageBytes = message.decodeHex()

var totalWeight: UFix64 = 0.0
let seenKeyIndices: {Int: Bool} = {}

var i = 0

for keyIndex in keyIndices {

let accountKey = account.keys.get(keyIndex: keyIndex) ?? panic("Key provided does not exist on account")
let signature = signatures[i].decodeHex()

// Ensure this key index has not already been seen
if seenKeyIndices[accountKey.keyIndex] ?? false {
return false
}

// Record the key index was seen
seenKeyIndices[accountKey.keyIndex] = true

// Ensure the key is not revoked
if accountKey.isRevoked {
return false
}

// Ensure the signature is valid
if !accountKey.publicKey.verify(
signature: signature,
signedData: messageBytes,
domainSeparationTag: domainSeparationTag,
hashAlgorithm: accountKey.hashAlgorithm
) {
return false
}

totalWeight = totalWeight + accountKey.weight

i = i + 1
}

return totalWeight >= 1000.0
}

priv let domainSeparationTagFlowUser: String
priv let domainSeparationTagFCLUser: String
priv let domainSeparationTagAccountProof: String

init() {
self.domainSeparationTagFlowUser = "FLOW-V0.0-user"
self.domainSeparationTagFCLUser = "FCL-USER-V0.0"
self.domainSeparationTagAccountProof = "FCL-ACCOUNT-PROOF-V0.0"
}
}
2 changes: 1 addition & 1 deletion flow/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fcl from "@onflow/fcl"
import getConfig from "next/config"

const USE_LOCAL = false
const USE_LOCAL = true
const resolver = async () => ({
appIdentifier: "Awesome App (v0.0)",
nonce: "3037366134636339643564623330316636626239323161663465346131393662",
Expand Down

0 comments on commit 2e2e37c

Please sign in to comment.