├── .classpath
├── .gitattributes
├── .gitignore
├── .project
├── .settings
├── org.eclipse.buildship.core.prefs
└── org.eclipse.jdt.core.prefs
├── LICENSE
├── README.md
├── bin
└── .gitignore
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
├── java
│ └── com
│ │ └── scaleton
│ │ └── dfinity
│ │ ├── agent
│ │ ├── Agent.java
│ │ ├── AgentBuilder.java
│ │ ├── AgentConfig.java
│ │ ├── AgentError.java
│ │ ├── ByteUtils.java
│ │ ├── MethodType.java
│ │ ├── NonceFactory.java
│ │ ├── ProxyBuilder.java
│ │ ├── QueryBuilder.java
│ │ ├── ReplicaTransport.java
│ │ ├── RequestStatusResponse.java
│ │ ├── ResponseAuthentication.java
│ │ ├── Serialize.java
│ │ ├── Serializer.java
│ │ ├── Status.java
│ │ ├── UpdateBuilder.java
│ │ ├── Value.java
│ │ ├── Waiter.java
│ │ ├── annotations
│ │ │ ├── Agent.java
│ │ │ ├── Canister.java
│ │ │ ├── EffectiveCanister.java
│ │ │ ├── Identity.java
│ │ │ ├── IdentityType.java
│ │ │ ├── Transport.java
│ │ │ ├── TransportType.java
│ │ │ └── Waiter.java
│ │ ├── hashtree
│ │ │ ├── EmptyHashTreeNode.java
│ │ │ ├── ForkHashTreeNode.java
│ │ │ ├── HashTree.java
│ │ │ ├── HashTreeDeserializer.java
│ │ │ ├── HashTreeNode.java
│ │ │ ├── Label.java
│ │ │ ├── LabeledHashTreeNode.java
│ │ │ ├── LeafHashTreeNode.java
│ │ │ ├── LookupResult.java
│ │ │ ├── NodeType.java
│ │ │ └── PrunedHashTreeNode.java
│ │ ├── http
│ │ │ ├── ReplicaApacheHttpTransport.java
│ │ │ ├── ReplicaHttpProperties.java
│ │ │ └── ReplicaOkHttpTransport.java
│ │ ├── identity
│ │ │ ├── AnonymousIdentity.java
│ │ │ ├── BasicIdentity.java
│ │ │ ├── Identity.java
│ │ │ ├── PemError.java
│ │ │ ├── Secp256k1Identity.java
│ │ │ └── Signature.java
│ │ ├── replicaapi
│ │ │ ├── CallReply.java
│ │ │ ├── CallRequestContent.java
│ │ │ ├── Certificate.java
│ │ │ ├── Envelope.java
│ │ │ ├── QueryContent.java
│ │ │ ├── QueryResponse.java
│ │ │ ├── ReadStateContent.java
│ │ │ ├── ReadStateResponse.java
│ │ │ └── Status.java
│ │ └── requestid
│ │ │ ├── RequestId.java
│ │ │ ├── RequestIdError.java
│ │ │ └── RequestIdSerializer.java
│ │ ├── candid
│ │ ├── Bytes.java
│ │ ├── CandidError.java
│ │ ├── Deserialize.java
│ │ ├── Deserializer.java
│ │ ├── IDLBuilder.java
│ │ ├── IDLDeserialize.java
│ │ ├── IDLUtils.java
│ │ ├── Leb128.java
│ │ ├── ObjectDeserializer.java
│ │ ├── ObjectSerializer.java
│ │ ├── Serializer.java
│ │ ├── TypeSerialize.java
│ │ ├── TypeTable.java
│ │ ├── TypeTableResponse.java
│ │ ├── ValueSerializer.java
│ │ ├── annotations
│ │ │ ├── Argument.java
│ │ │ ├── Deserializer.java
│ │ │ ├── Field.java
│ │ │ ├── Ignore.java
│ │ │ ├── Name.java
│ │ │ ├── QUERY.java
│ │ │ ├── Serializer.java
│ │ │ └── UPDATE.java
│ │ ├── dom
│ │ │ ├── DOMDeserializer.java
│ │ │ ├── DOMSerDeserBase.java
│ │ │ ├── DOMSerializer.java
│ │ │ └── DOMUtils.java
│ │ ├── jackson
│ │ │ ├── JacksonDeserializer.java
│ │ │ └── JacksonSerializer.java
│ │ ├── jdbc
│ │ │ └── JDBCSerializer.java
│ │ ├── parser
│ │ │ ├── IDLArgs.java
│ │ │ ├── IDLField.java
│ │ │ ├── IDLType.java
│ │ │ └── IDLValue.java
│ │ ├── pojo
│ │ │ ├── PojoDeserializer.java
│ │ │ └── PojoSerializer.java
│ │ └── types
│ │ │ ├── Label.java
│ │ │ ├── Numbers.java
│ │ │ ├── Opcode.java
│ │ │ └── Type.java
│ │ └── types
│ │ ├── Principal.java
│ │ ├── PrincipalDeserializer.java
│ │ ├── PrincipalError.java
│ │ └── PrincipalSerializer.java
└── resources
│ ├── dfinity_agent.properties
│ ├── dfinity_candid.properties
│ ├── dfinity_pem.properties
│ ├── dfinity_requestid.properties
│ └── dfinity_types.properties
└── test
├── java
└── com
│ └── scaleton
│ └── dfinity
│ └── test
│ ├── CandidAssert.java
│ ├── CandidTest.java
│ ├── ComplexArrayPojo.java
│ ├── ComplexPojo.java
│ ├── DOMTest.java
│ ├── HelloProxy.java
│ ├── ICTest.java
│ ├── IdentityTest.java
│ ├── JDBCTest.java
│ ├── JacksonPojo.java
│ ├── JacksonTest.java
│ ├── MockTest.java
│ ├── Pojo.java
│ ├── PojoTest.java
│ ├── PrincipalTest.java
│ ├── QueryTest.java
│ ├── StatusTest.java
│ ├── TestProperties.java
│ └── UpdateTest.java
├── main.mo
└── resources
├── ComplexNode.xml
├── Ed25519_identity.pem
├── Secp256k1_identity.pem
├── SimpleArrayNode.json
├── SimpleNode.json
├── SimpleNode.xml
├── cbor.echoBool.query.response
├── cbor.echoFloat.query.response
├── cbor.echoInt.query.response
├── cbor.echoOption.query.response
├── cbor.echoPrincipal.query.response
├── cbor.echoRecord.query.response
├── cbor.echoVec.query.response
├── cbor.hello.query.response
├── cbor.peek.query.response
├── cbor.query.response
├── cbor.status.response
├── cbor.update.greet.response
├── rrkah-fqaaa-aaaaa-aaaaq-cai
├── rrkah-fqaaa-aaaaa-aaaaq-cai2.requestStatus
├── simplelogger.properties
└── test.properties
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | #
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | #
4 | # These are explicitly windows files and should use crlf
5 | *.bat text eol=crlf
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore Gradle project-specific cache directory
2 | .gradle
3 |
4 | # Ignore Gradle build output directory
5 | build
6 | /gradle.properties
7 | /build-export.gradle
8 | /secring.gpg
9 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | dfinityAgent
4 | Project dfinityAgent created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | arguments=
2 | auto.sync=false
3 | build.scans.enabled=false
4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.0.2))
5 | connection.project.dir=
6 | eclipse.preferences.version=1
7 | gradle.user.home=
8 | java.home=
9 | jvm.arguments=
10 | offline.mode=false
11 | override.workspace.settings=true
12 | show.console.view=true
13 | show.executions.view=true
14 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.8
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
12 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
13 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
14 | org.eclipse.jdt.core.compiler.release=disabled
15 | org.eclipse.jdt.core.compiler.source=1.8
16 |
--------------------------------------------------------------------------------
/bin/.gitignore:
--------------------------------------------------------------------------------
1 | /main/
2 | /test/
3 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * This generated file contains a sample Java Library project to get you started.
5 | * For more details take a look at the Java Libraries chapter in the Gradle
6 | * User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
7 | */
8 |
9 | plugins {
10 | id 'java'
11 | id 'eclipse'
12 | }
13 |
14 |
15 | group 'com.scaleton.dfinity'
16 | version '0.5.7'
17 |
18 | sourceCompatibility = 1.8
19 |
20 | repositories {
21 | mavenLocal()
22 | mavenCentral()
23 | }
24 |
25 | jar {
26 | manifest {
27 | attributes('Implementation-Title': 'dfinity-agent',
28 | 'Implementation-Version': project.version)
29 | }
30 |
31 | archiveBaseName = 'dfinity-agent'
32 | }
33 |
34 | task fatJar(type: Jar) {
35 | manifest {
36 | attributes('Implementation-Title': 'dfinity-agent',
37 | 'Implementation-Version': project.version)
38 | }
39 |
40 | archiveBaseName = 'dfinity-agent-with-dependencies'
41 |
42 | from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
43 | with jar
44 | }
45 |
46 | test {
47 | useJUnitPlatform()
48 |
49 | exclude '**/*ICTest*'
50 | }
51 |
52 | dependencies {
53 | // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
54 | implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
55 |
56 | // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
57 | implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.1'
58 |
59 | // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
60 | implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.9.2'
61 |
62 | // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
63 | implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.5'
64 |
65 | // https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jdk8
66 | implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: '2.12.5'
67 |
68 | // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor
69 | implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-cbor', version: '2.12.5'
70 |
71 | // https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on
72 | implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69'
73 |
74 | // https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on
75 | implementation group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.69'
76 |
77 | // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine
78 | testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.0'
79 |
80 | // https://mvnrepository.com/artifact/org.mock-server/mockserver-netty
81 | testImplementation group: 'org.mock-server', name: 'mockserver-netty', version: '5.11.2'
82 |
83 | // https://mvnrepository.com/artifact/org.mock-server/mockserver-junit-rule
84 | testImplementation group: 'org.mock-server', name: 'mockserver-junit-jupiter', version: '5.11.2'
85 |
86 | // https://mvnrepository.com/artifact/org.slf4j/slf4j-simple
87 | testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.32'
88 |
89 | // https://mvnrepository.com/artifact/org.skyscreamer/jsonassert
90 | testImplementation group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.0'
91 |
92 | // https://mvnrepository.com/artifact/org.apache.derby/derby
93 | testImplementation group: 'org.apache.derby', name: 'derby', version: '10.14.2.0'
94 | }
95 |
96 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rdobrik/dfinity-agent/ae064f8b9c22c8f3f4d7539ce101fef33862bcf2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 | @rem Execute Gradle
88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
89 |
90 | :end
91 | @rem End local scope for the variables with windows NT shell
92 | if "%ERRORLEVEL%"=="0" goto mainEnd
93 |
94 | :fail
95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
96 | rem the _cmd.exe /c_ return code!
97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
98 | exit /b 1
99 |
100 | :mainEnd
101 | if "%OS%"=="Windows_NT" endlocal
102 |
103 | :omega
104 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | *
6 | * Detailed information about configuring a multi-project build in Gradle can be found
7 | * in the user manual at https://docs.gradle.org/6.3/userguide/multi_project_builds.html
8 | */
9 |
10 | rootProject.name = 'dfinityAgent'
11 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/AgentBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.time.Duration;
20 | import java.util.Optional;
21 |
22 | import com.scaleton.dfinity.agent.identity.Identity;
23 |
24 |
25 | public class AgentBuilder {
26 | AgentConfig config = new AgentConfig();
27 |
28 | /**
29 | * Create an instance of [Agent] with the information from this builder.
30 | * @return agent Dfinity agent instance
31 | */
32 | public Agent build()
33 | {
34 | Agent agent = new Agent(this);
35 |
36 | return agent;
37 | }
38 |
39 | public AgentBuilder transport(ReplicaTransport transport)
40 | {
41 | this.config.transport = Optional.of(transport);
42 | return this;
43 | }
44 |
45 | /**
46 | * Provides a _default_ ingress expiry. This is the delta that will be applied
47 | * at the time an update or query is made. The default expiry cannot be a
48 | * fixed system time.
49 | * @param duration default ingress expiry
50 | */
51 |
52 | public AgentBuilder ingresExpiry(Duration duration)
53 | {
54 | this.config.ingressExpiryDuration = Optional.of(duration);
55 | return this;
56 | }
57 |
58 | /*
59 | * Add an identity provider for signing messages. This is required.
60 | * @param identity identity provider
61 | */
62 | public AgentBuilder identity(Identity identity)
63 | {
64 | this.config.identity = identity;
65 | return this;
66 | }
67 |
68 | /*
69 | * Add a NonceFactory to this Agent. By default, no nonce is produced.
70 | */
71 |
72 | public AgentBuilder nonceFactory(NonceFactory nonceFactory)
73 | {
74 | this.config.nonceFactory = nonceFactory;
75 | return this;
76 | }
77 |
78 |
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/AgentConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.time.Duration;
20 | import java.util.Optional;
21 |
22 | import com.scaleton.dfinity.agent.identity.AnonymousIdentity;
23 | import com.scaleton.dfinity.agent.identity.Identity;
24 |
25 | /**
26 | * A configuration for an agent.
27 | */
28 | class AgentConfig
29 | {
30 | AgentConfig()
31 | {
32 | }
33 |
34 | Optional transport = Optional.empty();
35 | Optional ingressExpiryDuration = Optional.empty();
36 | Identity identity = new AnonymousIdentity();
37 | NonceFactory nonceFactory = new NonceFactory();
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/AgentError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.text.MessageFormat;
20 | import java.util.ResourceBundle;
21 |
22 | public final class AgentError extends Error {
23 | /**
24 | *
25 | */
26 | private static final long serialVersionUID = 1L;
27 |
28 | final static String RESOURCE_BUNDLE_FILE = "dfinity_agent";
29 | static ResourceBundle properties;
30 |
31 | AgentErrorCode code;
32 |
33 |
34 | static {
35 | properties = ResourceBundle.getBundle(RESOURCE_BUNDLE_FILE);
36 | }
37 |
38 | public static AgentError create(AgentErrorCode code, Object... args) {
39 |
40 | String message = properties.getString(code.label);
41 | // set arguments
42 | message = MessageFormat.format(message, args);
43 |
44 | return new AgentError(code, message);
45 | }
46 |
47 | public static AgentError create(AgentErrorCode code,Throwable t, Object... args) {
48 |
49 | String message = properties.getString(code.label);
50 | // set arguments
51 | message = MessageFormat.format(message, args);
52 |
53 | return new AgentError(code,t, message);
54 | }
55 |
56 | private AgentError(AgentErrorCode code, String message) {
57 | super(message);
58 | }
59 |
60 | private AgentError(AgentErrorCode code, Throwable t, String message) {
61 | super(message, t);
62 | }
63 |
64 | public AgentErrorCode getCode() {
65 | return code;
66 | }
67 |
68 | public enum AgentErrorCode {
69 | INVALID_REPLICA_URL("InvalidReplicaUrl"),
70 | TIMEOUT_WAITING_FOR_RESPONSE("TimeoutWaitingForResponse"),
71 | URL_SYNTAX_ERROR("UrlSyntaxError"),
72 | URL_PARSE_ERROR("UrlParseError"),
73 | PRINCIPAL_ERROR("PrincipalError"),
74 | REPLICA_ERROR("ReplicaError"),
75 | INVALID_CBOR_DATA("InvalidCborData"),
76 | HTTP_ERROR("HttpError"),
77 | CANNOT_USE_AUTHENTICATION_ON_NONSECURE_URL("CannotUseAuthenticationOnNonSecureUrl"),
78 | AUTHENTICATION_ERROR("AuthenticationError"),
79 | INVALID_REPLICA_STATUS("InvalidReplicaStatus"),
80 | REQUEST_STATUS_DONE_NO_REPLY("RequestStatusDoneNoReply"),
81 | MESSAGE_ERROR("MessageError"),
82 | CUSTOM_ERROR("CustomError"),
83 | LEB128_READ_ERROR("Leb128ReadError"),
84 | UTF8_READ_ERROR("Utf8ReadError"),
85 | LOOKUP_PATH_ABSENT("LookupPathAbsent"),
86 | LOOKUP_PATH_UNKNOWN("LookupPathUnknown"),
87 | LOOKUP_PATH_ERROR("LookupPathError"),
88 | INVALID_REQUEST_STATUS("InvalidRequestStatus"),
89 | CERTIFICATE_VERIFICATION_FAILED("CertificateVerificationFailed"),
90 | NO_ROOT_KEY_IN_STATUS("NoRootKeyInStatus"),
91 | COULD_NOT_READ_ROOT_KEY("CouldNotReadRootKey"),
92 | MISSING_REPLICA_TRANSPORT("MissingReplicaTransport"),
93 | TRANSPORT_ERROR("TransportError");
94 |
95 | public String label;
96 |
97 | AgentErrorCode(String label) {
98 | this.label = label;
99 | }
100 |
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/ByteUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | public final class ByteUtils {
20 |
21 | /*
22 | * Helper function to convert byte array to unsigned int array.
23 | * Makes easier to compare with data in Rust implementation
24 | */
25 |
26 | public static int[] toUnsignedIntegerArray(byte[] input)
27 | {
28 | int[] output = new int[input.length];
29 |
30 | for(int i = 0; i < input.length; i++)
31 | output[i] = Byte.toUnsignedInt(input[i]);
32 |
33 | return output;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/MethodType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | enum MethodType {
20 | QUERY,UPDATE
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/NonceFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.security.SecureRandom;
20 |
21 | public final class NonceFactory {
22 |
23 | public byte[] generate()
24 | {
25 | byte[] nonce = new byte[16];
26 |
27 | new SecureRandom().nextBytes(nonce);
28 |
29 | return nonce;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/QueryBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.time.Duration;
20 | import java.time.LocalDateTime;
21 | import java.time.ZoneOffset;
22 | import java.util.Optional;
23 | import java.util.concurrent.CompletableFuture;
24 |
25 | import org.apache.commons.lang3.ArrayUtils;
26 |
27 | import com.scaleton.dfinity.types.Principal;
28 |
29 | /*
30 | * A Query Request Builder.
31 | * This makes it easier to do query calls without actually passing all arguments.
32 | */
33 |
34 | public final class QueryBuilder {
35 | Agent agent;
36 | Principal effectiveCanisterId;
37 | Principal canisterId;
38 | String methodName;
39 | byte[] arg;
40 | Optional ingressExpiryDatetime;
41 |
42 | QueryBuilder(Agent agent, Principal canisterId,String methodName )
43 | {
44 | this.agent = agent;
45 | this.canisterId = canisterId;
46 | this.methodName = methodName;
47 | this.effectiveCanisterId = canisterId.clone();
48 | this.ingressExpiryDatetime = Optional.empty();
49 | this.arg = ArrayUtils.EMPTY_BYTE_ARRAY;
50 | }
51 |
52 | public static QueryBuilder create(Agent agent, Principal canisterId,String methodName )
53 | {
54 | return new QueryBuilder(agent, canisterId, methodName);
55 | }
56 |
57 | public QueryBuilder effectiveCanisterId(Principal effectiveCanisterId)
58 | {
59 | this.effectiveCanisterId = effectiveCanisterId;
60 | return this;
61 | }
62 |
63 | public QueryBuilder arg(byte[] arg)
64 | {
65 | this.arg = arg;
66 | return this;
67 | }
68 |
69 | /**
70 | Takes a SystemTime converts it to a Duration by calling
71 | duration_since(UNIX_EPOCH) to learn about where in time this SystemTime lies.
72 | The Duration is converted to nanoseconds and stored in ingressExpiryDatetime
73 | */
74 | public QueryBuilder expireAt(LocalDateTime time)
75 | {
76 | this.ingressExpiryDatetime = Optional.of(time.toEpochSecond(ZoneOffset.UTC));
77 |
78 | return this;
79 | }
80 | /**
81 | Takes a Duration (i.e. 30 sec/5 min 30 sec/1 h 30 min, etc.) and adds it to the
82 | Duration of the current SystemTime since the UNIX_EPOCH
83 | Subtracts a permitted drift from the sum to account for using system time and not block time.
84 | Converts the difference to nanoseconds and stores in ingressExpiryDatetime
85 | */
86 |
87 | public QueryBuilder expireAfter(Duration duration)
88 | {
89 | Duration permittedDrift = Duration.ofSeconds(Agent.DEFAULT_PERMITTED_DRIFT);
90 |
91 | this.ingressExpiryDatetime = Optional.of((Duration.ofMillis(System.currentTimeMillis()).plus(duration).minus(permittedDrift)).toNanos());
92 |
93 | return this;
94 | }
95 |
96 | /*
97 | * Make a query call. This will return a byte vector.
98 | */
99 |
100 | public CompletableFuture call() throws AgentError
101 | {
102 | return agent.queryRaw(this.canisterId, this.effectiveCanisterId, this.methodName, this.arg, this.ingressExpiryDatetime);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/ReplicaTransport.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.util.concurrent.CompletableFuture;
20 |
21 | import com.scaleton.dfinity.agent.requestid.RequestId;
22 | import com.scaleton.dfinity.types.Principal;
23 |
24 |
25 | public interface ReplicaTransport {
26 |
27 | public CompletableFuture status();
28 |
29 | public CompletableFuture query(Principal canisterId, byte[] envelope);
30 |
31 | public CompletableFuture call(Principal canisterId, byte[] envelope, RequestId requestId);
32 |
33 | public CompletableFuture readState(Principal canisterId, byte[] envelope);
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/RequestStatusResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.util.Optional;
20 |
21 | import com.scaleton.dfinity.agent.replicaapi.CallReply;
22 |
23 | public final class RequestStatusResponse {
24 | public static final String UNKNOWN_STATUS_VALUE = "unknown";
25 | public static final String RECEIVED_STATUS_VALUE = "received";
26 | public static final String PROCESSING_STATUS_VALUE = "processing";
27 | public static final String REJECTED_STATUS_VALUE = "rejected";
28 | public static final String REPLIED_STATUS_VALUE = "replied";
29 | public static final String DONE_STATUS_VALUE = "done";
30 |
31 | public InnerStatus status;
32 |
33 | public Optional replied;
34 |
35 | public Optional rejected;
36 |
37 |
38 | RequestStatusResponse(InnerStatus status)
39 | {
40 | this.status = status;
41 | }
42 |
43 | RequestStatusResponse(CallReply replied)
44 | {
45 | this.status = InnerStatus.REPLIED_STATUS;
46 | this.replied = Optional.of(replied);
47 | }
48 |
49 | RequestStatusResponse(Integer rejectCode, String rejectMessage)
50 | {
51 |
52 | this.status = InnerStatus.REJECTED_STATUS;
53 | this.rejected = Optional.of(new Rejected(rejectCode, rejectMessage));
54 | }
55 |
56 | public final class Rejected {
57 | public Integer rejectCode;
58 | public String rejectMessage;
59 |
60 | Rejected(Integer rejectCode, String rejectMessage)
61 | {
62 | this.rejectCode = rejectCode;
63 | this.rejectMessage = rejectMessage;
64 | }
65 | }
66 |
67 | public enum InnerStatus {
68 | UNKNOWN_STATUS(UNKNOWN_STATUS_VALUE),
69 | RECEIVED_STATUS(RECEIVED_STATUS_VALUE),
70 | PROCESSING_STATUS(PROCESSING_STATUS_VALUE),
71 | REJECTED_STATUS(REJECTED_STATUS_VALUE),
72 | REPLIED_STATUS(REPLIED_STATUS_VALUE),
73 | DONE_STATUS(DONE_STATUS_VALUE);
74 |
75 | String value;
76 |
77 | InnerStatus(String value) {
78 | this.value = value;
79 | }
80 |
81 | public String toString()
82 | {
83 | return this.value;
84 | }
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/com/scaleton/dfinity/agent/ResponseAuthentication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Exilor Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.scaleton.dfinity.agent;
18 |
19 | import java.nio.charset.StandardCharsets;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import com.scaleton.dfinity.agent.hashtree.Label;
24 | import com.scaleton.dfinity.agent.hashtree.LookupResult;
25 | import com.scaleton.dfinity.agent.replicaapi.CallReply;
26 | import com.scaleton.dfinity.agent.replicaapi.Certificate;
27 | import com.scaleton.dfinity.agent.requestid.RequestId;
28 | import com.scaleton.dfinity.candid.Leb128;
29 |
30 | public final class ResponseAuthentication {
31 |
32 | static RequestStatusResponse lookupRequestStatus(Certificate certificate, RequestId requestId) throws AgentError
33 | {
34 | List