# StarkWare Provider

Heads up! The StarkWare provider is currently only available for **Ropsten** testnet and not feature complete yet.

## Getting started

Install `authereum@next` version:

```bash
npm install authereum@next
```

Instantiate the Authereum SDK and get StarkWare provider:

```javascript
import Authereum from 'authereum'

const authereum = new Authereum('ropsten')
await authereum.login()

const starkProvider = authereum.getStarkProvider()
const starkKey = await starkProvider.getStarkKey()
console.log(starkKey)
```

## Methods

These are the methods available under the Authereum StarkWare provider:

### `getStarkKey():Promise<string>`

> Returns the Stark key.

**Arguments:**&#x20;

*none*

**Returns:**

`Promise<string>`: Returns a promise with stark key string.

**Example:**

```javascript
const starkKey = await starkProvider.getStarkKey()
```

### `getPublicKey():Promise<string>`

> Returns the Stark public key.

**Arguments:**&#x20;

*none*

**Returns:**

`Promise<string>`: Returns a promise with stark public key string.

**Example:**

```javascript
const starkPublicKey = await starkProvider.getPublicKey()
```

### `setContractAddress(contractAddress):Promise<void>`

Sets the StarkEx contract address to use for the provider.

**Arguments:**&#x20;

| Value             | Type   | Definition               |
| ----------------- | ------ | ------------------------ |
| `contractAddress` | String | StarkEx contract address |

**Returns:**

`Promise<void>`

**Example:**

```javascript
await starkProvider.setContractAddress('0x5FedCE831BD3Bdb71F938EC26f984c84f40dB477')
```

### `getContractAddress():Promise<string>`

> Returns the StarkEx contract address.

**Arguments:**&#x20;

*none*

**Returns:**

`Promise<string>` : Returns a promise with contract address.

**Example:**

```javascript
const address = await starkProvider.getContractAddress()
```

### `registerUser(ethKey, operatorSignature):Promise<string>`

> Submits a transaction to register the Stark key.

**Arguments:**&#x20;

| Value               | Type   | Definition                                   |
| ------------------- | ------ | -------------------------------------------- |
| `ethKey`            | String | Ethereum EOA and account contract address    |
| `operatorSignature` | String | Operator signature required for registration |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const ethKey = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b'
const operatorSignature = '0xae50f29764c96ff5d1554f1d0605bdb992a62700eb8a0b2ffd711da6d6fd90781dbfbb8918c98c15e9fd6251ad89d55e30c20060cf300b51929129726718b6711c'
const txHash = await starkProvider.registerUser(ethKey, operatorSignature)
```

### `depositEth(vaultId, amount, quantum):Promise<string>`

> Submits a transaction to deposit ETH to vault.

**Arguments:**&#x20;

| Value     | Type   | Definition                                             |
| --------- | ------ | ------------------------------------------------------ |
| `vaultId` | String | Vault ID (e.g. `15`)                                   |
| `amount`  | String | ETH amount to deposit in wei (e.g. `1000000000000000`) |
| `quantum` | String | Quantum value (e.g. `10`)                              |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const amount = '1000000000000000' // wei
const quantum = '10'
const txHash = await starkProvider.depositEth(vaultId, amount, quantum)
```

### `depositErc20(vaultId, amount, quantum, token):Promise<string>`

> Submits a transaction to deposit ERC20 token to vault.

**Arguments:**&#x20;

| Value     | Type   | Definition                                                                                                                              |
| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `vaultId` | String | Vault ID (e.g. `15`)                                                                                                                    |
| `amount`  | String | <p>Token amount to deposit</p><p>(e.g. if decimals is <code>6</code>, to deposit <code>0.42</code> it would be <code>420000</code>)</p> |
| `quantum` | String | Quantum value (e.g. `1000`)                                                                                                             |
| `token`   | String | Token contract address                                                                                                                  |

**Returns:**

