Created
January 12, 2021 05:52
-
-
Save t8/e5485597c479b5c949aee580b7feeab2 to your computer and use it in GitHub Desktop.
Test PST contract that supports the Foreign Call Protocol
This file contains hidden or 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
export async function handle (state, action) { | |
const owner = state.owner; | |
const balances = state.balances; | |
const invocations = state.invocations; | |
const input = action.input; | |
const caller = action.caller; | |
if (input.function == "transfer") { | |
const target = input.target; | |
const qty = input.qty; | |
if (!Number.isInteger(qty)) { | |
throw new ContractError(`Invalid value for "qty". Must be an integer`); | |
} | |
if (!target) { | |
throw new ContractError(`No target specified`); | |
} | |
if (qty <= 0 || caller == target) { | |
throw new ContractError("Invalid token transfer"); | |
} | |
if (balances[caller] < qty) { | |
throw new ContractError(`Caller balance not high enough to send ${qty} token(s)!`); | |
} | |
balances[caller] -= qty; | |
if (target in balances) { | |
balances[target] += qty; | |
} else { | |
balances[target] = qty; | |
} | |
return { state }; | |
} | |
if (input.function == "balance") { | |
const target = input.target; | |
const ticker = state.ticker; | |
if (typeof target !== "string") { | |
throw new ContractError(`Must specificy target to get balance for`); | |
} | |
if (typeof balances[target] !== "number") { | |
throw new ContractError(`Cannnot get balance, target does not exist`); | |
} | |
return { result: { target, ticker, balance: balances[target] } }; | |
} | |
if (input.function === "invoke") { | |
if (caller !== owner) { | |
throw new ContractError(`Caller does not own the token`); | |
} | |
if (!input.invocation) { | |
throw new ContractError(`Missing function invocation`); | |
} | |
state.foreignCalls.push(input.invocation); | |
return { state }; | |
} | |
if (input.function === "foreignInvoke") { | |
if (!input.contract) { | |
throw new ContractError(`Missing contract to invoke`); | |
} | |
const foreignState = await SmartWeave.contracts.readContractState(input.contract); | |
if (!foreignState.foreignCalls) { | |
throw new ContractError(`Contract is missing support for foreign calls`); | |
} | |
const invocation = foreignState.foreignCalls[input.id]; | |
if (invocations.includes(invocation)) { | |
throw new ContractError(`Contract invokation already exists`); | |
} | |
const foreignAction = action; | |
foreignAction.caller = input.contract; | |
foreignAction.input = invocation; | |
const resultState = handle(state, foreignAction); | |
return { resultState }; | |
} | |
throw new ContractError(`No function supplied or function not recognised: "${input.function}"`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment