-
Notifications
You must be signed in to change notification settings - Fork 312
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Server/ContractClient methods to construct from contractId (#960)
* Add ContractClient.from to instantiate from a contractId * Add a getContractWasm method to Server * Add test for getContractWasm server method * Add getContractWasmByHash and analogous method in client * Allow passing wasmHash as string for getting wasm bytecode * Update stellar-base reference to full release --------- Co-authored-by: George <[email protected]>
- Loading branch information
1 parent
e4db91c
commit b5729cc
Showing
11 changed files
with
528 additions
and
24 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
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
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,110 @@ | ||
const test = require('ava') | ||
const { spawnSync } = require('node:child_process') | ||
const { Address } = require('../../..') | ||
const { contracts, networkPassphrase, rpcUrl, friendbotUrl } = require('./util') | ||
const { ContractSpec } = require('../../..') | ||
const { Keypair } = require('../../..') | ||
|
||
const { | ||
ContractClient, | ||
basicNodeSigner, | ||
} = require('../../../lib/contract_client') | ||
|
||
async function generateFundedKeypair() { | ||
const keypair = Keypair.random() | ||
await fetch(`${friendbotUrl}/friendbot?addr=${keypair.publicKey()}`) | ||
return keypair | ||
}; | ||
|
||
/** | ||
* Generates a ContractClient for the contract with the given name. | ||
* Also generates a new account to use as as the keypair of this contract. This | ||
* account is funded by friendbot. You can pass in an account to re-use the | ||
* same account with multiple contract clients. | ||
* | ||
* By default, will re-deploy the contract every time. Pass in the same | ||
* `contractId` again if you want to re-use the a contract instance. | ||
*/ | ||
async function clientFromConstructor(contract, { keypair = generateFundedKeypair(), contractId } = {}) { | ||
if (!contracts[contract]) { | ||
throw new Error( | ||
`Contract ${contract} not found. ` + | ||
`Pick one of: ${Object.keys(contracts).join(", ")}` | ||
) | ||
} | ||
keypair = await keypair // eslint-disable-line no-param-reassign | ||
const wallet = basicNodeSigner(keypair, networkPassphrase) | ||
|
||
const {path} = contracts[contract]; | ||
const xdr = JSON.parse(spawnSync("./target/bin/soroban", ["contract", "inspect", "--wasm", path, "--output", "xdr-base64-array"], { shell: true, encoding: "utf8" }).stdout.trim()) | ||
|
||
const spec = new ContractSpec(xdr); | ||
let wasmHash = contracts[contract].hash; | ||
if (!wasmHash) { | ||
wasmHash = spawnSync("./target/bin/soroban", ["contract", "install", "--wasm", path], { shell: true, encoding: "utf8" }).stdout.trim() | ||
} | ||
|
||
// TODO: do this with js-stellar-sdk, instead of shelling out to the CLI | ||
contractId = contractId ?? spawnSync("./target/bin/soroban", [ // eslint-disable-line no-param-reassign | ||
"contract", | ||
"deploy", | ||
"--source", | ||
keypair.secret(), | ||
"--wasm-hash", | ||
wasmHash, | ||
], { shell: true, encoding: "utf8" }).stdout.trim(); | ||
|
||
const client = new ContractClient(spec, { | ||
networkPassphrase, | ||
contractId, | ||
rpcUrl, | ||
allowHttp: true, | ||
publicKey: keypair.publicKey(), | ||
...wallet, | ||
}); | ||
return { | ||
keypair, | ||
client, | ||
contractId, | ||
} | ||
} | ||
|
||
/** | ||
* Generates a ContractClient given the contractId using the from method. | ||
*/ | ||
async function clientForFromTest(contractId, publicKey, keypair) { | ||
keypair = await keypair; // eslint-disable-line no-param-reassign | ||
const wallet = basicNodeSigner(keypair, networkPassphrase); | ||
const options = { | ||
networkPassphrase, | ||
contractId, | ||
rpcUrl, | ||
allowHttp: true, | ||
publicKey, | ||
...wallet, | ||
}; | ||
return ContractClient.from(options); | ||
} | ||
|
||
test.before(async t => { | ||
const { client, keypair, contractId } = await clientFromConstructor('customTypes') | ||
const publicKey = keypair.publicKey() | ||
const addr = Address.fromString(publicKey) | ||
t.context = { client, publicKey, addr, contractId, keypair } // eslint-disable-line no-param-reassign | ||
}); | ||
|
||
test('hello from constructor', async t => { | ||
const { result } = await t.context.client.hello({ hello: 'tests' }) | ||
t.is(result, 'tests') | ||
}) | ||
|
||
test('from', async (t) => { | ||
// objects with different constructors will not pass deepEqual check | ||
function constructorWorkaround(object) { | ||
return JSON.parse(JSON.stringify(object)); | ||
} | ||
|
||
const clientFromFrom = await clientForFromTest(t.context.contractId, t.context.publicKey, t.context.keypair); | ||
t.deepEqual(constructorWorkaround(clientFromFrom), constructorWorkaround(t.context.client)); | ||
t.deepEqual(t.context.client.spec.entries, clientFromFrom.spec.entries); | ||
}); |
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
Oops, something went wrong.