`Promise<>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const amount = '420000' 
const quantum = '1000'
const token = '0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c'
const txHash = await starkProvider.depositErc20(vaultId, amount, quantum, token)
```

### `depositErc721(vaultId, tokenId, token):Promise<string>`

> Submits a transaction to deposit ERC721 NFT to vault.

**Arguments:**&#x20;

| Value     | Definition            |
| --------- | --------------------- |
| `vaultId` | Vault ID (e.g. `15`)  |
| `tokenId` | Token ID (e.g. `452`) |
| `token`   | NFT contract address  |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const tokenId = '1234'
const token = '0x6B5E013ba22F08ED46d33Fa6d483Fd60e001262e'
const txHash = await starkProvider.depositErc721(vaultId, tokenId, token)
```

### `cancelDeposit(vaultId, assetType):Promise<string>`

> Submits transaction to cancel deposit.

**Arguments:**&#x20;

| Value       | Type   | Definition           |
| ----------- | ------ | -------------------- |
| `assetType` | String | Asset type hash      |
| `vauldId`   | String | Vault ID (e.g. `15`) |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const assetType = '0x4b744eda38322858d42ba43046badd5bd91e94844c0b7c47a4975d8b5b77b5'
const txHash = await starkProvider.cancelDeposit(vaultId, assetType)
```

### `reclaimDeposit(vaultId, assetType):Promise<string>`

> Submits transaction to reclaim deposit after cancelling deposit.

**Arguments:**&#x20;

| Value       | Type   | Definition           |
| ----------- | ------ | -------------------- |
| `assetType` | String | Asset type hash      |
| `vaultId`   | String | Vault ID (e.g. `15`) |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const assetType = '0x4b744eda38322858d42ba43046badd5bd91e94844c0b7c47a4975d8b5b77b5'
const txHash = await starkProvider.relcaimDeposit(vaultId, assetType)
```

### `withdrawEth(quantum, recipient?):Promise<string>`

Submits transaction to withdraw ETH from vault.

**Arguments:**&#x20;

| Value       | Type   | Definition                   |
| ----------- | ------ | ---------------------------- |
| `quantum`   | String | Quantum value (e.g. `10`)    |
| `recipient` | String | (Optional) Recipient address |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const recipient = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b'
const txHash = await starkProvider.withdrawEth(quantum, recipient)
```

### `withdrawErc20(quantum, token, recipient?):Promise<string>`

Submits transaction to withdraw ERC20 token from vault.

**Arguments:**&#x20;

| Value       | Type   | Definition                   |
| ----------- | ------ | ---------------------------- |
| `quantum`   | String | Quantum value (e.g. `1000`)  |
| `token`     | String | Token contract address       |
| `recipient` | String | (Optional) Recipient address |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const quantum = '1000'
const token = '0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c'
const recipient = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b'
const txHash = await starkProvider.withdrawErc20(quantum, token, recipient)
```

### `withdrawErc721(tokenId, token, recipient?):Promise<string>`

Submits transaction to withdraw ERC721 NFT from vault.

**Arguments:**&#x20;

| Value       | Type   | Definition                   |
| ----------- | ------ | ---------------------------- |
| `tokenId`   | String | Quantum value (e.g. `1000`)  |
| `token`     | String | Token ID (e.g. `452`)        |
| `recipient` | String | (Optional) Recipient address |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const tokenId = '1234'
const token = '0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c'
const recipient = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b'
const txHash = await starkProvider.withdrawErc721(tokenId, token, recipient)
```

### `fullWithdrawalRequest(vaultId):Promise<string>`

> Submits transaction to do a request to withdraw all tokens from vault.

**Arguments:**&#x20;

| Value     | Type   | Definition           |
| --------- | ------ | -------------------- |
| `vaultId` | String | Vault ID (e.g. `15`) |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const txHash = await starkProvider.fullWithdrawalRequest(vaultId)
```

### `freezeRequest(vaultId):Promise<string>`

> Submits transaction to freeze vault.

**Arguments:**&#x20;

| Value     | Type   | Definition           |
| --------- | ------ | -------------------- |
| `vaultId` | String | Vault ID (e.g. `15`) |

**Returns:**

`Promise<string>:` Returns a promise with transaction hash.

**Example:**

```javascript
const vaultId = '10'
const txHash = await starkProvider.freezeRequest(vaultId)
```

### `escape(vaultId, assetType, quantizedAmount):Promise<string>`

> Submits transaction to request escape from frozen contract.

**Arguments:**&#x20;

| Value             | Type   | Definition                                 |
| ----------------- | ------ | ------------------------------------------ |
| `vaultId`         | String | Vault ID (e.g. `15`)                       |
| `assetType`       | String | Asset type hash                            |
| `quantizedAmount` | String | Quantized amount (e.g. `amount / quantum`) |

**Returns:**

`Promise<string>:` Returns a promise with object containing transaction hash.

**Example:**

```javascript
const vaultId = '10'
const assetType = '0x4b744eda38322858d42ba43046badd5bd91e94844c0b7c47a4975d8b5b77b5'
const quantizedAmount = '8233298795789816600'
const txHash = await starkProvider.escape(vaultId, assetType, quantizedAmount)
```

### `transfer({object}):Promise<string>`

> Transfer ETH, ERC20, or ERC721 to a stark account. Returns signature.

**Arguments:** &#x20;

Object parameters:

| Value                        | Type           | Definition                                                                      |
| ---------------------------- | -------------- | ------------------------------------------------------------------------------- |
| `from`                       | TransferParams | Transfer sender params.                                                         |
| `to`                         | TransferParams | Transfer recipient params.                                                      |
| `asset`                      | Asset          | Asset to transfer                                                               |
| `amount`                     | String         | Amount                                                                          |
| `nonce`                      | String         | Nonce                                                                           |
| `expirationTimestamp`        | String         | Expiration timestamp                                                            |
| `condition`                  | String         | (optional) Condition hash (encoded hash of transfer address and fact)           |
| `conditionalTransferAddress` | String         | (optional) Conditional transfer address (not needed if `condition` hash is set) |
| `conditionalTransferFact`    | String         | (optional) Condition transfer fact  (not needed if `condition` hash is set)     |

**`Asset`**

| Value  | Type      | Definition                                     |
| ------ | --------- | ---------------------------------------------- |
| `type` | String    | Asset standard (e.g. `ETH`, `ERC20`, `ERC721)` |
| `data` | AssetData | Asset data object                              |

**`AssetData`**

| Value          | Type   | Definition                                                   |
| -------------- | ------ | ------------------------------------------------------------ |
| `quantum`      | String | Quantum value. Required if asset type is `ETH` or `ERC20`    |
| `tokenAddress` | String | Token address. Required if asset type is `ERC20` or `ERC721` |
| `tokenId`      | String | Token ID. Required if asset type is `ERC721`                 |

**`TransferParams`**

| Value      | Type   | Definition |
| ---------- | ------ | ---------- |
| `vaultId`  | String | Vault ID   |
| `starkKey` | String | Stark key. |

**Returns:**

`Promise<string>:` Returns a promise with transfer stark signature.

**Example:**

```javascript
const starkSignature = await starkProvider.transfer({
    from: {
        vaultId: '10',
    },
    to: {
        vaultId: '15',
        starkKey: '0x04887f4c82218a6d13c6a0a249413e6e53b6910de5f0e6b5d85cfef1db04553b',
    },
    asset: {
        type: 'ETH',
        data: {
            quantum: '1000'
        }
    },
    amount: '1',
    nonce: '2433',
    expirationTimestamp: '1605826942',
    condition: null,
})
```

### `transferEth({object}):Promise<string>`

> Transfer ETH to a stark account. Returns signature.

**Arguments:**&#x20;

Object parameters:

| Value                 | Type   | Definition                |
| --------------------- | ------ | ------------------------- |
| `senderVaultId`       | String | Sender vault ID           |
| `receiverVaultId`     | String | Receiver vault ID         |
| `receiverKey`         | String | Receiver stark key        |
| `nonce`               | String | Nonce                     |
| `expirationTimestamp` | String | Expiration timestamp      |
| `condition`           | String | Conditional transfer hash |
| `quantum`             | String | Quantum value             |
| `amount`              | String | Amount                    |

**Returns:**

`Promise<string>:` Returns a promise with transfer stark signature.

**Example:**

```javascript
const starkSignature = await starkProvider.depositEth({
    senderVaultId: '10',
    receiverVaultId: '15',
    receiverKey: '0x04887f4c82218a6d13c6a0a249413e6e53b6910de5f0e6b5d85cfef1db04553b',
    nonce: '2433',
    expirationTimestamp: '1605826942',
    condition: null,
    quantum: '10',
    amount: '1'
})
```

### `transferErc20({object}):Promise<string>`

> Transfer ERC20 token to a stark account. Returns signature.

**Arguments:**&#x20;

Object parameters:

| Value                  | Type   | Definition                |
| ---------------------- | ------ | ------------------------- |
| `senderVaultId`        | String | Sender vault ID           |
| `receiverVaultId`      | String | Receiver vault ID         |
| `receiverKey`          | String | Receiver stark key        |
| `nonce`                | String | Nonce                     |
| `expirationTimestamp`  | String | Expiration timestamp      |
| `condition`            | String | Conditional transfer hash |
| `assetContractAddress` | String | ERC20 contract address    |
| `quantum`              | String | Quantum value             |
| `amount`               | String | Amount                    |

**Returns:**

`Promise<string>:` Returns a promise with transfer stark signature.

**Example:**

```javascript
const starkSignature = await starkProvider.depositErc20({
    senderVaultId: '10',
    receiverVaultId: '15',
    receiverKey: '0x04887f4c82218a6d13c6a0a249413e6e53b6910de5f0e6b5d85cfef1db04553b',
    nonce: '2433',
    expirationTimestamp: '1605826942',
    condition: null,
    assetContractAddress: '0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c',
    quantum: '10',
    amount: '1'
})
```

### `transferErc721({object}):Promise<string>`

> Transfer ERC721 token to a stark account. Returns signature.

**Arguments:**&#x20;

Object parameters:

| Value                  | Type   | Definition                |
| ---------------------- | ------ | ------------------------- |
| `senderVaultId`        | String | Sender vault ID           |
| `receiverVaultId`      | String | Receiver vault ID         |
| `receiverKey`          | String | Receiver stark key        |
| `nonce`                | String | Nonce                     |
| `expirationTimestamp`  | String | Expiration timestamp      |
| `condition`            | String | Conditional transfer hash |
| `assetContractAddress` | String | ERC721 contract address   |
| `tokenId`              | String | Token ID                  |

**Returns:**

`Promise<string>:` Returns a promise with transfer stark signature.

**Example:**

```javascript
const starkSignature = await starkProvider.depositErc721({
    senderVaultId: '10',
    receiverVaultId: '15',
    receiverKey: '0x04887f4c82218a6d13c6a0a249413e6e53b6910de5f0e6b5d85cfef1db04553b',
    nonce: '2433',
    expirationTimestamp: '1605826942',
    condition: null,
    assetContractAddress: '0x6B5E013ba22F08ED46d33Fa6d483Fd60e001262e',
    tokenId: '1234'
})
```

### `createOrder({object}):Promise<string>`

> Create a buy or sell limit order. Returns a signature

**Arguments:**&#x20;

Object parameters:

| Value                 | Type        | Definition           |
| --------------------- | ----------- | -------------------- |
| `sell`                | OrderParams | Sell order params    |
| `buy`                 | OrderParams | Buy order params.    |
| `nonce`               | String      | Nonce                |
| `expirationTimestamp` | String      | Expiration timestamp |

**`OrderParams`**

| Value     | Type      | Definition                                     |
| --------- | --------- | ---------------------------------------------- |
| `type`    | String    | Asset standard (e.g. `ETH`, `ERC20`, `ERC721)` |
| `data`    | AssetData | Asset data object                              |
| `amount`  | String    | Amount                                         |
| `vaultId` | String    | Vault ID                                       |

**`AssetData`**

| Value          | Type   | Definition                                                   |
| -------------- | ------ | ------------------------------------------------------------ |
| `quantum`      | String | Quantum value. Required if asset type is `ETH` or `ERC20`    |
| `tokenAddress` | String | Token address. Required if asset type is `ERC20` or `ERC721` |
| `tokenId`      | String | Token ID. Required if asset type is `ERC721`                 |

**Returns:**

`Promise<string>:`Returns a promise with transfer stark signature.

Example

```javascript
const starkSignature = await starkProvider.createOrder({
    sell: {
      type: 'ETH',
      data: {
        quantum: '1000'
      },
      amount: '1',
      vaultId: '10'
    },
    buy: {
      type: 'ERC20',
      data: {
        quantum: '10',
        tokenAddress: '0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c'
      },
      amount: '2',
      vaultId: '15'
    },
    nonce: '2433',
    expirationTimestamp: '1605826942'
})
```

### ~~deserializeSignature(signature)~~

* Returns the `r` and `s` values of serialized signature.

**Arguments:**&#x20;

| Value       | Type   | Definition           |
| ----------- | ------ | -------------------- |
| `signature` | String | Signature hex string |

**Returns:**

`Promise<{r, s, recoveryParam?}>:` Returns object

**Example:**

```javascript
const {r, s} = starkProvider.deserializeSignature(signature)
```

### ~~serializeSignature({r, s, recoveryParam?}):string~~

* Returns the serialized signature.

**Arguments:**&#x20;

| Value           | Type   | Definition                          |
| --------------- | ------ | ----------------------------------- |
| `r`             | String | Signature `r value`                 |
| `v`             | String | Signature `v` value                 |
| `recoveryParam` | Number | (optional) Recovery parameter value |

**Returns:**

`Promise<string>: Returns serialized signature as hex string.`

**Example:**

```javascript
const signature = starkProvider.serializeSignature({r, s})
```

### `send(method, params):Promise<object>`

> Call StarkWare JSON RPC method with payload.

**Arguments:**&#x20;

| Value    | Type            | Definition                            |
| -------- | --------------- | ------------------------------------- |
| `method` | String          | Method name (e.g. `stark_transfer`)   |
| `params` | Object \| Array | Object or array containing parameters |

**Returns:**

`Promise<{id, result}>:` Returns promise with object containing response result.

**Example:**

```javascript
const method = 'stark_register'
const params = {ethKey, operatorSignature}
const txHash = starkProvider.send(method, params)
```

### `getAssetType({assetStandard, assetContractAddress?, quantum?, amount?}):Promise<string>`

> Returns asset type hash.

`TODO`

### `starkSignMessage(msg):Promise<string>`

> Signs message with stark key.

`TODO`

### `signMessage(msg):Promise<string>`

> Signs message with ethereum key.

`TODO`

### `signPersonalMessage(msg):Promise<string>`

> Signs personal message with ethereum key.

`TODO`

### `signTransaction(tx):Promise<string>`

> Sign transaction.

`TODO`

### `sendTransaction(tx):Promise<string>`

> Send transaction.

`TODO`

### `estimateGas(tx):Promise<string>`

> Estimate gas.

`TODO`

## Additional information

Please refer to the [StarkWare JSON RPC specification](https://hackmd.io/4XaD-LTeTLWGaNG-h-KHWA?view) for example inputs.

You can test out StarkWare methods in the [Authereum Ropsten Kitchen Sink](https://ropsten.demo.authereum.com/).
