-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from violetprotocol/auth
Auth
- Loading branch information
Showing
8 changed files
with
115 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Ethereum Access Token Helpers | ||
|
||
Utilities for the Ethereum Access Token smart contract system. | ||
|
||
Use these tools to help you generate and sign your EATs. First ensure that your smart contracts follow appropriate EAT interfaces by ensuring all functions that intend to be modified with `requiresAuth` to use the following parameters prepended before your usual function parameters: | ||
|
||
```solidity | ||
function yourFunction(uint8 v, bytes32 r, bytes32 s, uint256 expiry, ...) {} | ||
``` | ||
|
||
where you insert your own function parameters in place of `...`. | ||
|
||
## Install | ||
|
||
Using npm: | ||
`npm install @violetprotocol/ethereum-access-token-helpers` | ||
|
||
Using yarn: | ||
`yarn add @violetprotocol/ethereum-access-token-helpers` | ||
|
||
## Usage | ||
|
||
```typescript | ||
const { splitSignature } = require("@ethersproject/bytes"); | ||
const { | ||
signAuthMessage, | ||
getSignerFromMnemonic, getSignerFromPrivateKey | ||
packParameters | ||
} = require("@violetprotocol/ethereum-access-token-helpers/utils"); | ||
|
||
const INTERVAL: number = 100 // seconds | ||
const FUNCTION_SIGNATURE = "0xabcdefgh"; | ||
const CONTRACT: ethers.Contract = ...; // for example an ERC20 token contract | ||
const SIGNER: ethers.Signer = ...; | ||
const CALLER: ethers.Signer = ...; | ||
const VERIFIER = "0x..."; // AuthVerifier contract address | ||
|
||
const recipient = "0x123..."; | ||
const amount = 1; | ||
|
||
// AuthToken domain for clear namespacing | ||
const authDomain = { | ||
name: "Ethereum Access Token", | ||
version: "1", | ||
chainId: SIGNER.getChainId(), | ||
verifyingContract: VERIFIER, | ||
}; | ||
|
||
// Construct AuthToken message with relevant data using ERC20 `transfer(address to, uint256 amount)` as the example tx | ||
// In the Auth compatible case, the ERC20 transfer function actually looks like this: | ||
// `transfer(uint8 v, bytes32 r, bytes32 s, uint256 expiry, address to, uint256 amount)` | ||
// where we just augment the original function with the required parameters for auth | ||
// the `parameters` property takes a packed, abi-encoded set of original function parameters | ||
const authMessage = { | ||
expiry: Math.floor(new Date().getTime() / 1000) + interval, | ||
functionCall: { | ||
functionSignature: FUNCTION_SIGNATURE, | ||
target: CONTRACT.address.toLowerCase(), | ||
caller: CALLER.address.toLowerCase(), | ||
parameters: packParameters(CONTRACT.interface, "transfer", [recipient, amount]), | ||
}, | ||
}; | ||
|
||
// Sign the AuthToken using the Signer | ||
const signature = splitSignature(await signAuthMessage(SIGNER, authDomain, authMessage)); | ||
|
||
// Pass all signed data to a transaction function call | ||
await CONTRACT.functionName( | ||
signature.v, | ||
signature.r, | ||
signature.s, | ||
authMessage.expiry, | ||
...params | ||
) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export { signAuthMessage } from "./signAuthMessage"; | ||
export { signMailMessage } from "./signMailMessage"; | ||
export { getSignerFromMnemonic, getSignerFromPrivateKey } from "./signer"; | ||
export { packParameters as packDummyParameters } from "./dummy"; | ||
export { packParameters } from "./packParameters"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { hexlify } from "@ethersproject/bytes"; | ||
import { ethers } from "ethers"; | ||
|
||
const packParameters = ( | ||
contractInterface: ethers.utils.Interface, | ||
functionNameOrSelector: string, | ||
params: any[], | ||
): string => { | ||
// detect function fragment | ||
const functionFragment = contractInterface.getFunction(functionNameOrSelector); | ||
|
||
// check if selected function fragment complies with auth compatible function format: | ||
// functionName(uint8 v, bytes32 r, bytes32 s, uint256 expiry, ...) | ||
if (!isAuthCompatible(functionFragment)) throw "packParameters: specified function is not AuthCompatible"; | ||
|
||
// hexlify function encoding from index 4 onwards with parameters | ||
return hexlify(contractInterface._encodeParams(functionFragment.inputs.slice(4), params)); | ||
}; | ||
|
||
const isAuthCompatible = (functionFragment: ethers.utils.FunctionFragment): boolean => { | ||
if (functionFragment.inputs[0].name != "v" || functionFragment.inputs[0].type != "uint8") return false; | ||
if (functionFragment.inputs[1].name != "r" || functionFragment.inputs[1].type != "bytes32") return false; | ||
if (functionFragment.inputs[2].name != "s" || functionFragment.inputs[2].type != "bytes32") return false; | ||
if (functionFragment.inputs[3].name != "expiry" || functionFragment.inputs[3].type != "uint256") return false; | ||
return true; | ||
}; | ||
|
||
export { packParameters }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters