agreement update, contract tested and fixed, readme init
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
.idea
|
||||
.env
|
||||
.env
|
||||
.vscode
|
8
.idea/.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/block-accounting.iml" filepath="$PROJECT_DIR$/.idea/block-accounting.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
</component>
|
||||
</project>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"solidity.compileUsingRemoteVersion": "v0.8.25+commit.b61c2a91"
|
||||
}
|
21
README.md
@ -1,11 +1,14 @@
|
||||
![LOGIN FLOW](./login-flow.png "Login")
|
||||
### CHAIN-API
|
||||
|
||||
[//]: # (![Example architecture](./arch.png "Arch"))
|
||||
![License](./license.png "Arch")
|
||||
![Salaries](./salaries.png "Arch")
|
||||
- ### Multi-Sig Deploy
|
||||
![Alt Text](./excalidraw/multisig.png)
|
||||
|
||||
# Registration Flow
|
||||
|
||||
- On First Login - Owner inputs his SEED_KEY (mnemonic), creates an organization, we save its seed hash for future login and signing internal txs.
|
||||
- When inviting an employee to organization- we generate an invitation link, then after clicking on this link - the user is asked for seed, if he's already registered or able to generate a seed for new account.
|
||||
-
|
||||
- ### Payroll Deploy
|
||||
![Alt Text](./excalidraw/payroll-deploy.png)
|
||||
- ### Payroll
|
||||
![set-salary.png](excalidraw%2Fset-salary.png)
|
||||
![payroll.png](excalidraw%2Fpayroll.png)
|
||||
- ### License
|
||||
![license-deploy.png](excalidraw%2Flicense-deploy.png)
|
||||
![data-request-license.png](excalidraw%2Fdata-request-license.png)
|
||||
![license-payout-2of3steps.png](excalidraw%2Flicense-payout-2of3steps.png)![3step-license-payout.png](excalidraw%2F3step-license-payout.png)
|
@ -4,6 +4,8 @@ import { AppService } from './app.service';
|
||||
|
||||
import { ContractInteractModule } from './contract-interact/contract-interact.module';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { EthereumModule } from './ethereum/ethereum.module';
|
||||
import { AgreementModule } from './contract-interact/agreement/agreement.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -11,6 +13,8 @@ import { ConfigModule } from '@nestjs/config';
|
||||
isGlobal: true,
|
||||
}),
|
||||
ContractInteractModule,
|
||||
EthereumModule,
|
||||
AgreementModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
@ -4,7 +4,7 @@ import { ProviderModule } from './provider/provider.module';
|
||||
@Module({
|
||||
imports: [ProviderModule],
|
||||
controllers: [],
|
||||
providers: [ProviderModule],
|
||||
providers: [],
|
||||
exports: [ProviderModule],
|
||||
})
|
||||
export class BaseModule {}
|
||||
|
@ -18,11 +18,7 @@ export class ProviderService {
|
||||
if (this.provider) {
|
||||
return this.provider;
|
||||
}
|
||||
const polygonProvider = new ethers.JsonRpcProvider(
|
||||
this.nodeUrl,
|
||||
this.networkId,
|
||||
);
|
||||
this.provider = polygonProvider;
|
||||
this.provider = new ethers.JsonRpcProvider(this.nodeUrl, this.networkId);
|
||||
return this.provider;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ export const CHAINLINK = {
|
||||
},
|
||||
JOB_IDS: {
|
||||
UINT: 'a8356f48569c434eaa4ac5fcb4db5cc0',
|
||||
BOOL: '43309009a154495cb2ed794233e6ff56',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -0,0 +1,29 @@
|
||||
import { Body, Controller, Post, Get, Param } from '@nestjs/common';
|
||||
import { AgreementService } from './agreement.service';
|
||||
import {
|
||||
DeployAgreementDto,
|
||||
GetAgreementInfoDto,
|
||||
RequestAgreementDto,
|
||||
} from './agreement.dto';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
@ApiTags('Agreement')
|
||||
@Controller('agreements')
|
||||
export class AgreementController {
|
||||
constructor(private readonly agreementService: AgreementService) {}
|
||||
|
||||
@Post('deploy')
|
||||
async deployAgreement(@Body() deployDto: DeployAgreementDto) {
|
||||
return await this.agreementService.deploy(deployDto);
|
||||
}
|
||||
|
||||
@Get(':contractAddress')
|
||||
async getAgreementResponse(
|
||||
@Param('contractAddress') contractAddress: string,
|
||||
) {
|
||||
return await this.agreementService.getResponse({ contractAddress });
|
||||
}
|
||||
@Post('request')
|
||||
async requestAgreement(@Body() requestDto: RequestAgreementDto) {
|
||||
return await this.agreementService.request(requestDto);
|
||||
}
|
||||
}
|
21
chain-api/src/contract-interact/agreement/agreement.dto.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsUrl } from 'class-validator';
|
||||
|
||||
export class DeployAgreementDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
multiSigWallet: string;
|
||||
}
|
||||
export class GetAgreementInfoDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
contractAddress: string;
|
||||
}
|
||||
export class RequestAgreementDto extends GetAgreementInfoDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
multiSigWallet: string;
|
||||
@ApiProperty()
|
||||
@IsUrl()
|
||||
url: string;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AgreementController } from './agreement.controller';
|
||||
import { AgreementService } from './agreement.service';
|
||||
import { BaseModule } from '../../base/base.module';
|
||||
import { MultiSigModule } from '../multi-sig/multi-sig.module';
|
||||
|
||||
@Module({
|
||||
imports: [BaseModule, MultiSigModule],
|
||||
controllers: [AgreementController],
|
||||
providers: [AgreementService],
|
||||
|
||||
exports: [],
|
||||
})
|
||||
export class AgreementModule {}
|
@ -0,0 +1,75 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { BaseContractService } from '../../base/base-contract.service';
|
||||
import * as hre from 'hardhat';
|
||||
import { ethers } from 'ethers';
|
||||
import { CHAINLINK } from '../../config/chainlink.config';
|
||||
import {
|
||||
DeployAgreementDto,
|
||||
GetAgreementInfoDto,
|
||||
RequestAgreementDto,
|
||||
} from './agreement.dto';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
import { ProviderService } from '../../base/provider/provider.service';
|
||||
|
||||
@Injectable()
|
||||
export class AgreementService extends BaseContractService {
|
||||
constructor(
|
||||
public readonly providerService: ProviderService,
|
||||
public readonly multiSigService: MultiSigWalletService,
|
||||
) {
|
||||
super(providerService);
|
||||
}
|
||||
async deploy(dto: DeployAgreementDto): Promise<any> {
|
||||
const { multiSigWallet } = dto;
|
||||
const { bytecode } = await hre.artifacts.readArtifact('Agreement');
|
||||
|
||||
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
||||
|
||||
const abiEncodedConstructorArguments = abiCoder.encode(
|
||||
['address', 'address', 'string', 'uint', 'address'],
|
||||
[
|
||||
CHAINLINK.AMOY.CHAINLINK_TOKEN,
|
||||
CHAINLINK.AMOY.ORACLE_ADDRESS,
|
||||
CHAINLINK.AMOY.JOB_IDS.BOOL,
|
||||
0,
|
||||
multiSigWallet,
|
||||
],
|
||||
);
|
||||
const fullBytecode = bytecode + abiEncodedConstructorArguments.substring(2);
|
||||
const submitData = await this.multiSigService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
destination: null,
|
||||
value: '0',
|
||||
data: fullBytecode,
|
||||
});
|
||||
delete submitData.data;
|
||||
return submitData;
|
||||
}
|
||||
|
||||
async getResponse(dto: GetAgreementInfoDto) {
|
||||
const { contractAddress } = dto;
|
||||
const { abi } = await hre.artifacts.readArtifact('Agreement');
|
||||
const signer = await this.providerService.getSigner();
|
||||
|
||||
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||
|
||||
const answer = await contract.response();
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
async request(dto: RequestAgreementDto) {
|
||||
const { multiSigWallet, contractAddress, url } = dto;
|
||||
|
||||
const ISubmitMultiSig = new ethers.Interface([
|
||||
'function request(string memory url)',
|
||||
]);
|
||||
const data = ISubmitMultiSig.encodeFunctionData('request', [url]);
|
||||
|
||||
return await this.multiSigService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
destination: contractAddress,
|
||||
value: '0',
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { IsArray, IsNumber, IsString } from 'class-validator';
|
||||
import { IsArray, IsNumber, IsString, IsUrl } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
export class GetLicenseInfoDto {
|
||||
@ApiProperty()
|
||||
@ -24,6 +24,9 @@ export class RequestLicenseDto extends GetLicenseInfoDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
multiSigWallet: string;
|
||||
@ApiProperty()
|
||||
@IsUrl()
|
||||
url: string;
|
||||
}
|
||||
|
||||
export class GetLicenseResponseDto extends GetLicenseInfoDto {}
|
||||
|
@ -10,23 +10,25 @@ import {
|
||||
RequestLicenseDto,
|
||||
SetPayoutContractDto,
|
||||
} from './license.dto';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
import { ProviderService } from '../../base/provider/provider.service';
|
||||
import { CHAINLINK } from '../../config/chainlink.config';
|
||||
import { ProviderService } from '../../base/provider/provider.service';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
|
||||
@Injectable()
|
||||
export class LicenseService extends BaseContractService {
|
||||
constructor(
|
||||
private readonly multiSigService: MultiSigWalletService,
|
||||
public readonly providerService: ProviderService,
|
||||
public readonly multiSigService: MultiSigWalletService,
|
||||
) {
|
||||
super(providerService);
|
||||
}
|
||||
async request(dto: RequestLicenseDto) {
|
||||
const { multiSigWallet, contractAddress } = dto;
|
||||
const { multiSigWallet, contractAddress, url } = dto;
|
||||
|
||||
const ISubmitMultiSig = new ethers.Interface(['function request()']);
|
||||
const data = ISubmitMultiSig.encodeFunctionData('request');
|
||||
const ISubmitMultiSig = new ethers.Interface([
|
||||
'function request(string memory url)',
|
||||
]);
|
||||
const data = ISubmitMultiSig.encodeFunctionData('request', [url]);
|
||||
|
||||
return await this.multiSigService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
@ -46,7 +48,6 @@ export class LicenseService extends BaseContractService {
|
||||
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||
|
||||
const answer: bigint = await contract.totalPayoutInUSD();
|
||||
console.log('=>(license.service.ts:45) answer', answer);
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
|
@ -7,17 +7,17 @@ import {
|
||||
SetSalaryDto,
|
||||
} from './salaries.dto';
|
||||
import * as hre from 'hardhat';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
import { BaseContractService } from '../../base/base-contract.service';
|
||||
import { ProviderService } from '../../base/provider/provider.service';
|
||||
import { DepositContractDto } from '../multi-sig.dto';
|
||||
import { CHAINLINK } from '../../config/chainlink.config';
|
||||
import { ProviderService } from '../../base/provider/provider.service';
|
||||
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||
|
||||
@Injectable()
|
||||
export class SalariesService extends BaseContractService {
|
||||
constructor(
|
||||
private readonly multiSigWalletService: MultiSigWalletService,
|
||||
public readonly providerService: ProviderService,
|
||||
public readonly multiSigService: MultiSigWalletService,
|
||||
) {
|
||||
super(providerService);
|
||||
}
|
||||
@ -57,7 +57,7 @@ export class SalariesService extends BaseContractService {
|
||||
salary,
|
||||
]);
|
||||
|
||||
return await this.multiSigWalletService.submitTransaction({
|
||||
return await this.multiSigService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
destination: contractAddress,
|
||||
value: '0',
|
||||
@ -87,7 +87,7 @@ export class SalariesService extends BaseContractService {
|
||||
employeeAddress,
|
||||
]);
|
||||
|
||||
return await this.multiSigWalletService.submitTransaction({
|
||||
return await this.multiSigService.submitTransaction({
|
||||
contractAddress: multiSigWallet,
|
||||
destination: contractAddress,
|
||||
value: '0',
|
||||
|
12
chain-api/src/ethereum/ethereum.controller.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Controller, Get, Param } from '@nestjs/common';
|
||||
import { EthereumService } from './ethereum.service';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
@ApiTags('Ethereum')
|
||||
@Controller()
|
||||
export class EthereumController {
|
||||
constructor(private readonly ethereumService: EthereumService) {}
|
||||
@Get('/address/:privateKey')
|
||||
async getAddressFromPrivateKey(@Param('privateKey') privateKey: string) {
|
||||
return this.ethereumService.getAddressFromPrivateKey(privateKey);
|
||||
}
|
||||
}
|
11
chain-api/src/ethereum/ethereum.module.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { EthereumController } from './ethereum.controller';
|
||||
import { EthereumService } from './ethereum.service';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [EthereumController],
|
||||
providers: [EthereumService],
|
||||
exports: [],
|
||||
})
|
||||
export class EthereumModule {}
|
10
chain-api/src/ethereum/ethereum.service.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
@Injectable()
|
||||
export class EthereumService {
|
||||
async getAddressFromPrivateKey(privateKey: string) {
|
||||
const wallet = new ethers.Wallet(privateKey);
|
||||
return wallet.address;
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ export class AllExceptionsFilter implements ExceptionFilter {
|
||||
|
||||
const responseBody = {
|
||||
statusCode: httpStatus,
|
||||
error: exception?.info?.error.message || exception.toString(),
|
||||
error: exception?.info?.error?.message || exception.toString(),
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
|
@ -4,30 +4,20 @@ pragma solidity ^0.8.17;
|
||||
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
|
||||
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
|
||||
|
||||
/**
|
||||
* Request testnet LINK and ETH here: https://faucets.chain.link/
|
||||
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
|
||||
*/
|
||||
|
||||
/**
|
||||
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
|
||||
*/
|
||||
|
||||
contract LinkWellBoolConsumerContractExample is ChainlinkClient, ConfirmedOwner {
|
||||
contract Agreement is ChainlinkClient, ConfirmedOwner {
|
||||
using Chainlink for Chainlink.Request;
|
||||
|
||||
address private oracleAddress;
|
||||
bytes32 private jobId;
|
||||
uint256 private fee;
|
||||
address public multisigWallet;
|
||||
|
||||
constructor(
|
||||
address _chainLinkToken,
|
||||
address _oracleAddress,
|
||||
string memory _jobId,
|
||||
uint _fee,
|
||||
address _multiSigAddress,
|
||||
address[] memory _owners,
|
||||
uint[] memory _shares
|
||||
address _multiSigAddress
|
||||
) ConfirmedOwner(_multiSigAddress) {
|
||||
|
||||
_setChainlinkToken(_chainLinkToken);
|
||||
@ -41,32 +31,18 @@ contract LinkWellBoolConsumerContractExample is ChainlinkClient, ConfirmedOwner
|
||||
multisigWallet = _multiSigAddress;
|
||||
}
|
||||
|
||||
constructor() ConfirmedOwner(msg.sender) {
|
||||
_setChainlinkToken(0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904);
|
||||
setOracleAddress(0xd36c6B1777c7f3Db1B3201bDD87081A9045B7b46);
|
||||
setJobId("43309009a154495cb2ed794233e6ff56");
|
||||
setFeeInHundredthsOfLink(0); // 0 LINK
|
||||
}
|
||||
|
||||
// Send a request to the Chainlink oracle
|
||||
function request() public {
|
||||
function request(string memory url) public {
|
||||
|
||||
Chainlink.Request memory req = _buildOperatorRequest(jobId, this.fulfill.selector);
|
||||
|
||||
// DEFINE THE REQUEST PARAMETERS (example)
|
||||
req._add('method', 'POST');
|
||||
req._add('url', 'https://httpbin.org/post');
|
||||
req._add('headers', '["accept", "application/json", "set-cookie", "sid=14A52"]');
|
||||
req._add('body', '{"data":[{"coin":"BTC","isActive":false},{"coin":"ETH","isActive":false},{"coin":"LINK","isActive":true}]}');
|
||||
req._add('contact', ''); // PLEASE ENTER YOUR CONTACT INFO. this allows us to notify you in the event of any emergencies related to your request (ie, bugs, downtime, etc.). example values: 'derek_linkwellnodes.io' (Discord handle) OR 'derek@linkwellnodes.io' OR '+1-617-545-4721'
|
||||
|
||||
// The following curl command simulates the above request parameters:
|
||||
// curl 'https://httpbin.org/post' --request 'POST' --header 'content-type: application/json' --header 'set-cookie: sid=14A52' --data '{"data":[{"coin":"BTC","isActive":false},{"coin":"ETH","isActive":false},{"coin":"LINK","isActive":true}]}'
|
||||
|
||||
// PROCESS THE RESULT (example)
|
||||
req._add('path', 'json,data,2,isActive');
|
||||
|
||||
// Send the request to the Chainlink oracle
|
||||
req._add('method', 'GET');
|
||||
req._add('url', url);
|
||||
req._add('headers', '["content-type", "application/json"]');
|
||||
req._add('body', '');
|
||||
req._add('contact', '');
|
||||
req._add('path', '');
|
||||
_sendOperatorRequest(req, fee);
|
||||
}
|
||||
|
||||
@ -75,9 +51,8 @@ contract LinkWellBoolConsumerContractExample is ChainlinkClient, ConfirmedOwner
|
||||
// Receive the result from the Chainlink oracle
|
||||
event RequestFulfilled(bytes32 indexed requestId);
|
||||
function fulfill(bytes32 requestId, bool data) public recordChainlinkFulfillment(requestId) {
|
||||
// Process the oracle response
|
||||
// emit RequestFulfilled(requestId); // (optional) emits this event in the on-chain transaction logs, allowing Web3 applications to listen for this transaction
|
||||
response = data; // example value: true
|
||||
emit RequestFulfilled(requestId);
|
||||
response = data;
|
||||
}
|
||||
|
||||
// Update oracle address
|
||||
|
@ -55,10 +55,6 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
|
||||
owners.push(_owners[i]);
|
||||
}
|
||||
}
|
||||
//get share
|
||||
//update share
|
||||
//change payout address
|
||||
//
|
||||
modifier hasValidPayoutContract() {
|
||||
require(address(payoutContract) != address(0), "payoutContract not initialized");
|
||||
_;
|
||||
@ -73,26 +69,20 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
|
||||
payoutContract = Payroll(_payoutAddress);
|
||||
}
|
||||
|
||||
|
||||
// Send a request to the Chainlink oracle
|
||||
function request() external onlyOwner{
|
||||
function request(string memory url) external onlyOwner{
|
||||
|
||||
Chainlink.Request memory req = _buildOperatorRequest(jobId, this.fulfill.selector);
|
||||
|
||||
// DEFINE THE REQUEST PARAMETERS (example)
|
||||
req._add('method', 'GET');
|
||||
req._add('url', 'https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD,EUR');
|
||||
req._add('headers', '["content-type", "application/json", "set-cookie", "sid=14A52"]');
|
||||
req._add('body', '');
|
||||
req._add('contact', ''); // PLEASE ENTER YOUR CONTACT INFO. this allows us to notify you in the event of any emergencies related to your request (ie, bugs, downtime, etc.). example values: 'derek_linkwellnodes.io' (Discord handle) OR 'derek@linkwellnodes.io' OR '+1-617-545-4721'
|
||||
req._add('url', url);
|
||||
|
||||
// The following curl command simulates the above request parameters:
|
||||
// curl 'https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC,ETH&tsyms=USD,EUR' --request 'GET' --header 'content-type: application/json' --header 'set-cookie: sid=14A52'
|
||||
|
||||
// PROCESS THE RESULT (example)
|
||||
req._add('path', 'ETH,USD');
|
||||
//if returns just int - then empty path
|
||||
req._add('path', '');
|
||||
req._addInt('multiplier', 10 ** 18);
|
||||
// Send the request to the Chainlink oracle
|
||||
req._add('headers', '["content-type", "application/json"]');
|
||||
req._add('body', '');
|
||||
req._add('contact', '');
|
||||
_sendOperatorRequest(req, fee);
|
||||
}
|
||||
|
||||
@ -102,9 +92,7 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner {
|
||||
event RequestFulfilled(bytes32 indexed requestId);
|
||||
|
||||
function fulfill(bytes32 requestId, uint256 data) public recordChainlinkFulfillment(requestId) {
|
||||
// Process the oracle response
|
||||
// emit RequestFulfilled(requestId); // (optional) emits this event in the on-chain transaction logs, allowing Web3 applications to listen for this transaction
|
||||
totalPayoutInUSD = data / 1e18 / 100; // example value: 1875870000000000000000 (1875.87 before "multiplier" is applied)
|
||||
totalPayoutInUSD = data / 1e18;
|
||||
}
|
||||
|
||||
function payout() external onlyOwner hasValidPayoutContract{
|
||||
|
4
docs.md
@ -1,4 +0,0 @@
|
||||
# links
|
||||
|
||||
chainlink-feeds amoy
|
||||
https://docs.chain.link/data-feeds/price-feeds/addresses?network=polygon&page=1
|
1603
excalidraw/3step-license-payout.excalidraw
Normal file
BIN
excalidraw/3step-license-payout.png
Normal file
After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
1772
excalidraw/data-request-license.excalidraw
Normal file
BIN
excalidraw/data-request-license.png
Normal file
After Width: | Height: | Size: 130 KiB |
1038
excalidraw/license-deploy.excalidraw
Normal file
BIN
excalidraw/license-deploy.png
Normal file
After Width: | Height: | Size: 113 KiB |
2088
excalidraw/license-payout-2of3steps.excalidraw
Normal file
BIN
excalidraw/license-payout-2of3steps.png
Normal file
After Width: | Height: | Size: 138 KiB |
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
1004
excalidraw/multisig.excalidraw
Normal file
BIN
excalidraw/multisig.png
Normal file
After Width: | Height: | Size: 108 KiB |
1014
excalidraw/payroll-deploy.excalidraw
Normal file
BIN
excalidraw/payroll-deploy.png
Normal file
After Width: | Height: | Size: 42 KiB |
1250
excalidraw/payroll.excalidraw
Normal file
BIN
excalidraw/payroll.png
Normal file
After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 282 KiB |
1033
excalidraw/set-salary.excalidraw
Normal file
BIN
excalidraw/set-salary.png
Normal file
After Width: | Height: | Size: 88 KiB |