-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TS Errors while requesting a contract's wasm code #166
Comments
It's complaining about types because your types aren't matching up. There are a few issues here, starting on this line:
the There's also this line:
You can see that the signature of the class ContractExecutable {
// etc...
static contractExecutableWasm(value: Buffer): ContractExecutable; so we need a |
The tutorial you're following is, unfortunately, slightly outdated. I've rewritten it slightly in a way that is catered towards your issue and is hopefully easier to understand! Requesting a Contract's Wasm CodeWe are trying to answer the following question:
This is answered in two parts, because multiple contracts can refer to the same WASM blob on the ledger:
Retrieve the instanceThe lookup import { xdr, Server } from 'soroban-client';
async function getInstanceValue(contractId: string): xdr.ContractDataEntry {
const instanceKey = xdr.LedgerKey.contractData(
new LedgerKeyContractData({
contract: new Address(contractId).toScAddress(),
key: xdr.ScVal.scvLedgerKeyContractInstance(),
durability: xdr.ContractDataDurability.persistent(),
})
);
// warning: ignoring error checks
const response = await Server('<rpc url>').getLedgerEntries(instanceKey);
const dataEntry = response.entries[0].val.contractData()
return dataEntry;
} Retrieve the WASM codeNow that we have the inner details of the contract instance, we can fetch the corresponding WASM. The async function getWasmCode(instance: xdr.ScContractInstance): Buffer {
const codeKey = xdr.LedgerKey.contractCode(
new xdr.LedgerKeyContractCode({
hash: instance.wasmHash()
})
);
// warning: ignoring error checks
const response = await Server('<rpc url>').getLedgerEntries(codeKey);
const wasmCode = response.entries[0].val.contractCode().code();
return wasmCode;
}
const code = getInstanceValue().then((value) => {
return getWasmCode(value.val().instance());
}); |
Thanks @Shaptic for your detailed guide. I was able to implement both functions: async getInstanceValue(contractId: string): Promise<xdr.ContractDataEntry> {
try {
const instanceKey = xdr.LedgerKey.contractData(
new xdr.LedgerKeyContractData({
contract: new Address(contractId).toScAddress(),
key: xdr.ScVal.scvLedgerKeyContractInstance(),
durability: xdr.ContractDataDurability.persistent(),
}),
);
const response = await this.server.getLedgerEntries(instanceKey);
const dataEntry = response.entries[0].val.contractData();
return dataEntry;
} catch (error) {
console.log('Error while getting instance value: ', error);
}
}
async getWasmCode(instance: xdr.ScContractInstance): Promise<Buffer> {
try {
const codeKey = xdr.LedgerKey.contractCode(
new xdr.LedgerKeyContractCode({
hash: instance.executable().wasmHash(),
}),
);
const response = await this.server.getLedgerEntries(codeKey);
const wasmCode = response.entries[0].val.contractCode().code();
return wasmCode;
} catch (error) {
console.log('Error while getting wasm code: ', error);
}
} The only problem I get now is that sometimes and it seems to be random I get the next error:
It happens in any of the two functions, Error while getting instance value: TypeError: expiration not set
at ChildUnion.get ([...]/node_modules/js-xdr/lib/webpack:/XDR/src/union.js:26:13)
at ChildUnion.get [as expiration] ([...]/node_modules/js-xdr/lib/webpack:/XDR/src/union.js:156:25)
at [...]/node_modules/soroban-client/lib/server.js:636:104
at Array.forEach (<anonymous>)
at mergeResponseExpirationLedgers ([...]/node_modules/soroban-client/lib/server.js:626:135)
at [...]/node_modules/soroban-client/lib/server.js:230:24
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at StellarService.getInstanceValue ([...]/src/common/application/service/stellar.service.ts:149:24)
at StellarService.getContractSpecEntries ([...]/src/common/application/service/stellar.service.ts:175:29)
at StellarService.runInvocation ([...]/src/common/application/service/stellar.service.ts:217:25)
Error while getting wasm code: TypeError: expiration not set
at ChildUnion.get ([...]/node_modules/js-xdr/lib/webpack:/XDR/src/union.js:26:13)
at ChildUnion.get [as expiration] ([...]/node_modules/js-xdr/lib/webpack:/XDR/src/union.js:156:25)
at [...]/node_modules/soroban-client/lib/server.js:636:104
at Array.forEach (<anonymous>)
at mergeResponseExpirationLedgers ([...]/node_modules/soroban-client/lib/server.js:626:135)
at [...]/node_modules/soroban-client/lib/server.js:230:24
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at StellarService.getWasmCode ([...]/src/common/application/service/stellar.service.ts:165:24)
at StellarService.getContractSpecEntries ([...]/src/common/application/service/stellar.service.ts:176:28)
at StellarService.runInvocation ([...]/src/common/application/service/stellar.service.ts:217:25) And it seems to be random, because if I retry most of the times it works without any problem 🤔 Any idea what could this be? |
### Summary - We want to replace the current way of getting the contract code, according to [this comment](stellar/js-soroban-client#166 (comment)) we should do it in a different way. ### Changes - Remove `getLedgerKeyWasmId` function - Add `getInstanceValue` and `getWasmCode` functions
Describe the bug
I'm trying to generate a contract's Wasm Code following the official docs. The problem I have is that TS is complaining about different issues specifically in this function:
I receive 2 errors when creating the instance:
Property 'wasmHash' is missing in type 'ScVal' but required in type 'ContractExecutable'.
any
I see the following error. Any idea what storage is in this case?Property 'storage' is missing in type '{ executable: any; }' but required in type '{ executable: ContractExecutable; storage: ScMapEntry[]; }'
When getting the wasm hash I get 2 more errors:
instance.executable()
Argument of type 'ContractExecutable' is not assignable to parameter of type 'Buffer'. Type 'ContractExecutable' is missing the following properties from type 'Buffer': write, toJSON, equals, compare, and 97 more.ts(2345)
instace()
Property 'instance' does not exist on type 'Buffer'
In JS files the function is working properly so I'm not sure how should I procede using TypeScript.
What version are you on?
^1.0.0-beta.3
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Happy to provide additional code or information if needed!
The text was updated successfully, but these errors were encountered: