-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
irfi
committed
Apr 10, 2021
1 parent
c0d57f1
commit 3221153
Showing
5 changed files
with
250 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
require('dotenv').config() | ||
const Near = require('./src/helpers/Near') | ||
|
||
const deploy = async () => { | ||
const near = new Near() | ||
|
||
await near.init() | ||
|
||
try { | ||
await near.deployContract() | ||
} catch (err) { | ||
console.log(err) | ||
} | ||
} | ||
|
||
deploy() | ||
|
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,2 @@ | ||
TESTNET_ROOT_ACCOUNT='{"account_id":"","public_key":"","private_key":""}' | ||
TESTNET_CONTRACT_ACCOUNT='{"account_id":"","public_key":"","private_key":""}' |
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,70 @@ | ||
function getConfig(env, contractName) { | ||
if (!contractName) { | ||
throw '[env] contractName not found' | ||
} | ||
|
||
switch (env) { | ||
case 'mainnet': | ||
return { | ||
networkId: 'mainnet', | ||
nodeUrl: 'https://rpc.mainnet.near.org', | ||
contractName: contractName, | ||
walletUrl: 'https://wallet.mainnet.near.org', | ||
helperUrl: 'https://helper.mainnet.near.org', | ||
} | ||
case 'development': | ||
case 'testnet': | ||
return { | ||
networkId: 'default', | ||
nodeUrl: 'https://rpc.testnet.near.org', | ||
contractName: contractName, | ||
walletUrl: 'https://wallet.testnet.near.org', | ||
helperUrl: 'https://helper.testnet.near.org', | ||
} | ||
case 'devnet': | ||
return { | ||
networkId: 'devnet', | ||
nodeUrl: 'https://rpc.devnet.near.org', | ||
contractName: contractName, | ||
walletUrl: 'https://wallet.devnet.near.org', | ||
helperUrl: 'https://helper.devnet.near.org', | ||
} | ||
case 'betanet': | ||
return { | ||
networkId: 'betanet', | ||
nodeUrl: 'https://rpc.betanet.near.org', | ||
contractName: contractName, | ||
walletUrl: 'https://wallet.betanet.near.org', | ||
helperUrl: 'https://helper.betanet.near.org', | ||
} | ||
case 'local': | ||
return { | ||
networkId: 'local', | ||
nodeUrl: 'http://localhost:3030', | ||
keyPath: `${process.env.HOME}/.near/validator_key.json`, | ||
walletUrl: 'http://localhost:4000/wallet', | ||
contractName: contractName, | ||
} | ||
case 'test': | ||
case 'ci': | ||
return { | ||
networkId: 'shared-test', | ||
nodeUrl: 'https://rpc.ci-testnet.near.org', | ||
contractName: contractName, | ||
masterAccount: 'test.near', | ||
} | ||
case 'ci-betanet': | ||
return { | ||
networkId: 'shared-test-staging', | ||
nodeUrl: 'https://rpc.ci-betanet.near.org', | ||
contractName: contractName, | ||
masterAccount: 'test.near', | ||
} | ||
default: | ||
throw Error( | ||
`Unconfigured environment '${env}'. Can be configured in src/config.js.` | ||
) | ||
} | ||
} | ||
|
||
module.exports = getConfig |
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,146 @@ | ||
const { Contract, KeyPair, connect } = require('near-api-js') | ||
const { join } = require('path') | ||
const { InMemoryKeyStore } = require('near-api-js').keyStores | ||
const getConfig = require('../configs/near') | ||
|
||
const Base64 = require('js-base64').Base64 | ||
const nacl = require('tweetnacl') | ||
const bs58 = require('bs58') | ||
const sha256 = require('js-sha256') | ||
const axios = require('axios') | ||
|
||
const _hexToArr = (str) => { | ||
try { | ||
return new Uint8Array( | ||
str.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)) | ||
) | ||
} catch (err) { | ||
throw err | ||
} | ||
} | ||
|
||
const contractConfig = { | ||
changeMethods: [ | ||
'new', | ||
'ft_transfer', | ||
'ft_transfer_call', | ||
'ft_resolve_transfer' | ||
], | ||
viewMethods: [ | ||
'ft_total_supply', | ||
'ft_balance_of', | ||
'ft_metadata' | ||
] | ||
} | ||
|
||
class Near { | ||
constructor() { | ||
this.ctx = null | ||
this.config = null | ||
} | ||
|
||
async init() { | ||
console.log('==================================================') | ||
console.log(`ENV: ${process.env.NODE_ENV}`) | ||
const ROOT_ACCOUNT = | ||
process.env[`${process.env.NODE_ENV.toUpperCase()}_ROOT_ACCOUNT`] | ||
const CONTRACT_ACCOUNT = | ||
process.env[`${process.env.NODE_ENV.toUpperCase()}_CONTRACT_ACCOUNT`] | ||
|
||
if (!ROOT_ACCOUNT) { | ||
throw '[env] ROOT_ACCOUNT not found' | ||
} | ||
if (!CONTRACT_ACCOUNT) { | ||
throw '[env] CONTRACT_ACCOUNT not found' | ||
} | ||
const rootAccount = JSON.parse(ROOT_ACCOUNT) | ||
const contractAccount = JSON.parse(CONTRACT_ACCOUNT) | ||
console.log(`ROOT ACCOUNT: ${rootAccount.account_id}`) | ||
console.log(`CONTRACT ACCOUNT: ${contractAccount.account_id}`) | ||
console.log('==================================================') | ||
const config = getConfig( | ||
process.env.NODE_ENV || 'testnet', | ||
contractAccount.account_id | ||
) | ||
this.config = config | ||
|
||
const keyStore = new InMemoryKeyStore() | ||
|
||
// add root account | ||
const rootKeyPair = KeyPair.fromString( | ||
rootAccount.secret_key || rootAccount.private_key | ||
) | ||
await keyStore.setKey(config.networkId, rootAccount.account_id, rootKeyPair) | ||
|
||
// add contract account | ||
const contractKeyPair = KeyPair.fromString( | ||
contractAccount.secret_key || contractAccount.private_key | ||
) | ||
await keyStore.setKey( | ||
config.networkId, | ||
contractAccount.account_id, | ||
contractKeyPair | ||
) | ||
|
||
const near = await connect({ | ||
deps: { | ||
keyStore: keyStore, | ||
}, | ||
...config, | ||
}) | ||
this.ctx = near | ||
this.masterAccount = await near.account(rootAccount.account_id) | ||
this.contractAccount = await near.account(contractAccount.account_id) | ||
this.contract = new Contract( | ||
this.masterAccount, | ||
this.contractAccount.accountId, | ||
contractConfig | ||
) | ||
} | ||
|
||
async deployContract() { | ||
console.log('Setting up and deploying contract') | ||
const contractPath = join(process.cwd(), 'res/paras_claim_rewards_contract.wasm') | ||
await this.contractAccount.deployContract( | ||
require('fs').readFileSync(contractPath) | ||
) | ||
|
||
console.log(`Contract ${this.contractAccount.accountId} deployed`) | ||
} | ||
|
||
async authSignature(authHeader) { | ||
try { | ||
const decodeAuthHeader = Base64.decode(authHeader) | ||
const [userId, pubKey, signature] = decodeAuthHeader.split('&') | ||
const pubKeyArr = _hexToArr(pubKey) | ||
const signatureArr = _hexToArr(signature) | ||
const hash = new Uint8Array(sha256.sha256.array(userId)) | ||
const verify = nacl.sign.detached.verify(hash, signatureArr, pubKeyArr) | ||
if (!verify) { | ||
throw new Error('unauthorized') | ||
} | ||
const b58pubKey = bs58.encode(Buffer.from(pubKey.toUpperCase(), 'hex')) | ||
const response = await axios.post(this.config.nodeUrl, { | ||
jsonrpc: '2.0', | ||
id: 'dontcare', | ||
method: 'query', | ||
params: { | ||
request_type: 'view_access_key', | ||
finality: 'final', | ||
account_id: userId, | ||
public_key: `ed25519:${b58pubKey}`, | ||
}, | ||
}) | ||
|
||
if (response.data.result && response.data.result.error) { | ||
console.log(response.data.result.error) | ||
throw new Error('unauthorized') | ||
} | ||
return userId | ||
} catch (err) { | ||
return null | ||
} | ||
} | ||
} | ||
|
||
module.exports = Near |